From nobody Thu May 15 23:37:32 2025 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 150309309963531.957280822255143; Fri, 18 Aug 2017 14:51:39 -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 E7FBBC058EA8; Fri, 18 Aug 2017 21:51:37 +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 9BA46707DE; Fri, 18 Aug 2017 21:51:37 +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 5F688180610A; Fri, 18 Aug 2017 21:51:37 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v7ILom23005068 for ; Fri, 18 Aug 2017 17:50:48 -0400 Received: by smtp.corp.redhat.com (Postfix) id E7F485D962; Fri, 18 Aug 2017 21:50:48 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-120-47.rdu2.redhat.com [10.10.120.47]) by smtp.corp.redhat.com (Postfix) with ESMTP id B5C325D961 for ; Fri, 18 Aug 2017 21:50:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com E7FBBC058EA8 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: Fri, 18 Aug 2017 17:50:37 -0400 Message-Id: <20170818215041.8118-14-jferlan@redhat.com> In-Reply-To: <20170818215041.8118-1-jferlan@redhat.com> References: <20170818215041.8118-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v4 13/17] interface: Use virObjectLookup{Keys|Hash} 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.32]); Fri, 18 Aug 2017 21:51:38 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Use the virObjectLookupKeys in _virInterfaceObj and 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 HashLookup 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 | 300 ++++++++++++++++++++++++-----------------= ---- 1 file changed, 157 insertions(+), 143 deletions(-) diff --git a/src/conf/virinterfaceobj.c b/src/conf/virinterfaceobj.c index e993b92..f2475b8 100644 --- a/src/conf/virinterfaceobj.c +++ b/src/conf/virinterfaceobj.c @@ -33,15 +33,13 @@ VIR_LOG_INIT("conf.virinterfaceobj"); =20 struct _virInterfaceObj { - virObjectLockable parent; + virObjectLookupKeys parent; =20 - bool active; /* true if interface is active (up) */ virInterfaceDefPtr def; /* The interface definition */ }; =20 struct _virInterfaceObjList { - size_t count; - virInterfaceObjPtr *objs; + virObjectLookupHash parent; }; =20 /* virInterfaceObj manipulation */ @@ -52,7 +50,7 @@ static void virInterfaceObjDispose(void *obj); static int virInterfaceObjOnceInit(void) { - if (!(virInterfaceObjClass =3D virClassNew(virClassForObjectLockable(), + if (!(virInterfaceObjClass =3D virClassNew(virClassForObjectLookupKeys= (), "virInterfaceObj", sizeof(virInterfaceObj), virInterfaceObjDispose))) @@ -74,14 +72,14 @@ virInterfaceObjDispose(void *opaque) =20 =20 static virInterfaceObjPtr -virInterfaceObjNew(void) +virInterfaceObjNew(const char *name) { virInterfaceObjPtr obj; =20 if (virInterfaceObjInitialize() < 0) return NULL; =20 - if (!(obj =3D virObjectLockableNew(virInterfaceObjClass))) + if (!(obj =3D virObjectLookupKeysNew(virInterfaceObjClass, name, NULL)= )) return NULL; =20 virObjectLock(obj); @@ -112,7 +110,7 @@ virInterfaceObjGetDef(virInterfaceObjPtr obj) bool virInterfaceObjIsActive(virInterfaceObjPtr obj) { - return obj->active; + return virObjectLookupKeysIsActive(obj); } =20 =20 @@ -120,7 +118,7 @@ void virInterfaceObjSetActive(virInterfaceObjPtr obj, bool active) { - obj->active =3D active; + virObjectLookupKeysSetActive(obj, active); } =20 =20 @@ -128,11 +126,40 @@ virInterfaceObjSetActive(virInterfaceObjPtr obj, virInterfaceObjListPtr virInterfaceObjListNew(void) { - virInterfaceObjListPtr interfaces; + return virObjectLookupHashNew(virClassForObjectLookupHash(), 10, false= ); +} =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 +169,22 @@ 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 virObjectLookupHashForEach(interfaces, + virInterfaceObjListFindByMACStringCb, + &data); +} =20 - error: - while (--matchct >=3D 0) - VIR_FREE(matches[matchct]); =20 - return -1; +static virInterfaceObjPtr +virInterfaceObjListFindByNameLocked(virInterfaceObjListPtr interfaces, + const char *name) +{ + virObjectLookupKeysPtr obj =3D virObjectLookupHashFindLocked(interface= s, name); + return (virInterfaceObjPtr)obj; } =20 =20 @@ -176,73 +192,73 @@ 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; + virObjectLookupKeysPtr obj =3D virObjectLookupHashFind(interfaces, nam= e); + return (virInterfaceObjPtr) obj; } =20 =20 void virInterfaceObjListFree(virInterfaceObjListPtr interfaces) { - size_t i; + virObjectUnref(interfaces); +} + + +struct interfaceCloneData { + const char *primaryKey; + virInterfaceObjListPtr dest; + bool error; +}; + +static int +virInterfaceObjListCloneCb(void *destHashTable, + void *sourceObject) +{ + virInterfaceObjListPtr dest =3D destHashTable; + 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; =20 - for (i =3D 0; i < interfaces->count; i++) - virObjectUnref(interfaces->objs[i]); - VIR_FREE(interfaces->objs); - VIR_FREE(interfaces); + if (!(backup =3D virInterfaceDefParseString(xml))) + goto cleanup; + + if (!(obj =3D virInterfaceObjListAssignDef(dest, backup))) + goto cleanup; + + 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; - - if (!(backup =3D virInterfaceDefParseString(xml))) { - VIR_FREE(xml); - goto error; - } - - VIR_FREE(xml); - if (!(obj =3D virInterfaceObjListAssignDef(dest, backup))) - goto error; - virInterfaceObjEndAPI(&obj); - } + return destInterfaces; =20 - return dest; - - error: - virInterfaceObjListFree(dest); + cleanup: + virObjectUnref(destInterfaces); return NULL; } =20 @@ -252,24 +268,29 @@ virInterfaceObjListAssignDef(virInterfaceObjListPtr i= nterfaces, virInterfaceDefPtr def) { virInterfaceObjPtr obj; + virInterfaceObjPtr ret =3D NULL; + + virObjectRWLockWrite(interfaces); =20 - if ((obj =3D virInterfaceObjListFindByName(interfaces, def->name))) { + if ((obj =3D virInterfaceObjListFindByNameLocked(interfaces, def->name= ))) { virInterfaceDefFree(obj->def); obj->def =3D def; + } else { + if (!(obj =3D virInterfaceObjNew(def->name))) + goto cleanup; =20 - return obj; + if (virObjectLookupHashAdd(interfaces, (virObjectLookupKeysPtr)obj= ) < 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 +298,39 @@ void virInterfaceObjListRemove(virInterfaceObjListPtr interfaces, virInterfaceObjPtr obj) { - size_t i; + virObjectLookupHashRemove(interfaces, (virObjectLookupKeysPtr)obj); +} =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; + +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 +338,12 @@ 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 virObjectLookupHashForEach(interfaces, virInterfaceObjListGetHe= lper, + &data); } =20 =20 @@ -319,30 +353,10 @@ 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 virObjectLookupHashForEach(interfaces, virInterfaceObjListGetHe= lper, + &data); } --=20 2.9.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list