On 4/25/19 7:45 AM, Peter Krempa wrote:
On Wed, Apr 17, 2019 at 09:09:07 -0500, Eric Blake wrote:
> 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.
>
> The virDomainMomentObjList code is not quite polymorphic enough until
> we patch virDomainMomentDef to be a proper virObject, but doing that
> is a bigger audit. So for now, I had to duplicate the cleanup calls
> based on a bool flag for which type needs cleaning. Oh well.
I'm afraid that with this being committed the motivation to refactor it
properly will be gone.
Then I'll try harder to get that audit done before v9.
> +++ b/src/conf/virdomaincheckpointobjlist.c
> @@ -0,0 +1,223 @@
[...]
> +
> +#define VIR_FROM_THIS VIR_FROM_DOMAIN_CHECKPOINT
> +
> +VIR_LOG_INIT("conf.virdomaincheckpointobjlist");
> +
> +struct _virDomainCheckpointObjList {
> + virDomainMomentObjListPtr base;
> +};
Is this just for compile time typechecking?
Pretty much (but also because I don't have the VirObject inheritance
going, so doing that for snapshots may change what we need here as well).
> +static int
> +virDomainCheckpointObjListGetNames(virDomainCheckpointObjListPtr checkpoints,
> + 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 ==
> + (int) VIR_DOMAIN_MOMENT_LIST_ROOTS);
> + verify(VIR_DOMAIN_CHECKPOINT_LIST_TOPOLOGICAL ==
> + (int) VIR_DOMAIN_MOMENT_LIST_TOPOLOGICAL);
> + verify(VIR_DOMAIN_CHECKPOINT_LIST_LEAVES ==
> + (int) VIR_DOMAIN_MOMENT_LIST_LEAVES);
> + verify(VIR_DOMAIN_CHECKPOINT_LIST_NO_LEAVES ==
> + (int) VIR_DOMAIN_MOMENT_LIST_NO_LEAVES);
> + verify(VIR_DOMAIN_CHECKPOINT_LIST_METADATA ==
> + (int) VIR_DOMAIN_MOMENT_LIST_METADATA);
> + verify(VIR_DOMAIN_CHECKPOINT_LIST_NO_METADATA ==
> + (int) VIR_DOMAIN_MOMENT_LIST_NO_METADATA);
This looks like it should be near the VIR_DOMAIN_CHECKPOINT_LIST enum
rather than somewhere in the code randomly.
Okay, I can try to move it.
> +
> +static void
> +virDomainSnapshotObjListDataFree(void *payload,
> + const void *name ATTRIBUTE_UNUSED)
> +{
> + virDomainMomentObjPtr obj = payload;
> +
> + virDomainSnapshotObjFree(obj);
> }
>
>
> virDomainMomentObjListPtr
> -virDomainMomentObjListNew(void)
> +virDomainMomentObjListNew(bool snapshot)
Please create a new entrypoint for this. I don't see the need to
overload it using the argument.
Better than a bool would be a virClassPtr that describes the class of
the virObject to construct. So yes, making things properly polymorphic
is worthwhile to make this code cleaner.
> {
> virDomainMomentObjListPtr moments;
>
> if (VIR_ALLOC(moments) < 0)
> return NULL;
> - moments->objs = virHashCreate(50, virDomainMomentObjListDataFree);
> + moments->objs = virHashCreate(50,
> + snapshot ? virDomainSnapshotObjListDataFree :
> + virDomainCheckpointObjListDataFree);
With virObject in play, the destructor is already automatically
polymorphic (with virObjectUnref() being the common call to trigger the
correct cleanup).
> if (!moments->objs) {
> VIR_FREE(moments);
> return NULL;
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization:
qemu.org |
libvirt.org