[PATCH v2] conf: Add new module node_device_util

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



There's a lot of stuff going on in src/conf/nodedev_conf which is
sometimes not directly related to config and we're not really consistent
with putting only parser/formatter related stuff here, e.g. like we do
for domains. So, let's start simply by adding a new module
node_device_util containing some of the helpers. Unfortunately, even
though these helpers tend to open a secondary driver connection and would
be much therefore better suited as a nodedev driver module, we can't do
that without pulling headers from the driver into conf/ and that's wrong
because we want conf/ to stay driver-agnostic.

Signed-off-by: Erik Skultety <eskultet@xxxxxxxxxx>
---
 src/conf/Makefile.inc.am             |   2 +
 src/conf/node_device_conf.c          | 199 -----------------------
 src/conf/node_device_conf.h          |  11 --
 src/conf/node_device_util.c          | 229 +++++++++++++++++++++++++++
 src/conf/node_device_util.h          |  35 ++++
 src/conf/virstorageobj.c             |   1 +
 src/libvirt_private.syms             |   7 +-
 src/node_device/node_device_driver.c |   1 +
 src/storage/storage_backend_scsi.c   |   1 +
 9 files changed, 273 insertions(+), 213 deletions(-)
 create mode 100644 src/conf/node_device_util.c
 create mode 100644 src/conf/node_device_util.h

diff --git a/src/conf/Makefile.inc.am b/src/conf/Makefile.inc.am
index af23810640..219ff350d7 100644
--- a/src/conf/Makefile.inc.am
+++ b/src/conf/Makefile.inc.am
@@ -119,6 +119,8 @@ SECRET_CONF_SOURCES = \
 NODE_DEVICE_CONF_SOURCES = \
 	conf/node_device_conf.c \
 	conf/node_device_conf.h \
+	conf/node_device_util.c \
+	conf/node_device_util.h \
 	conf/virnodedeviceobj.c \
 	conf/virnodedeviceobj.h \
 	$(NULL)
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/node_device_util.c b/src/conf/node_device_util.c
new file mode 100644
index 0000000000..d1d9c3ee49
--- /dev/null
+++ b/src/conf/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/conf/node_device_util.h b/src/conf/node_device_util.h
new file mode 100644
index 0000000000..5cb225d03e
--- /dev/null
+++ b/src/conf/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/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..2343a757c1 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;
@@ -742,6 +739,10 @@ virNodeDeviceEventLifecycleNew;
 virNodeDeviceEventStateRegisterID;
 virNodeDeviceEventUpdateNew;

+# conf/node_device_util.h
+virNodeDeviceCreateVport;
+virNodeDeviceDeleteVport;
+virNodeDeviceGetParentName;

 # conf/numa_conf.h
 virDomainMemoryAccessTypeFromString;
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/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.19.1

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



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux