1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-22 17:34:18 +03:00

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:

<devices>
  <disk type=... snapshot='no|internal|external'>
    ...
    <transient/>
  </disk>
</devices>

* 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.
This commit is contained in:
Eric Blake 2011-08-13 13:20:21 -06:00
parent 5a1f272875
commit 471235307f
9 changed files with 175 additions and 6 deletions

View File

@ -889,7 +889,7 @@
<pre>
...
&lt;devices&gt;
&lt;disk type='file'&gt;
&lt;disk type='file' snapshot='external'&gt;
&lt;driver name="tap" type="aio" cache="default"/&gt;
&lt;source file='/var/lib/xen/images/fv0'/&gt;
&lt;target dev='hda' bus='ide'/&gt;
@ -910,8 +910,14 @@
&lt;/source&gt;
&lt;target dev="hdb" bus="ide"/&gt;
&lt;boot order='1'/&gt;
&lt;transient/&gt;
&lt;address type='drive' controller='0' bus='1' unit='0'/&gt;
&lt;/disk&gt;
&lt;disk type='block' device='cdrom'&gt;
&lt;driver name='qemu' type='raw'/&gt;
&lt;target def='hdc' bus='ide'/&gt;
&lt;readonly/&gt;
&lt;/disk&gt;
&lt;/devices&gt;
...</pre>
@ -923,9 +929,23 @@
and refers to the underlying source for the disk. The optional
<code>device</code> 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".
<span class="since">Since 0.0.3; "device" attribute since 0.1.4;
"network" attribute since 0.8.7</span></dd>
and "cdrom", defaulting to "disk". The
optional <code>snapshot</code> 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 <a href="formatsnapshot.html">domain snapshot
creation</a>. Not all snapshot modes are supported;
for example, <code>snapshot='yes'</code> with a transient disk
generally does not make sense. <span class="since">Since 0.0.3;
"device" attribute since 0.1.4;
"network" attribute since 0.8.7; "snapshot" since
0.9.5</span></dd>
<dt><code>source</code></dt>
<dd>If the disk <code>type</code> is "file", then
the <code>file</code> attribute specifies the fully-qualified
@ -1034,11 +1054,23 @@
the <a href="formatstorageencryption.html">Storage Encryption</a> page
for more information.
</dd>
<dt><code>readonly</code></dt>
<dd>If present, this indicates the device cannot be modified by
the guest. For now, this is the default for disks with
attribute <code>type='cdrom'</code>.
</dd>
<dt><code>shareable</code></dt>
<dd>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.
</dd>
<dt><code>transient</code></dt>
<dd>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. <span class="since">Since 0.9.5</span>
</dd>
<dt><code>serial</code></dt>
<dd>If present, this specify serial number of virtual hard drive.
For example, it may look

View File

@ -616,6 +616,11 @@
<empty/>
</element>
</optional>
<optional>
<element name="transient">
<empty/>
</element>
</optional>
<optional>
<element name="serial">
<ref name="diskSerial"/>
@ -628,6 +633,15 @@
<ref name="address"/>
</optional>
</define>
<define name="snapshot">
<attribute name="snapshot">
<choice>
<value>no</value>
<value>internal</value>
<value>external</value>
</choice>
</attribute>
</define>
<define name="lease">
<element name="lease">
@ -667,6 +681,9 @@
</choice>
</attribute>
</optional>
<optional>
<ref name="snapshot"/>
</optional>
<choice>
<group>
<attribute name="type">

View File

@ -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,
" <disk type='%s' device='%s'>\n",
" <disk type='%s' device='%s'",
type, device);
if (def->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, " <readonly/>\n");
if (def->shared)
virBufferAddLit(buf, " <shareable/>\n");
if (def->transient)
virBufferAddLit(buf, " <transient/>\n");
if (def->serial)
virBufferEscapeString(buf, " <serial>%s</serial>\n",
def->serial);

View File

@ -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)

View File

@ -289,6 +289,8 @@ virDomainDiskIoTypeFromString;
virDomainDiskIoTypeToString;
virDomainDiskRemove;
virDomainDiskRemoveByName;
virDomainDiskSnapshotTypeFromString;
virDomainDiskSnapshotTypeToString;
virDomainDiskTypeFromString;
virDomainDiskTypeToString;
virDomainFSDefFree;

View File

@ -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

View File

@ -0,0 +1,39 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219100</memory>
<currentMemory>219100</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk' snapshot='internal'>
<driver name='qemu' type='qcow2' cache='none'/>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<disk type='block' device='cdrom' snapshot='no'>
<driver name='qemu' type='raw'/>
<source dev='/dev/HostVG/QEMUGuest2'/>
<target dev='hdc' bus='ide'/>
<readonly/>
<address type='drive' controller='0' bus='1' unit='0'/>
</disk>
<disk type='block' device='disk' snapshot='external'>
<driver name='qemu' type='qcow2' cache='none'/>
<source dev='/dev/HostVG/QEMUGuest3'/>
<target dev='hdb' bus='ide'/>
<address type='drive' controller='0' bus='2' unit='0'/>
</disk>
<controller type='ide' index='0'/>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -0,0 +1,27 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219100</memory>
<currentMemory>219100</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='block' device='disk'>
<driver name='qemu' type='qcow2' cache='none'/>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<transient/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<controller type='ide' index='0'/>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -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,