From b9146e4dab45e2f76ceca3772564c0f01e227a9f Mon Sep 17 00:00:00 2001 From: Liu Yuan Yuan Date: Fri, 13 Nov 2015 11:50:42 +0100 Subject: [PATCH] udev/path_id: improve and enhance bus detection for Linux on z Systems Improve and enhance the path_id udev builtin to correctly handle bus' available on Linux on z Systems (s390). Previously, the CCW bus and, in particular, any FCP devices on it, have been treated separately. This commit integrates the CCW bus into the device chain loop. FCP devices and their associated SCSI disks are now handled through the common SCSI handling functions in path_id. This implies also a change in the naming of the symbolic links created by udev. So any backports of this commit to existing Linux distribution must be done with care. If a backport is required, a udev rule must be created to also create the "old-style" symbolic links. Apart from the CCW bus, this commit adds bus support for the: - ccwgroup bus which manages network devices, and - ap bus which manages cryptographic adapters - iucv bus which manages IUCV devices on z/VM Cherry-picked from: e7eb5a8d88367a755944fdda3023a308e5272953 Resolves: #1274401 --- rules/40-redhat.rules | 25 +++++++++++++ src/udev/udev-builtin-path_id.c | 63 ++++++++++++++++++--------------- 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules index 0164dc921..c928d412b 100644 --- a/rules/40-redhat.rules +++ b/rules/40-redhat.rules @@ -15,3 +15,28 @@ SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_target", TEST!="[module/sg]", RUN+="/sbin # Rule for prandom character device node permissions KERNEL=="prandom", MODE="0644" + + +# Rules for creating the ID_PATH for SCSI devices based on the CCW bus +# using the form: ccw--zfcp-: +# +ACTION=="remove", GOTO="zfcp_scsi_device_end" + +# +# Set environment variable "ID_ZFCP_BUS" to "1" if the devices +# (both disk and partition) are SCSI devices based on FCP devices +# +KERNEL=="sd*", SUBSYSTEMS=="ccw", DRIVERS=="zfcp", ENV{.ID_ZFCP_BUS}="1" + +# For SCSI disks +KERNEL=="sd*[!0-9]", SUBSYSTEMS=="scsi", + ENV{.ID_ZFCP_BUS}=="1", ENV{DEVTYPE}=="disk", + SYMLINK+="disk/by-path/ccw-$attr{hba_id}-zfcp-$attr{wwpn}:$attr{fcp_lun}" + + +# For partitions on a SCSI disk +KERNEL=="sd*[0-9]", SUBSYSTEMS=="scsi", + ENV{.ID_ZFCP_BUS}=="1", ENV{DEVTYPE}=="partition", + SYMLINK+="disk/by-path/ccw-$attr{hba_id}-zfcp-$attr{wwpn}:$attr{fcp_lun}-part%n" + +LABEL="zfcp_scsi_device_end" diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c index 88a812ff5..19447201b 100644 --- a/src/udev/udev-builtin-path_id.c +++ b/src/udev/udev-builtin-path_id.c @@ -615,27 +615,23 @@ static struct udev_device *handle_bcma(struct udev_device *parent, char **path) return parent; } -static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path) { - struct udev_device *scsi_dev; - - scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device"); - if (scsi_dev != NULL) { - const char *wwpn; - const char *lun; - const char *hba_id; - - hba_id = udev_device_get_sysattr_value(scsi_dev, "hba_id"); - wwpn = udev_device_get_sysattr_value(scsi_dev, "wwpn"); - lun = udev_device_get_sysattr_value(scsi_dev, "fcp_lun"); - if (hba_id != NULL && lun != NULL && wwpn != NULL) { - path_prepend(path, "ccw-%s-zfcp-%s:%s", hba_id, wwpn, lun); - goto out; - } - } +/* Handle devices of AP bus in System z platform. */ +static struct udev_device *handle_ap(struct udev_device *parent, char **path) { + const char *type, *func; + + assert(parent); + assert(path); + + type = udev_device_get_sysattr_value(parent, "type"); + func = udev_device_get_sysattr_value(parent, "ap_functions"); - path_prepend(path, "ccw-%s", udev_device_get_sysname(parent)); + if (type != NULL && func != NULL) { + path_prepend(path, "ap-%s-%s", type, func); + goto out; + } + path_prepend(path, "ap-%s", udev_device_get_sysname(parent)); out: - parent = skip_subsystem(parent, "ccw"); + parent = skip_subsystem(parent, "ap"); return parent; } @@ -647,15 +643,8 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool bool new_sas_path = false; bool enable_new_sas_path = true; - /* S390 ccw bus */ - parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL); - if (parent != NULL) { - handle_ccw(parent, dev, &path); - goto out; - } - restart: - ; + /* walk up the chain of devices and compose path */ parent = dev; while (parent != NULL) { @@ -718,6 +707,25 @@ restart: supported_parent = true; supported_transport = true; } + } else if (streq(subsys, "ccw")) { + path_prepend(&path, "ccw-%s", udev_device_get_sysname(parent)); + parent = skip_subsystem(parent, "ccw"); + supported_transport = true; + supported_parent = true; + } else if (streq(subsys, "ccwgroup")) { + path_prepend(&path, "ccwgroup-%s", udev_device_get_sysname(parent)); + parent = skip_subsystem(parent, "ccwgroup"); + supported_transport = true; + supported_parent = true; + } else if (streq(subsys, "ap")) { + parent = handle_ap(parent, &path); + supported_transport = true; + supported_parent = true; + } else if (streq(subsys, "iucv")) { + path_prepend(&path, "iucv-%s", udev_device_get_sysname(parent)); + parent = skip_subsystem(parent, "iucv"); + supported_transport = true; + supported_parent = true; } parent = udev_device_get_parent(parent); @@ -743,7 +751,6 @@ restart: path = NULL; } -out: if (path != NULL) { char tag[UTIL_NAME_SIZE]; size_t i;