From nobody Thu May 2 03:40:31 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) client-ip=209.132.183.37; envelope-from=libvir-list-bounces@redhat.com; helo=mx5-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx5-phx2.redhat.com (mx5-phx2.redhat.com [209.132.183.37]) by mx.zohomail.com with SMTPS id 1486830819150218.9323422710928; Sat, 11 Feb 2017 08:33:39 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx5-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGTrUR010164; Sat, 11 Feb 2017 11:29:54 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGToPP028501 for ; Sat, 11 Feb 2017 11:29:50 -0500 Received: from localhost.localdomain.com (ovpn-116-36.phx2.redhat.com [10.3.116.36]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGTmIl000660 for ; Sat, 11 Feb 2017 11:29:50 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Sat, 11 Feb 2017 11:29:37 -0500 Message-Id: <1486830585-23866-2-git-send-email-jferlan@redhat.com> In-Reply-To: <1486830585-23866-1-git-send-email-jferlan@redhat.com> References: <1486830585-23866-1-git-send-email-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH RFC 1/9] conf: Modify gendispatch.pl to make ACL argument opaque 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" The various drivers each have vir*EnsureACL and vir*CheckACL API's which are generated on the fly by gendispatch to include the driver typed "def" name as the last argument based on the API being checked and the driver name (e.g. Node, Interface, Secrets, etc.). Rather than having that name by typed, it's possible to generate the API prototype using a "void *opaque" argument and then modify the first line of the code to make the typed def argumment based off the opaque data. This way we can generalize the ACL typedefs in object parsing code to just be an opaque type. The next step in that generalization is to remove the multiple typdef's and replace it with one general typedef in order to further generalize the various drivers object and object list handling functions. Signed-off-by: John Ferlan --- src/conf/domain_conf.h | 3 +-- src/conf/interface_conf.h | 3 +-- src/conf/network_conf.h | 3 +-- src/conf/node_device_conf.h | 3 +-- src/conf/storage_conf.h | 3 +-- src/conf/virsecretobj.h | 3 +-- src/rpc/gendispatch.pl | 5 ++++- 7 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index dd79206..dd9e43e 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2400,8 +2400,7 @@ struct _virDomainObj { * restore will be required later= */ }; =20 -typedef bool (*virDomainObjListACLFilter)(virConnectPtr conn, - virDomainDefPtr def); +typedef bool (*virDomainObjListACLFilter)(virConnectPtr conn, void *opaque= ); =20 =20 typedef enum { diff --git a/src/conf/interface_conf.h b/src/conf/interface_conf.h index 2523207..1e38412 100644 --- a/src/conf/interface_conf.h +++ b/src/conf/interface_conf.h @@ -212,8 +212,7 @@ char *virInterfaceDefFormat(const virInterfaceDef *def); void virInterfaceObjLock(virInterfaceObjPtr obj); void virInterfaceObjUnlock(virInterfaceObjPtr obj); =20 -typedef bool (*virInterfaceObjListFilter)(virConnectPtr conn, - virInterfaceDefPtr def); +typedef bool (*virInterfaceObjListFilter)(virConnectPtr conn, void *opaque= ); =20 # define VIR_CONNECT_LIST_INTERFACES_FILTERS_ACTIVE \ (VIR_CONNECT_LIST_INTERFACES_ACTIVE | \ diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 9e4ae71..217b548 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -331,8 +331,7 @@ bool virNetworkObjTaint(virNetworkObjPtr obj, =20 void virNetworkDefFree(virNetworkDefPtr def); =20 -typedef bool (*virNetworkObjListFilter)(virConnectPtr conn, - virNetworkDefPtr def); +typedef bool (*virNetworkObjListFilter)(virConnectPtr conn, void *opaque); =20 enum { VIR_NETWORK_OBJ_LIST_ADD_LIVE =3D (1 << 0), diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index 1634483..e1cdb1d 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -315,8 +315,7 @@ void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj); VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPORTS | \ VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_GENERIC) =20 -typedef bool (*virNodeDeviceObjListFilter)(virConnectPtr conn, - virNodeDeviceDefPtr def); +typedef bool (*virNodeDeviceObjListFilter)(virConnectPtr conn, void *opaqu= e); =20 int virNodeDeviceObjListExport(virConnectPtr conn, virNodeDeviceObjList devobjs, diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index e952f5f..5eda544 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -314,8 +314,7 @@ struct _virStoragePoolSourceList { virStoragePoolSourcePtr sources; }; =20 -typedef bool (*virStoragePoolObjListFilter)(virConnectPtr conn, - virStoragePoolDefPtr def); +typedef bool (*virStoragePoolObjListFilter)(virConnectPtr conn, void *opaq= ue); =20 static inline int virStoragePoolObjIsActive(virStoragePoolObjPtr pool) diff --git a/src/conf/virsecretobj.h b/src/conf/virsecretobj.h index fa45b42..673a4c8 100644 --- a/src/conf/virsecretobj.h +++ b/src/conf/virsecretobj.h @@ -65,8 +65,7 @@ virSecretObjPtr virSecretObjListAdd(virSecretObjListPtr s= ecrets, const char *configDir, virSecretDefPtr *oldDef); =20 -typedef bool (*virSecretObjListACLFilter)(virConnectPtr conn, - virSecretDefPtr def); +typedef bool (*virSecretObjListACLFilter)(virConnectPtr conn, void *opaque= ); =20 int virSecretObjListNumOfSecrets(virSecretObjListPtr secrets, virSecretObjListACLFilter filter, diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl index 173189c..12b047b 100755 --- a/src/rpc/gendispatch.pl +++ b/src/rpc/gendispatch.pl @@ -2066,7 +2066,7 @@ elsif ($mode eq "client") { if ($object eq "StorageVol") { push @argdecls, "virStoragePoolDefPtr pool"; } - push @argdecls, "$objecttype $arg"; + push @argdecls, "void *opaque"; } if ($checkflags) { push @argdecls, "unsigned int flags"; @@ -2101,6 +2101,9 @@ elsif ($mode eq "client") { print "/* Returns: $fail on error/denied, $pass on allowed= */\n"; print "$ret $apiname(" . join(", ", @argdecls) . ")\n"; print "{\n"; + if ($object ne "Connect") { + print " $objecttype $arg =3D opaque;\n"; + } print " virAccessManagerPtr mgr;\n"; print " int rv;\n"; print "\n"; --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 03:40:31 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) client-ip=209.132.183.37; envelope-from=libvir-list-bounces@redhat.com; helo=mx5-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx5-phx2.redhat.com (mx5-phx2.redhat.com [209.132.183.37]) by mx.zohomail.com with SMTPS id 148683083225278.35531746505058; Sat, 11 Feb 2017 08:33:52 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx5-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGTrX5010160; Sat, 11 Feb 2017 11:29:53 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGTp55028509 for ; Sat, 11 Feb 2017 11:29:51 -0500 Received: from localhost.localdomain.com (ovpn-116-36.phx2.redhat.com [10.3.116.36]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGTmIm000660 for ; Sat, 11 Feb 2017 11:29:50 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Sat, 11 Feb 2017 11:29:38 -0500 Message-Id: <1486830585-23866-3-git-send-email-jferlan@redhat.com> In-Reply-To: <1486830585-23866-1-git-send-email-jferlan@redhat.com> References: <1486830585-23866-1-git-send-email-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH RFC 2/9] conf: Introduce virPoolObj and virPoolTableObj and PoolObj API's 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" Introduce a new generic virPoolObj[Ptr] and virPoolObjTable[Ptr] in order to generically manage driver lists of objects rather than the current hodgepodge of some drivers using a forward linked list and other drivers using a single UUID only based hash table to look up objects. The concept is to mimic the domain objects which keep objects in a UUID hash table and a name hash table for faster lookup. There's also generic API's in order to Lock, Reference, Unreference, and Unlock the objects to remove the need for a heavy handed driver lock. Since these are Hash Table objects rather than List Objects, the structures and API's have been named thusly. These are all based upon the existing generic object/class model so allocation/freeing is using existing API's. In addition to common structures and API's, as each driver is converted the driver specific ACL filter API's can be replaced by a generic pool ACL filter API. Each of the API's is designed to have a consistency with respect to returni= ng a locked and referenced object, so that a virPoolObjEndAPI can be called in order to dereference and unlock the object. The ultimate goal is to have a single way to think about these objects management so that the various drivers don't have to have special or differ= ent code in order to manage based on the "style" of list/table the driver needs to manage. A _virPoolObj uses a fairly generic structure: virObjectLockable parent; bool flags virPoolDefPtr pooldef; void *def; void *newDef; virFreeCallback defFreeFunc; void *privateData; void (*privateDataFreeFunc)(void *); Access to the fields of the object is handled via API's to fetch or set the various fields rather than allowing the calling driver to manage the object directly. This ensures a more consistent look and feel to the code for each driver. The "def" and "newDef" field along with the defFreeFunc will point at the driver's specific vir*DefPtr data and the FreeFunc handles the free of the data when the object is finally removed. The vir*DefPtr API's will each need to be modified to take an "void *opaque" and assign that to the specific driver definition type. Most drivers have no need for privateData; however, a few drivers will need to manage driver specific object private data. For those drivers additional object management code is generated in order to manage the Get, Set, and test of the private data. The goal being to have one set of API's to manage the data rather than drivers directly touching it. A _virPoolObjTable is another generic structure: virObjectLockable parent; virPoolObjTableType type; bool nameOnly; int hashStart; virHashTable *objsUuid; virHashTable *objsName; Not every driver supports UUID's, so the UUID table isn't required, but it is the preferred lookup mechanism. The bool 'nameOnly' will help the table code make those decisions. The various Pool Object Table API's are taken from the current object list managements and converted to use tables. Objects are added to the table allowing for a callback mechanism to handle driver specific "assignment" options when the object already appears in the table and the driver would be managing the replacement of the "existing" object "def". There are common API's to Add, Clear, Remove, Search, Iterate, Collect, List, Clone, and Prune objects. Each uses the same common methodology to lock the table list, use the virHash* APIs, and unlock the table list returning the requested data for the operation. Generally that means a locked and referenced object. The virPoolObjEndAPI will handle the dereference and unlocking. Add new error code for the new poolobj subsystem Signed-off-by: John Ferlan --- include/libvirt/virterror.h | 1 + po/POTFILES.in | 1 + src/Makefile.am | 5 + src/conf/virpoolobj.c | 1184 +++++++++++++++++++++++++++++++++++++++= ++++ src/conf/virpoolobj.h | 222 ++++++++ src/libvirt_private.syms | 33 ++ src/util/virerror.c | 1 + 7 files changed, 1447 insertions(+) create mode 100644 src/conf/virpoolobj.c create mode 100644 src/conf/virpoolobj.h diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index 2efee8f..2174334 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -132,6 +132,7 @@ typedef enum { =20 VIR_FROM_PERF =3D 65, /* Error from perf */ VIR_FROM_LIBSSH =3D 66, /* Error from libssh connection transpor= t */ + VIR_FROM_POOLOBJ =3D 67, /* Error from the poolobj code */ =20 # ifdef VIR_ENUM_SENTINELS VIR_ERR_DOMAIN_LAST diff --git a/po/POTFILES.in b/po/POTFILES.in index 365ea66..95fa9a6 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/virpoolobj.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 2f32d41..03a8cf3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -373,6 +373,10 @@ NWFILTER_CONF_SOURCES =3D \ $(NWFILTER_PARAM_CONF_SOURCES) \ conf/nwfilter_conf.c conf/nwfilter_conf.h =20 +# "Generic" poolobj sources +POOLOBJ_SOURCES =3D \ + conf/virpoolobj.h conf/virpoolobj.c + # Storage driver generic impl APIs STORAGE_CONF_SOURCES =3D \ conf/storage_conf.h conf/storage_conf.c @@ -405,6 +409,7 @@ CONF_SOURCES =3D \ $(NETDEV_CONF_SOURCES) \ $(DOMAIN_CONF_SOURCES) \ $(OBJECT_EVENT_SOURCES) \ + $(POOLOBJ_SOURCES) \ $(DOMAIN_EVENT_SOURCES) \ $(NETWORK_EVENT_SOURCES) \ $(STORAGE_EVENT_SOURCES) \ diff --git a/src/conf/virpoolobj.c b/src/conf/virpoolobj.c new file mode 100644 index 0000000..bca6524 --- /dev/null +++ b/src/conf/virpoolobj.c @@ -0,0 +1,1184 @@ +/* + * virpoolobj.c: internal pool objects handling + * + * Copyright (C) 2016 Red Hat, Inc. + * + * 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 "viralloc.h" +#include "virpoolobj.h" +#include "virerror.h" +#include "virlog.h" +#include "virhash.h" +#include "virstring.h" + +#define VIR_FROM_THIS VIR_FROM_POOLOBJ + +VIR_LOG_INIT("conf.virpoolobj"); + +VIR_ENUM_DECL(virPoolObjTable); +VIR_ENUM_IMPL(virPoolObjTable, VIR_POOLOBJTABLE_LAST, + "nodedev", "interface", "nwfilter", "volume", "block storage= ", + "secret", "network", "domain snapshot", "domain") + +struct _virPoolDef { + char *uuid; + char *name; +}; + +struct _virPoolObj { + virObjectLockable parent; + + /* copy of the def->name and def->uuid (if available) used for lookups + * without needing to know the object type */ + virPoolDefPtr pooldef; + + /* Boolean states that can be managed by consumer */ + bool active; /* object is active or not */ + bool beingRemoved; /* object being prepared for removal */ + bool autostart; /* object is autostarted */ + bool persistent; /* object definition is persistent */ + bool updated; /* object config has been updated in some way */ + + /* Boolean states managed by virPoolObj */ + bool removing; /* true when object has been removed from table(s) */ + + /* 'def' is the current config definition. + * 'newDef' is the next boot configuration. + * The 'type' value will describe which _vir*Def struct describes + * The 'privateData' will be private object data for each pool obj + * and specific to the 'type' of object being managed. */ + void *def; + void *newDef; + virFreeCallback defFreeFunc; + + /* Private data to be managed by the specific object using + * vir{$OBJ}ObjPrivate{Get|Set}{$FIELD} type API's. Each of those + * calling the virPoolObjGetPrivateData in order to access this field = */ + void *privateData; + void (*privateDataFreeFunc)(void *); +}; + +struct _virPoolObjTable { + virObjectLockable parent; + virPoolObjTableType type; + bool nameOnly; + int hashStart; + + /* uuid string -> virPoolObj mapping + * for O(1), lockless lookup-by-uuid */ + virHashTable *objsUuid; + + /* name -> virPoolObj mapping for O(1), + * lockless lookup-by-name */ + virHashTable *objsName; +}; + +static virClassPtr virPoolObjClass; +static void virPoolObjDispose(void *obj); + +static int +virPoolObjOnceInit(void) +{ + if (!(virPoolObjClass =3D virClassNew(virClassForObjectLockable(), + "virPoolObj", + sizeof(virPoolObj), + virPoolObjDispose))) + return -1; + + return 0; +} +VIR_ONCE_GLOBAL_INIT(virPoolObj) + + +/** + * @pooldef: The 'name' and possible 'uuid' of the def for lookups + * @def: The 'def' for the object + * @newDef: The 'newDef' (next) for the object + * @defFreeFunc: The vir$OBJFreeDef callback + * + * Create/return a new poolobj to be placed into the hash table + * + * Returns: Object on success, NULL on failure + */ +virPoolObjPtr +virPoolObjNew(virPoolDefPtr pooldef, + void *def, + void *newDef, + virFreeCallback defFreeFunc) +{ + virPoolObjPtr obj; + + if (virPoolObjInitialize() < 0) + return NULL; + + if (!(obj =3D virObjectLockableNew(virPoolObjClass))) + return NULL; + + VIR_DEBUG("obj=3D%p pooldef=3D%p def=3D%p newDef=3D%p ff=3D%p", + obj, pooldef, def, newDef, defFreeFunc); + obj->pooldef =3D pooldef; + obj->def =3D def; + obj->newDef =3D newDef; + obj->defFreeFunc =3D defFreeFunc; + + return obj; +} + + +static void +virPoolDefFree(virPoolDefPtr def) +{ + if (!def) + return; + + VIR_FREE(def->uuid); + VIR_FREE(def->name); + VIR_FREE(def); +} + + +static void +virPoolObjDispose(void *_obj) +{ + virPoolObjPtr obj =3D _obj; + + if (!obj) + return; + + VIR_DEBUG("obj=3D%p, pooldef=3D%p def=3D%p newDef=3D%p ff=3D%p", + obj, obj->pooldef, obj->def, obj->newDef, obj->defFreeFunc); + + virPoolDefFree(obj->pooldef); + (obj->defFreeFunc)(obj->def); + (obj->defFreeFunc)(obj->newDef); + + if (obj->privateDataFreeFunc) + (obj->privateDataFreeFunc)(obj->privateData); +} + + +/** + * @obj: A locked poolobj pointer + * @active: The "new" state + * + * Set the @active bit in the object. + */ +void +virPoolObjSetActive(virPoolObjPtr obj, + bool active) +{ + obj->active =3D active; +} + + +/** + * @obj: A locked poolobj pointer + * @autostart: The @autostart value sent from the driver + * + * Set the @autostart bit in the object. + */ +void +virPoolObjSetAutostart(virPoolObjPtr obj, + bool autostart) +{ + obj->autostart =3D autostart; +} + + +/** + * @obj: A locked poolobj pointer + * @beingRemoved: The @beingRemoved value sent from the driver + * + * Set the @beingRemoved bit in the object. + */ +void +virPoolObjSetBeingRemoved(virPoolObjPtr obj, + bool beingRemoved) +{ + obj->beingRemoved =3D beingRemoved; +} + + +/** + * @obj: A locked poolobj pointer + * @persistent: The @persistent value sent from the driver + * + * Set the @persistent bit in the object. + */ +void +virPoolObjSetPersistent(virPoolObjPtr obj, + bool persistent) +{ + obj->persistent =3D persistent; +} + + +/** + * @obj: A locked poolobj pointer + * @def: Opaque 'def' to replace in the object + * + * Set the @def in the object. This code will call the defFreeFunc + * on the existing object in obj->def before assigning. + */ +void +virPoolObjSetDef(virPoolObjPtr obj, + void *def) +{ + obj->defFreeFunc(obj->def); + obj->def =3D def; +} + + +/** + * @obj: A locked poolobj pointer + * @newDef: Opaque 'newDef' to replace in the object + * + * Set the @newDef in the object. This code will call the defFreeFunc + * on the existing object in obj->newDef before assigning. + */ +void +virPoolObjSetNewDef(virPoolObjPtr obj, + void *newDef) +{ + obj->defFreeFunc(obj->newDef); + obj->newDef =3D newDef; +} + + +/** + * @obj: A locked poolobj pointer + * @privateData: Pointer to private data + * @privateDataFreeFunc: Callback function when the object is free t + * free the privateData details + * + * Set the @privateData address and @privateDataFreeFunc addresses. + */ +void +virPoolObjSetPrivateData(virPoolObjPtr obj, + void *privateData, + virFreeCallback privateDataFreeFunc) +{ + obj->privateData =3D privateData; + obj->privateDataFreeFunc =3D privateDataFreeFunc; +} + + +/* virPoolObjIs{Active|Autostart|BeingRemoved|Persistent} + * @obj: A locked poolobj pointer + * + * Various accessor fetch functions for the bool bits in the object + */ +bool +virPoolObjIsActive(const virPoolObj *obj) +{ + return obj->active; +} + + +bool +virPoolObjIsAutostart(const virPoolObj *obj) +{ + return obj->autostart; +} + + +bool +virPoolObjIsBeingRemoved(const virPoolObj *obj) +{ + return obj->beingRemoved; +} + + +bool +virPoolObjIsPersistent(const virPoolObj *obj) +{ + return obj->persistent; +} + + +/** + * @obj: A locked poolobj pointer + * + * Return the obj->def pointer to the caller + */ +void * +virPoolObjGetDef(const virPoolObj *obj) +{ + return obj->def; +} + + +/** + * @obj: A locked poolobj pointer + * + * Return the obj->newDef pointer to the caller + */ +void * +virPoolObjGetNewDef(const virPoolObj *obj) +{ + return obj->newDef; +} + + +/** + * @obj: A locked poolobj pointer + * + * Return the obj->privateData pointer to the caller + */ +void * +virPoolObjGetPrivateData(const virPoolObj *obj) +{ + return obj->privateData; +} + + +/** + * @obj: A locked and ref'd poolobj pointer + * + * Unref and unlock the object + */ +void +virPoolObjEndAPI(virPoolObjPtr *obj) +{ + if (!*obj) + return; + + virObjectUnlock(*obj); + virObjectUnref(*obj); + *obj =3D NULL; +} + + +static virClassPtr virPoolObjTableClass; +static void virPoolObjTableDispose(void *obj); + +static int +virPoolObjTableOnceInit(void) +{ + if (!(virPoolObjTableClass =3D virClassNew(virClassForObjectLockable(), + "virPoolObjTable", + sizeof(virPoolObjTable), + virPoolObjTableDispose))) + return -1; + + return 0; +} + + +VIR_ONCE_GLOBAL_INIT(virPoolObjTable) + +/* virPoolObjTableNew: + * @type: The virPoolObjTableType type of hash table + * @hashStart: Initial size of the table + * @nameOnly: Whether the table will only have names + * + * Allocate the hash table object and initialize the hash table(s). + * At least a "Name" hash table is always allocated, but there may + * also be a "UUID" hash table as well based on the @nameOnly argument + * + * Returns: The hash table on success, NULL on failure + */ +virPoolObjTablePtr +virPoolObjTableNew(virPoolObjTableType type, + int hashStart, + bool nameOnly) +{ + virPoolObjTablePtr poolobjs; + + if (virPoolObjTableInitialize() < 0) + return NULL; + + if (!(poolobjs =3D virObjectLockableNew(virPoolObjTableClass))) + return NULL; + + VIR_DEBUG("objtable=3D%p type=3D%s", + poolobjs, virPoolObjTableTypeToString(type)); + poolobjs->type =3D type; + poolobjs->hashStart =3D hashStart; + poolobjs->nameOnly =3D nameOnly; + + if (!nameOnly && + !(poolobjs->objsUuid =3D virHashCreate(hashStart, virObjectFreeHas= hData))) + goto error; + + if (!(poolobjs->objsName =3D virHashCreate(hashStart, virObjectFreeHas= hData))) + goto error; + + return poolobjs; + + error: + virObjectUnref(poolobjs); + return NULL; +} + + +static void +virPoolObjTableDispose(void *obj) +{ + virPoolObjTablePtr poolobjs =3D obj; + + if (!poolobjs) + return; + + VIR_DEBUG("objtable=3D%p type=3D%s", + poolobjs, virPoolObjTableTypeToString(poolobjs->type)); + + if (!poolobjs->nameOnly) + virHashFree(poolobjs->objsUuid); + virHashFree(poolobjs->objsName); +} + + +/* virPoolObjTableAdd[Locked] + * @poolobjs: Pool object table + * @new_uuidstr: Optional uuid by formatted string (offers more uniqueness) + * @new_name: Required name for uniqueness + * @def: Pointer to a void Object definition + * @newDef: Pointer to the "next" void Object definition + * @defFreeFunc: Callback to free the def/newDef + * @assignDefFunc: Callback to assign def logic (def/newDef manipulation) + * @assignFlags: Flags to pass to @assignDefFunc + * + * Search for the @new_uuidstr/@new_name keys in @poolobjs and either + * update the definition via the @assignDefFunc or add the @def and + * @newDef to @poolobjs. + * + * The @defFreeFunc is a reference to the vir*DefFree function for + * the type of pool + * + * The optional @assignDefFunc is a callback function that will + * handle the management of @def, @newDef, and @oldDef long with + * an @assignFlags option depending on how/where it's called. + * + * Returns: A locked pool object with incremented ref or NULL + * Caller must use virPoolObjEndAPI when done. + */ +static virPoolObjPtr +virPoolObjTableAddLocked(virPoolObjTablePtr poolobjs, + const char *new_uuidstr, + const char *new_name, + void *def, + void *newDef, + void *oldDef, + virFreeCallback defFreeFunc, + virPoolObjTableAssignDefFunc assignDefFunc, + unsigned int assignFlags) +{ + virPoolDefPtr pooldef =3D NULL; + virPoolObjPtr obj =3D NULL; + + VIR_DEBUG("poolobjs=3D%p uuidstr=3D%s name=3D%s", + poolobjs, NULLSTR(new_uuidstr), new_name); + + /* UUID is the primary search, although if the name is sufficiently + * unique (such as for node devices and interfaces), then name will + * be the primary */ + if (poolobjs->nameOnly) + obj =3D virHashLookup(poolobjs->objsName, new_name); + else + obj =3D virHashLookup(poolobjs->objsUuid, new_uuidstr); + + if (obj) { + virObjectLock(obj); + + /* If used UUID for Lookup, ensure name matches too */ + if (new_uuidstr && STRNEQ(obj->pooldef->name, new_name)) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("%s '%s' is already defined with uuid %s"), + virPoolObjTableTypeToString(poolobjs->type), + obj->pooldef->name, obj->pooldef->uuid); + virObjectUnlock(obj); + return NULL; + } + + if (assignDefFunc) { + if (assignDefFunc(obj, def, oldDef, assignFlags) < 0) { + virObjectUnlock(obj); + return NULL; + } + } else { + /* Simple replacement */ + defFreeFunc(obj->def); + obj->def =3D def; + } + } else { + /* Ensure that something by the same name doesn't already exist */ + if (!new_uuidstr && + (obj =3D virHashLookup(poolobjs->objsName, new_name))) { + virObjectLock(obj); + virReportError(VIR_ERR_OPERATION_FAILED, + _("%s '%s' already exists with uuid %s"), + virPoolObjTableTypeToString(poolobjs->type), + new_name, obj->pooldef->uuid); + virObjectUnlock(obj); + return NULL; + } + + if (VIR_ALLOC(pooldef) < 0) + return NULL; + + if (VIR_STRDUP(pooldef->uuid, new_uuidstr) < 0 || + VIR_STRDUP(pooldef->name, new_name) < 0) + goto error; + + if (!(obj =3D virPoolObjNew(pooldef, def, newDef, defFreeFunc))) + goto error; + + virObjectLock(obj); + + if (!poolobjs->nameOnly && + virHashAddEntry(poolobjs->objsUuid, new_uuidstr, obj) < 0) + goto error; + + if (virHashAddEntry(poolobjs->objsName, new_name, obj) < 0) { + if (!poolobjs->nameOnly) + virHashRemoveEntry(poolobjs->objsUuid, new_uuidstr); + goto error; + } + + /* If it's in two hash tables, increment ref count! */ + if (new_uuidstr) + virObjectRef(obj); + } + + virObjectRef(obj); + return obj; + + error: + VIR_DEBUG("Fail to add object to table"); + virPoolDefFree(pooldef); + virObjectUnref(obj); + virObjectUnlock(obj); + return NULL; +} + + +virPoolObjPtr +virPoolObjTableAdd(virPoolObjTablePtr poolobjs, + const char *new_uuidstr, + const char *new_name, + void *def, + void *newDef, + void *oldDef, + virFreeCallback defFreeFunc, + virPoolObjTableAssignDefFunc assignDefFunc, + unsigned int assignFlags) +{ + virPoolObjPtr ret; + + virObjectLock(poolobjs); + ret =3D virPoolObjTableAddLocked(poolobjs, new_uuidstr, new_name, + def, newDef, oldDef, defFreeFunc, + assignDefFunc, assignFlags); + VIR_DEBUG("poolobjs=3D%p, ret=3D%p", poolobjs, ret); + virObjectUnlock(poolobjs); + return ret; +} + + +/* + * virPoolObjTableClear + * @poolobjs: Pool object table + * + * Remove all the objects from @poolobjs, but don't free the table. + * Useful for @poolobjs tables that can repopulate themselves and don't + * want to determine the difference between two objects. + */ +void +virPoolObjTableClearAll(virPoolObjTablePtr poolobjs) +{ + ssize_t count; + virObjectLock(poolobjs); + if (!poolobjs->nameOnly) { + count =3D virHashRemoveAll(poolobjs->objsUuid); + VIR_DEBUG("cleared out %ld objects from objsUuid", count); + } + + count =3D virHashRemoveAll(poolobjs->objsName); + VIR_DEBUG("cleared out %ld objects from objsName", count); + virObjectUnlock(poolobjs); +} + + +/* + * virPoolObjTableRemove + * @poolobjs: Pool object table + * @obj: Object to remove + * + * Remove the object from the table. + * + * The caller must hold a lock on the driver owning @poolobjs and + * must have locked @obj to ensure no one else is either waiting for + * @obj or still using it. The caller can also take out an extra + * reference on @obj to ensure it doesn't disappear if it needs it + * beyond this removal. + * + * Upon exit, the lock held upon entry is removed. + */ +void +virPoolObjTableRemove(virPoolObjTablePtr poolobjs, + virPoolObjPtr *obj) +{ + virPoolDefPtr pooldef =3D (*obj)->pooldef; + + VIR_DEBUG("poolobjs=3D%p, obj=3D%p", poolobjs, obj); + + (*obj)->removing =3D true; + virObjectRef(*obj); + virObjectUnlock(*obj); + + virObjectLock(poolobjs); + virObjectLock(*obj); + if (!poolobjs->nameOnly) + virHashRemoveEntry(poolobjs->objsUuid, pooldef->uuid); + virHashRemoveEntry(poolobjs->objsName, pooldef->name); + virObjectUnlock(*obj); + virObjectUnref(*obj); + virObjectUnlock(poolobjs); +} + + +/** + * virPoolObjFindByUUIDInternal: + * @poolobjs: Pool object table + * @uuid: pool uuid to find + * + * Lock and search the pool for the UUID. Depending on 'ref' argument + * we either return with referenced count incremented on the object too + * + * Returns: pool object + */ +static virPoolObjPtr +virPoolObjTableFindByUUIDInternal(virPoolObjTablePtr poolobjs, + const unsigned char *uuid, + bool ref) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virPoolObjPtr obj; + + virObjectLock(poolobjs); + if (poolobjs->nameOnly) { + virObjectUnlock(poolobjs); + return NULL; + } + + virUUIDFormat(uuid, uuidstr); + + obj =3D virHashLookup(poolobjs->objsUuid, uuidstr); + if (ref) { + virObjectRef(obj); + virObjectUnlock(poolobjs); + } + if (obj) { + virObjectLock(obj); + if (obj->removing) { + virObjectUnlock(obj); + if (ref) + virObjectUnref(obj); + obj =3D NULL; + } + } + if (!ref) + virObjectUnlock(poolobjs); + return obj; +} + + +/** + * virPoolObjFindByUUID: + * @poolobjs: Pool object table + * @uuid: pool uuid to find + * + * Returns: Locked pool object. + */ +virPoolObjPtr +virPoolObjTableFindByUUID(virPoolObjTablePtr poolobjs, + const unsigned char *uuid) +{ + return virPoolObjTableFindByUUIDInternal(poolobjs, uuid, false); +} + + +/** + * virPoolObjFindByUUIDUnlocked: + * @poolobjs: Pool object table + * @uuid: pool uuid to find + * + * Returns: Locked and ref count incremented pool object. + */ +virPoolObjPtr +virPoolObjTableFindByUUIDRef(virPoolObjTablePtr poolobjs, + const unsigned char *uuid) +{ + return virPoolObjTableFindByUUIDInternal(poolobjs, uuid, true); +} + + +virPoolObjPtr +virPoolObjTableFindByName(virPoolObjTablePtr poolobjs, + const char *name) +{ + virPoolObjPtr obj; + + virObjectLock(poolobjs); + obj =3D virHashLookup(poolobjs->objsName, name); + virObjectRef(obj); + virObjectUnlock(poolobjs); + if (obj) { + virObjectLock(obj); + if (obj->removing) { + virObjectUnlock(obj); + virObjectUnref(obj); + obj =3D NULL; + } + } + return obj; +} + + +static int +virPoolObjTableSearchCallback(const void *payload, + const void *name ATTRIBUTE_UNUSED, + const void *opaque) +{ + virPoolObjPtr obj =3D (virPoolObjPtr) payload; + struct virPoolObjTableSearchIterData *data =3D + (struct virPoolObjTableSearchIterData *) opaque; + int found =3D 0; + + virObjectLock(obj); + + if (data->callback(obj, data->opaque) =3D=3D 1) + found =3D 1; + + virObjectUnlock(obj); + return found; +} + + +/* virPoolObjTableSearchInternal + * @poolobjs: Pool object table + * @callback: Consumer specific callback function for search + * @opaque: Consumer specific data to the callback function + * @ref: Whether to place a reference on the object or not + * + * Search through the poolobj table by name, calling the consumer + * specific callback with the obj and consumer specific data structure. + * If the consumer determines there's a match, it will return true + * and the cause the search to complete + * + * Returns virPoolObjPtr if data is found, NULL if not. The returned + * object will be locked and can have it reference count incremented. + * If the reference count is incremented, use the virPoolObjEndAPI on + * the object; otherwise, use virObjectUnlock to release the object lock. + */ +static virPoolObjPtr +virPoolObjTableSearchInternal(virPoolObjTablePtr poolobjs, + virPoolObjTableSearchIterator callback, + void *opaque, + bool ref) +{ + virPoolObjPtr ret; + struct virPoolObjTableSearchIterData data =3D { .callback =3D callback, + .opaque =3D opaque }; + + virObjectLock(poolobjs); + if (poolobjs->nameOnly) + ret =3D virHashSearch(poolobjs->objsName, virPoolObjTableSearchCal= lback, + &data); + else + ret =3D virHashSearch(poolobjs->objsUuid, virPoolObjTableSearchCal= lback, + &data); + if (ref) { + virObjectRef(ret); + virObjectUnlock(poolobjs); + } + if (ret) { + virObjectLock(ret); + if (ret->removing) { + virObjectUnlock(ret); + if (ref) + virObjectUnref(ret); + ret =3D NULL; + } + } + if (!ref) + virObjectUnlock(poolobjs); + + return ret; +} + + +virPoolObjPtr +virPoolObjTableSearch(virPoolObjTablePtr poolobjs, + virPoolObjTableSearchIterator callback, + void *opaque) +{ + return virPoolObjTableSearchInternal(poolobjs, callback, opaque, false= ); +} + + +virPoolObjPtr +virPoolObjTableSearchRef(virPoolObjTablePtr poolobjs, + virPoolObjTableSearchIterator callback, + void *opaque) +{ + return virPoolObjTableSearchInternal(poolobjs, callback, opaque, true); +} + + +struct iterateData { + virPoolObjTableIteratorCallback callback; + void *opaque; +}; + +static int +virPoolObjTableIterator(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + virPoolObjPtr obj =3D payload; + struct iterateData *data =3D opaque; + + virObjectLock(obj); + data->callback(obj, data->opaque); + virObjectUnlock(obj); + + return 0; +} + + +/* virPoolObjTableIterate: + * @poolobjs: Source table to perform iteration + * @callback: Function to call + * @opaque: Opaque data for callback + * + * Just iterate through each entry in @poolobjs calling the + * void function with the locked pool object + * + * Returns: void + */ +void +virPoolObjTableIterate(virPoolObjTablePtr poolobjs, + virPoolObjTableIteratorCallback callback, + void *opaque) +{ + struct iterateData data =3D { .callback =3D callback, + .opaque =3D opaque }; + virObjectLock(poolobjs); + if (poolobjs->nameOnly) + virHashForEach(poolobjs->objsName, virPoolObjTableIterator, &data); + else + virHashForEach(poolobjs->objsUuid, virPoolObjTableIterator, &data); + virObjectUnlock(poolobjs); +} + + +struct collectData { + virPoolObjPtr *objs; + size_t nobjs; +}; + +static int +virPoolObjTableCollectIterator(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + struct collectData *data =3D opaque; + + data->objs[data->nobjs++] =3D virObjectRef(payload); + return 0; +} + + +static void +virPoolObjTableFilter(virPoolObjPtr **list, + size_t *nobjs, + virConnectPtr conn, + virPoolObjACLFilter aclfilter, + virPoolObjMatchFilter matchfilter, + unsigned int flags) +{ + size_t i =3D 0; + + while (i < *nobjs) { + virPoolObjPtr obj =3D (*list)[i]; + + virObjectLock(obj); + + /* do not list the object if: + * 1) it's being removed. + * 2) connection does not have ACL to see it + * 3) it doesn't match the filter + */ + if (obj->removing || + (aclfilter && !aclfilter(conn, obj->def)) || + (matchfilter && !matchfilter(obj, flags))) { + virObjectUnlock(obj); + virObjectUnref(obj); + VIR_DELETE_ELEMENT(*list, i, *nobjs); + continue; + } + + virObjectUnlock(obj); + i++; + } +} + + +/* virPoolObjTableCollect: + * @poolobjs: Pool object table + * @conn: Pointer to connection + * @objs: Pointer to a list of objects to return + * @nobjs: Count of objects + * @aclfilter: Filter results based on ACL + * @matchfilter: Possible consumer callback to futher "match" the data + * @flags: Consumer specific flags + * + * Create a list of poolobjs that match both the ACL filter and the consum= er + * provided match filter and return them and the count to the caller. Each + * of the returned object is returned with an incremented ref count. When + * the caller is done with the list, each object in the returned @objs list + * should be run through virObjectListFreeCount to Unref the object. + * + * Returns 0 on success, -1 on failure + */ +int +virPoolObjTableCollect(virPoolObjTablePtr poolobjs, + virConnectPtr conn, + virPoolObjPtr **objs, + size_t *nobjs, + virPoolObjACLFilter aclfilter, + virPoolObjMatchFilter matchfilter, + unsigned int flags) +{ + struct collectData data =3D { NULL, 0 }; + + virObjectLock(poolobjs); + if (poolobjs->nameOnly) { + if (VIR_ALLOC_N(data.objs, virHashSize(poolobjs->objsName)) < 0) { + virObjectUnlock(poolobjs); + return -1; + } + virHashForEach(poolobjs->objsName, virPoolObjTableCollectIterator, + &data); + } else { + if (VIR_ALLOC_N(data.objs, virHashSize(poolobjs->objsUuid)) < 0) { + virObjectUnlock(poolobjs); + return -1; + } + virHashForEach(poolobjs->objsUuid, virPoolObjTableCollectIterator, + &data); + } + virObjectUnlock(poolobjs); + + virPoolObjTableFilter(&data.objs, &data.nobjs, conn, + aclfilter, matchfilter, flags); + + *nobjs =3D data.nobjs; + *objs =3D data.objs; + + return 0; +} + + +static int +virPoolObjTableListIterator(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + virPoolObjPtr obj =3D payload; + struct virPoolObjTableListIterData *data =3D opaque; + + virObjectLock(obj); + if (data->aclfilter && !data->aclfilter(data->conn, obj->def)) + goto cleanup; + + if (data->callback && data->callback(obj, data->opaque) < 0) + data->ret =3D -1; + + cleanup: + virObjectUnlock(obj); + return 0; +} + + +/* virPoolObjTableList: + * @poolobjs: Pool object table + * @conn: Pointer to connection + * @aclfilter: Filter results based on ACL + * @callback: Possible consumer callback handle @opaque data + * @opaque: Consumer opaque data + * + * Similar to Collect, except allowing the consumer to build up it's + * @opaque data based on consumer @callback defined rules. + * + * Returns 0 on success, -1 on failure + */ +int +virPoolObjTableList(virPoolObjTablePtr poolobjs, + virConnectPtr conn, + virPoolObjACLFilter aclfilter, + virPoolObjTableListCallback callback, + void *opaque) +{ + struct virPoolObjTableListIterData data =3D { .conn =3D conn, + .aclfilter =3D aclfilter, + .callback =3D callback, + .opaque =3D opaque, + .ret =3D 0 }; + + virObjectLock(poolobjs); + if (poolobjs->nameOnly) + virHashForEach(poolobjs->objsName, virPoolObjTableListIterator, &d= ata); + else + virHashForEach(poolobjs->objsUuid, virPoolObjTableListIterator, &d= ata); + virObjectUnlock(poolobjs); + + return data.ret; +} + + +struct cloneData { + virPoolObjTableCloneCallback callback; + int ret; + virPoolObjTablePtr dst; +}; + +static int +virPoolObjTableCloneIterator(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + virPoolObjPtr src =3D payload; + virPoolObjPtr dst =3D NULL; + struct cloneData *data =3D opaque; + void *def; + int ret =3D -1; + + virObjectLock(src); + + if (!(def =3D data->callback(src))) + goto error; + + if (!(dst =3D virPoolObjTableAdd(data->dst, src->pooldef->uuid, + src->pooldef->name, def, NULL, NULL, + src->defFreeFunc, NULL, 0))) + goto error; + def =3D NULL; + + ret =3D 0; + + cleanup: + src->defFreeFunc(def); + virObjectUnlock(dst); + virObjectUnlock(src); + return ret; + + error: + data->ret =3D -1; + goto cleanup; +} + + +/* virPoolObjTableClone: + * @src: Source table to perform a deep copy on + * @callback: Callback to create @def to be added into the cloned table. + * + * Make a deep copy of the object table including all objects and + * all defs within each hash table. This function does not use the + * assignFlags for the virPoolObjTableAdd[Locked] since generation + * of the cloned objects would be all considered new rather than + * assigning or redefining a definition. + * + * Returns: Cloned table or NULL + */ +virPoolObjTablePtr +virPoolObjTableClone(virPoolObjTablePtr src, + virPoolObjTableCloneCallback callback) +{ + struct cloneData data =3D { .callback =3D callback, + .ret =3D 0 }; + + virObjectLock(src); + if (!(data.dst =3D virPoolObjTableNew(src->type, src->hashStart, + src->nameOnly))) + goto cleanup; + + /* Clone both the UUID and Name table in the result */ + if (!src->nameOnly) + virHashForEach(src->objsUuid, virPoolObjTableCloneIterator, &data); + + virHashForEach(src->objsName, virPoolObjTableCloneIterator, &data); + + if (data.ret < 0) { + virObjectUnref(data.dst); + data.dst =3D NULL; + } + + cleanup: + virObjectUnlock(src); + return data.dst; +} + + +struct pruneData { + unsigned int flags; + virPoolObjMatchFilter matchfilter; +}; + +static int +pruneList(const void *payload, + const void *name ATTRIBUTE_UNUSED, + const void *opaque) +{ + virPoolObjPtr obj =3D (virPoolObjPtr) payload; + const struct pruneData *data =3D opaque; + int want =3D 0; + + virObjectLock(obj); + want =3D data->matchfilter(obj, data->flags); + virObjectUnlock(obj); + return want; +} + + +/** + * virPoolObjTablePrune: + * @poolobjs: Pool objects table + * @flags: bitwise-OR of flags to be prunedvirConnectListAllNetworksFlags + * + * Iterate over list of objects and remove the desired ones from the + * name and uuid (if exists) table + */ +void +virPoolObjTablePrune(virPoolObjTablePtr poolobjs, + virPoolObjMatchFilter matchfilter, + unsigned int flags) +{ + struct pruneData data =3D { .flags =3D flags, + .matchfilter =3D matchfilter }; + + virObjectLock(poolobjs); + if (!poolobjs->nameOnly) + virHashRemoveSet(poolobjs->objsUuid, pruneList, &data); + virHashRemoveSet(poolobjs->objsName, pruneList, &data); + virObjectUnlock(poolobjs); +} diff --git a/src/conf/virpoolobj.h b/src/conf/virpoolobj.h new file mode 100644 index 0000000..fcccb1e --- /dev/null +++ b/src/conf/virpoolobj.h @@ -0,0 +1,222 @@ +/* + * virpoolobj.h: internal pool objects handling + * + * Copyright (C) 2016 Red Hat, Inc. + * + * 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 __VIRPOOLOBJ_H__ +# define __VIRPOOLOBJ_H__ + +# include "internal.h" + +typedef enum { + VIR_POOLOBJTABLE_NODEDEVICE, + VIR_POOLOBJTABLE_INTERFACE, + VIR_POOLOBJTABLE_NWFILTER, + VIR_POOLOBJTABLE_VOLUME, + VIR_POOLOBJTABLE_BLOCK_STORAGE, + VIR_POOLOBJTABLE_SECRET, + VIR_POOLOBJTABLE_NETWORK, + VIR_POOLOBJTABLE_SNAPSHOT, + VIR_POOLOBJTABLE_DOMAIN, + + VIR_POOLOBJTABLE_LAST +} virPoolObjTableType; + +/* Some default hash table size start values */ +# define VIR_POOLOBJTABLE_NODEDEVICE_HASHSTART 50 +# define VIR_POOLOBJTABLE_INTERFACE_HASHSTART 10 +# define VIR_POOLOBJTABLE_NWFILTER_HASHSTART 20 +# define VIR_POOLOBJTABLE_VOLUME_HASHSTART 10 +# define VIR_POOLOBJTABLE_BLOCK_STORAGE_HASHSTART 20 +# define VIR_POOLOBJTABLE_SECRET_HASHSTART 20 +# define VIR_POOLOBJTABLE_NETWORK_HASHSTART 10 +# define VIR_POOLOBJTABLE_SNAPSHOT_HASHSTART 10 +# define VIR_POOLOBJTABLE_DOMAIN_HASHSTART 50 + +typedef struct _virPoolDef virPoolDef; +typedef virPoolDef *virPoolDefPtr; + +typedef struct _virPoolObj virPoolObj; +typedef virPoolObj *virPoolObjPtr; + +typedef struct _virPoolObjTable virPoolObjTable; +typedef virPoolObjTable *virPoolObjTablePtr; + + +/* virPoolObjTableAssignDef + */ +typedef int (*virPoolObjTableAssignDefFunc)(virPoolObjPtr obj, + void *newDef, + void *oldDef, + unsigned int flags); + +/* + * virPoolObjTableSearchIterator: + * @obj: the virPoolObj for the current table entry + * @opaque: opaque user data provided at registration + * + * The virPoolObjTableSearch[Ref] functions walk through the PoolObjTable + * hash table entries expecting the SearchIterator function to return true + * once the searched on criteria is met. + * + * It is forbidden to call any other libvirt APIs from an implementation + * of this callback, since it can be invoked from a context which is not + * re-entrant safe. Failure to abide by this requirement may lead to + * application deadlocks or crashes. + */ +typedef bool (*virPoolObjTableSearchIterator)(virPoolObjPtr obj, void *opa= que); +struct virPoolObjTableSearchIterData { + virPoolObjTableSearchIterator callback; + void *opaque; +}; + +/* + * virPoolObjACLFilter: + * Used by Collect and List API's in order filter results based on object = ACL + */ +typedef bool (*virPoolObjACLFilter)(virConnectPtr conn, void *objdef); + +/* + * virPoolObjMatchFilter: + * Used by Collect and List API's in order filter results based on caller + * specific criteria + */ +typedef bool (*virPoolObjMatchFilter)(virPoolObjPtr obj, unsigned int filt= er); + +/* + * virPoolObjTableListCallback: + * Similar to the Match filter except, passing an opaque handle allows the + * List function to alter/generate what data is collected/filtered + */ +typedef int (*virPoolObjTableListCallback)(virPoolObjPtr obj, void *opaque= ); +struct virPoolObjTableListIterData { + virConnectPtr conn; + virPoolObjACLFilter aclfilter; + virPoolObjTableListCallback callback; + void *opaque; + int ret; +}; + + +typedef void *(*virPoolObjTableCloneCallback)(virPoolObjPtr src); + +typedef void (*virPoolObjTableIteratorCallback)(virPoolObjPtr obj, + void *opaque); + + +virPoolObjPtr virPoolObjNew(virPoolDefPtr pooldef, + void *def, + void *newDef, + virFreeCallback defFreeFunc); + +void virPoolObjSetActive(virPoolObjPtr obj, bool active); + +void virPoolObjSetAutostart(virPoolObjPtr obj, bool autostart); + +void virPoolObjSetBeingRemoved(virPoolObjPtr obj, bool beingRemoved); + +void virPoolObjSetPersistent(virPoolObjPtr obj, bool persistent); + +void virPoolObjSetDef(virPoolObjPtr obj, void *def); + +void virPoolObjSetNewDef(virPoolObjPtr obj, void *newDef); + +void virPoolObjSetPrivateData(virPoolObjPtr obj, + void *privateData, + virFreeCallback privateDataFreeFunc); + +bool virPoolObjIsActive(const virPoolObj *obj); + +bool virPoolObjIsAutostart(const virPoolObj *obj); + +bool virPoolObjIsBeingRemoved(const virPoolObj *obj); + +bool virPoolObjIsPersistent(const virPoolObj *obj); + +void *virPoolObjGetDef(const virPoolObj *obj); + +void *virPoolObjGetNewDef(const virPoolObj *obj); + +void *virPoolObjGetPrivateData(const virPoolObj *obj); + +void virPoolObjEndAPI(virPoolObjPtr *obj); + +virPoolObjTablePtr virPoolObjTableNew(virPoolObjTableType type, + int hashStart, + bool nameOnly); + +virPoolObjPtr virPoolObjTableAdd(virPoolObjTablePtr poolobjs, + const char *new_uuidstr, + const char *new_name, + void *def, + void *newDef, + void *oldDef, + virFreeCallback defFreeFunc, + virPoolObjTableAssignDefFunc assignDefFun= c, + unsigned int assignFlags) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4) + ATTRIBUTE_NONNULL(7); + +void virPoolObjTableClearAll(virPoolObjTablePtr poolobjs); + +void virPoolObjTableRemove(virPoolObjTablePtr poolobjs, + virPoolObjPtr *obj); + +virPoolObjPtr virPoolObjTableFindByUUID(virPoolObjTablePtr poolobjs, + const unsigned char *uuid); + +virPoolObjPtr virPoolObjTableFindByUUIDRef(virPoolObjTablePtr poolobjs, + const unsigned char *uuid); + +virPoolObjPtr virPoolObjTableFindByName(virPoolObjTablePtr poolobjs, + const char *name); + +virPoolObjPtr virPoolObjTableSearch(virPoolObjTablePtr poolobjs, + virPoolObjTableSearchIterator callback, + void *opaque); + +virPoolObjPtr virPoolObjTableSearchRef(virPoolObjTablePtr poolobjs, + virPoolObjTableSearchIterator callb= ack, + void *opaque); + +void virPoolObjTableIterate(virPoolObjTablePtr src, + virPoolObjTableIteratorCallback callback, + void *opaque); + +int virPoolObjTableCollect(virPoolObjTablePtr poolobjs, + virConnectPtr conn, + virPoolObjPtr **objs, + size_t *nobjs, + virPoolObjACLFilter aclfilter, + virPoolObjMatchFilter matchfilter, + unsigned int flags); + +int virPoolObjTableList(virPoolObjTablePtr poolobjs, + virConnectPtr conn, + virPoolObjACLFilter aclfilter, + virPoolObjTableListCallback callback, + void *opaque); + +virPoolObjTablePtr virPoolObjTableClone(virPoolObjTablePtr src, + virPoolObjTableCloneCallback callb= ack); + +void virPoolObjTablePrune(virPoolObjTablePtr poolobjs, + virPoolObjMatchFilter matchfilter, + unsigned int flags); + +#endif /* __VIRPOOLOBJ_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6bbb36b..1f2157d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -961,6 +961,39 @@ virDomainObjListRemoveLocked; virDomainObjListRename; =20 =20 +# conf/virpoolobj.h +virPoolObjEndAPI; +virPoolObjGetDef; +virPoolObjGetNewDef; +virPoolObjGetPrivateData; +virPoolObjIsActive; +virPoolObjIsAutostart; +virPoolObjIsBeingRemoved; +virPoolObjIsPersistent; +virPoolObjNew; +virPoolObjSetActive; +virPoolObjSetAutostart; +virPoolObjSetBeingRemoved; +virPoolObjSetDef; +virPoolObjSetNewDef; +virPoolObjSetPersistent; +virPoolObjSetPrivateData; +virPoolObjTableAdd; +virPoolObjTableClearAll; +virPoolObjTableClone; +virPoolObjTableCollect; +virPoolObjTableFindByName; +virPoolObjTableFindByUUID; +virPoolObjTableFindByUUIDRef; +virPoolObjTableIterate; +virPoolObjTableList; +virPoolObjTableNew; +virPoolObjTablePrune; +virPoolObjTableRemove; +virPoolObjTableSearch; +virPoolObjTableSearchRef; + + # conf/virsecretobj.h virSecretLoadAllConfigs; virSecretObjDeleteConfig; diff --git a/src/util/virerror.c b/src/util/virerror.c index ef17fb5..5330fb2 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -139,6 +139,7 @@ VIR_ENUM_IMPL(virErrorDomain, VIR_ERR_DOMAIN_LAST, =20 "Perf", /* 65 */ "Libssh transport layer", + "Pool Object", ) =20 =20 --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 03:40:31 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.25 as permitted sender) client-ip=209.132.183.25; envelope-from=libvir-list-bounces@redhat.com; helo=mx4-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.25 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx4-phx2.redhat.com (mx4-phx2.redhat.com [209.132.183.25]) by mx.zohomail.com with SMTPS id 1486830900062620.6099945818252; Sat, 11 Feb 2017 08:35:00 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGUfIw031761; Sat, 11 Feb 2017 11:30:41 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGTq4W028521 for ; Sat, 11 Feb 2017 11:29:52 -0500 Received: from localhost.localdomain.com (ovpn-116-36.phx2.redhat.com [10.3.116.36]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGTmIn000660 for ; Sat, 11 Feb 2017 11:29:51 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Sat, 11 Feb 2017 11:29:39 -0500 Message-Id: <1486830585-23866-4-git-send-email-jferlan@redhat.com> In-Reply-To: <1486830585-23866-1-git-send-email-jferlan@redhat.com> References: <1486830585-23866-1-git-send-email-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH RFC 3/9] nodedev: Convert virNodeDevObj[List] to use virPoolObj[Table] 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" Use the virPoolObj[Table] object management model in order to manage the Node Device objects. While making the adjustments to use the new model, there are some code formatting adjustments that were also made with the goal to follow more recent code flow and layout. For API's that were static, rather than use "virNode*", some names were converted to be "node*" - makes it easier to determine while reading code what is local and what is "outside" the perveyance of the module. For the node_device_hal.c - removed the usage of privateData - it wasn't actually used anyway other than alloc()/free(). The NODE_DEV_UDI was never referenced. Signed-off-by: John Ferlan --- po/POTFILES.in | 1 + src/Makefile.am | 3 +- src/conf/node_device_conf.c | 497 +----------------------------- src/conf/node_device_conf.h | 85 +----- src/conf/virnodedeviceobj.c | 570 +++++++++++++++++++++++++++++++= ++++ src/conf/virnodedeviceobj.h | 86 ++++++ src/libvirt_private.syms | 25 +- src/node_device/node_device_driver.c | 388 ++++++++++-------------- src/node_device/node_device_driver.h | 2 +- src/node_device/node_device_hal.c | 82 ++--- src/node_device/node_device_udev.c | 76 +++-- src/test/test_driver.c | 294 +++++++----------- 12 files changed, 1032 insertions(+), 1077 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 95fa9a6..37379b5 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/virpoolobj.c src/conf/virsecretobj.c src/cpu/cpu.c diff --git a/src/Makefile.am b/src/Makefile.am index 03a8cf3..20ee73a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -392,7 +392,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 4d3268f..cfd576d 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -59,7 +59,7 @@ VIR_ENUM_IMPL(virNodeDevNetCap, VIR_NODE_DEV_CAP_NET_LAST, "80211") =20 static int -virNodeDevCapsDefParseString(const char *xpath, +nodeDeviceCapsDefParseString(const char *xpath, xmlXPathContextPtr ctxt, char **string) { @@ -72,173 +72,11 @@ 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; -} =20 - -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 virNodeDeviceDefFree(virNodeDeviceDefPtr def) +void +virNodeDeviceDefFree(void *opaque) { + virNodeDeviceDefPtr def =3D opaque; virNodeDevCapsDefPtr caps; =20 if (!def) @@ -263,82 +101,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, @@ -377,7 +139,9 @@ virPCIEDeviceInfoFormat(virBufferPtr buf, virBufferAddLit(buf, "\n"); } =20 -char *virNodeDeviceDefFormat(const virNodeDeviceDef *def) + +char * +virNodeDeviceDefFormat(const virNodeDeviceDef *def) { virBuffer buf =3D VIR_BUFFER_INITIALIZER; virNodeDevCapsDefPtr caps; @@ -1009,7 +773,7 @@ virNodeDevCapSCSIHostParseXML(xmlXPathContextPtr ctxt, orignode2 =3D ctxt->node; ctxt->node =3D nodes[i]; =20 - if (virNodeDevCapsDefParseString("string(./wwnn[1])", + if (nodeDeviceCapsDefParseString("string(./wwnn[1])", ctxt, &data->scsi_host.wwnn) < 0) { if (virRandomGenerateWWN(&data->scsi_host.wwnn, virt_type)= < 0) { @@ -1021,7 +785,7 @@ virNodeDevCapSCSIHostParseXML(xmlXPathContextPtr ctxt, } } =20 - if (virNodeDevCapsDefParseString("string(./wwpn[1])", + if (nodeDeviceCapsDefParseString("string(./wwpn[1])", ctxt, &data->scsi_host.wwpn) < 0) { if (virRandomGenerateWWN(&data->scsi_host.wwpn, virt_type)= < 0) { @@ -1872,132 +1636,6 @@ virNodeDeviceGetWWNs(virNodeDeviceDefPtr def, return ret; } =20 -/* - * Return the NPIV dev's parent device name - */ -/* virNodeDeviceFindFCParentHost: - * @parent: Pointer to node device object - * @parent_host: Pointer to return parent host number - * - * Search the capabilities for the device to find the FC capabilities - * in order to set the parent_host value. - * - * Returns: - * 0 on success with parent_host set, -1 otherwise; - */ -static int -virNodeDeviceFindFCParentHost(virNodeDeviceObjPtr parent, - int *parent_host) -{ - 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; - } - - *parent_host =3D cap->data.scsi_host.host; - return 0; -} - - -int -virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs, - const char *dev_name, - const char *parent_name, - int *parent_host) -{ - 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, parent_host); - - virNodeDeviceObjUnlock(parent); - - return ret; -} - - -int -virNodeDeviceGetParentHostByWWNs(virNodeDeviceObjListPtr devs, - const char *dev_name, - const char *parent_wwnn, - const char *parent_wwpn, - int *parent_host) -{ - 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, parent_host); - - virNodeDeviceObjUnlock(parent); - - return ret; -} - - -int -virNodeDeviceGetParentHostByFabricWWN(virNodeDeviceObjListPtr devs, - const char *dev_name, - const char *parent_fabric_wwn, - int *parent_host) -{ - 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, parent_host); - - virNodeDeviceObjUnlock(parent); - - return ret; -} - - -int -virNodeDeviceFindVportParentHost(virNodeDeviceObjListPtr devs, - int *parent_host) -{ - 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, parent_host); - - virNodeDeviceObjUnlock(parent); - - return ret; -} - =20 void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps) { @@ -2071,120 +1709,3 @@ void virNodeDevCapsDefFree(virNodeDevCapsDefPtr cap= s) =20 VIR_FREE(caps); } - - -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))) - 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))) { - 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/node_device_conf.h b/src/conf/node_device_conf.h index e1cdb1d..ec7f079 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 @@ -207,53 +205,6 @@ struct _virNodeDeviceDef { virNodeDevCapsDefPtr caps; /* optional device capabilities */ }; =20 - -typedef struct _virNodeDeviceObj virNodeDeviceObj; -typedef virNodeDeviceObj *virNodeDeviceObjPtr; -struct _virNodeDeviceObj { - virMutex lock; - - virNodeDeviceDefPtr def; /* device definition */ - void *privateData; /* driver-specific private data */ - void (*privateFree)(void *data); /* destructor for private data */ - -}; - -typedef struct _virNodeDeviceObjList virNodeDeviceObjList; -typedef virNodeDeviceObjList *virNodeDeviceObjListPtr; -struct _virNodeDeviceObjList { - size_t count; - 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); =20 virNodeDeviceDefPtr virNodeDeviceDefParseString(const char *str, @@ -271,36 +222,10 @@ int virNodeDeviceGetWWNs(virNodeDeviceDefPtr def, char **wwnn, char **wwpn); =20 -int virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs, - const char *dev_name, - const char *parent_name, - int *parent_host); - -int virNodeDeviceGetParentHostByWWNs(virNodeDeviceObjListPtr devs, - const char *dev_name, - const char *parent_wwnn, - const char *parent_wwpn, - int *parent_host); - -int virNodeDeviceGetParentHostByFabricWWN(virNodeDeviceObjListPtr devs, - const char *dev_name, - const char *parent_fabric_wwn, - int *parent_host); - -int virNodeDeviceFindVportParentHost(virNodeDeviceObjListPtr devs, - int *parent_host); - -void virNodeDeviceDefFree(virNodeDeviceDefPtr def); - -void virNodeDeviceObjFree(virNodeDeviceObjPtr dev); - -void virNodeDeviceObjListFree(virNodeDeviceObjListPtr devs); +void virNodeDeviceDefFree(void *opaque); =20 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 | \ @@ -315,12 +240,4 @@ void virNodeDeviceObjUnlock(virNodeDeviceObjPtr obj); VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPORTS | \ VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_GENERIC) =20 -typedef bool (*virNodeDeviceObjListFilter)(virConnectPtr conn, void *opaqu= e); - -int virNodeDeviceObjListExport(virConnectPtr conn, - virNodeDeviceObjList devobjs, - virNodeDevicePtr **devices, - virNodeDeviceObjListFilter filter, - unsigned int flags); - #endif /* __VIR_NODE_DEVICE_CONF_H__ */ diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c new file mode 100644 index 0000000..73a43ac --- /dev/null +++ b/src/conf/virnodedeviceobj.c @@ -0,0 +1,570 @@ +/* + * 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"); + +static int +nodeDeviceHasCap(const virNodeDeviceDef *def, + const char *cap) +{ + virNodeDevCapsDefPtr caps =3D 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; +} + + +/* nodeDeviceFindFCCapDef: + * @def: Node device definition + * + * Search the device object 'caps' array for fc_host capability. + * + * Returns: + * Pointer to the caps or NULL if not found + */ +static virNodeDevCapsDefPtr +nodeDeviceFindFCCapDef(const virNodeDeviceDef *def) +{ + virNodeDevCapsDefPtr caps =3D 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; +} + + +/* nodeDeviceFindVPORTCapDef: + * @def: Node device definition + * + * Search the device object 'caps' array for vport_ops capability. + * + * Returns: + * Pointer to the caps or NULL if not found + */ +static virNodeDevCapsDefPtr +nodeDeviceFindVPORTCapDef(const virNodeDeviceDef *def) +{ + virNodeDevCapsDefPtr caps =3D 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; +} + + +struct searchData { + const char *sysfs_path; + const char *cap; + const char *parent_wwnn; + const char *parent_wwpn; + const char *parent_fabric_wwn; +}; + + +static bool +searchBySysfsPath(virPoolObjPtr obj, + void *opaque) +{ + virNodeDeviceDefPtr def =3D virPoolObjGetDef(obj); + struct searchData *data =3D opaque; + + if (STREQ_NULLABLE(def->sysfs_path, data->sysfs_path)) + return true; + + return false; +} + + +static bool +searchByCap(virPoolObjPtr obj, + void *opaque) +{ + virNodeDeviceDefPtr def =3D virPoolObjGetDef(obj); + struct searchData *data =3D opaque; + + if (nodeDeviceHasCap(def, data->cap)) + return true; + + return false; +} + + +static bool +searchByWWNs(virPoolObjPtr obj, + void *opaque) +{ + virNodeDeviceDefPtr def =3D virPoolObjGetDef(obj); + struct searchData *data =3D opaque; + virNodeDevCapsDefPtr cap; + + if ((cap =3D nodeDeviceFindFCCapDef(def)) && + STREQ_NULLABLE(cap->data.scsi_host.wwnn, data->parent_wwnn) && + STREQ_NULLABLE(cap->data.scsi_host.wwpn, data->parent_wwpn)) + return true; + + return false; +} + + +static bool +searchByFabricWWN(virPoolObjPtr obj, + void *opaque) +{ + virNodeDeviceDefPtr def =3D virPoolObjGetDef(obj); + struct searchData *data =3D opaque; + virNodeDevCapsDefPtr cap; + + if ((cap =3D nodeDeviceFindFCCapDef(def)) && + STREQ_NULLABLE(cap->data.scsi_host.fabric_wwn, data->parent_fabric= _wwn)) + return true; + + return false; +} + + +/* virNodeDeviceObjFindBy{SysfsPath|Cap|WWNs|FabricWWN} + * @devs: Pointer to pool object table + * + * API specific: + * @sysfs_path: Sysfs path to search + * @cap: Capability name to search + * @wwnn & @wwpn: WWNN & WWPN name to search + * @fabric_wwn: Fabric_WWN to search + * + * Search by API specific argument in the table to return a pool object + * matching the argument specifics + * + * Returns: NULL if not found, a locked and ref'd object reference that + * needs a virPoolObjEndAPI to clear + */ +virPoolObjPtr +virNodeDeviceObjFindBySysfsPath(virPoolObjTablePtr devs, + const char *sysfs_path) +{ + struct searchData data =3D { .sysfs_path =3D sysfs_path }; + + return virPoolObjTableSearchRef(devs, searchBySysfsPath, &data); +} + + +static virPoolObjPtr +nodeDeviceFindByCap(virPoolObjTablePtr devs, + const char *cap) +{ + struct searchData data =3D { .cap =3D cap }; + + return virPoolObjTableSearchRef(devs, searchByCap, &data); +} + + +static virPoolObjPtr +nodeDeviceFindByWWNs(virPoolObjTablePtr devs, + const char *parent_wwnn, + const char *parent_wwpn) +{ + struct searchData data =3D { .parent_wwnn =3D parent_wwnn, + .parent_wwpn =3D parent_wwpn }; + + return virPoolObjTableSearchRef(devs, searchByWWNs, &data); +} + + +static virPoolObjPtr +nodeDeviceFindByFabricWWN(virPoolObjTablePtr devs, + const char *parent_fabric_wwn) +{ + struct searchData data =3D { .parent_fabric_wwn =3D parent_fabric_wwn = }; + + return virPoolObjTableSearchRef(devs, searchByFabricWWN, &data); +} + + +/* + * Return the NPIV dev's parent device name + */ +/* nodeDeviceFindFCParentHost: + * @def: Pointer to node device def + * @parent_host: Pointer to return parent host number + * + * Search the capabilities for the device to find the FC capabilities + * in order to set the parent_host value. + * + * Returns: + * 0 on success with parent_host set, -1 otherwise; + */ +static int +nodeDeviceFindFCParentHost(const virNodeDeviceDef *def, + int *parent_host) +{ + virNodeDevCapsDefPtr cap =3D nodeDeviceFindVPORTCapDef(def); + + if (!cap) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Parent device %s is not capable " + "of vport operations"), + def->name); + return -1; + } + + *parent_host =3D cap->data.scsi_host.host; + return 0; +} + + +int +virNodeDeviceObjGetParentHost(virPoolObjTablePtr devs, + const char *dev_name, + const char *parent_name, + int *parent_host) +{ + virPoolObjPtr obj; + virNodeDeviceDefPtr def; + int ret; + + if (!(obj =3D virPoolObjTableFindByName(devs, parent_name))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find parent device for '%s'"), + dev_name); + return -1; + } + def =3D virPoolObjGetDef(obj); + + ret =3D nodeDeviceFindFCParentHost(def, parent_host); + + virPoolObjEndAPI(&obj); + return ret; +} + + +int +virNodeDeviceObjGetParentHostByWWNs(virPoolObjTablePtr devs, + const char *dev_name, + const char *parent_wwnn, + const char *parent_wwpn, + int *parent_host) +{ + virPoolObjPtr obj =3D NULL; + virNodeDeviceDefPtr def; + int ret; + + if (!(obj =3D nodeDeviceFindByWWNs(devs, parent_wwnn, parent_wwpn))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find parent device for '%s'"), + dev_name); + return -1; + } + def =3D virPoolObjGetDef(obj); + + ret =3D nodeDeviceFindFCParentHost(def, parent_host); + + virPoolObjEndAPI(&obj); + + return ret; +} + + +int +virNodeDeviceObjGetParentHostByFabricWWN(virPoolObjTablePtr devs, + const char *dev_name, + const char *parent_fabric_wwn, + int *parent_host) +{ + virPoolObjPtr obj; + virNodeDeviceDefPtr def; + int ret; + + if (!(obj =3D nodeDeviceFindByFabricWWN(devs, parent_fabric_wwn))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not find parent device for '%s'"), + dev_name); + return -1; + } + def =3D virPoolObjGetDef(obj); + + ret =3D nodeDeviceFindFCParentHost(def, parent_host); + + virPoolObjEndAPI(&obj); + + return ret; +} + + +int +virNodeDeviceObjFindVportParentHost(virPoolObjTablePtr devs, + int *parent_host) +{ + virPoolObjPtr obj; + virNodeDeviceDefPtr def; + const char *cap =3D virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS); + int ret; + + if (!(obj =3D nodeDeviceFindByCap(devs, cap))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not find any vport capable device")); + return -1; + } + def =3D virPoolObjGetDef(obj); + + ret =3D nodeDeviceFindFCParentHost(def, parent_host); + + virPoolObjEndAPI(&obj); + return ret; +} + + +static bool +nodeDeviceCapMatch(virPoolObjPtr obj, + int type) +{ + virNodeDeviceDefPtr def =3D virPoolObjGetDef(obj); + virNodeDevCapsDefPtr cap =3D NULL; + + for (cap =3D 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; +} + + +virPoolObjPtr +virNodeDeviceObjFindByName(virPoolObjTablePtr devobjs, + const char *name) +{ + virPoolObjPtr obj; + + if (!(obj =3D virPoolObjTableFindByName(devobjs, name))) + virReportError(VIR_ERR_NO_NODE_DEVICE, + _("no node device with matching name '%s'"), + name); + + return obj; +} + + +struct nodeCountData { + const char *cap; + int count; +}; + +static int +nodeCount(virPoolObjPtr obj, + void *opaque) +{ + virNodeDeviceDefPtr def =3D virPoolObjGetDef(obj); + struct nodeCountData *data =3D opaque; + + if (!data->cap || nodeDeviceHasCap(def, data->cap)) + data->count++; + + return 0; +} + + +int +virNodeDeviceObjNumOfDevices(virPoolObjTablePtr devobjs, + virConnectPtr conn, + const char *cap, + virPoolObjACLFilter aclfilter) +{ + struct nodeCountData data =3D { .cap =3D cap, + .count =3D 0 }; + + if (virPoolObjTableList(devobjs, conn, aclfilter, nodeCount, &data) < = 0) + return 0; + + return data.count; +} + + +struct nodedevNameData { + const char *cap; + int nnames; + char **const names; + int maxnames; +}; + +static int +nodedevGetNames(virPoolObjPtr obj, + void *opaque) +{ + virNodeDeviceDefPtr def =3D virPoolObjGetDef(obj); + struct nodedevNameData *data =3D opaque; + + if (data->nnames < data->maxnames) { + if (!data->cap || nodeDeviceHasCap(def, data->cap)) { + if (VIR_STRDUP(data->names[data->nnames++], def->name) < 0) + return -1; + } + } + return 0; +} + + +int +virNodeDeviceObjGetNames(virPoolObjTablePtr devobjs, + virConnectPtr conn, + virPoolObjACLFilter aclfilter, + const char *cap, + char **const names, + int maxnames) +{ + struct nodedevNameData data =3D { .cap =3D cap, + .nnames =3D 0, + .names =3D names, + .maxnames =3D maxnames }; + + if (virPoolObjTableList(devobjs, conn, aclfilter, + nodedevGetNames, &data) < 0) + goto failure; + + return data.nnames; + + failure: + while (--data.nnames >=3D 0) + VIR_FREE(names[data.nnames]); + return -1; +} + + +#define MATCH(FLAG) ((flags & (VIR_CONNECT_LIST_NODE_DEVICES_CAP_ ## FLAG)= ) && \ + nodeDeviceCapMatch(obj, VIR_NODE_DEV_CAP_ ## FLAG)) +static bool +nodeDeviceMatchFilter(virPoolObjPtr obj, + 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))) + return false; + } + + return true; +} +#undef MATCH + + +int +virNodeDeviceObjExportList(virConnectPtr conn, + virPoolObjTablePtr devobjs, + virNodeDevicePtr **devices, + virPoolObjACLFilter aclfilter, + unsigned int flags) +{ + virPoolObjPtr *objs =3D NULL; + virNodeDevicePtr *devs =3D NULL; + size_t nobjs =3D 0; + int ret =3D -1; + size_t i; + + if (virPoolObjTableCollect(devobjs, conn, &objs, &nobjs, aclfilter, + nodeDeviceMatchFilter, flags) < 0) + return -1; + + if (devices) { + if (VIR_ALLOC_N(devs, nobjs + 1) < 0) + goto cleanup; + + for (i =3D 0; i < nobjs; i++) { + virPoolObjPtr obj =3D objs[i]; + virNodeDeviceDefPtr def; + + virObjectLock(obj); + def =3D virPoolObjGetDef(obj); + devs[i] =3D virGetNodeDevice(conn, def->name); + virObjectUnlock(obj); + + if (!devs[i]) + goto cleanup; + } + + *devices =3D devs; + devs =3D NULL; + } + + ret =3D nobjs; + + cleanup: + virObjectListFree(devs); + virObjectListFreeCount(objs, nobjs); + return ret; +} diff --git a/src/conf/virnodedeviceobj.h b/src/conf/virnodedeviceobj.h new file mode 100644 index 0000000..3359211 --- /dev/null +++ b/src/conf/virnodedeviceobj.h @@ -0,0 +1,86 @@ +/* + * 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 "virpoolobj.h" +# include "virthread.h" + +# include "object_event.h" + + +typedef struct _virNodeDeviceDriverState virNodeDeviceDriverState; +typedef virNodeDeviceDriverState *virNodeDeviceDriverStatePtr; +struct _virNodeDeviceDriverState { + virMutex lock; + + virPoolObjTablePtr devs; /* currently-known devices */ + void *privateData; /* driver-specific private data */ + + /* Immutable pointer, self-locking APIs */ + virObjectEventStatePtr nodeDeviceEventState; +}; + +virPoolObjPtr virNodeDeviceObjFindBySysfsPath(virPoolObjTablePtr devs, + const char *sysfs_path) + ATTRIBUTE_NONNULL(2); + +int virNodeDeviceObjGetParentHost(virPoolObjTablePtr devs, + const char *dev_name, + const char *parent_name, + int *parent_host); + +int virNodeDeviceObjGetParentHostByWWNs(virPoolObjTablePtr devs, + const char *dev_name, + const char *parent_wwnn, + const char *parent_wwpn, + int *parent_host); + +int virNodeDeviceObjGetParentHostByFabricWWN(virPoolObjTablePtr devs, + const char *dev_name, + const char *parent_fabric_wwn, + int *parent_host); + +int virNodeDeviceObjFindVportParentHost(virPoolObjTablePtr devs, + int *parent_host); + +virPoolObjPtr virNodeDeviceObjFindByName(virPoolObjTablePtr devobjs, + const char *name); + +int virNodeDeviceObjNumOfDevices(virPoolObjTablePtr devobjs, + virConnectPtr conn, + const char *cap, + virPoolObjACLFilter aclfilter); + +int virNodeDeviceObjGetNames(virPoolObjTablePtr devobjs, + virConnectPtr conn, + virPoolObjACLFilter aclfilter, + const char *cap, + char **const names, + int maxnames); + +int virNodeDeviceObjExportList(virConnectPtr conn, + virPoolObjTablePtr devobjs, + virNodeDevicePtr **devices, + virPoolObjACLFilter aclfilter, + unsigned int flags); + +#endif /* __VIRNODEDEVICEOBJ_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1f2157d..98b3840 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -694,25 +694,12 @@ virNetDevIPRouteParseXML; virNodeDevCapsDefFree; virNodeDevCapTypeFromString; virNodeDevCapTypeToString; -virNodeDeviceAssignDef; virNodeDeviceDefFormat; virNodeDeviceDefFree; virNodeDeviceDefParseFile; virNodeDeviceDefParseNode; virNodeDeviceDefParseString; -virNodeDeviceFindByName; -virNodeDeviceFindBySysfsPath; -virNodeDeviceFindVportParentHost; -virNodeDeviceGetParentHost; -virNodeDeviceGetParentHostByFabricWWN; -virNodeDeviceGetParentHostByWWNs; virNodeDeviceGetWWNs; -virNodeDeviceHasCap; -virNodeDeviceObjListExport; -virNodeDeviceObjListFree; -virNodeDeviceObjLock; -virNodeDeviceObjRemove; -virNodeDeviceObjUnlock; =20 =20 # conf/node_device_event.h @@ -961,6 +948,18 @@ virDomainObjListRemoveLocked; virDomainObjListRename; =20 =20 +# conf/virnodedeviceobj.h +virNodeDeviceObjExportList; +virNodeDeviceObjFindByName; +virNodeDeviceObjFindBySysfsPath; +virNodeDeviceObjFindVportParentHost; +virNodeDeviceObjGetNames; +virNodeDeviceObjGetParentHost; +virNodeDeviceObjGetParentHostByFabricWWN; +virNodeDeviceObjGetParentHostByWWNs; +virNodeDeviceObjNumOfDevices; + + # conf/virpoolobj.h virPoolObjEndAPI; virPoolObjGetDef; diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_de= vice_driver.c index 5238e23..f7e460c 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -42,19 +42,22 @@ #include "virutil.h" #include "viraccessapicheck.h" #include "virnetdev.h" +#include "virpoolobj.h" =20 #define VIR_FROM_THIS VIR_FROM_NODEDEV =20 virNodeDeviceDriverStatePtr driver; =20 -static int update_caps(virNodeDeviceObjPtr dev) +static int +update_caps(virPoolObjPtr obj) { - virNodeDevCapsDefPtr cap =3D dev->def->caps; + virNodeDeviceDefPtr def =3D virPoolObjGetDef(obj); + virNodeDevCapsDefPtr cap =3D def->caps; =20 while (cap) { switch (cap->data.type) { case VIR_NODE_DEV_CAP_SCSI_HOST: - nodeDeviceSysfsGetSCSIHostCaps(&dev->def->caps->data); + nodeDeviceSysfsGetSCSIHostCaps(&def->caps->data); break; case VIR_NODE_DEV_CAP_NET: if (virNetDevGetLinkInfo(cap->data.net.ifname, &cap->data.net.= lnk) < 0) @@ -64,8 +67,8 @@ static int update_caps(virNodeDeviceObjPtr dev) return -1; break; case VIR_NODE_DEV_CAP_PCI_DEV: - if (nodeDeviceSysfsGetPCIRelatedDevCaps(dev->def->sysfs_path, - &dev->def->caps->data) = < 0) + if (nodeDeviceSysfsGetPCIRelatedDevCaps(def->sysfs_path, + &def->caps->data) < 0) return -1; break; =20 @@ -100,16 +103,18 @@ static int update_caps(virNodeDeviceObjPtr dev) * the driver name for a device each time its entry is used, both for * udev *and* HAL backends. */ -static int update_driver_name(virNodeDeviceObjPtr dev) +static int +update_driver_name(virPoolObjPtr obj) { + virNodeDeviceDefPtr def =3D virPoolObjGetDef(obj); char *driver_link =3D NULL; char *devpath =3D NULL; char *p; int ret =3D -1; =20 - VIR_FREE(dev->def->driver); + VIR_FREE(def->driver); =20 - if (virAsprintf(&driver_link, "%s/driver", dev->def->sysfs_path) < 0) + if (virAsprintf(&driver_link, "%s/driver", def->sysfs_path) < 0) goto cleanup; =20 /* Some devices don't have an explicit driver, so just return @@ -126,7 +131,7 @@ static int update_driver_name(virNodeDeviceObjPtr dev) } =20 p =3D strrchr(devpath, '/'); - if (p && VIR_STRDUP(dev->def->driver, p + 1) < 0) + if (p && VIR_STRDUP(def->driver, p + 1) < 0) goto cleanup; ret =3D 0; =20 @@ -137,7 +142,7 @@ static int update_driver_name(virNodeDeviceObjPtr dev) } #else /* XXX: Implement me for non-linux */ -static int update_driver_name(virNodeDeviceObjPtr dev ATTRIBUTE_UNUSED) +static int update_driver_name(virPoolObjPtr obj ATTRIBUTE_UNUSED) { return 0; } @@ -153,74 +158,41 @@ void nodeDeviceUnlock(void) virMutexUnlock(&driver->lock); } =20 +/* Node device implementations */ + int nodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags) { - int ndevs =3D 0; - size_t i; + virCheckFlags(0, -1); =20 if (virNodeNumOfDevicesEnsureACL(conn) < 0) return -1; =20 - virCheckFlags(0, -1); - - nodeDeviceLock(); - for (i =3D 0; i < driver->devs.count; i++) { - virNodeDeviceObjPtr obj =3D driver->devs.objs[i]; - virNodeDeviceObjLock(obj); - if (virNodeNumOfDevicesCheckACL(conn, obj->def) && - ((cap =3D=3D NULL) || - virNodeDeviceHasCap(obj, cap))) - ++ndevs; - virNodeDeviceObjUnlock(obj); - } - nodeDeviceUnlock(); - - return ndevs; + return virNodeDeviceObjNumOfDevices(driver->devs, conn, cap, + virNodeNumOfDevicesCheckACL); } =20 + int nodeListDevices(virConnectPtr conn, const char *cap, - char **const names, int maxnames, + char **const names, + int maxnames, unsigned int flags) { - int ndevs =3D 0; - size_t i; + virCheckFlags(0, -1); =20 if (virNodeListDevicesEnsureACL(conn) < 0) return -1; =20 - virCheckFlags(0, -1); - - nodeDeviceLock(); - for (i =3D 0; i < driver->devs.count && ndevs < maxnames; i++) { - virNodeDeviceObjPtr obj =3D driver->devs.objs[i]; - virNodeDeviceObjLock(obj); - if (virNodeListDevicesCheckACL(conn, obj->def) && - (cap =3D=3D NULL || - virNodeDeviceHasCap(obj, cap))) { - if (VIR_STRDUP(names[ndevs++], obj->def->name) < 0) { - virNodeDeviceObjUnlock(obj); - goto failure; - } - } - virNodeDeviceObjUnlock(obj); - } - nodeDeviceUnlock(); - - return ndevs; - - failure: - nodeDeviceUnlock(); - --ndevs; - while (--ndevs >=3D 0) - VIR_FREE(names[ndevs]); - return -1; + return virNodeDeviceObjGetNames(driver->devs, conn, + virNodeListDevicesCheckACL, + cap, names, maxnames); } =20 + int nodeConnectListAllNodeDevices(virConnectPtr conn, virNodeDevicePtr **devices, @@ -233,89 +205,92 @@ nodeConnectListAllNodeDevices(virConnectPtr conn, if (virConnectListAllNodeDevicesEnsureACL(conn) < 0) return -1; =20 - nodeDeviceLock(); - ret =3D virNodeDeviceObjListExport(conn, driver->devs, devices, + ret =3D virNodeDeviceObjExportList(conn, driver->devs, devices, virConnectListAllNodeDevicesCheckACL, flags); - nodeDeviceUnlock(); return ret; } =20 + virNodeDevicePtr nodeDeviceLookupByName(virConnectPtr conn, const char *name) { - virNodeDeviceObjPtr obj; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; virNodeDevicePtr ret =3D NULL; =20 - nodeDeviceLock(); - obj =3D virNodeDeviceFindByName(&driver->devs, name); - nodeDeviceUnlock(); - - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - name); - goto cleanup; - } + if (!(obj =3D virNodeDeviceObjFindByName(driver->devs, name))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - if (virNodeDeviceLookupByNameEnsureACL(conn, obj->def) < 0) + if (virNodeDeviceLookupByNameEnsureACL(conn, def) < 0) goto cleanup; =20 ret =3D virGetNodeDevice(conn, name); =20 cleanup: - if (obj) - virNodeDeviceObjUnlock(obj); + virPoolObjEndAPI(&obj); return ret; } =20 =20 +struct nodeDeviceSearchData { + const char *wwnn; + const char *wwpn; +}; + +static bool +nodeLookupSCSIHostByWWN(virPoolObjPtr obj, + void *opaque) +{ + virNodeDeviceDefPtr def =3D virPoolObjGetDef(obj); + struct nodeDeviceSearchData *data =3D opaque; + virNodeDevCapsDefPtr cap; + + for (cap =3D def->caps; cap; cap =3D cap->next) { + if (cap->data.type !=3D VIR_NODE_DEV_CAP_SCSI_HOST) + continue; + + nodeDeviceSysfsGetSCSIHostCaps(&cap->data); + if (cap->data.scsi_host.flags & + VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) { + if (STREQ(cap->data.scsi_host.wwnn, data->wwnn) && + STREQ(cap->data.scsi_host.wwpn, data->wwpn)) { + return true; + } + } + } + + return false; +} + + virNodeDevicePtr nodeDeviceLookupSCSIHostByWWN(virConnectPtr conn, const char *wwnn, const char *wwpn, unsigned int flags) { - size_t i; - virNodeDeviceObjListPtr devs =3D &driver->devs; - virNodeDevCapsDefPtr cap =3D NULL; - virNodeDeviceObjPtr obj =3D NULL; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; virNodeDevicePtr dev =3D NULL; + struct nodeDeviceSearchData data =3D { .wwnn =3D wwnn, + .wwpn =3D wwpn }; =20 virCheckFlags(0, NULL); =20 - nodeDeviceLock(); + if (!(obj =3D virPoolObjTableSearchRef(driver->devs, nodeLookupSCSIHos= tByWWN, + &data))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - for (i =3D 0; i < devs->count; i++) { - obj =3D devs->objs[i]; - virNodeDeviceObjLock(obj); - cap =3D obj->def->caps; - - while (cap) { - if (cap->data.type =3D=3D VIR_NODE_DEV_CAP_SCSI_HOST) { - nodeDeviceSysfsGetSCSIHostCaps(&cap->data); - if (cap->data.scsi_host.flags & - VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) { - if (STREQ(cap->data.scsi_host.wwnn, wwnn) && - STREQ(cap->data.scsi_host.wwpn, wwpn)) { - - if (virNodeDeviceLookupSCSIHostByWWNEnsureACL(conn= , obj->def) < 0) - goto out; - - dev =3D virGetNodeDevice(conn, obj->def->name); - virNodeDeviceObjUnlock(obj); - goto out; - } - } - } - cap =3D cap->next; - } + if (virNodeDeviceLookupSCSIHostByWWNEnsureACL(conn, def) < 0) + goto cleanup; =20 - virNodeDeviceObjUnlock(obj); - } + dev =3D virGetNodeDevice(conn, def->name); =20 - out: - nodeDeviceUnlock(); + cleanup: + virPoolObjEndAPI(&obj); return dev; } =20 @@ -324,34 +299,27 @@ char * nodeDeviceGetXMLDesc(virNodeDevicePtr dev, unsigned int flags) { - virNodeDeviceObjPtr obj; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; char *ret =3D NULL; =20 virCheckFlags(0, NULL); =20 - nodeDeviceLock(); - obj =3D virNodeDeviceFindByName(&driver->devs, dev->name); - nodeDeviceUnlock(); - - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - dev->name); - goto cleanup; - } + if (!(obj =3D virNodeDeviceObjFindByName(driver->devs, dev->name))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - if (virNodeDeviceGetXMLDescEnsureACL(dev->conn, obj->def) < 0) + if (virNodeDeviceGetXMLDescEnsureACL(dev->conn, def) < 0) goto cleanup; =20 update_driver_name(obj); if (update_caps(obj) < 0) goto cleanup; =20 - ret =3D virNodeDeviceDefFormat(obj->def); + ret =3D virNodeDeviceDefFormat(def); =20 cleanup: - if (obj) - virNodeDeviceObjUnlock(obj); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -359,25 +327,19 @@ nodeDeviceGetXMLDesc(virNodeDevicePtr dev, char * nodeDeviceGetParent(virNodeDevicePtr dev) { - virNodeDeviceObjPtr obj; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; char *ret =3D NULL; =20 - nodeDeviceLock(); - obj =3D virNodeDeviceFindByName(&driver->devs, dev->name); - nodeDeviceUnlock(); - - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - dev->name); - goto cleanup; - } + if (!(obj =3D virNodeDeviceObjFindByName(driver->devs, dev->name))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - if (virNodeDeviceGetParentEnsureACL(dev->conn, obj->def) < 0) + if (virNodeDeviceGetParentEnsureACL(dev->conn, def) < 0) goto cleanup; =20 - if (obj->def->parent) { - if (VIR_STRDUP(ret, obj->def->parent) < 0) + if (def->parent) { + if (VIR_STRDUP(ret, def->parent) < 0) goto cleanup; } else { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -385,8 +347,7 @@ nodeDeviceGetParent(virNodeDevicePtr dev) } =20 cleanup: - if (obj) - virNodeDeviceObjUnlock(obj); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -394,26 +355,20 @@ nodeDeviceGetParent(virNodeDevicePtr dev) int nodeDeviceNumOfCaps(virNodeDevicePtr dev) { - virNodeDeviceObjPtr obj; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; virNodeDevCapsDefPtr caps; int ncaps =3D 0; int ret =3D -1; =20 - nodeDeviceLock(); - obj =3D virNodeDeviceFindByName(&driver->devs, dev->name); - nodeDeviceUnlock(); - - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - dev->name); - goto cleanup; - } + if (!(obj =3D virNodeDeviceObjFindByName(driver->devs, dev->name))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNodeDeviceNumOfCapsEnsureACL(dev->conn, obj->def) < 0) + if (virNodeDeviceNumOfCapsEnsureACL(dev->conn, def) < 0) goto cleanup; =20 - for (caps =3D obj->def->caps; caps; caps =3D caps->next) { + for (caps =3D def->caps; caps; caps =3D caps->next) { ++ncaps; =20 if (caps->data.type =3D=3D VIR_NODE_DEV_CAP_SCSI_HOST) { @@ -430,36 +385,32 @@ nodeDeviceNumOfCaps(virNodeDevicePtr dev) ret =3D ncaps; =20 cleanup: - if (obj) - virNodeDeviceObjUnlock(obj); + virPoolObjEndAPI(&obj); return ret; } =20 =20 int -nodeDeviceListCaps(virNodeDevicePtr dev, char **const names, int maxnames) +nodeDeviceListCaps(virNodeDevicePtr dev, + char **const names, + int maxnames) { - virNodeDeviceObjPtr obj; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; virNodeDevCapsDefPtr caps; int ncaps =3D 0; int ret =3D -1; =20 - nodeDeviceLock(); - obj =3D virNodeDeviceFindByName(&driver->devs, dev->name); - nodeDeviceUnlock(); - - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - dev->name); - goto cleanup; - } + if (!(obj =3D virNodeDeviceObjFindByName(driver->devs, dev->name))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNodeDeviceListCapsEnsureACL(dev->conn, obj->def) < 0) + if (virNodeDeviceListCapsEnsureACL(dev->conn, def) < 0) goto cleanup; =20 - for (caps =3D obj->def->caps; caps && ncaps < maxnames; caps =3D caps-= >next) { - if (VIR_STRDUP(names[ncaps++], virNodeDevCapTypeToString(caps->dat= a.type)) < 0) + for (caps =3D def->caps; caps && ncaps < maxnames; caps =3D caps->next= ) { + if (VIR_STRDUP(names[ncaps++], + virNodeDevCapTypeToString(caps->data.type)) < 0) goto cleanup; =20 if (caps->data.type =3D=3D VIR_NODE_DEV_CAP_SCSI_HOST) { @@ -483,8 +434,7 @@ nodeDeviceListCaps(virNodeDevicePtr dev, char **const n= ames, int maxnames) ret =3D ncaps; =20 cleanup: - if (obj) - virNodeDeviceObjUnlock(obj); + virPoolObjEndAPI(&obj); if (ret =3D=3D -1) { --ncaps; while (--ncaps >=3D 0) @@ -573,9 +523,7 @@ nodeDeviceCreateXML(virConnectPtr conn, virt_type =3D virConnectGetType(conn); =20 nodeDeviceLock(); - - def =3D virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, virt_type); - if (def =3D=3D NULL) + if (!(def =3D virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, virt= _type))) goto cleanup; =20 if (virNodeDeviceCreateXMLEnsureACL(conn, def) < 0) @@ -585,36 +533,35 @@ nodeDeviceCreateXML(virConnectPtr conn, goto cleanup; =20 if (def->parent) { - if (virNodeDeviceGetParentHost(&driver->devs, - def->name, - def->parent, - &parent_host) < 0) + if (virNodeDeviceObjGetParentHost(driver->devs, + def->name, + def->parent, + &parent_host) < 0) goto cleanup; } else if (def->parent_wwnn && def->parent_wwpn) { - if (virNodeDeviceGetParentHostByWWNs(&driver->devs, - def->name, - def->parent_wwnn, - def->parent_wwpn, - &parent_host) < 0) + if (virNodeDeviceObjGetParentHostByWWNs(driver->devs, + def->name, + def->parent_wwnn, + def->parent_wwpn, + &parent_host) < 0) goto cleanup; } else if (def->parent_fabric_wwn) { - if (virNodeDeviceGetParentHostByFabricWWN(&driver->devs, - def->name, - def->parent_fabric_wwn, - &parent_host) < 0) + if (virNodeDeviceObjGetParentHostByFabricWWN(driver->devs, + def->name, + def->parent_fabric_ww= n, + &parent_host) < 0) goto cleanup; } else { /* Try to find a vport capable scsi_host when no parent supplied */ - if (virNodeDeviceFindVportParentHost(&driver->devs, &parent_host) = < 0) + if (virNodeDeviceObjFindVportParentHost(driver->devs, &parent_host= ) < 0) goto cleanup; } =20 if (virManageVport(parent_host, wwpn, wwnn, - VPORT_CREATE) =3D=3D -1) { + VPORT_CREATE) =3D=3D -1) goto cleanup; - } =20 dev =3D find_new_device(conn, wwnn, wwpn); /* We don't check the return value, because one way or another, @@ -638,64 +585,45 @@ int nodeDeviceDestroy(virNodeDevicePtr dev) { int ret =3D -1; - virNodeDeviceObjPtr obj =3D NULL; - char *parent_name =3D NULL, *wwnn =3D NULL, *wwpn =3D NULL; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; + char *wwnn =3D NULL; + char *wwpn =3D NULL; int parent_host =3D -1; =20 - nodeDeviceLock(); - obj =3D virNodeDeviceFindByName(&driver->devs, dev->name); - nodeDeviceUnlock(); - - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - dev->name); - goto out; - } - - if (virNodeDeviceDestroyEnsureACL(dev->conn, obj->def) < 0) - goto out; + if (!(obj =3D virNodeDeviceObjFindByName(driver->devs, dev->name))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNodeDeviceGetWWNs(obj->def, &wwnn, &wwpn) =3D=3D -1) - goto out; + if (virNodeDeviceDestroyEnsureACL(dev->conn, def) < 0) + goto cleanup; =20 + if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) =3D=3D -1) + goto cleanup; =20 - /* virNodeDeviceGetParentHost will cause the device object's lock to be - * taken, so we have to dup the parent's name and drop the lock - * before calling it. We don't need the reference to the object - * any more once we have the parent's name. */ - if (VIR_STRDUP(parent_name, obj->def->parent) < 0) { - virNodeDeviceObjUnlock(obj); - obj =3D NULL; - goto out; - } - virNodeDeviceObjUnlock(obj); - obj =3D NULL; - - if (virNodeDeviceGetParentHost(&driver->devs, - dev->name, - parent_name, - &parent_host) =3D=3D -1) { - goto out; - } + if (virNodeDeviceObjGetParentHost(driver->devs, + dev->name, + def->parent, + &parent_host) =3D=3D -1) + goto cleanup; =20 if (virManageVport(parent_host, wwpn, wwnn, - VPORT_DELETE) =3D=3D -1) { - goto out; - } + VPORT_DELETE) =3D=3D -1) + goto cleanup; + + virPoolObjTableRemove(driver->devs, &obj); =20 ret =3D 0; - out: - if (obj) - virNodeDeviceObjUnlock(obj); - VIR_FREE(parent_name); + cleanup: + virPoolObjEndAPI(&obj); VIR_FREE(wwnn); VIR_FREE(wwpn); return ret; } =20 + int nodeConnectNodeDeviceEventRegisterAny(virConnectPtr conn, virNodeDevicePtr dev, 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/node_device/node_device_hal.c b/src/node_device/node_devic= e_hal.c index fb7bf25..70c37c9 100644 --- a/src/node_device/node_device_hal.c +++ b/src/node_device/node_device_hal.c @@ -52,9 +52,6 @@ VIR_LOG_INIT("node_device.node_device_hal"); =20 #define DRV_STATE_HAL_CTX(ds) ((LibHalContext *)((ds)->privateData)) =20 -#define NODE_DEV_UDI(obj) ((const char *)((obj)->privateData) - - static const char * hal_name(const char *udi) { @@ -446,27 +443,18 @@ gather_capabilities(LibHalContext *ctx, const char *u= di, return rv; } =20 -static void -free_udi(void *udi) -{ - VIR_FREE(udi); -} =20 static void dev_create(const char *udi) { LibHalContext *ctx; char *parent_key =3D NULL; - virNodeDeviceObjPtr dev =3D NULL; + virPoolObjPtr obj =3D NULL; virNodeDeviceDefPtr def =3D NULL; const char *name =3D hal_name(udi); int rv; - char *privData; char *devicePath =3D NULL; =20 - if (VIR_STRDUP(privData, udi) < 0) - return; - nodeDeviceLock(); ctx =3D DRV_STATE_HAL_CTX(driver); =20 @@ -492,29 +480,23 @@ dev_create(const char *udi) =20 /* Some devices don't have a path in sysfs, so ignore failure */ (void)get_str_prop(ctx, udi, "linux.sysfs_path", &devicePath); + VIR_STEAL_PTR(def->sysfs_path, devicePath); =20 - dev =3D virNodeDeviceAssignDef(&driver->devs, - def); - - if (!dev) { - VIR_FREE(devicePath); + if (!(obj =3D virPoolObjTableAdd(driver->devs, NULL, def->name, + def, NULL, NULL, virNodeDeviceDefFree, + NULL, 0))) goto failure; - } - - dev->privateData =3D privData; - dev->privateFree =3D free_udi; - dev->def->sysfs_path =3D devicePath; - - virNodeDeviceObjUnlock(dev); + def =3D NULL; =20 + virPoolObjEndAPI(&obj); nodeDeviceUnlock(); return; =20 failure: VIR_DEBUG("FAILED TO ADD dev %s", name); cleanup: - VIR_FREE(privData); virNodeDeviceDefFree(def); + virPoolObjEndAPI(&obj); nodeDeviceUnlock(); } =20 @@ -522,19 +504,17 @@ static void dev_refresh(const char *udi) { const char *name =3D hal_name(udi); - virNodeDeviceObjPtr dev; + virPoolObjPtr obj; =20 - nodeDeviceLock(); - dev =3D virNodeDeviceFindByName(&driver->devs, name); - if (dev) { + if ((obj =3D virPoolObjTableFindByName(driver->devs, name))) { /* Simply "rediscover" device -- incrementally handling changes * to sub-capabilities (like net.80203) is nasty ... so avoid it. */ - virNodeDeviceObjRemove(&driver->devs, &dev); + virPoolObjTableObjRemove(driver->devs, &obj); } else { VIR_DEBUG("no device named %s", name); } - nodeDeviceUnlock(); + virPoolObjEndAPI(&obj); =20 if (dev) dev_create(udi); @@ -554,16 +534,14 @@ device_removed(LibHalContext *ctx ATTRIBUTE_UNUSED, const char *udi) { const char *name =3D hal_name(udi); - virNodeDeviceObjPtr dev; + virPoolObjPtr obj; =20 - nodeDeviceLock(); - dev =3D virNodeDeviceFindByName(&driver->devs, name); VIR_DEBUG("%s", name); - if (dev) - virNodeDeviceObjRemove(&driver->devs, &dev); + if ((obj =3D virPoolObjTableFindByName(driver->devs, name))) + virPoolObjTableRemove(driver->devs, &obj); else VIR_DEBUG("no device named %s", name); - nodeDeviceUnlock(); + virPoolObjEndAPI(&obj); } =20 =20 @@ -572,18 +550,18 @@ device_cap_added(LibHalContext *ctx, const char *udi, const char *cap) { const char *name =3D hal_name(udi); - virNodeDeviceObjPtr dev; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; =20 - nodeDeviceLock(); - dev =3D virNodeDeviceFindByName(&driver->devs, name); - nodeDeviceUnlock(); VIR_DEBUG("%s %s", cap, name); - if (dev) { - (void)gather_capability(ctx, udi, cap, &dev->def->caps); - virNodeDeviceObjUnlock(dev); + + if ((obj =3D virPoolObjTableFindByName(driver->devs, name))) { + def =3D virPoolObjGetDef(obj); + (void)gather_capability(ctx, udi, cap, &def->caps); } else { VIR_DEBUG("no device named %s", name); } + virPoolObjEndAPI(&obj); } =20 =20 @@ -639,6 +617,11 @@ nodeStateInitialize(bool privileged ATTRIBUTE_UNUSED, } nodeDeviceLock(); =20 + if (!(driver->devs =3D + virPoolObjTableNew(VIR_POOLOBJTABLE_NODEDEVICE, + VIR_POOLOBJTABLE_NODEDEVICE_HASHSTART, true))) + goto cleanup; + dbus_error_init(&err); if (!(sysbus =3D virDBusGetSystemBus())) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -713,9 +696,9 @@ nodeStateInitialize(bool privileged ATTRIBUTE_UNUSED, _("%s: %s"), err.name, err.message); dbus_error_free(&err); } - virNodeDeviceObjListFree(&driver->devs); if (hal_ctx) (void)libhal_ctx_free(hal_ctx); + virObjectUnref(driver->devs); nodeDeviceUnlock(); VIR_FREE(driver); =20 @@ -729,7 +712,7 @@ nodeStateCleanup(void) if (driver) { nodeDeviceLock(); LibHalContext *hal_ctx =3D DRV_STATE_HAL_CTX(driver); - virNodeDeviceObjListFree(&driver->devs); + virObjectUnref(driver->devs); (void)libhal_ctx_shutdown(hal_ctx, NULL); (void)libhal_ctx_free(hal_ctx); nodeDeviceUnlock(); @@ -751,10 +734,9 @@ nodeStateReload(void) LibHalContext *hal_ctx; =20 VIR_INFO("Reloading HAL device state"); - nodeDeviceLock(); + VIR_INFO("Removing existing objects"); - virNodeDeviceObjListFree(&driver->devs); - nodeDeviceUnlock(); + virPoolObjTableClearAll(driver->devs); =20 hal_ctx =3D DRV_STATE_HAL_CTX(driver); VIR_INFO("Creating new objects"); diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_devi= ce_udev.c index 4b81312..33e8cc7 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -43,6 +43,7 @@ #include "virpci.h" #include "virstring.h" #include "virnetdev.h" +#include "virpoolobj.h" =20 #define VIR_FROM_THIS VIR_FROM_NODEDEV =20 @@ -1024,32 +1025,34 @@ static int udevGetDeviceDetails(struct udev_device = *device, =20 static int udevRemoveOneDevice(struct udev_device *device) { - virNodeDeviceObjPtr dev =3D NULL; + virPoolObjPtr obj =3D NULL; + virNodeDeviceDefPtr def; virObjectEventPtr event =3D NULL; const char *name =3D NULL; int ret =3D -1; =20 name =3D udev_device_get_syspath(device); - dev =3D virNodeDeviceFindBySysfsPath(&driver->devs, name); =20 - if (!dev) { + if (!(obj =3D virNodeDeviceObjFindBySysfsPath(driver->devs, name))) { VIR_DEBUG("Failed to find device to remove that has udev name '%s'= ", name); goto cleanup; } =20 - event =3D virNodeDeviceEventLifecycleNew(dev->def->name, + def =3D virPoolObjGetDef(obj); + event =3D virNodeDeviceEventLifecycleNew(def->name, VIR_NODE_DEVICE_EVENT_DELETED, 0); =20 VIR_DEBUG("Removing device '%s' with sysfs path '%s'", - dev->def->name, name); - virNodeDeviceObjRemove(&driver->devs, &dev); + def->name, name); + virPoolObjTableRemove(driver->devs, &obj); =20 ret =3D 0; cleanup: if (event) virObjectEventStateQueue(driver->nodeDeviceEventState, event); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -1059,7 +1062,7 @@ static int udevSetParent(struct udev_device *device, { struct udev_device *parent_device =3D NULL; const char *parent_sysfs_path =3D NULL; - virNodeDeviceObjPtr dev =3D NULL; + virPoolObjPtr obj =3D NULL; int ret =3D -1; =20 parent_device =3D device; @@ -1077,14 +1080,11 @@ static int udevSetParent(struct udev_device *device, goto cleanup; } =20 - dev =3D virNodeDeviceFindBySysfsPath(&driver->devs, - parent_sysfs_path); - if (dev !=3D NULL) { - if (VIR_STRDUP(def->parent, dev->def->name) < 0) { - virNodeDeviceObjUnlock(dev); + if ((obj =3D virNodeDeviceObjFindBySysfsPath(driver->devs, + parent_sysfs_path))) { + virNodeDeviceDefPtr objdef =3D virPoolObjGetDef(obj); + if (VIR_STRDUP(def->parent, objdef->name) < 0) goto cleanup; - } - virNodeDeviceObjUnlock(dev); =20 if (VIR_STRDUP(def->parent_sysfs_path, parent_sysfs_path) < 0) goto cleanup; @@ -1098,6 +1098,7 @@ static int udevSetParent(struct udev_device *device, ret =3D 0; =20 cleanup: + virPoolObjEndAPI(&obj); return ret; } =20 @@ -1105,7 +1106,8 @@ static int udevSetParent(struct udev_device *device, static int udevAddOneDevice(struct udev_device *device) { virNodeDeviceDefPtr def =3D NULL; - virNodeDeviceObjPtr dev =3D NULL; + virPoolObjPtr obj =3D NULL; + virNodeDeviceDefPtr newdef; virObjectEventPtr event =3D NULL; bool new_device =3D true; int ret =3D -1; @@ -1128,29 +1130,37 @@ static int udevAddOneDevice(struct udev_device *dev= ice) if (udevGetDeviceDetails(device, def) !=3D 0) goto cleanup; =20 + if (!def->name) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Did not generate def->name for '%s'"), + udev_device_get_syspath(device)); + goto cleanup; + } + if (udevSetParent(device, def) !=3D 0) goto cleanup; =20 - dev =3D virNodeDeviceFindByName(&driver->devs, def->name); - if (dev) { - virNodeDeviceObjUnlock(dev); + if ((obj =3D virPoolObjTableFindByName(driver->devs, def->name))) { + virPoolObjEndAPI(&obj); new_device =3D false; } =20 /* If this is a device change, the old definition will be freed * and the current definition will take its place. */ - dev =3D virNodeDeviceAssignDef(&driver->devs, def); - if (dev =3D=3D NULL) + if (!(obj =3D virPoolObjTableAdd(driver->devs, NULL, def->name, + def, NULL, NULL, virNodeDeviceDefFree, + NULL, 0))) goto cleanup; + VIR_STEAL_PTR(newdef, def); =20 if (new_device) - event =3D virNodeDeviceEventLifecycleNew(dev->def->name, + event =3D virNodeDeviceEventLifecycleNew(newdef->name, VIR_NODE_DEVICE_EVENT_CREAT= ED, 0); else - event =3D virNodeDeviceEventUpdateNew(dev->def->name); + event =3D virNodeDeviceEventUpdateNew(newdef->name); =20 - virNodeDeviceObjUnlock(dev); + virPoolObjEndAPI(&obj); =20 ret =3D 0; =20 @@ -1288,7 +1298,7 @@ static int nodeStateCleanup(void) if (udev !=3D NULL) udev_unref(udev); =20 - virNodeDeviceObjListFree(&driver->devs); + virObjectUnref(driver->devs); nodeDeviceUnlock(); virMutexDestroy(&driver->lock); VIR_FREE(driver); @@ -1404,7 +1414,7 @@ udevGetDMIData(virNodeDevCapDataPtr data) static int udevSetupSystemDev(void) { virNodeDeviceDefPtr def =3D NULL; - virNodeDeviceObjPtr dev =3D NULL; + virPoolObjPtr obj =3D NULL; int ret =3D -1; =20 if (VIR_ALLOC(def) < 0) @@ -1420,17 +1430,18 @@ static int udevSetupSystemDev(void) udevGetDMIData(&def->caps->data); #endif =20 - dev =3D virNodeDeviceAssignDef(&driver->devs, def); - if (dev =3D=3D NULL) + if (!(obj =3D virPoolObjTableAdd(driver->devs, NULL, def->name, + def, NULL, NULL, virNodeDeviceDefFree, + NULL, 0))) goto cleanup; + def =3D NULL; =20 - virNodeDeviceObjUnlock(dev); + virPoolObjEndAPI(&obj); =20 ret =3D 0; =20 cleanup: - if (ret =3D=3D -1) - virNodeDeviceDefFree(def); + virNodeDeviceDefFree(def); =20 return ret; } @@ -1488,6 +1499,11 @@ static int nodeStateInitialize(bool privileged, nodeDeviceLock(); driver->nodeDeviceEventState =3D virObjectEventStateNew(); =20 + if (!(driver->devs =3D + virPoolObjTableNew(VIR_POOLOBJTABLE_NODEDEVICE, + VIR_POOLOBJTABLE_NODEDEVICE_HASHSTART, true))) + goto cleanup; + if (udevPCITranslateInit(privileged) < 0) goto cleanup; =20 diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 6820298..ce44728 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -36,6 +36,7 @@ #include "virerror.h" #include "datatypes.h" #include "test_driver.h" +#include "virpoolobj.h" #include "virbuffer.h" #include "viruuid.h" #include "capabilities.h" @@ -51,6 +52,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" @@ -98,7 +100,7 @@ struct _testDriver { bool transaction_running; virInterfaceObjList backupIfaces; virStoragePoolObjList pools; - virNodeDeviceObjList devs; + virPoolObjTablePtr devs; int numCells; testCell cells[MAX_CELLS]; size_t numAuths; @@ -149,7 +151,7 @@ testDriverFree(testDriverPtr driver) virObjectUnref(driver->caps); virObjectUnref(driver->xmlopt); virObjectUnref(driver->domains); - virNodeDeviceObjListFree(&driver->devs); + virObjectUnref(driver->devs); virObjectUnref(driver->networks); virInterfaceObjListFree(&driver->ifaces); virStoragePoolObjListFree(&driver->pools); @@ -413,6 +415,9 @@ testDriverNew(void) =20 if (!(ret->xmlopt =3D virDomainXMLOptionNew(NULL, NULL, &ns)) || !(ret->eventState =3D virObjectEventStateNew()) || + !(ret->devs =3D virPoolObjTableNew(VIR_POOLOBJTABLE_NODEDEVICE, + VIR_POOLOBJTABLE_NODEDEVICE_HASHS= TART, + true)) || !(ret->domains =3D virDomainObjListNew()) || !(ret->networks =3D virNetworkObjListNew())) goto error; @@ -1113,33 +1118,32 @@ testParseNodedevs(testDriverPtr privconn, int num, ret =3D -1; size_t i; xmlNodePtr *nodes =3D NULL; - virNodeDeviceObjPtr obj; + virNodeDeviceDefPtr def =3D NULL; + xmlNodePtr node; + virPoolObjPtr obj =3D NULL; =20 - num =3D virXPathNodeSet("/node/device", ctxt, &nodes); - if (num < 0) + if ((num =3D virXPathNodeSet("/node/device", ctxt, &nodes)) < 0) goto error; =20 for (i =3D 0; i < num; i++) { - virNodeDeviceDefPtr def; - xmlNodePtr node =3D testParseXMLDocFromFile(nodes[i], file, - "nodedev"); - if (!node) + if (!(node =3D testParseXMLDocFromFile(nodes[i], file, "nodedev"))) goto error; =20 - def =3D virNodeDeviceDefParseNode(ctxt->doc, node, 0, NULL); - if (!def) + if (!(def =3D virNodeDeviceDefParseNode(ctxt->doc, node, 0, NULL))) goto error; =20 - if (!(obj =3D virNodeDeviceAssignDef(&privconn->devs, def))) { - virNodeDeviceDefFree(def); + if (!(obj =3D virPoolObjTableAdd(privconn->devs, NULL, def->name, + def, NULL, NULL, virNodeDeviceDefFr= ee, + NULL, 0))) goto error; - } + def =3D NULL; =20 - virNodeDeviceObjUnlock(obj); + virPoolObjEndAPI(&obj); } =20 ret =3D 0; error: + virNodeDeviceDefFree(def); VIR_FREE(nodes); return ret; } @@ -5374,27 +5378,34 @@ testStorageVolGetPath(virStorageVolPtr vol) =20 /* Node device implementations */ =20 +static virPoolObjPtr +testNodeDeviceObjFindByName(virPoolObjTablePtr devobjs, + const char *name) +{ + virPoolObjPtr obj; + + if (!(obj =3D virPoolObjTableFindByName(devobjs, name))) + virReportError(VIR_ERR_NO_NODE_DEVICE, + _("no node device with matching name '%s'"), + name); + + return obj; +} + + static int testNodeNumOfDevices(virConnectPtr conn, const char *cap, unsigned int flags) { testDriverPtr driver =3D conn->privateData; - int ndevs =3D 0; - size_t i; =20 virCheckFlags(0, -1); =20 - testDriverLock(driver); - for (i =3D 0; i < driver->devs.count; i++) - if ((cap =3D=3D NULL) || - virNodeDeviceHasCap(driver->devs.objs[i], cap)) - ++ndevs; - testDriverUnlock(driver); - - return ndevs; + return virNodeDeviceObjNumOfDevices(driver->devs, conn, cap, NULL); } =20 + static int testNodeListDevices(virConnectPtr conn, const char *cap, @@ -5403,118 +5414,73 @@ testNodeListDevices(virConnectPtr conn, unsigned int flags) { testDriverPtr driver =3D conn->privateData; - int ndevs =3D 0; - size_t i; =20 virCheckFlags(0, -1); =20 - testDriverLock(driver); - for (i =3D 0; i < driver->devs.count && ndevs < maxnames; i++) { - virNodeDeviceObjLock(driver->devs.objs[i]); - if (cap =3D=3D NULL || - virNodeDeviceHasCap(driver->devs.objs[i], cap)) { - if (VIR_STRDUP(names[ndevs++], driver->devs.objs[i]->def->name= ) < 0) { - virNodeDeviceObjUnlock(driver->devs.objs[i]); - goto failure; - } - } - virNodeDeviceObjUnlock(driver->devs.objs[i]); - } - testDriverUnlock(driver); - - return ndevs; - - failure: - testDriverUnlock(driver); - --ndevs; - while (--ndevs >=3D 0) - VIR_FREE(names[ndevs]); - return -1; + return virNodeDeviceObjGetNames(driver->devs, conn, NULL, + cap, names, maxnames); } =20 + static virNodeDevicePtr testNodeDeviceLookupByName(virConnectPtr conn, const char *name) { testDriverPtr driver =3D conn->privateData; - virNodeDeviceObjPtr obj; + virPoolObjPtr obj; virNodeDevicePtr ret =3D NULL; =20 - testDriverLock(driver); - obj =3D virNodeDeviceFindByName(&driver->devs, name); - testDriverUnlock(driver); - - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - name); - goto cleanup; - } + if (!(obj =3D testNodeDeviceObjFindByName(driver->devs, name))) + return NULL; =20 ret =3D virGetNodeDevice(conn, name); =20 - cleanup: - if (obj) - virNodeDeviceObjUnlock(obj); + virPoolObjEndAPI(&obj); return ret; } =20 + static char * testNodeDeviceGetXMLDesc(virNodeDevicePtr dev, unsigned int flags) { testDriverPtr driver =3D dev->conn->privateData; - virNodeDeviceObjPtr obj; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; char *ret =3D NULL; =20 virCheckFlags(0, NULL); =20 - testDriverLock(driver); - obj =3D virNodeDeviceFindByName(&driver->devs, dev->name); - testDriverUnlock(driver); - - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - dev->name); - goto cleanup; - } + if (!(obj =3D testNodeDeviceObjFindByName(driver->devs, dev->name))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - ret =3D virNodeDeviceDefFormat(obj->def); + ret =3D virNodeDeviceDefFormat(def); =20 - cleanup: - if (obj) - virNodeDeviceObjUnlock(obj); + virPoolObjEndAPI(&obj); return ret; } =20 + static char * testNodeDeviceGetParent(virNodeDevicePtr dev) { testDriverPtr driver =3D dev->conn->privateData; - virNodeDeviceObjPtr obj; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; char *ret =3D NULL; =20 - testDriverLock(driver); - obj =3D virNodeDeviceFindByName(&driver->devs, dev->name); - testDriverUnlock(driver); - - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - dev->name); - goto cleanup; - } + if (!(obj =3D testNodeDeviceObjFindByName(driver->devs, dev->name))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - if (obj->def->parent) { - ignore_value(VIR_STRDUP(ret, obj->def->parent)); + if (def->parent) { + ignore_value(VIR_STRDUP(ret, def->parent)); } else { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no parent for this device")); } =20 - cleanup: - if (obj) - virNodeDeviceObjUnlock(obj); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -5523,30 +5489,20 @@ static int testNodeDeviceNumOfCaps(virNodeDevicePtr dev) { testDriverPtr driver =3D dev->conn->privateData; - virNodeDeviceObjPtr obj; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; virNodeDevCapsDefPtr caps; int ncaps =3D 0; - int ret =3D -1; - - testDriverLock(driver); - obj =3D virNodeDeviceFindByName(&driver->devs, dev->name); - testDriverUnlock(driver); =20 - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - dev->name); - goto cleanup; - } + if (!(obj =3D testNodeDeviceObjFindByName(driver->devs, dev->name))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - for (caps =3D obj->def->caps; caps; caps =3D caps->next) + for (caps =3D def->caps; caps; caps =3D caps->next) ++ncaps; - ret =3D ncaps; =20 - cleanup: - if (obj) - virNodeDeviceObjUnlock(obj); - return ret; + virPoolObjEndAPI(&obj); + return ncaps; } =20 =20 @@ -5554,31 +5510,25 @@ static int testNodeDeviceListCaps(virNodeDevicePtr dev, char **const names, int maxna= mes) { testDriverPtr driver =3D dev->conn->privateData; - virNodeDeviceObjPtr obj; + virPoolObjPtr obj; + virNodeDeviceDefPtr def; virNodeDevCapsDefPtr caps; int ncaps =3D 0; int ret =3D -1; =20 - testDriverLock(driver); - obj =3D virNodeDeviceFindByName(&driver->devs, dev->name); - testDriverUnlock(driver); - - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - dev->name); - goto cleanup; - } + if (!(obj =3D testNodeDeviceObjFindByName(driver->devs, dev->name))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - for (caps =3D obj->def->caps; caps && ncaps < maxnames; caps =3D caps-= >next) { - if (VIR_STRDUP(names[ncaps++], virNodeDevCapTypeToString(caps->dat= a.type)) < 0) + for (caps =3D def->caps; caps && ncaps < maxnames; caps =3D caps->next= ) { + if (VIR_STRDUP(names[ncaps++], + virNodeDevCapTypeToString(caps->data.type)) < 0) goto cleanup; } ret =3D ncaps; =20 cleanup: - if (obj) - virNodeDeviceObjUnlock(obj); + virPoolObjEndAPI(&obj); if (ret =3D=3D -1) { --ncaps; while (--ncaps >=3D 0) @@ -5587,6 +5537,7 @@ testNodeDeviceListCaps(virNodeDevicePtr dev, char **c= onst names, int maxnames) return ret; } =20 + static virNodeDevicePtr testNodeDeviceCreateXML(virConnectPtr conn, const char *xmlDesc, @@ -5594,7 +5545,8 @@ testNodeDeviceCreateXML(virConnectPtr conn, { testDriverPtr driver =3D conn->privateData; virNodeDeviceDefPtr def =3D NULL; - virNodeDeviceObjPtr obj =3D NULL; + virPoolObjPtr obj =3D NULL; + virNodeDeviceDefPtr objdef; char *wwnn =3D NULL, *wwpn =3D NULL; int parent_host =3D -1; virNodeDevicePtr dev =3D NULL; @@ -5603,20 +5555,17 @@ testNodeDeviceCreateXML(virConnectPtr conn, =20 virCheckFlags(0, NULL); =20 - testDriverLock(driver); - - def =3D virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, NULL); - if (def =3D=3D NULL) + if (!(def =3D virNodeDeviceDefParseString(xmlDesc, CREATE_DEVICE, NULL= ))) goto cleanup; =20 /* We run these next two simply for validation */ if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) =3D=3D -1) goto cleanup; =20 - if (virNodeDeviceGetParentHost(&driver->devs, - def->name, - def->parent, - &parent_host) =3D=3D -1) { + if (virNodeDeviceObjGetParentHost(driver->devs, + def->name, + def->parent, + &parent_host) =3D=3D -1) { goto cleanup; } =20 @@ -5638,19 +5587,20 @@ testNodeDeviceCreateXML(virConnectPtr conn, caps =3D caps->next; } =20 - - if (!(obj =3D virNodeDeviceAssignDef(&driver->devs, def))) + if (!(obj =3D virPoolObjTableAdd(driver->devs, NULL, def->name, + def, NULL, NULL, virNodeDeviceDefFree, + NULL, 0))) goto cleanup; - virNodeDeviceObjUnlock(obj); + VIR_STEAL_PTR(objdef, def); =20 - event =3D virNodeDeviceEventLifecycleNew(def->name, + event =3D virNodeDeviceEventLifecycleNew(objdef->name, VIR_NODE_DEVICE_EVENT_CREATED, 0); =20 - dev =3D virGetNodeDevice(conn, def->name); - def =3D NULL; + dev =3D virGetNodeDevice(conn, objdef->name); + cleanup: - testDriverUnlock(driver); + virPoolObjEndAPI(&obj); virNodeDeviceDefFree(def); testObjectEventQueue(driver, event); VIR_FREE(wwnn); @@ -5658,60 +5608,44 @@ testNodeDeviceCreateXML(virConnectPtr conn, return dev; } =20 + static int testNodeDeviceDestroy(virNodeDevicePtr dev) { - int ret =3D 0; + int ret =3D -1; testDriverPtr driver =3D dev->conn->privateData; - virNodeDeviceObjPtr obj =3D NULL; - char *parent_name =3D NULL, *wwnn =3D NULL, *wwpn =3D NULL; + virPoolObjPtr obj =3D NULL; + virNodeDeviceDefPtr def; + char *wwnn =3D NULL; + char *wwpn =3D NULL; int parent_host =3D -1; virObjectEventPtr event =3D NULL; =20 - testDriverLock(driver); - obj =3D virNodeDeviceFindByName(&driver->devs, dev->name); - testDriverUnlock(driver); - - if (!obj) { - virReportError(VIR_ERR_NO_NODE_DEVICE, - _("no node device with matching name '%s'"), - dev->name); - goto out; - } - - if (virNodeDeviceGetWWNs(obj->def, &wwnn, &wwpn) =3D=3D -1) - goto out; - - if (VIR_STRDUP(parent_name, obj->def->parent) < 0) - goto out; + if (!(obj =3D testNodeDeviceObjFindByName(driver->devs, dev->name))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - /* virNodeDeviceGetParentHost will cause the device object's lock to be - * taken, so we have to dup the parent's name and drop the lock - * before calling it. We don't need the reference to the object - * any more once we have the parent's name. */ - virNodeDeviceObjUnlock(obj); + if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) =3D=3D -1) + goto cleanup; =20 /* We do this just for basic validation */ - if (virNodeDeviceGetParentHost(&driver->devs, - dev->name, - parent_name, - &parent_host) =3D=3D -1) { - obj =3D NULL; - goto out; - } + if (virNodeDeviceObjGetParentHost(driver->devs, + dev->name, + def->parent, + &parent_host) =3D=3D -1) + goto cleanup; =20 event =3D virNodeDeviceEventLifecycleNew(dev->name, VIR_NODE_DEVICE_EVENT_DELETED, 0); =20 - virNodeDeviceObjLock(obj); - virNodeDeviceObjRemove(&driver->devs, &obj); + virPoolObjTableRemove(driver->devs, &obj); =20 - out: - if (obj) - virNodeDeviceObjUnlock(obj); + ret =3D 0; + + cleanup: + virPoolObjEndAPI(&obj); testObjectEventQueue(driver, event); - VIR_FREE(parent_name); VIR_FREE(wwnn); VIR_FREE(wwpn); return ret; --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 03:40:31 2024 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 1486830875968805.2825976394776; Sat, 11 Feb 2017 08:34:35 -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 v1BGUh4Y023691; Sat, 11 Feb 2017 11:30:43 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGTraZ028526 for ; Sat, 11 Feb 2017 11:29:53 -0500 Received: from localhost.localdomain.com (ovpn-116-36.phx2.redhat.com [10.3.116.36]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGTmIo000660 for ; Sat, 11 Feb 2017 11:29:52 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Sat, 11 Feb 2017 11:29:40 -0500 Message-Id: <1486830585-23866-5-git-send-email-jferlan@redhat.com> In-Reply-To: <1486830585-23866-1-git-send-email-jferlan@redhat.com> References: <1486830585-23866-1-git-send-email-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH RFC 4/9] interface: Convert virInterfaceObj[List] to use virPoolObj[Table] 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" Use the virPoolObj[Table] object management model in order to manage the Interface objects. While making the adjustments to use the new model, there are some code formatting adjustments that were also made with the goal to follow more recent code flow and layout. All interface object management API's have their own virinterfaceobj entry points now instead of being mashed in with interface_conf Signed-off-by: John Ferlan --- src/Makefile.am | 3 +- src/conf/interface_conf.c | 170 +--------------- src/conf/interface_conf.h | 46 +---- src/conf/virinterfaceobj.c | 205 +++++++++++++++++++ src/conf/virinterfaceobj.h | 46 +++++ src/interface/interface_backend_netcf.c | 6 +- src/interface/interface_backend_udev.c | 5 +- src/libvirt_private.syms | 15 +- src/test/test_driver.c | 349 +++++++++++++---------------= ---- 9 files changed, 415 insertions(+), 430 deletions(-) create mode 100644 src/conf/virinterfaceobj.c create mode 100644 src/conf/virinterfaceobj.h diff --git a/src/Makefile.am b/src/Makefile.am index 20ee73a..d864e6c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -383,7 +383,8 @@ STORAGE_CONF_SOURCES =3D = \ =20 # Interface driver generic impl APIs INTERFACE_CONF_SOURCES =3D \ - conf/interface_conf.c conf/interface_conf.h + conf/interface_conf.c conf/interface_conf.h \ + conf/virinterfaceobj.c conf/virinterfaceobj.h =20 # Secret driver generic impl APIs SECRET_CONF_SOURCES =3D \ diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c index e1e6a25..cbab22b 100644 --- a/src/conf/interface_conf.c +++ b/src/conf/interface_conf.c @@ -68,8 +68,10 @@ void virInterfaceProtocolDefFree(virInterfaceProtocolDef= Ptr def) VIR_FREE(def); } =20 -void virInterfaceDefFree(virInterfaceDefPtr def) +void +virInterfaceDefFree(void *opaque) { + virInterfaceDefPtr def =3D opaque; size_t i; int pp; =20 @@ -1114,169 +1116,3 @@ char *virInterfaceDefFormat(const virInterfaceDef *= def) } return virBufferContentAndReset(&buf); } - -/* virInterfaceObj manipulation */ - -void virInterfaceObjLock(virInterfaceObjPtr obj) -{ - virMutexLock(&obj->lock); -} - -void virInterfaceObjUnlock(virInterfaceObjPtr obj) -{ - virMutexUnlock(&obj->lock); -} - -void virInterfaceObjFree(virInterfaceObjPtr iface) -{ - if (!iface) - return; - - virInterfaceDefFree(iface->def); - virMutexDestroy(&iface->lock); - VIR_FREE(iface); -} - -/* virInterfaceObjList manipulation */ - -int virInterfaceFindByMACString(virInterfaceObjListPtr interfaces, - const char *mac, - virInterfaceObjPtr *matches, int maxmatche= s) -{ - size_t i; - unsigned int matchct =3D 0; - - for (i =3D 0; i < interfaces->count; i++) { - - virInterfaceObjLock(interfaces->objs[i]); - if (STRCASEEQ(interfaces->objs[i]->def->mac, mac)) { - matchct++; - if (matchct <=3D maxmatches) { - matches[matchct - 1] =3D interfaces->objs[i]; - /* keep the lock if we're returning object to caller */ - /* it is the caller's responsibility to unlock *all* match= es */ - continue; - } - } - virInterfaceObjUnlock(interfaces->objs[i]); - - } - return matchct; -} - -virInterfaceObjPtr virInterfaceFindByName(virInterfaceObjListPtr interface= s, - const char *name) -{ - size_t i; - - for (i =3D 0; i < interfaces->count; i++) { - virInterfaceObjLock(interfaces->objs[i]); - if (STREQ(interfaces->objs[i]->def->name, name)) - return interfaces->objs[i]; - virInterfaceObjUnlock(interfaces->objs[i]); - } - - return NULL; -} - -void virInterfaceObjListFree(virInterfaceObjListPtr interfaces) -{ - size_t i; - - for (i =3D 0; i < interfaces->count; i++) - virInterfaceObjFree(interfaces->objs[i]); - - VIR_FREE(interfaces->objs); - interfaces->count =3D 0; -} - -int virInterfaceObjListClone(virInterfaceObjListPtr src, - virInterfaceObjListPtr dest) -{ - int ret =3D -1; - size_t i; - unsigned int cnt; - - if (!src || !dest) - goto cleanup; - - virInterfaceObjListFree(dest); /* start with an empty list */ - cnt =3D src->count; - for (i =3D 0; i < cnt; i++) { - virInterfaceDefPtr def =3D src->objs[i]->def; - virInterfaceDefPtr backup; - virInterfaceObjPtr iface; - char *xml =3D virInterfaceDefFormat(def); - - if (!xml) - goto cleanup; - - if ((backup =3D virInterfaceDefParseString(xml)) =3D=3D NULL) { - VIR_FREE(xml); - goto cleanup; - } - - VIR_FREE(xml); - if ((iface =3D virInterfaceAssignDef(dest, backup)) =3D=3D NULL) - goto cleanup; - virInterfaceObjUnlock(iface); /* was locked by virInterfaceAssignD= ef */ - } - - ret =3D cnt; - cleanup: - if ((ret < 0) && dest) - virInterfaceObjListFree(dest); - return ret; -} - -virInterfaceObjPtr virInterfaceAssignDef(virInterfaceObjListPtr interfaces, - virInterfaceDefPtr def) -{ - virInterfaceObjPtr iface; - - if ((iface =3D virInterfaceFindByName(interfaces, def->name))) { - virInterfaceDefFree(iface->def); - iface->def =3D def; - - return iface; - } - - if (VIR_ALLOC(iface) < 0) - return NULL; - if (virMutexInit(&iface->lock) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("cannot initialize mutex")); - VIR_FREE(iface); - return NULL; - } - virInterfaceObjLock(iface); - - if (VIR_APPEND_ELEMENT_COPY(interfaces->objs, - interfaces->count, iface) < 0) { - virInterfaceObjFree(iface); - return NULL; - } - - iface->def =3D def; - return iface; - -} - -void virInterfaceRemove(virInterfaceObjListPtr interfaces, - virInterfaceObjPtr iface) -{ - size_t i; - - virInterfaceObjUnlock(iface); - for (i =3D 0; i < interfaces->count; i++) { - virInterfaceObjLock(interfaces->objs[i]); - if (interfaces->objs[i] =3D=3D iface) { - virInterfaceObjUnlock(interfaces->objs[i]); - virInterfaceObjFree(interfaces->objs[i]); - - VIR_DELETE_ELEMENT(interfaces->objs, i, interfaces->count); - break; - } - virInterfaceObjUnlock(interfaces->objs[i]); - } -} diff --git a/src/conf/interface_conf.h b/src/conf/interface_conf.h index 1e38412..31523dc 100644 --- a/src/conf/interface_conf.h +++ b/src/conf/interface_conf.h @@ -161,46 +161,7 @@ struct _virInterfaceDef { virInterfaceProtocolDefPtr *protos; /* ptr to array of protos[nprotos]= */ }; =20 -typedef struct _virInterfaceObj virInterfaceObj; -typedef virInterfaceObj *virInterfaceObjPtr; -struct _virInterfaceObj { - virMutex lock; - - bool active; /* true if interface is active (up) */ - virInterfaceDefPtr def; /* The interface definition */ -}; - -typedef struct _virInterfaceObjList virInterfaceObjList; -typedef virInterfaceObjList *virInterfaceObjListPtr; -struct _virInterfaceObjList { - size_t count; - virInterfaceObjPtr *objs; -}; - -static inline bool -virInterfaceObjIsActive(const virInterfaceObj *iface) -{ - return iface->active; -} - -int virInterfaceFindByMACString(virInterfaceObjListPtr interfaces, - const char *mac, - virInterfaceObjPtr *matches, int maxmatche= s); -virInterfaceObjPtr virInterfaceFindByName(virInterfaceObjListPtr interface= s, - const char *name); - - -void virInterfaceDefFree(virInterfaceDefPtr def); -void virInterfaceObjFree(virInterfaceObjPtr iface); -void virInterfaceObjListFree(virInterfaceObjListPtr vms); -int virInterfaceObjListClone(virInterfaceObjListPtr src, - virInterfaceObjListPtr dest); - - -virInterfaceObjPtr virInterfaceAssignDef(virInterfaceObjListPtr interfaces, - virInterfaceDefPtr def); -void virInterfaceRemove(virInterfaceObjListPtr interfaces, - virInterfaceObjPtr iface); +void virInterfaceDefFree(void *opaque); =20 virInterfaceDefPtr virInterfaceDefParseString(const char *xmlStr); virInterfaceDefPtr virInterfaceDefParseFile(const char *filename); @@ -209,11 +170,6 @@ virInterfaceDefPtr virInterfaceDefParseNode(xmlDocPtr = xml, =20 char *virInterfaceDefFormat(const virInterfaceDef *def); =20 -void virInterfaceObjLock(virInterfaceObjPtr obj); -void virInterfaceObjUnlock(virInterfaceObjPtr obj); - -typedef bool (*virInterfaceObjListFilter)(virConnectPtr conn, void *opaque= ); - # define VIR_CONNECT_LIST_INTERFACES_FILTERS_ACTIVE \ (VIR_CONNECT_LIST_INTERFACES_ACTIVE | \ VIR_CONNECT_LIST_INTERFACES_INACTIVE) diff --git a/src/conf/virinterfaceobj.c b/src/conf/virinterfaceobj.c new file mode 100644 index 0000000..9ef0a45 --- /dev/null +++ b/src/conf/virinterfaceobj.c @@ -0,0 +1,205 @@ +/* + * virinterfaceobj.c: interface object handling + * (derived from interface_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 "interface_conf.h" + +#include "viralloc.h" +#include "virerror.h" +#include "virinterfaceobj.h" +#include "virlog.h" +#include "virstring.h" + +#define VIR_FROM_THIS VIR_FROM_INTERFACE + +VIR_LOG_INIT("conf.virinterfaceobj"); + + +struct interfaceCountData { + bool wantActive; + int count; +}; + +static int +interfaceCount(virPoolObjPtr obj, + void *opaque) +{ + struct interfaceCountData *data =3D opaque; + + if ((data->wantActive && virPoolObjIsActive(obj)) || + (!data->wantActive && !virPoolObjIsActive(obj))) + data->count++; + + return 0; +} + + +int +virInterfaceObjNumOfInterfaces(virPoolObjTablePtr ifaces, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter) +{ + struct interfaceCountData data =3D { .wantActive =3D wantActive, + .count =3D 0 }; + + if (virPoolObjTableList(ifaces, conn, aclfilter, interfaceCount, &data= ) < 0) + return 0; + + return data.count; +} + + +struct interfaceNameData { + bool wantActive; + int nnames; + char **const names; + int maxnames; +}; + +static int +interfaceGetNames(virPoolObjPtr obj, + void *opaque) +{ + struct interfaceNameData *data =3D opaque; + + if (data->nnames < data->maxnames) { + if (data->wantActive && virPoolObjIsActive(obj)) { + virInterfaceDefPtr def =3D virPoolObjGetDef(obj); + + if (VIR_STRDUP(data->names[data->nnames++], def->name) < 0) + return -1; + } else if (!data->wantActive && !virPoolObjIsActive(obj)) { + virInterfaceDefPtr def =3D virPoolObjGetDef(obj); + + if (VIR_STRDUP(data->names[data->nnames++], def->name) < 0) + return -1; + } + } + + return 0; +} + + +int +virInterfaceObjGetNames(virPoolObjTablePtr ifaces, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter, + char **const names, + int maxnames) +{ + struct interfaceNameData data =3D { .wantActive =3D wantActive, + .nnames =3D 0, + .names =3D names, + .maxnames =3D maxnames }; + + memset(names, 0, sizeof(*names) * maxnames); + if (virPoolObjTableList(ifaces, conn, aclfilter, + interfaceGetNames, &data) < 0) + goto error; + + return data.nnames; + + error: + while (--data.nnames >=3D 0) + VIR_FREE(names[data.nnames]); + return -1; +} + + +struct interfaceListMACData { + const char *mac; + int nmatches; + char **const matches; + int maxmatches; +}; + +static int +interfaceListMACString(virPoolObjPtr obj, + void *opaque) +{ + virInterfaceDefPtr def =3D virPoolObjGetDef(obj); + struct interfaceListMACData *data =3D opaque; + + if (STRCASEEQ(def->mac, data->mac)) { + if (data->nmatches < data->maxmatches) { + if (VIR_STRDUP(data->matches[data->nmatches++], def->name) < 0) + return -1; + } + } + return 0; +} + + +/* virInterfaceFindByMACString: + * @interfaces: Pointer to object table + * @mac: String to search on + * @matches: Array of entries to store names matching MAC + * @maxmatches: Size of the array + * + * Search the object table for matching MAC's + * + * Returns: count of matches found, -1 on error + */ +int +virInterfaceObjFindByMACString(virConnectPtr conn, + virPoolObjTablePtr interfaces, + const char *mac, + char **const matches, + int maxmatches) +{ + struct interfaceListMACData data =3D { .mac =3D mac, + .nmatches =3D 0, + .matches =3D matches, + .maxmatches =3D maxmatches }; + + if (virPoolObjTableList(interfaces, conn, NULL, + interfaceListMACString, &data) < 0) + return -1; + + return data.nmatches; +} + + +static void * +cloneObjCallback(virPoolObjPtr src) +{ + virInterfaceDefPtr srcdef =3D virPoolObjGetDef(src); + virInterfaceDefPtr dstdef; + char *xml; + + if (!(xml =3D virInterfaceDefFormat(srcdef))) + return NULL; + + dstdef =3D virInterfaceDefParseString(xml); + + VIR_FREE(xml); + + return dstdef; +} + + +virPoolObjTablePtr +virInterfaceObjClone(virPoolObjTablePtr src) +{ + return virPoolObjTableClone(src, cloneObjCallback); +} diff --git a/src/conf/virinterfaceobj.h b/src/conf/virinterfaceobj.h new file mode 100644 index 0000000..3a59616 --- /dev/null +++ b/src/conf/virinterfaceobj.h @@ -0,0 +1,46 @@ +/* + * virinterfaceobj.h: interface object handling entry points + * (derived from interface_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 __VIRINTERFACEOBJ_H__ +# define __VIRINTERFACEOBJ_H__ + +# include "internal.h" +# include "virpoolobj.h" + +int virInterfaceObjNumOfInterfaces(virPoolObjTablePtr ifaces, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter); + +int virInterfaceObjGetNames(virPoolObjTablePtr ifaces, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter, + char **const names, + int maxnames); + +int virInterfaceObjFindByMACString(virConnectPtr conn, + virPoolObjTablePtr interfaces, + const char *mac, + char **const matches, + int maxmatches); + +virPoolObjTablePtr virInterfaceObjClone(virPoolObjTablePtr src); + +#endif /* __VIRINTERFACEOBJ_H__ */ diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interf= ace_backend_netcf.c index 0181635..fa57905 100644 --- a/src/interface/interface_backend_netcf.c +++ b/src/interface/interface_backend_netcf.c @@ -31,6 +31,7 @@ #include "interface_conf.h" #include "viralloc.h" #include "virlog.h" +#include "virpoolobj.h" #include "virstring.h" #include "viraccessapicheck.h" =20 @@ -95,6 +96,7 @@ netcfStateInitialize(bool privileged ATTRIBUTE_UNUSED, driver =3D NULL; return -1; } + return 0; } =20 @@ -266,7 +268,7 @@ netcfInterfaceObjIsActive(struct netcf_if *iface, =20 static int netcfConnectNumOfInterfacesImpl(virConnectPtr conn, int status, - virInterfaceObjListFilter filte= r) + virPoolObjACLFilter filter) { int count; int want =3D 0; @@ -359,7 +361,7 @@ static int netcfConnectNumOfInterfacesImpl(virConnectPt= r conn, static int netcfConnectListInterfacesImpl(virConnectPtr conn, int status, char **const names, int nnames, - virInterfaceObjListFilter filter) + virPoolObjACLFilter filter) { int count =3D 0; int want =3D 0; diff --git a/src/interface/interface_backend_udev.c b/src/interface/interfa= ce_backend_udev.c index 5d0fc64..c9a3143 100644 --- a/src/interface/interface_backend_udev.c +++ b/src/interface/interface_backend_udev.c @@ -32,6 +32,7 @@ #include "interface_driver.h" #include "interface_conf.h" #include "viralloc.h" +#include "virpoolobj.h" #include "virstring.h" #include "viraccessapicheck.h" #include "virnetdev.h" @@ -137,7 +138,7 @@ udevGetDevices(struct udev *udev, virUdevStatus status) =20 static int udevNumOfInterfacesByStatus(virConnectPtr conn, virUdevStatus status, - virInterfaceObjListFilter filter) + virPoolObjACLFilter filter) { struct udev *udev =3D udev_ref(driver->udev); struct udev_enumerate *enumerate =3D NULL; @@ -190,7 +191,7 @@ udevListInterfacesByStatus(virConnectPtr conn, char **const names, int names_len, virUdevStatus status, - virInterfaceObjListFilter filter) + virPoolObjACLFilter filter) { struct udev *udev =3D udev_ref(driver->udev); struct udev_enumerate *enumerate =3D NULL; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 98b3840..5f95814 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -594,19 +594,11 @@ virDomainConfVMNWFilterTeardown; =20 =20 # conf/interface_conf.h -virInterfaceAssignDef; virInterfaceDefFormat; virInterfaceDefFree; virInterfaceDefParseFile; virInterfaceDefParseNode; virInterfaceDefParseString; -virInterfaceFindByMACString; -virInterfaceFindByName; -virInterfaceObjListClone; -virInterfaceObjListFree; -virInterfaceObjLock; -virInterfaceObjUnlock; -virInterfaceRemove; =20 =20 # conf/netdev_bandwidth_conf.h @@ -948,6 +940,13 @@ virDomainObjListRemoveLocked; virDomainObjListRename; =20 =20 +# conf/virinterfaceobj.h +virInterfaceObjClone; +virInterfaceObjFindByMACString; +virInterfaceObjGetNames; +virInterfaceObjNumOfInterfaces; + + # conf/virnodedeviceobj.h virNodeDeviceObjExportList; virNodeDeviceObjFindByName; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index ce44728..51605f3 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -65,6 +65,7 @@ #include "virauth.h" #include "viratomic.h" #include "virdomainobjlist.h" +#include "virinterfaceobj.h" #include "virhostcpu.h" =20 #define VIR_FROM_THIS VIR_FROM_TEST @@ -96,9 +97,9 @@ struct _testDriver { virMutex lock; =20 virNodeInfo nodeInfo; - virInterfaceObjList ifaces; + virPoolObjTablePtr ifaces; bool transaction_running; - virInterfaceObjList backupIfaces; + virPoolObjTablePtr backupIfaces; virStoragePoolObjList pools; virPoolObjTablePtr devs; int numCells; @@ -153,7 +154,8 @@ testDriverFree(testDriverPtr driver) virObjectUnref(driver->domains); virObjectUnref(driver->devs); virObjectUnref(driver->networks); - virInterfaceObjListFree(&driver->ifaces); + virObjectUnref(driver->ifaces); + virObjectUnref(driver->backupIfaces); virStoragePoolObjListFree(&driver->pools); virObjectUnref(driver->eventState); virMutexUnlock(&driver->lock); @@ -418,6 +420,9 @@ testDriverNew(void) !(ret->devs =3D virPoolObjTableNew(VIR_POOLOBJTABLE_NODEDEVICE, VIR_POOLOBJTABLE_NODEDEVICE_HASHS= TART, true)) || + !(ret->ifaces =3D virPoolObjTableNew(VIR_POOLOBJTABLE_INTERFACE, + VIR_POOLOBJTABLE_INTERFACE_HASH= START, + true)) || !(ret->domains =3D virDomainObjListNew()) || !(ret->networks =3D virNetworkObjListNew())) goto error; @@ -970,34 +975,33 @@ testParseInterfaces(testDriverPtr privconn, int num, ret =3D -1; size_t i; xmlNodePtr *nodes =3D NULL; - virInterfaceObjPtr obj; + virInterfaceDefPtr def =3D NULL; + xmlNodePtr node; + virPoolObjPtr obj; =20 - num =3D virXPathNodeSet("/node/interface", ctxt, &nodes); - if (num < 0) + if ((num =3D virXPathNodeSet("/node/interface", ctxt, &nodes)) < 0) goto error; =20 for (i =3D 0; i < num; i++) { - virInterfaceDefPtr def; - xmlNodePtr node =3D testParseXMLDocFromFile(nodes[i], file, - "interface"); - if (!node) + if (!(node =3D testParseXMLDocFromFile(nodes[i], file, "interface"= ))) goto error; =20 - def =3D virInterfaceDefParseNode(ctxt->doc, node); - if (!def) + if (!(def =3D virInterfaceDefParseNode(ctxt->doc, node))) goto error; =20 - if (!(obj =3D virInterfaceAssignDef(&privconn->ifaces, def))) { - virInterfaceDefFree(def); + if (!(obj =3D virPoolObjTableAdd(privconn->ifaces, NULL, def->name, + def, NULL, NULL, virInterfaceDefFre= e, + NULL, 0))) goto error; - } + def =3D NULL; =20 - obj->active =3D 1; - virInterfaceObjUnlock(obj); + virPoolObjSetActive(obj, true); + virPoolObjEndAPI(&obj); } =20 ret =3D 0; error: + virInterfaceDefFree(def); VIR_FREE(nodes); return ret; } @@ -3605,133 +3609,94 @@ static int testNetworkSetAutostart(virNetworkPtr n= etwork, */ =20 =20 -static int testConnectNumOfInterfaces(virConnectPtr conn) +static int +testConnectNumOfInterfaces(virConnectPtr conn) { testDriverPtr privconn =3D conn->privateData; - size_t i; - int count =3D 0; =20 - testDriverLock(privconn); - for (i =3D 0; (i < privconn->ifaces.count); i++) { - virInterfaceObjLock(privconn->ifaces.objs[i]); - if (virInterfaceObjIsActive(privconn->ifaces.objs[i])) - count++; - virInterfaceObjUnlock(privconn->ifaces.objs[i]); - } - testDriverUnlock(privconn); - return count; + return virInterfaceObjNumOfInterfaces(privconn->ifaces, conn, true, NU= LL); } =20 -static int testConnectListInterfaces(virConnectPtr conn, char **const name= s, int nnames) + +static int +testConnectListInterfaces(virConnectPtr conn, + char **const names, + int maxnames) { testDriverPtr privconn =3D conn->privateData; - int n =3D 0; - size_t i; =20 - testDriverLock(privconn); - memset(names, 0, sizeof(*names)*nnames); - for (i =3D 0; (i < privconn->ifaces.count) && (n < nnames); i++) { - virInterfaceObjLock(privconn->ifaces.objs[i]); - if (virInterfaceObjIsActive(privconn->ifaces.objs[i])) { - if (VIR_STRDUP(names[n++], privconn->ifaces.objs[i]->def->name= ) < 0) { - virInterfaceObjUnlock(privconn->ifaces.objs[i]); - goto error; - } - } - virInterfaceObjUnlock(privconn->ifaces.objs[i]); - } - testDriverUnlock(privconn); + return virInterfaceObjGetNames(privconn->ifaces, conn, true, NULL, + names, maxnames); +} =20 - return n; =20 - error: - for (n =3D 0; n < nnames; n++) - VIR_FREE(names[n]); - testDriverUnlock(privconn); - return -1; +static int +testConnectNumOfDefinedInterfaces(virConnectPtr conn) +{ + testDriverPtr privconn =3D conn->privateData; + + return virInterfaceObjNumOfInterfaces(privconn->ifaces, conn, false, N= ULL); } =20 -static int testConnectNumOfDefinedInterfaces(virConnectPtr conn) + +static int +testConnectListDefinedInterfaces(virConnectPtr conn, + char **const names, + int maxnames) { testDriverPtr privconn =3D conn->privateData; - size_t i; - int count =3D 0; =20 - testDriverLock(privconn); - for (i =3D 0; i < privconn->ifaces.count; i++) { - virInterfaceObjLock(privconn->ifaces.objs[i]); - if (!virInterfaceObjIsActive(privconn->ifaces.objs[i])) - count++; - virInterfaceObjUnlock(privconn->ifaces.objs[i]); - } - testDriverUnlock(privconn); - return count; + return virInterfaceObjGetNames(privconn->ifaces, conn, false, NULL, + names, maxnames); } =20 -static int testConnectListDefinedInterfaces(virConnectPtr conn, char **con= st names, int nnames) + +static virPoolObjPtr +testInterfaceObjFromName(virPoolObjTablePtr ifaces, + const char *name) { - testDriverPtr privconn =3D conn->privateData; - int n =3D 0; - size_t i; + virPoolObjPtr obj; =20 - testDriverLock(privconn); - memset(names, 0, sizeof(*names)*nnames); - for (i =3D 0; (i < privconn->ifaces.count) && (n < nnames); i++) { - virInterfaceObjLock(privconn->ifaces.objs[i]); - if (!virInterfaceObjIsActive(privconn->ifaces.objs[i])) { - if (VIR_STRDUP(names[n++], privconn->ifaces.objs[i]->def->name= ) < 0) { - virInterfaceObjUnlock(privconn->ifaces.objs[i]); - goto error; - } - } - virInterfaceObjUnlock(privconn->ifaces.objs[i]); + if (!(obj =3D virPoolObjTableFindByName(ifaces, name))) { + virReportError(VIR_ERR_NO_INTERFACE, + _("no interface with matching name '%s'"), name); + return NULL; } - testDriverUnlock(privconn); =20 - return n; - - error: - for (n =3D 0; n < nnames; n++) - VIR_FREE(names[n]); - testDriverUnlock(privconn); - return -1; + return obj; } =20 -static virInterfacePtr testInterfaceLookupByName(virConnectPtr conn, - const char *name) + +static virInterfacePtr +testInterfaceLookupByName(virConnectPtr conn, + const char *name) { testDriverPtr privconn =3D conn->privateData; - virInterfaceObjPtr iface; + virPoolObjPtr obj; + virInterfaceDefPtr def; virInterfacePtr ret =3D NULL; =20 - testDriverLock(privconn); - iface =3D virInterfaceFindByName(&privconn->ifaces, name); - testDriverUnlock(privconn); - - if (iface =3D=3D NULL) { - virReportError(VIR_ERR_NO_INTERFACE, NULL); - goto cleanup; - } + if (!(obj =3D testInterfaceObjFromName(privconn->ifaces, name))) + return NULL; =20 - ret =3D virGetInterface(conn, iface->def->name, iface->def->mac); + def =3D virPoolObjGetDef(obj); + ret =3D virGetInterface(conn, def->name, def->mac); =20 - cleanup: - if (iface) - virInterfaceObjUnlock(iface); + virPoolObjEndAPI(&obj); return ret; } =20 -static virInterfacePtr testInterfaceLookupByMACString(virConnectPtr conn, - const char *mac) +static virInterfacePtr +testInterfaceLookupByMACString(virConnectPtr conn, + const char *mac) { testDriverPtr privconn =3D conn->privateData; - virInterfaceObjPtr iface; int ifacect; + char *ifacenames[] =3D { NULL, NULL }; virInterfacePtr ret =3D NULL; =20 - testDriverLock(privconn); - ifacect =3D virInterfaceFindByMACString(&privconn->ifaces, mac, &iface= , 1); - testDriverUnlock(privconn); + ifacect =3D virInterfaceObjFindByMACString(conn, privconn->ifaces, + mac, ifacenames, 2); =20 if (ifacect =3D=3D 0) { virReportError(VIR_ERR_NO_INTERFACE, NULL); @@ -3743,35 +3708,35 @@ static virInterfacePtr testInterfaceLookupByMACStri= ng(virConnectPtr conn, goto cleanup; } =20 - ret =3D virGetInterface(conn, iface->def->name, iface->def->mac); + ret =3D virGetInterface(conn, ifacenames[0], mac); =20 cleanup: - if (iface) - virInterfaceObjUnlock(iface); + VIR_FREE(ifacenames[0]); + VIR_FREE(ifacenames[1]); return ret; } =20 -static int testInterfaceIsActive(virInterfacePtr iface) + +static int +testInterfaceIsActive(virInterfacePtr iface) { testDriverPtr privconn =3D iface->conn->privateData; - virInterfaceObjPtr obj; + virPoolObjPtr obj; int ret =3D -1; =20 - testDriverLock(privconn); - obj =3D virInterfaceFindByName(&privconn->ifaces, iface->name); - testDriverUnlock(privconn); - if (!obj) { - virReportError(VIR_ERR_NO_INTERFACE, NULL); - goto cleanup; - } - ret =3D virInterfaceObjIsActive(obj); + if (!(obj =3D testInterfaceObjFromName(privconn->ifaces, iface->name))) + return -1; =20 - cleanup: - if (obj) - virInterfaceObjUnlock(obj); + if (virPoolObjIsActive(obj)) + ret =3D 1; + else + ret =3D 0; + + virPoolObjEndAPI(&obj); return ret; } =20 + static int testInterfaceChangeBegin(virConnectPtr conn, unsigned int flags) { @@ -3789,8 +3754,7 @@ static int testInterfaceChangeBegin(virConnectPtr con= n, =20 privconn->transaction_running =3D true; =20 - if (virInterfaceObjListClone(&privconn->ifaces, - &privconn->backupIfaces) < 0) + if (!(privconn->backupIfaces =3D virInterfaceObjClone(privconn->ifaces= ))) goto cleanup; =20 ret =3D 0; @@ -3816,7 +3780,8 @@ static int testInterfaceChangeCommit(virConnectPtr co= nn, goto cleanup; } =20 - virInterfaceObjListFree(&privconn->backupIfaces); + virObjectUnref(privconn->backupIfaces); + privconn->backupIfaces =3D NULL; privconn->transaction_running =3D false; =20 ret =3D 0; @@ -3844,11 +3809,8 @@ static int testInterfaceChangeRollback(virConnectPtr= conn, goto cleanup; } =20 - virInterfaceObjListFree(&privconn->ifaces); - privconn->ifaces.count =3D privconn->backupIfaces.count; - privconn->ifaces.objs =3D privconn->backupIfaces.objs; - privconn->backupIfaces.count =3D 0; - privconn->backupIfaces.objs =3D NULL; + virObjectUnref(privconn->ifaces); + VIR_STEAL_PTR(privconn->ifaces, privconn->backupIfaces); =20 privconn->transaction_running =3D false; =20 @@ -3859,40 +3821,36 @@ static int testInterfaceChangeRollback(virConnectPt= r conn, return ret; } =20 -static char *testInterfaceGetXMLDesc(virInterfacePtr iface, - unsigned int flags) + +static char * +testInterfaceGetXMLDesc(virInterfacePtr iface, + unsigned int flags) { testDriverPtr privconn =3D iface->conn->privateData; - virInterfaceObjPtr privinterface; + virPoolObjPtr obj; char *ret =3D NULL; =20 virCheckFlags(0, NULL); =20 - testDriverLock(privconn); - privinterface =3D virInterfaceFindByName(&privconn->ifaces, - iface->name); - testDriverUnlock(privconn); - - if (privinterface =3D=3D NULL) { - virReportError(VIR_ERR_NO_INTERFACE, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testInterfaceObjFromName(privconn->ifaces, iface->name))) + return NULL; =20 - ret =3D virInterfaceDefFormat(privinterface->def); + ret =3D virInterfaceDefFormat(virPoolObjGetDef(obj)); =20 - cleanup: - if (privinterface) - virInterfaceObjUnlock(privinterface); + virPoolObjEndAPI(&obj); return ret; } =20 =20 -static virInterfacePtr testInterfaceDefineXML(virConnectPtr conn, const ch= ar *xmlStr, - unsigned int flags) +static virInterfacePtr +testInterfaceDefineXML(virConnectPtr conn, + const char *xmlStr, + unsigned int flags) { testDriverPtr privconn =3D conn->privateData; - virInterfaceDefPtr def; - virInterfaceObjPtr iface =3D NULL; + virInterfaceDefPtr def =3D NULL; + virPoolObjPtr obj; + virInterfaceDefPtr objdef; virInterfacePtr ret =3D NULL; =20 virCheckFlags(0, NULL); @@ -3901,107 +3859,88 @@ static virInterfacePtr testInterfaceDefineXML(virC= onnectPtr conn, const char *xm if ((def =3D virInterfaceDefParseString(xmlStr)) =3D=3D NULL) goto cleanup; =20 - if ((iface =3D virInterfaceAssignDef(&privconn->ifaces, def)) =3D=3D N= ULL) + if (!(obj =3D virPoolObjTableAdd(privconn->ifaces, NULL, def->name, + def, NULL, NULL, virInterfaceDefFree, + NULL, 0))) goto cleanup; - def =3D NULL; + VIR_STEAL_PTR(objdef, def); =20 - ret =3D virGetInterface(conn, iface->def->name, iface->def->mac); + ret =3D virGetInterface(conn, objdef->name, objdef->mac); =20 cleanup: virInterfaceDefFree(def); - if (iface) - virInterfaceObjUnlock(iface); + virPoolObjEndAPI(&obj); testDriverUnlock(privconn); return ret; } =20 -static int testInterfaceUndefine(virInterfacePtr iface) + +static int +testInterfaceUndefine(virInterfacePtr iface) { testDriverPtr privconn =3D iface->conn->privateData; - virInterfaceObjPtr privinterface; - int ret =3D -1; - - testDriverLock(privconn); - privinterface =3D virInterfaceFindByName(&privconn->ifaces, - iface->name); + virPoolObjPtr obj; =20 - if (privinterface =3D=3D NULL) { - virReportError(VIR_ERR_NO_INTERFACE, NULL); - goto cleanup; - } + if (!(obj =3D testInterfaceObjFromName(privconn->ifaces, iface->name))) + return -1; =20 - virInterfaceRemove(&privconn->ifaces, - privinterface); - ret =3D 0; + virPoolObjTableRemove(privconn->ifaces, &obj); =20 - cleanup: - testDriverUnlock(privconn); - return ret; + virPoolObjEndAPI(&obj); + return 0; } =20 -static int testInterfaceCreate(virInterfacePtr iface, - unsigned int flags) + +static int +testInterfaceCreate(virInterfacePtr iface, + unsigned int flags) { testDriverPtr privconn =3D iface->conn->privateData; - virInterfaceObjPtr privinterface; + virPoolObjPtr obj; int ret =3D -1; =20 virCheckFlags(0, -1); =20 - testDriverLock(privconn); - privinterface =3D virInterfaceFindByName(&privconn->ifaces, - iface->name); - - if (privinterface =3D=3D NULL) { - virReportError(VIR_ERR_NO_INTERFACE, NULL); - goto cleanup; - } + if (!(obj =3D testInterfaceObjFromName(privconn->ifaces, iface->name))) + return -1; =20 - if (privinterface->active !=3D 0) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, NULL); goto cleanup; } =20 - privinterface->active =3D 1; + virPoolObjSetActive(obj, true); ret =3D 0; =20 cleanup: - if (privinterface) - virInterfaceObjUnlock(privinterface); - testDriverUnlock(privconn); + virPoolObjEndAPI(&obj); return ret; } =20 -static int testInterfaceDestroy(virInterfacePtr iface, - unsigned int flags) + +static int +testInterfaceDestroy(virInterfacePtr iface, + unsigned int flags) { testDriverPtr privconn =3D iface->conn->privateData; - virInterfaceObjPtr privinterface; + virPoolObjPtr obj; int ret =3D -1; =20 virCheckFlags(0, -1); =20 - testDriverLock(privconn); - privinterface =3D virInterfaceFindByName(&privconn->ifaces, - iface->name); - - if (privinterface =3D=3D NULL) { - virReportError(VIR_ERR_NO_INTERFACE, NULL); - goto cleanup; - } + if (!(obj =3D testInterfaceObjFromName(privconn->ifaces, iface->name))) + return -1; =20 - if (privinterface->active =3D=3D 0) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, NULL); goto cleanup; } =20 - privinterface->active =3D 0; + virPoolObjSetActive(obj, false); ret =3D 0; =20 cleanup: - if (privinterface) - virInterfaceObjUnlock(privinterface); - testDriverUnlock(privconn); + virPoolObjEndAPI(&obj); return ret; } =20 --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 03:40:31 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.25 as permitted sender) client-ip=209.132.183.25; envelope-from=libvir-list-bounces@redhat.com; helo=mx4-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.25 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx4-phx2.redhat.com (mx4-phx2.redhat.com [209.132.183.25]) by mx.zohomail.com with SMTPS id 1486830895824440.3006763506995; Sat, 11 Feb 2017 08:34:55 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGUj1E031786; Sat, 11 Feb 2017 11:30:45 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGTrl9028531 for ; Sat, 11 Feb 2017 11:29:53 -0500 Received: from localhost.localdomain.com (ovpn-116-36.phx2.redhat.com [10.3.116.36]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGTmIp000660 for ; Sat, 11 Feb 2017 11:29:53 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Sat, 11 Feb 2017 11:29:41 -0500 Message-Id: <1486830585-23866-6-git-send-email-jferlan@redhat.com> In-Reply-To: <1486830585-23866-1-git-send-email-jferlan@redhat.com> References: <1486830585-23866-1-git-send-email-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH RFC 5/9] nwfilter: Convert virNWFilterObj[List] to use virPoolObj[Table] 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" Use the virPoolObj[Table] object management model in order to manage the NWFilter objects. While making the adjustments to use the new model, there are some code formatting adjustments that were also made with the goal to follow more recent code flow and layout. All nwfilter object management API's have their own virnwfilterobj entry points now instead of being mashed in with nwfilter_conf Signed-off-by: John Ferlan --- po/POTFILES.in | 1 + src/Makefile.am | 3 +- src/conf/nwfilter_conf.c | 381 ++---------------------------= ---- src/conf/nwfilter_conf.h | 69 +----- src/conf/virnwfilterobj.c | 373 +++++++++++++++++++++++++++++= +++ src/conf/virnwfilterobj.h | 64 ++++++ src/libvirt_private.syms | 23 +- src/nwfilter/nwfilter_driver.c | 225 +++++++------------ src/nwfilter/nwfilter_gentech_driver.c | 111 +++++----- src/nwfilter/nwfilter_gentech_driver.h | 2 +- src/nwfilter/nwfilter_tech_driver.h | 2 +- 11 files changed, 612 insertions(+), 642 deletions(-) create mode 100644 src/conf/virnwfilterobj.c create mode 100644 src/conf/virnwfilterobj.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 37379b5..0435265 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -43,6 +43,7 @@ src/conf/storage_conf.c src/conf/virchrdev.c src/conf/virdomainobjlist.c src/conf/virnodedeviceobj.c +src/conf/virnwfilterobj.c src/conf/virpoolobj.c src/conf/virsecretobj.c src/cpu/cpu.c diff --git a/src/Makefile.am b/src/Makefile.am index d864e6c..73f3dd0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -371,7 +371,8 @@ NWFILTER_PARAM_CONF_SOURCES =3D \ =20 NWFILTER_CONF_SOURCES =3D \ $(NWFILTER_PARAM_CONF_SOURCES) \ - conf/nwfilter_conf.c conf/nwfilter_conf.h + conf/nwfilter_conf.c conf/nwfilter_conf.h \ + conf/virnwfilterobj.c conf/virnwfilterobj.h =20 # "Generic" poolobj sources POOLOBJ_SOURCES =3D \ diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index 2cdcfa7..2d55667 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -30,7 +30,6 @@ #include #include #include -#include #if HAVE_NET_ETHERNET_H # include #endif @@ -326,8 +325,9 @@ virNWFilterEntryFree(virNWFilterEntryPtr entry) =20 =20 void -virNWFilterDefFree(virNWFilterDefPtr def) +virNWFilterDefFree(void *opaque) { + virNWFilterDefPtr def =3D opaque; size_t i; if (!def) return; @@ -344,32 +344,6 @@ virNWFilterDefFree(virNWFilterDefPtr def) } =20 =20 -void -virNWFilterObjFree(virNWFilterObjPtr obj) -{ - if (!obj) - return; - - virNWFilterDefFree(obj->def); - virNWFilterDefFree(obj->newDef); - - virMutexDestroy(&obj->lock); - - VIR_FREE(obj); -} - - -void -virNWFilterObjListFree(virNWFilterObjListPtr nwfilters) -{ - size_t i; - for (i =3D 0; i < nwfilters->count; i++) - virNWFilterObjFree(nwfilters->objs[i]); - VIR_FREE(nwfilters->objs); - nwfilters->count =3D 0; -} - - static int virNWFilterRuleDefAddVar(virNWFilterRuleDefPtr nwf, nwItemDesc *item, @@ -418,27 +392,6 @@ virNWFilterRuleDefAddString(virNWFilterRuleDefPtr nwf, } =20 =20 -void -virNWFilterObjRemove(virNWFilterObjListPtr nwfilters, - virNWFilterObjPtr nwfilter) -{ - size_t i; - - virNWFilterObjUnlock(nwfilter); - - for (i =3D 0; i < nwfilters->count; i++) { - virNWFilterObjLock(nwfilters->objs[i]); - if (nwfilters->objs[i] =3D=3D nwfilter) { - virNWFilterObjUnlock(nwfilters->objs[i]); - virNWFilterObjFree(nwfilters->objs[i]); - - VIR_DELETE_ELEMENT(nwfilters->objs, i, nwfilters->count); - break; - } - virNWFilterObjUnlock(nwfilters->objs[i]); - } -} - union data { void *v; char *c; @@ -2779,39 +2732,6 @@ virNWFilterDefParseFile(const char *filename) } =20 =20 -virNWFilterObjPtr -virNWFilterObjFindByUUID(virNWFilterObjListPtr nwfilters, - const unsigned char *uuid) -{ - size_t i; - - for (i =3D 0; i < nwfilters->count; i++) { - virNWFilterObjLock(nwfilters->objs[i]); - if (!memcmp(nwfilters->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN)) - return nwfilters->objs[i]; - virNWFilterObjUnlock(nwfilters->objs[i]); - } - - return NULL; -} - - -virNWFilterObjPtr -virNWFilterObjFindByName(virNWFilterObjListPtr nwfilters, const char *name) -{ - size_t i; - - for (i =3D 0; i < nwfilters->count; i++) { - virNWFilterObjLock(nwfilters->objs[i]); - if (STREQ_NULLABLE(nwfilters->objs[i]->def->name, name)) - return nwfilters->objs[i]; - virNWFilterObjUnlock(nwfilters->objs[i]); - } - - return NULL; -} - - int virNWFilterSaveXML(const char *configDir, virNWFilterDefPtr def, const char *xml) @@ -2860,62 +2780,6 @@ int virNWFilterSaveConfig(const char *configDir, } =20 =20 -static int -_virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters, - virNWFilterDefPtr def, - const char *filtername) -{ - int rc =3D 0; - size_t i; - virNWFilterEntryPtr entry; - virNWFilterObjPtr obj; - - if (!def) - return 0; - - for (i =3D 0; i < def->nentries; i++) { - entry =3D def->filterEntries[i]; - if (entry->include) { - - if (STREQ(filtername, entry->include->filterref)) { - rc =3D -1; - break; - } - - obj =3D virNWFilterObjFindByName(nwfilters, - entry->include->filterref); - if (obj) { - rc =3D _virNWFilterDefLoopDetect(nwfilters, - obj->def, filtername); - - virNWFilterObjUnlock(obj); - if (rc < 0) - break; - } - } - } - - return rc; -} - - -/* - * virNWFilterDefLoopDetect: - * @nwfilters : the nwfilters to search - * @def : the filter definition that may add a loop and is to be tested - * - * Detect a loop introduced through the filters being able to - * reference each other. - * - * Returns 0 in case no loop was detected, -1 otherwise. - */ -static int -virNWFilterDefLoopDetect(virNWFilterObjListPtr nwfilters, - virNWFilterDefPtr def) -{ - return _virNWFilterDefLoopDetect(nwfilters, def, def->name); -} - int nCallbackDriver; #define MAX_CALLBACK_DRIVER 10 static virNWFilterCallbackDriverPtr callbackDrvArray[MAX_CALLBACK_DRIVER]; @@ -2987,7 +2851,7 @@ virNWFilterInstFiltersOnAllVMs(void) return 0; } =20 -static int +int virNWFilterTriggerVMFilterRebuild(void) { size_t i; @@ -3028,223 +2892,23 @@ virNWFilterTriggerVMFilterRebuild(void) =20 =20 int -virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter) -{ - int rc =3D 0; - - nwfilter->wantRemoved =3D 1; - /* trigger the update on VMs referencing the filter */ - if (virNWFilterTriggerVMFilterRebuild()) - rc =3D -1; - - nwfilter->wantRemoved =3D 0; - - return rc; -} - -static bool -virNWFilterDefEqual(const virNWFilterDef *def1, virNWFilterDefPtr def2, - bool cmpUUIDs) -{ - bool ret =3D false; - unsigned char rem_uuid[VIR_UUID_BUFLEN]; - char *xml1, *xml2 =3D NULL; - - if (!cmpUUIDs) { - /* make sure the UUIDs are equal */ - memcpy(rem_uuid, def2->uuid, sizeof(rem_uuid)); - memcpy(def2->uuid, def1->uuid, sizeof(def2->uuid)); - } - - if (!(xml1 =3D virNWFilterDefFormat(def1)) || - !(xml2 =3D virNWFilterDefFormat(def2))) - goto cleanup; - - ret =3D STREQ(xml1, xml2); - - cleanup: - if (!cmpUUIDs) - memcpy(def2->uuid, rem_uuid, sizeof(rem_uuid)); - - VIR_FREE(xml1); - VIR_FREE(xml2); - - return ret; -} - -virNWFilterObjPtr -virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters, - virNWFilterDefPtr def) -{ - virNWFilterObjPtr nwfilter; - - nwfilter =3D virNWFilterObjFindByUUID(nwfilters, def->uuid); - - if (nwfilter) { - if (STRNEQ(def->name, nwfilter->def->name)) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("filter with same UUID but different name " - "('%s') already exists"), - nwfilter->def->name); - virNWFilterObjUnlock(nwfilter); - return NULL; - } - virNWFilterObjUnlock(nwfilter); - } else { - nwfilter =3D virNWFilterObjFindByName(nwfilters, def->name); - if (nwfilter) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(nwfilter->def->uuid, uuidstr); - virReportError(VIR_ERR_OPERATION_FAILED, - _("filter '%s' already exists with uuid %s"), - def->name, uuidstr); - virNWFilterObjUnlock(nwfilter); - return NULL; - } - } - - if (virNWFilterDefLoopDetect(nwfilters, def) < 0) { - virReportError(VIR_ERR_OPERATION_FAILED, - "%s", _("filter would introduce a loop")); - return NULL; - } - - - if ((nwfilter =3D virNWFilterObjFindByName(nwfilters, def->name))) { - - if (virNWFilterDefEqual(def, nwfilter->def, false)) { - virNWFilterDefFree(nwfilter->def); - nwfilter->def =3D def; - return nwfilter; - } - - nwfilter->newDef =3D def; - /* trigger the update on VMs referencing the filter */ - if (virNWFilterTriggerVMFilterRebuild()) { - nwfilter->newDef =3D NULL; - virNWFilterObjUnlock(nwfilter); - return NULL; - } - - virNWFilterDefFree(nwfilter->def); - nwfilter->def =3D def; - nwfilter->newDef =3D NULL; - return nwfilter; - } - - if (VIR_ALLOC(nwfilter) < 0) - return NULL; - - if (virMutexInitRecursive(&nwfilter->lock) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("cannot initialize mutex")); - VIR_FREE(nwfilter); - return NULL; - } - virNWFilterObjLock(nwfilter); - nwfilter->active =3D 0; - - if (VIR_APPEND_ELEMENT_COPY(nwfilters->objs, - nwfilters->count, nwfilter) < 0) { - virNWFilterObjUnlock(nwfilter); - virNWFilterObjFree(nwfilter); - return NULL; - } - nwfilter->def =3D def; - - return nwfilter; -} - - -static virNWFilterObjPtr -virNWFilterLoadConfig(virNWFilterObjListPtr nwfilters, - const char *configDir, - const char *name) -{ - virNWFilterDefPtr def =3D NULL; - virNWFilterObjPtr nwfilter; - char *configFile =3D NULL; - - if (!(configFile =3D virFileBuildPath(configDir, name, ".xml"))) - goto error; - - if (!(def =3D virNWFilterDefParseFile(configFile))) - goto error; - - if (STRNEQ(name, def->name)) { - virReportError(VIR_ERR_XML_ERROR, - _("network filter config filename '%s' " - "does not match name '%s'"), - configFile, def->name); - goto error; - } - - /* We generated a UUID, make it permanent by saving the config to disk= */ - if (!def->uuid_specified && - virNWFilterSaveConfig(configDir, def) < 0) - goto error; - - if (!(nwfilter =3D virNWFilterObjAssignDef(nwfilters, def))) - goto error; - - VIR_FREE(configFile); - return nwfilter; - - error: - VIR_FREE(configFile); - virNWFilterDefFree(def); - return NULL; -} - - -int -virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters, - const char *configDir) -{ - DIR *dir; - struct dirent *entry; - int ret =3D -1; - int rc; - - if ((rc =3D virDirOpenIfExists(&dir, configDir)) <=3D 0) - return rc; - - while ((ret =3D virDirRead(dir, &entry, configDir)) > 0) { - virNWFilterObjPtr nwfilter; - - if (!virFileStripSuffix(entry->d_name, ".xml")) - continue; - - nwfilter =3D virNWFilterLoadConfig(nwfilters, configDir, entry->d_= name); - if (nwfilter) - virNWFilterObjUnlock(nwfilter); - } - - VIR_DIR_CLOSE(dir); - return ret; -} - - -int -virNWFilterObjSaveDef(virNWFilterDriverStatePtr driver, - virNWFilterDefPtr def) +virNWFilterSaveDef(const char *configDir, + virNWFilterDefPtr def) { char uuidstr[VIR_UUID_STRING_BUFLEN]; char *xml; int ret =3D -1; char *configFile =3D NULL; =20 - if (virFileMakePath(driver->configDir) < 0) { + if (virFileMakePath(configDir) < 0) { virReportSystemError(errno, _("cannot create config directory %s"), - driver->configDir); + configDir); goto error; } =20 - if (!(configFile =3D virFileBuildPath(driver->configDir, - def->name, ".xml"))) { + if (!(configFile =3D virFileBuildPath(configDir, def->name, ".xml"))) goto error; - } =20 if (!(xml =3D virNWFilterDefFormat(def))) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -3265,26 +2929,24 @@ virNWFilterObjSaveDef(virNWFilterDriverStatePtr dri= ver, =20 =20 int -virNWFilterObjDeleteDef(const char *configDir, - virNWFilterObjPtr nwfilter) +virNWFilterDeleteDef(const char *configDir, + virNWFilterDefPtr def) { int ret =3D -1; char *configFile =3D NULL; =20 - if (!(configFile =3D virFileBuildPath(configDir, - nwfilter->def->name, ".xml"))) { - goto error; - } + if (!(configFile =3D virFileBuildPath(configDir, def->name, ".xml"))) + return -1; =20 if (unlink(configFile) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot remove config for %s"), - nwfilter->def->name); - goto error; + _("cannot remove config for %s"), def->name); + goto cleanup; } =20 ret =3D 0; - error: + + cleanup: VIR_FREE(configFile); return ret; } @@ -3572,17 +3234,6 @@ void virNWFilterConfLayerShutdown(void) } =20 =20 -void virNWFilterObjLock(virNWFilterObjPtr obj) -{ - virMutexLock(&obj->lock); -} - -void virNWFilterObjUnlock(virNWFilterObjPtr obj) -{ - virMutexUnlock(&obj->lock); -} - - bool virNWFilterRuleIsProtocolIPv4(virNWFilterRuleDefPtr rule) { if (rule->prtclType >=3D VIR_NWFILTER_RULE_PROTOCOL_TCP && diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h index ea3cd5c..7f997a4 100644 --- a/src/conf/nwfilter_conf.h +++ b/src/conf/nwfilter_conf.h @@ -546,41 +546,6 @@ struct _virNWFilterDef { }; =20 =20 -typedef struct _virNWFilterObj virNWFilterObj; -typedef virNWFilterObj *virNWFilterObjPtr; - -struct _virNWFilterObj { - virMutex lock; - - int active; - int wantRemoved; - - virNWFilterDefPtr def; - virNWFilterDefPtr newDef; -}; - - -typedef struct _virNWFilterObjList virNWFilterObjList; -typedef virNWFilterObjList *virNWFilterObjListPtr; -struct _virNWFilterObjList { - size_t count; - virNWFilterObjPtr *objs; -}; - - -typedef struct _virNWFilterDriverState virNWFilterDriverState; -typedef virNWFilterDriverState *virNWFilterDriverStatePtr; -struct _virNWFilterDriverState { - virMutex lock; - bool privileged; - - virNWFilterObjList nwfilters; - - char *configDir; - bool watchingFirewallD; -}; - - typedef enum { STEP_APPLY_NEW, STEP_TEAR_NEW, @@ -597,30 +562,15 @@ struct domUpdateCBStruct { =20 void virNWFilterRuleDefFree(virNWFilterRuleDefPtr def); =20 -void virNWFilterDefFree(virNWFilterDefPtr def); -void virNWFilterObjListFree(virNWFilterObjListPtr nwfilters); -void virNWFilterObjRemove(virNWFilterObjListPtr nwfilters, - virNWFilterObjPtr nwfilter); - -void virNWFilterObjFree(virNWFilterObjPtr obj); +void virNWFilterDefFree(void *opaque); =20 -virNWFilterObjPtr virNWFilterObjFindByUUID(virNWFilterObjListPtr nwfilters, - const unsigned char *uuid); +int virNWFilterTriggerVMFilterRebuild(void); =20 -virNWFilterObjPtr virNWFilterObjFindByName(virNWFilterObjListPtr nwfilters, - const char *name); - - -int virNWFilterObjSaveDef(virNWFilterDriverStatePtr driver, - virNWFilterDefPtr def); +int virNWFilterSaveDef(const char *configDir, + virNWFilterDefPtr def); =20 -int virNWFilterObjDeleteDef(const char *configDir, - virNWFilterObjPtr nwfilter); - -virNWFilterObjPtr virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters, - virNWFilterDefPtr def); - -int virNWFilterTestUnassignDef(virNWFilterObjPtr nwfilter); +int virNWFilterDeleteDef(const char *configDir, + virNWFilterDefPtr def); =20 virNWFilterDefPtr virNWFilterDefParseNode(xmlDocPtr xml, xmlNodePtr root); @@ -634,18 +584,12 @@ int virNWFilterSaveXML(const char *configDir, int virNWFilterSaveConfig(const char *configDir, virNWFilterDefPtr def); =20 -int virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters, - const char *configDir); - char *virNWFilterConfigFile(const char *dir, const char *name); =20 virNWFilterDefPtr virNWFilterDefParseString(const char *xml); virNWFilterDefPtr virNWFilterDefParseFile(const char *filename); =20 -void virNWFilterObjLock(virNWFilterObjPtr obj); -void virNWFilterObjUnlock(virNWFilterObjPtr obj); - void virNWFilterWriteLockFilterUpdates(void); void virNWFilterReadLockFilterUpdates(void); void virNWFilterUnlockFilterUpdates(void); @@ -655,7 +599,6 @@ void virNWFilterConfLayerShutdown(void); =20 int virNWFilterInstFiltersOnAllVMs(void); =20 - typedef int (*virNWFilterRebuild)(virDomainObjListIterator domUpdateCB, void *data); typedef void (*virNWFilterVoidCall)(void); diff --git a/src/conf/virnwfilterobj.c b/src/conf/virnwfilterobj.c new file mode 100644 index 0000000..44c171f --- /dev/null +++ b/src/conf/virnwfilterobj.c @@ -0,0 +1,373 @@ +/* + * virnwfilterobj.c: network filter object processing + * (derived from nwfilter_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 + +#include "datatypes.h" + +#include "viralloc.h" +#include "virerror.h" +#include "virfile.h" +#include "virlog.h" +#include "virnwfilterobj.h" +#include "virstring.h" + +#define VIR_FROM_THIS VIR_FROM_NWFILTER + +VIR_LOG_INIT("conf.virnwfilterobj"); + +struct nwfilterLoopSearchData { + const char *filtername; +}; + +static bool +nwfilterLoopSearch(virPoolObjPtr obj, + void *opaque) +{ + virNWFilterDefPtr def =3D virPoolObjGetDef(obj); + struct nwfilterLoopSearchData *data =3D opaque; + virNWFilterEntryPtr entry; + size_t i; + + for (i =3D 0; i < def->nentries; i++) { + entry =3D def->filterEntries[i]; + if (entry->include && + STREQ(data->filtername, entry->include->filterref)) + return true; + } + + return false; +} + + +/* + * nwfilterLoopDetect: + * @nwfilters : the nwfilters to search + * @filtername: the filter name that may add a loop and is to be tested + * + * Detect a loop introduced through the filters being able to + * reference each other. + * + * Returns 0 in case no loop was detected, -1 otherwise. + */ +static int +nwfilterLoopDetect(virPoolObjTablePtr nwfilters, + const char *filtername) +{ + struct nwfilterLoopSearchData data =3D { .filtername =3D filtername }; + virPoolObjPtr obj; + + if ((obj =3D virPoolObjTableSearch(nwfilters, nwfilterLoopSearch, &dat= a))) { + virObjectUnlock(obj); + return -1; + } + + return 0; +} + + +static bool +nwfilterDefEqual(const virNWFilterDef *def1, + virNWFilterDefPtr def2, + bool cmpUUIDs) +{ + bool ret =3D false; + unsigned char rem_uuid[VIR_UUID_BUFLEN]; + char *xml1, *xml2 =3D NULL; + + if (!cmpUUIDs) { + /* make sure the UUIDs are equal */ + memcpy(rem_uuid, def2->uuid, sizeof(rem_uuid)); + memcpy(def2->uuid, def1->uuid, sizeof(def2->uuid)); + } + + if (!(xml1 =3D virNWFilterDefFormat(def1)) || + !(xml2 =3D virNWFilterDefFormat(def2))) + goto cleanup; + + ret =3D STREQ(xml1, xml2); + + cleanup: + if (!cmpUUIDs) + memcpy(def2->uuid, rem_uuid, sizeof(rem_uuid)); + + VIR_FREE(xml1); + VIR_FREE(xml2); + + return ret; +} + + +static int +nwfilterAssignDef(virPoolObjPtr obj, + void *newDef, + void *oldDef ATTRIBUTE_UNUSED, + unsigned int assignFlags ATTRIBUTE_UNUSED) +{ + virNWFilterDefPtr newdef =3D newDef; + + + if (nwfilterDefEqual(newdef, virPoolObjGetDef(obj), false)) { + virPoolObjSetDef(obj, newdef); + } else { + virPoolObjSetNewDef(obj, newdef); + + /* trigger the update on VMs referencing the filter */ + if (virNWFilterTriggerVMFilterRebuild()) { + virPoolObjSetNewDef(obj, NULL); + return -1; + } + + virPoolObjSetDef(obj, newdef); + virPoolObjSetNewDef(obj, NULL); + } + return 0; +} + + +virPoolObjPtr +virNWFilterObjAdd(virPoolObjTablePtr nwfilters, + virNWFilterDefPtr def) +{ + virPoolObjPtr obj; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + + /* Check if this filter def's name is referenced already by + * some other filter's include path */ + if (nwfilterLoopDetect(nwfilters, def->name) < 0) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("filter '%s' would introduce a loop"), def->name); + return NULL; + } + + virUUIDFormat(def->uuid, uuidstr); + if (!(obj =3D virPoolObjTableAdd(nwfilters, uuidstr, def->name, + def, NULL, NULL, virNWFilterDefFree, + nwfilterAssignDef, 0))) + return NULL; + + return obj; +} + + +int +virNWFilterObjTestUnassignDef(virPoolObjPtr obj) +{ + int rc =3D 0; + + virPoolObjSetBeingRemoved(obj, true); + /* trigger the update on VMs referencing the filter */ + if (virNWFilterTriggerVMFilterRebuild()) + rc =3D -1; + virPoolObjSetBeingRemoved(obj, false); + + return rc; +} + + +struct nwfilterCountData { + int count; +}; + +static int +nwfilterCount(virPoolObjPtr obj ATTRIBUTE_UNUSED, + void *opaque) +{ + struct nwfilterCountData *data =3D opaque; + + data->count++; + return 0; +} + + +int +virNWFilterObjNumOfNWFilters(virPoolObjTablePtr nwfilters, + virConnectPtr conn, + virPoolObjACLFilter aclfilter) +{ + struct nwfilterCountData data =3D { .count =3D 0 }; + + if (virPoolObjTableList(nwfilters, conn, aclfilter, + nwfilterCount, &data) < 0) + return 0; + + return data.count; +} + + +struct nwfilterNameData { + int nnames; + char **const names; + int maxnames; +}; + +static int nwfilterGetNames(virPoolObjPtr obj, + void *opaque) +{ + virNWFilterDefPtr def =3D virPoolObjGetDef(obj); + struct nwfilterNameData *data =3D opaque; + + if (data->nnames < data->maxnames) { + if (VIR_STRDUP(data->names[data->nnames++], def->name) < 0) + return -1; + } + + return 0; +} + + +int +virNWFilterObjGetFilters(virPoolObjTablePtr nwfilters, + virConnectPtr conn, + virPoolObjACLFilter aclfilter, + char **names, + int maxnames) +{ + struct nwfilterNameData data =3D { .nnames =3D 0, + .names =3D names, + .maxnames =3D maxnames }; + + if (virPoolObjTableList(nwfilters, conn, aclfilter, + nwfilterGetNames, &data) < 0) + goto failure; + + return data.nnames; + + failure: + while (data.nnames >=3D 0) + VIR_FREE(data.names[--data.nnames]); + + return -1; +} + + +int +virNWFilterObjExportList(virConnectPtr conn, + virPoolObjTablePtr nwfilters, + virNWFilterPtr **filters, + virPoolObjACLFilter aclfilter, + unsigned int flags) +{ + virPoolObjPtr *objs =3D NULL; + size_t nobjs =3D 0; + virNWFilterPtr *filts =3D NULL; + int ret =3D -1; + size_t i; + + if (virPoolObjTableCollect(nwfilters, conn, &objs, &nobjs, aclfilter, + NULL, flags) < 0) + return -1; + + if (filters) { + if (VIR_ALLOC_N(filts, nobjs + 1) < 0) + goto cleanup; + + for (i =3D 0; i < nobjs; i++) { + virPoolObjPtr obj =3D objs[i]; + virNWFilterDefPtr def; + + virObjectLock(obj); + def =3D virPoolObjGetDef(obj); + filts[i] =3D virGetNWFilter(conn, def->name, def->uuid); + virObjectUnlock(obj); + + if (!filts[i]) + goto cleanup; + } + + *filters =3D filts; + filts =3D NULL; + } + + ret =3D nobjs; + + cleanup: + virObjectListFree(filts); + virObjectListFreeCount(objs, nobjs); + return ret; +} + + +static virPoolObjPtr +virNWFilterLoadConfig(virPoolObjTablePtr nwfilters, + const char *configDir, + const char *name) +{ + virNWFilterDefPtr def =3D NULL; + virPoolObjPtr obj; + char *configFile =3D NULL; + + if (!(configFile =3D virFileBuildPath(configDir, name, ".xml"))) + goto error; + + if (!(def =3D virNWFilterDefParseFile(configFile))) + goto error; + + if (STRNEQ(name, def->name)) { + virReportError(VIR_ERR_XML_ERROR, + _("network filter config filename '%s' " + "does not match name '%s'"), + configFile, def->name); + goto error; + } + + /* We generated a UUID, make it permanent by saving the config to disk= */ + if (!def->uuid_specified && + virNWFilterSaveConfig(configDir, def) < 0) + goto error; + + if (!(obj =3D virNWFilterObjAdd(nwfilters, def))) + goto error; + + VIR_FREE(configFile); + return obj; + + error: + VIR_FREE(configFile); + virNWFilterDefFree(def); + return NULL; +} + + +int +virNWFilterObjLoadAllConfigs(virPoolObjTablePtr nwfilters, + const char *configDir) +{ + DIR *dir; + struct dirent *entry; + int ret =3D -1; + int rc; + + if ((rc =3D virDirOpenIfExists(&dir, configDir)) <=3D 0) + return rc; + + while ((ret =3D virDirRead(dir, &entry, configDir)) > 0) { + virPoolObjPtr obj; + + if (!virFileStripSuffix(entry->d_name, ".xml")) + continue; + + if ((obj =3D virNWFilterLoadConfig(nwfilters, configDir, entry->d_= name))) + virPoolObjEndAPI(&obj); + } + + VIR_DIR_CLOSE(dir); + return ret; +} diff --git a/src/conf/virnwfilterobj.h b/src/conf/virnwfilterobj.h new file mode 100644 index 0000000..29eaf10 --- /dev/null +++ b/src/conf/virnwfilterobj.h @@ -0,0 +1,64 @@ +/* + * virnwfilterobj.h: network filter object processing + * (derived from nwfilter_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 VIRNWFILTEROBJ_H +# define VIRNWFILTEROBJ_H + +# include "internal.h" + +# include "nwfilter_conf.h" +# include "virpoolobj.h" + +typedef struct _virNWFilterDriverState virNWFilterDriverState; +typedef virNWFilterDriverState *virNWFilterDriverStatePtr; +struct _virNWFilterDriverState { + virMutex lock; + bool privileged; + + virPoolObjTablePtr nwfilters; + + char *configDir; + bool watchingFirewallD; +}; + + +virPoolObjPtr virNWFilterObjAdd(virPoolObjTablePtr nwfilters, + virNWFilterDefPtr def); + +int virNWFilterObjTestUnassignDef(virPoolObjPtr obj); + +int virNWFilterObjNumOfNWFilters(virPoolObjTablePtr nwfilters, + virConnectPtr conn, + virPoolObjACLFilter aclfilter); + +int virNWFilterObjGetFilters(virPoolObjTablePtr nwfilters, + virConnectPtr conn, + virPoolObjACLFilter aclfilter, + char **names, + int maxnames); + +int virNWFilterObjExportList(virConnectPtr conn, + virPoolObjTablePtr nwfilters, + virNWFilterPtr **filters, + virPoolObjACLFilter aclfilter, + unsigned int flags); + +int virNWFilterObjLoadAllConfigs(virPoolObjTablePtr nwfilters, + const char *configDir); + +#endif /* VIRNWFILTEROBJ_H */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5f95814..2e9f0c2 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -742,18 +742,9 @@ virNWFilterDefFormat; virNWFilterDefFree; virNWFilterDefParseFile; virNWFilterDefParseString; +virNWFilterDeleteDef; virNWFilterInstFiltersOnAllVMs; virNWFilterJumpTargetTypeToString; -virNWFilterLoadAllConfigs; -virNWFilterObjAssignDef; -virNWFilterObjDeleteDef; -virNWFilterObjFindByName; -virNWFilterObjFindByUUID; -virNWFilterObjListFree; -virNWFilterObjLock; -virNWFilterObjRemove; -virNWFilterObjSaveDef; -virNWFilterObjUnlock; virNWFilterPrintStateMatchFlags; virNWFilterPrintTCPFlags; virNWFilterReadLockFilterUpdates; @@ -764,7 +755,8 @@ virNWFilterRuleIsProtocolEthernet; virNWFilterRuleIsProtocolIPv4; virNWFilterRuleIsProtocolIPv6; virNWFilterRuleProtocolTypeToString; -virNWFilterTestUnassignDef; +virNWFilterSaveDef; +virNWFilterTriggerVMFilterRebuild; virNWFilterUnlockFilterUpdates; virNWFilterUnRegisterCallbackDriver; virNWFilterWriteLockFilterUpdates; @@ -959,6 +951,15 @@ virNodeDeviceObjGetParentHostByWWNs; virNodeDeviceObjNumOfDevices; =20 =20 +# conf/virnwfilterobj.h +virNWFilterObjAdd; +virNWFilterObjExportList; +virNWFilterObjGetFilters; +virNWFilterObjLoadAllConfigs; +virNWFilterObjNumOfNWFilters; +virNWFilterObjTestUnassignDef; + + # conf/virpoolobj.h virPoolObjEndAPI; virPoolObjGetDef; diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c index 186830c..4d69072 100644 --- a/src/nwfilter/nwfilter_driver.c +++ b/src/nwfilter/nwfilter_driver.c @@ -37,7 +37,6 @@ #include "viralloc.h" #include "domain_conf.h" #include "domain_nwfilter.h" -#include "nwfilter_conf.h" #include "nwfilter_driver.h" #include "nwfilter_gentech_driver.h" #include "configmake.h" @@ -238,8 +237,12 @@ nwfilterStateInitialize(bool privileged, =20 VIR_FREE(base); =20 - if (virNWFilterLoadAllConfigs(&driver->nwfilters, - driver->configDir) < 0) + if (!(driver->nwfilters =3D + virPoolObjTableNew(VIR_POOLOBJTABLE_NWFILTER, + VIR_POOLOBJTABLE_NWFILTER_HASHSTART, false))) + goto error; + + if (virNWFilterObjLoadAllConfigs(driver->nwfilters, driver->configDir)= < 0) goto error; =20 nwfilterDriverUnlock(); @@ -291,8 +294,7 @@ nwfilterStateReload(void) virNWFilterWriteLockFilterUpdates(); virNWFilterCallbackDriversLock(); =20 - virNWFilterLoadAllConfigs(&driver->nwfilters, - driver->configDir); + virNWFilterObjLoadAllConfigs(driver->nwfilters, driver->configDir); =20 virNWFilterCallbackDriversUnlock(); virNWFilterUnlockFilterUpdates(); @@ -343,7 +345,7 @@ nwfilterStateCleanup(void) nwfilterDriverRemoveDBusMatches(); =20 /* free inactive nwfilters */ - virNWFilterObjListFree(&driver->nwfilters); + virObjectUnref(driver->nwfilters); =20 VIR_FREE(driver->configDir); nwfilterDriverUnlock(); @@ -356,31 +358,45 @@ nwfilterStateCleanup(void) } =20 =20 +static virPoolObjPtr +nwfilterObjFromNWFilter(virNWFilterPtr nwfilter) +{ + virPoolObjPtr obj; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + + if (!(obj =3D virPoolObjTableFindByUUIDRef(driver->nwfilters, + nwfilter->uuid))) { + virReportError(VIR_ERR_NO_NWFILTER, + _("no nwfilter with matching uuid '%s'"), + uuidstr); + return NULL; + } + return obj; +} + + static virNWFilterPtr nwfilterLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { - virNWFilterObjPtr nwfilter; + virPoolObjPtr obj; + virNWFilterDefPtr def; virNWFilterPtr ret =3D NULL; =20 - nwfilterDriverLock(); - nwfilter =3D virNWFilterObjFindByUUID(&driver->nwfilters, uuid); - nwfilterDriverUnlock(); - - if (!nwfilter) { + if (!(obj =3D virPoolObjTableFindByUUIDRef(driver->nwfilters, uuid))) { virReportError(VIR_ERR_NO_NWFILTER, "%s", _("no nwfilter with matching uuid")); goto cleanup; } =20 - if (virNWFilterLookupByUUIDEnsureACL(conn, nwfilter->def) < 0) + def =3D virPoolObjGetDef(obj); + if (virNWFilterLookupByUUIDEnsureACL(conn, def) < 0) goto cleanup; =20 - ret =3D virGetNWFilter(conn, nwfilter->def->name, nwfilter->def->uuid); + ret =3D virGetNWFilter(conn, def->name, def->uuid); =20 cleanup: - if (nwfilter) - virNWFilterObjUnlock(nwfilter); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -389,27 +405,24 @@ static virNWFilterPtr nwfilterLookupByName(virConnectPtr conn, const char *name) { - virNWFilterObjPtr nwfilter; + virPoolObjPtr obj; + virNWFilterDefPtr def; virNWFilterPtr ret =3D NULL; =20 - nwfilterDriverLock(); - nwfilter =3D virNWFilterObjFindByName(&driver->nwfilters, name); - nwfilterDriverUnlock(); - - if (!nwfilter) { + if (!(obj =3D virPoolObjTableFindByName(driver->nwfilters, name))) { virReportError(VIR_ERR_NO_NWFILTER, _("no nwfilter with matching name '%s'"), name); goto cleanup; } =20 - if (virNWFilterLookupByNameEnsureACL(conn, nwfilter->def) < 0) + def =3D virPoolObjGetDef(obj); + if (virNWFilterLookupByNameEnsureACL(conn, def) < 0) goto cleanup; =20 - ret =3D virGetNWFilter(conn, nwfilter->def->name, nwfilter->def->uuid); + ret =3D virGetNWFilter(conn, def->name, def->uuid); =20 cleanup: - if (nwfilter) - virNWFilterObjUnlock(nwfilter); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -417,58 +430,27 @@ nwfilterLookupByName(virConnectPtr conn, static int nwfilterConnectNumOfNWFilters(virConnectPtr conn) { - size_t i; - int n; - if (virConnectNumOfNWFiltersEnsureACL(conn) < 0) return -1; =20 - n =3D 0; - for (i =3D 0; i < driver->nwfilters.count; i++) { - virNWFilterObjPtr obj =3D driver->nwfilters.objs[i]; - virNWFilterObjLock(obj); - if (virConnectNumOfNWFiltersCheckACL(conn, obj->def)) - n++; - virNWFilterObjUnlock(obj); - } - - return n; + return virNWFilterObjNumOfNWFilters(driver->nwfilters, conn, + virConnectNumOfNWFiltersCheckACL); } =20 =20 static int nwfilterConnectListNWFilters(virConnectPtr conn, - char **const names, - int nnames) + char **names, + int maxnames) { - int got =3D 0; - size_t i; + memset(names, 0, maxnames * sizeof(*names)); =20 if (virConnectListNWFiltersEnsureACL(conn) < 0) return -1; =20 - nwfilterDriverLock(); - for (i =3D 0; i < driver->nwfilters.count && got < nnames; i++) { - virNWFilterObjPtr obj =3D driver->nwfilters.objs[i]; - virNWFilterObjLock(obj); - if (virConnectListNWFiltersCheckACL(conn, obj->def)) { - if (VIR_STRDUP(names[got], obj->def->name) < 0) { - virNWFilterObjUnlock(obj); - goto cleanup; - } - got++; - } - virNWFilterObjUnlock(obj); - } - nwfilterDriverUnlock(); - return got; - - cleanup: - nwfilterDriverUnlock(); - for (i =3D 0; i < got; i++) - VIR_FREE(names[i]); - memset(names, 0, nnames * sizeof(*names)); - return -1; + return virNWFilterObjGetFilters(driver->nwfilters, conn, + virConnectListNWFiltersCheckACL, + names, maxnames); } =20 =20 @@ -477,63 +459,23 @@ nwfilterConnectListAllNWFilters(virConnectPtr conn, virNWFilterPtr **filters, unsigned int flags) { - virNWFilterPtr *tmp_filters =3D NULL; - int nfilters =3D 0; - virNWFilterPtr filter =3D NULL; - virNWFilterObjPtr obj =3D NULL; - size_t i; - int ret =3D -1; - virCheckFlags(0, -1); =20 if (virConnectListAllNWFiltersEnsureACL(conn) < 0) return -1; =20 - nwfilterDriverLock(); - - if (!filters) { - ret =3D driver->nwfilters.count; - goto cleanup; - } - - if (VIR_ALLOC_N(tmp_filters, driver->nwfilters.count + 1) < 0) - goto cleanup; - - for (i =3D 0; i < driver->nwfilters.count; i++) { - obj =3D driver->nwfilters.objs[i]; - virNWFilterObjLock(obj); - if (virConnectListAllNWFiltersCheckACL(conn, obj->def)) { - if (!(filter =3D virGetNWFilter(conn, obj->def->name, - obj->def->uuid))) { - virNWFilterObjUnlock(obj); - goto cleanup; - } - tmp_filters[nfilters++] =3D filter; - } - virNWFilterObjUnlock(obj); - } - - *filters =3D tmp_filters; - tmp_filters =3D NULL; - ret =3D nfilters; - - cleanup: - nwfilterDriverUnlock(); - if (tmp_filters) { - for (i =3D 0; i < nfilters; i ++) - virObjectUnref(tmp_filters[i]); - } - VIR_FREE(tmp_filters); - - return ret; + return virNWFilterObjExportList(conn, driver->nwfilters, filters, + virConnectListAllNWFiltersCheckACL, fl= ags); } =20 + static virNWFilterPtr nwfilterDefineXML(virConnectPtr conn, const char *xml) { virNWFilterDefPtr def; - virNWFilterObjPtr nwfilter =3D NULL; + virNWFilterDefPtr objdef; + virPoolObjPtr obj =3D NULL; virNWFilterPtr ret =3D NULL; =20 if (!driver->privileged) { @@ -552,22 +494,20 @@ nwfilterDefineXML(virConnectPtr conn, if (virNWFilterDefineXMLEnsureACL(conn, def) < 0) goto cleanup; =20 - if (!(nwfilter =3D virNWFilterObjAssignDef(&driver->nwfilters, def))) + if (!(obj =3D virNWFilterObjAdd(driver->nwfilters, def))) goto cleanup; + VIR_STEAL_PTR(objdef, def); =20 - if (virNWFilterObjSaveDef(driver, def) < 0) { - virNWFilterObjRemove(&driver->nwfilters, nwfilter); - def =3D NULL; + if (virNWFilterSaveDef(driver->configDir, objdef) < 0) { + virPoolObjTableRemove(driver->nwfilters, &obj); goto cleanup; } - def =3D NULL; =20 - ret =3D virGetNWFilter(conn, nwfilter->def->name, nwfilter->def->uuid); + ret =3D virGetNWFilter(conn, objdef->name, objdef->uuid); =20 cleanup: virNWFilterDefFree(def); - if (nwfilter) - virNWFilterObjUnlock(nwfilter); + virPoolObjEndAPI(&obj); =20 virNWFilterCallbackDriversUnlock(); virNWFilterUnlockFilterUpdates(); @@ -577,42 +517,37 @@ nwfilterDefineXML(virConnectPtr conn, =20 =20 static int -nwfilterUndefine(virNWFilterPtr obj) +nwfilterUndefine(virNWFilterPtr nwfilter) { - virNWFilterObjPtr nwfilter; + virPoolObjPtr obj; + virNWFilterDefPtr def; int ret =3D -1; =20 nwfilterDriverLock(); virNWFilterWriteLockFilterUpdates(); virNWFilterCallbackDriversLock(); =20 - nwfilter =3D virNWFilterObjFindByUUID(&driver->nwfilters, obj->uuid); - if (!nwfilter) { - virReportError(VIR_ERR_NO_NWFILTER, - "%s", _("no nwfilter with matching uuid")); + if (!(obj =3D nwfilterObjFromNWFilter(nwfilter))) goto cleanup; - } + def =3D virPoolObjGetDef(obj); =20 - if (virNWFilterUndefineEnsureACL(obj->conn, nwfilter->def) < 0) + if (virNWFilterUndefineEnsureACL(nwfilter->conn, def) < 0) goto cleanup; =20 - if (virNWFilterTestUnassignDef(nwfilter) < 0) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", + if (virNWFilterObjTestUnassignDef(obj) < 0) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("nwfilter is in use")); goto cleanup; } =20 - if (virNWFilterObjDeleteDef(driver->configDir, nwfilter) < 0) + if (virNWFilterDeleteDef(driver->configDir, def) < 0) goto cleanup; =20 - virNWFilterObjRemove(&driver->nwfilters, nwfilter); - nwfilter =3D NULL; + virPoolObjTableRemove(driver->nwfilters, &obj); ret =3D 0; =20 cleanup: - if (nwfilter) - virNWFilterObjUnlock(nwfilter); + virPoolObjEndAPI(&obj); =20 virNWFilterCallbackDriversUnlock(); virNWFilterUnlockFilterUpdates(); @@ -622,32 +557,26 @@ nwfilterUndefine(virNWFilterPtr obj) =20 =20 static char * -nwfilterGetXMLDesc(virNWFilterPtr obj, +nwfilterGetXMLDesc(virNWFilterPtr nwfilter, unsigned int flags) { - virNWFilterObjPtr nwfilter; + virPoolObjPtr obj; + virNWFilterDefPtr def; char *ret =3D NULL; =20 virCheckFlags(0, NULL); =20 - nwfilterDriverLock(); - nwfilter =3D virNWFilterObjFindByUUID(&driver->nwfilters, obj->uuid); - nwfilterDriverUnlock(); - - if (!nwfilter) { - virReportError(VIR_ERR_NO_NWFILTER, - "%s", _("no nwfilter with matching uuid")); + if (!(obj =3D nwfilterObjFromNWFilter(nwfilter))) goto cleanup; - } =20 - if (virNWFilterGetXMLDescEnsureACL(obj->conn, nwfilter->def) < 0) + def =3D virPoolObjGetDef(obj); + if (virNWFilterGetXMLDescEnsureACL(nwfilter->conn, def) < 0) goto cleanup; =20 - ret =3D virNWFilterDefFormat(nwfilter->def); + ret =3D virNWFilterDefFormat(def); =20 cleanup: - if (nwfilter) - virNWFilterObjUnlock(nwfilter); + virPoolObjEndAPI(&obj); return ret; } =20 diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter= _gentech_driver.c index 761a01b..3c2697d 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -302,7 +302,7 @@ virNWFilterCreateVarsFrom(virNWFilterHashTablePtr vars1, typedef struct _virNWFilterInst virNWFilterInst; typedef virNWFilterInst *virNWFilterInstPtr; struct _virNWFilterInst { - virNWFilterObjPtr *filters; + virPoolObjPtr *filters; size_t nfilters; virNWFilterRuleInstPtr *rules; size_t nrules; @@ -315,7 +315,7 @@ virNWFilterInstReset(virNWFilterInstPtr inst) size_t i; =20 for (i =3D 0; i < inst->nfilters; i++) - virNWFilterObjUnlock(inst->filters[i]); + virObjectUnref(inst->filters[i]); VIR_FREE(inst->filters); inst->nfilters =3D 0; =20 @@ -368,6 +368,21 @@ virNWFilterRuleDefToRuleInst(virNWFilterDefPtr def, } =20 =20 +static virPoolObjPtr +nwfilterObjFromFiltername(virNWFilterDriverStatePtr driver, + const char *name) +{ + virPoolObjPtr obj; + + if (!(obj =3D virPoolObjTableFindByName(driver->nwfilters, name))) { + virReportError(VIR_ERR_NO_NWFILTER, + _("Could not find filter '%s'"), name); + } + + return obj; +} + + static int virNWFilterIncludeDefToRuleInst(virNWFilterDriverStatePtr driver, virNWFilterIncludeDefPtr inc, @@ -376,21 +391,20 @@ virNWFilterIncludeDefToRuleInst(virNWFilterDriverStat= ePtr driver, bool *foundNewFilter, virNWFilterInstPtr inst) { - virNWFilterObjPtr obj; + virPoolObjPtr obj; + virNWFilterDefPtr def; + virNWFilterDefPtr newdef; virNWFilterHashTablePtr tmpvars =3D NULL; virNWFilterDefPtr childdef; int ret =3D -1; =20 VIR_DEBUG("Instantiating filter %s", inc->filterref); - obj =3D virNWFilterObjFindByName(&driver->nwfilters, - inc->filterref); - if (!obj) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("referenced filter '%s' is missing"), - inc->filterref); - goto cleanup; - } - if (obj->wantRemoved) { + if (!(obj =3D nwfilterObjFromFiltername(driver, inc->filterref))) + return -1; + def =3D virPoolObjGetDef(obj); + newdef =3D virPoolObjGetNewDef(obj); + + if (virPoolObjIsBeingRemoved(obj)) { virReportError(VIR_ERR_NO_NWFILTER, _("Filter '%s' is in use."), inc->filterref); @@ -398,16 +412,15 @@ virNWFilterIncludeDefToRuleInst(virNWFilterDriverStat= ePtr driver, } =20 /* create a temporary hashmap for depth-first tree traversal */ - if (!(tmpvars =3D virNWFilterCreateVarsFrom(inc->params, - vars))) + if (!(tmpvars =3D virNWFilterCreateVarsFrom(inc->params, vars))) goto cleanup; =20 - childdef =3D obj->def; + childdef =3D def; =20 switch (useNewFilter) { case INSTANTIATE_FOLLOW_NEWFILTER: - if (obj->newDef) { - childdef =3D obj->newDef; + if (newdef) { + childdef =3D newdef; *foundNewFilter =3D true; } break; @@ -419,7 +432,7 @@ virNWFilterIncludeDefToRuleInst(virNWFilterDriverStateP= tr driver, inst->nfilters, obj) < 0) goto cleanup; - obj =3D NULL; + virObjectRef(obj); =20 if (virNWFilterDefToInst(driver, childdef, @@ -434,8 +447,7 @@ virNWFilterIncludeDefToRuleInst(virNWFilterDriverStateP= tr driver, if (ret < 0) virNWFilterInstReset(inst); virNWFilterHashTableFree(tmpvars); - if (obj) - virNWFilterObjUnlock(obj); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -501,7 +513,7 @@ virNWFilterDetermineMissingVarsRec(virNWFilterDefPtr fi= lter, int useNewFilter, virNWFilterDriverStatePtr driver) { - virNWFilterObjPtr obj; + virPoolObjPtr obj =3D NULL; int rc =3D 0; size_t i, j; virNWFilterDefPtr next_filter; @@ -542,34 +554,34 @@ virNWFilterDetermineMissingVarsRec(virNWFilterDefPtr = filter, break; } else if (inc) { VIR_DEBUG("Following filter %s", inc->filterref); - obj =3D virNWFilterObjFindByName(&driver->nwfilters, inc->filt= erref); - if (obj) { + if (!(obj =3D nwfilterObjFromFiltername(driver, inc->filterref= ))) { + rc =3D -1; + break; + } else { + virNWFilterDefPtr def =3D virPoolObjGetDef(obj); + virNWFilterDefPtr newdef =3D virPoolObjGetNewDef(obj); + virNWFilterHashTablePtr tmpvars; =20 - if (obj->wantRemoved) { + if (virPoolObjIsBeingRemoved(obj)) { virReportError(VIR_ERR_NO_NWFILTER, _("Filter '%s' is in use."), inc->filterref); rc =3D -1; - virNWFilterObjUnlock(obj); break; } =20 /* create a temporary hashmap for depth-first tree travers= al */ - virNWFilterHashTablePtr tmpvars =3D - virNWFilterCreateVarsFrom(inc->param= s, - vars); - if (!tmpvars) { + if (!(tmpvars =3D virNWFilterCreateVarsFrom(inc->params, v= ars))) { rc =3D -1; - virNWFilterObjUnlock(obj); break; } =20 - next_filter =3D obj->def; + next_filter =3D def; =20 switch (useNewFilter) { case INSTANTIATE_FOLLOW_NEWFILTER: - if (obj->newDef) - next_filter =3D obj->newDef; + if (newdef) + next_filter =3D newdef; break; case INSTANTIATE_ALWAYS: break; @@ -583,18 +595,14 @@ virNWFilterDetermineMissingVarsRec(virNWFilterDefPtr = filter, =20 virNWFilterHashTableFree(tmpvars); =20 - virNWFilterObjUnlock(obj); + virPoolObjEndAPI(&obj); if (rc < 0) break; - } else { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("referenced filter '%s' is missing"), - inc->filterref); - rc =3D -1; - break; } } } + + virPoolObjEndAPI(&obj); return rc; } =20 @@ -787,7 +795,9 @@ __virNWFilterInstantiateFilter(virNWFilterDriverStatePt= r driver, int rc; const char *drvname =3D EBIPTABLES_DRIVER_ID; virNWFilterTechDriverPtr techdriver; - virNWFilterObjPtr obj; + virPoolObjPtr obj; + virNWFilterDefPtr def; + virNWFilterDefPtr newdef; virNWFilterHashTablePtr vars, vars1; virNWFilterDefPtr filter; char vmmacaddr[VIR_MAC_STRING_BUFLEN] =3D {0}; @@ -807,15 +817,12 @@ __virNWFilterInstantiateFilter(virNWFilterDriverState= Ptr driver, =20 VIR_DEBUG("filter name: %s", filtername); =20 - obj =3D virNWFilterObjFindByName(&driver->nwfilters, filtername); - if (!obj) { - virReportError(VIR_ERR_NO_NWFILTER, - _("Could not find filter '%s'"), - filtername); + if (!(obj =3D nwfilterObjFromFiltername(driver, filtername))) return -1; - } + def =3D virPoolObjGetDef(obj); + newdef =3D virPoolObjGetNewDef(obj); =20 - if (obj->wantRemoved) { + if (virPoolObjIsBeingRemoved(obj)) { virReportError(VIR_ERR_NO_NWFILTER, _("Filter '%s' is in use."), filtername); @@ -847,12 +854,12 @@ __virNWFilterInstantiateFilter(virNWFilterDriverState= Ptr driver, goto err_exit_vars1; } =20 - filter =3D obj->def; + filter =3D def; =20 switch (useNewFilter) { case INSTANTIATE_FOLLOW_NEWFILTER: - if (obj->newDef) { - filter =3D obj->newDef; + if (newdef) { + filter =3D newdef; *foundNewFilter =3D true; } break; @@ -880,7 +887,7 @@ __virNWFilterInstantiateFilter(virNWFilterDriverStatePt= r driver, virNWFilterHashTableFree(vars1); =20 err_exit: - virNWFilterObjUnlock(obj); + virPoolObjEndAPI(&obj); =20 VIR_FREE(str_ipaddr); VIR_FREE(str_macaddr); diff --git a/src/nwfilter/nwfilter_gentech_driver.h b/src/nwfilter/nwfilter= _gentech_driver.h index 8349ab4..7192487 100644 --- a/src/nwfilter/nwfilter_gentech_driver.h +++ b/src/nwfilter/nwfilter_gentech_driver.h @@ -24,7 +24,7 @@ #ifndef __NWFILTER_GENTECH_DRIVER_H # define __NWFILTER_GENTECH_DRIVER_H =20 -# include "nwfilter_conf.h" +# include "virnwfilterobj.h" # include "nwfilter_tech_driver.h" =20 virNWFilterTechDriverPtr virNWFilterTechDriverForName(const char *name); diff --git a/src/nwfilter/nwfilter_tech_driver.h b/src/nwfilter/nwfilter_te= ch_driver.h index 7b6f56f..bc30496 100644 --- a/src/nwfilter/nwfilter_tech_driver.h +++ b/src/nwfilter/nwfilter_tech_driver.h @@ -26,7 +26,7 @@ #ifndef __NWFILTER_TECH_DRIVER_H__ # define __NWFILTER_TECH_DRIVER_H__ =20 -# include "nwfilter_conf.h" +# include "virnwfilterobj.h" =20 typedef struct _virNWFilterTechDriver virNWFilterTechDriver; typedef virNWFilterTechDriver *virNWFilterTechDriverPtr; --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 03:40:31 2024 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 1486830881046502.4764152012268; Sat, 11 Feb 2017 08:34:41 -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 v1BGUl1k023719; Sat, 11 Feb 2017 11:30:47 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGTsnn028539 for ; Sat, 11 Feb 2017 11:29:54 -0500 Received: from localhost.localdomain.com (ovpn-116-36.phx2.redhat.com [10.3.116.36]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGTmIq000660 for ; Sat, 11 Feb 2017 11:29:53 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Sat, 11 Feb 2017 11:29:42 -0500 Message-Id: <1486830585-23866-7-git-send-email-jferlan@redhat.com> In-Reply-To: <1486830585-23866-1-git-send-email-jferlan@redhat.com> References: <1486830585-23866-1-git-send-email-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH RFC 6/9] secret: Convert virSecretObj[List] to use virPoolObj[Table] 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" Use the virPoolObj[Table] object management model in order to manage the Secret objects. While making the adjustments to use the new model, there are some code formatting adjustments that were also made with the goal to follow more recent code flow and layout. Signed-off-by: John Ferlan --- src/conf/secret_conf.c | 3 +- src/conf/secret_conf.h | 2 +- src/conf/virsecretobj.c | 782 ++++++++++++++---------------------------= ---- src/conf/virsecretobj.h | 91 ++---- src/libvirt_private.syms | 15 +- src/secret/secret_driver.c | 187 ++++++----- 6 files changed, 373 insertions(+), 707 deletions(-) diff --git a/src/conf/secret_conf.c b/src/conf/secret_conf.c index 985bae4..7f04cf9 100644 --- a/src/conf/secret_conf.c +++ b/src/conf/secret_conf.c @@ -42,8 +42,9 @@ VIR_ENUM_IMPL(virSecretUsage, VIR_SECRET_USAGE_TYPE_LAST, "none", "volume", "ceph", "iscsi", "tls") =20 void -virSecretDefFree(virSecretDefPtr def) +virSecretDefFree(void *opaque) { + virSecretDefPtr def =3D opaque; if (def =3D=3D NULL) return; =20 diff --git a/src/conf/secret_conf.h b/src/conf/secret_conf.h index e0d9465..e008626 100644 --- a/src/conf/secret_conf.h +++ b/src/conf/secret_conf.h @@ -39,7 +39,7 @@ struct _virSecretDef { char *usage_id; /* May be NULL */ }; =20 -void virSecretDefFree(virSecretDefPtr def); +void virSecretDefFree(void *opaque); virSecretDefPtr virSecretDefParseString(const char *xml); virSecretDefPtr virSecretDefParseFile(const char *filename); char *virSecretDefFormat(const virSecretDef *def); diff --git a/src/conf/virsecretobj.c b/src/conf/virsecretobj.c index 049cab3..5ab2e54 100644 --- a/src/conf/virsecretobj.c +++ b/src/conf/virsecretobj.c @@ -37,280 +37,83 @@ =20 VIR_LOG_INIT("conf.virsecretobj"); =20 -struct _virSecretObj { - virObjectLockable parent; +struct _virSecretObjPrivate { char *configFile; char *base64File; - virSecretDefPtr def; unsigned char *value; /* May be NULL */ size_t value_size; }; =20 -static virClassPtr virSecretObjClass; -static virClassPtr virSecretObjListClass; -static void virSecretObjDispose(void *obj); -static void virSecretObjListDispose(void *obj); =20 -struct _virSecretObjList { - virObjectLockable parent; - - /* uuid string -> virSecretObj mapping - * for O(1), lockless lookup-by-uuid */ - virHashTable *objs; -}; - -struct virSecretSearchData { - int usageType; - const char *usageID; -}; - - -static int -virSecretObjOnceInit(void) -{ - if (!(virSecretObjClass =3D virClassNew(virClassForObjectLockable(), - "virSecretObj", - sizeof(virSecretObj), - virSecretObjDispose))) - return -1; - - if (!(virSecretObjListClass =3D virClassNew(virClassForObjectLockable(= ), - "virSecretObjList", - sizeof(virSecretObjList), - virSecretObjListDispose))) - return -1; - - return 0; -} - - -VIR_ONCE_GLOBAL_INIT(virSecretObj) - -virSecretObjPtr -virSecretObjNew(void) +static void +virSecretObjPrivateFree(void *obj) { - virSecretObjPtr secret; - - if (virSecretObjInitialize() < 0) - return NULL; - - if (!(secret =3D virObjectLockableNew(virSecretObjClass))) - return NULL; - - return secret; -} - + virSecretObjPrivatePtr objpriv =3D obj; =20 -void -virSecretObjEndAPI(virSecretObjPtr *secret) -{ - if (!*secret) + if (!objpriv) return; =20 - virObjectUnlock(*secret); - virObjectUnref(*secret); - *secret =3D NULL; + if (objpriv->value) { + /* Wipe before free to ensure we don't leave a secret on the heap = */ + memset(objpriv->value, 0, objpriv->value_size); + VIR_FREE(objpriv->value); + } + VIR_FREE(objpriv->configFile); + VIR_FREE(objpriv->base64File); + VIR_FREE(objpriv); } =20 =20 -virSecretObjListPtr -virSecretObjListNew(void) +static virSecretObjPrivatePtr +virSecretObjPrivateAlloc(const char *configDir, + const char *uuidstr) { - virSecretObjListPtr secrets; - - if (virSecretObjInitialize() < 0) - return NULL; + virSecretObjPrivatePtr objpriv =3D NULL; =20 - if (!(secrets =3D virObjectLockableNew(virSecretObjListClass))) + if (VIR_ALLOC(objpriv) < 0) return NULL; =20 - if (!(secrets->objs =3D virHashCreate(50, virObjectFreeHashData))) { - virObjectUnref(secrets); + if (!(objpriv->configFile =3D virFileBuildPath(configDir, uuidstr, ".x= ml")) || + !(objpriv->base64File =3D virFileBuildPath(configDir, uuidstr, + ".base64"))) { + virSecretObjPrivateFree(objpriv); return NULL; } =20 - return secrets; -} - - -static void -virSecretObjDispose(void *obj) -{ - virSecretObjPtr secret =3D obj; - - virSecretDefFree(secret->def); - if (secret->value) { - /* Wipe before free to ensure we don't leave a secret on the heap = */ - memset(secret->value, 0, secret->value_size); - VIR_FREE(secret->value); - } - VIR_FREE(secret->configFile); - VIR_FREE(secret->base64File); -} - - -static void -virSecretObjListDispose(void *obj) -{ - virSecretObjListPtr secrets =3D obj; - - virHashFree(secrets->objs); -} - - -/** - * virSecretObjFindByUUIDLocked: - * @secrets: list of secret objects - * @uuid: secret uuid to find - * - * This functions requires @secrets to be locked already! - * - * Returns: not locked, but ref'd secret object. - */ -virSecretObjPtr -virSecretObjListFindByUUIDLocked(virSecretObjListPtr secrets, - const unsigned char *uuid) -{ - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - virUUIDFormat(uuid, uuidstr); - - return virObjectRef(virHashLookup(secrets->objs, uuidstr)); -} - - -/** - * virSecretObjFindByUUID: - * @secrets: list of secret objects - * @uuid: secret uuid to find - * - * This function locks @secrets and finds the secret object which - * corresponds to @uuid. - * - * Returns: locked and ref'd secret object. - */ -virSecretObjPtr -virSecretObjListFindByUUID(virSecretObjListPtr secrets, - const unsigned char *uuid) -{ - virSecretObjPtr ret; - - virObjectLock(secrets); - ret =3D virSecretObjListFindByUUIDLocked(secrets, uuid); - virObjectUnlock(secrets); - if (ret) - virObjectLock(ret); - return ret; + return objpriv; } =20 =20 static int -virSecretObjSearchName(const void *payload, - const void *name ATTRIBUTE_UNUSED, - const void *opaque) -{ - virSecretObjPtr secret =3D (virSecretObjPtr) payload; - struct virSecretSearchData *data =3D (struct virSecretSearchData *) op= aque; - int found =3D 0; - - virObjectLock(secret); - - if (secret->def->usage_type !=3D data->usageType) - goto cleanup; - - if (data->usageType !=3D VIR_SECRET_USAGE_TYPE_NONE && - STREQ(secret->def->usage_id, data->usageID)) - found =3D 1; - - cleanup: - virObjectUnlock(secret); - return found; -} - - -/** - * virSecretObjFindByUsageLocked: - * @secrets: list of secret objects - * @usageType: secret usageType to find - * @usageID: secret usage string - * - * This functions requires @secrets to be locked already! - * - * Returns: not locked, but ref'd secret object. - */ -virSecretObjPtr -virSecretObjListFindByUsageLocked(virSecretObjListPtr secrets, - int usageType, - const char *usageID) -{ - virSecretObjPtr ret =3D NULL; - struct virSecretSearchData data =3D { .usageType =3D usageType, - .usageID =3D usageID }; - - ret =3D virHashSearch(secrets->objs, virSecretObjSearchName, &data); - if (ret) - virObjectRef(ret); - return ret; -} - - -/** - * virSecretObjFindByUsage: - * @secrets: list of secret objects - * @usageType: secret usageType to find - * @usageID: secret usage string - * - * This function locks @secrets and finds the secret object which - * corresponds to @usageID of @usageType. - * - * Returns: locked and ref'd secret object. - */ -virSecretObjPtr -virSecretObjListFindByUsage(virSecretObjListPtr secrets, - int usageType, - const char *usageID) -{ - virSecretObjPtr ret; - - virObjectLock(secrets); - ret =3D virSecretObjListFindByUsageLocked(secrets, usageType, usageID); - virObjectUnlock(secrets); - if (ret) - virObjectLock(ret); - return ret; -} - +secretAssignDef(virPoolObjPtr obj, + void *newDef, + void *oldDef, + unsigned int assignFlags ATTRIBUTE_UNUSED) +{ + virSecretDefPtr objdef =3D virPoolObjGetDef(obj); + virSecretDefPtr newdef =3D newDef; + virSecretDefPtr *olddef =3D oldDef; + + if (objdef->isprivate && !newdef->isprivate) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot change private flag on existing secret")); + return -1; + } =20 -/* - * virSecretObjListRemove: - * @secrets: list of secret objects - * @secret: a secret object - * - * Remove the object from the hash table. The caller must hold the lock - * on the driver owning @secrets and must have also locked @secret to - * ensure no one else is either waiting for @secret or still using it. - */ -void -virSecretObjListRemove(virSecretObjListPtr secrets, - virSecretObjPtr secret) -{ - char uuidstr[VIR_UUID_STRING_BUFLEN]; + /* Store away current objdef in olddef, clear it out since the SetDef + * will attempt to free first, and replace objdef with newdef */ + if (olddef) { + *olddef =3D objdef; + virPoolObjSetDef(obj, NULL); + } =20 - virUUIDFormat(secret->def->uuid, uuidstr); - virObjectRef(secret); - virObjectUnlock(secret); + virPoolObjSetDef(obj, newdef); =20 - virObjectLock(secrets); - virObjectLock(secret); - virHashRemoveEntry(secrets->objs, uuidstr); - virObjectUnlock(secret); - virObjectUnref(secret); - virObjectUnlock(secrets); + return 0; } =20 =20 -/* - * virSecretObjListAddLocked: +/* virSecretObjAdd: * @secrets: list of secret objects * @def: new secret definition * @configDir: directory to place secret config files @@ -318,196 +121,153 @@ virSecretObjListRemove(virSecretObjListPtr secrets, * * Add the new def to the secret obj table hash * - * This functions requires @secrets to be locked already! - * - * Returns pointer to secret or NULL if failure to add + * Returns: Either a pointer to a locked and ref'd secret obj that needs + * to use virPoolObjEndAPI when the caller is done with the object + * or NULL if failure to add. */ -virSecretObjPtr -virSecretObjListAddLocked(virSecretObjListPtr secrets, - virSecretDefPtr def, - const char *configDir, - virSecretDefPtr *oldDef) +virPoolObjPtr +virSecretObjAdd(virPoolObjTablePtr secrets, + virSecretDefPtr def, + const char *configDir, + virSecretDefPtr *oldDef) { - virSecretObjPtr secret; - virSecretObjPtr ret =3D NULL; + virPoolObjPtr obj =3D NULL; char uuidstr[VIR_UUID_STRING_BUFLEN]; - char *configFile =3D NULL, *base64File =3D NULL; - - if (oldDef) - *oldDef =3D NULL; - - /* Is there a secret already matching this UUID */ - if ((secret =3D virSecretObjListFindByUUIDLocked(secrets, def->uuid)))= { - virObjectLock(secret); + virSecretObjPrivatePtr objpriv =3D NULL; =20 - if (STRNEQ_NULLABLE(secret->def->usage_id, def->usage_id)) { - virUUIDFormat(secret->def->uuid, uuidstr); - virReportError(VIR_ERR_INTERNAL_ERROR, - _("a secret with UUID %s is already defined for= " - "use with %s"), - uuidstr, secret->def->usage_id); - goto cleanup; - } + if (!def->usage_id || !*def->usage_id) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("secret with UUID %s does not have usage defined"= ), + uuidstr); + return NULL; + } =20 - if (secret->def->isprivate && !def->isprivate) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("cannot change private flag on existing secre= t")); - goto cleanup; - } + virUUIDFormat(def->uuid, uuidstr); + if (!(obj =3D virPoolObjTableAdd(secrets, uuidstr, def->usage_id, + def, NULL, oldDef, virSecretDefFree, + secretAssignDef, 0))) + return NULL; =20 - if (oldDef) - *oldDef =3D secret->def; - else - virSecretDefFree(secret->def); - secret->def =3D def; - } else { - /* No existing secret with same UUID, - * try look for matching usage instead */ - if ((secret =3D virSecretObjListFindByUsageLocked(secrets, - def->usage_type, - def->usage_id))) { - virObjectLock(secret); - virUUIDFormat(secret->def->uuid, uuidstr); - virReportError(VIR_ERR_INTERNAL_ERROR, - _("a secret with UUID %s already defined for " - "use with %s"), - uuidstr, def->usage_id); - goto cleanup; - } + if (!(objpriv =3D virPoolObjGetPrivateData(obj))) { + if (!(objpriv =3D virSecretObjPrivateAlloc(configDir, uuidstr))) + goto error; =20 - /* Generate the possible configFile and base64File strings - * using the configDir, uuidstr, and appropriate suffix - */ - virUUIDFormat(def->uuid, uuidstr); - if (!(configFile =3D virFileBuildPath(configDir, uuidstr, ".xml"))= || - !(base64File =3D virFileBuildPath(configDir, uuidstr, ".base64= "))) - goto cleanup; + virPoolObjSetPrivateData(obj, objpriv, virSecretObjPrivateFree); + } =20 - if (!(secret =3D virSecretObjNew())) - goto cleanup; + return obj; =20 - virObjectLock(secret); + error: + virPoolObjTableRemove(secrets, &obj); + virPoolObjEndAPI(&obj); + return NULL; +} =20 - if (virHashAddEntry(secrets->objs, uuidstr, secret) < 0) - goto cleanup; =20 - secret->def =3D def; - secret->configFile =3D configFile; - secret->base64File =3D base64File; - configFile =3D NULL; - base64File =3D NULL; - virObjectRef(secret); - } +struct secretCountData { + int count; +}; =20 - ret =3D secret; - secret =3D NULL; +static int +secretCount(virPoolObjPtr obj ATTRIBUTE_UNUSED, + void *opaque) +{ + struct secretCountData *data =3D opaque; =20 - cleanup: - virSecretObjEndAPI(&secret); - VIR_FREE(configFile); - VIR_FREE(base64File); - return ret; + data->count++; + return 0; } =20 =20 -virSecretObjPtr -virSecretObjListAdd(virSecretObjListPtr secrets, - virSecretDefPtr def, - const char *configDir, - virSecretDefPtr *oldDef) +int +virSecretObjNumOfSecrets(virPoolObjTablePtr secretobjs, + virConnectPtr conn, + virPoolObjACLFilter aclfilter) { - virSecretObjPtr ret; + struct secretCountData data =3D { .count =3D 0 }; =20 - virObjectLock(secrets); - ret =3D virSecretObjListAddLocked(secrets, def, configDir, oldDef); - virObjectUnlock(secrets); - return ret; + if (virPoolObjTableList(secretobjs, conn, aclfilter, + secretCount, &data) < 0) + return 0; + + return data.count; } =20 =20 -struct virSecretObjListGetHelperData { - virConnectPtr conn; - virSecretObjListACLFilter filter; - int got; - char **uuids; +struct secretListData { int nuuids; - bool error; + char **const uuids; + int maxuuids; }; =20 =20 -static int -virSecretObjListGetHelper(void *payload, - const void *name ATTRIBUTE_UNUSED, +static int secretGetUUIDs(virPoolObjPtr obj, void *opaque) { - struct virSecretObjListGetHelperData *data =3D opaque; - virSecretObjPtr obj =3D payload; - - if (data->error) - return 0; - - if (data->nuuids >=3D 0 && data->got =3D=3D data->nuuids) - return 0; - - virObjectLock(obj); + virSecretDefPtr def =3D virPoolObjGetDef(obj); + struct secretListData *data =3D opaque; =20 - if (data->filter && !data->filter(data->conn, obj->def)) - goto cleanup; - - if (data->uuids) { + if (data->nuuids < data->maxuuids) { char *uuidstr; =20 if (VIR_ALLOC_N(uuidstr, VIR_UUID_STRING_BUFLEN) < 0) - goto cleanup; + return -1; =20 - virUUIDFormat(obj->def->uuid, uuidstr); - data->uuids[data->got] =3D uuidstr; + virUUIDFormat(def->uuid, uuidstr); + data->uuids[data->nuuids++] =3D uuidstr; } =20 - data->got++; - - cleanup: - virObjectUnlock(obj); return 0; } =20 =20 int -virSecretObjListNumOfSecrets(virSecretObjListPtr secrets, - virSecretObjListACLFilter filter, - virConnectPtr conn) +virSecretObjGetUUIDs(virPoolObjTablePtr secrets, + char **uuids, + int maxuuids, + virPoolObjACLFilter aclfilter, + virConnectPtr conn) { - struct virSecretObjListGetHelperData data =3D { - .conn =3D conn, .filter =3D filter, .got =3D 0, - .uuids =3D NULL, .nuuids =3D -1, .error =3D false }; + struct secretListData data =3D { .nuuids =3D 0, + .uuids =3D uuids, + .maxuuids =3D maxuuids }; + + if (virPoolObjTableList(secrets, conn, aclfilter, + secretGetUUIDs, &data) < 0) + goto failure; =20 - virObjectLock(secrets); - virHashForEach(secrets->objs, virSecretObjListGetHelper, &data); - virObjectUnlock(secrets); + return data.nuuids; =20 - return data.got; + failure: + + while (data.nuuids >=3D 0) + VIR_FREE(data.uuids[--data.nuuids]); + + return -1; } =20 =20 #define MATCH(FLAG) (flags & (FLAG)) static bool -virSecretObjMatchFlags(virSecretObjPtr secret, - unsigned int flags) +secretMatchFlags(virPoolObjPtr obj, + unsigned int flags) { + virSecretDefPtr def =3D virPoolObjGetDef(obj); + /* filter by whether it's ephemeral */ if (MATCH(VIR_CONNECT_LIST_SECRETS_FILTERS_EPHEMERAL) && !((MATCH(VIR_CONNECT_LIST_SECRETS_EPHEMERAL) && - secret->def->isephemeral) || + def->isephemeral) || (MATCH(VIR_CONNECT_LIST_SECRETS_NO_EPHEMERAL) && - !secret->def->isephemeral))) + !def->isephemeral))) return false; =20 /* filter by whether it's private */ if (MATCH(VIR_CONNECT_LIST_SECRETS_FILTERS_PRIVATE) && !((MATCH(VIR_CONNECT_LIST_SECRETS_PRIVATE) && - secret->def->isprivate) || + def->isprivate) || (MATCH(VIR_CONNECT_LIST_SECRETS_NO_PRIVATE) && - !secret->def->isprivate))) + !def->isprivate))) return false; =20 return true; @@ -515,135 +275,60 @@ virSecretObjMatchFlags(virSecretObjPtr secret, #undef MATCH =20 =20 -struct virSecretObjListData { - virConnectPtr conn; - virSecretPtr *secrets; - virSecretObjListACLFilter filter; - unsigned int flags; - int nsecrets; - bool error; -}; - -static int -virSecretObjListPopulate(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *opaque) -{ - struct virSecretObjListData *data =3D opaque; - virSecretObjPtr obj =3D payload; - virSecretPtr secret =3D NULL; - - if (data->error) - return 0; - - virObjectLock(obj); - - if (data->filter && !data->filter(data->conn, obj->def)) - goto cleanup; - - if (!virSecretObjMatchFlags(obj, data->flags)) - goto cleanup; - - if (!data->secrets) { - data->nsecrets++; - goto cleanup; - } - - if (!(secret =3D virGetSecret(data->conn, obj->def->uuid, - obj->def->usage_type, - obj->def->usage_id))) { - data->error =3D true; - goto cleanup; - } - - data->secrets[data->nsecrets++] =3D secret; - - cleanup: - virObjectUnlock(obj); - return 0; -} - - int -virSecretObjListExport(virConnectPtr conn, - virSecretObjListPtr secretobjs, +virSecretObjExportList(virConnectPtr conn, + virPoolObjTablePtr secretobjs, virSecretPtr **secrets, - virSecretObjListACLFilter filter, + virPoolObjACLFilter aclfilter, unsigned int flags) { - int ret =3D -1; - struct virSecretObjListData data =3D { - .conn =3D conn, .secrets =3D NULL, - .filter =3D filter, .flags =3D flags, - .nsecrets =3D 0, .error =3D false }; - - virObjectLock(secretobjs); - if (secrets && - VIR_ALLOC_N(data.secrets, virHashSize(secretobjs->objs) + 1) < 0) - goto cleanup; - - virHashForEach(secretobjs->objs, virSecretObjListPopulate, &data); - - if (data.error) - goto cleanup; - - if (data.secrets) { - /* trim the array to the final size */ - ignore_value(VIR_REALLOC_N(data.secrets, data.nsecrets + 1)); - *secrets =3D data.secrets; - data.secrets =3D NULL; - } - - ret =3D data.nsecrets; - - cleanup: - virObjectUnlock(secretobjs); - while (data.secrets && data.nsecrets) - virObjectUnref(data.secrets[--data.nsecrets]); - - VIR_FREE(data.secrets); - return ret; -} + virPoolObjPtr *objs =3D NULL; + size_t nobjs =3D 0; + virSecretPtr *secs =3D NULL; =20 + if (virPoolObjTableCollect(secretobjs, conn, &objs, &nobjs, aclfilter, + secretMatchFlags, flags) < 0) + return -1; =20 -int -virSecretObjListGetUUIDs(virSecretObjListPtr secrets, - char **uuids, - int nuuids, - virSecretObjListACLFilter filter, - virConnectPtr conn) -{ - int ret =3D -1; + if (secrets) { + size_t i; =20 - struct virSecretObjListGetHelperData data =3D { - .conn =3D conn, .filter =3D filter, .got =3D 0, - .uuids =3D uuids, .nuuids =3D nuuids, .error =3D false }; + if (VIR_ALLOC_N(secs, nobjs + 1) < 0) + goto cleanup; =20 - virObjectLock(secrets); - virHashForEach(secrets->objs, virSecretObjListGetHelper, &data); - virObjectUnlock(secrets); + for (i =3D 0; i < nobjs; i++) { + virSecretDefPtr def; =20 - if (data.error) - goto cleanup; + virObjectLock(objs[i]); + def =3D virPoolObjGetDef(objs[i]); + secs[i] =3D virGetSecret(conn, def->uuid, def->usage_type, + def->usage_id); + virObjectUnlock(objs[i]); + if (!secs[i]) + goto cleanup; + } =20 - ret =3D data.got; + VIR_STEAL_PTR(*secrets, secs); + } =20 cleanup: - if (ret < 0) { - while (data.got) - VIR_FREE(data.uuids[--data.got]); - } - return ret; + virObjectListFree(secs); + virObjectListFreeCount(objs, nobjs); + + return nobjs; } =20 =20 int -virSecretObjDeleteConfig(virSecretObjPtr secret) +virSecretObjDeleteConfig(virPoolObjPtr obj) { - if (!secret->def->isephemeral && - unlink(secret->configFile) < 0 && errno !=3D ENOENT) { + virSecretDefPtr def =3D virPoolObjGetDef(obj); + virSecretObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + if (!def->isephemeral && + unlink(objpriv->configFile) < 0 && errno !=3D ENOENT) { virReportSystemError(errno, _("cannot unlink '%s'"), - secret->configFile); + objpriv->configFile); return -1; } =20 @@ -652,11 +337,13 @@ virSecretObjDeleteConfig(virSecretObjPtr secret) =20 =20 void -virSecretObjDeleteData(virSecretObjPtr secret) +virSecretObjDeleteData(virPoolObjPtr obj) { + virSecretObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + /* The configFile will already be removed, so secret won't be * loaded again if this fails */ - (void)unlink(secret->base64File); + (void)unlink(objpriv->base64File); } =20 =20 @@ -667,15 +354,17 @@ virSecretObjDeleteData(virSecretObjPtr secret) secret is defined, it is stored as base64 (with no formatting) in "$basename.base64". "$basename" is in both cases the base64-encoded UU= ID. */ int -virSecretObjSaveConfig(virSecretObjPtr secret) +virSecretObjSaveConfig(virPoolObjPtr obj) { + virSecretDefPtr def =3D virPoolObjGetDef(obj); + virSecretObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); char *xml =3D NULL; int ret =3D -1; =20 - if (!(xml =3D virSecretDefFormat(secret->def))) + if (!(xml =3D virSecretDefFormat(def))) goto cleanup; =20 - if (virFileRewriteStr(secret->configFile, S_IRUSR | S_IWUSR, xml) < 0) + if (virFileRewriteStr(objpriv->configFile, S_IRUSR | S_IWUSR, xml) < 0) goto cleanup; =20 ret =3D 0; @@ -687,18 +376,19 @@ virSecretObjSaveConfig(virSecretObjPtr secret) =20 =20 int -virSecretObjSaveData(virSecretObjPtr secret) +virSecretObjSaveData(virPoolObjPtr obj) { + virSecretObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); char *base64 =3D NULL; int ret =3D -1; =20 - if (!secret->value) + if (!objpriv->value) return 0; =20 - if (!(base64 =3D virStringEncodeBase64(secret->value, secret->value_si= ze))) + if (!(base64 =3D virStringEncodeBase64(objpriv->value, objpriv->value_= size))) goto cleanup; =20 - if (virFileRewriteStr(secret->base64File, S_IRUSR | S_IWUSR, base64) <= 0) + if (virFileRewriteStr(objpriv->base64File, S_IRUSR | S_IWUSR, base64) = < 0) goto cleanup; =20 ret =3D 0; @@ -709,37 +399,24 @@ virSecretObjSaveData(virSecretObjPtr secret) } =20 =20 -virSecretDefPtr -virSecretObjGetDef(virSecretObjPtr secret) -{ - return secret->def; -} - - -void -virSecretObjSetDef(virSecretObjPtr secret, - virSecretDefPtr def) -{ - secret->def =3D def; -} - - unsigned char * -virSecretObjGetValue(virSecretObjPtr secret) +virSecretObjGetValue(virPoolObjPtr obj) { + virSecretDefPtr def =3D virPoolObjGetDef(obj); + virSecretObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); unsigned char *ret =3D NULL; =20 - if (!secret->value) { + if (!objpriv->value) { char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(secret->def->uuid, uuidstr); + virUUIDFormat(def->uuid, uuidstr); virReportError(VIR_ERR_NO_SECRET, _("secret '%s' does not have a value"), uuidstr); goto cleanup; } =20 - if (VIR_ALLOC_N(ret, secret->value_size) < 0) + if (VIR_ALLOC_N(ret, objpriv->value_size) < 0) goto cleanup; - memcpy(ret, secret->value, secret->value_size); + memcpy(ret, objpriv->value, objpriv->value_size); =20 cleanup: return ret; @@ -747,24 +424,26 @@ virSecretObjGetValue(virSecretObjPtr secret) =20 =20 int -virSecretObjSetValue(virSecretObjPtr secret, +virSecretObjSetValue(virPoolObjPtr obj, const unsigned char *value, size_t value_size) { + virSecretDefPtr def =3D virPoolObjGetDef(obj); + virSecretObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); unsigned char *old_value, *new_value; size_t old_value_size; =20 if (VIR_ALLOC_N(new_value, value_size) < 0) return -1; =20 - old_value =3D secret->value; - old_value_size =3D secret->value_size; + old_value =3D objpriv->value; + old_value_size =3D objpriv->value_size; =20 memcpy(new_value, value, value_size); - secret->value =3D new_value; - secret->value_size =3D value_size; + objpriv->value =3D new_value; + objpriv->value_size =3D value_size; =20 - if (!secret->def->isephemeral && virSecretObjSaveData(secret) < 0) + if (!def->isephemeral && virSecretObjSaveData(obj) < 0) goto error; =20 /* Saved successfully - drop old value */ @@ -777,8 +456,8 @@ virSecretObjSetValue(virSecretObjPtr secret, =20 error: /* Error - restore previous state and free new value */ - secret->value =3D old_value; - secret->value_size =3D old_value_size; + objpriv->value =3D old_value; + objpriv->value_size =3D old_value_size; memset(new_value, 0, value_size); VIR_FREE(new_value); return -1; @@ -786,17 +465,21 @@ virSecretObjSetValue(virSecretObjPtr secret, =20 =20 size_t -virSecretObjGetValueSize(virSecretObjPtr secret) +virSecretObjGetValueSize(virPoolObjPtr obj) { - return secret->value_size; + virSecretObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + return objpriv->value_size; } =20 =20 void -virSecretObjSetValueSize(virSecretObjPtr secret, +virSecretObjSetValueSize(virPoolObjPtr obj, size_t value_size) { - secret->value_size =3D value_size; + virSecretObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + objpriv->value_size =3D value_size; } =20 =20 @@ -820,33 +503,34 @@ virSecretLoadValidateUUID(virSecretDefPtr def, =20 =20 static int -virSecretLoadValue(virSecretObjPtr secret) +virSecretLoadValue(virPoolObjPtr obj) { int ret =3D -1, fd =3D -1; struct stat st; char *contents =3D NULL, *value =3D NULL; size_t value_size; + virSecretObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); =20 - if ((fd =3D open(secret->base64File, O_RDONLY)) =3D=3D -1) { + if ((fd =3D open(objpriv->base64File, O_RDONLY)) =3D=3D -1) { if (errno =3D=3D ENOENT) { ret =3D 0; goto cleanup; } virReportSystemError(errno, _("cannot open '%s'"), - secret->base64File); + objpriv->base64File); goto cleanup; } =20 if (fstat(fd, &st) < 0) { virReportSystemError(errno, _("cannot stat '%s'"), - secret->base64File); + objpriv->base64File); goto cleanup; } =20 if ((size_t)st.st_size !=3D st.st_size) { virReportError(VIR_ERR_INTERNAL_ERROR, _("'%s' file does not fit in memory"), - secret->base64File); + objpriv->base64File); goto cleanup; } =20 @@ -855,7 +539,7 @@ virSecretLoadValue(virSecretObjPtr secret) =20 if (saferead(fd, contents, st.st_size) !=3D st.st_size) { virReportSystemError(errno, _("cannot read '%s'"), - secret->base64File); + objpriv->base64File); goto cleanup; } =20 @@ -864,15 +548,15 @@ virSecretLoadValue(virSecretObjPtr secret) if (!base64_decode_alloc(contents, st.st_size, &value, &value_size)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("invalid base64 in '%s'"), - secret->base64File); + objpriv->base64File); goto cleanup; } if (value =3D=3D NULL) goto cleanup; =20 - secret->value =3D (unsigned char *)value; + objpriv->value =3D (unsigned char *)value; value =3D NULL; - secret->value_size =3D value_size; + objpriv->value_size =3D value_size; =20 ret =3D 0; =20 @@ -890,14 +574,14 @@ virSecretLoadValue(virSecretObjPtr secret) } =20 =20 -static virSecretObjPtr -virSecretLoad(virSecretObjListPtr secrets, +static virPoolObjPtr +virSecretLoad(virPoolObjTablePtr secrets, const char *file, const char *path, const char *configDir) { virSecretDefPtr def =3D NULL; - virSecretObjPtr secret =3D NULL, ret =3D NULL; + virPoolObjPtr obj =3D NULL, ret =3D NULL; =20 if (!(def =3D virSecretDefParseFile(path))) goto cleanup; @@ -905,26 +589,26 @@ virSecretLoad(virSecretObjListPtr secrets, if (virSecretLoadValidateUUID(def, file) < 0) goto cleanup; =20 - if (!(secret =3D virSecretObjListAdd(secrets, def, configDir, NULL))) + if (!(obj =3D virSecretObjAdd(secrets, def, configDir, NULL))) goto cleanup; def =3D NULL; =20 - if (virSecretLoadValue(secret) < 0) + if (virSecretLoadValue(obj) < 0) goto cleanup; =20 - ret =3D secret; - secret =3D NULL; + VIR_STEAL_PTR(ret, obj); =20 cleanup: - if (secret) - virSecretObjListRemove(secrets, secret); + if (obj) + virPoolObjTableRemove(secrets, &obj); virSecretDefFree(def); + virPoolObjEndAPI(&obj); return ret; } =20 =20 int -virSecretLoadAllConfigs(virSecretObjListPtr secrets, +virSecretLoadAllConfigs(virPoolObjTablePtr secrets, const char *configDir) { DIR *dir =3D NULL; @@ -938,7 +622,7 @@ virSecretLoadAllConfigs(virSecretObjListPtr secrets, * loop (if any). It's better to keep the secrets we managed to find.= */ while (virDirRead(dir, &de, NULL) > 0) { char *path; - virSecretObjPtr secret; + virPoolObjPtr obj; =20 if (!virFileHasSuffix(de->d_name, ".xml")) continue; @@ -946,7 +630,7 @@ virSecretLoadAllConfigs(virSecretObjListPtr secrets, if (!(path =3D virFileBuildPath(configDir, de->d_name, NULL))) continue; =20 - if (!(secret =3D virSecretLoad(secrets, de->d_name, path, configDi= r))) { + if (!(obj =3D virSecretLoad(secrets, de->d_name, path, configDir))= ) { VIR_ERROR(_("Error reading secret: %s"), virGetLastErrorMessage()); VIR_FREE(path); @@ -954,7 +638,7 @@ virSecretLoadAllConfigs(virSecretObjListPtr secrets, } =20 VIR_FREE(path); - virSecretObjEndAPI(&secret); + virPoolObjEndAPI(&obj); } =20 VIR_DIR_CLOSE(dir); diff --git a/src/conf/virsecretobj.h b/src/conf/virsecretobj.h index 673a4c8..407cd4f 100644 --- a/src/conf/virsecretobj.h +++ b/src/conf/virsecretobj.h @@ -25,85 +25,56 @@ =20 # include "secret_conf.h" # include "virobject.h" +# include "virpoolobj.h" =20 -typedef struct _virSecretObj virSecretObj; -typedef virSecretObj *virSecretObjPtr; +typedef struct _virSecretObjTablePrivate virSecretObjTablePrivate; +typedef virSecretObjTablePrivate *virSecretObjTablePrivatePtr; =20 -virSecretObjPtr virSecretObjNew(void); +typedef struct _virSecretObjPrivate virSecretObjPrivate; +typedef virSecretObjPrivate *virSecretObjPrivatePtr; =20 -void virSecretObjEndAPI(virSecretObjPtr *secret); +virPoolObjPtr virSecretObjAdd(virPoolObjTablePtr secrets, + virSecretDefPtr def, + const char *configDir, + virSecretDefPtr *oldDef); =20 -typedef struct _virSecretObjList virSecretObjList; -typedef virSecretObjList *virSecretObjListPtr; +int virSecretObjNumOfSecrets(virPoolObjTablePtr secretobjs, + virConnectPtr conn, + virPoolObjACLFilter aclfilter); =20 -virSecretObjListPtr virSecretObjListNew(void); +int virSecretObjGetUUIDs(virPoolObjTablePtr secrets, + char **uuids, + int nuuids, + virPoolObjACLFilter aclfilter, + virConnectPtr conn); =20 -virSecretObjPtr virSecretObjListFindByUUIDLocked(virSecretObjListPtr secre= ts, - const unsigned char *uuid= ); - -virSecretObjPtr virSecretObjListFindByUUID(virSecretObjListPtr secrets, - const unsigned char *uuid); - -virSecretObjPtr virSecretObjListFindByUsageLocked(virSecretObjListPtr secr= ets, - int usageType, - const char *usageID); - -virSecretObjPtr virSecretObjListFindByUsage(virSecretObjListPtr secrets, - int usageType, - const char *usageID); - -void virSecretObjListRemove(virSecretObjListPtr secrets, - virSecretObjPtr secret); - -virSecretObjPtr virSecretObjListAddLocked(virSecretObjListPtr secrets, - virSecretDefPtr def, - const char *configDir, - virSecretDefPtr *oldDef); - -virSecretObjPtr virSecretObjListAdd(virSecretObjListPtr secrets, - virSecretDefPtr def, - const char *configDir, - virSecretDefPtr *oldDef); - -typedef bool (*virSecretObjListACLFilter)(virConnectPtr conn, void *opaque= ); - -int virSecretObjListNumOfSecrets(virSecretObjListPtr secrets, - virSecretObjListACLFilter filter, - virConnectPtr conn); - -int virSecretObjListExport(virConnectPtr conn, - virSecretObjListPtr secretobjs, +int virSecretObjExportList(virConnectPtr conn, + virPoolObjTablePtr secretobjs, virSecretPtr **secrets, - virSecretObjListACLFilter filter, + virPoolObjACLFilter aclfilter, unsigned int flags); =20 -int virSecretObjListGetUUIDs(virSecretObjListPtr secrets, - char **uuids, - int nuuids, - virSecretObjListACLFilter filter, - virConnectPtr conn); - -int virSecretObjDeleteConfig(virSecretObjPtr secret); +int virSecretObjDeleteConfig(virPoolObjPtr obj); =20 -void virSecretObjDeleteData(virSecretObjPtr secret); +void virSecretObjDeleteData(virPoolObjPtr obj); =20 -int virSecretObjSaveConfig(virSecretObjPtr secret); +int virSecretObjSaveConfig(virPoolObjPtr obj); =20 -int virSecretObjSaveData(virSecretObjPtr secret); +int virSecretObjSaveData(virPoolObjPtr obj); =20 -virSecretDefPtr virSecretObjGetDef(virSecretObjPtr secret); +virSecretDefPtr virSecretObjGetDef(virPoolObjPtr obj); =20 -void virSecretObjSetDef(virSecretObjPtr secret, virSecretDefPtr def); +void virSecretObjSetDef(virPoolObjPtr obj, virSecretDefPtr def); =20 -unsigned char *virSecretObjGetValue(virSecretObjPtr secret); +unsigned char *virSecretObjGetValue(virPoolObjPtr obj); =20 -int virSecretObjSetValue(virSecretObjPtr secret, +int virSecretObjSetValue(virPoolObjPtr obj, const unsigned char *value, size_t value_size); =20 -size_t virSecretObjGetValueSize(virSecretObjPtr secret); +size_t virSecretObjGetValueSize(virPoolObjPtr obj); =20 -void virSecretObjSetValueSize(virSecretObjPtr secret, size_t value_size); +void virSecretObjSetValueSize(virPoolObjPtr obj, size_t value_size); =20 -int virSecretLoadAllConfigs(virSecretObjListPtr secrets, +int virSecretLoadAllConfigs(virPoolObjTablePtr secrets, const char *configDir); #endif /* __VIRSECRETOBJ_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2e9f0c2..17de708 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -995,23 +995,16 @@ virPoolObjTableSearchRef; =20 # conf/virsecretobj.h virSecretLoadAllConfigs; +virSecretObjAdd; virSecretObjDeleteConfig; virSecretObjDeleteData; -virSecretObjEndAPI; -virSecretObjGetDef; +virSecretObjExportList; +virSecretObjGetUUIDs; virSecretObjGetValue; virSecretObjGetValueSize; -virSecretObjListAdd; -virSecretObjListExport; -virSecretObjListFindByUsage; -virSecretObjListFindByUUID; -virSecretObjListGetUUIDs; -virSecretObjListNew; -virSecretObjListNumOfSecrets; -virSecretObjListRemove; +virSecretObjNumOfSecrets; virSecretObjSaveConfig; virSecretObjSaveData; -virSecretObjSetDef; virSecretObjSetValue; virSecretObjSetValueSize; =20 diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c index 2a371b6..bdb6dfd 100644 --- a/src/secret/secret_driver.c +++ b/src/secret/secret_driver.c @@ -57,7 +57,7 @@ typedef struct _virSecretDriverState virSecretDriverState; typedef virSecretDriverState *virSecretDriverStatePtr; struct _virSecretDriverState { virMutex lock; - virSecretObjListPtr secrets; + virPoolObjTablePtr secrets; char *configDir; =20 /* Immutable pointer, self-locking APIs */ @@ -80,13 +80,13 @@ secretDriverUnlock(void) =20 =20 =20 -static virSecretObjPtr +static virPoolObjPtr secretObjFromSecret(virSecretPtr secret) { - virSecretObjPtr obj; + virPoolObjPtr obj; char uuidstr[VIR_UUID_STRING_BUFLEN]; =20 - if (!(obj =3D virSecretObjListFindByUUID(driver->secrets, secret->uuid= ))) { + if (!(obj =3D virPoolObjTableFindByUUIDRef(driver->secrets, secret->uu= id))) { virUUIDFormat(secret->uuid, uuidstr); virReportError(VIR_ERR_NO_SECRET, _("no secret with matching uuid '%s'"), uuidstr); @@ -115,11 +115,11 @@ secretConnectNumOfSecrets(virConnectPtr conn) if (virConnectNumOfSecretsEnsureACL(conn) < 0) return -1; =20 - return virSecretObjListNumOfSecrets(driver->secrets, - virConnectNumOfSecretsCheckACL, - conn); + return virSecretObjNumOfSecrets(driver->secrets, conn, + virConnectNumOfSecretsCheckACL); } =20 + static int secretConnectListSecrets(virConnectPtr conn, char **uuids, @@ -130,8 +130,8 @@ secretConnectListSecrets(virConnectPtr conn, if (virConnectListSecretsEnsureACL(conn) < 0) return -1; =20 - return virSecretObjListGetUUIDs(driver->secrets, uuids, maxuuids, - virConnectListSecretsCheckACL, conn); + return virSecretObjGetUUIDs(driver->secrets, uuids, maxuuids, + virConnectListSecretsCheckACL, conn); } =20 =20 @@ -145,7 +145,7 @@ secretConnectListAllSecrets(virConnectPtr conn, if (virConnectListAllSecretsEnsureACL(conn) < 0) return -1; =20 - return virSecretObjListExport(conn, driver->secrets, secrets, + return virSecretObjExportList(conn, driver->secrets, secrets, virConnectListAllSecretsCheckACL, flags); } @@ -156,10 +156,10 @@ secretLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { virSecretPtr ret =3D NULL; - virSecretObjPtr secret; + virPoolObjPtr obj; virSecretDefPtr def; =20 - if (!(secret =3D virSecretObjListFindByUUID(driver->secrets, uuid))) { + if (!(obj =3D virPoolObjTableFindByUUIDRef(driver->secrets, uuid))) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virUUIDFormat(uuid, uuidstr); virReportError(VIR_ERR_NO_SECRET, @@ -167,7 +167,7 @@ secretLookupByUUID(virConnectPtr conn, goto cleanup; } =20 - def =3D virSecretObjGetDef(secret); + def =3D virPoolObjGetDef(obj); if (virSecretLookupByUUIDEnsureACL(conn, def) < 0) goto cleanup; =20 @@ -177,7 +177,7 @@ secretLookupByUUID(virConnectPtr conn, def->usage_id); =20 cleanup: - virSecretObjEndAPI(&secret); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -188,27 +188,33 @@ secretLookupByUsage(virConnectPtr conn, const char *usageID) { virSecretPtr ret =3D NULL; - virSecretObjPtr secret; + virPoolObjPtr obj; virSecretDefPtr def; =20 - if (!(secret =3D virSecretObjListFindByUsage(driver->secrets, - usageType, usageID))) { + if (!(obj =3D virPoolObjTableFindByName(driver->secrets, usageID))) { virReportError(VIR_ERR_NO_SECRET, _("no secret with matching usage '%s'"), usageID); - goto cleanup; + return NULL; } =20 - def =3D virSecretObjGetDef(secret); + def =3D virPoolObjGetDef(obj); if (virSecretLookupByUsageEnsureACL(conn, def) < 0) goto cleanup; =20 + if (usageType !=3D def->usage_type) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("expected usage type=3D%d does not match secret= =3D%d"), + usageType, def->usage_type); + goto cleanup; + } + ret =3D virGetSecret(conn, def->uuid, def->usage_type, def->usage_id); =20 cleanup: - virSecretObjEndAPI(&secret); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -219,129 +225,130 @@ secretDefineXML(virConnectPtr conn, unsigned int flags) { virSecretPtr ret =3D NULL; - virSecretObjPtr secret =3D NULL; + virPoolObjPtr obj =3D NULL; + virSecretDefPtr def; + virSecretDefPtr objdef; virSecretDefPtr backup =3D NULL; - virSecretDefPtr new_attrs; virObjectEventPtr event =3D NULL; =20 virCheckFlags(0, NULL); =20 - if (!(new_attrs =3D virSecretDefParseString(xml))) + if (!(def =3D virSecretDefParseString(xml))) return NULL; =20 - if (virSecretDefineXMLEnsureACL(conn, new_attrs) < 0) + if (virSecretDefineXMLEnsureACL(conn, def) < 0) goto cleanup; =20 - if (!(secret =3D virSecretObjListAdd(driver->secrets, new_attrs, - driver->configDir, &backup))) + if (!(obj =3D virSecretObjAdd(driver->secrets, def, + driver->configDir, &backup))) goto cleanup; + VIR_STEAL_PTR(objdef, def); =20 - if (!new_attrs->isephemeral) { + if (!objdef->isephemeral) { if (secretEnsureDirectory() < 0) goto cleanup; =20 if (backup && backup->isephemeral) { - if (virSecretObjSaveData(secret) < 0) + if (virSecretObjSaveData(obj) < 0) goto restore_backup; } =20 - if (virSecretObjSaveConfig(secret) < 0) { + if (virSecretObjSaveConfig(obj) < 0) { if (backup && backup->isephemeral) { /* Undo the virSecretObjSaveData() above; ignore errors */ - virSecretObjDeleteData(secret); + virSecretObjDeleteData(obj); } goto restore_backup; } } else if (backup && !backup->isephemeral) { - if (virSecretObjDeleteConfig(secret) < 0) + if (virSecretObjDeleteConfig(obj) < 0) goto restore_backup; =20 - virSecretObjDeleteData(secret); + virSecretObjDeleteData(obj); } - /* Saved successfully - drop old values */ - virSecretDefFree(backup); =20 - event =3D virSecretEventLifecycleNew(new_attrs->uuid, - new_attrs->usage_type, - new_attrs->usage_id, + event =3D virSecretEventLifecycleNew(objdef->uuid, + objdef->usage_type, + objdef->usage_id, VIR_SECRET_EVENT_DEFINED, 0); =20 ret =3D virGetSecret(conn, - new_attrs->uuid, - new_attrs->usage_type, - new_attrs->usage_id); - new_attrs =3D NULL; - goto cleanup; - - restore_backup: - /* If we have a backup, then secret was defined before, so just restore - * the backup. The current (new_attrs) will be handled below. - * Otherwise, this is a new secret, thus remove it. - */ - if (backup) - virSecretObjSetDef(secret, backup); - else - virSecretObjListRemove(driver->secrets, secret); + objdef->uuid, + objdef->usage_type, + objdef->usage_id); =20 cleanup: - virSecretDefFree(new_attrs); - virSecretObjEndAPI(&secret); + virSecretDefFree(def); + virSecretDefFree(backup); + virPoolObjEndAPI(&obj); if (event) virObjectEventStateQueue(driver->secretEventState, event); =20 return ret; + + restore_backup: + /* If we have a backup, then secret was defined before, so just restore + * the backup. Otherwise, this is a new secret, thus remove it. */ + if (backup) + virPoolObjSetDef(obj, backup); + else + virPoolObjTableRemove(driver->secrets, &obj); + backup =3D NULL; + goto cleanup; } =20 + static char * -secretGetXMLDesc(virSecretPtr obj, +secretGetXMLDesc(virSecretPtr secret, unsigned int flags) { char *ret =3D NULL; - virSecretObjPtr secret; + virPoolObjPtr obj; virSecretDefPtr def; =20 virCheckFlags(0, NULL); =20 - if (!(secret =3D secretObjFromSecret(obj))) + if (!(obj =3D secretObjFromSecret(secret))) goto cleanup; =20 - def =3D virSecretObjGetDef(secret); - if (virSecretGetXMLDescEnsureACL(obj->conn, def) < 0) + def =3D virPoolObjGetDef(obj); + if (virSecretGetXMLDescEnsureACL(secret->conn, def) < 0) goto cleanup; =20 ret =3D virSecretDefFormat(def); =20 cleanup: - virSecretObjEndAPI(&secret); + virPoolObjEndAPI(&obj); =20 return ret; } =20 + static int -secretSetValue(virSecretPtr obj, +secretSetValue(virSecretPtr secret, const unsigned char *value, size_t value_size, unsigned int flags) { int ret =3D -1; - virSecretObjPtr secret; + virPoolObjPtr obj; virSecretDefPtr def; virObjectEventPtr event =3D NULL; =20 virCheckFlags(0, -1); =20 - if (!(secret =3D secretObjFromSecret(obj))) + if (!(obj =3D secretObjFromSecret(secret))) goto cleanup; =20 - def =3D virSecretObjGetDef(secret); - if (virSecretSetValueEnsureACL(obj->conn, def) < 0) + def =3D virPoolObjGetDef(obj); + if (virSecretSetValueEnsureACL(secret->conn, def) < 0) goto cleanup; =20 if (secretEnsureDirectory() < 0) goto cleanup; =20 - if (virSecretObjSetValue(secret, value, value_size) < 0) + if (virSecretObjSetValue(obj, value, value_size) < 0) goto cleanup; =20 event =3D virSecretEventValueChangedNew(def->uuid, @@ -350,30 +357,31 @@ secretSetValue(virSecretPtr obj, ret =3D 0; =20 cleanup: - virSecretObjEndAPI(&secret); + virPoolObjEndAPI(&obj); if (event) virObjectEventStateQueue(driver->secretEventState, event); =20 return ret; } =20 + static unsigned char * -secretGetValue(virSecretPtr obj, +secretGetValue(virSecretPtr secret, size_t *value_size, unsigned int flags, unsigned int internalFlags) { unsigned char *ret =3D NULL; - virSecretObjPtr secret; + virPoolObjPtr obj; virSecretDefPtr def; =20 virCheckFlags(0, NULL); =20 - if (!(secret =3D secretObjFromSecret(obj))) + if (!(obj =3D secretObjFromSecret(secret))) goto cleanup; =20 - def =3D virSecretObjGetDef(secret); - if (virSecretGetValueEnsureACL(obj->conn, def) < 0) + def =3D virPoolObjGetDef(obj); + if (virSecretGetValueEnsureACL(secret->conn, def) < 0) goto cleanup; =20 if ((internalFlags & VIR_SECRET_GET_VALUE_INTERNAL_CALL) =3D=3D 0 && @@ -383,33 +391,34 @@ secretGetValue(virSecretPtr obj, goto cleanup; } =20 - if (!(ret =3D virSecretObjGetValue(secret))) + if (!(ret =3D virSecretObjGetValue(obj))) goto cleanup; =20 - *value_size =3D virSecretObjGetValueSize(secret); + *value_size =3D virSecretObjGetValueSize(obj); =20 cleanup: - virSecretObjEndAPI(&secret); + virPoolObjEndAPI(&obj); =20 return ret; } =20 + static int -secretUndefine(virSecretPtr obj) +secretUndefine(virSecretPtr secret) { int ret =3D -1; - virSecretObjPtr secret; + virPoolObjPtr obj; virSecretDefPtr def; virObjectEventPtr event =3D NULL; =20 - if (!(secret =3D secretObjFromSecret(obj))) + if (!(obj =3D secretObjFromSecret(secret))) goto cleanup; =20 - def =3D virSecretObjGetDef(secret); - if (virSecretUndefineEnsureACL(obj->conn, def) < 0) + def =3D virPoolObjGetDef(obj); + if (virSecretUndefineEnsureACL(secret->conn, def) < 0) goto cleanup; =20 - if (virSecretObjDeleteConfig(secret) < 0) + if (virSecretObjDeleteConfig(obj) < 0) goto cleanup; =20 event =3D virSecretEventLifecycleNew(def->uuid, @@ -418,20 +427,21 @@ secretUndefine(virSecretPtr obj) VIR_SECRET_EVENT_UNDEFINED, 0); =20 - virSecretObjDeleteData(secret); + virSecretObjDeleteData(obj); =20 - virSecretObjListRemove(driver->secrets, secret); + virPoolObjTableRemove(driver->secrets, &obj); =20 ret =3D 0; =20 cleanup: - virSecretObjEndAPI(&secret); + virPoolObjEndAPI(&obj); if (event) virObjectEventStateQueue(driver->secretEventState, event); =20 return ret; } =20 + static int secretStateCleanup(void) { @@ -452,6 +462,7 @@ secretStateCleanup(void) return 0; } =20 + static int secretStateInitialize(bool privileged, virStateInhibitCallback callback ATTRIBUTE_UNUSED, @@ -481,7 +492,9 @@ secretStateInitialize(bool privileged, goto error; VIR_FREE(base); =20 - if (!(driver->secrets =3D virSecretObjListNew())) + if (!(driver->secrets =3D + virPoolObjTableNew(VIR_POOLOBJTABLE_SECRET, + VIR_POOLOBJTABLE_SECRET_HASHSTART, false))) goto error; =20 if (virSecretLoadAllConfigs(driver->secrets, driver->configDir) < 0) @@ -497,6 +510,7 @@ secretStateInitialize(bool privileged, return -1; } =20 + static int secretStateReload(void) { @@ -511,6 +525,7 @@ secretStateReload(void) return 0; } =20 + static int secretConnectSecretEventRegisterAny(virConnectPtr conn, virSecretPtr secret, @@ -532,6 +547,7 @@ secretConnectSecretEventRegisterAny(virConnectPtr conn, return callbackID; } =20 + static int secretConnectSecretEventDeregisterAny(virConnectPtr conn, int callbackID) @@ -576,6 +592,7 @@ static virStateDriver stateDriver =3D { .stateReload =3D secretStateReload, }; =20 + int secretRegister(void) { --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 03:40:31 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) client-ip=209.132.183.37; envelope-from=libvir-list-bounces@redhat.com; helo=mx5-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx5-phx2.redhat.com (mx5-phx2.redhat.com [209.132.183.37]) by mx.zohomail.com with SMTPS id 1486830908813602.7558744795172; Sat, 11 Feb 2017 08:35:08 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx5-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGUmYX010235; Sat, 11 Feb 2017 11:30:48 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGTt4P028554 for ; Sat, 11 Feb 2017 11:29:55 -0500 Received: from localhost.localdomain.com (ovpn-116-36.phx2.redhat.com [10.3.116.36]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGTmIr000660 for ; Sat, 11 Feb 2017 11:29:54 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Sat, 11 Feb 2017 11:29:43 -0500 Message-Id: <1486830585-23866-8-git-send-email-jferlan@redhat.com> In-Reply-To: <1486830585-23866-1-git-send-email-jferlan@redhat.com> References: <1486830585-23866-1-git-send-email-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH RFC 7/9] volume: Convert virStorageVolObj[List] to use virPoolObj[Table] 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" Use the virPoolObj[Table] object management model in order to manage the storage volume objects. While making the adjustments to use the new model, there are some code formatting adjustments that were also made with the goal to follow more recent code flow and layout. Signed-off-by: John Ferlan --- src/conf/storage_conf.c | 205 +++++++++++-- src/conf/storage_conf.h | 45 ++- src/libvirt_private.syms | 10 +- src/storage/storage_backend_disk.c | 143 ++++++--- src/storage/storage_backend_gluster.c | 17 +- src/storage/storage_backend_logical.c | 58 ++-- src/storage/storage_backend_mpath.c | 10 +- src/storage/storage_backend_rbd.c | 10 +- src/storage/storage_backend_sheepdog.c | 7 +- src/storage/storage_backend_zfs.c | 51 ++-- src/storage/storage_driver.c | 539 ++++++++++++++++++-----------= ---- src/storage/storage_util.c | 10 +- src/test/test_driver.c | 371 ++++++++++++----------- 13 files changed, 875 insertions(+), 601 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index c9b93aa..8012b6f 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -321,8 +321,9 @@ virStorageVolOptionsForPoolType(int type) =20 =20 void -virStorageVolDefFree(virStorageVolDefPtr def) +virStorageVolDefFree(void *opaque) { + virStorageVolDefPtr def =3D opaque; size_t i; =20 if (!def) @@ -415,7 +416,7 @@ virStoragePoolObjFree(virStoragePoolObjPtr obj) if (!obj) return; =20 - virStoragePoolObjClearVols(obj); + virObjectUnref(obj->volumes); =20 virStoragePoolDefFree(obj->def); virStoragePoolDefFree(obj->newDef); @@ -1776,56 +1777,74 @@ virStoragePoolSourceFindDuplicateDevices(virStorage= PoolObjPtr pool, return NULL; } =20 + void virStoragePoolObjClearVols(virStoragePoolObjPtr pool) { - size_t i; - for (i =3D 0; i < pool->volumes.count; i++) - virStorageVolDefFree(pool->volumes.objs[i]); + virPoolObjTableClearAll(pool->volumes); +} + + +struct volSearchData { + const char *compare; +}; =20 - VIR_FREE(pool->volumes.objs); - pool->volumes.count =3D 0; +static bool +volFindByKey(virPoolObjPtr obj, + void *opaque) +{ + virStorageVolDefPtr def =3D virPoolObjGetDef(obj); + struct volSearchData *data =3D opaque; + + if (STREQ(def->key, data->compare)) + return true; + + return false; } =20 -virStorageVolDefPtr -virStorageVolDefFindByKey(virStoragePoolObjPtr pool, + +virPoolObjPtr +virStorageVolObjFindByKey(virStoragePoolObjPtr pool, const char *key) { - size_t i; + struct volSearchData data =3D { .compare =3D key }; =20 - for (i =3D 0; i < pool->volumes.count; i++) - if (STREQ(pool->volumes.objs[i]->key, key)) - return pool->volumes.objs[i]; - - return NULL; + return virPoolObjTableSearchRef(pool->volumes, volFindByKey, &data); } =20 -virStorageVolDefPtr -virStorageVolDefFindByPath(virStoragePoolObjPtr pool, - const char *path) + +static bool +volFindByPath(virPoolObjPtr obj, + void *opaque) { - size_t i; + virStorageVolDefPtr def =3D virPoolObjGetDef(obj); + struct volSearchData *data =3D opaque; =20 - for (i =3D 0; i < pool->volumes.count; i++) - if (STREQ(pool->volumes.objs[i]->target.path, path)) - return pool->volumes.objs[i]; + if (STREQ(def->target.path, data->compare)) + return true; =20 - return NULL; + return false; } =20 -virStorageVolDefPtr -virStorageVolDefFindByName(virStoragePoolObjPtr pool, - const char *name) + +virPoolObjPtr +virStorageVolObjFindByPath(virStoragePoolObjPtr pool, + const char *path) { - size_t i; + struct volSearchData data =3D { .compare =3D path }; =20 - for (i =3D 0; i < pool->volumes.count; i++) - if (STREQ(pool->volumes.objs[i]->name, name)) - return pool->volumes.objs[i]; + return virPoolObjTableSearchRef(pool->volumes, volFindByPath, &data); +} =20 - return NULL; + +virPoolObjPtr +virStorageVolObjFindByName(virStoragePoolObjPtr pool, + const char *name) +{ + return virPoolObjTableFindByName(pool->volumes, name); } =20 + virStoragePoolObjPtr virStoragePoolObjAssignDef(virStoragePoolObjListPtr pools, virStoragePoolDefPtr def) @@ -1855,6 +1874,14 @@ virStoragePoolObjAssignDef(virStoragePoolObjListPtr = pools, virStoragePoolObjLock(pool); pool->active =3D 0; =20 + if (!(pool->volumes =3D + virPoolObjTableNew(VIR_POOLOBJTABLE_VOLUME, + VIR_POOLOBJTABLE_VOLUME_HASHSTART, true))) { + virStoragePoolObjUnlock(pool); + virStoragePoolObjFree(pool); + return NULL; + } + if (VIR_APPEND_ELEMENT_COPY(pools->objs, pools->count, pool) < 0) { virStoragePoolObjUnlock(pool); virStoragePoolObjFree(pool); @@ -1865,6 +1892,122 @@ virStoragePoolObjAssignDef(virStoragePoolObjListPtr= pools, return pool; } =20 + +virPoolObjPtr +virStoragePoolObjAddVolume(virStoragePoolObjPtr pool, + virStorageVolDefPtr voldef) +{ + return virPoolObjTableAdd(pool->volumes, NULL, voldef->name, voldef, + NULL, NULL, virStorageVolDefFree, NULL, 0); +} + + +void +virStoragePoolObjRemoveVolume(virStoragePoolObjPtr pool, + virPoolObjPtr *volobj) +{ + virPoolObjTableRemove(pool->volumes, volobj); +} + + +struct volCountData { + virConnectPtr conn; + virStoragePoolDefPtr pooldef; + virStoragePoolVolumeACLFilter aclfilter; + int count; +}; + +static int +volCount(virPoolObjPtr obj, + void *opaque) +{ + struct volCountData *data =3D opaque; + + /* Similar to virPoolObjTableListIterator */ + if (data->aclfilter && !data->aclfilter(data->conn, data->pooldef, obj= )) + return 0; + + data->count++; + return 0; +} + + +int +virStoragePoolObjNumOfVolumes(virPoolObjTablePtr volumes, + virConnectPtr conn, + virStoragePoolDefPtr pooldef, + virStoragePoolVolumeACLFilter aclfilter) +{ + struct volCountData data =3D { .conn =3D conn, + .count =3D 0, + .pooldef =3D pooldef, + .aclfilter =3D aclfilter }; + + if (virPoolObjTableList(volumes, conn, NULL, volCount, &data) < 0) + return 0; + + return data.count; +} + + +struct volListData { + virConnectPtr conn; + virStoragePoolDefPtr pooldef; + virStoragePoolVolumeACLFilter aclfilter; + int nnames; + char **const names; + int maxnames; +}; + +static int +volListVolumes(virPoolObjPtr obj, + void *opaque) +{ + virStorageVolDefPtr def =3D virPoolObjGetDef(obj); + struct volListData *data =3D opaque; + + /* Similar to virPoolObjTableListIterator */ + if (data->aclfilter && !data->aclfilter(data->conn, data->pooldef, obj= )) + return 0; + + if (data->nnames < data->maxnames) { + if (VIR_STRDUP(data->names[data->nnames++], def->name) < 0) + return -1; + } + + return 0; +} + + +int +virStoragePoolObjListVolumes(virPoolObjTablePtr volumes, + virConnectPtr conn, + virStoragePoolDefPtr pooldef, + virStoragePoolVolumeACLFilter aclfilter, + char **const names, + int maxnames) +{ + struct volListData data =3D { .conn =3D conn, + .nnames =3D 0, + .pooldef =3D pooldef, + .aclfilter =3D aclfilter, + .names =3D names, + .maxnames =3D maxnames }; + + memset(names, 0, maxnames * sizeof(*names)); + + if (virPoolObjTableList(volumes, conn, NULL, volListVolumes, &data) < = 0) + goto error; + + return data.nnames; + + error: + while (--data.nnames >=3D 0) + VIR_FREE(names[data.nnames]); + return -1; +} + + static virStoragePoolObjPtr virStoragePoolObjLoad(virStoragePoolObjListPtr pools, const char *file, diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 5eda544..cfc8281 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -28,6 +28,7 @@ # include "virstorageencryption.h" # include "virstoragefile.h" # include "virbitmap.h" +# include "virpoolobj.h" # include "virthread.h" # include "device_conf.h" # include "node_device_conf.h" @@ -73,13 +74,6 @@ struct _virStorageVolDef { virStorageSource target; }; =20 -typedef struct _virStorageVolDefList virStorageVolDefList; -typedef virStorageVolDefList *virStorageVolDefListPtr; -struct _virStorageVolDefList { - size_t count; - virStorageVolDefPtr *objs; -}; - VIR_ENUM_DECL(virStorageVol) =20 typedef enum { @@ -279,7 +273,7 @@ struct _virStoragePoolObj { virStoragePoolDefPtr def; virStoragePoolDefPtr newDef; =20 - virStorageVolDefList volumes; + virPoolObjTablePtr volumes; }; =20 typedef struct _virStoragePoolObjList virStoragePoolObjList; @@ -343,14 +337,14 @@ virStoragePoolObjPtr virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool, virStoragePoolDefPtr def); =20 -virStorageVolDefPtr -virStorageVolDefFindByKey(virStoragePoolObjPtr pool, +virPoolObjPtr +virStorageVolObjFindByKey(virStoragePoolObjPtr pool, const char *key); -virStorageVolDefPtr -virStorageVolDefFindByPath(virStoragePoolObjPtr pool, +virPoolObjPtr +virStorageVolObjFindByPath(virStoragePoolObjPtr pool, const char *path); -virStorageVolDefPtr -virStorageVolDefFindByName(virStoragePoolObjPtr pool, +virPoolObjPtr +virStorageVolObjFindByName(virStoragePoolObjPtr pool, const char *name); =20 void virStoragePoolObjClearVols(virStoragePoolObjPtr pool); @@ -387,6 +381,27 @@ virStoragePoolObjPtr virStoragePoolObjAssignDef(virStoragePoolObjListPtr pools, virStoragePoolDefPtr def); =20 +virPoolObjPtr virStoragePoolObjAddVolume(virStoragePoolObjPtr pool, + virStorageVolDefPtr voldef); + +void virStoragePoolObjRemoveVolume(virStoragePoolObjPtr pool, + virPoolObjPtr *volobj); + +typedef bool (*virStoragePoolVolumeACLFilter) + (virConnectPtr conn, virStoragePoolDefPtr pool, void *objdef); + +int virStoragePoolObjNumOfVolumes(virPoolObjTablePtr volumes, + virConnectPtr conn, + virStoragePoolDefPtr pooldef, + virStoragePoolVolumeACLFilter aclfilter); + +int virStoragePoolObjListVolumes(virPoolObjTablePtr volumes, + virConnectPtr conn, + virStoragePoolDefPtr pooldef, + virStoragePoolVolumeACLFilter aclfilter, + char **const names, + int maxnames); + int virStoragePoolSaveState(const char *stateFile, virStoragePoolDefPtr def); int virStoragePoolSaveConfig(const char *configFile, @@ -396,7 +411,7 @@ int virStoragePoolObjSaveDef(virStorageDriverStatePtr d= river, virStoragePoolDefPtr def); int virStoragePoolObjDeleteDef(virStoragePoolObjPtr pool); =20 -void virStorageVolDefFree(virStorageVolDefPtr def); +void virStorageVolDefFree(void *opaque); void virStoragePoolSourceClear(virStoragePoolSourcePtr source); void virStoragePoolSourceDeviceClear(virStoragePoolSourceDevicePtr dev); void virStoragePoolSourceFree(virStoragePoolSourcePtr source); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 17de708..14c3682 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -862,6 +862,7 @@ virStoragePoolFormatLogicalTypeToString; virStoragePoolGetVhbaSCSIHostParent; virStoragePoolLoadAllConfigs; virStoragePoolLoadAllState; +virStoragePoolObjAddVolume; virStoragePoolObjAssignDef; virStoragePoolObjClearVols; virStoragePoolObjDeleteDef; @@ -870,8 +871,11 @@ virStoragePoolObjFindByUUID; virStoragePoolObjIsDuplicate; virStoragePoolObjListExport; virStoragePoolObjListFree; +virStoragePoolObjListVolumes; virStoragePoolObjLock; +virStoragePoolObjNumOfVolumes; virStoragePoolObjRemove; +virStoragePoolObjRemoveVolume; virStoragePoolObjSaveDef; virStoragePoolObjUnlock; virStoragePoolSaveConfig; @@ -887,14 +891,14 @@ virStoragePoolSourceListFormat; virStoragePoolSourceListNewSource; virStoragePoolTypeFromString; virStoragePoolTypeToString; -virStorageVolDefFindByKey; -virStorageVolDefFindByName; -virStorageVolDefFindByPath; virStorageVolDefFormat; virStorageVolDefFree; virStorageVolDefParseFile; virStorageVolDefParseNode; virStorageVolDefParseString; +virStorageVolObjFindByKey; +virStorageVolObjFindByName; +virStorageVolObjFindByPath; virStorageVolTypeFromString; virStorageVolTypeToString; =20 diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backe= nd_disk.c index 819f1e5..dcf4e3e 100644 --- a/src/storage/storage_backend_disk.c +++ b/src/storage/storage_backend_disk.c @@ -43,6 +43,20 @@ VIR_LOG_INIT("storage.storage_backend_disk"); =20 #define SECTOR_SIZE 512 =20 + +static bool +volPartFindExtended(virPoolObjPtr volobj, + void *opaque ATTRIBUTE_UNUSED) +{ + virStorageVolDefPtr def =3D virPoolObjGetDef(volobj); + + if (def->source.partType =3D=3D VIR_STORAGE_VOL_DISK_TYPE_EXTENDED) + return true; + + return false; +} + + static int virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr pool, char **const groups, @@ -59,17 +73,21 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr p= ool, partname =3D groups[0]; =20 if (vol =3D=3D NULL) { + virPoolObjPtr volobj; /* This is typically a reload/restart/refresh path where * we're discovering the existing partitions for the pool */ - if (VIR_ALLOC(vol) < 0) + if (VIR_ALLOC(vol) < 0 || + VIR_STRDUP(vol->name, partname) < 0) { + VIR_FREE(vol); return -1; - if (VIR_STRDUP(vol->name, partname) < 0 || - VIR_APPEND_ELEMENT_COPY(pool->volumes.objs, - pool->volumes.count, vol) < 0) { + } + + if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) { virStorageVolDefFree(vol); return -1; } + virPoolObjEndAPI(&volobj); } =20 if (vol->target.path =3D=3D NULL) { @@ -192,15 +210,13 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr= pool, =20 /* Find the extended partition and increase the allocation value */ if (vol->source.partType =3D=3D VIR_STORAGE_VOL_DISK_TYPE_LOGICAL) { - size_t i; + virPoolObjPtr volobj; =20 - for (i =3D 0; i < pool->volumes.count; i++) { - if (pool->volumes.objs[i]->source.partType =3D=3D - VIR_STORAGE_VOL_DISK_TYPE_EXTENDED) { - pool->volumes.objs[i]->target.allocation +=3D - vol->target.allocation; - break; - } + if ((volobj =3D virPoolObjTableSearch(pool->volumes, volPartFindEx= tended, + NULL))) { + virStorageVolDefPtr voldef =3D virPoolObjGetDef(volobj); + voldef->target.allocation +=3D vol->target.allocation; + virPoolObjEndAPI(&volobj); } } =20 @@ -285,21 +301,26 @@ virStorageBackendDiskMakeVol(size_t ntok ATTRIBUTE_UN= USED, /* Remaining data / metadata parts get turn into volumes... */ if (STREQ(groups[2], "metadata") || STREQ(groups[2], "data")) { - virStorageVolDefPtr vol =3D data->vol; + virStorageVolDefPtr voldef =3D data->vol; =20 - if (vol) { + if (voldef) { /* We're searching for a specific vol only */ - if (vol->key) { - if (STRNEQ(vol->key, groups[0])) + if (voldef->key) { + if (STRNEQ(voldef->key, groups[0])) + return 0; + } else { + virPoolObjPtr volobj; + + if ((volobj =3D virStorageVolObjFindByKey(pool, groups[0])= )) { + /* If no key, the volume must be newly created. If gro= ups[0] + * isn't already a volume, assume it's the path we wan= t */ + virPoolObjEndAPI(&volobj); return 0; - } else if (virStorageVolDefFindByKey(pool, groups[0]) !=3D NUL= L) { - /* If no key, the volume must be newly created. If groups[= 0] - * isn't already a volume, assume it's the path we want */ - return 0; + } } } =20 - return virStorageBackendDiskMakeDataVol(pool, groups, vol); + return virStorageBackendDiskMakeDataVol(pool, groups, voldef); } else if (STREQ(groups[2], "free")) { /* ....or free space extents */ return virStorageBackendDiskMakeFreeExtent(pool, groups); @@ -518,6 +539,28 @@ virStorageBackendDiskBuildPool(virConnectPtr conn ATTR= IBUTE_UNUSED, return ret; } =20 + +struct volPartListData { + int count; +}; + + +static int +volNumOfPartTypes(virPoolObjPtr volobj, + void *opaque) +{ + virStorageVolDefPtr def =3D virPoolObjGetDef(volobj); + struct volPartListData *data =3D opaque; + int partType =3D def->source.partType; + + if (partType =3D=3D VIR_STORAGE_VOL_DISK_TYPE_PRIMARY || + partType =3D=3D VIR_STORAGE_VOL_DISK_TYPE_EXTENDED) + data->count++; + + return 0; +} + + /** * Decides what kind of partition type that should be created. * Important when the partition table is of msdos type @@ -525,19 +568,17 @@ virStorageBackendDiskBuildPool(virConnectPtr conn ATT= RIBUTE_UNUSED, static int virStorageBackendDiskPartTypeToCreate(virStoragePoolObjPtr pool) { + struct volPartListData data =3D { .count =3D 0 }; + if (pool->def->source.format =3D=3D VIR_STORAGE_POOL_DISK_DOS) { + /* count primary and extended partitions, - can't be more than 3 to create a new primary partition */ - size_t i; - int count =3D 0; - for (i =3D 0; i < pool->volumes.count; i++) { - int partType =3D pool->volumes.objs[i]->source.partType; - if (partType =3D=3D VIR_STORAGE_VOL_DISK_TYPE_PRIMARY || - partType =3D=3D VIR_STORAGE_VOL_DISK_TYPE_EXTENDED) - count++; + * can't be more than 3 to create a new primary partition */ + if (virPoolObjTableList(pool->volumes, NULL, NULL, + volNumOfPartTypes, &data) =3D=3D 0) { + if (data.count >=3D 4) + return VIR_STORAGE_VOL_DISK_TYPE_LOGICAL; } - if (count >=3D 4) - return VIR_STORAGE_VOL_DISK_TYPE_LOGICAL; } =20 /* for all other cases, all partitions are primary */ @@ -549,7 +590,8 @@ virStorageBackendDiskPartFormat(virStoragePoolObjPtr po= ol, virStorageVolDefPtr vol, char** partFormat) { - size_t i; + virPoolObjPtr volobj; + if (pool->def->source.format =3D=3D VIR_STORAGE_POOL_DISK_DOS) { const char *partedFormat; partedFormat =3D virStoragePartedFsTypeToString(vol->target.format= ); @@ -560,14 +602,14 @@ virStorageBackendDiskPartFormat(virStoragePoolObjPtr = pool, } if (vol->target.format =3D=3D VIR_STORAGE_VOL_DISK_EXTENDED) { /* make sure we don't have an extended partition already */ - for (i =3D 0; i < pool->volumes.count; i++) { - if (pool->volumes.objs[i]->source.partType =3D=3D - VIR_STORAGE_VOL_DISK_TYPE_EXTENDED) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("extended partition already exists")); - return -1; - } + if ((volobj =3D=3D virPoolObjTableSearch(pool->volumes, + volPartFindExtended, NULL= ))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("extended partition already exists")); + virPoolObjEndAPI(&volobj); + return -1; } + if (VIR_STRDUP(*partFormat, partedFormat) < 0) return -1; } else { @@ -582,18 +624,19 @@ virStorageBackendDiskPartFormat(virStoragePoolObjPtr = pool, break; case VIR_STORAGE_VOL_DISK_TYPE_LOGICAL: /* make sure we have an extended partition */ - for (i =3D 0; i < pool->volumes.count; i++) { - if (pool->volumes.objs[i]->source.partType =3D=3D - VIR_STORAGE_VOL_DISK_TYPE_EXTENDED) { - if (virAsprintf(partFormat, "logical %s", - partedFormat) < 0) - return -1; - break; + if ((volobj =3D=3D virPoolObjTableSearch(pool->volumes, + volPartFindExtended, + NULL))) { + if (virAsprintf(partFormat, "logical %s", + partedFormat) < 0) { + virPoolObjEndAPI(&volobj); + return -1; } - } - if (i =3D=3D pool->volumes.count) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("no extended partition found an= d no primary partition available")); + virPoolObjEndAPI(&volobj); + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("no extended partition found and no " + "primary partition available")); return -1; } break; diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_ba= ckend_gluster.c index 7be2d9e..aa9d7be 100644 --- a/src/storage/storage_backend_gluster.c +++ b/src/storage/storage_backend_gluster.c @@ -379,15 +379,20 @@ virStorageBackendGlusterRefreshPool(virConnectPtr con= n ATTRIBUTE_UNUSED, } while (!(errno =3D glfs_readdirplus_r(dir, &st, &de.ent, &ent)) && ent= ) { virStorageVolDefPtr vol; - int okay =3D virStorageBackendGlusterRefreshVol(state, - ent->d_name, &st, - &vol); + virPoolObjPtr volobj; =20 - if (okay < 0) + if (virStorageBackendGlusterRefreshVol(state, ent->d_name, + &st, &vol) < 0) goto cleanup; - if (vol && VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.co= unt, - vol) < 0) + + if (!vol) + continue; + + if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) { + virStorageVolDefFree(vol); goto cleanup; + } + virPoolObjEndAPI(&volobj); } if (errno) { virReportSystemError(errno, _("failed to read directory '%s' in '%= s'"), diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_ba= ckend_logical.c index b0191aa..ad66656 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -288,7 +288,8 @@ virStorageBackendLogicalMakeVol(char **const groups, { struct virStorageBackendLogicalPoolVolData *data =3D opaque; virStoragePoolObjPtr pool =3D data->pool; - virStorageVolDefPtr vol =3D NULL; + virPoolObjPtr volobj =3D NULL; + virStorageVolDefPtr voldef =3D data->vol; bool is_new_vol =3D false; int ret =3D -1; const char *attrs =3D groups[9]; @@ -306,32 +307,30 @@ virStorageBackendLogicalMakeVol(char **const groups, return 0; =20 /* See if we're only looking for a specific volume */ - if (data->vol !=3D NULL) { - vol =3D data->vol; - if (STRNEQ(vol->name, groups[0])) - return 0; - } + if (voldef && STRNEQ(voldef->name, groups[0])) + return 0; =20 /* Or filling in more data on an existing volume */ - if (vol =3D=3D NULL) - vol =3D virStorageVolDefFindByName(pool, groups[0]); + if (!voldef) { + if ((volobj =3D virStorageVolObjFindByName(pool, groups[0]))) + voldef =3D virPoolObjGetDef(volobj); + } =20 /* Or a completely new volume */ - if (vol =3D=3D NULL) { - if (VIR_ALLOC(vol) < 0) + if (!voldef) { + if (VIR_ALLOC(voldef) < 0) return -1; =20 is_new_vol =3D true; - vol->type =3D VIR_STORAGE_VOL_BLOCK; + voldef->type =3D VIR_STORAGE_VOL_BLOCK; =20 - if (VIR_STRDUP(vol->name, groups[0]) < 0) + if (VIR_STRDUP(voldef->name, groups[0]) < 0) goto cleanup; - } =20 - if (vol->target.path =3D=3D NULL) { - if (virAsprintf(&vol->target.path, "%s/%s", - pool->def->target.path, vol->name) < 0) + if (!voldef->target.path) { + if (virAsprintf(&voldef->target.path, "%s/%s", + pool->def->target.path, voldef->name) < 0) goto cleanup; } =20 @@ -342,7 +341,7 @@ virStorageBackendLogicalMakeVol(char **const groups, * in brackets [] described for the groups[1] (backingStore). */ if (attrs[0] =3D=3D 's') - vol->target.sparse =3D true; + voldef->target.sparse =3D true; =20 /* Skips the backingStore of lv created with "--virtualsize", * its original device "/dev/$vgname/$lvname_vorigin" is @@ -352,41 +351,44 @@ virStorageBackendLogicalMakeVol(char **const groups, * lv is created with "--virtualsize"). */ if (groups[1] && STRNEQ(groups[1], "") && (groups[1][0] !=3D '[')) { - if (VIR_ALLOC(vol->target.backingStore) < 0) + if (VIR_ALLOC(voldef->target.backingStore) < 0) goto cleanup; =20 - if (virAsprintf(&vol->target.backingStore->path, "%s/%s", + if (virAsprintf(&voldef->target.backingStore->path, "%s/%s", pool->def->target.path, groups[1]) < 0) goto cleanup; =20 - vol->target.backingStore->format =3D VIR_STORAGE_POOL_LOGICAL_LVM2; + voldef->target.backingStore->format =3D VIR_STORAGE_POOL_LOGICAL_L= VM2; } =20 - if (!vol->key && VIR_STRDUP(vol->key, groups[2]) < 0) + if (!voldef->key && VIR_STRDUP(voldef->key, groups[2]) < 0) goto cleanup; =20 - if (virStorageBackendUpdateVolInfo(vol, false, + if (virStorageBackendUpdateVolInfo(voldef, false, VIR_STORAGE_VOL_OPEN_DEFAULT, 0) < = 0) goto cleanup; =20 - if (virStrToLong_ull(groups[8], NULL, 10, &vol->target.allocation) < 0= ) { + if (virStrToLong_ull(groups[8], NULL, 10, &voldef->target.allocation) = < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed volume allocation value")); goto cleanup; } =20 - if (virStorageBackendLogicalParseVolExtents(vol, groups) < 0) + if (virStorageBackendLogicalParseVolExtents(voldef, groups) < 0) goto cleanup; =20 - if (is_new_vol && - VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vol) <= 0) - goto cleanup; + if (is_new_vol) { + if (!(volobj =3D virStoragePoolObjAddVolume(pool, voldef))) + goto cleanup; + voldef =3D NULL; + virPoolObjEndAPI(&volobj); + } =20 ret =3D 0; =20 cleanup: if (is_new_vol) - virStorageVolDefFree(vol); + virStorageVolDefFree(voldef); return ret; } =20 diff --git a/src/storage/storage_backend_mpath.c b/src/storage/storage_back= end_mpath.c index a5d692a..514b59b 100644 --- a/src/storage/storage_backend_mpath.c +++ b/src/storage/storage_backend_mpath.c @@ -48,6 +48,7 @@ virStorageBackendMpathNewVol(virStoragePoolObjPtr pool, const char *dev) { virStorageVolDefPtr vol; + virPoolObjPtr volobj; int ret =3D -1; =20 if (VIR_ALLOC(vol) < 0) @@ -70,16 +71,19 @@ virStorageBackendMpathNewVol(virStoragePoolObjPtr pool, if (VIR_STRDUP(vol->key, vol->target.path) < 0) goto cleanup; =20 - if (VIR_APPEND_ELEMENT_COPY(pool->volumes.objs, pool->volumes.count, v= ol) < 0) + if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) goto cleanup; + + vol =3D NULL; + virPoolObjEndAPI(&volobj); + pool->def->capacity +=3D vol->target.capacity; pool->def->allocation +=3D vol->target.allocation; ret =3D 0; =20 cleanup: =20 - if (ret !=3D 0) - virStorageVolDefFree(vol); + virStorageVolDefFree(vol); =20 return ret; } diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backen= d_rbd.c index 45beb10..5a46664 100644 --- a/src/storage/storage_backend_rbd.c +++ b/src/storage/storage_backend_rbd.c @@ -429,6 +429,7 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn, int ret =3D -1; int len =3D -1; int r =3D 0; + int count =3D 0; char *name, *names =3D NULL; virStorageBackendRBDStatePtr ptr =3D NULL; struct rados_cluster_stat_t clusterstat; @@ -473,6 +474,7 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn, =20 for (name =3D names; name < names + max_size;) { virStorageVolDefPtr vol; + virPoolObjPtr volobj; =20 if (STREQ(name, "")) break; @@ -506,15 +508,17 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn, goto cleanup; } =20 - if (VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vo= l) < 0) { + if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) { virStorageVolDefFree(vol); virStoragePoolObjClearVols(pool); goto cleanup; } + count++; + virPoolObjEndAPI(&volobj); } =20 - VIR_DEBUG("Found %zu images in RBD pool %s", - pool->volumes.count, pool->def->source.name); + VIR_DEBUG("Found %d images in RBD pool %s", + count, pool->def->source.name); =20 ret =3D 0; =20 diff --git a/src/storage/storage_backend_sheepdog.c b/src/storage/storage_b= ackend_sheepdog.c index 36458a5..04734c8 100644 --- a/src/storage/storage_backend_sheepdog.c +++ b/src/storage/storage_backend_sheepdog.c @@ -115,6 +115,7 @@ virStorageBackendSheepdogAddVolume(virConnectPtr conn A= TTRIBUTE_UNUSED, virStoragePoolObjPtr pool, const char *d= iskInfo) { virStorageVolDefPtr vol =3D NULL; + virPoolObjPtr obj; =20 if (diskInfo =3D=3D NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -130,11 +131,11 @@ virStorageBackendSheepdogAddVolume(virConnectPtr conn= ATTRIBUTE_UNUSED, if (virStorageBackendSheepdogRefreshVol(conn, pool, vol) < 0) goto error; =20 - if (VIR_EXPAND_N(pool->volumes.objs, pool->volumes.count, 1) < 0) + if (!(obj =3D virStoragePoolObjAddVolume(pool, vol))) goto error; + vol =3D NULL; =20 - pool->volumes.objs[pool->volumes.count - 1] =3D vol; - + virPoolObjEndAPI(&obj); return 0; =20 error: diff --git a/src/storage/storage_backend_zfs.c b/src/storage/storage_backen= d_zfs.c index 70c533a..fab29fb 100644 --- a/src/storage/storage_backend_zfs.c +++ b/src/storage/storage_backend_zfs.c @@ -99,16 +99,17 @@ virStorageBackendZFSCheckPool(virStoragePoolObjPtr pool= ATTRIBUTE_UNUSED, =20 static int virStorageBackendZFSParseVol(virStoragePoolObjPtr pool, - virStorageVolDefPtr vol, + virStorageVolDefPtr volume, const char *volume_string) { + virPoolObjPtr volobj =3D NULL; + virStorageVolDefPtr voldef =3D volume; int ret =3D -1; char **tokens; size_t count; char **name_tokens =3D NULL; char *vol_name; bool is_new_vol =3D false; - virStorageVolDefPtr volume =3D NULL; =20 if (!(tokens =3D virStringSplitCount(volume_string, "\t", 0, &count))) return -1; @@ -121,58 +122,60 @@ virStorageBackendZFSParseVol(virStoragePoolObjPtr poo= l, =20 vol_name =3D name_tokens[1]; =20 - if (vol =3D=3D NULL) - volume =3D virStorageVolDefFindByName(pool, vol_name); - else - volume =3D vol; + if (!voldef) { + if ((volobj =3D virStorageVolObjFindByName(pool, vol_name))) + voldef =3D virPoolObjGetDef(volobj); + } =20 - if (volume =3D=3D NULL) { - if (VIR_ALLOC(volume) < 0) + if (!voldef) { + if (VIR_ALLOC(voldef) < 0) goto cleanup; =20 is_new_vol =3D true; - volume->type =3D VIR_STORAGE_VOL_BLOCK; + voldef->type =3D VIR_STORAGE_VOL_BLOCK; =20 - if (VIR_STRDUP(volume->name, vol_name) < 0) + if (VIR_STRDUP(voldef->name, vol_name) < 0) goto cleanup; } =20 - if (!volume->key && VIR_STRDUP(volume->key, tokens[0]) < 0) + if (!voldef->key && VIR_STRDUP(voldef->key, tokens[0]) < 0) goto cleanup; =20 - if (volume->target.path =3D=3D NULL) { - if (virAsprintf(&volume->target.path, "%s/%s", - pool->def->target.path, volume->name) < 0) + if (voldef->target.path =3D=3D NULL) { + if (virAsprintf(&voldef->target.path, "%s/%s", + pool->def->target.path, voldef->name) < 0) goto cleanup; } =20 - if (virStrToLong_ull(tokens[1], NULL, 10, &volume->target.capacity) < = 0) { + if (virStrToLong_ull(tokens[1], NULL, 10, &voldef->target.capacity) < = 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed volsize reported")); goto cleanup; } =20 - if (virStrToLong_ull(tokens[2], NULL, 10, &volume->target.allocation) = < 0) { + if (virStrToLong_ull(tokens[2], NULL, 10, &voldef->target.allocation) = < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed refreservation reported")); goto cleanup; } =20 - if (volume->target.allocation < volume->target.capacity) - volume->target.sparse =3D true; + if (voldef->target.allocation < voldef->target.capacity) + voldef->target.sparse =3D true; =20 - if (is_new_vol && - VIR_APPEND_ELEMENT(pool->volumes.objs, - pool->volumes.count, - volume) < 0) - goto cleanup; + if (is_new_vol) { + if (!(volobj =3D virStoragePoolObjAddVolume(pool, voldef))) + goto cleanup; + + voldef =3D NULL; + } =20 ret =3D 0; cleanup: virStringListFree(tokens); virStringListFree(name_tokens); + virPoolObjEndAPI(&volobj); if (is_new_vol) - virStorageVolDefFree(volume); + virStorageVolDefFree(voldef); return ret; } =20 diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index ed4772a..19f7a88 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -1370,13 +1370,11 @@ storagePoolSetAutostart(virStoragePoolPtr obj, return ret; } =20 - static int storagePoolNumOfVolumes(virStoragePoolPtr obj) { virStoragePoolObjPtr pool; int ret =3D -1; - size_t i; =20 if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) return -1; @@ -1389,26 +1387,27 @@ storagePoolNumOfVolumes(virStoragePoolPtr obj) _("storage pool '%s' is not active"), pool->def->na= me); goto cleanup; } - ret =3D 0; - for (i =3D 0; i < pool->volumes.count; i++) { - if (virStoragePoolNumOfVolumesCheckACL(obj->conn, pool->def, - pool->volumes.objs[i])) - ret++; - } + + /* NB: Cannot call filter in List function since the volume ACL filter + * function requires 3 instead of 2 params for virPoolObjACLFilter. + * Setting up this way fulfills check-aclrules.pl's check that the + * driver function calls the CheckACL API */ + ret =3D virStoragePoolObjNumOfVolumes(pool->volumes, obj->conn, pool->= def, + virStoragePoolNumOfVolumesCheckACL= ); =20 cleanup: virStoragePoolObjUnlock(pool); return ret; } =20 + static int storagePoolListVolumes(virStoragePoolPtr obj, char **const names, int maxnames) { + int ret =3D -1; virStoragePoolObjPtr pool; - size_t i; - int n =3D 0; =20 memset(names, 0, maxnames * sizeof(*names)); =20 @@ -1424,35 +1423,30 @@ storagePoolListVolumes(virStoragePoolPtr obj, goto cleanup; } =20 - for (i =3D 0; i < pool->volumes.count && n < maxnames; i++) { - if (!virStoragePoolListVolumesCheckACL(obj->conn, pool->def, - pool->volumes.objs[i])) - continue; - if (VIR_STRDUP(names[n++], pool->volumes.objs[i]->name) < 0) - goto cleanup; - } - - virStoragePoolObjUnlock(pool); - return n; + /* NB: Cannot call filter in List function since the volume ACL filter + * function requires 3 instead of 2 params for virPoolObjACLFilter. + * Setting up this way fulfills check-aclrules.pl's check that the + * driver function calls the CheckACL API */ + ret =3D virStoragePoolObjListVolumes(pool->volumes, obj->conn, pool->d= ef, + virStoragePoolListVolumesCheckACL, + names, maxnames); =20 cleanup: virStoragePoolObjUnlock(pool); - for (n =3D 0; n < maxnames; n++) - VIR_FREE(names[n]); - - memset(names, 0, maxnames * sizeof(*names)); - return -1; + return ret; } =20 + static int storagePoolListAllVolumes(virStoragePoolPtr pool, - virStorageVolPtr **vols, + virStorageVolPtr **volumes, unsigned int flags) { virStoragePoolObjPtr obj; + virPoolObjPtr *volobjs =3D NULL; + size_t nvolobjs =3D 0; size_t i; - virStorageVolPtr *tmp_vols =3D NULL; - virStorageVolPtr vol =3D NULL; + virStorageVolPtr *vols =3D NULL; int nvols =3D 0; int ret =3D -1; =20 @@ -1470,40 +1464,45 @@ storagePoolListAllVolumes(virStoragePoolPtr pool, goto cleanup; } =20 - /* Just returns the volumes count */ - if (!vols) { - ret =3D obj->volumes.count; + if (virPoolObjTableCollect(obj->volumes, pool->conn, &volobjs, &nvolob= js, + NULL, NULL, flags) < 0) goto cleanup; - } =20 - if (VIR_ALLOC_N(tmp_vols, obj->volumes.count + 1) < 0) - goto cleanup; - - for (i =3D 0; i < obj->volumes.count; i++) { - if (!virStoragePoolListAllVolumesCheckACL(pool->conn, obj->def, - obj->volumes.objs[i])) - continue; - if (!(vol =3D virGetStorageVol(pool->conn, obj->def->name, - obj->volumes.objs[i]->name, - obj->volumes.objs[i]->key, - NULL, NULL))) + if (volumes) { + if (VIR_ALLOC_N(vols, nvolobjs + 1) < 0) goto cleanup; - tmp_vols[nvols++] =3D vol; - } =20 - *vols =3D tmp_vols; - tmp_vols =3D NULL; - ret =3D nvols; + for (i =3D 0; i < nvolobjs; i++) { + bool passacl =3D false; + virPoolObjPtr volobj =3D volobjs[i]; + virStorageVolDefPtr def; + + virObjectLock(volobj); + def =3D virPoolObjGetDef(volobj); + /* NB: Cannot call ACL filter in Collect function since it + * takes 3 params and the volume ACL filter requires 3 */ + if (virStoragePoolListAllVolumesCheckACL(pool->conn, obj->def, + obj)) { + vols[nvols++] =3D virGetStorageVol(pool->conn, obj->def->n= ame, + def->name, def->key, + NULL, NULL); + passacl =3D true; + } + virObjectUnlock(volobj); =20 - cleanup: - if (tmp_vols) { - for (i =3D 0; i < nvols; i++) - virObjectUnref(tmp_vols[i]); - VIR_FREE(tmp_vols); + if (passacl && !vols[i]) + goto cleanup; + } + + *volumes =3D vols; + vols =3D NULL; } =20 - virStoragePoolObjUnlock(obj); + ret =3D nvols; =20 + cleanup: + virObjectListFree(vols); + virObjectListFreeCount(volobjs, nvolobjs); return ret; } =20 @@ -1512,7 +1511,8 @@ storageVolLookupByName(virStoragePoolPtr obj, const char *name) { virStoragePoolObjPtr pool; - virStorageVolDefPtr vol; + virPoolObjPtr volobj =3D NULL; + virStorageVolDefPtr voldef; virStorageVolPtr ret =3D NULL; =20 if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) @@ -1524,22 +1524,22 @@ storageVolLookupByName(virStoragePoolPtr obj, goto cleanup; } =20 - vol =3D virStorageVolDefFindByName(pool, name); - - if (!vol) { + if (!(volobj =3D virStorageVolObjFindByName(pool, name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), name); goto cleanup; } + voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolLookupByNameEnsureACL(obj->conn, pool->def, vol) < 0) + if (virStorageVolLookupByNameEnsureACL(obj->conn, pool->def, voldef) <= 0) goto cleanup; =20 - ret =3D virGetStorageVol(obj->conn, pool->def->name, vol->name, vol->k= ey, - NULL, NULL); + ret =3D virGetStorageVol(obj->conn, pool->def->name, voldef->name, + voldef->key, NULL, NULL); =20 cleanup: + virPoolObjEndAPI(&volobj); virStoragePoolObjUnlock(pool); return ret; } @@ -1556,21 +1556,25 @@ storageVolLookupByKey(virConnectPtr conn, for (i =3D 0; i < driver->pools.count && !ret; i++) { virStoragePoolObjLock(driver->pools.objs[i]); if (virStoragePoolObjIsActive(driver->pools.objs[i])) { - virStorageVolDefPtr vol =3D - virStorageVolDefFindByKey(driver->pools.objs[i], key); + virPoolObjPtr volobj; =20 - if (vol) { + if ((volobj =3D virStorageVolObjFindByKey(driver->pools.objs[i= ], + key))) { virStoragePoolDefPtr def =3D driver->pools.objs[i]->def; - if (virStorageVolLookupByKeyEnsureACL(conn, def, vol) < 0)= { + virStorageVolDefPtr voldef =3D virPoolObjGetDef(volobj); + + if (virStorageVolLookupByKeyEnsureACL(conn, def, voldef) <= 0) { + virPoolObjEndAPI(&volobj); virStoragePoolObjUnlock(driver->pools.objs[i]); goto cleanup; } =20 ret =3D virGetStorageVol(conn, def->name, - vol->name, - vol->key, + voldef->name, + voldef->key, NULL, NULL); + virPoolObjEndAPI(&volobj); } } virStoragePoolObjUnlock(driver->pools.objs[i]); @@ -1600,7 +1604,7 @@ storageVolLookupByPath(virConnectPtr conn, storageDriverLock(); for (i =3D 0; i < driver->pools.count && !ret; i++) { virStoragePoolObjPtr pool =3D driver->pools.objs[i]; - virStorageVolDefPtr vol; + virPoolObjPtr volobj =3D NULL; char *stable_path =3D NULL; =20 virStoragePoolObjLock(pool); @@ -1646,18 +1650,22 @@ storageVolLookupByPath(virConnectPtr conn, break; } =20 - vol =3D virStorageVolDefFindByPath(pool, stable_path); + volobj =3D virStorageVolObjFindByPath(pool, stable_path); VIR_FREE(stable_path); =20 - if (vol) { - if (virStorageVolLookupByPathEnsureACL(conn, pool->def, vol) <= 0) { + if (volobj) { + virStorageVolDefPtr voldef =3D virPoolObjGetDef(volobj); + if (virStorageVolLookupByPathEnsureACL(conn, pool->def, + voldef) < 0) { + virPoolObjEndAPI(&volobj); virStoragePoolObjUnlock(pool); goto cleanup; } =20 ret =3D virGetStorageVol(conn, pool->def->name, - vol->name, vol->key, + voldef->name, voldef->key, NULL, NULL); + virPoolObjEndAPI(&volobj); } =20 virStoragePoolObjUnlock(pool); @@ -1727,18 +1735,21 @@ static void storageVolRemoveFromPool(virStoragePoolObjPtr pool, virStorageVolDefPtr vol) { - size_t i; + virPoolObjPtr obj; =20 - for (i =3D 0; i < pool->volumes.count; i++) { - if (pool->volumes.objs[i] =3D=3D vol) { - VIR_INFO("Deleting volume '%s' from storage pool '%s'", - vol->name, pool->def->name); - virStorageVolDefFree(vol); - - VIR_DELETE_ELEMENT(pool->volumes.objs, i, pool->volumes.count); - break; - } + if (!(obj =3D virPoolObjTableFindByName(pool->volumes, vol->name))) { + virReportError(VIR_ERR_NO_STORAGE_VOL, + _("no storage vol with matching name '%s'"), + vol->name); + return; } + + VIR_INFO("Deleting volume '%s' from storage pool '%s'", + vol->name, pool->def->name); + + virStoragePoolObjRemoveVolume(pool, &obj); + + virPoolObjEndAPI(&obj); } =20 =20 @@ -1781,23 +1792,23 @@ storageVolDeleteInternal(virStorageVolPtr obj, } =20 =20 -static virStorageVolDefPtr -virStorageVolDefFromVol(virStorageVolPtr obj, +static virPoolObjPtr +virStorageVolObjFromVol(virStorageVolPtr volume, virStoragePoolObjPtr *pool, virStorageBackendPtr *backend) { - virStorageVolDefPtr vol =3D NULL; + virPoolObjPtr volobj =3D NULL; =20 *pool =3D NULL; =20 storageDriverLock(); - *pool =3D virStoragePoolObjFindByName(&driver->pools, obj->pool); + *pool =3D virStoragePoolObjFindByName(&driver->pools, volume->pool); storageDriverUnlock(); =20 if (!*pool) { virReportError(VIR_ERR_NO_STORAGE_POOL, _("no storage pool with matching name '%s'"), - obj->pool); + volume->pool); return NULL; } =20 @@ -1808,10 +1819,10 @@ virStorageVolDefFromVol(virStorageVolPtr obj, goto error; } =20 - if (!(vol =3D virStorageVolDefFindByName(*pool, obj->name))) { + if (!(volobj =3D virStorageVolObjFindByName(*pool, volume->name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), - obj->name); + volume->name); goto error; } =20 @@ -1820,7 +1831,7 @@ virStorageVolDefFromVol(virStorageVolPtr obj, goto error; } =20 - return vol; + return volobj; =20 error: virStoragePoolObjUnlock(*pool); @@ -1831,40 +1842,44 @@ virStorageVolDefFromVol(virStorageVolPtr obj, =20 =20 static int -storageVolDelete(virStorageVolPtr obj, +storageVolDelete(virStorageVolPtr volume, unsigned int flags) { virStoragePoolObjPtr pool; + virPoolObjPtr volobj; + virStorageVolDefPtr voldef; virStorageBackendPtr backend; - virStorageVolDefPtr vol =3D NULL; int ret =3D -1; =20 - if (!(vol =3D virStorageVolDefFromVol(obj, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) return -1; + voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolDeleteEnsureACL(obj->conn, pool->def, vol) < 0) + if (virStorageVolDeleteEnsureACL(volume->conn, pool->def, voldef) < 0) goto cleanup; =20 - if (vol->in_use) { + if (voldef->in_use) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still in use."), - vol->name); + voldef->name); goto cleanup; } =20 - if (vol->building) { + if (voldef->building) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still being allocated."), - vol->name); + voldef->name); goto cleanup; } =20 - if (storageVolDeleteInternal(obj, backend, pool, vol, flags, true) < 0) + if (storageVolDeleteInternal(volume, backend, pool, voldef, + flags, true) < 0) goto cleanup; =20 ret =3D 0; =20 cleanup: + virPoolObjEndAPI(&volobj); virStoragePoolObjUnlock(pool); return ret; } @@ -1878,7 +1893,10 @@ storageVolCreateXML(virStoragePoolPtr obj, virStoragePoolObjPtr pool; virStorageBackendPtr backend; virStorageVolDefPtr voldef =3D NULL; - virStorageVolPtr ret =3D NULL, volobj =3D NULL; + virStorageVolDefPtr objvoldef; + virPoolObjPtr volobj =3D NULL; + virStorageVolPtr vol =3D NULL; + virStorageVolPtr ret =3D NULL; =20 virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL); =20 @@ -1894,9 +1912,8 @@ storageVolCreateXML(virStoragePoolPtr obj, if ((backend =3D virStorageBackendForType(pool->def->type)) =3D=3D NUL= L) goto cleanup; =20 - voldef =3D virStorageVolDefParseString(pool->def, xmldesc, - VIR_VOL_XML_PARSE_OPT_CAPACITY); - if (voldef =3D=3D NULL) + if (!(voldef =3D virStorageVolDefParseString(pool->def, xmldesc, + VIR_VOL_XML_PARSE_OPT_CAPAC= ITY))) goto cleanup; =20 if (!voldef->target.capacity && !backend->buildVol) { @@ -1909,7 +1926,7 @@ storageVolCreateXML(virStoragePoolPtr obj, if (virStorageVolCreateXMLEnsureACL(obj->conn, pool->def, voldef) < 0) goto cleanup; =20 - if (virStorageVolDefFindByName(pool, voldef->name)) { + if ((volobj =3D virStorageVolObjFindByName(pool, voldef->name))) { virReportError(VIR_ERR_STORAGE_VOL_EXIST, _("'%s'"), voldef->name); goto cleanup; @@ -1922,43 +1939,38 @@ storageVolCreateXML(virStoragePoolPtr obj, goto cleanup; } =20 - if (VIR_REALLOC_N(pool->volumes.objs, - pool->volumes.count+1) < 0) - goto cleanup; - /* Wipe any key the user may have suggested, as volume creation * will generate the canonical key. */ VIR_FREE(voldef->key); if (backend->createVol(obj->conn, pool, voldef) < 0) goto cleanup; =20 - pool->volumes.objs[pool->volumes.count++] =3D voldef; - volobj =3D virGetStorageVol(obj->conn, pool->def->name, voldef->name, - voldef->key, NULL, NULL); - if (!volobj) { - pool->volumes.count--; + if (!(volobj =3D virStoragePoolObjAddVolume(pool, voldef))) goto cleanup; - } + VIR_STEAL_PTR(objvoldef, voldef); =20 + if (!(vol =3D virGetStorageVol(obj->conn, pool->def->name, objvoldef->= name, + objvoldef->key, NULL, NULL))) { + virStoragePoolObjRemoveVolume(pool, &volobj); + goto cleanup; + } =20 if (backend->buildVol) { int buildret; virStorageVolDefPtr buildvoldef =3D NULL; =20 - if (VIR_ALLOC(buildvoldef) < 0) { - voldef =3D NULL; + if (VIR_ALLOC(buildvoldef) < 0) goto cleanup; - } =20 /* Make a shallow copy of the 'defined' volume definition, since t= he * original allocation value will change as the user polls 'info', * but we only need the initial requested values */ - memcpy(buildvoldef, voldef, sizeof(*voldef)); + memcpy(buildvoldef, objvoldef, sizeof(*objvoldef)); =20 /* Drop the pool lock during volume allocation */ pool->asyncjobs++; - voldef->building =3D true; + objvoldef->building =3D true; virStoragePoolObjUnlock(pool); =20 buildret =3D backend->buildVol(obj->conn, pool, buildvoldef, flags= ); @@ -1969,23 +1981,21 @@ storageVolCreateXML(virStoragePoolPtr obj, virStoragePoolObjLock(pool); storageDriverUnlock(); =20 - voldef->building =3D false; + objvoldef->building =3D false; pool->asyncjobs--; =20 if (buildret < 0) { /* buildVol handles deleting volume on failure */ - storageVolRemoveFromPool(pool, voldef); - voldef =3D NULL; + storageVolRemoveFromPool(pool, objvoldef); goto cleanup; } =20 } =20 if (backend->refreshVol && - backend->refreshVol(obj->conn, pool, voldef) < 0) { - storageVolDeleteInternal(volobj, backend, pool, voldef, + backend->refreshVol(obj->conn, pool, objvoldef) < 0) { + storageVolDeleteInternal(vol, backend, pool, objvoldef, 0, false); - voldef =3D NULL; goto cleanup; } =20 @@ -1993,18 +2003,18 @@ storageVolCreateXML(virStoragePoolPtr obj, * it updates the pool values. */ if (pool->def->type !=3D VIR_STORAGE_POOL_DISK) { - pool->def->allocation +=3D voldef->target.allocation; - pool->def->available -=3D voldef->target.allocation; + pool->def->allocation +=3D objvoldef->target.allocation; + pool->def->available -=3D objvoldef->target.allocation; } =20 VIR_INFO("Creating volume '%s' in storage pool '%s'", - volobj->name, pool->def->name); - ret =3D volobj; - volobj =3D NULL; - voldef =3D NULL; + vol->name, pool->def->name); + ret =3D vol; + vol =3D NULL; =20 cleanup: - virObjectUnref(volobj); + virPoolObjEndAPI(&volobj); + virObjectUnref(vol); virStorageVolDefFree(voldef); if (pool) virStoragePoolObjUnlock(pool); @@ -2014,13 +2024,19 @@ storageVolCreateXML(virStoragePoolPtr obj, static virStorageVolPtr storageVolCreateXMLFrom(virStoragePoolPtr obj, const char *xmldesc, - virStorageVolPtr vobj, + virStorageVolPtr volume, unsigned int flags) { virStoragePoolObjPtr pool, origpool =3D NULL; virStorageBackendPtr backend; - virStorageVolDefPtr origvol =3D NULL, newvol =3D NULL, shadowvol =3D N= ULL; - virStorageVolPtr ret =3D NULL, volobj =3D NULL; + virPoolObjPtr newvolobj =3D NULL; + virPoolObjPtr origvolobj =3D NULL; + virStorageVolDefPtr origvoldef; + virStorageVolDefPtr newvoldef =3D NULL; + virStorageVolDefPtr objnewvoldef; + virStorageVolDefPtr shadowvoldef =3D NULL; + virStorageVolPtr vol =3D NULL; + virStorageVolPtr ret =3D NULL; int buildret; =20 virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA | @@ -2029,9 +2045,9 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, =20 storageDriverLock(); pool =3D virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); - if (pool && STRNEQ(obj->name, vobj->pool)) { + if (pool && STRNEQ(obj->name, volume->pool)) { virStoragePoolObjUnlock(pool); - origpool =3D virStoragePoolObjFindByName(&driver->pools, vobj->poo= l); + origpool =3D virStoragePoolObjFindByName(&driver->pools, volume->p= ool); virStoragePoolObjLock(pool); } storageDriverUnlock(); @@ -2044,10 +2060,10 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, goto cleanup; } =20 - if (STRNEQ(obj->name, vobj->pool) && !origpool) { + if (STRNEQ(obj->name, volume->pool) && !origpool) { virReportError(VIR_ERR_NO_STORAGE_POOL, _("no storage pool with matching name '%s'"), - vobj->pool); + volume->pool); goto cleanup; } =20 @@ -2067,41 +2083,42 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, if ((backend =3D virStorageBackendForType(pool->def->type)) =3D=3D NUL= L) goto cleanup; =20 - origvol =3D virStorageVolDefFindByName(origpool ? - origpool : pool, vobj->name); - if (!origvol) { + if (!(origvolobj =3D virStorageVolObjFindByName(origpool ? origpool : + pool, volume->name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), - vobj->name); + volume->name); goto cleanup; } + origvoldef =3D virPoolObjGetDef(origvolobj); =20 - newvol =3D virStorageVolDefParseString(pool->def, xmldesc, - VIR_VOL_XML_PARSE_NO_CAPACITY); - if (newvol =3D=3D NULL) + if (!(newvoldef =3D + virStorageVolDefParseString(pool->def, xmldesc, + VIR_VOL_XML_PARSE_NO_CAPACITY))) goto cleanup; =20 - if (virStorageVolCreateXMLFromEnsureACL(obj->conn, pool->def, newvol) = < 0) + if (virStorageVolCreateXMLFromEnsureACL(obj->conn, pool->def, + newvoldef) < 0) goto cleanup; =20 - if (virStorageVolDefFindByName(pool, newvol->name)) { + if ((newvolobj =3D virStorageVolObjFindByName(pool, newvoldef->name)))= { virReportError(VIR_ERR_INTERNAL_ERROR, _("storage volume name '%s' already in use."), - newvol->name); + newvoldef->name); goto cleanup; } =20 /* Use the original volume's capacity in case the new capacity * is less than that, or it was omitted */ - if (newvol->target.capacity < origvol->target.capacity) - newvol->target.capacity =3D origvol->target.capacity; + if (newvoldef->target.capacity < origvoldef->target.capacity) + newvoldef->target.capacity =3D origvoldef->target.capacity; =20 /* If the allocation was not provided in the XML, then use capacity * as it's specifically documented "If omitted when creating a volume, * the volume will be fully allocated at time of creation.". This * is especially important for logical volume creation. */ - if (!newvol->target.has_allocation) - newvol->target.allocation =3D newvol->target.capacity; + if (!newvoldef->target.has_allocation) + newvoldef->target.allocation =3D newvoldef->target.capacity; =20 if (!backend->buildVolFrom) { virReportError(VIR_ERR_NO_SUPPORT, @@ -2110,49 +2127,47 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, goto cleanup; } =20 - if (origvol->building) { + if (origvoldef->building) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still being allocated."), - origvol->name); + origvoldef->name); goto cleanup; } =20 if (backend->refreshVol && - backend->refreshVol(obj->conn, pool, origvol) < 0) - goto cleanup; - - if (VIR_REALLOC_N(pool->volumes.objs, - pool->volumes.count+1) < 0) + backend->refreshVol(obj->conn, pool, origvoldef) < 0) goto cleanup; =20 /* 'Define' the new volume so we get async progress reporting. * Wipe any key the user may have suggested, as volume creation * will generate the canonical key. */ - VIR_FREE(newvol->key); - if (backend->createVol(obj->conn, pool, newvol) < 0) + VIR_FREE(newvoldef->key); + if (backend->createVol(obj->conn, pool, newvoldef) < 0) goto cleanup; =20 /* Make a shallow copy of the 'defined' volume definition, since the * original allocation value will change as the user polls 'info', * but we only need the initial requested values */ - if (VIR_ALLOC(shadowvol) < 0) + if (VIR_ALLOC(shadowvoldef) < 0) goto cleanup; =20 - memcpy(shadowvol, newvol, sizeof(*newvol)); + memcpy(shadowvoldef, newvoldef, sizeof(*newvoldef)); + + if (!(newvolobj =3D virStoragePoolObjAddVolume(pool, newvoldef))) + goto cleanup; + VIR_STEAL_PTR(objnewvoldef, newvoldef); =20 - pool->volumes.objs[pool->volumes.count++] =3D newvol; - volobj =3D virGetStorageVol(obj->conn, pool->def->name, newvol->name, - newvol->key, NULL, NULL); - if (!volobj) { - pool->volumes.count--; + if (!(vol =3D virGetStorageVol(obj->conn, pool->def->name, objnewvolde= f->name, + objnewvoldef->key, NULL, NULL))) { + virStoragePoolObjRemoveVolume(pool, &newvolobj); goto cleanup; } =20 /* Drop the pool lock during volume allocation */ pool->asyncjobs++; - newvol->building =3D true; - origvol->in_use++; + objnewvoldef->building =3D true; + origvoldef->in_use++; virStoragePoolObjUnlock(pool); =20 if (origpool) { @@ -2160,7 +2175,8 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, virStoragePoolObjUnlock(origpool); } =20 - buildret =3D backend->buildVolFrom(obj->conn, pool, shadowvol, origvol= , flags); + buildret =3D backend->buildVolFrom(obj->conn, pool, shadowvoldef, + origvoldef, flags); =20 storageDriverLock(); virStoragePoolObjLock(pool); @@ -2168,8 +2184,8 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, virStoragePoolObjLock(origpool); storageDriverUnlock(); =20 - origvol->in_use--; - newvol->building =3D false; + origvoldef->in_use--; + objnewvoldef->building =3D false; pool->asyncjobs--; =20 if (origpool) { @@ -2180,9 +2196,8 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, =20 if (buildret < 0 || (backend->refreshVol && - backend->refreshVol(obj->conn, pool, newvol) < 0)) { - storageVolDeleteInternal(volobj, backend, pool, newvol, 0, false); - newvol =3D NULL; + backend->refreshVol(obj->conn, pool, objnewvoldef) < 0)) { + storageVolDeleteInternal(vol, backend, pool, objnewvoldef, 0, fals= e); goto cleanup; } =20 @@ -2190,20 +2205,21 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, * it updates the pool values */ if (pool->def->type !=3D VIR_STORAGE_POOL_DISK) { - pool->def->allocation +=3D newvol->target.allocation; - pool->def->available -=3D newvol->target.allocation; + pool->def->allocation +=3D objnewvoldef->target.allocation; + pool->def->available -=3D objnewvoldef->target.allocation; } =20 VIR_INFO("Creating volume '%s' in storage pool '%s'", - volobj->name, pool->def->name); - ret =3D volobj; - volobj =3D NULL; - newvol =3D NULL; + vol->name, pool->def->name); + ret =3D vol; + vol =3D NULL; =20 cleanup: - virObjectUnref(volobj); - virStorageVolDefFree(newvol); - VIR_FREE(shadowvol); + virPoolObjEndAPI(&origvolobj); + virPoolObjEndAPI(&newvolobj); + virObjectUnref(vol); + virStorageVolDefFree(newvoldef); + VIR_FREE(shadowvoldef); if (pool) virStoragePoolObjUnlock(pool); if (origpool) @@ -2213,7 +2229,7 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, =20 =20 static int -storageVolDownload(virStorageVolPtr obj, +storageVolDownload(virStorageVolPtr volume, virStreamPtr stream, unsigned long long offset, unsigned long long length, @@ -2221,21 +2237,23 @@ storageVolDownload(virStorageVolPtr obj, { virStorageBackendPtr backend; virStoragePoolObjPtr pool =3D NULL; - virStorageVolDefPtr vol =3D NULL; + virPoolObjPtr volobj; + virStorageVolDefPtr voldef; int ret =3D -1; =20 virCheckFlags(0, -1); =20 - if (!(vol =3D virStorageVolDefFromVol(obj, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) return -1; + voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolDownloadEnsureACL(obj->conn, pool->def, vol) < 0) + if (virStorageVolDownloadEnsureACL(volume->conn, pool->def, voldef) < = 0) goto cleanup; =20 - if (vol->building) { + if (voldef->building) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still being allocated."), - vol->name); + voldef->name); goto cleanup; } =20 @@ -2245,10 +2263,11 @@ storageVolDownload(virStorageVolPtr obj, goto cleanup; } =20 - ret =3D backend->downloadVol(obj->conn, pool, vol, stream, + ret =3D backend->downloadVol(volume->conn, pool, voldef, stream, offset, length, flags); =20 cleanup: + virPoolObjEndAPI(&volobj); virStoragePoolObjUnlock(pool); =20 return ret; @@ -2380,7 +2399,7 @@ virStorageVolFDStreamCloseCb(virStreamPtr st ATTRIBUT= E_UNUSED, } =20 static int -storageVolUpload(virStorageVolPtr obj, +storageVolUpload(virStorageVolPtr volume, virStreamPtr stream, unsigned long long offset, unsigned long long length, @@ -2388,29 +2407,31 @@ storageVolUpload(virStorageVolPtr obj, { virStorageBackendPtr backend; virStoragePoolObjPtr pool =3D NULL; - virStorageVolDefPtr vol =3D NULL; + virPoolObjPtr volobj; + virStorageVolDefPtr voldef; virStorageVolStreamInfoPtr cbdata =3D NULL; int ret =3D -1; =20 virCheckFlags(0, -1); =20 - if (!(vol =3D virStorageVolDefFromVol(obj, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) return -1; + voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolUploadEnsureACL(obj->conn, pool->def, vol) < 0) + if (virStorageVolUploadEnsureACL(volume->conn, pool->def, voldef) < 0) goto cleanup; =20 - if (vol->in_use) { + if (voldef->in_use) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still in use."), - vol->name); + voldef->name); goto cleanup; } =20 - if (vol->building) { + if (voldef->building) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still being allocated."), - vol->name); + voldef->name); goto cleanup; } =20 @@ -2429,11 +2450,11 @@ storageVolUpload(virStorageVolPtr obj, if (VIR_ALLOC(cbdata) < 0 || VIR_STRDUP(cbdata->pool_name, pool->def->name) < 0) goto cleanup; - if (vol->type =3D=3D VIR_STORAGE_VOL_PLOOP && - VIR_STRDUP(cbdata->vol_path, vol->target.path) < 0) + if (voldef->type =3D=3D VIR_STORAGE_VOL_PLOOP && + VIR_STRDUP(cbdata->vol_path, voldef->target.path) < 0) goto cleanup; =20 - if ((ret =3D backend->uploadVol(obj->conn, pool, vol, stream, + if ((ret =3D backend->uploadVol(volume->conn, pool, voldef, stream, offset, length, flags)) < 0) goto cleanup; =20 @@ -2446,6 +2467,7 @@ storageVolUpload(virStorageVolPtr obj, cbdata =3D NULL; =20 cleanup: + virPoolObjEndAPI(&volobj); virStoragePoolObjUnlock(pool); if (cbdata) virStorageVolPoolRefreshDataFree(cbdata); @@ -2454,13 +2476,14 @@ storageVolUpload(virStorageVolPtr obj, } =20 static int -storageVolResize(virStorageVolPtr obj, +storageVolResize(virStorageVolPtr volume, unsigned long long capacity, unsigned int flags) { virStorageBackendPtr backend; virStoragePoolObjPtr pool =3D NULL; - virStorageVolDefPtr vol =3D NULL; + virPoolObjPtr volobj; + virStorageVolDefPtr voldef; unsigned long long abs_capacity, delta =3D 0; int ret =3D -1; =20 @@ -2468,44 +2491,46 @@ storageVolResize(virStorageVolPtr obj, VIR_STORAGE_VOL_RESIZE_DELTA | VIR_STORAGE_VOL_RESIZE_SHRINK, -1); =20 - if (!(vol =3D virStorageVolDefFromVol(obj, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) return -1; + voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolResizeEnsureACL(obj->conn, pool->def, vol) < 0) + if (virStorageVolResizeEnsureACL(volume->conn, pool->def, voldef) < 0) goto cleanup; =20 - if (vol->in_use) { + if (voldef->in_use) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still in use."), - vol->name); + voldef->name); goto cleanup; } =20 - if (vol->building) { + if (voldef->building) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still being allocated."), - vol->name); + voldef->name); goto cleanup; } =20 if (flags & VIR_STORAGE_VOL_RESIZE_DELTA) { if (flags & VIR_STORAGE_VOL_RESIZE_SHRINK) - abs_capacity =3D vol->target.capacity - MIN(capacity, vol->tar= get.capacity); + abs_capacity =3D voldef->target.capacity - + MIN(capacity, voldef->target.capacity); else - abs_capacity =3D vol->target.capacity + capacity; + abs_capacity =3D voldef->target.capacity + capacity; flags &=3D ~VIR_STORAGE_VOL_RESIZE_DELTA; } else { abs_capacity =3D capacity; } =20 - if (abs_capacity < vol->target.allocation) { + if (abs_capacity < voldef->target.allocation) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("can't shrink capacity below " "existing allocation")); goto cleanup; } =20 - if (abs_capacity < vol->target.capacity && + if (abs_capacity < voldef->target.capacity && !(flags & VIR_STORAGE_VOL_RESIZE_SHRINK)) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("Can't shrink capacity below current " @@ -2514,7 +2539,7 @@ storageVolResize(virStorageVolPtr obj, } =20 if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE) - delta =3D abs_capacity - vol->target.allocation; + delta =3D abs_capacity - voldef->target.allocation; =20 if (delta > pool->def->available) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", @@ -2529,16 +2554,16 @@ storageVolResize(virStorageVolPtr obj, goto cleanup; } =20 - if (backend->resizeVol(obj->conn, pool, vol, abs_capacity, flags) < 0) + if (backend->resizeVol(volume->conn, pool, voldef, abs_capacity, flags= ) < 0) goto cleanup; =20 - vol->target.capacity =3D abs_capacity; + voldef->target.capacity =3D abs_capacity; /* Only update the allocation and pool values if we actually did the * allocation; otherwise, this is akin to a create operation with a * capacity value different and potentially much larger than available */ if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE) { - vol->target.allocation =3D abs_capacity; + voldef->target.allocation =3D abs_capacity; pool->def->allocation +=3D delta; pool->def->available -=3D delta; } @@ -2546,6 +2571,7 @@ storageVolResize(virStorageVolPtr obj, ret =3D 0; =20 cleanup: + virPoolObjEndAPI(&volobj); virStoragePoolObjUnlock(pool); =20 return ret; @@ -2553,13 +2579,14 @@ storageVolResize(virStorageVolPtr obj, =20 =20 static int -storageVolWipePattern(virStorageVolPtr obj, +storageVolWipePattern(virStorageVolPtr volume, unsigned int algorithm, unsigned int flags) { virStorageBackendPtr backend; virStoragePoolObjPtr pool =3D NULL; - virStorageVolDefPtr vol =3D NULL; + virPoolObjPtr volobj; + virStorageVolDefPtr voldef; int ret =3D -1; =20 virCheckFlags(0, -1); @@ -2571,24 +2598,24 @@ storageVolWipePattern(virStorageVolPtr obj, return -1; } =20 - if (!(vol =3D virStorageVolDefFromVol(obj, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) return -1; + voldef =3D virPoolObjGetDef(volobj); =20 - - if (virStorageVolWipePatternEnsureACL(obj->conn, pool->def, vol) < 0) + if (virStorageVolWipePatternEnsureACL(volume->conn, pool->def, voldef)= < 0) goto cleanup; =20 - if (vol->in_use) { + if (voldef->in_use) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still in use."), - vol->name); + voldef->name); goto cleanup; } =20 - if (vol->building) { + if (voldef->building) { virReportError(VIR_ERR_OPERATION_INVALID, _("volume '%s' is still being allocated."), - vol->name); + voldef->name); goto cleanup; } =20 @@ -2598,16 +2625,17 @@ storageVolWipePattern(virStorageVolPtr obj, goto cleanup; } =20 - if (backend->wipeVol(obj->conn, pool, vol, algorithm, flags) < 0) + if (backend->wipeVol(volume->conn, pool, voldef, algorithm, flags) < 0) goto cleanup; =20 if (backend->refreshVol && - backend->refreshVol(obj->conn, pool, vol) < 0) + backend->refreshVol(volume->conn, pool, voldef) < 0) goto cleanup; =20 ret =3D 0; =20 cleanup: + virPoolObjEndAPI(&volobj); virStoragePoolObjUnlock(pool); =20 return ret; @@ -2622,37 +2650,40 @@ storageVolWipe(virStorageVolPtr obj, =20 =20 static int -storageVolGetInfoFlags(virStorageVolPtr obj, +storageVolGetInfoFlags(virStorageVolPtr volume, virStorageVolInfoPtr info, unsigned int flags) { virStoragePoolObjPtr pool; virStorageBackendPtr backend; - virStorageVolDefPtr vol; + virPoolObjPtr volobj; + virStorageVolDefPtr voldef; int ret =3D -1; =20 virCheckFlags(VIR_STORAGE_VOL_GET_PHYSICAL, -1); =20 - if (!(vol =3D virStorageVolDefFromVol(obj, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) return -1; + voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolGetInfoFlagsEnsureACL(obj->conn, pool->def, vol) < 0) + if (virStorageVolGetInfoFlagsEnsureACL(volume->conn, pool->def, voldef= ) < 0) goto cleanup; =20 if (backend->refreshVol && - backend->refreshVol(obj->conn, pool, vol) < 0) + backend->refreshVol(volume->conn, pool, voldef) < 0) goto cleanup; =20 memset(info, 0, sizeof(*info)); - info->type =3D vol->type; - info->capacity =3D vol->target.capacity; + info->type =3D voldef->type; + info->capacity =3D voldef->target.capacity; if (flags & VIR_STORAGE_VOL_GET_PHYSICAL) - info->allocation =3D vol->target.physical; + info->allocation =3D voldef->target.physical; else - info->allocation =3D vol->target.allocation; + info->allocation =3D voldef->target.allocation; ret =3D 0; =20 cleanup: + virPoolObjEndAPI(&volobj); virStoragePoolObjUnlock(pool); return ret; } @@ -2667,50 +2698,56 @@ storageVolGetInfo(virStorageVolPtr obj, =20 =20 static char * -storageVolGetXMLDesc(virStorageVolPtr obj, +storageVolGetXMLDesc(virStorageVolPtr volume, unsigned int flags) { virStoragePoolObjPtr pool; virStorageBackendPtr backend; - virStorageVolDefPtr vol; + virPoolObjPtr volobj; + virStorageVolDefPtr voldef; char *ret =3D NULL; =20 virCheckFlags(0, NULL); =20 - if (!(vol =3D virStorageVolDefFromVol(obj, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) return NULL; + voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolGetXMLDescEnsureACL(obj->conn, pool->def, vol) < 0) + if (virStorageVolGetXMLDescEnsureACL(volume->conn, pool->def, voldef) = < 0) goto cleanup; =20 if (backend->refreshVol && - backend->refreshVol(obj->conn, pool, vol) < 0) + backend->refreshVol(volume->conn, pool, voldef) < 0) goto cleanup; =20 - ret =3D virStorageVolDefFormat(pool->def, vol); + ret =3D virStorageVolDefFormat(pool->def, voldef); =20 cleanup: + virPoolObjEndAPI(&volobj); virStoragePoolObjUnlock(pool); =20 return ret; } =20 static char * -storageVolGetPath(virStorageVolPtr obj) +storageVolGetPath(virStorageVolPtr volume) { virStoragePoolObjPtr pool; - virStorageVolDefPtr vol; + virPoolObjPtr volobj; + virStorageVolDefPtr voldef; char *ret =3D NULL; =20 - if (!(vol =3D virStorageVolDefFromVol(obj, &pool, NULL))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, NULL))) return NULL; + voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolGetPathEnsureACL(obj->conn, pool->def, vol) < 0) + if (virStorageVolGetPathEnsureACL(volume->conn, pool->def, voldef) < 0) goto cleanup; =20 - ignore_value(VIR_STRDUP(ret, vol->target.path)); + ignore_value(VIR_STRDUP(ret, voldef->target.path)); =20 cleanup: + virPoolObjEndAPI(&volobj); virStoragePoolObjUnlock(pool); return ret; } diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index a665bac..644c3e7 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -3471,6 +3471,7 @@ virStorageBackendRefreshLocal(virConnectPtr conn ATTR= IBUTE_UNUSED, struct statvfs sb; struct stat statbuf; virStorageVolDefPtr vol =3D NULL; + virPoolObjPtr volobj; virStorageSourcePtr target =3D NULL; int direrr; int fd =3D -1, ret =3D -1; @@ -3539,8 +3540,11 @@ virStorageBackendRefreshLocal(virConnectPtr conn ATT= RIBUTE_UNUSED, * An error message was raised, but we just continue. */ } =20 - if (VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vo= l) < 0) + if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) goto cleanup; + + vol =3D NULL; + virPoolObjEndAPI(&volobj); } if (direrr < 0) goto cleanup; @@ -3656,6 +3660,7 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr pool, const char *dev) { virStorageVolDefPtr vol =3D NULL; + virPoolObjPtr volobj; char *devpath =3D NULL; int retval =3D -1; =20 @@ -3727,10 +3732,11 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr po= ol, pool->def->capacity +=3D vol->target.capacity; pool->def->allocation +=3D vol->target.allocation; =20 - if (VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vol) <= 0) + if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) goto cleanup; =20 vol =3D NULL; + virPoolObjEndAPI(&volobj); retval =3D 0; =20 cleanup: diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 51605f3..fedf415 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -1016,7 +1016,9 @@ testOpenVolumesForPool(const char *file, size_t i; int num, ret =3D -1; xmlNodePtr *nodes =3D NULL; + xmlNodePtr node; virStorageVolDefPtr def =3D NULL; + virPoolObjPtr volobj =3D NULL; =20 /* Find storage volumes */ if (virAsprintf(&vol_xpath, "/node/pool[%d]/volume", poolidx) < 0) @@ -1028,25 +1030,22 @@ testOpenVolumesForPool(const char *file, goto error; =20 for (i =3D 0; i < num; i++) { - xmlNodePtr node =3D testParseXMLDocFromFile(nodes[i], file, - "volume"); - if (!node) + if (!(node =3D testParseXMLDocFromFile(nodes[i], file, "volume"))) goto error; =20 - def =3D virStorageVolDefParseNode(pool->def, ctxt->doc, node, 0); - if (!def) + if (!(def =3D virStorageVolDefParseNode(pool->def, ctxt->doc, node= , 0))) goto error; =20 if (def->target.path =3D=3D NULL) { if (virAsprintf(&def->target.path, "%s/%s", - pool->def->target.path, - def->name) =3D=3D -1) + pool->def->target.path, def->name) < 0) goto error; } =20 if (!def->key && VIR_STRDUP(def->key, def->target.path) < 0) goto error; - if (VIR_APPEND_ELEMENT_COPY(pool->volumes.objs, pool->volumes.coun= t, def) < 0) + + if (!(volobj =3D virStoragePoolObjAddVolume(pool, def))) goto error; =20 pool->def->allocation +=3D def->target.allocation; @@ -1057,6 +1056,7 @@ testOpenVolumesForPool(const char *file, =20 ret =3D 0; error: + virPoolObjEndAPI(&volobj); virStorageVolDefFree(def); VIR_FREE(nodes); return ret; @@ -4702,9 +4702,9 @@ testStoragePoolNumOfVolumes(virStoragePoolPtr pool) pool->name); testDriverUnlock(privconn); =20 - if (privpool =3D=3D NULL) { + if (!privpool) { virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; + return -1; } =20 if (!virStoragePoolObjIsActive(privpool)) { @@ -4713,23 +4713,26 @@ testStoragePoolNumOfVolumes(virStoragePoolPtr pool) goto cleanup; } =20 - ret =3D privpool->volumes.count; + /* NB: Neither pool->def nor aclfilter is being used for test purposes + * so last two args can be NULL */ + ret =3D virStoragePoolObjNumOfVolumes(privpool->volumes, pool->conn, + NULL, NULL); =20 cleanup: - if (privpool) - virStoragePoolObjUnlock(privpool); + virStoragePoolObjUnlock(privpool); return ret; } =20 + + static int testStoragePoolListVolumes(virStoragePoolPtr pool, char **const names, int maxnames) { + int ret =3D -1; testDriverPtr privconn =3D pool->conn->privateData; virStoragePoolObjPtr privpool; - size_t i =3D 0; - int n =3D 0; =20 memset(names, 0, maxnames * sizeof(*names)); =20 @@ -4738,47 +4741,39 @@ testStoragePoolListVolumes(virStoragePoolPtr pool, pool->name); testDriverUnlock(privconn); =20 - if (privpool =3D=3D NULL) { + if (!privpool) { virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; + return -1; } =20 - if (!virStoragePoolObjIsActive(privpool)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), pool->name); goto cleanup; } =20 - for (i =3D 0; i < privpool->volumes.count && n < maxnames; i++) { - if (VIR_STRDUP(names[n++], privpool->volumes.objs[i]->name) < 0) - goto cleanup; - } - - virStoragePoolObjUnlock(privpool); - return n; + /* NB: Neither pool->def nor aclfilter is being used for test purposes + * so those two args can be NULL */ + ret =3D virStoragePoolObjListVolumes(privpool->volumes, pool->conn, + NULL, NULL, names, maxnames); =20 cleanup: - for (n =3D 0; n < maxnames; n++) - VIR_FREE(names[i]); - - memset(names, 0, maxnames * sizeof(*names)); - if (privpool) - virStoragePoolObjUnlock(privpool); - return -1; + virStoragePoolObjUnlock(privpool); + return ret; } =20 + static int testStoragePoolListAllVolumes(virStoragePoolPtr obj, - virStorageVolPtr **vols, + virStorageVolPtr **volumes, unsigned int flags) { testDriverPtr privconn =3D obj->conn->privateData; virStoragePoolObjPtr pool; + virPoolObjPtr *volobjs =3D NULL; + size_t nvolobjs =3D 0; size_t i; - virStorageVolPtr *tmp_vols =3D NULL; - virStorageVolPtr vol =3D NULL; - int nvols =3D 0; + virStorageVolPtr *vols =3D NULL; int ret =3D -1; =20 virCheckFlags(0, -1); @@ -4790,7 +4785,7 @@ testStoragePoolListAllVolumes(virStoragePoolPtr obj, if (!pool) { virReportError(VIR_ERR_NO_STORAGE_POOL, "%s", _("no storage pool with matching uuid")); - goto cleanup; + return -1; } =20 if (!virStoragePoolObjIsActive(pool)) { @@ -4799,40 +4794,39 @@ testStoragePoolListAllVolumes(virStoragePoolPtr obj, goto cleanup; } =20 - /* Just returns the volumes count */ - if (!vols) { - ret =3D pool->volumes.count; + if (virPoolObjTableCollect(pool->volumes, obj->conn, &volobjs, &nvolob= js, + NULL, NULL, flags) < 0) goto cleanup; - } =20 - if (VIR_ALLOC_N(tmp_vols, pool->volumes.count + 1) < 0) - goto cleanup; - - for (i =3D 0; i < pool->volumes.count; i++) { - if (!(vol =3D virGetStorageVol(obj->conn, pool->def->name, - pool->volumes.objs[i]->name, - pool->volumes.objs[i]->key, - NULL, NULL))) + if (volumes) { + if (VIR_ALLOC_N(vols, nvolobjs + 1) < 0) goto cleanup; - tmp_vols[nvols++] =3D vol; - } =20 - *vols =3D tmp_vols; - tmp_vols =3D NULL; - ret =3D nvols; + for (i =3D 0; i < nvolobjs; i++) { + virPoolObjPtr volobj =3D volobjs[i]; + virStorageVolDefPtr def; =20 - cleanup: - if (tmp_vols) { - for (i =3D 0; i < nvols; i++) { - if (tmp_vols[i]) - virStorageVolFree(tmp_vols[i]); + virObjectLock(volobj); + def =3D virPoolObjGetDef(volobj); + vols[i] =3D virGetStorageVol(obj->conn, pool->def->name, + def->name, def->key, NULL, NULL); + virObjectUnlock(volobj); + + if (!vols[i]) + goto cleanup; } - VIR_FREE(tmp_vols); + + *volumes =3D vols; + vols =3D NULL; } =20 - if (pool) - virStoragePoolObjUnlock(pool); + ret =3D nvolobjs; =20 + cleanup: + virObjectListFree(vols); + virObjectListFreeCount(volobjs, nvolobjs); + + virStoragePoolObjUnlock(pool); return ret; } =20 @@ -4842,7 +4836,8 @@ testStorageVolLookupByName(virStoragePoolPtr pool, { testDriverPtr privconn =3D pool->conn->privateData; virStoragePoolObjPtr privpool; - virStorageVolDefPtr privvol; + virPoolObjPtr volobj =3D NULL; + virStorageVolDefPtr voldef; virStorageVolPtr ret =3D NULL; =20 testDriverLock(privconn); @@ -4862,19 +4857,19 @@ testStorageVolLookupByName(virStoragePoolPtr pool, goto cleanup; } =20 - privvol =3D virStorageVolDefFindByName(privpool, name); - - if (!privvol) { + if (!(volobj =3D virStorageVolObjFindByName(privpool, name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), name); goto cleanup; } + voldef =3D virPoolObjGetDef(volobj); =20 ret =3D virGetStorageVol(pool->conn, privpool->def->name, - privvol->name, privvol->key, + voldef->name, voldef->key, NULL, NULL); =20 cleanup: + virPoolObjEndAPI(&volobj); if (privpool) virStoragePoolObjUnlock(privpool); return ret; @@ -4886,6 +4881,8 @@ testStorageVolLookupByKey(virConnectPtr conn, const char *key) { testDriverPtr privconn =3D conn->privateData; + virPoolObjPtr volobj; + virStorageVolDefPtr voldef; size_t i; virStorageVolPtr ret =3D NULL; =20 @@ -4893,18 +4890,19 @@ testStorageVolLookupByKey(virConnectPtr conn, for (i =3D 0; i < privconn->pools.count; i++) { virStoragePoolObjLock(privconn->pools.objs[i]); if (virStoragePoolObjIsActive(privconn->pools.objs[i])) { - virStorageVolDefPtr privvol =3D - virStorageVolDefFindByKey(privconn->pools.objs[i], key); - - if (privvol) { - ret =3D virGetStorageVol(conn, - privconn->pools.objs[i]->def->name, - privvol->name, - privvol->key, - NULL, NULL); - virStoragePoolObjUnlock(privconn->pools.objs[i]); - break; - } + if (!(volobj =3D virStorageVolObjFindByKey(privconn->pools.obj= s[i], + key))) + continue; + voldef =3D virPoolObjGetDef(volobj); + + ret =3D virGetStorageVol(conn, + privconn->pools.objs[i]->def->name, + voldef->name, + voldef->key, + NULL, NULL); + virPoolObjEndAPI(&volobj); + virStoragePoolObjUnlock(privconn->pools.objs[i]); + break; } virStoragePoolObjUnlock(privconn->pools.objs[i]); } @@ -4922,6 +4920,8 @@ testStorageVolLookupByPath(virConnectPtr conn, const char *path) { testDriverPtr privconn =3D conn->privateData; + virPoolObjPtr volobj; + virStorageVolDefPtr voldef; size_t i; virStorageVolPtr ret =3D NULL; =20 @@ -4929,18 +4929,19 @@ testStorageVolLookupByPath(virConnectPtr conn, for (i =3D 0; i < privconn->pools.count; i++) { virStoragePoolObjLock(privconn->pools.objs[i]); if (virStoragePoolObjIsActive(privconn->pools.objs[i])) { - virStorageVolDefPtr privvol =3D - virStorageVolDefFindByPath(privconn->pools.objs[i], path); - - if (privvol) { - ret =3D virGetStorageVol(conn, - privconn->pools.objs[i]->def->name, - privvol->name, - privvol->key, - NULL, NULL); - virStoragePoolObjUnlock(privconn->pools.objs[i]); - break; - } + if (!(volobj =3D virStorageVolObjFindByPath(privconn->pools.ob= js[i], + path))) + continue; + voldef =3D virPoolObjGetDef(volobj); + + ret =3D virGetStorageVol(conn, + privconn->pools.objs[i]->def->name, + voldef->name, + voldef->key, + NULL, NULL); + virPoolObjEndAPI(&volobj); + virStoragePoolObjUnlock(privconn->pools.objs[i]); + break; } virStoragePoolObjUnlock(privconn->pools.objs[i]); } @@ -4960,7 +4961,9 @@ testStorageVolCreateXML(virStoragePoolPtr pool, { testDriverPtr privconn =3D pool->conn->privateData; virStoragePoolObjPtr privpool; - virStorageVolDefPtr privvol =3D NULL; + virStorageVolDefPtr voldef =3D NULL; + virPoolObjPtr volobj =3D NULL; + virStorageVolDefPtr objvoldef; virStorageVolPtr ret =3D NULL; =20 virCheckFlags(0, NULL); @@ -4981,46 +4984,48 @@ testStorageVolCreateXML(virStoragePoolPtr pool, goto cleanup; } =20 - privvol =3D virStorageVolDefParseString(privpool->def, xmldesc, 0); - if (privvol =3D=3D NULL) + if (!(voldef =3D virStorageVolDefParseString(privpool->def, xmldesc, 0= ))) goto cleanup; =20 - if (virStorageVolDefFindByName(privpool, privvol->name)) { + if ((volobj =3D virStorageVolObjFindByName(privpool, voldef->name))) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("storage vol already exists")); goto cleanup; } =20 /* Make sure enough space */ - if ((privpool->def->allocation + privvol->target.allocation) > + if ((privpool->def->allocation + voldef->target.allocation) > privpool->def->capacity) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Not enough free space in pool for volume '%s'"), - privvol->name); + voldef->name); goto cleanup; } =20 - if (virAsprintf(&privvol->target.path, "%s/%s", + if (virAsprintf(&voldef->target.path, "%s/%s", privpool->def->target.path, - privvol->name) =3D=3D -1) + voldef->name) =3D=3D -1) + goto cleanup; + + if (VIR_STRDUP(voldef->key, voldef->target.path) < 0) goto cleanup; =20 - if (VIR_STRDUP(privvol->key, privvol->target.path) < 0 || - VIR_APPEND_ELEMENT_COPY(privpool->volumes.objs, - privpool->volumes.count, privvol) < 0) + if (!(volobj =3D virStoragePoolObjAddVolume(privpool, voldef))) goto cleanup; + VIR_STEAL_PTR(objvoldef, voldef); =20 - privpool->def->allocation +=3D privvol->target.allocation; + privpool->def->allocation +=3D objvoldef->target.allocation; privpool->def->available =3D (privpool->def->capacity - privpool->def->allocation); =20 - ret =3D virGetStorageVol(pool->conn, privpool->def->name, - privvol->name, privvol->key, - NULL, NULL); - privvol =3D NULL; + if (!(ret =3D virGetStorageVol(pool->conn, privpool->def->name, + objvoldef->name, objvoldef->key, + NULL, NULL))) + virStoragePoolObjRemoveVolume(privpool, &volobj); =20 cleanup: - virStorageVolDefFree(privvol); + virPoolObjEndAPI(&volobj); + virStorageVolDefFree(voldef); if (privpool) virStoragePoolObjUnlock(privpool); return ret; @@ -5034,7 +5039,10 @@ testStorageVolCreateXMLFrom(virStoragePoolPtr pool, { testDriverPtr privconn =3D pool->conn->privateData; virStoragePoolObjPtr privpool; - virStorageVolDefPtr privvol =3D NULL, origvol =3D NULL; + virStorageVolDefPtr voldef =3D NULL; + virPoolObjPtr volobj =3D NULL; + virStorageVolDefPtr objvoldef; + virPoolObjPtr origvolobj =3D NULL; virStorageVolPtr ret =3D NULL; =20 virCheckFlags(0, NULL); @@ -5055,18 +5063,16 @@ testStorageVolCreateXMLFrom(virStoragePoolPtr pool, goto cleanup; } =20 - privvol =3D virStorageVolDefParseString(privpool->def, xmldesc, 0); - if (privvol =3D=3D NULL) + if (!(voldef =3D virStorageVolDefParseString(privpool->def, xmldesc, 0= ))) goto cleanup; =20 - if (virStorageVolDefFindByName(privpool, privvol->name)) { + if ((volobj =3D virStorageVolObjFindByName(privpool, voldef->name))) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("storage vol already exists")); goto cleanup; } =20 - origvol =3D virStorageVolDefFindByName(privpool, clonevol->name); - if (!origvol) { + if (!(origvolobj =3D virStorageVolObjFindByName(privpool, clonevol->na= me))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), clonevol->name); @@ -5074,57 +5080,61 @@ testStorageVolCreateXMLFrom(virStoragePoolPtr pool, } =20 /* Make sure enough space */ - if ((privpool->def->allocation + privvol->target.allocation) > + if ((privpool->def->allocation + voldef->target.allocation) > privpool->def->capacity) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Not enough free space in pool for volume '%s'"), - privvol->name); + voldef->name); goto cleanup; } privpool->def->available =3D (privpool->def->capacity - privpool->def->allocation); =20 - if (virAsprintf(&privvol->target.path, "%s/%s", + if (virAsprintf(&voldef->target.path, "%s/%s", privpool->def->target.path, - privvol->name) =3D=3D -1) + voldef->name) =3D=3D -1) goto cleanup; =20 - if (VIR_STRDUP(privvol->key, privvol->target.path) < 0 || - VIR_APPEND_ELEMENT_COPY(privpool->volumes.objs, - privpool->volumes.count, privvol) < 0) + if (VIR_STRDUP(voldef->key, voldef->target.path) < 0) goto cleanup; =20 - privpool->def->allocation +=3D privvol->target.allocation; + if (!(volobj =3D virStoragePoolObjAddVolume(privpool, voldef))) + goto cleanup; + VIR_STEAL_PTR(objvoldef, voldef); + + privpool->def->allocation +=3D objvoldef->target.allocation; privpool->def->available =3D (privpool->def->capacity - privpool->def->allocation); =20 - ret =3D virGetStorageVol(pool->conn, privpool->def->name, - privvol->name, privvol->key, - NULL, NULL); - privvol =3D NULL; + if (!(ret =3D virGetStorageVol(pool->conn, privpool->def->name, + objvoldef->name, objvoldef->key, + NULL, NULL))) + virStoragePoolObjRemoveVolume(privpool, &volobj); =20 cleanup: - virStorageVolDefFree(privvol); + virPoolObjEndAPI(&origvolobj); + virPoolObjEndAPI(&volobj); + virStorageVolDefFree(voldef); if (privpool) virStoragePoolObjUnlock(privpool); return ret; } =20 static int -testStorageVolDelete(virStorageVolPtr vol, +testStorageVolDelete(virStorageVolPtr volume, unsigned int flags) { - testDriverPtr privconn =3D vol->conn->privateData; + testDriverPtr privconn =3D volume->conn->privateData; virStoragePoolObjPtr privpool; - virStorageVolDefPtr privvol; - size_t i; + virPoolObjPtr volobj =3D NULL; + virStorageVolDefPtr voldef; int ret =3D -1; =20 virCheckFlags(0, -1); =20 testDriverLock(privconn); privpool =3D virStoragePoolObjFindByName(&privconn->pools, - vol->pool); + volume->pool); testDriverUnlock(privconn); =20 if (privpool =3D=3D NULL) { @@ -5132,38 +5142,32 @@ testStorageVolDelete(virStorageVolPtr vol, goto cleanup; } =20 - - privvol =3D virStorageVolDefFindByName(privpool, vol->name); - - if (privvol =3D=3D NULL) { - virReportError(VIR_ERR_NO_STORAGE_VOL, - _("no storage vol with matching name '%s'"), - vol->name); - goto cleanup; - } - if (!virStoragePoolObjIsActive(privpool)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), vol->pool); + _("storage pool '%s' is not active"), volume->pool); goto cleanup; } =20 + if (!(volobj =3D virPoolObjTableFindByName(privpool->volumes, + volume->name))) { + virReportError(VIR_ERR_NO_STORAGE_VOL, + _("no storage vol with matching name '%s'"), + volume->name); + goto cleanup; + } + voldef =3D virPoolObjGetDef(volobj); =20 - privpool->def->allocation -=3D privvol->target.allocation; + privpool->def->allocation -=3D voldef->target.allocation; privpool->def->available =3D (privpool->def->capacity - privpool->def->allocation); =20 - for (i =3D 0; i < privpool->volumes.count; i++) { - if (privpool->volumes.objs[i] =3D=3D privvol) { - virStorageVolDefFree(privvol); =20 - VIR_DELETE_ELEMENT(privpool->volumes.objs, i, privpool->volume= s.count); - break; - } - } + virStoragePoolObjRemoveVolume(privpool, &volobj); + ret =3D 0; =20 cleanup: + virPoolObjEndAPI(&volobj); if (privpool) virStoragePoolObjUnlock(privpool); return ret; @@ -5184,17 +5188,18 @@ static int testStorageVolumeTypeForPool(int pooltyp= e) } =20 static int -testStorageVolGetInfo(virStorageVolPtr vol, +testStorageVolGetInfo(virStorageVolPtr volume, virStorageVolInfoPtr info) { - testDriverPtr privconn =3D vol->conn->privateData; + testDriverPtr privconn =3D volume->conn->privateData; virStoragePoolObjPtr privpool; - virStorageVolDefPtr privvol; + virPoolObjPtr volobj =3D NULL; + virStorageVolDefPtr voldef; int ret =3D -1; =20 testDriverLock(privconn); privpool =3D virStoragePoolObjFindByName(&privconn->pools, - vol->pool); + volume->pool); testDriverUnlock(privconn); =20 if (privpool =3D=3D NULL) { @@ -5202,47 +5207,48 @@ testStorageVolGetInfo(virStorageVolPtr vol, goto cleanup; } =20 - privvol =3D virStorageVolDefFindByName(privpool, vol->name); - - if (privvol =3D=3D NULL) { + if (!(volobj =3D virStorageVolObjFindByName(privpool, volume->name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), - vol->name); + volume->name); goto cleanup; } + voldef =3D virPoolObjGetDef(volobj); =20 if (!virStoragePoolObjIsActive(privpool)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), vol->pool); + _("storage pool '%s' is not active"), volume->pool); goto cleanup; } =20 memset(info, 0, sizeof(*info)); info->type =3D testStorageVolumeTypeForPool(privpool->def->type); - info->capacity =3D privvol->target.capacity; - info->allocation =3D privvol->target.allocation; + info->capacity =3D voldef->target.capacity; + info->allocation =3D voldef->target.allocation; ret =3D 0; =20 cleanup: + virPoolObjEndAPI(&volobj); if (privpool) virStoragePoolObjUnlock(privpool); return ret; } =20 static char * -testStorageVolGetXMLDesc(virStorageVolPtr vol, +testStorageVolGetXMLDesc(virStorageVolPtr volume, unsigned int flags) { - testDriverPtr privconn =3D vol->conn->privateData; + testDriverPtr privconn =3D volume->conn->privateData; virStoragePoolObjPtr privpool; - virStorageVolDefPtr privvol; + virPoolObjPtr volobj =3D NULL; + virStorageVolDefPtr voldef; char *ret =3D NULL; =20 virCheckFlags(0, NULL); =20 testDriverLock(privconn); privpool =3D virStoragePoolObjFindByName(&privconn->pools, - vol->pool); + volume->pool); testDriverUnlock(privconn); =20 if (privpool =3D=3D NULL) { @@ -5250,40 +5256,41 @@ testStorageVolGetXMLDesc(virStorageVolPtr vol, goto cleanup; } =20 - privvol =3D virStorageVolDefFindByName(privpool, vol->name); - - if (privvol =3D=3D NULL) { + if (!(volobj =3D virStorageVolObjFindByName(privpool, volume->name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), - vol->name); + volume->name); goto cleanup; } + voldef =3D virPoolObjGetDef(volobj); =20 if (!virStoragePoolObjIsActive(privpool)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), vol->pool); + _("storage pool '%s' is not active"), volume->pool); goto cleanup; } =20 - ret =3D virStorageVolDefFormat(privpool->def, privvol); + ret =3D virStorageVolDefFormat(privpool->def, voldef); =20 cleanup: + virPoolObjEndAPI(&volobj); if (privpool) virStoragePoolObjUnlock(privpool); return ret; } =20 static char * -testStorageVolGetPath(virStorageVolPtr vol) +testStorageVolGetPath(virStorageVolPtr volume) { - testDriverPtr privconn =3D vol->conn->privateData; + testDriverPtr privconn =3D volume->conn->privateData; virStoragePoolObjPtr privpool; - virStorageVolDefPtr privvol; + virPoolObjPtr volobj =3D NULL; + virStorageVolDefPtr voldef; char *ret =3D NULL; =20 testDriverLock(privconn); privpool =3D virStoragePoolObjFindByName(&privconn->pools, - vol->pool); + volume->pool); testDriverUnlock(privconn); =20 if (privpool =3D=3D NULL) { @@ -5291,24 +5298,24 @@ testStorageVolGetPath(virStorageVolPtr vol) goto cleanup; } =20 - privvol =3D virStorageVolDefFindByName(privpool, vol->name); - - if (privvol =3D=3D NULL) { + if (!(volobj =3D virStorageVolObjFindByName(privpool, volume->name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), - vol->name); + volume->name); goto cleanup; } + voldef =3D virPoolObjGetDef(volobj); =20 if (!virStoragePoolObjIsActive(privpool)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), vol->pool); + _("storage pool '%s' is not active"), volume->pool); goto cleanup; } =20 - ignore_value(VIR_STRDUP(ret, privvol->target.path)); + ignore_value(VIR_STRDUP(ret, voldef->target.path)); =20 cleanup: + virPoolObjEndAPI(&volobj); if (privpool) virStoragePoolObjUnlock(privpool); return ret; --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 03:40:31 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.25 as permitted sender) client-ip=209.132.183.25; envelope-from=libvir-list-bounces@redhat.com; helo=mx4-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.25 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx4-phx2.redhat.com (mx4-phx2.redhat.com [209.132.183.25]) by mx.zohomail.com with SMTPS id 1486831054443743.2779306229879; Sat, 11 Feb 2017 08:37:34 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGWNCp032086; Sat, 11 Feb 2017 11:32:23 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGTuee028566 for ; Sat, 11 Feb 2017 11:29:56 -0500 Received: from localhost.localdomain.com (ovpn-116-36.phx2.redhat.com [10.3.116.36]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGTmIs000660 for ; Sat, 11 Feb 2017 11:29:55 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Sat, 11 Feb 2017 11:29:44 -0500 Message-Id: <1486830585-23866-9-git-send-email-jferlan@redhat.com> In-Reply-To: <1486830585-23866-1-git-send-email-jferlan@redhat.com> References: <1486830585-23866-1-git-send-email-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-loop: libvir-list@redhat.com X-Mailman-Approved-At: Sat, 11 Feb 2017 11:32:22 -0500 Subject: [libvirt] [PATCH RFC 8/9] storage: Convert virStoragePoolObj[List] to use virPoolObj[Table] 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" Use the virPoolObj[Table] object management model in order to manage the StoragePool objects. While making the adjustments to use the new model, there are some code formatting adjustments that were also made with the goal to follow more recent code flow and layout. For API's that were static, rather than use "virStoragePool*", the names we= re converted to be "storagePool*" - makes it easier to determine while reading= code what is local and what is "outside" the perveyance of the module. All storage pool and volume object management API's have their own virstorageobj entry points now instead of being mashed in with storage_conf Signed-off-by: John Ferlan --- po/POTFILES.in | 1 + src/Makefile.am | 3 +- src/conf/storage_conf.c | 1062 +-------------------- src/conf/storage_conf.h | 138 +-- src/conf/virstorageobj.c | 1206 +++++++++++++++++++++++ src/conf/virstorageobj.h | 143 +++ src/libvirt_private.syms | 50 +- src/storage/storage_backend.h | 32 +- src/storage/storage_backend_disk.c | 182 ++-- src/storage/storage_backend_fs.c | 145 +-- src/storage/storage_backend_gluster.c | 37 +- src/storage/storage_backend_iscsi.c | 65 +- src/storage/storage_backend_logical.c | 127 +-- src/storage/storage_backend_mpath.c | 29 +- src/storage/storage_backend_rbd.c | 109 ++- src/storage/storage_backend_scsi.c | 57 +- src/storage/storage_backend_sheepdog.c | 90 +- src/storage/storage_backend_vstorage.c | 47 +- src/storage/storage_backend_zfs.c | 68 +- src/storage/storage_driver.c | 1645 +++++++++++++++-------------= ---- src/storage/storage_driver.h | 6 +- src/storage/storage_util.c | 228 ++--- src/storage/storage_util.h | 31 +- src/test/test_driver.c | 1022 +++++++++----------- tests/storagevolxml2argvtest.c | 16 +- 25 files changed, 3303 insertions(+), 3236 deletions(-) create mode 100644 src/conf/virstorageobj.c create mode 100644 src/conf/virstorageobj.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 0435265..a2e961f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -46,6 +46,7 @@ src/conf/virnodedeviceobj.c src/conf/virnwfilterobj.c src/conf/virpoolobj.c src/conf/virsecretobj.c +src/conf/virstorageobj.c src/cpu/cpu.c src/cpu/cpu_arm.c src/cpu/cpu_map.c diff --git a/src/Makefile.am b/src/Makefile.am index 73f3dd0..2d95020 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -380,7 +380,8 @@ POOLOBJ_SOURCES =3D \ =20 # Storage driver generic impl APIs STORAGE_CONF_SOURCES =3D \ - conf/storage_conf.h conf/storage_conf.c + conf/storage_conf.h conf/storage_conf.c \ + conf/virstorageobj.h conf/virstorageobj.c =20 # Interface driver generic impl APIs INTERFACE_CONF_SOURCES =3D \ diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 8012b6f..b24b09c 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -395,8 +394,9 @@ virStoragePoolSourceFree(virStoragePoolSourcePtr source) } =20 void -virStoragePoolDefFree(virStoragePoolDefPtr def) +virStoragePoolDefFree(void *opaque) { + virStoragePoolDefPtr def =3D opaque; if (!def) return; =20 @@ -410,56 +410,6 @@ virStoragePoolDefFree(virStoragePoolDefPtr def) } =20 =20 -void -virStoragePoolObjFree(virStoragePoolObjPtr obj) -{ - if (!obj) - return; - - virObjectUnref(obj->volumes); - - virStoragePoolDefFree(obj->def); - virStoragePoolDefFree(obj->newDef); - - VIR_FREE(obj->configFile); - VIR_FREE(obj->autostartLink); - - virMutexDestroy(&obj->lock); - - VIR_FREE(obj); -} - -void -virStoragePoolObjListFree(virStoragePoolObjListPtr pools) -{ - size_t i; - for (i =3D 0; i < pools->count; i++) - virStoragePoolObjFree(pools->objs[i]); - VIR_FREE(pools->objs); - pools->count =3D 0; -} - -void -virStoragePoolObjRemove(virStoragePoolObjListPtr pools, - virStoragePoolObjPtr pool) -{ - size_t i; - - virStoragePoolObjUnlock(pool); - - for (i =3D 0; i < pools->count; i++) { - virStoragePoolObjLock(pools->objs[i]); - if (pools->objs[i] =3D=3D pool) { - virStoragePoolObjUnlock(pools->objs[i]); - virStoragePoolObjFree(pools->objs[i]); - - VIR_DELETE_ELEMENT(pools->objs, i, pools->count); - break; - } - virStoragePoolObjUnlock(pools->objs[i]); - } -} - static int virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, virStoragePoolSourcePtr source, @@ -829,7 +779,7 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt, return ret; } =20 -static virStoragePoolDefPtr +virStoragePoolDefPtr virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) { virStoragePoolOptionsPtr options; @@ -1729,463 +1679,10 @@ virStorageVolDefFormat(virStoragePoolDefPtr pool, } =20 =20 -virStoragePoolObjPtr -virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools, - const unsigned char *uuid) -{ - size_t i; - - for (i =3D 0; i < pools->count; i++) { - virStoragePoolObjLock(pools->objs[i]); - if (!memcmp(pools->objs[i]->def->uuid, uuid, VIR_UUID_BUFLEN)) - return pools->objs[i]; - virStoragePoolObjUnlock(pools->objs[i]); - } - - return NULL; -} - -virStoragePoolObjPtr -virStoragePoolObjFindByName(virStoragePoolObjListPtr pools, - const char *name) -{ - size_t i; - - for (i =3D 0; i < pools->count; i++) { - virStoragePoolObjLock(pools->objs[i]); - if (STREQ(pools->objs[i]->def->name, name)) - return pools->objs[i]; - virStoragePoolObjUnlock(pools->objs[i]); - } - - return NULL; -} - -virStoragePoolObjPtr -virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool, - virStoragePoolDefPtr def) -{ - size_t i, j; - - for (i =3D 0; i < pool->def->source.ndevice; i++) { - for (j =3D 0; j < def->source.ndevice; j++) { - if (STREQ(pool->def->source.devices[i].path, def->source.devic= es[j].path)) - return pool; - } - } - - return NULL; -} - - -void -virStoragePoolObjClearVols(virStoragePoolObjPtr pool) -{ - virPoolObjTableClearAll(pool->volumes); -} - - -struct volSearchData { - const char *compare; -}; - -static bool -volFindByKey(virPoolObjPtr obj, - void *opaque) -{ - virStorageVolDefPtr def =3D virPoolObjGetDef(obj); - struct volSearchData *data =3D opaque; - - if (STREQ(def->key, data->compare)) - return true; - - return false; -} - - -virPoolObjPtr -virStorageVolObjFindByKey(virStoragePoolObjPtr pool, - const char *key) -{ - struct volSearchData data =3D { .compare =3D key }; - - return virPoolObjTableSearchRef(pool->volumes, volFindByKey, &data); -} - - -static bool -volFindByPath(virPoolObjPtr obj, - void *opaque) -{ - virStorageVolDefPtr def =3D virPoolObjGetDef(obj); - struct volSearchData *data =3D opaque; - - if (STREQ(def->target.path, data->compare)) - return true; - - return false; -} - - -virPoolObjPtr -virStorageVolObjFindByPath(virStoragePoolObjPtr pool, - const char *path) -{ - struct volSearchData data =3D { .compare =3D path }; - - return virPoolObjTableSearchRef(pool->volumes, volFindByPath, &data); -} - - -virPoolObjPtr -virStorageVolObjFindByName(virStoragePoolObjPtr pool, - const char *name) -{ - return virPoolObjTableFindByName(pool->volumes, name); -} - - -virStoragePoolObjPtr -virStoragePoolObjAssignDef(virStoragePoolObjListPtr pools, - virStoragePoolDefPtr def) -{ - virStoragePoolObjPtr pool; - - if ((pool =3D virStoragePoolObjFindByName(pools, def->name))) { - if (!virStoragePoolObjIsActive(pool)) { - virStoragePoolDefFree(pool->def); - pool->def =3D def; - } else { - virStoragePoolDefFree(pool->newDef); - pool->newDef =3D def; - } - return pool; - } - - if (VIR_ALLOC(pool) < 0) - return NULL; - - if (virMutexInit(&pool->lock) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("cannot initialize mutex")); - VIR_FREE(pool); - return NULL; - } - virStoragePoolObjLock(pool); - pool->active =3D 0; - - if (!(pool->volumes =3D - virPoolObjTableNew(VIR_POOLOBJTABLE_VOLUME, - VIR_POOLOBJTABLE_VOLUME_HASHSTART, true))) { - virStoragePoolObjUnlock(pool); - virStoragePoolObjFree(pool); - return NULL; - } - - if (VIR_APPEND_ELEMENT_COPY(pools->objs, pools->count, pool) < 0) { - virStoragePoolObjUnlock(pool); - virStoragePoolObjFree(pool); - return NULL; - } - pool->def =3D def; - - return pool; -} - - -virPoolObjPtr -virStoragePoolObjAddVolume(virStoragePoolObjPtr pool, - virStorageVolDefPtr voldef) -{ - return virPoolObjTableAdd(pool->volumes, NULL, voldef->name, voldef, - NULL, NULL, virStorageVolDefFree, NULL, 0); -} - - -void -virStoragePoolObjRemoveVolume(virStoragePoolObjPtr pool, - virPoolObjPtr *volobj) -{ - virPoolObjTableRemove(pool->volumes, volobj); -} - - -struct volCountData { - virConnectPtr conn; - virStoragePoolDefPtr pooldef; - virStoragePoolVolumeACLFilter aclfilter; - int count; -}; - -static int -volCount(virPoolObjPtr obj, - void *opaque) -{ - struct volCountData *data =3D opaque; - - /* Similar to virPoolObjTableListIterator */ - if (data->aclfilter && !data->aclfilter(data->conn, data->pooldef, obj= )) - return 0; - - data->count++; - return 0; -} - - -int -virStoragePoolObjNumOfVolumes(virPoolObjTablePtr volumes, - virConnectPtr conn, - virStoragePoolDefPtr pooldef, - virStoragePoolVolumeACLFilter aclfilter) -{ - struct volCountData data =3D { .conn =3D conn, - .count =3D 0, - .pooldef =3D pooldef, - .aclfilter =3D aclfilter }; - - if (virPoolObjTableList(volumes, conn, NULL, volCount, &data) < 0) - return 0; - - return data.count; -} - - -struct volListData { - virConnectPtr conn; - virStoragePoolDefPtr pooldef; - virStoragePoolVolumeACLFilter aclfilter; - int nnames; - char **const names; - int maxnames; -}; - static int -volListVolumes(virPoolObjPtr obj, - void *opaque) -{ - virStorageVolDefPtr def =3D virPoolObjGetDef(obj); - struct volListData *data =3D opaque; - - /* Similar to virPoolObjTableListIterator */ - if (data->aclfilter && !data->aclfilter(data->conn, data->pooldef, obj= )) - return 0; - - if (data->nnames < data->maxnames) { - if (VIR_STRDUP(data->names[data->nnames++], def->name) < 0) - return -1; - } - - return 0; -} - - -int -virStoragePoolObjListVolumes(virPoolObjTablePtr volumes, - virConnectPtr conn, - virStoragePoolDefPtr pooldef, - virStoragePoolVolumeACLFilter aclfilter, - char **const names, - int maxnames) -{ - struct volListData data =3D { .conn =3D conn, - .nnames =3D 0, - .pooldef =3D pooldef, - .aclfilter =3D aclfilter, - .names =3D names, - .maxnames =3D maxnames }; - - memset(names, 0, maxnames * sizeof(*names)); - - if (virPoolObjTableList(volumes, conn, NULL, volListVolumes, &data) < = 0) - goto error; - - return data.nnames; - - error: - while (--data.nnames >=3D 0) - VIR_FREE(names[data.nnames]); - return -1; -} - - -static virStoragePoolObjPtr -virStoragePoolObjLoad(virStoragePoolObjListPtr pools, - const char *file, - const char *path, - const char *autostartLink) -{ - virStoragePoolDefPtr def; - virStoragePoolObjPtr pool; - - if (!(def =3D virStoragePoolDefParseFile(path))) - return NULL; - - if (!virFileMatchesNameSuffix(file, def->name, ".xml")) { - virReportError(VIR_ERR_XML_ERROR, - _("Storage pool config filename '%s' does " - "not match pool name '%s'"), - path, def->name); - virStoragePoolDefFree(def); - return NULL; - } - - if (!(pool =3D virStoragePoolObjAssignDef(pools, def))) { - virStoragePoolDefFree(def); - return NULL; - } - - VIR_FREE(pool->configFile); /* for driver reload */ - if (VIR_STRDUP(pool->configFile, path) < 0) { - virStoragePoolObjRemove(pools, pool); - return NULL; - } - VIR_FREE(pool->autostartLink); /* for driver reload */ - if (VIR_STRDUP(pool->autostartLink, autostartLink) < 0) { - virStoragePoolObjRemove(pools, pool); - return NULL; - } - - pool->autostart =3D virFileLinkPointsTo(pool->autostartLink, - pool->configFile); - - return pool; -} - - -virStoragePoolObjPtr -virStoragePoolLoadState(virStoragePoolObjListPtr pools, - const char *stateDir, - const char *name) -{ - char *stateFile =3D NULL; - virStoragePoolDefPtr def =3D NULL; - virStoragePoolObjPtr pool =3D NULL; - xmlDocPtr xml =3D NULL; - xmlXPathContextPtr ctxt =3D NULL; - xmlNodePtr node =3D NULL; - - if (!(stateFile =3D virFileBuildPath(stateDir, name, ".xml"))) - goto error; - - if (!(xml =3D virXMLParseCtxt(stateFile, NULL, _("(pool state)"), &ctx= t))) - goto error; - - if (!(node =3D virXPathNode("//pool", ctxt))) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Could not find any 'pool' element in state file"= )); - goto error; - } - - ctxt->node =3D node; - if (!(def =3D virStoragePoolDefParseXML(ctxt))) - goto error; - - if (STRNEQ(name, def->name)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Storage pool state file '%s' does not match " - "pool name '%s'"), - stateFile, def->name); - goto error; - } - - /* create the object */ - if (!(pool =3D virStoragePoolObjAssignDef(pools, def))) - goto error; - - /* XXX: future handling of some additional useful status data, - * for now, if a status file for a pool exists, the pool will be marked - * as active - */ - - pool->active =3D 1; - - cleanup: - VIR_FREE(stateFile); - xmlFreeDoc(xml); - xmlXPathFreeContext(ctxt); - return pool; - - error: - virStoragePoolDefFree(def); - goto cleanup; -} - - -int -virStoragePoolLoadAllState(virStoragePoolObjListPtr pools, - const char *stateDir) -{ - DIR *dir; - struct dirent *entry; - int ret =3D -1; - int rc; - - if ((rc =3D virDirOpenIfExists(&dir, stateDir)) <=3D 0) - return rc; - - while ((ret =3D virDirRead(dir, &entry, stateDir)) > 0) { - virStoragePoolObjPtr pool; - - if (!virFileStripSuffix(entry->d_name, ".xml")) - continue; - - if (!(pool =3D virStoragePoolLoadState(pools, stateDir, entry->d_n= ame))) - continue; - virStoragePoolObjUnlock(pool); - } - - VIR_DIR_CLOSE(dir); - return ret; -} - - -int -virStoragePoolLoadAllConfigs(virStoragePoolObjListPtr pools, - const char *configDir, - const char *autostartDir) -{ - DIR *dir; - struct dirent *entry; - int ret; - int rc; - - if ((rc =3D virDirOpenIfExists(&dir, configDir)) <=3D 0) - return rc; - - while ((ret =3D virDirRead(dir, &entry, configDir)) > 0) { - char *path; - char *autostartLink; - virStoragePoolObjPtr pool; - - if (!virFileHasSuffix(entry->d_name, ".xml")) - continue; - - if (!(path =3D virFileBuildPath(configDir, entry->d_name, NULL))) - continue; - - if (!(autostartLink =3D virFileBuildPath(autostartDir, entry->d_na= me, - NULL))) { - VIR_FREE(path); - continue; - } - - pool =3D virStoragePoolObjLoad(pools, entry->d_name, path, - autostartLink); - if (pool) - virStoragePoolObjUnlock(pool); - - VIR_FREE(path); - VIR_FREE(autostartLink); - } - - VIR_DIR_CLOSE(dir); - return ret; -} - - -static int virStoragePoolSaveXML(const char *path, - virStoragePoolDefPtr def, - const char *xml) +virStoragePoolSaveXML(const char *path, + virStoragePoolDefPtr def, + const char *xml) { char uuidstr[VIR_UUID_STRING_BUFLEN]; int ret =3D -1; @@ -2255,52 +1752,6 @@ virStoragePoolSaveConfig(const char *configFile, return ret; } =20 -int -virStoragePoolObjSaveDef(virStorageDriverStatePtr driver, - virStoragePoolObjPtr pool, - virStoragePoolDefPtr def) -{ - if (!pool->configFile) { - if (virFileMakePath(driver->configDir) < 0) { - virReportSystemError(errno, - _("cannot create config directory %s"), - driver->configDir); - return -1; - } - - if (!(pool->configFile =3D virFileBuildPath(driver->configDir, - def->name, ".xml"))) { - return -1; - } - - if (!(pool->autostartLink =3D virFileBuildPath(driver->autostartDi= r, - def->name, ".xml"))) { - VIR_FREE(pool->configFile); - return -1; - } - } - - return virStoragePoolSaveConfig(pool->configFile, def); -} - -int -virStoragePoolObjDeleteDef(virStoragePoolObjPtr pool) -{ - if (!pool->configFile) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("no config file for %s"), pool->def->name); - return -1; - } - - if (unlink(pool->configFile) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot remove config for %s"), - pool->def->name); - return -1; - } - - return 0; -} =20 virStoragePoolSourcePtr virStoragePoolSourceListNewSource(virStoragePoolSourceListPtr list) @@ -2356,68 +1807,6 @@ virStoragePoolSourceListFormat(virStoragePoolSourceL= istPtr def) =20 =20 /* - * virStoragePoolObjIsDuplicate: - * @doms : virStoragePoolObjListPtr to search - * @def : virStoragePoolDefPtr definition of pool to lookup - * @check_active: If true, ensure that pool is not active - * - * Returns: -1 on error - * 0 if pool is new - * 1 if pool is a duplicate - */ -int -virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools, - virStoragePoolDefPtr def, - unsigned int check_active) -{ - int ret =3D -1; - virStoragePoolObjPtr pool =3D NULL; - - /* See if a Pool with matching UUID already exists */ - pool =3D virStoragePoolObjFindByUUID(pools, def->uuid); - if (pool) { - /* UUID matches, but if names don't match, refuse it */ - if (STRNEQ(pool->def->name, def->name)) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(pool->def->uuid, uuidstr); - virReportError(VIR_ERR_OPERATION_FAILED, - _("pool '%s' is already defined with uuid %s"), - pool->def->name, uuidstr); - goto cleanup; - } - - if (check_active) { - /* UUID & name match, but if Pool is already active, refuse it= */ - if (virStoragePoolObjIsActive(pool)) { - virReportError(VIR_ERR_OPERATION_INVALID, - _("pool is already active as '%s'"), - pool->def->name); - goto cleanup; - } - } - - ret =3D 1; - } else { - /* UUID does not match, but if a name matches, refuse it */ - pool =3D virStoragePoolObjFindByName(pools, def->name); - if (pool) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(pool->def->uuid, uuidstr); - virReportError(VIR_ERR_OPERATION_FAILED, - _("pool '%s' already exists with uuid %s"), - def->name, uuidstr); - goto cleanup; - } - ret =3D 0; - } - - cleanup: - if (pool) - virStoragePoolObjUnlock(pool); - return ret; -} - -/* * virStoragePoolGetVhbaSCSIHostParent: * * Using the Node Device Driver, find the host# name found via wwnn/wwpn @@ -2475,442 +1864,3 @@ virStoragePoolGetVhbaSCSIHostParent(virConnectPtr c= onn, virObjectUnref(device); return vhba_parent; } - -static int -getSCSIHostNumber(virStoragePoolSourceAdapter adapter, - unsigned int *hostnum) -{ - int ret =3D -1; - unsigned int num; - char *name =3D NULL; - - if (adapter.data.scsi_host.has_parent) { - virPCIDeviceAddress addr =3D adapter.data.scsi_host.parentaddr; - unsigned int unique_id =3D adapter.data.scsi_host.unique_id; - - if (!(name =3D virGetSCSIHostNameByParentaddr(addr.domain, - addr.bus, - addr.slot, - addr.function, - unique_id))) - goto cleanup; - if (virGetSCSIHostNumber(name, &num) < 0) - goto cleanup; - } else { - if (virGetSCSIHostNumber(adapter.data.scsi_host.name, &num) < 0) - goto cleanup; - } - - *hostnum =3D num; - ret =3D 0; - - cleanup: - VIR_FREE(name); - return ret; -} - -/* - * matchFCHostToSCSIHost: - * - * @conn: Connection pointer - * @fc_adapter: fc_host adapter (either def or pool->def) - * @scsi_hostnum: Already determined "scsi_pool" hostnum - * - * Returns true/false whether there is a match between the incoming - * fc_adapter host# and the scsi_host host# - */ -static bool -matchFCHostToSCSIHost(virConnectPtr conn, - virStoragePoolSourceAdapter fc_adapter, - unsigned int scsi_hostnum) -{ - char *name =3D NULL; - char *parent_name =3D NULL; - unsigned int fc_hostnum; - - /* If we have a parent defined, get its hostnum, and compare to the - * scsi_hostnum. If they are the same, then we have a match - */ - if (fc_adapter.data.fchost.parent && - virGetSCSIHostNumber(fc_adapter.data.fchost.parent, &fc_hostnum) = =3D=3D 0 && - scsi_hostnum =3D=3D fc_hostnum) - return true; - - /* If we find an fc_adapter name, then either libvirt created a vHBA - * for this fc_host or a 'virsh nodedev-create' generated a vHBA. - */ - if ((name =3D virGetFCHostNameByWWN(NULL, fc_adapter.data.fchost.wwnn, - fc_adapter.data.fchost.wwpn))) { - - /* Get the scsi_hostN for the vHBA in order to see if it - * matches our scsi_hostnum - */ - if (virGetSCSIHostNumber(name, &fc_hostnum) =3D=3D 0 && - scsi_hostnum =3D=3D fc_hostnum) { - VIR_FREE(name); - return true; - } - - /* We weren't provided a parent, so we have to query the node - * device driver in order to ascertain the parent of the vHBA. - * If the parent fc_hostnum is the same as the scsi_hostnum, we - * have a match. - */ - if (conn && !fc_adapter.data.fchost.parent) { - parent_name =3D virStoragePoolGetVhbaSCSIHostParent(conn, name= ); - if (parent_name) { - if (virGetSCSIHostNumber(parent_name, &fc_hostnum) =3D=3D = 0 && - scsi_hostnum =3D=3D fc_hostnum) { - VIR_FREE(parent_name); - VIR_FREE(name); - return true; - } - VIR_FREE(parent_name); - } else { - /* Throw away the error and fall through */ - virResetLastError(); - VIR_DEBUG("Could not determine parent vHBA"); - } - } - VIR_FREE(name); - } - - /* NB: Lack of a name means that this vHBA hasn't yet been created, - * which means our scsi_host cannot be using the vHBA. Furthermore, - * lack of a provided parent means libvirt is going to choose the - * "best" fc_host capable adapter based on availabilty. That could - * conflict with an existing scsi_host definition, but there's no - * way to know that now. - */ - return false; -} - -static bool -matchSCSIAdapterParent(virStoragePoolObjPtr pool, - virStoragePoolDefPtr def) -{ - virPCIDeviceAddressPtr pooladdr =3D - &pool->def->source.adapter.data.scsi_host.parentaddr; - virPCIDeviceAddressPtr defaddr =3D - &def->source.adapter.data.scsi_host.parentaddr; - int pool_unique_id =3D - pool->def->source.adapter.data.scsi_host.unique_id; - int def_unique_id =3D - def->source.adapter.data.scsi_host.unique_id; - if (pooladdr->domain =3D=3D defaddr->domain && - pooladdr->bus =3D=3D defaddr->bus && - pooladdr->slot =3D=3D defaddr->slot && - pooladdr->function =3D=3D defaddr->function && - pool_unique_id =3D=3D def_unique_id) { - return true; - } - return false; -} - -static bool -virStoragePoolSourceMatchSingleHost(virStoragePoolSourcePtr poolsrc, - virStoragePoolSourcePtr defsrc) -{ - if (poolsrc->nhost !=3D 1 && defsrc->nhost !=3D 1) - return false; - - if (defsrc->hosts[0].port && - poolsrc->hosts[0].port !=3D defsrc->hosts[0].port) - return false; - - return STREQ(poolsrc->hosts[0].name, defsrc->hosts[0].name); -} - - -static bool -virStoragePoolSourceISCSIMatch(virStoragePoolObjPtr matchpool, - virStoragePoolDefPtr def) -{ - virStoragePoolSourcePtr poolsrc =3D &matchpool->def->source; - virStoragePoolSourcePtr defsrc =3D &def->source; - - /* NB: Do not check the source host name */ - if (STRNEQ_NULLABLE(poolsrc->initiator.iqn, defsrc->initiator.iqn)) - return false; - - return true; -} - - -int -virStoragePoolSourceFindDuplicate(virConnectPtr conn, - virStoragePoolObjListPtr pools, - virStoragePoolDefPtr def) -{ - size_t i; - int ret =3D 1; - virStoragePoolObjPtr pool =3D NULL; - virStoragePoolObjPtr matchpool =3D NULL; - - /* Check the pool list for duplicate underlying storage */ - for (i =3D 0; i < pools->count; i++) { - pool =3D pools->objs[i]; - if (def->type !=3D pool->def->type) - continue; - - /* Don't match against ourself if re-defining existing pool ! */ - if (STREQ(pool->def->name, def->name)) - continue; - - virStoragePoolObjLock(pool); - - switch ((virStoragePoolType)pool->def->type) { - case VIR_STORAGE_POOL_DIR: - if (STREQ(pool->def->target.path, def->target.path)) - matchpool =3D pool; - break; - - case VIR_STORAGE_POOL_GLUSTER: - if (STREQ(pool->def->source.name, def->source.name) && - STREQ_NULLABLE(pool->def->source.dir, def->source.dir) && - virStoragePoolSourceMatchSingleHost(&pool->def->source, - &def->source)) - matchpool =3D pool; - break; - - case VIR_STORAGE_POOL_NETFS: - if (STREQ(pool->def->source.dir, def->source.dir) && - virStoragePoolSourceMatchSingleHost(&pool->def->source, - &def->source)) - matchpool =3D pool; - break; - - case VIR_STORAGE_POOL_SCSI: - if (pool->def->source.adapter.type =3D=3D - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST && - def->source.adapter.type =3D=3D - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (STREQ(pool->def->source.adapter.data.fchost.wwnn, - def->source.adapter.data.fchost.wwnn) && - STREQ(pool->def->source.adapter.data.fchost.wwpn, - def->source.adapter.data.fchost.wwpn)) - matchpool =3D pool; - } else if (pool->def->source.adapter.type =3D=3D - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST && - def->source.adapter.type =3D=3D - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - unsigned int pool_hostnum, def_hostnum; - - if (pool->def->source.adapter.data.scsi_host.has_parent && - def->source.adapter.data.scsi_host.has_parent && - matchSCSIAdapterParent(pool, def)) { - matchpool =3D pool; - break; - } - - if (getSCSIHostNumber(pool->def->source.adapter, - &pool_hostnum) < 0 || - getSCSIHostNumber(def->source.adapter, &def_hostnum) <= 0) - break; - if (pool_hostnum =3D=3D def_hostnum) - matchpool =3D pool; - } else if (pool->def->source.adapter.type =3D=3D - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST && - def->source.adapter.type =3D=3D - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - unsigned int scsi_hostnum; - - /* Get the scsi_hostN for the scsi_host source adapter def= */ - if (getSCSIHostNumber(def->source.adapter, - &scsi_hostnum) < 0) - break; - - if (matchFCHostToSCSIHost(conn, pool->def->source.adapter, - scsi_hostnum)) { - matchpool =3D pool; - break; - } - - } else if (pool->def->source.adapter.type =3D=3D - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST && - def->source.adapter.type =3D=3D - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - unsigned int scsi_hostnum; - - if (getSCSIHostNumber(pool->def->source.adapter, - &scsi_hostnum) < 0) - break; - - if (matchFCHostToSCSIHost(conn, def->source.adapter, - scsi_hostnum)) { - matchpool =3D pool; - break; - } - } - break; - case VIR_STORAGE_POOL_ISCSI: - matchpool =3D virStoragePoolSourceFindDuplicateDevices(pool, d= ef); - if (matchpool) { - if (!virStoragePoolSourceISCSIMatch(matchpool, def)) - matchpool =3D NULL; - } - break; - case VIR_STORAGE_POOL_FS: - case VIR_STORAGE_POOL_LOGICAL: - case VIR_STORAGE_POOL_DISK: - case VIR_STORAGE_POOL_ZFS: - matchpool =3D virStoragePoolSourceFindDuplicateDevices(pool, d= ef); - break; - case VIR_STORAGE_POOL_SHEEPDOG: - if (virStoragePoolSourceMatchSingleHost(&pool->def->source, - &def->source)) - matchpool =3D pool; - break; - case VIR_STORAGE_POOL_MPATH: - /* Only one mpath pool is valid per host */ - matchpool =3D pool; - break; - case VIR_STORAGE_POOL_VSTORAGE: - if (STREQ(pool->def->source.name, def->source.name)) - matchpool =3D pool; - break; - case VIR_STORAGE_POOL_RBD: - case VIR_STORAGE_POOL_LAST: - break; - } - virStoragePoolObjUnlock(pool); - - if (matchpool) - break; - } - - if (matchpool) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("Storage source conflict with pool: '%s'"), - matchpool->def->name); - ret =3D -1; - } - return ret; -} - -void -virStoragePoolObjLock(virStoragePoolObjPtr obj) -{ - virMutexLock(&obj->lock); -} - -void -virStoragePoolObjUnlock(virStoragePoolObjPtr obj) -{ - virMutexUnlock(&obj->lock); -} - -#define MATCH(FLAG) (flags & (FLAG)) -static bool -virStoragePoolMatch(virStoragePoolObjPtr poolobj, - unsigned int flags) -{ - /* filter by active state */ - if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ACTIVE) && - !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE) && - virStoragePoolObjIsActive(poolobj)) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE) && - !virStoragePoolObjIsActive(poolobj)))) - return false; - - /* filter by persistence */ - if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_PERSISTENT) && - !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_PERSISTENT) && - poolobj->configFile) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_TRANSIENT) && - !poolobj->configFile))) - return false; - - /* filter by autostart option */ - if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_AUTOSTART) && - !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_AUTOSTART) && - poolobj->autostart) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_NO_AUTOSTART) && - !poolobj->autostart))) - return false; - - /* filter by pool type */ - if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_POOL_TYPE)) { - if (!((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_DIR) && - (poolobj->def->type =3D=3D VIR_STORAGE_POOL_DIR)) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FS) && - (poolobj->def->type =3D=3D VIR_STORAGE_POOL_FS)) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_NETFS) && - (poolobj->def->type =3D=3D VIR_STORAGE_POOL_NETFS)) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_LOGICAL) && - (poolobj->def->type =3D=3D VIR_STORAGE_POOL_LOGICAL)) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_DISK) && - (poolobj->def->type =3D=3D VIR_STORAGE_POOL_DISK)) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI) && - (poolobj->def->type =3D=3D VIR_STORAGE_POOL_ISCSI)) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_SCSI) && - (poolobj->def->type =3D=3D VIR_STORAGE_POOL_SCSI)) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_MPATH) && - (poolobj->def->type =3D=3D VIR_STORAGE_POOL_MPATH)) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_RBD) && - (poolobj->def->type =3D=3D VIR_STORAGE_POOL_RBD)) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG) && - (poolobj->def->type =3D=3D VIR_STORAGE_POOL_SHEEPDOG)) || - (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER) && - (poolobj->def->type =3D=3D VIR_STORAGE_POOL_GLUSTER)))) - return false; - } - - return true; -} -#undef MATCH - -int -virStoragePoolObjListExport(virConnectPtr conn, - virStoragePoolObjList poolobjs, - virStoragePoolPtr **pools, - virStoragePoolObjListFilter filter, - unsigned int flags) -{ - virStoragePoolPtr *tmp_pools =3D NULL; - virStoragePoolPtr pool =3D NULL; - int npools =3D 0; - int ret =3D -1; - size_t i; - - if (pools && VIR_ALLOC_N(tmp_pools, poolobjs.count + 1) < 0) - goto cleanup; - - for (i =3D 0; i < poolobjs.count; i++) { - virStoragePoolObjPtr poolobj =3D poolobjs.objs[i]; - virStoragePoolObjLock(poolobj); - if ((!filter || filter(conn, poolobj->def)) && - virStoragePoolMatch(poolobj, flags)) { - if (pools) { - if (!(pool =3D virGetStoragePool(conn, - poolobj->def->name, - poolobj->def->uuid, - NULL, NULL))) { - virStoragePoolObjUnlock(poolobj); - goto cleanup; - } - tmp_pools[npools] =3D pool; - } - npools++; - } - virStoragePoolObjUnlock(poolobj); - } - - if (tmp_pools) { - /* trim the array to the final size */ - ignore_value(VIR_REALLOC_N(tmp_pools, npools + 1)); - *pools =3D tmp_pools; - tmp_pools =3D NULL; - } - - ret =3D npools; - - cleanup: - if (tmp_pools) { - for (i =3D 0; i < npools; i++) - virObjectUnref(tmp_pools[i]); - } - - VIR_FREE(tmp_pools); - return ret; -} diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index cfc8281..96bfd90 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -258,48 +258,6 @@ struct _virStoragePoolDef { virStoragePoolTarget target; }; =20 -typedef struct _virStoragePoolObj virStoragePoolObj; -typedef virStoragePoolObj *virStoragePoolObjPtr; - -struct _virStoragePoolObj { - virMutex lock; - - char *configFile; - char *autostartLink; - bool active; - int autostart; - unsigned int asyncjobs; - - virStoragePoolDefPtr def; - virStoragePoolDefPtr newDef; - - virPoolObjTablePtr volumes; -}; - -typedef struct _virStoragePoolObjList virStoragePoolObjList; -typedef virStoragePoolObjList *virStoragePoolObjListPtr; -struct _virStoragePoolObjList { - size_t count; - virStoragePoolObjPtr *objs; -}; - -typedef struct _virStorageDriverState virStorageDriverState; -typedef virStorageDriverState *virStorageDriverStatePtr; - -struct _virStorageDriverState { - virMutex lock; - - virStoragePoolObjList pools; - - char *configDir; - char *autostartDir; - char *stateDir; - bool privileged; - - /* Immutable pointer, self-locking APIs */ - virObjectEventStatePtr storageEventState; -}; - typedef struct _virStoragePoolSourceList virStoragePoolSourceList; typedef virStoragePoolSourceList *virStoragePoolSourceListPtr; struct _virStoragePoolSourceList { @@ -308,47 +266,7 @@ struct _virStoragePoolSourceList { virStoragePoolSourcePtr sources; }; =20 -typedef bool (*virStoragePoolObjListFilter)(virConnectPtr conn, void *opaq= ue); - -static inline int -virStoragePoolObjIsActive(virStoragePoolObjPtr pool) -{ - return pool->active; -} - -int virStoragePoolLoadAllConfigs(virStoragePoolObjListPtr pools, - const char *configDir, - const char *autostartDir); - -int virStoragePoolLoadAllState(virStoragePoolObjListPtr pools, - const char *stateDir); - -virStoragePoolObjPtr -virStoragePoolLoadState(virStoragePoolObjListPtr pools, - const char *stateDir, - const char *name); -virStoragePoolObjPtr -virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools, - const unsigned char *uuid); -virStoragePoolObjPtr -virStoragePoolObjFindByName(virStoragePoolObjListPtr pools, - const char *name); -virStoragePoolObjPtr -virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool, - virStoragePoolDefPtr def); - -virPoolObjPtr -virStorageVolObjFindByKey(virStoragePoolObjPtr pool, - const char *key); -virPoolObjPtr -virStorageVolObjFindByPath(virStoragePoolObjPtr pool, - const char *path); -virPoolObjPtr -virStorageVolObjFindByName(virStoragePoolObjPtr pool, - const char *name); - -void virStoragePoolObjClearVols(virStoragePoolObjPtr pool); - +virStoragePoolDefPtr virStoragePoolDefParseXML(xmlXPathContextPtr ctxt); virStoragePoolDefPtr virStoragePoolDefParseString(const char *xml); virStoragePoolDefPtr virStoragePoolDefParseFile(const char *filename); virStoragePoolDefPtr virStoragePoolDefParseNode(xmlDocPtr xml, @@ -377,49 +295,17 @@ virStorageVolDefParseNode(virStoragePoolDefPtr pool, char *virStorageVolDefFormat(virStoragePoolDefPtr pool, virStorageVolDefPtr def); =20 -virStoragePoolObjPtr -virStoragePoolObjAssignDef(virStoragePoolObjListPtr pools, - virStoragePoolDefPtr def); - -virPoolObjPtr virStoragePoolObjAddVolume(virStoragePoolObjPtr pool, - virStorageVolDefPtr voldef); - -void virStoragePoolObjRemoveVolume(virStoragePoolObjPtr pool, - virPoolObjPtr *volobj); - -typedef bool (*virStoragePoolVolumeACLFilter) - (virConnectPtr conn, virStoragePoolDefPtr pool, void *objdef); - -int virStoragePoolObjNumOfVolumes(virPoolObjTablePtr volumes, - virConnectPtr conn, - virStoragePoolDefPtr pooldef, - virStoragePoolVolumeACLFilter aclfilter); - -int virStoragePoolObjListVolumes(virPoolObjTablePtr volumes, - virConnectPtr conn, - virStoragePoolDefPtr pooldef, - virStoragePoolVolumeACLFilter aclfilter, - char **const names, - int maxnames); - int virStoragePoolSaveState(const char *stateFile, virStoragePoolDefPtr def); int virStoragePoolSaveConfig(const char *configFile, virStoragePoolDefPtr def); -int virStoragePoolObjSaveDef(virStorageDriverStatePtr driver, - virStoragePoolObjPtr pool, - virStoragePoolDefPtr def); -int virStoragePoolObjDeleteDef(virStoragePoolObjPtr pool); =20 void virStorageVolDefFree(void *opaque); void virStoragePoolSourceClear(virStoragePoolSourcePtr source); void virStoragePoolSourceDeviceClear(virStoragePoolSourceDevicePtr dev); void virStoragePoolSourceFree(virStoragePoolSourcePtr source); -void virStoragePoolDefFree(virStoragePoolDefPtr def); -void virStoragePoolObjFree(virStoragePoolObjPtr pool); -void virStoragePoolObjListFree(virStoragePoolObjListPtr pools); -void virStoragePoolObjRemove(virStoragePoolObjListPtr pools, - virStoragePoolObjPtr pool); +void virStoragePoolDefFree(void *opaque); +void virStorageObjPrivateFree(void *opaque); =20 virStoragePoolSourcePtr virStoragePoolDefParseSourceString(const char *srcSpec, @@ -428,22 +314,10 @@ virStoragePoolSourcePtr virStoragePoolSourceListNewSource(virStoragePoolSourceListPtr list); char *virStoragePoolSourceListFormat(virStoragePoolSourceListPtr def); =20 -int virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools, - virStoragePoolDefPtr def, - unsigned int check_active); - char *virStoragePoolGetVhbaSCSIHostParent(virConnectPtr conn, const char *name) ATTRIBUTE_NONNULL(1); =20 -int virStoragePoolSourceFindDuplicate(virConnectPtr conn, - virStoragePoolObjListPtr pools, - virStoragePoolDefPtr def); - -void virStoragePoolObjLock(virStoragePoolObjPtr obj); -void virStoragePoolObjUnlock(virStoragePoolObjPtr obj); - - typedef enum { VIR_STORAGE_POOL_FS_AUTO =3D 0, VIR_STORAGE_POOL_FS_EXT2, @@ -571,10 +445,4 @@ VIR_ENUM_DECL(virStoragePartedFs) VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_AUTOSTART | \ VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_POOL_TYPE) =20 -int virStoragePoolObjListExport(virConnectPtr conn, - virStoragePoolObjList poolobjs, - virStoragePoolPtr **pools, - virStoragePoolObjListFilter filter, - unsigned int flags); - #endif /* __VIR_STORAGE_CONF_H__ */ diff --git a/src/conf/virstorageobj.c b/src/conf/virstorageobj.c new file mode 100644 index 0000000..665f1a0 --- /dev/null +++ b/src/conf/virstorageobj.c @@ -0,0 +1,1206 @@ +/* + * virstorageobj.c: internal storage pool and volume objects handling + * (derived from storage_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 + * . + * + * Author: Daniel P. Berrange + */ + +#include +#include + +#include "datatypes.h" +#include "virstorageobj.h" + +#include "viralloc.h" +#include "virerror.h" +#include "virfile.h" +#include "virlog.h" +#include "virstring.h" + +#define VIR_FROM_THIS VIR_FROM_STORAGE + +VIR_LOG_INIT("conf.virstorageobj"); + +struct _virStoragePoolObjPrivate { + char *configFile; + char *autostartLink; + unsigned int asyncjobs; + + virPoolObjTablePtr volumes; +}; + + +static void +virStoragePoolObjPrivateFree(void *obj) +{ + virStoragePoolObjPrivatePtr objpriv =3D obj; + if (!objpriv) + return; + + virObjectUnref(objpriv->volumes); + + VIR_FREE(objpriv->configFile); + VIR_FREE(objpriv->autostartLink); + VIR_FREE(objpriv); +} + + +static virStoragePoolObjPrivatePtr +virStoragePoolObjPrivateAlloc(void) +{ + virStoragePoolObjPrivatePtr objpriv =3D NULL; + + if (VIR_ALLOC(objpriv) < 0) + return NULL; + + if (!(objpriv->volumes =3D + virPoolObjTableNew(VIR_POOLOBJTABLE_VOLUME, + VIR_POOLOBJTABLE_VOLUME_HASHSTART, true))) + goto error; + + return objpriv; + + error: + virStoragePoolObjPrivateFree(objpriv); + return NULL; +} + + +const char * +virStoragePoolObjPrivateGetConfigFile(virPoolObjPtr poolobj) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + + return objpriv->configFile; +} + + +const char * +virStoragePoolObjPrivateGetAutostartLink(virPoolObjPtr poolobj) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + + return objpriv->autostartLink; +} + + +int +virStoragePoolObjPrivateGetAsyncjobs(virPoolObjPtr poolobj) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + + return objpriv->asyncjobs; +} + + +void +virStoragePoolObjPrivateIncrAsyncjobs(virPoolObjPtr poolobj) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + + objpriv->asyncjobs++; +} + + +void +virStoragePoolObjPrivateDecrAsyncjobs(virPoolObjPtr poolobj) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + + objpriv->asyncjobs--; +} + + +virPoolObjTablePtr +virStoragePoolObjPrivateGetVolumes(virPoolObjPtr poolobj) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + + return objpriv->volumes; +} + + +virPoolObjPtr +virStoragePoolObjAddVolume(virPoolObjPtr poolobj, + virStorageVolDefPtr voldef) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + + return virPoolObjTableAdd(objpriv->volumes, NULL, voldef->name, + voldef, NULL, NULL, virStorageVolDefFree, + NULL, 0); +} + + +void +virStoragePoolObjRemoveVolume(virPoolObjPtr poolobj, + virPoolObjPtr *volobj) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + + virPoolObjTableRemove(objpriv->volumes, volobj); +} + + +void +virStoragePoolObjClearVols(virPoolObjPtr poolobj) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + virPoolObjTableClearAll(objpriv->volumes); +} + + +struct volCountData { + virConnectPtr conn; + virStoragePoolDefPtr pooldef; + virStoragePoolVolumeACLFilter aclfilter; + int count; +}; + +static int +volCount(virPoolObjPtr obj, + void *opaque) +{ + struct volCountData *data =3D opaque; + + /* Similar to virPoolObjTableListIterator */ + if (data->aclfilter && !data->aclfilter(data->conn, data->pooldef, obj= )) + return 0; + + data->count++; + return 0; +} + + +int +virStoragePoolObjNumOfVolumes(virPoolObjTablePtr volumes, + virConnectPtr conn, + virStoragePoolDefPtr pooldef, + virStoragePoolVolumeACLFilter aclfilter) +{ + struct volCountData data =3D { .conn =3D conn, + .count =3D 0, + .pooldef =3D pooldef, + .aclfilter =3D aclfilter }; + + if (virPoolObjTableList(volumes, conn, NULL, volCount, &data) < 0) + return 0; + + return data.count; +} + + +struct volListData { + virConnectPtr conn; + virStoragePoolDefPtr pooldef; + virStoragePoolVolumeACLFilter aclfilter; + int nnames; + char **const names; + int maxnames; +}; + +static int +volListVolumes(virPoolObjPtr obj, + void *opaque) +{ + virStorageVolDefPtr def =3D virPoolObjGetDef(obj); + struct volListData *data =3D opaque; + + /* Similar to virPoolObjTableListIterator */ + if (data->aclfilter && !data->aclfilter(data->conn, data->pooldef, obj= )) + return 0; + + if (data->nnames < data->maxnames) { + if (VIR_STRDUP(data->names[data->nnames++], def->name) < 0) + return -1; + } + + return 0; +} + + +int +virStoragePoolObjListVolumes(virPoolObjTablePtr volumes, + virConnectPtr conn, + virStoragePoolDefPtr pooldef, + virStoragePoolVolumeACLFilter aclfilter, + char **const names, + int maxnames) +{ + struct volListData data =3D { .conn =3D conn, + .nnames =3D 0, + .pooldef =3D pooldef, + .aclfilter =3D aclfilter, + .names =3D names, + .maxnames =3D maxnames }; + + memset(names, 0, maxnames * sizeof(*names)); + + if (virPoolObjTableList(volumes, conn, NULL, volListVolumes, &data) < = 0) + goto error; + + return data.nnames; + + error: + while (--data.nnames >=3D 0) + VIR_FREE(names[data.nnames]); + return -1; +} + + +/* + * virStoragePoolObjIsDuplicate: + * @pools: Pool to search + * @def: virStoragePoolDefPtr definition of pool to lookup + * @check_active: If true, ensure that pool is not active + * + * Returns: -1 on error + * 0 if pool is new + * 1 if pool is a duplicate + */ +int +virStoragePoolObjIsDuplicate(virPoolObjTablePtr pools, + virStoragePoolDefPtr def, + unsigned int check_active) +{ + int ret =3D -1; + virPoolObjPtr obj =3D NULL; + + /* See if a Pool with matching UUID already exists */ + if ((obj =3D virPoolObjTableFindByUUIDRef(pools, def->uuid))) { + virStoragePoolDefPtr objdef =3D virPoolObjGetDef(obj); + + /* UUID matches, but if names don't match, refuse it */ + if (STRNEQ(objdef->name, def->name)) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(objdef->uuid, uuidstr); + virReportError(VIR_ERR_OPERATION_FAILED, + _("pool '%s' is already defined with uuid %s"), + objdef->name, uuidstr); + goto cleanup; + } + + if (check_active) { + /* UUID & name match, but if Pool is already active, refuse it= */ + if (virPoolObjIsActive(obj)) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("pool is already active as '%s'"), + objdef->name); + goto cleanup; + } + } + + ret =3D 1; + } else { + /* UUID does not match, but if a name matches, refuse it */ + if ((obj =3D virPoolObjTableFindByName(pools, def->name))) { + virStoragePoolDefPtr objdef =3D virPoolObjGetDef(obj); + char uuidstr[VIR_UUID_STRING_BUFLEN]; + + virUUIDFormat(objdef->uuid, uuidstr); + virReportError(VIR_ERR_OPERATION_FAILED, + _("pool '%s' already exists with uuid %s"), + objdef->name, uuidstr); + goto cleanup; + } + ret =3D 0; + } + + cleanup: + virPoolObjEndAPI(&obj); + return ret; +} + + +static int +storagePoolAssignDef(virPoolObjPtr obj, + void *newDef, + void *oldDef ATTRIBUTE_UNUSED, + unsigned int assignFlags ATTRIBUTE_UNUSED) +{ + virStoragePoolDefPtr newdef =3D newDef; + + if (!virPoolObjIsActive(obj)) + virPoolObjSetDef(obj, newdef); + else + virPoolObjSetNewDef(obj, newdef); + return 0; +} + + +virPoolObjPtr +virStoragePoolObjAdd(virPoolObjTablePtr pools, + virStoragePoolDefPtr def) +{ + virPoolObjPtr obj =3D NULL; + virStoragePoolObjPrivatePtr objpriv =3D NULL; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + + virUUIDFormat(def->uuid, uuidstr); + + if (!(obj =3D virPoolObjTableAdd(pools, uuidstr, def->name, + def, NULL, NULL, virStoragePoolDefFree, + storagePoolAssignDef, 0))) + return NULL; + + if (!(objpriv =3D virPoolObjGetPrivateData(obj))) { + if (!(objpriv =3D virStoragePoolObjPrivateAlloc())) + goto error; + + virPoolObjSetPrivateData(obj, objpriv, virStoragePoolObjPrivateFre= e); + } + + return obj; + + error: + virPoolObjTableRemove(pools, &obj); + virPoolObjEndAPI(&obj); + return NULL; +} + + +static virPoolObjPtr +virStoragePoolObjLoad(virPoolObjTablePtr pools, + const char *configFile) +{ + virStoragePoolDefPtr def; + + if (!(def =3D virStoragePoolDefParseFile(configFile))) + return NULL; + + if (!virFileMatchesNameSuffix(configFile, def->name, ".xml")) { + virReportError(VIR_ERR_XML_ERROR, + _("Storage pool config filename '%s' does " + "not match pool name '%s'"), + configFile, def->name); + virStoragePoolDefFree(def); + return NULL; + } + + return virStoragePoolObjAdd(pools, def); +} + + +static virPoolObjPtr +virStoragePoolLoadState(virPoolObjTablePtr pools, + const char *stateDir, + const char *name) +{ + char *stateFile =3D NULL; + virStoragePoolDefPtr def =3D NULL; + virPoolObjPtr obj =3D NULL; + xmlDocPtr xml =3D NULL; + xmlXPathContextPtr ctxt =3D NULL; + xmlNodePtr node =3D NULL; + + if (!(stateFile =3D virFileBuildPath(stateDir, name, ".xml"))) + goto error; + + if (!(xml =3D virXMLParseCtxt(stateFile, NULL, _("(pool state)"), &ctx= t))) + goto error; + + if (!(node =3D virXPathNode("//pool", ctxt))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not find any 'pool' element in state file"= )); + goto error; + } + + ctxt->node =3D node; + if (!(def =3D virStoragePoolDefParseXML(ctxt))) + goto error; + + if (STRNEQ(name, def->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Storage pool state file '%s' does not match " + "pool name '%s'"), + stateFile, def->name); + goto error; + } + + /* create the object */ + if (!(obj =3D virStoragePoolObjAdd(pools, def))) + goto error; + + /* XXX: future handling of some additional useful status data, + * for now, if a status file for a pool exists, the pool will be marked + * as active + */ + virPoolObjSetActive(obj, true); + + cleanup: + VIR_FREE(stateFile); + xmlFreeDoc(xml); + xmlXPathFreeContext(ctxt); + return obj; + + error: + virStoragePoolDefFree(def); + goto cleanup; +} + + +int +virStoragePoolObjLoadAllState(virPoolObjTablePtr pools, + const char *stateDir) +{ + DIR *dir; + struct dirent *entry; + int ret =3D -1; + int rc; + + if ((rc =3D virDirOpenIfExists(&dir, stateDir)) <=3D 0) + return rc; + + while ((ret =3D virDirRead(dir, &entry, stateDir)) > 0) { + virPoolObjPtr obj; + + if (!virFileStripSuffix(entry->d_name, ".xml")) + continue; + + if (!(obj =3D virStoragePoolLoadState(pools, stateDir, entry->d_na= me))) + continue; + virPoolObjEndAPI(&obj); + } + + VIR_DIR_CLOSE(dir); + return ret; +} + + +int +virStoragePoolObjLoadAllConfigs(virPoolObjTablePtr pools, + const char *configDir, + const char *autostartDir) +{ + DIR *dir; + struct dirent *entry; + int ret; + int rc; + + if ((rc =3D virDirOpenIfExists(&dir, configDir)) <=3D 0) + return rc; + + while ((ret =3D virDirRead(dir, &entry, configDir)) > 0) { + char *configFile; + char *autostartLink; + virPoolObjPtr obj; + virStoragePoolObjPrivatePtr objpriv; + + if (!virFileHasSuffix(entry->d_name, ".xml")) + continue; + + if (!(configFile =3D virFileBuildPath(configDir, entry->d_name, NU= LL))) + continue; + + if (!(autostartLink =3D virFileBuildPath(autostartDir, entry->d_na= me, + NULL))) { + VIR_FREE(configFile); + continue; + } + + if (!(obj =3D virStoragePoolObjLoad(pools, configFile))) { + VIR_FREE(configFile); + VIR_FREE(autostartLink); + continue; + } + objpriv =3D virPoolObjGetPrivateData(obj); + + /* for driver reload */ + VIR_FREE(objpriv->configFile); + VIR_FREE(objpriv->autostartLink); + + VIR_STEAL_PTR(objpriv->configFile, configFile); + VIR_STEAL_PTR(objpriv->autostartLink, autostartLink); + + if (virFileLinkPointsTo(objpriv->autostartLink, objpriv->configFil= e)) + virPoolObjSetAutostart(obj, true); + else + virPoolObjSetAutostart(obj, false); + + virPoolObjEndAPI(&obj); + } + + VIR_DIR_CLOSE(dir); + return ret; +} + + +int +virStoragePoolObjSaveDef(virStorageDriverStatePtr driver, + virPoolObjPtr obj) +{ + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + if (!objpriv->configFile) { + if (virFileMakePath(driver->configDir) < 0) { + virReportSystemError(errno, + _("cannot create config directory %s"), + driver->configDir); + return -1; + } + + if (!(objpriv->configFile =3D virFileBuildPath(driver->configDir, + def->name, ".xml"))) { + return -1; + } + + if (!(objpriv->autostartLink =3D virFileBuildPath(driver->autostar= tDir, + def->name, ".xml")= )) { + VIR_FREE(objpriv->configFile); + return -1; + } + } + + return virStoragePoolSaveConfig(objpriv->configFile, def); +} + + +int +virStoragePoolObjDeleteDef(virPoolObjPtr obj) +{ + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + if (!objpriv->configFile) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("no config file for %s"), def->name); + return -1; + } + + if (unlink(objpriv->configFile) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot remove config for %s"), + def->name); + return -1; + } + + if (unlink(objpriv->autostartLink) < 0 && + errno !=3D ENOENT && errno !=3D ENOTDIR) { + char ebuf[1024]; + + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to delete autostart link '%s': %s"), + objpriv->autostartLink, + virStrerror(errno, ebuf, sizeof(ebuf))); + return -1; + } + + return 0; +} + +struct storageCountData { + bool wantActive; + int count; +}; + +static int +storageCount(virPoolObjPtr obj, + void *opaque) +{ + struct storageCountData *data =3D opaque; + + if ((data->wantActive && virPoolObjIsActive(obj)) || + (!data->wantActive && !virPoolObjIsActive(obj))) + data->count++; + + return 0; +} + + +int +virStoragePoolObjNumOfStoragePools(virPoolObjTablePtr pools, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter) +{ + struct storageCountData data =3D { .count =3D 0, + .wantActive =3D wantActive }; + + if (virPoolObjTableList(pools, conn, aclfilter, storageCount, &data) <= 0) + return 0; + + return data.count; +} + + +struct poolNameData { + bool wantActive; + int nnames; + char **const names; + int maxnames; +}; + +static int +storageGetNames(virPoolObjPtr obj ATTRIBUTE_UNUSED, + void *opaque) +{ + struct poolNameData *data =3D opaque; + + if (data->nnames < data->maxnames) { + if (data->wantActive && virPoolObjIsActive(obj)) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + + if (VIR_STRDUP(data->names[data->nnames++], def->name) < 0) + return -1; + } else if (!data->wantActive && !virPoolObjIsActive(obj)) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + + if (VIR_STRDUP(data->names[data->nnames++], def->name) < 0) + return -1; + } + } + return 0; +} + + +int +virStoragePoolObjGetNames(virPoolObjTablePtr pools, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter, + char **const names, + int maxnames) +{ + struct poolNameData data =3D { .wantActive =3D wantActive, + .nnames =3D 0, + .names =3D names, + .maxnames =3D maxnames }; + + memset(names, 0, sizeof(*names) * maxnames); + if (virPoolObjTableList(pools, conn, aclfilter, + storageGetNames, &data) < 0) + goto error; + + return data.nnames; + + error: + while (--data.nnames >=3D 0) + VIR_FREE(names[data.nnames]); + return -1; +} + + +static int +getSCSIHostNumber(virStoragePoolSourceAdapter adapter, + unsigned int *hostnum) +{ + int ret =3D -1; + unsigned int num; + char *name =3D NULL; + + if (adapter.data.scsi_host.has_parent) { + virPCIDeviceAddress addr =3D adapter.data.scsi_host.parentaddr; + unsigned int unique_id =3D adapter.data.scsi_host.unique_id; + + if (!(name =3D virGetSCSIHostNameByParentaddr(addr.domain, + addr.bus, + addr.slot, + addr.function, + unique_id))) + goto cleanup; + if (virGetSCSIHostNumber(name, &num) < 0) + goto cleanup; + } else { + if (virGetSCSIHostNumber(adapter.data.scsi_host.name, &num) < 0) + goto cleanup; + } + + *hostnum =3D num; + ret =3D 0; + + cleanup: + VIR_FREE(name); + return ret; +} + + +/* + * matchFCHostToSCSIHost: + * + * @conn: Connection pointer + * @fc_adapter: fc_host adapter (either def or pool->def) + * @scsi_hostnum: Already determined "scsi_pool" hostnum + * + * Returns true/false whether there is a match between the incoming + * fc_adapter host# and the scsi_host host# + */ +static bool +matchFCHostToSCSIHost(virConnectPtr conn, + virStoragePoolSourceAdapter fc_adapter, + unsigned int scsi_hostnum) +{ + char *name =3D NULL; + char *parent_name =3D NULL; + unsigned int fc_hostnum; + + /* If we have a parent defined, get its hostnum, and compare to the + * scsi_hostnum. If they are the same, then we have a match + */ + if (fc_adapter.data.fchost.parent && + virGetSCSIHostNumber(fc_adapter.data.fchost.parent, &fc_hostnum) = =3D=3D 0 && + scsi_hostnum =3D=3D fc_hostnum) + return true; + + /* If we find an fc_adapter name, then either libvirt created a vHBA + * for this fc_host or a 'virsh nodedev-create' generated a vHBA. + */ + if ((name =3D virGetFCHostNameByWWN(NULL, fc_adapter.data.fchost.wwnn, + fc_adapter.data.fchost.wwpn))) { + + /* Get the scsi_hostN for the vHBA in order to see if it + * matches our scsi_hostnum + */ + if (virGetSCSIHostNumber(name, &fc_hostnum) =3D=3D 0 && + scsi_hostnum =3D=3D fc_hostnum) { + VIR_FREE(name); + return true; + } + + /* We weren't provided a parent, so we have to query the node + * device driver in order to ascertain the parent of the vHBA. + * If the parent fc_hostnum is the same as the scsi_hostnum, we + * have a match. + */ + if (conn && !fc_adapter.data.fchost.parent) { + parent_name =3D virStoragePoolGetVhbaSCSIHostParent(conn, name= ); + if (parent_name) { + if (virGetSCSIHostNumber(parent_name, &fc_hostnum) =3D=3D = 0 && + scsi_hostnum =3D=3D fc_hostnum) { + VIR_FREE(parent_name); + VIR_FREE(name); + return true; + } + VIR_FREE(parent_name); + } else { + /* Throw away the error and fall through */ + virResetLastError(); + VIR_DEBUG("Could not determine parent vHBA"); + } + } + VIR_FREE(name); + } + + /* NB: Lack of a name means that this vHBA hasn't yet been created, + * which means our scsi_host cannot be using the vHBA. Furthermore, + * lack of a provided parent means libvirt is going to choose the + * "best" fc_host capable adapter based on availabilty. That could + * conflict with an existing scsi_host definition, but there's no + * way to know that now. + */ + return false; +} + + +static bool +matchSCSIAdapterParent(virPoolObjPtr obj, + virStoragePoolDefPtr def) +{ + virStoragePoolDefPtr objdef =3D virPoolObjGetDef(obj); + virPCIDeviceAddressPtr objaddr =3D + &objdef->source.adapter.data.scsi_host.parentaddr; + virPCIDeviceAddressPtr defaddr =3D + &def->source.adapter.data.scsi_host.parentaddr; + int obj_unique_id =3D + objdef->source.adapter.data.scsi_host.unique_id; + int def_unique_id =3D + def->source.adapter.data.scsi_host.unique_id; + + return (objaddr->domain =3D=3D defaddr->domain && + objaddr->bus =3D=3D defaddr->bus && + objaddr->slot =3D=3D defaddr->slot && + objaddr->function =3D=3D defaddr->function && + obj_unique_id =3D=3D def_unique_id); +} + + +static bool +virStoragePoolSourceMatchSingleHost(virStoragePoolSourcePtr poolsrc, + virStoragePoolSourcePtr defsrc) +{ + if (poolsrc->nhost !=3D 1 && defsrc->nhost !=3D 1) + return false; + + if (defsrc->hosts[0].port && + poolsrc->hosts[0].port !=3D defsrc->hosts[0].port) + return false; + + return STREQ(poolsrc->hosts[0].name, defsrc->hosts[0].name); +} + + +static bool +virStoragePoolSourceISCSIMatch(virPoolObjPtr obj, + virStoragePoolDefPtr def) +{ + virStoragePoolDefPtr pooldef =3D virPoolObjGetDef(obj); + virStoragePoolSourcePtr objsrc =3D &pooldef->source; + virStoragePoolSourcePtr defsrc =3D &def->source; + + /* NB: Do not check the source host name */ + if (STRNEQ_NULLABLE(objsrc->initiator.iqn, defsrc->initiator.iqn)) + return false; + + return true; +} + + +struct storagePoolDuplicateData { + virConnectPtr conn; + virStoragePoolDefPtr def; +}; + +static bool +storagePoolSourceFindDuplicateDevices(virPoolObjPtr obj, + virStoragePoolDefPtr def) +{ + virStoragePoolDefPtr objdef =3D virPoolObjGetDef(obj); + size_t i, j; + + for (i =3D 0; i < objdef->source.ndevice; i++) { + for (j =3D 0; j < def->source.ndevice; j++) { + if (STREQ(objdef->source.devices[i].path, + def->source.devices[j].path)) + return true; + } + } + + return false; +} + + +static bool +storagePoolSourceFindDuplicate(virPoolObjPtr obj, + void *opaque) +{ + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + struct storagePoolDuplicateData *data =3D opaque; + + /* Check the pool list for duplicate underlying storage */ + if (data->def->type !=3D def->type) + return false; + + /* Don't match against ourself if re-defining existing pool ! */ + if (STREQ(def->name, data->def->name)) + return false; + + switch ((virStoragePoolType)def->type) { + case VIR_STORAGE_POOL_DIR: + if (STREQ(def->target.path, data->def->target.path)) + return true; + break; + + case VIR_STORAGE_POOL_GLUSTER: + if (STREQ(def->source.name, data->def->source.name) && + STREQ_NULLABLE(def->source.dir, data->def->source.dir) && + virStoragePoolSourceMatchSingleHost(&def->source, + &data->def->source)) + return true; + break; + + case VIR_STORAGE_POOL_NETFS: + if (STREQ(def->source.dir, data->def->source.dir) && + virStoragePoolSourceMatchSingleHost(&def->source, + &data->def->source)) + return true; + break; + + case VIR_STORAGE_POOL_SCSI: + if (def->source.adapter.type =3D=3D + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST && + data->def->source.adapter.type =3D=3D + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (STREQ(def->source.adapter.data.fchost.wwnn, + data->def->source.adapter.data.fchost.wwnn) && + STREQ(def->source.adapter.data.fchost.wwpn, + data->def->source.adapter.data.fchost.wwpn)) + return true; + } else if (def->source.adapter.type =3D=3D + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST && + data->def->source.adapter.type =3D=3D + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + unsigned int pool_hostnum, def_hostnum; + + if (def->source.adapter.data.scsi_host.has_parent && + data->def->source.adapter.data.scsi_host.has_parent && + matchSCSIAdapterParent(obj, data->def)) + return true; + + if (getSCSIHostNumber(def->source.adapter, + &pool_hostnum) < 0 || + getSCSIHostNumber(data->def->source.adapter, &def_hostnum)= < 0) + break; + if (pool_hostnum =3D=3D def_hostnum) + return true; + } else if (def->source.adapter.type =3D=3D + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST && + data->def->source.adapter.type =3D=3D + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + unsigned int scsi_hostnum; + + /* Get the scsi_hostN for the scsi_host source adapter def */ + if (getSCSIHostNumber(data->def->source.adapter, + &scsi_hostnum) < 0) + break; + + if (matchFCHostToSCSIHost(data->conn, def->source.adapter, + scsi_hostnum)) { + return true; + } + + } else if (def->source.adapter.type =3D=3D + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST && + data->def->source.adapter.type =3D=3D + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + unsigned int scsi_hostnum; + + if (getSCSIHostNumber(def->source.adapter, + &scsi_hostnum) < 0) + break; + + if (matchFCHostToSCSIHost(data->conn, data->def->source.adapte= r, + scsi_hostnum)) + return true; + } + break; + case VIR_STORAGE_POOL_ISCSI: + if (storagePoolSourceFindDuplicateDevices(obj, data->def)) { + if (virStoragePoolSourceISCSIMatch(obj, data->def)) + return true; + } + break; + case VIR_STORAGE_POOL_FS: + case VIR_STORAGE_POOL_LOGICAL: + case VIR_STORAGE_POOL_DISK: + case VIR_STORAGE_POOL_ZFS: + if (storagePoolSourceFindDuplicateDevices(obj, data->def)) + return true; + break; + case VIR_STORAGE_POOL_SHEEPDOG: + if (virStoragePoolSourceMatchSingleHost(&def->source, + &data->def->source)) + return true; + break; + case VIR_STORAGE_POOL_MPATH: + /* Only one mpath pool is valid per host */ + return true; + break; + case VIR_STORAGE_POOL_VSTORAGE: + if (STREQ(def->source.name, def->source.name)) + return true; + break; + case VIR_STORAGE_POOL_RBD: + case VIR_STORAGE_POOL_LAST: + break; + } + + return false; +} + + +bool +virStoragePoolObjFindDuplicate(virPoolObjTablePtr pools, + virConnectPtr conn, + virStoragePoolDefPtr def) +{ + virPoolObjPtr obj; + struct storagePoolDuplicateData data =3D { .conn =3D conn, + .def =3D def }; + + if ((obj =3D virPoolObjTableSearchRef(pools, storagePoolSourceFindDupl= icate, + &data))) { + virStoragePoolDefPtr objdef =3D virPoolObjGetDef(obj); + virReportError(VIR_ERR_OPERATION_FAILED, + _("Storage source conflict with pool: '%s'"), + objdef->name); + virPoolObjEndAPI(&obj); + return true; + } + + return false; + +} + + +#define MATCH(FLAG) (flags & (FLAG)) +static bool +virStoragePoolMatch(virPoolObjPtr obj, + unsigned int flags) +{ + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + /* filter by active state */ + if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ACTIVE) && + !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE) && + virPoolObjIsActive(obj)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE) && + !virPoolObjIsActive(obj)))) + return false; + + /* filter by persistence */ + if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_PERSISTENT) && + !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_PERSISTENT) && + objpriv->configFile) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_TRANSIENT) && + !objpriv->configFile))) + return false; + + /* filter by autostart option */ + if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_AUTOSTART) && + !((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_AUTOSTART) && + virPoolObjIsAutostart(obj)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_NO_AUTOSTART) && + !virPoolObjIsAutostart(obj)))) + return false; + + /* filter by pool type */ + if (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_POOL_TYPE)) { + if (!((MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_DIR) && + (def->type =3D=3D VIR_STORAGE_POOL_DIR)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_FS) && + (def->type =3D=3D VIR_STORAGE_POOL_FS)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_NETFS) && + (def->type =3D=3D VIR_STORAGE_POOL_NETFS)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_LOGICAL) && + (def->type =3D=3D VIR_STORAGE_POOL_LOGICAL)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_DISK) && + (def->type =3D=3D VIR_STORAGE_POOL_DISK)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI) && + (def->type =3D=3D VIR_STORAGE_POOL_ISCSI)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_SCSI) && + (def->type =3D=3D VIR_STORAGE_POOL_SCSI)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_MPATH) && + (def->type =3D=3D VIR_STORAGE_POOL_MPATH)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_RBD) && + (def->type =3D=3D VIR_STORAGE_POOL_RBD)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG) && + (def->type =3D=3D VIR_STORAGE_POOL_SHEEPDOG)) || + (MATCH(VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER) && + (def->type =3D=3D VIR_STORAGE_POOL_GLUSTER)))) + return false; + } + + return true; +} +#undef MATCH + +int +virStoragePoolObjExportList(virConnectPtr conn, + virPoolObjTablePtr poolobjs, + virStoragePoolPtr **pools, + virPoolObjACLFilter aclfilter, + unsigned int flags) +{ + virPoolObjPtr *objs =3D NULL; + size_t nobjs; + virStoragePoolPtr *tmp_pools =3D NULL; + size_t i; + + if (virPoolObjTableCollect(poolobjs, conn, &objs, &nobjs, aclfilter, + virStoragePoolMatch, flags) < 0) + return -1; + + if (pools) { + if (VIR_ALLOC_N(tmp_pools, nobjs + 1) < 0) + goto cleanup; + + for (i =3D 0; i < nobjs; i++) { + virStoragePoolDefPtr def; + + virObjectLock(objs[i]); + def =3D virPoolObjGetDef(objs[i]); + tmp_pools[i] =3D virGetStoragePool(conn, def->name, def->uuid, + NULL, NULL); + virObjectUnlock(objs[i]); + if (!tmp_pools[i]) + goto cleanup; + } + + VIR_STEAL_PTR(*pools, tmp_pools); + } + + cleanup: + virObjectListFree(tmp_pools); + virObjectListFreeCount(objs, nobjs); + + return nobjs; +} + + +struct volSearchData { + const char *compare; +}; + +static bool +volFindByKey(virPoolObjPtr obj, + void *opaque) +{ + virStorageVolDefPtr def =3D virPoolObjGetDef(obj); + struct volSearchData *data =3D opaque; + + if (STREQ(def->key, data->compare)) + return true; + + return false; +} + + +virPoolObjPtr +virStorageVolObjFindByKey(virPoolObjPtr poolobj, + const char *key) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + struct volSearchData data =3D { .compare =3D key }; + + return virPoolObjTableSearchRef(objpriv->volumes, volFindByKey, &data); +} + + +static bool +volFindByPath(virPoolObjPtr obj, + void *opaque) +{ + virStorageVolDefPtr def =3D virPoolObjGetDef(obj); + struct volSearchData *data =3D opaque; + + if (STREQ(def->target.path, data->compare)) + return true; + + return false; +} + + +virPoolObjPtr +virStorageVolObjFindByPath(virPoolObjPtr poolobj, + const char *path) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + struct volSearchData data =3D { .compare =3D path }; + + return virPoolObjTableSearchRef(objpriv->volumes, volFindByPath, &data= ); +} + + +virPoolObjPtr +virStorageVolObjFindByName(virPoolObjPtr poolobj, + const char *name) +{ + virStoragePoolObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(poolo= bj); + + return virPoolObjTableFindByName(objpriv->volumes, name); +} diff --git a/src/conf/virstorageobj.h b/src/conf/virstorageobj.h new file mode 100644 index 0000000..bbdc9aa --- /dev/null +++ b/src/conf/virstorageobj.h @@ -0,0 +1,143 @@ +/* + * virstorageobj.h: internal storage pool and volume objects handling + * (derived from storage_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 __VIR_STORAGEOBJ_H__ +# define __VIR_STORAGEOBJ_H__ + +# include "internal.h" + +# include "storage_conf.h" +# include "virpoolobj.h" + +typedef struct _virStoragePoolObjPrivate virStoragePoolObjPrivate; +typedef virStoragePoolObjPrivate *virStoragePoolObjPrivatePtr; + +typedef struct _virStorageDriverState virStorageDriverState; +typedef virStorageDriverState *virStorageDriverStatePtr; + +struct _virStorageDriverState { + virMutex lock; + + virPoolObjTablePtr pools; + + char *configDir; + char *autostartDir; + char *stateDir; + bool privileged; + + /* Immutable pointer, self-locking APIs */ + virObjectEventStatePtr storageEventState; +}; + +const char *virStoragePoolObjPrivateGetConfigFile(virPoolObjPtr poolobj); + +const char *virStoragePoolObjPrivateGetAutostartLink(virPoolObjPtr poolobj= ); + +int virStoragePoolObjPrivateGetAutostart(virPoolObjPtr poolobj); + +void virStoragePoolObjPrivateSetAutostart(virPoolObjPtr poolobj, + int autostart); + +int virStoragePoolObjPrivateGetAsyncjobs(virPoolObjPtr poolobj); + +void virStoragePoolObjPrivateIncrAsyncjobs(virPoolObjPtr poolobj); + +void virStoragePoolObjPrivateDecrAsyncjobs(virPoolObjPtr poolobj); + +virPoolObjTablePtr +virStoragePoolObjPrivateGetVolumes(virPoolObjPtr poolobj); + +virPoolObjPtr +virStoragePoolObjAddVolume(virPoolObjPtr poolobj, virStorageVolDefPtr vold= ef); + +void +virStoragePoolObjRemoveVolume(virPoolObjPtr poolobj, virPoolObjPtr *volobj= ); + +void virStoragePoolObjClearVols(virPoolObjPtr pool); + +typedef bool (*virStoragePoolVolumeACLFilter) + (virConnectPtr conn, virStoragePoolDefPtr pool, void *objdef); + +int virStoragePoolObjNumOfVolumes(virPoolObjTablePtr volumes, + virConnectPtr conn, + virStoragePoolDefPtr pooldef, + virStoragePoolVolumeACLFilter aclfilter); + +int virStoragePoolObjListVolumes(virPoolObjTablePtr volumes, + virConnectPtr conn, + virStoragePoolDefPtr pooldef, + virStoragePoolVolumeACLFilter aclfilter, + char **const names, + int maxnames); + +int virStoragePoolObjIsDuplicate(virPoolObjTablePtr pools, + virStoragePoolDefPtr def, + unsigned int check_active); + +virPoolObjPtr +virStoragePoolObjAdd(virPoolObjTablePtr pools, + virStoragePoolDefPtr def); + +int virStoragePoolObjLoadAllConfigs(virPoolObjTablePtr pools, + const char *configDir, + const char *autostartDir); + +int virStoragePoolObjLoadAllState(virPoolObjTablePtr pools, + const char *stateDir); + +int virStoragePoolObjSaveDef(virStorageDriverStatePtr driver, + virPoolObjPtr obj); + +int virStoragePoolObjDeleteDef(virPoolObjPtr obj); + +int virStoragePoolObjNumOfStoragePools(virPoolObjTablePtr pools, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter); + +int virStoragePoolObjGetNames(virPoolObjTablePtr pools, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter, + char **const names, + int maxnames); + +bool virStoragePoolObjFindDuplicate(virPoolObjTablePtr pools, + virConnectPtr conn, + virStoragePoolDefPtr def); + +int virStoragePoolObjExportList(virConnectPtr conn, + virPoolObjTablePtr poolobjs, + virStoragePoolPtr **pools, + virPoolObjACLFilter aclfilter, + unsigned int flags); + +virPoolObjPtr +virStorageVolObjFindByKey(virPoolObjPtr poolobj, + const char *key); + +virPoolObjPtr +virStorageVolObjFindByPath(virPoolObjPtr poolobj, + const char *path); + +virPoolObjPtr +virStorageVolObjFindByName(virPoolObjPtr poolobj, + const char *name); + +#endif /* __VIR_STORAGEOBJ_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 14c3682..5c91988 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -860,32 +860,12 @@ virStoragePoolFormatFileSystemNetTypeToString; virStoragePoolFormatFileSystemTypeToString; virStoragePoolFormatLogicalTypeToString; virStoragePoolGetVhbaSCSIHostParent; -virStoragePoolLoadAllConfigs; -virStoragePoolLoadAllState; -virStoragePoolObjAddVolume; -virStoragePoolObjAssignDef; -virStoragePoolObjClearVols; -virStoragePoolObjDeleteDef; -virStoragePoolObjFindByName; -virStoragePoolObjFindByUUID; -virStoragePoolObjIsDuplicate; -virStoragePoolObjListExport; -virStoragePoolObjListFree; -virStoragePoolObjListVolumes; -virStoragePoolObjLock; -virStoragePoolObjNumOfVolumes; -virStoragePoolObjRemove; -virStoragePoolObjRemoveVolume; -virStoragePoolObjSaveDef; -virStoragePoolObjUnlock; virStoragePoolSaveConfig; virStoragePoolSaveState; virStoragePoolSourceAdapterTypeFromString; virStoragePoolSourceAdapterTypeToString; virStoragePoolSourceClear; virStoragePoolSourceDeviceClear; -virStoragePoolSourceFindDuplicate; -virStoragePoolSourceFindDuplicateDevices; virStoragePoolSourceFree; virStoragePoolSourceListFormat; virStoragePoolSourceListNewSource; @@ -896,9 +876,6 @@ virStorageVolDefFree; virStorageVolDefParseFile; virStorageVolDefParseNode; virStorageVolDefParseString; -virStorageVolObjFindByKey; -virStorageVolObjFindByName; -virStorageVolObjFindByPath; virStorageVolTypeFromString; virStorageVolTypeToString; =20 @@ -1013,6 +990,33 @@ virSecretObjSetValue; virSecretObjSetValueSize; =20 =20 +# conf/virstorageobj.h +virStoragePoolObjAdd; +virStoragePoolObjAddVolume; +virStoragePoolObjClearVols; +virStoragePoolObjDeleteDef; +virStoragePoolObjExportList; +virStoragePoolObjFindDuplicate; +virStoragePoolObjGetNames; +virStoragePoolObjIsDuplicate; +virStoragePoolObjListVolumes; +virStoragePoolObjLoadAllConfigs; +virStoragePoolObjLoadAllState; +virStoragePoolObjNumOfStoragePools; +virStoragePoolObjNumOfVolumes; +virStoragePoolObjPrivateDecrAsyncjobs; +virStoragePoolObjPrivateGetAsyncjobs; +virStoragePoolObjPrivateGetAutostartLink; +virStoragePoolObjPrivateGetConfigFile; +virStoragePoolObjPrivateGetVolumes; +virStoragePoolObjPrivateIncrAsyncjobs; +virStoragePoolObjRemoveVolume; +virStoragePoolObjSaveDef; +virStorageVolObjFindByKey; +virStorageVolObjFindByName; +virStorageVolObjFindByPath; + + # cpu/cpu.h cpuBaseline; cpuBaselineXML; diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h index b8fb368..e82fc31 100644 --- a/src/storage/storage_backend.h +++ b/src/storage/storage_backend.h @@ -22,25 +22,25 @@ # include =20 # include "internal.h" -# include "storage_conf.h" +# include "virstorageobj.h" # include "storage_driver.h" =20 typedef char * (*virStorageBackendFindPoolSources)(virConnectPtr conn, const char *srcSpec, unsigned int flags); -typedef int (*virStorageBackendCheckPool)(virStoragePoolObjPtr pool, +typedef int (*virStorageBackendCheckPool)(virPoolObjPtr obj, bool *active); typedef int (*virStorageBackendStartPool)(virConnectPtr conn, - virStoragePoolObjPtr pool); + virPoolObjPtr obj); typedef int (*virStorageBackendBuildPool)(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr obj, unsigned int flags); typedef int (*virStorageBackendRefreshPool)(virConnectPtr conn, - virStoragePoolObjPtr pool); + virPoolObjPtr obj); typedef int (*virStorageBackendStopPool)(virConnectPtr conn, - virStoragePoolObjPtr pool); + virPoolObjPtr obj); typedef int (*virStorageBackendDeletePool)(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr obj, unsigned int flags); =20 /* A 'buildVol' backend must remove any volume created on error since @@ -53,45 +53,45 @@ typedef int (*virStorageBackendDeletePool)(virConnectPt= r conn, * also avoids extra round trips to just delete a file. */ typedef int (*virStorageBackendBuildVol)(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags); typedef int (*virStorageBackendCreateVol)(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol); typedef int (*virStorageBackendRefreshVol)(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol); typedef int (*virStorageBackendDeleteVol)(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags); typedef int (*virStorageBackendBuildVolFrom)(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr origvol, virStorageVolDefPtr newvol, unsigned int flags); typedef int (*virStorageBackendVolumeResize)(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned long long capacity, unsigned int flags); typedef int (*virStorageBackendVolumeDownload)(virConnectPtr conn, - virStoragePoolObjPtr obj, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, virStreamPtr stream, unsigned long long offset, unsigned long long length, unsigned int flags); typedef int (*virStorageBackendVolumeUpload)(virConnectPtr conn, - virStoragePoolObjPtr obj, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, virStreamPtr stream, unsigned long long offset, unsigned long long len, unsigned int flags); typedef int (*virStorageBackendVolumeWipe)(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int algorithm, unsigned int flags); diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backe= nd_disk.c index dcf4e3e..b1ac431 100644 --- a/src/storage/storage_backend_disk.c +++ b/src/storage/storage_backend_disk.c @@ -58,10 +58,11 @@ volPartFindExtended(virPoolObjPtr volobj, =20 =20 static int -virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr pool, +virStorageBackendDiskMakeDataVol(virPoolObjPtr poolobj, char **const groups, virStorageVolDefPtr vol) { + virStoragePoolDefPtr pooldef =3D virPoolObjGetDef(poolobj); char *tmp, *devpath, *partname; =20 /* Prepended path will be same for all partitions, so we can @@ -83,7 +84,7 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr poo= l, return -1; } =20 - if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) { + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, vol))) { virStorageVolDefFree(vol); return -1; } @@ -100,7 +101,7 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr p= ool, * dir every time its run. Should figure out a more efficient * way of doing this... */ - vol->target.path =3D virStorageBackendStablePath(pool, devpath, tr= ue); + vol->target.path =3D virStorageBackendStablePath(poolobj, devpath,= true); VIR_FREE(devpath); if (vol->target.path =3D=3D NULL) return -1; @@ -122,7 +123,7 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr p= ool, * our deletion will fail because the name we generated is wrong. * Check for our conditions and see if the generated name is the * same as StablePath returns and has the 'p' in it */ - if (pool->def->source.devices[0].part_separator =3D=3D + if (pooldef->source.devices[0].part_separator =3D=3D VIR_TRISTATE_BOOL_YES && !virIsDevMapperDevice(vol->target.path) && STREQ(groups[0], vol->target.path) && @@ -166,7 +167,7 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr p= ool, } =20 if (VIR_STRDUP(vol->source.extents[0].path, - pool->def->source.devices[0].path) < 0) + pooldef->source.devices[0].path) < 0) return -1; } =20 @@ -210,9 +211,11 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr = pool, =20 /* Find the extended partition and increase the allocation value */ if (vol->source.partType =3D=3D VIR_STORAGE_VOL_DISK_TYPE_LOGICAL) { + virPoolObjTablePtr volumes =3D + virStoragePoolObjPrivateGetVolumes(poolobj); virPoolObjPtr volobj; =20 - if ((volobj =3D virPoolObjTableSearch(pool->volumes, volPartFindEx= tended, + if ((volobj =3D virPoolObjTableSearch(volumes, volPartFindExtended, NULL))) { virStorageVolDefPtr voldef =3D virPoolObjGetDef(volobj); voldef->target.allocation +=3D vol->target.allocation; @@ -221,18 +224,19 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr= pool, } =20 if (STRNEQ(groups[2], "metadata")) - pool->def->allocation +=3D vol->target.allocation; - if (vol->source.extents[0].end > pool->def->capacity) - pool->def->capacity =3D vol->source.extents[0].end; + pooldef->allocation +=3D vol->target.allocation; + if (vol->source.extents[0].end > pooldef->capacity) + pooldef->capacity =3D vol->source.extents[0].end; =20 return 0; } =20 static int -virStorageBackendDiskMakeFreeExtent(virStoragePoolObjPtr pool, +virStorageBackendDiskMakeFreeExtent(virPoolObjPtr poolobj, char **const groups) { - virStoragePoolSourceDevicePtr dev =3D &pool->def->source.devices[0]; + virStoragePoolDefPtr pooldef =3D virPoolObjGetDef(poolobj); + virStoragePoolSourceDevicePtr dev =3D &pooldef->source.devices[0]; =20 if (VIR_REALLOC_N(dev->freeExtents, dev->nfreeExtent + 1) < 0) @@ -262,11 +266,11 @@ virStorageBackendDiskMakeFreeExtent(virStoragePoolObj= Ptr pool, if (dev->freeExtents[dev->nfreeExtent].start =3D=3D 0) dev->freeExtents[dev->nfreeExtent].start =3D SECTOR_SIZE; =20 - pool->def->available +=3D + pooldef->available +=3D (dev->freeExtents[dev->nfreeExtent].end - dev->freeExtents[dev->nfreeExtent].start); - if (dev->freeExtents[dev->nfreeExtent].end > pool->def->capacity) - pool->def->capacity =3D dev->freeExtents[dev->nfreeExtent].end; + if (dev->freeExtents[dev->nfreeExtent].end > pooldef->capacity) + pooldef->capacity =3D dev->freeExtents[dev->nfreeExtent].end; =20 dev->nfreeExtent++; =20 @@ -275,7 +279,7 @@ virStorageBackendDiskMakeFreeExtent(virStoragePoolObjPt= r pool, =20 =20 struct virStorageBackendDiskPoolVolData { - virStoragePoolObjPtr pool; + virPoolObjPtr poolobj; virStorageVolDefPtr vol; }; =20 @@ -285,7 +289,7 @@ virStorageBackendDiskMakeVol(size_t ntok ATTRIBUTE_UNUS= ED, void *opaque) { struct virStorageBackendDiskPoolVolData *data =3D opaque; - virStoragePoolObjPtr pool =3D data->pool; + virPoolObjPtr poolobj =3D data->poolobj; /* * Ignore normal+metadata, and logical+metadata partitions * since they're basically internal book-keeping regions @@ -311,7 +315,7 @@ virStorageBackendDiskMakeVol(size_t ntok ATTRIBUTE_UNUS= ED, } else { virPoolObjPtr volobj; =20 - if ((volobj =3D virStorageVolObjFindByKey(pool, groups[0])= )) { + if ((volobj =3D virStorageVolObjFindByKey(poolobj, groups[= 0]))) { /* If no key, the volume must be newly created. If gro= ups[0] * isn't already a volume, assume it's the path we wan= t */ virPoolObjEndAPI(&volobj); @@ -320,10 +324,10 @@ virStorageBackendDiskMakeVol(size_t ntok ATTRIBUTE_UN= USED, } } =20 - return virStorageBackendDiskMakeDataVol(pool, groups, voldef); + return virStorageBackendDiskMakeDataVol(poolobj, groups, voldef); } else if (STREQ(groups[2], "free")) { /* ....or free space extents */ - return virStorageBackendDiskMakeFreeExtent(pool, groups); + return virStorageBackendDiskMakeFreeExtent(poolobj, groups); } else { /* This code path should never happen unless someone changed * libvirt_parthelper forgot to change this code */ @@ -342,7 +346,7 @@ virStorageBackendDiskMakeVol(size_t ntok ATTRIBUTE_UNUS= ED, * and we can even ensure the output is friendly. */ static int -virStorageBackendDiskReadPartitions(virStoragePoolObjPtr pool, +virStorageBackendDiskReadPartitions(virPoolObjPtr poolobj, virStorageVolDefPtr vol) { /* @@ -353,10 +357,11 @@ virStorageBackendDiskReadPartitions(virStoragePoolObj= Ptr pool, * */ =20 + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); char *parthelper_path; virCommandPtr cmd; struct virStorageBackendDiskPoolVolData cbdata =3D { - .pool =3D pool, + .poolobj =3D poolobj, .vol =3D vol, }; int ret; @@ -367,7 +372,7 @@ virStorageBackendDiskReadPartitions(virStoragePoolObjPt= r pool, return -1; =20 cmd =3D virCommandNewArgList(parthelper_path, - pool->def->source.devices[0].path, + def->source.devices[0].path, NULL); =20 /* Check for the presence of the part_separator=3D'yes'. Pass this @@ -376,16 +381,15 @@ virStorageBackendDiskReadPartitions(virStoragePoolObj= Ptr pool, * the generated device name for a source device which ends with * a non-numeric value (e.g. mpatha would generate mpathap#). */ - if (pool->def->source.devices[0].part_separator =3D=3D - VIR_TRISTATE_BOOL_YES) + if (def->source.devices[0].part_separator =3D=3D VIR_TRISTATE_BOOL_YES) virCommandAddArg(cmd, "-p"); =20 /* If a volume is passed, virStorageBackendDiskMakeVol only updates the * pool allocation for that single volume. */ if (!vol) - pool->def->allocation =3D 0; - pool->def->capacity =3D pool->def->available =3D 0; + def->allocation =3D 0; + def->capacity =3D def->available =3D 0; =20 ret =3D virCommandRunNul(cmd, 6, @@ -401,8 +405,10 @@ virStorageBackendDiskMakePoolGeometry(size_t ntok ATTR= IBUTE_UNUSED, char **const groups, void *data) { - virStoragePoolObjPtr pool =3D data; - virStoragePoolSourceDevicePtr device =3D &(pool->def->source.devices[0= ]); + virPoolObjPtr poolobj =3D data; + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + + virStoragePoolSourceDevicePtr device =3D &(def->source.devices[0]); if (virStrToLong_i(groups[0], NULL, 0, &device->geometry.cylinders) < = 0 || virStrToLong_i(groups[1], NULL, 0, &device->geometry.heads) < 0 || virStrToLong_i(groups[2], NULL, 0, &device->geometry.sectors) < 0)= { @@ -415,8 +421,9 @@ virStorageBackendDiskMakePoolGeometry(size_t ntok ATTRI= BUTE_UNUSED, } =20 static int -virStorageBackendDiskReadGeometry(virStoragePoolObjPtr pool) +virStorageBackendDiskReadGeometry(virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); char *parthelper_path; virCommandPtr cmd; int ret; @@ -427,14 +434,14 @@ virStorageBackendDiskReadGeometry(virStoragePoolObjPt= r pool) return -1; =20 cmd =3D virCommandNewArgList(parthelper_path, - pool->def->source.devices[0].= path, - "-g", - NULL); + def->source.devices[0].path, + "-g", + NULL); =20 ret =3D virCommandRunNul(cmd, 3, virStorageBackendDiskMakePoolGeometry, - pool); + poolobj); virCommandFree(cmd); VIR_FREE(parthelper_path); return ret; @@ -442,34 +449,37 @@ virStorageBackendDiskReadGeometry(virStoragePoolObjPt= r pool) =20 static int virStorageBackendDiskRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { - VIR_FREE(pool->def->source.devices[0].freeExtents); - pool->def->source.devices[0].nfreeExtent =3D 0; + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + + VIR_FREE(def->source.devices[0].freeExtents); + def->source.devices[0].nfreeExtent =3D 0; =20 virFileWaitForDevices(); =20 - if (!virFileExists(pool->def->source.devices[0].path)) { + if (!virFileExists(def->source.devices[0].path)) { virReportError(VIR_ERR_INVALID_ARG, _("device path '%s' doesn't exist"), - pool->def->source.devices[0].path); + def->source.devices[0].path); return -1; } =20 - if (virStorageBackendDiskReadGeometry(pool) !=3D 0) + if (virStorageBackendDiskReadGeometry(poolobj) !=3D 0) return -1; =20 - return virStorageBackendDiskReadPartitions(pool, NULL); + return virStorageBackendDiskReadPartitions(poolobj, NULL); } =20 =20 static int virStorageBackendDiskStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); const char *format =3D - virStoragePoolFormatDiskTypeToString(pool->def->source.format); - const char *path =3D pool->def->source.devices[0].path; + virStoragePoolFormatDiskTypeToString(def->source.format); + const char *path =3D def->source.devices[0].path; =20 virFileWaitForDevices(); =20 @@ -491,10 +501,11 @@ virStorageBackendDiskStartPool(virConnectPtr conn ATT= RIBUTE_UNUSED, */ static int virStorageBackendDiskBuildPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, unsigned int flags) { - int format =3D pool->def->source.format; + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + int format =3D def->source.format; const char *fmt; bool ok_to_mklabel =3D false; int ret =3D -1; @@ -511,22 +522,22 @@ virStorageBackendDiskBuildPool(virConnectPtr conn ATT= RIBUTE_UNUSED, if (flags & VIR_STORAGE_POOL_BUILD_OVERWRITE) { ok_to_mklabel =3D true; } else { - if (virStorageBackendDeviceIsEmpty(pool->def->source.devices[0].pa= th, - fmt, true)) + if (virStorageBackendDeviceIsEmpty(def->source.devices[0].path, + fmt, true)) ok_to_mklabel =3D true; } =20 if (ok_to_mklabel) { /* eg parted /dev/sda mklabel --script msdos */ if (format =3D=3D VIR_STORAGE_POOL_DISK_UNKNOWN) - format =3D pool->def->source.format =3D VIR_STORAGE_POOL_DISK_= DOS; + format =3D def->source.format =3D VIR_STORAGE_POOL_DISK_DOS; if (format =3D=3D VIR_STORAGE_POOL_DISK_DOS) fmt =3D "msdos"; else fmt =3D virStoragePoolFormatDiskTypeToString(format); =20 cmd =3D virCommandNewArgList(PARTED, - pool->def->source.devices[0].path, + def->source.devices[0].path, "mklabel", "--script", fmt, @@ -566,16 +577,19 @@ volNumOfPartTypes(virPoolObjPtr volobj, * Important when the partition table is of msdos type */ static int -virStorageBackendDiskPartTypeToCreate(virStoragePoolObjPtr pool) +virStorageBackendDiskPartTypeToCreate(virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); struct volPartListData data =3D { .count =3D 0 }; =20 - if (pool->def->source.format =3D=3D VIR_STORAGE_POOL_DISK_DOS) { + if (def->source.format =3D=3D VIR_STORAGE_POOL_DISK_DOS) { + virPoolObjTablePtr volumes =3D + virStoragePoolObjPrivateGetVolumes(poolobj); =20 /* count primary and extended partitions, * can't be more than 3 to create a new primary partition */ - if (virPoolObjTableList(pool->volumes, NULL, NULL, - volNumOfPartTypes, &data) =3D=3D 0) { + if (virPoolObjTableList(volumes, NULL, NULL, volNumOfPartTypes, + &data) =3D=3D 0) { if (data.count >=3D 4) return VIR_STORAGE_VOL_DISK_TYPE_LOGICAL; } @@ -586,13 +600,15 @@ virStorageBackendDiskPartTypeToCreate(virStoragePoolO= bjPtr pool) } =20 static int -virStorageBackendDiskPartFormat(virStoragePoolObjPtr pool, +virStorageBackendDiskPartFormat(virPoolObjPtr poolobj, virStorageVolDefPtr vol, char** partFormat) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + virPoolObjTablePtr volumes =3D virStoragePoolObjPrivateGetVolumes(pool= obj); virPoolObjPtr volobj; =20 - if (pool->def->source.format =3D=3D VIR_STORAGE_POOL_DISK_DOS) { + if (def->source.format =3D=3D VIR_STORAGE_POOL_DISK_DOS) { const char *partedFormat; partedFormat =3D virStoragePartedFsTypeToString(vol->target.format= ); if (partedFormat =3D=3D NULL) { @@ -602,8 +618,8 @@ virStorageBackendDiskPartFormat(virStoragePoolObjPtr po= ol, } if (vol->target.format =3D=3D VIR_STORAGE_VOL_DISK_EXTENDED) { /* make sure we don't have an extended partition already */ - if ((volobj =3D=3D virPoolObjTableSearch(pool->volumes, - volPartFindExtended, NULL= ))) { + if ((volobj =3D=3D virPoolObjTableSearch(volumes, volPartFindE= xtended, + NULL))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("extended partition already exists")); virPoolObjEndAPI(&volobj); @@ -617,14 +633,14 @@ virStorageBackendDiskPartFormat(virStoragePoolObjPtr = pool, and after that check if an extended partition exists to create logical partitions. */ /* XXX Only support one extended partition */ - switch (virStorageBackendDiskPartTypeToCreate(pool)) { + switch (virStorageBackendDiskPartTypeToCreate(poolobj)) { case VIR_STORAGE_VOL_DISK_TYPE_PRIMARY: if (virAsprintf(partFormat, "primary %s", partedFormat) < = 0) return -1; break; case VIR_STORAGE_VOL_DISK_TYPE_LOGICAL: /* make sure we have an extended partition */ - if ((volobj =3D=3D virPoolObjTableSearch(pool->volumes, + if ((volobj =3D=3D virPoolObjTableSearch(volumes, volPartFindExtended, NULL))) { if (virAsprintf(partFormat, "logical %s", @@ -660,23 +676,24 @@ virStorageBackendDiskPartFormat(virStoragePoolObjPtr = pool, * partitions */ static int -virStorageBackendDiskPartBoundaries(virStoragePoolObjPtr pool, +virStorageBackendDiskPartBoundaries(virPoolObjPtr poolobj, unsigned long long *start, unsigned long long *end, unsigned long long allocation) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); size_t i; int smallestExtent =3D -1; unsigned long long smallestSize =3D 0; unsigned long long extraBytes =3D 0; unsigned long long alignedAllocation =3D allocation; - virStoragePoolSourceDevicePtr dev =3D &pool->def->source.devices[0]; + virStoragePoolSourceDevicePtr dev =3D &def->source.devices[0]; unsigned long long cylinderSize =3D (unsigned long long)dev->geometry.= heads * dev->geometry.sectors * SECTOR_SIZE; =20 VIR_DEBUG("find free area: allocation %llu, cyl size %llu", allocation, cylinderSize); - int partType =3D virStorageBackendDiskPartTypeToCreate(pool); + int partType =3D virStorageBackendDiskPartTypeToCreate(poolobj); =20 /* how many extra bytes we have since we allocate aligned to the cylinder boundary */ @@ -688,7 +705,7 @@ virStorageBackendDiskPartBoundaries(virStoragePoolObjPt= r pool, dev->freeExtents[i].start; unsigned long long neededSize =3D allocation; =20 - if (pool->def->source.format =3D=3D VIR_STORAGE_POOL_DISK_DOS) { + if (def->source.format =3D=3D VIR_STORAGE_POOL_DISK_DOS) { /* align to cylinder boundary */ neededSize +=3D extraBytes; if ((*start % cylinderSize) > extraBytes) { @@ -736,7 +753,7 @@ virStorageBackendDiskPartBoundaries(virStoragePoolObjPt= r pool, } =20 *end =3D *start + alignedAllocation; - if (pool->def->source.format =3D=3D VIR_STORAGE_POOL_DISK_DOS) { + if (def->source.format =3D=3D VIR_STORAGE_POOL_DISK_DOS) { /* adjust our allocation if start is not at a cylinder boundary */ *end -=3D (*start % cylinderSize); } @@ -750,7 +767,7 @@ virStorageBackendDiskPartBoundaries(virStoragePoolObjPt= r pool, =20 /* virStorageBackendDiskDeleteVol * @conn: Pointer to a libvirt connection - * @pool: Pointer to the storage pool + * @poolobj: Pointer to the storage pool * @vol: Pointer to the volume definition * @flags: flags (unused for now) * @@ -775,14 +792,15 @@ virStorageBackendDiskPartBoundaries(virStoragePoolObj= Ptr pool, */ static int virStorageBackendDiskDeleteVol(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); char *part_num =3D NULL; char *devpath =3D NULL; char *dev_name; - char *src_path =3D pool->def->source.devices[0].path; + char *src_path =3D def->source.devices[0].path; char *srcname =3D last_component(src_path); virCommandPtr cmd =3D NULL; bool isDevMapperDevice; @@ -852,8 +870,8 @@ virStorageBackendDiskDeleteVol(virConnectPtr conn, * virStorageBackendDiskMakeDataVol and trying to redo that logic * here is pointless */ - virStoragePoolObjClearVols(pool); - if (virStorageBackendDiskRefreshPool(conn, pool) < 0) + virStoragePoolObjClearVols(poolobj); + if (virStorageBackendDiskRefreshPool(conn, poolobj) < 0) goto cleanup; =20 rc =3D 0; @@ -866,14 +884,15 @@ virStorageBackendDiskDeleteVol(virConnectPtr conn, =20 static int virStorageBackendDiskCreateVol(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int res =3D -1; char *partFormat =3D NULL; unsigned long long startOffset =3D 0, endOffset =3D 0; virCommandPtr cmd =3D virCommandNewArgList(PARTED, - pool->def->source.devices[0].= path, + def->source.devices[0].path, "mkpart", "--script", NULL); @@ -885,11 +904,11 @@ virStorageBackendDiskCreateVol(virConnectPtr conn, goto cleanup; } =20 - if (virStorageBackendDiskPartFormat(pool, vol, &partFormat) !=3D 0) + if (virStorageBackendDiskPartFormat(poolobj, vol, &partFormat) !=3D 0) goto cleanup; virCommandAddArg(cmd, partFormat); =20 - if (virStorageBackendDiskPartBoundaries(pool, &startOffset, + if (virStorageBackendDiskPartBoundaries(poolobj, &startOffset, &endOffset, vol->target.capacity) !=3D 0) { goto cleanup; @@ -905,19 +924,19 @@ virStorageBackendDiskCreateVol(virConnectPtr conn, virFileWaitForDevices(); =20 /* Blow away free extent info, as we're about to re-populate it */ - VIR_FREE(pool->def->source.devices[0].freeExtents); - pool->def->source.devices[0].nfreeExtent =3D 0; + VIR_FREE(def->source.devices[0].freeExtents); + def->source.devices[0].nfreeExtent =3D 0; =20 /* Specifying a target path is meaningless */ VIR_FREE(vol->target.path); =20 /* Fetch actual extent info, generate key */ - if (virStorageBackendDiskReadPartitions(pool, vol) < 0) { + if (virStorageBackendDiskReadPartitions(poolobj, vol) < 0) { /* Best effort to remove the partition. Ignore any errors * since we could be calling this with vol->target.path =3D=3D NULL */ virErrorPtr save_err =3D virSaveLastError(); - ignore_value(virStorageBackendDiskDeleteVol(conn, pool, vol, 0)); + ignore_value(virStorageBackendDiskDeleteVol(conn, poolobj, vol, 0)= ); virSetError(save_err); virFreeError(save_err); goto cleanup; @@ -933,7 +952,7 @@ virStorageBackendDiskCreateVol(virConnectPtr conn, =20 static int virStorageBackendDiskBuildVolFrom(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags) @@ -944,19 +963,20 @@ virStorageBackendDiskBuildVolFrom(virConnectPtr conn, if (!build_func) return -1; =20 - return build_func(conn, pool, vol, inputvol, flags); + return build_func(conn, poolobj, vol, inputvol, flags); } =20 =20 static int virStorageBackendDiskVolWipe(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int algorithm, unsigned int flags) { if (vol->source.partType !=3D VIR_STORAGE_VOL_DISK_TYPE_EXTENDED) - return virStorageBackendVolWipeLocal(conn, pool, vol, algorithm, f= lags); + return virStorageBackendVolWipeLocal(conn, poolobj, vol, + algorithm, flags); =20 /* Wiping an extended partition is not support */ virReportError(VIR_ERR_NO_SUPPORT, diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend= _fs.c index 71f605b..2a30dd9 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -38,7 +38,6 @@ #include "virerror.h" #include "storage_backend_fs.h" #include "storage_util.h" -#include "storage_conf.h" #include "virstoragefile.h" #include "vircommand.h" #include "viralloc.h" @@ -213,34 +212,36 @@ virStorageBackendFileSystemNetFindPoolSources(virConn= ectPtr conn ATTRIBUTE_UNUSE } =20 /** - * @pool storage pool to check FS types + * @poolobj: storage pool to check FS types * * Determine if storage pool FS types are properly set up * * Return 0 if everything's OK, -1 on error */ static int -virStorageBackendFileSystemIsValid(virStoragePoolObjPtr pool) +virStorageBackendFileSystemIsValid(virPoolObjPtr poolobj) { - if (pool->def->type =3D=3D VIR_STORAGE_POOL_NETFS) { - if (pool->def->source.nhost !=3D 1) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + + if (def->type =3D=3D VIR_STORAGE_POOL_NETFS) { + if (def->source.nhost !=3D 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("expected exactly 1 host for the storage pool= ")); return -1; } - if (pool->def->source.hosts[0].name =3D=3D NULL) { + if (def->source.hosts[0].name =3D=3D NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing source host")); return -1; } - if (pool->def->source.dir =3D=3D NULL) { + if (def->source.dir =3D=3D NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing source path")); return -1; } } else { - if (pool->def->source.ndevice !=3D 1) { - if (pool->def->source.ndevice =3D=3D 0) + if (def->source.ndevice !=3D 1) { + if (def->source.ndevice =3D=3D 0) virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing source device")); else @@ -256,30 +257,31 @@ virStorageBackendFileSystemIsValid(virStoragePoolObjP= tr pool) =20 /** * virStorageBackendFileSystemGetPoolSource - * @pool: storage pool object pointer + * @poolobj: storage pool object pointer * * Allocate/return a string representing the FS storage pool source. * It is up to the caller to VIR_FREE the allocated string */ static char * -virStorageBackendFileSystemGetPoolSource(virStoragePoolObjPtr pool) +virStorageBackendFileSystemGetPoolSource(virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); char *src =3D NULL; =20 - if (pool->def->type =3D=3D VIR_STORAGE_POOL_NETFS) { - if (pool->def->source.format =3D=3D VIR_STORAGE_POOL_NETFS_CIFS) { + if (def->type =3D=3D VIR_STORAGE_POOL_NETFS) { + if (def->source.format =3D=3D VIR_STORAGE_POOL_NETFS_CIFS) { if (virAsprintf(&src, "//%s/%s", - pool->def->source.hosts[0].name, - pool->def->source.dir) < 0) + def->source.hosts[0].name, + def->source.dir) < 0) return NULL; } else { if (virAsprintf(&src, "%s:%s", - pool->def->source.hosts[0].name, - pool->def->source.dir) < 0) + def->source.hosts[0].name, + def->source.dir) < 0) return NULL; } } else { - if (VIR_STRDUP(src, pool->def->source.devices[0].path) < 0) + if (VIR_STRDUP(src, def->source.devices[0].path) < 0) return NULL; } return src; @@ -287,15 +289,16 @@ virStorageBackendFileSystemGetPoolSource(virStoragePo= olObjPtr pool) =20 =20 /** - * @pool storage pool to check for status + * @poolobj: storage pool to check for status * * Determine if a storage pool is already mounted * * Return 0 if not mounted, 1 if mounted, -1 on error */ static int -virStorageBackendFileSystemIsMounted(virStoragePoolObjPtr pool) +virStorageBackendFileSystemIsMounted(virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int ret =3D -1; char *src =3D NULL; FILE *mtab; @@ -311,14 +314,13 @@ virStorageBackendFileSystemIsMounted(virStoragePoolOb= jPtr pool) } =20 while ((getmntent_r(mtab, &ent, buf, sizeof(buf))) !=3D NULL) { - if (!(src =3D virStorageBackendFileSystemGetPoolSource(pool))) + if (!(src =3D virStorageBackendFileSystemGetPoolSource(poolobj))) goto cleanup; =20 /* compare both mount destinations and sources to be sure the moun= ted * FS pool is really the one we're looking for */ - if ((rc1 =3D virFileComparePaths(ent.mnt_dir, - pool->def->target.path)) < 0 || + if ((rc1 =3D virFileComparePaths(ent.mnt_dir, def->target.path)) <= 0 || (rc2 =3D virFileComparePaths(ent.mnt_fsname, src)) < 0) goto cleanup; =20 @@ -339,7 +341,7 @@ virStorageBackendFileSystemIsMounted(virStoragePoolObjP= tr pool) } =20 /** - * @pool storage pool to mount + * @poolobj: storage pool to mount * * Ensure that a FS storage pool is mounted on its target location. * If already mounted, this is a no-op @@ -347,68 +349,69 @@ virStorageBackendFileSystemIsMounted(virStoragePoolOb= jPtr pool) * Returns 0 if successfully mounted, -1 on error */ static int -virStorageBackendFileSystemMount(virStoragePoolObjPtr pool) +virStorageBackendFileSystemMount(virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); char *src =3D NULL; /* 'mount -t auto' doesn't seem to auto determine nfs (or cifs), * while plain 'mount' does. We have to craft separate argvs to * accommodate this */ - bool netauto =3D (pool->def->type =3D=3D VIR_STORAGE_POOL_NETFS && - pool->def->source.format =3D=3D VIR_STORAGE_POOL_NETFS= _AUTO); - bool glusterfs =3D (pool->def->type =3D=3D VIR_STORAGE_POOL_NETFS && - pool->def->source.format =3D=3D VIR_STORAGE_POOL_NET= FS_GLUSTERFS); - bool cifsfs =3D (pool->def->type =3D=3D VIR_STORAGE_POOL_NETFS && - pool->def->source.format =3D=3D VIR_STORAGE_POOL_NETFS_= CIFS); + bool netauto =3D (def->type =3D=3D VIR_STORAGE_POOL_NETFS && + def->source.format =3D=3D VIR_STORAGE_POOL_NETFS_AUTO); + bool glusterfs =3D (def->type =3D=3D VIR_STORAGE_POOL_NETFS && + def->source.format =3D=3D VIR_STORAGE_POOL_NETFS_GLU= STERFS); + bool cifsfs =3D (def->type =3D=3D VIR_STORAGE_POOL_NETFS && + def->source.format =3D=3D VIR_STORAGE_POOL_NETFS_CIFS); virCommandPtr cmd =3D NULL; int ret =3D -1; int rc; =20 - if (virStorageBackendFileSystemIsValid(pool) < 0) + if (virStorageBackendFileSystemIsValid(poolobj) < 0) return -1; =20 - if ((rc =3D virStorageBackendFileSystemIsMounted(pool)) < 0) + if ((rc =3D virStorageBackendFileSystemIsMounted(poolobj)) < 0) return -1; =20 /* Short-circuit if already mounted */ if (rc =3D=3D 1) { - VIR_INFO("Target '%s' is already mounted", pool->def->target.path); + VIR_INFO("Target '%s' is already mounted", def->target.path); return 0; } =20 - if (!(src =3D virStorageBackendFileSystemGetPoolSource(pool))) + if (!(src =3D virStorageBackendFileSystemGetPoolSource(poolobj))) return -1; =20 if (netauto) cmd =3D virCommandNewArgList(MOUNT, src, - pool->def->target.path, + def->target.path, NULL); else if (glusterfs) cmd =3D virCommandNewArgList(MOUNT, "-t", - virStoragePoolFormatFileSystemNetTypeTo= String(pool->def->source.format), + virStoragePoolFormatFileSystemNetTypeTo= String(def->source.format), src, "-o", "direct-io-mode=3D1", - pool->def->target.path, + def->target.path, NULL); else if (cifsfs) cmd =3D virCommandNewArgList(MOUNT, "-t", - virStoragePoolFormatFileSystemNetTypeTo= String(pool->def->source.format), + virStoragePoolFormatFileSystemNetTypeTo= String(def->source.format), src, - pool->def->target.path, + def->target.path, "-o", "guest", NULL); else cmd =3D virCommandNewArgList(MOUNT, "-t", - (pool->def->type =3D=3D VIR_STORAGE_POO= L_FS ? - virStoragePoolFormatFileSystemTypeToSt= ring(pool->def->source.format) : - virStoragePoolFormatFileSystemNetTypeT= oString(pool->def->source.format)), + (def->type =3D=3D VIR_STORAGE_POOL_FS ? + virStoragePoolFormatFileSystemTypeToSt= ring(def->source.format) : + virStoragePoolFormatFileSystemNetTypeT= oString(def->source.format)), src, - pool->def->target.path, + def->target.path, NULL); =20 if (virCommandRun(cmd, NULL) < 0) @@ -424,7 +427,7 @@ virStorageBackendFileSystemMount(virStoragePoolObjPtr p= ool) =20 /** * @conn connection to report errors against - * @pool storage pool to start + * @poolobj: storage pool to start * * Starts a directory or FS based storage pool. The underlying source * device will be mounted for FS based pools. @@ -433,10 +436,11 @@ virStorageBackendFileSystemMount(virStoragePoolObjPtr= pool) */ static int virStorageBackendFileSystemStart(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { - if (pool->def->type !=3D VIR_STORAGE_POOL_DIR && - virStorageBackendFileSystemMount(pool) < 0) + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + if (def->type !=3D VIR_STORAGE_POOL_DIR && + virStorageBackendFileSystemMount(poolobj) < 0) return -1; =20 return 0; @@ -445,7 +449,7 @@ virStorageBackendFileSystemStart(virConnectPtr conn ATT= RIBUTE_UNUSED, =20 /** * @conn connection to report errors against - * @pool storage pool to unmount + * @poolobj: storage pool to unmount * * Stops a file storage pool. The underlying source device is unmounted * for FS based pools. Any cached data about volumes is released. @@ -457,20 +461,21 @@ virStorageBackendFileSystemStart(virConnectPtr conn A= TTRIBUTE_UNUSED, */ static int virStorageBackendFileSystemStop(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virCommandPtr cmd =3D NULL; int ret =3D -1; int rc; =20 - if (virStorageBackendFileSystemIsValid(pool) < 0) + if (virStorageBackendFileSystemIsValid(poolobj) < 0) return -1; =20 /* Short-circuit if already unmounted */ - if ((rc =3D virStorageBackendFileSystemIsMounted(pool)) !=3D 1) + if ((rc =3D virStorageBackendFileSystemIsMounted(poolobj)) !=3D 1) return rc; =20 - cmd =3D virCommandNewArgList(UMOUNT, pool->def->target.path, NULL); + cmd =3D virCommandNewArgList(UMOUNT, def->target.path, NULL); if (virCommandRun(cmd, NULL) < 0) goto cleanup; =20 @@ -483,20 +488,22 @@ virStorageBackendFileSystemStop(virConnectPtr conn AT= TRIBUTE_UNUSED, =20 =20 static int -virStorageBackendFileSystemCheck(virStoragePoolObjPtr pool, +virStorageBackendFileSystemCheck(virPoolObjPtr poolobj, bool *isActive) { - if (pool->def->type =3D=3D VIR_STORAGE_POOL_DIR) { - *isActive =3D virFileExists(pool->def->target.path); + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + + if (def->type =3D=3D VIR_STORAGE_POOL_DIR) { + *isActive =3D virFileExists(def->target.path); #if WITH_STORAGE_FS } else { int ret; *isActive =3D false; =20 - if (virStorageBackendFileSystemIsValid(pool) < 0) + if (virStorageBackendFileSystemIsValid(poolobj) < 0) return -1; =20 - if ((ret =3D virStorageBackendFileSystemIsMounted(pool)) !=3D 0) { + if ((ret =3D virStorageBackendFileSystemIsMounted(poolobj)) !=3D 0= ) { if (ret < 0) return -1; *isActive =3D true; @@ -507,6 +514,7 @@ virStorageBackendFileSystemCheck(virStoragePoolObjPtr p= ool, return 0; } =20 + /* some platforms don't support mkfs */ #ifdef MKFS static int @@ -558,28 +566,29 @@ virStorageBackendExecuteMKFS(const char *device ATTRI= BUTE_UNUSED, #endif /* #ifdef MKFS */ =20 static int -virStorageBackendMakeFileSystem(virStoragePoolObjPtr pool, +virStorageBackendMakeFileSystem(virPoolObjPtr poolobj, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); const char *device =3D NULL, *format =3D NULL; bool ok_to_mkfs =3D false; int ret =3D -1; =20 - if (pool->def->source.devices =3D=3D NULL) { + if (def->source.devices =3D=3D NULL) { virReportError(VIR_ERR_OPERATION_INVALID, _("No source device specified when formatting pool = '%s'"), - pool->def->name); + def->name); goto error; } =20 - device =3D pool->def->source.devices[0].path; - format =3D virStoragePoolFormatFileSystemTypeToString(pool->def->sourc= e.format); + device =3D def->source.devices[0].path; + format =3D virStoragePoolFormatFileSystemTypeToString(def->source.form= at); VIR_DEBUG("source device: '%s' format: '%s'", device, format); =20 if (!virFileExists(device)) { virReportError(VIR_ERR_OPERATION_INVALID, _("Source device does not exist when formatting poo= l '%s'"), - pool->def->name); + def->name); goto error; } =20 @@ -600,7 +609,7 @@ virStorageBackendMakeFileSystem(virStoragePoolObjPtr po= ol, =20 /** * @conn connection to report errors against - * @pool storage pool to build + * @poolobj: storage pool to build * @flags controls the pool formatting behaviour * * Build a directory or FS based storage pool. @@ -621,7 +630,7 @@ virStorageBackendMakeFileSystem(virStoragePoolObjPtr po= ol, */ static int virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, unsigned int flags) { virCheckFlags(VIR_STORAGE_POOL_BUILD_OVERWRITE | @@ -631,11 +640,11 @@ virStorageBackendFileSystemBuild(virConnectPtr conn A= TTRIBUTE_UNUSED, VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, -1); =20 - if (virStorageBackendBuildLocal(pool) < 0) + if (virStorageBackendBuildLocal(poolobj) < 0) return -1; =20 if (flags !=3D 0) - return virStorageBackendMakeFileSystem(pool, flags); + return virStorageBackendMakeFileSystem(poolobj, flags); =20 return 0; } diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_ba= ckend_gluster.c index aa9d7be..c797e29 100644 --- a/src/storage/storage_backend_gluster.c +++ b/src/storage/storage_backend_gluster.c @@ -24,7 +24,6 @@ #include =20 #include "storage_backend_gluster.h" -#include "storage_conf.h" #include "viralloc.h" #include "virerror.h" #include "virlog.h" @@ -71,11 +70,12 @@ virStorageBackendGlusterClose(virStorageBackendGlusterS= tatePtr state) } =20 static virStorageBackendGlusterStatePtr -virStorageBackendGlusterOpen(virStoragePoolObjPtr pool) +virStorageBackendGlusterOpen(virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virStorageBackendGlusterStatePtr ret =3D NULL; - const char *name =3D pool->def->source.name; - const char *dir =3D pool->def->source.dir; + const char *name =3D def->source.name; + const char *dir =3D def->source.dir; bool trailing_slash =3D true; =20 /* Volume name must not contain '/'; optional path allows use of a @@ -112,11 +112,11 @@ virStorageBackendGlusterOpen(virStoragePoolObjPtr poo= l) goto error; if (VIR_STRDUP(ret->uri->scheme, "gluster") < 0) goto error; - if (VIR_STRDUP(ret->uri->server, pool->def->source.hosts[0].name) < 0) + if (VIR_STRDUP(ret->uri->server, def->source.hosts[0].name) < 0) goto error; if (virAsprintf(&ret->uri->path, "/%s%s", ret->volname, ret->dir) < 0) goto error; - ret->uri->port =3D pool->def->source.hosts[0].port; + ret->uri->port =3D def->source.hosts[0].port; =20 /* Actually connect to glfs */ if (!(ret->vol =3D glfs_new(ret->volname))) { @@ -339,8 +339,9 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlu= sterStatePtr state, =20 static int virStorageBackendGlusterRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int ret =3D -1; virStorageBackendGlusterStatePtr state =3D NULL; struct { @@ -354,7 +355,7 @@ virStorageBackendGlusterRefreshPool(virConnectPtr conn = ATTRIBUTE_UNUSED, struct stat st; struct statvfs sb; =20 - if (!(state =3D virStorageBackendGlusterOpen(pool))) + if (!(state =3D virStorageBackendGlusterOpen(poolobj))) goto cleanup; =20 /* Why oh why did glfs 3.4 decide to expose only readdir_r rather @@ -388,7 +389,7 @@ virStorageBackendGlusterRefreshPool(virConnectPtr conn = ATTRIBUTE_UNUSED, if (!vol) continue; =20 - if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) { + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, vol))) { virStorageVolDefFree(vol); goto cleanup; } @@ -406,11 +407,11 @@ virStorageBackendGlusterRefreshPool(virConnectPtr con= n ATTRIBUTE_UNUSED, goto cleanup; } =20 - pool->def->capacity =3D ((unsigned long long)sb.f_frsize * - (unsigned long long)sb.f_blocks); - pool->def->available =3D ((unsigned long long)sb.f_bfree * - (unsigned long long)sb.f_frsize); - pool->def->allocation =3D pool->def->capacity - pool->def->available; + def->capacity =3D ((unsigned long long)sb.f_frsize * + (unsigned long long)sb.f_blocks); + def->available =3D ((unsigned long long)sb.f_bfree * + (unsigned long long)sb.f_frsize); + def->allocation =3D def->capacity - def->available; =20 ret =3D 0; cleanup: @@ -418,14 +419,14 @@ virStorageBackendGlusterRefreshPool(virConnectPtr con= n ATTRIBUTE_UNUSED, glfs_closedir(dir); virStorageBackendGlusterClose(state); if (ret < 0) - virStoragePoolObjClearVols(pool); + virStoragePoolObjClearVols(poolobj); return ret; } =20 =20 static int virStorageBackendGlusterVolDelete(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags) { @@ -449,7 +450,7 @@ virStorageBackendGlusterVolDelete(virConnectPtr conn AT= TRIBUTE_UNUSED, break; =20 case VIR_STORAGE_VOL_NETWORK: - if (!(state =3D virStorageBackendGlusterOpen(pool))) + if (!(state =3D virStorageBackendGlusterOpen(poolobj))) goto cleanup; =20 if (glfs_unlink(state->vol, vol->name) < 0) { @@ -463,7 +464,7 @@ virStorageBackendGlusterVolDelete(virConnectPtr conn AT= TRIBUTE_UNUSED, break; =20 case VIR_STORAGE_VOL_NETDIR: - if (!(state =3D virStorageBackendGlusterOpen(pool))) + if (!(state =3D virStorageBackendGlusterOpen(poolobj))) goto cleanup; =20 if (glfs_rmdir(state->vol, vol->target.path) < 0) { diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_back= end_iscsi.c index 2813341..32a509f 100644 --- a/src/storage/storage_backend_iscsi.c +++ b/src/storage/storage_backend_iscsi.c @@ -80,10 +80,11 @@ virStorageBackendISCSIPortal(virStoragePoolSourcePtr so= urce) =20 =20 static char * -virStorageBackendISCSISession(virStoragePoolObjPtr pool, +virStorageBackendISCSISession(virPoolObjPtr obj, bool probe) { - return virISCSIGetSession(pool->def->source.devices[0].path, probe); + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + return virISCSIGetSession(def->source.devices[0].path, probe); } =20 =20 @@ -129,7 +130,7 @@ virStorageBackendISCSIGetHostNumber(const char *sysfs_p= ath, } =20 static int -virStorageBackendISCSIFindLUs(virStoragePoolObjPtr pool, +virStorageBackendISCSIFindLUs(virPoolObjPtr obj, const char *session) { char *sysfs_path; @@ -143,7 +144,7 @@ virStorageBackendISCSIFindLUs(virStoragePoolObjPtr pool, if (virStorageBackendISCSIGetHostNumber(sysfs_path, &host) < 0) goto cleanup; =20 - if (virStorageBackendSCSIFindLUs(pool, host) < 0) + if (virStorageBackendSCSIFindLUs(obj, host) < 0) goto cleanup; =20 retval =3D 0; @@ -232,34 +233,35 @@ virStorageBackendISCSIFindPoolSources(virConnectPtr c= onn ATTRIBUTE_UNUSED, } =20 static int -virStorageBackendISCSICheckPool(virStoragePoolObjPtr pool, +virStorageBackendISCSICheckPool(virPoolObjPtr obj, bool *isActive) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); char *session =3D NULL; int ret =3D -1; =20 *isActive =3D false; =20 - if (pool->def->source.nhost !=3D 1) { + if (def->source.nhost !=3D 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Expected exactly 1 host for the storage pool")); return -1; } =20 - if (pool->def->source.hosts[0].name =3D=3D NULL) { + if (def->source.hosts[0].name =3D=3D NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing source host")); return -1; } =20 - if (pool->def->source.ndevice !=3D 1 || - pool->def->source.devices[0].path =3D=3D NULL) { + if (def->source.ndevice !=3D 1 || + def->source.devices[0].path =3D=3D NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing source device")); return -1; } =20 - if ((session =3D virStorageBackendISCSISession(pool, true)) !=3D NULL)= { + if ((session =3D virStorageBackendISCSISession(obj, true)) !=3D NULL) { *isActive =3D true; VIR_FREE(session); } @@ -325,46 +327,47 @@ virStorageBackendISCSISetAuth(const char *portal, =20 static int virStorageBackendISCSIStartPool(virConnectPtr conn, - virStoragePoolObjPtr pool) + virPoolObjPtr obj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); char *portal =3D NULL; char *session =3D NULL; int ret =3D -1; =20 - if (pool->def->source.nhost !=3D 1) { + if (def->source.nhost !=3D 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Expected exactly 1 host for the storage pool")); return -1; } =20 - if (pool->def->source.hosts[0].name =3D=3D NULL) { + if (def->source.hosts[0].name =3D=3D NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing source host")); return -1; } =20 - if (pool->def->source.ndevice !=3D 1 || - pool->def->source.devices[0].path =3D=3D NULL) { + if (def->source.ndevice !=3D 1 || + def->source.devices[0].path =3D=3D NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing source device")); return -1; } =20 - if ((session =3D virStorageBackendISCSISession(pool, true)) =3D=3D NUL= L) { - if ((portal =3D virStorageBackendISCSIPortal(&pool->def->source)) = =3D=3D NULL) + if ((session =3D virStorageBackendISCSISession(obj, true)) =3D=3D NULL= ) { + if ((portal =3D virStorageBackendISCSIPortal(&def->source)) =3D=3D= NULL) goto cleanup; =20 /* Create a static node record for the IQN target. Must be done * in order for login to the target */ - if (virISCSINodeNew(portal, pool->def->source.devices[0].path) < 0) + if (virISCSINodeNew(portal, def->source.devices[0].path) < 0) goto cleanup; =20 - if (virStorageBackendISCSISetAuth(portal, conn, &pool->def->source= ) < 0) + if (virStorageBackendISCSISetAuth(portal, conn, &def->source) < 0) goto cleanup; =20 if (virISCSIConnectionLogin(portal, - pool->def->source.initiator.iqn, - pool->def->source.devices[0].path) < 0) + def->source.initiator.iqn, + def->source.devices[0].path) < 0) goto cleanup; } ret =3D 0; @@ -377,17 +380,18 @@ virStorageBackendISCSIStartPool(virConnectPtr conn, =20 static int virStorageBackendISCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr obj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); char *session =3D NULL; =20 - pool->def->allocation =3D pool->def->capacity =3D pool->def->available= =3D 0; + def->allocation =3D def->capacity =3D def->available =3D 0; =20 - if ((session =3D virStorageBackendISCSISession(pool, false)) =3D=3D NU= LL) + if ((session =3D virStorageBackendISCSISession(obj, false)) =3D=3D NUL= L) goto cleanup; if (virISCSIRescanLUNs(session) < 0) goto cleanup; - if (virStorageBackendISCSIFindLUs(pool, session) < 0) + if (virStorageBackendISCSIFindLUs(obj, session) < 0) goto cleanup; VIR_FREE(session); =20 @@ -401,22 +405,23 @@ virStorageBackendISCSIRefreshPool(virConnectPtr conn = ATTRIBUTE_UNUSED, =20 static int virStorageBackendISCSIStopPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr obj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); char *portal; char *session; int ret =3D -1; =20 - if ((session =3D virStorageBackendISCSISession(pool, true)) =3D=3D NUL= L) + if ((session =3D virStorageBackendISCSISession(obj, true)) =3D=3D NULL) return 0; VIR_FREE(session); =20 - if ((portal =3D virStorageBackendISCSIPortal(&pool->def->source)) =3D= =3D NULL) + if ((portal =3D virStorageBackendISCSIPortal(&def->source)) =3D=3D NUL= L) return -1; =20 if (virISCSIConnectionLogout(portal, - pool->def->source.initiator.iqn, - pool->def->source.devices[0].path) < 0) + def->source.initiator.iqn, + def->source.devices[0].path) < 0) goto cleanup; ret =3D 0; =20 diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_ba= ckend_logical.c index ad66656..4e95d01 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -33,7 +33,6 @@ =20 #include "virerror.h" #include "storage_backend_logical.h" -#include "storage_conf.h" #include "vircommand.h" #include "viralloc.h" #include "virlog.h" @@ -49,14 +48,15 @@ VIR_LOG_INIT("storage.storage_backend_logical"); =20 =20 static int -virStorageBackendLogicalSetActive(virStoragePoolObjPtr pool, +virStorageBackendLogicalSetActive(virPoolObjPtr poolobj, int on) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int ret; virCommandPtr cmd =3D virCommandNewArgList(VGCHANGE, on ? "-aly" : "-aln", - pool->def->source.name, + def->source.name, NULL); =20 ret =3D virCommandRun(cmd, NULL); @@ -147,7 +147,7 @@ virStorageBackendLogicalInitializeDevice(const char *pa= th) #define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_RAID "raid" =20 struct virStorageBackendLogicalPoolVolData { - virStoragePoolObjPtr pool; + virPoolObjPtr poolobj; virStorageVolDefPtr vol; }; =20 @@ -287,7 +287,8 @@ virStorageBackendLogicalMakeVol(char **const groups, void *opaque) { struct virStorageBackendLogicalPoolVolData *data =3D opaque; - virStoragePoolObjPtr pool =3D data->pool; + virPoolObjPtr poolobj =3D data->poolobj; + virStoragePoolDefPtr pooldef =3D virPoolObjGetDef(poolobj); virPoolObjPtr volobj =3D NULL; virStorageVolDefPtr voldef =3D data->vol; bool is_new_vol =3D false; @@ -312,7 +313,7 @@ virStorageBackendLogicalMakeVol(char **const groups, =20 /* Or filling in more data on an existing volume */ if (!voldef) { - if ((volobj =3D virStorageVolObjFindByName(pool, groups[0]))) + if ((volobj =3D virStorageVolObjFindByName(poolobj, groups[0]))) voldef =3D virPoolObjGetDef(volobj); } =20 @@ -330,7 +331,7 @@ virStorageBackendLogicalMakeVol(char **const groups, =20 if (!voldef->target.path) { if (virAsprintf(&voldef->target.path, "%s/%s", - pool->def->target.path, voldef->name) < 0) + pooldef->target.path, voldef->name) < 0) goto cleanup; } =20 @@ -355,7 +356,7 @@ virStorageBackendLogicalMakeVol(char **const groups, goto cleanup; =20 if (virAsprintf(&voldef->target.backingStore->path, "%s/%s", - pool->def->target.path, groups[1]) < 0) + pooldef->target.path, groups[1]) < 0) goto cleanup; =20 voldef->target.backingStore->format =3D VIR_STORAGE_POOL_LOGICAL_L= VM2; @@ -378,10 +379,9 @@ virStorageBackendLogicalMakeVol(char **const groups, goto cleanup; =20 if (is_new_vol) { - if (!(volobj =3D virStoragePoolObjAddVolume(pool, voldef))) + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, voldef))) goto cleanup; voldef =3D NULL; - virPoolObjEndAPI(&volobj); } =20 ret =3D 0; @@ -389,6 +389,7 @@ virStorageBackendLogicalMakeVol(char **const groups, cleanup: if (is_new_vol) virStorageVolDefFree(voldef); + virPoolObjEndAPI(&volobj); return ret; } =20 @@ -421,7 +422,7 @@ virStorageBackendLogicalMakeVol(char **const groups, VIR_STORAGE_VOL_LOGICAL_SUFFIX_REGEX =20 static int -virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool, +virStorageBackendLogicalFindLVs(virPoolObjPtr poolobj, virStorageVolDefPtr vol) { /* @@ -457,8 +458,9 @@ virStorageBackendLogicalFindLVs(virStoragePoolObjPtr po= ol, }; int ret =3D -1; virCommandPtr cmd; + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); struct virStorageBackendLogicalPoolVolData cbdata =3D { - .pool =3D pool, + .poolobj =3D poolobj, .vol =3D vol, }; =20 @@ -470,7 +472,7 @@ virStorageBackendLogicalFindLVs(virStoragePoolObjPtr po= ol, "--nosuffix", "--options", "lv_name,origin,uuid,devices,segtype,stripe= s,seg_size,vg_extent_size,size,lv_attr", - pool->def->source.name, + def->source.name, NULL); if (virCommandRunRegex(cmd, 1, @@ -492,12 +494,14 @@ static int virStorageBackendLogicalRefreshPoolFunc(char **const groups, void *data) { - virStoragePoolObjPtr pool =3D data; - if (virStrToLong_ull(groups[0], NULL, 10, &pool->def->capacity) < 0) + virPoolObjPtr poolobj =3D data; + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + + if (virStrToLong_ull(groups[0], NULL, 10, &def->capacity) < 0) return -1; - if (virStrToLong_ull(groups[1], NULL, 10, &pool->def->available) < 0) + if (virStrToLong_ull(groups[1], NULL, 10, &def->available) < 0) return -1; - pool->def->allocation =3D pool->def->capacity - pool->def->available; + def->allocation =3D def->capacity - def->available; =20 return 0; } @@ -640,7 +644,7 @@ virStorageBackendLogicalFindPoolSources(virConnectPtr c= onn ATTRIBUTE_UNUSED, =20 /* * virStorageBackendLogicalMatchPoolSource - * @pool: Pointer to the source pool object + * @poolobj: Pointer to the source pool object * * Search the output generated by a 'pvs --noheadings -o pv_name,vg_name' * to match the 'vg_name' with the pool def->source.name and for the list @@ -653,8 +657,9 @@ virStorageBackendLogicalFindPoolSources(virConnectPtr c= onn ATTRIBUTE_UNUSED, * the any device list members. */ static bool -virStorageBackendLogicalMatchPoolSource(virStoragePoolObjPtr pool) +virStorageBackendLogicalMatchPoolSource(virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virStoragePoolSourceList sourceList; virStoragePoolSource *thisSource =3D NULL; size_t i, j; @@ -670,14 +675,14 @@ virStorageBackendLogicalMatchPoolSource(virStoragePoo= lObjPtr pool) /* Search the pvs output for this pool's source.name */ for (i =3D 0; i < sourceList.nsources; i++) { thisSource =3D &sourceList.sources[i]; - if (STREQ(thisSource->name, pool->def->source.name)) + if (STREQ(thisSource->name, def->source.name)) break; } =20 if (i =3D=3D sourceList.nsources) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("cannot find logical volume group name '%s'"), - pool->def->source.name); + def->source.name); goto cleanup; } =20 @@ -685,7 +690,7 @@ virStorageBackendLogicalMatchPoolSource(virStoragePoolO= bjPtr pool) * they match as well; otherwise, matching can only occur on the * pool's name. */ - if (!pool->def->source.ndevice) { + if (!def->source.ndevice) { ret =3D true; goto cleanup; } @@ -693,9 +698,9 @@ virStorageBackendLogicalMatchPoolSource(virStoragePoolO= bjPtr pool) /* Let's make sure the pool's device(s) match what the pvs output has * for volume group devices. */ - for (i =3D 0; i < pool->def->source.ndevice; i++) { + for (i =3D 0; i < def->source.ndevice; i++) { for (j =3D 0; j < thisSource->ndevice; j++) { - if (STREQ(pool->def->source.devices[i].path, + if (STREQ(def->source.devices[i].path, thisSource->devices[j].path)) matchcount++; } @@ -707,7 +712,7 @@ virStorageBackendLogicalMatchPoolSource(virStoragePoolO= bjPtr pool) if (matchcount =3D=3D 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("cannot find any matching source devices for logi= cal " - "volume group '%s'"), pool->def->source.name); + "volume group '%s'"), def->source.name); goto cleanup; } =20 @@ -716,7 +721,7 @@ virStorageBackendLogicalMatchPoolSource(virStoragePoolO= bjPtr pool) * to 'add' to or 'remove' from the volume group outside of libvirt's * knowledge. Rather than fail on that, provide a warning and move on. */ - if (matchcount !=3D pool->def->source.ndevice) + if (matchcount !=3D def->source.ndevice) VIR_WARN("pool device list count doesn't match pvs device list cou= nt"); =20 ret =3D true; @@ -731,26 +736,27 @@ virStorageBackendLogicalMatchPoolSource(virStoragePoo= lObjPtr pool) =20 =20 static int -virStorageBackendLogicalCheckPool(virStoragePoolObjPtr pool, +virStorageBackendLogicalCheckPool(virPoolObjPtr poolobj, bool *isActive) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); /* If we can find the target.path as well as ensure that the * pool's def source */ - *isActive =3D virFileExists(pool->def->target.path) && - virStorageBackendLogicalMatchPoolSource(pool); + *isActive =3D virFileExists(def->target.path) && + virStorageBackendLogicalMatchPoolSource(poolobj); return 0; } =20 static int virStorageBackendLogicalStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { /* Let's make sure that the pool's name matches the pvs output and * that the pool's source devices match the pvs output. */ - if (!virStorageBackendLogicalMatchPoolSource(pool) || - virStorageBackendLogicalSetActive(pool, 1) < 0) + if (!virStorageBackendLogicalMatchPoolSource(poolobj) || + virStorageBackendLogicalSetActive(poolobj, 1) < 0) return -1; =20 return 0; @@ -759,9 +765,10 @@ virStorageBackendLogicalStartPool(virConnectPtr conn A= TTRIBUTE_UNUSED, =20 static int virStorageBackendLogicalBuildPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virCommandPtr vgcmd =3D NULL; int ret =3D -1; size_t i =3D 0; @@ -773,10 +780,10 @@ virStorageBackendLogicalBuildPool(virConnectPtr conn = ATTRIBUTE_UNUSED, VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, cleanup); =20 - vgcmd =3D virCommandNewArgList(VGCREATE, pool->def->source.name, NULL); + vgcmd =3D virCommandNewArgList(VGCREATE, def->source.name, NULL); =20 - for (i =3D 0; i < pool->def->source.ndevice; i++) { - const char *path =3D pool->def->source.devices[i].path; + for (i =3D 0; i < def->source.ndevice; i++) { + const char *path =3D def->source.devices[i].path; =20 /* The blkid FS and Part probing code doesn't know "lvm2" (this * pool's only format type), but it does know "LVM2_member", so @@ -806,7 +813,7 @@ virStorageBackendLogicalBuildPool(virConnectPtr conn AT= TRIBUTE_UNUSED, if (ret < 0) { size_t j; for (j =3D 0; j < i; j++) - virStorageBackendLogicalRemoveDevice(pool->def->source.devices= [j].path); + virStorageBackendLogicalRemoveDevice(def->source.devices[j].pa= th); } return ret; } @@ -814,7 +821,7 @@ virStorageBackendLogicalBuildPool(virConnectPtr conn AT= TRIBUTE_UNUSED, =20 static int virStorageBackendLogicalRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { /* * # vgs --separator : --noheadings --units b --unbuffered --nosuffix= --options "vg_size,vg_free" VGNAME @@ -830,13 +837,14 @@ virStorageBackendLogicalRefreshPool(virConnectPtr con= n ATTRIBUTE_UNUSED, int vars[] =3D { 2 }; + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virCommandPtr cmd =3D NULL; int ret =3D -1; =20 virFileWaitForDevices(); =20 /* Get list of all logical volumes */ - if (virStorageBackendLogicalFindLVs(pool, NULL) < 0) + if (virStorageBackendLogicalFindLVs(poolobj, NULL) < 0) goto cleanup; =20 cmd =3D virCommandNewArgList(VGS, @@ -846,7 +854,7 @@ virStorageBackendLogicalRefreshPool(virConnectPtr conn = ATTRIBUTE_UNUSED, "--unbuffered", "--nosuffix", "--options", "vg_size,vg_free", - pool->def->source.name, + def->source.name, NULL); =20 /* Now get basic volgrp metadata */ @@ -855,7 +863,7 @@ virStorageBackendLogicalRefreshPool(virConnectPtr conn = ATTRIBUTE_UNUSED, regexes, vars, virStorageBackendLogicalRefreshPoolFunc, - pool, + poolobj, "vgs", NULL) < 0) goto cleanup; @@ -865,7 +873,7 @@ virStorageBackendLogicalRefreshPool(virConnectPtr conn = ATTRIBUTE_UNUSED, cleanup: virCommandFree(cmd); if (ret < 0) - virStoragePoolObjClearVols(pool); + virStoragePoolObjClearVols(poolobj); return ret; } =20 @@ -876,9 +884,9 @@ virStorageBackendLogicalRefreshPool(virConnectPtr conn = ATTRIBUTE_UNUSED, */ static int virStorageBackendLogicalStopPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { - if (virStorageBackendLogicalSetActive(pool, 0) < 0) + if (virStorageBackendLogicalSetActive(poolobj, 0) < 0) return -1; =20 return 0; @@ -886,9 +894,10 @@ virStorageBackendLogicalStopPool(virConnectPtr conn AT= TRIBUTE_UNUSED, =20 static int virStorageBackendLogicalDeletePool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virCommandPtr cmd =3D NULL; size_t i; int ret =3D -1; @@ -897,14 +906,14 @@ virStorageBackendLogicalDeletePool(virConnectPtr conn= ATTRIBUTE_UNUSED, =20 /* first remove the volume group */ cmd =3D virCommandNewArgList(VGREMOVE, - "-f", pool->def->source.name, + "-f", def->source.name, NULL); if (virCommandRun(cmd, NULL) < 0) goto cleanup; =20 /* now remove the pv devices and clear them out */ - for (i =3D 0; i < pool->def->source.ndevice; i++) - virStorageBackendLogicalRemoveDevice(pool->def->source.devices[i].= path); + for (i =3D 0; i < def->source.ndevice; i++) + virStorageBackendLogicalRemoveDevice(def->source.devices[i].path); =20 ret =3D 0; =20 @@ -916,7 +925,7 @@ virStorageBackendLogicalDeletePool(virConnectPtr conn A= TTRIBUTE_UNUSED, =20 static int virStorageBackendLogicalDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool ATTRIBUTE_UNUS= ED, + virPoolObjPtr poolobj ATTRIBUTE_UNUSED, virStorageVolDefPtr vol, unsigned int flags) { @@ -951,9 +960,10 @@ virStorageBackendLogicalDeleteVol(virConnectPtr conn A= TTRIBUTE_UNUSED, =20 static int virStorageBackendLogicalCreateVol(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int fd =3D -1; virCommandPtr cmd =3D NULL; virErrorPtr err; @@ -971,7 +981,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn, =20 VIR_FREE(vol->target.path); if (virAsprintf(&vol->target.path, "%s/%s", - pool->def->target.path, + def->target.path, vol->name) =3D=3D -1) return -1; =20 @@ -992,7 +1002,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn, if (vol->target.backingStore) virCommandAddArgList(cmd, "-s", vol->target.backingStore->path, NU= LL); else - virCommandAddArg(cmd, pool->def->source.name); + virCommandAddArg(cmd, def->source.name); =20 if (virCommandRun(cmd, NULL) < 0) goto error; @@ -1031,7 +1041,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn, } =20 /* Fill in data about this new vol */ - if (virStorageBackendLogicalFindLVs(pool, vol) < 0) { + if (virStorageBackendLogicalFindLVs(poolobj, vol) < 0) { virReportSystemError(errno, _("cannot find newly created volume '%s'"), vol->target.path); @@ -1044,7 +1054,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn, err =3D virSaveLastError(); VIR_FORCE_CLOSE(fd); if (created) - virStorageBackendLogicalDeleteVol(conn, pool, vol, 0); + virStorageBackendLogicalDeleteVol(conn, poolobj, vol, 0); virCommandFree(cmd); virSetError(err); virFreeError(err); @@ -1053,7 +1063,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn, =20 static int virStorageBackendLogicalBuildVolFrom(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags) @@ -1064,18 +1074,19 @@ virStorageBackendLogicalBuildVolFrom(virConnectPtr = conn, if (!build_func) return -1; =20 - return build_func(conn, pool, vol, inputvol, flags); + return build_func(conn, poolobj, vol, inputvol, flags); } =20 static int virStorageBackendLogicalVolWipe(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int algorithm, unsigned int flags) { if (!vol->target.sparse) - return virStorageBackendVolWipeLocal(conn, pool, vol, algorithm, f= lags); + return virStorageBackendVolWipeLocal(conn, poolobj, vol, + algorithm, flags); =20 /* The wiping algorithms will write something to the logical volume. * Writing to a sparse logical volume causes it to be filled resulting diff --git a/src/storage/storage_backend_mpath.c b/src/storage/storage_back= end_mpath.c index 514b59b..eaa16e9 100644 --- a/src/storage/storage_backend_mpath.c +++ b/src/storage/storage_backend_mpath.c @@ -30,7 +30,6 @@ #include =20 #include "virerror.h" -#include "storage_conf.h" #include "storage_backend.h" #include "viralloc.h" #include "virlog.h" @@ -43,10 +42,11 @@ VIR_LOG_INIT("storage.storage_backend_mpath"); =20 static int -virStorageBackendMpathNewVol(virStoragePoolObjPtr pool, +virStorageBackendMpathNewVol(virPoolObjPtr poolobj, const int devnum, const char *dev) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virStorageVolDefPtr vol; virPoolObjPtr volobj; int ret =3D -1; @@ -71,14 +71,14 @@ virStorageBackendMpathNewVol(virStoragePoolObjPtr pool, if (VIR_STRDUP(vol->key, vol->target.path) < 0) goto cleanup; =20 - if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, vol))) goto cleanup; =20 vol =3D NULL; virPoolObjEndAPI(&volobj); =20 - pool->def->capacity +=3D vol->target.capacity; - pool->def->allocation +=3D vol->target.allocation; + def->capacity +=3D vol->target.capacity; + def->allocation +=3D vol->target.allocation; ret =3D 0; =20 cleanup: @@ -160,7 +160,7 @@ virStorageBackendGetMinorNumber(const char *dev_name, u= int32_t *minor) =20 =20 static int -virStorageBackendCreateVols(virStoragePoolObjPtr pool, +virStorageBackendCreateVols(virPoolObjPtr poolobj, struct dm_names *names) { int retval =3D -1, is_mpath =3D 0; @@ -186,7 +186,7 @@ virStorageBackendCreateVols(virStoragePoolObjPtr pool, goto out; } =20 - if (virStorageBackendMpathNewVol(pool, minor, map_device) < 0) + if (virStorageBackendMpathNewVol(poolobj, minor, map_device) <= 0) goto out; =20 VIR_FREE(map_device); @@ -208,7 +208,7 @@ virStorageBackendCreateVols(virStoragePoolObjPtr pool, =20 =20 static int -virStorageBackendGetMaps(virStoragePoolObjPtr pool) +virStorageBackendGetMaps(virPoolObjPtr poolobj) { int retval =3D 0; struct dm_task *dmt =3D NULL; @@ -236,7 +236,7 @@ virStorageBackendGetMaps(virStoragePoolObjPtr pool) goto out; } =20 - virStorageBackendCreateVols(pool, names); + virStorageBackendCreateVols(poolobj, names); =20 out: if (dmt !=3D NULL) @@ -245,7 +245,7 @@ virStorageBackendGetMaps(virStoragePoolObjPtr pool) } =20 static int -virStorageBackendMpathCheckPool(virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, +virStorageBackendMpathCheckPool(virPoolObjPtr poolobj ATTRIBUTE_UNUSED, bool *isActive) { *isActive =3D virFileExists("/dev/mapper") || @@ -257,17 +257,18 @@ virStorageBackendMpathCheckPool(virStoragePoolObjPtr = pool ATTRIBUTE_UNUSED, =20 static int virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int retval =3D 0; =20 - VIR_DEBUG("conn=3D%p, pool=3D%p", conn, pool); + VIR_DEBUG("conn=3D%p, obj=3D%p", conn, poolobj); =20 - pool->def->allocation =3D pool->def->capacity =3D pool->def->available= =3D 0; + def->allocation =3D def->capacity =3D def->available =3D 0; =20 virFileWaitForDevices(); =20 - virStorageBackendGetMaps(pool); + virStorageBackendGetMaps(poolobj); =20 return retval; } diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backen= d_rbd.c index 5a46664..b3fec95 100644 --- a/src/storage/storage_backend_rbd.c +++ b/src/storage/storage_backend_rbd.c @@ -27,7 +27,6 @@ #include "datatypes.h" #include "virerror.h" #include "storage_backend_rbd.h" -#include "storage_conf.h" #include "viralloc.h" #include "virlog.h" #include "base64.h" @@ -208,12 +207,15 @@ virStorageBackendRBDOpenRADOSConn(virStorageBackendRB= DStatePtr ptr, =20 static int virStorageBackendRBDOpenIoCTX(virStorageBackendRBDStatePtr ptr, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { - int r =3D rados_ioctx_create(ptr->cluster, pool->def->source.name, &pt= r->ioctx); + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + + int r =3D rados_ioctx_create(ptr->cluster, def->source.name, &ptr->ioc= tx); if (r < 0) { - virReportSystemError(-r, _("failed to create the RBD IoCTX. Does t= he pool '%s' exist?"), - pool->def->source.name); + virReportSystemError(-r, _("failed to create the RBD IoCTX. " + "Does the pool '%s' exist?"), + def->source.name); } return r; } @@ -252,17 +254,18 @@ virStorageBackendRBDFreeState(virStorageBackendRBDSta= tePtr *ptr) =20 static virStorageBackendRBDStatePtr virStorageBackendRBDNewState(virConnectPtr conn, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virStorageBackendRBDStatePtr ptr; =20 if (VIR_ALLOC(ptr) < 0) return NULL; =20 - if (virStorageBackendRBDOpenRADOSConn(ptr, conn, &pool->def->source) <= 0) + if (virStorageBackendRBDOpenRADOSConn(ptr, conn, &def->source) < 0) goto error; =20 - if (virStorageBackendRBDOpenIoCTX(ptr, pool) < 0) + if (virStorageBackendRBDOpenIoCTX(ptr, poolobj) < 0) goto error; =20 return ptr; @@ -355,9 +358,10 @@ virStorageBackendRBDSetAllocation(virStorageVolDefPtr = vol ATTRIBUTE_UNUSED, =20 static int volStorageBackendRBDRefreshVolInfo(virStorageVolDefPtr vol, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageBackendRBDStatePtr ptr) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int ret =3D -1; int r =3D 0; rbd_image_t image =3D NULL; @@ -388,7 +392,7 @@ volStorageBackendRBDRefreshVolInfo(virStorageVolDefPtr = vol, if (volStorageBackendRBDUseFastDiff(features)) { VIR_DEBUG("RBD image %s/%s has fast-diff feature enabled. " "Querying for actual allocation", - pool->def->source.name, vol->name); + def->source.name, vol->name); =20 if (virStorageBackendRBDSetAllocation(vol, image, &info) < 0) goto cleanup; @@ -398,18 +402,18 @@ volStorageBackendRBDRefreshVolInfo(virStorageVolDefPt= r vol, =20 VIR_DEBUG("Refreshed RBD image %s/%s (capacity: %llu allocation: %llu " "obj_size: %"PRIu64" num_objs: %"PRIu64")", - pool->def->source.name, vol->name, vol->target.capacity, + def->source.name, vol->name, vol->target.capacity, vol->target.allocation, info.obj_size, info.num_objs); =20 VIR_FREE(vol->target.path); if (virAsprintf(&vol->target.path, "%s/%s", - pool->def->source.name, + def->source.name, vol->name) =3D=3D -1) goto cleanup; =20 VIR_FREE(vol->key); if (virAsprintf(&vol->key, "%s/%s", - pool->def->source.name, + def->source.name, vol->name) =3D=3D -1) goto cleanup; =20 @@ -423,8 +427,9 @@ volStorageBackendRBDRefreshVolInfo(virStorageVolDefPtr = vol, =20 static int virStorageBackendRBDRefreshPool(virConnectPtr conn, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); size_t max_size =3D 1024; int ret =3D -1; int len =3D -1; @@ -435,7 +440,7 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn, struct rados_cluster_stat_t clusterstat; struct rados_pool_stat_t poolstat; =20 - if (!(ptr =3D virStorageBackendRBDNewState(conn, pool))) + if (!(ptr =3D virStorageBackendRBDNewState(conn, poolobj))) goto cleanup; =20 if ((r =3D rados_cluster_stat(ptr->cluster, &clusterstat)) < 0) { @@ -445,17 +450,17 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn, =20 if ((r =3D rados_ioctx_pool_stat(ptr->ioctx, &poolstat)) < 0) { virReportSystemError(-r, _("failed to stat the RADOS pool '%s'"), - pool->def->source.name); + def->source.name); goto cleanup; } =20 - pool->def->capacity =3D clusterstat.kb * 1024; - pool->def->available =3D clusterstat.kb_avail * 1024; - pool->def->allocation =3D poolstat.num_bytes; + def->capacity =3D clusterstat.kb * 1024; + def->available =3D clusterstat.kb_avail * 1024; + def->allocation =3D poolstat.num_bytes; =20 VIR_DEBUG("Utilization of RBD pool %s: (kb: %"PRIu64" kb_avail: %"PRIu= 64 " num_bytes: %"PRIu64")", - pool->def->source.name, clusterstat.kb, clusterstat.kb_avail, + def->source.name, clusterstat.kb, clusterstat.kb_avail, poolstat.num_bytes); =20 while (true) { @@ -489,7 +494,7 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn, =20 name +=3D strlen(name) + 1; =20 - r =3D volStorageBackendRBDRefreshVolInfo(vol, pool, ptr); + r =3D volStorageBackendRBDRefreshVolInfo(vol, poolobj, ptr); =20 /* It could be that a volume has been deleted through a different = route * then libvirt and that will cause a -ENOENT to be returned. @@ -508,9 +513,9 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn, goto cleanup; } =20 - if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) { + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, vol))) { virStorageVolDefFree(vol); - virStoragePoolObjClearVols(pool); + virStoragePoolObjClearVols(poolobj); goto cleanup; } count++; @@ -518,7 +523,7 @@ virStorageBackendRBDRefreshPool(virConnectPtr conn, } =20 VIR_DEBUG("Found %d images in RBD pool %s", - count, pool->def->source.name); + count, def->source.name); =20 ret =3D 0; =20 @@ -608,10 +613,11 @@ virStorageBackendRBDCleanupSnapshots(rados_ioctx_t io= ctx, =20 static int virStorageBackendRBDDeleteVol(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int ret =3D -1; int r =3D 0; virStorageBackendRBDStatePtr ptr =3D NULL; @@ -619,26 +625,26 @@ virStorageBackendRBDDeleteVol(virConnectPtr conn, virCheckFlags(VIR_STORAGE_VOL_DELETE_ZEROED | VIR_STORAGE_VOL_DELETE_WITH_SNAPSHOTS, -1); =20 - VIR_DEBUG("Removing RBD image %s/%s", pool->def->source.name, vol->nam= e); + VIR_DEBUG("Removing RBD image %s/%s", def->source.name, vol->name); =20 if (flags & VIR_STORAGE_VOL_DELETE_ZEROED) VIR_WARN("%s", "This storage backend does not support zeroed remov= al of volumes"); =20 - if (!(ptr =3D virStorageBackendRBDNewState(conn, pool))) + if (!(ptr =3D virStorageBackendRBDNewState(conn, poolobj))) goto cleanup; =20 if (flags & VIR_STORAGE_VOL_DELETE_WITH_SNAPSHOTS) { - if (virStorageBackendRBDCleanupSnapshots(ptr->ioctx, &pool->def->s= ource, + if (virStorageBackendRBDCleanupSnapshots(ptr->ioctx, &def->source, vol) < 0) goto cleanup; } =20 - VIR_DEBUG("Removing volume %s/%s", pool->def->source.name, vol->name); + VIR_DEBUG("Removing volume %s/%s", def->source.name, vol->name); =20 r =3D rbd_remove(ptr->ioctx, vol->name); if (r < 0 && (-r) !=3D ENOENT) { virReportSystemError(-r, _("failed to remove volume '%s/%s'"), - pool->def->source.name, vol->name); + def->source.name, vol->name); goto cleanup; } =20 @@ -652,9 +658,11 @@ virStorageBackendRBDDeleteVol(virConnectPtr conn, =20 static int virStorageBackendRBDCreateVol(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + vol->type =3D VIR_STORAGE_VOL_NETWORK; =20 if (vol->target.format !=3D VIR_STORAGE_FILE_RAW) { @@ -665,13 +673,13 @@ virStorageBackendRBDCreateVol(virConnectPtr conn ATTR= IBUTE_UNUSED, =20 VIR_FREE(vol->target.path); if (virAsprintf(&vol->target.path, "%s/%s", - pool->def->source.name, + def->source.name, vol->name) =3D=3D -1) return -1; =20 VIR_FREE(vol->key); if (virAsprintf(&vol->key, "%s/%s", - pool->def->source.name, + def->source.name, vol->name) =3D=3D -1) return -1; =20 @@ -687,16 +695,17 @@ static int virStorageBackendRBDCreateImage(rados_ioct= x_t io, =20 static int virStorageBackendRBDBuildVol(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virStorageBackendRBDStatePtr ptr =3D NULL; int ret =3D -1; int r =3D 0; =20 VIR_DEBUG("Creating RBD image %s/%s with size %llu", - pool->def->source.name, + def->source.name, vol->name, vol->target.capacity); =20 virCheckFlags(0, -1); @@ -719,13 +728,13 @@ virStorageBackendRBDBuildVol(virConnectPtr conn, goto cleanup; } =20 - if (!(ptr =3D virStorageBackendRBDNewState(conn, pool))) + if (!(ptr =3D virStorageBackendRBDNewState(conn, poolobj))) goto cleanup; =20 if ((r =3D virStorageBackendRBDCreateImage(ptr->ioctx, vol->name, vol->target.capacity)) < 0) { virReportSystemError(-r, _("failed to create volume '%s/%s'"), - pool->def->source.name, + def->source.name, vol->name); goto cleanup; } @@ -1044,20 +1053,21 @@ virStorageBackendRBDCloneImage(rados_ioctx_t io, =20 static int virStorageBackendRBDBuildVolFrom(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr newvol, virStorageVolDefPtr origvol, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virStorageBackendRBDStatePtr ptr =3D NULL; int ret =3D -1; =20 VIR_DEBUG("Creating clone of RBD image %s/%s with name %s", - pool->def->source.name, origvol->name, newvol->name); + def->source.name, origvol->name, newvol->name); =20 virCheckFlags(0, -1); =20 - if (!(ptr =3D virStorageBackendRBDNewState(conn, pool))) + if (!(ptr =3D virStorageBackendRBDNewState(conn, poolobj))) goto cleanup; =20 if ((virStorageBackendRBDCloneImage(ptr->ioctx, origvol->name, @@ -1073,16 +1083,16 @@ virStorageBackendRBDBuildVolFrom(virConnectPtr conn, =20 static int virStorageBackendRBDRefreshVol(virConnectPtr conn, - virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virPoolObjPtr poolobj, virStorageVolDefPtr vol) { virStorageBackendRBDStatePtr ptr =3D NULL; int ret =3D -1; =20 - if (!(ptr =3D virStorageBackendRBDNewState(conn, pool))) + if (!(ptr =3D virStorageBackendRBDNewState(conn, poolobj))) goto cleanup; =20 - if (volStorageBackendRBDRefreshVolInfo(vol, pool, ptr) < 0) + if (volStorageBackendRBDRefreshVolInfo(vol, poolobj, ptr) < 0) goto cleanup; =20 ret =3D 0; @@ -1094,7 +1104,7 @@ virStorageBackendRBDRefreshVol(virConnectPtr conn, =20 static int virStorageBackendRBDResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned long long capacity, unsigned int flags) @@ -1106,7 +1116,7 @@ virStorageBackendRBDResizeVol(virConnectPtr conn ATTR= IBUTE_UNUSED, =20 virCheckFlags(0, -1); =20 - if (!(ptr =3D virStorageBackendRBDNewState(conn, pool))) + if (!(ptr =3D virStorageBackendRBDNewState(conn, poolobj))) goto cleanup; =20 if ((r =3D rbd_open(ptr->ioctx, vol->name, &image, NULL)) < 0) { @@ -1206,11 +1216,12 @@ virStorageBackendRBDVolWipeDiscard(rbd_image_t imag= e, =20 static int virStorageBackendRBDVolWipe(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int algorithm, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virStorageBackendRBDStatePtr ptr =3D NULL; rbd_image_t image =3D NULL; rbd_image_info_t info; @@ -1220,9 +1231,9 @@ virStorageBackendRBDVolWipe(virConnectPtr conn, =20 virCheckFlags(0, -1); =20 - VIR_DEBUG("Wiping RBD image %s/%s", pool->def->source.name, vol->name); + VIR_DEBUG("Wiping RBD image %s/%s", def->source.name, vol->name); =20 - if (!(ptr =3D virStorageBackendRBDNewState(conn, pool))) + if (!(ptr =3D virStorageBackendRBDNewState(conn, poolobj))) goto cleanup; =20 if ((r =3D rbd_open(ptr->ioctx, vol->name, &image, NULL)) < 0) { @@ -1244,7 +1255,7 @@ virStorageBackendRBDVolWipe(virConnectPtr conn, } =20 VIR_DEBUG("Need to wipe %"PRIu64" bytes from RBD image %s/%s", - info.size, pool->def->source.name, vol->name); + info.size, def->source.name, vol->name); =20 switch ((virStorageVolWipeAlgorithm) algorithm) { case VIR_STORAGE_VOL_WIPE_ALG_ZERO: diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backe= nd_scsi.c index 0cc1148..46aa6ab 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -137,7 +137,8 @@ virStoragePoolFCRefreshThread(void *opaque) virStoragePoolFCRefreshInfoPtr cbdata =3D opaque; const char *fchost_name =3D cbdata->fchost_name; const unsigned char *pool_uuid =3D cbdata->pool_uuid; - virStoragePoolObjPtr pool =3D NULL; + virPoolObjPtr obj =3D NULL; + virStoragePoolDefPtr def =3D NULL; unsigned int host; int found =3D 0; int tries =3D 2; @@ -146,27 +147,29 @@ virStoragePoolFCRefreshThread(void *opaque) sleep(5); /* Give it time */ =20 /* Let's see if the pool still exists - */ - if (!(pool =3D virStoragePoolObjFindPoolByUUID(pool_uuid))) + if (!(obj =3D virStoragePoolObjFindPoolByUUID(pool_uuid))) break; =20 + def =3D virPoolObjGetDef(obj); + /* Return with pool lock, if active, we can get the host number, * successfully, rescan, and find LUN's, then we are happy */ VIR_DEBUG("Attempt FC Refresh for pool=3D'%s' name=3D'%s' tries=3D= '%d'", - pool->def->name, fchost_name, tries); + def->name, fchost_name, tries); =20 - pool->def->allocation =3D pool->def->capacity =3D pool->def->avail= able =3D 0; + def->allocation =3D def->capacity =3D def->available =3D 0; =20 - if (virStoragePoolObjIsActive(pool) && + if (virPoolObjIsActive(obj) && virGetSCSIHostNumber(fchost_name, &host) =3D=3D 0 && virStorageBackendSCSITriggerRescan(host) =3D=3D 0) { - virStoragePoolObjClearVols(pool); - found =3D virStorageBackendSCSIFindLUs(pool, host); + virStoragePoolObjClearVols(obj); + found =3D virStorageBackendSCSIFindLUs(obj, host); } - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); } while (!found && --tries); =20 - if (pool && !found) + if (obj && !found) VIR_DEBUG("FC Refresh Thread failed to find LU's"); =20 virStoragePoolFCRefreshDataFree(cbdata); @@ -246,10 +249,11 @@ checkVhbaSCSIHostParent(virConnectPtr conn, =20 static int createVport(virConnectPtr conn, - virStoragePoolObjPtr pool) + virPoolObjPtr obj) { - const char *configFile =3D pool->configFile; - virStoragePoolSourceAdapterPtr adapter =3D &pool->def->source.adapter; + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + const char *configFile =3D virStoragePoolObjPrivateGetConfigFile(obj); + virStoragePoolSourceAdapterPtr adapter =3D &def->source.adapter; unsigned int parent_host; char *name =3D NULL; char *parent_hoststr =3D NULL; @@ -337,7 +341,7 @@ createVport(virConnectPtr conn, if (adapter->data.fchost.managed !=3D VIR_TRISTATE_BOOL_YES) { adapter->data.fchost.managed =3D VIR_TRISTATE_BOOL_YES; if (configFile) { - if (virStoragePoolSaveConfig(configFile, pool->def) < 0) + if (virStoragePoolSaveConfig(configFile, def) < 0) goto cleanup; } } @@ -356,7 +360,7 @@ createVport(virConnectPtr conn, if ((name =3D virGetFCHostNameByWWN(NULL, adapter->data.fchost.wwnn, adapter->data.fchost.wwpn))) { if (VIR_ALLOC(cbdata) =3D=3D 0) { - memcpy(cbdata->pool_uuid, pool->def->uuid, VIR_UUID_BUFLEN); + memcpy(cbdata->pool_uuid, def->uuid, VIR_UUID_BUFLEN); VIR_STEAL_PTR(cbdata->fchost_name, name); =20 if (virThreadCreate(&thread, false, virStoragePoolFCRefreshThr= ead, @@ -435,9 +439,10 @@ deleteVport(virConnectPtr conn, =20 =20 static int -virStorageBackendSCSICheckPool(virStoragePoolObjPtr pool, +virStorageBackendSCSICheckPool(virPoolObjPtr obj, bool *isActive) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); char *path =3D NULL; char *name =3D NULL; unsigned int host; @@ -445,12 +450,12 @@ virStorageBackendSCSICheckPool(virStoragePoolObjPtr p= ool, =20 *isActive =3D false; =20 - if (!(name =3D getAdapterName(pool->def->source.adapter))) { + if (!(name =3D getAdapterName(def->source.adapter))) { /* It's normal for the pool with "fc_host" type source * adapter fails to get the adapter name, since the vHBA * the adapter based on might be not created yet. */ - if (pool->def->source.adapter.type =3D=3D + if (def->source.adapter.type =3D=3D VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { virResetLastError(); return 0; @@ -477,15 +482,16 @@ virStorageBackendSCSICheckPool(virStoragePoolObjPtr p= ool, =20 static int virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr obj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); char *name =3D NULL; unsigned int host; int ret =3D -1; =20 - pool->def->allocation =3D pool->def->capacity =3D pool->def->available= =3D 0; + def->allocation =3D def->capacity =3D def->available =3D 0; =20 - if (!(name =3D getAdapterName(pool->def->source.adapter))) + if (!(name =3D getAdapterName(def->source.adapter))) return -1; =20 if (virGetSCSIHostNumber(name, &host) < 0) @@ -496,7 +502,7 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn ATT= RIBUTE_UNUSED, if (virStorageBackendSCSITriggerRescan(host) < 0) goto out; =20 - if (virStorageBackendSCSIFindLUs(pool, host) < 0) + if (virStorageBackendSCSIFindLUs(obj, host) < 0) goto out; =20 ret =3D 0; @@ -507,16 +513,17 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn A= TTRIBUTE_UNUSED, =20 static int virStorageBackendSCSIStartPool(virConnectPtr conn, - virStoragePoolObjPtr pool) + virPoolObjPtr obj) { - return createVport(conn, pool); + return createVport(conn, obj); } =20 static int virStorageBackendSCSIStopPool(virConnectPtr conn, - virStoragePoolObjPtr pool) + virPoolObjPtr obj) { - virStoragePoolSourceAdapter adapter =3D pool->def->source.adapter; + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + virStoragePoolSourceAdapter adapter =3D def->source.adapter; return deleteVport(conn, adapter); } =20 diff --git a/src/storage/storage_backend_sheepdog.c b/src/storage/storage_b= ackend_sheepdog.c index 04734c8..2dc9f1c 100644 --- a/src/storage/storage_backend_sheepdog.c +++ b/src/storage/storage_backend_sheepdog.c @@ -30,7 +30,6 @@ #include "virerror.h" #include "storage_backend_sheepdog.h" #include "storage_backend_sheepdog_priv.h" -#include "storage_conf.h" #include "vircommand.h" #include "viralloc.h" #include "virstring.h" @@ -39,14 +38,14 @@ #define VIR_FROM_THIS VIR_FROM_STORAGE =20 static int virStorageBackendSheepdogRefreshVol(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol); =20 void virStorageBackendSheepdogAddHostArg(virCommandPtr cmd, - virStoragePoolObjPtr pool); + virPoolObjPtr poolobj); =20 int -virStorageBackendSheepdogParseNodeInfo(virStoragePoolDefPtr pool, +virStorageBackendSheepdogParseNodeInfo(virStoragePoolDefPtr def, char *output) { /* fields: @@ -59,7 +58,7 @@ virStorageBackendSheepdogParseNodeInfo(virStoragePoolDefP= tr pool, =20 const char *p, *next; =20 - pool->allocation =3D pool->capacity =3D pool->available =3D 0; + def->allocation =3D def->capacity =3D def->available =3D 0; =20 p =3D output; do { @@ -75,16 +74,16 @@ virStorageBackendSheepdogParseNodeInfo(virStoragePoolDe= fPtr pool, =20 p =3D p + 6; =20 - if (virStrToLong_ull(p, &end, 10, &pool->capacity) < 0) + if (virStrToLong_ull(p, &end, 10, &def->capacity) < 0) break; =20 if ((p =3D end + 1) > next) break; =20 - if (virStrToLong_ull(p, &end, 10, &pool->allocation) < 0) + if (virStrToLong_ull(p, &end, 10, &def->allocation) < 0) break; =20 - pool->available =3D pool->capacity - pool->allocation; + def->available =3D def->capacity - def->allocation; return 0; =20 } while ((p =3D next)); @@ -94,15 +93,16 @@ virStorageBackendSheepdogParseNodeInfo(virStoragePoolDe= fPtr pool, =20 void virStorageBackendSheepdogAddHostArg(virCommandPtr cmd, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); const char *address =3D "localhost"; int port =3D 7000; - if (pool->def->source.nhost > 0) { - if (pool->def->source.hosts[0].name !=3D NULL) - address =3D pool->def->source.hosts[0].name; - if (pool->def->source.hosts[0].port) - port =3D pool->def->source.hosts[0].port; + if (def->source.nhost > 0) { + if (def->source.hosts[0].name !=3D NULL) + address =3D def->source.hosts[0].name; + if (def->source.hosts[0].port) + port =3D def->source.hosts[0].port; } virCommandAddArg(cmd, "-a"); virCommandAddArgFormat(cmd, "%s", address); @@ -112,10 +112,11 @@ virStorageBackendSheepdogAddHostArg(virCommandPtr cmd, =20 static int virStorageBackendSheepdogAddVolume(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, const char *d= iskInfo) + virPoolObjPtr poolobj, + const char *diskInfo) { - virStorageVolDefPtr vol =3D NULL; - virPoolObjPtr obj; + virPoolObjPtr volobj; + virStorageVolDefPtr voldef =3D NULL; =20 if (diskInfo =3D=3D NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -123,29 +124,29 @@ virStorageBackendSheepdogAddVolume(virConnectPtr conn= ATTRIBUTE_UNUSED, goto error; } =20 - if (VIR_ALLOC(vol) < 0 || VIR_STRDUP(vol->name, diskInfo) < 0) + if (VIR_ALLOC(voldef) < 0 || VIR_STRDUP(voldef->name, diskInfo) < 0) goto error; =20 - vol->type =3D VIR_STORAGE_VOL_NETWORK; + voldef->type =3D VIR_STORAGE_VOL_NETWORK; =20 - if (virStorageBackendSheepdogRefreshVol(conn, pool, vol) < 0) + if (virStorageBackendSheepdogRefreshVol(conn, poolobj, voldef) < 0) goto error; =20 - if (!(obj =3D virStoragePoolObjAddVolume(pool, vol))) + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, voldef))) goto error; - vol =3D NULL; + voldef =3D NULL; =20 - virPoolObjEndAPI(&obj); + virPoolObjEndAPI(&volobj); return 0; =20 error: - virStorageVolDefFree(vol); + virStorageVolDefFree(voldef); return -1; } =20 static int virStorageBackendSheepdogRefreshAllVol(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { int ret =3D -1; char *output =3D NULL; @@ -154,7 +155,7 @@ virStorageBackendSheepdogRefreshAllVol(virConnectPtr co= nn ATTRIBUTE_UNUSED, size_t i; =20 virCommandPtr cmd =3D virCommandNewArgList(SHEEPDOGCLI, "vdi", "list",= "-r", NULL); - virStorageBackendSheepdogAddHostArg(cmd, pool); + virStorageBackendSheepdogAddHostArg(cmd, poolobj); virCommandSetOutputBuffer(cmd, &output); if (virCommandRun(cmd, NULL) < 0) goto cleanup; @@ -172,7 +173,8 @@ virStorageBackendSheepdogRefreshAllVol(virConnectPtr co= nn ATTRIBUTE_UNUSED, =20 if (cells !=3D NULL && virStringListLength((const char * const *)cells) > 2) { - if (virStorageBackendSheepdogAddVolume(conn, pool, cells[1]) <= 0) + if (virStorageBackendSheepdogAddVolume(conn, poolobj, + cells[1]) < 0) goto cleanup; } =20 @@ -193,22 +195,23 @@ virStorageBackendSheepdogRefreshAllVol(virConnectPtr = conn ATTRIBUTE_UNUSED, =20 static int virStorageBackendSheepdogRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int ret =3D -1; char *output =3D NULL; virCommandPtr cmd; =20 cmd =3D virCommandNewArgList(SHEEPDOGCLI, "node", "info", "-r", NULL); - virStorageBackendSheepdogAddHostArg(cmd, pool); + virStorageBackendSheepdogAddHostArg(cmd, poolobj); virCommandSetOutputBuffer(cmd, &output); if (virCommandRun(cmd, NULL) < 0) goto cleanup; =20 - if (virStorageBackendSheepdogParseNodeInfo(pool->def, output) < 0) + if (virStorageBackendSheepdogParseNodeInfo(def, output) < 0) goto cleanup; =20 - ret =3D virStorageBackendSheepdogRefreshAllVol(conn, pool); + ret =3D virStorageBackendSheepdogRefreshAllVol(conn, poolobj); cleanup: virCommandFree(cmd); VIR_FREE(output); @@ -218,7 +221,7 @@ virStorageBackendSheepdogRefreshPool(virConnectPtr conn= ATTRIBUTE_UNUSED, =20 static int virStorageBackendSheepdogDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags) { @@ -226,7 +229,7 @@ virStorageBackendSheepdogDeleteVol(virConnectPtr conn A= TTRIBUTE_UNUSED, virCheckFlags(0, -1); =20 virCommandPtr cmd =3D virCommandNewArgList(SHEEPDOGCLI, "vdi", "delete= ", vol->name, NULL); - virStorageBackendSheepdogAddHostArg(cmd, pool); + virStorageBackendSheepdogAddHostArg(cmd, poolobj); int ret =3D virCommandRun(cmd, NULL); =20 virCommandFree(cmd); @@ -236,9 +239,11 @@ virStorageBackendSheepdogDeleteVol(virConnectPtr conn = ATTRIBUTE_UNUSED, =20 static int virStorageBackendSheepdogCreateVol(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + if (vol->target.encryption !=3D NULL) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("storage pool does not support encrypted " @@ -250,7 +255,7 @@ virStorageBackendSheepdogCreateVol(virConnectPtr conn A= TTRIBUTE_UNUSED, =20 VIR_FREE(vol->key); if (virAsprintf(&vol->key, "%s/%s", - pool->def->source.name, vol->name) =3D=3D -1) + def->source.name, vol->name) =3D=3D -1) return -1; =20 VIR_FREE(vol->target.path); @@ -263,7 +268,7 @@ virStorageBackendSheepdogCreateVol(virConnectPtr conn A= TTRIBUTE_UNUSED, =20 static int virStorageBackendSheepdogBuildVol(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags) { @@ -280,7 +285,7 @@ virStorageBackendSheepdogBuildVol(virConnectPtr conn AT= TRIBUTE_UNUSED, =20 cmd =3D virCommandNewArgList(SHEEPDOGCLI, "vdi", "create", vol->name, = NULL); virCommandAddArgFormat(cmd, "%llu", vol->target.capacity); - virStorageBackendSheepdogAddHostArg(cmd, pool); + virStorageBackendSheepdogAddHostArg(cmd, poolobj); if (virCommandRun(cmd, NULL) < 0) goto cleanup; =20 @@ -354,14 +359,15 @@ virStorageBackendSheepdogParseVdiList(virStorageVolDe= fPtr vol, =20 static int virStorageBackendSheepdogRefreshVol(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int ret; char *output =3D NULL; =20 virCommandPtr cmd =3D virCommandNewArgList(SHEEPDOGCLI, "vdi", "list",= vol->name, "-r", NULL); - virStorageBackendSheepdogAddHostArg(cmd, pool); + virStorageBackendSheepdogAddHostArg(cmd, poolobj); virCommandSetOutputBuffer(cmd, &output); ret =3D virCommandRun(cmd, NULL); =20 @@ -375,7 +381,7 @@ virStorageBackendSheepdogRefreshVol(virConnectPtr conn = ATTRIBUTE_UNUSED, =20 VIR_FREE(vol->key); if (virAsprintf(&vol->key, "%s/%s", - pool->def->source.name, vol->name) =3D=3D -1) + def->source.name, vol->name) =3D=3D -1) goto cleanup; =20 VIR_FREE(vol->target.path); @@ -388,7 +394,7 @@ virStorageBackendSheepdogRefreshVol(virConnectPtr conn = ATTRIBUTE_UNUSED, =20 static int virStorageBackendSheepdogResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned long long capacity, unsigned int flags) @@ -398,7 +404,7 @@ virStorageBackendSheepdogResizeVol(virConnectPtr conn A= TTRIBUTE_UNUSED, =20 virCommandPtr cmd =3D virCommandNewArgList(SHEEPDOGCLI, "vdi", "resize= ", vol->name, NULL); virCommandAddArgFormat(cmd, "%llu", capacity); - virStorageBackendSheepdogAddHostArg(cmd, pool); + virStorageBackendSheepdogAddHostArg(cmd, poolobj); int ret =3D virCommandRun(cmd, NULL); =20 virCommandFree(cmd); diff --git a/src/storage/storage_backend_vstorage.c b/src/storage/storage_b= ackend_vstorage.c index ac1fa75..3ec080d 100644 --- a/src/storage/storage_backend_vstorage.c +++ b/src/storage/storage_backend_vstorage.c @@ -18,7 +18,7 @@ VIR_LOG_INIT("storage.storage_backend_vstorage"); =20 /** * @conn connection to report errors against - * @pool storage pool to build + * @poolobj storage pool object to build * @flags controls the pool formatting behaviour * * Does not support @flags, if provided an error will occur. @@ -27,19 +27,20 @@ VIR_LOG_INIT("storage.storage_backend_vstorage"); */ static int virStorageBackendVzPoolBuild(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, unsigned int flags) { virCheckFlags(0, -1); =20 - return virStorageBackendBuildLocal(pool); + return virStorageBackendBuildLocal(poolobj); } =20 =20 static int virStorageBackendVzPoolStart(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int ret =3D -1; virCommandPtr cmd =3D NULL; char *grp_name =3D NULL; @@ -47,27 +48,27 @@ virStorageBackendVzPoolStart(virConnectPtr conn ATTRIBU= TE_UNUSED, char *mode =3D NULL; =20 /* Check the permissions */ - if (pool->def->target.perms.mode =3D=3D (mode_t) - 1) - pool->def->target.perms.mode =3D VIR_STORAGE_DEFAULT_POOL_PERM_MOD= E; - if (pool->def->target.perms.uid =3D=3D (uid_t) -1) - pool->def->target.perms.uid =3D geteuid(); - if (pool->def->target.perms.gid =3D=3D (gid_t) -1) - pool->def->target.perms.gid =3D getegid(); + if (def->target.perms.mode =3D=3D (mode_t) - 1) + def->target.perms.mode =3D VIR_STORAGE_DEFAULT_POOL_PERM_MODE; + if (def->target.perms.uid =3D=3D (uid_t) -1) + def->target.perms.uid =3D geteuid(); + if (def->target.perms.gid =3D=3D (gid_t) -1) + def->target.perms.gid =3D getegid(); =20 /* Convert ids to names because vstorage uses names */ =20 - if (!(grp_name =3D virGetGroupName(pool->def->target.perms.gid))) + if (!(grp_name =3D virGetGroupName(def->target.perms.gid))) goto cleanup; =20 - if (!(usr_name =3D virGetUserName(pool->def->target.perms.uid))) + if (!(usr_name =3D virGetUserName(def->target.perms.uid))) goto cleanup; =20 - if (virAsprintf(&mode, "%o", pool->def->target.perms.mode) < 0) + if (virAsprintf(&mode, "%o", def->target.perms.mode) < 0) goto cleanup; =20 cmd =3D virCommandNewArgList(VSTORAGE_MOUNT, - "-c", pool->def->source.name, - pool->def->target.path, + "-c", def->source.name, + def->target.path, "-m", mode, "-g", grp_name, "-u", usr_name, NULL); @@ -86,8 +87,9 @@ virStorageBackendVzPoolStart(virConnectPtr conn ATTRIBUTE= _UNUSED, =20 =20 static int -virStorageBackendVzIsMounted(virStoragePoolObjPtr pool) +virStorageBackendVzIsMounted(virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int ret =3D -1; FILE *mtab; struct mntent ent; @@ -106,7 +108,7 @@ virStorageBackendVzIsMounted(virStoragePoolObjPtr pool) =20 while ((getmntent_r(mtab, &ent, buf, sizeof(buf))) !=3D NULL) { =20 - if (STREQ(ent.mnt_dir, pool->def->target.path) && + if (STREQ(ent.mnt_dir, def->target.path) && STREQ(ent.mnt_fsname, cluster)) { ret =3D 1; goto cleanup; @@ -124,17 +126,18 @@ virStorageBackendVzIsMounted(virStoragePoolObjPtr poo= l) =20 static int virStorageBackendVzPoolStop(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virCommandPtr cmd =3D NULL; int ret =3D -1; int rc; =20 /* Short-circuit if already unmounted */ - if ((rc =3D virStorageBackendVzIsMounted(pool)) !=3D 1) + if ((rc =3D virStorageBackendVzIsMounted(poolobj)) !=3D 1) return rc; =20 - cmd =3D virCommandNewArgList(UMOUNT, pool->def->target.path, NULL); + cmd =3D virCommandNewArgList(UMOUNT, def->target.path, NULL); if (virCommandRun(cmd, NULL) < 0) goto cleanup; =20 @@ -149,12 +152,12 @@ virStorageBackendVzPoolStop(virConnectPtr conn ATTRIB= UTE_UNUSED, * Check whether the cluster is mounted */ static int -virStorageBackendVzCheck(virStoragePoolObjPtr pool, +virStorageBackendVzCheck(virPoolObjPtr poolobj, bool *isActive) { int ret =3D -1; *isActive =3D false; - if ((ret =3D virStorageBackendVzIsMounted(pool)) !=3D 0) { + if ((ret =3D virStorageBackendVzIsMounted(poolobj)) !=3D 0) { if (ret < 0) return -1; *isActive =3D true; diff --git a/src/storage/storage_backend_zfs.c b/src/storage/storage_backen= d_zfs.c index fab29fb..4b20086 100644 --- a/src/storage/storage_backend_zfs.c +++ b/src/storage/storage_backend_zfs.c @@ -83,13 +83,14 @@ virStorageBackendZFSVolModeNeeded(void) } =20 static int -virStorageBackendZFSCheckPool(virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, +virStorageBackendZFSCheckPool(virPoolObjPtr poolobj, bool *isActive) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); char *devpath; =20 if (virAsprintf(&devpath, "/dev/zvol/%s", - pool->def->source.name) =3D=3D -1) + def->source.name) < 0) return -1; *isActive =3D virFileIsDir(devpath); VIR_FREE(devpath); @@ -98,10 +99,11 @@ virStorageBackendZFSCheckPool(virStoragePoolObjPtr pool= ATTRIBUTE_UNUSED, } =20 static int -virStorageBackendZFSParseVol(virStoragePoolObjPtr pool, +virStorageBackendZFSParseVol(virPoolObjPtr poolobj, virStorageVolDefPtr volume, const char *volume_string) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virPoolObjPtr volobj =3D NULL; virStorageVolDefPtr voldef =3D volume; int ret =3D -1; @@ -123,7 +125,7 @@ virStorageBackendZFSParseVol(virStoragePoolObjPtr pool, vol_name =3D name_tokens[1]; =20 if (!voldef) { - if ((volobj =3D virStorageVolObjFindByName(pool, vol_name))) + if ((volobj =3D virStorageVolObjFindByName(poolobj, vol_name))) voldef =3D virPoolObjGetDef(volobj); } =20 @@ -141,9 +143,9 @@ virStorageBackendZFSParseVol(virStoragePoolObjPtr pool, if (!voldef->key && VIR_STRDUP(voldef->key, tokens[0]) < 0) goto cleanup; =20 - if (voldef->target.path =3D=3D NULL) { + if (!voldef->target.path) { if (virAsprintf(&voldef->target.path, "%s/%s", - pool->def->target.path, voldef->name) < 0) + def->target.path, voldef->name) < 0) goto cleanup; } =20 @@ -163,7 +165,7 @@ virStorageBackendZFSParseVol(virStoragePoolObjPtr pool, voldef->target.sparse =3D true; =20 if (is_new_vol) { - if (!(volobj =3D virStoragePoolObjAddVolume(pool, voldef))) + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, voldef))) goto cleanup; =20 voldef =3D NULL; @@ -173,16 +175,17 @@ virStorageBackendZFSParseVol(virStoragePoolObjPtr poo= l, cleanup: virStringListFree(tokens); virStringListFree(name_tokens); - virPoolObjEndAPI(&volobj); if (is_new_vol) virStorageVolDefFree(voldef); + virPoolObjEndAPI(&volobj); return ret; } =20 static int -virStorageBackendZFSFindVols(virStoragePoolObjPtr pool, +virStorageBackendZFSFindVols(virPoolObjPtr poolobj, virStorageVolDefPtr vol) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virCommandPtr cmd =3D NULL; char *volumes_list =3D NULL; char **lines =3D NULL; @@ -204,7 +207,7 @@ virStorageBackendZFSFindVols(virStoragePoolObjPtr pool, "list", "-Hp", "-t", "volume", "-r", "-o", "name,volsize,refreservation", - pool->def->source.name, + def->source.name, NULL); virCommandSetOutputBuffer(cmd, &volumes_list); if (virCommandRun(cmd, NULL) < 0) @@ -217,7 +220,7 @@ virStorageBackendZFSFindVols(virStoragePoolObjPtr pool, if (STREQ(lines[i], "")) continue; =20 - if (virStorageBackendZFSParseVol(pool, vol, lines[i]) < 0) + if (virStorageBackendZFSParseVol(poolobj, vol, lines[i]) < 0) continue; } =20 @@ -231,8 +234,9 @@ virStorageBackendZFSFindVols(virStoragePoolObjPtr pool, =20 static int virStorageBackendZFSRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool ATTRIBUTE_UNUSED) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virCommandPtr cmd =3D NULL; char *zpool_props =3D NULL; char **lines =3D NULL; @@ -252,7 +256,7 @@ virStorageBackendZFSRefreshPool(virConnectPtr conn ATTR= IBUTE_UNUSED, cmd =3D virCommandNewArgList(ZPOOL, "get", "-Hp", "health,size,free,allocated", - pool->def->source.name, + def->source.name, NULL); virCommandSetOutputBuffer(cmd, &zpool_props); if (virCommandRun(cmd, NULL) < 0) @@ -284,16 +288,16 @@ virStorageBackendZFSRefreshPool(virConnectPtr conn AT= TRIBUTE_UNUSED, goto cleanup; =20 if (STREQ(prop_name, "free")) - pool->def->available =3D value; + def->available =3D value; else if (STREQ(prop_name, "size")) - pool->def->capacity =3D value; + def->capacity =3D value; else if (STREQ(prop_name, "allocated")) - pool->def->allocation =3D value; + def->allocation =3D value; } } =20 /* Obtain a list of volumes */ - if (virStorageBackendZFSFindVols(pool, NULL) < 0) + if (virStorageBackendZFSFindVols(poolobj, NULL) < 0) goto cleanup; =20 cleanup: @@ -307,9 +311,10 @@ virStorageBackendZFSRefreshPool(virConnectPtr conn ATT= RIBUTE_UNUSED, =20 static int virStorageBackendZFSCreateVol(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virCommandPtr cmd =3D NULL; int ret =3D -1; int volmode_needed =3D -1; @@ -325,7 +330,7 @@ virStorageBackendZFSCreateVol(virConnectPtr conn ATTRIB= UTE_UNUSED, =20 VIR_FREE(vol->target.path); if (virAsprintf(&vol->target.path, "%s/%s", - pool->def->target.path, vol->name) =3D=3D -1) + def->target.path, vol->name) =3D=3D -1) return -1; =20 if (VIR_STRDUP(vol->key, vol->target.path) < 0) @@ -362,12 +367,12 @@ virStorageBackendZFSCreateVol(virConnectPtr conn ATTR= IBUTE_UNUSED, virCommandAddArgFormat(cmd, "%lluK", VIR_DIV_UP(vol->target.capacity, 1024)); virCommandAddArgFormat(cmd, "%s/%s", - pool->def->source.name, vol->name); + def->source.name, vol->name); =20 if (virCommandRun(cmd, NULL) < 0) goto cleanup; =20 - if (virStorageBackendZFSFindVols(pool, vol) < 0) + if (virStorageBackendZFSFindVols(poolobj, vol) < 0) goto cleanup; =20 ret =3D 0; @@ -379,10 +384,11 @@ virStorageBackendZFSCreateVol(virConnectPtr conn ATTR= IBUTE_UNUSED, =20 static int virStorageBackendZFSDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int ret =3D -1; virCommandPtr destroy_cmd =3D NULL; =20 @@ -391,7 +397,7 @@ virStorageBackendZFSDeleteVol(virConnectPtr conn ATTRIB= UTE_UNUSED, destroy_cmd =3D virCommandNewArgList(ZFS, "destroy", NULL); =20 virCommandAddArgFormat(destroy_cmd, "%s/%s", - pool->def->source.name, vol->name); + def->source.name, vol->name); =20 if (virCommandRun(destroy_cmd, NULL) < 0) goto cleanup; @@ -404,26 +410,27 @@ virStorageBackendZFSDeleteVol(virConnectPtr conn ATTR= IBUTE_UNUSED, =20 static int virStorageBackendZFSBuildPool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virCommandPtr cmd =3D NULL; size_t i; int ret =3D -1; =20 virCheckFlags(0, -1); =20 - if (pool->def->source.ndevice =3D=3D 0) { + if (def->source.ndevice =3D=3D 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("missing source devices")); return -1; } =20 cmd =3D virCommandNewArgList(ZPOOL, "create", - pool->def->source.name, NULL); + def->source.name, NULL); =20 - for (i =3D 0; i < pool->def->source.ndevice; i++) - virCommandAddArg(cmd, pool->def->source.devices[i].path); + for (i =3D 0; i < def->source.ndevice; i++) + virCommandAddArg(cmd, def->source.devices[i].path); =20 if (virCommandRun(cmd, NULL) < 0) goto cleanup; @@ -437,16 +444,17 @@ virStorageBackendZFSBuildPool(virConnectPtr conn ATTR= IBUTE_UNUSED, =20 static int virStorageBackendZFSDeletePool(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); virCommandPtr cmd =3D NULL; int ret =3D -1; =20 virCheckFlags(0, -1); =20 cmd =3D virCommandNewArgList(ZPOOL, "destroy", - pool->def->source.name, NULL); + def->source.name, NULL); =20 if (virCommandRun(cmd, NULL) < 0) goto cleanup; diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 19f7a88..fe4f7aa 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -78,20 +78,21 @@ static void storageDriverUnlock(void) } =20 static void -storagePoolUpdateState(virStoragePoolObjPtr pool) +storagePoolUpdateState(virPoolObjPtr obj, + void *opaque ATTRIBUTE_UNUSED) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); bool active; virStorageBackendPtr backend; int ret =3D -1; char *stateFile; =20 - if (!(stateFile =3D virFileBuildPath(driver->stateDir, - pool->def->name, ".xml"))) + if (!(stateFile =3D virFileBuildPath(driver->stateDir, def->name, ".xm= l"))) goto error; =20 - if ((backend =3D virStorageBackendForType(pool->def->type)) =3D=3D NUL= L) { + if ((backend =3D virStorageBackendForType(def->type)) =3D=3D NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, - _("Missing backend %d"), pool->def->type); + _("Missing backend %d"), def->type); goto error; } =20 @@ -100,10 +101,10 @@ storagePoolUpdateState(virStoragePoolObjPtr pool) */ active =3D false; if (backend->checkPool && - backend->checkPool(pool, &active) < 0) { + backend->checkPool(obj, &active) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to initialize storage pool '%s': %s"), - pool->def->name, virGetLastErrorMessage()); + def->name, virGetLastErrorMessage()); goto error; } =20 @@ -112,18 +113,18 @@ storagePoolUpdateState(virStoragePoolObjPtr pool) * continue with other pools. */ if (active) { - virStoragePoolObjClearVols(pool); - if (backend->refreshPool(NULL, pool) < 0) { + virStoragePoolObjClearVols(obj); + if (backend->refreshPool(NULL, obj) < 0) { if (backend->stopPool) - backend->stopPool(NULL, pool); + backend->stopPool(NULL, obj); virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to restart storage pool '%s': %s"), - pool->def->name, virGetLastErrorMessage()); + def->name, virGetLastErrorMessage()); goto error; } } =20 - pool->active =3D active; + virPoolObjSetActive(obj, active); ret =3D 0; error: if (ret < 0) { @@ -135,24 +136,57 @@ storagePoolUpdateState(virStoragePoolObjPtr pool) return; } =20 + static void -storagePoolUpdateAllState(void) +storagePoolDoAutostart(virPoolObjPtr obj, + void *opaque ATTRIBUTE_UNUSED) { - size_t i; + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + virConnectPtr conn =3D opaque; + virStorageBackendPtr backend; + bool started =3D false; =20 - for (i =3D 0; i < driver->pools.count; i++) { - virStoragePoolObjPtr pool =3D driver->pools.objs[i]; + if (!(backend =3D virStorageBackendForType(def->type))) + return; =20 - virStoragePoolObjLock(pool); - storagePoolUpdateState(pool); - virStoragePoolObjUnlock(pool); + if (virPoolObjIsAutostart(obj) && !virPoolObjIsActive(obj)) { + if (backend->startPool && + backend->startPool(conn, obj) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to autostart storage pool '%s': %s"), + def->name, virGetLastErrorMessage()); + return; + } + started =3D true; } + + if (started) { + char *stateFile; + + virStoragePoolObjClearVols(obj); + stateFile =3D virFileBuildPath(driver->stateDir, def->name, ".xml"= ); + if (!stateFile || + virStoragePoolSaveState(stateFile, def) < 0 || + backend->refreshPool(conn, obj) < 0) { + if (stateFile) + unlink(stateFile); + if (backend->stopPool) + backend->stopPool(conn, obj); + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to autostart storage pool '%s': %s"), + def->name, virGetLastErrorMessage()); + } else { + virPoolObjSetActive(obj, true); + } + VIR_FREE(stateFile); + } + } =20 + static void storageDriverAutostart(void) { - size_t i; virConnectPtr conn =3D NULL; =20 /* XXX Remove hardcoding of QEMU URI */ @@ -160,59 +194,14 @@ storageDriverAutostart(void) conn =3D virConnectOpen("qemu:///system"); else conn =3D virConnectOpen("qemu:///session"); - /* Ignoring NULL conn - let backends decide */ - - for (i =3D 0; i < driver->pools.count; i++) { - virStoragePoolObjPtr pool =3D driver->pools.objs[i]; - virStorageBackendPtr backend; - bool started =3D false; - - virStoragePoolObjLock(pool); - if ((backend =3D virStorageBackendForType(pool->def->type)) =3D=3D= NULL) { - virStoragePoolObjUnlock(pool); - continue; - } - - if (pool->autostart && - !virStoragePoolObjIsActive(pool)) { - if (backend->startPool && - backend->startPool(conn, pool) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to autostart storage pool '%s': %= s"), - pool->def->name, virGetLastErrorMessage()); - virStoragePoolObjUnlock(pool); - continue; - } - started =3D true; - } =20 - if (started) { - char *stateFile; - - virStoragePoolObjClearVols(pool); - stateFile =3D virFileBuildPath(driver->stateDir, - pool->def->name, ".xml"); - if (!stateFile || - virStoragePoolSaveState(stateFile, pool->def) < 0 || - backend->refreshPool(conn, pool) < 0) { - if (stateFile) - unlink(stateFile); - if (backend->stopPool) - backend->stopPool(conn, pool); - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to autostart storage pool '%s': %= s"), - pool->def->name, virGetLastErrorMessage()); - } else { - pool->active =3D true; - } - VIR_FREE(stateFile); - } - virStoragePoolObjUnlock(pool); - } + /* Ignoring NULL conn - let backends decide */ + virPoolObjTableIterate(driver->pools, storagePoolDoAutostart, conn); =20 virObjectUnref(conn); } =20 + /** * virStorageStartup: * @@ -267,16 +256,21 @@ storageStateInitialize(bool privileged, goto error; } =20 - if (virStoragePoolLoadAllState(&driver->pools, - driver->stateDir) < 0) + if (!(driver->pools =3D + virPoolObjTableNew(VIR_POOLOBJTABLE_BLOCK_STORAGE, + VIR_POOLOBJTABLE_BLOCK_STORAGE_HASHSTART, fal= se))) + goto error; + + if (virStoragePoolObjLoadAllState(driver->pools, + driver->stateDir) < 0) goto error; =20 - if (virStoragePoolLoadAllConfigs(&driver->pools, - driver->configDir, - driver->autostartDir) < 0) + if (virStoragePoolObjLoadAllConfigs(driver->pools, + driver->configDir, + driver->autostartDir) < 0) goto error; =20 - storagePoolUpdateAllState(); + virPoolObjTableIterate(driver->pools, storagePoolUpdateState, NULL); =20 driver->storageEventState =3D virObjectEventStateNew(); =20 @@ -323,11 +317,11 @@ storageStateReload(void) return -1; =20 storageDriverLock(); - virStoragePoolLoadAllState(&driver->pools, - driver->stateDir); - virStoragePoolLoadAllConfigs(&driver->pools, - driver->configDir, - driver->autostartDir); + virStoragePoolObjLoadAllState(driver->pools, + driver->stateDir); + virStoragePoolObjLoadAllConfigs(driver->pools, + driver->configDir, + driver->autostartDir); storageDriverAutostart(); storageDriverUnlock(); =20 @@ -351,7 +345,7 @@ storageStateCleanup(void) virObjectUnref(driver->storageEventState); =20 /* free inactive pools */ - virStoragePoolObjListFree(&driver->pools); + virObjectUnref(driver->pools); =20 VIR_FREE(driver->configDir); VIR_FREE(driver->autostartDir); @@ -364,211 +358,173 @@ storageStateCleanup(void) } =20 =20 +static virPoolObjPtr +storagePoolObjFindByUUID(const unsigned char *uuid, + const char *name) +{ + virPoolObjPtr obj; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + + if (!(obj =3D virPoolObjTableFindByUUIDRef(driver->pools, uuid))) { + virUUIDFormat(uuid, uuidstr); + if (name) + virReportError(VIR_ERR_NO_STORAGE_POOL, + _("no storage pool with matching uuid '%s' (%s)= "), + uuidstr, name); + else + virReportError(VIR_ERR_NO_STORAGE_POOL, + _("no storage pool with matching uuid '%s'"), + uuidstr); + } + + return obj; +} + + +static virPoolObjPtr +storagePoolObjFromStoragePool(virStoragePoolPtr pool) +{ + return storagePoolObjFindByUUID(pool->uuid, pool->name); +} + + +static virPoolObjPtr +storagePoolObjFindByName(const char *name) +{ + virPoolObjPtr obj; + + if (!(obj =3D virPoolObjTableFindByName(driver->pools, name))) { + virReportError(VIR_ERR_NO_STORAGE_VOL, + _("no storage vol with matching name '%s'"), name); + } + + return obj; +} + =20 static virStoragePoolPtr storagePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; virStoragePoolPtr ret =3D NULL; =20 - storageDriverLock(); - pool =3D virStoragePoolObjFindByUUID(&driver->pools, uuid); - storageDriverUnlock(); - - if (!pool) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(uuid, uuidstr); - virReportError(VIR_ERR_NO_STORAGE_POOL, - _("no storage pool with matching uuid '%s'"), uuids= tr); + if (!(obj =3D storagePoolObjFindByUUID(uuid, NULL))) return NULL; - } + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolLookupByUUIDEnsureACL(conn, pool->def) < 0) + if (virStoragePoolLookupByUUIDEnsureACL(conn, def) < 0) goto cleanup; =20 - ret =3D virGetStoragePool(conn, pool->def->name, pool->def->uuid, - NULL, NULL); + ret =3D virGetStoragePool(conn, def->name, def->uuid, NULL, NULL); =20 cleanup: - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 + static virStoragePoolPtr storagePoolLookupByName(virConnectPtr conn, const char *name) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; virStoragePoolPtr ret =3D NULL; =20 - storageDriverLock(); - pool =3D virStoragePoolObjFindByName(&driver->pools, name); - storageDriverUnlock(); - - if (!pool) { - virReportError(VIR_ERR_NO_STORAGE_POOL, - _("no storage pool with matching name '%s'"), name); + if (!(obj =3D storagePoolObjFindByName(name))) return NULL; - } + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolLookupByNameEnsureACL(conn, pool->def) < 0) + if (virStoragePoolLookupByNameEnsureACL(conn, def) < 0) goto cleanup; =20 - ret =3D virGetStoragePool(conn, pool->def->name, pool->def->uuid, - NULL, NULL); + ret =3D virGetStoragePool(conn, def->name, def->uuid, NULL, NULL); =20 cleanup: - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 + static virStoragePoolPtr -storagePoolLookupByVolume(virStorageVolPtr vol) +storagePoolLookupByVolume(virStorageVolPtr volume) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; virStoragePoolPtr ret =3D NULL; =20 - storageDriverLock(); - pool =3D virStoragePoolObjFindByName(&driver->pools, vol->pool); - storageDriverUnlock(); - - if (!pool) { + if (!(obj =3D virPoolObjTableFindByName(driver->pools, volume->pool)))= { virReportError(VIR_ERR_NO_STORAGE_POOL, _("no storage pool with matching name '%s'"), - vol->pool); + volume->pool); return NULL; } + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolLookupByVolumeEnsureACL(vol->conn, pool->def) < 0) + if (virStoragePoolLookupByVolumeEnsureACL(volume->conn, def) < 0) goto cleanup; =20 - ret =3D virGetStoragePool(vol->conn, pool->def->name, pool->def->uuid, - NULL, NULL); + ret =3D virGetStoragePool(volume->conn, def->name, def->uuid, NULL, NU= LL); =20 cleanup: - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 + static int storageConnectNumOfStoragePools(virConnectPtr conn) { - size_t i; - int nactive =3D 0; =20 if (virConnectNumOfStoragePoolsEnsureACL(conn) < 0) return -1; =20 - storageDriverLock(); - for (i =3D 0; i < driver->pools.count; i++) { - virStoragePoolObjPtr obj =3D driver->pools.objs[i]; - virStoragePoolObjLock(obj); - if (virConnectNumOfStoragePoolsCheckACL(conn, obj->def) && - virStoragePoolObjIsActive(obj)) - nactive++; - virStoragePoolObjUnlock(obj); - } - storageDriverUnlock(); - - return nactive; + return virStoragePoolObjNumOfStoragePools(driver->pools, conn, true, + virConnectNumOfStoragePoolsCheck= ACL); } =20 + static int storageConnectListStoragePools(virConnectPtr conn, char **const names, - int nnames) + int maxnames) { - int got =3D 0; - size_t i; - if (virConnectListStoragePoolsEnsureACL(conn) < 0) return -1; =20 - storageDriverLock(); - for (i =3D 0; i < driver->pools.count && got < nnames; i++) { - virStoragePoolObjPtr obj =3D driver->pools.objs[i]; - virStoragePoolObjLock(obj); - if (virConnectListStoragePoolsCheckACL(conn, obj->def) && - virStoragePoolObjIsActive(obj)) { - if (VIR_STRDUP(names[got], obj->def->name) < 0) { - virStoragePoolObjUnlock(obj); - goto cleanup; - } - got++; - } - virStoragePoolObjUnlock(obj); - } - storageDriverUnlock(); - return got; - - cleanup: - storageDriverUnlock(); - for (i =3D 0; i < got; i++) - VIR_FREE(names[i]); - memset(names, 0, nnames * sizeof(*names)); - return -1; + return virStoragePoolObjGetNames(driver->pools, conn, true, + virConnectListStoragePoolsCheckACL, + names, maxnames); } =20 + static int storageConnectNumOfDefinedStoragePools(virConnectPtr conn) { - size_t i; - int nactive =3D 0; - if (virConnectNumOfDefinedStoragePoolsEnsureACL(conn) < 0) return -1; =20 - storageDriverLock(); - for (i =3D 0; i < driver->pools.count; i++) { - virStoragePoolObjPtr obj =3D driver->pools.objs[i]; - virStoragePoolObjLock(obj); - if (virConnectNumOfDefinedStoragePoolsCheckACL(conn, obj->def) && - !virStoragePoolObjIsActive(obj)) - nactive++; - virStoragePoolObjUnlock(obj); - } - storageDriverUnlock(); - - return nactive; + return virStoragePoolObjNumOfStoragePools(driver->pools, conn, false, + virConnectNumOfDefinedStoragePoolsCheck= ACL); } =20 + static int storageConnectListDefinedStoragePools(virConnectPtr conn, char **const names, - int nnames) + int maxnames) { - int got =3D 0; - size_t i; - if (virConnectListDefinedStoragePoolsEnsureACL(conn) < 0) return -1; =20 - storageDriverLock(); - for (i =3D 0; i < driver->pools.count && got < nnames; i++) { - virStoragePoolObjPtr obj =3D driver->pools.objs[i]; - virStoragePoolObjLock(obj); - if (virConnectListDefinedStoragePoolsCheckACL(conn, obj->def) && - !virStoragePoolObjIsActive(obj)) { - if (VIR_STRDUP(names[got], obj->def->name) < 0) { - virStoragePoolObjUnlock(obj); - goto cleanup; - } - got++; - } - virStoragePoolObjUnlock(obj); - } - storageDriverUnlock(); - return got; - - cleanup: - storageDriverUnlock(); - for (i =3D 0; i < got; i++) - VIR_FREE(names[i]); - memset(names, 0, nnames * sizeof(*names)); - return -1; + return virStoragePoolObjGetNames(driver->pools, conn, false, + virConnectListDefinedStoragePoolsChec= kACL, + names, maxnames); } =20 + /* This method is required to be re-entrant / thread safe, so uses no driver lock */ static char * @@ -609,58 +565,46 @@ storageConnectFindStoragePoolSources(virConnectPtr co= nn, } =20 =20 -static virStoragePoolObjPtr -virStoragePoolObjFromStoragePool(virStoragePoolPtr pool) -{ - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virStoragePoolObjPtr ret; - - storageDriverLock(); - if (!(ret =3D virStoragePoolObjFindByUUID(&driver->pools, pool->uuid))= ) { - virUUIDFormat(pool->uuid, uuidstr); - virReportError(VIR_ERR_NO_STORAGE_POOL, - _("no storage pool with matching uuid '%s' (%s)"), - uuidstr, pool->name); - } - storageDriverUnlock(); - - return ret; -} - - -static int storagePoolIsActive(virStoragePoolPtr pool) +static int +storagePoolIsActive(virStoragePoolPtr pool) { - virStoragePoolObjPtr obj; + virPoolObjPtr obj; + virStoragePoolDefPtr def; int ret =3D -1; =20 - if (!(obj =3D virStoragePoolObjFromStoragePool(pool))) + if (!(obj =3D storagePoolObjFromStoragePool(pool))) return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolIsActiveEnsureACL(pool->conn, obj->def) < 0) + if (virStoragePoolIsActiveEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - ret =3D virStoragePoolObjIsActive(obj); + ret =3D virPoolObjIsActive(obj); =20 cleanup: - virStoragePoolObjUnlock(obj); + virPoolObjEndAPI(&obj); return ret; } =20 -static int storagePoolIsPersistent(virStoragePoolPtr pool) + +static int +storagePoolIsPersistent(virStoragePoolPtr pool) { - virStoragePoolObjPtr obj; + virPoolObjPtr obj; + virStoragePoolDefPtr def; int ret =3D -1; =20 - if (!(obj =3D virStoragePoolObjFromStoragePool(pool))) + if (!(obj =3D storagePoolObjFromStoragePool(pool))) return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolIsPersistentEnsureACL(pool->conn, obj->def) < 0) + if (virStoragePoolIsPersistentEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - ret =3D obj->configFile ? 1 : 0; + ret =3D virStoragePoolObjPrivateGetConfigFile(obj) ? 1 : 0; =20 cleanup: - virStoragePoolObjUnlock(obj); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -671,7 +615,8 @@ storagePoolCreateXML(virConnectPtr conn, unsigned int flags) { virStoragePoolDefPtr def; - virStoragePoolObjPtr pool =3D NULL; + virPoolObjPtr obj =3D NULL; + virStoragePoolDefPtr pooldef; virStoragePoolPtr ret =3D NULL; virStorageBackendPtr backend; virObjectEventPtr event =3D NULL; @@ -685,25 +630,24 @@ storagePoolCreateXML(virConnectPtr conn, VIR_EXCLUSIVE_FLAGS_RET(VIR_STORAGE_POOL_BUILD_OVERWRITE, VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, NULL); =20 - storageDriverLock(); if (!(def =3D virStoragePoolDefParseString(xml))) - goto cleanup; + return NULL; =20 if (virStoragePoolCreateXMLEnsureACL(conn, def) < 0) goto cleanup; =20 - if (virStoragePoolObjIsDuplicate(&driver->pools, def, 1) < 0) + if (virStoragePoolObjIsDuplicate(driver->pools, def, 1) < 0) goto cleanup; =20 - if (virStoragePoolSourceFindDuplicate(conn, &driver->pools, def) < 0) + if (virStoragePoolObjFindDuplicate(driver->pools, conn, def)) goto cleanup; =20 if ((backend =3D virStorageBackendForType(def->type)) =3D=3D NULL) goto cleanup; =20 - if (!(pool =3D virStoragePoolObjAssignDef(&driver->pools, def))) + if (!(obj =3D virStoragePoolObjAdd(driver->pools, def))) goto cleanup; - def =3D NULL; + VIR_STEAL_PTR(pooldef, def); =20 if (backend->buildPool) { if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE) @@ -713,73 +657,67 @@ storagePoolCreateXML(virConnectPtr conn, =20 if (build_flags || (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) { - if (backend->buildPool(conn, pool, build_flags) < 0) { - virStoragePoolObjRemove(&driver->pools, pool); - pool =3D NULL; + if (backend->buildPool(conn, obj, build_flags) < 0) { + virPoolObjTableRemove(driver->pools, &obj); goto cleanup; } } } =20 if (backend->startPool && - backend->startPool(conn, pool) < 0) { - virStoragePoolObjRemove(&driver->pools, pool); - pool =3D NULL; + backend->startPool(conn, obj) < 0) { + virPoolObjTableRemove(driver->pools, &obj); goto cleanup; } =20 - stateFile =3D virFileBuildPath(driver->stateDir, - pool->def->name, ".xml"); + stateFile =3D virFileBuildPath(driver->stateDir, pooldef->name, ".xml"= ); =20 - virStoragePoolObjClearVols(pool); - if (!stateFile || virStoragePoolSaveState(stateFile, pool->def) < 0 || - backend->refreshPool(conn, pool) < 0) { + virStoragePoolObjClearVols(obj); + if (!stateFile || virStoragePoolSaveState(stateFile, pooldef) < 0 || + backend->refreshPool(conn, obj) < 0) { if (stateFile) unlink(stateFile); if (backend->stopPool) - backend->stopPool(conn, pool); - virStoragePoolObjRemove(&driver->pools, pool); - pool =3D NULL; + backend->stopPool(conn, obj); + virPoolObjTableRemove(driver->pools, &obj); goto cleanup; } =20 - event =3D virStoragePoolEventLifecycleNew(pool->def->name, - pool->def->uuid, + event =3D virStoragePoolEventLifecycleNew(pooldef->name, + pooldef->uuid, VIR_STORAGE_POOL_EVENT_STARTED, 0); =20 - VIR_INFO("Creating storage pool '%s'", pool->def->name); - pool->active =3D true; + VIR_INFO("Creating storage pool '%s'", pooldef->name); + virPoolObjSetActive(obj, true); =20 - ret =3D virGetStoragePool(conn, pool->def->name, pool->def->uuid, - NULL, NULL); + ret =3D virGetStoragePool(conn, pooldef->name, pooldef->uuid, NULL, NU= LL); =20 cleanup: VIR_FREE(stateFile); virStoragePoolDefFree(def); if (event) virObjectEventStateQueue(driver->storageEventState, event); - if (pool) - virStoragePoolObjUnlock(pool); - storageDriverUnlock(); + virPoolObjEndAPI(&obj); return ret; } =20 + static virStoragePoolPtr storagePoolDefineXML(virConnectPtr conn, const char *xml, unsigned int flags) { virStoragePoolDefPtr def; - virStoragePoolObjPtr pool =3D NULL; + virPoolObjPtr obj =3D NULL; + virStoragePoolDefPtr pooldef; virStoragePoolPtr ret =3D NULL; virObjectEventPtr event =3D NULL; =20 virCheckFlags(0, NULL); =20 - storageDriverLock(); if (!(def =3D virStoragePoolDefParseString(xml))) - goto cleanup; + return NULL; =20 if (virXMLCheckIllegalChars("name", def->name, "\n") < 0) goto cleanup; @@ -787,117 +725,95 @@ storagePoolDefineXML(virConnectPtr conn, if (virStoragePoolDefineXMLEnsureACL(conn, def) < 0) goto cleanup; =20 - if (virStoragePoolObjIsDuplicate(&driver->pools, def, 0) < 0) + if (virStoragePoolObjIsDuplicate(driver->pools, def, 0) < 0) goto cleanup; =20 - if (virStoragePoolSourceFindDuplicate(conn, &driver->pools, def) < 0) + if (virStoragePoolObjFindDuplicate(driver->pools, conn, def)) goto cleanup; =20 if (virStorageBackendForType(def->type) =3D=3D NULL) goto cleanup; =20 - if (!(pool =3D virStoragePoolObjAssignDef(&driver->pools, def))) + if (!(obj =3D virStoragePoolObjAdd(driver->pools, def))) goto cleanup; + VIR_STEAL_PTR(pooldef, def); =20 - if (virStoragePoolObjSaveDef(driver, pool, def) < 0) { - virStoragePoolObjRemove(&driver->pools, pool); - def =3D NULL; - pool =3D NULL; + if (virStoragePoolObjSaveDef(driver, obj) < 0) { + virPoolObjTableRemove(driver->pools, &obj); goto cleanup; } =20 - event =3D virStoragePoolEventLifecycleNew(def->name, def->uuid, + event =3D virStoragePoolEventLifecycleNew(pooldef->name, pooldef->uuid, VIR_STORAGE_POOL_EVENT_DEFINED, 0); =20 - def =3D NULL; - - VIR_INFO("Defining storage pool '%s'", pool->def->name); - ret =3D virGetStoragePool(conn, pool->def->name, pool->def->uuid, - NULL, NULL); + VIR_INFO("Defining storage pool '%s'", pooldef->name); + ret =3D virGetStoragePool(conn, pooldef->name, pooldef->uuid, NULL, NU= LL); =20 cleanup: if (event) virObjectEventStateQueue(driver->storageEventState, event); virStoragePoolDefFree(def); - if (pool) - virStoragePoolObjUnlock(pool); - storageDriverUnlock(); + virPoolObjEndAPI(&obj); return ret; } =20 + static int -storagePoolUndefine(virStoragePoolPtr obj) +storagePoolUndefine(virStoragePoolPtr pool) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; virObjectEventPtr event =3D NULL; int ret =3D -1; =20 - storageDriverLock(); - if (!(pool =3D virStoragePoolObjFindByUUID(&driver->pools, obj->uuid))= ) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(obj->uuid, uuidstr); - virReportError(VIR_ERR_NO_STORAGE_POOL, - _("no storage pool with matching uuid '%s' (%s)"), - uuidstr, obj->name); - goto cleanup; - } + if (!(obj =3D storagePoolObjFromStoragePool(pool))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolUndefineEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolUndefineEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if (virStoragePoolObjIsActive(pool)) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is still active"), - pool->def->name); + def->name); goto cleanup; } =20 - if (pool->asyncjobs > 0) { + if (virStoragePoolObjPrivateGetAsyncjobs(obj) > 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("pool '%s' has asynchronous jobs running."), - pool->def->name); + def->name); goto cleanup; } =20 - if (virStoragePoolObjDeleteDef(pool) < 0) + if (virStoragePoolObjDeleteDef(obj) < 0) goto cleanup; =20 - if (unlink(pool->autostartLink) < 0 && - errno !=3D ENOENT && - errno !=3D ENOTDIR) { - char ebuf[1024]; - VIR_ERROR(_("Failed to delete autostart link '%s': %s"), - pool->autostartLink, virStrerror(errno, ebuf, sizeof(ebu= f))); - } - - VIR_FREE(pool->configFile); - VIR_FREE(pool->autostartLink); - - event =3D virStoragePoolEventLifecycleNew(pool->def->name, - pool->def->uuid, + event =3D virStoragePoolEventLifecycleNew(def->name, + def->uuid, VIR_STORAGE_POOL_EVENT_UNDEFIN= ED, 0); =20 - VIR_INFO("Undefining storage pool '%s'", pool->def->name); - virStoragePoolObjRemove(&driver->pools, pool); - pool =3D NULL; + VIR_INFO("Undefining storage pool '%s'", def->name); + virPoolObjTableRemove(driver->pools, &obj); ret =3D 0; =20 cleanup: if (event) virObjectEventStateQueue(driver->storageEventState, event); - if (pool) - virStoragePoolObjUnlock(pool); - storageDriverUnlock(); + virPoolObjEndAPI(&obj); return ret; } =20 + static int -storagePoolCreate(virStoragePoolPtr obj, +storagePoolCreate(virStoragePoolPtr pool, unsigned int flags) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; virStorageBackendPtr backend; virObjectEventPtr event =3D NULL; int ret =3D -1; @@ -911,19 +827,20 @@ storagePoolCreate(virStoragePoolPtr obj, VIR_EXCLUSIVE_FLAGS_RET(VIR_STORAGE_POOL_BUILD_OVERWRITE, VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, -1); =20 - if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) + if (!(obj =3D storagePoolObjFromStoragePool(pool))) return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolCreateEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolCreateEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if ((backend =3D virStorageBackendForType(pool->def->type)) =3D=3D NUL= L) + if ((backend =3D virStorageBackendForType(def->type)) =3D=3D NULL) goto cleanup; =20 - if (virStoragePoolObjIsActive(pool)) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is already active"), - pool->def->name); + def->name); goto cleanup; } =20 @@ -935,199 +852,190 @@ storagePoolCreate(virStoragePoolPtr obj, =20 if (build_flags || (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) { - if (backend->buildPool(obj->conn, pool, build_flags) < 0) + if (backend->buildPool(pool->conn, obj, build_flags) < 0) goto cleanup; } } =20 - VIR_INFO("Starting up storage pool '%s'", pool->def->name); + VIR_INFO("Starting up storage pool '%s'", def->name); if (backend->startPool && - backend->startPool(obj->conn, pool) < 0) + backend->startPool(pool->conn, obj) < 0) goto cleanup; =20 - stateFile =3D virFileBuildPath(driver->stateDir, - pool->def->name, ".xml"); + stateFile =3D virFileBuildPath(driver->stateDir, def->name, ".xml"); =20 - virStoragePoolObjClearVols(pool); - if (!stateFile || virStoragePoolSaveState(stateFile, pool->def) < 0 || - backend->refreshPool(obj->conn, pool) < 0) { + virStoragePoolObjClearVols(obj); + if (!stateFile || virStoragePoolSaveState(stateFile, def) < 0 || + backend->refreshPool(pool->conn, obj) < 0) { if (stateFile) unlink(stateFile); if (backend->stopPool) - backend->stopPool(obj->conn, pool); + backend->stopPool(pool->conn, obj); goto cleanup; } =20 - event =3D virStoragePoolEventLifecycleNew(pool->def->name, - pool->def->uuid, + event =3D virStoragePoolEventLifecycleNew(def->name, + def->uuid, VIR_STORAGE_POOL_EVENT_STARTED, 0); =20 - pool->active =3D true; + virPoolObjSetActive(obj, true); ret =3D 0; =20 cleanup: VIR_FREE(stateFile); if (event) virObjectEventStateQueue(driver->storageEventState, event); - if (pool) - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 + static int -storagePoolBuild(virStoragePoolPtr obj, +storagePoolBuild(virStoragePoolPtr pool, unsigned int flags) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; virStorageBackendPtr backend; int ret =3D -1; =20 - if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) + if (!(obj =3D storagePoolObjFromStoragePool(pool))) return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolBuildEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolBuildEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if ((backend =3D virStorageBackendForType(pool->def->type)) =3D=3D NUL= L) + if ((backend =3D virStorageBackendForType(def->type)) =3D=3D NULL) goto cleanup; =20 - if (virStoragePoolObjIsActive(pool)) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is already active"), - pool->def->name); + def->name); goto cleanup; } =20 if (backend->buildPool && - backend->buildPool(obj->conn, pool, flags) < 0) + backend->buildPool(pool->conn, obj, flags) < 0) goto cleanup; ret =3D 0; =20 cleanup: - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 =20 static int -storagePoolDestroy(virStoragePoolPtr obj) +storagePoolDestroy(virStoragePoolPtr pool) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; + virStoragePoolDefPtr newDef; virStorageBackendPtr backend; virObjectEventPtr event =3D NULL; char *stateFile =3D NULL; int ret =3D -1; =20 - storageDriverLock(); - if (!(pool =3D virStoragePoolObjFindByUUID(&driver->pools, obj->uuid))= ) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(obj->uuid, uuidstr); - virReportError(VIR_ERR_NO_STORAGE_POOL, - _("no storage pool with matching uuid '%s' (%s)"), - uuidstr, obj->name); - goto cleanup; - } + if (!(obj =3D storagePoolObjFromStoragePool(pool))) + return -1; + def =3D virPoolObjGetDef(obj); + newDef =3D virPoolObjGetNewDef(obj); =20 - if (virStoragePoolDestroyEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolDestroyEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if ((backend =3D virStorageBackendForType(pool->def->type)) =3D=3D NUL= L) + if ((backend =3D virStorageBackendForType(def->type)) =3D=3D NULL) goto cleanup; =20 - VIR_INFO("Destroying storage pool '%s'", pool->def->name); + VIR_INFO("Destroying storage pool '%s'", def->name); =20 - if (!virStoragePoolObjIsActive(pool)) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), pool->def->na= me); + _("storage pool '%s' is not active"), def->name); goto cleanup; } =20 - if (pool->asyncjobs > 0) { + if (virStoragePoolObjPrivateGetAsyncjobs(obj) > 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("pool '%s' has asynchronous jobs running."), - pool->def->name); + def->name); goto cleanup; } =20 - if (!(stateFile =3D virFileBuildPath(driver->stateDir, - pool->def->name, - ".xml"))) + if (!(stateFile =3D virFileBuildPath(driver->stateDir, def->name, ".xm= l"))) goto cleanup; =20 unlink(stateFile); VIR_FREE(stateFile); =20 if (backend->stopPool && - backend->stopPool(obj->conn, pool) < 0) + backend->stopPool(pool->conn, obj) < 0) goto cleanup; =20 - virStoragePoolObjClearVols(pool); + virStoragePoolObjClearVols(obj); =20 - event =3D virStoragePoolEventLifecycleNew(pool->def->name, - pool->def->uuid, + event =3D virStoragePoolEventLifecycleNew(def->name, + def->uuid, VIR_STORAGE_POOL_EVENT_STOPPED, 0); =20 - pool->active =3D false; + virPoolObjSetActive(obj, false); =20 - if (pool->configFile =3D=3D NULL) { - virStoragePoolObjRemove(&driver->pools, pool); - pool =3D NULL; - } else if (pool->newDef) { - virStoragePoolDefFree(pool->def); - pool->def =3D pool->newDef; - pool->newDef =3D NULL; - } + if (!virStoragePoolObjPrivateGetConfigFile(obj)) + virPoolObjTableRemove(driver->pools, &obj); + else if (newDef) + virPoolObjSetDef(obj, newDef); =20 ret =3D 0; =20 cleanup: if (event) virObjectEventStateQueue(driver->storageEventState, event); - if (pool) - virStoragePoolObjUnlock(pool); - storageDriverUnlock(); + virPoolObjEndAPI(&obj); return ret; } =20 + static int -storagePoolDelete(virStoragePoolPtr obj, +storagePoolDelete(virStoragePoolPtr pool, unsigned int flags) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; virStorageBackendPtr backend; char *stateFile =3D NULL; int ret =3D -1; =20 - if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) + if (!(obj =3D storagePoolObjFromStoragePool(pool))) return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolDeleteEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolDeleteEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if ((backend =3D virStorageBackendForType(pool->def->type)) =3D=3D NUL= L) + if ((backend =3D virStorageBackendForType(def->type)) =3D=3D NULL) goto cleanup; =20 - VIR_INFO("Deleting storage pool '%s'", pool->def->name); + VIR_INFO("Deleting storage pool '%s'", def->name); =20 - if (virStoragePoolObjIsActive(pool)) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is still active"), - pool->def->name); + def->name); goto cleanup; } =20 - if (pool->asyncjobs > 0) { + if (virStoragePoolObjPrivateGetAsyncjobs(obj) > 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("pool '%s' has asynchronous jobs running."), - pool->def->name); + def->name); goto cleanup; } =20 - if (!(stateFile =3D virFileBuildPath(driver->stateDir, - pool->def->name, - ".xml"))) + if (!(stateFile =3D virFileBuildPath(driver->stateDir, def->name, ".xm= l"))) goto cleanup; =20 unlink(stateFile); @@ -1138,204 +1046,200 @@ storagePoolDelete(virStoragePoolPtr obj, "%s", _("pool does not support pool deletion")); goto cleanup; } - if (backend->deletePool(obj->conn, pool, flags) < 0) + if (backend->deletePool(pool->conn, obj, flags) < 0) goto cleanup; =20 ret =3D 0; =20 cleanup: - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 =20 static int -storagePoolRefresh(virStoragePoolPtr obj, +storagePoolRefresh(virStoragePoolPtr pool, unsigned int flags) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; virStorageBackendPtr backend; int ret =3D -1; virObjectEventPtr event =3D NULL; =20 virCheckFlags(0, -1); =20 - storageDriverLock(); - if (!(pool =3D virStoragePoolObjFindByUUID(&driver->pools, obj->uuid))= ) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(obj->uuid, uuidstr); - virReportError(VIR_ERR_NO_STORAGE_POOL, - _("no storage pool with matching uuid '%s' (%s)"), - uuidstr, obj->name); - goto cleanup; - } + if (!(obj =3D storagePoolObjFromStoragePool(pool))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolRefreshEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolRefreshEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if ((backend =3D virStorageBackendForType(pool->def->type)) =3D=3D NUL= L) + if ((backend =3D virStorageBackendForType(def->type)) =3D=3D NULL) goto cleanup; =20 - if (!virStoragePoolObjIsActive(pool)) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), pool->def->na= me); + _("storage pool '%s' is not active"), def->name); goto cleanup; } =20 - if (pool->asyncjobs > 0) { + if (virStoragePoolObjPrivateGetAsyncjobs(obj) > 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("pool '%s' has asynchronous jobs running."), - pool->def->name); + def->name); goto cleanup; } =20 - virStoragePoolObjClearVols(pool); - if (backend->refreshPool(obj->conn, pool) < 0) { + virStoragePoolObjClearVols(obj); + if (backend->refreshPool(pool->conn, obj) < 0) { if (backend->stopPool) - backend->stopPool(obj->conn, pool); + backend->stopPool(pool->conn, obj); =20 - event =3D virStoragePoolEventLifecycleNew(pool->def->name, - pool->def->uuid, + event =3D virStoragePoolEventLifecycleNew(def->name, + def->uuid, VIR_STORAGE_POOL_EVENT_STO= PPED, 0); - pool->active =3D false; + virPoolObjSetActive(obj, false); =20 - if (pool->configFile =3D=3D NULL) { - virStoragePoolObjRemove(&driver->pools, pool); - pool =3D NULL; - } + if (!virStoragePoolObjPrivateGetConfigFile(obj)) + virPoolObjTableRemove(driver->pools, &obj); goto cleanup; } =20 - event =3D virStoragePoolEventRefreshNew(pool->def->name, - pool->def->uuid); + event =3D virStoragePoolEventRefreshNew(def->name, def->uuid); ret =3D 0; =20 cleanup: if (event) virObjectEventStateQueue(driver->storageEventState, event); - if (pool) - virStoragePoolObjUnlock(pool); - storageDriverUnlock(); + virPoolObjEndAPI(&obj); return ret; } =20 =20 static int -storagePoolGetInfo(virStoragePoolPtr obj, +storagePoolGetInfo(virStoragePoolPtr pool, virStoragePoolInfoPtr info) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; int ret =3D -1; =20 - if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) + if (!(obj =3D storagePoolObjFromStoragePool(pool))) return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolGetInfoEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolGetInfoEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if (virStorageBackendForType(pool->def->type) =3D=3D NULL) + if (virStorageBackendForType(def->type) =3D=3D NULL) goto cleanup; =20 memset(info, 0, sizeof(virStoragePoolInfo)); - if (pool->active) + if (virPoolObjIsActive(obj)) info->state =3D VIR_STORAGE_POOL_RUNNING; else info->state =3D VIR_STORAGE_POOL_INACTIVE; - info->capacity =3D pool->def->capacity; - info->allocation =3D pool->def->allocation; - info->available =3D pool->def->available; + info->capacity =3D def->capacity; + info->allocation =3D def->allocation; + info->available =3D def->available; ret =3D 0; =20 cleanup: - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 + static char * -storagePoolGetXMLDesc(virStoragePoolPtr obj, +storagePoolGetXMLDesc(virStoragePoolPtr pool, unsigned int flags) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; virStoragePoolDefPtr def; + virStoragePoolDefPtr newDef; char *ret =3D NULL; =20 virCheckFlags(VIR_STORAGE_XML_INACTIVE, NULL); =20 - if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) + if (!(obj =3D storagePoolObjFromStoragePool(pool))) return NULL; + def =3D virPoolObjGetDef(obj); + newDef =3D virPoolObjGetNewDef(obj); =20 - if (virStoragePoolGetXMLDescEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolGetXMLDescEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if ((flags & VIR_STORAGE_XML_INACTIVE) && pool->newDef) - def =3D pool->newDef; - else - def =3D pool->def; + if ((flags & VIR_STORAGE_XML_INACTIVE) && newDef) + def =3D newDef; =20 ret =3D virStoragePoolDefFormat(def); =20 cleanup: - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 + static int -storagePoolGetAutostart(virStoragePoolPtr obj, +storagePoolGetAutostart(virStoragePoolPtr pool, int *autostart) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; int ret =3D -1; =20 - if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) + if (!(obj =3D storagePoolObjFromStoragePool(pool))) return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virStoragePoolGetAutostartEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolGetAutostartEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if (!pool->configFile) { - *autostart =3D 0; - } else { - *autostart =3D pool->autostart; - } + *autostart =3D 0; + if (virStoragePoolObjPrivateGetConfigFile(obj) && + virPoolObjIsAutostart(obj)) + *autostart =3D 1; + ret =3D 0; =20 cleanup: - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 + static int -storagePoolSetAutostart(virStoragePoolPtr obj, - int autostart) +storagePoolSetAutostart(virStoragePoolPtr pool, + int new_autostart) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; + bool autostart; + const char *configFile; int ret =3D -1; =20 - storageDriverLock(); - pool =3D virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); - - if (!pool) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(obj->uuid, uuidstr); - virReportError(VIR_ERR_NO_STORAGE_POOL, - _("no storage pool with matching uuid '%s' (%s)"), - uuidstr, obj->name); - goto cleanup; - } + if (!(obj =3D storagePoolObjFromStoragePool(pool))) + return -1; + def =3D virPoolObjGetDef(obj); + configFile =3D virStoragePoolObjPrivateGetConfigFile(obj); =20 - if (virStoragePoolSetAutostartEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolSetAutostartEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if (!pool->configFile) { + if (!configFile) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("pool has no config file")); goto cleanup; } =20 - autostart =3D (autostart !=3D 0); + autostart =3D (new_autostart !=3D 0); =20 - if (pool->autostart !=3D autostart) { + if (virPoolObjIsAutostart(obj) !=3D autostart) { + const char *autostartLink =3D + virStoragePoolObjPrivateGetAutostartLink(obj); if (autostart) { if (virFileMakePath(driver->autostartDir) < 0) { virReportSystemError(errno, @@ -1344,47 +1248,50 @@ storagePoolSetAutostart(virStoragePoolPtr obj, goto cleanup; } =20 - if (symlink(pool->configFile, pool->autostartLink) < 0) { + if (symlink(configFile, autostartLink) < 0) { virReportSystemError(errno, _("Failed to create symlink '%s' to '= %s'"), - pool->autostartLink, pool->configFile= ); + autostartLink, configFile); goto cleanup; } } else { - if (unlink(pool->autostartLink) < 0 && + if (unlink(autostartLink) < 0 && errno !=3D ENOENT && errno !=3D ENOTDIR) { virReportSystemError(errno, _("Failed to delete symlink '%s'"), - pool->autostartLink); + autostartLink); goto cleanup; } } - pool->autostart =3D autostart; + virPoolObjSetAutostart(obj, autostart); } ret =3D 0; =20 cleanup: - if (pool) - virStoragePoolObjUnlock(pool); - storageDriverUnlock(); + virPoolObjEndAPI(&obj); return ret; } =20 + static int -storagePoolNumOfVolumes(virStoragePoolPtr obj) +storagePoolNumOfVolumes(virStoragePoolPtr pool) { - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; + virPoolObjTablePtr objvolumes; int ret =3D -1; =20 - if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) + if (!(obj =3D storagePoolObjFromStoragePool(pool))) return -1; + def =3D virPoolObjGetDef(obj); + objvolumes =3D virStoragePoolObjPrivateGetVolumes(obj); =20 - if (virStoragePoolNumOfVolumesEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolNumOfVolumesEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if (!virStoragePoolObjIsActive(pool)) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), pool->def->na= me); + _("storage pool '%s' is not active"), def->name); goto cleanup; } =20 @@ -1392,34 +1299,38 @@ storagePoolNumOfVolumes(virStoragePoolPtr obj) * function requires 3 instead of 2 params for virPoolObjACLFilter. * Setting up this way fulfills check-aclrules.pl's check that the * driver function calls the CheckACL API */ - ret =3D virStoragePoolObjNumOfVolumes(pool->volumes, obj->conn, pool->= def, + ret =3D virStoragePoolObjNumOfVolumes(objvolumes, pool->conn, def, virStoragePoolNumOfVolumesCheckACL= ); =20 cleanup: - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 =20 static int -storagePoolListVolumes(virStoragePoolPtr obj, +storagePoolListVolumes(virStoragePoolPtr pool, char **const names, int maxnames) { int ret =3D -1; - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; + virPoolObjTablePtr objvolumes; =20 memset(names, 0, maxnames * sizeof(*names)); =20 - if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) + if (!(obj =3D storagePoolObjFromStoragePool(pool))) return -1; + def =3D virPoolObjGetDef(obj); + objvolumes =3D virStoragePoolObjPrivateGetVolumes(obj); =20 - if (virStoragePoolListVolumesEnsureACL(obj->conn, pool->def) < 0) + if (virStoragePoolListVolumesEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if (!virStoragePoolObjIsActive(pool)) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), pool->def->na= me); + _("storage pool '%s' is not active"), def->name); goto cleanup; } =20 @@ -1427,12 +1338,12 @@ storagePoolListVolumes(virStoragePoolPtr obj, * function requires 3 instead of 2 params for virPoolObjACLFilter. * Setting up this way fulfills check-aclrules.pl's check that the * driver function calls the CheckACL API */ - ret =3D virStoragePoolObjListVolumes(pool->volumes, obj->conn, pool->d= ef, + ret =3D virStoragePoolObjListVolumes(objvolumes, pool->conn, def, virStoragePoolListVolumesCheckACL, names, maxnames); =20 cleanup: - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -1442,7 +1353,9 @@ storagePoolListAllVolumes(virStoragePoolPtr pool, virStorageVolPtr **volumes, unsigned int flags) { - virStoragePoolObjPtr obj; + virPoolObjPtr obj; + virStoragePoolDefPtr def; + virPoolObjTablePtr objvolumes; virPoolObjPtr *volobjs =3D NULL; size_t nvolobjs =3D 0; size_t i; @@ -1452,19 +1365,21 @@ storagePoolListAllVolumes(virStoragePoolPtr pool, =20 virCheckFlags(0, -1); =20 - if (!(obj =3D virStoragePoolObjFromStoragePool(pool))) + if (!(obj =3D storagePoolObjFromStoragePool(pool))) return -1; + def =3D virPoolObjGetDef(obj); + objvolumes =3D virStoragePoolObjPrivateGetVolumes(obj); =20 - if (virStoragePoolListAllVolumesEnsureACL(pool->conn, obj->def) < 0) + if (virStoragePoolListAllVolumesEnsureACL(pool->conn, def) < 0) goto cleanup; =20 - if (!virStoragePoolObjIsActive(obj)) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), obj->def->nam= e); + _("storage pool '%s' is not active"), def->name); goto cleanup; } =20 - if (virPoolObjTableCollect(obj->volumes, pool->conn, &volobjs, &nvolob= js, + if (virPoolObjTableCollect(objvolumes, pool->conn, &volobjs, &nvolobjs, NULL, NULL, flags) < 0) goto cleanup; =20 @@ -1475,16 +1390,15 @@ storagePoolListAllVolumes(virStoragePoolPtr pool, for (i =3D 0; i < nvolobjs; i++) { bool passacl =3D false; virPoolObjPtr volobj =3D volobjs[i]; - virStorageVolDefPtr def; + virStorageVolDefPtr voldef; =20 virObjectLock(volobj); - def =3D virPoolObjGetDef(volobj); + voldef =3D virPoolObjGetDef(volobj); /* NB: Cannot call ACL filter in Collect function since it * takes 3 params and the volume ACL filter requires 3 */ - if (virStoragePoolListAllVolumesCheckACL(pool->conn, obj->def, - obj)) { - vols[nvols++] =3D virGetStorageVol(pool->conn, obj->def->n= ame, - def->name, def->key, + if (virStoragePoolListAllVolumesCheckACL(pool->conn, def, obj)= ) { + vols[nvols++] =3D virGetStorageVol(pool->conn, def->name, + voldef->name, voldef->key, NULL, NULL); passacl =3D true; } @@ -1503,28 +1417,32 @@ storagePoolListAllVolumes(virStoragePoolPtr pool, cleanup: virObjectListFree(vols); virObjectListFreeCount(volobjs, nvolobjs); + virPoolObjEndAPI(&obj); return ret; } =20 + static virStorageVolPtr -storageVolLookupByName(virStoragePoolPtr obj, +storageVolLookupByName(virStoragePoolPtr pool, const char *name) { - virStoragePoolObjPtr pool; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj =3D NULL; virStorageVolDefPtr voldef; virStorageVolPtr ret =3D NULL; =20 - if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) + if (!(poolobj =3D storagePoolObjFromStoragePool(pool))) return NULL; + pooldef =3D virPoolObjGetDef(poolobj); =20 - if (!virStoragePoolObjIsActive(pool)) { + if (!virPoolObjIsActive(poolobj)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), pool->def->na= me); + _("storage pool '%s' is not active"), pooldef->name= ); goto cleanup; } =20 - if (!(volobj =3D virStorageVolObjFindByName(pool, name))) { + if (!(volobj =3D virStorageVolObjFindByName(poolobj, name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), name); @@ -1532,89 +1450,99 @@ storageVolLookupByName(virStoragePoolPtr obj, } voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolLookupByNameEnsureACL(obj->conn, pool->def, voldef) <= 0) + if (virStorageVolLookupByNameEnsureACL(pool->conn, pooldef, voldef) < = 0) goto cleanup; =20 - ret =3D virGetStorageVol(obj->conn, pool->def->name, voldef->name, - voldef->key, NULL, NULL); + ret =3D virGetStorageVol(pool->conn, pooldef->name, voldef->name, vold= ef->key, + NULL, NULL); =20 cleanup: virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&poolobj); return ret; } =20 =20 +/* NB: Cannot use the "real" name since check-aclrules.pl will get confuse= d */ +typedef int (*ensureFilter)(virConnectPtr conn, + virStoragePoolDefPtr pool, + void *opaque); +struct storageSearchData { + virConnectPtr conn; + ensureFilter aclfilter; + const char *key; + const char *path; + char *retname; + char *retkey; +}; + +static bool +storageVolSearchByKey(virPoolObjPtr obj, + void *opaque) +{ + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + struct storageSearchData *data =3D opaque; + + if (virPoolObjIsActive(obj)) { + virPoolObjPtr volobj; + + if ((volobj =3D virStorageVolObjFindByKey(obj, data->key))) { + virStorageVolDefPtr voldef =3D virPoolObjGetDef(volobj); + + if (data->aclfilter(data->conn, def, voldef) =3D=3D 0) + ignore_value(VIR_STRDUP(data->retname, def->name)); + virPoolObjEndAPI(&volobj); + } + + if (data->retname) + return true; + } + + return false; +} + + static virStorageVolPtr storageVolLookupByKey(virConnectPtr conn, const char *key) { - size_t i; virStorageVolPtr ret =3D NULL; + virPoolObjPtr obj; + struct storageSearchData data =3D + { .conn =3D conn, + .aclfilter =3D virStorageVolLookupByKeyEnsureACL, + .key =3D key, + .retname =3D NULL }; =20 - storageDriverLock(); - for (i =3D 0; i < driver->pools.count && !ret; i++) { - virStoragePoolObjLock(driver->pools.objs[i]); - if (virStoragePoolObjIsActive(driver->pools.objs[i])) { - virPoolObjPtr volobj; - - if ((volobj =3D virStorageVolObjFindByKey(driver->pools.objs[i= ], - key))) { - virStoragePoolDefPtr def =3D driver->pools.objs[i]->def; - virStorageVolDefPtr voldef =3D virPoolObjGetDef(volobj); - - if (virStorageVolLookupByKeyEnsureACL(conn, def, voldef) <= 0) { - virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(driver->pools.objs[i]); - goto cleanup; - } + if ((obj =3D virPoolObjTableSearchRef(driver->pools, storageVolSearchB= yKey, + &data))) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); =20 - ret =3D virGetStorageVol(conn, - def->name, - voldef->name, - voldef->key, - NULL, NULL); - virPoolObjEndAPI(&volobj); - } - } - virStoragePoolObjUnlock(driver->pools.objs[i]); + ret =3D virGetStorageVol(conn, def->name, data.retname, key, NULL,= NULL); + VIR_FREE(data.retname); + virPoolObjEndAPI(&obj); } =20 if (!ret) virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching key %s"), key); =20 - cleanup: - storageDriverUnlock(); return ret; } =20 -static virStorageVolPtr -storageVolLookupByPath(virConnectPtr conn, - const char *path) -{ - size_t i; - virStorageVolPtr ret =3D NULL; - char *cleanpath; =20 - cleanpath =3D virFileSanitizePath(path); - if (!cleanpath) - return NULL; +static bool +storageVolSearchByPath(virPoolObjPtr obj, + void *opaque) +{ + virStoragePoolDefPtr pooldef =3D virPoolObjGetDef(obj); + struct storageSearchData *data =3D opaque; =20 - storageDriverLock(); - for (i =3D 0; i < driver->pools.count && !ret; i++) { - virStoragePoolObjPtr pool =3D driver->pools.objs[i]; - virPoolObjPtr volobj =3D NULL; + if (virPoolObjIsActive(obj)) { + virPoolObjPtr volobj; char *stable_path =3D NULL; =20 - virStoragePoolObjLock(pool); - - if (!virStoragePoolObjIsActive(pool)) { - virStoragePoolObjUnlock(pool); - continue; - } - - switch ((virStoragePoolType) pool->def->type) { + switch ((virStoragePoolType) pooldef->type) { case VIR_STORAGE_POOL_DIR: case VIR_STORAGE_POOL_FS: case VIR_STORAGE_POOL_NETFS: @@ -1624,17 +1552,14 @@ storageVolLookupByPath(virConnectPtr conn, case VIR_STORAGE_POOL_SCSI: case VIR_STORAGE_POOL_MPATH: case VIR_STORAGE_POOL_VSTORAGE: - stable_path =3D virStorageBackendStablePath(pool, - cleanpath, - false); - if (stable_path =3D=3D NULL) { + if (!(stable_path =3D virStorageBackendStablePath(obj, dat= a->path, + false))) { /* Don't break the whole lookup process if it fails on * getting the stable path for some of the pools. */ VIR_WARN("Failed to get stable path for pool '%s'", - pool->def->name); - virStoragePoolObjUnlock(pool); - continue; + pooldef->name); + return false; } break; =20 @@ -1643,32 +1568,57 @@ storageVolLookupByPath(virConnectPtr conn, case VIR_STORAGE_POOL_SHEEPDOG: case VIR_STORAGE_POOL_ZFS: case VIR_STORAGE_POOL_LAST: - if (VIR_STRDUP(stable_path, path) < 0) { - virStoragePoolObjUnlock(pool); - goto cleanup; - } + if (VIR_STRDUP(stable_path, data->path) < 0) + return false; break; } =20 - volobj =3D virStorageVolObjFindByPath(pool, stable_path); - VIR_FREE(stable_path); - - if (volobj) { + if ((volobj =3D virStorageVolObjFindByPath(obj, stable_path))) { virStorageVolDefPtr voldef =3D virPoolObjGetDef(volobj); - if (virStorageVolLookupByPathEnsureACL(conn, pool->def, - voldef) < 0) { - virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(pool); - goto cleanup; - } =20 - ret =3D virGetStorageVol(conn, pool->def->name, - voldef->name, voldef->key, - NULL, NULL); + if (data->aclfilter(data->conn, pooldef, voldef) =3D=3D 0) { + ignore_value(VIR_STRDUP(data->retname, voldef->name)); + ignore_value(VIR_STRDUP(data->retkey, voldef->key)); + } virPoolObjEndAPI(&volobj); } =20 - virStoragePoolObjUnlock(pool); + if (data->retname && data->retkey) + return true; + + VIR_FREE(data->retname); + VIR_FREE(data->retkey); + } + + return false; +} + + +static virStorageVolPtr +storageVolLookupByPath(virConnectPtr conn, + const char *path) +{ + virStorageVolPtr ret =3D NULL; + virPoolObjPtr obj; + struct storageSearchData data =3D + { .conn =3D conn, + .aclfilter =3D virStorageVolLookupByPathEnsureACL, + .retname =3D NULL, + .retkey =3D NULL }; + char *cleanpath; + + if (!(cleanpath =3D virFileSanitizePath(path))) + return NULL; + data.path =3D cleanpath; + + if ((obj =3D virPoolObjTableSearchRef(driver->pools, storageVolSearchB= yPath, + &data))) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + ret =3D virGetStorageVol(conn, def->name, data.retname, data.retke= y, + NULL, NULL); + VIR_FREE(data.retname); + VIR_FREE(data.retkey); + virPoolObjEndAPI(&obj); } =20 if (!ret) { @@ -1682,43 +1632,49 @@ storageVolLookupByPath(virConnectPtr conn, } } =20 - cleanup: VIR_FREE(cleanpath); - storageDriverUnlock(); return ret; } =20 + +static bool +storagePoolSearchByTargetPath(virPoolObjPtr obj, + void *opaque) +{ + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + struct storageSearchData *data =3D opaque; + + if (virPoolObjIsActive(obj)) { + if (STREQ(data->path, def->target.path)) + return true; + } + + return false; +} + + virStoragePoolPtr storagePoolLookupByTargetPath(virConnectPtr conn, const char *path) { - size_t i; virStoragePoolPtr ret =3D NULL; + virPoolObjPtr obj; + struct storageSearchData data =3D { 0 }; char *cleanpath; =20 - cleanpath =3D virFileSanitizePath(path); - if (!cleanpath) + if (!(cleanpath =3D virFileSanitizePath(path))) return NULL; + data.path =3D cleanpath; =20 - storageDriverLock(); - for (i =3D 0; i < driver->pools.count && !ret; i++) { - virStoragePoolObjPtr pool =3D driver->pools.objs[i]; - - virStoragePoolObjLock(pool); - - if (!virStoragePoolObjIsActive(pool)) { - virStoragePoolObjUnlock(pool); - continue; - } + if ((obj =3D virPoolObjTableSearchRef(driver->pools, + storagePoolSearchByTargetPath, + &data))) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); =20 - if (STREQ(path, pool->def->target.path)) { - ret =3D virGetStoragePool(conn, pool->def->name, pool->def->uu= id, - NULL, NULL); - } - - virStoragePoolObjUnlock(pool); + ret =3D virGetStoragePool(conn, def->name, def->uuid, NULL, NULL); + virPoolObjEndAPI(&obj); } - storageDriverUnlock(); + =20 if (!ret) { virReportError(VIR_ERR_NO_STORAGE_VOL, @@ -1732,35 +1688,28 @@ storagePoolLookupByTargetPath(virConnectPtr conn, =20 =20 static void -storageVolRemoveFromPool(virStoragePoolObjPtr pool, - virStorageVolDefPtr vol) +storageVolRemoveFromPool(virPoolObjPtr poolobj, + virPoolObjPtr *volobj) { - virPoolObjPtr obj; - - if (!(obj =3D virPoolObjTableFindByName(pool->volumes, vol->name))) { - virReportError(VIR_ERR_NO_STORAGE_VOL, - _("no storage vol with matching name '%s'"), - vol->name); - return; - } + virStorageVolDefPtr voldef =3D virPoolObjGetDef(*volobj); =20 VIR_INFO("Deleting volume '%s' from storage pool '%s'", - vol->name, pool->def->name); - - virStoragePoolObjRemoveVolume(pool, &obj); + voldef->name, voldef->name); =20 - virPoolObjEndAPI(&obj); + virStoragePoolObjRemoveVolume(poolobj, volobj); } =20 =20 static int -storageVolDeleteInternal(virStorageVolPtr obj, +storageVolDeleteInternal(virStorageVolPtr volume, virStorageBackendPtr backend, - virStoragePoolObjPtr pool, - virStorageVolDefPtr vol, + virPoolObjPtr poolobj, + virPoolObjPtr *volobj, unsigned int flags, bool updateMeta) { + virStoragePoolDefPtr pooldef =3D virPoolObjGetDef(poolobj); + virStorageVolDefPtr voldef =3D virPoolObjGetDef(*volobj); int ret =3D -1; =20 if (!backend->deleteVol) { @@ -1770,7 +1719,7 @@ storageVolDeleteInternal(virStorageVolPtr obj, goto cleanup; } =20 - if (backend->deleteVol(obj->conn, pool, vol, flags) < 0) + if (backend->deleteVol(volume->conn, poolobj, voldef, flags) < 0) goto cleanup; =20 /* Update pool metadata - don't update meta data from error paths @@ -1778,13 +1727,13 @@ storageVolDeleteInternal(virStorageVolPtr obj, * Ignore the disk backend since it updates the pool values. */ if (updateMeta) { - if (pool->def->type !=3D VIR_STORAGE_POOL_DISK) { - pool->def->allocation -=3D vol->target.allocation; - pool->def->available +=3D vol->target.allocation; + if (pooldef->type !=3D VIR_STORAGE_POOL_DISK) { + pooldef->allocation -=3D voldef->target.allocation; + pooldef->available +=3D voldef->target.allocation; } } =20 - storageVolRemoveFromPool(pool, vol); + storageVolRemoveFromPool(poolobj, volobj); ret =3D 0; =20 cleanup: @@ -1794,32 +1743,27 @@ storageVolDeleteInternal(virStorageVolPtr obj, =20 static virPoolObjPtr virStorageVolObjFromVol(virStorageVolPtr volume, - virStoragePoolObjPtr *pool, + virPoolObjPtr *pool, virStorageBackendPtr *backend) { - virPoolObjPtr volobj =3D NULL; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; + virPoolObjPtr volobj; =20 *pool =3D NULL; =20 - storageDriverLock(); - *pool =3D virStoragePoolObjFindByName(&driver->pools, volume->pool); - storageDriverUnlock(); - - if (!*pool) { - virReportError(VIR_ERR_NO_STORAGE_POOL, - _("no storage pool with matching name '%s'"), - volume->pool); + if (!(poolobj =3D storagePoolObjFindByName(volume->pool))) return NULL; - } + pooldef =3D virPoolObjGetDef(poolobj); =20 - if (!virStoragePoolObjIsActive(*pool)) { + if (!virPoolObjIsActive(poolobj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), - (*pool)->def->name); + pooldef->name); goto error; } =20 - if (!(volobj =3D virStorageVolObjFindByName(*pool, volume->name))) { + if (!(volobj =3D virStorageVolObjFindByName(poolobj, volume->name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), volume->name); @@ -1827,15 +1771,15 @@ virStorageVolObjFromVol(virStorageVolPtr volume, } =20 if (backend) { - if (!(*backend =3D virStorageBackendForType((*pool)->def->type))) + if (!(*backend =3D virStorageBackendForType(pooldef->type))) goto error; } =20 + *pool =3D poolobj; return volobj; =20 error: - virStoragePoolObjUnlock(*pool); - *pool =3D NULL; + virPoolObjEndAPI(&poolobj); =20 return NULL; } @@ -1845,17 +1789,19 @@ static int storageVolDelete(virStorageVolPtr volume, unsigned int flags) { - virStoragePoolObjPtr pool; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj; virStorageVolDefPtr voldef; virStorageBackendPtr backend; int ret =3D -1; =20 - if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &poolobj, &backend))) return -1; + pooldef =3D virPoolObjGetDef(poolobj); voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolDeleteEnsureACL(volume->conn, pool->def, voldef) < 0) + if (virStorageVolDeleteEnsureACL(volume->conn, pooldef, voldef) < 0) goto cleanup; =20 if (voldef->in_use) { @@ -1872,7 +1818,7 @@ storageVolDelete(virStorageVolPtr volume, goto cleanup; } =20 - if (storageVolDeleteInternal(volume, backend, pool, voldef, + if (storageVolDeleteInternal(volume, backend, poolobj, &volobj, flags, true) < 0) goto cleanup; =20 @@ -1880,39 +1826,41 @@ storageVolDelete(virStorageVolPtr volume, =20 cleanup: virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&poolobj); return ret; } =20 =20 static virStorageVolPtr -storageVolCreateXML(virStoragePoolPtr obj, +storageVolCreateXML(virStoragePoolPtr pool, const char *xmldesc, unsigned int flags) { - virStoragePoolObjPtr pool; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virStorageBackendPtr backend; virStorageVolDefPtr voldef =3D NULL; virStorageVolDefPtr objvoldef; virPoolObjPtr volobj =3D NULL; - virStorageVolPtr vol =3D NULL; + virStorageVolPtr volume =3D NULL; virStorageVolPtr ret =3D NULL; =20 virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL); =20 - if (!(pool =3D virStoragePoolObjFromStoragePool(obj))) + if (!(poolobj =3D storagePoolObjFromStoragePool(pool))) return NULL; + pooldef =3D virPoolObjGetDef(poolobj); =20 - if (!virStoragePoolObjIsActive(pool)) { + if (!virPoolObjIsActive(poolobj)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), pool->def->na= me); + _("storage pool '%s' is not active"), pooldef->name= ); goto cleanup; } =20 - if ((backend =3D virStorageBackendForType(pool->def->type)) =3D=3D NUL= L) + if ((backend =3D virStorageBackendForType(pooldef->type)) =3D=3D NULL) goto cleanup; =20 - if (!(voldef =3D virStorageVolDefParseString(pool->def, xmldesc, + if (!(voldef =3D virStorageVolDefParseString(pooldef, xmldesc, VIR_VOL_XML_PARSE_OPT_CAPAC= ITY))) goto cleanup; =20 @@ -1923,10 +1871,10 @@ storageVolCreateXML(virStoragePoolPtr obj, goto cleanup; } =20 - if (virStorageVolCreateXMLEnsureACL(obj->conn, pool->def, voldef) < 0) + if (virStorageVolCreateXMLEnsureACL(pool->conn, pooldef, voldef) < 0) goto cleanup; =20 - if ((volobj =3D virStorageVolObjFindByName(pool, voldef->name))) { + if ((volobj =3D virStorageVolObjFindByName(poolobj, voldef->name))) { virReportError(VIR_ERR_STORAGE_VOL_EXIST, _("'%s'"), voldef->name); goto cleanup; @@ -1942,16 +1890,16 @@ storageVolCreateXML(virStoragePoolPtr obj, /* Wipe any key the user may have suggested, as volume creation * will generate the canonical key. */ VIR_FREE(voldef->key); - if (backend->createVol(obj->conn, pool, voldef) < 0) + if (backend->createVol(pool->conn, poolobj, voldef) < 0) goto cleanup; =20 - if (!(volobj =3D virStoragePoolObjAddVolume(pool, voldef))) + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, voldef))) goto cleanup; VIR_STEAL_PTR(objvoldef, voldef); =20 - if (!(vol =3D virGetStorageVol(obj->conn, pool->def->name, objvoldef->= name, - objvoldef->key, NULL, NULL))) { - virStoragePoolObjRemoveVolume(pool, &volobj); + if (!(volume =3D virGetStorageVol(pool->conn, pooldef->name, objvoldef= ->name, + objvoldef->key, NULL, NULL))) { + storageVolRemoveFromPool(poolobj, &volobj); goto cleanup; } =20 @@ -1969,32 +1917,30 @@ storageVolCreateXML(virStoragePoolPtr obj, memcpy(buildvoldef, objvoldef, sizeof(*objvoldef)); =20 /* Drop the pool lock during volume allocation */ - pool->asyncjobs++; + virStoragePoolObjPrivateIncrAsyncjobs(poolobj); objvoldef->building =3D true; - virStoragePoolObjUnlock(pool); + virObjectUnlock(volobj); =20 - buildret =3D backend->buildVol(obj->conn, pool, buildvoldef, flags= ); + buildret =3D backend->buildVol(pool->conn, volobj, buildvoldef, fl= ags); =20 VIR_FREE(buildvoldef); =20 - storageDriverLock(); - virStoragePoolObjLock(pool); - storageDriverUnlock(); + virObjectLock(volobj); =20 objvoldef->building =3D false; - pool->asyncjobs--; + virStoragePoolObjPrivateDecrAsyncjobs(poolobj); =20 if (buildret < 0) { /* buildVol handles deleting volume on failure */ - storageVolRemoveFromPool(pool, objvoldef); + storageVolRemoveFromPool(poolobj, &volobj); goto cleanup; } =20 } =20 if (backend->refreshVol && - backend->refreshVol(obj->conn, pool, objvoldef) < 0) { - storageVolDeleteInternal(vol, backend, pool, objvoldef, + backend->refreshVol(pool->conn, poolobj, objvoldef) < 0) { + storageVolDeleteInternal(volume, backend, poolobj, &volobj, 0, false); goto cleanup; } @@ -2002,32 +1948,35 @@ storageVolCreateXML(virStoragePoolPtr obj, /* Update pool metadata ignoring the disk backend since * it updates the pool values. */ - if (pool->def->type !=3D VIR_STORAGE_POOL_DISK) { - pool->def->allocation +=3D objvoldef->target.allocation; - pool->def->available -=3D objvoldef->target.allocation; + if (pooldef->type !=3D VIR_STORAGE_POOL_DISK) { + pooldef->allocation +=3D objvoldef->target.allocation; + pooldef->available -=3D objvoldef->target.allocation; } =20 VIR_INFO("Creating volume '%s' in storage pool '%s'", - vol->name, pool->def->name); - ret =3D vol; - vol =3D NULL; + volume->name, pooldef->name); + ret =3D volume; + volume =3D NULL; =20 cleanup: virPoolObjEndAPI(&volobj); - virObjectUnref(vol); + virObjectUnref(volume); virStorageVolDefFree(voldef); - if (pool) - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&poolobj); return ret; } =20 + static virStorageVolPtr -storageVolCreateXMLFrom(virStoragePoolPtr obj, +storageVolCreateXMLFrom(virStoragePoolPtr pool, const char *xmldesc, virStorageVolPtr volume, unsigned int flags) { - virStoragePoolObjPtr pool, origpool =3D NULL; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; + virPoolObjPtr origpoolobj =3D NULL; + virStoragePoolDefPtr origpooldef; virStorageBackendPtr backend; virPoolObjPtr newvolobj =3D NULL; virPoolObjPtr origvolobj =3D NULL; @@ -2043,48 +1992,39 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, VIR_STORAGE_VOL_CREATE_REFLINK, NULL); =20 - storageDriverLock(); - pool =3D virStoragePoolObjFindByUUID(&driver->pools, obj->uuid); - if (pool && STRNEQ(obj->name, volume->pool)) { - virStoragePoolObjUnlock(pool); - origpool =3D virStoragePoolObjFindByName(&driver->pools, volume->p= ool); - virStoragePoolObjLock(pool); - } - storageDriverUnlock(); - if (!pool) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(obj->uuid, uuidstr); - virReportError(VIR_ERR_NO_STORAGE_POOL, - _("no storage pool with matching uuid '%s' (%s)"), - uuidstr, obj->name); - goto cleanup; - } + if (!(poolobj =3D storagePoolObjFromStoragePool(pool))) + return NULL; + pooldef =3D virPoolObjGetDef(poolobj); =20 - if (STRNEQ(obj->name, volume->pool) && !origpool) { + if (STRNEQ(pooldef->name, volume->pool)) + origpoolobj =3D storagePoolObjFindByName(volume->pool); + + if (STRNEQ(pooldef->name, volume->pool) && !origpoolobj) { virReportError(VIR_ERR_NO_STORAGE_POOL, _("no storage pool with matching name '%s'"), volume->pool); goto cleanup; } =20 - if (!virStoragePoolObjIsActive(pool)) { + if (!virPoolObjIsActive(poolobj)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), pool->def->na= me); + _("storage pool '%s' is not active"), pooldef->name= ); goto cleanup; } =20 - if (origpool && !virStoragePoolObjIsActive(origpool)) { + if (origpoolobj && !virPoolObjIsActive(origpoolobj)) { + origpooldef =3D virPoolObjGetDef(poolobj); virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), - origpool->def->name); + origpooldef->name); goto cleanup; } =20 - if ((backend =3D virStorageBackendForType(pool->def->type)) =3D=3D NUL= L) + if ((backend =3D virStorageBackendForType(pooldef->type)) =3D=3D NULL) goto cleanup; =20 - if (!(origvolobj =3D virStorageVolObjFindByName(origpool ? origpool : - pool, volume->name))) { + if (!(origvolobj =3D virStorageVolObjFindByName(origpoolobj ? origpool= obj : + poolobj, volume->name)))= { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), volume->name); @@ -2093,15 +2033,14 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, origvoldef =3D virPoolObjGetDef(origvolobj); =20 if (!(newvoldef =3D - virStorageVolDefParseString(pool->def, xmldesc, + virStorageVolDefParseString(pooldef, xmldesc, VIR_VOL_XML_PARSE_NO_CAPACITY))) goto cleanup; =20 - if (virStorageVolCreateXMLFromEnsureACL(obj->conn, pool->def, - newvoldef) < 0) + if (virStorageVolCreateXMLFromEnsureACL(pool->conn, pooldef, newvoldef= ) < 0) goto cleanup; =20 - if ((newvolobj =3D virStorageVolObjFindByName(pool, newvoldef->name)))= { + if (virStorageVolObjFindByName(poolobj, newvoldef->name)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("storage volume name '%s' already in use."), newvoldef->name); @@ -2135,14 +2074,14 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, } =20 if (backend->refreshVol && - backend->refreshVol(obj->conn, pool, origvoldef) < 0) + backend->refreshVol(pool->conn, poolobj, origvoldef) < 0) goto cleanup; =20 /* 'Define' the new volume so we get async progress reporting. * Wipe any key the user may have suggested, as volume creation * will generate the canonical key. */ VIR_FREE(newvoldef->key); - if (backend->createVol(obj->conn, pool, newvoldef) < 0) + if (backend->createVol(pool->conn, poolobj, newvoldef) < 0) goto cleanup; =20 /* Make a shallow copy of the 'defined' volume definition, since the @@ -2154,63 +2093,58 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, =20 memcpy(shadowvoldef, newvoldef, sizeof(*newvoldef)); =20 - if (!(newvolobj =3D virStoragePoolObjAddVolume(pool, newvoldef))) + if (!(newvolobj =3D virStoragePoolObjAddVolume(poolobj, newvoldef))) goto cleanup; VIR_STEAL_PTR(objnewvoldef, newvoldef); =20 - if (!(vol =3D virGetStorageVol(obj->conn, pool->def->name, objnewvolde= f->name, + if (!(vol =3D virGetStorageVol(pool->conn, pooldef->name, objnewvoldef= ->name, objnewvoldef->key, NULL, NULL))) { - virStoragePoolObjRemoveVolume(pool, &newvolobj); + virStoragePoolObjRemoveVolume(poolobj, &newvolobj); goto cleanup; } =20 /* Drop the pool lock during volume allocation */ - pool->asyncjobs++; + virStoragePoolObjPrivateIncrAsyncjobs(poolobj); objnewvoldef->building =3D true; origvoldef->in_use++; - virStoragePoolObjUnlock(pool); + virObjectUnlock(poolobj); =20 - if (origpool) { - origpool->asyncjobs++; - virStoragePoolObjUnlock(origpool); + if (origpoolobj) { + virStoragePoolObjPrivateIncrAsyncjobs(origpoolobj); + virObjectUnlock(origpoolobj); } =20 - buildret =3D backend->buildVolFrom(obj->conn, pool, shadowvoldef, + buildret =3D backend->buildVolFrom(pool->conn, poolobj, shadowvoldef, origvoldef, flags); =20 - storageDriverLock(); - virStoragePoolObjLock(pool); - if (origpool) - virStoragePoolObjLock(origpool); - storageDriverUnlock(); + virObjectLock(poolobj); + if (origpoolobj) + virObjectLock(origpoolobj); =20 origvoldef->in_use--; objnewvoldef->building =3D false; - pool->asyncjobs--; + virStoragePoolObjPrivateDecrAsyncjobs(poolobj); =20 - if (origpool) { - origpool->asyncjobs--; - virStoragePoolObjUnlock(origpool); - origpool =3D NULL; - } + if (origpoolobj) + virStoragePoolObjPrivateDecrAsyncjobs(origpoolobj); =20 if (buildret < 0 || (backend->refreshVol && - backend->refreshVol(obj->conn, pool, objnewvoldef) < 0)) { - storageVolDeleteInternal(vol, backend, pool, objnewvoldef, 0, fals= e); + backend->refreshVol(pool->conn, poolobj, objnewvoldef) < 0)) { + storageVolDeleteInternal(vol, backend, poolobj, &newvolobj, 0, fal= se); goto cleanup; } =20 /* Updating pool metadata ignoring the disk backend since * it updates the pool values */ - if (pool->def->type !=3D VIR_STORAGE_POOL_DISK) { - pool->def->allocation +=3D objnewvoldef->target.allocation; - pool->def->available -=3D objnewvoldef->target.allocation; + if (pooldef->type !=3D VIR_STORAGE_POOL_DISK) { + pooldef->allocation +=3D objnewvoldef->target.allocation; + pooldef->available -=3D objnewvoldef->target.allocation; } =20 VIR_INFO("Creating volume '%s' in storage pool '%s'", - vol->name, pool->def->name); + vol->name, pooldef->name); ret =3D vol; vol =3D NULL; =20 @@ -2220,10 +2154,8 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj, virObjectUnref(vol); virStorageVolDefFree(newvoldef); VIR_FREE(shadowvoldef); - if (pool) - virStoragePoolObjUnlock(pool); - if (origpool) - virStoragePoolObjUnlock(origpool); + virPoolObjEndAPI(&origpoolobj); + virPoolObjEndAPI(&poolobj); return ret; } =20 @@ -2235,19 +2167,21 @@ storageVolDownload(virStorageVolPtr volume, unsigned long long length, unsigned int flags) { - virStorageBackendPtr backend; - virStoragePoolObjPtr pool =3D NULL; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj; virStorageVolDefPtr voldef; + virStorageBackendPtr backend; int ret =3D -1; =20 virCheckFlags(0, -1); =20 - if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &poolobj, &backend))) return -1; + pooldef =3D virPoolObjGetDef(poolobj); voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolDownloadEnsureACL(volume->conn, pool->def, voldef) < = 0) + if (virStorageVolDownloadEnsureACL(volume->conn, pooldef, voldef) < 0) goto cleanup; =20 if (voldef->building) { @@ -2263,13 +2197,12 @@ storageVolDownload(virStorageVolPtr volume, goto cleanup; } =20 - ret =3D backend->downloadVol(volume->conn, pool, voldef, stream, + ret =3D backend->downloadVol(volume->conn, poolobj, voldef, stream, offset, length, flags); =20 cleanup: virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(pool); - + virPoolObjEndAPI(&poolobj); return ret; } =20 @@ -2341,38 +2274,38 @@ virStorageVolPoolRefreshThread(void *opaque) { =20 virStorageVolStreamInfoPtr cbdata =3D opaque; - virStoragePoolObjPtr pool =3D NULL; + virPoolObjPtr poolobj =3D NULL; + virStoragePoolDefPtr pooldef; virStorageBackendPtr backend; virObjectEventPtr event =3D NULL; =20 - storageDriverLock(); if (cbdata->vol_path) { if (virStorageBackendPloopRestoreDesc(cbdata->vol_path) < 0) goto cleanup; } - if (!(pool =3D virStoragePoolObjFindByName(&driver->pools, - cbdata->pool_name))) + + if (!(poolobj =3D storagePoolObjFindByName(cbdata->pool_name))) goto cleanup; + pooldef =3D virPoolObjGetDef(poolobj); =20 - if (!(backend =3D virStorageBackendForType(pool->def->type))) + if (!(backend =3D virStorageBackendForType(pooldef->type))) goto cleanup; =20 - virStoragePoolObjClearVols(pool); - if (backend->refreshPool(NULL, pool) < 0) + virStoragePoolObjClearVols(poolobj); + if (backend->refreshPool(NULL, poolobj) < 0) VIR_DEBUG("Failed to refresh storage pool"); =20 - event =3D virStoragePoolEventRefreshNew(pool->def->name, - pool->def->uuid); + event =3D virStoragePoolEventRefreshNew(pooldef->name, + pooldef->uuid); =20 cleanup: if (event) virObjectEventStateQueue(driver->storageEventState, event); - if (pool) - virStoragePoolObjUnlock(pool); - storageDriverUnlock(); + virPoolObjEndAPI(&poolobj); virStorageVolPoolRefreshDataFree(cbdata); } =20 + /** * Callback being called if a FDstream is closed. Will spin off a thread * to perform a pool refresh. @@ -2398,6 +2331,7 @@ virStorageVolFDStreamCloseCb(virStreamPtr st ATTRIBUT= E_UNUSED, virStorageVolPoolRefreshDataFree(opaque); } =20 + static int storageVolUpload(virStorageVolPtr volume, virStreamPtr stream, @@ -2405,20 +2339,22 @@ storageVolUpload(virStorageVolPtr volume, unsigned long long length, unsigned int flags) { - virStorageBackendPtr backend; - virStoragePoolObjPtr pool =3D NULL; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj; virStorageVolDefPtr voldef; + virStorageBackendPtr backend; virStorageVolStreamInfoPtr cbdata =3D NULL; int ret =3D -1; =20 virCheckFlags(0, -1); =20 - if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &poolobj, &backend))) return -1; + pooldef =3D virPoolObjGetDef(poolobj); voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolUploadEnsureACL(volume->conn, pool->def, voldef) < 0) + if (virStorageVolUploadEnsureACL(volume->conn, pooldef, voldef) < 0) goto cleanup; =20 if (voldef->in_use) { @@ -2448,13 +2384,13 @@ storageVolUpload(virStorageVolPtr volume, * routine in order to call the refresh API. */ if (VIR_ALLOC(cbdata) < 0 || - VIR_STRDUP(cbdata->pool_name, pool->def->name) < 0) + VIR_STRDUP(cbdata->pool_name, pooldef->name) < 0) goto cleanup; if (voldef->type =3D=3D VIR_STORAGE_VOL_PLOOP && VIR_STRDUP(cbdata->vol_path, voldef->target.path) < 0) goto cleanup; =20 - if ((ret =3D backend->uploadVol(volume->conn, pool, voldef, stream, + if ((ret =3D backend->uploadVol(volume->conn, poolobj, voldef, stream, offset, length, flags)) < 0) goto cleanup; =20 @@ -2468,22 +2404,24 @@ storageVolUpload(virStorageVolPtr volume, =20 cleanup: virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&poolobj); if (cbdata) virStorageVolPoolRefreshDataFree(cbdata); =20 return ret; } =20 + static int storageVolResize(virStorageVolPtr volume, unsigned long long capacity, unsigned int flags) { - virStorageBackendPtr backend; - virStoragePoolObjPtr pool =3D NULL; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj; virStorageVolDefPtr voldef; + virStorageBackendPtr backend; unsigned long long abs_capacity, delta =3D 0; int ret =3D -1; =20 @@ -2491,11 +2429,12 @@ storageVolResize(virStorageVolPtr volume, VIR_STORAGE_VOL_RESIZE_DELTA | VIR_STORAGE_VOL_RESIZE_SHRINK, -1); =20 - if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &poolobj, &backend))) return -1; + pooldef =3D virPoolObjGetDef(poolobj); voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolResizeEnsureACL(volume->conn, pool->def, voldef) < 0) + if (virStorageVolResizeEnsureACL(volume->conn, pooldef, voldef) < 0) goto cleanup; =20 if (voldef->in_use) { @@ -2525,23 +2464,22 @@ storageVolResize(virStorageVolPtr volume, =20 if (abs_capacity < voldef->target.allocation) { virReportError(VIR_ERR_INVALID_ARG, "%s", - _("can't shrink capacity below " - "existing allocation")); + _("can't shrink capacity below existing allocation"= )); goto cleanup; } =20 if (abs_capacity < voldef->target.capacity && !(flags & VIR_STORAGE_VOL_RESIZE_SHRINK)) { virReportError(VIR_ERR_INVALID_ARG, "%s", - _("Can't shrink capacity below current " - "capacity unless shrink flag explicitly specified= ")); + _("Can't shrink capacity below current capacity unl= ess " + "shrink flag explicitly specified")); goto cleanup; } =20 if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE) delta =3D abs_capacity - voldef->target.allocation; =20 - if (delta > pool->def->available) { + if (delta > pooldef->available) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Not enough space left in storage pool")); goto cleanup; @@ -2554,7 +2492,8 @@ storageVolResize(virStorageVolPtr volume, goto cleanup; } =20 - if (backend->resizeVol(volume->conn, pool, voldef, abs_capacity, flags= ) < 0) + if (backend->resizeVol(volume->conn, poolobj, voldef, + abs_capacity, flags) < 0) goto cleanup; =20 voldef->target.capacity =3D abs_capacity; @@ -2564,15 +2503,15 @@ storageVolResize(virStorageVolPtr volume, */ if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE) { voldef->target.allocation =3D abs_capacity; - pool->def->allocation +=3D delta; - pool->def->available -=3D delta; + pooldef->allocation +=3D delta; + pooldef->available -=3D delta; } =20 ret =3D 0; =20 cleanup: virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&poolobj); =20 return ret; } @@ -2583,10 +2522,11 @@ storageVolWipePattern(virStorageVolPtr volume, unsigned int algorithm, unsigned int flags) { - virStorageBackendPtr backend; - virStoragePoolObjPtr pool =3D NULL; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj; virStorageVolDefPtr voldef; + virStorageBackendPtr backend; int ret =3D -1; =20 virCheckFlags(0, -1); @@ -2598,11 +2538,12 @@ storageVolWipePattern(virStorageVolPtr volume, return -1; } =20 - if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &poolobj, &backend))) return -1; + pooldef =3D virPoolObjGetDef(poolobj); voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolWipePatternEnsureACL(volume->conn, pool->def, voldef)= < 0) + if (virStorageVolWipePatternEnsureACL(volume->conn, pooldef, voldef) <= 0) goto cleanup; =20 if (voldef->in_use) { @@ -2625,27 +2566,28 @@ storageVolWipePattern(virStorageVolPtr volume, goto cleanup; } =20 - if (backend->wipeVol(volume->conn, pool, voldef, algorithm, flags) < 0) + if (backend->wipeVol(volume->conn, poolobj, voldef, algorithm, flags) = < 0) goto cleanup; =20 if (backend->refreshVol && - backend->refreshVol(volume->conn, pool, voldef) < 0) + backend->refreshVol(volume->conn, poolobj, voldef) < 0) goto cleanup; =20 ret =3D 0; =20 cleanup: virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&poolobj); =20 return ret; } =20 + static int -storageVolWipe(virStorageVolPtr obj, +storageVolWipe(virStorageVolPtr volume, unsigned int flags) { - return storageVolWipePattern(obj, VIR_STORAGE_VOL_WIPE_ALG_ZERO, flags= ); + return storageVolWipePattern(volume, VIR_STORAGE_VOL_WIPE_ALG_ZERO, fl= ags); } =20 =20 @@ -2654,23 +2596,25 @@ storageVolGetInfoFlags(virStorageVolPtr volume, virStorageVolInfoPtr info, unsigned int flags) { - virStoragePoolObjPtr pool; - virStorageBackendPtr backend; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj; virStorageVolDefPtr voldef; + virStorageBackendPtr backend; int ret =3D -1; =20 virCheckFlags(VIR_STORAGE_VOL_GET_PHYSICAL, -1); =20 - if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &poolobj, &backend))) return -1; + pooldef =3D virPoolObjGetDef(poolobj); voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolGetInfoFlagsEnsureACL(volume->conn, pool->def, voldef= ) < 0) + if (virStorageVolGetInfoFlagsEnsureACL(volume->conn, pooldef, voldef) = < 0) goto cleanup; =20 if (backend->refreshVol && - backend->refreshVol(volume->conn, pool, voldef) < 0) + backend->refreshVol(volume->conn, poolobj, voldef) < 0) goto cleanup; =20 memset(info, 0, sizeof(*info)); @@ -2684,16 +2628,16 @@ storageVolGetInfoFlags(virStorageVolPtr volume, =20 cleanup: virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&poolobj); return ret; } =20 =20 static int -storageVolGetInfo(virStorageVolPtr obj, +storageVolGetInfo(virStorageVolPtr volume, virStorageVolInfoPtr info) { - return storageVolGetInfoFlags(obj, info, 0); + return storageVolGetInfoFlags(volume, info, 0); } =20 =20 @@ -2701,79 +2645,79 @@ static char * storageVolGetXMLDesc(virStorageVolPtr volume, unsigned int flags) { - virStoragePoolObjPtr pool; - virStorageBackendPtr backend; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj; virStorageVolDefPtr voldef; + virStorageBackendPtr backend; char *ret =3D NULL; =20 virCheckFlags(0, NULL); =20 - if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, &backend))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &poolobj, &backend))) return NULL; + pooldef =3D virPoolObjGetDef(poolobj); voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolGetXMLDescEnsureACL(volume->conn, pool->def, voldef) = < 0) + if (virStorageVolGetXMLDescEnsureACL(volume->conn, pooldef, voldef) < = 0) goto cleanup; =20 if (backend->refreshVol && - backend->refreshVol(volume->conn, pool, voldef) < 0) + backend->refreshVol(volume->conn, poolobj, voldef) < 0) goto cleanup; =20 - ret =3D virStorageVolDefFormat(pool->def, voldef); + ret =3D virStorageVolDefFormat(pooldef, voldef); =20 cleanup: virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&poolobj); =20 return ret; } =20 + static char * storageVolGetPath(virStorageVolPtr volume) { - virStoragePoolObjPtr pool; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj; virStorageVolDefPtr voldef; char *ret =3D NULL; =20 - if (!(volobj =3D virStorageVolObjFromVol(volume, &pool, NULL))) + if (!(volobj =3D virStorageVolObjFromVol(volume, &poolobj, NULL))) return NULL; + pooldef =3D virPoolObjGetDef(poolobj); voldef =3D virPoolObjGetDef(volobj); =20 - if (virStorageVolGetPathEnsureACL(volume->conn, pool->def, voldef) < 0) + if (virStorageVolGetPathEnsureACL(volume->conn, pooldef, voldef) < 0) goto cleanup; =20 ignore_value(VIR_STRDUP(ret, voldef->target.path)); =20 cleanup: virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&poolobj); return ret; } =20 + static int storageConnectListAllStoragePools(virConnectPtr conn, virStoragePoolPtr **pools, unsigned int flags) { - int ret =3D -1; - virCheckFlags(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ALL, -1); =20 if (virConnectListAllStoragePoolsEnsureACL(conn) < 0) - goto cleanup; - - storageDriverLock(); - ret =3D virStoragePoolObjListExport(conn, driver->pools, pools, - virConnectListAllStoragePoolsCheckAC= L, - flags); - storageDriverUnlock(); + return -1; =20 - cleanup: - return ret; + return virStoragePoolObjExportList(conn, driver->pools, pools, + virConnectListAllStoragePoolsCheckA= CL, + flags); } =20 + static int storageConnectStoragePoolEventRegisterAny(virConnectPtr conn, virStoragePoolPtr pool, @@ -3655,21 +3599,16 @@ virStorageTranslateDiskSourcePool(virConnectPtr con= n, * * Returns NULL if pool is not found or a locked pool object pointer */ -virStoragePoolObjPtr +virPoolObjPtr virStoragePoolObjFindPoolByUUID(const unsigned char *uuid) { - virStoragePoolObjPtr pool; - - storageDriverLock(); - pool =3D virStoragePoolObjFindByUUID(&driver->pools, uuid); - storageDriverUnlock(); - return pool; + return storagePoolObjFindByUUID(uuid, NULL); } =20 =20 /* - * virStoragePoolObjBuildTempFilePath - * @pool: pool object pointer + * virStoragePoolBuildTempFilePath + * @def: pool definition pointer * @vol: volume definition * * Generate a name for a temporary file using the driver stateDir @@ -3679,13 +3618,13 @@ virStoragePoolObjFindPoolByUUID(const unsigned char= *uuid) * Returns a string pointer on success, NULL on failure */ char * -virStoragePoolObjBuildTempFilePath(virStoragePoolObjPtr pool, - virStorageVolDefPtr vol) +virStoragePoolBuildTempFilePath(virStoragePoolDefPtr def, + virStorageVolDefPtr vol) =20 { char *tmp =3D NULL; =20 ignore_value(virAsprintf(&tmp, "%s/%s.%s.secret.XXXXXX", - driver->stateDir, pool->def->name, vol->name)= ); + driver->stateDir, def->name, vol->name)); return tmp; } diff --git a/src/storage/storage_driver.h b/src/storage/storage_driver.h index 682c9ff..c0bccb5 100644 --- a/src/storage/storage_driver.h +++ b/src/storage/storage_driver.h @@ -57,7 +57,7 @@ int virStorageFileGetMetadata(virStorageSourcePtr src, int virStorageTranslateDiskSourcePool(virConnectPtr conn, virDomainDiskDefPtr def); =20 -virStoragePoolObjPtr virStoragePoolObjFindPoolByUUID(const unsigned char *= uuid) +virPoolObjPtr virStoragePoolObjFindPoolByUUID(const unsigned char *uuid) ATTRIBUTE_NONNULL(1); =20 virStoragePoolPtr @@ -65,8 +65,8 @@ storagePoolLookupByTargetPath(virConnectPtr conn, const char *path) ATTRIBUTE_NONNULL(2); =20 -char *virStoragePoolObjBuildTempFilePath(virStoragePoolObjPtr pool, - virStorageVolDefPtr vol) +char *virStoragePoolBuildTempFilePath(virStoragePoolDefPtr def, + virStorageVolDefPtr vol) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; =20 int storageRegister(void); diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index 644c3e7..45f787c 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -223,7 +223,7 @@ virStorageBackendCopyToFD(virStorageVolDefPtr vol, =20 static int storageBackendCreateBlockFrom(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virPoolObjPtr obj ATTRIBUTE_UNUSED, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags) @@ -391,11 +391,12 @@ createRawFile(int fd, virStorageVolDefPtr vol, =20 static int storageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, - virStorageVolDefPtr vol, - virStorageVolDefPtr inputvol, + virPoolObjPtr obj, + virStorageVolDefPtr voldef, + virStorageVolDefPtr inputvoldef, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); int ret =3D -1; int fd =3D -1; int operation_flags; @@ -414,7 +415,7 @@ storageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UN= USED, goto cleanup; } =20 - if (vol->target.backingStore) { + if (voldef->target.backingStore) { virReportError(VIR_ERR_NO_SUPPORT, "%s", _("backing storage not supported for raw volumes")); goto cleanup; @@ -424,33 +425,33 @@ storageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_= UNUSED, reflink_copy =3D true; =20 =20 - if (vol->target.encryption !=3D NULL) { + if (voldef->target.encryption !=3D NULL) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("storage pool does not support encrypted volumes"= )); goto cleanup; } =20 operation_flags =3D VIR_FILE_OPEN_FORCE_MODE | VIR_FILE_OPEN_FORCE_OWN= ER; - if (pool->def->type =3D=3D VIR_STORAGE_POOL_NETFS) + if (def->type =3D=3D VIR_STORAGE_POOL_NETFS) operation_flags |=3D VIR_FILE_OPEN_FORK; =20 - if (vol->target.perms->mode !=3D (mode_t) -1) - open_mode =3D vol->target.perms->mode; + if (voldef->target.perms->mode !=3D (mode_t) -1) + open_mode =3D voldef->target.perms->mode; =20 - if ((fd =3D virFileOpenAs(vol->target.path, + if ((fd =3D virFileOpenAs(voldef->target.path, O_RDWR | O_CREAT | O_EXCL, open_mode, - vol->target.perms->uid, - vol->target.perms->gid, + voldef->target.perms->uid, + voldef->target.perms->gid, operation_flags)) < 0) { virReportSystemError(-fd, _("Failed to create file '%s'"), - vol->target.path); + voldef->target.path); goto cleanup; } created =3D true; =20 - if (vol->target.nocow) { + if (voldef->target.nocow) { #ifdef __linux__ int attr; =20 @@ -470,15 +471,15 @@ storageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_= UNUSED, #endif } =20 - if ((ret =3D createRawFile(fd, vol, inputvol, reflink_copy)) < 0) + if ((ret =3D createRawFile(fd, voldef, inputvoldef, reflink_copy)) < 0) /* createRawFile already reported the exact error. */ ret =3D -1; =20 cleanup: if (ret < 0 && created) - ignore_value(virFileRemove(vol->target.path, - vol->target.perms->uid, - vol->target.perms->gid)); + ignore_value(virFileRemove(voldef->target.path, + voldef->target.perms->uid, + voldef->target.perms->gid)); VIR_FORCE_CLOSE(fd); return ret; } @@ -593,10 +594,11 @@ virStorageGenerateQcowEncryption(virConnectPtr conn, } =20 static int -virStorageBackendCreateExecCommand(virStoragePoolObjPtr pool, +virStorageBackendCreateExecCommand(virPoolObjPtr obj, virStorageVolDefPtr vol, virCommandPtr cmd) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); struct stat st; gid_t gid; uid_t uid; @@ -606,7 +608,7 @@ virStorageBackendCreateExecCommand(virStoragePoolObjPtr= pool, bool filecreated =3D false; int ret =3D -1; =20 - if ((pool->def->type =3D=3D VIR_STORAGE_POOL_NETFS) + if ((def->type =3D=3D VIR_STORAGE_POOL_NETFS) && (((geteuid() =3D=3D 0) && (vol->target.perms->uid !=3D (uid_t) -1) && (vol->target.perms->uid !=3D 0)) @@ -694,7 +696,7 @@ virStorageBackendCreateExecCommand(virStoragePoolObjPtr= pool, * if function fails to create image file the directory will be deleted.*/ static int storageBackendCreatePloop(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virPoolObjPtr obj ATTRIBUTE_UNUSED, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags) @@ -1022,11 +1024,12 @@ storageBackendCreateQemuImgSetInput(virStorageVolDe= fPtr inputvol, =20 =20 static int -storageBackendCreateQemuImgSetBacking(virStoragePoolObjPtr pool, +storageBackendCreateQemuImgSetBacking(virPoolObjPtr obj, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, struct _virStorageBackendQemuImgInfo= *info) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); int accessRetCode =3D -1; char *absolutePath =3D NULL; =20 @@ -1069,7 +1072,7 @@ storageBackendCreateQemuImgSetBacking(virStoragePoolO= bjPtr pool, * validation. */ if ('/' !=3D *(info->backingPath) && - virAsprintf(&absolutePath, "%s/%s", pool->def->target.path, + virAsprintf(&absolutePath, "%s/%s", def->target.path, info->backingPath) < 0) return -1; accessRetCode =3D access(absolutePath ? absolutePath : @@ -1146,7 +1149,7 @@ storageBackendCreateQemuImgSecretObject(virCommandPtr= cmd, */ virCommandPtr virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr obj, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags, @@ -1223,7 +1226,7 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPt= r conn, return NULL; =20 if (vol->target.backingStore && - storageBackendCreateQemuImgSetBacking(pool, vol, inputvol, &info) = < 0) + storageBackendCreateQemuImgSetBacking(obj, vol, inputvol, &info) <= 0) return NULL; =20 if (info.encryption && @@ -1280,9 +1283,10 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectP= tr conn, =20 static char * storageBackendCreateQemuImgSecretPath(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr obj, virStorageVolDefPtr vol) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); virStorageEncryptionPtr enc =3D vol->target.encryption; char *secretPath =3D NULL; int fd =3D -1; @@ -1304,7 +1308,7 @@ storageBackendCreateQemuImgSecretPath(virConnectPtr c= onn, return NULL; } =20 - if (!(secretPath =3D virStoragePoolObjBuildTempFilePath(pool, vol))) + if (!(secretPath =3D virStoragePoolBuildTempFilePath(def, vol))) goto cleanup; =20 if ((fd =3D mkostemp(secretPath, O_CLOEXEC)) < 0) { @@ -1350,7 +1354,7 @@ storageBackendCreateQemuImgSecretPath(virConnectPtr c= onn, =20 static int storageBackendCreateQemuImg(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr obj, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags) @@ -1379,17 +1383,17 @@ storageBackendCreateQemuImg(virConnectPtr conn, vol->target.encryption && vol->target.encryption->format =3D=3D VIR_STORAGE_ENCRYPTION_FORMA= T_LUKS) { if (!(secretPath =3D - storageBackendCreateQemuImgSecretPath(conn, pool, vol))) + storageBackendCreateQemuImgSecretPath(conn, obj, vol))) goto cleanup; } =20 - cmd =3D virStorageBackendCreateQemuImgCmdFromVol(conn, pool, vol, inpu= tvol, + cmd =3D virStorageBackendCreateQemuImgCmdFromVol(conn, obj, vol, input= vol, flags, create_tool, imgformat, secretPath); if (!cmd) goto cleanup; =20 - ret =3D virStorageBackendCreateExecCommand(pool, vol, cmd); + ret =3D virStorageBackendCreateExecCommand(obj, vol, cmd); =20 virCommandFree(cmd); cleanup: @@ -1931,10 +1935,11 @@ virStorageBackendPoolPathIsStable(const char *path) * a change to appear. */ char * -virStorageBackendStablePath(virStoragePoolObjPtr pool, +virStorageBackendStablePath(virPoolObjPtr obj, const char *devpath, bool loop) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); DIR *dh; struct dirent *dent; char *stablepath; @@ -1943,8 +1948,8 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool, int direrr; =20 /* Logical pools are under /dev but already have stable paths */ - if (pool->def->type =3D=3D VIR_STORAGE_POOL_LOGICAL || - !virStorageBackendPoolPathIsStable(pool->def->target.path)) + if (def->type =3D=3D VIR_STORAGE_POOL_LOGICAL || + !virStorageBackendPoolPathIsStable(def->target.path)) goto ret_strdup; =20 /* We loop here because /dev/disk/by-{id,path} may not have existed @@ -1952,7 +1957,7 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool, * get created. */ reopen: - if (virDirOpenQuiet(&dh, pool->def->target.path) < 0) { + if (virDirOpenQuiet(&dh, def->target.path) < 0) { opentries++; if (loop && errno =3D=3D ENOENT && opentries < 50) { usleep(100 * 1000); @@ -1960,7 +1965,7 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool, } virReportSystemError(errno, _("cannot read dir '%s'"), - pool->def->target.path); + def->target.path); return NULL; } =20 @@ -1976,7 +1981,7 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool, retry: while ((direrr =3D virDirRead(dh, &dent, NULL)) > 0) { if (virAsprintf(&stablepath, "%s/%s", - pool->def->target.path, + def->target.path, dent->d_name) =3D=3D -1) { VIR_DIR_CLOSE(dh); return NULL; @@ -2010,11 +2015,12 @@ virStorageBackendStablePath(virStoragePoolObjPtr po= ol, /* Common/Local File System/Directory Volume API's */ static int createFileDir(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags) { + virStoragePoolDefPtr pooldef =3D virPoolObjGetDef(poolobj); int err; =20 virCheckFlags(0, -1); @@ -2039,7 +2045,7 @@ createFileDir(virConnectPtr conn ATTRIBUTE_UNUSED, vol->target.perms->mode), vol->target.perms->uid, vol->target.perms->gid, - (pool->def->type =3D=3D VIR_STORAGE_POOL_NETFS + (pooldef->type =3D=3D VIR_STORAGE_POOL_NETFS ? VIR_DIR_CREATE_AS_UID : 0))) < 0) { return -1; } @@ -2056,9 +2062,11 @@ createFileDir(virConnectPtr conn ATTRIBUTE_UNUSED, */ int virStorageBackendVolCreateLocal(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol) { + virStoragePoolDefPtr pooldef =3D virPoolObjGetDef(poolobj); + if (vol->target.format =3D=3D VIR_STORAGE_FILE_DIR) vol->type =3D VIR_STORAGE_VOL_DIR; else if (vol->target.format =3D=3D VIR_STORAGE_FILE_PLOOP) @@ -2076,7 +2084,7 @@ virStorageBackendVolCreateLocal(virConnectPtr conn AT= TRIBUTE_UNUSED, =20 VIR_FREE(vol->target.path); if (virAsprintf(&vol->target.path, "%s/%s", - pool->def->target.path, + pooldef->target.path, vol->name) =3D=3D -1) return -1; =20 @@ -2094,7 +2102,7 @@ virStorageBackendVolCreateLocal(virConnectPtr conn AT= TRIBUTE_UNUSED, =20 static int storageBackendVolBuildLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags) @@ -2123,7 +2131,7 @@ storageBackendVolBuildLocal(virConnectPtr conn, create_func =3D storageBackendCreateQemuImg; } =20 - if (create_func(conn, pool, vol, inputvol, flags) < 0) + if (create_func(conn, poolobj, vol, inputvol, flags) < 0) return -1; return 0; } @@ -2136,11 +2144,11 @@ storageBackendVolBuildLocal(virConnectPtr conn, */ int virStorageBackendVolBuildLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags) { - return storageBackendVolBuildLocal(conn, pool, vol, NULL, flags); + return storageBackendVolBuildLocal(conn, poolobj, vol, NULL, flags); } =20 =20 @@ -2149,12 +2157,12 @@ virStorageBackendVolBuildLocal(virConnectPtr conn, */ int virStorageBackendVolBuildFromLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags) { - return storageBackendVolBuildLocal(conn, pool, vol, inputvol, flags); + return storageBackendVolBuildLocal(conn, poolobj, vol, inputvol, flags= ); } =20 =20 @@ -2163,7 +2171,7 @@ virStorageBackendVolBuildFromLocal(virConnectPtr conn, */ int virStorageBackendVolDeleteLocal(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virPoolObjPtr poolobj ATTRIBUTE_UNUSED, virStorageVolDefPtr vol, unsigned int flags) { @@ -2260,7 +2268,7 @@ storageBackendLoadDefaultSecrets(virConnectPtr conn, */ int virStorageBackendVolRefreshLocal(virConnectPtr conn, - virStoragePoolObjPtr pool ATTRIBUTE_UNUSE= D, + virPoolObjPtr poolobj ATTRIBUTE_UNUSED, virStorageVolDefPtr vol) { int ret; @@ -2313,7 +2321,7 @@ storageBackendResizeQemuImg(const char *path, */ int virStorageBackendVolResizeLocal(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virPoolObjPtr poolobj ATTRIBUTE_UNUSED, virStorageVolDefPtr vol, unsigned long long capacity, unsigned int flags) @@ -2385,7 +2393,7 @@ storageBackendPloopHasSnapshots(char *path) =20 int virStorageBackendVolUploadLocal(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virPoolObjPtr poolobj ATTRIBUTE_UNUSED, virStorageVolDefPtr vol, virStreamPtr stream, unsigned long long offset, @@ -2431,7 +2439,7 @@ virStorageBackendVolUploadLocal(virConnectPtr conn AT= TRIBUTE_UNUSED, =20 int virStorageBackendVolDownloadLocal(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool ATTRIBUTE_UNUS= ED, + virPoolObjPtr poolobj ATTRIBUTE_UNUSED, virStorageVolDefPtr vol, virStreamPtr stream, unsigned long long offset, @@ -2714,7 +2722,7 @@ storageBackendVolWipePloop(virStorageVolDefPtr vol, =20 int virStorageBackendVolWipeLocal(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virPoolObjPtr poolobj ATTRIBUTE_UNUSED, virStorageVolDefPtr vol, unsigned int algorithm, unsigned int flags) @@ -2738,16 +2746,16 @@ virStorageBackendVolWipeLocal(virConnectPtr conn AT= TRIBUTE_UNUSED, =20 =20 /** - * @pool: storage pool to build - * @dir_create_flags: flags for directory creation + * @poolobj: storage pool to build * * Common code to build a directory based storage pool * * Returns 0 on success, -1 on failure */ int -virStorageBackendBuildLocal(virStoragePoolObjPtr pool) +virStorageBackendBuildLocal(virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); int ret =3D -1; char *parent =3D NULL; char *p =3D NULL; @@ -2755,12 +2763,12 @@ virStorageBackendBuildLocal(virStoragePoolObjPtr po= ol) bool needs_create_as_uid; unsigned int dir_create_flags; =20 - if (VIR_STRDUP(parent, pool->def->target.path) < 0) + if (VIR_STRDUP(parent, def->target.path) < 0) goto cleanup; if (!(p =3D strrchr(parent, '/'))) { virReportError(VIR_ERR_INVALID_ARG, _("path '%s' is not absolute"), - pool->def->target.path); + def->target.path); goto cleanup; } =20 @@ -2776,11 +2784,11 @@ virStorageBackendBuildLocal(virStoragePoolObjPtr po= ol) } =20 dir_create_flags =3D VIR_DIR_CREATE_ALLOW_EXIST; - needs_create_as_uid =3D (pool->def->type =3D=3D VIR_STORAGE_POOL_NETFS= ); - mode =3D pool->def->target.perms.mode; + needs_create_as_uid =3D (def->type =3D=3D VIR_STORAGE_POOL_NETFS); + mode =3D def->target.perms.mode; =20 if (mode =3D=3D (mode_t) -1 && - (needs_create_as_uid || !virFileExists(pool->def->target.path))) + (needs_create_as_uid || !virFileExists(def->target.path))) mode =3D VIR_STORAGE_DEFAULT_POOL_PERM_MODE; if (needs_create_as_uid) dir_create_flags |=3D VIR_DIR_CREATE_AS_UID; @@ -2788,10 +2796,10 @@ virStorageBackendBuildLocal(virStoragePoolObjPtr po= ol) /* Now create the final dir in the path with the uid/gid/mode * requested in the config. If the dir already exists, just set * the perms. */ - if (virDirCreate(pool->def->target.path, + if (virDirCreate(def->target.path, mode, - pool->def->target.perms.uid, - pool->def->target.perms.gid, + def->target.perms.uid, + def->target.perms.gid, dir_create_flags) < 0) goto cleanup; =20 @@ -2813,17 +2821,19 @@ virStorageBackendBuildLocal(virStoragePoolObjPtr po= ol) */ int virStorageBackendDeleteLocal(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, unsigned int flags) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); + virCheckFlags(0, -1); =20 /* XXX delete all vols first ? */ =20 - if (rmdir(pool->def->target.path) < 0) { + if (rmdir(def->target.path) < 0) { virReportSystemError(errno, _("failed to remove pool '%s'"), - pool->def->target.path); + def->target.path); return -1; } =20 @@ -3464,8 +3474,9 @@ storageBackendProbeTarget(virStorageSourcePtr target, */ int virStorageBackendRefreshLocal(virConnectPtr conn ATTRIBUTE_UNUSED, - virStoragePoolObjPtr pool) + virPoolObjPtr poolobj) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(poolobj); DIR *dir; struct dirent *ent; struct statvfs sb; @@ -3476,15 +3487,15 @@ virStorageBackendRefreshLocal(virConnectPtr conn AT= TRIBUTE_UNUSED, int direrr; int fd =3D -1, ret =3D -1; =20 - if (virDirOpen(&dir, pool->def->target.path) < 0) + if (virDirOpen(&dir, def->target.path) < 0) goto cleanup; =20 - while ((direrr =3D virDirRead(dir, &ent, pool->def->target.path)) > 0)= { + while ((direrr =3D virDirRead(dir, &ent, def->target.path)) > 0) { int err; =20 if (virStringHasControlChars(ent->d_name)) { VIR_WARN("Ignoring file with control characters under '%s'", - pool->def->target.path); + def->target.path); continue; } =20 @@ -3497,7 +3508,7 @@ virStorageBackendRefreshLocal(virConnectPtr conn ATTR= IBUTE_UNUSED, vol->type =3D VIR_STORAGE_VOL_FILE; vol->target.format =3D VIR_STORAGE_FILE_RAW; /* Real value is fill= ed in during probe */ if (virAsprintf(&vol->target.path, "%s/%s", - pool->def->target.path, + def->target.path, vol->name) =3D=3D -1) goto cleanup; =20 @@ -3540,7 +3551,7 @@ virStorageBackendRefreshLocal(virConnectPtr conn ATTR= IBUTE_UNUSED, * An error message was raised, but we just continue. */ } =20 - if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, vol))) goto cleanup; =20 vol =3D NULL; @@ -3554,17 +3565,17 @@ virStorageBackendRefreshLocal(virConnectPtr conn AT= TRIBUTE_UNUSED, if (VIR_ALLOC(target)) goto cleanup; =20 - if ((fd =3D open(pool->def->target.path, O_RDONLY)) < 0) { + if ((fd =3D open(def->target.path, O_RDONLY)) < 0) { virReportSystemError(errno, _("cannot open path '%s'"), - pool->def->target.path); + def->target.path); goto cleanup; } =20 if (fstat(fd, &statbuf) < 0) { virReportSystemError(errno, _("cannot stat path '%s'"), - pool->def->target.path); + def->target.path); goto cleanup; } =20 @@ -3572,24 +3583,24 @@ virStorageBackendRefreshLocal(virConnectPtr conn AT= TRIBUTE_UNUSED, goto cleanup; =20 /* VolTargetInfoFD doesn't update capacity correctly for the pool case= */ - if (statvfs(pool->def->target.path, &sb) < 0) { + if (statvfs(def->target.path, &sb) < 0) { virReportSystemError(errno, _("cannot statvfs path '%s'"), - pool->def->target.path); + def->target.path); goto cleanup; } =20 - pool->def->capacity =3D ((unsigned long long)sb.f_frsize * - (unsigned long long)sb.f_blocks); - pool->def->available =3D ((unsigned long long)sb.f_bfree * - (unsigned long long)sb.f_frsize); - pool->def->allocation =3D pool->def->capacity - pool->def->available; + def->capacity =3D ((unsigned long long)sb.f_frsize * + (unsigned long long)sb.f_blocks); + def->available =3D ((unsigned long long)sb.f_bfree * + (unsigned long long)sb.f_frsize); + def->allocation =3D def->capacity - def->available; =20 - pool->def->target.perms.mode =3D target->perms->mode; - pool->def->target.perms.uid =3D target->perms->uid; - pool->def->target.perms.gid =3D target->perms->gid; - VIR_FREE(pool->def->target.perms.label); - if (VIR_STRDUP(pool->def->target.perms.label, target->perms->label) < = 0) + def->target.perms.mode =3D target->perms->mode; + def->target.perms.uid =3D target->perms->uid; + def->target.perms.gid =3D target->perms->gid; + VIR_FREE(def->target.perms.label); + if (VIR_STRDUP(def->target.perms.label, target->perms->label) < 0) goto cleanup; =20 ret =3D 0; @@ -3599,7 +3610,7 @@ virStorageBackendRefreshLocal(virConnectPtr conn ATTR= IBUTE_UNUSED, virStorageVolDefFree(vol); virStorageSourceFree(target); if (ret < 0) - virStoragePoolObjClearVols(pool); + virStoragePoolObjClearVols(poolobj); return ret; } =20 @@ -3652,13 +3663,14 @@ virStorageBackendSCSISerial(const char *dev) * -2 =3D> Failure to find a stable path, not fatal, caller can try anoth= er */ static int -virStorageBackendSCSINewLun(virStoragePoolObjPtr pool, +virStorageBackendSCSINewLun(virPoolObjPtr obj, uint32_t host ATTRIBUTE_UNUSED, uint32_t bus, uint32_t target, uint32_t lun, const char *dev) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); virStorageVolDefPtr vol =3D NULL; virPoolObjPtr volobj; char *devpath =3D NULL; @@ -3671,12 +3683,12 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr po= ol, * path to the device if the virDirRead loop to search the * target pool path for our devpath had failed. */ - if (!virStorageBackendPoolPathIsStable(pool->def->target.path) && - !(STREQ(pool->def->target.path, "/dev") || - STREQ(pool->def->target.path, "/dev/"))) { + if (!virStorageBackendPoolPathIsStable(def->target.path) && + !(STREQ(def->target.path, "/dev") || + STREQ(def->target.path, "/dev/"))) { virReportError(VIR_ERR_INVALID_ARG, _("unable to use target path '%s' for dev '%s'"), - NULLSTR(pool->def->target.path), dev); + NULLSTR(def->target.path), dev); goto cleanup; } =20 @@ -3704,17 +3716,15 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr po= ol, * dir every time its run. Should figure out a more efficient * way of doing this... */ - if ((vol->target.path =3D virStorageBackendStablePath(pool, - devpath, - true)) =3D=3D NULL) + if (!(vol->target.path =3D virStorageBackendStablePath(obj, devpath, t= rue))) goto cleanup; =20 if (STREQ(devpath, vol->target.path) && - !(STREQ(pool->def->target.path, "/dev") || - STREQ(pool->def->target.path, "/dev/"))) { + !(STREQ(def->target.path, "/dev") || + STREQ(def->target.path, "/dev/"))) { =20 VIR_DEBUG("No stable path found for '%s' in '%s'", - devpath, pool->def->target.path); + devpath, def->target.path); =20 retval =3D -2; goto cleanup; @@ -3729,10 +3739,10 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr po= ol, if (!(vol->key =3D virStorageBackendSCSISerial(vol->target.path))) goto cleanup; =20 - pool->def->capacity +=3D vol->target.capacity; - pool->def->allocation +=3D vol->target.allocation; + def->capacity +=3D vol->target.capacity; + def->allocation +=3D vol->target.allocation; =20 - if (!(volobj =3D virStoragePoolObjAddVolume(pool, vol))) + if (!(volobj =3D virStoragePoolObjAddVolume(obj, vol))) goto cleanup; =20 vol =3D NULL; @@ -3746,7 +3756,6 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr pool, } =20 =20 - static int getNewStyleBlockDevice(const char *lun_path, const char *block_name ATTRIBUTE_UNUSED, @@ -3952,7 +3961,7 @@ getDeviceType(uint32_t host, * -2 =3D> non-fatal error or a non-disk entry */ static int -processLU(virStoragePoolObjPtr pool, +processLU(virPoolObjPtr obj, uint32_t host, uint32_t bus, uint32_t target, @@ -3987,7 +3996,7 @@ processLU(virStoragePoolObjPtr pool, return retval; } =20 - retval =3D virStorageBackendSCSINewLun(pool, host, bus, target, lun, + retval =3D virStorageBackendSCSINewLun(obj, host, bus, target, lun, block_device); if (retval < 0) { VIR_DEBUG("Failed to create new storage volume for %u:%u:%u:%u", @@ -4005,9 +4014,10 @@ processLU(virStoragePoolObjPtr pool, =20 =20 int -virStorageBackendSCSIFindLUs(virStoragePoolObjPtr pool, +virStorageBackendSCSIFindLUs(virPoolObjPtr obj, uint32_t scanhost) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); int retval =3D 0; uint32_t bus, target, lun; const char *device_path =3D "/sys/bus/scsi/devices"; @@ -4035,7 +4045,7 @@ virStorageBackendSCSIFindLUs(virStoragePoolObjPtr poo= l, =20 VIR_DEBUG("Found possible LU '%s'", lun_dirent->d_name); =20 - rc =3D processLU(pool, scanhost, bus, target, lun); + rc =3D processLU(obj, scanhost, bus, target, lun); if (rc =3D=3D -1) { retval =3D -1; break; @@ -4049,7 +4059,7 @@ virStorageBackendSCSIFindLUs(virStoragePoolObjPtr poo= l, if (retval < 0) return -1; =20 - VIR_DEBUG("Found %d LUs for pool %s", found, pool->def->name); + VIR_DEBUG("Found %d LUs for pool %s", found, def->name); =20 return found; } diff --git a/src/storage/storage_util.h b/src/storage/storage_util.h index 326d555..82a4adc 100644 --- a/src/storage/storage_util.h +++ b/src/storage/storage_util.h @@ -22,7 +22,6 @@ # include =20 # include "internal.h" -# include "storage_conf.h" # include "vircommand.h" # include "storage_driver.h" # include "storage_backend.h" @@ -33,37 +32,37 @@ virStorageBackendGetBuildVolFromFunction(virStorageVolD= efPtr vol, virStorageVolDefPtr inputvol); =20 int virStorageBackendVolCreateLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr obj, virStorageVolDefPtr vol); =20 int virStorageBackendVolBuildLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags); =20 int virStorageBackendVolBuildFromLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags); =20 int virStorageBackendVolDeleteLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned int flags); =20 int virStorageBackendVolRefreshLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol); =20 int virStorageBackendVolResizeLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, virStorageVolDefPtr vol, unsigned long long capacity, unsigned int flags); =20 int virStorageBackendVolUploadLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr obj, virStorageVolDefPtr vol, virStreamPtr stream, unsigned long long offset, @@ -71,7 +70,7 @@ int virStorageBackendVolUploadLocal(virConnectPtr conn, unsigned int flags); =20 int virStorageBackendVolDownloadLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr obj, virStorageVolDefPtr vol, virStreamPtr stream, unsigned long long offset, @@ -79,20 +78,20 @@ int virStorageBackendVolDownloadLocal(virConnectPtr con= n, unsigned int flags); =20 int virStorageBackendVolWipeLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr obj, virStorageVolDefPtr vol, unsigned int algorithm, unsigned int flags); =20 /* Local/Common Storage Pool Backend APIs */ -int virStorageBackendBuildLocal(virStoragePoolObjPtr pool); +int virStorageBackendBuildLocal(virPoolObjPtr poolobj); =20 int virStorageBackendDeleteLocal(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, unsigned int flags); =20 int virStorageBackendRefreshLocal(virConnectPtr conn, - virStoragePoolObjPtr pool); + virPoolObjPtr poolobj); =20 int virStorageBackendFindGlusterPoolSources(const char *host, int pooltype, @@ -147,13 +146,13 @@ int virStorageBackendUpdateVolTargetInfoFD(virStorage= SourcePtr target, struct stat *sb); =20 bool virStorageBackendPoolPathIsStable(const char *path); -char *virStorageBackendStablePath(virStoragePoolObjPtr pool, +char *virStorageBackendStablePath(virPoolObjPtr obj, const char *devpath, bool loop); =20 virCommandPtr virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, - virStoragePoolObjPtr pool, + virPoolObjPtr obj, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags, @@ -161,7 +160,7 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr = conn, int imgformat, const char *secretPath); =20 -int virStorageBackendSCSIFindLUs(virStoragePoolObjPtr pool, +int virStorageBackendSCSIFindLUs(virPoolObjPtr obj, uint32_t scanhost); =20 #endif /* __VIR_STORAGE_UTIL_H__ */ diff --git a/src/test/test_driver.c b/src/test/test_driver.c index fedf415..26924b5 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -50,6 +50,7 @@ #include "snapshot_conf.h" #include "fdstream.h" #include "storage_conf.h" +#include "virstorageobj.h" #include "storage_event.h" #include "node_device_conf.h" #include "virnodedeviceobj.h" @@ -100,7 +101,7 @@ struct _testDriver { virPoolObjTablePtr ifaces; bool transaction_running; virPoolObjTablePtr backupIfaces; - virStoragePoolObjList pools; + virPoolObjTablePtr pools; virPoolObjTablePtr devs; int numCells; testCell cells[MAX_CELLS]; @@ -156,7 +157,7 @@ testDriverFree(testDriverPtr driver) virObjectUnref(driver->networks); virObjectUnref(driver->ifaces); virObjectUnref(driver->backupIfaces); - virStoragePoolObjListFree(&driver->pools); + virObjectUnref(driver->pools); virObjectUnref(driver->eventState); virMutexUnlock(&driver->lock); virMutexDestroy(&driver->lock); @@ -423,6 +424,10 @@ testDriverNew(void) !(ret->ifaces =3D virPoolObjTableNew(VIR_POOLOBJTABLE_INTERFACE, VIR_POOLOBJTABLE_INTERFACE_HASH= START, true)) || + !(ret->pools =3D + virPoolObjTableNew(VIR_POOLOBJTABLE_BLOCK_STORAGE, + VIR_POOLOBJTABLE_BLOCK_STORAGE_HASHSTART, + false)) || !(ret->domains =3D virDomainObjListNew()) || !(ret->networks =3D virNetworkObjListNew())) goto error; @@ -537,7 +542,7 @@ static const char *defaultPoolSourcesNetFSXML =3D static const unsigned long long defaultPoolCap =3D (100 * 1024 * 1024 * 10= 24ull); static const unsigned long long defaultPoolAlloc; =20 -static int testStoragePoolObjSetDefaults(virStoragePoolObjPtr pool); +static int testStoragePoolObjSetDefaults(virPoolObjPtr obj); static int testNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info); =20 static virDomainObjPtr @@ -1009,9 +1014,10 @@ testParseInterfaces(testDriverPtr privconn, static int testOpenVolumesForPool(const char *file, xmlXPathContextPtr ctxt, - virStoragePoolObjPtr pool, + virPoolObjPtr poolobj, int poolidx) { + virStoragePoolDefPtr pooldef =3D virPoolObjGetDef(poolobj); char *vol_xpath; size_t i; int num, ret =3D -1; @@ -1033,30 +1039,29 @@ testOpenVolumesForPool(const char *file, if (!(node =3D testParseXMLDocFromFile(nodes[i], file, "volume"))) goto error; =20 - if (!(def =3D virStorageVolDefParseNode(pool->def, ctxt->doc, node= , 0))) + if (!(def =3D virStorageVolDefParseNode(pooldef, ctxt->doc, node, = 0))) goto error; =20 if (def->target.path =3D=3D NULL) { if (virAsprintf(&def->target.path, "%s/%s", - pool->def->target.path, def->name) < 0) + pooldef->target.path, def->name) < 0) goto error; } =20 if (!def->key && VIR_STRDUP(def->key, def->target.path) < 0) goto error; =20 - if (!(volobj =3D virStoragePoolObjAddVolume(pool, def))) + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, def))) goto error; =20 - pool->def->allocation +=3D def->target.allocation; - pool->def->available =3D (pool->def->capacity - - pool->def->allocation); + pooldef->allocation +=3D def->target.allocation; + pooldef->available =3D pooldef->capacity - pooldef->allocation; def =3D NULL; + virPoolObjEndAPI(&volobj); } =20 ret =3D 0; error: - virPoolObjEndAPI(&volobj); virStorageVolDefFree(def); VIR_FREE(nodes); return ret; @@ -1070,46 +1075,40 @@ testParseStorage(testDriverPtr privconn, int num, ret =3D -1; size_t i; xmlNodePtr *nodes =3D NULL; - virStoragePoolObjPtr obj; + xmlNodePtr node; + virStoragePoolDefPtr def =3D NULL; + virPoolObjPtr obj =3D NULL; =20 num =3D virXPathNodeSet("/node/pool", ctxt, &nodes); if (num < 0) goto error; =20 for (i =3D 0; i < num; i++) { - virStoragePoolDefPtr def; - xmlNodePtr node =3D testParseXMLDocFromFile(nodes[i], file, - "pool"); - if (!node) + if (!(node =3D testParseXMLDocFromFile(nodes[i], file, "pool"))) goto error; =20 - def =3D virStoragePoolDefParseNode(ctxt->doc, node); - if (!def) + if (!(def =3D virStoragePoolDefParseNode(ctxt->doc, node))) goto error; =20 - if (!(obj =3D virStoragePoolObjAssignDef(&privconn->pools, - def))) { - virStoragePoolDefFree(def); + if (!(obj =3D virStoragePoolObjAdd(privconn->pools, def))) goto error; - } + def =3D NULL; =20 - if (testStoragePoolObjSetDefaults(obj) =3D=3D -1) { - virStoragePoolObjUnlock(obj); + if (testStoragePoolObjSetDefaults(obj) =3D=3D -1) goto error; - } - obj->active =3D 1; + virPoolObjSetActive(obj, true); =20 /* Find storage volumes */ - if (testOpenVolumesForPool(file, ctxt, obj, i+1) < 0) { - virStoragePoolObjUnlock(obj); + if (testOpenVolumesForPool(file, ctxt, obj, i + 1) < 0) goto error; - } =20 - virStoragePoolObjUnlock(obj); + virPoolObjEndAPI(&obj); } =20 ret =3D 0; error: + virStoragePoolDefFree(def); + virPoolObjEndAPI(&obj); VIR_FREE(nodes); return ret; } @@ -3951,14 +3950,29 @@ testInterfaceDestroy(virInterfacePtr iface, */ =20 =20 -static int testStoragePoolObjSetDefaults(virStoragePoolObjPtr pool) +static int +testStoragePoolObjSetDefaults(virPoolObjPtr obj) +{ + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + + def->capacity =3D defaultPoolCap; + def->allocation =3D defaultPoolAlloc; + def->available =3D defaultPoolCap - defaultPoolAlloc; + + return 0; +} + + +static virPoolObjPtr +testStoragePoolObjFindByUUID(virPoolObjTablePtr pools, + const unsigned char *uuid) { + virPoolObjPtr obj; =20 - pool->def->capacity =3D defaultPoolCap; - pool->def->allocation =3D defaultPoolAlloc; - pool->def->available =3D defaultPoolCap - defaultPoolAlloc; + if (!(obj =3D virPoolObjTableFindByUUIDRef(pools, uuid))) + virReportError(VIR_ERR_NO_STORAGE_POOL, NULL); =20 - return VIR_STRDUP(pool->configFile, ""); + return obj; } =20 =20 @@ -3967,156 +3981,114 @@ testStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid) { testDriverPtr privconn =3D conn->privateData; - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; virStoragePoolPtr ret =3D NULL; =20 - testDriverLock(privconn); - pool =3D virStoragePoolObjFindByUUID(&privconn->pools, uuid); - testDriverUnlock(privconn); - - if (pool =3D=3D NULL) { - virReportError(VIR_ERR_NO_STORAGE_POOL, NULL); - goto cleanup; - } + if (!(obj =3D testStoragePoolObjFindByUUID(privconn->pools, uuid))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - ret =3D virGetStoragePool(conn, pool->def->name, pool->def->uuid, - NULL, NULL); + ret =3D virGetStoragePool(conn, def->name, def->uuid, NULL, NULL); =20 - cleanup: - if (pool) - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 + +static virPoolObjPtr +testStoragePoolObjFromStoragePool(virStoragePoolPtr pool) +{ + testDriverPtr privconn =3D pool->conn->privateData; + + return testStoragePoolObjFindByUUID(privconn->pools, pool->uuid); +} + + +static virPoolObjPtr +testStoragePoolObjFindByName(virPoolObjTablePtr pools, + const char *name) +{ + virPoolObjPtr obj; + + if (!(obj =3D virPoolObjTableFindByName(pools, name))) + virReportError(VIR_ERR_NO_STORAGE_POOL, NULL); + + return obj; +} + + static virStoragePoolPtr testStoragePoolLookupByName(virConnectPtr conn, const char *name) { testDriverPtr privconn =3D conn->privateData; - virStoragePoolObjPtr pool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; virStoragePoolPtr ret =3D NULL; =20 - testDriverLock(privconn); - pool =3D virStoragePoolObjFindByName(&privconn->pools, name); - testDriverUnlock(privconn); - - if (pool =3D=3D NULL) { - virReportError(VIR_ERR_NO_STORAGE_POOL, NULL); - goto cleanup; - } + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, name))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - ret =3D virGetStoragePool(conn, pool->def->name, pool->def->uuid, - NULL, NULL); + ret =3D virGetStoragePool(conn, def->name, def->uuid, NULL, NULL); =20 - cleanup: - if (pool) - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&obj); return ret; } =20 + static virStoragePoolPtr testStoragePoolLookupByVolume(virStorageVolPtr vol) { return testStoragePoolLookupByName(vol->conn, vol->pool); } =20 + static int testConnectNumOfStoragePools(virConnectPtr conn) { testDriverPtr privconn =3D conn->privateData; - int numActive =3D 0; - size_t i; =20 - testDriverLock(privconn); - for (i =3D 0; i < privconn->pools.count; i++) - if (virStoragePoolObjIsActive(privconn->pools.objs[i])) - numActive++; - testDriverUnlock(privconn); - - return numActive; + return virStoragePoolObjNumOfStoragePools(privconn->pools, conn, + true, NULL); } =20 + static int testConnectListStoragePools(virConnectPtr conn, char **const names, - int nnames) + int maxnames) { testDriverPtr privconn =3D conn->privateData; - int n =3D 0; - size_t i; =20 - testDriverLock(privconn); - memset(names, 0, sizeof(*names)*nnames); - for (i =3D 0; i < privconn->pools.count && n < nnames; i++) { - virStoragePoolObjLock(privconn->pools.objs[i]); - if (virStoragePoolObjIsActive(privconn->pools.objs[i]) && - VIR_STRDUP(names[n++], privconn->pools.objs[i]->def->name) < 0= ) { - virStoragePoolObjUnlock(privconn->pools.objs[i]); - goto error; - } - virStoragePoolObjUnlock(privconn->pools.objs[i]); - } - testDriverUnlock(privconn); - - return n; - - error: - for (n =3D 0; n < nnames; n++) - VIR_FREE(names[n]); - testDriverUnlock(privconn); - return -1; + return virStoragePoolObjGetNames(privconn->pools, conn, true, NULL, + names, maxnames); } =20 + static int testConnectNumOfDefinedStoragePools(virConnectPtr conn) { testDriverPtr privconn =3D conn->privateData; - int numInactive =3D 0; - size_t i; =20 - testDriverLock(privconn); - for (i =3D 0; i < privconn->pools.count; i++) { - virStoragePoolObjLock(privconn->pools.objs[i]); - if (!virStoragePoolObjIsActive(privconn->pools.objs[i])) - numInactive++; - virStoragePoolObjUnlock(privconn->pools.objs[i]); - } - testDriverUnlock(privconn); - - return numInactive; + return virStoragePoolObjNumOfStoragePools(privconn->pools, conn, + false, NULL); } =20 + static int testConnectListDefinedStoragePools(virConnectPtr conn, char **const names, - int nnames) + int maxnames) { testDriverPtr privconn =3D conn->privateData; - int n =3D 0; - size_t i; - - testDriverLock(privconn); - memset(names, 0, sizeof(*names)*nnames); - for (i =3D 0; i < privconn->pools.count && n < nnames; i++) { - virStoragePoolObjLock(privconn->pools.objs[i]); - if (!virStoragePoolObjIsActive(privconn->pools.objs[i]) && - VIR_STRDUP(names[n++], privconn->pools.objs[i]->def->name) < 0= ) { - virStoragePoolObjUnlock(privconn->pools.objs[i]); - goto error; - } - virStoragePoolObjUnlock(privconn->pools.objs[i]); - } - testDriverUnlock(privconn); =20 - return n; - - error: - for (n =3D 0; n < nnames; n++) - VIR_FREE(names[n]); - testDriverUnlock(privconn); - return -1; + return virStoragePoolObjGetNames(privconn->pools, conn, false, NULL, + names, maxnames); } =20 + static int testConnectListAllStoragePools(virConnectPtr conn, virStoragePoolPtr **pools, @@ -4127,86 +4099,65 @@ testConnectListAllStoragePools(virConnectPtr conn, =20 virCheckFlags(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ALL, -1); =20 - testDriverLock(privconn); - ret =3D virStoragePoolObjListExport(conn, privconn->pools, pools, + ret =3D virStoragePoolObjExportList(conn, privconn->pools, pools, NULL, flags); - testDriverUnlock(privconn); =20 return ret; } =20 -static int testStoragePoolIsActive(virStoragePoolPtr pool) + +static int +testStoragePoolIsActive(virStoragePoolPtr pool) { - testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr obj; + virPoolObjPtr obj; int ret =3D -1; =20 - testDriverLock(privconn); - obj =3D virStoragePoolObjFindByUUID(&privconn->pools, pool->uuid); - testDriverUnlock(privconn); - if (!obj) { - virReportError(VIR_ERR_NO_STORAGE_POOL, NULL); - goto cleanup; - } - ret =3D virStoragePoolObjIsActive(obj); + if (!(obj =3D testStoragePoolObjFromStoragePool(pool))) + return -1; =20 - cleanup: - if (obj) - virStoragePoolObjUnlock(obj); + ret =3D virPoolObjIsActive(obj); + + virPoolObjEndAPI(&obj); return ret; } =20 -static int testStoragePoolIsPersistent(virStoragePoolPtr pool) +static int +testStoragePoolIsPersistent(virStoragePoolPtr pool) { - testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr obj; + virPoolObjPtr obj; int ret =3D -1; =20 - testDriverLock(privconn); - obj =3D virStoragePoolObjFindByUUID(&privconn->pools, pool->uuid); - testDriverUnlock(privconn); - if (!obj) { - virReportError(VIR_ERR_NO_STORAGE_POOL, NULL); - goto cleanup; - } - ret =3D obj->configFile ? 1 : 0; + if (!(obj =3D testStoragePoolObjFromStoragePool(pool))) + return -1; =20 - cleanup: - if (obj) - virStoragePoolObjUnlock(obj); + ret =3D virStoragePoolObjPrivateGetConfigFile(obj) ? 1 : 0; + + virPoolObjEndAPI(&obj); return ret; } =20 =20 - static int testStoragePoolCreate(virStoragePoolPtr pool, unsigned int flags) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; int ret =3D -1; virObjectEventPtr event =3D NULL; =20 virCheckFlags(0, -1); =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) + return -1; =20 - if (virStoragePoolObjIsActive(privpool)) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is already active"), pool->nam= e); goto cleanup; } =20 - privpool->active =3D 1; + virPoolObjSetActive(obj, true); =20 event =3D virStoragePoolEventLifecycleNew(pool->name, pool->uuid, VIR_STORAGE_POOL_EVENT_STARTED, @@ -4215,11 +4166,11 @@ testStoragePoolCreate(virStoragePoolPtr pool, =20 cleanup: testObjectEventQueue(privconn, event); - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&obj); return ret; } =20 + static char * testConnectFindStoragePoolSources(virConnectPtr conn ATTRIBUTE_UNUSED, const char *type, @@ -4232,18 +4183,15 @@ testConnectFindStoragePoolSources(virConnectPtr con= n ATTRIBUTE_UNUSED, =20 virCheckFlags(0, NULL); =20 - pool_type =3D virStoragePoolTypeFromString(type); - if (!pool_type) { + if (!(pool_type =3D virStoragePoolTypeFromString(type))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unknown storage pool type %s"), type); goto cleanup; } =20 - if (srcSpec) { - source =3D virStoragePoolDefParseSourceString(srcSpec, pool_type); - if (!source) - goto cleanup; - } + if (srcSpec && + !(source =3D virStoragePoolDefParseSourceString(srcSpec, pool_type= ))) + goto cleanup; =20 switch (pool_type) { =20 @@ -4280,52 +4228,49 @@ testStoragePoolCreateXML(virConnectPtr conn, { testDriverPtr privconn =3D conn->privateData; virStoragePoolDefPtr def; - virStoragePoolObjPtr pool =3D NULL; + virPoolObjPtr obj =3D NULL; + virStoragePoolDefPtr pooldef; virStoragePoolPtr ret =3D NULL; virObjectEventPtr event =3D NULL; =20 virCheckFlags(0, NULL); =20 - testDriverLock(privconn); if (!(def =3D virStoragePoolDefParseString(xml))) goto cleanup; =20 - pool =3D virStoragePoolObjFindByUUID(&privconn->pools, def->uuid); - if (!pool) - pool =3D virStoragePoolObjFindByName(&privconn->pools, def->name); - if (pool) { + if (!(obj =3D virPoolObjTableFindByUUIDRef(privconn->pools, def->uuid)= )) + obj =3D virPoolObjTableFindByName(privconn->pools, def->name); + + if (obj) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("storage pool already exists")); goto cleanup; } =20 - if (!(pool =3D virStoragePoolObjAssignDef(&privconn->pools, def))) + if (!(obj =3D virStoragePoolObjAdd(privconn->pools, def))) goto cleanup; - def =3D NULL; + VIR_STEAL_PTR(pooldef, def); =20 - if (testStoragePoolObjSetDefaults(pool) =3D=3D -1) { - virStoragePoolObjRemove(&privconn->pools, pool); - pool =3D NULL; + if (testStoragePoolObjSetDefaults(obj) =3D=3D -1) { + virPoolObjTableRemove(privconn->pools, &obj); goto cleanup; } - pool->active =3D 1; + virPoolObjSetActive(obj, true); =20 - event =3D virStoragePoolEventLifecycleNew(pool->def->name, pool->def->= uuid, + event =3D virStoragePoolEventLifecycleNew(pooldef->name, pooldef->uuid, VIR_STORAGE_POOL_EVENT_STARTED, 0); =20 - ret =3D virGetStoragePool(conn, pool->def->name, pool->def->uuid, - NULL, NULL); + ret =3D virGetStoragePool(conn, pooldef->name, pooldef->uuid, NULL, NU= LL); =20 cleanup: virStoragePoolDefFree(def); testObjectEventQueue(privconn, event); - if (pool) - virStoragePoolObjUnlock(pool); - testDriverUnlock(privconn); + virPoolObjEndAPI(&obj); return ret; } =20 + static virStoragePoolPtr testStoragePoolDefineXML(virConnectPtr conn, const char *xml, @@ -4333,13 +4278,13 @@ testStoragePoolDefineXML(virConnectPtr conn, { testDriverPtr privconn =3D conn->privateData; virStoragePoolDefPtr def; - virStoragePoolObjPtr pool =3D NULL; + virPoolObjPtr obj =3D NULL; + virStoragePoolDefPtr pooldef; virStoragePoolPtr ret =3D NULL; virObjectEventPtr event =3D NULL; =20 virCheckFlags(0, NULL); =20 - testDriverLock(privconn); if (!(def =3D virStoragePoolDefParseString(xml))) goto cleanup; =20 @@ -4347,50 +4292,41 @@ testStoragePoolDefineXML(virConnectPtr conn, def->allocation =3D defaultPoolAlloc; def->available =3D defaultPoolCap - defaultPoolAlloc; =20 - if (!(pool =3D virStoragePoolObjAssignDef(&privconn->pools, def))) + if (!(obj =3D virStoragePoolObjAdd(privconn->pools, def))) goto cleanup; - def =3D NULL; + VIR_STEAL_PTR(pooldef, def); =20 - event =3D virStoragePoolEventLifecycleNew(pool->def->name, pool->def->= uuid, + event =3D virStoragePoolEventLifecycleNew(pooldef->name, pooldef->uuid, VIR_STORAGE_POOL_EVENT_DEFINED, 0); =20 - if (testStoragePoolObjSetDefaults(pool) =3D=3D -1) { - virStoragePoolObjRemove(&privconn->pools, pool); - pool =3D NULL; + if (testStoragePoolObjSetDefaults(obj) =3D=3D -1) { + virPoolObjTableRemove(privconn->pools, &obj); goto cleanup; } =20 - ret =3D virGetStoragePool(conn, pool->def->name, pool->def->uuid, - NULL, NULL); + ret =3D virGetStoragePool(conn, pooldef->name, pooldef->uuid, NULL, NU= LL); =20 cleanup: virStoragePoolDefFree(def); testObjectEventQueue(privconn, event); - if (pool) - virStoragePoolObjUnlock(pool); - testDriverUnlock(privconn); + virPoolObjEndAPI(&obj); return ret; } =20 + static int testStoragePoolUndefine(virStoragePoolPtr pool) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; int ret =3D -1; virObjectEventPtr event =3D NULL; =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) + return -1; =20 - if (virStoragePoolObjIsActive(privpool)) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is already active"), pool->nam= e); goto cleanup; @@ -4400,48 +4336,39 @@ testStoragePoolUndefine(virStoragePoolPtr pool) VIR_STORAGE_POOL_EVENT_UNDEFIN= ED, 0); =20 - virStoragePoolObjRemove(&privconn->pools, privpool); - privpool =3D NULL; + virPoolObjTableRemove(privconn->pools, &obj); ret =3D 0; =20 cleanup: - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&obj); testObjectEventQueue(privconn, event); - testDriverUnlock(privconn); return ret; } =20 + static int testStoragePoolBuild(virStoragePoolPtr pool, unsigned int flags) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; int ret =3D -1; =20 virCheckFlags(0, -1); =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) + return -1; =20 - if (virStoragePoolObjIsActive(privpool)) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is already active"), pool->nam= e); goto cleanup; } + ret =3D 0; =20 cleanup: - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -4450,41 +4377,34 @@ static int testStoragePoolDestroy(virStoragePoolPtr pool) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; int ret =3D -1; virObjectEventPtr event =3D NULL; =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (!virStoragePoolObjIsActive(privpool)) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), pool->name); goto cleanup; } =20 - privpool->active =3D 0; - event =3D virStoragePoolEventLifecycleNew(privpool->def->name, privpoo= l->def->uuid, + virPoolObjSetActive(obj, false); + event =3D virStoragePoolEventLifecycleNew(def->name, def->uuid, VIR_STORAGE_POOL_EVENT_STOPPED, 0); =20 - if (privpool->configFile =3D=3D NULL) { - virStoragePoolObjRemove(&privconn->pools, privpool); - privpool =3D NULL; - } + if (!virStoragePoolObjPrivateGetConfigFile(obj)) + virPoolObjTableRemove(privconn->pools, &obj); + ret =3D 0; =20 cleanup: testObjectEventQueue(privconn, event); - if (privpool) - virStoragePoolObjUnlock(privpool); - testDriverUnlock(privconn); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -4494,22 +4414,15 @@ testStoragePoolDelete(virStoragePoolPtr pool, unsigned int flags) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; int ret =3D -1; =20 virCheckFlags(0, -1); =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) + return -1; =20 - if (virStoragePoolObjIsActive(privpool)) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is already active"), pool->nam= e); goto cleanup; @@ -4518,8 +4431,7 @@ testStoragePoolDelete(virStoragePoolPtr pool, ret =3D 0; =20 cleanup: - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -4529,23 +4441,16 @@ testStoragePoolRefresh(virStoragePoolPtr pool, unsigned int flags) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; int ret =3D -1; virObjectEventPtr event =3D NULL; =20 virCheckFlags(0, -1); =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) + return -1; =20 - if (!virStoragePoolObjIsActive(privpool)) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), pool->name); goto cleanup; @@ -4556,8 +4461,7 @@ testStoragePoolRefresh(virStoragePoolPtr pool, =20 cleanup: testObjectEventQueue(privconn, event); - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -4567,125 +4471,94 @@ testStoragePoolGetInfo(virStoragePoolPtr pool, virStoragePoolInfoPtr info) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; + virStoragePoolDefPtr def; int ret =3D -1; =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) + return -1; + def =3D virPoolObjGetDef(obj); =20 memset(info, 0, sizeof(virStoragePoolInfo)); - if (privpool->active) + if (virPoolObjIsActive(obj)) info->state =3D VIR_STORAGE_POOL_RUNNING; else info->state =3D VIR_STORAGE_POOL_INACTIVE; - info->capacity =3D privpool->def->capacity; - info->allocation =3D privpool->def->allocation; - info->available =3D privpool->def->available; + info->capacity =3D def->capacity; + info->allocation =3D def->allocation; + info->available =3D def->available; ret =3D 0; =20 - cleanup: - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&obj); return ret; } =20 + static char * testStoragePoolGetXMLDesc(virStoragePoolPtr pool, unsigned int flags) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; char *ret =3D NULL; =20 virCheckFlags(0, NULL); =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) + return NULL; =20 - ret =3D virStoragePoolDefFormat(privpool->def); + ret =3D virStoragePoolDefFormat(virPoolObjGetDef(obj)); =20 - cleanup: - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&obj); return ret; } =20 + static int testStoragePoolGetAutostart(virStoragePoolPtr pool, int *autostart) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; int ret =3D -1; =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) + return -1; =20 - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + *autostart =3D 0; + if (virStoragePoolObjPrivateGetConfigFile(obj) && + virPoolObjIsAutostart(obj)) + *autostart =3D 1; =20 - if (!privpool->configFile) { - *autostart =3D 0; - } else { - *autostart =3D privpool->autostart; - } ret =3D 0; =20 - cleanup: - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&obj); return ret; } =20 + static int testStoragePoolSetAutostart(virStoragePoolPtr pool, int autostart) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; int ret =3D -1; =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) + return -1; =20 - if (!privpool->configFile) { + if (!virStoragePoolObjPrivateGetConfigFile(obj)) { virReportError(VIR_ERR_INVALID_ARG, "%s", _("pool has no config file")); goto cleanup; } =20 - autostart =3D (autostart !=3D 0); - privpool->autostart =3D autostart; + virPoolObjSetAutostart(obj, (autostart !=3D 0)); ret =3D 0; =20 cleanup: - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -4694,20 +4567,15 @@ static int testStoragePoolNumOfVolumes(virStoragePoolPtr pool) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; + virPoolObjTablePtr objvolumes; int ret =3D -1; =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (!privpool) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) return -1; - } + objvolumes =3D virStoragePoolObjPrivateGetVolumes(obj); =20 - if (!virStoragePoolObjIsActive(privpool)) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), pool->name); goto cleanup; @@ -4715,11 +4583,10 @@ testStoragePoolNumOfVolumes(virStoragePoolPtr pool) =20 /* NB: Neither pool->def nor aclfilter is being used for test purposes * so last two args can be NULL */ - ret =3D virStoragePoolObjNumOfVolumes(privpool->volumes, pool->conn, - NULL, NULL); + ret =3D virStoragePoolObjNumOfVolumes(objvolumes, pool->conn, NULL, NU= LL); =20 cleanup: - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -4732,21 +4599,16 @@ testStoragePoolListVolumes(virStoragePoolPtr pool, { int ret =3D -1; testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr obj; + virPoolObjTablePtr objvolumes; =20 memset(names, 0, maxnames * sizeof(*names)); =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (!privpool) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - return -1; - } + if (!(obj =3D testStoragePoolObjFindByName(privconn->pools, pool->name= ))) + goto cleanup; + objvolumes =3D virStoragePoolObjPrivateGetVolumes(obj); =20 - if (!virStoragePoolObjIsActive(privpool)) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), pool->name); goto cleanup; @@ -4754,22 +4616,24 @@ testStoragePoolListVolumes(virStoragePoolPtr pool, =20 /* NB: Neither pool->def nor aclfilter is being used for test purposes * so those two args can be NULL */ - ret =3D virStoragePoolObjListVolumes(privpool->volumes, pool->conn, + ret =3D virStoragePoolObjListVolumes(objvolumes, pool->conn, NULL, NULL, names, maxnames); =20 cleanup: - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&obj); return ret; } =20 =20 static int -testStoragePoolListAllVolumes(virStoragePoolPtr obj, +testStoragePoolListAllVolumes(virStoragePoolPtr pool, virStorageVolPtr **volumes, unsigned int flags) { - testDriverPtr privconn =3D obj->conn->privateData; - virStoragePoolObjPtr pool; + testDriverPtr privconn =3D pool->conn->privateData; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; + virPoolObjTablePtr poolobjvolumes; virPoolObjPtr *volobjs =3D NULL; size_t nvolobjs =3D 0; size_t i; @@ -4778,23 +4642,22 @@ testStoragePoolListAllVolumes(virStoragePoolPtr obj, =20 virCheckFlags(0, -1); =20 - testDriverLock(privconn); - pool =3D virStoragePoolObjFindByUUID(&privconn->pools, obj->uuid); - testDriverUnlock(privconn); - - if (!pool) { + if (!(poolobj =3D testStoragePoolObjFindByUUID(privconn->pools, + pool->uuid))) { virReportError(VIR_ERR_NO_STORAGE_POOL, "%s", _("no storage pool with matching uuid")); return -1; } + pooldef =3D virPoolObjGetDef(poolobj); + poolobjvolumes =3D virStoragePoolObjPrivateGetVolumes(poolobj); =20 - if (!virStoragePoolObjIsActive(pool)) { + if (!virPoolObjIsActive(poolobj)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("storage pool is not active")); goto cleanup; } =20 - if (virPoolObjTableCollect(pool->volumes, obj->conn, &volobjs, &nvolob= js, + if (virPoolObjTableCollect(poolobjvolumes, pool->conn, &volobjs, &nvol= objs, NULL, NULL, flags) < 0) goto cleanup; =20 @@ -4804,12 +4667,12 @@ testStoragePoolListAllVolumes(virStoragePoolPtr obj, =20 for (i =3D 0; i < nvolobjs; i++) { virPoolObjPtr volobj =3D volobjs[i]; - virStorageVolDefPtr def; + virStorageVolDefPtr voldef; =20 virObjectLock(volobj); - def =3D virPoolObjGetDef(volobj); - vols[i] =3D virGetStorageVol(obj->conn, pool->def->name, - def->name, def->key, NULL, NULL); + voldef =3D virPoolObjGetDef(volobj); + vols[i] =3D virGetStorageVol(pool->conn, pooldef->name, + voldef->name, voldef->key, NULL, NU= LL); virObjectUnlock(volobj); =20 if (!vols[i]) @@ -4825,88 +4688,99 @@ testStoragePoolListAllVolumes(virStoragePoolPtr obj, cleanup: virObjectListFree(vols); virObjectListFreeCount(volobjs, nvolobjs); - - virStoragePoolObjUnlock(pool); + virPoolObjEndAPI(&poolobj); return ret; } =20 static virStorageVolPtr testStorageVolLookupByName(virStoragePoolPtr pool, - const char *name ATTRIBUTE_UNUSED) + const char *name) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj =3D NULL; virStorageVolDefPtr voldef; virStorageVolPtr ret =3D NULL; =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } - + if (!(poolobj =3D testStoragePoolObjFindByName(privconn->pools, pool->= name))) + return NULL; + pooldef =3D virPoolObjGetDef(poolobj); =20 - if (!virStoragePoolObjIsActive(privpool)) { + if (!virPoolObjIsActive(poolobj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), pool->name); goto cleanup; } =20 - if (!(volobj =3D virStorageVolObjFindByName(privpool, name))) { + if (!(volobj =3D virStorageVolObjFindByName(poolobj, name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), name); goto cleanup; } voldef =3D virPoolObjGetDef(volobj); =20 - ret =3D virGetStorageVol(pool->conn, privpool->def->name, - voldef->name, voldef->key, + ret =3D virGetStorageVol(pool->conn, pooldef->name, voldef->name, vold= ef->key, NULL, NULL); =20 cleanup: virPoolObjEndAPI(&volobj); - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&poolobj); return ret; } =20 =20 +struct storageSearchData { + virConnectPtr conn; + const char *key; + const char *path; + char *retname; + char *retkey; +}; + +static bool +storageVolSearchByKey(virPoolObjPtr obj, + void *opaque) +{ + struct storageSearchData *data =3D opaque; + + if (virPoolObjIsActive(obj)) { + virPoolObjPtr volobj; + + if ((volobj =3D virStorageVolObjFindByKey(obj, data->key))) { + virStorageVolDefPtr voldef =3D virPoolObjGetDef(volobj); + + ignore_value(VIR_STRDUP(data->retname, voldef->name)); + virPoolObjEndAPI(&volobj); + } + + if (data->retname) + return true; + } + + return false; +} + + static virStorageVolPtr testStorageVolLookupByKey(virConnectPtr conn, const char *key) { testDriverPtr privconn =3D conn->privateData; - virPoolObjPtr volobj; - virStorageVolDefPtr voldef; - size_t i; virStorageVolPtr ret =3D NULL; + virPoolObjPtr obj; + struct storageSearchData data =3D { .conn =3D conn, + .key =3D key, + .retname =3D NULL }; =20 - testDriverLock(privconn); - for (i =3D 0; i < privconn->pools.count; i++) { - virStoragePoolObjLock(privconn->pools.objs[i]); - if (virStoragePoolObjIsActive(privconn->pools.objs[i])) { - if (!(volobj =3D virStorageVolObjFindByKey(privconn->pools.obj= s[i], - key))) - continue; - voldef =3D virPoolObjGetDef(volobj); + if ((obj =3D virPoolObjTableSearchRef(privconn->pools, storageVolSearc= hByKey, + &data))) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); =20 - ret =3D virGetStorageVol(conn, - privconn->pools.objs[i]->def->name, - voldef->name, - voldef->key, - NULL, NULL); - virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(privconn->pools.objs[i]); - break; - } - virStoragePoolObjUnlock(privconn->pools.objs[i]); + ret =3D virGetStorageVol(conn, def->name, data.retname, key, NULL,= NULL); + VIR_FREE(data.retname); + virPoolObjEndAPI(&obj); } - testDriverUnlock(privconn); =20 if (!ret) virReportError(VIR_ERR_NO_STORAGE_VOL, @@ -4915,37 +4789,57 @@ testStorageVolLookupByKey(virConnectPtr conn, return ret; } =20 + +static bool +storageVolSearchByPath(virPoolObjPtr obj, + void *opaque) +{ + struct storageSearchData *data =3D opaque; + + if (virPoolObjIsActive(obj)) { + virPoolObjPtr volobj; + + if ((volobj =3D virStorageVolObjFindByPath(obj, data->path))) { + virStorageVolDefPtr voldef =3D virPoolObjGetDef(volobj); + + ignore_value(VIR_STRDUP(data->retname, voldef->name)); + ignore_value(VIR_STRDUP(data->retkey, voldef->key)); + + virPoolObjEndAPI(&volobj); + } + + if (data->retname && data->retkey) + return true; + + VIR_FREE(data->retname); + VIR_FREE(data->retkey); + } + + return false; +} + + static virStorageVolPtr testStorageVolLookupByPath(virConnectPtr conn, const char *path) { testDriverPtr privconn =3D conn->privateData; - virPoolObjPtr volobj; - virStorageVolDefPtr voldef; - size_t i; virStorageVolPtr ret =3D NULL; - - testDriverLock(privconn); - for (i =3D 0; i < privconn->pools.count; i++) { - virStoragePoolObjLock(privconn->pools.objs[i]); - if (virStoragePoolObjIsActive(privconn->pools.objs[i])) { - if (!(volobj =3D virStorageVolObjFindByPath(privconn->pools.ob= js[i], - path))) - continue; - voldef =3D virPoolObjGetDef(volobj); - - ret =3D virGetStorageVol(conn, - privconn->pools.objs[i]->def->name, - voldef->name, - voldef->key, - NULL, NULL); - virPoolObjEndAPI(&volobj); - virStoragePoolObjUnlock(privconn->pools.objs[i]); - break; - } - virStoragePoolObjUnlock(privconn->pools.objs[i]); + virPoolObjPtr obj; + struct storageSearchData data =3D { .conn =3D conn, + .path =3D path, + .retname =3D NULL, + .retkey =3D NULL }; + + if ((obj =3D virPoolObjTableSearchRef(privconn->pools, storageVolSearc= hByPath, + &data))) { + virStoragePoolDefPtr def =3D virPoolObjGetDef(obj); + ret =3D virGetStorageVol(conn, def->name, data.retname, data.retke= y, + NULL, NULL); + VIR_FREE(data.retname); + VIR_FREE(data.retkey); + virPoolObjEndAPI(&obj); } - testDriverUnlock(privconn); =20 if (!ret) virReportError(VIR_ERR_NO_STORAGE_VOL, @@ -4954,13 +4848,15 @@ testStorageVolLookupByPath(virConnectPtr conn, return ret; } =20 + static virStorageVolPtr testStorageVolCreateXML(virStoragePoolPtr pool, const char *xmldesc, unsigned int flags) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virStorageVolDefPtr voldef =3D NULL; virPoolObjPtr volobj =3D NULL; virStorageVolDefPtr objvoldef; @@ -4968,34 +4864,27 @@ testStorageVolCreateXML(virStoragePoolPtr pool, =20 virCheckFlags(0, NULL); =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(poolobj =3D testStoragePoolObjFindByName(privconn->pools, pool->= name))) + return NULL; + pooldef =3D virPoolObjGetDef(poolobj); =20 - if (!virStoragePoolObjIsActive(privpool)) { + if (!virPoolObjIsActive(poolobj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), pool->name); goto cleanup; } =20 - if (!(voldef =3D virStorageVolDefParseString(privpool->def, xmldesc, 0= ))) + if (!(voldef =3D virStorageVolDefParseString(pooldef, xmldesc, 0))) goto cleanup; =20 - if ((volobj =3D virStorageVolObjFindByName(privpool, voldef->name))) { + if ((volobj =3D virStorageVolObjFindByName(poolobj, voldef->name))) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("storage vol already exists")); goto cleanup; } =20 /* Make sure enough space */ - if ((privpool->def->allocation + voldef->target.allocation) > - privpool->def->capacity) { + if ((pooldef->allocation + voldef->target.allocation) > pooldef->capac= ity) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Not enough free space in pool for volume '%s'"), voldef->name); @@ -5003,34 +4892,32 @@ testStorageVolCreateXML(virStoragePoolPtr pool, } =20 if (virAsprintf(&voldef->target.path, "%s/%s", - privpool->def->target.path, - voldef->name) =3D=3D -1) + pooldef->target.path, voldef->name) < 0) goto cleanup; =20 if (VIR_STRDUP(voldef->key, voldef->target.path) < 0) goto cleanup; =20 - if (!(volobj =3D virStoragePoolObjAddVolume(privpool, voldef))) + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, voldef))) goto cleanup; VIR_STEAL_PTR(objvoldef, voldef); =20 - privpool->def->allocation +=3D objvoldef->target.allocation; - privpool->def->available =3D (privpool->def->capacity - - privpool->def->allocation); + pooldef->allocation +=3D objvoldef->target.allocation; + pooldef->available =3D pooldef->capacity - pooldef->allocation; =20 - if (!(ret =3D virGetStorageVol(pool->conn, privpool->def->name, + if (!(ret =3D virGetStorageVol(pool->conn, pooldef->name, objvoldef->name, objvoldef->key, NULL, NULL))) - virStoragePoolObjRemoveVolume(privpool, &volobj); + virStoragePoolObjRemoveVolume(poolobj, &volobj); =20 cleanup: virPoolObjEndAPI(&volobj); virStorageVolDefFree(voldef); - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&poolobj); return ret; } =20 + static virStorageVolPtr testStorageVolCreateXMLFrom(virStoragePoolPtr pool, const char *xmldesc, @@ -5038,41 +4925,36 @@ testStorageVolCreateXMLFrom(virStoragePoolPtr pool, unsigned int flags) { testDriverPtr privconn =3D pool->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virStorageVolDefPtr voldef =3D NULL; virPoolObjPtr volobj =3D NULL; - virStorageVolDefPtr objvoldef; + virStorageVolDefPtr objvoldef =3D NULL; virPoolObjPtr origvolobj =3D NULL; virStorageVolPtr ret =3D NULL; =20 virCheckFlags(0, NULL); =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - pool->name); - testDriverUnlock(privconn); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(poolobj =3D testStoragePoolObjFindByName(privconn->pools, pool->= name))) + return NULL; + pooldef =3D virPoolObjGetDef(poolobj); =20 - if (!virStoragePoolObjIsActive(privpool)) { + if (!virPoolObjIsActive(poolobj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), pool->name); goto cleanup; } =20 - if (!(voldef =3D virStorageVolDefParseString(privpool->def, xmldesc, 0= ))) + if (!(voldef =3D virStorageVolDefParseString(pooldef, xmldesc, 0))) goto cleanup; =20 - if ((volobj =3D virStorageVolObjFindByName(privpool, voldef->name))) { + if ((volobj =3D virStorageVolObjFindByName(poolobj, voldef->name))) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("storage vol already exists")); goto cleanup; } =20 - if (!(origvolobj =3D virStorageVolObjFindByName(privpool, clonevol->na= me))) { + if (!(origvolobj =3D virStorageVolObjFindByName(poolobj, clonevol->nam= e))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), clonevol->name); @@ -5080,76 +4962,69 @@ testStorageVolCreateXMLFrom(virStoragePoolPtr pool, } =20 /* Make sure enough space */ - if ((privpool->def->allocation + voldef->target.allocation) > - privpool->def->capacity) { + if ((pooldef->allocation + voldef->target.allocation) > pooldef->capac= ity) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Not enough free space in pool for volume '%s'"), voldef->name); goto cleanup; } - privpool->def->available =3D (privpool->def->capacity - - privpool->def->allocation); + pooldef->available =3D pooldef->capacity - pooldef->allocation; =20 if (virAsprintf(&voldef->target.path, "%s/%s", - privpool->def->target.path, - voldef->name) =3D=3D -1) + pooldef->target.path, voldef->name) < 0) goto cleanup; =20 if (VIR_STRDUP(voldef->key, voldef->target.path) < 0) goto cleanup; =20 - if (!(volobj =3D virStoragePoolObjAddVolume(privpool, voldef))) + if (!(volobj =3D virStoragePoolObjAddVolume(poolobj, voldef))) goto cleanup; VIR_STEAL_PTR(objvoldef, voldef); =20 - privpool->def->allocation +=3D objvoldef->target.allocation; - privpool->def->available =3D (privpool->def->capacity - - privpool->def->allocation); + pooldef->allocation +=3D objvoldef->target.allocation; + pooldef->available =3D pooldef->capacity - pooldef->allocation; + + if (!(ret =3D virGetStorageVol(pool->conn, pooldef->name, objvoldef->n= ame, + objvoldef->key, NULL, NULL))) + virStoragePoolObjRemoveVolume(poolobj, &volobj); =20 - if (!(ret =3D virGetStorageVol(pool->conn, privpool->def->name, - objvoldef->name, objvoldef->key, - NULL, NULL))) - virStoragePoolObjRemoveVolume(privpool, &volobj); =20 cleanup: virPoolObjEndAPI(&origvolobj); virPoolObjEndAPI(&volobj); virStorageVolDefFree(voldef); - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&poolobj); return ret; } =20 + static int testStorageVolDelete(virStorageVolPtr volume, unsigned int flags) { testDriverPtr privconn =3D volume->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; + virPoolObjTablePtr poolobjvolumes; virPoolObjPtr volobj =3D NULL; virStorageVolDefPtr voldef; int ret =3D -1; =20 virCheckFlags(0, -1); =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - volume->pool); - testDriverUnlock(privconn); - - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(poolobj =3D testStoragePoolObjFindByName(privconn->pools, + volume->pool))) + return -1; + pooldef =3D virPoolObjGetDef(poolobj); + poolobjvolumes =3D virStoragePoolObjPrivateGetVolumes(poolobj); =20 - if (!virStoragePoolObjIsActive(privpool)) { + if (!virPoolObjIsActive(poolobj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("storage pool '%s' is not active"), volume->pool); goto cleanup; } =20 - if (!(volobj =3D virPoolObjTableFindByName(privpool->volumes, - volume->name))) { + if (!(volobj =3D virPoolObjTableFindByName(poolobjvolumes, volume->nam= e))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), volume->name); @@ -5157,19 +5032,16 @@ testStorageVolDelete(virStorageVolPtr volume, } voldef =3D virPoolObjGetDef(volobj); =20 - privpool->def->allocation -=3D voldef->target.allocation; - privpool->def->available =3D (privpool->def->capacity - - privpool->def->allocation); + pooldef->allocation -=3D voldef->target.allocation; + pooldef->available =3D pooldef->capacity - pooldef->allocation; =20 - - virStoragePoolObjRemoveVolume(privpool, &volobj); + virPoolObjTableRemove(poolobjvolumes, &volobj); =20 ret =3D 0; =20 cleanup: virPoolObjEndAPI(&volobj); - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&poolobj); return ret; } =20 @@ -5187,27 +5059,30 @@ static int testStorageVolumeTypeForPool(int pooltyp= e) } } =20 + static int testStorageVolGetInfo(virStorageVolPtr volume, virStorageVolInfoPtr info) { testDriverPtr privconn =3D volume->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj =3D NULL; virStorageVolDefPtr voldef; int ret =3D -1; =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - volume->pool); - testDriverUnlock(privconn); + if (!(poolobj =3D testStoragePoolObjFindByName(privconn->pools, + volume->pool))) + return -1; + pooldef =3D virPoolObjGetDef(poolobj); =20 - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); + if (!virPoolObjIsActive(poolobj)) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("storage pool '%s' is not active"), volume->pool); goto cleanup; } =20 - if (!(volobj =3D virStorageVolObjFindByName(privpool, volume->name))) { + if (!(volobj =3D virStorageVolObjFindByName(poolobj, volume->name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), volume->name); @@ -5215,48 +5090,44 @@ testStorageVolGetInfo(virStorageVolPtr volume, } voldef =3D virPoolObjGetDef(volobj); =20 - if (!virStoragePoolObjIsActive(privpool)) { - virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), volume->pool); - goto cleanup; - } - memset(info, 0, sizeof(*info)); - info->type =3D testStorageVolumeTypeForPool(privpool->def->type); + info->type =3D testStorageVolumeTypeForPool(pooldef->type); info->capacity =3D voldef->target.capacity; info->allocation =3D voldef->target.allocation; ret =3D 0; =20 cleanup: virPoolObjEndAPI(&volobj); - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&poolobj); return ret; } =20 + static char * testStorageVolGetXMLDesc(virStorageVolPtr volume, unsigned int flags) { testDriverPtr privconn =3D volume->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr poolobj; + virStoragePoolDefPtr pooldef; virPoolObjPtr volobj =3D NULL; virStorageVolDefPtr voldef; char *ret =3D NULL; =20 virCheckFlags(0, NULL); =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - volume->pool); - testDriverUnlock(privconn); + if (!(poolobj =3D testStoragePoolObjFindByName(privconn->pools, + volume->pool))) + return NULL; + pooldef =3D virPoolObjGetDef(poolobj); =20 - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); + if (!virPoolObjIsActive(poolobj)) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("storage pool '%s' is not active"), volume->pool); goto cleanup; } =20 - if (!(volobj =3D virStorageVolObjFindByName(privpool, volume->name))) { + if (!(volobj =3D virStorageVolObjFindByName(poolobj, volume->name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), volume->name); @@ -5264,41 +5135,35 @@ testStorageVolGetXMLDesc(virStorageVolPtr volume, } voldef =3D virPoolObjGetDef(volobj); =20 - if (!virStoragePoolObjIsActive(privpool)) { - virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), volume->pool); - goto cleanup; - } - - ret =3D virStorageVolDefFormat(privpool->def, voldef); + ret =3D virStorageVolDefFormat(pooldef, voldef); =20 cleanup: virPoolObjEndAPI(&volobj); - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&poolobj); return ret; } =20 + static char * testStorageVolGetPath(virStorageVolPtr volume) { testDriverPtr privconn =3D volume->conn->privateData; - virStoragePoolObjPtr privpool; + virPoolObjPtr poolobj; virPoolObjPtr volobj =3D NULL; virStorageVolDefPtr voldef; char *ret =3D NULL; =20 - testDriverLock(privconn); - privpool =3D virStoragePoolObjFindByName(&privconn->pools, - volume->pool); - testDriverUnlock(privconn); + if (!(poolobj =3D testStoragePoolObjFindByName(privconn->pools, + volume->pool))) + return NULL; =20 - if (privpool =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); + if (!virPoolObjIsActive(poolobj)) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("storage pool '%s' is not active"), volume->pool); goto cleanup; } =20 - if (!(volobj =3D virStorageVolObjFindByName(privpool, volume->name))) { + if (!(volobj =3D virStorageVolObjFindByName(poolobj, volume->name))) { virReportError(VIR_ERR_NO_STORAGE_VOL, _("no storage vol with matching name '%s'"), volume->name); @@ -5306,18 +5171,11 @@ testStorageVolGetPath(virStorageVolPtr volume) } voldef =3D virPoolObjGetDef(volobj); =20 - if (!virStoragePoolObjIsActive(privpool)) { - virReportError(VIR_ERR_OPERATION_INVALID, - _("storage pool '%s' is not active"), volume->pool); - goto cleanup; - } - ignore_value(VIR_STRDUP(ret, voldef->target.path)); =20 cleanup: virPoolObjEndAPI(&volobj); - if (privpool) - virStoragePoolObjUnlock(privpool); + virPoolObjEndAPI(&poolobj); return ret; } =20 diff --git a/tests/storagevolxml2argvtest.c b/tests/storagevolxml2argvtest.c index bf9dbe5..b2a16d3 100644 --- a/tests/storagevolxml2argvtest.c +++ b/tests/storagevolxml2argvtest.c @@ -5,6 +5,7 @@ #include "datatypes.h" #include "storage/storage_util.h" #include "testutilsqemu.h" +#include "virpoolobj.h" #include "virstring.h" =20 #define VIR_FROM_THIS VIR_FROM_NONE @@ -52,7 +53,8 @@ testCompareXMLToArgvFiles(bool shouldFail, virStorageVolDefPtr vol =3D NULL, inputvol =3D NULL; virStoragePoolDefPtr pool =3D NULL; virStoragePoolDefPtr inputpool =3D NULL; - virStoragePoolObj poolobj =3D {.def =3D NULL }; + virPoolObjPtr poolobj =3D NULL; + virStoragePoolDefPtr pooldef; =20 =20 if (!(conn =3D virGetConnect())) @@ -61,7 +63,10 @@ testCompareXMLToArgvFiles(bool shouldFail, if (!(pool =3D virStoragePoolDefParseFile(poolxml))) goto cleanup; =20 - poolobj.def =3D pool; + if (!(poolobj =3D virPoolObjNew(NULL, pool, NULL, virStoragePoolDefFre= e))) + goto cleanup; + virObjectRef(poolobj); + VIR_STEAL_PTR(pooldef, pool); =20 if (inputpoolxml) { if (!(inputpool =3D virStoragePoolDefParseFile(inputpoolxml))) @@ -71,17 +76,17 @@ testCompareXMLToArgvFiles(bool shouldFail, if (inputvolxml) parse_flags |=3D VIR_VOL_XML_PARSE_NO_CAPACITY; =20 - if (!(vol =3D virStorageVolDefParseFile(pool, volxml, parse_flags))) + if (!(vol =3D virStorageVolDefParseFile(pooldef, volxml, parse_flags))) goto cleanup; =20 if (inputvolxml && !(inputvol =3D virStorageVolDefParseFile(inputpool, inputvolxml, 0= ))) goto cleanup; =20 - testSetVolumeType(vol, pool); + testSetVolumeType(vol, pooldef); testSetVolumeType(inputvol, inputpool); =20 - cmd =3D virStorageBackendCreateQemuImgCmdFromVol(conn, &poolobj, vol, + cmd =3D virStorageBackendCreateQemuImgCmdFromVol(conn, poolobj, vol, inputvol, flags, create_tool, imgformat, NULL); @@ -103,6 +108,7 @@ testCompareXMLToArgvFiles(bool shouldFail, =20 cleanup: virStoragePoolDefFree(pool); + virObjectUnref(poolobj); virStoragePoolDefFree(inputpool); virStorageVolDefFree(vol); virStorageVolDefFree(inputvol); --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 03:40:31 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) client-ip=209.132.183.37; envelope-from=libvir-list-bounces@redhat.com; helo=mx5-phx2.redhat.com; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.37 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx5-phx2.redhat.com (mx5-phx2.redhat.com [209.132.183.37]) by mx.zohomail.com with SMTPS id 1486830951655311.5379349312882; Sat, 11 Feb 2017 08:35:51 -0800 (PST) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx5-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGUo0m010246; Sat, 11 Feb 2017 11:30:50 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v1BGTvcu028574 for ; Sat, 11 Feb 2017 11:29:57 -0500 Received: from localhost.localdomain.com (ovpn-116-36.phx2.redhat.com [10.3.116.36]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1BGTmIt000660 for ; Sat, 11 Feb 2017 11:29:56 -0500 From: John Ferlan To: libvir-list@redhat.com Date: Sat, 11 Feb 2017 11:29:45 -0500 Message-Id: <1486830585-23866-10-git-send-email-jferlan@redhat.com> In-Reply-To: <1486830585-23866-1-git-send-email-jferlan@redhat.com> References: <1486830585-23866-1-git-send-email-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH RFC 9/9] network: Convert virNetworkObj[List] to use virPoolObj[Table] 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" Use the virPoolObj[Table] object management model in order to manage the Network objects. While making the adjustments to use the new model, there are some code formatting adjustments that were also made with the goal to follow more recent code flow and layout. For API's that were static, rather than use "virNetwork*", the names were converted to be "network*" - makes it easier to determine while reading code what is local and what is "outside" the perveyance of the module. All network object management API's have their own virnetworkobj entry points now instead of being mashed in with network_conf Signed-off-by: John Ferlan --- po/POTFILES.in | 1 + src/Makefile.am | 1 + src/conf/network_conf.c | 1308 +----------------------- src/conf/network_conf.h | 132 +-- src/conf/virnetworkobj.c | 1166 ++++++++++++++++++++++ src/conf/virnetworkobj.h | 121 +++ src/libvirt_private.syms | 60 +- src/network/bridge_driver.c | 1812 ++++++++++++++++++------------= ---- src/network/bridge_driver.h | 11 +- src/network/bridge_driver_platform.h | 3 +- src/test/test_driver.c | 399 ++++---- tests/networkxml2conftest.c | 18 +- 12 files changed, 2521 insertions(+), 2511 deletions(-) create mode 100644 src/conf/virnetworkobj.c create mode 100644 src/conf/virnetworkobj.h diff --git a/po/POTFILES.in b/po/POTFILES.in index a2e961f..98fc000 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/virnetworkobj.c src/conf/virnodedeviceobj.c src/conf/virnwfilterobj.c src/conf/virpoolobj.c diff --git a/src/Makefile.am b/src/Makefile.am index 2d95020..41e384d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -360,6 +360,7 @@ SECRET_EVENT_SOURCES =3D \ # Network driver generic impl APIs NETWORK_CONF_SOURCES =3D \ conf/network_conf.c conf/network_conf.h \ + conf/virnetworkobj.h conf/virnetworkobj.c \ conf/networkcommon_conf.c conf/networkcommon_conf.h =20 # Network filter driver generic impl APIs diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 0e20dac..9c98eea 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -29,7 +29,6 @@ #include #include #include -#include =20 #include "virerror.h" #include "datatypes.h" @@ -46,14 +45,6 @@ #include "virstring.h" =20 #define VIR_FROM_THIS VIR_FROM_NETWORK -/* currently, /sbin/tc implementation allows up to 16 bits for minor class= size */ -#define CLASS_ID_BITMAP_SIZE (1<<16) - -struct _virNetworkObjList { - virObjectLockable parent; - - virHashTablePtr objs; -}; =20 VIR_ENUM_IMPL(virNetworkForward, VIR_NETWORK_FORWARD_LAST, @@ -79,206 +70,6 @@ VIR_ENUM_IMPL(virNetworkForwardDriverName, VIR_ENUM_IMPL(virNetworkTaint, VIR_NETWORK_TAINT_LAST, "hook-script"); =20 -static virClassPtr virNetworkObjClass; -static virClassPtr virNetworkObjListClass; -static void virNetworkObjDispose(void *obj); -static void virNetworkObjListDispose(void *obj); - -static int virNetworkObjOnceInit(void) -{ - if (!(virNetworkObjClass =3D virClassNew(virClassForObjectLockable(), - "virNetworkObj", - sizeof(virNetworkObj), - virNetworkObjDispose))) - return -1; - - if (!(virNetworkObjListClass =3D virClassNew(virClassForObjectLockable= (), - "virNetworkObjList", - sizeof(virNetworkObjList), - virNetworkObjListDispose))) - return -1; - return 0; -} - - -VIR_ONCE_GLOBAL_INIT(virNetworkObj) - -virNetworkObjPtr -virNetworkObjNew(void) -{ - virNetworkObjPtr net; - - if (virNetworkObjInitialize() < 0) - return NULL; - - if (!(net =3D virObjectLockableNew(virNetworkObjClass))) - return NULL; - - if (!(net->class_id =3D virBitmapNew(CLASS_ID_BITMAP_SIZE))) - goto error; - - /* The first three class IDs are already taken */ - ignore_value(virBitmapSetBit(net->class_id, 0)); - ignore_value(virBitmapSetBit(net->class_id, 1)); - ignore_value(virBitmapSetBit(net->class_id, 2)); - - return net; - - error: - virObjectUnref(net); - return NULL; -} - -void -virNetworkObjEndAPI(virNetworkObjPtr *net) -{ - if (!*net) - return; - - virObjectUnlock(*net); - virObjectUnref(*net); - *net =3D NULL; -} - -virNetworkObjListPtr virNetworkObjListNew(void) -{ - virNetworkObjListPtr nets; - - if (virNetworkObjInitialize() < 0) - return NULL; - - if (!(nets =3D virObjectLockableNew(virNetworkObjListClass))) - return NULL; - - if (!(nets->objs =3D virHashCreate(50, virObjectFreeHashData))) { - virObjectUnref(nets); - return NULL; - } - - return nets; -} - -/** - * virNetworkObjFindByUUIDLocked: - * @nets: list of network objects - * @uuid: network uuid to find - * - * This functions requires @nets to be locked already! - * - * Returns: not locked, but ref'd network object. - */ -virNetworkObjPtr -virNetworkObjFindByUUIDLocked(virNetworkObjListPtr nets, - const unsigned char *uuid) -{ - virNetworkObjPtr ret =3D NULL; - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - virUUIDFormat(uuid, uuidstr); - - ret =3D virHashLookup(nets->objs, uuidstr); - if (ret) - virObjectRef(ret); - return ret; -} - -/** - * virNetworkObjFindByUUID: - * @nets: list of network objects - * @uuid: network uuid to find - * - * This functions locks @nets and find network object which - * corresponds to @uuid. - * - * Returns: locked and ref'd network object. - */ -virNetworkObjPtr -virNetworkObjFindByUUID(virNetworkObjListPtr nets, - const unsigned char *uuid) -{ - virNetworkObjPtr ret; - - virObjectLock(nets); - ret =3D virNetworkObjFindByUUIDLocked(nets, uuid); - virObjectUnlock(nets); - if (ret) - virObjectLock(ret); - return ret; -} - -static int -virNetworkObjSearchName(const void *payload, - const void *name ATTRIBUTE_UNUSED, - const void *data) -{ - virNetworkObjPtr net =3D (virNetworkObjPtr) payload; - int want =3D 0; - - virObjectLock(net); - if (STREQ(net->def->name, (const char *)data)) - want =3D 1; - virObjectUnlock(net); - return want; -} - -/* - * virNetworkObjFindByNameLocked: - * @nets: list of network objects - * @name: network name to find - * - * This functions requires @nets to be locked already! - * - * Returns: not locked, but ref'd network object. - */ -virNetworkObjPtr -virNetworkObjFindByNameLocked(virNetworkObjListPtr nets, - const char *name) -{ - virNetworkObjPtr ret =3D NULL; - - ret =3D virHashSearch(nets->objs, virNetworkObjSearchName, name); - if (ret) - virObjectRef(ret); - return ret; -} - -/** - * virNetworkObjFindByName: - * @nets: list of network objects - * @name: network name to find - * - * This functions locks @nets and find network object which - * corresponds to @name. - * - * Returns: locked and ref'd network object. - */ -virNetworkObjPtr -virNetworkObjFindByName(virNetworkObjListPtr nets, - const char *name) -{ - virNetworkObjPtr ret; - - virObjectLock(nets); - ret =3D virNetworkObjFindByNameLocked(nets, name); - virObjectUnlock(nets); - if (ret) - virObjectLock(ret); - return ret; -} - -bool -virNetworkObjTaint(virNetworkObjPtr obj, - virNetworkTaintFlags taint) -{ - unsigned int flag =3D (1 << taint); - - if (obj->taint & flag) - return false; - - obj->taint |=3D flag; - return true; -} - =20 static void virPortGroupDefClear(virPortGroupDefPtr def) @@ -398,8 +189,9 @@ virNetworkForwardDefClear(virNetworkForwardDefPtr def) } =20 void -virNetworkDefFree(virNetworkDefPtr def) +virNetworkDefFree(void *opaque) { + virNetworkDefPtr def =3D opaque; size_t i; =20 if (!def) @@ -435,273 +227,6 @@ virNetworkDefFree(virNetworkDefPtr def) VIR_FREE(def); } =20 -static void -virNetworkObjDispose(void *obj) -{ - virNetworkObjPtr net =3D obj; - - virNetworkDefFree(net->def); - virNetworkDefFree(net->newDef); - virBitmapFree(net->class_id); -} - -static void -virNetworkObjListDispose(void *obj) -{ - virNetworkObjListPtr nets =3D obj; - - virHashFree(nets->objs); -} - -/* - * virNetworkObjAssignDef: - * @network: the network object to update - * @def: the new NetworkDef (will be consumed by this function) - * @live: is this new def the "live" version, or the "persistent" version - * - * Replace the appropriate copy of the given network's def or newDef - * with def. Use "live" and current state of the network to determine - * which to replace and what to do with the old defs. When a non-live - * def is set, indicate that the network is now persistent. - * - * NB: a persistent network can be made transient by calling with: - * virNetworkObjAssignDef(network, NULL, false) (i.e. set the - * persistent def to NULL) - * - */ -void -virNetworkObjAssignDef(virNetworkObjPtr network, - virNetworkDefPtr def, - bool live) -{ - if (live) { - /* before setting new live def, save (into newDef) any - * existing persistent (!live) def to be restored when the - * network is destroyed, unless there is one already saved. - */ - if (network->persistent && !network->newDef) - network->newDef =3D network->def; - else - virNetworkDefFree(network->def); - network->def =3D def; - } else { /* !live */ - virNetworkDefFree(network->newDef); - if (virNetworkObjIsActive(network)) { - /* save new configuration to be restored on network - * shutdown, leaving current live def alone - */ - network->newDef =3D def; - } else { /* !live and !active */ - if (network->def && !network->persistent) { - /* network isn't (yet) marked active or persistent, - * but already has a "live" def set. This means we are - * currently setting the persistent def as a part of - * the process of starting the network, so we need to - * preserve the "not yet live" def in network->def. - */ - network->newDef =3D def; - } else { - /* either there is no live def set, or this network - * was already set as persistent, so the proper thing - * is to overwrite network->def. - */ - network->newDef =3D NULL; - virNetworkDefFree(network->def); - network->def =3D def; - } - } - network->persistent =3D !!def; - } -} - -/* - * If flags & VIR_NETWORK_OBJ_LIST_ADD_CHECK_LIVE then this will - * refuse updating an existing def if the current def is live - * - * If flags & VIR_NETWORK_OBJ_LIST_ADD_LIVE then the @def being - * added is assumed to represent a live config, not a future - * inactive config - * - * If flags is zero, network is considered as inactive and persistent. - */ -static virNetworkObjPtr -virNetworkAssignDefLocked(virNetworkObjListPtr nets, - virNetworkDefPtr def, - unsigned int flags) -{ - virNetworkObjPtr network; - virNetworkObjPtr ret =3D NULL; - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - /* See if a network with matching UUID already exists */ - if ((network =3D virNetworkObjFindByUUIDLocked(nets, def->uuid))) { - virObjectLock(network); - /* UUID matches, but if names don't match, refuse it */ - if (STRNEQ(network->def->name, def->name)) { - virUUIDFormat(network->def->uuid, uuidstr); - virReportError(VIR_ERR_OPERATION_FAILED, - _("network '%s' is already defined with uuid %s= "), - network->def->name, uuidstr); - goto cleanup; - } - - if (flags & VIR_NETWORK_OBJ_LIST_ADD_CHECK_LIVE) { - /* UUID & name match, but if network is already active, refuse= it */ - if (virNetworkObjIsActive(network)) { - virReportError(VIR_ERR_OPERATION_INVALID, - _("network is already active as '%s'"), - network->def->name); - goto cleanup; - } - } - - virNetworkObjAssignDef(network, - def, - !!(flags & VIR_NETWORK_OBJ_LIST_ADD_LIVE)); - } else { - /* UUID does not match, but if a name matches, refuse it */ - if ((network =3D virNetworkObjFindByNameLocked(nets, def->name))) { - virObjectLock(network); - virUUIDFormat(network->def->uuid, uuidstr); - virReportError(VIR_ERR_OPERATION_FAILED, - _("network '%s' already exists with uuid %s"), - def->name, uuidstr); - goto cleanup; - } - - if (!(network =3D virNetworkObjNew())) - goto cleanup; - - virObjectLock(network); - - virUUIDFormat(def->uuid, uuidstr); - if (virHashAddEntry(nets->objs, uuidstr, network) < 0) - goto cleanup; - - network->def =3D def; - network->persistent =3D !(flags & VIR_NETWORK_OBJ_LIST_ADD_LIVE); - virObjectRef(network); - } - - ret =3D network; - network =3D NULL; - - cleanup: - virNetworkObjEndAPI(&network); - return ret; -} - -/* - * virNetworkAssignDef: - * @nets: list of all networks - * @def: the new NetworkDef (will be consumed by this function iff success= ful) - * @flags: bitwise-OR of VIR_NETWORK_OBJ_LIST_ADD_* flags - * - * Either replace the appropriate copy of the NetworkDef with name - * matching def->name or, if not found, create a new NetworkObj with - * def. For an existing network, use "live" and current state of the - * network to determine which to replace. - * - * Look at virNetworkAssignDefLocked() for @flags description. - * - * Returns NULL on error, virNetworkObjPtr on success. - */ -virNetworkObjPtr -virNetworkAssignDef(virNetworkObjListPtr nets, - virNetworkDefPtr def, - unsigned int flags) -{ - virNetworkObjPtr network; - - virObjectLock(nets); - network =3D virNetworkAssignDefLocked(nets, def, flags); - virObjectUnlock(nets); - return network; -} - -/* - * virNetworkObjSetDefTransient: - * @network: network object pointer - * @live: if true, run this operation even for an inactive network. - * this allows freely updated network->def with runtime defaults - * before starting the network, which will be discarded on network - * shutdown. Any cleanup paths need to be sure to handle newDef if - * the network is never started. - * - * Mark the active network config as transient. Ensures live-only update - * operations do not persist past network destroy. - * - * Returns 0 on success, -1 on failure - */ -int -virNetworkObjSetDefTransient(virNetworkObjPtr network, bool live) -{ - if (!virNetworkObjIsActive(network) && !live) - return 0; - - if (!network->persistent || network->newDef) - return 0; - - network->newDef =3D virNetworkDefCopy(network->def, VIR_NETWORK_XML_IN= ACTIVE); - return network->newDef ? 0 : -1; -} - -/* virNetworkObjUnsetDefTransient: - * - * This *undoes* what virNetworkObjSetDefTransient did. - */ -void -virNetworkObjUnsetDefTransient(virNetworkObjPtr network) -{ - if (network->newDef) { - virNetworkDefFree(network->def); - network->def =3D network->newDef; - network->newDef =3D NULL; - } -} - -/* - * virNetworkObjGetPersistentDef: - * @network: network object pointer - * - * Return the persistent network configuration. If network is transient, - * return the running config. - * - * Returns NULL on error, virNetworkDefPtr on success. - */ -virNetworkDefPtr -virNetworkObjGetPersistentDef(virNetworkObjPtr network) -{ - if (network->newDef) - return network->newDef; - else - return network->def; -} - -/* - * virNetworkObjReplacePersistentDef: - * @network: network object pointer - * @def: new virNetworkDef to replace current persistent config - * - * Replace the "persistent" network configuration with the given new - * virNetworkDef. This pays attention to whether or not the network - * is active. - * - * Returns -1 on error, 0 on success - */ -int -virNetworkObjReplacePersistentDef(virNetworkObjPtr network, - virNetworkDefPtr def) -{ - if (virNetworkObjIsActive(network)) { - virNetworkDefFree(network->newDef); - network->newDef =3D def; - } else { - virNetworkDefFree(network->def); - network->def =3D def; - } - return 0; -} =20 /* * virNetworkDefCopy: @@ -733,64 +258,6 @@ virNetworkDefCopy(virNetworkDefPtr def, unsigned int f= lags) return newDef; } =20 -/* - * virNetworkConfigChangeSetup: - * - * 1) checks whether network state is consistent with the requested - * type of modification. - * - * 3) make sure there are separate "def" and "newDef" copies of - * networkDef if appropriate. - * - * Returns 0 on success, -1 on error. - */ -int -virNetworkConfigChangeSetup(virNetworkObjPtr network, unsigned int flags) -{ - bool isActive; - int ret =3D -1; - - isActive =3D virNetworkObjIsActive(network); - - if (!isActive && (flags & VIR_NETWORK_UPDATE_AFFECT_LIVE)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("network is not running")); - goto cleanup; - } - - if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) { - if (!network->persistent) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("cannot change persistent config of a " - "transient network")); - goto cleanup; - } - /* this should already have been done by the driver, but do it - * anyway just in case. - */ - if (isActive && (virNetworkObjSetDefTransient(network, false) < 0)) - goto cleanup; - } - - ret =3D 0; - cleanup: - return ret; -} - -void virNetworkRemoveInactive(virNetworkObjListPtr nets, - virNetworkObjPtr net) -{ - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - virUUIDFormat(net->def->uuid, uuidstr); - virObjectRef(net); - virObjectUnlock(net); - virObjectLock(nets); - virObjectLock(net); - virHashRemoveEntry(nets->objs, uuidstr); - virObjectUnlock(nets); - virObjectUnref(net); -} =20 /* return ips[index], or NULL if there aren't enough ips */ virNetworkIPDefPtr @@ -2092,7 +1559,7 @@ virNetworkForwardDefParseXML(const char *networkName, return ret; } =20 -static virNetworkDefPtr +virNetworkDefPtr virNetworkDefParseXML(xmlXPathContextPtr ctxt) { virNetworkDefPtr def; @@ -3071,45 +2538,6 @@ virNetworkDefFormat(const virNetworkDef *def, return NULL; } =20 -static char * -virNetworkObjFormat(virNetworkObjPtr net, - unsigned int flags) -{ - virBuffer buf =3D VIR_BUFFER_INITIALIZER; - char *class_id =3D virBitmapFormat(net->class_id); - size_t i; - - if (!class_id) - goto error; - - virBufferAddLit(&buf, "\n"); - virBufferAdjustIndent(&buf, 2); - virBufferAsprintf(&buf, "\n", class_id); - virBufferAsprintf(&buf, "\n", net->floor_sum); - VIR_FREE(class_id); - - for (i =3D 0; i < VIR_NETWORK_TAINT_LAST; i++) { - if (net->taint & (1 << i)) - virBufferAsprintf(&buf, "\n", - virNetworkTaintTypeToString(i)); - } - - if (virNetworkDefFormatBuf(&buf, net->def, flags) < 0) - goto error; - - virBufferAdjustIndent(&buf, -2); - virBufferAddLit(&buf, ""); - - if (virBufferCheckError(&buf) < 0) - goto error; - - return virBufferContentAndReset(&buf); - - error: - virBufferFreeAndReset(&buf); - return NULL; -} - const char * virNetworkDefForwardIf(const virNetworkDef *def, size_t n) { @@ -3181,356 +2609,20 @@ int virNetworkSaveConfig(const char *configDir, } =20 =20 -int virNetworkSaveStatus(const char *statusDir, - virNetworkObjPtr network) + +char * +virNetworkConfigFile(const char *dir, + const char *name) { - int ret =3D -1; - int flags =3D 0; - char *xml; + char *ret =3D NULL; =20 - if (!(xml =3D virNetworkObjFormat(network, flags))) - goto cleanup; + ignore_value(virAsprintf(&ret, "%s/%s.xml", dir, name)); + return ret; +} =20 - if (virNetworkSaveXML(statusDir, network->def, xml)) - goto cleanup; =20 - ret =3D 0; - cleanup: - VIR_FREE(xml); - return ret; -} - -virNetworkObjPtr -virNetworkLoadState(virNetworkObjListPtr nets, - const char *stateDir, - const char *name) -{ - char *configFile =3D NULL; - virNetworkDefPtr def =3D NULL; - virNetworkObjPtr net =3D NULL; - xmlDocPtr xml =3D NULL; - xmlNodePtr node =3D NULL, *nodes =3D NULL; - xmlXPathContextPtr ctxt =3D NULL; - virBitmapPtr class_id_map =3D NULL; - unsigned long long floor_sum_val =3D 0; - unsigned int taint =3D 0; - int n; - size_t i; - - - if ((configFile =3D virNetworkConfigFile(stateDir, name)) =3D=3D NULL) - goto error; - - if (!(xml =3D virXMLParseCtxt(configFile, NULL, _("(network status)"),= &ctxt))) - goto error; - - if (!(node =3D virXPathNode("//network", ctxt))) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Could not find any 'network' element in status f= ile")); - goto error; - } - - /* parse the definition first */ - ctxt->node =3D node; - if (!(def =3D virNetworkDefParseXML(ctxt))) - goto error; - - if (STRNEQ(name, def->name)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Network config filename '%s'" - " does not match network name '%s'"), - configFile, def->name); - goto error; - } - - /* now parse possible status data */ - node =3D xmlDocGetRootElement(xml); - if (xmlStrEqual(node->name, BAD_CAST "networkstatus")) { - /* Newer network status file. Contains useful - * info which are not to be found in bare config XML */ - char *class_id =3D NULL; - char *floor_sum =3D NULL; - - ctxt->node =3D node; - if ((class_id =3D virXPathString("string(./class_id[1]/@bitmap)", = ctxt))) { - if (virBitmapParse(class_id, &class_id_map, - CLASS_ID_BITMAP_SIZE) < 0) { - VIR_FREE(class_id); - goto error; - } - } - VIR_FREE(class_id); - - floor_sum =3D virXPathString("string(./floor[1]/@sum)", ctxt); - if (floor_sum && - virStrToLong_ull(floor_sum, NULL, 10, &floor_sum_val) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Malformed 'floor_sum' attribute: %s"), - floor_sum); - VIR_FREE(floor_sum); - goto error; - } - VIR_FREE(floor_sum); - - if ((n =3D virXPathNodeSet("./taint", ctxt, &nodes)) < 0) - goto error; - - for (i =3D 0; i < n; i++) { - char *str =3D virXMLPropString(nodes[i], "flag"); - if (str) { - int flag =3D virNetworkTaintTypeFromString(str); - if (flag < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Unknown taint flag %s"), str); - VIR_FREE(str); - goto error; - } - VIR_FREE(str); - /* Compute taint mask here. The network object does not - * exist yet, so we can't use virNetworkObjtTaint. */ - taint |=3D (1 << flag); - } - } - VIR_FREE(nodes); - } - - /* create the object */ - if (!(net =3D virNetworkAssignDef(nets, def, VIR_NETWORK_OBJ_LIST_ADD_= LIVE))) - goto error; - /* do not put any "goto error" below this comment */ - - /* assign status data stored in the network object */ - if (class_id_map) { - virBitmapFree(net->class_id); - net->class_id =3D class_id_map; - } - - if (floor_sum_val > 0) - net->floor_sum =3D floor_sum_val; - - net->taint =3D taint; - net->active =3D 1; /* any network with a state file is by definition a= ctive */ - - cleanup: - VIR_FREE(configFile); - xmlFreeDoc(xml); - xmlXPathFreeContext(ctxt); - return net; - - error: - VIR_FREE(nodes); - virBitmapFree(class_id_map); - virNetworkDefFree(def); - goto cleanup; -} - -virNetworkObjPtr virNetworkLoadConfig(virNetworkObjListPtr nets, - const char *configDir, - const char *autostartDir, - const char *name) -{ - char *configFile =3D NULL, *autostartLink =3D NULL; - virNetworkDefPtr def =3D NULL; - virNetworkObjPtr net; - int autostart; - - if ((configFile =3D virNetworkConfigFile(configDir, name)) =3D=3D NULL) - goto error; - if ((autostartLink =3D virNetworkConfigFile(autostartDir, name)) =3D= =3D NULL) - goto error; - - if ((autostart =3D virFileLinkPointsTo(autostartLink, configFile)) < 0) - goto error; - - if (!(def =3D virNetworkDefParseFile(configFile))) - goto error; - - if (STRNEQ(name, def->name)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Network config filename '%s'" - " does not match network name '%s'"), - configFile, def->name); - goto error; - } - - if (def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE || - def->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT || - def->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE || - def->forward.type =3D=3D VIR_NETWORK_FORWARD_OPEN) { - - if (!def->mac_specified) { - virNetworkSetBridgeMacAddr(def); - virNetworkSaveConfig(configDir, def); - } - } else { - /* Throw away MAC address for other forward types, - * which could have been generated by older libvirt RPMs */ - def->mac_specified =3D false; - } - - if (!(net =3D virNetworkAssignDef(nets, def, 0))) - goto error; - - net->autostart =3D autostart; - - VIR_FREE(configFile); - VIR_FREE(autostartLink); - - return net; - - error: - VIR_FREE(configFile); - VIR_FREE(autostartLink); - virNetworkDefFree(def); - return NULL; -} - - -int -virNetworkLoadAllState(virNetworkObjListPtr nets, - const char *stateDir) -{ - DIR *dir; - struct dirent *entry; - int ret =3D -1; - int rc; - - if ((rc =3D virDirOpenIfExists(&dir, stateDir)) <=3D 0) - return rc; - - while ((ret =3D virDirRead(dir, &entry, stateDir)) > 0) { - virNetworkObjPtr net; - - if (!virFileStripSuffix(entry->d_name, ".xml")) - continue; - - net =3D virNetworkLoadState(nets, stateDir, entry->d_name); - virNetworkObjEndAPI(&net); - } - - VIR_DIR_CLOSE(dir); - return ret; -} - - -int virNetworkLoadAllConfigs(virNetworkObjListPtr nets, - const char *configDir, - const char *autostartDir) -{ - DIR *dir; - struct dirent *entry; - int ret =3D -1; - int rc; - - if ((rc =3D virDirOpenIfExists(&dir, configDir)) <=3D 0) - return rc; - - while ((ret =3D virDirRead(dir, &entry, configDir)) > 0) { - virNetworkObjPtr net; - - if (!virFileStripSuffix(entry->d_name, ".xml")) - continue; - - /* NB: ignoring errors, so one malformed config doesn't - kill the whole process */ - net =3D virNetworkLoadConfig(nets, - configDir, - autostartDir, - entry->d_name); - virNetworkObjEndAPI(&net); - } - - VIR_DIR_CLOSE(dir); - return ret; -} - -int virNetworkDeleteConfig(const char *configDir, - const char *autostartDir, - virNetworkObjPtr net) -{ - char *configFile =3D NULL; - char *autostartLink =3D NULL; - int ret =3D -1; - - if ((configFile =3D virNetworkConfigFile(configDir, net->def->name)) = =3D=3D NULL) - goto error; - if ((autostartLink =3D virNetworkConfigFile(autostartDir, net->def->na= me)) =3D=3D NULL) - goto error; - - /* Not fatal if this doesn't work */ - unlink(autostartLink); - net->autostart =3D 0; - - if (unlink(configFile) < 0) { - virReportSystemError(errno, - _("cannot remove config file '%s'"), - configFile); - goto error; - } - - ret =3D 0; - - error: - VIR_FREE(configFile); - VIR_FREE(autostartLink); - return ret; -} - -char *virNetworkConfigFile(const char *dir, - const char *name) -{ - char *ret =3D NULL; - - ignore_value(virAsprintf(&ret, "%s/%s.xml", dir, name)); - return ret; -} - -struct virNetworkBridgeInUseHelperData { - const char *bridge; - const char *skipname; -}; - -static int -virNetworkBridgeInUseHelper(const void *payload, - const void *name ATTRIBUTE_UNUSED, - const void *opaque) -{ - int ret; - virNetworkObjPtr net =3D (virNetworkObjPtr) payload; - const struct virNetworkBridgeInUseHelperData *data =3D opaque; - - virObjectLock(net); - if (data->skipname && - ((net->def && STREQ(net->def->name, data->skipname)) || - (net->newDef && STREQ(net->newDef->name, data->skipname)))) - ret =3D 0; - else if ((net->def && net->def->bridge && - STREQ(net->def->bridge, data->bridge)) || - (net->newDef && net->newDef->bridge && - STREQ(net->newDef->bridge, data->bridge))) - ret =3D 1; - else - ret =3D 0; - virObjectUnlock(net); - return ret; -} - -int virNetworkBridgeInUse(virNetworkObjListPtr nets, - const char *bridge, - const char *skipname) -{ - virNetworkObjPtr obj; - struct virNetworkBridgeInUseHelperData data =3D {bridge, skipname}; - - virObjectLock(nets); - obj =3D virHashSearch(nets->objs, virNetworkBridgeInUseHelper, &data); - virObjectUnlock(nets); - - return obj !=3D NULL; -} - - -void virNetworkSetBridgeMacAddr(virNetworkDefPtr def) +void +virNetworkSetBridgeMacAddr(virNetworkDefPtr def) { if (!def->mac_specified) { /* if the bridge doesn't have a mac address explicitly defined, @@ -4449,377 +3541,3 @@ virNetworkDefUpdateSection(virNetworkDefPtr def, xmlXPathFreeContext(ctxt); return ret; } - -/* - * virNetworkObjUpdate: - * - * Apply the supplied update to the given virNetworkObj. Except for - * @network pointing to an actual network object rather than the - * opaque virNetworkPtr, parameters are identical to the public API - * virNetworkUpdate. - * - * The original virNetworkDefs are copied, and all modifications made - * to these copies. The originals are replaced with the copies only - * after success has been guaranteed. - * - * Returns: -1 on error, 0 on success. - */ -int -virNetworkObjUpdate(virNetworkObjPtr network, - unsigned int command, /* virNetworkUpdateCommand */ - unsigned int section, /* virNetworkUpdateSection */ - int parentIndex, - const char *xml, - unsigned int flags) /* virNetworkUpdateFlags */ -{ - int ret =3D -1; - virNetworkDefPtr livedef =3D NULL, configdef =3D NULL; - - /* normalize config data, and check for common invalid requests. */ - if (virNetworkConfigChangeSetup(network, flags) < 0) - goto cleanup; - - if (flags & VIR_NETWORK_UPDATE_AFFECT_LIVE) { - virNetworkDefPtr checkdef; - - /* work on a copy of the def */ - if (!(livedef =3D virNetworkDefCopy(network->def, 0))) - goto cleanup; - if (virNetworkDefUpdateSection(livedef, command, section, - parentIndex, xml, flags) < 0) { - goto cleanup; - } - /* run a final format/parse cycle to make sure we didn't - * add anything illegal to the def - */ - if (!(checkdef =3D virNetworkDefCopy(livedef, 0))) - goto cleanup; - virNetworkDefFree(checkdef); - } - - if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) { - virNetworkDefPtr checkdef; - - /* work on a copy of the def */ - if (!(configdef =3D virNetworkDefCopy(virNetworkObjGetPersistentDe= f(network), - VIR_NETWORK_XML_INACTIVE))) { - goto cleanup; - } - if (virNetworkDefUpdateSection(configdef, command, section, - parentIndex, xml, flags) < 0) { - goto cleanup; - } - if (!(checkdef =3D virNetworkDefCopy(configdef, - VIR_NETWORK_XML_INACTIVE))) { - goto cleanup; - } - virNetworkDefFree(checkdef); - } - - if (configdef) { - /* successfully modified copy, now replace original */ - if (virNetworkObjReplacePersistentDef(network, configdef) < 0) - goto cleanup; - configdef =3D NULL; - } - if (livedef) { - /* successfully modified copy, now replace original */ - virNetworkDefFree(network->def); - network->def =3D livedef; - livedef =3D NULL; - } - - ret =3D 0; - cleanup: - virNetworkDefFree(livedef); - virNetworkDefFree(configdef); - return ret; -} - -#define MATCH(FLAG) (flags & (FLAG)) -static bool -virNetworkMatch(virNetworkObjPtr netobj, - unsigned int flags) -{ - /* filter by active state */ - if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) && - !((MATCH(VIR_CONNECT_LIST_NETWORKS_ACTIVE) && - virNetworkObjIsActive(netobj)) || - (MATCH(VIR_CONNECT_LIST_NETWORKS_INACTIVE) && - !virNetworkObjIsActive(netobj)))) - return false; - - /* filter by persistence */ - if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_PERSISTENT) && - !((MATCH(VIR_CONNECT_LIST_NETWORKS_PERSISTENT) && - netobj->persistent) || - (MATCH(VIR_CONNECT_LIST_NETWORKS_TRANSIENT) && - !netobj->persistent))) - return false; - - /* filter by autostart option */ - if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_AUTOSTART) && - !((MATCH(VIR_CONNECT_LIST_NETWORKS_AUTOSTART) && - netobj->autostart) || - (MATCH(VIR_CONNECT_LIST_NETWORKS_NO_AUTOSTART) && - !netobj->autostart))) - return false; - - return true; -} -#undef MATCH - -struct virNetworkObjListData { - virConnectPtr conn; - virNetworkPtr *nets; - virNetworkObjListFilter filter; - unsigned int flags; - int nnets; - bool error; -}; - -static int -virNetworkObjListPopulate(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *opaque) -{ - struct virNetworkObjListData *data =3D opaque; - virNetworkObjPtr obj =3D payload; - virNetworkPtr net =3D NULL; - - if (data->error) - return 0; - - virObjectLock(obj); - - if (data->filter && - !data->filter(data->conn, obj->def)) - goto cleanup; - - if (!virNetworkMatch(obj, data->flags)) - goto cleanup; - - if (!data->nets) { - data->nnets++; - goto cleanup; - } - - if (!(net =3D virGetNetwork(data->conn, obj->def->name, obj->def->uuid= ))) { - data->error =3D true; - goto cleanup; - } - - data->nets[data->nnets++] =3D net; - - cleanup: - virObjectUnlock(obj); - return 0; -} - -int -virNetworkObjListExport(virConnectPtr conn, - virNetworkObjListPtr netobjs, - virNetworkPtr **nets, - virNetworkObjListFilter filter, - unsigned int flags) -{ - int ret =3D -1; - struct virNetworkObjListData data =3D { conn, NULL, filter, flags, 0, = false}; - - virObjectLock(netobjs); - if (nets && VIR_ALLOC_N(data.nets, virHashSize(netobjs->objs) + 1) < 0) - goto cleanup; - - virHashForEach(netobjs->objs, virNetworkObjListPopulate, &data); - - if (data.error) - goto cleanup; - - if (data.nets) { - /* trim the array to the final size */ - ignore_value(VIR_REALLOC_N(data.nets, data.nnets + 1)); - *nets =3D data.nets; - data.nets =3D NULL; - } - - ret =3D data.nnets; - cleanup: - virObjectUnlock(netobjs); - while (data.nets && data.nnets) - virObjectUnref(data.nets[--data.nnets]); - - VIR_FREE(data.nets); - return ret; -} - -struct virNetworkObjListForEachHelperData { - virNetworkObjListIterator callback; - void *opaque; - int ret; -}; - -static int -virNetworkObjListForEachHelper(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *opaque) -{ - struct virNetworkObjListForEachHelperData *data =3D opaque; - - if (data->callback(payload, data->opaque) < 0) - data->ret =3D -1; - return 0; -} - -/** - * virNetworkObjListForEach: - * @nets: a list of network objects - * @callback: function to call over each of object in the list - * @opaque: pointer to pass to the @callback - * - * Function iterates over the list of network objects and calls - * passed callback over each one of them. You should avoid - * calling those virNetworkObjList APIs, which lock the list - * again in favor of their virNetworkObj*Locked variants. - * - * Returns: 0 on success, -1 otherwise. - */ -int -virNetworkObjListForEach(virNetworkObjListPtr nets, - virNetworkObjListIterator callback, - void *opaque) -{ - struct virNetworkObjListForEachHelperData data =3D {callback, opaque, = 0}; - virObjectLock(nets); - virHashForEach(nets->objs, virNetworkObjListForEachHelper, &data); - virObjectUnlock(nets); - return data.ret; -} - -struct virNetworkObjListGetHelperData { - virConnectPtr conn; - virNetworkObjListFilter filter; - char **names; - int nnames; - bool active; - int got; - bool error; -}; - -static int -virNetworkObjListGetHelper(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *opaque) -{ - struct virNetworkObjListGetHelperData *data =3D opaque; - virNetworkObjPtr obj =3D payload; - - if (data->error) - return 0; - - if (data->nnames >=3D 0 && - data->got =3D=3D data->nnames) - return 0; - - virObjectLock(obj); - - if (data->filter && - !data->filter(data->conn, obj->def)) - goto cleanup; - - if ((data->active && virNetworkObjIsActive(obj)) || - (!data->active && !virNetworkObjIsActive(obj))) { - if (data->names && - VIR_STRDUP(data->names[data->got], obj->def->name) < 0) { - data->error =3D true; - goto cleanup; - } - data->got++; - } - - cleanup: - virObjectUnlock(obj); - return 0; -} - -int -virNetworkObjListGetNames(virNetworkObjListPtr nets, - bool active, - char **names, - int nnames, - virNetworkObjListFilter filter, - virConnectPtr conn) -{ - int ret =3D -1; - - struct virNetworkObjListGetHelperData data =3D { - conn, filter, names, nnames, active, 0, false}; - - virObjectLock(nets); - virHashForEach(nets->objs, virNetworkObjListGetHelper, &data); - virObjectUnlock(nets); - - if (data.error) - goto cleanup; - - ret =3D data.got; - cleanup: - if (ret < 0) { - while (data.got) - VIR_FREE(data.names[--data.got]); - } - return ret; -} - -int -virNetworkObjListNumOfNetworks(virNetworkObjListPtr nets, - bool active, - virNetworkObjListFilter filter, - virConnectPtr conn) -{ - struct virNetworkObjListGetHelperData data =3D { - conn, filter, NULL, -1, active, 0, false}; - - virObjectLock(nets); - virHashForEach(nets->objs, virNetworkObjListGetHelper, &data); - virObjectUnlock(nets); - - return data.got; -} - -struct virNetworkObjListPruneHelperData { - unsigned int flags; -}; - -static int -virNetworkObjListPruneHelper(const void *payload, - const void *name ATTRIBUTE_UNUSED, - const void *opaque) -{ - const struct virNetworkObjListPruneHelperData *data =3D opaque; - virNetworkObjPtr obj =3D (virNetworkObjPtr) payload; - int want =3D 0; - - virObjectLock(obj); - want =3D virNetworkMatch(obj, data->flags); - virObjectUnlock(obj); - return want; -} - -/** - * virNetworkObjListPrune: - * @nets: a list of network objects - * @flags: bitwise-OR of virConnectListAllNetworksFlags - * - * Iterate over list of network objects and remove the desired - * ones from it. - */ -void -virNetworkObjListPrune(virNetworkObjListPtr nets, - unsigned int flags) -{ - struct virNetworkObjListPruneHelperData data =3D {flags}; - - virObjectLock(nets); - virHashRemoveSet(nets->objs, virNetworkObjListPruneHelper, &data); - virObjectUnlock(nets); -} diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 217b548..ae936a6 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -270,35 +270,6 @@ struct _virNetworkDef { xmlNodePtr metadata; }; =20 -typedef struct _virNetworkObj virNetworkObj; -typedef virNetworkObj *virNetworkObjPtr; -struct _virNetworkObj { - virObjectLockable parent; - - pid_t dnsmasqPid; - pid_t radvdPid; - unsigned int active : 1; - unsigned int autostart : 1; - unsigned int persistent : 1; - - virNetworkDefPtr def; /* The current definition */ - virNetworkDefPtr newDef; /* New definition to activate at shutdown */ - - virBitmapPtr class_id; /* bitmap of class IDs for QoS */ - unsigned long long floor_sum; /* sum of all 'floor'-s of attached NICs= */ - - unsigned int taint; - - /* Immutable pointer, self locking APIs */ - virMacMapPtr macmap; -}; - -virNetworkObjPtr virNetworkObjNew(void); -void virNetworkObjEndAPI(virNetworkObjPtr *net); - -typedef struct _virNetworkObjList virNetworkObjList; -typedef virNetworkObjList *virNetworkObjListPtr; - typedef enum { VIR_NETWORK_TAINT_HOOK, /* Hook script was executed ov= er network. We can't guarantee @@ -310,50 +281,16 @@ typedef enum { VIR_NETWORK_TAINT_LAST } virNetworkTaintFlags; =20 -static inline int -virNetworkObjIsActive(const virNetworkObj *net) -{ - return net->active; -} - -virNetworkObjListPtr virNetworkObjListNew(void); - -virNetworkObjPtr virNetworkObjFindByUUIDLocked(virNetworkObjListPtr nets, - const unsigned char *uuid); -virNetworkObjPtr virNetworkObjFindByUUID(virNetworkObjListPtr nets, - const unsigned char *uuid); -virNetworkObjPtr virNetworkObjFindByNameLocked(virNetworkObjListPtr nets, - const char *name); -virNetworkObjPtr virNetworkObjFindByName(virNetworkObjListPtr nets, - const char *name); -bool virNetworkObjTaint(virNetworkObjPtr obj, - virNetworkTaintFlags taint); - -void virNetworkDefFree(virNetworkDefPtr def); - -typedef bool (*virNetworkObjListFilter)(virConnectPtr conn, void *opaque); +void virNetworkDefFree(void *opaque); =20 enum { VIR_NETWORK_OBJ_LIST_ADD_LIVE =3D (1 << 0), VIR_NETWORK_OBJ_LIST_ADD_CHECK_LIVE =3D (1 << 1), }; -virNetworkObjPtr virNetworkAssignDef(virNetworkObjListPtr nets, - virNetworkDefPtr def, - unsigned int flags); -void virNetworkObjAssignDef(virNetworkObjPtr network, - virNetworkDefPtr def, - bool live); -int virNetworkObjSetDefTransient(virNetworkObjPtr network, bool live); -void virNetworkObjUnsetDefTransient(virNetworkObjPtr network); -virNetworkDefPtr virNetworkObjGetPersistentDef(virNetworkObjPtr network); -int virNetworkObjReplacePersistentDef(virNetworkObjPtr network, - virNetworkDefPtr def); -virNetworkDefPtr virNetworkDefCopy(virNetworkDefPtr def, unsigned int flag= s); -int virNetworkConfigChangeSetup(virNetworkObjPtr dom, unsigned int flags); =20 -void virNetworkRemoveInactive(virNetworkObjListPtr nets, - virNetworkObjPtr net); +virNetworkDefPtr virNetworkDefCopy(virNetworkDefPtr def, unsigned int flag= s); =20 +virNetworkDefPtr virNetworkDefParseXML(xmlXPathContextPtr ctxt); virNetworkDefPtr virNetworkDefParseString(const char *xmlStr); virNetworkDefPtr virNetworkDefParseFile(const char *filename); virNetworkDefPtr virNetworkDefParseNode(xmlDocPtr xml, @@ -385,46 +322,11 @@ int virNetworkSaveXML(const char *configDir, int virNetworkSaveConfig(const char *configDir, virNetworkDefPtr def); =20 -int virNetworkSaveStatus(const char *statusDir, - virNetworkObjPtr net) ATTRIBUTE_RETURN_CHECK; - -virNetworkObjPtr virNetworkLoadConfig(virNetworkObjListPtr nets, - const char *configDir, - const char *autostartDir, - const char *file); - -virNetworkObjPtr virNetworkLoadState(virNetworkObjListPtr nets, - const char *stateDir, - const char *name); - -int virNetworkLoadAllConfigs(virNetworkObjListPtr nets, - const char *configDir, - const char *autostartDir); - -int virNetworkLoadAllState(virNetworkObjListPtr nets, - const char *stateDir); - -int virNetworkDeleteConfig(const char *configDir, - const char *autostartDir, - virNetworkObjPtr net); - char *virNetworkConfigFile(const char *dir, const char *name); =20 -int virNetworkBridgeInUse(virNetworkObjListPtr nets, - const char *bridge, - const char *skipname); - void virNetworkSetBridgeMacAddr(virNetworkDefPtr def); =20 -int -virNetworkObjUpdate(virNetworkObjPtr obj, - unsigned int command, /* virNetworkUpdateCommand */ - unsigned int section, /* virNetworkUpdateSection */ - int parentIndex, - const char *xml, - unsigned int flags); /* virNetworkUpdateFlags */ - VIR_ENUM_DECL(virNetworkForward) =20 # define VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE \ @@ -444,34 +346,6 @@ VIR_ENUM_DECL(virNetworkForward) VIR_CONNECT_LIST_NETWORKS_FILTERS_PERSISTENT | \ VIR_CONNECT_LIST_NETWORKS_FILTERS_AUTOSTART) =20 -int virNetworkObjListExport(virConnectPtr conn, - virNetworkObjListPtr netobjs, - virNetworkPtr **nets, - virNetworkObjListFilter filter, - unsigned int flags); - -typedef int (*virNetworkObjListIterator)(virNetworkObjPtr net, - void *opaque); - -int virNetworkObjListForEach(virNetworkObjListPtr nets, - virNetworkObjListIterator callback, - void *opaque); - -int virNetworkObjListGetNames(virNetworkObjListPtr nets, - bool active, - char **names, - int nnames, - virNetworkObjListFilter filter, - virConnectPtr conn); - -int virNetworkObjListNumOfNetworks(virNetworkObjListPtr nets, - bool active, - virNetworkObjListFilter filter, - virConnectPtr conn); - -void virNetworkObjListPrune(virNetworkObjListPtr nets, - unsigned int flags); - /* for testing */ int virNetworkDefUpdateSection(virNetworkDefPtr def, diff --git a/src/conf/virnetworkobj.c b/src/conf/virnetworkobj.c new file mode 100644 index 0000000..f85b8a1 --- /dev/null +++ b/src/conf/virnetworkobj.c @@ -0,0 +1,1166 @@ +/* + * virnetworkobj.c: handle network objects + * (derived from network_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 + +#include "datatypes.h" +#include "virnetworkobj.h" + +#include "viralloc.h" +#include "virerror.h" +#include "virfile.h" +#include "virlog.h" +#include "virstring.h" + +#define VIR_FROM_THIS VIR_FROM_NETWORK + +VIR_LOG_INIT("conf.virnetworkobj"); + +/* currently, /sbin/tc implementation allows up to 16 bits for minor class= size */ +#define CLASS_ID_BITMAP_SIZE (1<<16) + +struct _virNetworkObjPrivate { + pid_t dnsmasqPid; + pid_t radvdPid; + + virBitmapPtr class_id; /* bitmap of class IDs for QoS */ + unsigned long long floor_sum; /* sum of all 'floor'-s of attached NICs= */ + + unsigned int taint; + + /* Immutable pointer, self locking APIs */ + virMacMapPtr macmap; +}; + + +static void +virNetworkObjPrivateFree(void *obj) +{ + virNetworkObjPrivatePtr objpriv =3D obj; + if (!objpriv) + return; + + virBitmapFree(objpriv->class_id); + virObjectUnref(objpriv->macmap); + + VIR_FREE(objpriv); +} + + +static virNetworkObjPrivatePtr +virNetworkObjPrivateAlloc(void) +{ + virNetworkObjPrivatePtr objpriv =3D NULL; + + if (VIR_ALLOC(objpriv) < 0) + return NULL; + + if (!(objpriv->class_id =3D virBitmapNew(CLASS_ID_BITMAP_SIZE))) + goto error; + + /* The first three class IDs are already taken */ + ignore_value(virBitmapSetBit(objpriv->class_id, 0)); + ignore_value(virBitmapSetBit(objpriv->class_id, 1)); + ignore_value(virBitmapSetBit(objpriv->class_id, 2)); + + return objpriv; + + error: + virNetworkObjPrivateFree(objpriv); + return NULL; +} + + +pid_t +virNetworkObjPrivateGetDnsmasqPid(virPoolObjPtr obj) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + return objpriv->dnsmasqPid; +} + + +void +virNetworkObjPrivateSetDnsmasqPid(virPoolObjPtr obj, + pid_t dnsmasqPid) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + objpriv->dnsmasqPid =3D dnsmasqPid; +} + + +pid_t +virNetworkObjPrivateGetRadvdPid(virPoolObjPtr obj) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + return objpriv->radvdPid; +} + + +void +virNetworkObjPrivateSetRadvdPid(virPoolObjPtr obj, + pid_t radvdPid) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + objpriv->radvdPid =3D radvdPid; +} + + +virBitmapPtr +virNetworkObjPrivateGetClassId(virPoolObjPtr obj) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + return objpriv->class_id; +} + + +void +virNetworkObjPrivateSetClassId(virPoolObjPtr obj, + virBitmapPtr class_id) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + virBitmapFree(objpriv->class_id); + objpriv->class_id =3D class_id; +} + + +unsigned long long +virNetworkObjPrivateGetFloorSum(virPoolObjPtr obj) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + return objpriv->floor_sum; +} + + +void +virNetworkObjPrivateSetFloorSum(virPoolObjPtr obj, + unsigned long long floor_sum) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + objpriv->floor_sum =3D floor_sum; +} + + +virMacMapPtr +virNetworkObjPrivateGetMacMap(virPoolObjPtr obj) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + return objpriv->macmap; +} + + +void +virNetworkObjPrivateSetMacMap(virPoolObjPtr obj, + virMacMapPtr macmap) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + virObjectUnref(objpriv->macmap); + objpriv->macmap =3D macmap; +} + + +unsigned int +virNetworkObjPrivateGetTaint(virPoolObjPtr obj) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + return objpriv->taint; +} + + +bool +virNetworkObjPrivateIsTaint(virPoolObjPtr obj, + virNetworkTaintFlags taint) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + unsigned int flag =3D (1 << taint); + + if (objpriv->taint & flag) + return false; + + objpriv->taint |=3D flag; + return true; +} + + +void +virNetworkObjPrivateSetTaint(virPoolObjPtr obj, + unsigned int taint) +{ + virNetworkObjPrivatePtr objpriv =3D virPoolObjGetPrivateData(obj); + + objpriv->taint =3D taint; +} + + +/* + * If flags & VIR_NETWORK_OBJ_LIST_ADD_CHECK_LIVE then this will + * refuse updating an existing def if the current def is live + * + * If flags & VIR_NETWORK_OBJ_LIST_ADD_LIVE then the @def being + * added is assumed to represent a live config, not a future + * inactive config + * + * If flags is zero, network is considered as inactive and persistent. + */ +static int +networkAssignDef(virPoolObjPtr obj, + void *newDef, + void *oldDef ATTRIBUTE_UNUSED, + unsigned int assignFlags) +{ + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + virNetworkDefPtr newdef =3D newDef; + + if (assignFlags & VIR_NETWORK_OBJ_LIST_ADD_CHECK_LIVE) { + /* UUID & name match, but if network is already active, refuse it = */ + if (virPoolObjIsActive(obj)) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("network is already active as '%s'"), + def->name); + return -1; + } + } + + if (assignFlags & VIR_NETWORK_OBJ_LIST_ADD_LIVE) { + /* before setting new live def, save (into newDef) any + * existing persistent (!live) def to be restored when the + * network is destroyed, unless there is one already saved. + */ + if (virPoolObjIsPersistent(obj) && !virPoolObjGetNewDef(obj)) { + virPoolObjSetNewDef(obj, def); + virPoolObjSetDef(obj, NULL); /* Don't want SetDef to free def!= */ + } + virPoolObjSetDef(obj, newdef); + } else { /* !live */ + virNetworkDefFree(virPoolObjGetNewDef(obj)); + if (virPoolObjIsActive(obj)) { + /* save new configuration to be restored on network + * shutdown, leaving current live def alone + */ + virPoolObjSetNewDef(obj, newdef); + } else { /* !live and !active */ + if (def && !virPoolObjIsPersistent(obj)) { + /* network isn't (yet) marked active or persistent, + * but already has a "live" def set. This means we are + * currently setting the persistent def as a part of + * the process of starting the network, so we need to + * preserve the "not yet live" def in network->def. + */ + virPoolObjSetNewDef(obj, newdef); + } else { + /* either there is no live def set, or this network + * was already set as persistent, so the proper thing + * is to overwrite network->def. + */ + virPoolObjSetNewDef(obj, NULL); + virPoolObjSetDef(obj, newdef); + } + } + virPoolObjSetPersistent(obj, !!newdef); + } + + return 0; +} + + +/* + * virNetworkObjAdd: + * @netobjs: the network object to update + * @def: the new NetworkDef (will be consumed by this function) + * @assignFlags: assignment flags + * + * Replace the appropriate copy of the given network's def or newDef + * with def. Use "live" and current state of the network to determine + * which to replace and what to do with the old defs. When a non-live + * def is set, indicate that the network is now persistent. + * + * NB: a persistent network can be made transient by calling with: + * virNetworkObjAssignDef(network, NULL, false) (i.e. set the + * persistent def to NULL) + * + */ +virPoolObjPtr +virNetworkObjAdd(virPoolObjTablePtr netobjs, + virNetworkDefPtr def, + unsigned int assignFlags) +{ + virPoolObjPtr obj =3D NULL; + virNetworkObjPrivatePtr objpriv =3D NULL; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + + virUUIDFormat(def->uuid, uuidstr); + + if (!(obj =3D virPoolObjTableAdd(netobjs, uuidstr, def->name, + def, NULL, NULL, virNetworkDefFree, + networkAssignDef, assignFlags))) + return NULL; + + if (!(assignFlags & VIR_NETWORK_OBJ_LIST_ADD_LIVE)) + virPoolObjSetPersistent(obj, true); + + if (!(objpriv =3D virPoolObjGetPrivateData(obj))) { + if (!(objpriv =3D virNetworkObjPrivateAlloc())) + goto error; + + virPoolObjSetPrivateData(obj, objpriv, virNetworkObjPrivateFree); + } + + return obj; + + error: + virPoolObjTableRemove(netobjs, &obj); + virPoolObjEndAPI(&obj); + return NULL; +} + + +void +virNetworkObjAssignDef(virPoolObjPtr obj, + virNetworkDefPtr def) +{ + networkAssignDef(obj, def, NULL, false); +} + + +static char * +networkObjFormat(virPoolObjPtr obj, + unsigned int flags) +{ + virBuffer buf =3D VIR_BUFFER_INITIALIZER; + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + char *class_id =3D virBitmapFormat(virNetworkObjPrivateGetClassId(obj)= ); + unsigned int taint =3D virNetworkObjPrivateGetTaint(obj); + size_t i; + + if (!class_id) + goto error; + + virBufferAddLit(&buf, "\n"); + virBufferAdjustIndent(&buf, 2); + virBufferAsprintf(&buf, "\n", class_id); + virBufferAsprintf(&buf, "\n", + virNetworkObjPrivateGetFloorSum(obj)); + VIR_FREE(class_id); + + for (i =3D 0; i < VIR_NETWORK_TAINT_LAST; i++) { + if (taint & (1 << i)) + virBufferAsprintf(&buf, "\n", + virNetworkTaintTypeToString(i)); + } + + if (virNetworkDefFormatBuf(&buf, def, flags) < 0) + goto error; + + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, ""); + + if (virBufferCheckError(&buf) < 0) + goto error; + + return virBufferContentAndReset(&buf); + + error: + virBufferFreeAndReset(&buf); + return NULL; +} + + +int +virNetworkObjSaveStatus(const char *statusDir, + virPoolObjPtr obj) +{ + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + int ret =3D -1; + int flags =3D 0; + char *xml; + + if (!(xml =3D networkObjFormat(obj, flags))) + goto cleanup; + + if (virNetworkSaveXML(statusDir, def, xml)) + goto cleanup; + + ret =3D 0; + cleanup: + VIR_FREE(xml); + return ret; +} + + +int +virNetworkObjDeleteConfig(const char *configDir, + const char *autostartDir, + virPoolObjPtr obj) +{ + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + char *configFile =3D NULL; + char *autostartLink =3D NULL; + int ret =3D -1; + + if (!(configFile =3D virNetworkConfigFile(configDir, def->name))) + goto error; + + if (!(autostartLink =3D virNetworkConfigFile(autostartDir, def->name))) + goto error; + + /* Not fatal if this doesn't work */ + unlink(autostartLink); + virPoolObjSetAutostart(obj, false); + + if (unlink(configFile) < 0) { + virReportSystemError(errno, + _("cannot remove config file '%s'"), + configFile); + goto error; + } + + ret =3D 0; + + error: + VIR_FREE(configFile); + VIR_FREE(autostartLink); + return ret; +} + + +static virPoolObjPtr +networkLoadConfig(virPoolObjTablePtr netobjs, + const char *configDir, + const char *autostartDir, + const char *name) +{ + char *configFile =3D NULL; + char *autostartLink =3D NULL; + virNetworkDefPtr def =3D NULL; + virPoolObjPtr obj; + int autostart; + + if (!(configFile =3D virNetworkConfigFile(configDir, name))) + goto error; + + if (!(autostartLink =3D virNetworkConfigFile(autostartDir, name))) + goto error; + + if ((autostart =3D virFileLinkPointsTo(autostartLink, configFile)) < 0) + goto error; + + if (!(def =3D virNetworkDefParseFile(configFile))) + goto error; + + if (STRNEQ(name, def->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Network config filename '%s' does not match " + "network name '%s'"), + configFile, def->name); + goto error; + } + + if (def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE || + def->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT || + def->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE || + def->forward.type =3D=3D VIR_NETWORK_FORWARD_OPEN) { + + if (!def->mac_specified) { + virNetworkSetBridgeMacAddr(def); + virNetworkSaveConfig(configDir, def); + } + } else { + /* Throw away MAC address for other forward types, + * which could have been generated by older libvirt RPMs */ + def->mac_specified =3D false; + } + + if (!(obj =3D virNetworkObjAdd(netobjs, def, 0))) + goto error; + def =3D NULL; + + virPoolObjSetAutostart(obj, autostart); + + VIR_FREE(configFile); + VIR_FREE(autostartLink); + + return obj; + + error: + VIR_FREE(configFile); + VIR_FREE(autostartLink); + virNetworkDefFree(def); + return NULL; +} + + +int +virNetworkObjLoadAllConfigs(virPoolObjTablePtr netobjs, + const char *configDir, + const char *autostartDir) +{ + DIR *dir; + struct dirent *entry; + int ret =3D -1; + int rc; + + if ((rc =3D virDirOpenIfExists(&dir, configDir)) <=3D 0) + return rc; + + while ((ret =3D virDirRead(dir, &entry, configDir)) > 0) { + virPoolObjPtr obj; + + if (!virFileStripSuffix(entry->d_name, ".xml")) + continue; + + /* NB: ignoring errors, so one malformed config doesn't + kill the whole process */ + obj =3D networkLoadConfig(netobjs, configDir, autostartDir, + entry->d_name); + virPoolObjEndAPI(&obj); + } + + VIR_DIR_CLOSE(dir); + return ret; +} + + +static virPoolObjPtr +networkObjLoadState(virPoolObjTablePtr netobjs, + const char *stateDir, + const char *name) +{ + char *configFile =3D NULL; + virNetworkDefPtr def =3D NULL; + virPoolObjPtr obj =3D NULL; + xmlDocPtr xml =3D NULL; + xmlNodePtr node =3D NULL; + xmlNodePtr *nodes =3D NULL; + xmlXPathContextPtr ctxt =3D NULL; + virBitmapPtr class_id_map =3D NULL; + unsigned long long floor_sum_val =3D 0; + unsigned int taint =3D 0; + int n; + size_t i; + + + if ((configFile =3D virNetworkConfigFile(stateDir, name)) =3D=3D NULL) + goto error; + + if (!(xml =3D virXMLParseCtxt(configFile, NULL, _("(network status)"), + &ctxt))) + goto error; + + if (!(node =3D virXPathNode("//network", ctxt))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not find any 'network' element " + "in status file")); + goto error; + } + + /* parse the definition first */ + ctxt->node =3D node; + if (!(def =3D virNetworkDefParseXML(ctxt))) + goto error; + + if (STRNEQ(name, def->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Network config filename '%s' does not match " + "network name '%s'"), + configFile, def->name); + goto error; + } + + /* now parse possible status data */ + node =3D xmlDocGetRootElement(xml); + if (xmlStrEqual(node->name, BAD_CAST "networkstatus")) { + /* Newer network status file. Contains useful + * info which are not to be found in bare config XML */ + char *class_id =3D NULL; + char *floor_sum =3D NULL; + + ctxt->node =3D node; + if ((class_id =3D + virXPathString("string(./class_id[1]/@bitmap)", ctxt))) { + if (virBitmapParse(class_id, &class_id_map, + CLASS_ID_BITMAP_SIZE) < 0) { + VIR_FREE(class_id); + goto error; + } + } + VIR_FREE(class_id); + + floor_sum =3D virXPathString("string(./floor[1]/@sum)", ctxt); + if (floor_sum && + virStrToLong_ull(floor_sum, NULL, 10, &floor_sum_val) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Malformed 'floor_sum' attribute: %s"), + floor_sum); + VIR_FREE(floor_sum); + goto error; + } + VIR_FREE(floor_sum); + + if ((n =3D virXPathNodeSet("./taint", ctxt, &nodes)) < 0) + goto error; + + for (i =3D 0; i < n; i++) { + char *str =3D virXMLPropString(nodes[i], "flag"); + if (str) { + int flag =3D virNetworkTaintTypeFromString(str); + if (flag < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unknown taint flag %s"), str); + VIR_FREE(str); + goto error; + } + VIR_FREE(str); + /* Compute taint mask here. The network object does not + * exist yet, so we can't use virNetworkObjtTaint. */ + taint |=3D (1 << flag); + } + } + VIR_FREE(nodes); + } + + /* create the object */ + if (!(obj =3D virNetworkObjAdd(netobjs, def, VIR_NETWORK_OBJ_LIST_ADD_= LIVE))) + goto error; + def =3D NULL; + + /* assign status data stored in the network object */ + if (class_id_map) + virNetworkObjPrivateSetClassId(obj, class_id_map); + + if (floor_sum_val > 0) + virNetworkObjPrivateSetFloorSum(obj, floor_sum_val); + + virNetworkObjPrivateSetTaint(obj, taint); + + /* any network with a state file is by definition active */ + virPoolObjSetActive(obj, true); + + cleanup: + VIR_FREE(configFile); + xmlFreeDoc(xml); + xmlXPathFreeContext(ctxt); + return obj; + + error: + VIR_FREE(nodes); + virBitmapFree(class_id_map); + virNetworkDefFree(def); + goto cleanup; +} + + +int +virNetworkObjLoadAllState(virPoolObjTablePtr netobjs, + const char *stateDir) +{ + DIR *dir; + struct dirent *entry; + int ret =3D -1; + int rc; + + if ((rc =3D virDirOpenIfExists(&dir, stateDir)) <=3D 0) + return rc; + + while ((ret =3D virDirRead(dir, &entry, stateDir)) > 0) { + virPoolObjPtr obj; + + if (!virFileStripSuffix(entry->d_name, ".xml")) + continue; + + obj =3D networkObjLoadState(netobjs, stateDir, entry->d_name); + virPoolObjEndAPI(&obj); + } + + VIR_DIR_CLOSE(dir); + return ret; +} + + +/* + * virNetworkObjSetDefTransient: + * @obj: pool object pointer + * @live: if true, run this operation even for an inactive network. + * this allows freely updated network->def with runtime defaults + * before starting the network, which will be discarded on network + * shutdown. Any cleanup paths need to be sure to handle newDef if + * the network is never started. + * + * Mark the active network config as transient. Ensures live-only update + * operations do not persist past network destroy. + * + * Returns 0 on success, -1 on failure + */ +int +virNetworkObjSetDefTransient(virPoolObjPtr obj, + bool live) +{ + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + virNetworkDefPtr newDef; + + if (!virPoolObjIsActive(obj) && !live) + return 0; + + if (!virPoolObjIsPersistent(obj) || virPoolObjGetNewDef(obj)) + return 0; + + newDef =3D virNetworkDefCopy(def, VIR_NETWORK_XML_INACTIVE); + virPoolObjSetNewDef(obj, newDef); + return newDef ? 0 : -1; +} + + +/* virNetworkObjUnsetDefTransient: + * + * This *undoes* what virNetworkObjSetDefTransient did. + */ +void +virNetworkObjUnsetDefTransient(virPoolObjPtr obj) +{ + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + virNetworkDefPtr newDef =3D virPoolObjGetNewDef(obj); + if (newDef) { + virNetworkDefFree(def); + virPoolObjSetDef(obj, newDef); + virPoolObjSetNewDef(obj, NULL); + } +} + + +/* + * virNetworkObjGetPersistentDef: + * @obj: pool object pointer + * + * Return the persistent network configuration. If network is transient, + * return the running config. + * + * Returns NULL on error, virNetworkDefPtr on success. + */ +virNetworkDefPtr +virNetworkObjGetPersistentDef(virPoolObjPtr obj) +{ + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + virNetworkDefPtr newDef =3D virPoolObjGetNewDef(obj); + if (newDef) + return newDef; + else + return def; +} + + +/* + * virNetworkObjReplacePersistentDef: + * @obj: pool object pointer + * @def: new virNetworkDef to replace current persistent config + * + * Replace the "persistent" network configuration with the given new + * virNetworkDef. This pays attention to whether or not the network + * is active. + * + * Returns -1 on error, 0 on success + */ +int +virNetworkObjReplacePersistentDef(virPoolObjPtr obj, + virNetworkDefPtr def) +{ + virNetworkDefPtr curDef =3D virPoolObjGetDef(obj); + virNetworkDefPtr newDef =3D virPoolObjGetNewDef(obj); + + if (virPoolObjIsActive(obj)) { + virNetworkDefFree(newDef); + virPoolObjSetNewDef(obj, def); + } else { + virNetworkDefFree(curDef); + virPoolObjSetDef(obj, def); + } + return 0; +} + + +/* + * networkObjConfigChangeSetup: + * + * 1) checks whether network state is consistent with the requested + * type of modification. + * + * 3) make sure there are separate "def" and "newDef" copies of + * networkDef if appropriate. + * + * Returns 0 on success, -1 on error. + */ +static int +networkObjConfigChangeSetup(virPoolObjPtr obj, + unsigned int flags) +{ + bool isActive; + int ret =3D -1; + + isActive =3D virPoolObjIsActive(obj); + + if (!isActive && (flags & VIR_NETWORK_UPDATE_AFFECT_LIVE)) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("network is not running")); + goto cleanup; + } + + if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) { + if (!virPoolObjIsPersistent(obj)) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot change persistent config of a " + "transient network")); + goto cleanup; + } + /* this should already have been done by the driver, but do it + * anyway just in case. + */ + if (isActive && (virNetworkObjSetDefTransient(obj, false) < 0)) + goto cleanup; + } + + ret =3D 0; + + cleanup: + return ret; +} + + +/* + * virNetworkObjUpdate: + * + * Apply the supplied update to the given pool object. Except for + * @obj pointing to an actual network object rather than the + * opaque virNetworkPtr, parameters are identical to the public API + * virNetworkUpdate. + * + * The original virNetworkDefs are copied, and all modifications made + * to these copies. The originals are replaced with the copies only + * after success has been guaranteed. + * + * Returns: -1 on error, 0 on success. + */ +int +virNetworkObjUpdate(virPoolObjPtr obj, + unsigned int command, /* virNetworkUpdateCommand */ + unsigned int section, /* virNetworkUpdateSection */ + int parentIndex, + const char *xml, + unsigned int flags) /* virNetworkUpdateFlags */ +{ + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + int ret =3D -1; + virNetworkDefPtr livedef =3D NULL, configdef =3D NULL; + + /* normalize config data, and check for common invalid requests. */ + if (networkObjConfigChangeSetup(obj, flags) < 0) + goto cleanup; + + if (flags & VIR_NETWORK_UPDATE_AFFECT_LIVE) { + virNetworkDefPtr checkdef; + + /* work on a copy of the def */ + if (!(livedef =3D virNetworkDefCopy(def, 0))) + goto cleanup; + if (virNetworkDefUpdateSection(livedef, command, section, + parentIndex, xml, flags) < 0) + goto cleanup; + + /* run a final format/parse cycle to make sure we didn't + * add anything illegal to the def + */ + if (!(checkdef =3D virNetworkDefCopy(livedef, 0))) + goto cleanup; + virNetworkDefFree(checkdef); + } + + if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) { + virNetworkDefPtr checkdef; + + /* work on a copy of the def */ + if (!(configdef =3D virNetworkDefCopy(virNetworkObjGetPersistentDe= f(obj), + VIR_NETWORK_XML_INACTIVE))) { + goto cleanup; + } + if (virNetworkDefUpdateSection(configdef, command, section, + parentIndex, xml, flags) < 0) { + goto cleanup; + } + if (!(checkdef =3D virNetworkDefCopy(configdef, + VIR_NETWORK_XML_INACTIVE))) { + goto cleanup; + } + virNetworkDefFree(checkdef); + } + + if (configdef) { + /* successfully modified copy, now replace original */ + if (virNetworkObjReplacePersistentDef(obj, configdef) < 0) + goto cleanup; + configdef =3D NULL; + } + if (livedef) { + /* successfully modified copy, now replace original */ + virNetworkDefFree(def); + virPoolObjSetDef(obj, livedef); + livedef =3D NULL; + } + + ret =3D 0; + cleanup: + virNetworkDefFree(livedef); + virNetworkDefFree(configdef); + return ret; +} + + +struct networkCountData { + bool wantActive; + int count; +}; + +static int +networkCount(virPoolObjPtr obj, + void *opaque) +{ + struct networkCountData *data =3D opaque; + + if ((data->wantActive && virPoolObjIsActive(obj)) || + (!data->wantActive && !virPoolObjIsActive(obj))) + data->count++; + + return 0; +} + + +int +virNetworkObjNumOfNetworks(virPoolObjTablePtr netobjs, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter) +{ + struct networkCountData data =3D { .count =3D 0, + .wantActive =3D wantActive }; + + if (virPoolObjTableList(netobjs, conn, aclfilter, networkCount, &data)= < 0) + return 0; + + return data.count; +} + + +struct networkNameData { + bool wantActive; + int nnames; + char **const names; + int maxnames; +}; + +static int +networkListNames(virPoolObjPtr obj, + void *opaque) +{ + struct networkNameData *data =3D opaque; + + if (data->nnames < data->maxnames) { + if (data->wantActive && virPoolObjIsActive(obj)) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + + if (VIR_STRDUP(data->names[data->nnames++], def->name) < 0) + return -1; + } else if (!data->wantActive && !virPoolObjIsActive(obj)) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + + if (VIR_STRDUP(data->names[data->nnames++], def->name) < 0) + return -1; + } + } + return 0; +} + + +int +virNetworkObjGetNames(virPoolObjTablePtr netobjs, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter, + char **const names, + int maxnames) +{ + struct networkNameData data =3D { .wantActive =3D wantActive, + .nnames =3D 0, + .names =3D names, + .maxnames =3D maxnames }; + + memset(names, 0, sizeof(*names) * maxnames); + if (virPoolObjTableList(netobjs, conn, aclfilter, + networkListNames, &data) < 0) + goto error; + + return data.nnames; + + error: + while (--data.nnames >=3D 0) + VIR_FREE(names[data.nnames]); + return -1; +} + + +#define MATCH(FLAG) (flags & (FLAG)) +static bool +networkMatch(virPoolObjPtr obj, + unsigned int flags) +{ + /* filter by active state */ + if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) && + !((MATCH(VIR_CONNECT_LIST_NETWORKS_ACTIVE) && + virPoolObjIsActive(obj)) || + (MATCH(VIR_CONNECT_LIST_NETWORKS_INACTIVE) && + !virPoolObjIsActive(obj)))) + return false; + + /* filter by persistence */ + if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_PERSISTENT) && + !((MATCH(VIR_CONNECT_LIST_NETWORKS_PERSISTENT) && + virPoolObjIsPersistent(obj)) || + (MATCH(VIR_CONNECT_LIST_NETWORKS_TRANSIENT) && + !virPoolObjIsPersistent(obj)))) + return false; + + /* filter by autostart option */ + if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_AUTOSTART) && + !((MATCH(VIR_CONNECT_LIST_NETWORKS_AUTOSTART) && + virPoolObjIsAutostart(obj)) || + (MATCH(VIR_CONNECT_LIST_NETWORKS_NO_AUTOSTART) && + !virPoolObjIsAutostart(obj)))) + return false; + + return true; +} +#undef MATCH + +int +virNetworkObjExportList(virConnectPtr conn, + virPoolObjTablePtr netobjs, + virNetworkPtr **nets, + virPoolObjACLFilter aclfilter, + unsigned int flags) +{ + virPoolObjPtr *objs =3D NULL; + size_t nobjs; + virNetworkPtr *tmp_nets =3D NULL; + size_t i; + + if (virPoolObjTableCollect(netobjs, conn, &objs, &nobjs, aclfilter, + networkMatch, flags) < 0) + return -1; + + if (nets) { + if (VIR_ALLOC_N(tmp_nets, nobjs + 1) < 0) + goto cleanup; + + for (i =3D 0; i < nobjs; i++) { + virNetworkDefPtr def; + + virObjectLock(objs[i]); + def =3D virPoolObjGetDef(objs[i]); + tmp_nets[i] =3D virGetNetwork(conn, def->name, def->uuid); + virObjectUnlock(objs[i]); + if (!tmp_nets[i]) + goto cleanup; + } + + VIR_STEAL_PTR(*nets, tmp_nets); + } + + cleanup: + virObjectListFree(tmp_nets); + virObjectListFreeCount(objs, nobjs); + + return nobjs; +} + + +/** + * virNetworkObjListPrune: + * @netobjs: network objects table + * @flags: bitwise-OR of virConnectListAllNetworksFlags + * + * Iterate over list of network objects and remove the desired + * ones from it. + */ +void +virNetworkObjPrune(virPoolObjTablePtr netobjs, + unsigned int flags) +{ + virPoolObjTablePrune(netobjs, networkMatch, flags); +} + + +struct bridgeInUseData { + const char *bridge; + const char *skipname; +}; + +static bool +bridgeInUse(virPoolObjPtr obj, + void *opaque) +{ + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + virNetworkDefPtr newDef =3D virPoolObjGetNewDef(obj); + const struct bridgeInUseData *data =3D opaque; + + if (data->skipname && + ((STREQ(def->name, data->skipname)) || + (newDef && STREQ(newDef->name, data->skipname)))) + return false; + else if ((def->bridge && STREQ(def->bridge, data->bridge)) || + (newDef && newDef->bridge && + STREQ(newDef->bridge, data->bridge))) + return true; + + return false; +} + + +bool +virNetworkObjBridgeInUse(virPoolObjTablePtr netobjs, + const char *bridge, + const char *skipname) +{ + virPoolObjPtr obj; + struct bridgeInUseData data =3D { .bridge =3D bridge, + .skipname =3D skipname }; + + if ((obj =3D virPoolObjTableSearch(netobjs, bridgeInUse, &data))) { + virObjectUnlock(obj); + return true; + } + + return false; +} diff --git a/src/conf/virnetworkobj.h b/src/conf/virnetworkobj.h new file mode 100644 index 0000000..0154b56 --- /dev/null +++ b/src/conf/virnetworkobj.h @@ -0,0 +1,121 @@ +/* + * virnetworkobj.h: handle network objects + * (derived from network_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 __NETWORKOBJ_H__ +# define __NETWORKOBJ_H__ + +# include "internal.h" + +# include "network_conf.h" +# include "virpoolobj.h" + +typedef struct _virNetworkObjPrivate virNetworkObjPrivate; +typedef virNetworkObjPrivate *virNetworkObjPrivatePtr; + +pid_t virNetworkObjPrivateGetDnsmasqPid(virPoolObjPtr obj); + +void virNetworkObjPrivateSetDnsmasqPid(virPoolObjPtr obj, pid_t dnsmasqPid= ); + +pid_t virNetworkObjPrivateGetRadvdPid(virPoolObjPtr obj); + +void virNetworkObjPrivateSetRadvdPid(virPoolObjPtr obj, pid_t radvdPid); + +virBitmapPtr virNetworkObjPrivateGetClassId(virPoolObjPtr obj); + +void virNetworkObjPrivateSetClassId(virPoolObjPtr obj, virBitmapPtr class_= id); + +unsigned long long virNetworkObjPrivateGetFloorSum(virPoolObjPtr obj); + +void virNetworkObjPrivateSetFloorSum(virPoolObjPtr obj, + unsigned long long floor_sum); + +virMacMapPtr virNetworkObjPrivateGetMacMap(virPoolObjPtr obj); + +void virNetworkObjPrivateSetMacMap(virPoolObjPtr obj, virMacMapPtr macmap); + +unsigned int virNetworkObjPrivateGetTaint(virPoolObjPtr obj); + +bool virNetworkObjPrivateIsTaint(virPoolObjPtr obj, + virNetworkTaintFlags taint); + +void virNetworkObjPrivateSetTaint(virPoolObjPtr obj, unsigned int taint); + +virPoolObjPtr virNetworkObjAdd(virPoolObjTablePtr netobjs, + virNetworkDefPtr def, + unsigned int flags); + +void virNetworkObjAssignDef(virPoolObjPtr obj, + virNetworkDefPtr def); + +int virNetworkObjSaveStatus(const char *statusDir, + virPoolObjPtr obj) ATTRIBUTE_RETURN_CHECK; + +int virNetworkObjDeleteConfig(const char *configDir, + const char *autostartDir, + virPoolObjPtr obj); + +int virNetworkObjLoadAllConfigs(virPoolObjTablePtr netobjs, + const char *configDir, + const char *autostartDir); + +int virNetworkObjLoadAllState(virPoolObjTablePtr netobjs, + const char *stateDir); + +int virNetworkObjSetDefTransient(virPoolObjPtr obj, bool live); + +void virNetworkObjUnsetDefTransient(virPoolObjPtr obj); + +virNetworkDefPtr virNetworkObjGetPersistentDef(virPoolObjPtr obj); + +int virNetworkObjReplacePersistentDef(virPoolObjPtr obj, + virNetworkDefPtr def); + +int virNetworkObjUpdate(virPoolObjPtr obj, + unsigned int command, /* virNetworkUpdateCommand */ + unsigned int section, /* virNetworkUpdateSection */ + int parentIndex, + const char *xml, + unsigned int flags); /* virNetworkUpdateFlags */ + +int virNetworkObjNumOfNetworks(virPoolObjTablePtr netobjs, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter); + +int virNetworkObjGetNames(virPoolObjTablePtr netobjs, + virConnectPtr conn, + bool wantActive, + virPoolObjACLFilter aclfilter, + char **const names, + int maxnames); + +int virNetworkObjExportList(virConnectPtr conn, + virPoolObjTablePtr netobjs, + virNetworkPtr **nets, + virPoolObjACLFilter aclfilter, + unsigned int flags); + +void virNetworkObjPrune(virPoolObjTablePtr netobjs, + unsigned int flags); + +bool virNetworkObjBridgeInUse(virPoolObjTablePtr netobjs, + const char *bridge, + const char *skipname); + +#endif /* __NETWORKOBJ_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5c91988..59209df 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -620,11 +620,8 @@ virNetDevVPortTypeToString; =20 =20 # conf/network_conf.h -virNetworkAssignDef; -virNetworkBridgeInUse; virNetworkBridgeMACTableManagerTypeFromString; virNetworkBridgeMACTableManagerTypeToString; -virNetworkConfigChangeSetup; virNetworkConfigFile; virNetworkDefCopy; virNetworkDefFormat; @@ -636,35 +633,12 @@ virNetworkDefGetRouteByIndex; virNetworkDefParseFile; virNetworkDefParseNode; virNetworkDefParseString; +virNetworkDefParseXML; virNetworkDefUpdateSection; -virNetworkDeleteConfig; virNetworkForwardTypeToString; virNetworkIPDefNetmask; virNetworkIPDefPrefix; -virNetworkLoadAllConfigs; -virNetworkLoadAllState; -virNetworkObjAssignDef; -virNetworkObjEndAPI; -virNetworkObjFindByName; -virNetworkObjFindByNameLocked; -virNetworkObjFindByUUID; -virNetworkObjFindByUUIDLocked; -virNetworkObjGetPersistentDef; -virNetworkObjListExport; -virNetworkObjListForEach; -virNetworkObjListGetNames; -virNetworkObjListNew; -virNetworkObjListNumOfNetworks; -virNetworkObjListPrune; -virNetworkObjNew; -virNetworkObjReplacePersistentDef; -virNetworkObjSetDefTransient; -virNetworkObjTaint; -virNetworkObjUnsetDefTransient; -virNetworkObjUpdate; -virNetworkRemoveInactive; virNetworkSaveConfig; -virNetworkSaveStatus; virNetworkSetBridgeMacAddr; virNetworkTaintTypeFromString; virNetworkTaintTypeToString; @@ -920,6 +894,38 @@ virInterfaceObjGetNames; virInterfaceObjNumOfInterfaces; =20 =20 +# conf/virnetworkobj.h +virNetworkObjAdd; +virNetworkObjAssignDef; +virNetworkObjBridgeInUse; +virNetworkObjDeleteConfig; +virNetworkObjExportList; +virNetworkObjGetNames; +virNetworkObjGetPersistentDef; +virNetworkObjLoadAllConfigs; +virNetworkObjLoadAllState; +virNetworkObjNumOfNetworks; +virNetworkObjPrivateGetClassId; +virNetworkObjPrivateGetDnsmasqPid; +virNetworkObjPrivateGetFloorSum; +virNetworkObjPrivateGetMacMap; +virNetworkObjPrivateGetRadvdPid; +virNetworkObjPrivateGetTaint; +virNetworkObjPrivateIsTaint; +virNetworkObjPrivateSetClassId; +virNetworkObjPrivateSetDnsmasqPid; +virNetworkObjPrivateSetFloorSum; +virNetworkObjPrivateSetMacMap; +virNetworkObjPrivateSetRadvdPid; +virNetworkObjPrivateSetTaint; +virNetworkObjPrune; +virNetworkObjReplacePersistentDef; +virNetworkObjSaveStatus; +virNetworkObjSetDefTransient; +virNetworkObjUnsetDefTransient; +virNetworkObjUpdate; + + # conf/virnodedeviceobj.h virNodeDeviceObjExportList; virNodeDeviceObjFindByName; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 06759c6..926fe71 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -49,7 +49,6 @@ #include "datatypes.h" #include "bridge_driver.h" #include "bridge_driver_platform.h" -#include "network_conf.h" #include "device_conf.h" #include "driver.h" #include "virbuffer.h" @@ -66,6 +65,7 @@ #include "virnetdevbridge.h" #include "virnetdevtap.h" #include "virnetdevvportprofile.h" +#include "virnetworkobj.h" #include "virpci.h" #include "virdbus.h" #include "virfile.h" @@ -135,64 +135,92 @@ networkDnsmasqCapsRefresh(virNetworkDriverStatePtr dr= iver) static int networkStateCleanup(void); =20 static int networkStartNetwork(virNetworkDriverStatePtr driver, - virNetworkObjPtr network); + virPoolObjPtr obj); =20 static int networkShutdownNetwork(virNetworkDriverStatePtr driver, - virNetworkObjPtr network); + virPoolObjPtr obj); =20 static int networkStartNetworkVirtual(virNetworkDriverStatePtr driver, - virNetworkObjPtr network); + virPoolObjPtr obj); =20 static int networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver, - virNetworkObjPtr network); + virPoolObjPtr obj); =20 -static int networkStartNetworkExternal(virNetworkObjPtr network); +static int networkStartNetworkExternal(virPoolObjPtr obj); =20 -static int networkShutdownNetworkExternal(virNetworkObjPtr network); +static int networkShutdownNetworkExternal(virPoolObjPtr obj); =20 static void networkReloadFirewallRules(virNetworkDriverStatePtr driver); static void networkRefreshDaemons(virNetworkDriverStatePtr driver); =20 -static int networkPlugBandwidth(virNetworkObjPtr net, +static int networkPlugBandwidth(virPoolObjPtr obj, virDomainNetDefPtr iface); -static int networkUnplugBandwidth(virNetworkObjPtr net, +static int networkUnplugBandwidth(virPoolObjPtr obj, virDomainNetDefPtr iface); =20 -static void networkNetworkObjTaint(virNetworkObjPtr net, +static void networkNetworkObjTaint(virPoolObjPtr obj, virNetworkTaintFlags taint); =20 -static virNetworkObjPtr -networkObjFromNetwork(virNetworkPtr net) +static virPoolObjPtr +networkObjFindByUUID(const unsigned char *uuid, + const char *name) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - virNetworkObjPtr network; + virPoolObjPtr obj; char uuidstr[VIR_UUID_STRING_BUFLEN]; =20 - network =3D virNetworkObjFindByUUID(driver->networks, net->uuid); - if (!network) { - virUUIDFormat(net->uuid, uuidstr); + if (!(obj =3D virPoolObjTableFindByUUIDRef(driver->networks, uuid))) { + virUUIDFormat(uuid, uuidstr); + if (name) + virReportError(VIR_ERR_NO_NETWORK, + _("no network with matching uuid '%s' (%s)"), + uuidstr, name); + else + virReportError(VIR_ERR_NO_NETWORK, + _("no network with matching uuid '%s'"), + uuidstr); + } + + return obj; +} + +static virPoolObjPtr +networkObjFromNetwork(virNetworkPtr net) +{ + return networkObjFindByUUID(net->uuid, net->name); +} + + +static virPoolObjPtr +networkObjFindByName(const char *name) +{ + virNetworkDriverStatePtr driver =3D networkGetDriver(); + virPoolObjPtr obj; + + if (!(obj =3D virPoolObjTableFindByName(driver->networks, name))) { virReportError(VIR_ERR_NO_NETWORK, - _("no network with matching uuid '%s' (%s)"), - uuidstr, net->name); + _("no network with matching name '%s'"), name); } =20 - return network; + return obj; } =20 + static int -networkRunHook(virNetworkObjPtr network, +networkRunHook(virPoolObjPtr obj, virDomainDefPtr dom, virDomainNetDefPtr iface, int op, int sub_op) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); virBuffer buf =3D VIR_BUFFER_INITIALIZER; char *xml =3D NULL, *net_xml =3D NULL, *dom_xml =3D NULL; int hookret; int ret =3D -1; =20 if (virHookPresent(VIR_HOOK_DRIVER_NETWORK)) { - if (!network) { + if (!obj) { VIR_DEBUG("Not running hook as @network is NULL"); ret =3D 0; goto cleanup; @@ -202,7 +230,7 @@ networkRunHook(virNetworkObjPtr network, virBufferAdjustIndent(&buf, 2); if (iface && virDomainNetDefFormat(&buf, iface, NULL, 0) < 0) goto cleanup; - if (virNetworkDefFormatBuf(&buf, network->def, 0) < 0) + if (virNetworkDefFormatBuf(&buf, def, 0) < 0) goto cleanup; if (dom && virDomainDefFormatInternal(dom, NULL, 0, &buf) < 0) goto cleanup; @@ -214,7 +242,7 @@ networkRunHook(virNetworkObjPtr network, goto cleanup; =20 xml =3D virBufferContentAndReset(&buf); - hookret =3D virHookCall(VIR_HOOK_DRIVER_NETWORK, network->def->nam= e, + hookret =3D virHookCall(VIR_HOOK_DRIVER_NETWORK, def->name, op, sub_op, NULL, xml, NULL); =20 /* @@ -223,7 +251,7 @@ networkRunHook(virNetworkObjPtr network, if (hookret < 0) goto cleanup; =20 - networkNetworkObjTaint(network, VIR_NETWORK_TAINT_HOOK); + networkNetworkObjTaint(obj, VIR_NETWORK_TAINT_HOOK); } =20 ret =3D 0; @@ -235,6 +263,7 @@ networkRunHook(virNetworkObjPtr network, return ret; } =20 + static char * networkDnsmasqLeaseFileNameDefault(virNetworkDriverStatePtr driver, const char *netname) @@ -246,6 +275,7 @@ networkDnsmasqLeaseFileNameDefault(virNetworkDriverStat= ePtr driver, return leasefile; } =20 + static char * networkDnsmasqLeaseFileNameCustom(virNetworkDriverStatePtr driver, const char *bridge) @@ -257,6 +287,7 @@ networkDnsmasqLeaseFileNameCustom(virNetworkDriverState= Ptr driver, return leasefile; } =20 + static char * networkDnsmasqConfigFileName(virNetworkDriverStatePtr driver, const char *netname) @@ -268,6 +299,7 @@ networkDnsmasqConfigFileName(virNetworkDriverStatePtr d= river, return conffile; } =20 + static char * networkRadvdPidfileBasename(const char *netname) { @@ -278,6 +310,7 @@ networkRadvdPidfileBasename(const char *netname) return pidfilebase; } =20 + static char * networkRadvdConfigFileName(virNetworkDriverStatePtr driver, const char *netname) @@ -289,6 +322,7 @@ networkRadvdConfigFileName(virNetworkDriverStatePtr dri= ver, return configfile; } =20 + static char * networkMacMgrFileName(virNetworkDriverStatePtr driver, const char *bridge) @@ -300,10 +334,11 @@ networkMacMgrFileName(virNetworkDriverStatePtr driver, return filename; } =20 + /* do needed cleanup steps and remove the network from the list */ static int networkRemoveInactive(virNetworkDriverStatePtr driver, - virNetworkObjPtr net) + virPoolObjPtr *obj) { char *leasefile =3D NULL; char *customleasefile =3D NULL; @@ -313,7 +348,7 @@ networkRemoveInactive(virNetworkDriverStatePtr driver, char *statusfile =3D NULL; char *macMapFile =3D NULL; dnsmasqContext *dctx =3D NULL; - virNetworkDefPtr def =3D virNetworkObjGetPersistentDef(net); + virNetworkDefPtr def =3D virNetworkObjGetPersistentDef(*obj); =20 int ret =3D -1; =20 @@ -326,7 +361,8 @@ networkRemoveInactive(virNetworkDriverStatePtr driver, if (!(leasefile =3D networkDnsmasqLeaseFileNameDefault(driver, def->na= me))) goto cleanup; =20 - if (!(customleasefile =3D networkDnsmasqLeaseFileNameCustom(driver, de= f->bridge))) + if (!(customleasefile =3D networkDnsmasqLeaseFileNameCustom(driver, + def->bridge)= )) goto cleanup; =20 if (!(radvdconfigfile =3D networkRadvdConfigFileName(driver, def->name= ))) @@ -361,7 +397,7 @@ networkRemoveInactive(virNetworkDriverStatePtr driver, unlink(statusfile); =20 /* remove the network definition */ - virNetworkRemoveInactive(driver->networks, net); + virPoolObjTableRemove(driver->networks, obj); =20 ret =3D 0; =20 @@ -377,28 +413,31 @@ networkRemoveInactive(virNetworkDriverStatePtr driver, return ret; } =20 + static int networkMacMgrAdd(virNetworkDriverStatePtr driver, - virNetworkObjPtr network, + virPoolObjPtr obj, const char *domain, const virMacAddr *mac) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + virMacMapPtr macmap =3D virNetworkObjPrivateGetMacMap(obj); char macStr[VIR_MAC_STRING_BUFLEN]; char *file =3D NULL; int ret =3D -1; =20 - if (!network->macmap) + if (!macmap) return 0; =20 virMacAddrFormat(mac, macStr); =20 - if (!(file =3D networkMacMgrFileName(driver, network->def->bridge))) + if (!(file =3D networkMacMgrFileName(driver, def->bridge))) goto cleanup; =20 - if (virMacMapAdd(network->macmap, domain, macStr) < 0) + if (virMacMapAdd(macmap, domain, macStr) < 0) goto cleanup; =20 - if (virMacMapWriteFile(network->macmap, file) < 0) + if (virMacMapWriteFile(macmap, file) < 0) goto cleanup; =20 ret =3D 0; @@ -407,28 +446,31 @@ networkMacMgrAdd(virNetworkDriverStatePtr driver, return ret; } =20 + static int networkMacMgrDel(virNetworkDriverStatePtr driver, - virNetworkObjPtr network, + virPoolObjPtr obj, const char *domain, const virMacAddr *mac) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + virMacMapPtr macmap =3D virNetworkObjPrivateGetMacMap(obj); char macStr[VIR_MAC_STRING_BUFLEN]; char *file =3D NULL; int ret =3D -1; =20 - if (!network->macmap) + if (!macmap) return 0; =20 virMacAddrFormat(mac, macStr); =20 - if (!(file =3D networkMacMgrFileName(driver, network->def->bridge))) + if (!(file =3D networkMacMgrFileName(driver, def->bridge))) goto cleanup; =20 - if (virMacMapRemove(network->macmap, domain, macStr) < 0) + if (virMacMapRemove(macmap, domain, macStr) < 0) goto cleanup; =20 - if (virMacMapWriteFile(network->macmap, file) < 0) + if (virMacMapWriteFile(macmap, file) < 0) goto cleanup; =20 ret =3D 0; @@ -437,6 +479,7 @@ networkMacMgrDel(virNetworkDriverStatePtr driver, return ret; } =20 + static char * networkBridgeDummyNicName(const char *brname) { @@ -461,34 +504,33 @@ networkBridgeDummyNicName(const char *brname) return nicname; } =20 -static int -networkUpdateState(virNetworkObjPtr obj, + +/* Enter with locked virPoolObjPtr */ +static void +networkUpdateState(virPoolObjPtr obj, void *opaque) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); virNetworkDriverStatePtr driver =3D opaque; dnsmasqCapsPtr dnsmasq_caps =3D networkGetDnsmasqCaps(driver); - int ret =3D -1; =20 - virObjectLock(obj); - if (!virNetworkObjIsActive(obj)) { - ret =3D 0; + if (!virPoolObjIsActive(obj)) goto cleanup; - } =20 - switch (obj->def->forward.type) { + switch (def->forward.type) { case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: /* If bridge doesn't exist, then mark it inactive */ - if (!(obj->def->bridge && virNetDevExists(obj->def->bridge) =3D=3D= 1)) - obj->active =3D 0; + if (!(def->bridge && virNetDevExists(def->bridge) =3D=3D 1)) + virPoolObjSetActive(obj, false); break; =20 case VIR_NETWORK_FORWARD_BRIDGE: - if (obj->def->bridge) { - if (virNetDevExists(obj->def->bridge) !=3D 1) - obj->active =3D 0; + if (def->bridge) { + if (virNetDevExists(def->bridge) !=3D 1) + virPoolObjSetActive(obj, false); break; } /* intentionally drop through to common case for all @@ -507,63 +549,58 @@ networkUpdateState(virNetworkObjPtr obj, } =20 /* Try and read dnsmasq/radvd pids of active networks */ - if (obj->active && obj->def->ips && (obj->def->nips > 0)) { + if (virPoolObjIsActive(obj) && def->ips && (def->nips > 0)) { char *radvdpidbase; char *macMapFile; + pid_t dnsmasqPid; + pid_t radvdPid; + virMacMapPtr macmap =3D NULL; =20 ignore_value(virPidFileReadIfAlive(driver->pidDir, - obj->def->name, - &obj->dnsmasqPid, + def->name, + &dnsmasqPid, dnsmasqCapsGetBinaryPath(dnsmas= q_caps))); + virNetworkObjPrivateSetDnsmasqPid(obj, dnsmasqPid); =20 - radvdpidbase =3D networkRadvdPidfileBasename(obj->def->name); - if (!radvdpidbase) + if (!(radvdpidbase =3D networkRadvdPidfileBasename(def->name))) goto cleanup; =20 ignore_value(virPidFileReadIfAlive(driver->pidDir, radvdpidbase, - &obj->radvdPid, RADVD)); + &radvdPid, RADVD)); + virNetworkObjPrivateSetRadvdPid(obj, radvdPid); VIR_FREE(radvdpidbase); =20 - if (!(macMapFile =3D networkMacMgrFileName(driver, obj->def->bridg= e))) + if (!(macMapFile =3D networkMacMgrFileName(driver, def->bridge))) goto cleanup; =20 if (virFileExists(macMapFile) && - !(obj->macmap =3D virMacMapNew(macMapFile))) { + !(macmap =3D virMacMapNew(macMapFile))) { VIR_FREE(macMapFile); goto cleanup; } + virNetworkObjPrivateSetMacMap(obj, macmap); =20 VIR_FREE(macMapFile); } =20 - ret =3D 0; cleanup: - virObjectUnlock(obj); virObjectUnref(dnsmasq_caps); - return ret; } =20 =20 -static int -networkAutostartConfig(virNetworkObjPtr net, +/* Enter with locked virPoolObjPtr */ +static void +networkAutostartConfig(virPoolObjPtr obj, void *opaque) { virNetworkDriverStatePtr driver =3D opaque; - int ret =3D -1; - - virObjectLock(net); - if (net->autostart && - !virNetworkObjIsActive(net) && - networkStartNetwork(driver, net) < 0) - goto cleanup; =20 - ret =3D 0; - cleanup: - virObjectUnlock(net); - return ret; + if (virPoolObjIsAutostart(obj) && !virPoolObjIsActive(obj)) + ignore_value(networkStartNetwork(driver, obj)); } =20 + #if HAVE_FIREWALLD static DBusHandlerResult firewalld_dbus_filter_bridge(DBusConnection *connection ATTRIBUTE_UNUSED, @@ -584,6 +621,7 @@ firewalld_dbus_filter_bridge(DBusConnection *connection= ATTRIBUTE_UNUSED, } #endif =20 + static int networkMigrateStateFiles(virNetworkDriverStatePtr driver) { @@ -669,6 +707,7 @@ networkMigrateStateFiles(virNetworkDriverStatePtr drive= r) return ret; } =20 + /** * networkStateInitialize: * @@ -751,28 +790,30 @@ networkStateInitialize(bool privileged, /* if this fails now, it will be retried later with dnsmasqCapsRefresh= () */ network_driver->dnsmasqCaps =3D dnsmasqCapsNewFromBinary(DNSMASQ); =20 - if (!(network_driver->networks =3D virNetworkObjListNew())) + if (!(network_driver->networks =3D + virPoolObjTableNew(VIR_POOLOBJTABLE_NETWORK, + VIR_POOLOBJTABLE_NETWORK_HASHSTART, false))) goto error; =20 - if (virNetworkLoadAllState(network_driver->networks, - network_driver->stateDir) < 0) + if (virNetworkObjLoadAllState(network_driver->networks, + network_driver->stateDir) < 0) goto error; =20 - if (virNetworkLoadAllConfigs(network_driver->networks, - network_driver->networkConfigDir, - network_driver->networkAutostartDir) < 0) + if (virNetworkObjLoadAllConfigs(network_driver->networks, + network_driver->networkConfigDir, + network_driver->networkAutostartDir) <= 0) goto error; =20 /* Update the internal status of all allegedly active * networks according to external conditions on the host * (i.e. anything that isn't stored directly in each * network's state file). */ - virNetworkObjListForEach(network_driver->networks, - networkUpdateState, - network_driver); - virNetworkObjListPrune(network_driver->networks, - VIR_CONNECT_LIST_NETWORKS_INACTIVE | - VIR_CONNECT_LIST_NETWORKS_TRANSIENT); + virPoolObjTableIterate(network_driver->networks, + networkUpdateState, + network_driver); + virNetworkObjPrune(network_driver->networks, + VIR_CONNECT_LIST_NETWORKS_INACTIVE | + VIR_CONNECT_LIST_NETWORKS_TRANSIENT); networkReloadFirewallRules(network_driver); networkRefreshDaemons(network_driver); =20 @@ -814,6 +855,7 @@ networkStateInitialize(bool privileged, goto cleanup; } =20 + /** * networkStateAutoStart: * @@ -825,11 +867,12 @@ networkStateAutoStart(void) if (!network_driver) return; =20 - virNetworkObjListForEach(network_driver->networks, - networkAutostartConfig, - network_driver); + virPoolObjTableIterate(network_driver->networks, + networkAutostartConfig, + network_driver); } =20 + /** * networkStateReload: * @@ -842,16 +885,16 @@ networkStateReload(void) if (!network_driver) return 0; =20 - virNetworkLoadAllState(network_driver->networks, - network_driver->stateDir); - virNetworkLoadAllConfigs(network_driver->networks, - network_driver->networkConfigDir, - network_driver->networkAutostartDir); + virNetworkObjLoadAllState(network_driver->networks, + network_driver->stateDir); + virNetworkObjLoadAllConfigs(network_driver->networks, + network_driver->networkConfigDir, + network_driver->networkAutostartDir); networkReloadFirewallRules(network_driver); networkRefreshDaemons(network_driver); - virNetworkObjListForEach(network_driver->networks, - networkAutostartConfig, - network_driver); + virPoolObjTableIterate(network_driver->networks, + networkAutostartConfig, + network_driver); return 0; } =20 @@ -1032,17 +1075,18 @@ networkDnsmasqConfLocalPTRs(virBufferPtr buf, =20 =20 int -networkDnsmasqConfContents(virNetworkObjPtr network, +networkDnsmasqConfContents(virPoolObjPtr obj, const char *pidfile, char **configstr, dnsmasqContext *dctx, dnsmasqCapsPtr caps ATTRIBUTE_UNUSED) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); virBuffer configbuf =3D VIR_BUFFER_INITIALIZER; int r, ret =3D -1; int nbleases =3D 0; size_t i; - virNetworkDNSDefPtr dns =3D &network->def->dns; + virNetworkDNSDefPtr dns =3D &def->dns; bool wantDNS =3D dns->enable !=3D VIR_TRISTATE_BOOL_NO; virNetworkIPDefPtr tmpipdef, ipdef, ipv4def, ipv6def; bool ipv6SLAAC; @@ -1076,7 +1120,7 @@ networkDnsmasqConfContents(virNetworkObjPtr network, "## or other application using the libvirt API.\n" "##\n## dnsmasq conf file created by libvirt\n" "strict-order\n", - network->def->name); + def->name); =20 /* if dns is disabled, set its listening port to 0, which * tells dnsmasq to not listen @@ -1084,10 +1128,10 @@ networkDnsmasqConfContents(virNetworkObjPtr network, if (!wantDNS) virBufferAddLit(&configbuf, "port=3D0\n"); =20 - if (wantDNS && network->def->dns.forwarders) { + if (wantDNS && def->dns.forwarders) { virBufferAddLit(&configbuf, "no-resolv\n"); - for (i =3D 0; i < network->def->dns.nfwds; i++) { - virNetworkDNSForwarderPtr fwd =3D &network->def->dns.forwarder= s[i]; + for (i =3D 0; i < def->dns.nfwds; i++) { + virNetworkDNSForwarderPtr fwd =3D &def->dns.forwarders[i]; =20 virBufferAddLit(&configbuf, "server=3D"); if (fwd->domain) @@ -1106,23 +1150,23 @@ networkDnsmasqConfContents(virNetworkObjPtr network, } } =20 - if (network->def->domain) { - if (network->def->domainLocalOnly =3D=3D VIR_TRISTATE_BOOL_YES) { + if (def->domain) { + if (def->domainLocalOnly =3D=3D VIR_TRISTATE_BOOL_YES) { virBufferAsprintf(&configbuf, "local=3D/%s/\n", - network->def->domain); + def->domain); } virBufferAsprintf(&configbuf, "domain=3D%s\n" "expand-hosts\n", - network->def->domain); + def->domain); } =20 if (wantDNS && - networkDnsmasqConfLocalPTRs(&configbuf, network->def) < 0) + networkDnsmasqConfLocalPTRs(&configbuf, def) < 0) goto cleanup; =20 - if (wantDNS && network->def->dns.forwardPlainNames =3D=3D VIR_TRISTATE= _BOOL_NO) { + if (wantDNS && def->dns.forwardPlainNames =3D=3D VIR_TRISTATE_BOOL_NO)= { virBufferAddLit(&configbuf, "domain-needed\n"); /* need to specify local=3D// whether or not a domain is * specified, unless the config says we should forward "plain" @@ -1153,19 +1197,19 @@ networkDnsmasqConfContents(virNetworkObjPtr network, virBufferAsprintf(&configbuf, "bind-dynamic\n" "interface=3D%s\n", - network->def->bridge); + def->bridge); } else { virBufferAddLit(&configbuf, "bind-interfaces\n"); /* * --interface does not actually work with dnsmasq < 2.47, * due to DAD for ipv6 addresses on the interface. * - * virCommandAddArgList(cmd, "--interface", network->def->bridge, = NULL); + * virCommandAddArgList(cmd, "--interface", def->bridge, NULL); * * So listen on all defined IPv[46] addresses */ for (i =3D 0; - (tmpipdef =3D virNetworkDefGetIPByIndex(network->def, AF_UNSP= EC, i)); + (tmpipdef =3D virNetworkDefGetIPByIndex(def, AF_UNSPEC, i)); i++) { char *ipaddr =3D virSocketAddrFormat(&tmpipdef->address); =20 @@ -1211,7 +1255,7 @@ networkDnsmasqConfContents(virNetworkObjPtr network, * via the sender's link-local address. The only thing we can do * is set the lifetime of this route to 0, i.e. disable it. */ - if (network->def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE) { + if (def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE) { virBufferAddLit(&configbuf, "dhcp-option=3D3\n" "no-resolv\n"); if (dnsmasqCapsGet(caps, DNSMASQ_CAPS_RA_PARAM)) { @@ -1235,14 +1279,14 @@ networkDnsmasqConfContents(virNetworkObjPtr network, virReportError(VIR_ERR_INTERNAL_ERROR, _("Missing required 'service' " "attribute in SRV record of network '%s'"= ), - network->def->name); + def->name); goto cleanup; } if (!dns->srvs[i].protocol) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Missing required 'service' " "attribute in SRV record of network '%s'"= ), - network->def->name); + def->name); goto cleanup; } /* RFC2782 requires that service and protocol be preceded by @@ -1284,7 +1328,7 @@ networkDnsmasqConfContents(virNetworkObjPtr network, =20 /* Find the first dhcp for both IPv4 and IPv6 */ for (i =3D 0, ipv4def =3D NULL, ipv6def =3D NULL, ipv6SLAAC =3D false; - (ipdef =3D virNetworkDefGetIPByIndex(network->def, AF_UNSPEC, i)); + (ipdef =3D virNetworkDefGetIPByIndex(def, AF_UNSPEC, i)); i++) { if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) { if (ipdef->nranges || ipdef->nhosts) { @@ -1346,7 +1390,7 @@ networkDnsmasqConfContents(virNetworkObjPtr network, if (prefix < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("bridge '%s' has an invalid prefix"), - network->def->bridge); + def->bridge); goto cleanup; } for (r =3D 0; r < ipdef->nranges; r++) { @@ -1452,7 +1496,7 @@ networkDnsmasqConfContents(virNetworkObjPtr network, virBufferAddLit(&configbuf, "enable-ra\n"); } else { for (i =3D 0; - (ipdef =3D virNetworkDefGetIPByIndex(network->def, AF_INE= T6, i)); + (ipdef =3D virNetworkDefGetIPByIndex(def, AF_INET6, i)); i++) { if (!(ipdef->nranges || ipdef->nhosts)) { char *bridgeaddr =3D virSocketAddrFormat(&ipdef->addre= ss); @@ -1481,11 +1525,12 @@ networkDnsmasqConfContents(virNetworkObjPtr network, /* build the dnsmasq command line */ static int ATTRIBUTE_NONNULL(3) networkBuildDhcpDaemonCommandLine(virNetworkDriverStatePtr driver, - virNetworkObjPtr network, + virPoolObjPtr obj, virCommandPtr *cmdout, char *pidfile, dnsmasqContext *dctx) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); dnsmasqCapsPtr dnsmasq_caps =3D networkGetDnsmasqCaps(driver); virCommandPtr cmd =3D NULL; int ret =3D -1; @@ -1493,16 +1538,16 @@ networkBuildDhcpDaemonCommandLine(virNetworkDriverS= tatePtr driver, char *configstr =3D NULL; char *leaseshelper_path =3D NULL; =20 - network->dnsmasqPid =3D -1; + virNetworkObjPrivateSetDnsmasqPid(obj, -1); =20 - if (networkDnsmasqConfContents(network, pidfile, &configstr, + if (networkDnsmasqConfContents(obj, pidfile, &configstr, dctx, dnsmasq_caps) < 0) goto cleanup; if (!configstr) goto cleanup; =20 /* construct the filename */ - if (!(configfile =3D networkDnsmasqConfigFileName(driver, network->def= ->name))) + if (!(configfile =3D networkDnsmasqConfigFileName(driver, def->name))) goto cleanup; =20 /* Write the file */ @@ -1524,7 +1569,7 @@ networkBuildDhcpDaemonCommandLine(virNetworkDriverSta= tePtr driver, /* Libvirt gains full control of leases database */ virCommandAddArgFormat(cmd, "--leasefile-ro"); virCommandAddArgFormat(cmd, "--dhcp-script=3D%s", leaseshelper_path); - virCommandAddEnvPair(cmd, "VIR_BRIDGE_NAME", network->def->bridge); + virCommandAddEnvPair(cmd, "VIR_BRIDGE_NAME", def->bridge); =20 *cmdout =3D cmd; ret =3D 0; @@ -1536,21 +1581,24 @@ networkBuildDhcpDaemonCommandLine(virNetworkDriverS= tatePtr driver, return ret; } =20 + static int networkStartDhcpDaemon(virNetworkDriverStatePtr driver, - virNetworkObjPtr network) + virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); virNetworkIPDefPtr ipdef; size_t i; bool needDnsmasq =3D false; virCommandPtr cmd =3D NULL; char *pidfile =3D NULL; + pid_t dnsmasqPid =3D -1; int ret =3D -1; dnsmasqContext *dctx =3D NULL; =20 /* see if there are any IP addresses that need a dhcp server */ i =3D 0; - while ((ipdef =3D virNetworkDefGetIPByIndex(network->def, AF_UNSPEC, i= ))) { + while ((ipdef =3D virNetworkDefGetIPByIndex(def, AF_UNSPEC, i))) { i++; if (ipdef->nranges || ipdef->nhosts) needDnsmasq =3D true; @@ -1562,7 +1610,7 @@ networkStartDhcpDaemon(virNetworkDriverStatePtr drive= r, goto cleanup; } =20 - if (!needDnsmasq && network->def->dns.enable =3D=3D VIR_TRISTATE_BOOL_= NO) { + if (!needDnsmasq && def->dns.enable =3D=3D VIR_TRISTATE_BOOL_NO) { /* no DHCP services needed, and user disabled DNS service */ ret =3D 0; goto cleanup; @@ -1575,8 +1623,7 @@ networkStartDhcpDaemon(virNetworkDriverStatePtr drive= r, goto cleanup; } =20 - if (!(pidfile =3D virPidFileBuildPath(driver->pidDir, - network->def->name))) + if (!(pidfile =3D virPidFileBuildPath(driver->pidDir, def->name))) goto cleanup; =20 if (virFileMakePath(driver->dnsmasqStateDir) < 0) { @@ -1586,14 +1633,13 @@ networkStartDhcpDaemon(virNetworkDriverStatePtr dri= ver, goto cleanup; } =20 - dctx =3D dnsmasqContextNew(network->def->name, driver->dnsmasqStateDir= ); - if (dctx =3D=3D NULL) + if (!(dctx =3D dnsmasqContextNew(def->name, driver->dnsmasqStateDir))) goto cleanup; =20 if (networkDnsmasqCapsRefresh(driver) < 0) goto cleanup; =20 - ret =3D networkBuildDhcpDaemonCommandLine(driver, network, &cmd, pidfi= le, dctx); + ret =3D networkBuildDhcpDaemonCommandLine(driver, obj, &cmd, pidfile, = dctx); if (ret < 0) goto cleanup; =20 @@ -1613,10 +1659,9 @@ networkStartDhcpDaemon(virNetworkDriverStatePtr driv= er, * pid */ =20 - ret =3D virPidFileRead(driver->pidDir, network->def->name, - &network->dnsmasqPid); - if (ret < 0) + if ((ret =3D virPidFileRead(driver->pidDir, def->name, &dnsmasqPid)) <= 0) goto cleanup; + virNetworkObjPrivateSetDnsmasqPid(obj, dnsmasqPid); =20 ret =3D 0; cleanup: @@ -1635,43 +1680,39 @@ networkStartDhcpDaemon(virNetworkDriverStatePtr dri= ver, */ static int networkRefreshDhcpDaemon(virNetworkDriverStatePtr driver, - virNetworkObjPtr network) + virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + pid_t dnsmasqPid =3D virNetworkObjPrivateGetDnsmasqPid(obj); int ret =3D -1; size_t i; virNetworkIPDefPtr ipdef, ipv4def, ipv6def; dnsmasqContext *dctx =3D NULL; =20 /* if no IP addresses specified, nothing to do */ - if (!virNetworkDefGetIPByIndex(network->def, AF_UNSPEC, 0)) + if (!virNetworkDefGetIPByIndex(def, AF_UNSPEC, 0)) return 0; =20 /* if there's no running dnsmasq, just start it */ - if (network->dnsmasqPid <=3D 0 || (kill(network->dnsmasqPid, 0) < 0)) - return networkStartDhcpDaemon(driver, network); + if (dnsmasqPid <=3D 0 || (kill(dnsmasqPid, 0) < 0)) + return networkStartDhcpDaemon(driver, obj); =20 - VIR_INFO("Refreshing dnsmasq for network %s", network->def->bridge); - if (!(dctx =3D dnsmasqContextNew(network->def->name, - driver->dnsmasqStateDir))) { + VIR_INFO("Refreshing dnsmasq for network %s", def->bridge); + if (!(dctx =3D dnsmasqContextNew(def->name, driver->dnsmasqStateDir))) goto cleanup; - } =20 /* Look for first IPv4 address that has dhcp defined. * We only support dhcp-host config on one IPv4 subnetwork * and on one IPv6 subnetwork. */ ipv4def =3D NULL; - for (i =3D 0; - (ipdef =3D virNetworkDefGetIPByIndex(network->def, AF_INET, i)); - i++) { + for (i =3D 0; (ipdef =3D virNetworkDefGetIPByIndex(def, AF_INET, i)); = i++) { if (!ipv4def && (ipdef->nranges || ipdef->nhosts)) ipv4def =3D ipdef; } =20 ipv6def =3D NULL; - for (i =3D 0; - (ipdef =3D virNetworkDefGetIPByIndex(network->def, AF_INET6, i)); - i++) { + for (i =3D 0; (ipdef =3D virNetworkDefGetIPByIndex(def, AF_INET6, i));= i++) { if (!ipv6def && (ipdef->nranges || ipdef->nhosts)) ipv6def =3D ipdef; } @@ -1682,18 +1723,19 @@ networkRefreshDhcpDaemon(virNetworkDriverStatePtr d= river, if (ipv6def && (networkBuildDnsmasqDhcpHostsList(dctx, ipv6def) < 0)) goto cleanup; =20 - if (networkBuildDnsmasqHostsList(dctx, &network->def->dns) < 0) + if (networkBuildDnsmasqHostsList(dctx, &def->dns) < 0) goto cleanup; =20 if ((ret =3D dnsmasqSave(dctx)) < 0) goto cleanup; =20 - ret =3D kill(network->dnsmasqPid, SIGHUP); + ret =3D kill(dnsmasqPid, SIGHUP); cleanup: dnsmasqContextFree(dctx); return ret; } =20 + /* networkRestartDhcpDaemon: * * kill and restart dnsmasq, in order to update any config that is on @@ -1703,16 +1745,18 @@ networkRefreshDhcpDaemon(virNetworkDriverStatePtr d= river, */ static int networkRestartDhcpDaemon(virNetworkDriverStatePtr driver, - virNetworkObjPtr network) + virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + pid_t dnsmasqPid =3D virNetworkObjPrivateGetDnsmasqPid(obj); + /* if there is a running dnsmasq, kill it */ - if (network->dnsmasqPid > 0) { - networkKillDaemon(network->dnsmasqPid, "dnsmasq", - network->def->name); - network->dnsmasqPid =3D -1; + if (dnsmasqPid > 0) { + networkKillDaemon(dnsmasqPid, "dnsmasq", def->name); + virNetworkObjPrivateSetDnsmasqPid(obj, -1); } /* now start dnsmasq if it should be started */ - return networkStartDhcpDaemon(driver, network); + return networkStartDhcpDaemon(driver, obj); } =20 static char radvd1[] =3D " AdvOtherConfigFlag off;\n\n"; @@ -1722,8 +1766,9 @@ static char radvd3[] =3D " AdvOnLink on;\n" " AdvRouterAddr off;\n"; =20 static int -networkRadvdConfContents(virNetworkObjPtr network, char **configstr) +networkRadvdConfContents(virPoolObjPtr obj, char **configstr) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); virBuffer configbuf =3D VIR_BUFFER_INITIALIZER; int ret =3D -1; size_t i; @@ -1733,9 +1778,7 @@ networkRadvdConfContents(virNetworkObjPtr network, ch= ar **configstr) *configstr =3D NULL; =20 /* Check if DHCPv6 is needed */ - for (i =3D 0; - (ipdef =3D virNetworkDefGetIPByIndex(network->def, AF_INET6, i)); - i++) { + for (i =3D 0; (ipdef =3D virNetworkDefGetIPByIndex(def, AF_INET6, i));= i++) { v6present =3D true; if (ipdef->nranges || ipdef->nhosts) { dhcp6 =3D true; @@ -1758,22 +1801,19 @@ networkRadvdConfContents(virNetworkObjPtr network, = char **configstr) " IgnoreIfMissing on;\n" " AdvManagedFlag %s;\n" "%s", - network->def->bridge, + def->bridge, dhcp6 ? "on" : "off", dhcp6 ? "\n" : radvd1); =20 /* add a section for each IPv6 address in the config */ - for (i =3D 0; - (ipdef =3D virNetworkDefGetIPByIndex(network->def, AF_INET6, i)); - i++) { + for (i =3D 0; (ipdef =3D virNetworkDefGetIPByIndex(def, AF_INET6, i));= i++) { int prefix; char *netaddr; =20 - prefix =3D virNetworkIPDefPrefix(ipdef); - if (prefix < 0) { + if ((prefix =3D virNetworkIPDefPrefix(ipdef)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("bridge '%s' has an invalid prefix"), - network->def->bridge); + def->bridge); goto cleanup; } if (!(netaddr =3D virSocketAddrFormat(&ipdef->address))) @@ -1799,12 +1839,14 @@ networkRadvdConfContents(virNetworkObjPtr network, = char **configstr) return ret; } =20 + /* write file and return its name (which must be freed by caller) */ static int networkRadvdConfWrite(virNetworkDriverStatePtr driver, - virNetworkObjPtr network, + virPoolObjPtr obj, char **configFile) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); int ret =3D -1; char *configStr =3D NULL; char *myConfigFile =3D NULL; @@ -1814,7 +1856,7 @@ networkRadvdConfWrite(virNetworkDriverStatePtr driver, =20 *configFile =3D NULL; =20 - if (networkRadvdConfContents(network, &configStr) < 0) + if (networkRadvdConfContents(obj, &configStr) < 0) goto cleanup; =20 if (!configStr) { @@ -1823,8 +1865,9 @@ networkRadvdConfWrite(virNetworkDriverStatePtr driver, } =20 /* construct the filename */ - if (!(*configFile =3D networkRadvdConfigFileName(driver, network->def-= >name))) + if (!(*configFile =3D networkRadvdConfigFileName(driver, def->name))) goto cleanup; + /* write the file */ if (virFileWriteStr(*configFile, configStr, 0600) < 0) { virReportSystemError(errno, @@ -1840,18 +1883,21 @@ networkRadvdConfWrite(virNetworkDriverStatePtr driv= er, return ret; } =20 + static int networkStartRadvd(virNetworkDriverStatePtr driver, - virNetworkObjPtr network) + virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); dnsmasqCapsPtr dnsmasq_caps =3D networkGetDnsmasqCaps(driver); char *pidfile =3D NULL; char *radvdpidbase =3D NULL; char *configfile =3D NULL; virCommandPtr cmd =3D NULL; + pid_t radvdPid =3D -1; int ret =3D -1; =20 - network->radvdPid =3D -1; + virNetworkObjPrivateSetRadvdPid(obj, -1); =20 /* Is dnsmasq handling RA? */ if (DNSMASQ_RA_SUPPORT(dnsmasq_caps)) { @@ -1859,7 +1905,7 @@ networkStartRadvd(virNetworkDriverStatePtr driver, goto cleanup; } =20 - if (!virNetworkDefGetIPByIndex(network->def, AF_INET6, 0)) { + if (!virNetworkDefGetIPByIndex(def, AF_INET6, 0)) { /* no IPv6 addresses, so we don't need to run radvd */ ret =3D 0; goto cleanup; @@ -1887,12 +1933,13 @@ networkStartRadvd(virNetworkDriverStatePtr driver, } =20 /* construct pidfile name */ - if (!(radvdpidbase =3D networkRadvdPidfileBasename(network->def->name)= )) + if (!(radvdpidbase =3D networkRadvdPidfileBasename(def->name))) goto cleanup; + if (!(pidfile =3D virPidFileBuildPath(driver->pidDir, radvdpidbase))) goto cleanup; =20 - if (networkRadvdConfWrite(driver, network, &configfile) < 0) + if (networkRadvdConfWrite(driver, obj, &configfile) < 0) goto cleanup; =20 /* prevent radvd from daemonizing itself with "--debug 1", and use @@ -1915,8 +1962,9 @@ networkStartRadvd(virNetworkDriverStatePtr driver, if (virCommandRun(cmd, NULL) < 0) goto cleanup; =20 - if (virPidFileRead(driver->pidDir, radvdpidbase, &network->radvdPid) <= 0) + if (virPidFileRead(driver->pidDir, radvdpidbase, &radvdPid) < 0) goto cleanup; + virNetworkObjPrivateSetRadvdPid(obj, radvdPid); =20 ret =3D 0; cleanup: @@ -1928,96 +1976,97 @@ networkStartRadvd(virNetworkDriverStatePtr driver, return ret; } =20 + static int networkRefreshRadvd(virNetworkDriverStatePtr driver, - virNetworkObjPtr network) + virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + pid_t radvdPid =3D virNetworkObjPrivateGetRadvdPid(obj); dnsmasqCapsPtr dnsmasq_caps =3D networkGetDnsmasqCaps(driver); char *radvdpidbase; =20 /* Is dnsmasq handling RA? */ if (DNSMASQ_RA_SUPPORT(dnsmasq_caps)) { virObjectUnref(dnsmasq_caps); - if (network->radvdPid <=3D 0) + if (radvdPid <=3D 0) return 0; /* radvd should not be running but in case it is */ - if ((networkKillDaemon(network->radvdPid, "radvd", - network->def->name) >=3D 0) && - ((radvdpidbase =3D networkRadvdPidfileBasename(network->def->n= ame)) - !=3D NULL)) { + if ((networkKillDaemon(radvdPid, "radvd", def->name) >=3D 0) && + ((radvdpidbase =3D networkRadvdPidfileBasename(def->name)))) { virPidFileDelete(driver->pidDir, radvdpidbase); VIR_FREE(radvdpidbase); } - network->radvdPid =3D -1; + virNetworkObjPrivateSetRadvdPid(obj, -1); return 0; } virObjectUnref(dnsmasq_caps); =20 /* if there's no running radvd, just start it */ - if (network->radvdPid <=3D 0 || (kill(network->radvdPid, 0) < 0)) - return networkStartRadvd(driver, network); + if (radvdPid <=3D 0 || (kill(radvdPid, 0) < 0)) + return networkStartRadvd(driver, obj); =20 - if (!virNetworkDefGetIPByIndex(network->def, AF_INET6, 0)) { + if (!virNetworkDefGetIPByIndex(def, AF_INET6, 0)) { /* no IPv6 addresses, so we don't need to run radvd */ return 0; } =20 - if (networkRadvdConfWrite(driver, network, NULL) < 0) + if (networkRadvdConfWrite(driver, obj, NULL) < 0) return -1; =20 - return kill(network->radvdPid, SIGHUP); + return kill(radvdPid, SIGHUP); } =20 #if 0 /* currently unused, so it causes a build error unless we #if it out */ static int -networkRestartRadvd(virNetworkObjPtr network) +networkRestartRadvd(virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + radvdPid =3D virNetworkObjPrivateGetRadvdPid(obj); char *radvdpidbase; =20 /* if there is a running radvd, kill it */ - if (network->radvdPid > 0) { + if (radvdPid > 0) { /* essentially ignore errors from the following two functions, * since there's really no better recovery to be done than to * just push ahead (and that may be exactly what's needed). */ - if ((networkKillDaemon(network->radvdPid, "radvd", - network->def->name) >=3D 0) && - ((radvdpidbase =3D networkRadvdPidfileBasename(network->def->n= ame)) - !=3D NULL)) { + if ((networkKillDaemon(radvdPid, "radvd", def->name) >=3D 0) && + ((radvdpidbase =3D networkRadvdPidfileBasename(def->name)))) { virPidFileDelete(driver->pidDir, radvdpidbase); VIR_FREE(radvdpidbase); } - network->radvdPid =3D -1; + virNetworkObjPrivateSetRadvdPid(obj, -1); } /* now start radvd if it should be started */ - return networkStartRadvd(network); + return networkStartRadvd(obj); } #endif /* #if 0 */ =20 -static int -networkRefreshDaemonsHelper(virNetworkObjPtr net, + +/* Enter with locked virPoolObjPtr */ +static void +networkRefreshDaemonsHelper(virPoolObjPtr obj, void *opaque) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); virNetworkDriverStatePtr driver =3D opaque; =20 - virObjectLock(net); - if (virNetworkObjIsActive(net) && - ((net->def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE) || - (net->def->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT) || - (net->def->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE) || - (net->def->forward.type =3D=3D VIR_NETWORK_FORWARD_OPEN))) { + if (virPoolObjIsActive(obj) && + ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_OPEN))) { /* Only the three L3 network types that are configured by * libvirt will have a dnsmasq or radvd daemon associated * with them. Here we send a SIGHUP to an existing * dnsmasq and/or radvd, or restart them if they've * disappeared. */ - networkRefreshDhcpDaemon(driver, net); - networkRefreshRadvd(driver, net); + networkRefreshDhcpDaemon(driver, obj); + networkRefreshRadvd(driver, obj); } - virObjectUnlock(net); - return 0; } =20 /* SIGHUP/restart any dnsmasq or radvd daemons. @@ -2027,44 +2076,46 @@ static void networkRefreshDaemons(virNetworkDriverStatePtr driver) { VIR_INFO("Refreshing network daemons"); - virNetworkObjListForEach(driver->networks, - networkRefreshDaemonsHelper, - driver); + virPoolObjTableIterate(driver->networks, + networkRefreshDaemonsHelper, + driver); } =20 -static int -networkReloadFirewallRulesHelper(virNetworkObjPtr net, + +/* Enter with locked virPoolObjPtr */ +static void +networkReloadFirewallRulesHelper(virPoolObjPtr obj, void *opaque ATTRIBUTE_UNUSED) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); =20 - virObjectLock(net); - if (virNetworkObjIsActive(net) && - ((net->def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE) || - (net->def->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT) || - (net->def->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE))) { + if (virPoolObjIsActive(obj) && + ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE))) { /* Only three of the L3 network types that are configured by * libvirt need to have iptables rules reloaded. The 4th L3 * network type, forward=3D'open', doesn't need this because it * has no iptables rules. */ - networkRemoveFirewallRules(net->def); - if (networkAddFirewallRules(net->def) < 0) { + networkRemoveFirewallRules(def); + if (networkAddFirewallRules(def) < 0) { /* failed to add but already logged */ } } - virObjectUnlock(net); - return 0; } =20 + static void networkReloadFirewallRules(virNetworkDriverStatePtr driver) { VIR_INFO("Reloading iptables rules"); - virNetworkObjListForEach(driver->networks, - networkReloadFirewallRulesHelper, - NULL); + virPoolObjTableIterate(driver->networks, + networkReloadFirewallRulesHelper, + NULL); } =20 + /* Enable IP Forwarding. Return 0 for success, -1 for failure. */ static int networkEnableIPForwarding(bool enableIPv4, bool enableIPv6) @@ -2089,25 +2140,27 @@ networkEnableIPForwarding(bool enableIPv4, bool ena= bleIPv6) =20 #define SYSCTL_PATH "/proc/sys" =20 + static int -networkSetIPv6Sysctls(virNetworkObjPtr network) +networkSetIPv6Sysctls(virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); char *field =3D NULL; int ret =3D -1; - bool enableIPv6 =3D !!virNetworkDefGetIPByIndex(network->def, AF_INET= 6, 0); + bool enableIPv6 =3D !!virNetworkDefGetIPByIndex(def, AF_INET6, 0); =20 /* set disable_ipv6 if there are no ipv6 addresses defined for the * network. But also unset it if there *are* ipv6 addresses, as we * can't be sure of its default value. */ if (virAsprintf(&field, SYSCTL_PATH "/net/ipv6/conf/%s/disable_ipv6", - network->def->bridge) < 0) + def->bridge) < 0) goto cleanup; =20 if (access(field, W_OK) < 0 && errno =3D=3D ENOENT) { if (!enableIPv6) VIR_DEBUG("ipv6 appears to already be disabled on %s", - network->def->bridge); + def->bridge); ret =3D 0; goto cleanup; } @@ -2115,7 +2168,7 @@ networkSetIPv6Sysctls(virNetworkObjPtr network) if (virFileWriteStr(field, enableIPv6 ? "0" : "1", 0) < 0) { virReportSystemError(errno, _("cannot write to %s to enable/disable IPv6 " - "on bridge %s"), field, network->def->bridg= e); + "on bridge %s"), field, def->bridge); goto cleanup; } VIR_FREE(field); @@ -2128,7 +2181,7 @@ networkSetIPv6Sysctls(virNetworkObjPtr network) * their own router advertisements. */ if (virAsprintf(&field, SYSCTL_PATH "/net/ipv6/conf/%s/accept_ra", - network->def->bridge) < 0) + def->bridge) < 0) goto cleanup; =20 if (virFileWriteStr(field, "0", 0) < 0) { @@ -2142,7 +2195,7 @@ networkSetIPv6Sysctls(virNetworkObjPtr network) * definition), must always have autoconf=3D0. */ if (virAsprintf(&field, SYSCTL_PATH "/net/ipv6/conf/%s/autoconf", - network->def->bridge) < 0) + def->bridge) < 0) goto cleanup; =20 if (virFileWriteStr(field, "0", 0) < 0) { @@ -2157,22 +2210,23 @@ networkSetIPv6Sysctls(virNetworkObjPtr network) return ret; } =20 + /* add an IP address to a bridge */ static int -networkAddAddrToBridge(virNetworkObjPtr network, +networkAddAddrToBridge(virPoolObjPtr obj, virNetworkIPDefPtr ipdef) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); int prefix =3D virNetworkIPDefPrefix(ipdef); =20 if (prefix < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("bridge '%s' has an invalid netmask or IP address= "), - network->def->bridge); + def->bridge); return -1; } =20 - if (virNetDevIPAddrAdd(network->def->bridge, - &ipdef->address, NULL, prefix) < 0) + if (virNetDevIPAddrAdd(def->bridge, &ipdef->address, NULL, prefix) < 0) return -1; =20 return 0; @@ -2180,14 +2234,14 @@ networkAddAddrToBridge(virNetworkObjPtr network, =20 =20 static int -networkStartHandleMACTableManagerMode(virNetworkObjPtr network, +networkStartHandleMACTableManagerMode(virPoolObjPtr obj, const char *macTapIfName) { - const char *brname =3D network->def->bridge; + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + const char *brname =3D def->bridge; =20 if (brname && - network->def->macTableManager - =3D=3D VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LIBVIRT) { + def->macTableManager =3D=3D VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_L= IBVIRT) { if (virNetDevBridgeSetVlanFiltering(brname, true) < 0) return -1; if (macTapIfName) { @@ -2203,9 +2257,10 @@ networkStartHandleMACTableManagerMode(virNetworkObjP= tr network, =20 /* add an IP (static) route to a bridge */ static int -networkAddRouteToBridge(virNetworkObjPtr network, +networkAddRouteToBridge(virPoolObjPtr obj, virNetDevIPRoutePtr routedef) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); int prefix =3D virNetDevIPRouteGetPrefix(routedef); unsigned int metric =3D virNetDevIPRouteGetMetric(routedef); virSocketAddrPtr addr =3D virNetDevIPRouteGetAddress(routedef); @@ -2215,29 +2270,25 @@ networkAddRouteToBridge(virNetworkObjPtr network, virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' has an invalid netmask " "or IP address in route definition"), - network->def->name); + def->name); return -1; } =20 - if (virNetDevIPRouteAdd(network->def->bridge, addr, - prefix, gateway, metric) < 0) { - return -1; - } - return 0; + return virNetDevIPRouteAdd(def->bridge, addr, prefix, gateway, metric); } =20 static int -networkWaitDadFinish(virNetworkObjPtr network) +networkWaitDadFinish(virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); virNetworkIPDefPtr ipdef; virSocketAddrPtr *addrs =3D NULL, addr =3D NULL; size_t naddrs =3D 0; int ret =3D -1; =20 - VIR_DEBUG("Begin waiting for IPv6 DAD on network %s", network->def->na= me); + VIR_DEBUG("Begin waiting for IPv6 DAD on network %s", def->name); =20 - while ((ipdef =3D virNetworkDefGetIPByIndex(network->def, - AF_INET6, naddrs))) { + while ((ipdef =3D virNetworkDefGetIPByIndex(def, AF_INET6, naddrs))) { addr =3D &ipdef->address; if (VIR_APPEND_ELEMENT_COPY(addrs, naddrs, addr) < 0) goto cleanup; @@ -2248,14 +2299,18 @@ networkWaitDadFinish(virNetworkObjPtr network) cleanup: VIR_FREE(addrs); VIR_DEBUG("Finished waiting for IPv6 DAD on network %s with status %d", - network->def->name, ret); + def->name, ret); return ret; } =20 + static int networkStartNetworkVirtual(virNetworkDriverStatePtr driver, - virNetworkObjPtr network) + virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + pid_t dnsmasqPid; + virMacMapPtr macmap; size_t i; bool v4present =3D false, v6present =3D false; virErrorPtr save_err =3D NULL; @@ -2266,11 +2321,11 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr= driver, int tapfd =3D -1; =20 /* Check to see if any network IP collides with an existing route */ - if (networkCheckRouteCollision(network->def) < 0) + if (networkCheckRouteCollision(def) < 0) return -1; =20 /* Create and configure the bridge device */ - if (!network->def->bridge) { + if (!def->bridge) { /* bridge name can only be empty if the config files were * edited directly. Otherwise networkValidate() (called after * parsing the XML from networkCreateXML() and @@ -2281,27 +2336,26 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr= driver, */ virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' has no bridge name defined"), - network->def->name); + def->name); return -1; } - if (virNetDevBridgeCreate(network->def->bridge) < 0) + if (virNetDevBridgeCreate(def->bridge) < 0) return -1; =20 - if (network->def->mac_specified) { + if (def->mac_specified) { /* To set a mac for the bridge, we need to define a dummy tap * device, set its mac, then attach it to the bridge. As long * as its mac address is lower than any other interface that * gets attached, the bridge will always maintain this mac * address. */ - macTapIfName =3D networkBridgeDummyNicName(network->def->bridge); - if (!macTapIfName) + if (!(macTapIfName =3D networkBridgeDummyNicName(def->bridge))) goto err0; /* Keep tun fd open and interface up to allow for IPv6 DAD to happ= en */ - if (virNetDevTapCreateInBridgePort(network->def->bridge, - &macTapIfName, &network->def->m= ac, + if (virNetDevTapCreateInBridgePort(def->bridge, + &macTapIfName, &def->mac, NULL, NULL, &tapfd, 1, NULL, NU= LL, - network->def->mtu, NULL, + def->mtu, NULL, VIR_NETDEV_TAP_CREATE_USE_MAC_F= OR_BRIDGE | VIR_NETDEV_TAP_CREATE_IFUP | VIR_NETDEV_TAP_CREATE_PERSIST) = < 0) { @@ -2310,65 +2364,62 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr= driver, } } =20 - if (!(macMapFile =3D networkMacMgrFileName(driver, network->def->bridg= e)) || - !(network->macmap =3D virMacMapNew(macMapFile))) + if (!(macMapFile =3D networkMacMgrFileName(driver, def->bridge)) || + !(macmap =3D virMacMapNew(macMapFile))) goto err1; + virNetworkObjPrivateSetMacMap(obj, macmap); =20 /* Set bridge options */ =20 /* delay is configured in seconds, but virNetDevBridgeSetSTPDelay * expects milliseconds */ - if (virNetDevBridgeSetSTPDelay(network->def->bridge, - network->def->delay * 1000) < 0) + if (virNetDevBridgeSetSTPDelay(def->bridge, def->delay * 1000) < 0) goto err1; =20 - if (virNetDevBridgeSetSTP(network->def->bridge, - network->def->stp ? true : false) < 0) + if (virNetDevBridgeSetSTP(def->bridge, def->stp ? true : false) < 0) goto err1; =20 /* Disable IPv6 on the bridge if there are no IPv6 addresses * defined, and set other IPv6 sysctl tunables appropriately. */ - if (networkSetIPv6Sysctls(network) < 0) + if (networkSetIPv6Sysctls(obj) < 0) goto err1; =20 /* Add "once per network" rules */ - if (network->def->forward.type !=3D VIR_NETWORK_FORWARD_OPEN && - networkAddFirewallRules(network->def) < 0) + if (def->forward.type !=3D VIR_NETWORK_FORWARD_OPEN && + networkAddFirewallRules(def) < 0) goto err1; =20 - for (i =3D 0; - (ipdef =3D virNetworkDefGetIPByIndex(network->def, AF_UNSPEC, i)); - i++) { + for (i =3D 0; (ipdef =3D virNetworkDefGetIPByIndex(def, AF_UNSPEC, i))= ; i++) { if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) v4present =3D true; if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) v6present =3D true; =20 /* Add the IP address/netmask to the bridge */ - if (networkAddAddrToBridge(network, ipdef) < 0) + if (networkAddAddrToBridge(obj, ipdef) < 0) goto err2; } =20 - if (networkStartHandleMACTableManagerMode(network, macTapIfName) < 0) + if (networkStartHandleMACTableManagerMode(obj, macTapIfName) < 0) goto err2; =20 /* Bring up the bridge interface */ - if (virNetDevSetOnline(network->def->bridge, 1) < 0) + if (virNetDevSetOnline(def->bridge, 1) < 0) goto err2; =20 - for (i =3D 0; i < network->def->nroutes; i++) { + for (i =3D 0; i < def->nroutes; i++) { virSocketAddrPtr gateway =3D NULL; =20 - routedef =3D network->def->routes[i]; + routedef =3D def->routes[i]; gateway =3D virNetDevIPRouteGetGateway(routedef); =20 /* Add the IP route to the bridge */ /* ignore errors, error msg will be generated */ /* but libvirt will not know and net-destroy will work. */ if (VIR_SOCKET_ADDR_VALID(gateway)) { - if (networkAddRouteToBridge(network, routedef) < 0) { + if (networkAddRouteToBridge(obj, routedef) < 0) { /* an error occurred adding the static route */ continue; /* for now, do nothing */ } @@ -2376,7 +2427,7 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr d= river, } =20 /* If forward.type !=3D NONE, turn on global IP forwarding */ - if (network->def->forward.type !=3D VIR_NETWORK_FORWARD_NONE && + if (def->forward.type !=3D VIR_NETWORK_FORWARD_NONE && networkEnableIPForwarding(v4present, v6present) < 0) { virReportSystemError(errno, "%s", _("failed to enable IP forwarding")); @@ -2386,17 +2437,17 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr= driver, =20 /* start dnsmasq if there are any IP addresses (v4 or v6) */ if ((v4present || v6present) && - networkStartDhcpDaemon(driver, network) < 0) + networkStartDhcpDaemon(driver, obj) < 0) goto err3; =20 /* start radvd if there are any ipv6 addresses */ - if (v6present && networkStartRadvd(driver, network) < 0) + if (v6present && networkStartRadvd(driver, obj) < 0) goto err4; =20 /* dnsmasq does not wait for DAD to complete before daemonizing, * so we need to wait for it ourselves. */ - if (v6present && networkWaitDadFinish(network) < 0) + if (v6present && networkWaitDadFinish(obj) < 0) goto err4; =20 /* DAD has finished, dnsmasq is now bound to the @@ -2408,8 +2459,7 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr d= river, VIR_FORCE_CLOSE(tapfd); } =20 - if (virNetDevBandwidthSet(network->def->bridge, - network->def->bandwidth, true) < 0) + if (virNetDevBandwidthSet(def->bridge, def->bandwidth, true) < 0) goto err5; =20 VIR_FREE(macTapIfName); @@ -2418,28 +2468,28 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr= driver, return 0; =20 err5: - if (network->def->bandwidth) - virNetDevBandwidthClear(network->def->bridge); + if (def->bandwidth) + virNetDevBandwidthClear(def->bridge); =20 err4: if (!save_err) save_err =3D virSaveLastError(); =20 - if (network->dnsmasqPid > 0) { - kill(network->dnsmasqPid, SIGTERM); - network->dnsmasqPid =3D -1; + if ((dnsmasqPid =3D virNetworkObjPrivateGetDnsmasqPid(obj)) > 0) { + kill(dnsmasqPid, SIGTERM); + virNetworkObjPrivateSetDnsmasqPid(obj, -1); } =20 err3: if (!save_err) save_err =3D virSaveLastError(); - ignore_value(virNetDevSetOnline(network->def->bridge, 0)); + ignore_value(virNetDevSetOnline(def->bridge, 0)); =20 err2: if (!save_err) save_err =3D virSaveLastError(); - if (network->def->forward.type !=3D VIR_NETWORK_FORWARD_OPEN) - networkRemoveFirewallRules(network->def); + if (def->forward.type !=3D VIR_NETWORK_FORWARD_OPEN) + networkRemoveFirewallRules(def); =20 err1: if (!save_err) @@ -2455,7 +2505,7 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr d= river, err0: if (!save_err) save_err =3D virSaveLastError(); - ignore_value(virNetDevBridgeDelete(network->def->bridge)); + ignore_value(virNetDevBridgeDelete(def->bridge)); =20 if (save_err) { virSetError(save_err); @@ -2465,71 +2515,77 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr= driver, return -1; } =20 + static int networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver, - virNetworkObjPtr network) + virPoolObjPtr obj) { - if (network->def->bandwidth) - virNetDevBandwidthClear(network->def->bridge); + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + pid_t radvdPid =3D virNetworkObjPrivateGetRadvdPid(obj); + pid_t dnsmasqPid =3D virNetworkObjPrivateGetDnsmasqPid(obj); + virMacMapPtr macmap =3D virNetworkObjPrivateGetMacMap(obj); + + if (def->bandwidth) + virNetDevBandwidthClear(def->bridge); =20 - virObjectUnref(network->macmap); + virObjectUnref(macmap); + virNetworkObjPrivateSetMacMap(obj, NULL); =20 - if (network->radvdPid > 0) { + if (radvdPid > 0) { char *radvdpidbase; =20 - kill(network->radvdPid, SIGTERM); + kill(radvdPid, SIGTERM); /* attempt to delete the pidfile we created */ - if ((radvdpidbase =3D networkRadvdPidfileBasename(network->def->na= me))) { + if ((radvdpidbase =3D networkRadvdPidfileBasename(def->name))) { virPidFileDelete(driver->pidDir, radvdpidbase); VIR_FREE(radvdpidbase); } } =20 - if (network->dnsmasqPid > 0) - kill(network->dnsmasqPid, SIGTERM); + if (dnsmasqPid > 0) + kill(dnsmasqPid, SIGTERM); =20 - if (network->def->mac_specified) { - char *macTapIfName =3D networkBridgeDummyNicName(network->def->bri= dge); + if (def->mac_specified) { + char *macTapIfName =3D networkBridgeDummyNicName(def->bridge); if (macTapIfName) { ignore_value(virNetDevTapDelete(macTapIfName, NULL)); VIR_FREE(macTapIfName); } } =20 - ignore_value(virNetDevSetOnline(network->def->bridge, 0)); + ignore_value(virNetDevSetOnline(def->bridge, 0)); =20 - if (network->def->forward.type !=3D VIR_NETWORK_FORWARD_OPEN) - networkRemoveFirewallRules(network->def); + if (def->forward.type !=3D VIR_NETWORK_FORWARD_OPEN) + networkRemoveFirewallRules(def); =20 - ignore_value(virNetDevBridgeDelete(network->def->bridge)); + ignore_value(virNetDevBridgeDelete(def->bridge)); =20 /* See if its still alive and really really kill it */ - if (network->dnsmasqPid > 0 && - (kill(network->dnsmasqPid, 0) =3D=3D 0)) - kill(network->dnsmasqPid, SIGKILL); - network->dnsmasqPid =3D -1; + if (dnsmasqPid > 0 && (kill(dnsmasqPid, 0) =3D=3D 0)) + kill(dnsmasqPid, SIGKILL); + virNetworkObjPrivateSetDnsmasqPid(obj, -1); =20 - if (network->radvdPid > 0 && - (kill(network->radvdPid, 0) =3D=3D 0)) - kill(network->radvdPid, SIGKILL); - network->radvdPid =3D -1; + if (radvdPid > 0 && (kill(radvdPid, 0) =3D=3D 0)) + kill(radvdPid, SIGKILL); + virNetworkObjPrivateSetRadvdPid(obj, -1); =20 return 0; } =20 =20 static int -networkStartNetworkBridge(virNetworkObjPtr network) +networkStartNetworkBridge(virPoolObjPtr obj) { /* put anything here that needs to be done each time a network of * type BRIDGE, is started. On failure, undo anything you've done, * and return -1. On success return 0. */ - return networkStartHandleMACTableManagerMode(network, NULL); + return networkStartHandleMACTableManagerMode(obj, NULL); } =20 + static int -networkShutdownNetworkBridge(virNetworkObjPtr network ATTRIBUTE_UNUSED) +networkShutdownNetworkBridge(virPoolObjPtr obj ATTRIBUTE_UNUSED) { /* put anything here that needs to be done each time a network of * type BRIDGE is shutdown. On failure, undo anything you've done, @@ -2648,17 +2704,21 @@ networkCreateInterfacePool(virNetworkDefPtr netdef) =20 =20 static int -networkStartNetworkExternal(virNetworkObjPtr network) +networkStartNetworkExternal(virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); + /* put anything here that needs to be done each time a network of * type BRIDGE, PRIVATE, VEPA, HOSTDEV or PASSTHROUGH is started. On * failure, undo anything you've done, and return -1. On success * return 0. */ - return networkCreateInterfacePool(network->def); + return networkCreateInterfacePool(def); } =20 -static int networkShutdownNetworkExternal(virNetworkObjPtr network ATTRIBU= TE_UNUSED) + +static int +networkShutdownNetworkExternal(virPoolObjPtr obj ATTRIBUTE_UNUSED) { /* put anything here that needs to be done each time a network of * type BRIDGE, PRIVATE, VEPA, HOSTDEV or PASSTHROUGH is shutdown. On @@ -2668,15 +2728,17 @@ static int networkShutdownNetworkExternal(virNetwor= kObjPtr network ATTRIBUTE_UNU return 0; } =20 + static int networkStartNetwork(virNetworkDriverStatePtr driver, - virNetworkObjPtr network) + virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); int ret =3D -1; =20 - VIR_DEBUG("driver=3D%p, network=3D%p", driver, network); + VIR_DEBUG("driver=3D%p, network=3D%p", driver, obj); =20 - if (virNetworkObjIsActive(network)) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("network is already active")); return ret; @@ -2685,29 +2747,29 @@ networkStartNetwork(virNetworkDriverStatePtr driver, VIR_DEBUG("Beginning network startup process"); =20 VIR_DEBUG("Setting current network def as transient"); - if (virNetworkObjSetDefTransient(network, true) < 0) + if (virNetworkObjSetDefTransient(obj, true) < 0) goto cleanup; =20 /* Run an early hook to set-up missing devices. * If the script raised an error abort the launch. */ - if (networkRunHook(network, NULL, NULL, + if (networkRunHook(obj, NULL, NULL, VIR_HOOK_NETWORK_OP_START, VIR_HOOK_SUBOP_BEGIN) < 0) goto cleanup; =20 - switch (network->def->forward.type) { + switch (def->forward.type) { =20 case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: - if (networkStartNetworkVirtual(driver, network) < 0) + if (networkStartNetworkVirtual(driver, obj) < 0) goto cleanup; break; =20 case VIR_NETWORK_FORWARD_BRIDGE: - if (network->def->bridge) { - if (networkStartNetworkBridge(network) < 0) + if (def->bridge) { + if (networkStartNetworkBridge(obj) < 0) goto cleanup; break; } @@ -2719,13 +2781,13 @@ networkStartNetwork(virNetworkDriverStatePtr driver, case VIR_NETWORK_FORWARD_VEPA: case VIR_NETWORK_FORWARD_PASSTHROUGH: case VIR_NETWORK_FORWARD_HOSTDEV: - if (networkStartNetworkExternal(network) < 0) + if (networkStartNetworkExternal(obj) < 0) goto cleanup; break; } =20 /* finally we can call the 'started' hook script if any */ - if (networkRunHook(network, NULL, NULL, + if (networkRunHook(obj, NULL, NULL, VIR_HOOK_NETWORK_OP_STARTED, VIR_HOOK_SUBOP_BEGIN) < 0) goto cleanup; @@ -2734,19 +2796,19 @@ networkStartNetwork(virNetworkDriverStatePtr driver, * is setup. */ VIR_DEBUG("Writing network status to disk"); - if (virNetworkSaveStatus(driver->stateDir, network) < 0) + if (virNetworkObjSaveStatus(driver->stateDir, obj) < 0) goto cleanup; =20 - network->active =3D 1; - VIR_INFO("Network '%s' started up", network->def->name); + virPoolObjSetActive(obj, true); + VIR_INFO("Network '%s' started up", def->name); ret =3D 0; =20 cleanup: if (ret < 0) { - virNetworkObjUnsetDefTransient(network); + virNetworkObjUnsetDefTransient(obj); virErrorPtr save_err =3D virSaveLastError(); int save_errno =3D errno; - networkShutdownNetwork(driver, network); + networkShutdownNetwork(driver, obj); virSetError(save_err); virFreeError(save_err); errno =3D save_errno; @@ -2754,38 +2816,38 @@ networkStartNetwork(virNetworkDriverStatePtr driver, return ret; } =20 + static int networkShutdownNetwork(virNetworkDriverStatePtr driver, - virNetworkObjPtr network) + virPoolObjPtr obj) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); int ret =3D 0; char *stateFile; =20 - VIR_INFO("Shutting down network '%s'", network->def->name); + VIR_INFO("Shutting down network '%s'", def->name); =20 - if (!virNetworkObjIsActive(network)) + if (!virPoolObjIsActive(obj)) return 0; =20 - stateFile =3D virNetworkConfigFile(driver->stateDir, - network->def->name); - if (!stateFile) + if (!(stateFile =3D virNetworkConfigFile(driver->stateDir, def->name))) return -1; =20 unlink(stateFile); VIR_FREE(stateFile); =20 - switch (network->def->forward.type) { + switch (def->forward.type) { =20 case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: - ret =3D networkShutdownNetworkVirtual(driver, network); + ret =3D networkShutdownNetworkVirtual(driver, obj); break; =20 case VIR_NETWORK_FORWARD_BRIDGE: - if (network->def->bridge) { - ret =3D networkShutdownNetworkBridge(network); + if (def->bridge) { + ret =3D networkShutdownNetworkBridge(obj); break; } /* intentionally fall through to the macvtap/direct case for @@ -2796,157 +2858,141 @@ networkShutdownNetwork(virNetworkDriverStatePtr d= river, case VIR_NETWORK_FORWARD_VEPA: case VIR_NETWORK_FORWARD_PASSTHROUGH: case VIR_NETWORK_FORWARD_HOSTDEV: - ret =3D networkShutdownNetworkExternal(network); + ret =3D networkShutdownNetworkExternal(obj); break; } =20 /* now that we know it's stopped call the hook if present */ - networkRunHook(network, NULL, NULL, VIR_HOOK_NETWORK_OP_STOPPED, + networkRunHook(obj, NULL, NULL, VIR_HOOK_NETWORK_OP_STOPPED, VIR_HOOK_SUBOP_END); =20 - network->active =3D 0; - virNetworkObjUnsetDefTransient(network); + virPoolObjSetActive(obj, false); + virNetworkObjUnsetDefTransient(obj); return ret; } =20 =20 -static virNetworkPtr networkLookupByUUID(virConnectPtr conn, - const unsigned char *uuid) +static virNetworkPtr +networkLookupByUUID(virConnectPtr conn, + const unsigned char *uuid) { - virNetworkDriverStatePtr driver =3D networkGetDriver(); - virNetworkObjPtr network; + virPoolObjPtr obj; + virNetworkDefPtr def; virNetworkPtr ret =3D NULL; =20 - network =3D virNetworkObjFindByUUID(driver->networks, uuid); - if (!network) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(uuid, uuidstr); - virReportError(VIR_ERR_NO_NETWORK, - _("no network with matching uuid '%s'"), - uuidstr); - goto cleanup; - } + if (!(obj =3D networkObjFindByUUID(uuid, NULL))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkLookupByUUIDEnsureACL(conn, network->def) < 0) + if (virNetworkLookupByUUIDEnsureACL(conn, def) < 0) goto cleanup; =20 - ret =3D virGetNetwork(conn, network->def->name, network->def->uuid); + ret =3D virGetNetwork(conn, def->name, def->uuid); =20 cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 -static virNetworkPtr networkLookupByName(virConnectPtr conn, - const char *name) + +static virNetworkPtr +networkLookupByName(virConnectPtr conn, + const char *name) { - virNetworkDriverStatePtr driver =3D networkGetDriver(); - virNetworkObjPtr network; + virPoolObjPtr obj; + virNetworkDefPtr def; virNetworkPtr ret =3D NULL; =20 - network =3D virNetworkObjFindByName(driver->networks, name); - if (!network) { - virReportError(VIR_ERR_NO_NETWORK, - _("no network with matching name '%s'"), name); - goto cleanup; - } + if (!(obj =3D networkObjFindByName(name))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkLookupByNameEnsureACL(conn, network->def) < 0) + if (virNetworkLookupByNameEnsureACL(conn, def) < 0) goto cleanup; =20 - ret =3D virGetNetwork(conn, network->def->name, network->def->uuid); + ret =3D virGetNetwork(conn, def->name, def->uuid); =20 cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 -static int networkConnectNumOfNetworks(virConnectPtr conn) + +static int +networkConnectNumOfNetworks(virConnectPtr conn) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - int nactive; =20 if (virConnectNumOfNetworksEnsureACL(conn) < 0) return -1; =20 - nactive =3D virNetworkObjListNumOfNetworks(driver->networks, - true, - virConnectNumOfNetworksCheckA= CL, - conn); - - return nactive; + return virNetworkObjNumOfNetworks(driver->networks, conn, true, + virConnectNumOfNetworksCheckACL); } =20 -static int networkConnectListNetworks(virConnectPtr conn, - char **const names, - int nnames) + +static int +networkConnectListNetworks(virConnectPtr conn, + char **const names, + int maxnames) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - int got =3D 0; =20 if (virConnectListNetworksEnsureACL(conn) < 0) return -1; =20 - got =3D virNetworkObjListGetNames(driver->networks, - true, names, nnames, - virConnectListNetworksCheckACL, - conn); - - return got; + return virNetworkObjGetNames(driver->networks, conn, true, + virConnectListNetworksCheckACL, + names, maxnames); } =20 -static int networkConnectNumOfDefinedNetworks(virConnectPtr conn) + +static int +networkConnectNumOfDefinedNetworks(virConnectPtr conn) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - int ninactive =3D 0; =20 if (virConnectNumOfDefinedNetworksEnsureACL(conn) < 0) return -1; =20 - ninactive =3D virNetworkObjListNumOfNetworks(driver->networks, - false, - virConnectNumOfDefinedNetwo= rksCheckACL, - conn); - - return ninactive; + return virNetworkObjNumOfNetworks(driver->networks, conn, false, + virConnectNumOfDefinedNetworksCheckA= CL); } =20 -static int networkConnectListDefinedNetworks(virConnectPtr conn, char **co= nst names, int nnames) + +static int +networkConnectListDefinedNetworks(virConnectPtr conn, + char **const names, + int maxnames) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - int got =3D 0; =20 if (virConnectListDefinedNetworksEnsureACL(conn) < 0) return -1; =20 - got =3D virNetworkObjListGetNames(driver->networks, - false, names, nnames, - virConnectListDefinedNetworksCheckACL, - conn); - return got; + return virNetworkObjGetNames(driver->networks, conn, false, + virConnectListDefinedNetworksCheckACL, + names, maxnames); } =20 + static int networkConnectListAllNetworks(virConnectPtr conn, virNetworkPtr **nets, unsigned int flags) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - int ret =3D -1; =20 virCheckFlags(VIR_CONNECT_LIST_NETWORKS_FILTERS_ALL, -1); =20 if (virConnectListAllNetworksEnsureACL(conn) < 0) - goto cleanup; - - ret =3D virNetworkObjListExport(conn, driver->networks, nets, - virConnectListAllNetworksCheckACL, - flags); + return -1; =20 - cleanup: - return ret; + return virNetworkObjExportList(conn, driver->networks, nets, + virConnectListAllNetworksCheckACL, flag= s); } =20 + static int networkConnectNetworkEventRegisterAny(virConnectPtr conn, virNetworkPtr net, @@ -2991,39 +3037,46 @@ networkConnectNetworkEventDeregisterAny(virConnectP= tr conn, return ret; } =20 -static int networkIsActive(virNetworkPtr net) +static int +networkIsActive(virNetworkPtr net) { - virNetworkObjPtr obj; + virPoolObjPtr obj; + virNetworkDefPtr def; int ret =3D -1; =20 if (!(obj =3D networkObjFromNetwork(net))) - return ret; + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkIsActiveEnsureACL(net->conn, obj->def) < 0) + if (virNetworkIsActiveEnsureACL(net->conn, def) < 0) goto cleanup; =20 - ret =3D virNetworkObjIsActive(obj); + ret =3D virPoolObjIsActive(obj); =20 cleanup: - virNetworkObjEndAPI(&obj); + virPoolObjEndAPI(&obj); return ret; } =20 -static int networkIsPersistent(virNetworkPtr net) + +static int +networkIsPersistent(virNetworkPtr net) { - virNetworkObjPtr obj; + virPoolObjPtr obj; + virNetworkDefPtr def; int ret =3D -1; =20 if (!(obj =3D networkObjFromNetwork(net))) - return ret; + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkIsPersistentEnsureACL(net->conn, obj->def) < 0) + if (virNetworkIsPersistentEnsureACL(net->conn, def) < 0) goto cleanup; =20 - ret =3D obj->persistent; + ret =3D virPoolObjIsPersistent(obj); =20 cleanup: - virNetworkObjEndAPI(&obj); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -3035,7 +3088,7 @@ static int networkIsPersistent(virNetworkPtr net) * than libvirt). Set this network's name to that new name. */ static int -networkFindUnusedBridgeName(virNetworkObjListPtr nets, +networkFindUnusedBridgeName(virPoolObjTablePtr netobjs, virNetworkDefPtr def) { =20 @@ -3057,9 +3110,9 @@ networkFindUnusedBridgeName(virNetworkObjListPtr nets, * from virNetDevExists(), just in case it isn't implemented * on this platform (probably impossible). */ - if (!(virNetworkBridgeInUse(nets, newname, def->name) || + if (!(virNetworkObjBridgeInUse(netobjs, newname, def->name) || virNetDevExists(newname) =3D=3D 1)) { - VIR_FREE(def->bridge); /*could contain template */ + VIR_FREE(def->bridge); /* could contain template */ def->bridge =3D newname; ret =3D 0; goto cleanup; @@ -3087,13 +3140,13 @@ networkFindUnusedBridgeName(virNetworkObjListPtr ne= ts, * network's bridge name. */ static int -networkBridgeNameValidate(virNetworkObjListPtr nets, +networkBridgeNameValidate(virPoolObjTablePtr netobjs, virNetworkDefPtr def) { int ret =3D -1; =20 if (def->bridge && !strstr(def->bridge, "%d")) { - if (virNetworkBridgeInUse(nets, def->bridge, def->name)) { + if (virNetworkObjBridgeInUse(netobjs, def->bridge, def->name)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("bridge name '%s' already in use."), def->bridge); @@ -3101,7 +3154,7 @@ networkBridgeNameValidate(virNetworkObjListPtr nets, } } else { /* Allocate a bridge name */ - if (networkFindUnusedBridgeName(nets, def) < 0) + if (networkFindUnusedBridgeName(netobjs, def) < 0) goto cleanup; } =20 @@ -3348,11 +3401,14 @@ networkValidate(virNetworkDriverStatePtr driver, return 0; } =20 -static virNetworkPtr networkCreateXML(virConnectPtr conn, const char *xml) +static virNetworkPtr +networkCreateXML(virConnectPtr conn, + const char *xml) { virNetworkDriverStatePtr driver =3D networkGetDriver(); virNetworkDefPtr def; - virNetworkObjPtr network =3D NULL; + virPoolObjPtr obj =3D NULL; + virNetworkDefPtr objdef; virNetworkPtr ret =3D NULL; virObjectEventPtr event =3D NULL; =20 @@ -3369,40 +3425,42 @@ static virNetworkPtr networkCreateXML(virConnectPtr= conn, const char *xml) * we assign the def with live =3D true in anticipation that it will * be started momentarily. */ - if (!(network =3D virNetworkAssignDef(driver->networks, def, - VIR_NETWORK_OBJ_LIST_ADD_LIVE | - VIR_NETWORK_OBJ_LIST_ADD_CHECK_LIV= E))) + if (!(obj =3D virNetworkObjAdd(driver->networks, def, + VIR_NETWORK_OBJ_LIST_ADD_LIVE | + VIR_NETWORK_OBJ_LIST_ADD_CHECK_LIVE))) goto cleanup; - def =3D NULL; + VIR_STEAL_PTR(objdef, def); =20 - if (networkStartNetwork(driver, network) < 0) { - virNetworkRemoveInactive(driver->networks, - network); + if (networkStartNetwork(driver, obj) < 0) { + virPoolObjTableRemove(driver->networks, &obj); goto cleanup; } =20 - event =3D virNetworkEventLifecycleNew(network->def->name, - network->def->uuid, + event =3D virNetworkEventLifecycleNew(objdef->name, + objdef->uuid, VIR_NETWORK_EVENT_STARTED, 0); =20 - VIR_INFO("Creating network '%s'", network->def->name); - ret =3D virGetNetwork(conn, network->def->name, network->def->uuid); + VIR_INFO("Creating network '%s'", objdef->name); + ret =3D virGetNetwork(conn, objdef->name, objdef->uuid); =20 cleanup: virNetworkDefFree(def); if (event) virObjectEventStateQueue(driver->networkEventState, event); - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 -static virNetworkPtr networkDefineXML(virConnectPtr conn, const char *xml) + +static virNetworkPtr +networkDefineXML(virConnectPtr conn, + const char *xml) { virNetworkDriverStatePtr driver =3D networkGetDriver(); virNetworkDefPtr def =3D NULL; - bool freeDef =3D true; - virNetworkObjPtr network =3D NULL; + virPoolObjPtr obj =3D NULL; + virNetworkDefPtr objdef; virNetworkPtr ret =3D NULL; virObjectEventPtr event =3D NULL; =20 @@ -3415,86 +3473,86 @@ static virNetworkPtr networkDefineXML(virConnectPtr= conn, const char *xml) if (networkValidate(driver, def) < 0) goto cleanup; =20 - if (!(network =3D virNetworkAssignDef(driver->networks, def, 0))) + if (!(obj =3D virNetworkObjAdd(driver->networks, def, 0))) goto cleanup; + VIR_STEAL_PTR(objdef, def); =20 - /* def was assigned to network object */ - freeDef =3D false; - - if (virNetworkSaveConfig(driver->networkConfigDir, def) < 0) { - if (!virNetworkObjIsActive(network)) { - virNetworkRemoveInactive(driver->networks, network); + if (virNetworkSaveConfig(driver->networkConfigDir, objdef) < 0) { + if (!virPoolObjIsActive(obj)) { + virPoolObjTableRemove(driver->networks, &obj); goto cleanup; } /* if network was active already, just undo new persistent * definition by making it transient. * XXX - this isn't necessarily the correct thing to do. */ - virNetworkObjAssignDef(network, NULL, false); + virNetworkObjAssignDef(obj, NULL); goto cleanup; } =20 - event =3D virNetworkEventLifecycleNew(def->name, def->uuid, + event =3D virNetworkEventLifecycleNew(objdef->name, objdef->uuid, VIR_NETWORK_EVENT_DEFINED, 0); =20 - VIR_INFO("Defining network '%s'", def->name); - ret =3D virGetNetwork(conn, def->name, def->uuid); + VIR_INFO("Defining network '%s'", objdef->name); + ret =3D virGetNetwork(conn, objdef->name, objdef->uuid); =20 cleanup: if (event) virObjectEventStateQueue(driver->networkEventState, event); - if (freeDef) - virNetworkDefFree(def); - virNetworkObjEndAPI(&network); + virNetworkDefFree(def); + virPoolObjEndAPI(&obj); return ret; } =20 + static int networkUndefine(virNetworkPtr net) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - virNetworkObjPtr network; + virPoolObjPtr obj; + virNetworkDefPtr def; int ret =3D -1; bool active =3D false; virObjectEventPtr event =3D NULL; =20 - if (!(network =3D networkObjFromNetwork(net))) - goto cleanup; + if (!(obj =3D networkObjFromNetwork(net))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkUndefineEnsureACL(net->conn, network->def) < 0) + if (virNetworkUndefineEnsureACL(net->conn, def) < 0) goto cleanup; =20 - if (virNetworkObjIsActive(network)) + if (virPoolObjIsActive(obj)) active =3D true; =20 - if (!network->persistent) { + if (!virPoolObjIsPersistent(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("can't undefine transient network")); goto cleanup; } =20 /* remove autostart link */ - if (virNetworkDeleteConfig(driver->networkConfigDir, - driver->networkAutostartDir, - network) < 0) + if (virNetworkObjDeleteConfig(driver->networkConfigDir, + driver->networkAutostartDir, + obj) < 0) goto cleanup; =20 - event =3D virNetworkEventLifecycleNew(network->def->name, - network->def->uuid, + event =3D virNetworkEventLifecycleNew(def->name, + def->uuid, VIR_NETWORK_EVENT_UNDEFINED, 0); =20 - VIR_INFO("Undefining network '%s'", network->def->name); + VIR_INFO("Undefining network '%s'", def->name); if (!active) { - if (networkRemoveInactive(driver, network) < 0) + if (networkRemoveInactive(driver, &obj) < 0) goto cleanup; } else { =20 /* if the network still exists, it was active, and we need to make * it transient (by deleting the persistent def) */ - virNetworkObjAssignDef(network, NULL, false); + virNetworkObjAssignDef(obj, NULL); } =20 ret =3D 0; @@ -3502,10 +3560,11 @@ networkUndefine(virNetworkPtr net) cleanup: if (event) virObjectEventStateQueue(driver->networkEventState, event); - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 + static int networkUpdate(virNetworkPtr net, unsigned int command, @@ -3515,7 +3574,8 @@ networkUpdate(virNetworkPtr net, unsigned int flags) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - virNetworkObjPtr network =3D NULL; + virPoolObjPtr obj =3D NULL; + virNetworkDefPtr def =3D virPoolObjGetDef(obj); int isActive, ret =3D -1; size_t i; virNetworkIPDefPtr ipdef; @@ -3527,16 +3587,14 @@ networkUpdate(virNetworkPtr net, VIR_NETWORK_UPDATE_AFFECT_CONFIG, -1); =20 - if (!(network =3D networkObjFromNetwork(net))) - goto cleanup; + if (!(obj =3D networkObjFromNetwork(net))) + return -1; =20 - if (virNetworkUpdateEnsureACL(net->conn, network->def, flags) < 0) + if (virNetworkUpdateEnsureACL(net->conn, def, flags) < 0) goto cleanup; =20 /* see if we are listening for dhcp pre-modification */ - for (i =3D 0; - (ipdef =3D virNetworkDefGetIPByIndex(network->def, AF_INET, i)); - i++) { + for (i =3D 0; (ipdef =3D virNetworkDefGetIPByIndex(def, AF_INET, i)); = i++) { if (ipdef->nranges || ipdef->nhosts) { oldDhcpActive =3D true; break; @@ -3546,7 +3604,7 @@ networkUpdate(virNetworkPtr net, /* VIR_NETWORK_UPDATE_AFFECT_CURRENT means "change LIVE if network * is active, else change CONFIG */ - isActive =3D virNetworkObjIsActive(network); + isActive =3D virPoolObjIsActive(obj); if ((flags & (VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG)) =3D=3D VIR_NETWORK_UPDATE_AFFECT_CURRENT) { @@ -3560,9 +3618,9 @@ networkUpdate(virNetworkPtr net, /* Take care of anything that must be done before updating the * live NetworkDef. */ - if (network->def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE || - network->def->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT || - network->def->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE) { + if (def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE || + def->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT || + def->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE) { switch (section) { case VIR_NETWORK_SECTION_FORWARD: case VIR_NETWORK_SECTION_FORWARD_INTERFACE: @@ -3573,8 +3631,8 @@ networkUpdate(virNetworkPtr net, * old rules (and remember to load new ones after the * update). */ - if (network->def->forward.type !=3D VIR_NETWORK_FORWARD_OP= EN) { - networkRemoveFirewallRules(network->def); + if (def->forward.type !=3D VIR_NETWORK_FORWARD_OPEN) { + networkRemoveFirewallRules(def); needFirewallRefresh =3D true; } break; @@ -3585,19 +3643,20 @@ networkUpdate(virNetworkPtr net, } =20 /* update the network config in memory/on disk */ - if (virNetworkObjUpdate(network, command, section, parentIndex, xml, f= lags) < 0) { + if (virNetworkObjUpdate(obj, command, section, parentIndex, + xml, flags) < 0) { if (needFirewallRefresh) - ignore_value(networkAddFirewallRules(network->def)); + ignore_value(networkAddFirewallRules(def)); goto cleanup; } =20 - if (needFirewallRefresh && networkAddFirewallRules(network->def) < 0) + if (needFirewallRefresh && networkAddFirewallRules(def) < 0) goto cleanup; =20 if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) { /* save updated persistent config to disk */ if (virNetworkSaveConfig(driver->networkConfigDir, - virNetworkObjGetPersistentDef(network)) <= 0) { + virNetworkObjGetPersistentDef(obj)) < 0) { goto cleanup; } } @@ -3620,7 +3679,7 @@ networkUpdate(virNetworkPtr net, * to "nobody" after it starts, and is unable to re-read * the conf file (owned by root, mode 600) */ - if (networkRestartDhcpDaemon(driver, network) < 0) + if (networkRestartDhcpDaemon(driver, obj) < 0) goto cleanup; =20 } else if (section =3D=3D VIR_NETWORK_SECTION_IP_DHCP_HOST) { @@ -3631,8 +3690,7 @@ networkUpdate(virNetworkPtr net, */ bool newDhcpActive =3D false; =20 - for (i =3D 0; - (ipdef =3D virNetworkDefGetIPByIndex(network->def, AF_INE= T, i)); + for (i =3D 0; (ipdef =3D virNetworkDefGetIPByIndex(def, AF_INE= T, i)); i++) { if (ipdef->nranges || ipdef->nhosts) { newDhcpActive =3D true; @@ -3641,8 +3699,8 @@ networkUpdate(virNetworkPtr net, } =20 if ((newDhcpActive !=3D oldDhcpActive && - networkRestartDhcpDaemon(driver, network) < 0) || - networkRefreshDhcpDaemon(driver, network) < 0) { + networkRestartDhcpDaemon(driver, obj) < 0) || + networkRefreshDhcpDaemon(driver, obj) < 0) { goto cleanup; } =20 @@ -3651,95 +3709,102 @@ networkUpdate(virNetworkPtr net, * (not the .conf file) so we can just update the config * files and send SIGHUP to dnsmasq. */ - if (networkRefreshDhcpDaemon(driver, network) < 0) + if (networkRefreshDhcpDaemon(driver, obj) < 0) goto cleanup; =20 } =20 if (section =3D=3D VIR_NETWORK_SECTION_IP) { - /* only a change in IP addresses will affect radvd, and all of= radvd's - * config is stored in the conf file which will be re-read wit= h a SIGHUP. - */ - if (networkRefreshRadvd(driver, network) < 0) + /* only a change in IP addresses will affect radvd, and all + * of radvd's config is stored in the conf file which will + * be re-read with a SIGHUP. */ + if (networkRefreshRadvd(driver, obj) < 0) goto cleanup; } =20 /* save current network state to disk */ - if ((ret =3D virNetworkSaveStatus(driver->stateDir, - network)) < 0) { + if ((ret =3D virNetworkObjSaveStatus(driver->stateDir, obj)) < 0) goto cleanup; - } } =20 /* call the 'updated' network hook script */ - if (networkRunHook(network, NULL, NULL, VIR_HOOK_NETWORK_OP_UPDATED, + if (networkRunHook(obj, NULL, NULL, VIR_HOOK_NETWORK_OP_UPDATED, VIR_HOOK_SUBOP_BEGIN) < 0) goto cleanup; =20 ret =3D 0; + cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 -static int networkCreate(virNetworkPtr net) + +static int +networkCreate(virNetworkPtr net) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - virNetworkObjPtr network; + virPoolObjPtr obj; + virNetworkDefPtr def; int ret =3D -1; virObjectEventPtr event =3D NULL; =20 - if (!(network =3D networkObjFromNetwork(net))) - goto cleanup; + if (!(obj =3D networkObjFromNetwork(net))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkCreateEnsureACL(net->conn, network->def) < 0) + if (virNetworkCreateEnsureACL(net->conn, def) < 0) goto cleanup; =20 - if ((ret =3D networkStartNetwork(driver, network)) < 0) + if ((ret =3D networkStartNetwork(driver, obj)) < 0) goto cleanup; =20 - event =3D virNetworkEventLifecycleNew(network->def->name, - network->def->uuid, + event =3D virNetworkEventLifecycleNew(def->name, + def->uuid, VIR_NETWORK_EVENT_STARTED, 0); =20 cleanup: if (event) virObjectEventStateQueue(driver->networkEventState, event); - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 -static int networkDestroy(virNetworkPtr net) + +static int +networkDestroy(virNetworkPtr net) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - virNetworkObjPtr network; + virPoolObjPtr obj; + virNetworkDefPtr def; int ret =3D -1; virObjectEventPtr event =3D NULL; =20 - if (!(network =3D networkObjFromNetwork(net))) - goto cleanup; + if (!(obj =3D networkObjFromNetwork(net))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkDestroyEnsureACL(net->conn, network->def) < 0) + if (virNetworkDestroyEnsureACL(net->conn, def) < 0) goto cleanup; =20 - if (!virNetworkObjIsActive(network)) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("network '%s' is not active"), - network->def->name); + def->name); goto cleanup; } =20 - if ((ret =3D networkShutdownNetwork(driver, network)) < 0) + if ((ret =3D networkShutdownNetwork(driver, obj)) < 0) goto cleanup; =20 - event =3D virNetworkEventLifecycleNew(network->def->name, - network->def->uuid, + event =3D virNetworkEventLifecycleNew(def->name, + def->uuid, VIR_NETWORK_EVENT_STOPPED, 0); =20 - if (!network->persistent && - networkRemoveInactive(driver, network) < 0) { + if (!virPoolObjIsPersistent(obj) && + networkRemoveInactive(driver, &obj) < 0) { ret =3D -1; goto cleanup; } @@ -3747,108 +3812,130 @@ static int networkDestroy(virNetworkPtr net) cleanup: if (event) virObjectEventStateQueue(driver->networkEventState, event); - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 -static char *networkGetXMLDesc(virNetworkPtr net, - unsigned int flags) + +static char +*networkGetXMLDesc(virNetworkPtr net, + unsigned int flags) { - virNetworkObjPtr network; + virPoolObjPtr obj; virNetworkDefPtr def; + virNetworkDefPtr newDef; char *ret =3D NULL; =20 virCheckFlags(VIR_NETWORK_XML_INACTIVE, NULL); =20 - if (!(network =3D networkObjFromNetwork(net))) - return ret; + if (!(obj =3D networkObjFromNetwork(net))) + return NULL; + def =3D virPoolObjGetDef(obj); + newDef =3D virPoolObjGetNewDef(obj); =20 - if (virNetworkGetXMLDescEnsureACL(net->conn, network->def) < 0) + if (virNetworkGetXMLDescEnsureACL(net->conn, def) < 0) goto cleanup; =20 - if ((flags & VIR_NETWORK_XML_INACTIVE) && network->newDef) - def =3D network->newDef; - else - def =3D network->def; + if ((flags & VIR_NETWORK_XML_INACTIVE) && newDef) + def =3D newDef; =20 ret =3D virNetworkDefFormat(def, flags); =20 cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 -static char *networkGetBridgeName(virNetworkPtr net) { - virNetworkObjPtr network; + +static char * +networkGetBridgeName(virNetworkPtr net) +{ + virPoolObjPtr obj; + virNetworkDefPtr def; char *bridge =3D NULL; =20 - if (!(network =3D networkObjFromNetwork(net))) - return bridge; + if (!(obj =3D networkObjFromNetwork(net))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkGetBridgeNameEnsureACL(net->conn, network->def) < 0) + if (virNetworkGetBridgeNameEnsureACL(net->conn, def) < 0) goto cleanup; =20 - if (!(network->def->bridge)) { + if (!def->bridge) { virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' does not have a bridge name."), - network->def->name); + def->name); goto cleanup; } =20 - ignore_value(VIR_STRDUP(bridge, network->def->bridge)); + ignore_value(VIR_STRDUP(bridge, def->bridge)); =20 cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return bridge; } =20 -static int networkGetAutostart(virNetworkPtr net, - int *autostart) + +static int +networkGetAutostart(virNetworkPtr net, + int *autostart) { - virNetworkObjPtr network; + virPoolObjPtr obj; + virNetworkDefPtr def; int ret =3D -1; =20 - if (!(network =3D networkObjFromNetwork(net))) - return ret; + if (!(obj =3D networkObjFromNetwork(net))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkGetAutostartEnsureACL(net->conn, network->def) < 0) + if (virNetworkGetAutostartEnsureACL(net->conn, def) < 0) goto cleanup; =20 - *autostart =3D network->autostart; + *autostart =3D 0; + if (virPoolObjIsAutostart(obj)) + *autostart =3D 1; + ret =3D 0; =20 cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 -static int networkSetAutostart(virNetworkPtr net, - int autostart) + +static int +networkSetAutostart(virNetworkPtr net, + int new_autostart) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - virNetworkObjPtr network; + virPoolObjPtr obj; + virNetworkDefPtr def; + bool autostart; char *configFile =3D NULL, *autostartLink =3D NULL; int ret =3D -1; =20 + if (!(obj =3D networkObjFromNetwork(net))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (!(network =3D networkObjFromNetwork(net))) - goto cleanup; - - if (virNetworkSetAutostartEnsureACL(net->conn, network->def) < 0) + if (virNetworkSetAutostartEnsureACL(net->conn, def) < 0) goto cleanup; =20 - if (!network->persistent) { + if (!virPoolObjIsPersistent(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("cannot set autostart for transient network= ")); goto cleanup; } =20 - autostart =3D (autostart !=3D 0); + autostart =3D (new_autostart !=3D 0); =20 - if (network->autostart !=3D autostart) { - if ((configFile =3D virNetworkConfigFile(driver->networkConfigDir,= network->def->name)) =3D=3D NULL) + if (virPoolObjIsAutostart(obj) !=3D autostart) { + if (!(configFile =3D virNetworkConfigFile(driver->networkConfigDir, + def->name))) goto cleanup; - if ((autostartLink =3D virNetworkConfigFile(driver->networkAutosta= rtDir, network->def->name)) =3D=3D NULL) + + if (!(autostartLink =3D virNetworkConfigFile(driver->networkAutost= artDir, + def->name))) goto cleanup; =20 if (autostart) { @@ -3866,7 +3953,8 @@ static int networkSetAutostart(virNetworkPtr net, goto cleanup; } } else { - if (unlink(autostartLink) < 0 && errno !=3D ENOENT && errno != =3D ENOTDIR) { + if (unlink(autostartLink) < 0 && + errno !=3D ENOENT && errno !=3D ENOTDIR) { virReportSystemError(errno, _("Failed to delete symlink '%s'"), autostartLink); @@ -3874,17 +3962,18 @@ static int networkSetAutostart(virNetworkPtr net, } } =20 - network->autostart =3D autostart; + virPoolObjSetAutostart(obj, autostart); } ret =3D 0; =20 cleanup: VIR_FREE(configFile); VIR_FREE(autostartLink); - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 + static int networkGetDHCPLeases(virNetworkPtr network, const char *mac, @@ -3910,7 +3999,8 @@ networkGetDHCPLeases(virNetworkPtr network, virNetworkIPDefPtr ipdef_tmp =3D NULL; virNetworkDHCPLeasePtr lease =3D NULL; virNetworkDHCPLeasePtr *leases_ret =3D NULL; - virNetworkObjPtr obj; + virPoolObjPtr obj; + virNetworkDefPtr def; virMacAddr mac_addr; =20 virCheckFlags(0, -1); @@ -3923,12 +4013,13 @@ networkGetDHCPLeases(virNetworkPtr network, =20 if (!(obj =3D networkObjFromNetwork(network))) return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkGetDHCPLeasesEnsureACL(network->conn, obj->def) < 0) + if (virNetworkGetDHCPLeasesEnsureACL(network->conn, def) < 0) goto cleanup; =20 /* Retrieve custom leases file location */ - custom_lease_file =3D networkDnsmasqLeaseFileNameCustom(driver, obj->d= ef->bridge); + custom_lease_file =3D networkDnsmasqLeaseFileNameCustom(driver, def->b= ridge); =20 /* Read entire contents */ if ((custom_lease_file_len =3D virFileReadAll(custom_lease_file, @@ -3964,7 +4055,8 @@ networkGetDHCPLeases(virNetworkPtr network, goto error; } =20 - if (!(mac_tmp =3D virJSONValueObjectGetString(lease_tmp, "mac-addr= ess"))) { + if (!(mac_tmp =3D virJSONValueObjectGetString(lease_tmp, + "mac-address"))) { /* leaseshelper program guarantees that lease will be stored o= nly if * mac-address is known otherwise not */ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -3975,7 +4067,8 @@ networkGetDHCPLeases(virNetworkPtr network, if (mac && virMacAddrCompare(mac, mac_tmp)) continue; =20 - if (virJSONValueObjectGetNumberLong(lease_tmp, "expiry-time", &exp= irytime_tmp) < 0) { + if (virJSONValueObjectGetNumberLong(lease_tmp, "expiry-time", + &expirytime_tmp) < 0) { /* A lease cannot be present without expiry-time */ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("found lease without expiry-time")); @@ -3992,7 +4085,8 @@ networkGetDHCPLeases(virNetworkPtr network, =20 lease->expirytime =3D expirytime_tmp; =20 - if (!(ip_tmp =3D virJSONValueObjectGetString(lease_tmp, "ip-ad= dress"))) { + if (!(ip_tmp =3D virJSONValueObjectGetString(lease_tmp, + "ip-address"))) { /* A lease without ip-address makes no sense */ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("found lease without ip-address")); @@ -4004,8 +4098,8 @@ networkGetDHCPLeases(virNetworkPtr network, lease->type =3D ipv6 ? VIR_IP_ADDR_TYPE_IPV6 : VIR_IP_ADDR_TYP= E_IPV4; =20 /* Obtain prefix */ - for (j =3D 0; j < obj->def->nips; j++) { - ipdef_tmp =3D &obj->def->ips[j]; + for (j =3D 0; j < def->nips; j++) { + ipdef_tmp =3D &def->ips[j]; =20 if (ipv6 && VIR_SOCKET_ADDR_IS_FAMILY(&ipdef_tmp->address, AF_INET6)) { @@ -4023,7 +4117,7 @@ networkGetDHCPLeases(virNetworkPtr network, =20 if ((VIR_STRDUP(lease->mac, mac_tmp) < 0) || (VIR_STRDUP(lease->ipaddr, ip_tmp) < 0) || - (VIR_STRDUP(lease->iface, obj->def->bridge) < 0)) + (VIR_STRDUP(lease->iface, def->bridge) < 0)) goto error; =20 /* Fields that can be NULL */ @@ -4060,7 +4154,7 @@ networkGetDHCPLeases(virNetworkPtr network, VIR_FREE(custom_lease_file); virJSONValueFree(leases_array); =20 - virNetworkObjEndAPI(&obj); + virPoolObjEndAPI(&obj); =20 return rv; =20 @@ -4180,8 +4274,8 @@ networkAllocateActualDevice(virDomainDefPtr dom, { virNetworkDriverStatePtr driver =3D networkGetDriver(); virDomainNetType actualType =3D iface->type; - virNetworkObjPtr network =3D NULL; - virNetworkDefPtr netdef =3D NULL; + virPoolObjPtr obj =3D NULL; + virNetworkDefPtr def =3D NULL; virNetDevBandwidthPtr bandwidth =3D NULL; virPortGroupDefPtr portgroup =3D NULL; virNetDevVPortProfilePtr virtport =3D iface->virtPortProfile; @@ -4196,19 +4290,14 @@ networkAllocateActualDevice(virDomainDefPtr dom, virDomainActualNetDefFree(iface->data.network.actual); iface->data.network.actual =3D NULL; =20 - network =3D virNetworkObjFindByName(driver->networks, iface->data.netw= ork.name); - if (!network) { - virReportError(VIR_ERR_NO_NETWORK, - _("no network with matching name '%s'"), - iface->data.network.name); + if (!(obj =3D networkObjFindByName(iface->data.network.name))) goto error; - } - netdef =3D network->def; + def =3D virPoolObjGetDef(obj); =20 - if (!virNetworkObjIsActive(network)) { + if (!virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, _("network '%s' is not active"), - netdef->name); + def->name); goto error; } =20 @@ -4219,7 +4308,7 @@ networkAllocateActualDevice(virDomainDefPtr dom, * for bandwidth information, so we need to check for that and * fill it in appropriately for all forward types. */ - portgroup =3D virPortGroupFindByName(netdef, iface->data.network.portg= roup); + portgroup =3D virPortGroupFindByName(def, iface->data.network.portgrou= p); =20 /* If there is already interface-specific bandwidth, just use that * (already in NetDef). Otherwise, if there is bandwidth info in @@ -4240,8 +4329,8 @@ networkAllocateActualDevice(virDomainDefPtr dom, vlan =3D &iface->vlan; else if (portgroup && portgroup->vlan.nTags > 0) vlan =3D &portgroup->vlan; - else if (netdef->vlan.nTags > 0) - vlan =3D &netdef->vlan; + else if (def->vlan.nTags > 0) + vlan =3D &def->vlan; =20 if (vlan && virNetDevVlanCopy(&iface->data.network.actual->vlan, vlan)= < 0) goto error; @@ -4252,14 +4341,14 @@ networkAllocateActualDevice(virDomainDefPtr dom, else if (portgroup && portgroup->trustGuestRxFilters) iface->data.network.actual->trustGuestRxFilters =3D portgroup->trustGuestRxFilters; - else if (netdef->trustGuestRxFilters) + else if (def->trustGuestRxFilters) iface->data.network.actual->trustGuestRxFilters - =3D netdef->trustGuestRxFilters; + =3D def->trustGuestRxFilters; =20 - if ((netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_OPEN)) { + if ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_OPEN)) { /* for these forward types, the actual net type really *is* * NETWORK; we just keep the info from the portgroup in * iface->data.network.actual @@ -4272,16 +4361,16 @@ networkAllocateActualDevice(virDomainDefPtr dom, * bridge and set flood/learning mode on the tap device) */ if (VIR_STRDUP(iface->data.network.actual->data.bridge.brname, - netdef->bridge) < 0) + def->bridge) < 0) goto error; iface->data.network.actual->data.bridge.macTableManager - =3D netdef->macTableManager; + =3D def->macTableManager; =20 - if (networkPlugBandwidth(network, iface) < 0) + if (networkPlugBandwidth(obj, iface) < 0) goto error; =20 - } else if ((netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_BRIDGE) && - netdef->bridge) { + } else if ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_BRIDGE) && + def->bridge) { =20 /* * is VIR_DOMAIN_NET_TYPE_BRIDGE @@ -4289,17 +4378,17 @@ networkAllocateActualDevice(virDomainDefPtr dom, =20 iface->data.network.actual->type =3D actualType =3D VIR_DOMAIN_NET= _TYPE_BRIDGE; if (VIR_STRDUP(iface->data.network.actual->data.bridge.brname, - netdef->bridge) < 0) + def->bridge) < 0) goto error; iface->data.network.actual->data.bridge.macTableManager - =3D netdef->macTableManager; + =3D def->macTableManager; =20 /* merge virtualports from interface, network, and portgroup to * arrive at actual virtualport to use */ if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtP= ortProfile, iface->virtPortProfile, - netdef->virtPortProfile, + def->virtPortProfile, portgroup ? portgroup->virtPortProfile : NUL= L) < 0) { goto error; @@ -4312,23 +4401,23 @@ networkAllocateActualDevice(virDomainDefPtr dom, _(" not supported = for network " "'%s' which uses a bridge device"), virNetDevVPortTypeToString(virtport->virtPo= rtType), - netdef->name); + def->name); goto error; } } =20 - } else if (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_HOSTDEV) { + } else if (def->forward.type =3D=3D VIR_NETWORK_FORWARD_HOSTDEV) { =20 virDomainHostdevSubsysPCIBackendType backend; =20 iface->data.network.actual->type =3D actualType =3D VIR_DOMAIN_NET= _TYPE_HOSTDEV; - if (networkCreateInterfacePool(netdef) < 0) + if (networkCreateInterfacePool(def) < 0) goto error; =20 /* pick first dev with 0 connections */ - for (i =3D 0; i < netdef->forward.nifs; i++) { - if (netdef->forward.ifs[i].connections =3D=3D 0) { - dev =3D &netdef->forward.ifs[i]; + for (i =3D 0; i < def->forward.nifs; i++) { + if (def->forward.ifs[i].connections =3D=3D 0) { + dev =3D &def->forward.ifs[i]; break; } } @@ -4336,18 +4425,18 @@ networkAllocateActualDevice(virDomainDefPtr dom, virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' requires exclusive access " "to interfaces, but none are available"), - netdef->name); + def->name); goto error; } iface->data.network.actual->data.hostdev.def.parent.type =3D VIR_D= OMAIN_DEVICE_NET; iface->data.network.actual->data.hostdev.def.parent.data.net =3D i= face; iface->data.network.actual->data.hostdev.def.info =3D &iface->info; iface->data.network.actual->data.hostdev.def.mode =3D VIR_DOMAIN_H= OSTDEV_MODE_SUBSYS; - iface->data.network.actual->data.hostdev.def.managed =3D netdef->f= orward.managed ? 1 : 0; + iface->data.network.actual->data.hostdev.def.managed =3D def->forw= ard.managed ? 1 : 0; iface->data.network.actual->data.hostdev.def.source.subsys.type = =3D dev->type; iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.a= ddr =3D dev->device.pci; =20 - switch (netdef->forward.driverName) { + switch (def->forward.driverName) { case VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT: backend =3D VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT; break; @@ -4361,7 +4450,7 @@ networkAllocateActualDevice(virDomainDefPtr dom, virReportError(VIR_ERR_INTERNAL_ERROR, _("unrecognized driver name value %d " " in network '%s'"), - netdef->forward.driverName, netdef->name); + def->forward.driverName, def->name); goto error; } iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.b= ackend @@ -4372,7 +4461,7 @@ networkAllocateActualDevice(virDomainDefPtr dom, */ if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtP= ortProfile, iface->virtPortProfile, - netdef->virtPortProfile, + def->virtPortProfile, portgroup ? portgroup->virtPortProfile : NUL= L) < 0) { goto error; @@ -4387,15 +4476,15 @@ networkAllocateActualDevice(virDomainDefPtr dom, "'%s' which uses an SR-IOV Virtual Functi= on " "via PCI passthrough"), virNetDevVPortTypeToString(virtport->virtPo= rtType), - netdef->name); + def->name); goto error; } } =20 - } else if ((netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_BRIDGE) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_PRIVATE) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_VEPA) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_PASSTHROUG= H)) { + } else if ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_BRIDGE) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_PRIVATE) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_VEPA) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_PASSTHROUGH))= { =20 /* are all * VIR_DOMAIN_NET_TYPE_DIRECT. @@ -4403,7 +4492,7 @@ networkAllocateActualDevice(virDomainDefPtr dom, =20 /* Set type=3Ddirect and appropriate */ iface->data.network.actual->type =3D actualType =3D VIR_DOMAIN_NET= _TYPE_DIRECT; - switch (netdef->forward.type) { + switch (def->forward.type) { case VIR_NETWORK_FORWARD_BRIDGE: iface->data.network.actual->data.direct.mode =3D VIR_NETDEV_MA= CVLAN_MODE_BRIDGE; break; @@ -4423,7 +4512,7 @@ networkAllocateActualDevice(virDomainDefPtr dom, */ if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtP= ortProfile, iface->virtPortProfile, - netdef->virtPortProfile, + def->virtPortProfile, portgroup ? portgroup->virtPortProfile : NUL= L) < 0) { goto error; @@ -4437,7 +4526,7 @@ networkAllocateActualDevice(virDomainDefPtr dom, _(" not supported = for network " "'%s' which uses a macvtap device"), virNetDevVPortTypeToString(virtport->virtPo= rtType), - netdef->name); + def->name); goto error; } } @@ -4445,16 +4534,16 @@ networkAllocateActualDevice(virDomainDefPtr dom, /* If there is only a single device, just return it (caller will d= etect * any error if exclusive use is required but could not be acquire= d). */ - if ((netdef->forward.nifs <=3D 0) && (netdef->forward.npfs <=3D 0)= ) { + if ((def->forward.nifs <=3D 0) && (def->forward.npfs <=3D 0)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' uses a direct mode, but " "has no forward dev and no interface pool"), - netdef->name); + def->name); goto error; } else { /* pick an interface from the pool */ =20 - if (networkCreateInterfacePool(netdef) < 0) + if (networkCreateInterfacePool(def) < 0) goto error; =20 /* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both @@ -4463,25 +4552,25 @@ networkAllocateActualDevice(virDomainDefPtr dom, * just search for the one with the lowest number of * connections. */ - if ((netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_PASSTHROU= GH) || - ((netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_PRIVATE)= && + if ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_PASSTHROUGH)= || + ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_PRIVATE) && iface->data.network.actual->virtPortProfile && (iface->data.network.actual->virtPortProfile->virtPortType =3D=3D VIR_NETDEV_VPORT_PROFILE_8021QBH))) { =20 /* pick first dev with 0 connections */ - for (i =3D 0; i < netdef->forward.nifs; i++) { - if (netdef->forward.ifs[i].connections =3D=3D 0) { - dev =3D &netdef->forward.ifs[i]; + for (i =3D 0; i < def->forward.nifs; i++) { + if (def->forward.ifs[i].connections =3D=3D 0) { + dev =3D &def->forward.ifs[i]; break; } } } else { /* pick least used dev */ - dev =3D &netdef->forward.ifs[0]; - for (i =3D 1; i < netdef->forward.nifs; i++) { - if (netdef->forward.ifs[i].connections < dev->connecti= ons) - dev =3D &netdef->forward.ifs[i]; + dev =3D &def->forward.ifs[0]; + for (i =3D 1; i < def->forward.nifs; i++) { + if (def->forward.ifs[i].connections < dev->connections) + dev =3D &def->forward.ifs[i]; } } /* dev points at the physical device we want to use */ @@ -4489,7 +4578,7 @@ networkAllocateActualDevice(virDomainDefPtr dom, virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' requires exclusive access " "to interfaces, but none are available"), - netdef->name); + def->name); goto error; } if (VIR_STRDUP(iface->data.network.actual->data.direct.linkdev, @@ -4498,7 +4587,7 @@ networkAllocateActualDevice(virDomainDefPtr dom, } } =20 - if (networkMacMgrAdd(driver, network, dom->name, &iface->mac) < 0) + if (networkMacMgrAdd(driver, obj, dom->name, &iface->mac) < 0) goto error; =20 if (virNetDevVPortProfileCheckComplete(virtport, true) < 0) @@ -4523,12 +4612,12 @@ networkAllocateActualDevice(virDomainDefPtr dom, (actualType =3D=3D VIR_DOMAIN_NET_TYPE_BRIDGE && virtport && virtport->virtPortType =3D=3D VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH))) { - if (netdef) { + if (def) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("an interface connecting to network '%s' " "is requesting a vlan tag, but that is no= t " "supported for this type of network"), - netdef->name); + def->name); } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("an interface of type '%s' " @@ -4551,27 +4640,27 @@ networkAllocateActualDevice(virDomainDefPtr dom, } } =20 - if (netdef) { - netdef->connections++; + if (def) { + def->connections++; if (dev) dev->connections++; /* finally we can call the 'plugged' hook script if any */ - if (networkRunHook(network, dom, iface, + if (networkRunHook(obj, dom, iface, VIR_HOOK_NETWORK_OP_IFACE_PLUGGED, VIR_HOOK_SUBOP_BEGIN) < 0) { /* adjust for failure */ - netdef->connections--; + def->connections--; if (dev) dev->connections--; goto error; } - networkLogAllocation(netdef, actualType, dev, iface, true); + networkLogAllocation(def, actualType, dev, iface, true); } =20 ret =3D 0; =20 cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; =20 error: @@ -4582,6 +4671,7 @@ networkAllocateActualDevice(virDomainDefPtr dom, goto cleanup; } =20 + /* networkNotifyActualDevice: * @dom: domain definition that @iface belongs to * @iface: the domain's NetDef with an "actual" device already filled in. @@ -4597,10 +4687,9 @@ int networkNotifyActualDevice(virDomainDefPtr dom, virDomainNetDefPtr iface) { - virNetworkDriverStatePtr driver =3D networkGetDriver(); virDomainNetType actualType =3D virDomainNetGetActualType(iface); - virNetworkObjPtr network; - virNetworkDefPtr netdef; + virPoolObjPtr obj; + virNetworkDefPtr def; virNetworkForwardIfDefPtr dev =3D NULL; size_t i; int ret =3D -1; @@ -4608,14 +4697,9 @@ networkNotifyActualDevice(virDomainDefPtr dom, if (iface->type !=3D VIR_DOMAIN_NET_TYPE_NETWORK) return 0; =20 - network =3D virNetworkObjFindByName(driver->networks, iface->data.netw= ork.name); - if (!network) { - virReportError(VIR_ERR_NO_NETWORK, - _("no network with matching name '%s'"), - iface->data.network.name); - goto error; - } - netdef =3D network->def; + if (!(obj =3D networkObjFindByName(iface->data.network.name))) + return -1; + def =3D virPoolObjGetDef(obj); =20 /* if we're restarting libvirtd after an upgrade from a version * that didn't save bridge name in actualNetDef for @@ -4625,7 +4709,7 @@ networkNotifyActualDevice(virDomainDefPtr dom, if (actualType =3D=3D VIR_DOMAIN_NET_TYPE_NETWORK && !iface->data.network.actual->data.bridge.brname && (VIR_STRDUP(iface->data.network.actual->data.bridge.brname, - netdef->bridge) < 0)) + def->bridge) < 0)) goto error; =20 if (!iface->data.network.actual || @@ -4635,14 +4719,14 @@ networkNotifyActualDevice(virDomainDefPtr dom, goto success; } =20 - if (networkCreateInterfacePool(netdef) < 0) + if (networkCreateInterfacePool(def) < 0) goto error; =20 - if (netdef->forward.nifs =3D=3D 0) { + if (def->forward.nifs =3D=3D 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' uses a direct or hostdev mode, " "but has no forward dev and no interface pool"), - netdef->name); + def->name); goto error; } =20 @@ -4658,11 +4742,11 @@ networkNotifyActualDevice(virDomainDefPtr dom, } =20 /* find the matching interface and increment its connections */ - for (i =3D 0; i < netdef->forward.nifs; i++) { - if (netdef->forward.ifs[i].type + for (i =3D 0; i < def->forward.nifs; i++) { + if (def->forward.ifs[i].type =3D=3D VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV && - STREQ(actualDev, netdef->forward.ifs[i].device.dev)) { - dev =3D &netdef->forward.ifs[i]; + STREQ(actualDev, def->forward.ifs[i].device.dev)) { + dev =3D &def->forward.ifs[i]; break; } } @@ -4671,7 +4755,7 @@ networkNotifyActualDevice(virDomainDefPtr dom, virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' doesn't have dev=3D'%s' " "in use by domain"), - netdef->name, actualDev); + def->name, actualDev); goto error; } =20 @@ -4680,15 +4764,15 @@ networkNotifyActualDevice(virDomainDefPtr dom, * must be 0 in those cases. */ if ((dev->connections > 0) && - ((netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_PASSTHROUGH)= || - ((netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_PRIVATE) && + ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_PASSTHROUGH) || + ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_PRIVATE) && iface->data.network.actual->virtPortProfile && (iface->data.network.actual->virtPortProfile->virtPortType =3D=3D VIR_NETDEV_VPORT_PROFILE_8021QBH)))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' claims dev=3D'%s' is already in= " "use by a different domain"), - netdef->name, actualDev); + def->name, actualDev); goto error; } } else /* if (actualType =3D=3D VIR_DOMAIN_NET_TYPE_HOSTDEV) */ { @@ -4703,12 +4787,12 @@ networkNotifyActualDevice(virDomainDefPtr dom, } =20 /* find the matching interface and increment its connections */ - for (i =3D 0; i < netdef->forward.nifs; i++) { - if (netdef->forward.ifs[i].type + for (i =3D 0; i < def->forward.nifs; i++) { + if (def->forward.ifs[i].type =3D=3D VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI && virPCIDeviceAddressEqual(&hostdev->source.subsys.u.pci.add= r, - &netdef->forward.ifs[i].device.pc= i)) { - dev =3D &netdef->forward.ifs[i]; + &def->forward.ifs[i].device.pci))= { + dev =3D &def->forward.ifs[i]; break; } } @@ -4717,7 +4801,7 @@ networkNotifyActualDevice(virDomainDefPtr dom, virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' doesn't have " "PCI device %04x:%02x:%02x.%x in use by domai= n"), - netdef->name, + def->name, hostdev->source.subsys.u.pci.addr.domain, hostdev->source.subsys.u.pci.addr.bus, hostdev->source.subsys.u.pci.addr.slot, @@ -4730,12 +4814,12 @@ networkNotifyActualDevice(virDomainDefPtr dom, * current connections count must be 0 in those cases. */ if ((dev->connections > 0) && - netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_HOSTDEV) { + def->forward.type =3D=3D VIR_NETWORK_FORWARD_HOSTDEV) { virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' claims the PCI device at " "domain=3D%d bus=3D%d slot=3D%d function=3D%d= " "is already in use by a different domain"), - netdef->name, + def->name, dev->device.pci.domain, dev->device.pci.bus, dev->device.pci.slot, dev->device.pci.function); goto error; @@ -4743,23 +4827,23 @@ networkNotifyActualDevice(virDomainDefPtr dom, } =20 success: - netdef->connections++; + def->connections++; if (dev) dev->connections++; /* finally we can call the 'plugged' hook script if any */ - if (networkRunHook(network, dom, iface, VIR_HOOK_NETWORK_OP_IFACE_PLUG= GED, + if (networkRunHook(obj, dom, iface, VIR_HOOK_NETWORK_OP_IFACE_PLUGGED, VIR_HOOK_SUBOP_BEGIN) < 0) { /* adjust for failure */ if (dev) dev->connections--; - netdef->connections--; + def->connections--; goto error; } - networkLogAllocation(netdef, actualType, dev, iface, true); + networkLogAllocation(def, actualType, dev, iface, true); =20 ret =3D 0; cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; =20 error: @@ -4785,8 +4869,8 @@ networkReleaseActualDevice(virDomainDefPtr dom, { virNetworkDriverStatePtr driver =3D networkGetDriver(); virDomainNetType actualType =3D virDomainNetGetActualType(iface); - virNetworkObjPtr network; - virNetworkDefPtr netdef; + virPoolObjPtr obj; + virNetworkDefPtr def; virNetworkForwardIfDefPtr dev =3D NULL; size_t i; int ret =3D -1; @@ -4794,21 +4878,16 @@ networkReleaseActualDevice(virDomainDefPtr dom, if (iface->type !=3D VIR_DOMAIN_NET_TYPE_NETWORK) return 0; =20 - network =3D virNetworkObjFindByName(driver->networks, iface->data.netw= ork.name); - if (!network) { - virReportError(VIR_ERR_NO_NETWORK, - _("no network with matching name '%s'"), - iface->data.network.name); - goto error; - } - netdef =3D network->def; + if (!(obj =3D networkObjFindByName(iface->data.network.name))) + return -1; + def =3D virPoolObjGetDef(obj); =20 if (iface->data.network.actual && - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE || - netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT || - netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE || - netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_OPEN) && - networkUnplugBandwidth(network, iface) < 0) + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE || + def->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT || + def->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE || + def->forward.type =3D=3D VIR_NETWORK_FORWARD_OPEN) && + networkUnplugBandwidth(obj, iface) < 0) goto error; =20 if ((!iface->data.network.actual) || @@ -4818,11 +4897,11 @@ networkReleaseActualDevice(virDomainDefPtr dom, goto success; } =20 - if (netdef->forward.nifs =3D=3D 0) { + if (def->forward.nifs =3D=3D 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' uses a direct/hostdev mode, but " "has no forward dev and no interface pool"), - netdef->name); + def->name); goto error; } =20 @@ -4837,11 +4916,11 @@ networkReleaseActualDevice(virDomainDefPtr dom, goto error; } =20 - for (i =3D 0; i < netdef->forward.nifs; i++) { - if (netdef->forward.ifs[i].type + for (i =3D 0; i < def->forward.nifs; i++) { + if (def->forward.ifs[i].type =3D=3D VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV && - STREQ(actualDev, netdef->forward.ifs[i].device.dev)) { - dev =3D &netdef->forward.ifs[i]; + STREQ(actualDev, def->forward.ifs[i].device.dev)) { + dev =3D &def->forward.ifs[i]; break; } } @@ -4850,25 +4929,25 @@ networkReleaseActualDevice(virDomainDefPtr dom, virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' doesn't have dev=3D'%s' " "in use by domain"), - netdef->name, actualDev); + def->name, actualDev); goto error; } } else /* if (actualType =3D=3D VIR_DOMAIN_NET_TYPE_HOSTDEV) */ { virDomainHostdevDefPtr hostdev; =20 - hostdev =3D virDomainNetGetActualHostdev(iface); - if (!hostdev) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("the interface uses a hostdev mode, but= has no hostdev")); + if (!(hostdev =3D virDomainNetGetActualHostdev(iface))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("the interface uses a hostdev mode, " + "but has no hostdev")); goto error; } =20 - for (i =3D 0; i < netdef->forward.nifs; i++) { - if (netdef->forward.ifs[i].type + for (i =3D 0; i < def->forward.nifs; i++) { + if (def->forward.ifs[i].type =3D=3D VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI && virPCIDeviceAddressEqual(&hostdev->source.subsys.u.pci.add= r, - &netdef->forward.ifs[i].device.pc= i)) { - dev =3D &netdef->forward.ifs[i]; + &def->forward.ifs[i].device.pci))= { + dev =3D &def->forward.ifs[i]; break; } } @@ -4877,7 +4956,7 @@ networkReleaseActualDevice(virDomainDefPtr dom, virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' doesn't have " "PCI device %04x:%02x:%02x.%x in use by domai= n"), - netdef->name, + def->name, hostdev->source.subsys.u.pci.addr.domain, hostdev->source.subsys.u.pci.addr.bus, hostdev->source.subsys.u.pci.addr.slot, @@ -4887,20 +4966,20 @@ networkReleaseActualDevice(virDomainDefPtr dom, } =20 success: - networkMacMgrDel(driver, network, dom->name, &iface->mac); + networkMacMgrDel(driver, obj, dom->name, &iface->mac); =20 if (iface->data.network.actual) { - netdef->connections--; + def->connections--; if (dev) dev->connections--; /* finally we can call the 'unplugged' hook script if any */ - networkRunHook(network, dom, iface, VIR_HOOK_NETWORK_OP_IFACE_UNPL= UGGED, + networkRunHook(obj, dom, iface, VIR_HOOK_NETWORK_OP_IFACE_UNPLUGGE= D, VIR_HOOK_SUBOP_BEGIN); - networkLogAllocation(netdef, actualType, dev, iface, false); + networkLogAllocation(def, actualType, dev, iface, false); } ret =3D 0; cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); if (iface->type =3D=3D VIR_DOMAIN_NET_TYPE_NETWORK) { virDomainActualNetDefFree(iface->data.network.actual); iface->data.network.actual =3D NULL; @@ -4911,6 +4990,7 @@ networkReleaseActualDevice(virDomainDefPtr dom, goto cleanup; } =20 + /* * networkGetNetworkAddress: * @netname: the name of a network @@ -4931,44 +5011,38 @@ networkReleaseActualDevice(virDomainDefPtr dom, * completely unsupported. */ int -networkGetNetworkAddress(const char *netname, char **netaddr) +networkGetNetworkAddress(const char *netname, + char **netaddr) { - virNetworkDriverStatePtr driver =3D networkGetDriver(); int ret =3D -1; - virNetworkObjPtr network; - virNetworkDefPtr netdef; + virPoolObjPtr obj; + virNetworkDefPtr def; virNetworkIPDefPtr ipdef; virSocketAddr addr; virSocketAddrPtr addrptr =3D NULL; char *dev_name =3D NULL; =20 *netaddr =3D NULL; - network =3D virNetworkObjFindByName(driver->networks, netname); - if (!network) { - virReportError(VIR_ERR_NO_NETWORK, - _("no network with matching name '%s'"), - netname); - goto cleanup; - } - netdef =3D network->def; + if (!(obj =3D networkObjFindByName(netname))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - switch (netdef->forward.type) { + switch (def->forward.type) { case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_OPEN: - ipdef =3D virNetworkDefGetIPByIndex(netdef, AF_UNSPEC, 0); - if (!ipdef) { + if (!(ipdef =3D virNetworkDefGetIPByIndex(def, AF_UNSPEC, 0))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' doesn't have an IP address"), - netdef->name); + def->name); goto cleanup; } addrptr =3D &ipdef->address; break; =20 case VIR_NETWORK_FORWARD_BRIDGE: - if ((dev_name =3D netdef->bridge)) + if ((dev_name =3D def->bridge)) break; /* * fall through if netdef->bridge wasn't set, since that is @@ -4977,13 +5051,13 @@ networkGetNetworkAddress(const char *netname, char = **netaddr) case VIR_NETWORK_FORWARD_PRIVATE: case VIR_NETWORK_FORWARD_VEPA: case VIR_NETWORK_FORWARD_PASSTHROUGH: - if ((netdef->forward.nifs > 0) && netdef->forward.ifs) - dev_name =3D netdef->forward.ifs[0].device.dev; + if ((def->forward.nifs > 0) && def->forward.ifs) + dev_name =3D def->forward.ifs[0].device.dev; =20 if (!dev_name) { virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' has no associated interface or = bridge"), - netdef->name); + def->name); goto cleanup; } break; @@ -5001,11 +5075,13 @@ networkGetNetworkAddress(const char *netname, char = **netaddr) } =20 ret =3D 0; + cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 + /* networkGetActualType: * @dom: domain definition that @iface belongs to * @iface: the original NetDef from the domain @@ -5019,8 +5095,8 @@ int networkGetActualType(virDomainNetDefPtr iface) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - virNetworkObjPtr network =3D NULL; - virNetworkDefPtr netdef =3D NULL; + virPoolObjPtr obj =3D NULL; + virNetworkDefPtr def; int ret =3D -1; =20 if (!driver || iface->type !=3D VIR_DOMAIN_NET_TYPE_NETWORK) @@ -5029,27 +5105,22 @@ networkGetActualType(virDomainNetDefPtr iface) if (iface->data.network.actual) return iface->data.network.actual->type; =20 - network =3D virNetworkObjFindByName(driver->networks, iface->data.netw= ork.name); - if (!network) { - virReportError(VIR_ERR_NO_NETWORK, - _("no network with matching name '%s'"), - iface->data.network.name); + if (!(obj =3D networkObjFindByName(iface->data.network.name))) return -1; - } - netdef =3D network->def; + def =3D virPoolObjGetDef(obj); =20 - if ((netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_OPEN)) { + if ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_NONE) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_NAT) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_ROUTE) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_OPEN)) { /* for these forward types, the actual net type really *is* * NETWORK; we just keep the info from the portgroup in * iface->data.network.actual */ ret =3D VIR_DOMAIN_NET_TYPE_NETWORK; =20 - } else if ((netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_BRIDGE) && - netdef->bridge) { + } else if ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_BRIDGE) && + def->bridge) { =20 /* * is VIR_DOMAIN_NET_TYPE_BRIDGE @@ -5057,14 +5128,14 @@ networkGetActualType(virDomainNetDefPtr iface) =20 ret =3D VIR_DOMAIN_NET_TYPE_BRIDGE; =20 - } else if (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_HOSTDEV) { + } else if (def->forward.type =3D=3D VIR_NETWORK_FORWARD_HOSTDEV) { =20 ret =3D VIR_DOMAIN_NET_TYPE_HOSTDEV; =20 - } else if ((netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_BRIDGE) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_PRIVATE) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_VEPA) || - (netdef->forward.type =3D=3D VIR_NETWORK_FORWARD_PASSTHROUG= H)) { + } else if ((def->forward.type =3D=3D VIR_NETWORK_FORWARD_BRIDGE) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_PRIVATE) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_VEPA) || + (def->forward.type =3D=3D VIR_NETWORK_FORWARD_PASSTHROUGH))= { =20 /* are all * VIR_DOMAIN_NET_TYPE_DIRECT. @@ -5074,7 +5145,7 @@ networkGetActualType(virDomainNetDefPtr iface) =20 } =20 - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -5100,15 +5171,16 @@ networkGetActualType(virDomainNetDefPtr iface) * 1 if no QoS is set (@new_rate untouched) */ static int -networkCheckBandwidth(virNetworkObjPtr net, +networkCheckBandwidth(virPoolObjPtr obj, virNetDevBandwidthPtr ifaceBand, virNetDevBandwidthPtr oldBandwidth, virMacAddr ifaceMac, unsigned long long *new_rate) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); int ret =3D -1; - virNetDevBandwidthPtr netBand =3D net->def->bandwidth; - unsigned long long tmp_floor_sum =3D net->floor_sum; + virNetDevBandwidthPtr netBand =3D def->bandwidth; + unsigned long long tmp_floor_sum =3D virNetworkObjPrivateGetFloorSum(o= bj); unsigned long long tmp_new_rate =3D 0; char ifmac[VIR_MAC_STRING_BUFLEN]; =20 @@ -5119,7 +5191,7 @@ networkCheckBandwidth(virNetworkObjPtr net, virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("Invalid use of 'floor' on interface with MAC " "address %s - network '%s' has no inbound QoS set= "), - ifmac, net->def->name); + ifmac, def->name); return -1; } =20 @@ -5144,8 +5216,8 @@ networkCheckBandwidth(virNetworkObjPtr net, _("Cannot plug '%s' interface into '%s' because= it " "would overcommit 'peak' on network '%s'"), ifmac, - net->def->bridge, - net->def->name); + def->bridge, + def->name); goto cleanup; } } else if (tmp_floor_sum > netBand->in->average) { @@ -5155,8 +5227,8 @@ networkCheckBandwidth(virNetworkObjPtr net, _("Cannot plug '%s' interface into '%s' because it " "would overcommit 'average' on network '%s'"), ifmac, - net->def->bridge, - net->def->name); + def->bridge, + def->name); goto cleanup; } =20 @@ -5168,6 +5240,7 @@ networkCheckBandwidth(virNetworkObjPtr net, return ret; } =20 + /** * networkNextClassID: * @net: network object @@ -5179,13 +5252,14 @@ networkCheckBandwidth(virNetworkObjPtr net, * Returns next free class ID or -1 if none is available. */ static ssize_t -networkNextClassID(virNetworkObjPtr net) +networkNextClassID(virPoolObjPtr obj) { ssize_t ret =3D 0; + virBitmapPtr class_id =3D virNetworkObjPrivateGetClassId(obj); =20 - ret =3D virBitmapNextClearBit(net->class_id, -1); + ret =3D virBitmapNextClearBit(class_id, -1); =20 - if (ret < 0 || virBitmapSetBit(net->class_id, ret) < 0) + if (ret < 0 || virBitmapSetBit(class_id, ret) < 0) return -1; =20 return ret; @@ -5193,48 +5267,56 @@ networkNextClassID(virNetworkObjPtr net) =20 =20 static int -networkPlugBandwidthImpl(virNetworkObjPtr net, +networkPlugBandwidthImpl(virPoolObjPtr obj, virDomainNetDefPtr iface, virNetDevBandwidthPtr ifaceBand, unsigned long long new_rate) { virNetworkDriverStatePtr driver =3D networkGetDriver(); + virNetworkDefPtr def =3D virPoolObjGetDef(obj); ssize_t class_id =3D 0; + unsigned long long tmp_floor_sum; int plug_ret; int ret =3D -1; =20 /* generate new class_id */ - if ((class_id =3D networkNextClassID(net)) < 0) { + if ((class_id =3D networkNextClassID(obj)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not generate next class ID")); goto cleanup; } =20 - plug_ret =3D virNetDevBandwidthPlug(net->def->bridge, net->def->bandwi= dth, + plug_ret =3D virNetDevBandwidthPlug(def->bridge, def->bandwidth, &iface->mac, ifaceBand, class_id); if (plug_ret < 0) { - ignore_value(virNetDevBandwidthUnplug(net->def->bridge, class_id)); + ignore_value(virNetDevBandwidthUnplug(def->bridge, class_id)); goto cleanup; } =20 /* QoS was set, generate new class ID */ iface->data.network.actual->class_id =3D class_id; /* update sum of 'floor'-s of attached NICs */ - net->floor_sum +=3D ifaceBand->in->floor; + tmp_floor_sum =3D virNetworkObjPrivateGetFloorSum(obj); + tmp_floor_sum +=3D ifaceBand->in->floor; + virNetworkObjPrivateSetFloorSum(obj, tmp_floor_sum); + /* update status file */ - if (virNetworkSaveStatus(driver->stateDir, net) < 0) { - ignore_value(virBitmapClearBit(net->class_id, class_id)); - net->floor_sum -=3D ifaceBand->in->floor; + if (virNetworkObjSaveStatus(driver->stateDir, obj) < 0) { + virBitmapPtr obj_class_id =3D virNetworkObjPrivateGetClassId(obj); + + ignore_value(virBitmapClearBit(obj_class_id, class_id)); + tmp_floor_sum -=3D ifaceBand->in->floor; + virNetworkObjPrivateSetFloorSum(obj, tmp_floor_sum); iface->data.network.actual->class_id =3D 0; - ignore_value(virNetDevBandwidthUnplug(net->def->bridge, class_id)); + ignore_value(virNetDevBandwidthUnplug(def->bridge, class_id)); goto cleanup; } /* update rate for non guaranteed NICs */ - new_rate -=3D net->floor_sum; - if (virNetDevBandwidthUpdateRate(net->def->bridge, 2, - net->def->bandwidth, new_rate) < 0) + new_rate -=3D virNetworkObjPrivateGetFloorSum(obj); + if (virNetDevBandwidthUpdateRate(def->bridge, 2, + def->bandwidth, new_rate) < 0) VIR_WARN("Unable to update rate for 1:2 class on %s bridge", - net->def->bridge); + def->bridge); =20 ret =3D 0; cleanup: @@ -5243,7 +5325,7 @@ networkPlugBandwidthImpl(virNetworkObjPtr net, =20 =20 static int -networkPlugBandwidth(virNetworkObjPtr net, +networkPlugBandwidth(virPoolObjPtr obj, virDomainNetDefPtr iface) { int ret =3D -1; @@ -5252,7 +5334,7 @@ networkPlugBandwidth(virNetworkObjPtr net, char ifmac[VIR_MAC_STRING_BUFLEN]; virNetDevBandwidthPtr ifaceBand =3D virDomainNetGetActualBandwidth(ifa= ce); =20 - if ((plug_ret =3D networkCheckBandwidth(net, ifaceBand, NULL, + if ((plug_ret =3D networkCheckBandwidth(obj, ifaceBand, NULL, iface->mac, &new_rate)) < 0) { /* helper reported error */ goto cleanup; @@ -5273,7 +5355,7 @@ networkPlugBandwidth(virNetworkObjPtr net, goto cleanup; } =20 - if (networkPlugBandwidthImpl(net, iface, ifaceBand, new_rate) < 0) + if (networkPlugBandwidthImpl(obj, iface, ifaceBand, new_rate) < 0) goto cleanup; =20 ret =3D 0; @@ -5282,50 +5364,60 @@ networkPlugBandwidth(virNetworkObjPtr net, return ret; } =20 + static int -networkUnplugBandwidth(virNetworkObjPtr net, +networkUnplugBandwidth(virPoolObjPtr obj, virDomainNetDefPtr iface) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); virNetworkDriverStatePtr driver =3D networkGetDriver(); int ret =3D 0; unsigned long long new_rate; + unsigned long long tmp_floor_sum; + virBitmapPtr obj_class_id; virNetDevBandwidthPtr ifaceBand =3D virDomainNetGetActualBandwidth(ifa= ce); =20 if (iface->data.network.actual && iface->data.network.actual->class_id) { - if (!net->def->bandwidth || !net->def->bandwidth->in) { + if (!def->bandwidth || !def->bandwidth->in) { VIR_WARN("Network %s has no bandwidth but unplug requested", - net->def->name); + def->name); goto cleanup; } /* we must remove class from bridge */ - new_rate =3D net->def->bandwidth->in->average; + new_rate =3D def->bandwidth->in->average; =20 - if (net->def->bandwidth->in->peak > 0) - new_rate =3D net->def->bandwidth->in->peak; + if (def->bandwidth->in->peak > 0) + new_rate =3D def->bandwidth->in->peak; =20 - ret =3D virNetDevBandwidthUnplug(net->def->bridge, + ret =3D virNetDevBandwidthUnplug(def->bridge, iface->data.network.actual->class_i= d); if (ret < 0) goto cleanup; /* update sum of 'floor'-s of attached NICs */ - net->floor_sum -=3D ifaceBand->in->floor; + tmp_floor_sum =3D virNetworkObjPrivateGetFloorSum(obj); + tmp_floor_sum -=3D ifaceBand->in->floor; + virNetworkObjPrivateSetFloorSum(obj, tmp_floor_sum); + /* return class ID */ - ignore_value(virBitmapClearBit(net->class_id, + obj_class_id =3D virNetworkObjPrivateGetClassId(obj); + ignore_value(virBitmapClearBit(obj_class_id, iface->data.network.actual->class_i= d)); + /* update status file */ - if (virNetworkSaveStatus(driver->stateDir, net) < 0) { - net->floor_sum +=3D ifaceBand->in->floor; - ignore_value(virBitmapSetBit(net->class_id, + if (virNetworkObjSaveStatus(driver->stateDir, obj) < 0) { + tmp_floor_sum +=3D ifaceBand->in->floor; + virNetworkObjPrivateSetFloorSum(obj, tmp_floor_sum); + ignore_value(virBitmapSetBit(obj_class_id, iface->data.network.actual->class= _id)); goto cleanup; } /* update rate for non guaranteed NICs */ - new_rate -=3D net->floor_sum; - if (virNetDevBandwidthUpdateRate(net->def->bridge, 2, - net->def->bandwidth, new_rate) < = 0) + new_rate -=3D tmp_floor_sum; + if (virNetDevBandwidthUpdateRate(def->bridge, 2, + def->bandwidth, new_rate) < 0) VIR_WARN("Unable to update rate for 1:2 class on %s bridge", - net->def->bridge); + def->bridge); /* no class is associated any longer */ iface->data.network.actual->class_id =3D 0; } @@ -5334,17 +5426,18 @@ networkUnplugBandwidth(virNetworkObjPtr net, return ret; } =20 + static void -networkNetworkObjTaint(virNetworkObjPtr net, +networkNetworkObjTaint(virPoolObjPtr obj, virNetworkTaintFlags taint) { - if (virNetworkObjTaint(net, taint)) { + if (virNetworkObjPrivateIsTaint(obj, taint)) { + virNetworkDefPtr def =3D virPoolObjGetDef(obj); char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(net->def->uuid, uuidstr); + virUUIDFormat(def->uuid, uuidstr); =20 VIR_WARN("Network name=3D'%s' uuid=3D%s is tainted: %s", - net->def->name, - uuidstr, + def->name, uuidstr, virNetworkTaintTypeToString(taint)); } } @@ -5379,29 +5472,24 @@ bool networkBandwidthChangeAllowed(virDomainNetDefPtr iface, virNetDevBandwidthPtr newBandwidth) { - virNetworkDriverStatePtr driver =3D networkGetDriver(); - virNetworkObjPtr network =3D NULL; + virPoolObjPtr obj =3D NULL; virNetDevBandwidthPtr ifaceBand =3D virDomainNetGetActualBandwidth(ifa= ce); bool ret =3D false; =20 if (!networkBandwidthGenericChecks(iface, newBandwidth)) return true; =20 - network =3D virNetworkObjFindByName(driver->networks, iface->data.netw= ork.name); - if (!network) { - virReportError(VIR_ERR_NO_NETWORK, - _("no network with matching name '%s'"), - iface->data.network.name); + if (!(obj =3D networkObjFindByName(iface->data.network.name))) return false; - } =20 - if (networkCheckBandwidth(network, newBandwidth, ifaceBand, iface->mac= , NULL) < 0) + if (networkCheckBandwidth(obj, newBandwidth, ifaceBand, + iface->mac, NULL) < 0) goto cleanup; =20 ret =3D true; =20 cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 @@ -5411,24 +5499,22 @@ networkBandwidthUpdate(virDomainNetDefPtr iface, virNetDevBandwidthPtr newBandwidth) { virNetworkDriverStatePtr driver =3D networkGetDriver(); - virNetworkObjPtr network =3D NULL; + virPoolObjPtr obj; + virNetworkDefPtr def; virNetDevBandwidthPtr ifaceBand =3D virDomainNetGetActualBandwidth(ifa= ce); unsigned long long new_rate =3D 0; + unsigned long long tmp_floor_sum; int plug_ret; int ret =3D -1; =20 if (!networkBandwidthGenericChecks(iface, newBandwidth)) return 0; =20 - network =3D virNetworkObjFindByName(driver->networks, iface->data.netw= ork.name); - if (!network) { - virReportError(VIR_ERR_NO_NETWORK, - _("no network with matching name '%s'"), - iface->data.network.name); - return ret; - } + if (!(obj =3D networkObjFindByName(iface->data.network.name))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if ((plug_ret =3D networkCheckBandwidth(network, newBandwidth, ifaceBa= nd, + if ((plug_ret =3D networkCheckBandwidth(obj, newBandwidth, ifaceBand, iface->mac, &new_rate)) < 0) { /* helper reported error */ goto cleanup; @@ -5446,43 +5532,47 @@ networkBandwidthUpdate(virDomainNetDefPtr iface, newBandwidth && newBandwidth->in && newBandwidth->in->floor) { /* Either we just need to update @floor .. */ =20 - if (virNetDevBandwidthUpdateRate(network->def->bridge, + if (virNetDevBandwidthUpdateRate(def->bridge, iface->data.network.actual->class= _id, - network->def->bandwidth, + def->bandwidth, newBandwidth->in->floor) < 0) goto cleanup; =20 - network->floor_sum -=3D ifaceBand->in->floor; - network->floor_sum +=3D newBandwidth->in->floor; - new_rate -=3D network->floor_sum; + tmp_floor_sum =3D virNetworkObjPrivateGetFloorSum(obj); + tmp_floor_sum -=3D ifaceBand->in->floor; + tmp_floor_sum +=3D newBandwidth->in->floor; + virNetworkObjPrivateSetFloorSum(obj, tmp_floor_sum); + new_rate -=3D tmp_floor_sum; =20 - if (virNetDevBandwidthUpdateRate(network->def->bridge, 2, - network->def->bandwidth, new_rate= ) < 0 || - virNetworkSaveStatus(driver->stateDir, network) < 0) { + if (virNetDevBandwidthUpdateRate(def->bridge, 2, + def->bandwidth, new_rate) < 0 || + virNetworkObjSaveStatus(driver->stateDir, obj) < 0) { /* Ouch, rollback */ - network->floor_sum -=3D newBandwidth->in->floor; - network->floor_sum +=3D ifaceBand->in->floor; + tmp_floor_sum -=3D newBandwidth->in->floor; + tmp_floor_sum +=3D ifaceBand->in->floor; + virNetworkObjPrivateSetFloorSum(obj, tmp_floor_sum); =20 - ignore_value(virNetDevBandwidthUpdateRate(network->def->bridge, + ignore_value(virNetDevBandwidthUpdateRate(def->bridge, iface->data.network.= actual->class_id, - network->def->bandwi= dth, + def->bandwidth, ifaceBand->in->floor= )); goto cleanup; } } else if (newBandwidth->in && newBandwidth->in->floor) { /* .. or we need to plug in new .. */ =20 - if (networkPlugBandwidthImpl(network, iface, newBandwidth, new_rat= e) < 0) + if (networkPlugBandwidthImpl(obj, iface, newBandwidth, new_rate) <= 0) goto cleanup; } else { /* .. or unplug old. */ =20 - if (networkUnplugBandwidth(network, iface) < 0) + if (networkUnplugBandwidth(obj, iface) < 0) goto cleanup; } =20 ret =3D 0; + cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } diff --git a/src/network/bridge_driver.h b/src/network/bridge_driver.h index ff7f921..8962732 100644 --- a/src/network/bridge_driver.h +++ b/src/network/bridge_driver.h @@ -30,6 +30,7 @@ # include "domain_conf.h" # include "vircommand.h" # include "virdnsmasq.h" +# include "virpoolobj.h" =20 int networkRegister(void); =20 @@ -50,11 +51,11 @@ int networkGetNetworkAddress(const char *netname, char = **netaddr) int networkGetActualType(virDomainNetDefPtr iface) ATTRIBUTE_NONNULL(1); =20 -int networkDnsmasqConfContents(virNetworkObjPtr network, - const char *pidfile, - char **configstr, - dnsmasqContext *dctx, - dnsmasqCapsPtr caps); +int networkDnsmasqConfContents(virPoolObjPtr obj, + const char *pidfile, + char **configstr, + dnsmasqContext *dctx, + dnsmasqCapsPtr caps); =20 bool networkBandwidthChangeAllowed(virDomainNetDefPtr iface, virNetDevBandwidthPtr newBandwidth) diff --git a/src/network/bridge_driver_platform.h b/src/network/bridge_driv= er_platform.h index 904e731..3ab24cd 100644 --- a/src/network/bridge_driver_platform.h +++ b/src/network/bridge_driver_platform.h @@ -29,13 +29,14 @@ # include "virdnsmasq.h" # include "network_conf.h" # include "object_event.h" +# include "virpoolobj.h" =20 /* Main driver state */ struct _virNetworkDriverState { virMutex lock; =20 /* Immutable pointer, self-locking APIs */ - virNetworkObjListPtr networks; + virPoolObjTablePtr networks; =20 /* Immutable pointers, Immutable objects */ char *networkConfigDir; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 26924b5..cbffcbb 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -42,7 +42,7 @@ #include "capabilities.h" #include "configmake.h" #include "viralloc.h" -#include "network_conf.h" +#include "virnetworkobj.h" #include "interface_conf.h" #include "domain_conf.h" #include "domain_event.h" @@ -120,7 +120,7 @@ struct _testDriver { =20 /* immutable pointer, self-locking APIs */ virDomainObjListPtr domains; - virNetworkObjListPtr networks; + virPoolObjTablePtr networks; virObjectEventStatePtr eventState; }; typedef struct _testDriver testDriver; @@ -429,7 +429,9 @@ testDriverNew(void) VIR_POOLOBJTABLE_BLOCK_STORAGE_HASHSTART, false)) || !(ret->domains =3D virDomainObjListNew()) || - !(ret->networks =3D virNetworkObjListNew())) + !(ret->networks =3D + virPoolObjTableNew(VIR_POOLOBJTABLE_NETWORK, + VIR_POOLOBJTABLE_NETWORK_HASHSTART, false))) goto error; =20 virAtomicIntSet(&ret->nextDomID, 1); @@ -941,7 +943,7 @@ testParseNetworks(testDriverPtr privconn, int num, ret =3D -1; size_t i; xmlNodePtr *nodes =3D NULL; - virNetworkObjPtr obj; + virPoolObjPtr obj; =20 num =3D virXPathNodeSet("/node/network", ctxt, &nodes); if (num < 0) @@ -957,13 +959,13 @@ testParseNetworks(testDriverPtr privconn, if (!def) goto error; =20 - if (!(obj =3D virNetworkAssignDef(privconn->networks, def, 0))) { + if (!(obj =3D virNetworkObjAdd(privconn->networks, def, 0))) { virNetworkDefFree(def); goto error; } =20 - obj->active =3D 1; - virNetworkObjEndAPI(&obj); + virPoolObjSetActive(obj, true); + virPoolObjEndAPI(&obj); } =20 ret =3D 0; @@ -3187,85 +3189,114 @@ static int testDomainInterfaceStats(virDomainPtr d= omain, } =20 =20 -static virNetworkPtr testNetworkLookupByUUID(virConnectPtr conn, - const unsigned char *uuid) +static virPoolObjPtr +testNetworkObjFindByUUID(virPoolObjTablePtr networks, + const unsigned char *uuid) +{ + virPoolObjPtr obj; + + if (!(obj =3D virPoolObjTableFindByUUIDRef(networks, uuid))) + virReportError(VIR_ERR_NO_NETWORK, NULL); + + return obj; +} + + +static virPoolObjPtr +testNetworkObjFindByName(virPoolObjTablePtr networks, + const char *name) +{ + virPoolObjPtr obj; + + if (!(obj =3D virPoolObjTableFindByName(networks, name))) + virReportError(VIR_ERR_NO_NETWORK, NULL); + + return obj; +} + + +static virNetworkPtr +testNetworkLookupByUUID(virConnectPtr conn, + const unsigned char *uuid) { testDriverPtr privconn =3D conn->privateData; - virNetworkObjPtr net; + virPoolObjPtr obj; + virNetworkDefPtr def; virNetworkPtr ret =3D NULL; =20 - net =3D virNetworkObjFindByUUID(privconn->networks, uuid); - if (net =3D=3D NULL) { - virReportError(VIR_ERR_NO_NETWORK, NULL); - goto cleanup; - } + if (!(obj =3D testNetworkObjFindByUUID(privconn->networks, uuid))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - ret =3D virGetNetwork(conn, net->def->name, net->def->uuid); + ret =3D virGetNetwork(conn, def->name, def->uuid); =20 - cleanup: - virNetworkObjEndAPI(&net); + virPoolObjEndAPI(&obj); return ret; } =20 -static virNetworkPtr testNetworkLookupByName(virConnectPtr conn, - const char *name) + +static virNetworkPtr +testNetworkLookupByName(virConnectPtr conn, + const char *name) { testDriverPtr privconn =3D conn->privateData; - virNetworkObjPtr net; + virPoolObjPtr obj; + virNetworkDefPtr def; virNetworkPtr ret =3D NULL; =20 - net =3D virNetworkObjFindByName(privconn->networks, name); - if (net =3D=3D NULL) { - virReportError(VIR_ERR_NO_NETWORK, NULL); - goto cleanup; - } + if (!(obj =3D testNetworkObjFindByName(privconn->networks, name))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - ret =3D virGetNetwork(conn, net->def->name, net->def->uuid); + ret =3D virGetNetwork(conn, def->name, def->uuid); =20 - cleanup: - virNetworkObjEndAPI(&net); + virPoolObjEndAPI(&obj); return ret; } =20 =20 -static int testConnectNumOfNetworks(virConnectPtr conn) +static int +testConnectNumOfNetworks(virConnectPtr conn) { testDriverPtr privconn =3D conn->privateData; - int numActive; =20 - numActive =3D virNetworkObjListNumOfNetworks(privconn->networks, - true, NULL, conn); - return numActive; + return virNetworkObjNumOfNetworks(privconn->networks, conn, true, NULL= ); } =20 -static int testConnectListNetworks(virConnectPtr conn, char **const names,= int nnames) { + +static int +testConnectListNetworks(virConnectPtr conn, + char **const names, + int maxnames) +{ testDriverPtr privconn =3D conn->privateData; - int n; =20 - n =3D virNetworkObjListGetNames(privconn->networks, - true, names, nnames, NULL, conn); - return n; + return virNetworkObjGetNames(privconn->networks, conn, true, NULL, + names, maxnames); } =20 -static int testConnectNumOfDefinedNetworks(virConnectPtr conn) + +static int +testConnectNumOfDefinedNetworks(virConnectPtr conn) { testDriverPtr privconn =3D conn->privateData; - int numInactive; =20 - numInactive =3D virNetworkObjListNumOfNetworks(privconn->networks, - false, NULL, conn); - return numInactive; + return virNetworkObjNumOfNetworks(privconn->networks, conn, false, NUL= L); } =20 -static int testConnectListDefinedNetworks(virConnectPtr conn, char **const= names, int nnames) { + +static int +testConnectListDefinedNetworks(virConnectPtr conn, + char **const names, + int maxnames) +{ testDriverPtr privconn =3D conn->privateData; - int n; =20 - n =3D virNetworkObjListGetNames(privconn->networks, - false, names, nnames, NULL, conn); - return n; + return virNetworkObjGetNames(privconn->networks, conn, false, NULL, + names, maxnames); } =20 + static int testConnectListAllNetworks(virConnectPtr conn, virNetworkPtr **nets, @@ -3275,139 +3306,144 @@ testConnectListAllNetworks(virConnectPtr conn, =20 virCheckFlags(VIR_CONNECT_LIST_NETWORKS_FILTERS_ALL, -1); =20 - return virNetworkObjListExport(conn, privconn->networks, nets, NULL, f= lags); + return virNetworkObjExportList(conn, privconn->networks, nets, NULL, f= lags); } =20 -static int testNetworkIsActive(virNetworkPtr net) + +static int +testNetworkIsActive(virNetworkPtr net) { testDriverPtr privconn =3D net->conn->privateData; - virNetworkObjPtr obj; + virPoolObjPtr obj; int ret =3D -1; =20 - obj =3D virNetworkObjFindByUUID(privconn->networks, net->uuid); - if (!obj) { - virReportError(VIR_ERR_NO_NETWORK, NULL); - goto cleanup; - } - ret =3D virNetworkObjIsActive(obj); + if (!(obj =3D testNetworkObjFindByUUID(privconn->networks, net->uuid))) + return -1; =20 - cleanup: - virNetworkObjEndAPI(&obj); + ret =3D virPoolObjIsActive(obj); + + virPoolObjEndAPI(&obj); return ret; } =20 -static int testNetworkIsPersistent(virNetworkPtr net) + +static int +testNetworkIsPersistent(virNetworkPtr net) { testDriverPtr privconn =3D net->conn->privateData; - virNetworkObjPtr obj; + virPoolObjPtr obj; int ret =3D -1; =20 - obj =3D virNetworkObjFindByUUID(privconn->networks, net->uuid); - if (!obj) { - virReportError(VIR_ERR_NO_NETWORK, NULL); - goto cleanup; - } - ret =3D obj->persistent; + if (!(obj =3D testNetworkObjFindByUUID(privconn->networks, net->uuid))) + return -1; =20 - cleanup: - virNetworkObjEndAPI(&obj); + ret =3D virPoolObjIsPersistent(obj); + + virPoolObjEndAPI(&obj); return ret; } =20 =20 -static virNetworkPtr testNetworkCreateXML(virConnectPtr conn, const char *= xml) +static virNetworkPtr +testNetworkCreateXML(virConnectPtr conn, + const char *xml) { testDriverPtr privconn =3D conn->privateData; virNetworkDefPtr def; - virNetworkObjPtr net =3D NULL; + virPoolObjPtr obj; + virNetworkDefPtr objdef; virNetworkPtr ret =3D NULL; virObjectEventPtr event =3D NULL; =20 - if ((def =3D virNetworkDefParseString(xml)) =3D=3D NULL) - goto cleanup; + if (!(def =3D virNetworkDefParseString(xml))) + return NULL; =20 - if (!(net =3D virNetworkAssignDef(privconn->networks, def, - VIR_NETWORK_OBJ_LIST_ADD_LIVE | - VIR_NETWORK_OBJ_LIST_ADD_CHECK_LIVE))) + if (!(obj =3D virNetworkObjAdd(privconn->networks, def, + VIR_NETWORK_OBJ_LIST_ADD_LIVE | + VIR_NETWORK_OBJ_LIST_ADD_CHECK_LIVE))) goto cleanup; - def =3D NULL; - net->active =3D 1; + VIR_STEAL_PTR(objdef, def); + virPoolObjSetActive(obj, true); =20 - event =3D virNetworkEventLifecycleNew(net->def->name, net->def->uuid, + event =3D virNetworkEventLifecycleNew(objdef->name, objdef->uuid, VIR_NETWORK_EVENT_STARTED, 0); =20 - ret =3D virGetNetwork(conn, net->def->name, net->def->uuid); + ret =3D virGetNetwork(conn, objdef->name, objdef->uuid); =20 cleanup: virNetworkDefFree(def); testObjectEventQueue(privconn, event); - virNetworkObjEndAPI(&net); + virPoolObjEndAPI(&obj); return ret; } =20 -static -virNetworkPtr testNetworkDefineXML(virConnectPtr conn, const char *xml) + +static virNetworkPtr +testNetworkDefineXML(virConnectPtr conn, + const char *xml) { testDriverPtr privconn =3D conn->privateData; virNetworkDefPtr def; - virNetworkObjPtr net =3D NULL; + virPoolObjPtr obj =3D NULL; + virNetworkDefPtr objdef; virNetworkPtr ret =3D NULL; virObjectEventPtr event =3D NULL; =20 - if ((def =3D virNetworkDefParseString(xml)) =3D=3D NULL) - goto cleanup; + if (!(def =3D virNetworkDefParseString(xml))) + return NULL; =20 - if (!(net =3D virNetworkAssignDef(privconn->networks, def, 0))) + if (!(obj =3D virNetworkObjAdd(privconn->networks, def, 0))) goto cleanup; - def =3D NULL; + VIR_STEAL_PTR(objdef, def); =20 - event =3D virNetworkEventLifecycleNew(net->def->name, net->def->uuid, + event =3D virNetworkEventLifecycleNew(objdef->name, objdef->uuid, VIR_NETWORK_EVENT_DEFINED, 0); =20 - ret =3D virGetNetwork(conn, net->def->name, net->def->uuid); + ret =3D virGetNetwork(conn, objdef->name, objdef->uuid); =20 cleanup: virNetworkDefFree(def); testObjectEventQueue(privconn, event); - virNetworkObjEndAPI(&net); + virPoolObjEndAPI(&obj); return ret; } =20 -static int testNetworkUndefine(virNetworkPtr network) + +static int +testNetworkUndefine(virNetworkPtr network) { testDriverPtr privconn =3D network->conn->privateData; - virNetworkObjPtr privnet; + virPoolObjPtr obj; + virNetworkDefPtr def; int ret =3D -1; virObjectEventPtr event =3D NULL; =20 - privnet =3D virNetworkObjFindByName(privconn->networks, network->name); - - if (privnet =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testNetworkObjFindByName(privconn->networks, network->na= me))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkObjIsActive(privnet)) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Network '%s' is still running"), network->name); + _("Network '%s' is still running"), def->name); goto cleanup; } =20 - event =3D virNetworkEventLifecycleNew(network->name, network->uuid, + event =3D virNetworkEventLifecycleNew(def->name, def->uuid, VIR_NETWORK_EVENT_UNDEFINED, 0); =20 - virNetworkRemoveInactive(privconn->networks, privnet); + virPoolObjTableRemove(privconn->networks, &obj); ret =3D 0; =20 cleanup: testObjectEventQueue(privconn, event); - virNetworkObjEndAPI(&privnet); + virPoolObjEndAPI(&obj); return ret; } =20 + static int testNetworkUpdate(virNetworkPtr net, unsigned int command, @@ -3417,24 +3453,20 @@ testNetworkUpdate(virNetworkPtr net, unsigned int flags) { testDriverPtr privconn =3D net->conn->privateData; - virNetworkObjPtr network =3D NULL; + virPoolObjPtr obj =3D NULL; int isActive, ret =3D -1; =20 virCheckFlags(VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG, -1); =20 - network =3D virNetworkObjFindByUUID(privconn->networks, net->uuid); - if (!network) { - virReportError(VIR_ERR_NO_NETWORK, - "%s", _("no network with matching uuid")); - goto cleanup; - } + if (!(obj =3D testNetworkObjFindByUUID(privconn->networks, net->uuid))) + return -1; =20 /* VIR_NETWORK_UPDATE_AFFECT_CURRENT means "change LIVE if network * is active, else change CONFIG */ - isActive =3D virNetworkObjIsActive(network); + isActive =3D virPoolObjIsActive(obj); if ((flags & (VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG)) =3D=3D VIR_NETWORK_UPDATE_AFFECT_CURRENT) { @@ -3445,160 +3477,159 @@ testNetworkUpdate(virNetworkPtr net, } =20 /* update the network config in memory/on disk */ - if (virNetworkObjUpdate(network, command, section, parentIndex, xml, f= lags) < 0) + if (virNetworkObjUpdate(obj, command, section, parentIndex, xml, flags= ) < 0) goto cleanup; =20 ret =3D 0; cleanup: - virNetworkObjEndAPI(&network); + virPoolObjEndAPI(&obj); return ret; } =20 -static int testNetworkCreate(virNetworkPtr network) + +static int +testNetworkCreate(virNetworkPtr network) { testDriverPtr privconn =3D network->conn->privateData; - virNetworkObjPtr privnet; + virPoolObjPtr obj; + virNetworkDefPtr def; int ret =3D -1; virObjectEventPtr event =3D NULL; =20 - privnet =3D virNetworkObjFindByName(privconn->networks, network->name); - if (privnet =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testNetworkObjFindByName(privconn->networks, network->na= me))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - if (virNetworkObjIsActive(privnet)) { + if (virPoolObjIsActive(obj)) { virReportError(VIR_ERR_OPERATION_INVALID, - _("Network '%s' is already running"), network->name= ); + _("Network '%s' is already running"), def->name); goto cleanup; } =20 - privnet->active =3D 1; - event =3D virNetworkEventLifecycleNew(privnet->def->name, privnet->def= ->uuid, + virPoolObjSetActive(obj, true); + event =3D virNetworkEventLifecycleNew(def->name, def->uuid, VIR_NETWORK_EVENT_STARTED, 0); ret =3D 0; =20 cleanup: testObjectEventQueue(privconn, event); - virNetworkObjEndAPI(&privnet); + virPoolObjEndAPI(&obj); return ret; } =20 -static int testNetworkDestroy(virNetworkPtr network) + +static int +testNetworkDestroy(virNetworkPtr network) { testDriverPtr privconn =3D network->conn->privateData; - virNetworkObjPtr privnet; + virPoolObjPtr obj; + virNetworkDefPtr def; int ret =3D -1; virObjectEventPtr event =3D NULL; =20 - privnet =3D virNetworkObjFindByName(privconn->networks, network->name); - if (privnet =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testNetworkObjFindByName(privconn->networks, network->na= me))) + return -1; + def =3D virPoolObjGetDef(obj); =20 - privnet->active =3D 0; - event =3D virNetworkEventLifecycleNew(privnet->def->name, privnet->def= ->uuid, + virPoolObjSetActive(obj, false); + event =3D virNetworkEventLifecycleNew(def->name, def->uuid, VIR_NETWORK_EVENT_STOPPED, 0); - if (!privnet->persistent) - virNetworkRemoveInactive(privconn->networks, privnet); + if (!virPoolObjIsPersistent(obj)) + virPoolObjTableRemove(privconn->networks, &obj); =20 ret =3D 0; =20 - cleanup: testObjectEventQueue(privconn, event); - virNetworkObjEndAPI(&privnet); + virPoolObjEndAPI(&obj); return ret; } =20 -static char *testNetworkGetXMLDesc(virNetworkPtr network, - unsigned int flags) + +static char * +testNetworkGetXMLDesc(virNetworkPtr network, + unsigned int flags) { testDriverPtr privconn =3D network->conn->privateData; - virNetworkObjPtr privnet; + virPoolObjPtr obj; + virNetworkDefPtr def; char *ret =3D NULL; =20 virCheckFlags(0, NULL); =20 - privnet =3D virNetworkObjFindByName(privconn->networks, network->name); - if (privnet =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testNetworkObjFindByName(privconn->networks, network->na= me))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - ret =3D virNetworkDefFormat(privnet->def, flags); + ret =3D virNetworkDefFormat(def, flags); =20 - cleanup: - virNetworkObjEndAPI(&privnet); + virPoolObjEndAPI(&obj); return ret; } =20 -static char *testNetworkGetBridgeName(virNetworkPtr network) { + +static char * +testNetworkGetBridgeName(virNetworkPtr network) +{ testDriverPtr privconn =3D network->conn->privateData; char *bridge =3D NULL; - virNetworkObjPtr privnet; + virPoolObjPtr obj; + virNetworkDefPtr def; =20 - privnet =3D virNetworkObjFindByName(privconn->networks, network->name); - if (privnet =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testNetworkObjFindByName(privconn->networks, network->na= me))) + return NULL; + def =3D virPoolObjGetDef(obj); =20 - if (!(privnet->def->bridge)) { + if (!def->bridge) { virReportError(VIR_ERR_INTERNAL_ERROR, _("network '%s' does not have a bridge name."), - privnet->def->name); + def->name); goto cleanup; } =20 - ignore_value(VIR_STRDUP(bridge, privnet->def->bridge)); + ignore_value(VIR_STRDUP(bridge, def->bridge)); =20 cleanup: - virNetworkObjEndAPI(&privnet); + virPoolObjEndAPI(&obj); return bridge; } =20 -static int testNetworkGetAutostart(virNetworkPtr network, - int *autostart) + +static int +testNetworkGetAutostart(virNetworkPtr network, + int *autostart) { testDriverPtr privconn =3D network->conn->privateData; - virNetworkObjPtr privnet; + virPoolObjPtr obj; int ret =3D -1; =20 - privnet =3D virNetworkObjFindByName(privconn->networks, network->name); - if (privnet =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testNetworkObjFindByName(privconn->networks, network->na= me))) + return -1; =20 - *autostart =3D privnet->autostart; + *autostart =3D virPoolObjIsAutostart(obj); ret =3D 0; =20 - cleanup: - virNetworkObjEndAPI(&privnet); + virPoolObjEndAPI(&obj); return ret; } =20 -static int testNetworkSetAutostart(virNetworkPtr network, - int autostart) + +static int +testNetworkSetAutostart(virNetworkPtr network, + int autostart) { testDriverPtr privconn =3D network->conn->privateData; - virNetworkObjPtr privnet; + virPoolObjPtr obj; int ret =3D -1; =20 - privnet =3D virNetworkObjFindByName(privconn->networks, network->name); - if (privnet =3D=3D NULL) { - virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); - goto cleanup; - } + if (!(obj =3D testNetworkObjFindByName(privconn->networks, network->na= me))) + return -1; =20 - privnet->autostart =3D autostart ? 1 : 0; + virPoolObjSetAutostart(obj, autostart ? true : false); ret =3D 0; =20 - cleanup: - virNetworkObjEndAPI(&privnet); + virPoolObjEndAPI(&obj); return ret; } =20 diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c index 9b61077..73603bb 100644 --- a/tests/networkxml2conftest.c +++ b/tests/networkxml2conftest.c @@ -23,22 +23,21 @@ testCompareXMLToConfFiles(const char *inxml, const char= *outconf, dnsmasqCapsPtr { char *actual =3D NULL; int ret =3D -1; - virNetworkDefPtr dev =3D NULL; - virNetworkObjPtr obj =3D NULL; + virNetworkDefPtr def =3D NULL; + virPoolObjPtr obj =3D NULL; + virNetworkDefPtr objdef; virCommandPtr cmd =3D NULL; char *pidfile =3D NULL; dnsmasqContext *dctx =3D NULL; =20 - if (!(dev =3D virNetworkDefParseFile(inxml))) + if (!(def =3D virNetworkDefParseFile(inxml))) goto fail; =20 - if (!(obj =3D virNetworkObjNew())) + if (!(obj =3D virPoolObjNew(NULL, def, NULL, virNetworkDefFree))) goto fail; + VIR_STEAL_PTR(objdef, def); =20 - obj->def =3D dev; - dctx =3D dnsmasqContextNew(dev->name, "/var/lib/libvirt/dnsmasq"); - - if (dctx =3D=3D NULL) + if (!(dctx =3D dnsmasqContextNew(objdef->name, "/var/lib/libvirt/dnsma= sq"))) goto fail; =20 if (networkDnsmasqConfContents(obj, pidfile, &actual, dctx, caps) < 0) @@ -66,8 +65,9 @@ testCompareXMLToConfFiles(const char *inxml, const char *= outconf, dnsmasqCapsPtr VIR_FREE(actual); VIR_FREE(pidfile); virCommandFree(cmd); - virObjectUnref(obj); dnsmasqContextFree(dctx); + virObjectUnref(obj); + virNetworkDefFree(def); return ret; } =20 --=20 2.7.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list