From nobody Thu May 15 19:29:09 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 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