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 3e5fdd1bea..0412e99312 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 fa71c35583..22848fe78b 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 fdc44565e3..523016e1e8 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