[libvirt] [PATCH v4 5/7] qemu: Add secinfo for hotplug virtio disk

Ján Tomko jtomko at redhat.com
Thu Jul 14 14:31:59 UTC 2016


On Mon, Jul 11, 2016 at 02:07:56PM -0400, John Ferlan wrote:
>Commit id 'a1344f70a' added AES secret processing for RBD when starting
>up a guest. As such, when the hotplug code calls qemuDomainSecretDiskPrepare
>an AES secret could be added to the disk about to be hotplugged. If an AES
>secret was added, then the hotplug code would need to generate the secret
>object because qemuBuildDriveStr would add the "password-secret=" to the
>returned 'driveStr' rather than the base64 encoded password.
>
>Signed-off-by: John Ferlan <jferlan at redhat.com>
>---
> src/qemu/qemu_hotplug.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 50 insertions(+), 3 deletions(-)
>
>diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
>index 093aaf9..004d6e3 100644
>--- a/src/qemu/qemu_hotplug.c
>+++ b/src/qemu/qemu_hotplug.c
>@@ -303,13 +303,16 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
> {
>     int ret = -1;
>     qemuDomainObjPrivatePtr priv = vm->privateData;
>-    virErrorPtr orig_err;
>+    virErrorPtr orig_err = NULL;
>     char *devstr = NULL;
>     char *drivestr = NULL;
>     char *drivealias = NULL;
>     bool releaseaddr = false;
>     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
>     const char *src = virDomainDiskGetSource(disk);
>+    virJSONValuePtr secobjProps = NULL;
>+    qemuDomainDiskPrivatePtr diskPriv;
>+    qemuDomainSecretInfoPtr secinfo;
>
>     if (!disk->info.type) {
>         if (qemuDomainMachineIsS390CCW(vm->def) &&
>@@ -342,6 +345,13 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>     if (qemuDomainSecretDiskPrepare(conn, priv, disk) < 0)
>         goto error;
>
>+    diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
>+    secinfo = diskPriv->secinfo;
>+    if (secinfo && secinfo->type == VIR_DOMAIN_SECRET_INFO_TYPE_AES) {
>+        if (qemuBuildSecretInfoProps(secinfo, &secobjProps) < 0)
>+            goto error;
>+    }
>+
>     if (!(drivestr = qemuBuildDriveStr(disk, false, priv->qemuCaps)))
>         goto error;
>
>@@ -354,9 +364,13 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>     if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
>         goto error;
>
>-    /* Attach the device - 2 step process */
>     qemuDomainObjEnterMonitor(driver, vm);
>
>+    if (secobjProps && qemuMonitorAddObject(priv->mon, "secret",
>+                                            secinfo->s.aes.alias,
>+                                            secobjProps) < 0)
>+        goto exit_monitor;
>+
>     if (qemuMonitorAddDrive(priv->mon, drivestr) < 0)
>         goto failadddrive;
>
>@@ -368,12 +382,18 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>         goto failexitmonitor;
>     }
>
>+    /* qemuMonitorAddObject consumes the props, but we need to wait
>+     * for successful exit from monitor to clear; otherwise, error
>+     * paths wouldn't clean up properly */
>+    secobjProps = NULL;
>+

I would rather set it to NULL right after the AddObject call and track
whether we need to remove the object in a separate variable.

This way when qemuDomainObjExitMonitor fails, we jump to 'failexitmonitor'
without setting it to NULL and free it again.

>     virDomainAuditDisk(vm, NULL, disk->src, "attach", true);
>
>     virDomainDiskInsertPreAlloced(vm->def, disk);
>     ret = 0;
>
>  cleanup:
>+    virJSONValueFree(secobjProps);
>     qemuDomainSecretDiskDestroy(disk);
>     VIR_FREE(devstr);
>     VIR_FREE(drivestr);
>@@ -387,14 +407,23 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>         VIR_WARN("Unable to remove drive %s (%s) after failed "
>                  "qemuMonitorAddDevice", drivealias, drivestr);
>     }
>+
>+ failadddrive:
>+    if (secobjProps) {

>+        if (!orig_err)
>+            orig_err = virSaveLastError();

This will need to be repeated on every label.
In hindsight, using a set of bools for rollback (like
qemuDomainAttachHostUSBDevice does) might have been more readable than
separate labels.

>+        ignore_value(qemuMonitorDelObject(priv->mon, secinfo->s.aes.alias));
>+    }
>+
>     if (orig_err) {
>         virSetError(orig_err);
>         virFreeError(orig_err);
>     }
>
>- failadddrive:
>+ exit_monitor:
>     if (qemuDomainObjExitMonitor(driver, vm) < 0)
>         releaseaddr = false;
>+    secobjProps = NULL; /* qemuMonitorAddObject consumes props on failure too */
>
>  failexitmonitor:
>     virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
>@@ -2808,6 +2837,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
>     const char *src = virDomainDiskGetSource(disk);
>     qemuDomainObjPrivatePtr priv = vm->privateData;
>     char *drivestr;
>+    char *objAlias = NULL;
>
>     VIR_DEBUG("Removing disk %s from domain %p %s",
>               disk->info.alias, vm, vm->def->name);
>@@ -2818,7 +2848,24 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
>                     QEMU_DRIVE_HOST_PREFIX, disk->info.alias) < 0)
>         return -1;
>
>+    /* Let's look for some markers for a secret object and create an alias
>+     * object to be used to attempt to delete the object that was created */
>+    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_SECRET) &&
>+        qemuDomainSecretDiskCapable(disk->src)) {
>+
>+        if (!(objAlias = qemuDomainGetSecretAESAlias(disk->info.alias))) {

Can't we access the disk private info here, to use the same conditions
as we did for adding it?

ACK with the double free fixed.

Jan




More information about the libvir-list mailing list