summaryrefslogtreecommitdiff
path: root/src/udev/udev-builtin-net_id.c
diff options
context:
space:
mode:
authorArseny Maslennikov <arseny@altlinux.org>2018-09-18 12:47:20 +0300
committerArseny Maslennikov <arseny@altlinux.org>2018-09-18 20:13:42 +0300
commitcdd63a03ce15e9df94a137a993196ee48813e16a (patch)
treeedf4bbafe26674b598a2233b328c2902f46ca7ad /src/udev/udev-builtin-net_id.c
parenta0d415da3ac345bb656ce5cabc38fde61f6b23e1 (diff)
downloadsystemd-cdd63a03ce15e9df94a137a993196ee48813e16a.tar.gz
udev: Provide a fallback for IPoIB device port numbers
In older kernels IPoIB network devices expose the port number via the sysfs attribute 'dev_id', which is not intended to be used this way. Let's support both options for a while.
Diffstat (limited to 'src/udev/udev-builtin-net_id.c')
-rw-r--r--src/udev/udev-builtin-net_id.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index d808ddcfeb..b0bb0884be 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -291,7 +291,7 @@ static bool is_pci_ari_enabled(struct udev_device *dev) {
}
static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
- unsigned domain, bus, slot, func, dev_port = 0, hotplug_slot = 0;
+ unsigned type, domain, bus, slot, func, dev_port = 0, hotplug_slot = 0;
size_t l;
char *s;
const char *attr, *port_name;
@@ -311,8 +311,22 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
/* kernel provided port index for multiple ports on a single PCI function */
attr = udev_device_get_sysattr_value(dev, "dev_port");
- if (attr)
+ if (attr) {
dev_port = strtol(attr, NULL, 10);
+ /* With older kernels IP-over-InfiniBand network interfaces sometimes erroneously
+ * provide the port number in the 'dev_id' sysfs attribute instead of 'dev_port',
+ * which thus stays initialized as 0. */
+ if (dev_port == 0) {
+ attr = udev_device_get_sysattr_value(dev, "type");
+ /* The 'type' attribute always exists. */
+ type = strtoul(attr, NULL, 10);
+ if (type == ARPHRD_INFINIBAND) {
+ attr = udev_device_get_sysattr_value(dev, "dev_id");
+ if (attr)
+ dev_port = strtol(attr, NULL, 16);
+ }
+ }
+ }
/* kernel provided front panel port name for multiple port PCI device */
port_name = udev_device_get_sysattr_value(dev, "phys_port_name");