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.
This commit is contained in:
@@ -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))
|
#define NM_DEVICE_GRE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_GRE, NMDeviceGrePrivate))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMDevice *parent;
|
|
||||||
NMPlatformGreProperties props;
|
NMPlatformGreProperties props;
|
||||||
} NMDeviceGrePrivate;
|
} NMDeviceGrePrivate;
|
||||||
|
|
||||||
@@ -73,15 +72,8 @@ update_properties (NMDevice *device)
|
|||||||
|
|
||||||
g_object_freeze_notify (object);
|
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);
|
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)
|
if (priv->props.input_flags != props.input_flags)
|
||||||
g_object_notify (object, NM_DEVICE_GRE_INPUT_FLAGS);
|
g_object_notify (object, NM_DEVICE_GRE_INPUT_FLAGS);
|
||||||
if (priv->props.output_flags != props.output_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);
|
NMDeviceGrePrivate *priv = NM_DEVICE_GRE_GET_PRIVATE (object);
|
||||||
char buf[INET_ADDRSTRLEN];
|
char buf[INET_ADDRSTRLEN];
|
||||||
|
NMDevice *parent;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_PARENT:
|
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;
|
break;
|
||||||
case PROP_INPUT_FLAGS:
|
case PROP_INPUT_FLAGS:
|
||||||
g_value_set_uint (value, priv->props.input_flags);
|
g_value_set_uint (value, priv->props.input_flags);
|
||||||
|
@@ -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))
|
#define NM_DEVICE_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanPrivate))
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMDevice *parent;
|
|
||||||
NMPlatformMacvlanProperties props;
|
NMPlatformMacvlanProperties props;
|
||||||
} NMDeviceMacvlanPrivate;
|
} NMDeviceMacvlanPrivate;
|
||||||
|
|
||||||
@@ -68,14 +67,8 @@ update_properties (NMDevice *device)
|
|||||||
|
|
||||||
g_object_freeze_notify (object);
|
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);
|
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)
|
if (g_strcmp0 (priv->props.mode, props.mode) != 0)
|
||||||
g_object_notify (object, NM_DEVICE_MACVLAN_MODE);
|
g_object_notify (object, NM_DEVICE_MACVLAN_MODE);
|
||||||
if (priv->props.no_promisc != props.no_promisc)
|
if (priv->props.no_promisc != props.no_promisc)
|
||||||
@@ -125,10 +118,12 @@ get_property (GObject *object, guint prop_id,
|
|||||||
GValue *value, GParamSpec *pspec)
|
GValue *value, GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object);
|
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object);
|
||||||
|
NMDevice *parent;
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_PARENT:
|
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;
|
break;
|
||||||
case PROP_MODE:
|
case PROP_MODE:
|
||||||
g_value_set_string (value, priv->props.mode);
|
g_value_set_string (value, priv->props.mode);
|
||||||
|
@@ -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
|
static void
|
||||||
get_property (GObject *object, guint prop_id,
|
get_property (GObject *object, guint prop_id,
|
||||||
GValue *value, GParamSpec *pspec)
|
GValue *value, GParamSpec *pspec)
|
||||||
@@ -139,6 +153,7 @@ nm_device_veth_class_init (NMDeviceVethClass *klass)
|
|||||||
g_type_class_add_private (klass, sizeof (NMDeviceVethPrivate));
|
g_type_class_add_private (klass, sizeof (NMDeviceVethPrivate));
|
||||||
|
|
||||||
object_class->get_property = get_property;
|
object_class->get_property = get_property;
|
||||||
|
object_class->dispose = dispose;
|
||||||
|
|
||||||
/* properties */
|
/* properties */
|
||||||
g_object_class_install_property
|
g_object_class_install_property
|
||||||
|
Reference in New Issue
Block a user