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