mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
snapshot: Make virDomainMomentObjListGetNames more generic
Rather than hard-coding the snapshot filter bit values into the generic code, add another layer of indirection: callers must map which of their public filter bits correspond to supported moment bits, then pass two separate flags (the ones translated for moment code to operate on, and the remaining ones for the filter callback to operate on). Signed-off-by: Eric Blake <eblake@redhat.com> Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
015e71c54d
commit
a3d179807a
@ -281,6 +281,7 @@ struct virDomainMomentNameData {
|
|||||||
int count;
|
int count;
|
||||||
bool error;
|
bool error;
|
||||||
virDomainMomentObjListFilter filter;
|
virDomainMomentObjListFilter filter;
|
||||||
|
unsigned int filter_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -295,13 +296,12 @@ static int virDomainMomentObjListCopyNames(void *payload,
|
|||||||
return 0;
|
return 0;
|
||||||
/* Caller already sanitized flags. Filtering on DESCENDANTS was
|
/* Caller already sanitized flags. Filtering on DESCENDANTS was
|
||||||
* done by choice of iteration in the caller. */
|
* done by choice of iteration in the caller. */
|
||||||
/* TODO: Create VIR_DOMAIN_MOMENT_LIST names */
|
if ((data->flags & VIR_DOMAIN_MOMENT_LIST_LEAVES) && obj->nchildren)
|
||||||
if ((data->flags & VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) && obj->nchildren)
|
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
|
|
||||||
if (!data->filter(obj, data->flags))
|
if (!data->filter(obj, data->filter_flags))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (data->names && data->count < data->maxnames &&
|
if (data->names && data->count < data->maxnames &&
|
||||||
@ -320,25 +320,26 @@ virDomainMomentObjListGetNames(virDomainMomentObjListPtr moments,
|
|||||||
char **const names,
|
char **const names,
|
||||||
int maxnames,
|
int maxnames,
|
||||||
unsigned int flags,
|
unsigned int flags,
|
||||||
virDomainMomentObjListFilter filter)
|
virDomainMomentObjListFilter filter,
|
||||||
|
unsigned int filter_flags)
|
||||||
{
|
{
|
||||||
struct virDomainMomentNameData data = { names, maxnames, flags, 0,
|
struct virDomainMomentNameData data = { names, maxnames, flags, 0,
|
||||||
false, filter };
|
false, filter, filter_flags };
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
virCheckFlags(VIR_DOMAIN_MOMENT_FILTERS_ALL, -1);
|
||||||
if (!from) {
|
if (!from) {
|
||||||
/* LIST_ROOTS and LIST_DESCENDANTS have the same bit value,
|
/* LIST_ROOTS and LIST_DESCENDANTS have the same bit value,
|
||||||
* but opposite semantics. Toggle here to get the correct
|
* but opposite semantics. Toggle here to get the correct
|
||||||
* traversal on the metaroot. */
|
* traversal on the metaroot. */
|
||||||
/* TODO: Create VIR_DOMAIN_MOMENT_LIST names */
|
flags ^= VIR_DOMAIN_MOMENT_LIST_ROOTS;
|
||||||
flags ^= VIR_DOMAIN_SNAPSHOT_LIST_ROOTS;
|
|
||||||
from = &moments->metaroot;
|
from = &moments->metaroot;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We handle LIST_ROOT/LIST_DESCENDANTS and LIST_TOPOLOGICAL directly,
|
/* We handle LIST_ROOT/LIST_DESCENDANTS and LIST_TOPOLOGICAL directly,
|
||||||
* mask those bits out to determine when we must use the filter callback. */
|
* mask those bits out to determine when we must use the filter callback. */
|
||||||
data.flags &= ~(VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS |
|
data.flags &= ~(VIR_DOMAIN_MOMENT_LIST_DESCENDANTS |
|
||||||
VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL);
|
VIR_DOMAIN_MOMENT_LIST_TOPOLOGICAL);
|
||||||
|
|
||||||
/* If this common code is being used, we assume that all moments
|
/* If this common code is being used, we assume that all moments
|
||||||
* have metadata, and thus can handle METADATA up front as an
|
* have metadata, and thus can handle METADATA up front as an
|
||||||
@ -346,26 +347,26 @@ virDomainMomentObjListGetNames(virDomainMomentObjListPtr moments,
|
|||||||
* add the ability to track qcow2 internal snapshots without the
|
* add the ability to track qcow2 internal snapshots without the
|
||||||
* use of metadata, in which case this check should move into the
|
* use of metadata, in which case this check should move into the
|
||||||
* filter callback. */
|
* filter callback. */
|
||||||
if ((data.flags & VIR_DOMAIN_SNAPSHOT_FILTERS_METADATA) ==
|
if ((data.flags & VIR_DOMAIN_MOMENT_FILTERS_METADATA) ==
|
||||||
VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA)
|
VIR_DOMAIN_MOMENT_LIST_NO_METADATA)
|
||||||
return 0;
|
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
|
/* We could just always do a topological visit; but it is
|
||||||
* possible to optimize for less stack usage and time when a
|
* possible to optimize for less stack usage and time when a
|
||||||
* simpler full hashtable visit or counter will do. */
|
* simpler full hashtable visit or counter will do. */
|
||||||
if (from->def || (names &&
|
if (from->def || (names &&
|
||||||
(flags & VIR_DOMAIN_SNAPSHOT_LIST_TOPOLOGICAL)))
|
(flags & VIR_DOMAIN_MOMENT_LIST_TOPOLOGICAL)))
|
||||||
virDomainMomentForEachDescendant(from,
|
virDomainMomentForEachDescendant(from,
|
||||||
virDomainMomentObjListCopyNames,
|
virDomainMomentObjListCopyNames,
|
||||||
&data);
|
&data);
|
||||||
else if (names || data.flags)
|
else if (names || data.flags || filter_flags)
|
||||||
virHashForEach(moments->objs, virDomainMomentObjListCopyNames,
|
virHashForEach(moments->objs, virDomainMomentObjListCopyNames,
|
||||||
&data);
|
&data);
|
||||||
else
|
else
|
||||||
data.count = virHashSize(moments->objs);
|
data.count = virHashSize(moments->objs);
|
||||||
} else if (names || data.flags) {
|
} else if (names || data.flags || filter_flags) {
|
||||||
virDomainMomentForEachChild(from,
|
virDomainMomentForEachChild(from,
|
||||||
virDomainMomentObjListCopyNames, &data);
|
virDomainMomentObjListCopyNames, &data);
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,12 +70,40 @@ void virDomainMomentObjListFree(virDomainMomentObjListPtr moments);
|
|||||||
virDomainMomentObjPtr virDomainMomentAssignDef(virDomainMomentObjListPtr moments,
|
virDomainMomentObjPtr virDomainMomentAssignDef(virDomainMomentObjListPtr moments,
|
||||||
virDomainMomentDefPtr def);
|
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,
|
int virDomainMomentObjListGetNames(virDomainMomentObjListPtr moments,
|
||||||
virDomainMomentObjPtr from,
|
virDomainMomentObjPtr from,
|
||||||
char **const names,
|
char **const names,
|
||||||
int maxnames,
|
int maxnames,
|
||||||
unsigned int flags,
|
unsigned int moment_flags,
|
||||||
virDomainMomentObjListFilter filter);
|
virDomainMomentObjListFilter filter,
|
||||||
|
unsigned int filter_flags);
|
||||||
virDomainMomentObjPtr virDomainMomentFindByName(virDomainMomentObjListPtr moments,
|
virDomainMomentObjPtr virDomainMomentFindByName(virDomainMomentObjListPtr moments,
|
||||||
const char *name);
|
const char *name);
|
||||||
int virDomainMomentObjListSize(virDomainMomentObjListPtr moments);
|
int virDomainMomentObjListSize(virDomainMomentObjListPtr moments);
|
||||||
|
@ -278,6 +278,31 @@ virDomainSnapshotObjListGetNames(virDomainSnapshotObjListPtr snapshots,
|
|||||||
int maxnames,
|
int maxnames,
|
||||||
unsigned int flags)
|
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
|
/* For ease of coding the visitor, it is easier to zero each group
|
||||||
* where all of the bits are set. */
|
* where all of the bits are set. */
|
||||||
if ((flags & VIR_DOMAIN_SNAPSHOT_FILTERS_LEAVES) ==
|
if ((flags & VIR_DOMAIN_SNAPSHOT_FILTERS_LEAVES) ==
|
||||||
@ -290,8 +315,8 @@ virDomainSnapshotObjListGetNames(virDomainSnapshotObjListPtr snapshots,
|
|||||||
VIR_DOMAIN_SNAPSHOT_FILTERS_LOCATION)
|
VIR_DOMAIN_SNAPSHOT_FILTERS_LOCATION)
|
||||||
flags &= ~VIR_DOMAIN_SNAPSHOT_FILTERS_LOCATION;
|
flags &= ~VIR_DOMAIN_SNAPSHOT_FILTERS_LOCATION;
|
||||||
return virDomainMomentObjListGetNames(snapshots->base, from, names,
|
return virDomainMomentObjListGetNames(snapshots->base, from, names,
|
||||||
maxnames, flags,
|
maxnames, moment_flags,
|
||||||
virDomainSnapshotFilter);
|
virDomainSnapshotFilter, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user