diff options
Diffstat (limited to 'src/udev/udev-builtin-net_id.c')
-rw-r--r-- | src/udev/udev-builtin-net_id.c | 58 |
1 files changed, 44 insertions, 14 deletions
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 37ff1b8008..6e7e1271fb 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -35,7 +35,7 @@ * Type of names: * b<number> -- BCMA bus core number * ccw<name> -- CCW bus group name - * o<index> -- on-board device index number + * o<index>[d<dev_port>] -- on-board device index number * s<slot>[f<function>][d<dev_port>] -- hotplug slot index number * x<MAC> -- MAC address * [P<domain>]p<bus>s<slot>[f<function>][d<dev_port>] @@ -91,6 +91,7 @@ #include <stdlib.h> #include <stdarg.h> #include <unistd.h> +#include <fcntl.h> #include <string.h> #include <errno.h> #include <net/if.h> @@ -128,36 +129,53 @@ struct netnames { /* retrieve on-board index number and label from firmware */ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { - const char *index; + unsigned dev_port = 0; + size_t l; + char *s; + const char *attr; int idx; /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */ - index = udev_device_get_sysattr_value(names->pcidev, "acpi_index"); + attr = udev_device_get_sysattr_value(names->pcidev, "acpi_index"); /* SMBIOS type 41 -- Onboard Devices Extended Information */ - if (!index) - index = udev_device_get_sysattr_value(names->pcidev, "index"); - if (!index) + if (!attr) + attr = udev_device_get_sysattr_value(names->pcidev, "index"); + if (!attr) return -ENOENT; - idx = strtoul(index, NULL, 0); + + idx = strtoul(attr, NULL, 0); if (idx <= 0) return -EINVAL; - snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx); + + /* kernel provided port index for multiple ports on a single PCI function */ + attr = udev_device_get_sysattr_value(dev, "dev_port"); + if (attr) + dev_port = strtol(attr, NULL, 10); + + s = names->pci_onboard; + l = sizeof(names->pci_onboard); + l = strpcpyf(&s, l, "o%d", idx); + if (dev_port > 0) + l = strpcpyf(&s, l, "d%d", dev_port); + if (l == 0) + names->pci_onboard[0] = '\0'; names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label"); + return 0; } /* read the 256 bytes PCI configuration space to check the multi-function bit */ static bool is_pci_multifunction(struct udev_device *dev) { - _cleanup_fclose_ FILE *f = NULL; + _cleanup_close_ int fd = -1; const char *filename; uint8_t config[64]; filename = strjoina(udev_device_get_syspath(dev), "/config"); - f = fopen(filename, "re"); - if (!f) + fd = open(filename, O_RDONLY | O_CLOEXEC); + if (fd < 0) return false; - if (fread(&config, sizeof(config), 1, f) != 1) + if (read(fd, &config, sizeof(config)) != sizeof(config)) return false; /* bit 0-6 header type, bit 7 multi/single function device */ @@ -182,7 +200,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4) return -ENOENT; - /* kernel provided multi-device index */ + /* kernel provided port index for multiple ports on a single PCI function */ attr = udev_device_get_sysattr_value(dev, "dev_port"); if (attr) dev_port = strtol(attr, NULL, 10); @@ -248,7 +266,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { if (dev_port > 0) l = strpcpyf(&s, l, "d%d", dev_port); if (l == 0) - names->pci_path[0] = '\0'; + names->pci_slot[0] = '\0'; } out: udev_device_unref(pci); @@ -258,6 +276,9 @@ out: static int names_pci(struct udev_device *dev, struct netnames *names) { struct udev_device *parent; + assert(dev); + assert(names); + parent = udev_device_get_parent(dev); if (!parent) return -ENOENT; @@ -284,6 +305,9 @@ static int names_usb(struct udev_device *dev, struct netnames *names) { size_t l; char *s; + assert(dev); + assert(names); + usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface"); if (!usbdev) return -ENOENT; @@ -332,6 +356,9 @@ static int names_bcma(struct udev_device *dev, struct netnames *names) { struct udev_device *bcmadev; unsigned int core; + assert(dev); + assert(names); + bcmadev = udev_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL); if (!bcmadev) return -ENOENT; @@ -353,6 +380,9 @@ static int names_ccw(struct udev_device *dev, struct netnames *names) { size_t bus_id_len; int rc; + assert(dev); + assert(names); + /* Retrieve the associated CCW device */ cdev = udev_device_get_parent(dev); if (!cdev) |