From nobody Mon Feb 9 10:28:36 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 ARC-Seal: i=1; a=rsa-sha256; t=1562471851; cv=none; d=zoho.com; s=zohoarc; b=XNGfbiqbckW9JtU/mFhqAcK+qNamm10Z9v4s3MGMHdNYJxyx6adyE7bP5dXZfWXkp84mNrReVGohQQEMmT/6CFnIylyR36erePwTBDtQZgbC+gxoZQ75HjIzLk34RDUY/vdUXjeK1y8cvyS5rlyrfQ+1+MTnCnD4AZbG7VCCQNA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1562471851; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=C5up+NI9JA0n1g4hV0O1ByTW6yOB4h5hEBJ8LAZvoyc=; b=YlPCX0iydjO0w7uwXrDDvPv2aYOytysVHe85HBhaxSOS8nQMvB6lqdVeG27pnrINCcC6P0Fs7PCifZKTzW1+p2I3cPsMl0WamaaqRdBq0ETFRcNOvdLVHHbcuTjD4sqXfpMV60JgdpdafyHwovAs08t5T7sakQ6qUHbwoaapriw= ARC-Authentication-Results: i=1; mx.zoho.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 header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1562471851451343.5662828963382; Sat, 6 Jul 2019 20:57:31 -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 D08F22F8BF7; Sun, 7 Jul 2019 03:57:29 +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 AB32B2A2D7; Sun, 7 Jul 2019 03:57:29 +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 6A1CD206DC; Sun, 7 Jul 2019 03:57:29 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x673uV1R006292 for ; Sat, 6 Jul 2019 23:56:31 -0400 Received: by smtp.corp.redhat.com (Postfix) id 0511718A82; Sun, 7 Jul 2019 03:56:31 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-78.phx2.redhat.com [10.3.116.78]) by smtp.corp.redhat.com (Postfix) with ESMTP id 88A9A413A; Sun, 7 Jul 2019 03:56:30 +0000 (UTC) From: Eric Blake To: libvir-list@redhat.com Date: Sat, 6 Jul 2019 22:56:13 -0500 Message-Id: <20190707035613.25754-14-eblake@redhat.com> In-Reply-To: <20190707035613.25754-1-eblake@redhat.com> References: <20190707035613.25754-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Cc: nsoffer@redhat.com, eshenitz@redhat.com, pkrempa@redhat.com Subject: [libvirt] [PATCH v9 13/13] backup: Add virDomainCheckpointIsCurrent API 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.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]); Sun, 07 Jul 2019 03:57:30 +0000 (UTC) Content-Type: text/plain; charset="utf-8" It is possible, but tedious, to tell if a checkpoint is current by parsing XML. As this operation may be performed with some frequency, it is worth an additional API (comparable to the existing virDomainCheckpointGetParent that duplicates what can be learned from XML, or the counterpart virDomainSnapshotIsCurrent although snapshots don't currently expose whether they are current in public XML). Signed-off-by: Eric Blake --- include/libvirt/libvirt-domain-checkpoint.h | 4 +++ src/driver-hypervisor.h | 5 +++ src/libvirt-domain-checkpoint.c | 38 +++++++++++++++++++++ src/libvirt_public.syms | 1 + src/qemu/qemu_driver.c | 28 +++++++++++++++ src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 18 +++++++++- src/remote_protocol-structs | 8 +++++ src/test/test_driver.c | 25 ++++++++++++++ tools/virsh-checkpoint.c | 21 +++--------- 10 files changed, 132 insertions(+), 17 deletions(-) diff --git a/include/libvirt/libvirt-domain-checkpoint.h b/include/libvirt/= libvirt-domain-checkpoint.h index b2d5c5758b..b03e0f8328 100644 --- a/include/libvirt/libvirt-domain-checkpoint.h +++ b/include/libvirt/libvirt-domain-checkpoint.h @@ -127,6 +127,10 @@ virDomainCheckpointPtr virDomainCheckpointLookupByName= (virDomainPtr domain, virDomainCheckpointPtr virDomainCheckpointGetParent(virDomainCheckpointPtr= checkpoint, unsigned int flags); +/* Determine if a checkpoint is current */ +int virDomainCheckpointIsCurrent(virDomainCheckpointPtr checkpoint, + unsigned int flags); + /* Delete a checkpoint */ typedef enum { VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN =3D (1 << 0), /* Also delet= e children */ diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index c1632ae4c6..395b710a26 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1355,6 +1355,10 @@ typedef virDomainCheckpointPtr (*virDrvDomainCheckpointGetParent)(virDomainCheckpointPtr checkpoint, unsigned int flags); +typedef int +(*virDrvDomainCheckpointIsCurrent)(virDomainCheckpointPtr checkpoint, + unsigned int flags); + typedef int (*virDrvDomainCheckpointDelete)(virDomainCheckpointPtr checkpoint, unsigned int flags); @@ -1617,4 +1621,5 @@ struct _virHypervisorDriver { virDrvDomainCheckpointLookupByName domainCheckpointLookupByName; virDrvDomainCheckpointGetParent domainCheckpointGetParent; virDrvDomainCheckpointDelete domainCheckpointDelete; + virDrvDomainCheckpointIsCurrent domainCheckpointIsCurrent; }; diff --git a/src/libvirt-domain-checkpoint.c b/src/libvirt-domain-checkpoin= t.c index ab82d8422b..e1fd81ede0 100644 --- a/src/libvirt-domain-checkpoint.c +++ b/src/libvirt-domain-checkpoint.c @@ -471,6 +471,44 @@ virDomainCheckpointGetParent(virDomainCheckpointPtr ch= eckpoint, } +/** + * virDomainCheckpointIsCurrent: + * @checkpoint: a checkpoint object + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Determine if the given checkpoint is the domain's current checkpoint. = See + * also virDomainCheckpointCurrent(). + * + * Returns 1 if current, 0 if not current, or -1 on error. + */ +int +virDomainCheckpointIsCurrent(virDomainCheckpointPtr checkpoint, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DEBUG("checkpoint=3D%p, flags=3D0x%x", checkpoint, flags); + + virResetLastError(); + + virCheckDomainCheckpointReturn(checkpoint, -1); + conn =3D checkpoint->domain->conn; + + if (conn->driver->domainCheckpointIsCurrent) { + int ret; + ret =3D conn->driver->domainCheckpointIsCurrent(checkpoint, flags); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + error: + virDispatchError(conn); + return -1; +} + + /** * virDomainCheckpointDelete: * @checkpoint: the checkpoint to remove diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 54256b6317..6401916a81 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -846,6 +846,7 @@ LIBVIRT_5.6.0 { virDomainCheckpointGetName; virDomainCheckpointGetParent; virDomainCheckpointGetXMLDesc; + virDomainCheckpointIsCurrent; virDomainCheckpointListAllChildren; virDomainCheckpointLookupByName; virDomainCheckpointRef; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b37307abc7..4131367245 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -17328,6 +17328,33 @@ qemuDomainCheckpointGetParent(virDomainCheckpointP= tr checkpoint, } +static int +qemuDomainCheckpointIsCurrent(virDomainCheckpointPtr checkpoint, + unsigned int flags) +{ + virDomainObjPtr vm; + int ret =3D -1; + virDomainMomentObjPtr chk =3D NULL; + + virCheckFlags(0, -1); + + if (!(vm =3D qemuDomObjFromCheckpoint(checkpoint))) + return -1; + + if (virDomainCheckpointIsCurrentEnsureACL(checkpoint->domain->conn, vm= ->def) < 0) + goto cleanup; + + if (!(chk =3D qemuCheckObjFromCheckpoint(vm, checkpoint))) + goto cleanup; + + ret =3D chk =3D=3D virDomainCheckpointGetCurrent(vm->checkpoints); + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + + static char * qemuDomainCheckpointGetXMLDesc(virDomainCheckpointPtr checkpoint, unsigned int flags) @@ -23174,6 +23201,7 @@ static virHypervisorDriver qemuHypervisorDriver =3D= { .domainCheckpointLookupByName =3D qemuDomainCheckpointLookupByName, /*= 5.6.0 */ .domainCheckpointGetParent =3D qemuDomainCheckpointGetParent, /* 5.6.0= */ .domainCheckpointDelete =3D qemuDomainCheckpointDelete, /* 5.6.0 */ + .domainCheckpointIsCurrent =3D qemuDomainCheckpointIsCurrent, /* 5.6.0= */ }; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 72c2336b7a..9145aa91ff 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8596,6 +8596,7 @@ static virHypervisorDriver hypervisor_driver =3D { .domainCheckpointLookupByName =3D remoteDomainCheckpointLookupByName, = /* 5.6.0 */ .domainCheckpointGetParent =3D remoteDomainCheckpointGetParent, /* 5.6= .0 */ .domainCheckpointDelete =3D remoteDomainCheckpointDelete, /* 5.6.0 */ + .domainCheckpointIsCurrent =3D remoteDomainCheckpointIsCurrent, /* 5.6= .0 */ }; static virNetworkDriver network_driver =3D { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 2f91bd1921..a2bd30360f 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -3718,6 +3718,15 @@ struct remote_domain_checkpoint_get_parent_ret { remote_nonnull_domain_checkpoint parent; }; +struct remote_domain_checkpoint_is_current_args { + remote_nonnull_domain_checkpoint checkpoint; + unsigned int flags; +}; + +struct remote_domain_checkpoint_is_current_ret { + int current; +}; + struct remote_domain_checkpoint_delete_args { remote_nonnull_domain_checkpoint checkpoint; unsigned int flags; @@ -6584,5 +6593,12 @@ enum remote_procedure { * @generate: both * @acl: domain:checkpoint */ - REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE =3D 417 + REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE =3D 417, + + /** + * @generate: both + * @priority: high + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_CHECKPOINT_IS_CURRENT =3D 418 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index a42b4a9671..ba4337b1bd 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -3101,6 +3101,13 @@ struct remote_domain_checkpoint_get_parent_args { struct remote_domain_checkpoint_get_parent_ret { remote_nonnull_domain_checkpoint parent; }; +struct remote_domain_checkpoint_is_current_args { + remote_nonnull_domain_checkpoint checkpoint; + u_int flags; +}; +struct remote_domain_checkpoint_is_current_ret { + int current; +}; struct remote_domain_checkpoint_delete_args { remote_nonnull_domain_checkpoint checkpoint; u_int flags; @@ -3523,4 +3530,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_CHECKPOINT_LOOKUP_BY_NAME =3D 415, REMOTE_PROC_DOMAIN_CHECKPOINT_GET_PARENT =3D 416, REMOTE_PROC_DOMAIN_CHECKPOINT_DELETE =3D 417, + REMOTE_PROC_DOMAIN_CHECKPOINT_IS_CURRENT =3D 418, }; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index ddc8867bdd..0c3505b038 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -7880,6 +7880,30 @@ testDomainCheckpointGetXMLDesc(virDomainCheckpointPt= r checkpoint, } +static int +testDomainCheckpointIsCurrent(virDomainCheckpointPtr checkpoint, + unsigned int flags) +{ + virDomainObjPtr vm =3D NULL; + int ret =3D -1; + virDomainMomentObjPtr chk =3D NULL; + + virCheckFlags(0, -1); + + if (!(vm =3D testDomObjFromCheckpoint(checkpoint))) + return -1; + + if (!(chk =3D testCheckObjFromCheckpoint(vm, checkpoint))) + goto cleanup; + + ret =3D chk =3D=3D virDomainCheckpointGetCurrent(vm->checkpoints); + + cleanup: + virDomainObjEndAPI(&vm); + return ret; +} + + static int testDomainCheckpointDelete(virDomainCheckpointPtr checkpoint, unsigned int flags) @@ -8076,6 +8100,7 @@ static virHypervisorDriver testHypervisorDriver =3D { .domainCheckpointLookupByName =3D testDomainCheckpointLookupByName, /*= 5.6.0 */ .domainCheckpointGetParent =3D testDomainCheckpointGetParent, /* 5.6.0= */ .domainCheckpointDelete =3D testDomainCheckpointDelete, /* 5.6.0 */ + .domainCheckpointIsCurrent =3D testDomainCheckpointIsCurrent, /* 5.6.0= */ }; static virNetworkDriver testNetworkDriver =3D { diff --git a/tools/virsh-checkpoint.c b/tools/virsh-checkpoint.c index 8200687f8a..a2d34f2102 100644 --- a/tools/virsh-checkpoint.c +++ b/tools/virsh-checkpoint.c @@ -522,9 +522,6 @@ cmdCheckpointInfo(vshControl *ctl, virDomainCheckpointPtr checkpoint =3D NULL; const char *name; char *parent =3D NULL; - char *xml =3D NULL; - xmlDocPtr xmldoc =3D NULL; - xmlXPathContextPtr ctxt =3D NULL; bool ret =3D false; int count; unsigned int flags; @@ -542,17 +539,12 @@ cmdCheckpointInfo(vshControl *ctl, vshPrint(ctl, "%-15s %s\n", _("Domain:"), virDomainGetName(dom)); /* Determine if checkpoint is current. */ - xml =3D virDomainCheckpointGetXMLDesc(checkpoint, - VIR_DOMAIN_CHECKPOINT_XML_NO_DOMAI= N); - if (!xml) - goto cleanup; - - xmldoc =3D virXMLParseStringCtxt(xml, _("(domain_checkpoint)"), &ctxt); - if (!xmldoc) - goto cleanup; - - if (virXPathInt("string(/domaincheckpoint/current)", ctxt, ¤t) <= 0) + current =3D virDomainCheckpointIsCurrent(checkpoint, 0); + if (current < 0) { + vshError(ctl, "%s", + _("unexpected problem querying checkpoint state")); goto cleanup; + } vshPrint(ctl, "%-15s %s\n", _("Current:"), current > 0 ? _("yes") : _("no")); @@ -583,9 +575,6 @@ cmdCheckpointInfo(vshControl *ctl, ret =3D true; cleanup: - xmlXPathFreeContext(ctxt); - xmlFreeDoc(xmldoc); - VIR_FREE(xml); VIR_FREE(parent); virshDomainCheckpointFree(checkpoint); virshDomainFree(dom); --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list