From nobody Sun Feb 8 23:04:05 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.39 as permitted sender) client-ip=209.132.183.39; envelope-from=libvir-list-bounces@redhat.com; helo=mx6-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.39 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx6-phx2.redhat.com (mx6-phx2.redhat.com [209.132.183.39]) by mx.zohomail.com with SMTPS id 148841466922044.80938654172746; Wed, 1 Mar 2017 16:31:09 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx6-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v220RKKK005768; Wed, 1 Mar 2017 19:27:21 -0500 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v220RJsI009998 for ; Wed, 1 Mar 2017 19:27:19 -0500 Received: by smtp.corp.redhat.com (Postfix) id E4C4872380; Thu, 2 Mar 2017 00:27:19 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-116-78.phx2.redhat.com [10.3.116.78]) by smtp.corp.redhat.com (Postfix) with ESMTP id 777D82D655 for ; Thu, 2 Mar 2017 00:27:19 +0000 (UTC) From: John Ferlan To: libvir-list@redhat.com Date: Wed, 1 Mar 2017 19:27:14 -0500 Message-Id: <20170302002716.21337-2-jferlan@redhat.com> In-Reply-To: <20170302002716.21337-1-jferlan@redhat.com> References: <20170302002716.21337-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 1/3] conf: Introduce virnodedeviceobj 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-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" 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 --- 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 =3D = \ =20 # Network driver generic impl APIs NODE_DEVICE_CONF_SOURCES =3D \ - 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 =20 CPU_CONF_SOURCES =3D \ 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; } =20 -int virNodeDeviceHasCap(const virNodeDeviceObj *dev, const char *cap) -{ - virNodeDevCapsDefPtr caps =3D dev->def->caps; - const char *fc_host_cap =3D - virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_FC_HOST); - const char *vports_cap =3D - virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS); - - while (caps) { - if (STREQ(cap, virNodeDevCapTypeToString(caps->data.type))) - return 1; - else if (caps->data.type =3D=3D 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 =3D 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 =3D dev->def->caps; - - while (caps) { - if (caps->data.type =3D=3D VIR_NODE_DEV_CAP_SCSI_HOST && - (caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOS= T)) - break; - - caps =3D 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 =3D dev->def->caps; - - while (caps) { - if (caps->data.type =3D=3D VIR_NODE_DEV_CAP_SCSI_HOST && - (caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_= OPS)) - break; - - caps =3D caps->next; - } - return caps; -} - - -virNodeDeviceObjPtr -virNodeDeviceFindBySysfsPath(virNodeDeviceObjListPtr devs, - const char *sysfs_path) -{ - size_t i; - - for (i =3D 0; i < devs->count; i++) { - virNodeDeviceObjLock(devs->objs[i]); - if ((devs->objs[i]->def->sysfs_path !=3D 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 =3D 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 =3D 0; i < devs->count; i++) { - virNodeDevCapsDefPtr cap; - virNodeDeviceObjLock(devs->objs[i]); - if ((cap =3D 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 =3D 0; i < devs->count; i++) { - virNodeDevCapsDefPtr cap; - virNodeDeviceObjLock(devs->objs[i]); - if ((cap =3D virNodeDeviceFindFCCapDef(devs->objs[i])) && - STREQ_NULLABLE(cap->data.scsi_host.fabric_wwn, parent_fabric_w= wn)) - return devs->objs[i]; - virNodeDeviceObjUnlock(devs->objs[i]); - } - - return NULL; -} - - -static virNodeDeviceObjPtr -virNodeDeviceFindByCap(virNodeDeviceObjListPtr devs, - const char *cap) -{ - size_t i; - - for (i =3D 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; -} - =20 void virNodeDeviceDefFree(virNodeDeviceDefPtr def) { @@ -278,82 +114,6 @@ void virNodeDeviceDefFree(virNodeDeviceDefPtr def) VIR_FREE(def); } =20 -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 =3D 0; i < devs->count; i++) - virNodeDeviceObjFree(devs->objs[i]); - VIR_FREE(devs->objs); - devs->count =3D 0; -} - -virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDeviceObjListPtr devs, - virNodeDeviceDefPtr def) -{ - virNodeDeviceObjPtr device; - - if ((device =3D virNodeDeviceFindByName(devs, def->name))) { - virNodeDeviceDefFree(device->def); - device->def =3D 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 =3D def; - - return device; - -} - -void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs, - virNodeDeviceObjPtr *dev) -{ - size_t i; - - virNodeDeviceObjUnlock(*dev); - - for (i =3D 0; i < devs->count; i++) { - virNodeDeviceObjLock(*dev); - if (devs->objs[i] =3D=3D *dev) { - virNodeDeviceObjUnlock(*dev); - virNodeDeviceObjFree(devs->objs[i]); - *dev =3D NULL; - - VIR_DELETE_ELEMENT(devs->objs, i, devs->count); - break; - } - virNodeDeviceObjUnlock(*dev); - } -} =20 static void virPCIELinkFormat(virBufferPtr buf, @@ -1976,152 +1736,6 @@ virNodeDeviceGetWWNs(virNodeDeviceDefPtr def, return ret; } =20 -/* - * 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 (>=3D 0), -1 otherwise. - */ -static int -virNodeDeviceFindFCParentHost(virNodeDeviceObjPtr parent) -{ - virNodeDevCapsDefPtr cap =3D 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 =3D NULL; - int ret; - - if (!(parent =3D virNodeDeviceFindByName(devs, parent_name))) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not find parent device for '%s'"), - dev_name); - return -1; - } - - ret =3D 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 =3D NULL; - int ret; - - if (!(parent =3D virNodeDeviceFindByWWNs(devs, parent_wwnn, parent_wwp= n))) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not find parent device for '%s'"), - dev_name); - return -1; - } - - ret =3D virNodeDeviceFindFCParentHost(parent); - - virNodeDeviceObjUnlock(parent); - - return ret; -} - - -static int -virNodeDeviceGetParentHostByFabricWWN(virNodeDeviceObjListPtr devs, - const char *dev_name, - const char *parent_fabric_wwn) -{ - virNodeDeviceObjPtr parent =3D NULL; - int ret; - - if (!(parent =3D virNodeDeviceFindByFabricWWN(devs, parent_fabric_wwn)= )) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Could not find parent device for '%s'"), - dev_name); - return -1; - } - - ret =3D virNodeDeviceFindFCParentHost(parent); - - virNodeDeviceObjUnlock(parent); - - return ret; -} - - -static int -virNodeDeviceFindVportParentHost(virNodeDeviceObjListPtr devs) -{ - virNodeDeviceObjPtr parent =3D NULL; - const char *cap =3D virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS); - int ret; - - if (!(parent =3D virNodeDeviceFindByCap(devs, cap))) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Could not find any vport capable device")); - return -1; - } - - ret =3D virNodeDeviceFindFCParentHost(parent); - - virNodeDeviceObjUnlock(parent); - - return ret; -} - - -int -virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs, - virNodeDeviceDefPtr def, - int create) -{ - int parent_host =3D -1; - - if (def->parent) { - parent_host =3D virNodeDeviceGetParentHostByParent(devs, def->name, - def->parent); - } else if (def->parent_wwnn && def->parent_wwpn) { - parent_host =3D virNodeDeviceGetParentHostByWWNs(devs, def->name, - def->parent_wwnn, - def->parent_wwpn); - } else if (def->parent_fabric_wwn) { - parent_host =3D - virNodeDeviceGetParentHostByFabricWWN(devs, def->name, - def->parent_fabric_wwn); - } else if (create =3D=3D CREATE_DEVICE) { - /* Try to find a vport capable scsi_host when no parent supplied */ - parent_host =3D virNodeDeviceFindVportParentHost(devs); - } - - return parent_host; -} - =20 void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) { @@ -2198,125 +1812,6 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr cap= s) } =20 =20 -void virNodeDeviceObjLock(virNodeDeviceObjPtr obj) -{ - virMutexLock(&obj->lock); -} - -void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj) -{ - virMutexUnlock(&obj->lock); -} - -static bool -virNodeDeviceCapMatch(virNodeDeviceObjPtr devobj, - int type) -{ - virNodeDevCapsDefPtr cap =3D NULL; - - for (cap =3D devobj->def->caps; cap; cap =3D cap->next) { - if (type =3D=3D cap->data.type) - return true; - - if (cap->data.type =3D=3D VIR_NODE_DEV_CAP_SCSI_HOST) { - if (type =3D=3D VIR_NODE_DEV_CAP_FC_HOST && - (cap->data.scsi_host.flags & - VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST)) - return true; - - if (type =3D=3D 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_ ## FL= AG)) -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 =3D NULL; - virNodeDevicePtr device =3D NULL; - int ndevices =3D 0; - int ret =3D -1; - size_t i; - - if (devices && VIR_ALLOC_N(tmp_devices, devobjs.count + 1) < 0) - goto cleanup; - - for (i =3D 0; i < devobjs.count; i++) { - virNodeDeviceObjPtr devobj =3D devobjs.objs[i]; - virNodeDeviceObjLock(devobj); - if ((!filter || filter(conn, devobj->def)) && - virNodeDeviceMatch(devobj, flags)) { - if (devices) { - if (!(device =3D virGetNodeDevice(conn, devobj->def->name)= ) || - VIR_STRDUP(device->parent, devobj->def->parent) < 0) { - virObjectUnref(device); - virNodeDeviceObjUnlock(devobj); - goto cleanup; - } - tmp_devices[ndevices] =3D device; - } - ndevices++; - } - virNodeDeviceObjUnlock(devobj); - } - - if (tmp_devices) { - /* trim the array to the final size */ - ignore_value(VIR_REALLOC_N(tmp_devices, ndevices + 1)); - *devices =3D tmp_devices; - tmp_devices =3D NULL; - } - - ret =3D ndevices; - - cleanup: - if (tmp_devices) { - for (i =3D 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" =20 # include =20 @@ -253,34 +251,6 @@ struct _virNodeDeviceObjList { virNodeDeviceObjPtr *objs; }; =20 -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); =20 virNodeDeviceDefPtr virNodeDeviceDefParseString(const char *str, @@ -298,21 +268,10 @@ int virNodeDeviceGetWWNs(virNodeDeviceDefPtr def, char **wwnn, char **wwpn); =20 -int virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs, - virNodeDeviceDefPtr def, - int create); - void virNodeDeviceDefFree(virNodeDeviceDefPtr def); =20 -void virNodeDeviceObjFree(virNodeDeviceObjPtr dev); - -void virNodeDeviceObjListFree(virNodeDeviceObjListPtr devs); - void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps); =20 -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) =20 -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); =20 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 + * . + */ + +#include + +#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 =3D dev->def->caps; + const char *fc_host_cap =3D + virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_FC_HOST); + const char *vports_cap =3D + virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS); + + while (caps) { + if (STREQ(cap, virNodeDevCapTypeToString(caps->data.type))) + return 1; + else if (caps->data.type =3D=3D 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 =3D 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 =3D dev->def->caps; + + while (caps) { + if (caps->data.type =3D=3D VIR_NODE_DEV_CAP_SCSI_HOST && + (caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOS= T)) + break; + + caps =3D 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 =3D dev->def->caps; + + while (caps) { + if (caps->data.type =3D=3D VIR_NODE_DEV_CAP_SCSI_HOST && + (caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_= OPS)) + break; + + caps =3D caps->next; + } + return caps; +} + + +virNodeDeviceObjPtr +virNodeDeviceFindBySysfsPath(virNodeDeviceObjListPtr devs, + const char *sysfs_path) +{ + size_t i; + + for (i =3D 0; i < devs->count; i++) { + virNodeDeviceObjLock(devs->objs[i]); + if ((devs->objs[i]->def->sysfs_path !=3D 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 =3D 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 =3D 0; i < devs->count; i++) { + virNodeDevCapsDefPtr cap; + virNodeDeviceObjLock(devs->objs[i]); + if ((cap =3D 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 =3D 0; i < devs->count; i++) { + virNodeDevCapsDefPtr cap; + virNodeDeviceObjLock(devs->objs[i]); + if ((cap =3D virNodeDeviceFindFCCapDef(devs->objs[i])) && + STREQ_NULLABLE(cap->data.scsi_host.fabric_wwn, parent_fabric_w= wn)) + return devs->objs[i]; + virNodeDeviceObjUnlock(devs->objs[i]); + } + + return NULL; +} + + +static virNodeDeviceObjPtr +virNodeDeviceFindByCap(virNodeDeviceObjListPtr devs, + const char *cap) +{ + size_t i; + + for (i =3D 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 =3D 0; i < devs->count; i++) + virNodeDeviceObjFree(devs->objs[i]); + VIR_FREE(devs->objs); + devs->count =3D 0; +} + +virNodeDeviceObjPtr virNodeDeviceAssignDef(virNodeDeviceObjListPtr devs, + virNodeDeviceDefPtr def) +{ + virNodeDeviceObjPtr device; + + if ((device =3D virNodeDeviceFindByName(devs, def->name))) { + virNodeDeviceDefFree(device->def); + device->def =3D 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 =3D def; + + return device; + +} + +void virNodeDeviceObjRemove(virNodeDeviceObjListPtr devs, + virNodeDeviceObjPtr *dev) +{ + size_t i; + + virNodeDeviceObjUnlock(*dev); + + for (i =3D 0; i < devs->count; i++) { + virNodeDeviceObjLock(*dev); + if (devs->objs[i] =3D=3D *dev) { + virNodeDeviceObjUnlock(*dev); + virNodeDeviceObjFree(devs->objs[i]); + *dev =3D 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 (>=3D 0), -1 otherwise. + */ +static int +virNodeDeviceFindFCParentHost(virNodeDeviceObjPtr parent) +{ + virNodeDevCapsDefPtr cap =3D 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 =3D NULL; + int ret; + + if (!(parent =3D virNodeDeviceFindByName(devs, parent_name))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find parent device for '%s'"), + dev_name); + return -1; + } + + ret =3D 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 =3D NULL; + int ret; + + if (!(parent =3D virNodeDeviceFindByWWNs(devs, parent_wwnn, parent_wwp= n))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find parent device for '%s'"), + dev_name); + return -1; + } + + ret =3D virNodeDeviceFindFCParentHost(parent); + + virNodeDeviceObjUnlock(parent); + + return ret; +} + + +static int +virNodeDeviceGetParentHostByFabricWWN(virNodeDeviceObjListPtr devs, + const char *dev_name, + const char *parent_fabric_wwn) +{ + virNodeDeviceObjPtr parent =3D NULL; + int ret; + + if (!(parent =3D virNodeDeviceFindByFabricWWN(devs, parent_fabric_wwn)= )) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find parent device for '%s'"), + dev_name); + return -1; + } + + ret =3D virNodeDeviceFindFCParentHost(parent); + + virNodeDeviceObjUnlock(parent); + + return ret; +} + + +static int +virNodeDeviceFindVportParentHost(virNodeDeviceObjListPtr devs) +{ + virNodeDeviceObjPtr parent =3D NULL; + const char *cap =3D virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS); + int ret; + + if (!(parent =3D virNodeDeviceFindByCap(devs, cap))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not find any vport capable device")); + return -1; + } + + ret =3D virNodeDeviceFindFCParentHost(parent); + + virNodeDeviceObjUnlock(parent); + + return ret; +} + + +int +virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs, + virNodeDeviceDefPtr def, + int create) +{ + int parent_host =3D -1; + + if (def->parent) { + parent_host =3D virNodeDeviceGetParentHostByParent(devs, def->name, + def->parent); + } else if (def->parent_wwnn && def->parent_wwpn) { + parent_host =3D virNodeDeviceGetParentHostByWWNs(devs, def->name, + def->parent_wwnn, + def->parent_wwpn); + } else if (def->parent_fabric_wwn) { + parent_host =3D + virNodeDeviceGetParentHostByFabricWWN(devs, def->name, + def->parent_fabric_wwn); + } else if (create =3D=3D CREATE_DEVICE) { + /* Try to find a vport capable scsi_host when no parent supplied */ + parent_host =3D 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 =3D NULL; + + for (cap =3D devobj->def->caps; cap; cap =3D cap->next) { + if (type =3D=3D cap->data.type) + return true; + + if (cap->data.type =3D=3D VIR_NODE_DEV_CAP_SCSI_HOST) { + if (type =3D=3D VIR_NODE_DEV_CAP_FC_HOST && + (cap->data.scsi_host.flags & + VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST)) + return true; + + if (type =3D=3D 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_ ## FL= AG)) +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 =3D NULL; + virNodeDevicePtr device =3D NULL; + int ndevices =3D 0; + int ret =3D -1; + size_t i; + + if (devices && VIR_ALLOC_N(tmp_devices, devobjs.count + 1) < 0) + goto cleanup; + + for (i =3D 0; i < devobjs.count; i++) { + virNodeDeviceObjPtr devobj =3D devobjs.objs[i]; + virNodeDeviceObjLock(devobj); + if ((!filter || filter(conn, devobj->def)) && + virNodeDeviceMatch(devobj, flags)) { + if (devices) { + if (!(device =3D virGetNodeDevice(conn, devobj->def->name)= ) || + VIR_STRDUP(device->parent, devobj->def->parent) < 0) { + virObjectUnref(device); + virNodeDeviceObjUnlock(devobj); + goto cleanup; + } + tmp_devices[ndevices] =3D device; + } + ndevices++; + } + virNodeDeviceObjUnlock(devobj); + } + + if (tmp_devices) { + /* trim the array to the final size */ + ignore_value(VIR_REALLOC_N(tmp_devices, ndevices + 1)); + *devices =3D tmp_devices; + tmp_devices =3D NULL; + } + + ret =3D ndevices; + + cleanup: + if (tmp_devices) { + for (i =3D 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 + * . + */ + +#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; =20 =20 # conf/node_device_event.h @@ -958,6 +948,19 @@ virDomainObjListRemoveLocked; virDomainObjListRename; =20 =20 +# 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_de= vice_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 @@ =20 # include "internal.h" # include "driver.h" -# include "node_device_conf.h" +# include "virnodedeviceobj.h" =20 # define LINUX_NEW_DEVICE_WAIT_TIME 60 =20 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" --=20 2.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list