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: <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. --- 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 ++ 5 files changed, 100 insertions(+), 6 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index f46771d..911dee5 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -889,7 +889,7 @@ <pre> ... <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> ...</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 @@ -1032,11 +1052,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 diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 756e892..0af9e0f 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -617,6 +617,11 @@ </element> </optional> <optional> + <element name="transient"> + <empty/> + </element> + </optional> + <optional> <element name="serial"> <ref name="diskSerial"/> </element> @@ -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"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ade8a02..d2800d2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -187,6 +187,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", @@ -2073,6 +2079,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; @@ -2106,6 +2113,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) { @@ -2207,6 +2216,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 */ @@ -2278,6 +2289,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, @@ -2423,6 +2446,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, cleanup: VIR_FREE(bus); VIR_FREE(type); + VIR_FREE(snapshot); VIR_FREE(target); VIR_FREE(source); while (nhosts > 0) { @@ -2448,7 +2472,7 @@ cleanup: no_memory: virReportOOMError(); - error: +error: virDomainDiskDefFree(def); def = NULL; goto cleanup; @@ -8643,8 +8667,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) { @@ -8718,6 +8747,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); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 93bb7c8..7dbf353 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -217,6 +217,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; @@ -238,8 +247,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; }; @@ -1689,6 +1700,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 0d8aa99..6e313a9 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -286,6 +286,8 @@ virDomainDiskIoTypeFromString; virDomainDiskIoTypeToString; virDomainDiskRemove; virDomainDiskRemoveByName; +virDomainDiskSnapshotTypeFromString; +virDomainDiskSnapshotTypeToString; virDomainDiskTypeFromString; virDomainDiskTypeToString; virDomainFSDefFree; -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list