diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 6ad37f8f36a0630506f73b44b4593a6212ffdac6..a76d48a26cae434d1aefc8ca1b04b418b3122414 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -2078,6 +2078,65 @@ virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools, return ret; } +/* + * virStoragePoolGetVhbaSCSIHostParent: + * + * Using the Node Device Driver, find the host# name found via wwnn/wwpn + * lookup in the fc_host sysfs tree (e.g. virGetFCHostNameByWWN) to get + * the parent 'scsi_host#'. + * + * @conn: Connection pointer (must be non-NULL on entry) + * @name: Pointer a string from a virGetFCHostNameByWWN (e.g., "host#") + * + * Returns a "scsi_host#" string of the parent of the vHBA + */ +char * +virStoragePoolGetVhbaSCSIHostParent(virConnectPtr conn, + const char *name) +{ + char *nodedev_name = NULL; + virNodeDevicePtr device = NULL; + char *xml = NULL; + virNodeDeviceDefPtr def = NULL; + char *vhba_parent = NULL; + + VIR_DEBUG("conn=%p, name=%s", conn, name); + + /* We get passed "host#" from the return from virGetFCHostNameByWWN, + * so we need to adjust that to what the nodedev lookup expects + */ + if (virAsprintf(&nodedev_name, "scsi_%s", name) < 0) + goto cleanup; + + /* Compare the scsi_host for the name with the provided parent + * if not the same, then fail + */ + if (!(device = virNodeDeviceLookupByName(conn, nodedev_name))) { + virReportError(VIR_ERR_XML_ERROR, + _("Cannot find '%s' in node device database"), + nodedev_name); + goto cleanup; + } + + if (!(xml = virNodeDeviceGetXMLDesc(device, 0))) + goto cleanup; + + if (!(def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL))) + goto cleanup; + + /* The caller checks whether the returned value is NULL or not + * before continuing + */ + ignore_value(VIR_STRDUP(vhba_parent, def->parent)); + + cleanup: + VIR_FREE(nodedev_name); + virNodeDeviceDefFree(def); + VIR_FREE(xml); + virObjectUnref(device); + return vhba_parent; +} + static int getSCSIHostNumber(virStoragePoolSourceAdapter adapter, unsigned int *hostnum) diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 765f681d0aa8c57914a955efe7187f4731b4d8c9..228bb1c39e2bc445c5b6b6c2488fe83ebc2766bf 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -30,6 +30,7 @@ # include "virbitmap.h" # include "virthread.h" # include "device_conf.h" +# include "node_device_conf.h" # include @@ -389,6 +390,10 @@ int virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools, virStoragePoolDefPtr def, unsigned int check_active); +char *virStoragePoolGetVhbaSCSIHostParent(virConnectPtr conn, + const char *name) + ATTRIBUTE_NONNULL(1); + int virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools, virStoragePoolDefPtr def); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2647d36983c5c7bbb5bfc17db43a4ded1e46d31a..1853a9cebb4466eb3c512927f4f397321ace097e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -744,6 +744,7 @@ virStoragePoolDefParseString; virStoragePoolFormatDiskTypeToString; virStoragePoolFormatFileSystemNetTypeToString; virStoragePoolFormatFileSystemTypeToString; +virStoragePoolGetVhbaSCSIHostParent; virStoragePoolLoadAllConfigs; virStoragePoolObjAssignDef; virStoragePoolObjClearVols; diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 5a4c9d12ab2c69f457b378525abbb15a041a9187..c4879b0e7aedac68f05496ce906d794e4aaa400d 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -34,7 +34,6 @@ #include "virlog.h" #include "virfile.h" #include "vircommand.h" -#include "viraccessapicheck.h" #include "virstring.h" #define VIR_FROM_THIS VIR_FROM_STORAGE @@ -630,67 +629,6 @@ getAdapterName(virStoragePoolSourceAdapter adapter) return name; } -/* - * Using the host# name found via wwnn/wwpn lookup in the fc_host - * sysfs tree to get the parent 'scsi_host#'. On entry we need 'conn' - * set. We won't get here from the autostart path since the caller - * will return true before calling this function. For the shutdown - * path we won't be able to delete the vport. - */ -static char * ATTRIBUTE_NONNULL(1) -getVhbaSCSIHostParent(virConnectPtr conn, - const char *name) -{ - char *nodedev_name = NULL; - virNodeDevicePtr device = NULL; - char *xml = NULL; - virNodeDeviceDefPtr def = NULL; - char *vhba_parent = NULL; - virErrorPtr savedError = NULL; - - VIR_DEBUG("conn=%p, name=%s", conn, name); - - /* We get passed "host#" from the return from virGetFCHostNameByWWN, - * so we need to adjust that to what the nodedev lookup expects - */ - if (virAsprintf(&nodedev_name, "scsi_%s", name) < 0) - goto cleanup; - - /* Compare the scsi_host for the name with the provided parent - * if not the same, then fail - */ - if (!(device = virNodeDeviceLookupByName(conn, nodedev_name))) { - virReportError(VIR_ERR_XML_ERROR, - _("Cannot find '%s' in node device database"), - nodedev_name); - goto cleanup; - } - - if (!(xml = virNodeDeviceGetXMLDesc(device, 0))) - goto cleanup; - - if (!(def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL))) - goto cleanup; - - /* The caller checks whether the returned value is NULL or not - * before continuing - */ - ignore_value(VIR_STRDUP(vhba_parent, def->parent)); - - cleanup: - if (!vhba_parent) - savedError = virSaveLastError(); - VIR_FREE(nodedev_name); - virNodeDeviceDefFree(def); - VIR_FREE(xml); - virNodeDeviceFree(device); - if (savedError) { - virSetError(savedError); - virFreeError(savedError); - } - return vhba_parent; -} - /* * Using the host# name found via wwnn/wwpn lookup in the fc_host * sysfs tree to get the parent 'scsi_host#' to ensure it matches. @@ -709,7 +647,7 @@ checkVhbaSCSIHostParent(virConnectPtr conn, if (!conn) return true; - if (!(vhba_parent = getVhbaSCSIHostParent(conn, name))) + if (!(vhba_parent = virStoragePoolGetVhbaSCSIHostParent(conn, name))) goto cleanup; if (STRNEQ(parent_name, vhba_parent)) { @@ -886,7 +824,7 @@ deleteVport(virConnectPtr conn, if (virGetSCSIHostNumber(adapter.data.fchost.parent, &parent_host) < 0) goto cleanup; } else { - if (!(vhba_parent = getVhbaSCSIHostParent(conn, name))) + if (!(vhba_parent = virStoragePoolGetVhbaSCSIHostParent(conn, name))) goto cleanup; if (virGetSCSIHostNumber(vhba_parent, &parent_host) < 0)