summaryrefslogtreecommitdiff
path: root/src/udev
diff options
context:
space:
mode:
Diffstat (limited to 'src/udev')
-rw-r--r--src/udev/udev-builtin-net_id.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 5be158f527..b5a88c667c 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -34,7 +34,8 @@
*
* Type of names:
* b<number> — BCMA bus core number
- * c<bus_id> — CCW bus group name, without leading zeros [s390]
+ * c<bus_id> — bus id of a grouped CCW or CCW device,
+ * with all leading zeros stripped [s390]
* o<index>[n<phys_port_name>|d<dev_port>]
* — on-board device index number
* s<slot>[f<function>][n<phys_port_name>|d<dev_port>]
@@ -87,6 +88,11 @@
* /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2
* ID_NET_NAME_MAC=enxd626b3450fb5
* ID_NET_NAME_PATH=enp0s29u1u2
+ *
+ * s390 grouped CCW interface:
+ * /sys/devices/css0/0.0.0007/0.0.f5f0/group_device/net/encf5f0
+ * ID_NET_NAME_MAC=enx026d3c00000a
+ * ID_NET_NAME_PATH=encf5f0
*/
#include <errno.h>
@@ -115,7 +121,7 @@ enum netname_type{
NET_USB,
NET_BCMA,
NET_VIRTIO,
- NET_CCWGROUP,
+ NET_CCW,
};
struct netnames {
@@ -132,9 +138,21 @@ struct netnames {
char usb_ports[IFNAMSIZ];
char bcma_core[IFNAMSIZ];
- char ccw_group[IFNAMSIZ];
+ char ccw_busid[IFNAMSIZ];
};
+/* skip intermediate virtio devices */
+static struct udev_device *skip_virtio(struct udev_device *dev) {
+ struct udev_device *parent = dev;
+
+ /* there can only ever be one virtio bus per parent device, so we can
+ safely ignore any virtio buses. see
+ <http://lists.linuxfoundation.org/pipermail/virtualization/2015-August/030331.html> */
+ while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent)))
+ parent = udev_device_get_parent(parent);
+ return parent;
+}
+
/* retrieve on-board index number and label from firmware */
static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
unsigned dev_port = 0;
@@ -308,12 +326,8 @@ static int names_pci(struct udev_device *dev, struct netnames *names) {
assert(names);
parent = udev_device_get_parent(dev);
-
- /* there can only ever be one virtio bus per parent device, so we can
- safely ignore any virtio buses. see
- <http://lists.linuxfoundation.org/pipermail/virtualization/2015-August/030331.html> */
- while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent)))
- parent = udev_device_get_parent(parent);
+ /* skip virtio subsystem if present */
+ parent = skip_virtio(parent);
if (!parent)
return -ENOENT;
@@ -414,21 +428,26 @@ static int names_ccw(struct udev_device *dev, struct netnames *names) {
struct udev_device *cdev;
const char *bus_id;
size_t bus_id_len;
+ size_t bus_id_start;
int rc;
+ char *subsys;
assert(dev);
assert(names);
/* Retrieve the associated CCW device */
cdev = udev_device_get_parent(dev);
+ /* skip virtio subsystem if present */
+ cdev = skip_virtio(cdev);
if (!cdev)
return -ENOENT;
- /* Network devices are always grouped CCW devices */
- if (!streq_ptr("ccwgroup", udev_device_get_subsystem(cdev)))
+ /* Network devices are either single or grouped CCW devices */
+ subsys = udev_device_get_subsystem(cdev);
+ if (!STRPTR_IN_SET(subsys, "ccwgroup", "ccw"))
return -ENOENT;
- /* Retrieve bus-ID of the grouped CCW device. The bus-ID uniquely
+ /* Retrieve bus-ID of the CCW device. The bus-ID uniquely
* identifies the network device on the Linux on System z channel
* subsystem. Note that the bus-ID contains lowercase characters.
*/
@@ -447,14 +466,15 @@ static int names_ccw(struct udev_device *dev, struct netnames *names) {
/* Strip leading zeros from the bus id for aesthetic purposes. This
* keeps the ccw names stable, yet much shorter in general case of
* bus_id 0.0.0600 -> 600. This is similar to e.g. how PCI domain is
- * not prepended when it is zero.
+ * not prepended when it is zero. Preserve the last 0 for 0.0.0000.
*/
- bus_id += strspn(bus_id, ".0");
+ bus_id_start = strspn(bus_id, ".0");
+ bus_id += bus_id_start < bus_id_len ? bus_id_start : bus_id_len - 1;
/* Store the CCW bus-ID for use as network device name */
- rc = snprintf(names->ccw_group, sizeof(names->ccw_group), "c%s", bus_id);
- if (rc >= 0 && rc < (int)sizeof(names->ccw_group))
- names->type = NET_CCWGROUP;
+ rc = snprintf(names->ccw_busid, sizeof(names->ccw_busid), "c%s", bus_id);
+ if (rc >= 0 && rc < (int)sizeof(names->ccw_busid))
+ names->type = NET_CCW;
return 0;
}
@@ -564,10 +584,10 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
/* get path names for Linux on System z network devices */
err = names_ccw(dev, &names);
- if (err >= 0 && names.type == NET_CCWGROUP) {
+ if (err >= 0 && names.type == NET_CCW) {
char str[IFNAMSIZ];
- if (snprintf(str, sizeof(str), "%s%s", prefix, names.ccw_group) < (int)sizeof(str))
+ if (snprintf(str, sizeof(str), "%s%s", prefix, names.ccw_busid) < (int)sizeof(str))
udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
goto out;
}