diff options
author | Stuart Hayes <stuart_hayes@dell.com> | 2018-01-16 16:08:10 -0500 |
---|---|---|
committer | Stuart Hayes <stuart_hayes@dell.com> | 2018-03-26 13:57:12 -0400 |
commit | 9009d3b5c3b6d191be69215736be77583e0f23f9 (patch) | |
tree | cd313feed38c8bbb5edbf94b0a86caacf1a12891 /src/udev/udev-builtin-net_id.c | |
parent | 303d6b4ca6ebadca2f6faf63a76743e22efba242 (diff) | |
download | systemd-9009d3b5c3b6d191be69215736be77583e0f23f9.tar.gz |
udev: net_id: search parent devices for PCI slot number
To generate predictable network device names, the code in
udev-builting-net_id.c tries to match the PCI device address
of the network device to the entries in /sys/bus/pci/slots.
However, sometimes the slot number is not associated the
network controller PCI device itself, but rather with one of
its parents.
This change will try to find a match in /sys/bus/pci/slots for
the parents of the PCI network device, if it doesn't find a
match for the device itself.
Diffstat (limited to 'src/udev/udev-builtin-net_id.c')
-rw-r--r-- | src/udev/udev-builtin-net_id.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 6efa712930..3d3329b382 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -112,6 +112,7 @@ #include "dirent-util.h" #include "fd-util.h" #include "fileio.h" +#include "parse-util.h" #include "stdio-util.h" #include "string-util.h" #include "udev.h" @@ -233,15 +234,15 @@ static bool is_pci_multifunction(struct udev_device *dev) { static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { struct udev *udev = udev_device_get_udev(names->pcidev); - unsigned domain, bus, slot, func, dev_port = 0; + unsigned domain, bus, slot, func, dev_port = 0, hotplug_slot = 0; size_t l; char *s; const char *attr, *port_name; _cleanup_udev_device_unref_ struct udev_device *pci = NULL; + struct udev_device *hotplug_slot_dev; char slots[PATH_MAX]; _cleanup_closedir_ DIR *dir = NULL; struct dirent *dent; - int hotplug_slot = 0; if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4) return -ENOENT; @@ -281,27 +282,33 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { if (!dir) return -errno; - FOREACH_DIRENT_ALL(dent, dir, break) { - int i; - char *rest, str[PATH_MAX]; - _cleanup_free_ char *address = NULL; - - if (dent->d_name[0] == '.') - continue; - i = strtol(dent->d_name, &rest, 10); - if (rest[0] != '\0') - continue; - if (i < 1) - continue; - - if (snprintf_ok(str, sizeof str, "%s/%s/address", slots, dent->d_name) && - read_one_line_file(str, &address) >= 0) - /* match slot address with device by stripping the function */ - if (startswith(udev_device_get_sysname(names->pcidev), address)) - hotplug_slot = i; - + hotplug_slot_dev = names->pcidev; + while (hotplug_slot_dev) { + FOREACH_DIRENT_ALL(dent, dir, break) { + unsigned i; + int r; + char str[PATH_MAX]; + _cleanup_free_ char *address = NULL; + + if (dent->d_name[0] == '.') + continue; + r = safe_atou_full(dent->d_name, 10, &i); + if (i < 1 || r < 0) + continue; + + if (snprintf_ok(str, sizeof str, "%s/%s/address", slots, dent->d_name) && + read_one_line_file(str, &address) >= 0) + /* match slot address with device by stripping the function */ + if (startswith(udev_device_get_sysname(hotplug_slot_dev), address)) + hotplug_slot = i; + + if (hotplug_slot > 0) + break; + } if (hotplug_slot > 0) break; + rewinddir(dir); + hotplug_slot_dev = udev_device_get_parent_with_subsystem_devtype(hotplug_slot_dev, "pci", NULL); } if (hotplug_slot > 0) { |