6ae9ed
From ff0dba475aad3bcad524391a7fddfede1e6fe189 Mon Sep 17 00:00:00 2001
6ae9ed
Message-Id: <ff0dba475aad3bcad524391a7fddfede1e6fe189@dist-git>
6ae9ed
From: John Ferlan <jferlan@redhat.com>
6ae9ed
Date: Mon, 25 Jul 2016 12:42:58 -0400
6ae9ed
Subject: [PATCH] qemu: Add secinfo for hotplug virtio disk
6ae9ed
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1301021
6ae9ed
6ae9ed
Commit id 'a1344f70a' added AES secret processing for RBD when starting
6ae9ed
up a guest. As such, when the hotplug code calls qemuDomainSecretDiskPrepare
6ae9ed
an AES secret could be added to the disk about to be hotplugged. If an AES
6ae9ed
secret was added, then the hotplug code would need to generate the secret
6ae9ed
object because qemuBuildDriveStr would add the "password-secret=" to the
6ae9ed
returned 'driveStr' rather than the base64 encoded password.
6ae9ed
6ae9ed
Signed-off-by: John Ferlan <jferlan@redhat.com>
6ae9ed
(cherry picked from commit fceeeda2115bcb86b992c4add38704a886c099c8)
6ae9ed
---
6ae9ed
 src/qemu/qemu_hotplug.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
6ae9ed
 1 file changed, 46 insertions(+)
6ae9ed
6ae9ed
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
6ae9ed
index b3fab6a..084443f 100644
6ae9ed
--- a/src/qemu/qemu_hotplug.c
6ae9ed
+++ b/src/qemu/qemu_hotplug.c
6ae9ed
@@ -303,6 +303,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
6ae9ed
                                  virDomainDiskDefPtr disk)
6ae9ed
 {
6ae9ed
     int ret = -1;
6ae9ed
+    int rv;
6ae9ed
     qemuDomainObjPrivatePtr priv = vm->privateData;
6ae9ed
     virErrorPtr orig_err;
6ae9ed
     char *devstr = NULL;
6ae9ed
@@ -310,8 +311,12 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
6ae9ed
     char *drivealias = NULL;
6ae9ed
     bool releaseaddr = false;
6ae9ed
     bool driveAdded = false;
6ae9ed
+    bool secobjAdded = false;
6ae9ed
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
6ae9ed
     const char *src = virDomainDiskGetSource(disk);
6ae9ed
+    virJSONValuePtr secobjProps = NULL;
6ae9ed
+    qemuDomainDiskPrivatePtr diskPriv;
6ae9ed
+    qemuDomainSecretInfoPtr secinfo;
6ae9ed
 
6ae9ed
     if (!disk->info.type) {
6ae9ed
         if (qemuDomainMachineIsS390CCW(vm->def) &&
6ae9ed
@@ -344,6 +349,13 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
6ae9ed
     if (qemuDomainSecretDiskPrepare(conn, priv, disk) < 0)
6ae9ed
         goto error;
6ae9ed
 
6ae9ed
+    diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
6ae9ed
+    secinfo = diskPriv->secinfo;
6ae9ed
+    if (secinfo && secinfo->type == VIR_DOMAIN_SECRET_INFO_TYPE_AES) {
6ae9ed
+        if (qemuBuildSecretInfoProps(secinfo, &secobjProps) < 0)
6ae9ed
+            goto error;
6ae9ed
+    }
6ae9ed
+
6ae9ed
     if (!(drivestr = qemuBuildDriveStr(disk, false, priv->qemuCaps)))
6ae9ed
         goto error;
6ae9ed
 
6ae9ed
@@ -358,6 +370,15 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
6ae9ed
 
6ae9ed
     qemuDomainObjEnterMonitor(driver, vm);
6ae9ed
 
6ae9ed
+    if (secobjProps) {
6ae9ed
+        rv = qemuMonitorAddObject(priv->mon, "secret", secinfo->s.aes.alias,
6ae9ed
+                                  secobjProps);
6ae9ed
+        secobjProps = NULL; /* qemuMonitorAddObject consumes */
6ae9ed
+        if (rv < 0)
6ae9ed
+            goto exit_monitor;
6ae9ed
+    }
6ae9ed
+    secobjAdded = true;
6ae9ed
+
6ae9ed
     if (qemuMonitorAddDrive(priv->mon, drivestr) < 0)
6ae9ed
         goto exit_monitor;
6ae9ed
     driveAdded = true;
6ae9ed
@@ -376,6 +397,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
6ae9ed
     ret = 0;
6ae9ed
 
6ae9ed
  cleanup:
6ae9ed
+    virJSONValueFree(secobjProps);
6ae9ed
     qemuDomainSecretDiskDestroy(disk);
6ae9ed
     VIR_FREE(devstr);
6ae9ed
     VIR_FREE(drivestr);
6ae9ed
@@ -389,10 +411,13 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
6ae9ed
         VIR_WARN("Unable to remove drive %s (%s) after failed "
6ae9ed
                  "qemuMonitorAddDevice", drivealias, drivestr);
6ae9ed
     }
6ae9ed
+    if (secobjAdded)
6ae9ed
+        ignore_value(qemuMonitorDelObject(priv->mon, secinfo->s.aes.alias));
6ae9ed
     if (orig_err) {
6ae9ed
         virSetError(orig_err);
6ae9ed
         virFreeError(orig_err);
6ae9ed
     }
6ae9ed
+
6ae9ed
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
6ae9ed
         releaseaddr = false;
6ae9ed
 
6ae9ed
@@ -2830,6 +2855,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
6ae9ed
     const char *src = virDomainDiskGetSource(disk);
6ae9ed
     qemuDomainObjPrivatePtr priv = vm->privateData;
6ae9ed
     char *drivestr;
6ae9ed
+    char *objAlias = NULL;
6ae9ed
 
6ae9ed
     VIR_DEBUG("Removing disk %s from domain %p %s",
6ae9ed
               disk->info.alias, vm, vm->def->name);
6ae9ed
@@ -2840,7 +2866,27 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
6ae9ed
                     QEMU_DRIVE_HOST_PREFIX, disk->info.alias) < 0)
6ae9ed
         return -1;
6ae9ed
 
6ae9ed
+    /* Let's look for some markers for a secret object and create an alias
6ae9ed
+     * object to be used to attempt to delete the object that was created.
6ae9ed
+     * We cannot just use the disk private secret info since it would have
6ae9ed
+     * been removed during cleanup of qemuProcessLaunch. Likewise, libvirtd
6ae9ed
+     * restart wouldn't have them, so no assumption can be made. */
6ae9ed
+    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_SECRET) &&
6ae9ed
+        qemuDomainSecretDiskCapable(disk->src)) {
6ae9ed
+
6ae9ed
+        if (!(objAlias = qemuDomainGetSecretAESAlias(disk->info.alias))) {
6ae9ed
+            VIR_FREE(drivestr);
6ae9ed
+            return -1;
6ae9ed
+        }
6ae9ed
+    }
6ae9ed
+
6ae9ed
     qemuDomainObjEnterMonitor(driver, vm);
6ae9ed
+
6ae9ed
+    /* If it fails, then so be it - it was a best shot */
6ae9ed
+    if (objAlias)
6ae9ed
+        ignore_value(qemuMonitorDelObject(priv->mon, objAlias));
6ae9ed
+    VIR_FREE(objAlias);
6ae9ed
+
6ae9ed
     qemuMonitorDriveDel(priv->mon, drivestr);
6ae9ed
     VIR_FREE(drivestr);
6ae9ed
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
6ae9ed
-- 
6ae9ed
2.9.2
6ae9ed