To start multiple KVM guests from one qcow2 image with transient disk option

Masayoshi Mizuma msys.mizuma at gmail.com
Sat Dec 12 01:58:48 UTC 2020


Hello,

I would like to start multiple KVM guests from one qcow2 image, and
discard the changes which the KVM guests done.

transient disk option is useful for discarding the changes, however,
we cannot start multiple KVM guest from one qcow2 image because the
image is write-locked by the first guest to be started.

I suppose the disk which transient option is enabled don't need to
get the write lock because any changes go to the overlay image, and
the overlay image is removed when the guest shutdown.

qemu has 'locking' option and the write lock is disabled when locking=off.
To implement that, I have two ideas. I would appreciate it if you could
give me the ideas which way is better (or another way).

1. Add an element to handle 'locking' qemu option. Like as:

    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' locking='off'/>
      <source file='/var/lib/libvirt/images/guest.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <transient/>
    </disk>

2. Add locking=off internally only if the transient disk option is enabled.
   The sample code is as follows:

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 23415b323c..6fafe22ca3 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -10186,6 +10186,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
             def->src->shared = true;
         } else if (virXMLNodeNameEqual(cur, "transient")) {
             def->transient = true;
+            def->src->transient = true;
         } else if (!encryption &&
                    virXMLNodeNameEqual(cur, "encryption")) {
             if (!(encryption = virStorageEncryptionParseNode(cur, ctxt)))
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 4640e339c0..3db888d08b 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -1211,6 +1211,12 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
                                       "s:discard", "unmap",
                                       NULL) < 0)
                 return NULL;
+
+            if (src->transient) {
+                if (virJSONValueObjectAdd(fileprops,
+                                          "S:locking", "off", NULL) < 0)
+                    return NULL;
+            }
         }
     }
 
diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 15494c3415..7823810df6 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -1182,7 +1182,8 @@ qemuSnapshotDiskPrepareDisksTransient(virDomainObjPtr vm,
         snapdisk->src = virStorageSourceNew();
         snapdisk->src->type = VIR_STORAGE_TYPE_FILE;
         snapdisk->src->format = VIR_STORAGE_FILE_QCOW2;
-        snapdisk->src->path = g_strdup_printf("%s.TRANSIENT", domdisk->src->path);
+        snapdisk->src->path = g_strdup_printf("%s.TRANSIENT-%s",
+                                              domdisk->src->path, vm->def->name);
 
         if (virFileExists(snapdisk->src->path)) {
             virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 87763cf389..70c963bd42 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -384,6 +384,8 @@ struct _virStorageSource {
     /* these must not be used apart from formatting the output JSON in the qemu driver */
     char *ssh_user;
     bool ssh_host_key_check_disabled;
+
+    bool transient;
 };
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageSource, virObjectUnref);
--

Thanks,
Masa




More information about the libvir-list mailing list