Right now, the snapshot API permits at most one current snapshot, and
includes specific API for getting at that snapshot
(virDomainHasCurrentSnapshot, virDomainSnapshotCurrent,
virDomainSnapshotIsCurrent). However, with upcoming checkpoints, it
is conceivable that a hypervisor could mark multiple checkpoints as
current (the qemu implementation has only one current checkpoint for
an incremental backup, and computes the set of changes for a
differential backup by merging a chain of checkpoints - but other
hypervisors may treat all differential checkpoints as current). As
such, it is more desirable to avoid explicit API for getting at the
one current checkpoint, and instead have the List API include a filter
for that purpose. Still, it is easier to implement that filter
directly in the common virDomainMomentObjList code, since that is the
only code that tracks the one moment that is current (both for
existing snapshots, and for how qemu will be using current
checkpoints).
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
src/conf/virdomainmomentobjlist.h | 11 +++++++++--
src/conf/virdomainmomentobjlist.c | 9 ++++++++-
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/src/conf/virdomainmomentobjlist.h b/src/conf/virdomainmomentobjlist.h
index 4067e928f4..7628df5e29 100644
--- a/src/conf/virdomainmomentobjlist.h
+++ b/src/conf/virdomainmomentobjlist.h
@@ -78,8 +78,10 @@ typedef enum {
VIR_DOMAIN_MOMENT_LIST_TOPOLOGICAL = (1 << 1),
VIR_DOMAIN_MOMENT_LIST_LEAVES = (1 << 2),
VIR_DOMAIN_MOMENT_LIST_NO_LEAVES = (1 << 3),
- VIR_DOMAIN_MOMENT_LIST_METADATA = (1 << 4),
- VIR_DOMAIN_MOMENT_LIST_NO_METADATA = (1 << 5),
+ VIR_DOMAIN_MOMENT_LIST_CURRENT = (1 << 4),
+ VIR_DOMAIN_MOMENT_LIST_NO_CURRENT = (1 << 5),
+ VIR_DOMAIN_MOMENT_LIST_METADATA = (1 << 6),
+ VIR_DOMAIN_MOMENT_LIST_NO_METADATA = (1 << 7),
} virDomainMomentFilters;
#define VIR_DOMAIN_MOMENT_FILTERS_METADATA \
@@ -90,10 +92,15 @@ typedef enum {
(VIR_DOMAIN_MOMENT_LIST_LEAVES | \
VIR_DOMAIN_MOMENT_LIST_NO_LEAVES)
+#define VIR_DOMAIN_MOMENT_FILTERS_CURRENT \
+ (VIR_DOMAIN_MOMENT_LIST_CURRENT | \
+ VIR_DOMAIN_MOMENT_LIST_NO_CURRENT)
+
#define VIR_DOMAIN_MOMENT_FILTERS_ALL \
(VIR_DOMAIN_MOMENT_LIST_ROOTS | \
VIR_DOMAIN_MOMENT_LIST_TOPOLOGICAL | \
VIR_DOMAIN_MOMENT_FILTERS_METADATA | \
+ VIR_DOMAIN_MOMENT_FILTERS_CURRENT | \
VIR_DOMAIN_MOMENT_FILTERS_LEAVES)
int virDomainMomentObjListGetNames(virDomainMomentObjListPtr moments,
diff --git a/src/conf/virdomainmomentobjlist.c b/src/conf/virdomainmomentobjlist.c
index 0ea5e9af80..55d1db9fb0 100644
--- a/src/conf/virdomainmomentobjlist.c
+++ b/src/conf/virdomainmomentobjlist.c
@@ -283,6 +283,7 @@ struct virDomainMomentNameData {
unsigned int flags;
int count;
bool error;
+ virDomainMomentObjPtr current; /* The current moment, if any */
virDomainMomentObjListFilter filter;
unsigned int filter_flags;
};
@@ -303,6 +304,11 @@ static int virDomainMomentObjListCopyNames(void *payload,
return 0;
if ((data->flags & VIR_DOMAIN_MOMENT_LIST_NO_LEAVES) &&
!obj->nchildren)
return 0;
+ if ((data->flags & VIR_DOMAIN_MOMENT_LIST_CURRENT) && obj !=
data->current)
+ return 0;
+ if ((data->flags & VIR_DOMAIN_MOMENT_LIST_NO_CURRENT) &&
+ obj == data->current)
+ return 0;
if (!data->filter(obj, data->filter_flags))
return 0;
@@ -327,7 +333,8 @@ virDomainMomentObjListGetNames(virDomainMomentObjListPtr moments,
unsigned int filter_flags)
{
struct virDomainMomentNameData data = { names, maxnames, flags, 0,
- false, filter, filter_flags };
+ false, moments->current,
+ filter, filter_flags };
size_t i;
virCheckFlags(VIR_DOMAIN_MOMENT_FILTERS_ALL, -1);
--
2.20.1