From nobody Mon Feb 9 10:28:51 2026 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; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1553060496009741.7360342009645; Tue, 19 Mar 2019 22:41:36 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3A808C0B6146; Wed, 20 Mar 2019 05:41:34 +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 0E47B1A913; Wed, 20 Mar 2019 05:41:34 +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 CBE983FB15; Wed, 20 Mar 2019 05:41:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x2K5fP73017230 for ; Wed, 20 Mar 2019 01:41:25 -0400 Received: by smtp.corp.redhat.com (Postfix) id 477A11779A; Wed, 20 Mar 2019 05:41:25 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-65.phx2.redhat.com [10.3.116.65]) by smtp.corp.redhat.com (Postfix) with ESMTP id 23DDA17795; Wed, 20 Mar 2019 05:41:14 +0000 (UTC) From: Eric Blake To: libvir-list@redhat.com Date: Wed, 20 Mar 2019 00:40:55 -0500 Message-Id: <20190320054105.17689-7-eblake@redhat.com> In-Reply-To: <20190320054105.17689-1-eblake@redhat.com> References: <20190320054105.17689-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Cc: jtomko@redhat.com Subject: [libvirt] [PATCH 06/16] snapshot: Track current snapshot in virDomainSnapshotObjList 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: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Wed, 20 Mar 2019 05:41:34 +0000 (UTC) Content-Type: text/plain; charset="utf-8" It is easier to track the current snapshot as part of the list of snapshots. In particular, doing so lets us guarantee that the current snapshot is cleared if that snapshot is removed from the list (rather than depending on the caller to do so, and risking a use-after-free problem). This requires the addition of several new accessor functions. Signed-off-by: Eric Blake Reviewed-by: John Ferlan --- src/conf/domain_conf.h | 1 - src/conf/virdomainsnapshotobjlist.h | 10 +++-- src/conf/snapshot_conf.c | 4 +- src/conf/virdomainsnapshotobjlist.c | 63 ++++++++++++++++++++++++----- src/libvirt_private.syms | 4 ++ src/qemu/qemu_domain.c | 14 +++---- src/qemu/qemu_driver.c | 47 +++++++++------------ src/test/test_driver.c | 38 ++++++++--------- 8 files changed, 109 insertions(+), 72 deletions(-) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 538fb50b9e..e608440444 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2517,7 +2517,6 @@ struct _virDomainObj { virDomainDefPtr newDef; /* New definition to activate at shutdown */ virDomainSnapshotObjListPtr snapshots; - virDomainSnapshotObjPtr current_snapshot; bool hasManagedSave; diff --git a/src/conf/virdomainsnapshotobjlist.h b/src/conf/virdomainsnapsh= otobjlist.h index 2a1ee86586..e210849441 100644 --- a/src/conf/virdomainsnapshotobjlist.h +++ b/src/conf/virdomainsnapshotobjlist.h @@ -33,14 +33,12 @@ void virDomainSnapshotObjListFree(virDomainSnapshotObjL= istPtr snapshots); int virDomainSnapshotObjListParse(const char *xmlStr, const unsigned char *domain_uuid, virDomainSnapshotObjListPtr snapshots, - virDomainSnapshotObjPtr *current_snap, virCapsPtr caps, virDomainXMLOptionPtr xmlopt, unsigned int flags); int virDomainSnapshotObjListFormat(virBufferPtr buf, const char *uuidstr, virDomainSnapshotObjListPtr snapshots, - virDomainSnapshotObjPtr current_snapsho= t, virCapsPtr caps, virDomainXMLOptionPtr xmlopt, unsigned int flags); @@ -57,7 +55,13 @@ int virDomainSnapshotObjListNum(virDomainSnapshotObjList= Ptr snapshots, unsigned int flags); virDomainSnapshotObjPtr virDomainSnapshotFindByName(virDomainSnapshotObjLi= stPtr snapshots, const char *name); -void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots, +virDomainSnapshotObjPtr virDomainSnapshotGetCurrent(virDomainSnapshotObjLi= stPtr snapshots); +const char *virDomainSnapshotGetCurrentName(virDomainSnapshotObjListPtr sn= apshots); +bool virDomainSnapshotIsCurrentName(virDomainSnapshotObjListPtr snapshots, + const char *name); +void virDomainSnapshotSetCurrent(virDomainSnapshotObjListPtr snapshots, + virDomainSnapshotObjPtr snapshot); +bool virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots, virDomainSnapshotObjPtr snapshot); int virDomainSnapshotForEach(virDomainSnapshotObjListPtr snapshots, virHashIterator iter, diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c index bf5fdc0647..c692d36bd1 100644 --- a/src/conf/snapshot_conf.c +++ b/src/conf/snapshot_conf.c @@ -969,9 +969,9 @@ virDomainSnapshotRedefinePrep(virDomainPtr domain, return -1; } if (other) { - if (other =3D=3D vm->current_snapshot) { + if (other =3D=3D virDomainSnapshotGetCurrent(vm->snapshots)) { *update_current =3D true; - vm->current_snapshot =3D NULL; + virDomainSnapshotSetCurrent(vm->snapshots, NULL); } /* Drop and rebuild the parent relationship, but keep all diff --git a/src/conf/virdomainsnapshotobjlist.c b/src/conf/virdomainsnapsh= otobjlist.c index be44bdde71..1eecb89a5d 100644 --- a/src/conf/virdomainsnapshotobjlist.c +++ b/src/conf/virdomainsnapshotobjlist.c @@ -40,6 +40,7 @@ struct _virDomainSnapshotObjList { virHashTable *objs; virDomainSnapshotObj metaroot; /* Special parent of all root snapshots= */ + virDomainSnapshotObjPtr current; /* The current snapshot, if any */ }; @@ -50,7 +51,6 @@ int virDomainSnapshotObjListParse(const char *xmlStr, const unsigned char *domain_uuid, virDomainSnapshotObjListPtr snapshots, - virDomainSnapshotObjPtr *current_snap, virCapsPtr caps, virDomainXMLOptionPtr xmlopt, unsigned int flags) @@ -62,6 +62,7 @@ virDomainSnapshotObjListParse(const char *xmlStr, int n; size_t i; int keepBlanksDefault =3D xmlKeepBlanksDefault(0); + virDomainSnapshotObjPtr snap; VIR_AUTOFREE(xmlNodePtr *) nodes =3D NULL; VIR_AUTOFREE(char *) current =3D NULL; @@ -71,7 +72,7 @@ virDomainSnapshotObjListParse(const char *xmlStr, _("incorrect flags for bulk parse")); return -1; } - if (snapshots->metaroot.nchildren || *current_snap) { + if (snapshots->metaroot.nchildren || snapshots->current) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("bulk define of snapshots only possible with " "no existing snapshot")); @@ -106,7 +107,6 @@ virDomainSnapshotObjListParse(const char *xmlStr, for (i =3D 0; i < n; i++) { virDomainSnapshotDefPtr def; - virDomainSnapshotObjPtr snap; def =3D virDomainSnapshotDefParseNode(xml, nodes[i], caps, xmlopt,= NULL, flags); @@ -129,12 +129,13 @@ virDomainSnapshotObjListParse(const char *xmlStr, } if (current) { - if (!(*current_snap =3D virDomainSnapshotFindByName(snapshots, - current))) { + snap =3D virDomainSnapshotFindByName(snapshots, current); + if (!snap) { virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, _("no snapshot matching current=3D'%s'"), curre= nt); goto cleanup; } + virDomainSnapshotSetCurrent(snapshots, snap); } ret =3D 0; @@ -183,7 +184,6 @@ int virDomainSnapshotObjListFormat(virBufferPtr buf, const char *uuidstr, virDomainSnapshotObjListPtr snapshots, - virDomainSnapshotObjPtr current_snapshot, virCapsPtr caps, virDomainXMLOptionPtr xmlopt, unsigned int flags) @@ -197,9 +197,8 @@ virDomainSnapshotObjListFormat(virBufferPtr buf, }; virBufferAddLit(buf, "def->name); + virBufferEscapeString(buf, " current=3D'%s'", + virDomainSnapshotGetCurrentName(snapshots)); virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); if (virDomainSnapshotForEach(snapshots, virDomainSnapshotFormatOne, @@ -437,10 +436,52 @@ virDomainSnapshotFindByName(virDomainSnapshotObjListP= tr snapshots, return name ? virHashLookup(snapshots->objs, name) : &snapshots->metar= oot; } -void virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots, + +/* Return the current snapshot, or NULL */ +virDomainSnapshotObjPtr +virDomainSnapshotGetCurrent(virDomainSnapshotObjListPtr snapshots) +{ + return snapshots->current; +} + + +/* Return the current snapshot's name, or NULL */ +const char * +virDomainSnapshotGetCurrentName(virDomainSnapshotObjListPtr snapshots) +{ + if (snapshots->current) + return snapshots->current->def->name; + return NULL; +} + + +/* Return true if name matches the current snapshot */ +bool +virDomainSnapshotIsCurrentName(virDomainSnapshotObjListPtr snapshots, + const char *name) +{ + return snapshots->current && STREQ(snapshots->current->def->name, name= ); +} + + +/* Update the current snapshot, using NULL if no current remains */ +void +virDomainSnapshotSetCurrent(virDomainSnapshotObjListPtr snapshots, + virDomainSnapshotObjPtr snapshot) +{ + snapshots->current =3D snapshot; +} + + +/* Remove snapshot from the list; return true if it was current */ +bool virDomainSnapshotObjListRemove(virDomainSnapshotObjListPtr snapshots, virDomainSnapshotObjPtr snapshot) { + bool ret =3D snapshots->current =3D=3D snapshot; virHashRemoveEntry(snapshots->objs, snapshot->def->name); + if (ret) + snapshots->current =3D NULL; + return ret; } int @@ -507,6 +548,8 @@ virDomainSnapshotUpdateRelations(virDomainSnapshotObjLi= stPtr snapshots) snapshots->metaroot.nchildren =3D 0; snapshots->metaroot.first_child =3D NULL; virHashForEach(snapshots->objs, virDomainSnapshotSetRelations, &act); + if (act.err) + snapshots->current =3D NULL; return act.err; } diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 26f10bd47f..72c5cef528 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -990,6 +990,9 @@ virDomainListSnapshots; virDomainSnapshotAssignDef; virDomainSnapshotFindByName; virDomainSnapshotForEach; +virDomainSnapshotGetCurrent; +virDomainSnapshotGetCurrentName; +virDomainSnapshotIsCurrentName; virDomainSnapshotObjListFormat; virDomainSnapshotObjListFree; virDomainSnapshotObjListGetNames; @@ -997,6 +1000,7 @@ virDomainSnapshotObjListNew; virDomainSnapshotObjListNum; virDomainSnapshotObjListParse; virDomainSnapshotObjListRemove; +virDomainSnapshotSetCurrent; virDomainSnapshotUpdateRelations; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index f8387339f0..b1a84d3914 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -8461,7 +8461,7 @@ qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm, unsigned int flags =3D VIR_DOMAIN_SNAPSHOT_FORMAT_SECURE | VIR_DOMAIN_SNAPSHOT_FORMAT_INTERNAL; - if (vm->current_snapshot =3D=3D snapshot) + if (virDomainSnapshotGetCurrent(vm->snapshots) =3D=3D snapshot) flags |=3D VIR_DOMAIN_SNAPSHOT_FORMAT_CURRENT; virUUIDFormat(vm->def->uuid, uuidstr); newxml =3D virDomainSnapshotDefFormat(uuidstr, snapshot->def, caps, xm= lopt, @@ -8614,8 +8614,8 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver, vm->def->name, snap->def->name) < 0) goto cleanup; - if (snap =3D=3D vm->current_snapshot) { - vm->current_snapshot =3D NULL; + if (snap =3D=3D virDomainSnapshotGetCurrent(vm->snapshots)) { + virDomainSnapshotSetCurrent(vm->snapshots, NULL); if (update_parent && snap->def->parent) { parentsnap =3D virDomainSnapshotFindByName(vm->snapshots, snap->def->parent); @@ -8623,13 +8623,13 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver, VIR_WARN("missing parent snapshot matching name '%s'", snap->def->parent); } else { - vm->current_snapshot =3D parentsnap; + virDomainSnapshotSetCurrent(vm->snapshots, parentsnap); if (qemuDomainSnapshotWriteMetadata(vm, parentsnap, driver= ->caps, driver->xmlopt, cfg->snapshotDir) < 0)= { VIR_WARN("failed to set parent snapshot '%s' as curren= t", snap->def->parent); - vm->current_snapshot =3D NULL; + virDomainSnapshotSetCurrent(vm->snapshots, NULL); } } } @@ -8658,7 +8658,7 @@ int qemuDomainSnapshotDiscardAll(void *payload, virQEMUSnapRemovePtr curr =3D data; int err; - if (curr->vm->current_snapshot =3D=3D snap) + if (virDomainSnapshotGetCurrent(curr->vm->snapshots) =3D=3D snap) curr->current =3D true; err =3D qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap, false, curr->metadata_only); @@ -8679,8 +8679,6 @@ qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr= driver, rem.err =3D 0; virDomainSnapshotForEach(vm->snapshots, qemuDomainSnapshotDiscardAll, &rem); - if (rem.current) - vm->current_snapshot =3D NULL; if (virDomainSnapshotUpdateRelations(vm->snapshots) < 0 && !rem.err) rem.err =3D -1; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7e0e76a31a..6c71382b93 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -482,9 +482,11 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm, if (snap =3D=3D NULL) { virDomainSnapshotDefFree(def); } else if (cur) { + if (current) + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Too many snapshots claiming to be curren= t for domain %s"), + vm->def->name); current =3D snap; - if (!vm->current_snapshot) - vm->current_snapshot =3D snap; } VIR_FREE(fullpath); @@ -495,13 +497,7 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm, _("Failed to fully read directory %s"), snapDir); - if (vm->current_snapshot !=3D current) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Too many snapshots claiming to be current for do= main %s"), - vm->def->name); - vm->current_snapshot =3D NULL; - } - + virDomainSnapshotSetCurrent(vm->snapshots, current); if (virDomainSnapshotUpdateRelations(vm->snapshots) < 0) virReportError(VIR_ERR_INTERNAL_ERROR, _("Snapshots have inconsistent relations for domain= %s"), @@ -15858,13 +15854,13 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, def =3D NULL; } - current =3D vm->current_snapshot; + current =3D virDomainSnapshotGetCurrent(vm->snapshots); if (current) { if (!redefine && VIR_STRDUP(snap->def->parent, current->def->name) < 0) goto endjob; if (update_current) { - vm->current_snapshot =3D NULL; + virDomainSnapshotSetCurrent(vm->snapshots, NULL); if (qemuDomainSnapshotWriteMetadata(vm, current, driver->caps, driver->xmlo= pt, cfg->snapshotDir) < 0) @@ -15915,7 +15911,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, endjob: if (snapshot && !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) { if (update_current) - vm->current_snapshot =3D snap; + virDomainSnapshotSetCurrent(vm->snapshots, snap); if (qemuDomainSnapshotWriteMetadata(vm, snap, driver->caps, driver->xmlopt, cfg->snapshotDir) < 0) { @@ -15927,7 +15923,6 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, _("unable to save metadata for snapshot %s"), snap->def->name); virDomainSnapshotObjListRemove(vm->snapshots, snap); - vm->current_snapshot =3D NULL; } else { other =3D virDomainSnapshotFindByName(vm->snapshots, snap->def->parent); @@ -16166,7 +16161,7 @@ qemuDomainHasCurrentSnapshot(virDomainPtr domain, if (virDomainHasCurrentSnapshotEnsureACL(domain->conn, vm->def) < 0) goto cleanup; - ret =3D (vm->current_snapshot !=3D NULL); + ret =3D (virDomainSnapshotGetCurrent(vm->snapshots) !=3D NULL); cleanup: virDomainObjEndAPI(&vm); @@ -16223,13 +16218,13 @@ qemuDomainSnapshotCurrent(virDomainPtr domain, if (virDomainSnapshotCurrentEnsureACL(domain->conn, vm->def) < 0) goto cleanup; - if (!vm->current_snapshot) { + if (!virDomainSnapshotGetCurrent(vm->snapshots)) { virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s", _("the domain does not have a current snapshot")); goto cleanup; } - snapshot =3D virGetDomainSnapshot(domain, vm->current_snapshot->def->n= ame); + snapshot =3D virGetDomainSnapshot(domain, virDomainSnapshotGetCurrentN= ame(vm->snapshots)); cleanup: virDomainObjEndAPI(&vm); @@ -16289,8 +16284,7 @@ qemuDomainSnapshotIsCurrent(virDomainSnapshotPtr sn= apshot, if (!(snap =3D qemuSnapObjFromSnapshot(vm, snapshot))) goto cleanup; - ret =3D (vm->current_snapshot && - STREQ(virSnapName(snapshot), vm->current_snapshot->def->name)); + ret =3D virDomainSnapshotIsCurrentName(vm->snapshots, virSnapName(snap= shot)); cleanup: virDomainObjEndAPI(&vm); @@ -16443,14 +16437,14 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr s= napshot, } } - current =3D vm->current_snapshot; + current =3D virDomainSnapshotGetCurrent(vm->snapshots); if (current) { - vm->current_snapshot =3D NULL; + virDomainSnapshotSetCurrent(vm->snapshots, NULL); if (qemuDomainSnapshotWriteMetadata(vm, current, driver->caps, driver->xmlopt, cfg->snapshotDir) < 0) goto endjob; - /* XXX Should we restore vm->current_snapshot after this point + /* XXX Should we restore the current snapshot after this point * in the failure cases where we know there was no change? */ } @@ -16459,7 +16453,6 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr sna= pshot, * * XXX Should domain snapshots track live xml rather * than inactive xml? */ - vm->current_snapshot =3D snap; if (snap->def->dom) { config =3D virDomainDefCopy(snap->def->dom, caps, driver->xmlopt, NULL, true); @@ -16730,15 +16723,15 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr s= napshot, cleanup: if (ret =3D=3D 0) { - vm->current_snapshot =3D snap; + virDomainSnapshotSetCurrent(vm->snapshots, snap); if (qemuDomainSnapshotWriteMetadata(vm, snap, driver->caps, driver->xmlopt, cfg->snapshotDir) < 0) { - vm->current_snapshot =3D NULL; + virDomainSnapshotSetCurrent(vm->snapshots, NULL); ret =3D -1; } } else if (snap) { - vm->current_snapshot =3D NULL; + virDomainSnapshotSetCurrent(vm->snapshots, NULL); } if (ret =3D=3D 0 && config && vm->persistent && !(ret =3D virDomainSaveConfig(cfg->configDir, driver->caps, @@ -16866,7 +16859,7 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snaps= hot, if (rem.err < 0) goto endjob; if (rem.current) { - vm->current_snapshot =3D snap; + virDomainSnapshotSetCurrent(vm->snapshots, snap); if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) { if (qemuDomainSnapshotWriteMetadata(vm, snap, driver->caps, driver->xmlopt, @@ -16874,7 +16867,7 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snaps= hot, virReportError(VIR_ERR_INTERNAL_ERROR, _("failed to set snapshot '%s' as curre= nt"), snap->def->name); - vm->current_snapshot =3D NULL; + virDomainSnapshotSetCurrent(vm->snapshots, NULL); goto endjob; } } diff --git a/src/test/test_driver.c b/src/test/test_driver.c index ca480c1b21..9cbef70f1c 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -845,13 +845,13 @@ testParseDomainSnapshots(testDriverPtr privconn, } if (cur) { - if (domobj->current_snapshot) { + if (virDomainSnapshotGetCurrent(domobj->snapshots)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("more than one snapshot claims to be acti= ve")); goto error; } - domobj->current_snapshot =3D snap; + virDomainSnapshotSetCurrent(domobj->snapshots, snap); } } @@ -6151,7 +6151,7 @@ testDomainHasCurrentSnapshot(virDomainPtr domain, if (!(vm =3D testDomObjFromDomain(domain))) return -1; - ret =3D (vm->current_snapshot !=3D NULL); + ret =3D (virDomainSnapshotGetCurrent(vm->snapshots) !=3D NULL); virDomainObjEndAPI(&vm); return ret; @@ -6193,19 +6193,21 @@ testDomainSnapshotCurrent(virDomainPtr domain, { virDomainObjPtr vm; virDomainSnapshotPtr snapshot =3D NULL; + virDomainSnapshotObjPtr current; virCheckFlags(0, NULL); if (!(vm =3D testDomObjFromDomain(domain))) return NULL; - if (!vm->current_snapshot) { + current =3D virDomainSnapshotGetCurrent(vm->snapshots); + if (!current) { virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s", _("the domain does not have a current snapshot")); goto cleanup; } - snapshot =3D virGetDomainSnapshot(domain, vm->current_snapshot->def->n= ame); + snapshot =3D virGetDomainSnapshot(domain, current->def->name); cleanup: virDomainObjEndAPI(&vm); @@ -6253,8 +6255,7 @@ testDomainSnapshotIsCurrent(virDomainSnapshotPtr snap= shot, if (!(vm =3D testDomObjFromSnapshot(snapshot))) return -1; - ret =3D (vm->current_snapshot && - STREQ(virSnapName(snapshot), vm->current_snapshot->def->name)); + ret =3D virDomainSnapshotIsCurrentName(vm->snapshots, virSnapName(snap= shot)); virDomainObjEndAPI(&vm); return ret; @@ -6393,9 +6394,8 @@ testDomainSnapshotCreateXML(virDomainPtr domain, } if (!redefine) { - if (vm->current_snapshot && - (VIR_STRDUP(snap->def->parent, - vm->current_snapshot->def->name) < 0)) + if (VIR_STRDUP(snap->def->parent, + virDomainSnapshotGetCurrentName(vm->snapshots)) < 0) goto cleanup; if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT) && @@ -6413,7 +6413,7 @@ testDomainSnapshotCreateXML(virDomainPtr domain, if (snapshot) { virDomainSnapshotObjPtr other; if (update_current) - vm->current_snapshot =3D snap; + virDomainSnapshotSetCurrent(vm->snapshots, snap); other =3D virDomainSnapshotFindByName(vm->snapshots, snap->def->parent); snap->parent =3D other; @@ -6444,9 +6444,7 @@ testDomainSnapshotDiscardAll(void *payload, virDomainSnapshotObjPtr snap =3D payload; testSnapRemoveDataPtr curr =3D data; - if (curr->vm->current_snapshot =3D=3D snap) - curr->current =3D true; - virDomainSnapshotObjListRemove(curr->vm->snapshots, snap); + curr->current |=3D virDomainSnapshotObjListRemove(curr->vm->snapshots,= snap); return 0; } @@ -6511,7 +6509,7 @@ testDomainSnapshotDelete(virDomainSnapshotPtr snapsho= t, testDomainSnapshotDiscardAll, &rem); if (rem.current) - vm->current_snapshot =3D snap; + virDomainSnapshotSetCurrent(vm->snapshots, snap); } else if (snap->nchildren) { testSnapReparentData rep; rep.parent =3D snap->parent; @@ -6535,7 +6533,7 @@ testDomainSnapshotDelete(virDomainSnapshotPtr snapsho= t, snap->first_child =3D NULL; } else { virDomainSnapshotDropParent(snap); - if (snap =3D=3D vm->current_snapshot) { + if (snap =3D=3D virDomainSnapshotGetCurrent(vm->snapshots)) { if (snap->def->parent) { parentsnap =3D virDomainSnapshotFindByName(vm->snapshots, snap->def->parent= ); @@ -6543,7 +6541,7 @@ testDomainSnapshotDelete(virDomainSnapshotPtr snapsho= t, VIR_WARN("missing parent snapshot matching name '%s'", snap->def->parent); } - vm->current_snapshot =3D parentsnap; + virDomainSnapshotSetCurrent(vm->snapshots, parentsnap); } virDomainSnapshotObjListRemove(vm->snapshots, snap); } @@ -6619,9 +6617,7 @@ testDomainRevertToSnapshot(virDomainSnapshotPtr snaps= hot, } } - - if (vm->current_snapshot) - vm->current_snapshot =3D NULL; + virDomainSnapshotSetCurrent(vm->snapshots, NULL); config =3D virDomainDefCopy(snap->def->dom, privconn->caps, privconn->xmlopt, NULL, true); @@ -6746,7 +6742,7 @@ testDomainRevertToSnapshot(virDomainSnapshotPtr snaps= hot, } } - vm->current_snapshot =3D snap; + virDomainSnapshotSetCurrent(vm->snapshots, snap); ret =3D 0; cleanup: if (event) { --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list