merge: reflect parent device manage/unmanage state for VLANs (rh #1114681)

VLAN device watches the parent and reacts to its state change. However, on
creation, the device was made managed, even if the parent was unmanaged. Fix
that and export VLAN parent device property too. The property is added to
libnm/libnm-glib and nmcli as well.

https://bugzilla.redhat.com/show_bug.cgi?id=1114681
This commit is contained in:
Jiří Klimeš 2014-11-24 10:42:03 +01:00
commit 67d030a4f5
11 changed files with 131 additions and 23 deletions

View file

@ -192,11 +192,12 @@ static NmcOutputField nmc_fields_dev_show_master_prop[] = {
/* Available fields for 'device show' - VLAN part */
static NmcOutputField nmc_fields_dev_show_vlan_prop[] = {
{"NAME", N_("NAME"), 18}, /* 0 */
{"ID", N_("ID"), 5}, /* 1 */
{"PARENT", N_("PARENT"), 10}, /* 1 */
{"ID", N_("ID"), 5}, /* 2 */
{NULL, NULL, 0}
};
#define NMC_FIELDS_DEV_SHOW_VLAN_PROP_ALL "NAME,ID"
#define NMC_FIELDS_DEV_SHOW_VLAN_PROP_COMMON "NAME,ID"
#define NMC_FIELDS_DEV_SHOW_VLAN_PROP_ALL "NAME,PARENT,ID"
#define NMC_FIELDS_DEV_SHOW_VLAN_PROP_COMMON "NAME,PARENT,ID"
/* Available fields for 'device show' - BLUETOOTH part */
static NmcOutputField nmc_fields_dev_show_bluetooth[] = {
@ -1084,6 +1085,7 @@ show_device_info (NMDevice *device, NmCli *nmc)
if ((NM_IS_DEVICE_VLAN (device))) {
if (!strcasecmp (nmc_fields_dev_show_sections[section_idx].name, nmc_fields_dev_show_sections[14].name)) {
char * vlan_id_str = g_strdup_printf ("%u", nm_device_vlan_get_vlan_id (NM_DEVICE_VLAN (device)));
NMDevice *parent = nm_device_vlan_get_parent (NM_DEVICE_VLAN (device));
tmpl = nmc_fields_dev_show_vlan_prop;
tmpl_len = sizeof (nmc_fields_dev_show_vlan_prop);
@ -1094,7 +1096,8 @@ show_device_info (NMDevice *device, NmCli *nmc)
arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX);
set_val_strc (arr, 0, nmc_fields_dev_show_sections[14].name); /* "VLAN" */
set_val_str (arr, 1, vlan_id_str);
set_val_strc (arr, 1, parent ? nm_device_get_iface (parent) : NULL);
set_val_str (arr, 2, vlan_id_str);
g_ptr_array_add (nmc->output_data, arr);
print_data (nmc); /* Print all data */

View file

@ -15,6 +15,12 @@
</tp:docstring>
</property>
<property name="Parent" type="o" access="read">
<tp:docstring>
Object path of the parent device of this VLAN device.
</tp:docstring>
</property>
<property name="VlanId" type="u" access="read">
<tp:docstring>
The VLAN ID of this VLAN interface.

View file

@ -183,6 +183,7 @@ global:
nm_device_vlan_error_quark;
nm_device_vlan_get_carrier;
nm_device_vlan_get_hw_address;
nm_device_vlan_get_parent;
nm_device_vlan_get_type;
nm_device_vlan_get_vlan_id;
nm_device_vlan_new;

View file

@ -42,6 +42,7 @@ typedef struct {
char *hw_address;
gboolean carrier;
NMDevice *parent;
guint vlan_id;
} NMDeviceVlanPrivate;
@ -49,6 +50,7 @@ enum {
PROP_0,
PROP_HW_ADDRESS,
PROP_CARRIER,
PROP_PARENT,
PROP_VLAN_ID,
LAST_PROP
@ -131,6 +133,23 @@ nm_device_vlan_get_carrier (NMDeviceVlan *device)
return NM_DEVICE_VLAN_GET_PRIVATE (device)->carrier;
}
/**
* nm_device_vlan_get_parent:
* @device: a #NMDeviceVlan
*
* Returns: the device's parent device
*
* Since: 1.0
**/
NMDevice *
nm_device_vlan_get_parent (NMDeviceVlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE);
_nm_object_ensure_inited (NM_OBJECT (device));
return NM_DEVICE_VLAN_GET_PRIVATE (device)->parent;
}
/**
* nm_device_vlan_get_vlan_id:
* @device: a #NMDeviceVlan
@ -231,6 +250,7 @@ register_properties (NMDeviceVlan *device)
const NMPropertiesInfo property_info[] = {
{ NM_DEVICE_VLAN_HW_ADDRESS, &priv->hw_address },
{ NM_DEVICE_VLAN_CARRIER, &priv->carrier },
{ NM_DEVICE_VLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
{ NM_DEVICE_VLAN_VLAN_ID, &priv->vlan_id },
{ NULL },
};
@ -256,6 +276,7 @@ dispose (GObject *object)
{
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
g_clear_object (&priv->parent);
g_clear_object (&priv->proxy);
G_OBJECT_CLASS (nm_device_vlan_parent_class)->dispose (object);
@ -288,6 +309,9 @@ get_property (GObject *object,
case PROP_CARRIER:
g_value_set_boolean (value, nm_device_vlan_get_carrier (device));
break;
case PROP_PARENT:
g_value_set_object (value, nm_device_vlan_get_parent (device));
break;
case PROP_VLAN_ID:
g_value_set_uint (value, nm_device_vlan_get_vlan_id (device));
break;
@ -340,6 +364,20 @@ nm_device_vlan_class_init (NMDeviceVlanClass *vlan_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVlan:parent:
*
* The devices's parent device.
*
* Since: 1.0
**/
g_object_class_install_property
(object_class, PROP_PARENT,
g_param_spec_object (NM_DEVICE_VLAN_PARENT, "", "",
NM_TYPE_DEVICE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVlan:vlan-id:
*

View file

@ -15,7 +15,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2012 Red Hat, Inc.
* Copyright 2012 - 2014 Red Hat, Inc.
*/
#ifndef NM_DEVICE_VLAN_H
@ -55,6 +55,7 @@ GQuark nm_device_vlan_error_quark (void);
#define NM_DEVICE_VLAN_HW_ADDRESS "hw-address"
#define NM_DEVICE_VLAN_CARRIER "carrier"
#define NM_DEVICE_VLAN_PARENT "parent"
#define NM_DEVICE_VLAN_VLAN_ID "vlan-id"
typedef struct {
@ -79,6 +80,8 @@ GObject *nm_device_vlan_new (DBusGConnection *connection, const char *path);
const char * nm_device_vlan_get_hw_address (NMDeviceVlan *device);
gboolean nm_device_vlan_get_carrier (NMDeviceVlan *device);
NM_AVAILABLE_IN_1_0
NMDevice * nm_device_vlan_get_parent (NMDeviceVlan *device);
guint nm_device_vlan_get_vlan_id (NMDeviceVlan *device);
G_END_DECLS

View file

@ -237,6 +237,7 @@ global:
nm_device_type_get_type;
nm_device_vlan_get_carrier;
nm_device_vlan_get_hw_address;
nm_device_vlan_get_parent;
nm_device_vlan_get_type;
nm_device_vlan_get_vlan_id;
nm_device_wifi_capabilities_get_type;

View file

@ -41,6 +41,7 @@ G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE)
typedef struct {
char *hw_address;
gboolean carrier;
NMDevice *parent;
guint vlan_id;
} NMDeviceVlanPrivate;
@ -48,6 +49,7 @@ enum {
PROP_0,
PROP_HW_ADDRESS,
PROP_CARRIER,
PROP_PARENT,
PROP_VLAN_ID,
LAST_PROP
@ -86,6 +88,20 @@ nm_device_vlan_get_carrier (NMDeviceVlan *device)
return NM_DEVICE_VLAN_GET_PRIVATE (device)->carrier;
}
/**
* nm_device_vlan_get_parent:
* @device: a #NMDeviceVlan
*
* Returns: the device's parent device
**/
NMDevice *
nm_device_vlan_get_parent (NMDeviceVlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE);
return NM_DEVICE_VLAN_GET_PRIVATE (device)->parent;
}
/**
* nm_device_vlan_get_vlan_id:
* @device: a #NMDeviceVlan
@ -166,6 +182,7 @@ init_dbus (NMObject *object)
const NMPropertiesInfo property_info[] = {
{ NM_DEVICE_VLAN_HW_ADDRESS, &priv->hw_address },
{ NM_DEVICE_VLAN_CARRIER, &priv->carrier },
{ NM_DEVICE_VLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
{ NM_DEVICE_VLAN_VLAN_ID, &priv->vlan_id },
{ NULL },
};
@ -183,6 +200,7 @@ finalize (GObject *object)
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
g_free (priv->hw_address);
g_clear_object (&priv->parent);
G_OBJECT_CLASS (nm_device_vlan_parent_class)->finalize (object);
}
@ -202,6 +220,9 @@ get_property (GObject *object,
case PROP_CARRIER:
g_value_set_boolean (value, nm_device_vlan_get_carrier (device));
break;
case PROP_PARENT:
g_value_set_object (value, nm_device_vlan_get_parent (device));
break;
case PROP_VLAN_ID:
g_value_set_uint (value, nm_device_vlan_get_vlan_id (device));
break;
@ -258,6 +279,18 @@ nm_device_vlan_class_init (NMDeviceVlanClass *vlan_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVlan:parent:
*
* The devices's parent device.
**/
g_object_class_install_property
(object_class, PROP_PARENT,
g_param_spec_object (NM_DEVICE_VLAN_PARENT, "", "",
NM_TYPE_DEVICE,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
* NMDeviceVlan:vlan-id:
*

View file

@ -15,7 +15,7 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* Copyright 2012 Red Hat, Inc.
* Copyright 2012 - 2014 Red Hat, Inc.
*/
#ifndef __NM_DEVICE_VLAN_H__
@ -38,6 +38,7 @@ G_BEGIN_DECLS
#define NM_DEVICE_VLAN_HW_ADDRESS "hw-address"
#define NM_DEVICE_VLAN_CARRIER "carrier"
#define NM_DEVICE_VLAN_PARENT "parent"
#define NM_DEVICE_VLAN_VLAN_ID "vlan-id"
struct _NMDeviceVlan {
@ -55,6 +56,7 @@ GType nm_device_vlan_get_type (void);
const char * nm_device_vlan_get_hw_address (NMDeviceVlan *device);
gboolean nm_device_vlan_get_carrier (NMDeviceVlan *device);
NMDevice * nm_device_vlan_get_parent (NMDeviceVlan *device);
guint nm_device_vlan_get_vlan_id (NMDeviceVlan *device);
G_END_DECLS

View file

@ -67,6 +67,8 @@ enum {
PROP_PARENT,
PROP_VLAN_ID,
PROP_INT_PARENT_DEVICE,
LAST_PROP
};
@ -406,16 +408,7 @@ parent_state_changed (NMDevice *parent,
if (reason == NM_DEVICE_STATE_REASON_CARRIER)
return;
if (new_state < NM_DEVICE_STATE_DISCONNECTED) {
/* If the parent becomes unavailable or unmanaged so does the VLAN */
nm_device_state_changed (NM_DEVICE (self), new_state, reason);
} else if ( new_state == NM_DEVICE_STATE_DISCONNECTED
&& old_state < NM_DEVICE_STATE_DISCONNECTED) {
/* Mark VLAN interface as available/disconnected when the parent
* becomes available as a result of becoming initialized.
*/
nm_device_state_changed (NM_DEVICE (self), new_state, reason);
}
nm_device_set_unmanaged (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent), reason);
}
/******************************************************************/
@ -477,6 +470,12 @@ get_property (GObject *object, guint prop_id,
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
switch (prop_id) {
case PROP_PARENT:
g_value_set_boxed (value, priv->parent ? nm_device_get_path (priv->parent) : "/");
break;
case PROP_INT_PARENT_DEVICE:
g_value_set_object (value, priv->parent);
break;
case PROP_VLAN_ID:
g_value_set_uint (value, priv->vlan_id);
break;
@ -493,7 +492,7 @@ set_property (GObject *object, guint prop_id,
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
switch (prop_id) {
case PROP_PARENT:
case PROP_INT_PARENT_DEVICE:
nm_device_vlan_set_parent (NM_DEVICE_VLAN (object), g_value_get_object (value));
break;
case PROP_VLAN_ID:
@ -564,10 +563,10 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
/* properties */
g_object_class_install_property
(object_class, PROP_PARENT,
g_param_spec_object (NM_DEVICE_VLAN_PARENT, "", "",
NM_TYPE_DEVICE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_param_spec_boxed (NM_DEVICE_VLAN_PARENT, "", "",
DBUS_TYPE_G_OBJECT_PATH,
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property
(object_class, PROP_VLAN_ID,
g_param_spec_uint (NM_DEVICE_VLAN_ID, "", "",
@ -575,6 +574,14 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/* Internal properties */
g_object_class_install_property
(object_class, PROP_INT_PARENT_DEVICE,
g_param_spec_object (NM_DEVICE_VLAN_INT_PARENT_DEVICE, "", "",
NM_TYPE_DEVICE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
G_TYPE_FROM_CLASS (klass),
&dbus_glib_nm_device_vlan_object_info);
@ -613,7 +620,7 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error)
device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN,
NM_DEVICE_PLATFORM_DEVICE, plink,
NM_DEVICE_VLAN_PARENT, parent,
NM_DEVICE_VLAN_INT_PARENT_DEVICE, parent,
NM_DEVICE_DRIVER, "8021q",
NM_DEVICE_TYPE_DESC, "VLAN",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN,
@ -623,6 +630,10 @@ new_link (NMDeviceFactory *factory, NMPlatformLink *plink, GError **error)
device = NULL;
}
/* Set initial parent-dependent unmanaged flag */
if (device)
nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_PARENT, !nm_device_get_managed (parent));
return device;
}
@ -663,7 +674,7 @@ create_virtual_device_for_connection (NMDeviceFactory *factory,
device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_VLAN,
NM_DEVICE_IFACE, iface,
NM_DEVICE_VLAN_PARENT, parent,
NM_DEVICE_VLAN_INT_PARENT_DEVICE, parent,
NM_DEVICE_DRIVER, "8021q",
NM_DEVICE_TYPE_DESC, "VLAN",
NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_VLAN,
@ -674,6 +685,10 @@ create_virtual_device_for_connection (NMDeviceFactory *factory,
device = NULL;
}
/* Set initial parent-dependent unmanaged flag */
if (device)
nm_device_set_initial_unmanaged_flag (device, NM_UNMANAGED_PARENT, !nm_device_get_managed (parent));
return device;
}

View file

@ -40,9 +40,13 @@ typedef enum {
NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
} NMVlanError;
/* D-Bus exported properties */
#define NM_DEVICE_VLAN_PARENT "parent"
#define NM_DEVICE_VLAN_ID "vlan-id"
/* Internal non-exported properties */
#define NM_DEVICE_VLAN_INT_PARENT_DEVICE "int-parent-device"
typedef NMDevice NMDeviceVlan;
typedef NMDeviceClass NMDeviceVlanClass;

View file

@ -301,12 +301,14 @@ RfKillType nm_device_get_rfkill_type (NMDevice *device);
* @NM_UNMANAGED_INTERNAL: %TRUE when unmanaged by internal decision (ie,
* because NM is sleeping or not managed for some other reason)
* @NM_UNMANAGED_USER: %TRUE when unmanaged by user decision (via unmanaged-specs)
* @NM_UNMANAGED_PARENT: %TRUE when unmanaged due to parent device being unmanaged
*/
typedef enum {
NM_UNMANAGED_NONE = 0x00,
NM_UNMANAGED_DEFAULT = 0x01,
NM_UNMANAGED_INTERNAL = 0x02,
NM_UNMANAGED_USER = 0x04,
NM_UNMANAGED_PARENT = 0x08,
/* Boundary value */
__NM_UNMANAGED_LAST,