platform: fix getting "ifindex" for devices on 'remove' udev action

We have to get IFINDEX using g_udev_device_get_property() instead of
g_udev_device_get_sysfs_attr().

On removal the IFINDEX in sysfs may not be available - this didn't caused
problems because such an event was ignored. But sometimes the sysfs IFINDEX
in 'remove' action was present, but *wrong*. It contained IFINDEX of a newly
created device of the same name, and thus it triggered removal of the new
device instead of the old one.

Logs (grepped):
...
NetworkManager[30628]: <info> Auto-activating connection 'b1'.
NetworkManager[30628]: <debug> [1381930187.149545] [platform/nm-platform.c:1777] log_link(): signal: link added: bb (328)
NetworkManager[30628]: <debug> [1381930187.937222] [platform/nm-linux-platform.c:2568] handle_udev_event(): UDEV event: action 'add' subsys 'net' device 'bb' (328)
NetworkManager[30628]: <debug> [1381930187.937662] [platform/nm-platform.c:1777] log_link(): signal: link added: bb (328)
NetworkManager[30628]: <info> (bb): deactivating device (reason 'user-requested') [39]
NetworkManager[30628]: <debug> [1381930193.266097] [platform/nm-platform.c:397] nm_platform_link_delete(): link: deleting 'bb' (328)
NetworkManager[30628]: <debug> [1381930193.279324] [platform/nm-platform.c:1777] log_link(): signal: link removed: bb (328)
NetworkManager[30628]: <debug> [1381930193.348167] [platform/nm-linux-platform.c:2568] handle_udev_event(): UDEV event: action 'remove' subsys 'net' device 'bb' (unknown)
NetworkManager[30628]: <info> Auto-activating connection 'b1'.
NetworkManager[30628]: <debug> [1381930193.561106] [platform/nm-platform.c:1777] log_link(): signal: link added: bb (330)
NetworkManager[30628]: <debug> [1381930194.217300] [platform/nm-linux-platform.c:2568] handle_udev_event(): UDEV event: action 'add' subsys 'net' device 'bb' (330)
NetworkManager[30628]: <debug> [1381930194.217548] [platform/nm-platform.c:1777] log_link(): signal: link added: bb (330)
NetworkManager[30628]: <info> (bb): deactivating device (reason 'user-requested') [39]
NetworkManager[30628]: <debug> [1381930216.329118] [platform/nm-platform.c:397] nm_platform_link_delete(): link: deleting 'bb' (330)
NetworkManager[30628]: <debug> [1381930216.344442] [platform/nm-platform.c:1777] log_link(): signal: link removed: bb (330)
NetworkManager[30628]: <info> Auto-activating connection 'b1'.
NetworkManager[30628]: <debug> [1381930216.598636] [platform/nm-platform.c:1777] log_link(): signal: link added: bb (332)

This line is bad:
NetworkManager[30628]: <debug> [1381930217.79182] [platform/nm-linux-platform.c:2568] handle_udev_event(): UDEV event: action 'remove' subsys 'net' device 'bb' (332)

NetworkManager[30628]: <debug> [1381930217.81009] [platform/nm-platform.c:1777] log_link(): signal: link removed: bb (332)
NetworkManager[30628]: <info> (bb): deactivating device (reason 'removed') [36]
NetworkManager[30628]: <debug> [1381930217.95192] [platform/nm-linux-platform.c:2568] handle_udev_event(): UDEV event: action 'add' subsys 'net' device 'bb' (332)
NetworkManager[30628]: <debug> [1381930217.95492] [platform/nm-platform.c:1777] log_link(): signal: link added: bb (332)
NetworkManager[30628]: <info> Auto-activating connection 'b1'.
...
This commit is contained in:
Jiří Klimeš
2013-10-16 18:24:59 +02:00
parent 8ecbe53f37
commit a6944e157b
2 changed files with 18 additions and 15 deletions

View File

@@ -146,6 +146,7 @@ handle_uevent (GUdevClient *client,
NMAtmManager *self = NM_ATM_MANAGER (user_data); NMAtmManager *self = NM_ATM_MANAGER (user_data);
const char *subsys; const char *subsys;
const char *ifindex; const char *ifindex;
guint64 seqnum;
g_return_if_fail (action != NULL); g_return_if_fail (action != NULL);
@@ -153,10 +154,10 @@ handle_uevent (GUdevClient *client,
subsys = g_udev_device_get_subsystem (device); subsys = g_udev_device_get_subsystem (device);
g_return_if_fail (!g_strcmp0 (subsys, "atm")); g_return_if_fail (!g_strcmp0 (subsys, "atm"));
ifindex = g_udev_device_get_sysfs_attr (device, "ifindex"); ifindex = g_udev_device_get_property (device, "IFINDEX");
seqnum = g_udev_device_get_seqnum (device);
nm_log_dbg (LOGD_HW, "UDEV event: action '%s' subsys '%s' device '%s' (%s)", nm_log_dbg (LOGD_HW, "UDEV event: action '%s' subsys '%s' device '%s' (%s); seqnum=%" G_GUINT64_FORMAT,
action, subsys, g_udev_device_get_name (device), ifindex ? ifindex : "unknown"); action, subsys, g_udev_device_get_name (device), ifindex ? ifindex : "unknown", seqnum);
if (!strcmp (action, "add")) if (!strcmp (action, "add"))
adsl_add (self, device); adsl_add (self, device);

View File

@@ -2485,8 +2485,8 @@ udev_device_added (NMPlatform *platform,
return; return;
} }
if (g_udev_device_get_sysfs_attr (udev_device, "ifindex")) if (g_udev_device_get_property (udev_device, "IFINDEX"))
ifindex = g_udev_device_get_sysfs_attr_as_int (udev_device, "ifindex"); ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX");
else { else {
warning ("(%s): failed to get device's ifindex", ifname); warning ("(%s): failed to get device's ifindex", ifname);
return; return;
@@ -2517,15 +2517,16 @@ udev_device_removed (NMPlatform *platform,
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
int ifindex = 0; int ifindex = 0;
if (g_udev_device_get_sysfs_attr (udev_device, "ifindex")) { if (g_udev_device_get_property (udev_device, "IFINDEX")) {
ifindex = g_udev_device_get_sysfs_attr_as_int (udev_device, "ifindex"); ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX");
g_hash_table_remove (priv->udev_devices, GINT_TO_POINTER (ifindex)); g_hash_table_remove (priv->udev_devices, GINT_TO_POINTER (ifindex));
} else { } else {
GHashTableIter iter; GHashTableIter iter;
gpointer key, value; gpointer key, value;
/* On removal we aren't always be able to read properties like IFINDEX /* This should not happen, but just to be sure.
* anymore, as they may have already been removed from sysfs. * If we can't get IFINDEX, go through the devices and
* compare the pointers.
*/ */
g_hash_table_iter_init (&iter, priv->udev_devices); g_hash_table_iter_init (&iter, priv->udev_devices);
while (g_hash_table_iter_next (&iter, &key, &value)) { while (g_hash_table_iter_next (&iter, &key, &value)) {
@@ -2536,7 +2537,7 @@ udev_device_removed (NMPlatform *platform,
} }
} }
/* Announce device removal if it's still in the Netlink cache. */ /* Announce device removal if it's still in the Netlink cache. */
if (ifindex) { if (ifindex) {
auto_nl_object struct rtnl_link *device = rtnl_link_get (priv->link_cache, ifindex); auto_nl_object struct rtnl_link *device = rtnl_link_get (priv->link_cache, ifindex);
@@ -2554,6 +2555,7 @@ handle_udev_event (GUdevClient *client,
NMPlatform *platform = NM_PLATFORM (user_data); NMPlatform *platform = NM_PLATFORM (user_data);
const char *subsys; const char *subsys;
const char *ifindex; const char *ifindex;
guint64 seqnum;
g_return_if_fail (action != NULL); g_return_if_fail (action != NULL);
@@ -2561,11 +2563,11 @@ handle_udev_event (GUdevClient *client,
subsys = g_udev_device_get_subsystem (udev_device); subsys = g_udev_device_get_subsystem (udev_device);
g_return_if_fail (!g_strcmp0 (subsys, "net")); g_return_if_fail (!g_strcmp0 (subsys, "net"));
ifindex = g_udev_device_get_sysfs_attr (udev_device, "ifindex"); ifindex = g_udev_device_get_property (udev_device, "IFINDEX");
seqnum = g_udev_device_get_seqnum (udev_device);
debug ("UDEV event: action '%s' subsys '%s' device '%s' (%s)", debug ("UDEV event: action '%s' subsys '%s' device '%s' (%s); seqnum=%" G_GUINT64_FORMAT,
action, subsys, g_udev_device_get_name (udev_device), action, subsys, g_udev_device_get_name (udev_device),
ifindex ? ifindex : "unknown"); ifindex ? ifindex : "unknown", seqnum);
if (!strcmp (action, "add")) if (!strcmp (action, "add"))
udev_device_added (platform, udev_device); udev_device_added (platform, udev_device);