[libvirt] [PATCH] nodedev: Add new module node_device_util

Erik Skultety posted 1 patch 5 years, 5 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/libvirt tags/patchew/f866fc4ebbe7571db09672c44ad9c475286ed252.1541087399.git.eskultet@redhat.com
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
[libvirt] [PATCH] nodedev: Add new module node_device_util
Posted by Erik Skultety 5 years, 5 months ago
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 <eskultet@redhat.com>
---

I verified the build with debian 9, centos 7, fedora 28, rawhide, and freebsd
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 += libvirt_conf.la
 libvirt_conf_la_SOURCES = $(CONF_SOURCES)
 libvirt_conf_la_CFLAGS = \
 	-I$(srcdir)/conf \
+	-I$(srcdir)/node_device \
 	$(AM_CFLAGS) \
 	$(NULL)
 libvirt_conf_la_LDFLAGS = $(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 = NULL;
-    char *parent;
-
-    if (!(device = 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 unmanaged
- * 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 = NULL;
-    char *parent_hoststr = NULL;
-    bool skip_capable_check = false;
-
-    VIR_DEBUG("parent='%s', wwnn='%s' wwpn='%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 = 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 =
-              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 = 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 = 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 = 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 = NULL;
-    char *scsi_host_name = NULL;
-    unsigned int parent_host;
-    char *vhba_parent = NULL;
-    int ret = -1;
-
-    VIR_DEBUG("conn=%p parent='%s', managed='%d' wwnn='%s' wwpn='%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 != VIR_TRISTATE_BOOL_YES)
-        return 0;
-
-    /* Find our vHBA by searching the fc_host sysfs tree for our wwnn/wwpn */
-    if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Failed to find fc_host for wwnn='%s' and wwpn='%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 = 0;
-            goto cleanup;
-        }
-
-        if (virSCSIHostGetNumber(fchost->parent, &parent_host) < 0)
-            goto cleanup;
-    } else {
-        if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name)))
-            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 done */
-        if (!STRPREFIX(vhba_parent, "scsi_host")) {
-            ret = 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 = 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 = \
 	node_device/node_device_driver.h \
 	$(NULL)

+NODE_DEVICE_UTIL_SOURCES = \
+	node_device/node_device_util.h \
+	node_device/node_device_util.c \
+	$(NULL)
+
 NODE_DEVICE_DRIVER_HAL_SOURCES = \
 	node_device/node_device_hal.c \
 	node_device/node_device_hal.h \
@@ -17,6 +22,7 @@ DRIVER_SOURCE_FILES += \
 	$(NODE_DEVICE_DRIVER_SOURCES) \
 	$(NODE_DEVICE_DRIVER_HAL_SOURCES) \
 	$(NODE_DEVICE_DRIVER_UDEV_SOURCES) \
+	$(NODE_DEVICE_UTIL_SOURCES) \
 	$(NULL)

 STATEFUL_DRIVER_SOURCE_FILES += \
@@ -27,13 +33,22 @@ EXTRA_DIST += \
 	$(NODE_DEVICE_DRIVER_SOURCES) \
 	$(NODE_DEVICE_DRIVER_HAL_SOURCES) \
 	$(NODE_DEVICE_DRIVER_UDEV_SOURCES) \
+	$(NODE_DEVICE_UTIL_SOURCES) \
 	$(NULL)

+noinst_LTLIBRARIES += libvirt_nodedev.la
+libvirt_la_BUILT_LIBADD += libvirt_nodedev.la
+libvirt_nodedev_la_CFLAGS = $(AM_CFLAGS)
+libvirt_nodedev_la_LDFLAGS = $(AM_LDFLAGS)
+libvirt_nodedev_la_SOURCES = $(NODE_DEVICE_UTIL_SOURCES)

 if WITH_NODE_DEVICES
 # Needed to keep automake quiet about conditionals
 mod_LTLIBRARIES += libvirt_driver_nodedev.la
-libvirt_driver_nodedev_la_SOURCES = $(NODE_DEVICE_DRIVER_SOURCES)
+libvirt_driver_nodedev_la_SOURCES = \
+	$(NODE_DEVICE_DRIVER_SOURCES) \
+	$(NODE_DEVICE_UTIL_SOURCES) \
+	$(NULL)

 libvirt_driver_nodedev_la_CFLAGS = \
 	-I$(srcdir)/access \
diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_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_device_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
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#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 = NULL;
+    char *parent;
+
+    if (!(device = 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 unmanaged
+ * 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 = NULL;
+    char *parent_hoststr = NULL;
+    bool skip_capable_check = false;
+
+    VIR_DEBUG("parent='%s', wwnn='%s' wwpn='%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 = 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 =
+              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 = 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 = 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 = 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 = NULL;
+    char *scsi_host_name = NULL;
+    unsigned int parent_host;
+    char *vhba_parent = NULL;
+    int ret = -1;
+
+    VIR_DEBUG("conn=%p parent='%s', managed='%d' wwnn='%s' wwpn='%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 != VIR_TRISTATE_BOOL_YES)
+        return 0;
+
+    /* Find our vHBA by searching the fc_host sysfs tree for our wwnn/wwpn */
+    if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Failed to find fc_host for wwnn='%s' and wwpn='%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 = 0;
+            goto cleanup;
+        }
+
+        if (virSCSIHostGetNumber(fchost->parent, &parent_host) < 0)
+            goto cleanup;
+    } else {
+        if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name)))
+            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 done */
+        if (!STRPREFIX(vhba_parent, "scsi_host")) {
+            ret = 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 = 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_device_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
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#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 = $(STORAGE_DRIVER_SCSI_SOURCES)
 libvirt_storage_backend_scsi_la_CFLAGS = \
 	-I$(srcdir)/conf \
+	-I$(srcdir)/node_device \
 	$(AM_CFLAGS) \
 	$(NULL)

diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_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
Re: [libvirt] [PATCH] nodedev: Add new module node_device_util
Posted by Michal Privoznik 5 years, 5 months ago
On 11/01/2018 04:50 PM, Erik Skultety wrote:
> 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 <eskultet@redhat.com>
> ---
> 
> I verified the build with debian 9, centos 7, fedora 28, rawhide, and freebsd
> 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 += libvirt_conf.la
>  libvirt_conf_la_SOURCES = $(CONF_SOURCES)
>  libvirt_conf_la_CFLAGS = \
>  	-I$(srcdir)/conf \
> +	-I$(srcdir)/node_device \

This doesn't feel right. The conf parser/formatter should be driver
agnostic.

I see two options. If you want to clean up src/conf/node_device_conf.c
either you'll put node_device_util.c into src/conf/ right next to
node_device_conf.c or you move it into src/util/ because conf module can
use util.

The rest looks good.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list