]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: domain: Regenerate auth/enc secret aliases when restoring status XML
authorPeter Krempa <pkrempa@redhat.com>
Thu, 24 May 2018 16:24:13 +0000 (18:24 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 5 Jun 2018 06:13:57 +0000 (08:13 +0200)
Previously we did not store the aliases but rather re-generated them
when unplug was necessary. This is very cumbersome since the knowledge
when and which alias to use needs to be stored in the hotplug code as
well.

While this patch will not strictly improve this situation since there
still will be two places containing this code it at least will allow to
remove the mess from the disk-unplug code and will prevent introducing
more mess when adding blockdev support.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_domain.c
tests/qemustatusxml2xmldata/disk-secinfo-upgrade-out.xml

index dacf2b802a99a8b1ccc0353b63f45f4eb945e92a..0b50935938cb82c74a1b0f8081e8b4efcf04c3d0 100644 (file)
@@ -5856,8 +5856,91 @@ qemuDomainChrDefPostParse(virDomainChrDefPtr chr,
 }
 
 
+/**
+ * qemuDomainDeviceDiskDefPostParseRestoreSecAlias:
+ *
+ * Re-generate aliases for objects related to the storage source if they
+ * were not stored in the status XML by an older libvirt.
+ *
+ * Note that qemuCaps should be always present for a status XML.
+ */
+static int
+qemuDomainDeviceDiskDefPostParseRestoreSecAlias(virDomainDiskDefPtr disk,
+                                                virQEMUCapsPtr qemuCaps,
+                                                unsigned int parseFlags)
+{
+    qemuDomainStorageSourcePrivatePtr priv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(disk->src);
+    bool restoreAuthSecret = false;
+    bool restoreEncSecret = false;
+    char *authalias = NULL;
+    char *encalias = NULL;
+    int ret = -1;
+
+    if (!(parseFlags & VIR_DOMAIN_DEF_PARSE_STATUS) ||
+        !qemuCaps ||
+        virStorageSourceIsEmpty(disk->src) ||
+        !virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_SECRET))
+        return 0;
+
+    /* network storage authentication secret */
+    if (disk->src->auth &&
+        (!priv || !priv->secinfo)) {
+
+        /* only RBD and iSCSI (with capability) were supporting authentication
+         * using secret object at the time we did not format the alias into the
+         * status XML */
+        if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_NETWORK &&
+            (disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_RBD ||
+             (disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_ISCSI &&
+              virQEMUCapsGet(qemuCaps, QEMU_CAPS_ISCSI_PASSWORD_SECRET))))
+            restoreAuthSecret = true;
+    }
+
+    /* disk encryption secret */
+    if (disk->src->encryption &&
+        disk->src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS &&
+        (!priv || !priv->encinfo))
+        restoreEncSecret = true;
+
+    if (!restoreAuthSecret && !restoreEncSecret)
+        return 0;
+
+    if (!priv) {
+        if (!(disk->src->privateData = qemuDomainStorageSourcePrivateNew()))
+            return -1;
+
+        priv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(disk->src);
+    }
+
+    if (restoreAuthSecret) {
+        if (!(authalias = qemuDomainGetSecretAESAlias(disk->info.alias, false)))
+            goto cleanup;
+
+        if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->secinfo, &authalias) < 0)
+            goto cleanup;
+    }
+
+    if (restoreEncSecret) {
+        if (!(encalias = qemuDomainGetSecretAESAlias(disk->info.alias, true)))
+            goto cleanup;
+
+        if (qemuStorageSourcePrivateDataAssignSecinfo(&priv->encinfo, &encalias) < 0)
+            goto cleanup;
+    }
+
+    ret = 0;
+
+ cleanup:
+    VIR_FREE(authalias);
+    VIR_FREE(encalias);
+    return ret;
+}
+
+
 static int
 qemuDomainDeviceDiskDefPostParse(virDomainDiskDefPtr disk,
+                                 virQEMUCapsPtr qemuCaps,
+                                 unsigned int parseFlags,
                                  virQEMUDriverConfigPtr cfg)
 {
     /* set default disk types and drivers */
@@ -5891,6 +5974,10 @@ qemuDomainDeviceDiskDefPostParse(virDomainDiskDefPtr disk,
             disk->mirror->format = VIR_STORAGE_FILE_RAW;
     }
 
+    if (qemuDomainDeviceDiskDefPostParseRestoreSecAlias(disk, qemuCaps,
+                                                        parseFlags) < 0)
+        return -1;
+
     return 0;
 }
 
@@ -5982,7 +6069,8 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
         break;
 
     case VIR_DOMAIN_DEVICE_DISK:
-        ret = qemuDomainDeviceDiskDefPostParse(dev->data.disk, cfg);
+        ret = qemuDomainDeviceDiskDefPostParse(dev->data.disk, qemuCaps,
+                                               parseFlags, cfg);
         break;
 
     case VIR_DOMAIN_DEVICE_VIDEO:
index d364fc7644bbd935ec1955249a46ffab42c555bf..a554bca99c48cadb2f10c3135bedf9f0d40aabb9 100644 (file)
           <encryption format='luks'>
             <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/>
           </encryption>
+          <privateData>
+            <objects>
+              <secret type='encryption' alias='virtio-disk1-luks-secret0'/>
+            </objects>
+          </privateData>
         </source>
         <backingStore/>
         <target dev='vdb' bus='virtio'/>
           <encryption format='luks'>
             <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/>
           </encryption>
+          <privateData>
+            <objects>
+              <secret type='auth' alias='virtio-disk3-secret0'/>
+              <secret type='encryption' alias='virtio-disk3-luks-secret0'/>
+            </objects>
+          </privateData>
         </source>
         <backingStore/>
         <target dev='vdd' bus='virtio'/>
           <auth username='testuser-rbd'>
             <secret type='ceph' usage='testuser-rbd-secret'/>
           </auth>
+          <privateData>
+            <objects>
+              <secret type='auth' alias='virtio-disk5-secret0'/>
+            </objects>
+          </privateData>
         </source>
         <backingStore/>
         <target dev='vdf' bus='virtio'/>