diff --git a/po/POTFILES.in b/po/POTFILES.in index 365ea662fd..a044f90d0a 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -258,6 +258,7 @@ src/util/virtypedparam.c src/util/viruri.c src/util/virusb.c src/util/virutil.c +src/util/virvhba.c src/util/virxml.c src/vbox/vbox_MSCOMGlue.c src/vbox/vbox_XPCOMCGlue.c diff --git a/src/Makefile.am b/src/Makefile.am index 2f32d41979..3ea47db02c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -184,6 +184,7 @@ UTIL_SOURCES = \ util/viruri.h util/viruri.c \ util/virutil.c util/virutil.h \ util/viruuid.c util/viruuid.h \ + util/virvhba.c util/virvhba.h \ util/virxdrdefs.h \ util/virxml.c util/virxml.h \ $(NULL) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index c9b93aab75..fff7285517 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -45,6 +45,7 @@ #include "virfile.h" #include "virstring.h" #include "virlog.h" +#include "virvhba.h" #define VIR_FROM_THIS VIR_FROM_STORAGE @@ -2396,8 +2397,8 @@ matchFCHostToSCSIHost(virConnectPtr conn, /* If we find an fc_adapter name, then either libvirt created a vHBA * for this fc_host or a 'virsh nodedev-create' generated a vHBA. */ - if ((name = virGetFCHostNameByWWN(NULL, fc_adapter.data.fchost.wwnn, - fc_adapter.data.fchost.wwpn))) { + if ((name = virVHBAGetHostByWWN(NULL, fc_adapter.data.fchost.wwnn, + fc_adapter.data.fchost.wwpn))) { /* Get the scsi_hostN for the vHBA in order to see if it * matches our scsi_hostnum diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6bbb36b4e6..d721c12d3c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2679,15 +2679,12 @@ virUSBDeviceSetUsedBy; virDoubleToStr; virEnumFromString; virEnumToString; -virFindFCHostCapableVport; virFindSCSIHostByPCI; virFormatIntDecimal; virGetDeviceID; virGetDeviceUnprivSGIO; virGetEnvAllowSUID; virGetEnvBlockSUID; -virGetFCHostNameByFabricWWN; -virGetFCHostNameByWWN; virGetGroupID; virGetGroupList; virGetGroupName; @@ -2710,11 +2707,8 @@ virGetUserRuntimeDirectory; virGetUserShell; virHexToBin; virIndexToDiskName; -virIsCapableFCHost; -virIsCapableVport; virIsDevMapperDevice; virIsSUID; -virManageVport; virMemoryLimitIsSet; virMemoryLimitTruncate; virMemoryMaxValue; @@ -2722,7 +2716,6 @@ virParseNumber; virParseOwnershipIds; virParseVersionString; virPipeReadUntilEOF; -virReadFCHost; virReadSCSIUniqueId; virScaleInteger; virSetBlocking; @@ -2750,6 +2743,16 @@ virUUIDIsValid; virUUIDParse; +# util/virvhba.h +virVHBAFindVportHost; +virVHBAGetConfig; +virVHBAGetHostByFabricWWN; +virVHBAGetHostByWWN; +virVHBAIsVportCapable; +virVHBAManageVport; +virVHBAPathExists; + + # util/virxml.h virXMLCheckIllegalChars; virXMLChildElementCount; diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index df217f847b..bac57fa2c4 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -39,7 +39,7 @@ #include "node_device_driver.h" #include "node_device_hal.h" #include "node_device_linux_sysfs.h" -#include "virutil.h" +#include "virvhba.h" #include "viraccessapicheck.h" #include "virnetdev.h" @@ -616,12 +616,8 @@ nodeDeviceCreateXML(virConnectPtr conn, goto cleanup; } - if (virManageVport(parent_host, - wwpn, - wwnn, - VPORT_CREATE) == -1) { + if (virVHBAManageVport(parent_host, wwpn, wwnn, VPORT_CREATE) < 0) goto cleanup; - } dev = find_new_device(conn, wwnn, wwpn); /* We don't check the return value, because one way or another, @@ -679,19 +675,12 @@ nodeDeviceDestroy(virNodeDevicePtr dev) virNodeDeviceObjUnlock(obj); obj = NULL; - if (virNodeDeviceGetParentHost(&driver->devs, - dev->name, - parent_name, - &parent_host) == -1) { + if (virNodeDeviceGetParentHost(&driver->devs, dev->name, parent_name, + &parent_host) < 0) goto out; - } - if (virManageVport(parent_host, - wwpn, - wwnn, - VPORT_DELETE) == -1) { + if (virVHBAManageVport(parent_host, wwpn, wwnn, VPORT_DELETE) < 0) goto out; - } ret = 0; out: diff --git a/src/node_device/node_device_linux_sysfs.c b/src/node_device/node_device_linux_sysfs.c index 13520cd211..1c72b0760f 100644 --- a/src/node_device/node_device_linux_sysfs.c +++ b/src/node_device/node_device_linux_sysfs.c @@ -34,6 +34,7 @@ #include "virlog.h" #include "virfile.h" #include "virstring.h" +#include "virvhba.h" #define VIR_FROM_THIS VIR_FROM_NODEDEV @@ -55,34 +56,34 @@ nodeDeviceSysfsGetSCSIHostCaps(virNodeDevCapDataPtr d) VIR_DEBUG("Checking if host%d is an FC HBA", d->scsi_host.host); - if (virIsCapableFCHost(NULL, d->scsi_host.host)) { + if (virVHBAPathExists(NULL, d->scsi_host.host)) { d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST; - if (!(tmp = virReadFCHost(NULL, d->scsi_host.host, "port_name"))) { + if (!(tmp = virVHBAGetConfig(NULL, d->scsi_host.host, "port_name"))) { VIR_WARN("Failed to read WWPN for host%d", d->scsi_host.host); goto cleanup; } VIR_FREE(d->scsi_host.wwpn); VIR_STEAL_PTR(d->scsi_host.wwpn, tmp); - if (!(tmp = virReadFCHost(NULL, d->scsi_host.host, "node_name"))) { + if (!(tmp = virVHBAGetConfig(NULL, d->scsi_host.host, "node_name"))) { VIR_WARN("Failed to read WWNN for host%d", d->scsi_host.host); goto cleanup; } VIR_FREE(d->scsi_host.wwnn); VIR_STEAL_PTR(d->scsi_host.wwnn, tmp); - if ((tmp = virReadFCHost(NULL, d->scsi_host.host, "fabric_name"))) { + if ((tmp = virVHBAGetConfig(NULL, d->scsi_host.host, "fabric_name"))) { VIR_FREE(d->scsi_host.fabric_wwn); VIR_STEAL_PTR(d->scsi_host.fabric_wwn, tmp); } } - if (virIsCapableVport(NULL, d->scsi_host.host)) { + if (virVHBAIsVportCapable(NULL, d->scsi_host.host)) { d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS; - if (!(tmp = virReadFCHost(NULL, d->scsi_host.host, - "max_npiv_vports"))) { + if (!(tmp = virVHBAGetConfig(NULL, d->scsi_host.host, + "max_npiv_vports"))) { VIR_WARN("Failed to read max_npiv_vports for host%d", d->scsi_host.host); goto cleanup; @@ -93,8 +94,8 @@ nodeDeviceSysfsGetSCSIHostCaps(virNodeDevCapDataPtr d) goto cleanup; } - if (!(tmp = virReadFCHost(NULL, d->scsi_host.host, - "npiv_vports_inuse"))) { + if (!(tmp = virVHBAGetConfig(NULL, d->scsi_host.host, + "npiv_vports_inuse"))) { VIR_WARN("Failed to read npiv_vports_inuse for host%d", d->scsi_host.host); goto cleanup; diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 0cc11486b7..e037a93b75 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -34,6 +34,7 @@ #include "virfile.h" #include "vircommand.h" #include "virstring.h" +#include "virvhba.h" #include "storage_util.h" #define VIR_FROM_THIS VIR_FROM_STORAGE @@ -193,9 +194,9 @@ getAdapterName(virStoragePoolSourceAdapter adapter) ignore_value(VIR_STRDUP(name, adapter.data.scsi_host.name)); } } else if (adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (!(name = virGetFCHostNameByWWN(NULL, - adapter.data.fchost.wwnn, - adapter.data.fchost.wwpn))) { + if (!(name = virVHBAGetHostByWWN(NULL, + adapter.data.fchost.wwnn, + adapter.data.fchost.wwpn))) { virReportError(VIR_ERR_XML_ERROR, _("Failed to find SCSI host with wwnn='%s', " "wwpn='%s'"), adapter.data.fchost.wwnn, @@ -269,8 +270,8 @@ createVport(virConnectPtr conn, * using the wwnn/wwpn, then a nodedev is already created for * this pool and we don't have to create the vHBA */ - if ((name = virGetFCHostNameByWWN(NULL, adapter->data.fchost.wwnn, - adapter->data.fchost.wwpn))) { + if ((name = virVHBAGetHostByWWN(NULL, adapter->data.fchost.wwnn, + adapter->data.fchost.wwpn))) { /* If a parent was provided, let's make sure the 'name' we've * retrieved has the same parent */ @@ -287,22 +288,22 @@ createVport(virConnectPtr conn, } else if (adapter->data.fchost.parent_wwnn && adapter->data.fchost.parent_wwpn) { if (!(parent_hoststr = - virGetFCHostNameByWWN(NULL, adapter->data.fchost.parent_wwnn, - adapter->data.fchost.parent_wwpn))) { + virVHBAGetHostByWWN(NULL, adapter->data.fchost.parent_wwnn, + adapter->data.fchost.parent_wwpn))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot find parent using provided wwnn/wwpn")); goto cleanup; } } else if (adapter->data.fchost.parent_fabric_wwn) { if (!(parent_hoststr = - virGetFCHostNameByFabricWWN(NULL, - adapter->data.fchost.parent_fabric_wwn))) { + virVHBAGetHostByFabricWWN(NULL, + adapter->data.fchost.parent_fabric_wwn))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot find parent using provided fabric_wwn")); goto cleanup; } } else { - if (!(parent_hoststr = virFindFCHostCapableVport(NULL))) { + if (!(parent_hoststr = virVHBAFindVportHost(NULL))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("'parent' for vHBA not specified, and " "cannot find one on this host")); @@ -322,9 +323,9 @@ createVport(virConnectPtr conn, * parent. Besides we have a way to determine the parent based on * the 'name' field. */ - if (!skip_capable_check && !virIsCapableFCHost(NULL, parent_host)) { + if (!skip_capable_check && !virVHBAPathExists(NULL, parent_host)) { virReportError(VIR_ERR_XML_ERROR, - _("parent '%s' specified for vHBA is not vport capable"), + _("parent '%s' specified for vHBA does not exist"), parent_hoststr); goto cleanup; } @@ -342,8 +343,8 @@ createVport(virConnectPtr conn, } } - if (virManageVport(parent_host, adapter->data.fchost.wwpn, - adapter->data.fchost.wwnn, VPORT_CREATE) < 0) + if (virVHBAManageVport(parent_host, adapter->data.fchost.wwpn, + adapter->data.fchost.wwnn, VPORT_CREATE) < 0) goto cleanup; virFileWaitForDevices(); @@ -353,8 +354,8 @@ createVport(virConnectPtr conn, * retry logic set to true. If the thread isn't created, then no big * deal since it's still possible to refresh the pool later. */ - if ((name = virGetFCHostNameByWWN(NULL, adapter->data.fchost.wwnn, - adapter->data.fchost.wwpn))) { + if ((name = virVHBAGetHostByWWN(NULL, adapter->data.fchost.wwnn, + adapter->data.fchost.wwpn))) { if (VIR_ALLOC(cbdata) == 0) { memcpy(cbdata->pool_uuid, pool->def->uuid, VIR_UUID_BUFLEN); VIR_STEAL_PTR(cbdata->fchost_name, name); @@ -399,8 +400,8 @@ deleteVport(virConnectPtr conn, return 0; /* Find our vHBA by searching the fc_host sysfs tree for our wwnn/wwpn */ - if (!(name = virGetFCHostNameByWWN(NULL, adapter.data.fchost.wwnn, - adapter.data.fchost.wwpn))) { + if (!(name = virVHBAGetHostByWWN(NULL, adapter.data.fchost.wwnn, + adapter.data.fchost.wwpn))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to find fc_host for wwnn='%s' and wwpn='%s'"), adapter.data.fchost.wwnn, adapter.data.fchost.wwpn); @@ -422,8 +423,8 @@ deleteVport(virConnectPtr conn, goto cleanup; } - if (virManageVport(parent_host, adapter.data.fchost.wwpn, - adapter.data.fchost.wwnn, VPORT_DELETE) < 0) + if (virVHBAManageVport(parent_host, adapter.data.fchost.wwpn, + adapter.data.fchost.wwnn, VPORT_DELETE) < 0) goto cleanup; ret = 0; diff --git a/src/util/virscsi.c b/src/util/virscsi.c index 4fd8838755..22f2677a3f 100644 --- a/src/util/virscsi.c +++ b/src/util/virscsi.c @@ -35,6 +35,7 @@ #include #include +#include "virlog.h" #include "virscsi.h" #include "viralloc.h" #include "virfile.h" @@ -46,6 +47,9 @@ /* For virReportOOMError() and virReportSystemError() */ #define VIR_FROM_THIS VIR_FROM_NONE + +VIR_LOG_INIT("util.scsi"); + struct _virUsedByInfo { char *drvname; /* which driver */ char *domname; /* which domain */ diff --git a/src/util/virutil.c b/src/util/virutil.c index 2796671f4a..5391d74b3b 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -1777,7 +1777,7 @@ virGetDeviceUnprivSGIO(const char *path, } #ifdef __linux__ -# define SYSFS_FC_HOST_PATH "/sys/class/fc_host" + # define SYSFS_SCSI_HOST_PATH "/sys/class/scsi_host" /* virReadSCSIUniqueId: @@ -2004,404 +2004,8 @@ virGetSCSIHostNameByParentaddr(unsigned int domain, return name; } -/* virReadFCHost: - * @sysfs_prefix: "fc_host" sysfs path, defaults to SYSFS_FC_HOST_PATH - * @host: Host number, E.g. 5 of "fc_host/host5" - * @entry: Name of the sysfs entry to read - * - * Read the value of sysfs "fc_host" entry. - * - * Returns result as a string on success, caller must free @result after - * Otherwise returns NULL. - */ -char * -virReadFCHost(const char *sysfs_prefix, - int host, - const char *entry) -{ - char *sysfs_path = NULL; - char *p = NULL; - char *buf = NULL; - char *result = NULL; - - if (virAsprintf(&sysfs_path, "%s/host%d/%s", - sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH, - host, entry) < 0) - goto cleanup; - - if (!virFileExists(sysfs_path)) - goto cleanup; - - if (virFileReadAll(sysfs_path, 1024, &buf) < 0) - goto cleanup; - - if ((p = strchr(buf, '\n'))) - *p = '\0'; - - if ((p = strstr(buf, "0x"))) - p += strlen("0x"); - else - p = buf; - - ignore_value(VIR_STRDUP(result, p)); - - cleanup: - VIR_FREE(sysfs_path); - VIR_FREE(buf); - return result; -} - -bool -virIsCapableFCHost(const char *sysfs_prefix, - int host) -{ - char *sysfs_path = NULL; - bool ret = false; - - if (virAsprintf(&sysfs_path, "%s/host%d", - sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH, - host) < 0) - return false; - - if (virFileExists(sysfs_path)) - ret = true; - - VIR_FREE(sysfs_path); - return ret; -} - -bool -virIsCapableVport(const char *sysfs_prefix, - int host) -{ - char *scsi_host_path = NULL; - char *fc_host_path = NULL; - bool ret = false; - - if (virAsprintf(&fc_host_path, - "%s/host%d/%s", - sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH, - host, - "vport_create") < 0) - return false; - - if (virAsprintf(&scsi_host_path, - "%s/host%d/%s", - sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_HOST_PATH, - host, - "vport_create") < 0) - goto cleanup; - - if (virFileExists(fc_host_path) || - virFileExists(scsi_host_path)) - ret = true; - - cleanup: - VIR_FREE(fc_host_path); - VIR_FREE(scsi_host_path); - return ret; -} - -int -virManageVport(const int parent_host, - const char *wwpn, - const char *wwnn, - int operation) -{ - int ret = -1; - char *operation_path = NULL, *vport_name = NULL; - const char *operation_file = NULL; - - switch (operation) { - case VPORT_CREATE: - operation_file = "vport_create"; - break; - case VPORT_DELETE: - operation_file = "vport_delete"; - break; - default: - virReportError(VIR_ERR_OPERATION_INVALID, - _("Invalid vport operation (%d)"), operation); - goto cleanup; - } - - if (virAsprintf(&operation_path, - "%s/host%d/%s", - SYSFS_FC_HOST_PATH, - parent_host, - operation_file) < 0) - goto cleanup; - - if (!virFileExists(operation_path)) { - VIR_FREE(operation_path); - if (virAsprintf(&operation_path, - "%s/host%d/%s", - SYSFS_SCSI_HOST_PATH, - parent_host, - operation_file) < 0) - goto cleanup; - - if (!virFileExists(operation_path)) { - virReportError(VIR_ERR_OPERATION_INVALID, - _("vport operation '%s' is not supported for host%d"), - operation_file, parent_host); - goto cleanup; - } - } - - if (virAsprintf(&vport_name, - "%s:%s", - wwpn, - wwnn) < 0) - goto cleanup; - - if (virFileWriteStr(operation_path, vport_name, 0) == 0) - ret = 0; - else - virReportSystemError(errno, - _("Write of '%s' to '%s' during " - "vport create/delete failed"), - vport_name, operation_path); - - cleanup: - VIR_FREE(vport_name); - VIR_FREE(operation_path); - 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) - * by the provided "wwnn,wwpn" pair. - * - * Returns the FC host name which must be freed by the caller, - * or NULL on failure. - */ -char * -virGetFCHostNameByWWN(const char *sysfs_prefix, - const char *wwnn, - const char *wwpn) -{ - const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH; - struct dirent *entry = NULL; - DIR *dir = NULL; - char *ret = NULL; - - if (virDirOpen(&dir, prefix) < 0) - return NULL; - - while (virDirRead(dir, &entry, prefix) > 0) { - int rc; - - if ((rc = virReadCompareWWN(prefix, entry->d_name, - "node_name", wwnn)) < 0) - goto cleanup; - - if (rc == 0) - continue; - - if ((rc = virReadCompareWWN(prefix, entry->d_name, - "port_name", wwpn)) < 0) - goto cleanup; - - if (rc == 0) - continue; - - 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(vport_create_path)) - continue; - - if ((rc = virReadCompareWWN(prefix, entry->d_name, - "fabric_name", fabric_wwn)) < 0) - goto cleanup; - - if (rc == 0) - continue; - - ignore_value(VIR_STRDUP(ret, entry->d_name)); - break; - } - - cleanup: - VIR_DIR_CLOSE(dir); - VIR_FREE(vport_create_path); - return ret; -} - -# define PORT_STATE_ONLINE "Online" - -/* virFindFCHostCapableVport: - * - * Iterate over the sysfs and find out the first online HBA which - * supports vport, and not saturated. Returns the host name (e.g. - * host5) on success, or NULL on failure. - */ -char * -virFindFCHostCapableVport(const char *sysfs_prefix) -{ - const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH; - DIR *dir = NULL; - struct dirent *entry = NULL; - char *max_vports = NULL; - char *vports = NULL; - char *state = NULL; - char *ret = NULL; - - if (virDirOpen(&dir, prefix) < 0) - return NULL; - - while (virDirRead(dir, &entry, prefix) > 0) { - unsigned int host; - char *p = NULL; - - p = entry->d_name + strlen("host"); - if (virStrToLong_ui(p, NULL, 10, &host) == -1) { - VIR_DEBUG("Failed to parse host number from '%s'", - entry->d_name); - continue; - } - - if (!virIsCapableVport(prefix, host)) - continue; - - if (!(state = virReadFCHost(prefix, host, "port_state"))) { - VIR_DEBUG("Failed to read port_state for host%d", host); - continue; - } - - /* Skip the not online FC host */ - if (STRNEQ(state, PORT_STATE_ONLINE)) { - VIR_FREE(state); - continue; - } - VIR_FREE(state); - - if (!(max_vports = virReadFCHost(prefix, host, "max_npiv_vports"))) { - VIR_DEBUG("Failed to read max_npiv_vports for host%d", host); - continue; - } - - if (!(vports = virReadFCHost(prefix, host, "npiv_vports_inuse"))) { - VIR_DEBUG("Failed to read npiv_vports_inuse for host%d", host); - VIR_FREE(max_vports); - continue; - } - - /* Compare from the strings directly, instead of converting - * the strings to integers first - */ - if ((strlen(max_vports) >= strlen(vports)) || - ((strlen(max_vports) == strlen(vports)) && - strcmp(max_vports, vports) > 0)) { - ignore_value(VIR_STRDUP(ret, entry->d_name)); - goto cleanup; - } - - VIR_FREE(max_vports); - VIR_FREE(vports); - } - - cleanup: - VIR_DIR_CLOSE(dir); - VIR_FREE(max_vports); - VIR_FREE(vports); - return ret; -} #else + int virReadSCSIUniqueId(const char *sysfs_prefix ATTRIBUTE_UNUSED, int host ATTRIBUTE_UNUSED, @@ -2439,65 +2043,6 @@ virGetSCSIHostNameByParentaddr(unsigned int domain ATTRIBUTE_UNUSED, return NULL; } -char * -virReadFCHost(const char *sysfs_prefix ATTRIBUTE_UNUSED, - int host ATTRIBUTE_UNUSED, - const char *entry ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); - return NULL; -} - -bool -virIsCapableFCHost(const char *sysfs_prefix ATTRIBUTE_UNUSED, - int host ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); - return false; -} - -bool -virIsCapableVport(const char *sysfs_prefix ATTRIBUTE_UNUSED, - int host ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); - return false; -} - -int -virManageVport(const int parent_host ATTRIBUTE_UNUSED, - const char *wwpn ATTRIBUTE_UNUSED, - const char *wwnn ATTRIBUTE_UNUSED, - int operation ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); - return -1; -} - -char * -virGetFCHostNameByWWN(const char *sysfs_prefix ATTRIBUTE_UNUSED, - const char *wwnn ATTRIBUTE_UNUSED, - const char *wwpn ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); - return NULL; -} - -char * -virGetFCHostNameByFabricWWN(const char *sysfs_prefix ATTRIBUTE_UNUSED, - const char *fabric_wwn ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); - return NULL; -} - -char * -virFindFCHostCapableVport(const char *sysfs_prefix ATTRIBUTE_UNUSED) -{ - virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); - return NULL; -} - #endif /* __linux__ */ /** diff --git a/src/util/virutil.h b/src/util/virutil.h index 3fbd7b0688..b320c068d9 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -182,35 +182,8 @@ virGetSCSIHostNameByParentaddr(unsigned int domain, unsigned int slot, unsigned int function, unsigned int unique_id); -char *virReadFCHost(const char *sysfs_prefix, - int host, - const char *entry) - ATTRIBUTE_NONNULL(3); -bool virIsCapableFCHost(const char *sysfs_prefix, int host); -bool virIsCapableVport(const char *sysfs_prefix, int host); -enum { - VPORT_CREATE, - VPORT_DELETE, -}; - -int virManageVport(const int parent_host, - const char *wwpn, - const char *wwnn, - int operation) - ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); - -char *virGetFCHostNameByWWN(const char *sysfs_prefix, - const char *wwnn, - 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); diff --git a/src/util/virvhba.c b/src/util/virvhba.c new file mode 100644 index 0000000000..3a052f7b2e --- /dev/null +++ b/src/util/virvhba.c @@ -0,0 +1,534 @@ +/* + * virvhba.c: Generic vHBA management utility functions + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "viralloc.h" +#include "virerror.h" +#include "virfile.h" +#include "virlog.h" +#include "virstring.h" +#include "virvhba.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +VIR_LOG_INIT("util.vhba"); + +#ifdef __linux__ + +# define SYSFS_SCSI_HOST_PATH "/sys/class/scsi_host" +# define SYSFS_FC_HOST_PATH "/sys/class/fc_host" +# define PORT_STATE_ONLINE "Online" + + +/* virVHBAPathExists: + * @sysfs_prefix: "fc_host" sysfs path, defaults to SYSFS_FC_HOST_PATH + * @host: Host number, E.g. 5 of "fc_host/host5" + * + * Check if the "fc_host" to provided host# exists. This path may be either + * a vHBA capable path or a vHBA itself. + * + * Returns true if it does, false if not + */ +bool +virVHBAPathExists(const char *sysfs_prefix, + int host) +{ + char *sysfs_path = NULL; + bool ret = false; + + if (virAsprintf(&sysfs_path, "%s/host%d", + sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH, + host) < 0) + return false; + + if (virFileExists(sysfs_path)) + ret = true; + + VIR_FREE(sysfs_path); + return ret; +} + + +/* virVHBAIsVportCapable: + * @sysfs_prefix: "fc_host" sysfs path, defaults to SYSFS_FC_HOST_PATH + * @host: Host number, E.g. 5 of "fc_host/host5" + * + * Not all vHBA paths can create/delete a vport - only the parent NPIV + * capable HBA has the "vport_create" and "vport_delete" functions. + * A vHBA created path does not have the function files. + * + * NB: Checks both the "fc_host" and "scsi_host" paths. + * + * Returns true if capable, false if not + */ +bool +virVHBAIsVportCapable(const char *sysfs_prefix, + int host) +{ + char *scsi_host_path = NULL; + char *fc_host_path = NULL; + bool ret = false; + + if (virAsprintf(&fc_host_path, + "%s/host%d/%s", + sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH, + host, + "vport_create") < 0) + return false; + + if (virAsprintf(&scsi_host_path, + "%s/host%d/%s", + sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_HOST_PATH, + host, + "vport_create") < 0) + goto cleanup; + + if (virFileExists(fc_host_path) || virFileExists(scsi_host_path)) + ret = true; + + cleanup: + VIR_FREE(fc_host_path); + VIR_FREE(scsi_host_path); + return ret; +} + + +/* virVHBAGetConfig: + * @sysfs_prefix: "fc_host" sysfs path, defaults to SYSFS_FC_HOST_PATH + * @host: Host number, E.g. 5 of "fc_host/host5" + * @entry: Name of the FC sysfs entry to read + * + * Read the value of a vHBA sysfs "fc_host" entry (if it exists). + * + * Returns result as a string on success, caller is responsible for + * freeing the @result; otherwise returns NULL on failure. + */ +char * +virVHBAGetConfig(const char *sysfs_prefix, + int host, + const char *entry) +{ + char *sysfs_path = NULL; + char *p = NULL; + char *buf = NULL; + char *result = NULL; + + if (virAsprintf(&sysfs_path, "%s/host%d/%s", + sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH, + host, entry) < 0) + goto cleanup; + + if (!virFileExists(sysfs_path)) + goto cleanup; + + if (virFileReadAll(sysfs_path, 1024, &buf) < 0) + goto cleanup; + + if ((p = strchr(buf, '\n'))) + *p = '\0'; + + if ((p = strstr(buf, "0x"))) + p += strlen("0x"); + else + p = buf; + + ignore_value(VIR_STRDUP(result, p)); + + cleanup: + VIR_FREE(sysfs_path); + VIR_FREE(buf); + return result; +} + + +/* virVHBAFindVportHost: + * + * Iterate over the sysfs and find out the first online HBA which + * supports vport, and is not saturated. Returns the host name (e.g. + * host5) on success, or NULL on failure. + * + * It's up to the caller to free the returned string. + */ +char * +virVHBAFindVportHost(const char *sysfs_prefix) +{ + const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH; + DIR *dir = NULL; + struct dirent *entry = NULL; + char *max_vports = NULL; + char *vports = NULL; + char *state = NULL; + char *ret = NULL; + + if (virDirOpen(&dir, prefix) < 0) + return NULL; + + while (virDirRead(dir, &entry, prefix) > 0) { + unsigned int host; + char *p = NULL; + + p = entry->d_name + strlen("host"); + if (virStrToLong_ui(p, NULL, 10, &host) == -1) { + VIR_DEBUG("Failed to parse host number from '%s'", + entry->d_name); + continue; + } + + if (!virVHBAPathExists(prefix, host)) + continue; + + if (!(state = virVHBAGetConfig(prefix, host, "port_state"))) { + VIR_DEBUG("Failed to read port_state for host%d", host); + continue; + } + + /* Skip the not online FC host */ + if (STRNEQ(state, PORT_STATE_ONLINE)) { + VIR_FREE(state); + continue; + } + VIR_FREE(state); + + if (!(max_vports = virVHBAGetConfig(prefix, host, "max_npiv_vports"))) { + VIR_DEBUG("Failed to read max_npiv_vports for host%d", host); + continue; + } + + if (!(vports = virVHBAGetConfig(prefix, host, "npiv_vports_inuse"))) { + VIR_DEBUG("Failed to read npiv_vports_inuse for host%d", host); + VIR_FREE(max_vports); + continue; + } + + /* Compare from the strings directly, instead of converting + * the strings to integers first + */ + if ((strlen(max_vports) >= strlen(vports)) || + ((strlen(max_vports) == strlen(vports)) && + strcmp(max_vports, vports) > 0)) { + ignore_value(VIR_STRDUP(ret, entry->d_name)); + goto cleanup; + } + + VIR_FREE(max_vports); + VIR_FREE(vports); + } + + cleanup: + VIR_DIR_CLOSE(dir); + VIR_FREE(max_vports); + VIR_FREE(vports); + return ret; +} + +/* virVHBAManageVport: + * @sysfs_prefix: "fc_host" sysfs path, defaults to SYSFS_FC_HOST_PATH + * @wwnn: world wide node name used to create/delete the vport + * @wwpn: world wide port name used to create/delete the vport + * @operation: create or delete + * + * NB: Checks both the "fc_host" and "scsi_host" paths. + * Returns true if capable, false if not + */ +int +virVHBAManageVport(const int parent_host, + const char *wwpn, + const char *wwnn, + int operation) +{ + int ret = -1; + char *operation_path = NULL, *vport_name = NULL; + const char *operation_file = NULL; + + switch (operation) { + case VPORT_CREATE: + operation_file = "vport_create"; + break; + case VPORT_DELETE: + operation_file = "vport_delete"; + break; + default: + virReportError(VIR_ERR_OPERATION_INVALID, + _("Invalid vport operation (%d)"), operation); + goto cleanup; + } + + if (virAsprintf(&operation_path, "%s/host%d/%s", + SYSFS_FC_HOST_PATH, parent_host, operation_file) < 0) + goto cleanup; + + if (!virFileExists(operation_path)) { + VIR_FREE(operation_path); + if (virAsprintf(&operation_path, "%s/host%d/%s", + SYSFS_SCSI_HOST_PATH, parent_host, operation_file) < 0) + goto cleanup; + + if (!virFileExists(operation_path)) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("vport operation '%s' is not supported " + "for host%d"), + operation_file, parent_host); + goto cleanup; + } + } + + /* Create/Delete is handled through the file passing the wwpn:wwnn as + * a parameter. This results in the kernel managing the port. For udev, + * an event is posted and handled in udevEventHandleCallback resulting + * in calling either the Add or Remove device functions. This translates + * into either adding or removing a node device object and a node device + * lifecycle event for applications to consume. */ + if (virAsprintf(&vport_name, "%s:%s", wwpn, wwnn) < 0) + goto cleanup; + + if (virFileWriteStr(operation_path, vport_name, 0) == 0) + ret = 0; + else + virReportSystemError(errno, + _("Write of '%s' to '%s' during " + "vport create/delete failed"), + vport_name, operation_path); + + cleanup: + VIR_FREE(vport_name); + VIR_FREE(operation_path); + return ret; +} + + +/* vhbaReadCompareWWN + * @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 +vhbaReadCompareWWN(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; +} + +/* virVHBAGetHostByWWN: + * + * Iterate over the sysfs tree to get FC host name (e.g. host5) + * by the provided "wwnn,wwpn" pair. + * + * Returns the FC host name which must be freed by the caller, + * or NULL on failure. + */ +char * +virVHBAGetHostByWWN(const char *sysfs_prefix, + const char *wwnn, + const char *wwpn) +{ + const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH; + struct dirent *entry = NULL; + DIR *dir = NULL; + char *ret = NULL; + + if (virDirOpen(&dir, prefix) < 0) + return NULL; + + while (virDirRead(dir, &entry, prefix) > 0) { + int rc; + + if ((rc = vhbaReadCompareWWN(prefix, entry->d_name, + "node_name", wwnn)) < 0) + goto cleanup; + + if (rc == 0) + continue; + + if ((rc = vhbaReadCompareWWN(prefix, entry->d_name, + "port_name", wwpn)) < 0) + goto cleanup; + + if (rc == 0) + continue; + + ignore_value(VIR_STRDUP(ret, entry->d_name)); + break; + } + + cleanup: + VIR_DIR_CLOSE(dir); + return ret; +} + +/* virVHBAGetHostByFabricWWN: + * + * 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 * +virVHBAGetHostByFabricWWN(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(vport_create_path)) + continue; + + if ((rc = vhbaReadCompareWWN(prefix, entry->d_name, + "fabric_name", fabric_wwn)) < 0) + goto cleanup; + + if (rc == 0) + continue; + + ignore_value(VIR_STRDUP(ret, entry->d_name)); + break; + } + + cleanup: + VIR_DIR_CLOSE(dir); + VIR_FREE(vport_create_path); + return ret; +} + +#else + +bool +virVHBAPathExists(const char *sysfs_prefix ATTRIBUTE_UNUSED, + int host ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); + return false; +} + + +bool +virVHBAVportIsCapable(const char *sysfs_prefix ATTRIBUTE_UNUSED, + int host ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); + return false; +} + + +char * +virVHBAGetConfig(const char *sysfs_prefix ATTRIBUTE_UNUSED, + int host ATTRIBUTE_UNUSED, + const char *entry ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); + return NULL; +} + + +char * +virVHBAFindVportHost(const char *sysfs_prefix ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); + return NULL; +} + + +int +virVHBAManageVport(const int parent_host ATTRIBUTE_UNUSED, + const char *wwpn ATTRIBUTE_UNUSED, + const char *wwnn ATTRIBUTE_UNUSED, + int operation ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); + return -1; +} + + +char * +virVHBAGetHostByWWN(const char *sysfs_prefix ATTRIBUTE_UNUSED, + const char *wwnn ATTRIBUTE_UNUSED, + const char *wwpn ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); + return NULL; +} + + +char * +virVHBAGetHostByFabricWWN(const char *sysfs_prefix ATTRIBUTE_UNUSED, + const char *fabric_wwn ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); + return NULL; +} + +#endif /* __linux__ */ diff --git a/src/util/virvhba.h b/src/util/virvhba.h new file mode 100644 index 0000000000..67b1fa5376 --- /dev/null +++ b/src/util/virvhba.h @@ -0,0 +1,62 @@ +/* + * virvhba.h: Generic vHBA management utility functions + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#ifndef __VIR_VHBA_H__ +# define __VIR_VHBA_H__ + +# include "internal.h" + +enum { + VPORT_CREATE, + VPORT_DELETE, +}; + +bool +virVHBAPathExists(const char *sysfs_prefix, int host); + +bool +virVHBAIsVportCapable(const char *sysfs_prefix, int host); + +char * +virVHBAGetConfig(const char *sysfs_prefix, + int host, + const char *entry) + ATTRIBUTE_NONNULL(3); + +char * +virVHBAFindVportHost(const char *sysfs_prefix); + +int +virVHBAManageVport(const int parent_host, + const char *wwpn, + const char *wwnn, + int operation) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); + +char * +virVHBAGetHostByWWN(const char *sysfs_prefix, + const char *wwnn, + const char *wwpn) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); + +char * +virVHBAGetHostByFabricWWN(const char *sysfs_prefix, + const char *fabric_wwn) + ATTRIBUTE_NONNULL(2); + +#endif /* __VIR_VBHA_H__ */ diff --git a/tests/fchosttest.c b/tests/fchosttest.c index 0b4a8f20ed..39a06f3595 100644 --- a/tests/fchosttest.c +++ b/tests/fchosttest.c @@ -20,7 +20,7 @@ #include #include "virstring.h" -#include "virutil.h" +#include "virvhba.h" #include "testutils.h" #define VIR_FROM_THIS VIR_FROM_NONE @@ -31,31 +31,28 @@ static char *fchost_prefix; #define TEST_FC_HOST_NUM 5 #define TEST_FC_HOST_NUM_NO_FAB 6 -/* Test virIsCapableFCHost */ +/* Test virIsVHBACapable */ static int test1(const void *data ATTRIBUTE_UNUSED) { - if (virIsCapableFCHost(TEST_FC_HOST_PREFIX, - TEST_FC_HOST_NUM) && - virIsCapableFCHost(TEST_FC_HOST_PREFIX, - TEST_FC_HOST_NUM_NO_FAB)) + if (virVHBAPathExists(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM) && + virVHBAPathExists(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM_NO_FAB)) return 0; return -1; } -/* Test virIsCapableVport */ +/* Test virVHBAIsVportCapable */ static int test2(const void *data ATTRIBUTE_UNUSED) { - if (virIsCapableVport(TEST_FC_HOST_PREFIX, - TEST_FC_HOST_NUM)) + if (virVHBAIsVportCapable(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM)) return 0; return -1; } -/* Test virReadFCHost */ +/* Test virVHBAGetConfig */ static int test3(const void *data ATTRIBUTE_UNUSED) { @@ -71,25 +68,25 @@ test3(const void *data ATTRIBUTE_UNUSED) char *vports = NULL; int ret = -1; - if (!(wwnn = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, - "node_name"))) + if (!(wwnn = virVHBAGetConfig(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, + "node_name"))) return -1; - if (!(wwpn = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, - "port_name"))) + if (!(wwpn = virVHBAGetConfig(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, + "port_name"))) goto cleanup; - if (!(fabric_wwn = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, - "fabric_name"))) + if (!(fabric_wwn = virVHBAGetConfig(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, + "fabric_name"))) goto cleanup; - if (!(max_vports = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, - "max_npiv_vports"))) + if (!(max_vports = virVHBAGetConfig(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, + "max_npiv_vports"))) goto cleanup; - if (!(vports = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, - "npiv_vports_inuse"))) + if (!(vports = virVHBAGetConfig(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM, + "npiv_vports_inuse"))) goto cleanup; if (STRNEQ(expect_wwnn, wwnn) || @@ -109,7 +106,7 @@ test3(const void *data ATTRIBUTE_UNUSED) return ret; } -/* Test virGetFCHostNameByWWN */ +/* Test virVHBAGetHostByWWN */ static int test4(const void *data ATTRIBUTE_UNUSED) { @@ -117,9 +114,9 @@ test4(const void *data ATTRIBUTE_UNUSED) char *hostname = NULL; int ret = -1; - if (!(hostname = virGetFCHostNameByWWN(TEST_FC_HOST_PREFIX, - "2001001b32a9da4e", - "2101001b32a9da4e"))) + if (!(hostname = virVHBAGetHostByWWN(TEST_FC_HOST_PREFIX, + "2001001b32a9da4e", + "2101001b32a9da4e"))) return -1; if (STRNEQ(hostname, expect_hostname)) @@ -131,7 +128,10 @@ test4(const void *data ATTRIBUTE_UNUSED) return ret; } -/* Test virFindFCHostCapableVport (host4 is not Online) */ +/* Test virVHBAFindVportHost + * + * NB: host4 is not Online, so it should not be found + */ static int test5(const void *data ATTRIBUTE_UNUSED) { @@ -139,7 +139,7 @@ test5(const void *data ATTRIBUTE_UNUSED) char *hostname = NULL; int ret = -1; - if (!(hostname = virFindFCHostCapableVport(TEST_FC_HOST_PREFIX))) + if (!(hostname = virVHBAFindVportHost(TEST_FC_HOST_PREFIX))) return -1; if (STRNEQ(hostname, expect_hostname)) @@ -151,7 +151,7 @@ test5(const void *data ATTRIBUTE_UNUSED) return ret; } -/* Test virReadFCHost fabric name optional */ +/* Test virVHBAGetConfig fabric name optional */ static int test6(const void *data ATTRIBUTE_UNUSED) { @@ -162,17 +162,17 @@ test6(const void *data ATTRIBUTE_UNUSED) char *fabric_wwn = NULL; int ret = -1; - if (!(wwnn = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM_NO_FAB, - "node_name"))) + if (!(wwnn = virVHBAGetConfig(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM_NO_FAB, + "node_name"))) return -1; - if (!(wwpn = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM_NO_FAB, - "port_name"))) + if (!(wwpn = virVHBAGetConfig(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM_NO_FAB, + "port_name"))) goto cleanup; - if ((fabric_wwn = virReadFCHost(TEST_FC_HOST_PREFIX, - TEST_FC_HOST_NUM_NO_FAB, - "fabric_name"))) + if ((fabric_wwn = virVHBAGetConfig(TEST_FC_HOST_PREFIX, + TEST_FC_HOST_NUM_NO_FAB, + "fabric_name"))) goto cleanup; if (STRNEQ(expect_wwnn, wwnn) || @@ -198,17 +198,17 @@ mymain(void) goto cleanup; } - if (virTestRun("test1", test1, NULL) < 0) + if (virTestRun("virVHBAPathExists", test1, NULL) < 0) ret = -1; - if (virTestRun("test2", test2, NULL) < 0) + if (virTestRun("virVHBAIsVportCapable", test2, NULL) < 0) ret = -1; - if (virTestRun("test3", test3, NULL) < 0) + if (virTestRun("virVHBAGetConfig", test3, NULL) < 0) ret = -1; - if (virTestRun("test4", test4, NULL) < 0) + if (virTestRun("virVHBAGetHostByWWN", test4, NULL) < 0) ret = -1; - if (virTestRun("test5", test5, NULL) < 0) + if (virTestRun("virVHBAFindVportHost", test5, NULL) < 0) ret = -1; - if (virTestRun("test6", test6, NULL) < 0) + if (virTestRun("virVHBAGetConfig-empty-fabric_wwn", test6, NULL) < 0) ret = -1; cleanup: