|
|
1abbee |
From 569d98e9caae425120bf28f6b440e6cc117abc0d Mon Sep 17 00:00:00 2001
|
|
|
0e8dd1 |
From: Maurizio Lombardi <mlombard@redhat.com>
|
|
|
0e8dd1 |
Date: Mon, 1 Feb 2016 14:44:22 +0100
|
|
|
0e8dd1 |
Subject: [PATCH] udev: fibre channel: fix NPIV support
|
|
|
0e8dd1 |
|
|
|
0e8dd1 |
When using NPIV, you can create multiple virtual HBAs on top of the
|
|
|
0e8dd1 |
physical one, this means that the physical N_Port can have multiple
|
|
|
0e8dd1 |
port IDs associated to it.
|
|
|
0e8dd1 |
Suppose a LUN is assigned to the physical HBA and to a virtual HBA,
|
|
|
0e8dd1 |
in both cases the original code uses the ID of the physical HBA
|
|
|
0e8dd1 |
to build the by-path link and udev will end up trying to create two by-path
|
|
|
0e8dd1 |
links with the same name.
|
|
|
0e8dd1 |
|
|
|
0e8dd1 |
This patch fixes the problem by using the port ID of the virtual HBA
|
|
|
0e8dd1 |
whenever it detects that the device belongs to a virtual HBA,
|
|
|
0e8dd1 |
otherwise it uses the port ID of the physical HBA.
|
|
|
0e8dd1 |
|
|
|
0e8dd1 |
(cherry-picked from 155a760bcedd11b7f3b430350a46f10736286895)
|
|
|
0e8dd1 |
|
|
|
0e8dd1 |
Resolves: #1266934
|
|
|
0e8dd1 |
---
|
|
|
0e8dd1 |
src/udev/udev-builtin-path_id.c | 27 ++++++++++++++++++++++++---
|
|
|
0e8dd1 |
1 file changed, 24 insertions(+), 3 deletions(-)
|
|
|
0e8dd1 |
|
|
|
0e8dd1 |
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
|
|
|
c62b8e |
index 9ca608468c..695ac7fc1f 100644
|
|
|
0e8dd1 |
--- a/src/udev/udev-builtin-path_id.c
|
|
|
0e8dd1 |
+++ b/src/udev/udev-builtin-path_id.c
|
|
|
0e8dd1 |
@@ -92,6 +92,9 @@ static struct udev_device *skip_subsystem(struct udev_device *dev, const char *s
|
|
|
0e8dd1 |
static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path) {
|
|
|
0e8dd1 |
struct udev *udev = udev_device_get_udev(parent);
|
|
|
0e8dd1 |
struct udev_device *targetdev;
|
|
|
0e8dd1 |
+ struct udev_device *rportdev;
|
|
|
0e8dd1 |
+ struct udev_device *hostdev;
|
|
|
0e8dd1 |
+ struct udev_device *vportdev;
|
|
|
0e8dd1 |
struct udev_device *fcdev = NULL;
|
|
|
0e8dd1 |
const char *port;
|
|
|
0e8dd1 |
char *lun = NULL;
|
|
|
0e8dd1 |
@@ -100,9 +103,27 @@ static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent,
|
|
|
0e8dd1 |
if (targetdev == NULL)
|
|
|
0e8dd1 |
return NULL;
|
|
|
0e8dd1 |
|
|
|
0e8dd1 |
- fcdev = udev_device_new_from_subsystem_sysname(udev, "fc_transport", udev_device_get_sysname(targetdev));
|
|
|
0e8dd1 |
- if (fcdev == NULL)
|
|
|
0e8dd1 |
- return NULL;
|
|
|
0e8dd1 |
+ rportdev = udev_device_get_parent(targetdev);
|
|
|
0e8dd1 |
+ if (rportdev == NULL)
|
|
|
0e8dd1 |
+ goto skip_npiv_check;
|
|
|
0e8dd1 |
+
|
|
|
0e8dd1 |
+ hostdev = udev_device_get_parent(rportdev);
|
|
|
0e8dd1 |
+ if (hostdev == NULL)
|
|
|
0e8dd1 |
+ goto skip_npiv_check;
|
|
|
0e8dd1 |
+
|
|
|
0e8dd1 |
+ vportdev = udev_device_get_parent(hostdev);
|
|
|
0e8dd1 |
+ if (vportdev == NULL)
|
|
|
0e8dd1 |
+ goto skip_npiv_check;
|
|
|
0e8dd1 |
+
|
|
|
0e8dd1 |
+ fcdev = udev_device_new_from_subsystem_sysname(udev, "fc_vports", udev_device_get_sysname(vportdev));
|
|
|
0e8dd1 |
+
|
|
|
0e8dd1 |
+skip_npiv_check:
|
|
|
0e8dd1 |
+ if (fcdev == NULL) {
|
|
|
0e8dd1 |
+ fcdev = udev_device_new_from_subsystem_sysname(udev, "fc_transport", udev_device_get_sysname(targetdev));
|
|
|
0e8dd1 |
+ if (fcdev == NULL)
|
|
|
0e8dd1 |
+ return NULL;
|
|
|
0e8dd1 |
+ }
|
|
|
0e8dd1 |
+
|
|
|
0e8dd1 |
port = udev_device_get_sysattr_value(fcdev, "port_name");
|
|
|
0e8dd1 |
if (port == NULL) {
|
|
|
0e8dd1 |
parent = NULL;
|