On 08/19/2011 07:29 PM, Eric Blake wrote:
On 08/19/2011 03:58 PM, Eric Blake wrote:
> Adds an optional element to<domainsnapshot>, which will be used
> to give user control over external snapshot filenames on input,
> and specify generated filenames on output.
>
One more thing to squash in - make the auto-generation of names not
provided by the user be consistent across hypervisors, by stripping any
suffix after the last '.' and replacing it with the name of the snapshot.
diff --git i/docs/formatsnapshot.html.in w/docs/formatsnapshot.html.in
index e476c8f..e1a43e7 100644
--- i/docs/formatsnapshot.html.in
+++ w/docs/formatsnapshot.html.in
@@ -129,7 +129,10 @@
optional sub-element <code>driver</code>, with an
attribute <code>type</code> giving the driver type (such
as qcow2), of the new file created by the external
- snapshot of the new file. Remember that with external
+ snapshot of the new file. If <code>source</code> is not
+ given, a file name is generated that consists of the
+ existing file name with anything after the trailing dot
+ replaced by the snapshot name. Remember that with external
snapshots, the original file name becomes the read-only
snapshot, and the new file name contains the read-write
delta of all disk changes since the snapshot.
diff --git i/src/conf/domain_conf.c w/src/conf/domain_conf.c
index e1f71a6..c9daebb 100644
--- i/src/conf/domain_conf.c
+++ w/src/conf/domain_conf.c
@@ -11347,6 +11347,43 @@
virDomainSnapshotAlignDisks(virDomainSnapshotDefPtr def,
qsort(&def->disks[0], def->ndisks, sizeof(def->disks[0]), disksorter);
+ /* Generate any default external file names. */
+ for (i = 0; i < def->ndisks; i++) {
+ virDomainSnapshotDiskDefPtr disk = &def->disks[i];
+
+ if (disk->snapshot == VIR_DOMAIN_DISK_SNAPSHOT_EXTERNAL &&
+ !disk->file) {
+ const char *original = def->dom->disks[i]->src;
+ const char *tmp;
+
+ if (!original) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("cannot generate external backup
name "
+ "for disk '%s' without
source"),
+ disk->name);
+ goto cleanup;
+ }
+ tmp = strrchr(original, '.');
+ if (!tmp || strchr(tmp, '/')) {
+ ignore_value(virAsprintf(&disk->file, "%s.%s",
+ original, def->name));
+ } else {
+ if ((tmp - original) > INT_MAX) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("integer overflow"));
+ goto cleanup;
+ }
+ ignore_value(virAsprintf(&disk->file, "%*s%s",
+ (int) (tmp - original), original,
+ def->name));
+ }
+ if (!disk->file) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+ }
+
ret = 0;
cleanup:
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library
http://libvirt.org