From a1465e661e7629acfee6f2b6a6268d071c413a3b Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Fri, 4 Mar 2022 15:50:19 +0100 Subject: [PATCH] conf: snapshot: Introduce 'manual' mode for snapshot of a disk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The idea of the manual mode is to allow a synchronized snapshot in cases when the storage is outsourced to an unmanaged storage provider which requires cooperation with snapshotting. The mode will instruct the hypervisor to pause along when the other components are snapshotted and the 'manual' disk can be snapshotted along. This increases latency of the snapshot but allows them in otherwise impossible situations. Signed-off-by: Peter Krempa Reviewed-by: Ján Tomko --- docs/formatdomain.rst | 15 ++++++++------- docs/formatsnapshot.rst | 9 +++++++++ docs/schemas/domainsnapshot.rng | 3 +++ src/conf/domain_conf.c | 1 + src/conf/domain_conf.h | 1 + src/conf/snapshot_conf.c | 6 ++++++ src/qemu/qemu_snapshot.c | 5 +++++ src/test/test_driver.c | 17 +++++++++++++++++ 8 files changed, 50 insertions(+), 7 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 9b1b69bb4d..d188de4858 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -2620,13 +2620,14 @@ paravirtualized driver is specified via the ``disk`` element. Indicates the default behavior of the disk during disk snapshots: "``internal``" requires a file format such as qcow2 that can store both the snapshot and the data changes since the snapshot; "``external``" will - separate the snapshot from the live data; and "``no``" means the disk will - not participate in snapshots. Read-only disks default to "``no``", while - the default for other disks depends on the hypervisor's capabilities. Some - hypervisors allow a per-snapshot choice as well, during `domain snapshot - creation `__. Not all snapshot modes are supported; - for example, enabling snapshots with a transient disk generally does not - make sense. :since:`Since 0.9.5` + separate the snapshot from the live data; "``no``" means the disk will + not participate in snapshots; and ``manual`` allows snapshotting done via + an unmanaged storage provider. Read-only disks default to "``no``", while + the default for other disks depends on the hypervisor's capabilities. + Some hypervisors allow a per-snapshot choice as well, during `domain + snapshot creation `__. Not all snapshot modes are + supported; for example, enabling snapshots with a transient disk + generally does not make sense. :since:`Since 0.9.5` ``source`` Representation of the disk ``source`` depends on the disk ``type`` attribute diff --git a/docs/formatsnapshot.rst b/docs/formatsnapshot.rst index 0fee35d89c..9b874e4890 100644 --- a/docs/formatsnapshot.rst +++ b/docs/formatsnapshot.rst @@ -124,6 +124,15 @@ The top-level ``domainsnapshot`` element may contain the following elements: corresponding domain disk, while others like qemu allow this field to override the domain default. + :since:`Since 8.2.0` the ``snapshot`` attribute supports the ``manual`` + value which instructs the hypervisor to create the snapshot and keep a + synchronized state by pausing the VM which allows to snapshot disk + storage from outside of the hypervisor if the storage provider supports + it. The caller is responsible for resuming a VM paused by requesting a + ``manual`` snapshot. When reverting such snapshot, the expectation is that + the storage is configured in a way where the hypervisor will see the + correct image state. + :since:`Since 1.2.2` the ``disk`` element supports an optional attribute ``type`` if the ``snapshot`` attribute is set to ``external``. This attribute specifies the snapshot target storage type and allows to diff --git a/docs/schemas/domainsnapshot.rng b/docs/schemas/domainsnapshot.rng index 58c370878d..a5d1a40493 100644 --- a/docs/schemas/domainsnapshot.rng +++ b/docs/schemas/domainsnapshot.rng @@ -200,6 +200,9 @@ + + manual + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e0dfc9e45f..153954a0b0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1408,6 +1408,7 @@ VIR_ENUM_IMPL(virDomainSnapshotLocation, "no", "internal", "external", + "manual", ); /* Internal mapping: subset of block job types that can be present in diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a4de46773c..b69abfa270 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -542,6 +542,7 @@ typedef enum { VIR_DOMAIN_SNAPSHOT_LOCATION_NO, VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL, VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL, + VIR_DOMAIN_SNAPSHOT_LOCATION_MANUAL, VIR_DOMAIN_SNAPSHOT_LOCATION_LAST } virDomainSnapshotLocation; diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c index e2442441d0..80946beba9 100644 --- a/src/conf/snapshot_conf.c +++ b/src/conf/snapshot_conf.c @@ -312,6 +312,12 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt, &def->memory, VIR_DOMAIN_SNAPSHOT_LOCATION_DEFAULT) < 0) return NULL; + + if (def->memory == VIR_DOMAIN_SNAPSHOT_LOCATION_MANUAL) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'manual' memory snapshot mode not supported")); + return NULL; + } } if (def->memory == VIR_DOMAIN_SNAPSHOT_LOCATION_DEFAULT) { diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c index 6eebe69919..df808eef83 100644 --- a/src/qemu/qemu_snapshot.c +++ b/src/qemu/qemu_snapshot.c @@ -757,6 +757,11 @@ qemuSnapshotPrepare(virDomainObj *vm, external++; break; + case VIR_DOMAIN_SNAPSHOT_LOCATION_MANUAL: + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("'manual' disk snapshot mode not yet implemented")); + return -1; + case VIR_DOMAIN_SNAPSHOT_LOCATION_NO: /* Remember seeing a disk that has snapshot disabled */ if (!virStorageSourceIsEmpty(dom_disk->src) && diff --git a/src/test/test_driver.c b/src/test/test_driver.c index d9b4d2edf9..a824ef0186 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -8710,6 +8710,23 @@ testDomainSnapshotAlignDisks(virDomainObj *vm, unsigned int flags) { virDomainSnapshotLocation align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL; + size_t i; + + for (i = 0; i < def->ndisks; i++) { + switch (def->disks[i].snapshot) { + case VIR_DOMAIN_SNAPSHOT_LOCATION_DEFAULT: + case VIR_DOMAIN_SNAPSHOT_LOCATION_NO: + case VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL: + case VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL: + case VIR_DOMAIN_SNAPSHOT_LOCATION_LAST: + break; + + case VIR_DOMAIN_SNAPSHOT_LOCATION_MANUAL: + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("'manual' snapshot mode is not supported by the test driver")); + return -1; + } + } if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) { align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL;