[systemd-devel] [RFC][PATCH] udev: net_id - support multi-function, multi-port enpo* device names
I'd argue that having firmware labels for such devices makes no sense, but they exist, so make sure we handle them as best as we can. --- src/udev/udev-builtin-net_id.c | 64 -- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 71f3a59..1a72190 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 -- BCMA bus core number * ccw -- CCW bus group name - * o -- on-board device index number + * o[f][d]-- on-board device index number * s[f][d] -- hotplug slot index number * x-- MAC address * [P]ps[f][d] @@ -126,11 +126,38 @@ struct netnames { char ccw_group[IFNAMSIZ]; }; +/* 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; +const char *filename; +uint8_t config[64]; + +filename = strjoina(udev_device_get_syspath(dev), "/config"); +f = fopen(filename, "re"); +if (!f) +return false; +if (fread(&config, sizeof(config), 1, f) != 1) +return false; + +/* bit 0-6 header type, bit 7 multi/single function device */ +if ((config[PCI_HEADER_TYPE] & 0x80) != 0) +return true; + +return false; +} + /* retrieve on-board index number and label from firmware */ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { +unsigned func, dev_port = 0; +size_t l; +char *s; +const char *attr; const char *index; int idx; +if (sscanf(udev_device_get_sysname(names->pcidev), "%*x:%*x:%*x.%u", &func) != 1) +return -ENOENT; + /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */ index = udev_device_get_sysattr_value(names->pcidev, "acpi_index"); /* SMBIOS type 41 -- Onboard Devices Extended Information */ @@ -141,30 +168,25 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { idx = strtoul(index, NULL, 0); if (idx <= 0) return -EINVAL; -snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx); -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; -const char *filename; -uint8_t config[64]; +/* kernel provided multi-device index */ +attr = udev_device_get_sysattr_value(dev, "dev_port"); +if (attr) +dev_port = strtol(attr, NULL, 10); -filename = strjoina(udev_device_get_syspath(dev), "/config"); -f = fopen(filename, "re"); -if (!f) -return false; -if (fread(&config, sizeof(config), 1, f) != 1) -return false; +s = names->pci_onboard; +l = sizeof(names->pci_onboard); +l = strpcpyf(&s, l, "o%d", idx); +if (func > 0 || is_pci_multifunction(names->pcidev)) +l = strpcpyf(&s, l, "f%d", func); +if (dev_port > 0) +l = strpcpyf(&s, l, "d%d", dev_port); +if (l == 0) +names->pci_onboard[0] = '\0'; -/* bit 0-6 header type, bit 7 multi/single function device */ -if ((config[PCI_HEADER_TYPE] & 0x80) != 0) -return true; +names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label"); -return false; +return 0; } static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { -- 2.3.4 ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC][PATCH] udev: net_id - support multi-function, multi-port enpo* device names
I pushed a version of this only handling the multi-port devices. We can deal with multi-function if and when they appear in the wild. -t On Wed, Apr 1, 2015 at 4:52 PM, Tom Gundersen wrote: > I'd argue that having firmware labels for such devices makes no sense, but > they exist, so make sure > we handle them as best as we can. > --- > src/udev/udev-builtin-net_id.c | 64 > -- > 1 file changed, 43 insertions(+), 21 deletions(-) > > diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c > index 71f3a59..1a72190 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 -- BCMA bus core number > * ccw -- CCW bus group name > - * o -- on-board device index number > + * o[f][d]-- on-board device index number > * s[f][d] -- hotplug slot index number > * x-- MAC address > * [P]ps[f][d] > @@ -126,11 +126,38 @@ struct netnames { > char ccw_group[IFNAMSIZ]; > }; > > +/* 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; > +const char *filename; > +uint8_t config[64]; > + > +filename = strjoina(udev_device_get_syspath(dev), "/config"); > +f = fopen(filename, "re"); > +if (!f) > +return false; > +if (fread(&config, sizeof(config), 1, f) != 1) > +return false; > + > +/* bit 0-6 header type, bit 7 multi/single function device */ > +if ((config[PCI_HEADER_TYPE] & 0x80) != 0) > +return true; > + > +return false; > +} > + > /* retrieve on-board index number and label from firmware */ > static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) { > +unsigned func, dev_port = 0; > +size_t l; > +char *s; > +const char *attr; > const char *index; > int idx; > > +if (sscanf(udev_device_get_sysname(names->pcidev), "%*x:%*x:%*x.%u", > &func) != 1) > +return -ENOENT; > + > /* ACPI _DSM -- device specific method for naming a PCI or PCI > Express device */ > index = udev_device_get_sysattr_value(names->pcidev, "acpi_index"); > /* SMBIOS type 41 -- Onboard Devices Extended Information */ > @@ -141,30 +168,25 @@ static int dev_pci_onboard(struct udev_device *dev, > struct netnames *names) { > idx = strtoul(index, NULL, 0); > if (idx <= 0) > return -EINVAL; > -snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx); > > -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; > -const char *filename; > -uint8_t config[64]; > +/* kernel provided multi-device index */ > +attr = udev_device_get_sysattr_value(dev, "dev_port"); > +if (attr) > +dev_port = strtol(attr, NULL, 10); > > -filename = strjoina(udev_device_get_syspath(dev), "/config"); > -f = fopen(filename, "re"); > -if (!f) > -return false; > -if (fread(&config, sizeof(config), 1, f) != 1) > -return false; > +s = names->pci_onboard; > +l = sizeof(names->pci_onboard); > +l = strpcpyf(&s, l, "o%d", idx); > +if (func > 0 || is_pci_multifunction(names->pcidev)) > +l = strpcpyf(&s, l, "f%d", func); > +if (dev_port > 0) > +l = strpcpyf(&s, l, "d%d", dev_port); > +if (l == 0) > +names->pci_onboard[0] = '\0'; > > -/* bit 0-6 header type, bit 7 multi/single function device */ > -if ((config[PCI_HEADER_TYPE] & 0x80) != 0) > -return true; > +names->pci_onboard_label = > udev_device_get_sysattr_value(names->pcidev, "label"); > > -return false; > +return 0; > } > > static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { > -- > 2.3.4 > ___ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel
Re: [systemd-devel] [RFC][PATCH] udev: net_id - support multi-function, multi-port enpo* device names
Found one of these fabaled multi-function network devices you dropped from the patch, an Intel I350 Gigabit device on a Supermicro X9DRI-LN4F+ motherboard. The 4 different network interfaces are all are fighting over the 'eno1' name and are functions 06:00.0, 06:00.1, 06:00.2, and 06:00.3. On Wed, Apr 1, 2015 at 1:58 PM, Tom Gundersen wrote: > I pushed a version of this only handling the multi-port devices. We > can deal with multi-function if and when they appear in the wild. > > -t > > On Wed, Apr 1, 2015 at 4:52 PM, Tom Gundersen wrote: >> I'd argue that having firmware labels for such devices makes no sense, but >> they exist, so make sure >> we handle them as best as we can. >> --- >> src/udev/udev-builtin-net_id.c | 64 >> -- >> 1 file changed, 43 insertions(+), 21 deletions(-) >> >> diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c >> index 71f3a59..1a72190 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 -- BCMA bus core number >> * ccw -- CCW bus group name >> - * o -- on-board device index number >> + * o[f][d]-- on-board device index number >> * s[f][d] -- hotplug slot index number >> * x-- MAC address >> * [P]ps[f][d] >> @@ -126,11 +126,38 @@ struct netnames { >> char ccw_group[IFNAMSIZ]; >> }; >> >> +/* 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; >> +const char *filename; >> +uint8_t config[64]; >> + >> +filename = strjoina(udev_device_get_syspath(dev), "/config"); >> +f = fopen(filename, "re"); >> +if (!f) >> +return false; >> +if (fread(&config, sizeof(config), 1, f) != 1) >> +return false; >> + >> +/* bit 0-6 header type, bit 7 multi/single function device */ >> +if ((config[PCI_HEADER_TYPE] & 0x80) != 0) >> +return true; >> + >> +return false; >> +} >> + >> /* retrieve on-board index number and label from firmware */ >> static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) >> { >> +unsigned func, dev_port = 0; >> +size_t l; >> +char *s; >> +const char *attr; >> const char *index; >> int idx; >> >> +if (sscanf(udev_device_get_sysname(names->pcidev), >> "%*x:%*x:%*x.%u", &func) != 1) >> +return -ENOENT; >> + >> /* ACPI _DSM -- device specific method for naming a PCI or PCI >> Express device */ >> index = udev_device_get_sysattr_value(names->pcidev, "acpi_index"); >> /* SMBIOS type 41 -- Onboard Devices Extended Information */ >> @@ -141,30 +168,25 @@ static int dev_pci_onboard(struct udev_device *dev, >> struct netnames *names) { >> idx = strtoul(index, NULL, 0); >> if (idx <= 0) >> return -EINVAL; >> -snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", >> idx); >> >> -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; >> -const char *filename; >> -uint8_t config[64]; >> +/* kernel provided multi-device index */ >> +attr = udev_device_get_sysattr_value(dev, "dev_port"); >> +if (attr) >> +dev_port = strtol(attr, NULL, 10); >> >> -filename = strjoina(udev_device_get_syspath(dev), "/config"); >> -f = fopen(filename, "re"); >> -if (!f) >> -return false; >> -if (fread(&config, sizeof(config), 1, f) != 1) >> -return false; >> +s = names->pci_onboard; >> +l = sizeof(names->pci_onboard); >> +l = strpcpyf(&s, l, "o%d", idx); >> +if (func > 0 || is_pci_multifunction(names->pcidev)) >> +l = strpcpyf(&s, l, "f%d", func); >> +if (dev_port > 0) >> +l = strpcpyf(&s, l, "d%d", dev_port); >> +if (l == 0) >> +names->pci_onboard[0] = '\0'; >> >> -/* bit 0-6 header type, bit 7 multi/single function device */ >> -if ((config[PCI_HEADER_TYPE] & 0x80) != 0) >> -return true; >> +names->pci_onboard_label = >> udev_device_get_sysattr_value(names->pcidev, "label"); >> >> -return false; >> +return 0; >> } >> >> static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { >> -- >> 2.3.4 >> > __