提交 47123530 编写于 作者: E Eric Blake

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.
上级 5a1f2728
...@@ -889,7 +889,7 @@ ...@@ -889,7 +889,7 @@
<pre> <pre>
... ...
&lt;devices&gt; &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;driver name="tap" type="aio" cache="default"/&gt;
&lt;source file='/var/lib/xen/images/fv0'/&gt; &lt;source file='/var/lib/xen/images/fv0'/&gt;
&lt;target dev='hda' bus='ide'/&gt; &lt;target dev='hda' bus='ide'/&gt;
...@@ -910,8 +910,14 @@ ...@@ -910,8 +910,14 @@
&lt;/source&gt; &lt;/source&gt;
&lt;target dev="hdb" bus="ide"/&gt; &lt;target dev="hdb" bus="ide"/&gt;
&lt;boot order='1'/&gt; &lt;boot order='1'/&gt;
&lt;transient/&gt;
&lt;address type='drive' controller='0' bus='1' unit='0'/&gt; &lt;address type='drive' controller='0' bus='1' unit='0'/&gt;
&lt;/disk&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; &lt;/devices&gt;
...</pre> ...</pre>
...@@ -923,9 +929,23 @@ ...@@ -923,9 +929,23 @@
and refers to the underlying source for the disk. The optional and refers to the underlying source for the disk. The optional
<code>device</code> attribute indicates how the disk is to be exposed <code>device</code> attribute indicates how the disk is to be exposed
to the guest OS. Possible values for this attribute are "floppy", "disk" to the guest OS. Possible values for this attribute are "floppy", "disk"
and "cdrom", defaulting to "disk". and "cdrom", defaulting to "disk". The
<span class="since">Since 0.0.3; "device" attribute since 0.1.4; optional <code>snapshot</code> attribute indicates the default
"network" attribute since 0.8.7</span></dd> 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> <dt><code>source</code></dt>
<dd>If the disk <code>type</code> is "file", then <dd>If the disk <code>type</code> is "file", then
the <code>file</code> attribute specifies the fully-qualified the <code>file</code> attribute specifies the fully-qualified
...@@ -1034,11 +1054,23 @@ ...@@ -1034,11 +1054,23 @@
the <a href="formatstorageencryption.html">Storage Encryption</a> page the <a href="formatstorageencryption.html">Storage Encryption</a> page
for more information. for more information.
</dd> </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> <dt><code>shareable</code></dt>
<dd>If present, this indicates the device is expected to be shared <dd>If present, this indicates the device is expected to be shared
between domains (assuming the hypervisor and OS support this), between domains (assuming the hypervisor and OS support this),
which means that caching should be deactivated for that device. which means that caching should be deactivated for that device.
</dd> </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> <dt><code>serial</code></dt>
<dd>If present, this specify serial number of virtual hard drive. <dd>If present, this specify serial number of virtual hard drive.
For example, it may look For example, it may look
......
...@@ -616,6 +616,11 @@ ...@@ -616,6 +616,11 @@
<empty/> <empty/>
</element> </element>
</optional> </optional>
<optional>
<element name="transient">
<empty/>
</element>
</optional>
<optional> <optional>
<element name="serial"> <element name="serial">
<ref name="diskSerial"/> <ref name="diskSerial"/>
...@@ -628,6 +633,15 @@ ...@@ -628,6 +633,15 @@
<ref name="address"/> <ref name="address"/>
</optional> </optional>
</define> </define>
<define name="snapshot">
<attribute name="snapshot">
<choice>
<value>no</value>
<value>internal</value>
<value>external</value>
</choice>
</attribute>
</define>
<define name="lease"> <define name="lease">
<element name="lease"> <element name="lease">
...@@ -667,6 +681,9 @@ ...@@ -667,6 +681,9 @@
</choice> </choice>
</attribute> </attribute>
</optional> </optional>
<optional>
<ref name="snapshot"/>
</optional>
<choice> <choice>
<group> <group>
<attribute name="type"> <attribute name="type">
......
...@@ -191,6 +191,12 @@ VIR_ENUM_IMPL(virDomainVirtioEventIdx, VIR_DOMAIN_VIRTIO_EVENT_IDX_LAST, ...@@ -191,6 +191,12 @@ VIR_ENUM_IMPL(virDomainVirtioEventIdx, VIR_DOMAIN_VIRTIO_EVENT_IDX_LAST,
"on", "on",
"off") "off")
VIR_ENUM_IMPL(virDomainDiskSnapshot, VIR_DOMAIN_DISK_SNAPSHOT_LAST,
"default",
"no",
"internal",
"external")
VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST, VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
"ide", "ide",
"fdc", "fdc",
...@@ -2232,6 +2238,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, ...@@ -2232,6 +2238,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
xmlNodePtr cur, host; xmlNodePtr cur, host;
char *type = NULL; char *type = NULL;
char *device = NULL; char *device = NULL;
char *snapshot = NULL;
char *driverName = NULL; char *driverName = NULL;
char *driverType = NULL; char *driverType = NULL;
char *source = NULL; char *source = NULL;
...@@ -2265,6 +2272,8 @@ virDomainDiskDefParseXML(virCapsPtr caps, ...@@ -2265,6 +2272,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
def->type = VIR_DOMAIN_DISK_TYPE_FILE; def->type = VIR_DOMAIN_DISK_TYPE_FILE;
} }
snapshot = virXMLPropString(node, "snapshot");
cur = node->children; cur = node->children;
while (cur != NULL) { while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) { if (cur->type == XML_ELEMENT_NODE) {
...@@ -2366,6 +2375,8 @@ virDomainDiskDefParseXML(virCapsPtr caps, ...@@ -2366,6 +2375,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
def->readonly = 1; def->readonly = 1;
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) { } else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
def->shared = 1; def->shared = 1;
} else if (xmlStrEqual(cur->name, BAD_CAST "transient")) {
def->transient = 1;
} else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) && } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) &&
xmlStrEqual(cur->name, BAD_CAST "state")) { xmlStrEqual(cur->name, BAD_CAST "state")) {
/* Legacy back-compat. Don't add any more attributes here */ /* Legacy back-compat. Don't add any more attributes here */
...@@ -2437,6 +2448,18 @@ virDomainDiskDefParseXML(virCapsPtr caps, ...@@ -2437,6 +2448,18 @@ virDomainDiskDefParseXML(virCapsPtr caps,
goto error; 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 (bus) {
if ((def->bus = virDomainDiskBusTypeFromString(bus)) < 0) { if ((def->bus = virDomainDiskBusTypeFromString(bus)) < 0) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, virDomainReportError(VIR_ERR_INTERNAL_ERROR,
...@@ -2582,6 +2605,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, ...@@ -2582,6 +2605,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
cleanup: cleanup:
VIR_FREE(bus); VIR_FREE(bus);
VIR_FREE(type); VIR_FREE(type);
VIR_FREE(snapshot);
VIR_FREE(target); VIR_FREE(target);
VIR_FREE(source); VIR_FREE(source);
while (nhosts > 0) { while (nhosts > 0) {
...@@ -2607,7 +2631,7 @@ cleanup: ...@@ -2607,7 +2631,7 @@ cleanup:
no_memory: no_memory:
virReportOOMError(); virReportOOMError();
error: error:
virDomainDiskDefFree(def); virDomainDiskDefFree(def);
def = NULL; def = NULL;
goto cleanup; goto cleanup;
...@@ -8996,8 +9020,13 @@ virDomainDiskDefFormat(virBufferPtr buf, ...@@ -8996,8 +9020,13 @@ virDomainDiskDefFormat(virBufferPtr buf,
} }
virBufferAsprintf(buf, virBufferAsprintf(buf,
" <disk type='%s' device='%s'>\n", " <disk type='%s' device='%s'",
type, device); 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 || if (def->driverName || def->driverType || def->cachemode ||
def->ioeventfd || def->event_idx) { def->ioeventfd || def->event_idx) {
...@@ -9071,6 +9100,8 @@ virDomainDiskDefFormat(virBufferPtr buf, ...@@ -9071,6 +9100,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAddLit(buf, " <readonly/>\n"); virBufferAddLit(buf, " <readonly/>\n");
if (def->shared) if (def->shared)
virBufferAddLit(buf, " <shareable/>\n"); virBufferAddLit(buf, " <shareable/>\n");
if (def->transient)
virBufferAddLit(buf, " <transient/>\n");
if (def->serial) if (def->serial)
virBufferEscapeString(buf, " <serial>%s</serial>\n", virBufferEscapeString(buf, " <serial>%s</serial>\n",
def->serial); def->serial);
......
...@@ -244,6 +244,15 @@ enum virDomainVirtioEventIdx { ...@@ -244,6 +244,15 @@ enum virDomainVirtioEventIdx {
VIR_DOMAIN_VIRTIO_EVENT_IDX_LAST 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 */ /* Stores the virtual disk configuration */
typedef struct _virDomainDiskDef virDomainDiskDef; typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr; typedef virDomainDiskDef *virDomainDiskDefPtr;
...@@ -265,8 +274,10 @@ struct _virDomainDiskDef { ...@@ -265,8 +274,10 @@ struct _virDomainDiskDef {
int iomode; int iomode;
int ioeventfd; int ioeventfd;
int event_idx; int event_idx;
int snapshot; /* enum virDomainDiskSnapshot */
unsigned int readonly : 1; unsigned int readonly : 1;
unsigned int shared : 1; unsigned int shared : 1;
unsigned int transient : 1;
virDomainDeviceInfo info; virDomainDeviceInfo info;
virStorageEncryptionPtr encryption; virStorageEncryptionPtr encryption;
}; };
...@@ -1779,6 +1790,7 @@ VIR_ENUM_DECL(virDomainDiskCache) ...@@ -1779,6 +1790,7 @@ VIR_ENUM_DECL(virDomainDiskCache)
VIR_ENUM_DECL(virDomainDiskErrorPolicy) VIR_ENUM_DECL(virDomainDiskErrorPolicy)
VIR_ENUM_DECL(virDomainDiskProtocol) VIR_ENUM_DECL(virDomainDiskProtocol)
VIR_ENUM_DECL(virDomainDiskIo) VIR_ENUM_DECL(virDomainDiskIo)
VIR_ENUM_DECL(virDomainDiskSnapshot)
VIR_ENUM_DECL(virDomainIoEventFd) VIR_ENUM_DECL(virDomainIoEventFd)
VIR_ENUM_DECL(virDomainVirtioEventIdx) VIR_ENUM_DECL(virDomainVirtioEventIdx)
VIR_ENUM_DECL(virDomainController) VIR_ENUM_DECL(virDomainController)
......
...@@ -289,6 +289,8 @@ virDomainDiskIoTypeFromString; ...@@ -289,6 +289,8 @@ virDomainDiskIoTypeFromString;
virDomainDiskIoTypeToString; virDomainDiskIoTypeToString;
virDomainDiskRemove; virDomainDiskRemove;
virDomainDiskRemoveByName; virDomainDiskRemoveByName;
virDomainDiskSnapshotTypeFromString;
virDomainDiskSnapshotTypeToString;
virDomainDiskTypeFromString; virDomainDiskTypeFromString;
virDomainDiskTypeToString; virDomainDiskTypeToString;
virDomainFSDefFree; virDomainFSDefFree;
......
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
<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>
<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>
...@@ -362,6 +362,8 @@ mymain(void) ...@@ -362,6 +362,8 @@ mymain(void)
DO_TEST("disk-ioeventfd", false, DO_TEST("disk-ioeventfd", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_VIRTIO_IOEVENTFD, QEMU_CAPS_DRIVE, QEMU_CAPS_VIRTIO_IOEVENTFD,
QEMU_CAPS_VIRTIO_TX_ALG, QEMU_CAPS_DEVICE); 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, DO_TEST("event_idx", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE,
QEMU_CAPS_VIRTIO_BLK_EVENT_IDX, QEMU_CAPS_VIRTIO_BLK_EVENT_IDX,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册