[libvirt] [PATCH v6 7/9] backup: Introduce virDomainCheckpoint APIs

Daniel P. Berrangé berrange at redhat.com
Tue Mar 26 16:55:22 UTC 2019


On Tue, Mar 26, 2019 at 01:13:51AM -0500, Eric Blake wrote:
> Introduce a bunch of new public APIs related to backup checkpoints.
> Checkpoints are modeled heavily after virDomainSnapshotPtr (both
> represent a point in time of the guest), although a snapshot exists
> with the intent of rolling back to that state, while a checkpoint
> exists to make it possible to create an incremental backup at a later
> time.
> 
> The following map shows the API relations to snapshots, with new APIs
> on the right:
> 
> Operate on a domain object to create/redefine a child:
> virDomainSnapshotCreateXML          virDomainCheckpointCreateXML
> 
> Operate on a child object for lifetime management:
> virDomainSnapshotDelete             virDomainCheckpointDelete
> virDomainSnapshotFree               virDomainCheckpointFree
> virDomainSnapshotRef                virDomainCheckpointRef
> 
> Operate on a child object to learn more about it:
> virDomainSnapshotGetXMLDesc         virDomainCheckpointGetXMLDesc
> virDomainSnapshotGetConnect         virDomainCheckpointGetConnect
> virDomainSnapshotGetDomain          virDomainCheckpointGetDomain
> virDomainSnapshotGetName            virDomainCheckpiontGetName
> virDomainSnapshotGetParent          virDomainCheckpiontGetParent
> virDomainSnapshotHasMetadata        virDomainCheckpointHasMetadata
> virDomainSnapshotIsCurrent          virDomainCheckpointIsCurrent
> 
> Operate on a domain object to list all children:
> virDomainSnapshotNum                (no counterpart, this is the old
> virDomainSnapshotListNames           racy interface)
> virDomainSnapshotListAllSnapshots   virDomainListCheckpoints

The snapshot API was actually  virDomainListAllSnapshots.

For naming consistency I'd prefer to see "All" in the name of the
name API too eg virDomainListAllCheckpoints

> 
> Operate on a child object to list descendents:
> virDomainSnapshotNumChildren        (no counterpart, this is the old
> virDomainSnapshotListChildrenNames   racy interface)
> virDomainSnapshotListAllChildren    virDomainCheckpointListChildren

and virDomainCheckpointListAllChildren here too

> Operate on a domain to locate a particular child:
> virDomainSnapshotLookupByName       virDomainCheckpointLookupByName
> virDomainHasCurrentSnapshot         virDomainHasCurrentSnapshot

Presumably the second should be virDomainhasCurrentCheckpoint

> virDomainSnapshotCurrent            virDomainCheckpointCurrent
> 
> Operate on a snapshot to roll back to earlier state:
> virDomainSnapshotRevert             (no counterpart, instead checkpoints
>                                      are used in incremental backups via
> 				     XML to virDomainBackupBegin)
> 
> Signed-off-by: Eric Blake <eblake at redhat.com>
> ---
>  include/libvirt/libvirt-domain-checkpoint.h | 161 +++++
>  include/libvirt/libvirt-domain.h            |   6 +
>  include/libvirt/libvirt.h                   |   5 +-
>  src/conf/virdomainmomentobjlist.h           |   5 +-
>  src/driver-hypervisor.h                     |  60 +-
>  docs/Makefile.am                            |   3 +
>  docs/apibuild.py                            |   2 +
>  docs/docs.html.in                           |   1 +
>  libvirt.spec.in                             |   1 +
>  mingw-libvirt.spec.in                       |   2 +
>  po/POTFILES                                 |   1 +
>  src/Makefile.am                             |   2 +
>  src/libvirt-domain-checkpoint.c             | 749 ++++++++++++++++++++
>  src/libvirt-domain.c                        |   4 +-
>  src/libvirt_public.syms                     |  16 +
>  15 files changed, 1010 insertions(+), 8 deletions(-)
>  create mode 100644 include/libvirt/libvirt-domain-checkpoint.h
>  create mode 100644 src/libvirt-domain-checkpoint.c
> 
> diff --git a/include/libvirt/libvirt-domain-checkpoint.h b/include/libvirt/libvirt-domain-checkpoint.h
> new file mode 100644
> index 0000000000..332df93755
> --- /dev/null
> +++ b/include/libvirt/libvirt-domain-checkpoint.h
> @@ -0,0 +1,161 @@
> +/*
> + * libvirt-domain-checkpoint.h
> + * Summary: APIs for management of domain checkpoints
> + * Description: Provides APIs for the management of domain checkpoints
> + *
> + * Copyright (C) 2006-2019 Red Hat, Inc.
> + *
> + * 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
> + * <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef LIBVIRT_DOMAIN_CHECKPOINT_H
> +# define LIBVIRT_DOMAIN_CHECKPOINT_H
> +
> +# ifndef __VIR_LIBVIRT_H_INCLUDES__
> +#  error "Don't include this file directly, only use libvirt/libvirt.h"
> +# endif
> +
> +/**
> + * virDomainCheckpoint:
> + *
> + * A virDomainCheckpoint is a private structure representing a checkpoint of
> + * a domain.  A checkpoint is useful for tracking which portions of the
> + * domain disks have been altered since a point in time, but by itself does
> + * not allow reverting back to that point in time.
> + */
> +typedef struct _virDomainCheckpoint virDomainCheckpoint;
> +
> +/**
> + * virDomainCheckpointPtr:
> + *
> + * A virDomainCheckpointPtr is pointer to a virDomainCheckpoint
> + * private structure, and is the type used to reference a domain
> + * checkpoint in the API.
> + */
> +typedef virDomainCheckpoint *virDomainCheckpointPtr;
> +
> +const char *virDomainCheckpointGetName(virDomainCheckpointPtr checkpoint);
> +virDomainPtr virDomainCheckpointGetDomain(virDomainCheckpointPtr checkpoint);
> +virConnectPtr virDomainCheckpointGetConnect(virDomainCheckpointPtr checkpoint);
> +
> +typedef enum {
> +    VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE    = (1 << 0), /* Restore or alter
> +                                                            metadata */
> +    VIR_DOMAIN_CHECKPOINT_CREATE_CURRENT     = (1 << 1), /* With redefine, make
> +                                                            checkpoint current */
> +    VIR_DOMAIN_CHECKPOINT_CREATE_NO_METADATA = (1 << 2), /* Make checkpoint without
> +                                                            remembering it */
> +    VIR_DOMAIN_CHECKPOINT_CREATE_QUIESCE     = (1 << 3), /* use guest agent to
> +                                                            quiesce all mounted
> +                                                            file systems within
> +                                                            the domain */
> +} virDomainCheckpointCreateFlags;
> +
> +/* Create a checkpoint using the current VM state. */
> +virDomainCheckpointPtr virDomainCheckpointCreateXML(virDomainPtr domain,
> +                                                    const char *xmlDesc,
> +                                                    unsigned int flags);
> +
> +typedef enum {
> +    VIR_DOMAIN_CHECKPOINT_XML_SECURE    = (1 << 0), /* Include sensitive data */
> +    VIR_DOMAIN_CHECKPOINT_XML_NO_DOMAIN = (1 << 1), /* Suppress <domain>
> +                                                       subelement */
> +    VIR_DOMAIN_CHECKPOINT_XML_SIZE      = (1 << 2), /* Include dynamic
> +                                                       per-<disk> size */
> +} virDomainCheckpointXMLFlags;
> +
> +/* Dump the XML of a checkpoint */
> +char *virDomainCheckpointGetXMLDesc(virDomainCheckpointPtr checkpoint,
> +                                    unsigned int flags);
> +
> +/**
> + * virDomainCheckpointListFlags:
> + *
> + * Flags valid for virDomainListCheckpoints() and
> + * virDomainCheckpointListChildren().  Note that the interpretation of
> + * flag (1<<0) depends on which function it is passed to; but serves
> + * to toggle the per-call default of whether the listing is shallow or
> + * recursive.  Remaining bits come in groups; if all bits from a group
> + * are 0, then that group is not used to filter results.  */
> +typedef enum {
> +    VIR_DOMAIN_CHECKPOINT_LIST_ROOTS       = (1 << 0), /* Filter by checkpoints
> +                                                          with no parents, when
> +                                                          listing a domain */
> +    VIR_DOMAIN_CHECKPOINT_LIST_DESCENDANTS = (1 << 0), /* List all descendants,
> +                                                          not just children, when
> +                                                          listing a checkpoint */
> +    VIR_DOMAIN_CHECKPOINT_LIST_TOPOLOGICAL = (1 << 1), /* Ensure parents occur
> +                                                          before children in
> +                                                          the resulting list */
> +
> +    VIR_DOMAIN_CHECKPOINT_LIST_LEAVES      = (1 << 2), /* Filter by checkpoints
> +                                                          with no children */
> +    VIR_DOMAIN_CHECKPOINT_LIST_NO_LEAVES   = (1 << 3), /* Filter by checkpoints
> +                                                          that have children */
> +
> +    VIR_DOMAIN_CHECKPOINT_LIST_METADATA    = (1 << 4), /* Filter by checkpoints
> +                                                          which have metadata */
> +    VIR_DOMAIN_CHECKPOINT_LIST_NO_METADATA = (1 << 5), /* Filter by checkpoints
> +                                                          with no metadata */
> +} virDomainCheckpointListFlags;
> +
> +/* Get all checkpoint objects for this domain */
> +int virDomainListCheckpoints(virDomainPtr domain,
> +                             virDomainCheckpointPtr **checkpoints,
> +                             unsigned int flags);
> +
> +/* Get all checkpoint object children for this checkpoint */
> +int virDomainCheckpointListChildren(virDomainCheckpointPtr checkpoint,
> +                                    virDomainCheckpointPtr **children,
> +                                    unsigned int flags);
> +
> +/* Get a handle to a named checkpoint */
> +virDomainCheckpointPtr virDomainCheckpointLookupByName(virDomainPtr domain,
> +                                                       const char *name,
> +                                                       unsigned int flags);
> +
> +/* Check whether a domain has a checkpoint which is currently used */
> +int virDomainHasCurrentCheckpoint(virDomainPtr domain, unsigned int flags);
> +
> +/* Get a handle to the current checkpoint */
> +virDomainCheckpointPtr virDomainCheckpointCurrent(virDomainPtr domain,
> +                                                  unsigned int flags);
> +
> +/* Get a handle to the parent checkpoint, if one exists */
> +virDomainCheckpointPtr virDomainCheckpointGetParent(virDomainCheckpointPtr checkpoint,
> +                                                    unsigned int flags);
> +
> +/* Determine if a checkpoint is the current checkpoint of its domain.  */
> +int virDomainCheckpointIsCurrent(virDomainCheckpointPtr checkpoint,
> +                                 unsigned int flags);
> +
> +/* Determine if checkpoint has metadata that would prevent domain deletion.  */
> +int virDomainCheckpointHasMetadata(virDomainCheckpointPtr checkpoint,
> +                                   unsigned int flags);
> +
> +/* Delete a checkpoint */
> +typedef enum {
> +    VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN      = (1 << 0), /* Also delete children */
> +    VIR_DOMAIN_CHECKPOINT_DELETE_METADATA_ONLY = (1 << 1), /* Delete just metadata */
> +    VIR_DOMAIN_CHECKPOINT_DELETE_CHILDREN_ONLY = (1 << 2), /* Delete just children */
> +} virDomainCheckpointDeleteFlags;
> +
> +int virDomainCheckpointDelete(virDomainCheckpointPtr checkpoint,
> +                              unsigned int flags);
> +
> +int virDomainCheckpointRef(virDomainCheckpointPtr checkpoint);
> +int virDomainCheckpointFree(virDomainCheckpointPtr checkpoint);
> +
> +#endif /* LIBVIRT_DOMAIN_CHECKPOINT_H */
> diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
> index 1d5bdb545d..94504e70a6 100644
> --- a/include/libvirt/libvirt-domain.h
> +++ b/include/libvirt/libvirt-domain.h
> @@ -1774,6 +1774,9 @@ typedef enum {
>      VIR_DOMAIN_UNDEFINE_NVRAM              = (1 << 2), /* Also remove any
>                                                            nvram file */
>      VIR_DOMAIN_UNDEFINE_KEEP_NVRAM         = (1 << 3), /* Keep nvram file */
> +    VIR_DOMAIN_UNDEFINE_CHECKPOINTS_METADATA= (1 << 4),/* If last use of domain,
> +                                                          then also remove any
> +                                                          checkpoint metadata */

Whitespace missing before the "=" and between ",/"

> 
>      /* Future undefine control flags should come here. */
>  } virDomainUndefineFlagsValues;
> @@ -1812,6 +1815,9 @@ typedef enum {
> 
>      VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT   = 1 << 12,
>      VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT    = 1 << 13,
> +
> +    VIR_CONNECT_LIST_DOMAINS_HAS_CHECKPOINT = 1 << 14,
> +    VIR_CONNECT_LIST_DOMAINS_NO_CHECKPOINT  = 1 << 15,
>  } virConnectListAllDomainsFlags;
> 
>  int                     virConnectListAllDomains (virConnectPtr conn,



Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




More information about the libvir-list mailing list