From 2bc903aaf1adeea0ab248f85dee770d46f2f876a Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 26 Feb 2014 13:32:30 -0500 Subject: [PATCH] devices: fix up parent/peer tracking in some virtual devices NMDeviceGre and NMDeviceMacvlan didn't deal with the possibility that the virtual device might be created before its parent's NMDevice is created. Mostly fix this by having them put off the call to nm_manager_get_device_by_ifindex() until someone actually requests the device. This is not perfect; if someone listening to notify::parent checks right away, they may find that the parent property is still NULL, and notify::parent will not be emitted again when it gets filled in. But it's better than what's there now, when parent would remain NULL forever in this case. NMDeviceVeth did not have this problem, but it did have another possible problem because it wasn't cleaning up its weak references properly. --- src/devices/nm-device-gre.c | 14 ++++---------- src/devices/nm-device-macvlan.c | 13 ++++--------- src/devices/nm-device-veth.c | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/devices/nm-device-gre.c b/src/devices/nm-device-gre.c index 3e5fdd1be..0412e9931 100644 --- a/src/devices/nm-device-gre.c +++ b/src/devices/nm-device-gre.c @@ -36,7 +36,6 @@ G_DEFINE_TYPE (NMDeviceGre, nm_device_gre, NM_TYPE_DEVICE_GENERIC) #define NM_DEVICE_GRE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_GRE, NMDeviceGrePrivate)) typedef struct { - NMDevice *parent; NMPlatformGreProperties props; } NMDeviceGrePrivate; @@ -73,15 +72,8 @@ update_properties (NMDevice *device) g_object_freeze_notify (object); - if (priv->props.parent_ifindex != props.parent_ifindex) { + if (priv->props.parent_ifindex != props.parent_ifindex) g_object_notify (object, NM_DEVICE_GRE_PARENT); - if (priv->parent) - g_object_remove_weak_pointer (G_OBJECT (priv->parent), (gpointer *) &priv->parent); - priv->parent = nm_manager_get_device_by_ifindex (nm_manager_get (), props.parent_ifindex); - if (priv->parent) - g_object_add_weak_pointer (G_OBJECT (priv->parent), (gpointer *) &priv->parent); - } - if (priv->props.input_flags != props.input_flags) g_object_notify (object, NM_DEVICE_GRE_INPUT_FLAGS); if (priv->props.output_flags != props.output_flags) @@ -146,10 +138,12 @@ get_property (GObject *object, guint prop_id, { NMDeviceGrePrivate *priv = NM_DEVICE_GRE_GET_PRIVATE (object); char buf[INET_ADDRSTRLEN]; + NMDevice *parent; switch (prop_id) { case PROP_PARENT: - g_value_set_boxed (value, priv->parent ? nm_device_get_path (priv->parent) : "/"); + parent = nm_manager_get_device_by_ifindex (nm_manager_get (), priv->props.parent_ifindex); + g_value_set_boxed (value, parent ? nm_device_get_path (parent) : "/"); break; case PROP_INPUT_FLAGS: g_value_set_uint (value, priv->props.input_flags); diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index fa71c3558..22848fe78 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -36,7 +36,6 @@ G_DEFINE_TYPE (NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE_GENERIC) #define NM_DEVICE_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanPrivate)) typedef struct { - NMDevice *parent; NMPlatformMacvlanProperties props; } NMDeviceMacvlanPrivate; @@ -68,14 +67,8 @@ update_properties (NMDevice *device) g_object_freeze_notify (object); - if (priv->props.parent_ifindex != props.parent_ifindex) { + if (priv->props.parent_ifindex != props.parent_ifindex) g_object_notify (object, NM_DEVICE_MACVLAN_PARENT); - if (priv->parent) - g_object_remove_weak_pointer (G_OBJECT (priv->parent), (gpointer *) &priv->parent); - priv->parent = nm_manager_get_device_by_ifindex (nm_manager_get (), props.parent_ifindex); - if (priv->parent) - g_object_add_weak_pointer (G_OBJECT (priv->parent), (gpointer *) &priv->parent); - } if (g_strcmp0 (priv->props.mode, props.mode) != 0) g_object_notify (object, NM_DEVICE_MACVLAN_MODE); if (priv->props.no_promisc != props.no_promisc) @@ -125,10 +118,12 @@ get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object); + NMDevice *parent; switch (prop_id) { case PROP_PARENT: - g_value_set_boxed (value, priv->parent ? nm_device_get_path (priv->parent) : "/"); + parent = nm_manager_get_device_by_ifindex (nm_manager_get (), priv->props.parent_ifindex); + g_value_set_boxed (value, parent ? nm_device_get_path (parent) : "/"); break; case PROP_MODE: g_value_set_string (value, priv->props.mode); diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c index fdc44565e..523016e1e 100644 --- a/src/devices/nm-device-veth.c +++ b/src/devices/nm-device-veth.c @@ -113,6 +113,20 @@ nm_device_veth_init (NMDeviceVeth *self) { } +static void +dispose (GObject *object) +{ + NMDeviceVeth *self = NM_DEVICE_VETH (object); + NMDeviceVethPrivate *priv = NM_DEVICE_VETH_GET_PRIVATE (self); + + if (priv->peer) { + g_object_remove_weak_pointer (G_OBJECT (priv->peer), (gpointer *) &priv->peer); + priv->peer = NULL; + } + + G_OBJECT_CLASS (nm_device_veth_parent_class)->dispose (object); +} + static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -139,6 +153,7 @@ nm_device_veth_class_init (NMDeviceVethClass *klass) g_type_class_add_private (klass, sizeof (NMDeviceVethPrivate)); object_class->get_property = get_property; + object_class->dispose = dispose; /* properties */ g_object_class_install_property