diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2016-10-18 16:35:07 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2016-11-10 16:48:48 +0100 |
commit | 1f5b48a59eb46c40cb10bf4381b2b21a19a9f471 (patch) | |
tree | ff92cacbfccf0c1b1bb09ee397c515bcd6b90b5e /libnm/nm-device.c | |
parent | ff3eb24c15154d2fa7aec9cb1882c63e83a65e70 (diff) | |
download | NetworkManager-1f5b48a59eb46c40cb10bf4381b2b21a19a9f471.tar.gz |
libnm: use the o.fd.DBus.ObjectManager API for object managementlr/object-manager
This speeds up the initial object tree load significantly. Also, it
reduces the object management complexity by shifting the duties to
GDBusObjectManager.
The lifetime of all NMObjects is now managed by the NMClient via the
object manager. The NMClient creates the NMObjects for GDBus objects,
triggers the initialization and serves as an object registry (replaces
the nm-cache).
The ObjectManager uses the o.fd.DBus.ObjectManager API to learn of the
object creation, removal and property changes. It takes care of the
property changes so that we don't have to and lets us always see a
consistent object state. Thus at the time we learn of a new object we
already know its properties.
The NMObject unfortunately can't be made synchronously initializable as
the NMRemoteConnection's settings are not managed with standard
o.fd.DBus Properties and ObjectManager APIs and thus are not known to
the ObjectManager. Thus most of the asynchronous object property
changing code in nm-object.c is preserved. The objects notify the
properties that reference them of their initialization in from their
init_finish() methods, thus the asynchronously created objects are not
allowed to fail creation (or the dependees would wait forever). Not a
problem -- if a connection can't get its Settings, it's either invisible
or being removed (presumably we'd learn of the removal from the object
manager soon).
The NMObjects can't be created by the object manager itself, since we
can't determine the resulting object type in proxy_type() yet (we can't
tell from the name and can't access the interface list). Therefore the
GDBusObject is coupled with a NMObject later on.
Lastly, now that all the objects are managed by the object manager, the
NMRemoteSettings and NMManager go away when the daemon is stopped. The
complexity of dealing with calls to NMClient that would require any of
the resources that these objects manage (connection or device lists,
etc.) had to be moved to NMClient. The bright side is that his allows
for removal all of the daemon presence tracking from NMObject.
Diffstat (limited to 'libnm/nm-device.c')
-rw-r--r-- | libnm/nm-device.c | 193 |
1 files changed, 8 insertions, 185 deletions
diff --git a/libnm/nm-device.c b/libnm/nm-device.c index 228e60b70b..25788d92b1 100644 --- a/libnm/nm-device.c +++ b/libnm/nm-device.c @@ -28,29 +28,12 @@ #include "nm-dbus-interface.h" #include "nm-active-connection.h" -#include "nm-device-ethernet.h" -#include "nm-device-adsl.h" -#include "nm-device-wifi.h" -#include "nm-device-modem.h" #include "nm-device-bt.h" -#include "nm-device-olpc-mesh.h" -#include "nm-device-wimax.h" -#include "nm-device-infiniband.h" -#include "nm-device-bond.h" -#include "nm-device-team.h" -#include "nm-device-bridge.h" -#include "nm-device-vlan.h" -#include "nm-device-vxlan.h" -#include "nm-device-generic.h" -#include "nm-device-ip-tunnel.h" -#include "nm-device-macvlan.h" -#include "nm-device-private.h" #include "nm-dhcp4-config.h" #include "nm-dhcp6-config.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" #include "nm-object-private.h" -#include "nm-object-cache.h" #include "nm-remote-connection.h" #include "nm-core-internal.h" #include "nm-utils.h" @@ -60,16 +43,10 @@ #include "nmdbus-device.h" -static GType _nm_device_decide_type (GVariant *value); static gboolean connection_compatible (NMDevice *device, NMConnection *connection, GError **error); static NMLldpNeighbor *nm_lldp_neighbor_dup (NMLldpNeighbor *neighbor); -G_DEFINE_TYPE_WITH_CODE (NMDevice, nm_device, NM_TYPE_OBJECT, - _nm_object_register_type_func (g_define_type_id, - _nm_device_decide_type, - NM_DBUS_INTERFACE_DEVICE, - "DeviceType"); - ) +G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_OBJECT); #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate)) @@ -213,11 +190,7 @@ demarshal_lldp_neighbors (NMObject *object, GParamSpec *pspec, GVariant *value, } static void -device_state_changed (NMDBusDevice *proxy, - guint new_state, - guint old_state, - guint reason, - gpointer user_data); +device_state_reason_changed (GObject *object, GParamSpec *pspec, gpointer user_data); static void init_dbus (NMObject *object) @@ -263,136 +236,19 @@ init_dbus (NMObject *object) NM_DBUS_INTERFACE_DEVICE, property_info); - g_signal_connect (priv->proxy, "state-changed", - G_CALLBACK (device_state_changed), object); + g_signal_connect (priv->proxy, "notify::state-reason", + G_CALLBACK (device_state_reason_changed), object); } -typedef struct { - NMDeviceState old_state; - NMDeviceState new_state; - NMDeviceStateReason reason; -} StateChangeData; - static void -device_state_change_reloaded (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - NMDevice *self = NM_DEVICE (object); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - StateChangeData *data = user_data; - NMDeviceState old_state = data->old_state; - NMDeviceState new_state = data->new_state; - NMDeviceStateReason reason = data->reason; - - g_slice_free (StateChangeData, data); - - _nm_object_reload_properties_finish (NM_OBJECT (object), result, NULL); - - /* If the device changes state several times in rapid succession, then we'll - * queue several reload_properties() calls, and there's no guarantee that - * they'll finish in the right order. In that case, only emit the signal - * for the last one. - */ - if (priv->last_seen_state != new_state) - return; - - /* Ensure that nm_device_get_state() will return the right value even if - * we haven't processed the corresponding PropertiesChanged yet. - */ - priv->state = new_state; - - g_signal_emit (self, signals[STATE_CHANGED], 0, - new_state, old_state, reason); -} - -static void -device_state_changed (NMDBusDevice *proxy, - guint new_state, - guint old_state, - guint reason, - gpointer user_data) +device_state_reason_changed (GObject *object, GParamSpec *pspec, gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - StateChangeData *data; - - if (old_state == new_state) - return; - - /* Our object-valued properties (eg, ip4_config) will still - * have their old values at this point, because NMObject is - * in the process of asynchronously reading the new values. - * Wait for that to finish before emitting the signal. - */ - priv->last_seen_state = new_state; - - data = g_slice_new (StateChangeData); - data->old_state = old_state; - data->new_state = new_state; - data->reason = reason; - _nm_object_reload_properties_async (NM_OBJECT (user_data), - NULL, - device_state_change_reloaded, - data); -} - -static GType -_nm_device_gtype_from_dtype (NMDeviceType dtype) -{ - switch (dtype) { - case NM_DEVICE_TYPE_VETH: - case NM_DEVICE_TYPE_ETHERNET: - return NM_TYPE_DEVICE_ETHERNET; - case NM_DEVICE_TYPE_WIFI: - return NM_TYPE_DEVICE_WIFI; - case NM_DEVICE_TYPE_MODEM: - return NM_TYPE_DEVICE_MODEM; - case NM_DEVICE_TYPE_BT: - return NM_TYPE_DEVICE_BT; - case NM_DEVICE_TYPE_ADSL: - return NM_TYPE_DEVICE_ADSL; - case NM_DEVICE_TYPE_OLPC_MESH: - return NM_TYPE_DEVICE_OLPC_MESH; - case NM_DEVICE_TYPE_WIMAX: - return NM_TYPE_DEVICE_WIMAX; - case NM_DEVICE_TYPE_INFINIBAND: - return NM_TYPE_DEVICE_INFINIBAND; - case NM_DEVICE_TYPE_BOND: - return NM_TYPE_DEVICE_BOND; - case NM_DEVICE_TYPE_TEAM: - return NM_TYPE_DEVICE_TEAM; - case NM_DEVICE_TYPE_BRIDGE: - return NM_TYPE_DEVICE_BRIDGE; - case NM_DEVICE_TYPE_VLAN: - return NM_TYPE_DEVICE_VLAN; - case NM_DEVICE_TYPE_GENERIC: - return NM_TYPE_DEVICE_GENERIC; - case NM_DEVICE_TYPE_TUN: - return NM_TYPE_DEVICE_TUN; - case NM_DEVICE_TYPE_IP_TUNNEL: - return NM_TYPE_DEVICE_IP_TUNNEL; - case NM_DEVICE_TYPE_MACVLAN: - return NM_TYPE_DEVICE_MACVLAN; - case NM_DEVICE_TYPE_VXLAN: - return NM_TYPE_DEVICE_VXLAN; - default: - g_warning ("Unknown device type %d", dtype); - return G_TYPE_INVALID; - } -} - -static void -constructed (GObject *object) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); - - G_OBJECT_CLASS (nm_device_parent_class)->constructed (object); - /* Catch failure of subclasses to call _nm_device_set_device_type() */ - g_warn_if_fail (priv->device_type != NM_DEVICE_TYPE_UNKNOWN); - /* Catch a subclass setting the wrong type */ - g_warn_if_fail (G_OBJECT_TYPE (object) == _nm_device_gtype_from_dtype (priv->device_type)); + g_signal_emit (self, signals[STATE_CHANGED], 0, + priv->state, priv->last_seen_state, priv->reason); + priv->last_seen_state = priv->state; } static void @@ -571,11 +427,7 @@ nm_device_class_init (NMDeviceClass *device_class) g_type_class_add_private (device_class, sizeof (NMDevicePrivate)); - _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE); - _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_DEVICE, NMDBUS_TYPE_DEVICE_PROXY); - /* virtual methods */ - object_class->constructed = constructed; object_class->get_property = get_property; object_class->set_property = set_property; object_class->dispose = dispose; @@ -954,35 +806,6 @@ nm_device_class_init (NMDeviceClass *device_class) } /** - * _nm_device_set_device_type: - * @device: the device - * @dtype: the NM device type - * - * Sets the NM device type if it wasn't set during construction. INTERNAL - * ONLY METHOD. - **/ -void -_nm_device_set_device_type (NMDevice *device, NMDeviceType dtype) -{ - NMDevicePrivate *priv; - - g_return_if_fail (device != NULL); - g_return_if_fail (dtype != NM_DEVICE_TYPE_UNKNOWN); - - priv = NM_DEVICE_GET_PRIVATE (device); - if (priv->device_type == NM_DEVICE_TYPE_UNKNOWN) - priv->device_type = dtype; - else - g_warn_if_fail (dtype == priv->device_type); -} - -static GType -_nm_device_decide_type (GVariant *value) -{ - return _nm_device_gtype_from_dtype (g_variant_get_uint32 (value)); -} - -/** * nm_device_get_iface: * @device: a #NMDevice * |