From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523370296713.123966628373; Wed, 23 Aug 2017 14:22:50 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 804D74A707; Wed, 23 Aug 2017 21:22:48 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 541815D75C; Wed, 23 Aug 2017 21:22:48 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 1A5AF1806103; Wed, 23 Aug 2017 21:22:48 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLMc5a023945 for ; Wed, 23 Aug 2017 17:22:38 -0400 Received: by smtp.corp.redhat.com (Postfix) id 7292780DB1; Wed, 23 Aug 2017 21:22:38 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id E6F9366D36 for ; Wed, 23 Aug 2017 21:22:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 804D74A707 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:21:57 -0400 Message-Id: <20170823212211.4693-2-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 01/15] util: Use VIR_ERROR instead of VIR_WARN 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 23 Aug 2017 21:22:49 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Rather than use VIR_WARN, let's be a bit more forceful and direct using VIR_ERROR so that the "average consumer" may actually be more concerned that something is wrong even though we still continue to operate. Signed-off-by: John Ferlan --- src/util/virobject.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/util/virobject.c b/src/util/virobject.c index cfa821c..38db692 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -49,17 +49,17 @@ struct _virClass { =20 #define VIR_OBJECT_NOTVALID(obj) (!obj || ((obj->u.s.magic & 0xFFFF0000) != =3D 0xCAFE0000)) =20 -#define VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, objclass) = \ +#define VIR_OBJECT_USAGE_PRINT_ERROR(anyobj, objclass) = \ do { = \ virObjectPtr obj =3D anyobj; = \ if (VIR_OBJECT_NOTVALID(obj)) { = \ if (!obj) = \ - VIR_WARN("Object cannot be NULL"); = \ + VIR_ERROR(_("Object cannot be NULL")); = \ else = \ - VIR_WARN("Object %p has a bad magic number %X", = \ + VIR_ERROR(_("Object %p has a bad magic number %X"), = \ obj, obj->u.s.magic); = \ } else { = \ - VIR_WARN("Object %p (%s) is not a %s instance", = \ + VIR_ERROR(_("Object %p (%s) is not a %s instance"), = \ anyobj, obj->klass->name, #objclass); = \ } = \ } while (0) @@ -396,7 +396,7 @@ virObjectGetLockableObj(void *anyobj) if (virObjectIsClass(anyobj, virObjectLockableClass)) return anyobj; =20 - VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, virObjectLockable); + VIR_OBJECT_USAGE_PRINT_ERROR(anyobj, virObjectLockable); return NULL; } =20 @@ -407,7 +407,7 @@ virObjectGetRWLockableObj(void *anyobj) if (virObjectIsClass(anyobj, virObjectRWLockableClass)) return anyobj; =20 - VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, virObjectRWLockable); + VIR_OBJECT_USAGE_PRINT_ERROR(anyobj, virObjectRWLockable); return NULL; } =20 --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523375323981.9562307721267; Wed, 23 Aug 2017 14:22:55 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1CFCC806A6; Wed, 23 Aug 2017 21:22:48 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id ED0B369566; Wed, 23 Aug 2017 21:22:47 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id B2D8D4EE50; Wed, 23 Aug 2017 21:22:47 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLMjK0023961 for ; Wed, 23 Aug 2017 17:22:45 -0400 Received: by smtp.corp.redhat.com (Postfix) id C0B5366D39; Wed, 23 Aug 2017 21:22:45 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id E58C281EEB for ; Wed, 23 Aug 2017 21:22:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 1CFCC806A6 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:21:58 -0400 Message-Id: <20170823212211.4693-3-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 02/15] util: Introduce virObjectLookupHash 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 23 Aug 2017 21:22:53 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Define an object meant to combine/manage the aspects of the various _vir*ObjList structs into one common purpose list management system that will store and manage _vir*Obj virObjectLockable objects rather than having multiple structs and API's to do that. The object will use the virObjectRWLockable class as the base and may have one or two hash tables that will be keyed by UUID or Name based on the needs of the consumer stored in: objsUUID -> Hash table for storing objects for lookup by UUID objsName -> Hash table for storing objects for lookup by Name The virObjectLookupHashNew will require the consumer to provide which hash tables are to be used via virObjectLookupHashNewFlags. A secondary benefit of self locking hash tables is each driver then does not have to keep a higher level driver lock for interactions with the object storage since the object itself can manage locking as needed. Signed-off-by: John Ferlan --- src/libvirt_private.syms | 2 ++ src/util/virobject.c | 93 ++++++++++++++++++++++++++++++++++++++++++++= +++- src/util/virobject.h | 34 ++++++++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2149b11..33dbd92 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2318,6 +2318,7 @@ virNumaSetupMemoryPolicy; # util/virobject.h virClassForObject; virClassForObjectLockable; +virClassForObjectLookupHash; virClassForObjectRWLockable; virClassIsDerivedFrom; virClassName; @@ -2329,6 +2330,7 @@ virObjectListFree; virObjectListFreeCount; virObjectLock; virObjectLockableNew; +virObjectLookupHashNew; virObjectNew; virObjectRef; virObjectRWLockableNew; diff --git a/src/util/virobject.c b/src/util/virobject.c index 38db692..edd8097 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -68,9 +68,11 @@ struct _virClass { static virClassPtr virObjectClass; static virClassPtr virObjectLockableClass; static virClassPtr virObjectRWLockableClass; +static virClassPtr virObjectLookupHashClass; =20 static void virObjectLockableDispose(void *anyobj); static void virObjectRWLockableDispose(void *anyobj); +static void virObjectLookupHashDispose(void *anyobj); =20 static int virObjectOnceInit(void) @@ -93,6 +95,12 @@ virObjectOnceInit(void) virObjectRWLockableDispos= e))) return -1; =20 + if (!(virObjectLookupHashClass =3D virClassNew(virObjectRWLockableClas= s, + "virObjectLookupHash", + sizeof(virObjectLookupHas= h), + virObjectLookupHashDispos= e))) + return -1; + return 0; } =20 @@ -145,6 +153,21 @@ virClassForObjectRWLockable(void) =20 =20 /** + * virClassForObjectLookupHash: + * + * Returns the class instance for the virObjectLookupHash type + */ +virClassPtr +virClassForObjectLookupHash(void) +{ + if (virObjectInitialize() < 0) + return NULL; + + return virObjectLookupHashClass; +} + + +/** * virClassNew: * @parent: the parent class * @name: the class name @@ -328,6 +351,73 @@ virObjectRWLockableDispose(void *anyobj) =20 =20 /** + * virObjectLookupHashNew: + * @klass: the klass to check + * @tableElemsStart: initial size of each hash table + * @flags: virObjectLookupHashNewFlags to indicate which tables to create + * + * Create a new poolable hash table object for storing either 1 or 2 hash + * tables capable of storing virObjectLockable objects by UUID or Name. Th= is + * object will use the RWLockable objects in order to allow for concurrent + * table reads by multiple threads looking to return lists of data. + * + * Returns: New object on success, NULL on failure w/ error message set + */ +void * +virObjectLookupHashNew(virClassPtr klass, + int tableElemsStart, + virObjectLookupHashNewFlags flags) +{ + virObjectLookupHashPtr obj; + + if (!flags || !(flags & (VIR_OBJECT_LOOKUP_HASH_UUID | + VIR_OBJECT_LOOKUP_HASH_NAME))) { + virReportError(VIR_ERR_INVALID_ARG, + _("flags=3D%x must be non zero or properly set"), f= lags); + return NULL; + } + + if (!virClassIsDerivedFrom(klass, virClassForObjectLookupHash())) { + virReportInvalidArg(klass, + _("Class %s must derive from virObjectLookupHa= sh"), + virClassName(klass)); + return NULL; + } + + if (!(obj =3D virObjectRWLockableNew(klass))) + return NULL; + + if (flags & VIR_OBJECT_LOOKUP_HASH_UUID) { + if (!(obj->objsUUID =3D virHashCreate(tableElemsStart, + virObjectFreeHashData))) + goto error; + } + + if (flags & VIR_OBJECT_LOOKUP_HASH_NAME) { + if (!(obj->objsName =3D virHashCreate(tableElemsStart, + virObjectFreeHashData))) + goto error; + } + + return obj; + + error: + virObjectUnref(obj); + return NULL; +} + + +static void +virObjectLookupHashDispose(void *anyobj) +{ + virObjectLookupHashPtr obj =3D anyobj; + + virHashFree(obj->objsUUID); + virHashFree(obj->objsName); +} + + +/** * virObjectUnref: * @anyobj: any instance of virObjectPtr * @@ -404,7 +494,8 @@ virObjectGetLockableObj(void *anyobj) static virObjectRWLockablePtr virObjectGetRWLockableObj(void *anyobj) { - if (virObjectIsClass(anyobj, virObjectRWLockableClass)) + if (virObjectIsClass(anyobj, virObjectRWLockableClass) || + virObjectIsClass(anyobj, virObjectLookupHashClass)) return anyobj; =20 VIR_OBJECT_USAGE_PRINT_ERROR(anyobj, virObjectRWLockable); diff --git a/src/util/virobject.h b/src/util/virobject.h index ac6cf22..75efa90 100644 --- a/src/util/virobject.h +++ b/src/util/virobject.h @@ -23,6 +23,7 @@ # define __VIR_OBJECT_H__ =20 # include "internal.h" +# include "virhash.h" # include "virthread.h" =20 typedef struct _virClass virClass; @@ -37,6 +38,9 @@ typedef virObjectLockable *virObjectLockablePtr; typedef struct _virObjectRWLockable virObjectRWLockable; typedef virObjectRWLockable *virObjectRWLockablePtr; =20 +typedef struct _virObjectLookupHash virObjectLookupHash; +typedef virObjectLookupHash *virObjectLookupHashPtr; + typedef void (*virObjectDisposeCallback)(void *obj); =20 /* Most code should not play with the contents of this struct; however, @@ -71,6 +75,24 @@ virClassPtr virClassForObject(void); virClassPtr virClassForObjectLockable(void); virClassPtr virClassForObjectRWLockable(void); =20 +struct _virObjectLookupHash { + virObjectRWLockable parent; + + /* key1 string -> object mapping for O(1), + * lockless lookup-by-uuid */ + virHashTable *objsUUID; + + /* key2 string -> object mapping for O(1), + * lockless lookup-by-name */ + virHashTable *objsName; +}; + + +virClassPtr virClassForObject(void); +virClassPtr virClassForObjectLockable(void); +virClassPtr virClassForObjectRWLockable(void); +virClassPtr virClassForObjectLookupHash(void); + # ifndef VIR_PARENT_REQUIRED # define VIR_PARENT_REQUIRED ATTRIBUTE_NONNULL(1) # endif @@ -120,6 +142,18 @@ void * virObjectRWLockableNew(virClassPtr klass) ATTRIBUTE_NONNULL(1); =20 +typedef enum { + VIR_OBJECT_LOOKUP_HASH_UUID =3D (1 << 0), + VIR_OBJECT_LOOKUP_HASH_NAME =3D (1 << 1), +} virObjectLookupHashNewFlags; + +void * +virObjectLookupHashNew(virClassPtr klass, + int tableElemsStart, + virObjectLookupHashNewFlags flags) + + ATTRIBUTE_NONNULL(1); + void virObjectLock(void *lockableobj) ATTRIBUTE_NONNULL(1); --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 150352337391658.79069159763378; Wed, 23 Aug 2017 14:22:53 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E1AF24A6F6; Wed, 23 Aug 2017 21:22:51 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C359667C9C; Wed, 23 Aug 2017 21:22:51 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 8D39B3FA58; Wed, 23 Aug 2017 21:22:51 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLMlDP023968 for ; Wed, 23 Aug 2017 17:22:47 -0400 Received: by smtp.corp.redhat.com (Postfix) id 60C5480D99; Wed, 23 Aug 2017 21:22:47 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id F316466D36 for ; Wed, 23 Aug 2017 21:22:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com E1AF24A6F6 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:21:59 -0400 Message-Id: <20170823212211.4693-4-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 03/15] util: Introduce virObjectLookupHash{Add|Remove} 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 23 Aug 2017 21:22:52 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add a pair of API's to add/remove an object (virObjectLockable) to/from the LookupHash object. The caller must check return status and handle failure properly for the Add. The Remove API callers are all void functions, so only report the problem and ignore the attempt to remove if for some reason the passed @tableobj is not as expected. Signed-off-by: John Ferlan --- src/libvirt_private.syms | 2 + src/util/virobject.c | 126 +++++++++++++++++++++++++++++++++++++++++++= ++++ src/util/virobject.h | 14 ++++++ 3 files changed, 142 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 33dbd92..e98646c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2330,7 +2330,9 @@ virObjectListFree; virObjectListFreeCount; virObjectLock; virObjectLockableNew; +virObjectLookupHashAdd; virObjectLookupHashNew; +virObjectLookupHashRemove; virObjectNew; virObjectRef; virObjectRWLockableNew; diff --git a/src/util/virobject.c b/src/util/virobject.c index edd8097..76bf1bf 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -731,3 +731,129 @@ virObjectListFreeCount(void *list, =20 VIR_FREE(list); } + + +static virObjectLookupHashPtr +virObjectGetLookupHashObj(void *anyobj) +{ + if (virObjectIsClass(anyobj, virObjectLookupHashClass)) + return anyobj; + + VIR_OBJECT_USAGE_PRINT_ERROR(anyobj, virObjectLookupHashClass); + + return NULL; +} + + +static bool +virObjectLookupHashValidAddRemoveArgs(virObjectLookupHashPtr hashObj, + virObjectLockablePtr obj, + const char *uuidstr, + const char *name) +{ + if (!hashObj || !obj) + return false; + + if (uuidstr && !hashObj->objsUUID) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("no objsUUID for hashObj=3D%p, but uuidstr=3D%s p= rovided"), + hashObj, uuidstr); + return false; + } + + if (name && !hashObj->objsName) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("no objsName for hashObj=3D%p, but name=3D%s prov= ided"), + hashObj, name); + return false; + } + + return true; + +} + + +/** + * virObjectLookupHashAdd: + * @anyobj: LookupHash object + * @addObj: The (virObjectLockable) object to add to the hash table(s) + * @uuidstr: uuid formatted into a char string to add to UUID table + * @name: name to add to Name table + * + * Insert @obj into the hash tables found in @anyobj. Assumes that the + * caller has determined that @uuidstr and @name do not already exist + * in their respective hash table to be inserted. + * + * Returns 0 on success, -1 on failure. + */ +int +virObjectLookupHashAdd(void *anyobj, + void *addObj, + const char *uuidstr, + const char *name) +{ + virObjectLookupHashPtr hashObj =3D virObjectGetLookupHashObj(anyobj); + virObjectLockablePtr obj =3D virObjectGetLockableObj(addObj); + + if (!virObjectLookupHashValidAddRemoveArgs(hashObj, obj, uuidstr, name= )) + return -1; + + if (hashObj->objsUUID) { + if (virHashAddEntry(hashObj->objsUUID, uuidstr, obj) < 0) + return -1; + virObjectRef(obj); + } + + if (hashObj->objsName) { + if (virHashAddEntry(hashObj->objsName, name, obj) < 0) { + if (hashObj->objsUUID) + virHashRemoveEntry(hashObj->objsUUID, uuidstr); + return -1; + } + virObjectRef(obj); + } + + return 0; +} + + +/** + * virObjectLookupHashRemove: + * @anyobj: LookupHash object + * @delObj: The (virObjectLockable) object to remove from the hash table(s) + * @uuidstr: uuid formatted into a char string to add to UUID table + * @name: name to add to Name table + * + * Remove @obj from the hash tables found in @anyobj. The common + * function to remove an object from a hash table will also cause + * the virObjectUnref to be called via virObjectFreeHashData since + * the virHashCreate used that as the Free object element argument. + * + * NB: Caller must first check if @obj is NULL before calling. + * + * Even though this is a void, report the error for a bad @anyobj. + */ +void +virObjectLookupHashRemove(void *anyobj, + void *delObj, + const char *uuidstr, + const char *name) +{ + virObjectLookupHashPtr hashObj =3D virObjectGetLookupHashObj(anyobj); + virObjectLockablePtr obj =3D virObjectGetLockableObj(delObj); + + if (!virObjectLookupHashValidAddRemoveArgs(hashObj, obj, uuidstr, name= )) + return; + + virObjectRef(obj); + virObjectUnlock(obj); + virObjectRWLockWrite(hashObj); + virObjectLock(obj); + if (uuidstr) + virHashRemoveEntry(hashObj->objsUUID, uuidstr); + if (name) + virHashRemoveEntry(hashObj->objsName, name); + virObjectUnlock(obj); + virObjectUnref(obj); + virObjectRWUnlock(hashObj); +} diff --git a/src/util/virobject.h b/src/util/virobject.h index 75efa90..d149f30 100644 --- a/src/util/virobject.h +++ b/src/util/virobject.h @@ -181,4 +181,18 @@ void virObjectListFreeCount(void *list, size_t count); =20 +int +virObjectLookupHashAdd(void *anyobj, + void *addObj, + const char *uuidstr, + const char *name) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +void +virObjectLookupHashRemove(void *anyobj, + void *delObj, + const char *uuidstr, + const char *name) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + #endif /* __VIR_OBJECT_H */ --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523376461672.1604414919914; Wed, 23 Aug 2017 14:22:56 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9343B1F596; Wed, 23 Aug 2017 21:22:54 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7362860E3F; Wed, 23 Aug 2017 21:22:54 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 3D1791806106; Wed, 23 Aug 2017 21:22:54 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLMq9k023982 for ; Wed, 23 Aug 2017 17:22:52 -0400 Received: by smtp.corp.redhat.com (Postfix) id 64F4166D36; Wed, 23 Aug 2017 21:22:52 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id AB45080DAF for ; Wed, 23 Aug 2017 21:22:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 9343B1F596 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:00 -0400 Message-Id: <20170823212211.4693-5-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 04/15] util: Introduce virObjectLookupHashFind[Locked] 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Wed, 23 Aug 2017 21:22:55 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" These API's will use the virHashLookup in order to find the object in the lookup hash object by the specified @key. If two hash tables exist in the hash table object, then both will be searched for the key. Both API's will call an virObjectLookupHashFindInternal in order in handle the fetch. The virObjectLookupHashFindLocked is the primary workhorse and should only be called externally if the caller has taken the proper RW LookupHash lock. This is necessary in some paths, such as during Add/Assign processing where getting the RW Write lock early is required to ensure no other thread attempts to create/add the same object Signed-off-by: John Ferlan --- src/libvirt_private.syms | 2 ++ src/util/virobject.c | 73 ++++++++++++++++++++++++++++++++++++++++++++= ++++ src/util/virobject.h | 10 +++++++ 3 files changed, 85 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e98646c..8ad7223 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2331,6 +2331,8 @@ virObjectListFreeCount; virObjectLock; virObjectLockableNew; virObjectLookupHashAdd; +virObjectLookupHashFind; +virObjectLookupHashFindLocked; virObjectLookupHashNew; virObjectLookupHashRemove; virObjectNew; diff --git a/src/util/virobject.c b/src/util/virobject.c index 76bf1bf..63205d3 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -857,3 +857,76 @@ virObjectLookupHashRemove(void *anyobj, virObjectUnref(obj); virObjectRWUnlock(hashObj); } + + +static void * +virObjectLookupHashFindInternal(virObjectLookupHashPtr hashObj, + const char *key) +{ + virObjectLockablePtr obj; + + if (hashObj->objsUUID) { + if ((obj =3D virHashLookup(hashObj->objsUUID, key))) + return virObjectRef(obj); + } + + if (hashObj->objsName) { + obj =3D virHashLookup(hashObj->objsName, key); + return virObjectRef(obj); + } + + return NULL; +} + + +/** + * virObjectLookupHashFindLocked: + * @anyobj: LookupHash object + * @key: Key to use for lookup + * + * Search through the hash tables looking for the @key. The @key may be + * either UUID or Name - both tables if they exist will be searched. + * + * NB: Assumes that the LookupHash has already been locked + * + * Returns a pointer to the entry with refcnt incremented or NULL on failu= re + */ +void * +virObjectLookupHashFindLocked(void *anyobj, + const char *key) +{ + virObjectLookupHashPtr hashObj =3D virObjectGetLookupHashObj(anyobj); + + if (!hashObj) + return NULL; + + return virObjectLookupHashFindInternal(anyobj, key); + +} + + +/** + * virObjectLookupHashFind: + * @anyobj: LookupHash object + * @key: Key to use for lookup + * + * Call virObjectLookupHashFindLocked after locking the LookupHash + * + * Returns a pointer to the entry with refcnt incremented or NULL on failu= re + */ +void * +virObjectLookupHashFind(void *anyobj, + const char *key) +{ + virObjectLookupHashPtr hashObj =3D virObjectGetLookupHashObj(anyobj); + void *obj; + + if (!hashObj) + return NULL; + + virObjectRWLockRead(hashObj); + obj =3D virObjectLookupHashFindInternal(hashObj, key); + virObjectRWUnlock(hashObj); + + return obj; +} diff --git a/src/util/virobject.h b/src/util/virobject.h index d149f30..e5596e6 100644 --- a/src/util/virobject.h +++ b/src/util/virobject.h @@ -195,4 +195,14 @@ virObjectLookupHashRemove(void *anyobj, const char *name) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 +void * +virObjectLookupHashFindLocked(void *anyobj, + const char *key) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +void * +virObjectLookupHashFind(void *anyobj, + const char *key) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + #endif /* __VIR_OBJECT_H */ --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523385852199.93534897472136; Wed, 23 Aug 2017 14:23:05 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 35BEB5BECB; Wed, 23 Aug 2017 21:23:04 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1690880DB7; Wed, 23 Aug 2017 21:23:04 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id D06281806108; Wed, 23 Aug 2017 21:23:03 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLN2Yl024021 for ; Wed, 23 Aug 2017 17:23:02 -0400 Received: by smtp.corp.redhat.com (Postfix) id 8392C66D36; Wed, 23 Aug 2017 21:23:02 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id 92B7881EC0 for ; Wed, 23 Aug 2017 21:22:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 35BEB5BECB Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:01 -0400 Message-Id: <20170823212211.4693-6-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 05/15] util: Introduce virObjectLookupHashForEach{UUID|Name} 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 23 Aug 2017 21:23:04 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Introduce an API to use the virHashForEach API to go through each element of the LookupHash calling a callback for each object entry from the LookupHash in order for it to be processed. Create a common structure _virObjectLookupHashForEachData to define the various pieces of data needed by the callback consumers. Fields described in the API function description section. Upon successful completion, the data.nElems is returned to the caller and possibly various fields within the structure filled in depending on the callers need as follows: vir{Object}NumOf{Elem} vir{Object}Get{UUID|Name} =3D> Callback function can be combined since generally all that the NumOf cares about is counts, but the Get function also adds some {UUID|Name} to a returned list of @uuids/@names. vir{Object}Export =3D> When @maxElems =3D=3D -1, will cause allocation into data->elems of an array sized by the hash table size which will be used by the callback function to store addresses of objects specific to each {Object} that are typically associated with the virConnectListAll* API's from the virGet{Object}() calls. The @flags argument is typically used for additional filtering via vir{Object}Match or vir{Object}Filter APIs found in various vir*obj modules. Upon return from the call, the calling function must then move the data->elems into the returned structure. It is up to the callback function to set @error in the event of an error during processing resulting in calling the VIR_FREE() for each of the @nElems already in the array. When an error occurs, any collection done by the callback functions into the @elems array is discarded. Signed-off-by: John Ferlan --- src/libvirt_private.syms | 2 + src/util/virobject.c | 118 +++++++++++++++++++++++++++++++++++++++++++= ++++ src/util/virobject.h | 27 +++++++++++ 3 files changed, 147 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8ad7223..4d0883c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2333,6 +2333,8 @@ virObjectLockableNew; virObjectLookupHashAdd; virObjectLookupHashFind; virObjectLookupHashFindLocked; +virObjectLookupHashForEachName; +virObjectLookupHashForEachUUID; virObjectLookupHashNew; virObjectLookupHashRemove; virObjectNew; diff --git a/src/util/virobject.c b/src/util/virobject.c index 63205d3..dfd0bec 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -930,3 +930,121 @@ virObjectLookupHashFind(void *anyobj, =20 return obj; } + + +static int +virObjectLookupHashForEachInternal(virHashTablePtr objsTable, + virHashIterator iter, + virObjectLookupHashForEachDataPtr data) +{ + if (data->maxElems =3D=3D -1) { + if (VIR_ALLOC_N(data->elems, virHashSize(objsTable) + 1) < 0) + return -1; + } + + virHashForEach(objsTable, iter, data); + + if (data->error) + goto error; + + if (data->maxElems =3D=3D -1) { + /* trim the array to the final size */ + ignore_value(VIR_REALLOC_N(data->elems, data->nElems + 1)); + } + + return data->nElems; + + error: + if (data->elems) { + if (data->maxElems =3D=3D -1) { + virObjectListFree(data->elems); + } else { + while (--data->nElems) + VIR_FREE(data->elems[data->nElems]); + } + } + return -1; +} + + +/** + * virObjectLookupHashForEach{UUID|Name} + * @anyobj: LookupHash object + * @iter: callback function to handle the object specific checks + * @opaque: callback data + * + * For each element of the UUID or Name hash table make a call into the + * callback routine to handle its task. Even if there were two hash + * tables all the objects exist in both, so it's only necessary to + * run through one of them, but two API's are required since the caller + * can use either. + * + * NB: + * struct _virObjectLookupHashForEachData { + * virConnectPtr conn; -> Connect ptr for @filter APIs + * void *opaque; -> Opaque data as determined by caller + * void *filter; -> A pointer to function for ACL calls + * bool wantActive; -> Filter active objs + * bool error; -> Set by callback functions for error + * const char *matchStr; -> Filter for specific string in many objs + * unsigned int flags; -> @flags argument to for Export calls + * int nElems; -> # of elements found and passing filters + * void **elems; -> array of elements + * int maxElems; -> maximum # of elements to collect + * Use -1 to allocate array of N table sized + * elements to use for Export functions + * Use -2 for NumOf functions to avoid the + * allocation, but allow sharing with the + * GetNames type functions + * }; + * + * Returns number of elements found on success, -1 on failure + */ +int +virObjectLookupHashForEachUUID(void *anyobj, + virHashIterator iter, + virObjectLookupHashForEachDataPtr data) +{ + virObjectLookupHashPtr hashObj =3D virObjectGetLookupHashObj(anyobj); + int ret; + + if (!hashObj) + return -1; + + if (!hashObj->objsUUID) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("no objsUUID for hashObj=3D%p"), hashObj); + return -1; + } + + virObjectRWLockRead(hashObj); + ret =3D virObjectLookupHashForEachInternal(hashObj->objsUUID, iter, da= ta); + virObjectRWUnlock(hashObj); + + return ret; +} + + +int +virObjectLookupHashForEachName(void *anyobj, + virHashIterator iter, + virObjectLookupHashForEachDataPtr data) +{ + virObjectLookupHashPtr hashObj =3D virObjectGetLookupHashObj(anyobj); + int ret; + + if (!hashObj) + return -1; + + if (!hashObj->objsName) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("no objsName for hashObj=3D%p"), hashObj); + return -1; + } + + virObjectRWLockRead(hashObj); + ret =3D virObjectLookupHashForEachInternal(hashObj->objsName, iter, da= ta); + virObjectRWUnlock(hashObj); + + return ret; +} diff --git a/src/util/virobject.h b/src/util/virobject.h index e5596e6..a35cf3c 100644 --- a/src/util/virobject.h +++ b/src/util/virobject.h @@ -205,4 +205,31 @@ virObjectLookupHashFind(void *anyobj, const char *key) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 +typedef struct _virObjectLookupHashForEachData virObjectLookupHashForEachD= ata; +typedef virObjectLookupHashForEachData *virObjectLookupHashForEachDataPtr; +struct _virObjectLookupHashForEachData { + virConnectPtr conn; + void *opaque; + void *filter; + bool wantActive; + bool error; + const char *matchStr; + unsigned int flags; + int nElems; + void **elems; + int maxElems; +}; + +int +virObjectLookupHashForEachUUID(void *anyobj, + virHashIterator iter, + virObjectLookupHashForEachDataPtr data) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); + +int +virObjectLookupHashForEachName(void *anyobj, + virHashIterator iter, + virObjectLookupHashForEachDataPtr data) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); + #endif /* __VIR_OBJECT_H */ --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523391443146.54429128964534; Wed, 23 Aug 2017 14:23:11 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B07F861486; Wed, 23 Aug 2017 21:23:09 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8E2C668B32; Wed, 23 Aug 2017 21:23:09 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 5A11A3FC74; Wed, 23 Aug 2017 21:23:09 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLN7AH024035 for ; Wed, 23 Aug 2017 17:23:07 -0400 Received: by smtp.corp.redhat.com (Postfix) id 4C96980DA7; Wed, 23 Aug 2017 21:23:07 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id D6D7866D36 for ; Wed, 23 Aug 2017 21:23:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B07F861486 Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:02 -0400 Message-Id: <20170823212211.4693-7-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 06/15] util: Introduce virObjectLookupHashSearch{UUID|Name}[Locked] 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 23 Aug 2017 21:23:10 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add common object API wrappers to use the virHashSearch API to search the LookupHash for specific data defined in the @opaque parameter. Once data is found, the search would end and the object that is represented is returned locked with it's reference 's reference count incremented. The virObjectLookupHashSearch{UUID|Name}Locked is the workhorse, but similar to the virObjectLookupFind* APIs may be required an Add or AssignDef caller has the Write lock already to ensure no other thread will grab the lock and add the same or competing object. It is up to the caller to unlock and lower the refcnt once done with the object and of course handle a NULL return indicating no object found. Signed-off-by: John Ferlan --- src/libvirt_private.syms | 4 ++ src/util/virobject.c | 131 +++++++++++++++++++++++++++++++++++++++++++= ++++ src/util/virobject.h | 24 +++++++++ 3 files changed, 159 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4d0883c..b32004e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2337,6 +2337,10 @@ virObjectLookupHashForEachName; virObjectLookupHashForEachUUID; virObjectLookupHashNew; virObjectLookupHashRemove; +virObjectLookupHashSearchName; +virObjectLookupHashSearchNameLocked; +virObjectLookupHashSearchUUID; +virObjectLookupHashSearchUUIDLocked; virObjectNew; virObjectRef; virObjectRWLockableNew; diff --git a/src/util/virobject.c b/src/util/virobject.c index dfd0bec..b20e938 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -1048,3 +1048,134 @@ virObjectLookupHashForEachName(void *anyobj, =20 return ret; } + + +static void * +virObjectLookupHashSearchInternal(virHashTablePtr objsTable, + virHashSearcher iter, + void *opaque) +{ + virObjectLockablePtr obj; + + obj =3D virHashSearch(objsTable, iter, opaque, NULL); + virObjectRef(obj); + + if (obj) + virObjectLock(obj); + + return obj; +} + + +/** + * virObjectLookupHashSearch{UUID|Name}Locked + * @anyobj: LookupHash object + * @iter: callback function to handle the object specific checks + * @opaque: callback data + * + * Search the hash table UUID or Name table calling the specified @iter + * routine with an object and @opaque data in order to determine whether + * the object is represented by the @opaque data. + * + * NB: Caller assumes the responsibility for locking LookupHash + * + * Returns locked/refcnt incremented object on success, NULL on failure + */ +void * +virObjectLookupHashSearchUUIDLocked(void *anyobj, + virHashSearcher iter, + void *opaque) +{ + virObjectLookupHashPtr hashObj =3D virObjectGetLookupHashObj(anyobj); + + if (!hashObj) + return NULL; + + if (!hashObj->objsUUID) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("no objsUUID for hashObj=3D%p"), hashObj); + return NULL; + } + + return virObjectLookupHashSearchInternal(hashObj->objsUUID, iter, opaq= ue); +} + + +void * +virObjectLookupHashSearchNameLocked(void *anyobj, + virHashSearcher iter, + void *opaque) +{ + virObjectLookupHashPtr hashObj =3D virObjectGetLookupHashObj(anyobj); + + if (!hashObj) + return NULL; + + if (!hashObj->objsName) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("no objsName for hashObj=3D%p"), hashObj); + return NULL; + } + + return virObjectLookupHashSearchInternal(hashObj->objsName, iter, opaq= ue); +} + + +/** + * virObjectLookupHashSearch{UUID|Name} + * @anyobj: LookupHash object + * @iter: callback function to handle the object specific checks + * @opaque: callback data + * + * Call virObjectLookupHashSearchLocked with a locked hash table + * + * Returns @obj from virObjectLookupHashSearchLocked + */ +void * +virObjectLookupHashSearchUUID(void *anyobj, + virHashSearcher iter, + void *opaque) +{ + virObjectLookupHashPtr hashObj =3D virObjectGetLookupHashObj(anyobj); + virObjectLockablePtr obj; + + if (!hashObj) + return NULL; + + if (!hashObj->objsUUID) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("no objsUUID for hashObj=3D%p"), hashObj); + return NULL; + } + + virObjectRWLockRead(hashObj); + obj =3D virObjectLookupHashSearchInternal(hashObj->objsUUID, iter, opa= que); + virObjectRWUnlock(hashObj); + + return obj; +} + + +void * +virObjectLookupHashSearchName(void *anyobj, + virHashSearcher iter, + void *opaque) +{ + virObjectLookupHashPtr hashObj =3D virObjectGetLookupHashObj(anyobj); + virObjectLockablePtr obj; + + if (!hashObj) + return NULL; + + if (!hashObj->objsName) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("no objsName for hashObj=3D%p"), hashObj); + return NULL; + } + + virObjectRWLockRead(hashObj); + obj =3D virObjectLookupHashSearchInternal(hashObj->objsName, iter, opa= que); + virObjectRWUnlock(hashObj); + + return obj; +} diff --git a/src/util/virobject.h b/src/util/virobject.h index a35cf3c..03a23e0 100644 --- a/src/util/virobject.h +++ b/src/util/virobject.h @@ -232,4 +232,28 @@ virObjectLookupHashForEachName(void *anyobj, virObjectLookupHashForEachDataPtr data) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); =20 +void * +virObjectLookupHashSearchUUIDLocked(void *anyobj, + virHashSearcher iter, + void *opaque) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +void * +virObjectLookupHashSearchNameLocked(void *anyobj, + virHashSearcher iter, + void *opaque) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +void * +virObjectLookupHashSearchUUID(void *anyobj, + virHashSearcher iter, + void *opaque) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +void * +virObjectLookupHashSearchName(void *anyobj, + virHashSearcher iter, + void *opaque) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + #endif /* __VIR_OBJECT_H */ --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523397960898.2567336400474; Wed, 23 Aug 2017 14:23:17 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 47F0413A9F; Wed, 23 Aug 2017 21:23:16 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2110361F4C; Wed, 23 Aug 2017 21:23:16 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id DE7463FACD; Wed, 23 Aug 2017 21:23:15 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLNEuo024087 for ; Wed, 23 Aug 2017 17:23:14 -0400 Received: by smtp.corp.redhat.com (Postfix) id 8D2FB80DAF; Wed, 23 Aug 2017 21:23:14 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7965E66D39 for ; Wed, 23 Aug 2017 21:23:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 47F0413A9F Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:03 -0400 Message-Id: <20170823212211.4693-8-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 07/15] nodedev: Use virObjectLookupHash 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Wed, 23 Aug 2017 21:23:16 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Use the virObjectLookupHash in _virNodeDeviceObjList. Convert the code to use the LookupHash object and APIs rather than code within this module that uses virHash* calls. Since the _virNodeDeviceObjList only now contains the @parent object, the virClassNew must be removed from OnceInit because instantiation would fail since the object size would be the same as the parent object size. Usage of HashLookup{Find|Search} APIs returns a locked/reffed object so remove the virObjectLock after FindBy*Locked calls. The only function requiring taking a lock is the Add function since it needs to be synchronized in such a way to avoid multiple threads attempting to add the same named node device at the same time. The NumOfDevicesCallback and GetNamesCallback can use the same callback function with the only difference being the filling in of the @names array from the passed @data structure if it exists. Signed-off-by: John Ferlan --- src/conf/virnodedeviceobj.c | 273 ++++++++++++----------------------------= ---- 1 file changed, 75 insertions(+), 198 deletions(-) diff --git a/src/conf/virnodedeviceobj.c b/src/conf/virnodedeviceobj.c index b0dcee1..b97518b 100644 --- a/src/conf/virnodedeviceobj.c +++ b/src/conf/virnodedeviceobj.c @@ -40,19 +40,12 @@ struct _virNodeDeviceObj { }; =20 struct _virNodeDeviceObjList { - virObjectLockable parent; - - /* name string -> virNodeDeviceObj mapping - * for O(1), lockless lookup-by-name */ - virHashTable *objs; - + virObjectLookupHash parent; }; =20 =20 static virClassPtr virNodeDeviceObjClass; -static virClassPtr virNodeDeviceObjListClass; static void virNodeDeviceObjDispose(void *opaque); -static void virNodeDeviceObjListDispose(void *opaque); =20 static int virNodeDeviceObjOnceInit(void) @@ -63,12 +56,6 @@ virNodeDeviceObjOnceInit(void) virNodeDeviceObjDispose))) return -1; =20 - if (!(virNodeDeviceObjListClass =3D virClassNew(virClassForObjectLocka= ble(), - "virNodeDeviceObjList", - sizeof(virNodeDeviceObjL= ist), - virNodeDeviceObjListDisp= ose))) - return -1; - return 0; } =20 @@ -229,17 +216,7 @@ virNodeDeviceObjListSearch(virNodeDeviceObjListPtr dev= s, virHashSearcher callback, const void *data) { - virNodeDeviceObjPtr obj; - - virObjectLock(devs); - obj =3D virHashSearch(devs->objs, callback, data, NULL); - virObjectRef(obj); - virObjectUnlock(devs); - - if (obj) - virObjectLock(obj); - - return obj; + return virObjectLookupHashSearchName(devs, callback, (void *)data); } =20 =20 @@ -274,7 +251,7 @@ static virNodeDeviceObjPtr virNodeDeviceObjListFindByNameLocked(virNodeDeviceObjListPtr devs, const char *name) { - return virObjectRef(virHashLookup(devs->objs, name)); + return virObjectLookupHashFindLocked(devs, name); } =20 =20 @@ -282,15 +259,7 @@ virNodeDeviceObjPtr virNodeDeviceObjListFindByName(virNodeDeviceObjListPtr devs, const char *name) { - virNodeDeviceObjPtr obj; - - virObjectLock(devs); - obj =3D virNodeDeviceObjListFindByNameLocked(devs, name); - virObjectUnlock(devs); - if (obj) - virObjectLock(obj); - - return obj; + return virObjectLookupHashFind(devs, name); } =20 =20 @@ -445,32 +414,11 @@ virNodeDeviceObjListFindSCSIHostByWWNs(virNodeDeviceO= bjListPtr devs, } =20 =20 -static void -virNodeDeviceObjListDispose(void *obj) -{ - virNodeDeviceObjListPtr devs =3D obj; - - virHashFree(devs->objs); -} - - virNodeDeviceObjListPtr virNodeDeviceObjListNew(void) { - virNodeDeviceObjListPtr devs; - - if (virNodeDeviceObjInitialize() < 0) - return NULL; - - if (!(devs =3D virObjectLockableNew(virNodeDeviceObjListClass))) - return NULL; - - if (!(devs->objs =3D virHashCreate(50, virObjectFreeHashData))) { - virObjectUnref(devs); - return NULL; - } - - return devs; + return virObjectLookupHashNew(virClassForObjectLookupHash(), 50, + VIR_OBJECT_LOOKUP_HASH_NAME); } =20 =20 @@ -486,29 +434,31 @@ virNodeDeviceObjListAssignDef(virNodeDeviceObjListPtr= devs, virNodeDeviceDefPtr def) { virNodeDeviceObjPtr obj; + virNodeDeviceObjPtr ret =3D NULL; =20 - virObjectLock(devs); + virObjectRWLockWrite(devs); =20 if ((obj =3D virNodeDeviceObjListFindByNameLocked(devs, def->name))) { - virObjectLock(obj); virNodeDeviceDefFree(obj->def); obj->def =3D def; } else { if (!(obj =3D virNodeDeviceObjNew())) goto cleanup; =20 - if (virHashAddEntry(devs->objs, def->name, obj) < 0) { - virNodeDeviceObjEndAPI(&obj); + if (virObjectLookupHashAdd(devs, obj, NULL, def->name) < 0) goto cleanup; - } =20 obj->def =3D def; virObjectRef(obj); } =20 + ret =3D obj; + obj =3D NULL; + cleanup: - virObjectUnlock(devs); - return obj; + virNodeDeviceObjEndAPI(&obj); + virObjectRWUnlock(devs); + return ret; } =20 =20 @@ -516,20 +466,11 @@ void virNodeDeviceObjListRemove(virNodeDeviceObjListPtr devs, virNodeDeviceObjPtr obj) { - virNodeDeviceDefPtr def; - if (!obj) return; - def =3D obj->def; =20 - virObjectRef(obj); - virObjectUnlock(obj); - virObjectLock(devs); - virObjectLock(obj); - virHashRemoveEntry(devs->objs, def->name); - virObjectUnlock(obj); - virObjectUnref(obj); - virObjectUnlock(devs); + /* @obj is already locked on entry */ + virObjectLookupHashRemove(devs, obj, NULL, obj->def->name); } =20 =20 @@ -730,29 +671,33 @@ virNodeDeviceCapMatch(virNodeDeviceObjPtr obj, } =20 =20 -struct virNodeDeviceCountData { - virConnectPtr conn; - virNodeDeviceObjListFilter filter; - const char *matchstr; - int count; -}; - static int -virNodeDeviceObjListNumOfDevicesCallback(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *opaque) +virNodeDeviceObjListGetHelper(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) { virNodeDeviceObjPtr obj =3D payload; virNodeDeviceDefPtr def; - struct virNodeDeviceCountData *data =3D opaque; + virObjectLookupHashForEachDataPtr data =3D opaque; virNodeDeviceObjListFilter filter =3D data->filter; + char **names =3D (char **)data->elems; + + if (data->error) + return 0; =20 virObjectLock(obj); def =3D obj->def; + if ((!filter || filter(data->conn, def)) && - (!data->matchstr || virNodeDeviceObjHasCap(obj, data->matchstr))) - data->count++; + (!data->matchStr || virNodeDeviceObjHasCap(obj, data->matchStr))) { + if (names && VIR_STRDUP(names[data->nElems], def->name) < 0) { + data->error =3D true; + goto cleanup; + } + data->nElems++; + } =20 + cleanup: virObjectUnlock(obj); return 0; } @@ -764,55 +709,12 @@ virNodeDeviceObjListNumOfDevices(virNodeDeviceObjList= Ptr devs, const char *cap, virNodeDeviceObjListFilter filter) { - struct virNodeDeviceCountData data =3D { - .conn =3D conn, .filter =3D filter, .matchstr =3D cap, .count =3D = 0 }; - - virObjectLock(devs); - virHashForEach(devs->objs, virNodeDeviceObjListNumOfDevicesCallback, &= data); - virObjectUnlock(devs); + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .error =3D false, .matchStr = =3D cap, + .nElems =3D 0, .elems =3D NULL, .maxElems =3D -2 }; =20 - return data.count; -} - - -struct virNodeDeviceGetNamesData { - virConnectPtr conn; - virNodeDeviceObjListFilter filter; - const char *matchstr; - int nnames; - char **names; - int maxnames; - bool error; -}; - -static int -virNodeDeviceObjListGetNamesCallback(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *opaque) -{ - virNodeDeviceObjPtr obj =3D payload; - virNodeDeviceDefPtr def; - struct virNodeDeviceGetNamesData *data =3D opaque; - virNodeDeviceObjListFilter filter =3D data->filter; - - if (data->error) - return 0; - - virObjectLock(obj); - def =3D obj->def; - - if ((!filter || filter(data->conn, def)) && - (!data->matchstr || virNodeDeviceObjHasCap(obj, data->matchstr))) { - if (VIR_STRDUP(data->names[data->nnames], def->name) < 0) { - data->error =3D true; - goto cleanup; - } - data->nnames++; - } - - cleanup: - virObjectUnlock(obj); - return 0; + return virObjectLookupHashForEachName(devs, virNodeDeviceObjListGetHel= per, + &data); } =20 =20 @@ -824,23 +726,12 @@ virNodeDeviceObjListGetNames(virNodeDeviceObjListPtr = devs, char **const names, int maxnames) { - struct virNodeDeviceGetNamesData data =3D { - .conn =3D conn, .filter =3D filter, .matchstr =3D cap, .names =3D = names, - .nnames =3D 0, .maxnames =3D maxnames, .error =3D false }; + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .error =3D false, .matchStr = =3D cap, + .nElems =3D 0, .elems =3D (void **)names, .maxElems =3D maxnames }; =20 - virObjectLock(devs); - virHashForEach(devs->objs, virNodeDeviceObjListGetNamesCallback, &data= ); - virObjectUnlock(devs); - - if (data.error) - goto error; - - return data.nnames; - - error: - while (--data.nnames) - VIR_FREE(data.names[data.nnames]); - return -1; + return virObjectLookupHashForEachName(devs, virNodeDeviceObjListGetHel= per, + &data); } =20 =20 @@ -876,15 +767,6 @@ virNodeDeviceMatch(virNodeDeviceObjPtr obj, #undef MATCH =20 =20 -struct virNodeDeviceObjListExportData { - virConnectPtr conn; - virNodeDeviceObjListFilter filter; - unsigned int flags; - virNodeDevicePtr *devices; - int ndevices; - bool error; -}; - static int virNodeDeviceObjListExportCallback(void *payload, const void *name ATTRIBUTE_UNUSED, @@ -892,8 +774,10 @@ virNodeDeviceObjListExportCallback(void *payload, { virNodeDeviceObjPtr obj =3D payload; virNodeDeviceDefPtr def; - struct virNodeDeviceObjListExportData *data =3D opaque; + virObjectLookupHashForEachDataPtr data =3D opaque; + virNodeDeviceObjListFilter filter =3D data->filter; virNodeDevicePtr device =3D NULL; + virNodeDevicePtr *devices =3D (virNodeDevicePtr *)data->elems; =20 if (data->error) return 0; @@ -901,20 +785,25 @@ virNodeDeviceObjListExportCallback(void *payload, virObjectLock(obj); def =3D obj->def; =20 - if ((!data->filter || data->filter(data->conn, def)) && - virNodeDeviceMatch(obj, data->flags)) { - if (data->devices) { - if (!(device =3D virGetNodeDevice(data->conn, def->name)) || - VIR_STRDUP(device->parent, def->parent) < 0) { - virObjectUnref(device); - data->error =3D true; - goto cleanup; - } - data->devices[data->ndevices] =3D device; - } - data->ndevices++; + if (filter && !filter(data->conn, def)) + goto cleanup; + + if (!virNodeDeviceMatch(obj, data->flags)) + goto cleanup; + + if (!devices) { + data->nElems++; + goto cleanup; } =20 + if (!(device =3D virGetNodeDevice(data->conn, def->name)) || + VIR_STRDUP(device->parent, def->parent) < 0) { + virObjectUnref(device); + data->error =3D true; + goto cleanup; + } + devices[data->nElems++] =3D device; + cleanup: virObjectUnlock(obj); return 0; @@ -928,31 +817,19 @@ virNodeDeviceObjListExport(virConnectPtr conn, virNodeDeviceObjListFilter filter, unsigned int flags) { - struct virNodeDeviceObjListExportData data =3D { - .conn =3D conn, .filter =3D filter, .flags =3D flags, - .devices =3D NULL, .ndevices =3D 0, .error =3D false }; - - virObjectLock(devs); - if (devices && - VIR_ALLOC_N(data.devices, virHashSize(devs->objs) + 1) < 0) { - virObjectUnlock(devs); - return -1; - } - - virHashForEach(devs->objs, virNodeDeviceObjListExportCallback, &data); - virObjectUnlock(devs); + int ret; + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .error =3D false, .nElems =3D = 0, + .elems =3D NULL, .maxElems =3D 0, .flags =3D flags }; =20 - if (data.error) - goto cleanup; + if (devices) + data.maxElems =3D -1; =20 - if (data.devices) { - ignore_value(VIR_REALLOC_N(data.devices, data.ndevices + 1)); - *devices =3D data.devices; - } + ret =3D virObjectLookupHashForEachName(devs, virNodeDeviceObjListExpor= tCallback, + &data); =20 - return data.ndevices; + if (devices) + *devices =3D (virNodeDevicePtr *)data.elems; =20 - cleanup: - virObjectListFree(data.devices); - return -1; + return ret; } --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523402211472.2039692777996; Wed, 23 Aug 2017 14:23:22 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4FF15800A8; Wed, 23 Aug 2017 21:23:20 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2CF926047C; Wed, 23 Aug 2017 21:23:20 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id DE2AF1806109; Wed, 23 Aug 2017 21:23:19 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLNIYS024116 for ; Wed, 23 Aug 2017 17:23:18 -0400 Received: by smtp.corp.redhat.com (Postfix) id 9B03A66D39; Wed, 23 Aug 2017 21:23:18 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5783066D36 for ; Wed, 23 Aug 2017 21:23:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 4FF15800A8 Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:04 -0400 Message-Id: <20170823212211.4693-9-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 08/15] secret: Use virObjectLookupHash 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 23 Aug 2017 21:23:20 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Use the virObjectLookupHash in _virSecretObjList. Convert the code to use the LookupHash object and APIs rather than local code and usage of the virHash* calls. Since the _virSecretObjList only now contains the @parent object, the virClassNew must be removed from OnceInit because instantiation would fail since the object size would be the same as the parent object size. Usage of HashLookup{Find|Search} API's returns a locked/reffed object so need to remove virObjectLock after FindBy*Locked calls. The only function requiring a taking a lock is the Add function since it needs to be synchronized in such a way to avoid multiple threads attempting to add the same secret via UUID or UsageID at the same time. NB: We cannot make usageID a LookupHash key because it's possible that the usageType is NONE and thus usageID is NULL, thus leaving the only "unique" element the UUID. The NumOfSecretsCallback and GetUUIDsCallback can use the same callback function with the only difference being the filling in of the @uuids array from the passed @data structure if it exists. Signed-off-by: John Ferlan --- src/conf/virsecretobj.c | 251 ++++++++++++--------------------------------= ---- 1 file changed, 64 insertions(+), 187 deletions(-) diff --git a/src/conf/virsecretobj.c b/src/conf/virsecretobj.c index 4dca152..21a5ab7 100644 --- a/src/conf/virsecretobj.c +++ b/src/conf/virsecretobj.c @@ -47,16 +47,10 @@ struct _virSecretObj { }; =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; + virObjectLookupHash parent; }; =20 struct virSecretSearchData { @@ -74,12 +68,6 @@ virSecretObjOnceInit(void) virSecretObjDispose))) return -1; =20 - if (!(virSecretObjListClass =3D virClassNew(virClassForObjectLockable(= ), - "virSecretObjList", - sizeof(virSecretObjList), - virSecretObjListDispose))) - return -1; - return 0; } =20 @@ -118,20 +106,8 @@ virSecretObjEndAPI(virSecretObjPtr *obj) virSecretObjListPtr virSecretObjListNew(void) { - virSecretObjListPtr secrets; - - if (virSecretObjInitialize() < 0) - return NULL; - - if (!(secrets =3D virObjectLockableNew(virSecretObjListClass))) - return NULL; - - if (!(secrets->objs =3D virHashCreate(50, virObjectFreeHashData))) { - virObjectUnref(secrets); - return NULL; - } - - return secrets; + return virObjectLookupHashNew(virClassForObjectLookupHash(), 50, + VIR_OBJECT_LOOKUP_HASH_UUID); } =20 =20 @@ -151,15 +127,6 @@ virSecretObjDispose(void *opaque) } =20 =20 -static void -virSecretObjListDispose(void *obj) -{ - virSecretObjListPtr secrets =3D obj; - - virHashFree(secrets->objs); -} - - /** * virSecretObjFindByUUIDLocked: * @secrets: list of secret objects @@ -173,7 +140,7 @@ static virSecretObjPtr virSecretObjListFindByUUIDLocked(virSecretObjListPtr secrets, const char *uuidstr) { - return virObjectRef(virHashLookup(secrets->objs, uuidstr)); + return virObjectLookupHashFindLocked(secrets, uuidstr); } =20 =20 @@ -191,14 +158,7 @@ virSecretObjPtr virSecretObjListFindByUUID(virSecretObjListPtr secrets, const char *uuidstr) { - virSecretObjPtr obj; - - virObjectLock(secrets); - obj =3D virSecretObjListFindByUUIDLocked(secrets, uuidstr); - virObjectUnlock(secrets); - if (obj) - virObjectLock(obj); - return obj; + return virObjectLookupHashFind(secrets, uuidstr); } =20 =20 @@ -243,14 +203,11 @@ virSecretObjListFindByUsageLocked(virSecretObjListPtr= secrets, int usageType, const char *usageID) { - virSecretObjPtr obj =3D NULL; struct virSecretSearchData data =3D { .usageType =3D usageType, .usageID =3D usageID }; =20 - obj =3D virHashSearch(secrets->objs, virSecretObjSearchName, &data, NU= LL); - if (obj) - virObjectRef(obj); - return obj; + return virObjectLookupHashSearchUUIDLocked(secrets, virSecretObjSearch= Name, + &data); } =20 =20 @@ -263,6 +220,12 @@ virSecretObjListFindByUsageLocked(virSecretObjListPtr = secrets, * This function locks @secrets and finds the secret object which * corresponds to @usageID of @usageType. * + * NB: The usageID cannot be used as a hash table key because + * virSecretDefParseUsage will not fill in the def->usage_id + * if the def->usage_type is VIR_SECRET_USAGE_TYPE_NONE, thus + * we cannot use def->usage_id as a key since both keys must + * be present in every object in order to be valid. + * * Returns: locked and ref'd secret object. */ virSecretObjPtr @@ -270,21 +233,17 @@ virSecretObjListFindByUsage(virSecretObjListPtr secre= ts, int usageType, const char *usageID) { - virSecretObjPtr obj; + struct virSecretSearchData data =3D { .usageType =3D usageType, + .usageID =3D usageID }; =20 - virObjectLock(secrets); - obj =3D virSecretObjListFindByUsageLocked(secrets, usageType, usageID); - virObjectUnlock(secrets); - if (obj) - virObjectLock(obj); - return obj; + return virObjectLookupHashSearchUUID(secrets, virSecretObjSearchName, = &data); } =20 =20 /* * virSecretObjListRemove: * @secrets: list of secret objects - * @secret: a secret object + * @obj: a locked 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 @@ -295,22 +254,12 @@ virSecretObjListRemove(virSecretObjListPtr secrets, virSecretObjPtr obj) { char uuidstr[VIR_UUID_STRING_BUFLEN]; - virSecretDefPtr def; =20 if (!obj) return; - def =3D obj->def; =20 - virUUIDFormat(def->uuid, uuidstr); - virObjectRef(obj); - virObjectUnlock(obj); - - virObjectLock(secrets); - virObjectLock(obj); - virHashRemoveEntry(secrets->objs, uuidstr); - virObjectUnlock(obj); - virObjectUnref(obj); - virObjectUnlock(secrets); + virUUIDFormat(obj->def->uuid, uuidstr); + virObjectLookupHashRemove(secrets, obj, uuidstr, NULL); } =20 =20 @@ -336,7 +285,7 @@ virSecretObjListAdd(virSecretObjListPtr secrets, virSecretObjPtr ret =3D NULL; char uuidstr[VIR_UUID_STRING_BUFLEN]; =20 - virObjectLock(secrets); + virObjectRWLockWrite(secrets); =20 if (oldDef) *oldDef =3D NULL; @@ -345,7 +294,6 @@ virSecretObjListAdd(virSecretObjListPtr secrets, =20 /* Is there a secret already matching this UUID */ if ((obj =3D virSecretObjListFindByUUIDLocked(secrets, uuidstr))) { - virObjectLock(obj); objdef =3D obj->def; =20 if (STRNEQ_NULLABLE(objdef->usage_id, newdef->usage_id)) { @@ -373,7 +321,6 @@ virSecretObjListAdd(virSecretObjListPtr secrets, if ((obj =3D virSecretObjListFindByUsageLocked(secrets, newdef->usage_type, newdef->usage_id))) { - virObjectLock(obj); objdef =3D obj->def; virUUIDFormat(objdef->uuid, uuidstr); virReportError(VIR_ERR_INTERNAL_ERROR, @@ -393,11 +340,10 @@ virSecretObjListAdd(virSecretObjListPtr secrets, !(obj->base64File =3D virFileBuildPath(configDir, uuidstr, ".b= ase64"))) goto cleanup; =20 - if (virHashAddEntry(secrets->objs, uuidstr, obj) < 0) + if (virObjectLookupHashAdd(secrets, obj, uuidstr, NULL) < 0) goto cleanup; =20 obj->def =3D newdef; - virObjectRef(obj); } =20 ret =3D obj; @@ -405,72 +351,35 @@ virSecretObjListAdd(virSecretObjListPtr secrets, =20 cleanup: virSecretObjEndAPI(&obj); - virObjectUnlock(secrets); + virObjectRWUnlock(secrets); return ret; } =20 =20 -struct virSecretCountData { - virConnectPtr conn; - virSecretObjListACLFilter filter; - int count; -}; - static int -virSecretObjListNumOfSecretsCallback(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *opaque) +virSecretObjListGetHelper(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) { - struct virSecretCountData *data =3D opaque; - virSecretObjPtr obj =3D payload; - virSecretDefPtr def; - - virObjectLock(obj); - def =3D obj->def; - - if (data->filter && !data->filter(data->conn, def)) - goto cleanup; - - data->count++; - - cleanup: - virObjectUnlock(obj); - return 0; -} - - -struct virSecretListData { - virConnectPtr conn; - virSecretObjListACLFilter filter; - int nuuids; - char **uuids; - int maxuuids; - bool error; -}; - - -static int -virSecretObjListGetUUIDsCallback(void *payload, - const void *name ATTRIBUTE_UNUSED, - void *opaque) -{ - struct virSecretListData *data =3D opaque; virSecretObjPtr obj =3D payload; + virObjectLookupHashForEachDataPtr data =3D opaque; + virSecretObjListACLFilter filter =3D data->filter; + char **uuids =3D (char **)data->elems; virSecretDefPtr def; =20 if (data->error) return 0; =20 - if (data->maxuuids >=3D 0 && data->nuuids =3D=3D data->maxuuids) + if (data->maxElems >=3D 0 && data->nElems =3D=3D data->maxElems) return 0; =20 virObjectLock(obj); def =3D obj->def; =20 - if (data->filter && !data->filter(data->conn, def)) + if (filter && !filter(data->conn, def)) goto cleanup; =20 - if (data->uuids) { + if (uuids) { char *uuidstr; =20 if (VIR_ALLOC_N(uuidstr, VIR_UUID_STRING_BUFLEN) < 0) { @@ -479,7 +388,9 @@ virSecretObjListGetUUIDsCallback(void *payload, } =20 virUUIDFormat(def->uuid, uuidstr); - data->uuids[data->nuuids++] =3D uuidstr; + uuids[data->nElems++] =3D uuidstr; + } else { + data->nElems++; } =20 cleanup: @@ -493,14 +404,12 @@ virSecretObjListNumOfSecrets(virSecretObjListPtr secr= ets, virSecretObjListACLFilter filter, virConnectPtr conn) { - struct virSecretCountData data =3D { - .conn =3D conn, .filter =3D filter, .count =3D 0 }; - - virObjectLock(secrets); - virHashForEach(secrets->objs, virSecretObjListNumOfSecretsCallback, &d= ata); - virObjectUnlock(secrets); + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .error =3D false, .nElems =3D = 0, + .elems =3D NULL, .maxElems =3D -2 }; =20 - return data.count; + return virObjectLookupHashForEachUUID(secrets, virSecretObjListGetHelp= er, + &data); } =20 =20 @@ -532,22 +441,15 @@ virSecretObjMatchFlags(virSecretObjPtr obj, #undef MATCH =20 =20 -struct virSecretObjListData { - virConnectPtr conn; - virSecretPtr *secrets; - virSecretObjListACLFilter filter; - unsigned int flags; - int nsecrets; - bool error; -}; - static int virSecretObjListExportCallback(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) { - struct virSecretObjListData *data =3D opaque; virSecretObjPtr obj =3D payload; + virObjectLookupHashForEachDataPtr data =3D opaque; + virSecretPtr *secrets =3D (virSecretPtr *)data->elems; + virSecretObjListACLFilter filter =3D data->filter; virSecretDefPtr def; virSecretPtr secret =3D NULL; =20 @@ -557,25 +459,24 @@ virSecretObjListExportCallback(void *payload, virObjectLock(obj); def =3D obj->def; =20 - if (data->filter && !data->filter(data->conn, def)) + if (filter && !filter(data->conn, def)) goto cleanup; =20 if (!virSecretObjMatchFlags(obj, data->flags)) goto cleanup; =20 - if (!data->secrets) { - data->nsecrets++; + if (!secrets) { + data->nElems++; goto cleanup; } =20 if (!(secret =3D virGetSecret(data->conn, def->uuid, - def->usage_type, - def->usage_id))) { + def->usage_type, def->usage_id))) { data->error =3D true; goto cleanup; } =20 - data->secrets[data->nsecrets++] =3D secret; + secrets[data->nElems++] =3D secret; =20 cleanup: virObjectUnlock(obj); @@ -590,35 +491,22 @@ virSecretObjListExport(virConnectPtr conn, virSecretObjListACLFilter filter, unsigned int flags) { - 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) { - virObjectUnlock(secretobjs); - return -1; - } + int ret; =20 - virHashForEach(secretobjs->objs, virSecretObjListExportCallback, &data= ); - virObjectUnlock(secretobjs); + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .error =3D false, .nElems =3D = 0, + .elems =3D NULL, .maxElems =3D 0, .flags =3D flags }; =20 - if (data.error) - goto error; - - if (data.secrets) { - /* trim the array to the final size */ - ignore_value(VIR_REALLOC_N(data.secrets, data.nsecrets + 1)); - *secrets =3D data.secrets; - } + if (secrets) + data.maxElems =3D -1; =20 - return data.nsecrets; + ret =3D virObjectLookupHashForEachUUID(secretobjs, + virSecretObjListExportCallback, + &data); + if (secrets) + *secrets =3D (virSecretPtr *)data.elems; =20 - error: - virObjectListFree(data.secrets); - return -1; + return ret; } =20 =20 @@ -629,23 +517,12 @@ virSecretObjListGetUUIDs(virSecretObjListPtr secrets, virSecretObjListACLFilter filter, virConnectPtr conn) { - struct virSecretListData data =3D { - .conn =3D conn, .filter =3D filter, .uuids =3D uuids, .nuuids =3D = 0, - .maxuuids =3D maxuuids, .error =3D false }; + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .error =3D false, .nElems =3D = 0, + .elems =3D (void **)uuids, .maxElems =3D maxuuids }; =20 - virObjectLock(secrets); - virHashForEach(secrets->objs, virSecretObjListGetUUIDsCallback, &data); - virObjectUnlock(secrets); - - if (data.error) - goto error; - - return data.nuuids; - - error: - while (--data.nuuids) - VIR_FREE(data.uuids[data.nuuids]); - return -1; + return virObjectLookupHashForEachUUID(secrets, virSecretObjListGetHelp= er, + &data); } =20 =20 --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523405552601.0567055871511; Wed, 23 Aug 2017 14:23:25 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DDDCE404324; Wed, 23 Aug 2017 21:23:23 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BD61E80DB1; Wed, 23 Aug 2017 21:23:23 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 782A13FAD1; Wed, 23 Aug 2017 21:23:23 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLNLSK024135 for ; Wed, 23 Aug 2017 17:23:21 -0400 Received: by smtp.corp.redhat.com (Postfix) id A19C980D99; Wed, 23 Aug 2017 21:23:21 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id B880466D36 for ; Wed, 23 Aug 2017 21:23:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com DDDCE404324 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:05 -0400 Message-Id: <20170823212211.4693-10-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 09/15] util: Introduce virObjectLookupHashClone 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 23 Aug 2017 21:23:24 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" A convenience API that will utilize the virHashForEach API for the LookupHash in order to create a clone/copy. Primary consumer is the interface driver which has a desire to save off a copy of its only hash table in order to possible restore it if something goes wrong during processing. Signed-off-by: John Ferlan --- src/libvirt_private.syms | 1 + src/util/virobject.c | 83 ++++++++++++++++++++++++++++++++++++++++++++= ++++ src/util/virobject.h | 9 ++++++ 3 files changed, 93 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b32004e..ecbd84a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2331,6 +2331,7 @@ virObjectListFreeCount; virObjectLock; virObjectLockableNew; virObjectLookupHashAdd; +virObjectLookupHashClone; virObjectLookupHashFind; virObjectLookupHashFindLocked; virObjectLookupHashForEachName; diff --git a/src/util/virobject.c b/src/util/virobject.c index b20e938..7152b17 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -1179,3 +1179,86 @@ virObjectLookupHashSearchName(void *anyobj, =20 return obj; } + + +struct cloneData { + virObjectLookupHashCloneCallback callback; + virObjectLookupHashPtr dst; + bool error; +}; + +/* + * Take the provided virHashForEach element and call the @cb function + * with the input @dst hash table and the source element from the + * @src hash table in order to perform the copy - tracking success/ + * failure using the error boolean. + * + * Once there's a failure, no future copy/clone will occur. + * + * The @cb function can expect the @src hash table object to be + * locked upon entry. + * + * Returns 0 to the virHashForEach on success, -1 on failure. + */ +static int +cloneCallback(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + virObjectLockablePtr obj =3D payload; + struct cloneData *data =3D opaque; + + if (data->error) + return 0; + + virObjectLock(obj); + + if (data->callback(data->dst, obj) < 0) + data->error =3D true; + + virObjectUnlock(obj); + + if (data->error) + return -1; + + return 0; +} + +/** + * virObjectLookupHashClone + * @srcAnyobj: source LookupHash object to clone from + * @dstAnyobj: destination LookupHash object to clone to + * @cb: callback function to handle the clone + * + * The clone function is designed to traverse each source hash entry + * and call the driver specific @cb function with the element from the + * source hash table in order to clone into the destination hash table. + * This will be done for each hash table that exists. + * + * Return 0 on success, -1 on failure + */ +int +virObjectLookupHashClone(void *srcAnyobj, + void *dstAnyobj, + virObjectLookupHashCloneCallback cb) +{ + virObjectLookupHashPtr srcHashObj =3D virObjectGetLookupHashObj(srcAny= obj); + virObjectLookupHashPtr dstHashObj =3D virObjectGetLookupHashObj(dstAny= obj); + struct cloneData data =3D { .callback =3D cb, .dst =3D dstHashObj, + .error =3D false }; + + if (!srcHashObj || !dstHashObj) + return -1; + + virObjectRWLockRead(srcHashObj); + if (srcHashObj->objsUUID) + virHashForEach(srcHashObj->objsUUID, cloneCallback, &data); + if (srcHashObj->objsName) + virHashForEach(srcHashObj->objsName, cloneCallback, &data); + virObjectRWUnlock(srcHashObj); + + if (data.error) + return -1; + + return 0; +} diff --git a/src/util/virobject.h b/src/util/virobject.h index 03a23e0..66b44ca 100644 --- a/src/util/virobject.h +++ b/src/util/virobject.h @@ -256,4 +256,13 @@ virObjectLookupHashSearchName(void *anyobj, void *opaque) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 +typedef int (*virObjectLookupHashCloneCallback)(void *dstHashTable, + void *sourceObject); +int +virObjectLookupHashClone(void *srcAnyobj, + void *dstAnyobj, + virObjectLookupHashCloneCallback cb) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); + + #endif /* __VIR_OBJECT_H */ --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523410378697.9243480110704; Wed, 23 Aug 2017 14:23:30 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B1F53C056819; Wed, 23 Aug 2017 21:23:28 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9229061F4C; Wed, 23 Aug 2017 21:23:28 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 5917D180610A; Wed, 23 Aug 2017 21:23:28 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLNRn0024155 for ; Wed, 23 Aug 2017 17:23:27 -0400 Received: by smtp.corp.redhat.com (Postfix) id 5B4E180D99; Wed, 23 Aug 2017 21:23:27 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id 40CFD66D36 for ; Wed, 23 Aug 2017 21:23:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B1F53C056819 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:06 -0400 Message-Id: <20170823212211.4693-11-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 10/15] Revert "interface: Consume @def in virInterfaceObjNew" 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 23 Aug 2017 21:23:29 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This reverts commit 92840eb3a7e47cdf761e52afccc41d2a35327fbd. More recent reviews/changes don't have the vir*ObjNew APIs consuming the @def, so remove from Interface as well. Changes needed to also deal with conflicts from commit id '46f5eca4'. Signed-off-by: John Ferlan --- src/conf/virinterfaceobj.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/conf/virinterfaceobj.c b/src/conf/virinterfaceobj.c index 106f232..e993b92 100644 --- a/src/conf/virinterfaceobj.c +++ b/src/conf/virinterfaceobj.c @@ -74,7 +74,7 @@ virInterfaceObjDispose(void *opaque) =20 =20 static virInterfaceObjPtr -virInterfaceObjNew(virInterfaceDefPtr def) +virInterfaceObjNew(void) { virInterfaceObjPtr obj; =20 @@ -85,7 +85,6 @@ virInterfaceObjNew(virInterfaceDefPtr def) return NULL; =20 virObjectLock(obj); - obj->def =3D def; =20 return obj; } @@ -261,15 +260,15 @@ virInterfaceObjListAssignDef(virInterfaceObjListPtr i= nterfaces, return obj; } =20 - if (!(obj =3D virInterfaceObjNew(def))) + if (!(obj =3D virInterfaceObjNew())) return NULL; =20 if (VIR_APPEND_ELEMENT_COPY(interfaces->objs, interfaces->count, obj) < 0) { - obj->def =3D NULL; virInterfaceObjEndAPI(&obj); return NULL; } + obj->def =3D def; return virObjectRef(obj); } =20 --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 150352343504749.37366359623013; Wed, 23 Aug 2017 14:23:55 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6031A7EA90; Wed, 23 Aug 2017 21:23:53 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3FC8481EEE; Wed, 23 Aug 2017 21:23:53 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 065BE180884F; Wed, 23 Aug 2017 21:23:53 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLNqfU024245 for ; Wed, 23 Aug 2017 17:23:52 -0400 Received: by smtp.corp.redhat.com (Postfix) id 89BBB80DB8; Wed, 23 Aug 2017 21:23:52 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6ACF081EEB for ; Wed, 23 Aug 2017 21:23:27 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 6031A7EA90 Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:07 -0400 Message-Id: <20170823212211.4693-12-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 11/15] interface: Use virObjectLookupHash 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 23 Aug 2017 21:23:53 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Use the virObjectLookupHash in _virInterfaceObjList. Convert the code to use the LookupHash object and APIs rather than the local forward linked list processing. Usage of HashLookup{Find|Search} API's is via a callback mechanism and returns a locked/reffed object. The Clone API will make use of the ForEach functionality in copying whatever is in one LookupHash list into the destination. The only function requiring taking a lock is the AssignDef function since it needs to be synchronized in such a way to avoid multiple threads attempting to add the same named object at the same time. The NumOfInterfaces and GetNames can use the same callback function with the only difference being the filling in of the @names array from the passed @data structure if it exists. Signed-off-by: John Ferlan --- src/conf/virinterfaceobj.c | 286 ++++++++++++++++++++++++-----------------= ---- 1 file changed, 150 insertions(+), 136 deletions(-) diff --git a/src/conf/virinterfaceobj.c b/src/conf/virinterfaceobj.c index e993b92..a9b37d9 100644 --- a/src/conf/virinterfaceobj.c +++ b/src/conf/virinterfaceobj.c @@ -40,8 +40,7 @@ struct _virInterfaceObj { }; =20 struct _virInterfaceObjList { - size_t count; - virInterfaceObjPtr *objs; + virObjectLookupHash parent; }; =20 /* virInterfaceObj manipulation */ @@ -128,11 +127,41 @@ virInterfaceObjSetActive(virInterfaceObjPtr obj, virInterfaceObjListPtr virInterfaceObjListNew(void) { - virInterfaceObjListPtr interfaces; + return virObjectLookupHashNew(virClassForObjectLookupHash(), 10, + VIR_OBJECT_LOOKUP_HASH_NAME); +} =20 - if (VIR_ALLOC(interfaces) < 0) - return NULL; - return interfaces; + +static int +virInterfaceObjListFindByMACStringCb(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + virInterfaceObjPtr obj =3D payload; + virObjectLookupHashForEachDataPtr data =3D opaque; + char **const matches =3D (char **const)data->elems; + virInterfaceDefPtr def; + int ret =3D -1; + + if (data->error) + return 0; + + virObjectLock(obj); + def =3D obj->def; + if (STRCASEEQ(def->mac, data->matchStr)) { + if (data->nElems < data->maxElems) { + if (VIR_STRDUP(matches[data->nElems], def->name) < 0) { + data->error =3D true; + goto cleanup; + } + data->nElems++; + } + } + ret =3D 0; + + cleanup: + virObjectUnlock(obj); + return ret; } =20 =20 @@ -142,33 +171,21 @@ virInterfaceObjListFindByMACString(virInterfaceObjLis= tPtr interfaces, char **const matches, int maxmatches) { - size_t i; - int matchct =3D 0; - - for (i =3D 0; i < interfaces->count; i++) { - virInterfaceObjPtr obj =3D interfaces->objs[i]; - virInterfaceDefPtr def; - - virObjectLock(obj); - def =3D obj->def; - if (STRCASEEQ(def->mac, mac)) { - if (matchct < maxmatches) { - if (VIR_STRDUP(matches[matchct], def->name) < 0) { - virObjectUnlock(obj); - goto error; - } - matchct++; - } - } - virObjectUnlock(obj); - } - return matchct; + virObjectLookupHashForEachData data =3D { + .error =3D false, .matchStr =3D mac, .nElems =3D 0, + .elems =3D (void **)matches, .maxElems =3D maxmatches }; + + return virObjectLookupHashForEachName(interfaces, + virInterfaceObjListFindByMACStri= ngCb, + &data); +} =20 - error: - while (--matchct >=3D 0) - VIR_FREE(matches[matchct]); =20 - return -1; +static virInterfaceObjPtr +virInterfaceObjListFindByNameLocked(virInterfaceObjListPtr interfaces, + const char *name) +{ + return virObjectLookupHashFindLocked(interfaces, name); } =20 =20 @@ -176,73 +193,66 @@ virInterfaceObjPtr virInterfaceObjListFindByName(virInterfaceObjListPtr interfaces, const char *name) { - size_t i; - - for (i =3D 0; i < interfaces->count; i++) { - virInterfaceObjPtr obj =3D interfaces->objs[i]; - virInterfaceDefPtr def; - - virObjectLock(obj); - def =3D obj->def; - if (STREQ(def->name, name)) - return virObjectRef(obj); - virObjectUnlock(obj); - } - - return NULL; + return virObjectLookupHashFind(interfaces, name); } =20 =20 void virInterfaceObjListFree(virInterfaceObjListPtr interfaces) { - size_t i; + virObjectUnref(interfaces); +} + + +static int +virInterfaceObjListCloneCb(void *dstHashTable, + void *sourceObject) +{ + virInterfaceObjListPtr dest =3D dstHashTable; + virInterfaceObjPtr srcObj =3D sourceObject; + int ret =3D -1; + char *xml =3D NULL; + virInterfaceObjPtr obj; + virInterfaceDefPtr backup =3D NULL; + + if (!(xml =3D virInterfaceDefFormat(srcObj->def))) + goto cleanup; + + if (!(backup =3D virInterfaceDefParseString(xml))) + goto cleanup; + + if (!(obj =3D virInterfaceObjListAssignDef(dest, backup))) + goto cleanup; =20 - for (i =3D 0; i < interfaces->count; i++) - virObjectUnref(interfaces->objs[i]); - VIR_FREE(interfaces->objs); - VIR_FREE(interfaces); + ret =3D 0; + + cleanup: + VIR_FREE(xml); + virInterfaceDefFree(backup); + + return ret; } =20 =20 virInterfaceObjListPtr virInterfaceObjListClone(virInterfaceObjListPtr interfaces) { - size_t i; - unsigned int cnt; - virInterfaceObjListPtr dest; + virInterfaceObjListPtr destInterfaces =3D NULL; =20 if (!interfaces) return NULL; =20 - if (!(dest =3D virInterfaceObjListNew())) + if (!(destInterfaces =3D virInterfaceObjListNew())) return NULL; =20 - cnt =3D interfaces->count; - for (i =3D 0; i < cnt; i++) { - virInterfaceObjPtr srcobj =3D interfaces->objs[i]; - virInterfaceDefPtr backup; - virInterfaceObjPtr obj; - char *xml =3D virInterfaceDefFormat(srcobj->def); + if (virObjectLookupHashClone(interfaces, destInterfaces, + virInterfaceObjListCloneCb) < 0) + goto cleanup; =20 - if (!xml) - goto error; + return destInterfaces; =20 - if (!(backup =3D virInterfaceDefParseString(xml))) { - VIR_FREE(xml); - goto error; - } - - VIR_FREE(xml); - if (!(obj =3D virInterfaceObjListAssignDef(dest, backup))) - goto error; - virInterfaceObjEndAPI(&obj); - } - - return dest; - - error: - virInterfaceObjListFree(dest); + cleanup: + virObjectUnref(destInterfaces); return NULL; } =20 @@ -252,24 +262,29 @@ virInterfaceObjListAssignDef(virInterfaceObjListPtr i= nterfaces, virInterfaceDefPtr def) { virInterfaceObjPtr obj; + virInterfaceObjPtr ret =3D NULL; =20 - if ((obj =3D virInterfaceObjListFindByName(interfaces, def->name))) { + virObjectRWLockWrite(interfaces); + + if ((obj =3D virInterfaceObjListFindByNameLocked(interfaces, def->name= ))) { virInterfaceDefFree(obj->def); obj->def =3D def; + } else { + if (!(obj =3D virInterfaceObjNew())) + goto cleanup; =20 - return obj; + if (virObjectLookupHashAdd(interfaces, obj, NULL, def->name) < 0) + goto cleanup; + obj->def =3D def; } =20 - if (!(obj =3D virInterfaceObjNew())) - return NULL; + ret =3D obj; + obj =3D NULL; =20 - if (VIR_APPEND_ELEMENT_COPY(interfaces->objs, - interfaces->count, obj) < 0) { - virInterfaceObjEndAPI(&obj); - return NULL; - } - obj->def =3D def; - return virObjectRef(obj); + cleanup: + virInterfaceObjEndAPI(&obj); + virObjectRWUnlock(interfaces); + return ret; } =20 =20 @@ -277,20 +292,43 @@ void virInterfaceObjListRemove(virInterfaceObjListPtr interfaces, virInterfaceObjPtr obj) { - size_t i; + if (!obj) + return; =20 - virObjectUnlock(obj); - for (i =3D 0; i < interfaces->count; i++) { - virObjectLock(interfaces->objs[i]); - if (interfaces->objs[i] =3D=3D obj) { - virObjectUnlock(interfaces->objs[i]); - virObjectUnref(interfaces->objs[i]); - - VIR_DELETE_ELEMENT(interfaces->objs, i, interfaces->count); - break; + /* @obj is locked upon entry */ + virObjectLookupHashRemove(interfaces, obj, NULL, obj->def->name); +} + + +static int +virInterfaceObjListGetHelper(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + virInterfaceObjPtr obj =3D payload; + virObjectLookupHashForEachDataPtr data =3D opaque; + char **const names =3D (char **const)data->elems; + virInterfaceDefPtr def; + + if (data->error) + return 0; + + if (data->maxElems >=3D 0 && data->nElems =3D=3D data->maxElems) + return 0; + + virObjectLock(obj); + def =3D obj->def; + if (data->wantActive =3D=3D virInterfaceObjIsActive(obj)) { + if (names && VIR_STRDUP(names[data->nElems], def->name) < 0) { + data->error =3D true; + goto cleanup; } - virObjectUnlock(interfaces->objs[i]); - } + data->nElems++; + } + + cleanup: + virObjectUnlock(obj); + return 0; } =20 =20 @@ -298,18 +336,13 @@ int virInterfaceObjListNumOfInterfaces(virInterfaceObjListPtr interfaces, bool wantActive) { - size_t i; - int ninterfaces =3D 0; - - for (i =3D 0; (i < interfaces->count); i++) { - virInterfaceObjPtr obj =3D interfaces->objs[i]; - virObjectLock(obj); - if (wantActive =3D=3D virInterfaceObjIsActive(obj)) - ninterfaces++; - virObjectUnlock(obj); - } + virObjectLookupHashForEachData data =3D { + .wantActive =3D wantActive, .error =3D false, .nElems =3D 0, + .elems =3D NULL, .maxElems =3D -2 }; =20 - return ninterfaces; + return virObjectLookupHashForEachName(interfaces, + virInterfaceObjListGetHelper, + &data); } =20 =20 @@ -319,30 +352,11 @@ virInterfaceObjListGetNames(virInterfaceObjListPtr in= terfaces, char **const names, int maxnames) { - int nnames =3D 0; - size_t i; - - for (i =3D 0; i < interfaces->count && nnames < maxnames; i++) { - virInterfaceObjPtr obj =3D interfaces->objs[i]; - virInterfaceDefPtr def; - - virObjectLock(obj); - def =3D obj->def; - if (wantActive =3D=3D virInterfaceObjIsActive(obj)) { - if (VIR_STRDUP(names[nnames], def->name) < 0) { - virObjectUnlock(obj); - goto failure; - } - nnames++; - } - virObjectUnlock(obj); - } - - return nnames; - - failure: - while (--nnames >=3D 0) - VIR_FREE(names[nnames]); + virObjectLookupHashForEachData data =3D { + .wantActive =3D wantActive, .error =3D false, .nElems =3D 0, + .elems =3D (void **)names, .maxElems =3D maxnames }; =20 - return -1; + return virObjectLookupHashForEachName(interfaces, + virInterfaceObjListGetHelper, + &data); } --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523441081330.5200079847615; Wed, 23 Aug 2017 14:24:01 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 63FBE7EA97; Wed, 23 Aug 2017 21:23:59 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 41A9C60476; Wed, 23 Aug 2017 21:23:59 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 0A3773FAD0; Wed, 23 Aug 2017 21:23:59 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLNw35024264 for ; Wed, 23 Aug 2017 17:23:58 -0400 Received: by smtp.corp.redhat.com (Postfix) id 304C180DAF; Wed, 23 Aug 2017 21:23:58 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id 73859831A0 for ; Wed, 23 Aug 2017 21:23:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 63FBE7EA97 Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:08 -0400 Message-Id: <20170823212211.4693-13-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 12/15] test: Clean up test driver Interface interactions 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 23 Aug 2017 21:23:59 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Now that we have self locking hash table for Interface object lookups, there's no need to take the test driver lock in order to "lock" between the various API's, so remove the Lock/Unlock logic accordingly. Add a virInterfaceObjListFree during testDriverFree for the backupIfaces "just in case". Also use the VIR_STEAL_PTR rather than inline the code. Finally alter a couple of "if ((obj =3D function()) =3D=3D NULL" to use the more standard "if (!(obj =3D function()))" syntax. Signed-off-by: John Ferlan --- src/test/test_driver.c | 55 ++++++++++++----------------------------------= ---- 1 file changed, 13 insertions(+), 42 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index aa38f54..70977b8 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -155,6 +155,7 @@ testDriverFree(testDriverPtr driver) virNodeDeviceObjListFree(driver->devs); virObjectUnref(driver->networks); virInterfaceObjListFree(driver->ifaces); + virInterfaceObjListFree(driver->backupIfaces); virStoragePoolObjListFree(&driver->pools); virObjectUnref(driver->eventState); virMutexUnlock(&driver->lock); @@ -3689,11 +3690,7 @@ testInterfaceObjFindByName(testDriverPtr privconn, { virInterfaceObjPtr obj; =20 - testDriverLock(privconn); - obj =3D virInterfaceObjListFindByName(privconn->ifaces, name); - testDriverUnlock(privconn); - - if (!obj) + if (!(obj =3D virInterfaceObjListFindByName(privconn->ifaces, name))) virReportError(VIR_ERR_NO_INTERFACE, _("no interface with matching name '%s'"), name); @@ -3706,12 +3703,8 @@ static int testConnectNumOfInterfaces(virConnectPtr conn) { testDriverPtr privconn =3D conn->privateData; - int ninterfaces; =20 - testDriverLock(privconn); - ninterfaces =3D virInterfaceObjListNumOfInterfaces(privconn->ifaces, t= rue); - testDriverUnlock(privconn); - return ninterfaces; + return virInterfaceObjListNumOfInterfaces(privconn->ifaces, true); } =20 =20 @@ -3721,14 +3714,8 @@ testConnectListInterfaces(virConnectPtr conn, int maxnames) { testDriverPtr privconn =3D conn->privateData; - int nnames; =20 - testDriverLock(privconn); - nnames =3D virInterfaceObjListGetNames(privconn->ifaces, true, - names, maxnames); - testDriverUnlock(privconn); - - return nnames; + return virInterfaceObjListGetNames(privconn->ifaces, true, names, maxn= ames); } =20 =20 @@ -3736,12 +3723,8 @@ static int testConnectNumOfDefinedInterfaces(virConnectPtr conn) { testDriverPtr privconn =3D conn->privateData; - int ninterfaces; =20 - testDriverLock(privconn); - ninterfaces =3D virInterfaceObjListNumOfInterfaces(privconn->ifaces, f= alse); - testDriverUnlock(privconn); - return ninterfaces; + return virInterfaceObjListNumOfInterfaces(privconn->ifaces, false); } =20 =20 @@ -3751,14 +3734,8 @@ testConnectListDefinedInterfaces(virConnectPtr conn, int maxnames) { testDriverPtr privconn =3D conn->privateData; - int nnames; =20 - testDriverLock(privconn); - nnames =3D virInterfaceObjListGetNames(privconn->ifaces, false, - names, maxnames); - testDriverUnlock(privconn); - - return nnames; + return virInterfaceObjListGetNames(privconn->ifaces, false, names, max= names); } =20 =20 @@ -3791,12 +3768,8 @@ testInterfaceLookupByMACString(virConnectPtr conn, char *ifacenames[] =3D { NULL, NULL }; virInterfacePtr ret =3D NULL; =20 - testDriverLock(privconn); - ifacect =3D virInterfaceObjListFindByMACString(privconn->ifaces, mac, - ifacenames, 2); - testDriverUnlock(privconn); - - if (ifacect =3D=3D 0) { + if ((ifacect =3D virInterfaceObjListFindByMACString(privconn->ifaces, = mac, + ifacenames, 2)) =3D= =3D 0) { virReportError(VIR_ERR_NO_INTERFACE, _("no interface with matching mac '%s'"), mac); goto cleanup; @@ -3880,6 +3853,7 @@ testInterfaceChangeCommit(virConnectPtr conn, } =20 virInterfaceObjListFree(privconn->backupIfaces); + privconn->backupIfaces =3D NULL; privconn->transaction_running =3D false; =20 ret =3D 0; @@ -3910,8 +3884,7 @@ testInterfaceChangeRollback(virConnectPtr conn, } =20 virInterfaceObjListFree(privconn->ifaces); - privconn->ifaces =3D privconn->backupIfaces; - privconn->backupIfaces =3D NULL; + VIR_STEAL_PTR(privconn->ifaces, privconn->backupIfaces); =20 privconn->transaction_running =3D false; =20 @@ -3958,11 +3931,10 @@ testInterfaceDefineXML(virConnectPtr conn, =20 virCheckFlags(0, NULL); =20 - testDriverLock(privconn); - if ((def =3D virInterfaceDefParseString(xmlStr)) =3D=3D NULL) - goto cleanup; + if (!(def =3D virInterfaceDefParseString(xmlStr))) + return NULL; =20 - if ((obj =3D virInterfaceObjListAssignDef(privconn->ifaces, def)) =3D= =3D NULL) + if (!(obj =3D virInterfaceObjListAssignDef(privconn->ifaces, def))) goto cleanup; def =3D NULL; objdef =3D virInterfaceObjGetDef(obj); @@ -3972,7 +3944,6 @@ testInterfaceDefineXML(virConnectPtr conn, cleanup: virInterfaceDefFree(def); virInterfaceObjEndAPI(&obj); - testDriverUnlock(privconn); return ret; } =20 --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523443116986.4661103278206; Wed, 23 Aug 2017 14:24:03 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6D8517F3F8; Wed, 23 Aug 2017 21:24:01 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4C18381EF3; Wed, 23 Aug 2017 21:24:01 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 0EAF41806108; Wed, 23 Aug 2017 21:24:01 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLO0Be024274 for ; Wed, 23 Aug 2017 17:24:00 -0400 Received: by smtp.corp.redhat.com (Postfix) id 3144E80DAF; Wed, 23 Aug 2017 21:24:00 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id 56FB580DB8 for ; Wed, 23 Aug 2017 21:23:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 6D8517F3F8 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:09 -0400 Message-Id: <20170823212211.4693-14-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 13/15] util: Introduce virObjectLookupHashPrune 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 23 Aug 2017 21:24:01 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" A convenience API that will utilize the virHashForEach API for the LookupHash in order to remove elements from the hash table(s) that match some requirement from the callback. NB: Once elements are removed from objsUUID - if something goes wrong in objsName, the best that can be done is to issue an error message and hope for the best. Signed-off-by: John Ferlan --- src/libvirt_private.syms | 1 + src/util/virobject.c | 39 +++++++++++++++++++++++++++++++++++++++ src/util/virobject.h | 5 +++++ 3 files changed, 45 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ecbd84a..e4c465f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2337,6 +2337,7 @@ virObjectLookupHashFindLocked; virObjectLookupHashForEachName; virObjectLookupHashForEachUUID; virObjectLookupHashNew; +virObjectLookupHashPrune; virObjectLookupHashRemove; virObjectLookupHashSearchName; virObjectLookupHashSearchNameLocked; diff --git a/src/util/virobject.c b/src/util/virobject.c index 7152b17..c259ccc 100644 --- a/src/util/virobject.c +++ b/src/util/virobject.c @@ -1262,3 +1262,42 @@ virObjectLookupHashClone(void *srcAnyobj, =20 return 0; } + + +/** + * virObjectLookupHashPrune + * @anyobj: LookupHash object + * @callback: callback function to handle the object specific checks + * @opaque: callback data + * + * Call the callback function from virHashRemoveSet in order to determine + * if the incoming opaque data should be removed from the hash table(s) + * for the LookupHash. If a second hash table exists and we fail to remove + * the same number of elements, then issue an ERROR message, but continue + * on as there's not much we can do now to restore the data other than + * attempt to let someone know. + */ +void +virObjectLookupHashPrune(void *anyobj, + virHashSearcher callback, + void *opaque) +{ + virObjectLookupHashPtr hashObj =3D virObjectGetLookupHashObj(anyobj); + ssize_t cntUUIDs =3D 0; + ssize_t cntNames =3D 0; + + if (!hashObj) + return; + + virObjectRWLockWrite(hashObj); + if (hashObj->objsUUID) + cntUUIDs =3D virHashRemoveSet(hashObj->objsUUID, callback, opaque); + + if (hashObj->objsName) + cntNames =3D virHashRemoveSet(hashObj->objsName, callback, opaque); + + if (hashObj->objsUUID && hashObj->objsName && cntNames !=3D cntUUIDs) + VIR_ERROR(_("removed %zd elems from objsUUID and %zd elems " + "from objsName"), cntUUIDs, cntNames); + virObjectRWUnlock(hashObj); +} diff --git a/src/util/virobject.h b/src/util/virobject.h index 66b44ca..a6038fc 100644 --- a/src/util/virobject.h +++ b/src/util/virobject.h @@ -264,5 +264,10 @@ virObjectLookupHashClone(void *srcAnyobj, virObjectLookupHashCloneCallback cb) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); =20 +void +virObjectLookupHashPrune(void *anyobj, + virHashSearcher callback, + void *opaque) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); =20 #endif /* __VIR_OBJECT_H */ --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523446835798.1351372863925; Wed, 23 Aug 2017 14:24:06 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0E7687EA9B; Wed, 23 Aug 2017 21:24:05 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DDCC25D753; Wed, 23 Aug 2017 21:24:04 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 9E91B3FAD4; Wed, 23 Aug 2017 21:24:04 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLO38A024284 for ; Wed, 23 Aug 2017 17:24:03 -0400 Received: by smtp.corp.redhat.com (Postfix) id 18EA680DAF; Wed, 23 Aug 2017 21:24:03 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id E9EB681EFB for ; Wed, 23 Aug 2017 21:24:00 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 0E7687EA9B Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:10 -0400 Message-Id: <20170823212211.4693-15-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 14/15] network: Fix virNetworkObjBridgeInUse return type 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 23 Aug 2017 21:24:05 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Rather than an int, it returns a bool - so let's define it that way Signed-off-by: John Ferlan --- src/conf/virnetworkobj.c | 2 +- src/conf/virnetworkobj.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/conf/virnetworkobj.c b/src/conf/virnetworkobj.c index 2bd69dc..20f846d 100644 --- a/src/conf/virnetworkobj.c +++ b/src/conf/virnetworkobj.c @@ -1172,7 +1172,7 @@ virNetworkObjBridgeInUseHelper(const void *payload, } =20 =20 -int +bool virNetworkObjBridgeInUse(virNetworkObjListPtr nets, const char *bridge, const char *skipname) diff --git a/src/conf/virnetworkobj.h b/src/conf/virnetworkobj.h index 463be26..627277b 100644 --- a/src/conf/virnetworkobj.h +++ b/src/conf/virnetworkobj.h @@ -174,7 +174,7 @@ virNetworkObjDeleteConfig(const char *configDir, const char *autostartDir, virNetworkObjPtr net); =20 -int +bool virNetworkObjBridgeInUse(virNetworkObjListPtr nets, const char *bridge, const char *skipname); --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Wed May 1 11:23:36 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1503523450538522.980248593688; Wed, 23 Aug 2017 14:24:10 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CDBF1404336; Wed, 23 Aug 2017 21:24:07 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id ABCA87AA57; Wed, 23 Aug 2017 21:24:07 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 745623FAD7; Wed, 23 Aug 2017 21:24:07 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7NLO6Ko024294 for ; Wed, 23 Aug 2017 17:24:06 -0400 Received: by smtp.corp.redhat.com (Postfix) id 020C180DB1; Wed, 23 Aug 2017 21:24:06 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-123-165.rdu2.redhat.com [10.10.123.165]) by smtp.corp.redhat.com (Postfix) with ESMTP id 74C3181EEB for ; Wed, 23 Aug 2017 21:24:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com CDBF1404336 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=libvir-list-bounces@redhat.com From: John Ferlan To: libvir-list@redhat.com Date: Wed, 23 Aug 2017 17:22:11 -0400 Message-Id: <20170823212211.4693-16-jferlan@redhat.com> In-Reply-To: <20170823212211.4693-1-jferlan@redhat.com> References: <20170823212211.4693-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v5 15/15] network: Use virObjectLookupHash 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-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 23 Aug 2017 21:24:08 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Use the virObjectLookupHash in _virNetworkObjList. Convert the code to use the LookupHash object and APIs rather than the local code and usage of virHash* calls. Since the _virNetworkObjList only contains the @parent object the virClassNew must be removed from OnceInit because instantiation would fail since the object size would be the same as the parent object size. Usage of HashLookup{Find|Search} API's returns a locked/reffed object so need to remove virObjectLock after FindBy*Locked calls. Use the def->name as a second key to the LookupHash to make for faster lookup's by name (instead of using Search on uuid key and matching the name. Signed-off-by: John Ferlan --- src/conf/virnetworkobj.c | 278 ++++++++++++++-----------------------------= ---- 1 file changed, 79 insertions(+), 199 deletions(-) diff --git a/src/conf/virnetworkobj.c b/src/conf/virnetworkobj.c index 20f846d..a5c7d19 100644 --- a/src/conf/virnetworkobj.c +++ b/src/conf/virnetworkobj.c @@ -61,15 +61,11 @@ struct _virNetworkObj { }; =20 struct _virNetworkObjList { - virObjectLockable parent; - - virHashTablePtr objs; + virObjectLookupHash parent; }; =20 static virClassPtr virNetworkObjClass; -static virClassPtr virNetworkObjListClass; static void virNetworkObjDispose(void *obj); -static void virNetworkObjListDispose(void *obj); =20 static int virNetworkObjOnceInit(void) @@ -80,11 +76,6 @@ virNetworkObjOnceInit(void) virNetworkObjDispose))) return -1; =20 - if (!(virNetworkObjListClass =3D virClassNew(virClassForObjectLockable= (), - "virNetworkObjList", - sizeof(virNetworkObjList), - virNetworkObjListDispose))) - return -1; return 0; } =20 @@ -332,36 +323,17 @@ virNetworkObjMacMgrDel(virNetworkObjPtr obj, 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; + return virObjectLookupHashNew(virClassForObjectLookupHash(), 50, + VIR_OBJECT_LOOKUP_HASH_UUID | + VIR_OBJECT_LOOKUP_HASH_NAME); } =20 =20 static virNetworkObjPtr virNetworkObjFindByUUIDLocked(virNetworkObjListPtr nets, - const unsigned char *uuid) + const char *uuidstr) { - virNetworkObjPtr obj =3D NULL; - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - virUUIDFormat(uuid, uuidstr); - - obj =3D virHashLookup(nets->objs, uuidstr); - if (obj) - virObjectRef(obj); - return obj; + return virObjectLookupHashFindLocked(nets, uuidstr); } =20 =20 @@ -379,30 +351,10 @@ virNetworkObjPtr virNetworkObjFindByUUID(virNetworkObjListPtr nets, const unsigned char *uuid) { - virNetworkObjPtr obj; - - virObjectLock(nets); - obj =3D virNetworkObjFindByUUIDLocked(nets, uuid); - virObjectUnlock(nets); - if (obj) - virObjectLock(obj); - return obj; -} - - -static int -virNetworkObjSearchName(const void *payload, - const void *name ATTRIBUTE_UNUSED, - const void *data) -{ - virNetworkObjPtr obj =3D (virNetworkObjPtr) payload; - int want =3D 0; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(uuid, uuidstr); =20 - virObjectLock(obj); - if (STREQ(obj->def->name, (const char *)data)) - want =3D 1; - virObjectUnlock(obj); - return want; + return virObjectLookupHashFind(nets, uuidstr); } =20 =20 @@ -410,12 +362,7 @@ static virNetworkObjPtr virNetworkObjFindByNameLocked(virNetworkObjListPtr nets, const char *name) { - virNetworkObjPtr obj =3D NULL; - - obj =3D virHashSearch(nets->objs, virNetworkObjSearchName, name, NULL); - if (obj) - virObjectRef(obj); - return obj; + return virObjectLookupHashFindLocked(nets, name); } =20 =20 @@ -433,14 +380,7 @@ virNetworkObjPtr virNetworkObjFindByName(virNetworkObjListPtr nets, const char *name) { - virNetworkObjPtr obj; - - virObjectLock(nets); - obj =3D virNetworkObjFindByNameLocked(nets, name); - virObjectUnlock(nets); - if (obj) - virObjectLock(obj); - return obj; + return virObjectLookupHashFind(nets, name); } =20 =20 @@ -470,15 +410,6 @@ virNetworkObjDispose(void *opaque) } =20 =20 -static void -virNetworkObjListDispose(void *opaque) -{ - virNetworkObjListPtr nets =3D opaque; - - virHashFree(nets->objs); -} - - /* * virNetworkObjUpdateAssignDef: * @network: the network object to update @@ -560,12 +491,12 @@ virNetworkObjAssignDefLocked(virNetworkObjListPtr net= s, virNetworkObjPtr ret =3D NULL; char uuidstr[VIR_UUID_STRING_BUFLEN]; =20 + virUUIDFormat(def->uuid, uuidstr); /* See if a network with matching UUID already exists */ - if ((obj =3D virNetworkObjFindByUUIDLocked(nets, def->uuid))) { + if ((obj =3D virNetworkObjFindByUUIDLocked(nets, uuidstr))) { virObjectLock(obj); /* UUID matches, but if names don't match, refuse it */ if (STRNEQ(obj->def->name, def->name)) { - virUUIDFormat(obj->def->uuid, uuidstr); virReportError(VIR_ERR_OPERATION_FAILED, _("network '%s' is already defined with uuid %s= "), obj->def->name, uuidstr); @@ -588,7 +519,6 @@ virNetworkObjAssignDefLocked(virNetworkObjListPtr nets, /* UUID does not match, but if a name matches, refuse it */ if ((obj =3D virNetworkObjFindByNameLocked(nets, def->name))) { virObjectLock(obj); - virUUIDFormat(obj->def->uuid, uuidstr); virReportError(VIR_ERR_OPERATION_FAILED, _("network '%s' already exists with uuid %s"), def->name, uuidstr); @@ -596,12 +526,10 @@ virNetworkObjAssignDefLocked(virNetworkObjListPtr net= s, } =20 if (!(obj =3D virNetworkObjNew())) - goto cleanup; + goto cleanup; =20 - virUUIDFormat(def->uuid, uuidstr); - if (virHashAddEntry(nets->objs, uuidstr, obj) < 0) + if (virObjectLookupHashAdd(nets, obj, uuidstr, def->name) < 0) goto cleanup; - virObjectRef(obj); =20 obj->def =3D def; obj->persistent =3D !(flags & VIR_NETWORK_OBJ_LIST_ADD_LIVE); @@ -638,9 +566,9 @@ virNetworkObjAssignDef(virNetworkObjListPtr nets, { virNetworkObjPtr obj; =20 - virObjectLock(nets); + virObjectRWLockWrite(nets); obj =3D virNetworkObjAssignDefLocked(nets, def, flags); - virObjectUnlock(nets); + virObjectRWUnlock(nets); return obj; } =20 @@ -786,14 +714,12 @@ virNetworkObjRemoveInactive(virNetworkObjListPtr nets, { char uuidstr[VIR_UUID_STRING_BUFLEN]; =20 + if (!obj) + return; + + /* @obj is already locked on entry */ virUUIDFormat(obj->def->uuid, uuidstr); - virObjectRef(obj); - virObjectUnlock(obj); - virObjectLock(nets); - virObjectLock(obj); - virHashRemoveEntry(nets->objs, uuidstr); - virObjectUnlock(nets); - virObjectUnref(obj); + virObjectLookupHashRemove(nets, obj, uuidstr, obj->def->name); } =20 =20 @@ -968,7 +894,8 @@ virNetworkLoadState(virNetworkObjListPtr nets, obj->floor_sum =3D floor_sum_val; =20 obj->taint =3D taint; - obj->active =3D true; /* network with a state file is by definition ac= tive */ + /* network with a state file is by definition active */ + virNetworkObjSetActive(obj, true); =20 cleanup: VIR_FREE(configFile); @@ -1177,14 +1104,16 @@ virNetworkObjBridgeInUse(virNetworkObjListPtr nets, const char *bridge, const char *skipname) { + bool ret; virNetworkObjPtr obj; struct virNetworkObjBridgeInUseHelperData data =3D {bridge, skipname}; =20 - virObjectLock(nets); - obj =3D virHashSearch(nets->objs, virNetworkObjBridgeInUseHelper, &dat= a, NULL); - virObjectUnlock(nets); + obj =3D virObjectLookupHashSearchUUID(nets, virNetworkObjBridgeInUseHe= lper, + &data); =20 - return obj !=3D NULL; + ret =3D obj !=3D NULL; + virNetworkObjEndAPI(&obj); + return ret; } =20 =20 @@ -1309,21 +1238,14 @@ virNetworkMatch(virNetworkObjPtr obj, #undef MATCH =20 =20 -struct virNetworkObjListData { - virConnectPtr conn; - virNetworkPtr *nets; - virNetworkObjListFilter filter; - unsigned int flags; - int nnets; - bool error; -}; - static int -virNetworkObjListPopulate(void *payload, +virNetworkObjListExportCb(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) { - struct virNetworkObjListData *data =3D opaque; + virObjectLookupHashForEachDataPtr data =3D opaque; + virNetworkPtr *nets =3D (virNetworkPtr *)data->elems; + virNetworkObjListFilter filter =3D data->filter; virNetworkObjPtr obj =3D payload; virNetworkPtr net =3D NULL; =20 @@ -1332,15 +1254,14 @@ virNetworkObjListPopulate(void *payload, =20 virObjectLock(obj); =20 - if (data->filter && - !data->filter(data->conn, obj->def)) + if (filter && !filter(data->conn, obj->def)) goto cleanup; =20 if (!virNetworkMatch(obj, data->flags)) goto cleanup; =20 - if (!data->nets) { - data->nnets++; + if (!nets) { + data->nElems++; goto cleanup; } =20 @@ -1349,7 +1270,7 @@ virNetworkObjListPopulate(void *payload, goto cleanup; } =20 - data->nets[data->nnets++] =3D net; + nets[data->nElems++] =3D net; =20 cleanup: virObjectUnlock(obj); @@ -1364,34 +1285,20 @@ virNetworkObjListExport(virConnectPtr conn, virNetworkObjListFilter filter, unsigned int flags) { - int ret =3D -1; - struct virNetworkObjListData data =3D { - .conn =3D conn, .nets =3D NULL, .filter =3D filter, .flags =3D fla= gs, - .nnets =3D 0, .error =3D false }; - - virObjectLock(netobjs); - if (nets && VIR_ALLOC_N(data.nets, virHashSize(netobjs->objs) + 1) < 0) - goto cleanup; + int ret; + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .error =3D false, .nElems =3D = 0, + .elems =3D NULL, .maxElems =3D 0, .flags =3D flags }; =20 - virHashForEach(netobjs->objs, virNetworkObjListPopulate, &data); + if (nets) + data.maxElems =3D -1; =20 - 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 virObjectLookupHashForEachUUID(netobjs, virNetworkObjListExpor= tCb, + &data); =20 - ret =3D data.nnets; - cleanup: - virObjectUnlock(netobjs); - while (data.nets && data.nnets) - virObjectUnref(data.nets[--data.nnets]); + if (nets) + *nets =3D (virNetworkPtr *)data.elems; =20 - VIR_FREE(data.nets); return ret; } =20 @@ -1407,10 +1314,11 @@ virNetworkObjListForEachHelper(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) { - struct virNetworkObjListForEachHelperData *data =3D opaque; + virObjectLookupHashForEachDataPtr data =3D opaque; + struct virNetworkObjListForEachHelperData *helperData =3D data->opaque; =20 - if (data->callback(payload, data->opaque) < 0) - data->ret =3D -1; + if (helperData->callback(payload, helperData->opaque) < 0) + helperData->ret =3D -1; return 0; } =20 @@ -1433,54 +1341,45 @@ virNetworkObjListForEach(virNetworkObjListPtr nets, virNetworkObjListIterator callback, void *opaque) { - struct virNetworkObjListForEachHelperData data =3D { + struct virNetworkObjListForEachHelperData helperData =3D { .callback =3D callback, .opaque =3D opaque, .ret =3D 0}; - virObjectLock(nets); - virHashForEach(nets->objs, virNetworkObjListForEachHelper, &data); - virObjectUnlock(nets); - return data.ret; -} + virObjectLookupHashForEachData data =3D { + .opaque =3D &helperData, .error =3D false, .maxElems =3D 0 }; =20 + return virObjectLookupHashForEachUUID(nets, virNetworkObjListForEachHe= lper, + &data); +} =20 -struct virNetworkObjListGetHelperData { - virConnectPtr conn; - virNetworkObjListFilter filter; - char **names; - int nnames; - int maxnames; - bool active; - bool error; -}; =20 static int virNetworkObjListGetHelper(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) { - struct virNetworkObjListGetHelperData *data =3D opaque; virNetworkObjPtr obj =3D payload; + virObjectLookupHashForEachDataPtr data =3D opaque; + virNetworkObjListFilter filter =3D data->filter; + char **names =3D (char **)data->elems; =20 if (data->error) return 0; =20 - if (data->maxnames >=3D 0 && - data->nnames =3D=3D data->maxnames) + if (data->maxElems >=3D 0 && + data->nElems =3D=3D data->maxElems) return 0; =20 virObjectLock(obj); =20 - if (data->filter && - !data->filter(data->conn, obj->def)) + if (filter && !filter(data->conn, obj->def)) goto cleanup; =20 - if ((data->active && virNetworkObjIsActive(obj)) || - (!data->active && !virNetworkObjIsActive(obj))) { - if (data->names && - VIR_STRDUP(data->names[data->nnames], obj->def->name) < 0) { + if ((data->wantActive && virNetworkObjIsActive(obj)) || + (!data->wantActive && !virNetworkObjIsActive(obj))) { + if (names && VIR_STRDUP(names[data->nElems], obj->def->name) < 0) { data->error =3D true; goto cleanup; } - data->nnames++; + data->nElems++; } =20 cleanup: @@ -1497,26 +1396,12 @@ virNetworkObjListGetNames(virNetworkObjListPtr nets, virNetworkObjListFilter filter, virConnectPtr conn) { - int ret =3D -1; - - struct virNetworkObjListGetHelperData data =3D { - .conn =3D conn, .filter =3D filter, .names =3D names, .nnames =3D = 0, - .maxnames =3D maxnames, .active =3D active, .error =3D false}; - - virObjectLock(nets); - virHashForEach(nets->objs, virNetworkObjListGetHelper, &data); - virObjectUnlock(nets); - - if (data.error) - goto cleanup; + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .wantActive =3D active, .error= =3D false, + .nElems =3D 0, .elems =3D (void **)names, .maxElems =3D maxnames }; =20 - ret =3D data.nnames; - cleanup: - if (ret < 0) { - while (data.nnames) - VIR_FREE(data.names[--data.nnames]); - } - return ret; + return virObjectLookupHashForEachUUID(nets, virNetworkObjListGetHelper, + &data); } =20 =20 @@ -1526,15 +1411,12 @@ virNetworkObjListNumOfNetworks(virNetworkObjListPtr= nets, virNetworkObjListFilter filter, virConnectPtr conn) { - struct virNetworkObjListGetHelperData data =3D { - .conn =3D conn, .filter =3D filter, .names =3D NULL, .nnames =3D 0, - .maxnames =3D -1, .active =3D active, .error =3D false}; - - virObjectLock(nets); - virHashForEach(nets->objs, virNetworkObjListGetHelper, &data); - virObjectUnlock(nets); + virObjectLookupHashForEachData data =3D { + .conn =3D conn, .filter =3D filter, .wantActive =3D active, .error= =3D false, + .nElems =3D 0, .elems =3D NULL, .maxElems =3D -2 }; =20 - return data.nnames; + return virObjectLookupHashForEachUUID(nets, virNetworkObjListGetHelper, + &data); } =20 =20 @@ -1572,7 +1454,5 @@ virNetworkObjListPrune(virNetworkObjListPtr nets, { struct virNetworkObjListPruneHelperData data =3D {flags}; =20 - virObjectLock(nets); - virHashRemoveSet(nets->objs, virNetworkObjListPruneHelper, &data); - virObjectUnlock(nets); + virObjectLookupHashPrune(nets, virNetworkObjListPruneHelper, &data); } --=20 2.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list