Create a utility routine in order to read the scsi_host fabric_name files looking for a match to a passed fabric_name Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/virutil.c | 86 ++++++++++++++++++++++++++++++++++++++++-------- src/util/virutil.h | 4 +++ 3 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5673bda..3921897 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2620,6 +2620,7 @@ virGetDeviceID; virGetDeviceUnprivSGIO; virGetEnvAllowSUID; virGetEnvBlockSUID; +virGetFCHostNameByFabricWWN; virGetFCHostNameByWWN; virGetGroupID; virGetGroupList; diff --git a/src/util/virutil.c b/src/util/virutil.c index a135819..fb72f2d 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -2166,6 +2166,18 @@ virManageVport(const int parent_host, return ret; } +# define READ_WWN(wwn_path, buf) \ + do { \ + if (virFileReadAll(wwn_path, 1024, &buf) < 0) \ + goto cleanup; \ + if ((p = strchr(buf, '\n'))) \ + *p = '\0'; \ + if (STRPREFIX(buf, "0x")) \ + p = buf + strlen("0x"); \ + else \ + p = buf; \ + } while (0) + /* virGetFCHostNameByWWN: * * Iterate over the sysfs tree to get FC host name (e.g. host5) @@ -2192,18 +2204,6 @@ virGetFCHostNameByWWN(const char *sysfs_prefix, if (virDirOpen(&dir, prefix) < 0) return NULL; -# define READ_WWN(wwn_path, buf) \ - do { \ - if (virFileReadAll(wwn_path, 1024, &buf) < 0) \ - goto cleanup; \ - if ((p = strchr(buf, '\n'))) \ - *p = '\0'; \ - if (STRPREFIX(buf, "0x")) \ - p = buf + strlen("0x"); \ - else \ - p = buf; \ - } while (0) - while (virDirRead(dir, &entry, prefix) > 0) { VIR_FREE(wwnn_buf); VIR_FREE(wwnn_path); @@ -2239,7 +2239,6 @@ virGetFCHostNameByWWN(const char *sysfs_prefix, } cleanup: -# undef READ_WWN VIR_DIR_CLOSE(dir); VIR_FREE(wwnn_path); VIR_FREE(wwpn_path); @@ -2248,6 +2247,67 @@ virGetFCHostNameByWWN(const char *sysfs_prefix, return ret; } +/* virGetFCHostNameByFabricWWN: + * + * Iterate over the sysfs tree to get FC host name (e.g. host5) + * by the provided "fabric_wwn". This would find a host on a SAN. + * + * Returns the FC host name which must be freed by the caller, + * or NULL on failure. + */ +char * +virGetFCHostNameByFabricWWN(const char *sysfs_prefix, + const char *fabric_wwn) +{ + const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH; + struct dirent *entry = NULL; + DIR *dir = NULL; + char *fabric_wwn_path = NULL; + char *fabric_wwn_buf = NULL; + char *vport_create_path = NULL; + char *p; + char *ret = NULL; + + if (virDirOpen(&dir, prefix) < 0) + return NULL; + + while (virDirRead(dir, &entry, prefix) > 0) { + VIR_FREE(fabric_wwn_path); + VIR_FREE(fabric_wwn_buf); + VIR_FREE(vport_create_path); + + if (virAsprintf(&fabric_wwn_path, "%s/%s/fabric_name", prefix, + entry->d_name) < 0) + goto cleanup; + + /* Existing vHBA's will have the same fabric_name, but won't + * have the vport_create file - so we check for both */ + if (virAsprintf(&vport_create_path, "%s/%s/vport_create", prefix, + entry->d_name) < 0) + goto cleanup; + + if (!virFileExists(fabric_wwn_path) || + !virFileExists(vport_create_path)) + continue; + + READ_WWN(fabric_wwn_path, fabric_wwn_buf); + + if (STRNEQ(fabric_wwn, p)) + continue; + + ignore_value(VIR_STRDUP(ret, entry->d_name)); + break; + } + + cleanup: + VIR_DIR_CLOSE(dir); + VIR_FREE(fabric_wwn_path); + VIR_FREE(fabric_wwn_buf); + VIR_FREE(vport_create_path); + return ret; +} +# undef READ_WWN + # define PORT_STATE_ONLINE "Online" /* virFindFCHostCapableVport: diff --git a/src/util/virutil.h b/src/util/virutil.h index 8c0d83c..3fbd7b0 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -206,6 +206,10 @@ char *virGetFCHostNameByWWN(const char *sysfs_prefix, const char *wwpn) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +char *virGetFCHostNameByFabricWWN(const char *sysfs_prefix, + const char *fabric_wwn) + ATTRIBUTE_NONNULL(2); + char *virFindFCHostCapableVport(const char *sysfs_prefix); int virParseOwnershipIds(const char *label, uid_t *uidPtr, gid_t *gidPtr); -- 2.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list