From nobody Mon Feb 9 02:13:10 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=1560916213; cv=none; d=zoho.com; s=zohoarc; b=nZkCOTBu1Fsvh+lypgW2t7xRkhytSzNkCEueZRnDBNtmb/J+gNaZcOIVpwjG/f9wAxCmo8laJAybpEKNnvYrkPB3p/lGiXgU7ZDzbwXIxKyR0ydaLckgKekSA99O+f6xKPt0//iB8jUB8hq+54HVIhE3G4KOLf9WlTCrraX999U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1560916213; h=Content-Type:Content-Transfer-Encoding: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=ZZRg/a77Q2hxq5UdKsNarQmp0/vaJPUo/YBsVRZnk+s=; b=bxFX7HRJg7UlJj3UERzBTd2OSAVnck8LkTzwkZkoFzysUFC5WJuUXPXcmVxyer5+grIZm0Ek33MdKKlBFwDPTTGOR+Xxl3eHoqIJY+Enx20yajgP6jjWGtH4GiK/vWhhCBq0EeLaL6i1EkYONW3Dx4CF5aMAPXNjAcGAzm8ek4w= 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 1560916213685910.6090308285296; Tue, 18 Jun 2019 20:50:13 -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 5DDB830832EA; Wed, 19 Jun 2019 03:50:03 +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 B79C719C71; Wed, 19 Jun 2019 03:50:00 +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 77067C598; Wed, 19 Jun 2019 03:49:58 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x5J3m53C017753 for ; Tue, 18 Jun 2019 23:48:05 -0400 Received: by smtp.corp.redhat.com (Postfix) id F3755176BC; Wed, 19 Jun 2019 03:48:04 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-44.phx2.redhat.com [10.3.116.44]) by smtp.corp.redhat.com (Postfix) with ESMTP id AC9867E66A for ; Wed, 19 Jun 2019 03:48:03 +0000 (UTC) From: Eric Blake To: libvir-list@redhat.com Date: Tue, 18 Jun 2019 22:47:46 -0500 Message-Id: <20190619034754.2708-6-eblake@redhat.com> In-Reply-To: <20190619034754.2708-1-eblake@redhat.com> References: <20190619034754.2708-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 05/13] backup: Allow for lists of checkpoint objects 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.44]); Wed, 19 Jun 2019 03:50:12 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Create a new file for managing a list of checkpoint objects, borrowing heavily from existing virDomainSnapshotObjList paradigms. Note that while checkpoints definitely have a use case for multiple children to a single parent (create a base snapshot, create a child snapshot, revert to the base, then create another child snapshot), it's harder to predict how checkpoints will play out with reverting to prior points in time. Thus, in initial use, we may find that in a list of checkpoints, you never have more than one child. However, as the snapshot machinery is already generic, it is easier to reuse the generic machinery that tracks relations between domain moments than it is to open-code a new list-management scheme just for checkpoints. Signed-off-by: Eric Blake --- src/conf/checkpoint_conf.h | 7 + src/conf/domain_conf.h | 2 + src/conf/virconftypes.h | 6 + src/conf/virdomaincheckpointobjlist.h | 66 ++++++++ src/conf/virdomainobjlist.h | 7 +- src/conf/Makefile.inc.am | 2 + src/conf/checkpoint_conf.c | 87 ++++++++++ src/conf/domain_conf.c | 6 + src/conf/virdomaincheckpointobjlist.c | 219 ++++++++++++++++++++++++++ src/conf/virdomainmomentobjlist.c | 2 +- src/conf/virdomainobjlist.c | 11 ++ src/libvirt_private.syms | 18 +++ 12 files changed, 431 insertions(+), 2 deletions(-) create mode 100644 src/conf/virdomaincheckpointobjlist.h create mode 100644 src/conf/virdomaincheckpointobjlist.c diff --git a/src/conf/checkpoint_conf.h b/src/conf/checkpoint_conf.h index 665423d6e4..e5bc6876a4 100644 --- a/src/conf/checkpoint_conf.h +++ b/src/conf/checkpoint_conf.h @@ -91,4 +91,11 @@ char *virDomainCheckpointDefFormat(virDomainCheckpointDe= fPtr def, unsigned int flags); int virDomainCheckpointAlignDisks(virDomainCheckpointDefPtr checkpoint); +int virDomainCheckpointRedefinePrep(virDomainPtr domain, + virDomainObjPtr vm, + virDomainCheckpointDefPtr *def, + virDomainMomentObjPtr *checkpoint, + virDomainXMLOptionPtr xmlopt, + bool *update_current); + VIR_ENUM_DECL(virDomainCheckpoint); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 2878050672..466b2b16de 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2560,6 +2560,8 @@ struct _virDomainObj { bool hasManagedSave; + virDomainCheckpointObjListPtr checkpoints; + void *privateData; void (*privateDataFreeFunc)(void *); diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index fe3f0af14f..e8e9b6c314 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -105,6 +105,12 @@ typedef virDomainBlockIoTuneInfo *virDomainBlockIoTune= InfoPtr; typedef struct _virDomainCheckpointDef virDomainCheckpointDef; typedef virDomainCheckpointDef *virDomainCheckpointDefPtr; +typedef struct _virDomainCheckpointObj virDomainCheckpointObj; +typedef virDomainCheckpointObj *virDomainCheckpointObjPtr; + +typedef struct _virDomainCheckpointObjList virDomainCheckpointObjList; +typedef virDomainCheckpointObjList *virDomainCheckpointObjListPtr; + typedef struct _virDomainChrDef virDomainChrDef; typedef virDomainChrDef *virDomainChrDefPtr; diff --git a/src/conf/virdomaincheckpointobjlist.h b/src/conf/virdomainchec= kpointobjlist.h new file mode 100644 index 0000000000..6d74f5778a --- /dev/null +++ b/src/conf/virdomaincheckpointobjlist.h @@ -0,0 +1,66 @@ +/* + * virdomaincheckpointobjlist.h: handle a tree of checkpoint objects + * (derived from virdomainsnapshotobjlist.h) + * + * Copyright (C) 2006-2019 Red Hat, Inc. + * Copyright (C) 2006-2008 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#include "internal.h" +#include "virdomainmomentobjlist.h" +#include "virbuffer.h" + +virDomainCheckpointObjListPtr virDomainCheckpointObjListNew(void); +void virDomainCheckpointObjListFree(virDomainCheckpointObjListPtr checkpoi= nts); + +virDomainMomentObjPtr virDomainCheckpointAssignDef(virDomainCheckpointObjL= istPtr checkpoints, + virDomainCheckpointDefP= tr def); + +virDomainMomentObjPtr virDomainCheckpointFindByName(virDomainCheckpointObj= ListPtr checkpoints, + const char *name); +virDomainMomentObjPtr virDomainCheckpointGetCurrent(virDomainCheckpointObj= ListPtr checkpoints); +const char *virDomainCheckpointGetCurrentName(virDomainCheckpointObjListPt= r checkpoints); +void virDomainCheckpointSetCurrent(virDomainCheckpointObjListPtr checkpoin= ts, + virDomainMomentObjPtr checkpoint); +bool virDomainCheckpointObjListRemove(virDomainCheckpointObjListPtr checkp= oints, + virDomainMomentObjPtr checkpoint); +void virDomainCheckpointObjListRemoveAll(virDomainCheckpointObjListPtr che= ckpoints); +int virDomainCheckpointForEach(virDomainCheckpointObjListPtr checkpoints, + virHashIterator iter, + void *data); +int virDomainCheckpointUpdateRelations(virDomainCheckpointObjListPtr check= points); + +#define VIR_DOMAIN_CHECKPOINT_FILTERS_LEAVES \ + (VIR_DOMAIN_CHECKPOINT_LIST_LEAVES | \ + VIR_DOMAIN_CHECKPOINT_LIST_NO_LEAVES) + +#define VIR_DOMAIN_CHECKPOINT_FILTERS_ALL \ + (VIR_DOMAIN_CHECKPOINT_FILTERS_LEAVES) + +int virDomainListCheckpoints(virDomainCheckpointObjListPtr checkpoints, + virDomainMomentObjPtr from, + virDomainPtr dom, + virDomainCheckpointPtr **objs, + unsigned int flags); + +static inline virDomainCheckpointDefPtr +virDomainCheckpointObjGetDef(virDomainMomentObjPtr obj) +{ + return (virDomainCheckpointDefPtr) obj->def; +} diff --git a/src/conf/virdomainobjlist.h b/src/conf/virdomainobjlist.h index bf3ab396fa..7d71bc54d0 100644 --- a/src/conf/virdomainobjlist.h +++ b/src/conf/virdomainobjlist.h @@ -120,13 +120,18 @@ int virDomainObjListForEach(virDomainObjListPtr doms, (VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT | \ VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) +#define VIR_CONNECT_LIST_DOMAINS_FILTERS_CHECKPOINT \ + (VIR_CONNECT_LIST_DOMAINS_HAS_CHECKPOINT | \ + VIR_CONNECT_LIST_DOMAINS_NO_CHECKPOINT) + #define VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL \ (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE | \ VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT | \ VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE | \ VIR_CONNECT_LIST_DOMAINS_FILTERS_MANAGEDSAVE | \ VIR_CONNECT_LIST_DOMAINS_FILTERS_AUTOSTART | \ - VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT) + VIR_CONNECT_LIST_DOMAINS_FILTERS_SNAPSHOT | \ + VIR_CONNECT_LIST_DOMAINS_FILTERS_CHECKPOINT) int virDomainObjListCollect(virDomainObjListPtr doms, virConnectPtr conn, diff --git a/src/conf/Makefile.inc.am b/src/conf/Makefile.inc.am index f0135bcb1c..b72ebbbda5 100644 --- a/src/conf/Makefile.inc.am +++ b/src/conf/Makefile.inc.am @@ -35,6 +35,8 @@ DOMAIN_CONF_SOURCES =3D \ conf/numa_conf.c \ conf/numa_conf.h \ conf/virconftypes.h \ + conf/virdomaincheckpointobjlist.c \ + conf/virdomaincheckpointobjlist.h \ conf/virdomainobjlist.c \ conf/virdomainobjlist.h \ conf/virdomainmomentobjlist.c \ diff --git a/src/conf/checkpoint_conf.c b/src/conf/checkpoint_conf.c index a7a34d3887..469f665648 100644 --- a/src/conf/checkpoint_conf.c +++ b/src/conf/checkpoint_conf.c @@ -35,6 +35,7 @@ #include "virerror.h" #include "virxml.h" #include "virstring.h" +#include "virdomaincheckpointobjlist.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN_CHECKPOINT @@ -573,3 +574,89 @@ virDomainCheckpointDefFormat(virDomainCheckpointDefPtr= def, return virBufferContentAndReset(&buf); } + + +int +virDomainCheckpointRedefinePrep(virDomainPtr domain, + virDomainObjPtr vm, + virDomainCheckpointDefPtr *defptr, + virDomainMomentObjPtr *chk, + virDomainXMLOptionPtr xmlopt, + bool *update_current) +{ + virDomainCheckpointDefPtr def =3D *defptr; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virDomainMomentObjPtr other; + virDomainCheckpointDefPtr otherdef; + + virUUIDFormat(domain->uuid, uuidstr); + + /* TODO: Move this and snapshot version into virDomainMoment */ + /* Prevent circular chains */ + if (def->parent.parent_name) { + if (STREQ(def->parent.name, def->parent.parent_name)) { + virReportError(VIR_ERR_INVALID_ARG, + _("cannot set checkpoint %s as its own parent"), + def->parent.name); + return -1; + } + other =3D virDomainCheckpointFindByName(vm->checkpoints, + def->parent.parent_name); + if (!other) { + virReportError(VIR_ERR_INVALID_ARG, + _("parent %s for checkpoint %s not found"), + def->parent.parent_name, def->parent.name); + return -1; + } + otherdef =3D virDomainCheckpointObjGetDef(other); + while (otherdef->parent.parent_name) { + if (STREQ(otherdef->parent.parent_name, def->parent.name)) { + virReportError(VIR_ERR_INVALID_ARG, + _("parent %s would create cycle to %s"), + otherdef->parent.name, def->parent.name); + return -1; + } + other =3D virDomainCheckpointFindByName(vm->checkpoints, + otherdef->parent.parent_= name); + if (!other) { + VIR_WARN("checkpoints are inconsistent for %s", + vm->def->name); + break; + } + otherdef =3D virDomainCheckpointObjGetDef(other); + } + } + + if (!def->parent.dom || + memcmp(def->parent.dom->uuid, domain->uuid, VIR_UUID_BUFLEN)) { + virReportError(VIR_ERR_INVALID_ARG, + _("definition for checkpoint %s must use uuid %s"), + def->parent.name, uuidstr); + return -1; + } + if (virDomainCheckpointAlignDisks(def) < 0) + return -1; + + other =3D virDomainCheckpointFindByName(vm->checkpoints, def->parent.n= ame); + otherdef =3D other ? virDomainCheckpointObjGetDef(other) : NULL; + if (other) { + if (!virDomainDefCheckABIStability(otherdef->parent.dom, + def->parent.dom, xmlopt)) + return -1; + + if (other =3D=3D virDomainCheckpointGetCurrent(vm->checkpoints)) { + *update_current =3D true; + virDomainCheckpointSetCurrent(vm->checkpoints, NULL); + } + + /* Drop and rebuild the parent relationship, but keep all + * child relations by reusing chk. */ + virDomainMomentDropParent(other); + virObjectUnref(otherdef); + other->def =3D &(*defptr)->parent; + *defptr =3D NULL; + *chk =3D other; + } + + return 0; +} diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ee651e7742..ce6fb4766a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -29,6 +29,7 @@ #include "configmake.h" #include "internal.h" #include "virerror.h" +#include "checkpoint_conf.h" #include "datatypes.h" #include "domain_addr.h" #include "domain_conf.h" @@ -60,6 +61,7 @@ #include "virhostdev.h" #include "virmdev.h" #include "virdomainsnapshotobjlist.h" +#include "virdomaincheckpointobjlist.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN @@ -3484,6 +3486,7 @@ static void virDomainObjDispose(void *obj) (dom->privateDataFreeFunc)(dom->privateData); virDomainSnapshotObjListFree(dom->snapshots); + virDomainCheckpointObjListFree(dom->checkpoints); } virDomainObjPtr @@ -3513,6 +3516,9 @@ virDomainObjNew(virDomainXMLOptionPtr xmlopt) if (!(domain->snapshots =3D virDomainSnapshotObjListNew())) goto error; + if (!(domain->checkpoints =3D virDomainCheckpointObjListNew())) + goto error; + virObjectLock(domain); virDomainObjSetState(domain, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_UNKNOWN); diff --git a/src/conf/virdomaincheckpointobjlist.c b/src/conf/virdomainchec= kpointobjlist.c new file mode 100644 index 0000000000..84f9d352bc --- /dev/null +++ b/src/conf/virdomaincheckpointobjlist.c @@ -0,0 +1,219 @@ +/* + * virdomaincheckpointobjlist.c: handle a tree of checkpoint objects + * (derived from virdomainsnapshotobjlist.c) + * + * Copyright (C) 2006-2019 Red Hat, Inc. + * Copyright (C) 2006-2008 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "internal.h" +#include "virdomaincheckpointobjlist.h" +#include "checkpoint_conf.h" +#include "virlog.h" +#include "virerror.h" +#include "datatypes.h" +#include "virstring.h" +#include "viralloc.h" + +#define VIR_FROM_THIS VIR_FROM_DOMAIN_CHECKPOINT + +VIR_LOG_INIT("conf.virdomaincheckpointobjlist"); + +struct _virDomainCheckpointObjList { + virDomainMomentObjListPtr base; +}; + +virDomainMomentObjPtr +virDomainCheckpointAssignDef(virDomainCheckpointObjListPtr checkpoints, + virDomainCheckpointDefPtr def) +{ + return virDomainMomentAssignDef(checkpoints->base, &def->parent); +} + + +static bool +virDomainCheckpointFilter(virDomainMomentObjPtr obj ATTRIBUTE_UNUSED, + unsigned int flags) +{ + /* For now, we have no further filters than what the common code handl= es. */ + virCheckFlags(0, false); + return true; +} + + +virDomainCheckpointObjListPtr +virDomainCheckpointObjListNew(void) +{ + virDomainCheckpointObjListPtr checkpoints; + + if (VIR_ALLOC(checkpoints) < 0) + return NULL; + checkpoints->base =3D virDomainMomentObjListNew(); + if (!checkpoints->base) { + VIR_FREE(checkpoints); + return NULL; + } + return checkpoints; +} + + +void +virDomainCheckpointObjListFree(virDomainCheckpointObjListPtr checkpoints) +{ + if (!checkpoints) + return; + virDomainMomentObjListFree(checkpoints->base); + VIR_FREE(checkpoints); +} + + +static int +virDomainCheckpointObjListGetNames(virDomainCheckpointObjListPtr checkpoin= ts, + virDomainMomentObjPtr from, + char **const names, + int maxnames, + unsigned int flags) +{ + /* We intentionally chose our public flags to match the common flags */ + verify(VIR_DOMAIN_CHECKPOINT_LIST_ROOTS =3D=3D + (int) VIR_DOMAIN_MOMENT_LIST_ROOTS); + verify(VIR_DOMAIN_CHECKPOINT_LIST_TOPOLOGICAL =3D=3D + (int) VIR_DOMAIN_MOMENT_LIST_TOPOLOGICAL); + verify(VIR_DOMAIN_CHECKPOINT_LIST_LEAVES =3D=3D + (int) VIR_DOMAIN_MOMENT_LIST_LEAVES); + verify(VIR_DOMAIN_CHECKPOINT_LIST_NO_LEAVES =3D=3D + (int) VIR_DOMAIN_MOMENT_LIST_NO_LEAVES); + + return virDomainMomentObjListGetNames(checkpoints->base, from, names, + maxnames, flags, + virDomainCheckpointFilter, 0); +} + + +virDomainMomentObjPtr +virDomainCheckpointFindByName(virDomainCheckpointObjListPtr checkpoints, + const char *name) +{ + return virDomainMomentFindByName(checkpoints->base, name); +} + + +/* Return the current checkpoint, or NULL */ +virDomainMomentObjPtr +virDomainCheckpointGetCurrent(virDomainCheckpointObjListPtr checkpoints) +{ + return virDomainMomentGetCurrent(checkpoints->base); +} + + +/* Return the current checkpoint's name, or NULL */ +const char * +virDomainCheckpointGetCurrentName(virDomainCheckpointObjListPtr checkpoint= s) +{ + return virDomainMomentGetCurrentName(checkpoints->base); +} + + +/* Update the current checkpoint, using NULL if no current remains */ +void +virDomainCheckpointSetCurrent(virDomainCheckpointObjListPtr checkpoints, + virDomainMomentObjPtr checkpoint) +{ + virDomainMomentSetCurrent(checkpoints->base, checkpoint); +} + + +/* Remove checkpoint from the list; return true if it was current */ +bool +virDomainCheckpointObjListRemove(virDomainCheckpointObjListPtr checkpoints, + virDomainMomentObjPtr checkpoint) +{ + return virDomainMomentObjListRemove(checkpoints->base, checkpoint); +} + + +/* Remove all checkpoints tracked in the list */ +void +virDomainCheckpointObjListRemoveAll(virDomainCheckpointObjListPtr checkpoi= nts) +{ + return virDomainMomentObjListRemoveAll(checkpoints->base); +} + + +int +virDomainCheckpointForEach(virDomainCheckpointObjListPtr checkpoints, + virHashIterator iter, + void *data) +{ + return virDomainMomentForEach(checkpoints->base, iter, data); +} + + +/* Populate parent link and child count of all checkpoints, with all + * assigned defs having relations starting as 0/NULL. Return 0 on + * success, -1 if a parent is missing or if a circular relationship + * was requested. */ +int +virDomainCheckpointUpdateRelations(virDomainCheckpointObjListPtr checkpoin= ts) +{ + return virDomainMomentUpdateRelations(checkpoints->base); +} + + +int +virDomainListCheckpoints(virDomainCheckpointObjListPtr checkpoints, + virDomainMomentObjPtr from, + virDomainPtr dom, + virDomainCheckpointPtr **snaps, + unsigned int flags) +{ + int count =3D virDomainCheckpointObjListGetNames(checkpoints, from, NU= LL, + 0, flags); + virDomainCheckpointPtr *list =3D NULL; + char **names; + int ret =3D -1; + size_t i; + + if (!snaps || count < 0) + return count; + if (VIR_ALLOC_N(names, count) < 0 || + VIR_ALLOC_N(list, count + 1) < 0) + goto cleanup; + + if (virDomainCheckpointObjListGetNames(checkpoints, from, names, count, + flags) < 0) + goto cleanup; + for (i =3D 0; i < count; i++) + if ((list[i] =3D virGetDomainCheckpoint(dom, names[i])) =3D=3D NUL= L) + goto cleanup; + + ret =3D count; + *snaps =3D list; + + cleanup: + for (i =3D 0; i < count; i++) + VIR_FREE(names[i]); + VIR_FREE(names); + if (ret < 0 && list) { + for (i =3D 0; i < count; i++) + virObjectUnref(list[i]); + VIR_FREE(list); + } + return ret; +} diff --git a/src/conf/virdomainmomentobjlist.c b/src/conf/virdomainmomentob= jlist.c index f56b516343..332bdf9dbf 100644 --- a/src/conf/virdomainmomentobjlist.c +++ b/src/conf/virdomainmomentobjlist.c @@ -31,8 +31,8 @@ #include "viralloc.h" /* FIXME: using virObject would allow us to not need this */ -#include "snapshot_conf.h" #include "virdomainsnapshotobjlist.h" +#include "virdomaincheckpointobjlist.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN diff --git a/src/conf/virdomainobjlist.c b/src/conf/virdomainobjlist.c index d58d25f847..d640da6205 100644 --- a/src/conf/virdomainobjlist.c +++ b/src/conf/virdomainobjlist.c @@ -25,12 +25,14 @@ #include "internal.h" #include "datatypes.h" #include "virdomainobjlist.h" +#include "checkpoint_conf.h" #include "snapshot_conf.h" #include "viralloc.h" #include "virfile.h" #include "virlog.h" #include "virstring.h" #include "virdomainsnapshotobjlist.h" +#include "virdomaincheckpointobjlist.h" #define VIR_FROM_THIS VIR_FROM_DOMAIN @@ -887,6 +889,15 @@ virDomainObjMatchFilter(virDomainObjPtr vm, return false; } + /* filter by checkpoint existence */ + if (MATCH(VIR_CONNECT_LIST_DOMAINS_FILTERS_CHECKPOINT)) { + int nchk =3D virDomainListCheckpoints(vm->checkpoints, NULL, NULL, + NULL, 0); + if (!((MATCH(VIR_CONNECT_LIST_DOMAINS_HAS_CHECKPOINT) && nchk > 0)= || + (MATCH(VIR_CONNECT_LIST_DOMAINS_NO_CHECKPOINT) && nchk <=3D = 0))) + return false; + } + return true; } #undef MATCH diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6c504dfc86..95e428cf2a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -70,9 +70,12 @@ virCapabilitiesSetNetPrefix; # conf/checkpoint_conf.h +virDomainCheckpointAlignDisks; virDomainCheckpointDefFormat; virDomainCheckpointDefNew; virDomainCheckpointDefParseString; +virDomainCheckpointFormatConvertXMLFlags; +virDomainCheckpointRedefinePrep; virDomainCheckpointTypeFromString; virDomainCheckpointTypeToString; @@ -976,6 +979,21 @@ virChrdevFree; virChrdevOpen; +# conf/virdomaincheckpointobjlist.h +virDomainCheckpointAssignDef; +virDomainCheckpointFindByName; +virDomainCheckpointForEach; +virDomainCheckpointGetCurrent; +virDomainCheckpointGetCurrentName; +virDomainCheckpointObjListFree; +virDomainCheckpointObjListNew; +virDomainCheckpointObjListRemove; +virDomainCheckpointObjListRemoveAll; +virDomainCheckpointSetCurrent; +virDomainCheckpointUpdateRelations; +virDomainListCheckpoints; + + # conf/virdomainmomentobjlist.h virDomainMomentDropChildren; virDomainMomentDropParent; --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list