int count;
bool error;
virDomainMomentObjListFilter filter;
+ unsigned int filter_flags;
};
return 0;
/* Caller already sanitized flags. Filtering on DESCENDANTS was
* done by choice of iteration in the caller. */
- /* TODO: Create VIR_DOMAIN_MOMENT_LIST names */
- if ((data->flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) && obj->nchildren)
+ if ((data->flags & VIR_DOMAIN_MOMENT_LIST_LEAVES) && obj->nchildren)
return 0;
- if ((data->flags & VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES) && !obj->nchildren)
+ if ((data->flags & VIR_DOMAIN_MOMENT_LIST_NO_LEAVES) && !obj->nchildren)
return 0;
- if (!data->filter(obj, data->flags))
+ if (!data->filter(obj, data->filter_flags))
return 0;
if (data->names && data->count < data->maxnames &&
char **const names,
int maxnames,
unsigned int flags,
- virDomainMomentObjListFilter filter)
+ virDomainMomentObjListFilter filter,
+ unsigned int filter_flags)
{
struct virDomainMomentNameData data = { names, maxnames, flags, 0,
- false, filter };
+ false, filter, filter_flags };
size_t i;
+ virCheckFlags(VIR_DOMAIN_MOMENT_FILTERS_ALL, -1);
if (!from) {
/* LIST_ROOTS and LIST_DESCENDANTS have the same bit value,
* but opposite semantics. Toggle here to get the correct
* traversal on the metaroot. */
- /* TODO: Create VIR_DOMAIN_MOMENT_LIST names */
- flags ^= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
+ flags ^= VIR_DOMAIN_MOMENT_LIST_ROOTS;
from = &moments->metaroot;
}
/* We handle LIST_ROOT/LIST_DESCENDANTS and LIST_TOPOLOGICAL directly,
* mask those bits out to determine when we must use the filter callback. */
- data.flags &= ~(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
- VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL);
+ data.flags &= ~(VIR_DOMAIN_MOMENT_LIST_DESCENDANTS |
+ VIR_DOMAIN_MOMENT_LIST_TOPOLOGICAL);
/* If this common code is being used, we assume that all moments
* have metadata, and thus can handle METADATA up front as an
* add the ability to track qcow2 internal snapshots without the
* use of metadata, in which case this check should move into the
* filter callback. */
- if ((data.flags & VIR_DOMAIN_SNAPSHOT_FILTERS_METADATA) ==
- VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA)
+ if ((data.flags & VIR_DOMAIN_MOMENT_FILTERS_METADATA) ==
+ VIR_DOMAIN_MOMENT_LIST_NO_METADATA)
return 0;
- data.flags &= ~VIR_DOMAIN_SNAPSHOT_FILTERS_METADATA;
+ data.flags &= ~VIR_DOMAIN_MOMENT_FILTERS_METADATA;
- if (flags & VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS) {
+ if (flags & VIR_DOMAIN_MOMENT_LIST_DESCENDANTS) {
/* We could just always do a topological visit; but it is
* possible to optimize for less stack usage and time when a
* simpler full hashtable visit or counter will do. */
if (from->def || (names &&
- (flags & VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL)))
+ (flags & VIR_DOMAIN_MOMENT_LIST_TOPOLOGICAL)))
virDomainMomentForEachDescendant(from,
virDomainMomentObjListCopyNames,
&data);
- else if (names || data.flags)
+ else if (names || data.flags || filter_flags)
virHashForEach(moments->objs, virDomainMomentObjListCopyNames,
&data);
else
data.count = virHashSize(moments->objs);
- } else if (names || data.flags) {
+ } else if (names || data.flags || filter_flags) {
virDomainMomentForEachChild(from,
virDomainMomentObjListCopyNames, &data);
} else {
virDomainMomentObjPtr virDomainMomentAssignDef(virDomainMomentObjListPtr moments,
virDomainMomentDefPtr def);
+/* Various enum bits that map to public API filters. Note that the
+ * values of the internal bits are not necessarily the same as the
+ * public ones. */
+typedef enum {
+ VIR_DOMAIN_MOMENT_LIST_ROOTS = (1 << 0),
+ VIR_DOMAIN_MOMENT_LIST_DESCENDANTS = (1 << 0),
+ 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),
+} virDomainMomentFilters;
+
+# define VIR_DOMAIN_MOMENT_FILTERS_METADATA \
+ (VIR_DOMAIN_MOMENT_LIST_METADATA | \
+ VIR_DOMAIN_MOMENT_LIST_NO_METADATA)
+
+# define VIR_DOMAIN_MOMENT_FILTERS_LEAVES \
+ (VIR_DOMAIN_MOMENT_LIST_LEAVES | \
+ VIR_DOMAIN_MOMENT_LIST_NO_LEAVES)
+
+# 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_LEAVES)
+
int virDomainMomentObjListGetNames(virDomainMomentObjListPtr moments,
virDomainMomentObjPtr from,
char **const names,
int maxnames,
- unsigned int flags,
- virDomainMomentObjListFilter filter);
+ unsigned int moment_flags,
+ virDomainMomentObjListFilter filter,
+ unsigned int filter_flags);
virDomainMomentObjPtr virDomainMomentFindByName(virDomainMomentObjListPtr moments,
const char *name);
int virDomainMomentObjListSize(virDomainMomentObjListPtr moments);
int maxnames,
unsigned int flags)
{
+ /* Convert public flags into common flags */
+ unsigned int moment_flags = 0;
+ struct { int snap_flag; int moment_flag; } map[] = {
+ { VIR_DOMAIN_SNAPSHOT_LIST_ROOTS,
+ VIR_DOMAIN_MOMENT_LIST_ROOTS, },
+ { VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL,
+ VIR_DOMAIN_MOMENT_LIST_TOPOLOGICAL, },
+ { VIR_DOMAIN_SNAPSHOT_LIST_LEAVES,
+ VIR_DOMAIN_MOMENT_LIST_LEAVES, },
+ { VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES,
+ VIR_DOMAIN_MOMENT_LIST_NO_LEAVES, },
+ { VIR_DOMAIN_SNAPSHOT_LIST_METADATA,
+ VIR_DOMAIN_MOMENT_LIST_METADATA, },
+ { VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA,
+ VIR_DOMAIN_MOMENT_LIST_NO_METADATA, },
+ };
+ size_t i;
+
+ for (i = 0; i < ARRAY_CARDINALITY(map); i++) {
+ if (flags & map[i].snap_flag) {
+ flags &= ~map[i].snap_flag;
+ moment_flags |= map[i].moment_flag;
+ }
+ }
+
/* For ease of coding the visitor, it is easier to zero each group
* where all of the bits are set. */
if ((flags & VIR_DOMAIN_SNAPSHOT_FILTERS_LEAVES) ==
VIR_DOMAIN_SNAPSHOT_FILTERS_LOCATION)
flags &= ~VIR_DOMAIN_SNAPSHOT_FILTERS_LOCATION;
return virDomainMomentObjListGetNames(snapshots->base, from, names,
- maxnames, flags,
- virDomainSnapshotFilter);
+ maxnames, moment_flags,
+ virDomainSnapshotFilter, flags);
}