提交 8366cb0a 编写于 作者: J John Ferlan

util: Introduce virGetFCHostNameByFabricWWN

Create a utility routine in order to read the scsi_host fabric_name files
looking for a match to a passed fabric_name
上级 bb74a7ff
......@@ -2667,6 +2667,7 @@ virGetDeviceID;
virGetDeviceUnprivSGIO;
virGetEnvAllowSUID;
virGetEnvBlockSUID;
virGetFCHostNameByFabricWWN;
virGetFCHostNameByWWN;
virGetGroupID;
virGetGroupList;
......
......@@ -2166,6 +2166,60 @@ virManageVport(const int parent_host,
return ret;
}
/* virReadCompareWWN
* @prefix: path to the wwn file
* @d_name: name of the current directory
* @f_name: file name to read
*
* Read/compare the on-disk file with the passed wwn value.
*
* Returns:
* -1 : Error
* 0 : No match
* 1 : Match
*/
static int
virReadCompareWWN(const char *prefix,
const char *d_name,
const char *f_name,
const char *wwn)
{
char *path;
char *buf = NULL;
char *p;
int ret = -1;
if (virAsprintf(&path, "%s/%s/%s", prefix, d_name, f_name) < 0)
return -1;
if (!virFileExists(path)) {
ret = 0;
goto cleanup;
}
if (virFileReadAll(path, 1024, &buf) < 0)
goto cleanup;
if ((p = strchr(buf, '\n')))
*p = '\0';
if (STRPREFIX(buf, "0x"))
p = buf + strlen("0x");
else
p = buf;
if (STRNEQ(wwn, p))
ret = 0;
else
ret = 1;
cleanup:
VIR_FREE(path);
VIR_FREE(buf);
return ret;
}
/* virGetFCHostNameByWWN:
*
* Iterate over the sysfs tree to get FC host name (e.g. host5)
......@@ -2182,56 +2236,77 @@ virGetFCHostNameByWWN(const char *sysfs_prefix,
const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH;
struct dirent *entry = NULL;
DIR *dir = NULL;
char *wwnn_path = NULL;
char *wwpn_path = NULL;
char *wwnn_buf = NULL;
char *wwpn_buf = NULL;
char *p;
char *ret = NULL;
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);
VIR_FREE(wwpn_buf);
VIR_FREE(wwpn_path);
int rc;
if (virAsprintf(&wwnn_path, "%s/%s/node_name", prefix,
entry->d_name) < 0)
if ((rc = virReadCompareWWN(prefix, entry->d_name,
"node_name", wwnn)) < 0)
goto cleanup;
if (!virFileExists(wwnn_path))
if (rc == 0)
continue;
READ_WWN(wwnn_path, wwnn_buf);
if ((rc = virReadCompareWWN(prefix, entry->d_name,
"port_name", wwpn)) < 0)
goto cleanup;
if (STRNEQ(wwnn, p))
if (rc == 0)
continue;
if (virAsprintf(&wwpn_path, "%s/%s/port_name", prefix,
ignore_value(VIR_STRDUP(ret, entry->d_name));
break;
}
cleanup:
VIR_DIR_CLOSE(dir);
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 *vport_create_path = NULL;
char *ret = NULL;
if (virDirOpen(&dir, prefix) < 0)
return NULL;
while (virDirRead(dir, &entry, prefix) > 0) {
int rc;
VIR_FREE(vport_create_path);
/* 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(wwpn_path))
if (!virFileExists(vport_create_path))
continue;
READ_WWN(wwpn_path, wwpn_buf);
if ((rc = virReadCompareWWN(prefix, entry->d_name,
"fabric_name", fabric_wwn)) < 0)
goto cleanup;
if (STRNEQ(wwpn, p))
if (rc == 0)
continue;
ignore_value(VIR_STRDUP(ret, entry->d_name));
......@@ -2239,12 +2314,8 @@ virGetFCHostNameByWWN(const char *sysfs_prefix,
}
cleanup:
# undef READ_WWN
VIR_DIR_CLOSE(dir);
VIR_FREE(wwnn_path);
VIR_FREE(wwpn_path);
VIR_FREE(wwnn_buf);
VIR_FREE(wwpn_buf);
VIR_FREE(vport_create_path);
return ret;
}
......
......@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册