
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@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org