[systemd-devel] [RFC][PATCH] udev: net_id - support multi-function, multi-port enpo* device names
Michael Marineau
michael.marineau at coreos.com
Wed Jul 15 14:52:07 PDT 2015
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 <teg at jklm.no> 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 <teg at jklm.no> 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<number> -- BCMA bus core number
>> * ccw<name> -- CCW bus group name
>> - * o<index> -- on-board device index number
>> + * o<index>[f<function>][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>]
>> @@ -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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
More information about the systemd-devel
mailing list