mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-26 15:45:28 +00:00
snapshot: refuse to generate names for non-regular backing files
For whatever reason, the kernel allows you to create a regular file named /dev/sdc.12345; although this file will disappear the next time devtmpfs is remounted. If you let libvirt generate the name of the external snapshot for a disk image originally using the block device /dev/sdc, then the domain will be rendered unbootable once the qcow2 file is lost on the next devtmpfs remount. In this case, the user should have used 'virsh snapshot-create --xmlfile' or 'virsh snapshot-create-as --diskspec' to specify the name for the qcow2 file in a sane location, rather than relying on libvirt generating a name that is most likely to be wrong. We can help avoid naive mistakes by enforcing that the user provide the external name for any backing file that is not a regular file. * src/conf/domain_conf.c (virDomainSnapshotAlignDisks): Only generate names if backing file exists as regular file. Reported by MATSUDA Daiki.
This commit is contained in:
parent
d47ab3fe61
commit
c74b97156f
@ -12203,7 +12203,8 @@ virDomainSnapshotAlignDisks(virDomainSnapshotDefPtr def,
|
|||||||
|
|
||||||
qsort(&def->disks[0], def->ndisks, sizeof(def->disks[0]), disksorter);
|
qsort(&def->disks[0], def->ndisks, sizeof(def->disks[0]), disksorter);
|
||||||
|
|
||||||
/* Generate any default external file names. */
|
/* Generate any default external file names, but only if the
|
||||||
|
* backing file is a regular file. */
|
||||||
for (i = 0; i < def->ndisks; i++) {
|
for (i = 0; i < def->ndisks; i++) {
|
||||||
virDomainSnapshotDiskDefPtr disk = &def->disks[i];
|
virDomainSnapshotDiskDefPtr disk = &def->disks[i];
|
||||||
|
|
||||||
@ -12211,14 +12212,24 @@ virDomainSnapshotAlignDisks(virDomainSnapshotDefPtr def,
|
|||||||
!disk->file) {
|
!disk->file) {
|
||||||
const char *original = def->dom->disks[i]->src;
|
const char *original = def->dom->disks[i]->src;
|
||||||
const char *tmp;
|
const char *tmp;
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
if (!original) {
|
if (!original) {
|
||||||
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
_("cannot generate external backup name "
|
_("cannot generate external snapshot name "
|
||||||
"for disk '%s' without source"),
|
"for disk '%s' without source"),
|
||||||
disk->name);
|
disk->name);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
if (stat(original, &sb) < 0 || !S_ISREG(sb.st_mode)) {
|
||||||
|
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("source for disk '%s' is not a regular "
|
||||||
|
"file; refusing to generate external "
|
||||||
|
"snapshot name"),
|
||||||
|
disk->name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
tmp = strrchr(original, '.');
|
tmp = strrchr(original, '.');
|
||||||
if (!tmp || strchr(tmp, '/')) {
|
if (!tmp || strchr(tmp, '/')) {
|
||||||
ignore_value(virAsprintf(&disk->file, "%s.%s",
|
ignore_value(virAsprintf(&disk->file, "%s.%s",
|
||||||
|
Loading…
Reference in New Issue
Block a user