From 471235307f0de3c05b3508755bcc35949a954e1a Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 13 Aug 2011 13:20:21 -0600 Subject: [PATCH] snapshot: additions to domain xml for disks As discussed here: https://www.redhat.com/archives/libvir-list/2011-August/msg00361.html https://www.redhat.com/archives/libvir-list/2011-August/msg00552.html Adds snapshot attribute and transient sub-element: ... * docs/schemas/domaincommon.rng (snapshot): New define. (disk): Add snapshot and persistent attributes. * docs/formatdomain.html.in: Document them. * src/conf/domain_conf.h (virDomainDiskSnapshot): New enum. (_virDomainDiskDef): New fields. * tests/qemuxml2argvdata/qemuxml2argv-disk-transient.xml: New test of rng, no args counterpart until qemu support is complete. * tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.args: New file, snapshot attribute does not affect args. * tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml: Likewise. * tests/qemuxml2argvtest.c (mymain): Run new test. --- docs/formatdomain.html.in | 40 +++++++++++++++++-- docs/schemas/domaincommon.rng | 17 ++++++++ src/conf/domain_conf.c | 35 +++++++++++++++- src/conf/domain_conf.h | 12 ++++++ src/libvirt_private.syms | 2 + .../qemuxml2argv-disk-snapshot.args | 7 ++++ .../qemuxml2argv-disk-snapshot.xml | 39 ++++++++++++++++++ .../qemuxml2argv-disk-transient.xml | 27 +++++++++++++ tests/qemuxml2argvtest.c | 2 + 9 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-transient.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index b960381c9f..b6e6de3994 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -889,7 +889,7 @@
   ...
   <devices>
-    <disk type='file'>
+    <disk type='file' snapshot='external'>
       <driver name="tap" type="aio" cache="default"/>
       <source file='/var/lib/xen/images/fv0'/>
       <target dev='hda' bus='ide'/>
@@ -910,8 +910,14 @@
       </source>
       <target dev="hdb" bus="ide"/>
       <boot order='1'/>
+      <transient/>
       <address type='drive' controller='0' bus='1' unit='0'/>
     </disk>
+    <disk type='block' device='cdrom'>
+      <driver name='qemu' type='raw'/>
+      <target def='hdc' bus='ide'/>
+      <readonly/>
+    </disk>
   </devices>
   ...
@@ -923,9 +929,23 @@ and refers to the underlying source for the disk. The optional device attribute indicates how the disk is to be exposed to the guest OS. Possible values for this attribute are "floppy", "disk" - and "cdrom", defaulting to "disk". - Since 0.0.3; "device" attribute since 0.1.4; - "network" attribute since 0.8.7 + and "cdrom", defaulting to "disk". The + optional snapshot attribute 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, snapshot='yes' with a transient disk + generally does not make sense. Since 0.0.3; + "device" attribute since 0.1.4; + "network" attribute since 0.8.7; "snapshot" since + 0.9.5
source
If the disk type is "file", then the file attribute specifies the fully-qualified @@ -1034,11 +1054,23 @@ the Storage Encryption page for more information.
+
readonly
+
If present, this indicates the device cannot be modified by + the guest. For now, this is the default for disks with + attribute type='cdrom'. +
shareable
If present, this indicates the device is expected to be shared between domains (assuming the hypervisor and OS support this), which means that caching should be deactivated for that device.
+
transient
+
If present, this indicates that changes to the device + contents should be reverted automatically when the guest + exits. With some hypervisors, marking a disk transient + prevents the domain from participating in migration or + snapshots. Since 0.9.5 +
serial
If present, this specify serial number of virtual hard drive. For example, it may look diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 8e7fd63de2..e622cede6f 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -616,6 +616,11 @@ + + + + + @@ -628,6 +633,15 @@ + + + + no + internal + external + + + @@ -667,6 +681,9 @@ + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index cce9955655..c9e6e38bfa 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -191,6 +191,12 @@ VIR_ENUM_IMPL(virDomainVirtioEventIdx, VIR_DOMAIN_VIRTIO_EVENT_IDX_LAST, "on", "off") +VIR_ENUM_IMPL(virDomainDiskSnapshot, VIR_DOMAIN_DISK_SNAPSHOT_LAST, + "default", + "no", + "internal", + "external") + VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST, "ide", "fdc", @@ -2232,6 +2238,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, xmlNodePtr cur, host; char *type = NULL; char *device = NULL; + char *snapshot = NULL; char *driverName = NULL; char *driverType = NULL; char *source = NULL; @@ -2265,6 +2272,8 @@ virDomainDiskDefParseXML(virCapsPtr caps, def->type = VIR_DOMAIN_DISK_TYPE_FILE; } + snapshot = virXMLPropString(node, "snapshot"); + cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { @@ -2366,6 +2375,8 @@ virDomainDiskDefParseXML(virCapsPtr caps, def->readonly = 1; } else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) { def->shared = 1; + } else if (xmlStrEqual(cur->name, BAD_CAST "transient")) { + def->transient = 1; } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) && xmlStrEqual(cur->name, BAD_CAST "state")) { /* Legacy back-compat. Don't add any more attributes here */ @@ -2437,6 +2448,18 @@ virDomainDiskDefParseXML(virCapsPtr caps, goto error; } + if (snapshot) { + def->snapshot = virDomainDiskSnapshotTypeFromString(snapshot); + if (def->snapshot <= 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unknown disk snapshot setting '%s'"), + snapshot); + goto error; + } + } else if (def->readonly) { + def->snapshot = VIR_DOMAIN_DISK_SNAPSHOT_NO; + } + if (bus) { if ((def->bus = virDomainDiskBusTypeFromString(bus)) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, @@ -2582,6 +2605,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, cleanup: VIR_FREE(bus); VIR_FREE(type); + VIR_FREE(snapshot); VIR_FREE(target); VIR_FREE(source); while (nhosts > 0) { @@ -2607,7 +2631,7 @@ cleanup: no_memory: virReportOOMError(); - error: +error: virDomainDiskDefFree(def); def = NULL; goto cleanup; @@ -8996,8 +9020,13 @@ virDomainDiskDefFormat(virBufferPtr buf, } virBufferAsprintf(buf, - " \n", + " snapshot && + !(def->snapshot == VIR_DOMAIN_DISK_SNAPSHOT_NO && def->readonly)) + virBufferAsprintf(buf, " snapshot='%s'", + virDomainDiskSnapshotTypeToString(def->snapshot)); + virBufferAddLit(buf, ">\n"); if (def->driverName || def->driverType || def->cachemode || def->ioeventfd || def->event_idx) { @@ -9071,6 +9100,8 @@ virDomainDiskDefFormat(virBufferPtr buf, virBufferAddLit(buf, " \n"); if (def->shared) virBufferAddLit(buf, " \n"); + if (def->transient) + virBufferAddLit(buf, " \n"); if (def->serial) virBufferEscapeString(buf, " %s\n", def->serial); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e218a30244..7e09c0abb4 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -244,6 +244,15 @@ enum virDomainVirtioEventIdx { VIR_DOMAIN_VIRTIO_EVENT_IDX_LAST }; +enum virDomainDiskSnapshot { + VIR_DOMAIN_DISK_SNAPSHOT_DEFAULT = 0, + VIR_DOMAIN_DISK_SNAPSHOT_NO, + VIR_DOMAIN_DISK_SNAPSHOT_INTERNAL, + VIR_DOMAIN_DISK_SNAPSHOT_EXTERNAL, + + VIR_DOMAIN_DISK_SNAPSHOT_LAST +}; + /* Stores the virtual disk configuration */ typedef struct _virDomainDiskDef virDomainDiskDef; typedef virDomainDiskDef *virDomainDiskDefPtr; @@ -265,8 +274,10 @@ struct _virDomainDiskDef { int iomode; int ioeventfd; int event_idx; + int snapshot; /* enum virDomainDiskSnapshot */ unsigned int readonly : 1; unsigned int shared : 1; + unsigned int transient : 1; virDomainDeviceInfo info; virStorageEncryptionPtr encryption; }; @@ -1779,6 +1790,7 @@ VIR_ENUM_DECL(virDomainDiskCache) VIR_ENUM_DECL(virDomainDiskErrorPolicy) VIR_ENUM_DECL(virDomainDiskProtocol) VIR_ENUM_DECL(virDomainDiskIo) +VIR_ENUM_DECL(virDomainDiskSnapshot) VIR_ENUM_DECL(virDomainIoEventFd) VIR_ENUM_DECL(virDomainVirtioEventIdx) VIR_ENUM_DECL(virDomainController) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 011f7522d0..60e2f14e69 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -289,6 +289,8 @@ virDomainDiskIoTypeFromString; virDomainDiskIoTypeToString; virDomainDiskRemove; virDomainDiskRemoveByName; +virDomainDiskSnapshotTypeFromString; +virDomainDiskSnapshotTypeToString; virDomainDiskTypeFromString; virDomainDiskTypeToString; virDomainFSDefFree; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.args new file mode 100644 index 0000000000..7e62942b6d --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.args @@ -0,0 +1,7 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ +pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi -boot c \ +-drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,format=qcow2,cache=none \ +-drive file=/dev/HostVG/QEMUGuest3,if=ide,bus=2,unit=0,format=qcow2,cache=none \ +-drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0,format=raw \ +-net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml new file mode 100644 index 0000000000..aeb2315caa --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml @@ -0,0 +1,39 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + +
+ + + + + + +
+ + + + + +
+ + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-transient.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-transient.xml new file mode 100644 index 0000000000..df49c4853d --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-transient.xml @@ -0,0 +1,27 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + +
+ + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 335af4a6b5..fcb20bbd62 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -362,6 +362,8 @@ mymain(void) DO_TEST("disk-ioeventfd", false, QEMU_CAPS_DRIVE, QEMU_CAPS_VIRTIO_IOEVENTFD, QEMU_CAPS_VIRTIO_TX_ALG, QEMU_CAPS_DEVICE); + DO_TEST("disk-snapshot", false, + QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_FORMAT); DO_TEST("event_idx", false, QEMU_CAPS_DRIVE, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX, -- GitLab