Move all the NodeDeviceObj API's into their own module virnodedeviceobj
from the node_device_conf
Purely code motion at this point, plus adjustments to cleanly build.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
po/POTFILES.in | 1 +
src/Makefile.am | 3 +-
src/conf/node_device_conf.c | 505 --------------------------------
src/conf/node_device_conf.h | 50 ----
src/conf/virnodedeviceobj.c | 542 +++++++++++++++++++++++++++++++++++
src/conf/virnodedeviceobj.h | 78 +++++
src/libvirt_private.syms | 23 +-
src/node_device/node_device_driver.h | 2 +-
src/test/test_driver.c | 1 +
9 files changed, 638 insertions(+), 567 deletions(-)
create mode 100644 src/conf/virnodedeviceobj.c
create mode 100644 src/conf/virnodedeviceobj.h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9f66697..7c7f530 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -42,6 +42,7 @@ src/conf/snapshot_conf.c
src/conf/storage_conf.c
src/conf/virchrdev.c
src/conf/virdomainobjlist.c
+src/conf/virnodedeviceobj.c
src/conf/virsecretobj.c
src/cpu/cpu.c
src/cpu/cpu_arm.c
diff --git a/src/Makefile.am b/src/Makefile.am
index a85cd0d..7d42eac 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -390,7 +390,8 @@ SECRET_CONF_SOURCES = \
# Network driver generic impl APIs
NODE_DEVICE_CONF_SOURCES = \
- conf/node_device_conf.c conf/node_device_conf.h
+ conf/node_device_conf.c conf/node_device_conf.h \
+ conf/virnodedeviceobj.c conf/virnodedeviceobj.h
CPU_CONF_SOURCES = \
conf/cpu_conf.c conf/cpu_conf.h
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index 43e23fc..bc36527 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -85,170 +85,6 @@ virNodeDevCapsDefParseString(const char *xpath,
return 0;
}
-int virNodeDeviceHasCap(const virNodeDeviceObj *dev, const char *cap)
-{
- virNodeDevCapsDefPtr caps = dev->def->caps;
- const char *fc_host_cap =
- virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_FC_HOST);
- const char *vports_cap =
- virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS);
-
- while (caps) {
- if (STREQ(cap, virNodeDevCapTypeToString(caps->data.type)))
- return 1;
- else if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST)
- if ((STREQ(cap, fc_host_cap) &&
- (caps->data.scsi_host.flags &
- VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST)) ||
- (STREQ(cap, vports_cap) &&
- (caps->data.scsi_host.flags &
- VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS)))
- return 1;
- caps = caps->next;
- }
- return 0;
-}
-
-
-/* virNodeDeviceFindFCCapDef:
- * @dev: Pointer to current device
- *
- * Search the device object 'caps' array for fc_host capability.
- *
- * Returns:
- * Pointer to the caps or NULL if not found
- */
-static virNodeDevCapsDefPtr
-virNodeDeviceFindFCCapDef(const virNodeDeviceObj *dev)
-{
- virNodeDevCapsDefPtr caps = dev->def->caps;
-
- while (caps) {
- if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST &&
- (caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST))
- break;
-
- caps = caps->next;
- }
- return caps;
-}
-
-
-/* virNodeDeviceFindVPORTCapDef:
- * @dev: Pointer to current device
- *
- * Search the device object 'caps' array for vport_ops capability.
- *
- * Returns:
- * Pointer to the caps or NULL if not found
- */
-static virNodeDevCapsDefPtr
-virNodeDeviceFindVPORTCapDef(const virNodeDeviceObj *dev)
-{
- virNodeDevCapsDefPtr caps = dev->def->caps;
-
- while (caps) {
- if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST &&
- (caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS))
- break;
-
- caps = caps->next;
- }
- return caps;
-}
-
-
-virNodeDeviceObjPtr
-virNodeDeviceFindBySysfsPath(virNodeDeviceObjListPtr devs,
- const char *sysfs_path)
-{
- size_t i;
-
- for (i = 0; i < devs->count; i++) {
- virNodeDeviceObjLock(devs->objs[i]);
- if ((devs->objs[i]->def->sysfs_path != NULL) &&
- (STREQ(devs->objs[i]->def->sysfs_path, sysfs_path))) {
- return devs->objs[i];
- }
- virNodeDeviceObjUnlock(devs->objs[i]);
- }
-
- return NULL;
-}
-
-
-virNodeDeviceObjPtr virNodeDeviceFindByName(virNodeDeviceObjListPtr devs,
- const char *name)
-{
- size_t i;
-
- for (i = 0; i < devs->count; i++) {
- virNodeDeviceObjLock(devs->objs[i]);
- if (STREQ(devs->objs[i]->def->name, name))
- return devs->objs[i];
- virNodeDeviceObjUnlock(devs->objs[i]);
- }
-
- return NULL;
-}
-
-
-static virNodeDeviceObjPtr
-virNodeDeviceFindByWWNs(virNodeDeviceObjListPtr devs,
- const char *parent_wwnn,
- const char *parent_wwpn)
-{
- size_t i;
-
- for (i = 0; i < devs->count; i++) {
- virNodeDevCapsDefPtr cap;
- virNodeDeviceObjLock(devs->objs[i]);
- if ((cap = virNodeDeviceFindFCCapDef(devs->objs[i])) &&
- STREQ_NULLABLE(cap->data.scsi_host.wwnn, parent_wwnn) &&
- STREQ_NULLABLE(cap->data.scsi_host.wwpn, parent_wwpn))
- return devs->objs[i];
- virNodeDeviceObjUnlock(devs->objs[i]);
- }
-
- return NULL;
-}
-
-
-static virNodeDeviceObjPtr
-virNodeDeviceFindByFabricWWN(virNodeDeviceObjListPtr devs,
- const char *parent_fabric_wwn)
-{
- size_t i;
-
- for (i = 0; i < devs->count; i++) {
- virNodeDevCapsDefPtr cap;
- virNodeDeviceObjLock(devs->objs[i]);
- if ((cap = virNodeDeviceFindFCCapDef(devs->objs[i])) &&
- STREQ_NULLABLE(cap->data.scsi_host.fabric_wwn, parent_fabric_wwn))
- return devs->objs[i];
- virNodeDeviceObjUnlock(devs->objs[i]);
- }
-
- return NULL;
-}
-
-
-static virNodeDeviceObjPtr
-virNodeDeviceFindByCap(virNodeDeviceObjListPtr devs,
- const char *cap)
-{
- size_t i;
-
- for (i = 0; i < devs->count; i++) {
- virNodeDeviceObjLock(devs->objs[i]);
- if (virNodeDeviceHasCap(devs->objs[i], cap))
- return devs->objs[i];
- virNodeDeviceObjUnlock(devs->objs[i]);
- }
-
- return NULL;
-}
-
void virNodeDeviceDefFree(virNodeDeviceDefPtr def)
{
@@ -278,82 +114,6 @@ void virNodeDeviceDefFree(virNodeDeviceDefPtr def)
VIR_FREE(def);
}
-void virNodeDeviceObjFree(virNodeDeviceObjPtr dev)
-{
- if (!dev)
- return;
-
- virNodeDeviceDefFree(dev->def);
- if (dev->privateFree)
- (*dev->privateFree)(dev->privateData);
-
- virMutexDestroy(&dev->lock);
-
- VIR_FREE(dev);
-}
-
-void virNodeDeviceObjListFree(virNodeDeviceObjListPtr devs)
-{
- size_t i;
- for (i = 0; i < devs->count; i++)
- virNodeDeviceObjFree(devs->objs[i]);
- VIR_FREE(devs->objs);
- devs->count = 0;
-}
-
-virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDeviceObjListPtr devs,
- virNodeDeviceDefPtr def)
-{
- virNodeDeviceObjPtr device;
-
- if ((device = virNodeDeviceFindByName(devs, def->name))) {
- virNodeDeviceDefFree(device->def);
- device->def = def;
- return device;
- }
-
- if (VIR_ALLOC(device) < 0)
- return NULL;
-
- if (virMutexInit(&device->lock) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("cannot initialize mutex"));
- VIR_FREE(device);
- return NULL;
- }
- virNodeDeviceObjLock(device);
-
- if (VIR_APPEND_ELEMENT_COPY(devs->objs, devs->count, device) < 0) {
- virNodeDeviceObjUnlock(device);
- virNodeDeviceObjFree(device);
- return NULL;
- }
- device->def = def;
-
- return device;
-
-}
-
-void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs,
- virNodeDeviceObjPtr *dev)
-{
- size_t i;
-
- virNodeDeviceObjUnlock(*dev);
-
- for (i = 0; i < devs->count; i++) {
- virNodeDeviceObjLock(*dev);
- if (devs->objs[i] == *dev) {
- virNodeDeviceObjUnlock(*dev);
- virNodeDeviceObjFree(devs->objs[i]);
- *dev = NULL;
-
- VIR_DELETE_ELEMENT(devs->objs, i, devs->count);
- break;
- }
- virNodeDeviceObjUnlock(*dev);
- }
-}
static void
virPCIELinkFormat(virBufferPtr buf,
@@ -1976,152 +1736,6 @@ virNodeDeviceGetWWNs(virNodeDeviceDefPtr def,
return ret;
}
-/*
- * Return the NPIV dev's parent device name
- */
-/* virNodeDeviceFindFCParentHost:
- * @parent: Pointer to node device object
- *
- * Search the capabilities for the device to find the FC capabilities
- * in order to set the parent_host value.
- *
- * Returns:
- * parent_host value on success (>= 0), -1 otherwise.
- */
-static int
-virNodeDeviceFindFCParentHost(virNodeDeviceObjPtr parent)
-{
- virNodeDevCapsDefPtr cap = virNodeDeviceFindVPORTCapDef(parent);
-
- if (!cap) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Parent device %s is not capable "
- "of vport operations"),
- parent->def->name);
- return -1;
- }
-
- return cap->data.scsi_host.host;
-}
-
-
-static int
-virNodeDeviceGetParentHostByParent(virNodeDeviceObjListPtr devs,
- const char *dev_name,
- const char *parent_name)
-{
- virNodeDeviceObjPtr parent = NULL;
- int ret;
-
- if (!(parent = virNodeDeviceFindByName(devs, parent_name))) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Could not find parent device for '%s'"),
- dev_name);
- return -1;
- }
-
- ret = virNodeDeviceFindFCParentHost(parent);
-
- virNodeDeviceObjUnlock(parent);
-
- return ret;
-}
-
-
-static int
-virNodeDeviceGetParentHostByWWNs(virNodeDeviceObjListPtr devs,
- const char *dev_name,
- const char *parent_wwnn,
- const char *parent_wwpn)
-{
- virNodeDeviceObjPtr parent = NULL;
- int ret;
-
- if (!(parent = virNodeDeviceFindByWWNs(devs, parent_wwnn, parent_wwpn))) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Could not find parent device for '%s'"),
- dev_name);
- return -1;
- }
-
- ret = virNodeDeviceFindFCParentHost(parent);
-
- virNodeDeviceObjUnlock(parent);
-
- return ret;
-}
-
-
-static int
-virNodeDeviceGetParentHostByFabricWWN(virNodeDeviceObjListPtr devs,
- const char *dev_name,
- const char *parent_fabric_wwn)
-{
- virNodeDeviceObjPtr parent = NULL;
- int ret;
-
- if (!(parent = virNodeDeviceFindByFabricWWN(devs, parent_fabric_wwn))) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Could not find parent device for '%s'"),
- dev_name);
- return -1;
- }
-
- ret = virNodeDeviceFindFCParentHost(parent);
-
- virNodeDeviceObjUnlock(parent);
-
- return ret;
-}
-
-
-static int
-virNodeDeviceFindVportParentHost(virNodeDeviceObjListPtr devs)
-{
- virNodeDeviceObjPtr parent = NULL;
- const char *cap = virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS);
- int ret;
-
- if (!(parent = virNodeDeviceFindByCap(devs, cap))) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not find any vport capable device"));
- return -1;
- }
-
- ret = virNodeDeviceFindFCParentHost(parent);
-
- virNodeDeviceObjUnlock(parent);
-
- return ret;
-}
-
-
-int
-virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs,
- virNodeDeviceDefPtr def,
- int create)
-{
- int parent_host = -1;
-
- if (def->parent) {
- parent_host = virNodeDeviceGetParentHostByParent(devs, def->name,
- def->parent);
- } else if (def->parent_wwnn && def->parent_wwpn) {
- parent_host = virNodeDeviceGetParentHostByWWNs(devs, def->name,
- def->parent_wwnn,
- def->parent_wwpn);
- } else if (def->parent_fabric_wwn) {
- parent_host =
- virNodeDeviceGetParentHostByFabricWWN(devs, def->name,
- def->parent_fabric_wwn);
- } else if (create == CREATE_DEVICE) {
- /* Try to find a vport capable scsi_host when no parent supplied */
- parent_host = virNodeDeviceFindVportParentHost(devs);
- }
-
- return parent_host;
-}
-
void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
{
@@ -2198,125 +1812,6 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
}
-void virNodeDeviceObjLock(virNodeDeviceObjPtr obj)
-{
- virMutexLock(&obj->lock);
-}
-
-void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj)
-{
- virMutexUnlock(&obj->lock);
-}
-
-static bool
-virNodeDeviceCapMatch(virNodeDeviceObjPtr devobj,
- int type)
-{
- virNodeDevCapsDefPtr cap = NULL;
-
- for (cap = devobj->def->caps; cap; cap = cap->next) {
- if (type == cap->data.type)
- return true;
-
- if (cap->data.type == VIR_NODE_DEV_CAP_SCSI_HOST) {
- if (type == VIR_NODE_DEV_CAP_FC_HOST &&
- (cap->data.scsi_host.flags &
- VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST))
- return true;
-
- if (type == VIR_NODE_DEV_CAP_VPORTS &&
- (cap->data.scsi_host.flags &
- VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS))
- return true;
- }
- }
-
- return false;
-}
-
-#define MATCH(FLAG) ((flags & (VIR_CONNECT_LIST_NODE_DEVICES_CAP_ ## FLAG))
&& \
- virNodeDeviceCapMatch(devobj, VIR_NODE_DEV_CAP_ ## FLAG))
-static bool
-virNodeDeviceMatch(virNodeDeviceObjPtr devobj,
- unsigned int flags)
-{
- /* filter by cap type */
- if (flags & VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_CAP) {
- if (!(MATCH(SYSTEM) ||
- MATCH(PCI_DEV) ||
- MATCH(USB_DEV) ||
- MATCH(USB_INTERFACE) ||
- MATCH(NET) ||
- MATCH(SCSI_HOST) ||
- MATCH(SCSI_TARGET) ||
- MATCH(SCSI) ||
- MATCH(STORAGE) ||
- MATCH(FC_HOST) ||
- MATCH(VPORTS) ||
- MATCH(SCSI_GENERIC) ||
- MATCH(DRM)))
- return false;
- }
-
- return true;
-}
-#undef MATCH
-
-int
-virNodeDeviceObjListExport(virConnectPtr conn,
- virNodeDeviceObjList devobjs,
- virNodeDevicePtr **devices,
- virNodeDeviceObjListFilter filter,
- unsigned int flags)
-{
- virNodeDevicePtr *tmp_devices = NULL;
- virNodeDevicePtr device = NULL;
- int ndevices = 0;
- int ret = -1;
- size_t i;
-
- if (devices && VIR_ALLOC_N(tmp_devices, devobjs.count + 1) < 0)
- goto cleanup;
-
- for (i = 0; i < devobjs.count; i++) {
- virNodeDeviceObjPtr devobj = devobjs.objs[i];
- virNodeDeviceObjLock(devobj);
- if ((!filter || filter(conn, devobj->def)) &&
- virNodeDeviceMatch(devobj, flags)) {
- if (devices) {
- if (!(device = virGetNodeDevice(conn, devobj->def->name)) ||
- VIR_STRDUP(device->parent, devobj->def->parent) < 0) {
- virObjectUnref(device);
- virNodeDeviceObjUnlock(devobj);
- goto cleanup;
- }
- tmp_devices[ndevices] = device;
- }
- ndevices++;
- }
- virNodeDeviceObjUnlock(devobj);
- }
-
- if (tmp_devices) {
- /* trim the array to the final size */
- ignore_value(VIR_REALLOC_N(tmp_devices, ndevices + 1));
- *devices = tmp_devices;
- tmp_devices = NULL;
- }
-
- ret = ndevices;
-
- cleanup:
- if (tmp_devices) {
- for (i = 0; i < ndevices; i++)
- virObjectUnref(tmp_devices[i]);
- }
-
- VIR_FREE(tmp_devices);
- return ret;
-}
-
-
/* virNodeDeviceGetParentName
* @conn: Connection pointer
* @nodedev_name: Node device to lookup
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
index 8213c27..6c94262 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -28,10 +28,8 @@
# include "internal.h"
# include "virbitmap.h"
# include "virutil.h"
-# include "virthread.h"
# include "virpci.h"
# include "device_conf.h"
-# include "object_event.h"
# include <libxml/tree.h>
@@ -253,34 +251,6 @@ struct _virNodeDeviceObjList {
virNodeDeviceObjPtr *objs;
};
-typedef struct _virNodeDeviceDriverState virNodeDeviceDriverState;
-typedef virNodeDeviceDriverState *virNodeDeviceDriverStatePtr;
-struct _virNodeDeviceDriverState {
- virMutex lock;
-
- virNodeDeviceObjList devs; /* currently-known devices */
- void *privateData; /* driver-specific private data */
-
- /* Immutable pointer, self-locking APIs */
- virObjectEventStatePtr nodeDeviceEventState;
-};
-
-
-int virNodeDeviceHasCap(const virNodeDeviceObj *dev, const char *cap);
-
-virNodeDeviceObjPtr virNodeDeviceFindByName(virNodeDeviceObjListPtr devs,
- const char *name);
-virNodeDeviceObjPtr
-virNodeDeviceFindBySysfsPath(virNodeDeviceObjListPtr devs,
- const char *sysfs_path)
- ATTRIBUTE_NONNULL(2);
-
-virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDeviceObjListPtr devs,
- virNodeDeviceDefPtr def);
-
-void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs,
- virNodeDeviceObjPtr *dev);
-
char *virNodeDeviceDefFormat(const virNodeDeviceDef *def);
virNodeDeviceDefPtr virNodeDeviceDefParseString(const char *str,
@@ -298,21 +268,10 @@ int virNodeDeviceGetWWNs(virNodeDeviceDefPtr def,
char **wwnn,
char **wwpn);
-int virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs,
- virNodeDeviceDefPtr def,
- int create);
-
void virNodeDeviceDefFree(virNodeDeviceDefPtr def);
-void virNodeDeviceObjFree(virNodeDeviceObjPtr dev);
-
-void virNodeDeviceObjListFree(virNodeDeviceObjListPtr devs);
-
void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps);
-void virNodeDeviceObjLock(virNodeDeviceObjPtr obj);
-void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj);
-
# define VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_CAP \
(VIR_CONNECT_LIST_NODE_DEVICES_CAP_SYSTEM | \
VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV | \
@@ -328,15 +287,6 @@ void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj);
VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_GENERIC | \
VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM)
-typedef bool (*virNodeDeviceObjListFilter)(virConnectPtr conn,
- virNodeDeviceDefPtr def);
-
-int virNodeDeviceObjListExport(virConnectPtr conn,
- virNodeDeviceObjList devobjs,
- virNodeDevicePtr **devices,
- virNodeDeviceObjListFilter filter,
- unsigned int flags);
-
char *virNodeDeviceGetParentName(virConnectPtr conn,
const char *nodedev_name);
diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c
new file mode 100644
index 0000000..83f7217
--- /dev/null
+++ b/src/conf/virnodedeviceobj.c
@@ -0,0 +1,542 @@
+/*
+ * virnodedeviceobj.c: node device object handling
+ * (derived from node_device_conf.c)
+ *
+ * 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 "datatypes.h"
+#include "node_device_conf.h"
+
+#include "viralloc.h"
+#include "virnodedeviceobj.h"
+#include "virerror.h"
+#include "virlog.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_NODEDEV
+
+VIR_LOG_INIT("conf.virnodedeviceobj");
+
+
+int virNodeDeviceHasCap(const virNodeDeviceObj *dev, const char *cap)
+{
+ virNodeDevCapsDefPtr caps = dev->def->caps;
+ const char *fc_host_cap =
+ virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_FC_HOST);
+ const char *vports_cap =
+ virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS);
+
+ while (caps) {
+ if (STREQ(cap, virNodeDevCapTypeToString(caps->data.type)))
+ return 1;
+ else if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST)
+ if ((STREQ(cap, fc_host_cap) &&
+ (caps->data.scsi_host.flags &
+ VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST)) ||
+ (STREQ(cap, vports_cap) &&
+ (caps->data.scsi_host.flags &
+ VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS)))
+ return 1;
+ caps = caps->next;
+ }
+ return 0;
+}
+
+
+/* virNodeDeviceFindFCCapDef:
+ * @dev: Pointer to current device
+ *
+ * Search the device object 'caps' array for fc_host capability.
+ *
+ * Returns:
+ * Pointer to the caps or NULL if not found
+ */
+static virNodeDevCapsDefPtr
+virNodeDeviceFindFCCapDef(const virNodeDeviceObj *dev)
+{
+ virNodeDevCapsDefPtr caps = dev->def->caps;
+
+ while (caps) {
+ if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST &&
+ (caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST))
+ break;
+
+ caps = caps->next;
+ }
+ return caps;
+}
+
+
+/* virNodeDeviceFindVPORTCapDef:
+ * @dev: Pointer to current device
+ *
+ * Search the device object 'caps' array for vport_ops capability.
+ *
+ * Returns:
+ * Pointer to the caps or NULL if not found
+ */
+static virNodeDevCapsDefPtr
+virNodeDeviceFindVPORTCapDef(const virNodeDeviceObj *dev)
+{
+ virNodeDevCapsDefPtr caps = dev->def->caps;
+
+ while (caps) {
+ if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST &&
+ (caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS))
+ break;
+
+ caps = caps->next;
+ }
+ return caps;
+}
+
+
+virNodeDeviceObjPtr
+virNodeDeviceFindBySysfsPath(virNodeDeviceObjListPtr devs,
+ const char *sysfs_path)
+{
+ size_t i;
+
+ for (i = 0; i < devs->count; i++) {
+ virNodeDeviceObjLock(devs->objs[i]);
+ if ((devs->objs[i]->def->sysfs_path != NULL) &&
+ (STREQ(devs->objs[i]->def->sysfs_path, sysfs_path))) {
+ return devs->objs[i];
+ }
+ virNodeDeviceObjUnlock(devs->objs[i]);
+ }
+
+ return NULL;
+}
+
+
+virNodeDeviceObjPtr virNodeDeviceFindByName(virNodeDeviceObjListPtr devs,
+ const char *name)
+{
+ size_t i;
+
+ for (i = 0; i < devs->count; i++) {
+ virNodeDeviceObjLock(devs->objs[i]);
+ if (STREQ(devs->objs[i]->def->name, name))
+ return devs->objs[i];
+ virNodeDeviceObjUnlock(devs->objs[i]);
+ }
+
+ return NULL;
+}
+
+
+static virNodeDeviceObjPtr
+virNodeDeviceFindByWWNs(virNodeDeviceObjListPtr devs,
+ const char *parent_wwnn,
+ const char *parent_wwpn)
+{
+ size_t i;
+
+ for (i = 0; i < devs->count; i++) {
+ virNodeDevCapsDefPtr cap;
+ virNodeDeviceObjLock(devs->objs[i]);
+ if ((cap = virNodeDeviceFindFCCapDef(devs->objs[i])) &&
+ STREQ_NULLABLE(cap->data.scsi_host.wwnn, parent_wwnn) &&
+ STREQ_NULLABLE(cap->data.scsi_host.wwpn, parent_wwpn))
+ return devs->objs[i];
+ virNodeDeviceObjUnlock(devs->objs[i]);
+ }
+
+ return NULL;
+}
+
+
+static virNodeDeviceObjPtr
+virNodeDeviceFindByFabricWWN(virNodeDeviceObjListPtr devs,
+ const char *parent_fabric_wwn)
+{
+ size_t i;
+
+ for (i = 0; i < devs->count; i++) {
+ virNodeDevCapsDefPtr cap;
+ virNodeDeviceObjLock(devs->objs[i]);
+ if ((cap = virNodeDeviceFindFCCapDef(devs->objs[i])) &&
+ STREQ_NULLABLE(cap->data.scsi_host.fabric_wwn, parent_fabric_wwn))
+ return devs->objs[i];
+ virNodeDeviceObjUnlock(devs->objs[i]);
+ }
+
+ return NULL;
+}
+
+
+static virNodeDeviceObjPtr
+virNodeDeviceFindByCap(virNodeDeviceObjListPtr devs,
+ const char *cap)
+{
+ size_t i;
+
+ for (i = 0; i < devs->count; i++) {
+ virNodeDeviceObjLock(devs->objs[i]);
+ if (virNodeDeviceHasCap(devs->objs[i], cap))
+ return devs->objs[i];
+ virNodeDeviceObjUnlock(devs->objs[i]);
+ }
+
+ return NULL;
+}
+
+
+void virNodeDeviceObjFree(virNodeDeviceObjPtr dev)
+{
+ if (!dev)
+ return;
+
+ virNodeDeviceDefFree(dev->def);
+ if (dev->privateFree)
+ (*dev->privateFree)(dev->privateData);
+
+ virMutexDestroy(&dev->lock);
+
+ VIR_FREE(dev);
+}
+
+void virNodeDeviceObjListFree(virNodeDeviceObjListPtr devs)
+{
+ size_t i;
+ for (i = 0; i < devs->count; i++)
+ virNodeDeviceObjFree(devs->objs[i]);
+ VIR_FREE(devs->objs);
+ devs->count = 0;
+}
+
+virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDeviceObjListPtr devs,
+ virNodeDeviceDefPtr def)
+{
+ virNodeDeviceObjPtr device;
+
+ if ((device = virNodeDeviceFindByName(devs, def->name))) {
+ virNodeDeviceDefFree(device->def);
+ device->def = def;
+ return device;
+ }
+
+ if (VIR_ALLOC(device) < 0)
+ return NULL;
+
+ if (virMutexInit(&device->lock) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cannot initialize mutex"));
+ VIR_FREE(device);
+ return NULL;
+ }
+ virNodeDeviceObjLock(device);
+
+ if (VIR_APPEND_ELEMENT_COPY(devs->objs, devs->count, device) < 0) {
+ virNodeDeviceObjUnlock(device);
+ virNodeDeviceObjFree(device);
+ return NULL;
+ }
+ device->def = def;
+
+ return device;
+
+}
+
+void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs,
+ virNodeDeviceObjPtr *dev)
+{
+ size_t i;
+
+ virNodeDeviceObjUnlock(*dev);
+
+ for (i = 0; i < devs->count; i++) {
+ virNodeDeviceObjLock(*dev);
+ if (devs->objs[i] == *dev) {
+ virNodeDeviceObjUnlock(*dev);
+ virNodeDeviceObjFree(devs->objs[i]);
+ *dev = NULL;
+
+ VIR_DELETE_ELEMENT(devs->objs, i, devs->count);
+ break;
+ }
+ virNodeDeviceObjUnlock(*dev);
+ }
+}
+
+
+/*
+ * Return the NPIV dev's parent device name
+ */
+/* virNodeDeviceFindFCParentHost:
+ * @parent: Pointer to node device object
+ *
+ * Search the capabilities for the device to find the FC capabilities
+ * in order to set the parent_host value.
+ *
+ * Returns:
+ * parent_host value on success (>= 0), -1 otherwise.
+ */
+static int
+virNodeDeviceFindFCParentHost(virNodeDeviceObjPtr parent)
+{
+ virNodeDevCapsDefPtr cap = virNodeDeviceFindVPORTCapDef(parent);
+
+ if (!cap) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Parent device %s is not capable "
+ "of vport operations"),
+ parent->def->name);
+ return -1;
+ }
+
+ return cap->data.scsi_host.host;
+}
+
+
+static int
+virNodeDeviceGetParentHostByParent(virNodeDeviceObjListPtr devs,
+ const char *dev_name,
+ const char *parent_name)
+{
+ virNodeDeviceObjPtr parent = NULL;
+ int ret;
+
+ if (!(parent = virNodeDeviceFindByName(devs, parent_name))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not find parent device for '%s'"),
+ dev_name);
+ return -1;
+ }
+
+ ret = virNodeDeviceFindFCParentHost(parent);
+
+ virNodeDeviceObjUnlock(parent);
+
+ return ret;
+}
+
+
+static int
+virNodeDeviceGetParentHostByWWNs(virNodeDeviceObjListPtr devs,
+ const char *dev_name,
+ const char *parent_wwnn,
+ const char *parent_wwpn)
+{
+ virNodeDeviceObjPtr parent = NULL;
+ int ret;
+
+ if (!(parent = virNodeDeviceFindByWWNs(devs, parent_wwnn, parent_wwpn))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not find parent device for '%s'"),
+ dev_name);
+ return -1;
+ }
+
+ ret = virNodeDeviceFindFCParentHost(parent);
+
+ virNodeDeviceObjUnlock(parent);
+
+ return ret;
+}
+
+
+static int
+virNodeDeviceGetParentHostByFabricWWN(virNodeDeviceObjListPtr devs,
+ const char *dev_name,
+ const char *parent_fabric_wwn)
+{
+ virNodeDeviceObjPtr parent = NULL;
+ int ret;
+
+ if (!(parent = virNodeDeviceFindByFabricWWN(devs, parent_fabric_wwn))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not find parent device for '%s'"),
+ dev_name);
+ return -1;
+ }
+
+ ret = virNodeDeviceFindFCParentHost(parent);
+
+ virNodeDeviceObjUnlock(parent);
+
+ return ret;
+}
+
+
+static int
+virNodeDeviceFindVportParentHost(virNodeDeviceObjListPtr devs)
+{
+ virNodeDeviceObjPtr parent = NULL;
+ const char *cap = virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS);
+ int ret;
+
+ if (!(parent = virNodeDeviceFindByCap(devs, cap))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not find any vport capable device"));
+ return -1;
+ }
+
+ ret = virNodeDeviceFindFCParentHost(parent);
+
+ virNodeDeviceObjUnlock(parent);
+
+ return ret;
+}
+
+
+int
+virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs,
+ virNodeDeviceDefPtr def,
+ int create)
+{
+ int parent_host = -1;
+
+ if (def->parent) {
+ parent_host = virNodeDeviceGetParentHostByParent(devs, def->name,
+ def->parent);
+ } else if (def->parent_wwnn && def->parent_wwpn) {
+ parent_host = virNodeDeviceGetParentHostByWWNs(devs, def->name,
+ def->parent_wwnn,
+ def->parent_wwpn);
+ } else if (def->parent_fabric_wwn) {
+ parent_host =
+ virNodeDeviceGetParentHostByFabricWWN(devs, def->name,
+ def->parent_fabric_wwn);
+ } else if (create == CREATE_DEVICE) {
+ /* Try to find a vport capable scsi_host when no parent supplied */
+ parent_host = virNodeDeviceFindVportParentHost(devs);
+ }
+
+ return parent_host;
+}
+
+
+void virNodeDeviceObjLock(virNodeDeviceObjPtr obj)
+{
+ virMutexLock(&obj->lock);
+}
+
+void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj)
+{
+ virMutexUnlock(&obj->lock);
+}
+
+static bool
+virNodeDeviceCapMatch(virNodeDeviceObjPtr devobj,
+ int type)
+{
+ virNodeDevCapsDefPtr cap = NULL;
+
+ for (cap = devobj->def->caps; cap; cap = cap->next) {
+ if (type == cap->data.type)
+ return true;
+
+ if (cap->data.type == VIR_NODE_DEV_CAP_SCSI_HOST) {
+ if (type == VIR_NODE_DEV_CAP_FC_HOST &&
+ (cap->data.scsi_host.flags &
+ VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST))
+ return true;
+
+ if (type == VIR_NODE_DEV_CAP_VPORTS &&
+ (cap->data.scsi_host.flags &
+ VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#define MATCH(FLAG) ((flags & (VIR_CONNECT_LIST_NODE_DEVICES_CAP_ ## FLAG))
&& \
+ virNodeDeviceCapMatch(devobj, VIR_NODE_DEV_CAP_ ## FLAG))
+static bool
+virNodeDeviceMatch(virNodeDeviceObjPtr devobj,
+ unsigned int flags)
+{
+ /* filter by cap type */
+ if (flags & VIR_CONNECT_LIST_NODE_DEVICES_FILTERS_CAP) {
+ if (!(MATCH(SYSTEM) ||
+ MATCH(PCI_DEV) ||
+ MATCH(USB_DEV) ||
+ MATCH(USB_INTERFACE) ||
+ MATCH(NET) ||
+ MATCH(SCSI_HOST) ||
+ MATCH(SCSI_TARGET) ||
+ MATCH(SCSI) ||
+ MATCH(STORAGE) ||
+ MATCH(FC_HOST) ||
+ MATCH(VPORTS) ||
+ MATCH(SCSI_GENERIC) ||
+ MATCH(DRM)))
+ return false;
+ }
+
+ return true;
+}
+#undef MATCH
+
+int
+virNodeDeviceObjListExport(virConnectPtr conn,
+ virNodeDeviceObjList devobjs,
+ virNodeDevicePtr **devices,
+ virNodeDeviceObjListFilter filter,
+ unsigned int flags)
+{
+ virNodeDevicePtr *tmp_devices = NULL;
+ virNodeDevicePtr device = NULL;
+ int ndevices = 0;
+ int ret = -1;
+ size_t i;
+
+ if (devices && VIR_ALLOC_N(tmp_devices, devobjs.count + 1) < 0)
+ goto cleanup;
+
+ for (i = 0; i < devobjs.count; i++) {
+ virNodeDeviceObjPtr devobj = devobjs.objs[i];
+ virNodeDeviceObjLock(devobj);
+ if ((!filter || filter(conn, devobj->def)) &&
+ virNodeDeviceMatch(devobj, flags)) {
+ if (devices) {
+ if (!(device = virGetNodeDevice(conn, devobj->def->name)) ||
+ VIR_STRDUP(device->parent, devobj->def->parent) < 0) {
+ virObjectUnref(device);
+ virNodeDeviceObjUnlock(devobj);
+ goto cleanup;
+ }
+ tmp_devices[ndevices] = device;
+ }
+ ndevices++;
+ }
+ virNodeDeviceObjUnlock(devobj);
+ }
+
+ if (tmp_devices) {
+ /* trim the array to the final size */
+ ignore_value(VIR_REALLOC_N(tmp_devices, ndevices + 1));
+ *devices = tmp_devices;
+ tmp_devices = NULL;
+ }
+
+ ret = ndevices;
+
+ cleanup:
+ if (tmp_devices) {
+ for (i = 0; i < ndevices; i++)
+ virObjectUnref(tmp_devices[i]);
+ }
+
+ VIR_FREE(tmp_devices);
+ return ret;
+}
diff --git a/src/conf/virnodedeviceobj.h b/src/conf/virnodedeviceobj.h
new file mode 100644
index 0000000..6ad7fb1
--- /dev/null
+++ b/src/conf/virnodedeviceobj.h
@@ -0,0 +1,78 @@
+/*
+ * virnodedeviceobj.h: node device object handling for node devices
+ * (derived from node_device_conf.h)
+ *
+ * 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 __VIRNODEDEVICEOBJ_H__
+# define __VIRNODEDEVICEOBJ_H__
+
+# include "internal.h"
+# include "virthread.h"
+
+# include "node_device_conf.h"
+# include "object_event.h"
+
+
+typedef struct _virNodeDeviceDriverState virNodeDeviceDriverState;
+typedef virNodeDeviceDriverState *virNodeDeviceDriverStatePtr;
+struct _virNodeDeviceDriverState {
+ virMutex lock;
+
+ virNodeDeviceObjList devs; /* currently-known devices */
+ void *privateData; /* driver-specific private data */
+
+ /* Immutable pointer, self-locking APIs */
+ virObjectEventStatePtr nodeDeviceEventState;
+};
+
+
+int virNodeDeviceHasCap(const virNodeDeviceObj *dev, const char *cap);
+
+virNodeDeviceObjPtr virNodeDeviceFindByName(virNodeDeviceObjListPtr devs,
+ const char *name);
+virNodeDeviceObjPtr
+virNodeDeviceFindBySysfsPath(virNodeDeviceObjListPtr devs,
+ const char *sysfs_path)
+ ATTRIBUTE_NONNULL(2);
+
+virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDeviceObjListPtr devs,
+ virNodeDeviceDefPtr def);
+
+void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs,
+ virNodeDeviceObjPtr *dev);
+
+int virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs,
+ virNodeDeviceDefPtr def,
+ int create);
+
+void virNodeDeviceObjFree(virNodeDeviceObjPtr dev);
+
+void virNodeDeviceObjListFree(virNodeDeviceObjListPtr devs);
+
+void virNodeDeviceObjLock(virNodeDeviceObjPtr obj);
+void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj);
+
+typedef bool (*virNodeDeviceObjListFilter)(virConnectPtr conn,
+ virNodeDeviceDefPtr def);
+
+int virNodeDeviceObjListExport(virConnectPtr conn,
+ virNodeDeviceObjList devobjs,
+ virNodeDevicePtr **devices,
+ virNodeDeviceObjListFilter filter,
+ unsigned int flags);
+
+#endif /* __VIRNODEDEVICEOBJ_H__ */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index bce0487..8639979 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -694,23 +694,13 @@ virNetDevIPRouteParseXML;
virNodeDevCapsDefFree;
virNodeDevCapTypeFromString;
virNodeDevCapTypeToString;
-virNodeDeviceAssignDef;
virNodeDeviceDefFormat;
virNodeDeviceDefFree;
virNodeDeviceDefParseFile;
virNodeDeviceDefParseNode;
virNodeDeviceDefParseString;
-virNodeDeviceFindByName;
-virNodeDeviceFindBySysfsPath;
-virNodeDeviceGetParentHost;
virNodeDeviceGetParentName;
virNodeDeviceGetWWNs;
-virNodeDeviceHasCap;
-virNodeDeviceObjListExport;
-virNodeDeviceObjListFree;
-virNodeDeviceObjLock;
-virNodeDeviceObjRemove;
-virNodeDeviceObjUnlock;
# conf/node_device_event.h
@@ -958,6 +948,19 @@ virDomainObjListRemoveLocked;
virDomainObjListRename;
+# conf/virnodedeviceobj.h
+virNodeDeviceAssignDef;
+virNodeDeviceFindByName;
+virNodeDeviceFindBySysfsPath;
+virNodeDeviceGetParentHost;
+virNodeDeviceHasCap;
+virNodeDeviceObjListExport;
+virNodeDeviceObjListFree;
+virNodeDeviceObjLock;
+virNodeDeviceObjRemove;
+virNodeDeviceObjUnlock;
+
+
# conf/virsecretobj.h
virSecretLoadAllConfigs;
virSecretObjDeleteConfig;
diff --git a/src/node_device/node_device_driver.h b/src/node_device/node_device_driver.h
index 56f89ab..bc8af8a 100644
--- a/src/node_device/node_device_driver.h
+++ b/src/node_device/node_device_driver.h
@@ -26,7 +26,7 @@
# include "internal.h"
# include "driver.h"
-# include "node_device_conf.h"
+# include "virnodedeviceobj.h"
# define LINUX_NEW_DEVICE_WAIT_TIME 60
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 314f08c..c6214c6 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -51,6 +51,7 @@
#include "storage_conf.h"
#include "storage_event.h"
#include "node_device_conf.h"
+#include "virnodedeviceobj.h"
#include "node_device_event.h"
#include "virxml.h"
#include "virthread.h"
--
2.9.3