From nobody Fri Mar 29 10:51:25 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1541087861323627.8442059805182; Thu, 1 Nov 2018 08:57:41 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 49C239981B; Thu, 1 Nov 2018 15:57:38 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4BE0A5D6A6; Thu, 1 Nov 2018 15:57:37 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id D68DA3D380; Thu, 1 Nov 2018 15:57:32 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wA1FpA1L030644 for ; Thu, 1 Nov 2018 11:51:10 -0400 Received: by smtp.corp.redhat.com (Postfix) id 9F83A600D1; Thu, 1 Nov 2018 15:51:10 +0000 (UTC) Received: from beluga.usersys.redhat.com (unknown [10.43.2.166]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9B62A600CD; Thu, 1 Nov 2018 15:51:07 +0000 (UTC) From: Erik Skultety To: libvir-list@redhat.com Date: Thu, 1 Nov 2018 16:50:59 +0100 Message-Id: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Cc: Erik Skultety Subject: [libvirt] [PATCH] nodedev: Add new module node_device_util X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 01 Nov 2018 15:57:39 +0000 (UTC) Content-Type: text/plain; charset="utf-8" There's a lot of stuff going on in src/conf/nodedev_conf which not always has to do anything with config, so even though we're trying, we're not really consistent in putting only parser/formatter related stuff here like we do for domains. So, start the cleanup simply by adding a new module to the nodedev driver and put a few helper APIs which want to open a secondary driver connection in there (similar to storage_util module). Signed-off-by: Erik Skultety --- I verified the build with debian 9, centos 7, fedora 28, rawhide, and freeb= sd 11 src/conf/Makefile.inc.am | 1 + src/conf/node_device_conf.c | 199 ----------------------- src/conf/node_device_conf.h | 11 -- src/conf/virstorageobj.c | 1 + src/libvirt_private.syms | 8 +- src/node_device/Makefile.inc.am | 17 +- src/node_device/node_device_driver.c | 1 + src/node_device/node_device_util.c | 229 +++++++++++++++++++++++++++ src/node_device/node_device_util.h | 35 ++++ src/storage/Makefile.inc.am | 1 + src/storage/storage_backend_scsi.c | 1 + 11 files changed, 290 insertions(+), 214 deletions(-) create mode 100644 src/node_device/node_device_util.c create mode 100644 src/node_device/node_device_util.h diff --git a/src/conf/Makefile.inc.am b/src/conf/Makefile.inc.am index af23810640..7cb6c29d70 100644 --- a/src/conf/Makefile.inc.am +++ b/src/conf/Makefile.inc.am @@ -163,6 +163,7 @@ libvirt_la_BUILT_LIBADD +=3D libvirt_conf.la libvirt_conf_la_SOURCES =3D $(CONF_SOURCES) libvirt_conf_la_CFLAGS =3D \ -I$(srcdir)/conf \ + -I$(srcdir)/node_device \ $(AM_CFLAGS) \ $(NULL) libvirt_conf_la_LDFLAGS =3D $(AM_LDFLAGS) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 03bd794dc0..74a7bc3933 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -2220,205 +2220,6 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) } -/* virNodeDeviceGetParentName - * @conn: Connection pointer - * @nodedev_name: Node device to lookup - * - * Lookup the node device by name and return the parent name - * - * Returns parent name on success, caller is responsible for freeing; - * otherwise, returns NULL on failure - */ -char * -virNodeDeviceGetParentName(virConnectPtr conn, - const char *nodedev_name) -{ - virNodeDevicePtr device =3D NULL; - char *parent; - - if (!(device =3D virNodeDeviceLookupByName(conn, nodedev_name))) { - virReportError(VIR_ERR_XML_ERROR, - _("Cannot find '%s' in node device database"), - nodedev_name); - return NULL; - } - - ignore_value(VIR_STRDUP(parent, virNodeDeviceGetParent(device))); - virObjectUnref(device); - - return parent; -} - - -/** - * @fchost: Pointer to vHBA adapter - * - * Create a vHBA for Storage. This code accomplishes this via searching - * through the sysfs for scsi_host/fc_host in order to first ensure some - * vHBA doesn't already exist for the requested wwnn/wwpn (e.g. an unmanag= ed - * vHBA) and to search for the parent vport capable scsi_host by name, - * wwnn/wwpn, or fabric_wwn (if provided). If no parent is provided, then - * a vport capable scsi_host will be selected. - * - * Returns vHBA name on success, NULL on failure with an error message set - */ -char * -virNodeDeviceCreateVport(virStorageAdapterFCHostPtr fchost) -{ - unsigned int parent_host; - char *name =3D NULL; - char *parent_hoststr =3D NULL; - bool skip_capable_check =3D false; - - VIR_DEBUG("parent=3D'%s', wwnn=3D'%s' wwpn=3D'%s'", - NULLSTR(fchost->parent), fchost->wwnn, fchost->wwpn); - - if (fchost->parent) { - if (VIR_STRDUP(parent_hoststr, fchost->parent) < 0) - goto cleanup; - } else if (fchost->parent_wwnn && fchost->parent_wwpn) { - if (!(parent_hoststr =3D virVHBAGetHostByWWN(NULL, fchost->parent_= wwnn, - fchost->parent_wwpn))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("cannot find parent using provided wwnn/wwpn"= )); - goto cleanup; - } - } else if (fchost->parent_fabric_wwn) { - if (!(parent_hoststr =3D - virVHBAGetHostByFabricWWN(NULL, fchost->parent_fabric_wwn)))= { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("cannot find parent using provided fabric_wwn= ")); - goto cleanup; - } - } else { - if (!(parent_hoststr =3D virVHBAFindVportHost(NULL))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("'parent' for vHBA not specified, and " - "cannot find one on this host")); - goto cleanup; - } - skip_capable_check =3D true; - } - - if (virSCSIHostGetNumber(parent_hoststr, &parent_host) < 0) - goto cleanup; - - /* NOTE: - * We do not save the parent_hoststr in fchost->parent since - * we could be writing out the 'def' to the saved XML config. - * If we wrote out the name in the XML, then future starts would - * always use the same parent rather than finding the "best available" - * parent. Besides we have a way to determine the parent based on - * the 'name' field. - */ - if (!skip_capable_check && !virVHBAPathExists(NULL, parent_host)) { - virReportError(VIR_ERR_XML_ERROR, - _("parent '%s' specified for vHBA does not exist"), - parent_hoststr); - goto cleanup; - } - - if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, - VPORT_CREATE) < 0) - goto cleanup; - - /* Let's ensure the device was created */ - virWaitForDevices(); - if (!(name =3D virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn)))= { - ignore_value(virVHBAManageVport(parent_host, fchost->wwpn, fchost-= >wwnn, - VPORT_DELETE)); - goto cleanup; - } - - cleanup: - VIR_FREE(parent_hoststr); - return name; -} - - -/** - * @conn: Connection pointer - * @fchost: Pointer to vHBA adapter - * - * As long as the vHBA is being managed, search for the scsi_host via the - * provided wwnn/wwpn and then find the corresponding parent scsi_host in - * order to send the delete request. - * - * Returns 0 on success, -1 on failure - */ -int -virNodeDeviceDeleteVport(virConnectPtr conn, - virStorageAdapterFCHostPtr fchost) -{ - char *name =3D NULL; - char *scsi_host_name =3D NULL; - unsigned int parent_host; - char *vhba_parent =3D NULL; - int ret =3D -1; - - VIR_DEBUG("conn=3D%p parent=3D'%s', managed=3D'%d' wwnn=3D'%s' wwpn=3D= '%s'", - conn, NULLSTR(fchost->parent), fchost->managed, - fchost->wwnn, fchost->wwpn); - - /* If we're not managing the deletion of the vHBA, then just return */ - if (fchost->managed !=3D VIR_TRISTATE_BOOL_YES) - return 0; - - /* Find our vHBA by searching the fc_host sysfs tree for our wwnn/wwpn= */ - if (!(name =3D virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn)))= { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to find fc_host for wwnn=3D'%s' and wwpn= =3D'%s'"), - fchost->wwnn, fchost->wwpn); - goto cleanup; - } - - if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) - goto cleanup; - - /* If at startup time we provided a parent, then use that to - * get the parent_host value; otherwise, we have to determine - * the parent scsi_host which we did not save at startup time - */ - if (fchost->parent) { - /* Someone provided a parent string at startup time that - * was the same as the scsi_host - meaning we have a pool - * backed to an HBA, so there won't be a vHBA to delete */ - if (STREQ(scsi_host_name, fchost->parent)) { - ret =3D 0; - goto cleanup; - } - - if (virSCSIHostGetNumber(fchost->parent, &parent_host) < 0) - goto cleanup; - } else { - if (!(vhba_parent =3D virNodeDeviceGetParentName(conn, scsi_host_n= ame))) - goto cleanup; - - /* If the parent is not a scsi_host, then this is a pool backed - * directly to an HBA and there's no vHBA to remove - so we're don= e */ - if (!STRPREFIX(vhba_parent, "scsi_host")) { - ret =3D 0; - goto cleanup; - } - - if (virSCSIHostGetNumber(vhba_parent, &parent_host) < 0) - goto cleanup; - } - - if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, - VPORT_DELETE) < 0) - goto cleanup; - - ret =3D 0; - - cleanup: - VIR_FREE(name); - VIR_FREE(vhba_parent); - VIR_FREE(scsi_host_name); - return ret; -} - - int virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def) { diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index 685ae30347..fde239183d 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -367,17 +367,6 @@ virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps); VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV | \ VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV) -char * -virNodeDeviceGetParentName(virConnectPtr conn, - const char *nodedev_name); - -char * -virNodeDeviceCreateVport(virStorageAdapterFCHostPtr fchost); - -int -virNodeDeviceDeleteVport(virConnectPtr conn, - virStorageAdapterFCHostPtr fchost); - int virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host); diff --git a/src/conf/virstorageobj.c b/src/conf/virstorageobj.c index 0b3ba84af2..30aabb2b37 100644 --- a/src/conf/virstorageobj.c +++ b/src/conf/virstorageobj.c @@ -22,6 +22,7 @@ #include "datatypes.h" #include "node_device_conf.h" +#include "node_device_util.h" #include "virstorageobj.h" #include "viralloc.h" diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 335210c31d..e2f10acff4 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -722,14 +722,11 @@ virNodeDevCapsDefFree; virNodeDevCapTypeFromString; virNodeDevCapTypeToString; virNodeDeviceCapsListExport; -virNodeDeviceCreateVport; virNodeDeviceDefFormat; virNodeDeviceDefFree; virNodeDeviceDefParseFile; virNodeDeviceDefParseNode; virNodeDeviceDefParseString; -virNodeDeviceDeleteVport; -virNodeDeviceGetParentName; virNodeDeviceGetPCIDynamicCaps; virNodeDeviceGetSCSIHostCaps; virNodeDeviceGetSCSITargetCaps; @@ -1317,6 +1314,11 @@ virLogManagerFree; virLogManagerNew; +# node_device/node_device_util.h +virNodeDeviceCreateVport; +virNodeDeviceDeleteVport; +virNodeDeviceGetParentName; + # secret/secret_util.h virSecretGetSecretString; diff --git a/src/node_device/Makefile.inc.am b/src/node_device/Makefile.inc= .am index 0c3ad51273..f7aec97ba9 100644 --- a/src/node_device/Makefile.inc.am +++ b/src/node_device/Makefile.inc.am @@ -3,6 +3,11 @@ NODE_DEVICE_DRIVER_SOURCES =3D \ node_device/node_device_driver.h \ $(NULL) +NODE_DEVICE_UTIL_SOURCES =3D \ + node_device/node_device_util.h \ + node_device/node_device_util.c \ + $(NULL) + NODE_DEVICE_DRIVER_HAL_SOURCES =3D \ node_device/node_device_hal.c \ node_device/node_device_hal.h \ @@ -17,6 +22,7 @@ DRIVER_SOURCE_FILES +=3D \ $(NODE_DEVICE_DRIVER_SOURCES) \ $(NODE_DEVICE_DRIVER_HAL_SOURCES) \ $(NODE_DEVICE_DRIVER_UDEV_SOURCES) \ + $(NODE_DEVICE_UTIL_SOURCES) \ $(NULL) STATEFUL_DRIVER_SOURCE_FILES +=3D \ @@ -27,13 +33,22 @@ EXTRA_DIST +=3D \ $(NODE_DEVICE_DRIVER_SOURCES) \ $(NODE_DEVICE_DRIVER_HAL_SOURCES) \ $(NODE_DEVICE_DRIVER_UDEV_SOURCES) \ + $(NODE_DEVICE_UTIL_SOURCES) \ $(NULL) +noinst_LTLIBRARIES +=3D libvirt_nodedev.la +libvirt_la_BUILT_LIBADD +=3D libvirt_nodedev.la +libvirt_nodedev_la_CFLAGS =3D $(AM_CFLAGS) +libvirt_nodedev_la_LDFLAGS =3D $(AM_LDFLAGS) +libvirt_nodedev_la_SOURCES =3D $(NODE_DEVICE_UTIL_SOURCES) if WITH_NODE_DEVICES # Needed to keep automake quiet about conditionals mod_LTLIBRARIES +=3D libvirt_driver_nodedev.la -libvirt_driver_nodedev_la_SOURCES =3D $(NODE_DEVICE_DRIVER_SOURCES) +libvirt_driver_nodedev_la_SOURCES =3D \ + $(NODE_DEVICE_DRIVER_SOURCES) \ + $(NODE_DEVICE_UTIL_SOURCES) \ + $(NULL) libvirt_driver_nodedev_la_CFLAGS =3D \ -I$(srcdir)/access \ diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_de= vice_driver.c index c46d0fbe12..0bcb3de053 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -37,6 +37,7 @@ #include "node_device_event.h" #include "node_device_driver.h" #include "node_device_hal.h" +#include "node_device_util.h" #include "virvhba.h" #include "viraccessapicheck.h" #include "virnetdev.h" diff --git a/src/node_device/node_device_util.c b/src/node_device/node_devi= ce_util.c new file mode 100644 index 0000000000..d1d9c3ee49 --- /dev/null +++ b/src/node_device/node_device_util.c @@ -0,0 +1,229 @@ +/* + * node_device_util.c: helper functions for the node device driver + * + * 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 "internal.h" + +#include "node_device_util.h" +#include "virlog.h" +#include "virscsihost.h" +#include "virstring.h" +#include "virvhba.h" + +#define VIR_FROM_THIS VIR_FROM_NODEDEV + +VIR_LOG_INIT("node_device.node_device_util"); + +/* virNodeDeviceGetParentName + * @conn: Connection pointer + * @nodedev_name: Node device to lookup + * + * Lookup the node device by name and return the parent name + * + * Returns parent name on success, caller is responsible for freeing; + * otherwise, returns NULL on failure + */ +char * +virNodeDeviceGetParentName(virConnectPtr conn, + const char *nodedev_name) +{ + virNodeDevicePtr device =3D NULL; + char *parent; + + if (!(device =3D virNodeDeviceLookupByName(conn, nodedev_name))) { + virReportError(VIR_ERR_XML_ERROR, + _("Cannot find '%s' in node device database"), + nodedev_name); + return NULL; + } + + ignore_value(VIR_STRDUP(parent, virNodeDeviceGetParent(device))); + virObjectUnref(device); + + return parent; +} + + +/** + * @fchost: Pointer to vHBA adapter + * + * Create a vHBA for Storage. This code accomplishes this via searching + * through the sysfs for scsi_host/fc_host in order to first ensure some + * vHBA doesn't already exist for the requested wwnn/wwpn (e.g. an unmanag= ed + * vHBA) and to search for the parent vport capable scsi_host by name, + * wwnn/wwpn, or fabric_wwn (if provided). If no parent is provided, then + * a vport capable scsi_host will be selected. + * + * Returns vHBA name on success, NULL on failure with an error message set + */ +char * +virNodeDeviceCreateVport(virStorageAdapterFCHostPtr fchost) +{ + unsigned int parent_host; + char *name =3D NULL; + char *parent_hoststr =3D NULL; + bool skip_capable_check =3D false; + + VIR_DEBUG("parent=3D'%s', wwnn=3D'%s' wwpn=3D'%s'", + NULLSTR(fchost->parent), fchost->wwnn, fchost->wwpn); + + if (fchost->parent) { + if (VIR_STRDUP(parent_hoststr, fchost->parent) < 0) + goto cleanup; + } else if (fchost->parent_wwnn && fchost->parent_wwpn) { + if (!(parent_hoststr =3D virVHBAGetHostByWWN(NULL, fchost->parent_= wwnn, + fchost->parent_wwpn))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("cannot find parent using provided wwnn/wwpn"= )); + goto cleanup; + } + } else if (fchost->parent_fabric_wwn) { + if (!(parent_hoststr =3D + virVHBAGetHostByFabricWWN(NULL, fchost->parent_fabric_wwn)))= { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("cannot find parent using provided fabric_wwn= ")); + goto cleanup; + } + } else { + if (!(parent_hoststr =3D virVHBAFindVportHost(NULL))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'parent' for vHBA not specified, and " + "cannot find one on this host")); + goto cleanup; + } + skip_capable_check =3D true; + } + + if (virSCSIHostGetNumber(parent_hoststr, &parent_host) < 0) + goto cleanup; + + /* NOTE: + * We do not save the parent_hoststr in fchost->parent since + * we could be writing out the 'def' to the saved XML config. + * If we wrote out the name in the XML, then future starts would + * always use the same parent rather than finding the "best available" + * parent. Besides we have a way to determine the parent based on + * the 'name' field. + */ + if (!skip_capable_check && !virVHBAPathExists(NULL, parent_host)) { + virReportError(VIR_ERR_XML_ERROR, + _("parent '%s' specified for vHBA does not exist"), + parent_hoststr); + goto cleanup; + } + + if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, + VPORT_CREATE) < 0) + goto cleanup; + + /* Let's ensure the device was created */ + virWaitForDevices(); + if (!(name =3D virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn)))= { + ignore_value(virVHBAManageVport(parent_host, fchost->wwpn, fchost-= >wwnn, + VPORT_DELETE)); + goto cleanup; + } + + cleanup: + VIR_FREE(parent_hoststr); + return name; +} + + +/** + * @conn: Connection pointer + * @fchost: Pointer to vHBA adapter + * + * As long as the vHBA is being managed, search for the scsi_host via the + * provided wwnn/wwpn and then find the corresponding parent scsi_host in + * order to send the delete request. + * + * Returns 0 on success, -1 on failure + */ +int +virNodeDeviceDeleteVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost) +{ + char *name =3D NULL; + char *scsi_host_name =3D NULL; + unsigned int parent_host; + char *vhba_parent =3D NULL; + int ret =3D -1; + + VIR_DEBUG("conn=3D%p parent=3D'%s', managed=3D'%d' wwnn=3D'%s' wwpn=3D= '%s'", + conn, NULLSTR(fchost->parent), fchost->managed, + fchost->wwnn, fchost->wwpn); + + /* If we're not managing the deletion of the vHBA, then just return */ + if (fchost->managed !=3D VIR_TRISTATE_BOOL_YES) + return 0; + + /* Find our vHBA by searching the fc_host sysfs tree for our wwnn/wwpn= */ + if (!(name =3D virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn)))= { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to find fc_host for wwnn=3D'%s' and wwpn= =3D'%s'"), + fchost->wwnn, fchost->wwpn); + goto cleanup; + } + + if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) + goto cleanup; + + /* If at startup time we provided a parent, then use that to + * get the parent_host value; otherwise, we have to determine + * the parent scsi_host which we did not save at startup time + */ + if (fchost->parent) { + /* Someone provided a parent string at startup time that + * was the same as the scsi_host - meaning we have a pool + * backed to an HBA, so there won't be a vHBA to delete */ + if (STREQ(scsi_host_name, fchost->parent)) { + ret =3D 0; + goto cleanup; + } + + if (virSCSIHostGetNumber(fchost->parent, &parent_host) < 0) + goto cleanup; + } else { + if (!(vhba_parent =3D virNodeDeviceGetParentName(conn, scsi_host_n= ame))) + goto cleanup; + + /* If the parent is not a scsi_host, then this is a pool backed + * directly to an HBA and there's no vHBA to remove - so we're don= e */ + if (!STRPREFIX(vhba_parent, "scsi_host")) { + ret =3D 0; + goto cleanup; + } + + if (virSCSIHostGetNumber(vhba_parent, &parent_host) < 0) + goto cleanup; + } + + if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, + VPORT_DELETE) < 0) + goto cleanup; + + ret =3D 0; + + cleanup: + VIR_FREE(name); + VIR_FREE(vhba_parent); + VIR_FREE(scsi_host_name); + return ret; +} diff --git a/src/node_device/node_device_util.h b/src/node_device/node_devi= ce_util.h new file mode 100644 index 0000000000..5cb225d03e --- /dev/null +++ b/src/node_device/node_device_util.h @@ -0,0 +1,35 @@ +/* + * node_device_util.h: utility functions for node device driver + * + * 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_NODE_DEVICE_UTIL_H__ +# define __VIR_NODE_DEVICE_UTIL_H__ + +# include "conf/storage_adapter_conf.h" + +char * +virNodeDeviceGetParentName(virConnectPtr conn, + const char *nodedev_name); + +char * +virNodeDeviceCreateVport(virStorageAdapterFCHostPtr fchost); + +int +virNodeDeviceDeleteVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost); + +#endif /* __VIR_NODE_DEVICE_UTIL_H__ */ diff --git a/src/storage/Makefile.inc.am b/src/storage/Makefile.inc.am index b4400b556f..c1fd8cc7b3 100644 --- a/src/storage/Makefile.inc.am +++ b/src/storage/Makefile.inc.am @@ -221,6 +221,7 @@ if WITH_STORAGE_SCSI libvirt_storage_backend_scsi_la_SOURCES =3D $(STORAGE_DRIVER_SCSI_SOURCES) libvirt_storage_backend_scsi_la_CFLAGS =3D \ -I$(srcdir)/conf \ + -I$(srcdir)/node_device \ $(AM_CFLAGS) \ $(NULL) diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backe= nd_scsi.c index 7c927c4d95..fe3a1e36ac 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -35,6 +35,7 @@ #include "virstring.h" #include "storage_util.h" #include "node_device_conf.h" +#include "node_device_util.h" #include "driver.h" #define VIR_FROM_THIS VIR_FROM_STORAGE -- 2.17.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list