From nobody Thu May 2 02:33:24 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 1515528381470580.3536777938631; Tue, 9 Jan 2018 12:06:21 -0800 (PST) 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 DA3A4780E5; Tue, 9 Jan 2018 20:06:13 +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 B437D8060C; Tue, 9 Jan 2018 20:06:11 +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 7013F410B4; Tue, 9 Jan 2018 20:06:05 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w09K63iB030554 for ; Tue, 9 Jan 2018 15:06:03 -0500 Received: by smtp.corp.redhat.com (Postfix) id 6E09B7F7F7; Tue, 9 Jan 2018 20:06:03 +0000 (UTC) Received: from unknown4ceb42c824f4.attlocal.net.com (ovpn-116-205.phx2.redhat.com [10.3.116.205]) by smtp.corp.redhat.com (Postfix) with ESMTP id E727C60FB9 for ; Tue, 9 Jan 2018 20:06:01 +0000 (UTC) From: John Ferlan To: libvir-list@redhat.com Date: Tue, 9 Jan 2018 15:05:50 -0500 Message-Id: <20180109200553.22516-2-jferlan@redhat.com> In-Reply-To: <20180109200553.22516-1-jferlan@redhat.com> References: <20180109200553.22516-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 1/4] storage: When delete volume avoid disk backend removal 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.27]); Tue, 09 Jan 2018 20:06:14 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" For a disk backend, the deleteVol code will clear all the volumes in the pool and perform a pool refresh, thus the storageVolDeleteInternal should not use access @voldef after deleteVol succeeds. Signed-off-by: John Ferlan --- src/storage/storage_driver.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index f590f6b9b..3b66d5171 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -1670,15 +1670,21 @@ storageVolDeleteInternal(virStorageVolPtr vol, if (backend->deleteVol(vol->conn, obj, voldef, flags) < 0) goto cleanup; =20 + /* The disk backend updated the pool data including removing the + * voldef from the pool (for both the deleteVol and the createVol + * failure path. */ + if (def->type =3D=3D VIR_STORAGE_POOL_DISK) { + ret =3D 0; + goto cleanup; + } + /* Update pool metadata - don't update meta data from error paths * in this module since the allocation/available weren't adjusted yet. * Ignore the disk backend since it updates the pool values. */ if (updateMeta) { - if (def->type !=3D VIR_STORAGE_POOL_DISK) { - def->allocation -=3D voldef->target.allocation; - def->available +=3D voldef->target.allocation; - } + def->allocation -=3D voldef->target.allocation; + def->available +=3D voldef->target.allocation; } =20 virStoragePoolObjRemoveVol(obj, voldef); --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 02:33:24 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 1515528452862986.0216729200441; Tue, 9 Jan 2018 12:07:32 -0800 (PST) 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 1E26C8762C; Tue, 9 Jan 2018 20:07:26 +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 6E13E7E47B; Tue, 9 Jan 2018 20:07:24 +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 9341A18033DC; Tue, 9 Jan 2018 20:07:22 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w09K63oA030561 for ; Tue, 9 Jan 2018 15:06:03 -0500 Received: by smtp.corp.redhat.com (Postfix) id D906E60FB9; Tue, 9 Jan 2018 20:06:03 +0000 (UTC) Received: from unknown4ceb42c824f4.attlocal.net.com (ovpn-116-205.phx2.redhat.com [10.3.116.205]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9688A7F7F7 for ; Tue, 9 Jan 2018 20:06:03 +0000 (UTC) From: John Ferlan To: libvir-list@redhat.com Date: Tue, 9 Jan 2018 15:05:51 -0500 Message-Id: <20180109200553.22516-3-jferlan@redhat.com> In-Reply-To: <20180109200553.22516-1-jferlan@redhat.com> References: <20180109200553.22516-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 2/4] storage: Modify virStorageBackendDiskMakeDataVol logic 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.26]); Tue, 09 Jan 2018 20:07:27 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Alter the logic such that we only add the volume to the pool once we've filled in all the information and cause failure to go to a common error: label. Patches to place the @vol into a few hash tables will soon "require" that at least the keys (name, target.path, and key) be populated with valid data. Signed-off-by: John Ferlan --- src/storage/storage_backend_disk.c | 40 ++++++++++++++++++++++++----------= ---- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backe= nd_disk.c index 44c135d80..f862a896b 100644 --- a/src/storage/storage_backend_disk.c +++ b/src/storage/storage_backend_disk.c @@ -61,6 +61,7 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr poo= l, { virStoragePoolDefPtr def =3D virStoragePoolObjGetDef(pool); char *tmp, *devpath, *partname; + bool addVol =3D false; =20 /* Prepended path will be same for all partitions, so we can * strip the path to form a reasonable pool-unique name @@ -74,18 +75,16 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr p= ool, /* This is typically a reload/restart/refresh path where * we're discovering the existing partitions for the pool */ + addVol =3D true; if (VIR_ALLOC(vol) < 0) return -1; - if (VIR_STRDUP(vol->name, partname) < 0 || - virStoragePoolObjAddVol(pool, vol) < 0) { - virStorageVolDefFree(vol); - return -1; - } + if (VIR_STRDUP(vol->name, partname) < 0) + goto error; } =20 if (vol->target.path =3D=3D NULL) { if (VIR_STRDUP(devpath, groups[0]) < 0) - return -1; + goto error; =20 /* Now figure out the stable path * @@ -96,7 +95,7 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr poo= l, vol->target.path =3D virStorageBackendStablePath(pool, devpath, tr= ue); VIR_FREE(devpath); if (vol->target.path =3D=3D NULL) - return -1; + goto error; } =20 /* Enforce provided vol->name is the same as what parted created. @@ -129,37 +128,37 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr= pool, (tmp =3D strrchr(vol->target.path, 'p'))) memmove(tmp, tmp + 1, strlen(tmp)); } - return -1; + goto error; } =20 if (vol->key =3D=3D NULL) { /* XXX base off a unique key of the underlying disk */ if (VIR_STRDUP(vol->key, vol->target.path) < 0) - return -1; + goto error; } =20 if (vol->source.extents =3D=3D NULL) { if (VIR_ALLOC(vol->source.extents) < 0) - return -1; + goto error; vol->source.nextent =3D 1; =20 if (virStrToLong_ull(groups[3], NULL, 10, &vol->source.extents[0].start) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot parse device start location")); - return -1; + goto error; } =20 if (virStrToLong_ull(groups[4], NULL, 10, &vol->source.extents[0].end) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot parse device end location")); - return -1; + goto error; } =20 if (VIR_STRDUP(vol->source.extents[0].path, def->source.devices[0].path) < 0) - return -1; + goto error; } =20 /* set partition type */ @@ -190,16 +189,22 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr= pool, VIR_STORAGE_VOL_OPEN_DEFAULT | VIR_STORAGE_VOL_OPEN_NOERROR, 0) =3D=3D -1) - return -1; + goto error; vol->target.allocation =3D 0; vol->target.capacity =3D (vol->source.extents[0].end - vol->source.extents[0].start); } else { if (virStorageBackendUpdateVolInfo(vol, false, VIR_STORAGE_VOL_OPEN_DEFAULT, 0= ) < 0) - return -1; + goto error; } =20 + /* Now that we've updated @vol enough, let's add it to the pool + * if it's not already there so that the subsequent pool search + * pool def adjustments will work properly */ + if (addVol && virStoragePoolObjAddVol(pool, vol) < 0) + goto error; + /* Find the extended partition and increase the allocation value */ if (vol->source.partType =3D=3D VIR_STORAGE_VOL_DISK_TYPE_LOGICAL) { virStorageVolDefPtr voldef; @@ -217,6 +222,11 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr = pool, def->capacity =3D vol->source.extents[0].end; =20 return 0; + + error: + if (addVol) + virStorageVolDefFree(vol); + return -1; } =20 static int --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 02:33:24 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 1515528467485840.085273026209; Tue, 9 Jan 2018 12:07:47 -0800 (PST) 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 20E3F61BB2; Tue, 9 Jan 2018 20:07:46 +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 687D85D9C6; Tue, 9 Jan 2018 20:07:45 +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 77F94410B5; Tue, 9 Jan 2018 20:07:43 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w09K644M030566 for ; Tue, 9 Jan 2018 15:06:04 -0500 Received: by smtp.corp.redhat.com (Postfix) id 510D77F7F7; Tue, 9 Jan 2018 20:06:04 +0000 (UTC) Received: from unknown4ceb42c824f4.attlocal.net.com (ovpn-116-205.phx2.redhat.com [10.3.116.205]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0EE1760FB9 for ; Tue, 9 Jan 2018 20:06:03 +0000 (UTC) From: John Ferlan To: libvir-list@redhat.com Date: Tue, 9 Jan 2018 15:05:52 -0500 Message-Id: <20180109200553.22516-4-jferlan@redhat.com> In-Reply-To: <20180109200553.22516-1-jferlan@redhat.com> References: <20180109200553.22516-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 3/4] storage: Introduce _virStorageVolObj[List] 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]); Tue, 09 Jan 2018 20:07:46 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Prepare for hash table volume lists by creating the object infrastructure for a Volume Object and Volume Object List The _virStorageVolObj will contain just a pointer to the "current" (and live) volume definition. The _virStorageVolObjList will contain three hash tables, one for each of the lookup options allowed for a volume. Signed-off-by: John Ferlan --- src/conf/virstorageobj.c | 130 +++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 130 insertions(+) diff --git a/src/conf/virstorageobj.c b/src/conf/virstorageobj.c index 1eaa53423..8a1c6f782 100644 --- a/src/conf/virstorageobj.c +++ b/src/conf/virstorageobj.c @@ -39,11 +39,18 @@ VIR_LOG_INIT("conf.virstorageobj"); =20 static virClassPtr virStoragePoolObjClass; static virClassPtr virStoragePoolObjListClass; +static virClassPtr virStorageVolObjClass; +static virClassPtr virStorageVolObjListClass; =20 static void virStoragePoolObjDispose(void *opaque); static void virStoragePoolObjListDispose(void *opaque); +static void +virStorageVolObjDispose(void *opaque); +static void +virStorageVolObjListDispose(void *opaque); + =20 =20 struct _virStorageVolDefList { @@ -51,6 +58,32 @@ struct _virStorageVolDefList { virStorageVolDefPtr *objs; }; =20 +typedef struct _virStorageVolObj virStorageVolObj; +typedef virStorageVolObj *virStorageVolObjPtr; +struct _virStorageVolObj { + virObjectLockable parent; + + virStorageVolDefPtr voldef; +}; + +typedef struct _virStorageVolObjList virStorageVolObjList; +typedef virStorageVolObjList *virStorageVolObjListPtr; +struct _virStorageVolObjList { + virObjectRWLockable parent; + + /* key string -> virStorageVolObj mapping + * for (1), lockless lookup-by-key */ + virHashTable *objsKey; + + /* name string -> virStorageVolObj mapping + * for (1), lockless lookup-by-name */ + virHashTable *objsName; + + /* path string -> virStorageVolObj mapping + * for (1), lockless lookup-by-path */ + virHashTable *objsPath; +}; + struct _virStoragePoolObj { virObjectLockable parent; =20 @@ -80,6 +113,103 @@ struct _virStoragePoolObjList { =20 =20 static int +virStorageVolObjOnceInit(void) +{ + if (!(virStorageVolObjClass =3D virClassNew(virClassForObjectLockable(= ), + "virStorageVolObj", + sizeof(virStorageVolObj), + virStorageVolObjDispose))) + return -1; + + if (!(virStorageVolObjListClass =3D virClassNew(virClassForObjectRWLoc= kable(), + "virStorageVolObjList", + sizeof(virStorageVolObjL= ist), + virStorageVolObjListDisp= ose))) + return -1; + + return 0; +} + +VIR_ONCE_GLOBAL_INIT(virStorageVolObj) + + +static virStorageVolObjPtr ATTRIBUTE_UNUSED +virStorageVolObjNew(void) +{ + virStorageVolObjPtr obj; + + if (virStorageVolObjInitialize() < 0) + return NULL; + + if (!(obj =3D virObjectLockableNew(virStorageVolObjClass))) + return NULL; + + virObjectLock(obj); + return obj; +} + + +static void ATTRIBUTE_UNUSED +virStorageVolObjEndAPI(virStorageVolObjPtr *obj) +{ + if (!*obj) + return; + + virObjectUnlock(*obj); + virObjectUnref(*obj); + *obj =3D NULL; +} + + +static void +virStorageVolObjDispose(void *opaque) +{ + virStorageVolObjPtr obj =3D opaque; + + if (!obj) + return; + + virStorageVolDefFree(obj->voldef); +} + + +static virStorageVolObjListPtr ATTRIBUTE_UNUSED +virStorageVolObjListNew(void) +{ + virStorageVolObjListPtr vols; + + if (virStorageVolObjInitialize() < 0) + return NULL; + + if (!(vols =3D virObjectRWLockableNew(virStorageVolObjListClass))) + return NULL; + + if (!(vols->objsKey =3D virHashCreate(10, virObjectFreeHashData)) || + !(vols->objsName =3D virHashCreate(10, virObjectFreeHashData)) || + !(vols->objsPath =3D virHashCreate(10, virObjectFreeHashData))) { + virObjectUnref(vols); + return NULL; + } + + return vols; +} + + +static void +virStorageVolObjListDispose(void *opaque) +{ + virStorageVolObjListPtr vols =3D opaque; + + if (!vols) + return; + + virHashFree(vols->objsKey); + virHashFree(vols->objsName); + virHashFree(vols->objsPath); +} + + +static int virStoragePoolObjOnceInit(void) { if (!(virStoragePoolObjClass =3D virClassNew(virClassForObjectLockable= (), --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Thu May 2 02:33:24 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 151552840695252.86592264255489; Tue, 9 Jan 2018 12:06:46 -0800 (PST) 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 EF15A62EB1; Tue, 9 Jan 2018 20:06:13 +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 E98C563142; Tue, 9 Jan 2018 20:06:11 +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 DE2BB18033D9; Tue, 9 Jan 2018 20:06:07 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w09K64Y9030576 for ; Tue, 9 Jan 2018 15:06:05 -0500 Received: by smtp.corp.redhat.com (Postfix) id D4B277F7F7; Tue, 9 Jan 2018 20:06:04 +0000 (UTC) Received: from unknown4ceb42c824f4.attlocal.net.com (ovpn-116-205.phx2.redhat.com [10.3.116.205]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7B50660FB9 for ; Tue, 9 Jan 2018 20:06:04 +0000 (UTC) From: John Ferlan To: libvir-list@redhat.com Date: Tue, 9 Jan 2018 15:05:53 -0500 Message-Id: <20180109200553.22516-5-jferlan@redhat.com> In-Reply-To: <20180109200553.22516-1-jferlan@redhat.com> References: <20180109200553.22516-1-jferlan@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 4/4] storage: Complete implementation volume by hash object 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.39]); Tue, 09 Jan 2018 20:06:40 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Alter the volume logic to use the hash tables instead of forward linked lists. There are three hash tables to allow for fast lookup by name, target.path, and key. Modify the virStoragePoolObjAddVol to place the object in all 3 tables if possible using self locking RWLock on the volumes object. Conversely when removing the volume, it's a removal of the object from the various hash tables. Implement functions to handle remote ForEach and Search Volume type helpers. These are used by the disk backend in order to facilitate adding a primary, extended, or logical partition. Implement the various VolDefFindBy* helpers as simple (and fast) hash lookups. The NumOfVolumes, GetNames, and ListExport helpers are all implemented using standard for each hash table calls. Signed-off-by: John Ferlan --- src/conf/virstorageobj.c | 420 +++++++++++++++++++++++++++++++++++--------= ---- 1 file changed, 311 insertions(+), 109 deletions(-) diff --git a/src/conf/virstorageobj.c b/src/conf/virstorageobj.c index 8a1c6f782..d92b2b2e3 100644 --- a/src/conf/virstorageobj.c +++ b/src/conf/virstorageobj.c @@ -53,11 +53,6 @@ virStorageVolObjListDispose(void *opaque); =20 =20 =20 -struct _virStorageVolDefList { - size_t count; - virStorageVolDefPtr *objs; -}; - typedef struct _virStorageVolObj virStorageVolObj; typedef virStorageVolObj *virStorageVolObjPtr; struct _virStorageVolObj { @@ -96,7 +91,7 @@ struct _virStoragePoolObj { virStoragePoolDefPtr def; virStoragePoolDefPtr newDef; =20 - virStorageVolDefList volumes; + virStorageVolObjListPtr volumes; }; =20 struct _virStoragePoolObjList { @@ -133,7 +128,7 @@ virStorageVolObjOnceInit(void) VIR_ONCE_GLOBAL_INIT(virStorageVolObj) =20 =20 -static virStorageVolObjPtr ATTRIBUTE_UNUSED +static virStorageVolObjPtr virStorageVolObjNew(void) { virStorageVolObjPtr obj; @@ -149,7 +144,7 @@ virStorageVolObjNew(void) } =20 =20 -static void ATTRIBUTE_UNUSED +static void virStorageVolObjEndAPI(virStorageVolObjPtr *obj) { if (!*obj) @@ -173,7 +168,7 @@ virStorageVolObjDispose(void *opaque) } =20 =20 -static virStorageVolObjListPtr ATTRIBUTE_UNUSED +static virStorageVolObjListPtr virStorageVolObjListNew(void) { virStorageVolObjListPtr vols; @@ -241,6 +236,11 @@ virStoragePoolObjNew(void) if (!(obj =3D virObjectLockableNew(virStoragePoolObjClass))) return NULL; =20 + if (!(obj->volumes =3D virStorageVolObjListNew())) { + virObjectUnref(obj); + return NULL; + } + virObjectLock(obj); obj->active =3D false; return obj; @@ -377,6 +377,7 @@ virStoragePoolObjDispose(void *opaque) return; =20 virStoragePoolObjClearVols(obj); + virObjectUnref(obj->volumes); =20 virStoragePoolDefFree(obj->def); virStoragePoolDefFree(obj->newDef); @@ -625,12 +626,9 @@ virStoragePoolSourceFindDuplicateDevices(virStoragePoo= lObjPtr obj, void virStoragePoolObjClearVols(virStoragePoolObjPtr obj) { - size_t i; - for (i =3D 0; i < obj->volumes.count; i++) - virStorageVolDefFree(obj->volumes.objs[i]); - - VIR_FREE(obj->volumes.objs); - obj->volumes.count =3D 0; + virHashRemoveAll(obj->volumes->objsKey); + virHashRemoveAll(obj->volumes->objsName); + virHashRemoveAll(obj->volumes->objsPath); } =20 =20 @@ -638,9 +636,40 @@ int virStoragePoolObjAddVol(virStoragePoolObjPtr obj, virStorageVolDefPtr voldef) { - if (VIR_APPEND_ELEMENT(obj->volumes.objs, obj->volumes.count, voldef) = < 0) - return -1; + virStorageVolObjPtr volobj =3D NULL; + virStorageVolObjListPtr volumes =3D obj->volumes; + + virObjectRWLockWrite(volumes); + + if (!(volobj =3D virStorageVolObjNew())) + goto error; + + if (virHashAddEntry(volumes->objsKey, voldef->key, volobj) < 0) + goto error; + virObjectRef(volobj); + + if (virHashAddEntry(volumes->objsName, voldef->name, volobj) < 0) { + virHashRemoveEntry(volumes->objsKey, voldef->key); + goto error; + } + virObjectRef(volobj); + + if (virHashAddEntry(volumes->objsPath, voldef->target.path, volobj) < = 0) { + virHashRemoveEntry(volumes->objsKey, voldef->key); + virHashRemoveEntry(volumes->objsName, voldef->name); + goto error; + } + virObjectRef(volobj); + + volobj->voldef =3D voldef; + virObjectRWUnlock(volumes); + virStorageVolObjEndAPI(&volobj); return 0; + + error: + virStorageVolObjEndAPI(&volobj); + virObjectRWUnlock(volumes); + return -1; } =20 =20 @@ -648,26 +677,58 @@ void virStoragePoolObjRemoveVol(virStoragePoolObjPtr obj, virStorageVolDefPtr voldef) { - virStoragePoolDefPtr def =3D virStoragePoolObjGetDef(obj); - size_t i; - - for (i =3D 0; i < obj->volumes.count; i++) { - if (obj->volumes.objs[i] =3D=3D voldef) { - VIR_INFO("Deleting volume '%s' from storage pool '%s'", - voldef->name, def->name); - virStorageVolDefFree(voldef); + virStorageVolObjListPtr volumes =3D obj->volumes; + virStorageVolObjPtr volobj; =20 - VIR_DELETE_ELEMENT(obj->volumes.objs, i, obj->volumes.count); - return; - } + virObjectRWLockWrite(volumes); + volobj =3D virHashLookup(volumes->objsName, voldef->name); + if (!volobj) { + VIR_INFO("Cannot find volume '%s' from storage pool '%s'", + voldef->name, obj->def->name); + virObjectRWUnlock(volumes); + return; } + VIR_INFO("Deleting volume '%s' from storage pool '%s'", + voldef->name, obj->def->name); + + virObjectRef(volobj); + virObjectLock(volobj); + virHashRemoveEntry(volumes->objsKey, voldef->key); + virHashRemoveEntry(volumes->objsName, voldef->name); + virHashRemoveEntry(volumes->objsPath, voldef->target.path); + virStorageVolObjEndAPI(&volobj); + + virObjectRWUnlock(volumes); } =20 =20 size_t virStoragePoolObjGetVolumesCount(virStoragePoolObjPtr obj) { - return obj->volumes.count; + return virHashSize(obj->volumes->objsKey); +} + + +struct _virStoragePoolObjForEachVolData { + virStorageVolObjListIterator iter; + const void *opaque; +}; + +static int +virStoragePoolObjForEachVolumeCb(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + int ret =3D 0; + virStorageVolObjPtr volobj =3D payload; + struct _virStoragePoolObjForEachVolData *data =3D opaque; + + virObjectLock(volobj); + if (data->iter(volobj->voldef, data->opaque) < 0) + ret =3D -1; + virObjectUnlock(volobj); + + return ret; } =20 =20 @@ -676,28 +737,58 @@ virStoragePoolObjForEachVolume(virStoragePoolObjPtr o= bj, virStorageVolObjListIterator iter, const void *opaque) { - size_t i; - - for (i =3D 0; i < obj->volumes.count; i++) { - if (iter(obj->volumes.objs[i], opaque) < 0) - return -1; - } + struct _virStoragePoolObjForEachVolData data =3D { + .iter =3D iter, .opaque =3D opaque }; =20 + virObjectRWLockRead(obj->volumes); + virHashForEach(obj->volumes->objsKey, virStoragePoolObjForEachVolumeCb, + &data); + virObjectRWUnlock(obj->volumes); return 0; } =20 =20 +struct _virStoragePoolObjSearchVolData { + virStorageVolObjListSearcher iter; + const void *opaque; +}; + +static int +virStoragePoolObjSearchVolumeCb(const void *payload, + const void *name ATTRIBUTE_UNUSED, + const void *opaque) +{ + virStorageVolObjPtr volobj =3D (virStorageVolObjPtr) payload; + struct _virStoragePoolObjSearchVolData *data =3D + (struct _virStoragePoolObjSearchVolData *) opaque; + int found =3D 0; + + virObjectLock(volobj); + if (data->iter(volobj->voldef, data->opaque)) + found =3D 1; + virObjectUnlock(volobj); + + return found; +} + + virStorageVolDefPtr virStoragePoolObjSearchVolume(virStoragePoolObjPtr obj, virStorageVolObjListSearcher iter, const void *opaque) { - size_t i; + virStorageVolObjPtr volobj; + struct _virStoragePoolObjSearchVolData data =3D { + .iter =3D iter, .opaque =3D opaque }; =20 - for (i =3D 0; i < obj->volumes.count; i++) { - if (iter(obj->volumes.objs[i], opaque)) - return obj->volumes.objs[i]; - } + virObjectRWLockRead(obj->volumes); + volobj =3D virHashSearch(obj->volumes->objsKey, + virStoragePoolObjSearchVolumeCb, + &data, NULL); + virObjectRWUnlock(obj->volumes); + + if (volobj) + return volobj->voldef; =20 return NULL; } @@ -707,12 +798,14 @@ virStorageVolDefPtr virStorageVolDefFindByKey(virStoragePoolObjPtr obj, const char *key) { - size_t i; + virStorageVolObjPtr volobj; =20 - for (i =3D 0; i < obj->volumes.count; i++) - if (STREQ(obj->volumes.objs[i]->key, key)) - return obj->volumes.objs[i]; + virObjectRWLockRead(obj->volumes); + volobj =3D virHashLookup(obj->volumes->objsKey, key); + virObjectRWUnlock(obj->volumes); =20 + if (volobj) + return volobj->voldef; return NULL; } =20 @@ -721,12 +814,14 @@ virStorageVolDefPtr virStorageVolDefFindByPath(virStoragePoolObjPtr obj, const char *path) { - size_t i; + virStorageVolObjPtr volobj; =20 - for (i =3D 0; i < obj->volumes.count; i++) - if (STREQ(obj->volumes.objs[i]->target.path, path)) - return obj->volumes.objs[i]; + virObjectRWLockRead(obj->volumes); + volobj =3D virHashLookup(obj->volumes->objsPath, path); + virObjectRWUnlock(obj->volumes); =20 + if (volobj) + return volobj->voldef; return NULL; } =20 @@ -735,34 +830,107 @@ virStorageVolDefPtr virStorageVolDefFindByName(virStoragePoolObjPtr obj, const char *name) { - size_t i; + virStorageVolObjPtr volobj; =20 - for (i =3D 0; i < obj->volumes.count; i++) - if (STREQ(obj->volumes.objs[i]->name, name)) - return obj->volumes.objs[i]; + virObjectRWLockRead(obj->volumes); + volobj =3D virHashLookup(obj->volumes->objsName, name); + virObjectRWUnlock(obj->volumes); =20 + if (volobj) + return volobj->voldef; return NULL; } =20 =20 +struct _virStorageVolObjCountData { + virConnectPtr conn; + virStoragePoolVolumeACLFilter filter; + virStoragePoolDefPtr pooldef; + int count; +}; + + +static int +virStoragePoolObjNumOfVolumesCb(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + virStorageVolObjPtr volobj =3D payload; + struct _virStorageVolObjCountData *data =3D opaque; + + virObjectLock(volobj); + + if (data->filter && !data->filter(data->conn, data->pooldef, + volobj->voldef)) + goto cleanup; + + data->count++; + + cleanup: + virObjectUnlock(volobj); + return 0; +} + + int virStoragePoolObjNumOfVolumes(virStoragePoolObjPtr obj, virConnectPtr conn, virStoragePoolVolumeACLFilter filter) { - virStoragePoolDefPtr pooldef =3D obj->def; - virStorageVolDefListPtr volumes =3D &obj->volumes; - int nvolumes =3D 0; - size_t i; + virStorageVolObjListPtr volumes =3D obj->volumes; + struct _virStorageVolObjCountData data =3D { + .conn =3D conn, .filter =3D filter, .pooldef =3D obj->def, .count = =3D 0 }; =20 - for (i =3D 0; i < volumes->count; i++) { - virStorageVolDefPtr def =3D volumes->objs[i]; - if (filter && !filter(conn, pooldef, def)) - continue; - nvolumes++; + virObjectRWLockRead(volumes); + virHashForEach(volumes->objsName, virStoragePoolObjNumOfVolumesCb, &da= ta); + virObjectRWUnlock(volumes); + + return data.count; +} + + +struct _virStorageVolObjNameData { + virConnectPtr conn; + virStoragePoolVolumeACLFilter filter; + virStoragePoolDefPtr pooldef; + bool error; + int nnames; + int maxnames; + char **const names; +}; + +static int +virStoragePoolObjVolumeGetNamesCb(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + virStorageVolObjPtr volobj =3D payload; + struct _virStorageVolObjNameData *data =3D opaque; + + if (data->error) + return 0; + + if (data->maxnames >=3D 0 && data->nnames =3D=3D data->maxnames) + return 0; + + virObjectLock(volobj); + + if (data->filter && !data->filter(data->conn, data->pooldef, + volobj->voldef)) + goto cleanup; + + if (data->names) { + if (VIR_STRDUP(data->names[data->nnames], volobj->voldef->name) < = 0) { + data->error =3D true; + goto cleanup; + } } =20 - return nvolumes; + data->nnames++; + + cleanup: + virObjectUnlock(volobj); + return 0; } =20 =20 @@ -773,75 +941,109 @@ virStoragePoolObjVolumeGetNames(virStoragePoolObjPtr= obj, char **const names, int maxnames) { - virStoragePoolDefPtr pooldef =3D obj->def; - virStorageVolDefListPtr volumes =3D &obj->volumes; - int nnames =3D 0; - size_t i; + virStorageVolObjListPtr volumes =3D obj->volumes; + struct _virStorageVolObjNameData data =3D { + .conn =3D conn, .filter =3D filter, .pooldef =3D obj->def, .error = =3D false, + .nnames =3D 0, .maxnames =3D maxnames, .names =3D names }; =20 - for (i =3D 0; i < volumes->count && nnames < maxnames; i++) { - virStorageVolDefPtr def =3D volumes->objs[i]; - if (filter && !filter(conn, pooldef, def)) - continue; - if (VIR_STRDUP(names[nnames], def->name) < 0) - goto failure; - nnames++; - } + virObjectRWLockRead(volumes); + virHashForEach(volumes->objsName, virStoragePoolObjVolumeGetNamesCb, &= data); + virObjectRWUnlock(volumes); =20 - return nnames; + if (data.error) + goto error; =20 - failure: - while (--nnames >=3D 0) - VIR_FREE(names[nnames]); + return data.nnames; =20 + error: + while (--data.nnames) + VIR_FREE(data.names[data.nnames]); return -1; } =20 =20 +struct _virStorageVolObjExportData { + virConnectPtr conn; + virStoragePoolVolumeACLFilter filter; + virStoragePoolDefPtr pooldef; + bool error; + int nvols; + virStorageVolPtr *vols; +}; + +static int +virStoragePoolObjVolumeListExportCb(void *payload, + const void *name ATTRIBUTE_UNUSED, + void *opaque) +{ + virStorageVolObjPtr volobj =3D payload; + struct _virStorageVolObjExportData *data =3D opaque; + virStorageVolPtr vol =3D NULL; + + if (data->error) + return 0; + + virObjectLock(volobj); + + if (data->filter && !data->filter(data->conn, data->pooldef, + volobj->voldef)) + goto cleanup; + + if (data->vols) { + if (!(vol =3D virGetStorageVol(data->conn, data->pooldef->name, + volobj->voldef->name, volobj->voldef-= >key, + NULL, NULL))) { + data->error =3D true; + goto cleanup; + } + data->vols[data->nvols] =3D vol; + } + + data->nvols++; + + cleanup: + virObjectUnlock(volobj); + return 0; +} + + int virStoragePoolObjVolumeListExport(virConnectPtr conn, virStoragePoolObjPtr obj, virStorageVolPtr **vols, virStoragePoolVolumeACLFilter filter) { - virStoragePoolDefPtr pooldef =3D obj->def; - virStorageVolDefListPtr volumes =3D &obj->volumes; - int ret =3D -1; - size_t i; - virStorageVolPtr *tmp_vols =3D NULL; - virStorageVolPtr vol =3D NULL; - int nvols =3D 0; + virStorageVolObjListPtr volumes =3D obj->volumes; + struct _virStorageVolObjExportData data =3D { + .conn =3D conn, .filter =3D filter, .pooldef =3D obj->def, .error = =3D false, + .nvols =3D 0, .vols =3D NULL }; + + virObjectRWLockRead(volumes); =20 - /* Just returns the volumes count */ if (!vols) { - ret =3D volumes->count; - goto cleanup; + int ret =3D virHashSize(volumes->objsName); + virObjectRWUnlock(volumes); + return ret; } =20 - if (VIR_ALLOC_N(tmp_vols, volumes->count + 1) < 0) - goto cleanup; - - for (i =3D 0; i < volumes->count; i++) { - virStorageVolDefPtr def =3D volumes->objs[i]; - if (filter && !filter(conn, pooldef, def)) - continue; - if (!(vol =3D virGetStorageVol(conn, pooldef->name, def->name, def= ->key, - NULL, NULL))) - goto cleanup; - tmp_vols[nvols++] =3D vol; + if (VIR_ALLOC_N(data.vols, virHashSize(volumes->objsName) + 1) < 0) { + virObjectRWUnlock(volumes); + return -1; } =20 - *vols =3D tmp_vols; - tmp_vols =3D NULL; - ret =3D nvols; + virHashForEach(volumes->objsName, virStoragePoolObjVolumeListExportCb,= &data); + virObjectRWUnlock(volumes); =20 - cleanup: - if (tmp_vols) { - for (i =3D 0; i < nvols; i++) - virObjectUnref(tmp_vols[i]); - VIR_FREE(tmp_vols); - } + if (data.error) + goto error; =20 - return ret; + *vols =3D data.vols; + + return data.nvols; + + error: + virObjectListFree(data.vols); + return -1; } =20 =20 --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list