platform: add NMPlatformLink.parent, sort link_get_all() output

Add a "parent" field to NMPlatformLink, giving the parent device
ifindex for devices that have a parent.

Make nm_platform_link_get_all() sort the links before returning them,
so that masters appear after all of their slaves, and parent devices
appear before their children.

Remove the second call to nm_platform_query_devices() from NMManager
since it is now guaranteed that an NMDeviceVLAN's parent NMDevice will
have been created before the NMDeviceVLAN.
This commit is contained in:
Dan Winship
2013-06-03 11:49:55 -03:00
parent 2fe8019a79
commit 05216f67d6
6 changed files with 42 additions and 12 deletions

View File

@@ -3728,14 +3728,6 @@ nm_manager_start (NMManager *self)
nm_atm_manager_query_devices (priv->atm_mgr);
nm_bluez_manager_query_devices (priv->bluez_mgr);
/* Query devices again to ensure that we catch all virtual interfaces (like
* VLANs) that require a parent. If during the first pass the VLAN
* interface was detected first, the parent wouldn't exist yet and creating
* the VLAN would fail. The second query ensures that we'll have a valid
* parent for the VLAN during the second pass.
*/
nm_platform_query_devices ();
/*
* Connections added before the manager is started do not emit
* connection-added signals thus devices have to be created manually.

View File

@@ -42,7 +42,6 @@ typedef struct {
char *udi;
GBytes *address;
int vlan_parent;
int vlan_id;
} NMFakePlatformLink;
@@ -529,7 +528,7 @@ vlan_add (NMPlatform *platform, const char *name, int parent, int vlan_id, guint
g_return_val_if_fail (device, FALSE);
device->vlan_id = vlan_id;
device->vlan_parent = parent;
device->link.parent = parent;
return TRUE;
}
@@ -542,7 +541,7 @@ vlan_get_info (NMPlatform *platform, int ifindex, int *parent, int *vlan_id)
g_return_val_if_fail (device, FALSE);
if (parent)
*parent = device->vlan_parent;
*parent = device->link.parent;
if (vlan_id)
*vlan_id = device->vlan_id;

View File

@@ -543,6 +543,7 @@ link_init (NMPlatform *platform, NMPlatformLink *info, struct rtnl_link *rtnllin
info->connected = !!(rtnl_link_get_flags (rtnllink) & IFF_LOWER_UP);
info->arp = !(rtnl_link_get_flags (rtnllink) & IFF_NOARP);
info->master = rtnl_link_get_master (rtnllink);
info->parent = rtnl_link_get_link (rtnllink);
info->mtu = rtnl_link_get_mtu (rtnllink);
udev_device = g_hash_table_lookup (priv->udev_devices, GINT_TO_POINTER (info->ifindex));

View File

@@ -261,6 +261,37 @@ nm_platform_query_devices (void)
g_array_unref (links_array);
}
static int
compare_links (gconstpointer a, gconstpointer b)
{
NMPlatformLink *link_a = (NMPlatformLink *) a;
NMPlatformLink *link_b = (NMPlatformLink *) b;
int sortindex_a, sortindex_b;
/* We mostly want to sort by ifindex. However, slaves should sort
* before their masters, and children (eg, VLANs) should sort after
* their parents.
*/
if (link_a->master)
sortindex_a = link_a->master * 3 - 1;
else if (link_a->parent)
sortindex_a = link_a->parent * 3 + 1;
else
sortindex_a = link_a->ifindex * 3;
if (link_b->master)
sortindex_b = link_b->master * 3 - 1;
else if (link_b->parent)
sortindex_b = link_b->parent * 3 + 1;
else
sortindex_b = link_b->ifindex * 3;
if (sortindex_a == sortindex_b)
return link_a->ifindex - link_b->ifindex;
else
return sortindex_a - sortindex_b;
}
/**
* nm_platform_link_get_all:
*
@@ -270,11 +301,15 @@ nm_platform_query_devices (void)
GArray *
nm_platform_link_get_all (void)
{
GArray *links;
reset_error ();
g_return_val_if_fail (klass->link_get_all, NULL);
return klass->link_get_all (platform);
links = klass->link_get_all (platform);
g_array_sort (links, compare_links);
return links;
}
/**

View File

@@ -85,6 +85,7 @@ typedef struct {
const char *udi;
const char *driver;
int master;
int parent;
gboolean up;
gboolean connected;
gboolean arp;

View File

@@ -36,6 +36,8 @@ dump_interface (NMPlatformLink *link)
printf (" noarp");
if (link->master)
printf (" master %d", link->master);
if (link->parent)
printf (" parent %d", link->parent);
printf (" mtu %d", link->mtu);
printf ("\n");
if (link->driver)