[libvirt] [PATCH v7 11/11] qemu: Add TLS support for Veritas HyperScale (VxHS)

John Ferlan posted 11 patches 8 years, 3 months ago
There is a newer version of this series
[libvirt] [PATCH v7 11/11] qemu: Add TLS support for Veritas HyperScale (VxHS)
Posted by John Ferlan 8 years, 3 months ago
From: Ashish Mittal <Ashish.Mittal@veritas.com>

Alter qemu command line generation in order to possibly add TLS for
a suitably configured domain.

Sample TLS args generated by libvirt -

    -object tls-creds-x509,id=objvirtio-disk0_tls0,dir=/etc/pki/qemu,\
    endpoint=client,verify-peer=yes \
    -drive file.driver=vxhs,file.tls-creds=objvirtio-disk0_tls0,\
    file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc251,\
    file.server.0.type=tcp,file.server.0.host=192.168.0.1,\
    file.server.0.port=9999,format=raw,if=none,\
    id=drive-virtio-disk0,cache=none \
    -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
    id=virtio-disk0

Update the qemuxml2argvtest with a couple of examples. One for a
simple case and the other a bit more complex where multiple VxHS disks
are added where at least one uses a VxHS that doesn't require TLS
credentials and thus sets the domain disk source attribute "tls = 'no'".

Update the hotplug to be able to handle processing the tlsAlias whether
it's to add the TLS object when hotplugging a disk or to remove the TLS
object when hot unplugging a disk.  The hot plug/unplug code is largely
generic, but the addition code does make the VXHS specific checks only
because it needs to grab the correct config directory and generate the
object as the command line would do.

Signed-off-by: Ashish Mittal <Ashish.Mittal@veritas.com>
Signed-off-by: John Ferlan <jferlan@redhat.com>
---
 src/qemu/qemu_block.c                              |  8 +++
 src/qemu/qemu_command.c                            | 29 +++++++++
 src/qemu/qemu_hotplug.c                            | 73 ++++++++++++++++++++++
 ...-disk-drive-network-tlsx509-multidisk-vxhs.args | 43 +++++++++++++
 ...v-disk-drive-network-tlsx509-multidisk-vxhs.xml | 50 +++++++++++++++
 ...muxml2argv-disk-drive-network-tlsx509-vxhs.args | 30 +++++++++
 tests/qemuxml2argvtest.c                           |  7 +++
 7 files changed, 240 insertions(+)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.xml
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args

diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index f5269fb..be4e8fa 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -495,16 +495,24 @@ qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src)
         return NULL;
     }
 
+    if (src->haveTLS == VIR_TRISTATE_BOOL_YES && !src->tlsAlias) {
+        virReportError(VIR_ERR_INVALID_ARG, "%s",
+                       _("VxHS disk does not have TLS alias set"));
+        return NULL;
+    }
+
     if (!(server = qemuBlockStorageSourceBuildHostsJSONSocketAddress(src, true)))
         return NULL;
 
     /* VxHS disk specification example:
      * { driver:"vxhs",
+     *   [tls-creds:"objvirtio-disk0_tls0",]
      *   vdisk-id:"eb90327c-8302-4725-4e85ed4dc251",
      *   server:[{type:"tcp", host:"1.2.3.4", port:9999}]}
      */
     if (virJSONValueObjectCreate(&ret,
                                  "s:driver", protocol,
+                                 "S:tls-creds", src->tlsAlias,
                                  "s:vdisk-id", src->path,
                                  "a:server", server, NULL) < 0)
         virJSONValueFree(server);
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index b9e2ab3..d6b04a3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -791,6 +791,32 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd,
 }
 
 
+/* qemuBuildDiskTLSx509CommandLine:
+ *
+ * Add TLS object if the disk uses a secure communication channel
+ *
+ * Returns 0 on success, -1 w/ error on some sort of failure.
+ */
+static int
+qemuBuildDiskTLSx509CommandLine(virCommandPtr cmd,
+                                virQEMUDriverConfigPtr cfg,
+                                virDomainDiskDefPtr disk,
+                                virQEMUCapsPtr qemuCaps)
+{
+    virStorageSourcePtr src = disk->src;
+
+    /* other protocols may be added later */
+    if (src->protocol == VIR_STORAGE_NET_PROTOCOL_VXHS &&
+        disk->src->haveTLS == VIR_TRISTATE_BOOL_YES) {
+        return qemuBuildTLSx509CommandLine(cmd, cfg->vxhsTLSx509certdir,
+                                          false, true, false,
+                                          disk->info.alias, qemuCaps);
+    }
+
+    return 0;
+}
+
+
 static char *
 qemuBuildNetworkDriveURI(virStorageSourcePtr src,
                          qemuDomainSecretInfoPtr secinfo)
@@ -2218,6 +2244,9 @@ qemuBuildDiskDriveCommandLine(virCommandPtr cmd,
         if (qemuBuildDiskSecinfoCommandLine(cmd, encinfo) < 0)
             return -1;
 
+        if (qemuBuildDiskTLSx509CommandLine(cmd, cfg, disk, qemuCaps) < 0)
+            return -1;
+
         virCommandAddArg(cmd, "-drive");
 
         if (!(optstr = qemuBuildDriveStr(disk, cfg, driveBoot, qemuCaps)))
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 9611df5..4c1074d 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -152,6 +152,55 @@ qemuDomainPrepareDisk(virQEMUDriverPtr driver,
 
 
 static int
+qemuDomainAddDiskTLSObject(virQEMUDriverPtr driver,
+                           virDomainObjPtr vm,
+                           virDomainDiskDefPtr disk,
+                           char **tlsAlias)
+{
+    int ret = -1;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virStorageSourcePtr src = disk->src;
+    virJSONValuePtr tlsProps = NULL;
+
+    /* NB: This may alter haveTLS based on cfg */
+    qemuDomainPrepareDiskSourceTLS(src, disk->info.alias, cfg);
+
+    if (src->haveTLS != VIR_TRISTATE_BOOL_YES) {
+        ret = 0;
+        goto cleanup;
+    }
+
+    /* Initial implementation doesn't require/use a secret to decrypt
+     * a server certificate, so there's no need to manage a tlsSecAlias
+     * and tlsSecProps. See qemuDomainAddChardevTLSObjects for the
+     * methodology required to add a secret object. */
+
+    /* For a VxHS environment, create a TLS object for the client to
+     * connect to the VxHS server. */
+    if (src->type == VIR_STORAGE_TYPE_NETWORK &&
+        src->protocol == VIR_STORAGE_NET_PROTOCOL_VXHS &&
+        qemuDomainGetTLSObjects(priv->qemuCaps, NULL,
+                                cfg->vxhsTLSx509certdir, false, true,
+                                disk->info.alias, &tlsProps, tlsAlias,
+                                NULL, NULL) < 0)
+        goto cleanup;
+
+    if (qemuDomainAddTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE,
+                                NULL, NULL, *tlsAlias, &tlsProps) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    virJSONValueFree(tlsProps);
+    virObjectUnref(cfg);
+
+    return ret;
+}
+
+
+static int
 qemuHotplugWaitForTrayEject(virQEMUDriverPtr driver,
                             virDomainObjPtr vm,
                             virDomainDiskDefPtr disk,
@@ -315,6 +364,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
     char *devstr = NULL;
     char *drivestr = NULL;
     char *drivealias = NULL;
+    char *tlsAlias = NULL;
     bool releaseaddr = false;
     bool driveAdded = false;
     bool secobjAdded = false;
@@ -372,6 +422,9 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
     if (encinfo && qemuBuildSecretInfoProps(encinfo, &encobjProps) < 0)
         goto error;
 
+    if (qemuDomainAddDiskTLSObject(driver, vm, disk, &tlsAlias) < 0)
+        goto error;
+
     if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
         goto error;
 
@@ -422,6 +475,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
     ret = 0;
 
  cleanup:
+    VIR_FREE(tlsAlias);
     virJSONValueFree(secobjProps);
     virJSONValueFree(encobjProps);
     qemuDomainSecretDiskDestroy(disk);
@@ -453,6 +507,8 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
     virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
 
  error:
+    qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, NULL, tlsAlias);
+
     if (releaseaddr)
         qemuDomainReleaseDeviceAddress(vm, &disk->info, src);
 
@@ -611,6 +667,7 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
     virErrorPtr orig_err;
     char *drivestr = NULL;
     char *devstr = NULL;
+    char *tlsAlias = NULL;
     bool driveAdded = false;
     bool encobjAdded = false;
     bool secobjAdded = false;
@@ -667,6 +724,9 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
     if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
         goto error;
 
+    if (qemuDomainAddDiskTLSObject(driver, vm, disk, &tlsAlias) < 0)
+        goto error;
+
     if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
         goto error;
 
@@ -712,6 +772,7 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
     ret = 0;
 
  cleanup:
+    VIR_FREE(tlsAlias);
     virJSONValueFree(secobjProps);
     virJSONValueFree(encobjProps);
     qemuDomainSecretDiskDestroy(disk);
@@ -740,6 +801,8 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
     virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
 
  error:
+    qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, NULL, tlsAlias);
+
     ignore_value(qemuDomainPrepareDisk(driver, vm, disk, NULL, true));
     goto cleanup;
 }
@@ -756,6 +819,7 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver,
     char *drivealias = NULL;
     char *drivestr = NULL;
     char *devstr = NULL;
+    char *tlsAlias = NULL;
     bool driveAdded = false;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     const char *src = virDomainDiskGetSource(disk);
@@ -780,6 +844,9 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver,
     if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
         goto error;
 
+    if (qemuDomainAddDiskTLSObject(driver, vm, disk, &tlsAlias) < 0)
+        goto error;
+
     if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
         goto error;
 
@@ -810,6 +877,7 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver,
     ret = 0;
 
  cleanup:
+    VIR_FREE(tlsAlias);
     if (ret < 0 && releaseaddr)
         virDomainUSBAddressRelease(priv->usbaddrs, &disk->info);
     VIR_FREE(devstr);
@@ -833,6 +901,8 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver,
     virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
 
  error:
+    qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, NULL, tlsAlias);
+
     ignore_value(qemuDomainPrepareDisk(driver, vm, disk, NULL, true));
     goto cleanup;
 }
@@ -3710,6 +3780,9 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
         ignore_value(qemuMonitorDelObject(priv->mon, encAlias));
     VIR_FREE(encAlias);
 
+    if (disk->src->tlsAlias)
+        ignore_value(qemuMonitorDelObject(priv->mon, disk->src->tlsAlias));
+
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         return -1;
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.args
new file mode 100644
index 0000000..dceae52
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.args
@@ -0,0 +1,43 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name QEMUGuest1 \
+-S \
+-M pc \
+-cpu qemu32 \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline \
+-no-acpi \
+-boot c \
+-usb \
+-object tls-creds-x509,id=objvirtio-disk0_tls0,dir=/etc/pki/qemu,\
+endpoint=client,verify-peer=yes \
+-drive file.driver=vxhs,file.tls-creds=objvirtio-disk0_tls0,\
+file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc251,file.server.0.type=tcp,\
+file.server.0.host=192.168.0.1,file.server.0.port=9999,format=raw,if=none,\
+id=drive-virtio-disk0,cache=none \
+-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
+id=virtio-disk0 \
+-object tls-creds-x509,id=objvirtio-disk1_tls0,dir=/etc/pki/qemu,\
+endpoint=client,verify-peer=yes \
+-drive file.driver=vxhs,file.tls-creds=objvirtio-disk1_tls0,\
+file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc252,file.server.0.type=tcp,\
+file.server.0.host=192.168.0.2,file.server.0.port=9999,format=raw,if=none,\
+id=drive-virtio-disk1,cache=none \
+-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk1,\
+id=virtio-disk1 \
+-drive file.driver=vxhs,file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc253,\
+file.server.0.type=tcp,file.server.0.host=192.168.0.3,file.server.0.port=9999,\
+format=raw,if=none,id=drive-virtio-disk2,cache=none \
+-device virtio-blk-pci,bus=pci.0,addr=0x6,drive=drive-virtio-disk2,\
+id=virtio-disk2
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.xml
new file mode 100644
index 0000000..a66e81f
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.xml
@@ -0,0 +1,50 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <disk type='network' device='disk'>
+      <driver name='qemu' type='raw' cache='none'/>
+      <source protocol='vxhs' name='eb90327c-8302-4725-9e1b-4e85ed4dc251'>
+        <host name='192.168.0.1' port='9999'/>
+      </source>
+      <target dev='vda' bus='virtio'/>
+      <serial>eb90327c-8302-4725-9e1b-4e85ed4dc251</serial>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+    </disk>
+    <disk type='network' device='disk'>
+      <driver name='qemu' type='raw' cache='none'/>
+      <source protocol='vxhs' name='eb90327c-8302-4725-9e1b-4e85ed4dc252'>
+        <host name='192.168.0.2' port='9999'/>
+      </source>
+      <target dev='vdb' bus='virtio'/>
+      <serial>eb90327c-8302-4725-9e1b-4e85ed4dc252</serial>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+    </disk>
+    <disk type='network' device='disk'>
+      <driver name='qemu' type='raw' cache='none'/>
+      <source protocol='vxhs' name='eb90327c-8302-4725-9e1b-4e85ed4dc253' tls='no'>
+        <host name='192.168.0.3' port='9999'/>
+      </source>
+      <target dev='vdc' bus='virtio'/>
+      <serial>eb90327c-8302-4725-9e1b-4e85ed4dc252</serial>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args
new file mode 100644
index 0000000..5308a16
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args
@@ -0,0 +1,30 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name QEMUGuest1 \
+-S \
+-M pc \
+-cpu qemu32 \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-nographic \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline \
+-no-acpi \
+-boot c \
+-usb \
+-object tls-creds-x509,id=objvirtio-disk0_tls0,dir=/etc/pki/qemu,\
+endpoint=client,verify-peer=yes \
+-drive file.driver=vxhs,file.tls-creds=objvirtio-disk0_tls0,\
+file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc251,file.server.0.type=tcp,\
+file.server.0.host=192.168.0.1,file.server.0.port=9999,format=raw,if=none,\
+id=drive-virtio-disk0,cache=none \
+-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
+id=virtio-disk0
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index b92ded8..0366dc3 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -932,6 +932,13 @@ mymain(void)
     DO_TEST("disk-drive-network-rbd-ipv6", NONE);
     DO_TEST_FAILURE("disk-drive-network-rbd-no-colon", NONE);
     DO_TEST("disk-drive-network-vxhs", QEMU_CAPS_VXHS);
+    driver.config->vxhsTLS = 1;
+    DO_TEST("disk-drive-network-tlsx509-vxhs", QEMU_CAPS_VXHS,
+            QEMU_CAPS_OBJECT_TLS_CREDS_X509);
+    DO_TEST("disk-drive-network-tlsx509-multidisk-vxhs", QEMU_CAPS_VXHS,
+            QEMU_CAPS_OBJECT_TLS_CREDS_X509);
+    driver.config->vxhsTLS = 0;
+    VIR_FREE(driver.config->vxhsTLSx509certdir);
     DO_TEST("disk-drive-no-boot",
             QEMU_CAPS_BOOTINDEX);
     DO_TEST_PARSE_ERROR("disk-device-lun-type-invalid",
-- 
2.9.5

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v7 11/11] qemu: Add TLS support for Veritas HyperScale (VxHS)
Posted by ashish mittal 8 years, 2 months ago
Hi,

Not sure how to reply to the v8 series email thread, or how to add myself
to the libvirt email list! Updating the v7 thread instead.

I have already updated with the results of TLS testing by statically adding
TLS enabled VxHS devices to domain XML, booting up the guest, and making
sure devices are properly readable/writable.

I did the same test using hot plug. libvirtd crashes when adding TLS device
-

[root@audi Sources] 2017-09-18 19:54:27# virsh attach-device myfc24
hotplug_disk_2.xml
error: Disconnected from qemu:///system due to end of file
error: Failed to attach device from hotplug_disk_2.xml
error: End of file while reading data: Input/output error

gdb reports -

Thread 3 "libvirtd" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7f97e6b99700 (LWP 20096)]
0x00007f97c9c42a3d in qemuDomainGetTLSObjects (qemuCaps=0x7f97c00fcca0,
secinfo=secinfo@entry=0x0, tlsCertdir=0x7f97c00ff000
"/etc/pki/libvirt-vxhs",
    tlsListen=tlsListen@entry=false, tlsVerify=tlsVerify@entry=true,
srcAlias=0x7f97b8001e00 "virtio-disk0", tlsProps=0x7f97e6b988f0,
tlsAlias=0x7f97e6b98998, secProps=0x0,
    secAlias=0x0) at qemu/qemu_hotplug.c:1736
1736    }


Reason for crash seems to be a latent issue with qemuDomainGetTLSObjects().
Both qemuDomainGetTLSObjects() and qemuBuildTLSx509BackendProps() suggest
that char **secAlias may be NULL, but qemuDomainGetTLSObjects()
dereferences it without checking for NULL.

int
qemuDomainGetTLSObjects(virQEMUCapsPtr qemuCaps,
                        qemuDomainSecretInfoPtr secinfo,
                        const char *tlsCertdir,
                        bool tlsListen,
                        bool tlsVerify,
                        const char *srcAlias,
                        virJSONValuePtr *tlsProps,
                        char **tlsAlias,
                        virJSONValuePtr *secProps,
                        char **secAlias)
{
    /* Add a secret object in order to access the TLS environment.
     * The secinfo will only be created for serial TCP device. */
    if (secinfo) {
        if (qemuBuildSecretInfoProps(secinfo, secProps) < 0)
            return -1;

        if (!(*secAlias = qemuDomainGetSecretAESAlias(srcAlias, false)))
            return -1;
    }

    if (qemuBuildTLSx509BackendProps(tlsCertdir, tlsListen, tlsVerify,
                                     *secAlias, qemuCaps, tlsProps) < 0)
<=== *secAlias is dereferencing char **secAlias, which can be NULL
        return -1;
...
}


The following diff takes care of the above issue.

[root@audi libvirt] 2017-09-18 23:19:31# git diff
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 4c1074d..1448fe7 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1715,6 +1715,8 @@ qemuDomainGetTLSObjects(virQEMUCapsPtr qemuCaps,
                         virJSONValuePtr *secProps,
                         char **secAlias)
 {
+    char *secretAlias = NULL;
+
     /* Add a secret object in order to access the TLS environment.
      * The secinfo will only be created for serial TCP device. */
     if (secinfo) {
@@ -1723,10 +1725,11 @@ qemuDomainGetTLSObjects(virQEMUCapsPtr qemuCaps,

         if (!(*secAlias = qemuDomainGetSecretAESAlias(srcAlias, false)))
             return -1;
+        secretAlias = *secAlias;
     }

     if (qemuBuildTLSx509BackendProps(tlsCertdir, tlsListen, tlsVerify,
-                                     *secAlias, qemuCaps, tlsProps) < 0)
+                                     secretAlias, qemuCaps, tlsProps) < 0)
         return -1;

     if (!(*tlsAlias = qemuAliasTLSObjFromSrcAlias(srcAlias)))

I was able to attach and detach two TLS enabled VxHS disks to a running
guest multiple times with the above fix in place. Did a attach/detach of
these disks back-to-back without any problems. Was able to format these
disks and copy files to both these TLS hot plugged disks from within the
guest without any problems. Will send detailed test logs in a separate
email.


Regards,
Ashish


On Fri, Sep 1, 2017 at 10:09 AM, John Ferlan <jferlan@redhat.com> wrote:

> From: Ashish Mittal <Ashish.Mittal@veritas.com>
>
> Alter qemu command line generation in order to possibly add TLS for
> a suitably configured domain.
>
> Sample TLS args generated by libvirt -
>
>     -object tls-creds-x509,id=objvirtio-disk0_tls0,dir=/etc/pki/qemu,\
>     endpoint=client,verify-peer=yes \
>     -drive file.driver=vxhs,file.tls-creds=objvirtio-disk0_tls0,\
>     file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc251,\
>     file.server.0.type=tcp,file.server.0.host=192.168.0.1,\
>     file.server.0.port=9999,format=raw,if=none,\
>     id=drive-virtio-disk0,cache=none \
>     -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
>     id=virtio-disk0
>
> Update the qemuxml2argvtest with a couple of examples. One for a
> simple case and the other a bit more complex where multiple VxHS disks
> are added where at least one uses a VxHS that doesn't require TLS
> credentials and thus sets the domain disk source attribute "tls = 'no'".
>
> Update the hotplug to be able to handle processing the tlsAlias whether
> it's to add the TLS object when hotplugging a disk or to remove the TLS
> object when hot unplugging a disk.  The hot plug/unplug code is largely
> generic, but the addition code does make the VXHS specific checks only
> because it needs to grab the correct config directory and generate the
> object as the command line would do.
>
> Signed-off-by: Ashish Mittal <Ashish.Mittal@veritas.com>
> Signed-off-by: John Ferlan <jferlan@redhat.com>
> ---
>  src/qemu/qemu_block.c                              |  8 +++
>  src/qemu/qemu_command.c                            | 29 +++++++++
>  src/qemu/qemu_hotplug.c                            | 73
> ++++++++++++++++++++++
>  ...-disk-drive-network-tlsx509-multidisk-vxhs.args | 43 +++++++++++++
>  ...v-disk-drive-network-tlsx509-multidisk-vxhs.xml | 50 +++++++++++++++
>  ...muxml2argv-disk-drive-network-tlsx509-vxhs.args | 30 +++++++++
>  tests/qemuxml2argvtest.c                           |  7 +++
>  7 files changed, 240 insertions(+)
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.args
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.xml
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-vxhs.args
>
> diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
> index f5269fb..be4e8fa 100644
> --- a/src/qemu/qemu_block.c
> +++ b/src/qemu/qemu_block.c
> @@ -495,16 +495,24 @@ qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr
> src)
>          return NULL;
>      }
>
> +    if (src->haveTLS == VIR_TRISTATE_BOOL_YES && !src->tlsAlias) {
> +        virReportError(VIR_ERR_INVALID_ARG, "%s",
> +                       _("VxHS disk does not have TLS alias set"));
> +        return NULL;
> +    }
> +
>      if (!(server = qemuBlockStorageSourceBuildHostsJSONSocketAddress(src,
> true)))
>          return NULL;
>
>      /* VxHS disk specification example:
>       * { driver:"vxhs",
> +     *   [tls-creds:"objvirtio-disk0_tls0",]
>       *   vdisk-id:"eb90327c-8302-4725-4e85ed4dc251",
>       *   server:[{type:"tcp", host:"1.2.3.4", port:9999}]}
>       */
>      if (virJSONValueObjectCreate(&ret,
>                                   "s:driver", protocol,
> +                                 "S:tls-creds", src->tlsAlias,
>                                   "s:vdisk-id", src->path,
>                                   "a:server", server, NULL) < 0)
>          virJSONValueFree(server);
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index b9e2ab3..d6b04a3 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -791,6 +791,32 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd,
>  }
>
>
> +/* qemuBuildDiskTLSx509CommandLine:
> + *
> + * Add TLS object if the disk uses a secure communication channel
> + *
> + * Returns 0 on success, -1 w/ error on some sort of failure.
> + */
> +static int
> +qemuBuildDiskTLSx509CommandLine(virCommandPtr cmd,
> +                                virQEMUDriverConfigPtr cfg,
> +                                virDomainDiskDefPtr disk,
> +                                virQEMUCapsPtr qemuCaps)
> +{
> +    virStorageSourcePtr src = disk->src;
> +
> +    /* other protocols may be added later */
> +    if (src->protocol == VIR_STORAGE_NET_PROTOCOL_VXHS &&
> +        disk->src->haveTLS == VIR_TRISTATE_BOOL_YES) {
> +        return qemuBuildTLSx509CommandLine(cmd, cfg->vxhsTLSx509certdir,
> +                                          false, true, false,
> +                                          disk->info.alias, qemuCaps);
> +    }
> +
> +    return 0;
> +}
> +
> +
>  static char *
>  qemuBuildNetworkDriveURI(virStorageSourcePtr src,
>                           qemuDomainSecretInfoPtr secinfo)
> @@ -2218,6 +2244,9 @@ qemuBuildDiskDriveCommandLine(virCommandPtr cmd,
>          if (qemuBuildDiskSecinfoCommandLine(cmd, encinfo) < 0)
>              return -1;
>
> +        if (qemuBuildDiskTLSx509CommandLine(cmd, cfg, disk, qemuCaps) <
> 0)
> +            return -1;
> +
>          virCommandAddArg(cmd, "-drive");
>
>          if (!(optstr = qemuBuildDriveStr(disk, cfg, driveBoot, qemuCaps)))
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 9611df5..4c1074d 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -152,6 +152,55 @@ qemuDomainPrepareDisk(virQEMUDriverPtr driver,
>
>
>  static int
> +qemuDomainAddDiskTLSObject(virQEMUDriverPtr driver,
> +                           virDomainObjPtr vm,
> +                           virDomainDiskDefPtr disk,
> +                           char **tlsAlias)
> +{
> +    int ret = -1;
> +    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +    virStorageSourcePtr src = disk->src;
> +    virJSONValuePtr tlsProps = NULL;
> +
> +    /* NB: This may alter haveTLS based on cfg */
> +    qemuDomainPrepareDiskSourceTLS(src, disk->info.alias, cfg);
> +
> +    if (src->haveTLS != VIR_TRISTATE_BOOL_YES) {
> +        ret = 0;
> +        goto cleanup;
> +    }
> +
> +    /* Initial implementation doesn't require/use a secret to decrypt
> +     * a server certificate, so there's no need to manage a tlsSecAlias
> +     * and tlsSecProps. See qemuDomainAddChardevTLSObjects for the
> +     * methodology required to add a secret object. */
> +
> +    /* For a VxHS environment, create a TLS object for the client to
> +     * connect to the VxHS server. */
> +    if (src->type == VIR_STORAGE_TYPE_NETWORK &&
> +        src->protocol == VIR_STORAGE_NET_PROTOCOL_VXHS &&
> +        qemuDomainGetTLSObjects(priv->qemuCaps, NULL,
> +                                cfg->vxhsTLSx509certdir, false, true,
> +                                disk->info.alias, &tlsProps, tlsAlias,
> +                                NULL, NULL) < 0)
> +        goto cleanup;
> +
> +    if (qemuDomainAddTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE,
> +                                NULL, NULL, *tlsAlias, &tlsProps) < 0)
> +        goto cleanup;
> +
> +    ret = 0;
> +
> + cleanup:
> +    virJSONValueFree(tlsProps);
> +    virObjectUnref(cfg);
> +
> +    return ret;
> +}
> +
> +
> +static int
>  qemuHotplugWaitForTrayEject(virQEMUDriverPtr driver,
>                              virDomainObjPtr vm,
>                              virDomainDiskDefPtr disk,
> @@ -315,6 +364,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>      char *devstr = NULL;
>      char *drivestr = NULL;
>      char *drivealias = NULL;
> +    char *tlsAlias = NULL;
>      bool releaseaddr = false;
>      bool driveAdded = false;
>      bool secobjAdded = false;
> @@ -372,6 +422,9 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>      if (encinfo && qemuBuildSecretInfoProps(encinfo, &encobjProps) < 0)
>          goto error;
>
> +    if (qemuDomainAddDiskTLSObject(driver, vm, disk, &tlsAlias) < 0)
> +        goto error;
> +
>      if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
>          goto error;
>
> @@ -422,6 +475,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>      ret = 0;
>
>   cleanup:
> +    VIR_FREE(tlsAlias);
>      virJSONValueFree(secobjProps);
>      virJSONValueFree(encobjProps);
>      qemuDomainSecretDiskDestroy(disk);
> @@ -453,6 +507,8 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>      virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
>
>   error:
> +    qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, NULL,
> tlsAlias);
> +
>      if (releaseaddr)
>          qemuDomainReleaseDeviceAddress(vm, &disk->info, src);
>
> @@ -611,6 +667,7 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
>      virErrorPtr orig_err;
>      char *drivestr = NULL;
>      char *devstr = NULL;
> +    char *tlsAlias = NULL;
>      bool driveAdded = false;
>      bool encobjAdded = false;
>      bool secobjAdded = false;
> @@ -667,6 +724,9 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
>      if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0,
> priv->qemuCaps)))
>          goto error;
>
> +    if (qemuDomainAddDiskTLSObject(driver, vm, disk, &tlsAlias) < 0)
> +        goto error;
> +
>      if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
>          goto error;
>
> @@ -712,6 +772,7 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
>      ret = 0;
>
>   cleanup:
> +    VIR_FREE(tlsAlias);
>      virJSONValueFree(secobjProps);
>      virJSONValueFree(encobjProps);
>      qemuDomainSecretDiskDestroy(disk);
> @@ -740,6 +801,8 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
>      virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
>
>   error:
> +    qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, NULL,
> tlsAlias);
> +
>      ignore_value(qemuDomainPrepareDisk(driver, vm, disk, NULL, true));
>      goto cleanup;
>  }
> @@ -756,6 +819,7 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr
> driver,
>      char *drivealias = NULL;
>      char *drivestr = NULL;
>      char *devstr = NULL;
> +    char *tlsAlias = NULL;
>      bool driveAdded = false;
>      virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
>      const char *src = virDomainDiskGetSource(disk);
> @@ -780,6 +844,9 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr
> driver,
>      if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
>          goto error;
>
> +    if (qemuDomainAddDiskTLSObject(driver, vm, disk, &tlsAlias) < 0)
> +        goto error;
> +
>      if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
>          goto error;
>
> @@ -810,6 +877,7 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr
> driver,
>      ret = 0;
>
>   cleanup:
> +    VIR_FREE(tlsAlias);
>      if (ret < 0 && releaseaddr)
>          virDomainUSBAddressRelease(priv->usbaddrs, &disk->info);
>      VIR_FREE(devstr);
> @@ -833,6 +901,8 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr
> driver,
>      virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
>
>   error:
> +    qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, NULL,
> tlsAlias);
> +
>      ignore_value(qemuDomainPrepareDisk(driver, vm, disk, NULL, true));
>      goto cleanup;
>  }
> @@ -3710,6 +3780,9 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
>          ignore_value(qemuMonitorDelObject(priv->mon, encAlias));
>      VIR_FREE(encAlias);
>
> +    if (disk->src->tlsAlias)
> +        ignore_value(qemuMonitorDelObject(priv->mon,
> disk->src->tlsAlias));
> +
>      if (qemuDomainObjExitMonitor(driver, vm) < 0)
>          return -1;
>
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.args b/tests/qemuxml2argvdata/
> qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.args
> new file mode 100644
> index 0000000..dceae52
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.args
> @@ -0,0 +1,43 @@
> +LC_ALL=C \
> +PATH=/bin \
> +HOME=/home/test \
> +USER=test \
> +LOGNAME=test \
> +QEMU_AUDIO_DRV=none \
> +/usr/bin/qemu-system-x86_64 \
> +-name QEMUGuest1 \
> +-S \
> +-M pc \
> +-cpu qemu32 \
> +-m 214 \
> +-smp 1,sockets=1,cores=1,threads=1 \
> +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
> +-nographic \
> +-nodefaults \
> +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/
> monitor.sock,\
> +server,nowait \
> +-mon chardev=charmonitor,id=monitor,mode=readline \
> +-no-acpi \
> +-boot c \
> +-usb \
> +-object tls-creds-x509,id=objvirtio-disk0_tls0,dir=/etc/pki/qemu,\
> +endpoint=client,verify-peer=yes \
> +-drive file.driver=vxhs,file.tls-creds=objvirtio-disk0_tls0,\
> +file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc251,file.
> server.0.type=tcp,\
> +file.server.0.host=192.168.0.1,file.server.0.port=9999,
> format=raw,if=none,\
> +id=drive-virtio-disk0,cache=none \
> +-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
> +id=virtio-disk0 \
> +-object tls-creds-x509,id=objvirtio-disk1_tls0,dir=/etc/pki/qemu,\
> +endpoint=client,verify-peer=yes \
> +-drive file.driver=vxhs,file.tls-creds=objvirtio-disk1_tls0,\
> +file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc252,file.
> server.0.type=tcp,\
> +file.server.0.host=192.168.0.2,file.server.0.port=9999,
> format=raw,if=none,\
> +id=drive-virtio-disk1,cache=none \
> +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk1,\
> +id=virtio-disk1 \
> +-drive file.driver=vxhs,file.vdisk-id=eb90327c-8302-4725-9e1b-
> 4e85ed4dc253,\
> +file.server.0.type=tcp,file.server.0.host=192.168.0.3,
> file.server.0.port=9999,\
> +format=raw,if=none,id=drive-virtio-disk2,cache=none \
> +-device virtio-blk-pci,bus=pci.0,addr=0x6,drive=drive-virtio-disk2,\
> +id=virtio-disk2
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.xml b/tests/qemuxml2argvdata/
> qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.xml
> new file mode 100644
> index 0000000..a66e81f
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.xml
> @@ -0,0 +1,50 @@
> +<domain type='qemu'>
> +  <name>QEMUGuest1</name>
> +  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
> +  <memory unit='KiB'>219136</memory>
> +  <currentMemory unit='KiB'>219136</currentMemory>
> +  <vcpu placement='static'>1</vcpu>
> +  <os>
> +    <type arch='i686' machine='pc'>hvm</type>
> +    <boot dev='hd'/>
> +  </os>
> +  <clock offset='utc'/>
> +  <on_poweroff>destroy</on_poweroff>
> +  <on_reboot>restart</on_reboot>
> +  <on_crash>destroy</on_crash>
> +  <devices>
> +    <emulator>/usr/bin/qemu-system-x86_64</emulator>
> +    <disk type='network' device='disk'>
> +      <driver name='qemu' type='raw' cache='none'/>
> +      <source protocol='vxhs' name='eb90327c-8302-4725-9e1b-
> 4e85ed4dc251'>
> +        <host name='192.168.0.1' port='9999'/>
> +      </source>
> +      <target dev='vda' bus='virtio'/>
> +      <serial>eb90327c-8302-4725-9e1b-4e85ed4dc251</serial>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
> function='0x0'/>
> +    </disk>
> +    <disk type='network' device='disk'>
> +      <driver name='qemu' type='raw' cache='none'/>
> +      <source protocol='vxhs' name='eb90327c-8302-4725-9e1b-
> 4e85ed4dc252'>
> +        <host name='192.168.0.2' port='9999'/>
> +      </source>
> +      <target dev='vdb' bus='virtio'/>
> +      <serial>eb90327c-8302-4725-9e1b-4e85ed4dc252</serial>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x05'
> function='0x0'/>
> +    </disk>
> +    <disk type='network' device='disk'>
> +      <driver name='qemu' type='raw' cache='none'/>
> +      <source protocol='vxhs' name='eb90327c-8302-4725-9e1b-4e85ed4dc253'
> tls='no'>
> +        <host name='192.168.0.3' port='9999'/>
> +      </source>
> +      <target dev='vdc' bus='virtio'/>
> +      <serial>eb90327c-8302-4725-9e1b-4e85ed4dc252</serial>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x06'
> function='0x0'/>
> +    </disk>
> +    <controller type='usb' index='0'/>
> +    <controller type='pci' index='0' model='pci-root'/>
> +    <input type='mouse' bus='ps2'/>
> +    <input type='keyboard' bus='ps2'/>
> +    <memballoon model='none'/>
> +  </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args
> b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args
> new file mode 100644
> index 0000000..5308a16
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-vxhs.args
> @@ -0,0 +1,30 @@
> +LC_ALL=C \
> +PATH=/bin \
> +HOME=/home/test \
> +USER=test \
> +LOGNAME=test \
> +QEMU_AUDIO_DRV=none \
> +/usr/bin/qemu-system-x86_64 \
> +-name QEMUGuest1 \
> +-S \
> +-M pc \
> +-cpu qemu32 \
> +-m 214 \
> +-smp 1,sockets=1,cores=1,threads=1 \
> +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
> +-nographic \
> +-nodefaults \
> +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/
> monitor.sock,\
> +server,nowait \
> +-mon chardev=charmonitor,id=monitor,mode=readline \
> +-no-acpi \
> +-boot c \
> +-usb \
> +-object tls-creds-x509,id=objvirtio-disk0_tls0,dir=/etc/pki/qemu,\
> +endpoint=client,verify-peer=yes \
> +-drive file.driver=vxhs,file.tls-creds=objvirtio-disk0_tls0,\
> +file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc251,file.
> server.0.type=tcp,\
> +file.server.0.host=192.168.0.1,file.server.0.port=9999,
> format=raw,if=none,\
> +id=drive-virtio-disk0,cache=none \
> +-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
> +id=virtio-disk0
> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
> index b92ded8..0366dc3 100644
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -932,6 +932,13 @@ mymain(void)
>      DO_TEST("disk-drive-network-rbd-ipv6", NONE);
>      DO_TEST_FAILURE("disk-drive-network-rbd-no-colon", NONE);
>      DO_TEST("disk-drive-network-vxhs", QEMU_CAPS_VXHS);
> +    driver.config->vxhsTLS = 1;
> +    DO_TEST("disk-drive-network-tlsx509-vxhs", QEMU_CAPS_VXHS,
> +            QEMU_CAPS_OBJECT_TLS_CREDS_X509);
> +    DO_TEST("disk-drive-network-tlsx509-multidisk-vxhs", QEMU_CAPS_VXHS,
> +            QEMU_CAPS_OBJECT_TLS_CREDS_X509);
> +    driver.config->vxhsTLS = 0;
> +    VIR_FREE(driver.config->vxhsTLSx509certdir);
>      DO_TEST("disk-drive-no-boot",
>              QEMU_CAPS_BOOTINDEX);
>      DO_TEST_PARSE_ERROR("disk-device-lun-type-invalid",
> --
> 2.9.5
>
>
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v7 11/11] qemu: Add TLS support for Veritas HyperScale (VxHS)
Posted by John Ferlan 8 years, 2 months ago

On 09/19/2017 02:19 PM, ashish mittal wrote:
> Hi,
> 
> Not sure how to reply to the v8 series email thread, or how to add
> myself to the libvirt email list! Updating the v7 thread instead.
> 

There's some magic you can do with the right clients... I'll remember to
include you on the next series.

> I have already updated with the results of TLS testing by statically
> adding TLS enabled VxHS devices to domain XML, booting up the guest, and
> making sure devices are properly readable/writable.
> 
> I did the same test using hot plug. libvirtd crashes when adding TLS
> device -
> 
> [root@audi Sources] 2017-09-18 19:54:27# virsh attach-device myfc24
> hotplug_disk_2.xml
> error: Disconnected from qemu:///system due to end of file
> error: Failed to attach device from hotplug_disk_2.xml
> error: End of file while reading data: Input/output error
> 
> gdb reports -
> 
> Thread 3 "libvirtd" received signal SIGSEGV, Segmentation fault.
> [Switching to Thread 0x7f97e6b99700 (LWP 20096)]
> 0x00007f97c9c42a3d in qemuDomainGetTLSObjects (qemuCaps=0x7f97c00fcca0,
> secinfo=secinfo@entry=0x0, tlsCertdir=0x7f97c00ff000
> "/etc/pki/libvirt-vxhs",
>     tlsListen=tlsListen@entry=false, tlsVerify=tlsVerify@entry=true,
> srcAlias=0x7f97b8001e00 "virtio-disk0", tlsProps=0x7f97e6b988f0,
> tlsAlias=0x7f97e6b98998, secProps=0x0,
>     secAlias=0x0) at qemu/qemu_hotplug.c:1736
> 1736    }
> 
> 
> Reason for crash seems to be a latent issue with
> qemuDomainGetTLSObjects(). Both qemuDomainGetTLSObjects() and
> qemuBuildTLSx509BackendProps() suggest that char **secAlias may be NULL,
> but qemuDomainGetTLSObjects() dereferences it without checking for NULL.
> 
> int
> qemuDomainGetTLSObjects(virQEMUCapsPtr qemuCaps,
>                         qemuDomainSecretInfoPtr secinfo,
>                         const char *tlsCertdir,
>                         bool tlsListen,
>                         bool tlsVerify,
>                         const char *srcAlias,
>                         virJSONValuePtr *tlsProps,
>                         char **tlsAlias,
>                         virJSONValuePtr *secProps,
>                         char **secAlias)
> {
>     /* Add a secret object in order to access the TLS environment.
>      * The secinfo will only be created for serial TCP device. */
>     if (secinfo) {
>         if (qemuBuildSecretInfoProps(secinfo, secProps) < 0)
>             return -1;
> 
>         if (!(*secAlias = qemuDomainGetSecretAESAlias(srcAlias, false)))
>             return -1;
>     }
> 
>     if (qemuBuildTLSx509BackendProps(tlsCertdir, tlsListen, tlsVerify,
>                                      *secAlias, qemuCaps, tlsProps) < 0)
>   <=== *secAlias is dereferencing char **secAlias, which can be NULL
>         return -1;
> ...
> }
> 

Good thing we test before pushing!

> 
> The following diff takes care of the above issue. 
> 
> [root@audi libvirt] 2017-09-18 23:19:31# git diff
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 4c1074d..1448fe7 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -1715,6 +1715,8 @@ qemuDomainGetTLSObjects(virQEMUCapsPtr qemuCaps,
>                          virJSONValuePtr *secProps,
>                          char **secAlias)
>  {
> +    char *secretAlias = NULL;
> +
>      /* Add a secret object in order to access the TLS environment.
>       * The secinfo will only be created for serial TCP device. */
>      if (secinfo) {
> @@ -1723,10 +1725,11 @@ qemuDomainGetTLSObjects(virQEMUCapsPtr qemuCaps,
> 
>          if (!(*secAlias = qemuDomainGetSecretAESAlias(srcAlias, false)))
>              return -1;
> +        secretAlias = *secAlias;
>      }
> 
>      if (qemuBuildTLSx509BackendProps(tlsCertdir, tlsListen, tlsVerify,
> -                                     *secAlias, qemuCaps, tlsProps) < 0)
> +                                     secretAlias, qemuCaps, tlsProps) < 0)
>          return -1;
> 
>      if (!(*tlsAlias = qemuAliasTLSObjFromSrcAlias(srcAlias)))
> 

But it's not really right... it's OK to have NULL secalias - we just
have to handle it better.  There's no need to create a local for it. I
think if you do something that turns "*secalias," into "secalias ?
*secalias : NULL," that'd probably be better.  it it works, could you
just post a separate patch to fix that issue?


> I was able to attach and detach two TLS enabled VxHS disks to a running
> guest multiple times with the above fix in place. Did a attach/detach of
> these disks back-to-back without any problems. Was able to format these
> disks and copy files to both these TLS hot plugged disks from within the
> guest without any problems. Will send detailed test logs in a separate
> email.
> 

In the v8 review, Peter would like some adjustments which I'm in the
process of making.  I'm going to push the first part of the series, but
repost the TLS code as a v9.

Tks -

John

[...]

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v7 11/11] qemu: Add TLS support for Veritas HyperScale (VxHS)
Posted by ashish mittal 8 years, 2 months ago
Hi,

I've done some TLS testing with this patch and results look good. The
following test statically adds a VxHS disk to a guest in the TLS mode.
Boots up the guest and makes sure that we can do read/writes to the VxHS
disk from within the guest with TLS enabled.

(1) Create a backing store file /tmp/test_vxhs_disk_1 and start the VxHS
test server "qnio_server" with TLS enabled.

(2) Client side TLS env was setup as follows -

[root@audi ~] 2017-09-18 13:56:13# grep -i vxhs /etc/libvirt/qemu.conf |
grep -v "^#"
vxhs_tls = 1
vxhs_tls_x509_cert_dir = "/etc/pki/libvirt-vxhs"

[root@audi ~] 2017-09-18 13:56:22# ll /etc/pki/libvirt-vxhs
total 20
-r--r--r--. 1 root root 4062 Sep 17 23:15 ca-cert.pem
-rw-r--r--. 1 root root 1866 Sep 17 22:52 client-cert.pem
-r--------. 1 root root 1679 Sep 17 22:52 client-key.pem
[root@audi ~] 2017-09-18 13:56:35#

(3) virsh edit and add a new VxHS device with tls='yes'

The XML added to existing domain -

    <disk type='network' device='disk'>
      <driver name='qemu' type='raw' cache='none'/>
      <source protocol='vxhs' name='/tmp/test_vxhs_disk_1' tls='yes'>
        <host name='127.0.0.1' port='9999'/>
      </source>
      <backingStore/>
      <target dev='vdc' bus='virtio'/>
      <serial>eb90327c-8302-4725-9e1b-4e85ed4dc251</serial>
      <alias name='virtio-disk2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0a'
function='0x0'/>
    </disk>

(4) Start the domain and check if qemu command is correct

[root@audi ~] 2017-09-18 13:29:01# virsh start myfc24
Domain myfc24 started

[root@audi ~] 2017-09-18 13:29:20# ps -ef | grep qemu

root      9578     1 99 13:29 ?        00:00:20 /usr/bin/qemu-system-x86_64
-machine accel=kvm -name guest=myfc24,debug-threads=on -S -object
secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-1-myfc24/master-key.aes
-machine pc-i440fx-2.6,accel=kvm,usb=off,vmport=off,dump-guest-core=off
-cpu Opteron_G3 -m 1024 -realtime mlock=off -smp
2,sockets=2,cores=1,threads=1 -uuid 70454565-8185-4506-b50f-d2cf55d83796
-no-user-config -nodefaults -chardev
socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain-1-myfc24/monitor.sock,server,nowait
-mon chardev=charmonitor,id=monitor,mode=control -rtc
base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet
-no-shutdown -global PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1
-boot strict=on -device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x6.0x7
-device
ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x6
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x6.0x1
-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x6.0x2
-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x5 -drive
file=/var/lib/libvirt/images/myfc24_rootdisk.qcow2,format=qcow2,if=none,id=drive-ide0-0-0
-device
ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 -drive
if=none,id=drive-ide0-0-1,readonly=on -device
ide-cd,bus=ide.0,unit=1,drive=drive-ide0-0-1,id=ide0-0-1 -object
tls-creds-x509,id=objvirtio-disk2_tls0,dir=/etc/pki/libvirt-vxhs,endpoint=client,verify-peer=yes
-drive
file.driver=vxhs,file.tls-creds=objvirtio-disk2_tls0,file.vdisk-id=/tmp/test_vxhs_disk_1,file.server.type=tcp,file.server.host=127.0.0.1,file.server.port=9999,format=raw,if=none,id=drive-virtio-disk2,serial=eb90327c-8302-4725-9e1b-4e85ed4dc251,cache=none
-device
virtio-blk-pci,scsi=off,bus=pci.0,addr=0xa,drive=drive-virtio-disk2,id=virtio-disk2
-netdev tap,fd=27,id=hostnet0 -device
rtl8139,netdev=hostnet0,id=net0,mac=52:54:00:e4:9e:30,bus=pci.0,addr=0x3
-netdev tap,fd=29,id=hostnet1,vhost=on,vhostfd=30 -device
virtio-net-pci,netdev=hostnet1,id=net1,mac=52:54:00:b1:43:c4,bus=pci.0,addr=0x8
-chardev pty,id=charserial0 -device
isa-serial,chardev=charserial0,id=serial0 -chardev
spicevmc,id=charchannel0,name=vdagent -device
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
-spice
port=5900,addr=127.0.0.1,disable-ticketing,image-compression=off,seamless-migration=on
-device
qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pci.0,addr=0x2
-device intel-hda,id=sound0,bus=pci.0,addr=0x4 -device
hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -chardev
spicevmc,id=charredir0,name=usbredir -device
usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=1 -chardev
spicevmc,id=charredir1,name=usbredir -device
usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=2 -device
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7 -msg timestamp=on

(5) Log in to the guest domain and make sure we see this VxHS disk

[root@camshaft ~] 2017-09-18 13:32:22# fdisk -l
...
Disk /dev/vda: 1 MiB, 1048576 bytes, 2048 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/fedora-root: 45.4 GiB, 48704258048 bytes, 95125504 sectors
...

(6) Create a disk label and partition. Do mkfs and mount the FS. Copy some
files to the disk and check general read/write operations.

[root@camshaft ~] 2017-09-18 13:32:35# fdisk /dev/vda
....
Created a new partition 1 of type 'Linux' and of size 1023.5 KiB.

Command (m for help): p
Disk /dev/vda: 1 MiB, 1048576 bytes, 2048 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xcfd93e87

Device     Boot Start   End Sectors    Size Id Type
/dev/vda1           1  2047    2047 1023.5K 83 Linux

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

[root@camshaft ~]

[root@camshaft ~] 2017-09-18 13:34:29# mkfs.ext3 /dev/vda1
mke2fs 1.42.13 (17-May-2015)

Filesystem too small for a journal
Creating filesystem with 1020 1k blocks and 128 inodes

Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done

[root@camshaft ~] 2017-09-18 13:34:46# mount /dev/vda1 /mnt

[root@camshaft ~] 2017-09-18 13:34:56# cp /boot/System.map-4.* /mnt
cp: error writing '/mnt/System.map-4.5.5-300.fc24.x86_64': No space left on
device
cp: error writing '/mnt/System.map-4.8.8-200.fc24.x86_64': No space left on
device
[root@camshaft ~] 2017-09-18 13:35:08# df -h
Filesystem               Size  Used Avail Use% Mounted on
devtmpfs                 485M     0  485M   0% /dev
tmpfs                    497M  472K  496M   1% /dev/shm
tmpfs                    497M  1.3M  495M   1% /run
tmpfs                    497M     0  497M   0% /sys/fs/cgroup
/dev/mapper/fedora-root   45G  5.1G   38G  12% /
tmpfs                    497M   84K  497M   1% /tmp
/dev/mapper/fedora-home   22G  1.7G   19G   9% /home
/dev/sda1                477M  140M  308M  32% /boot
tmpfs                    100M   28K  100M   1% /run/user/42
tmpfs                    100M   20K  100M   1% /run/user/1000
/dev/vda1                999K  999K     0 100% /mnt
[root@camshaft ~] 2017-09-18 13:35:13#

[root@camshaft ~] 2017-09-18 13:37:07# dd
if=/mnt/System.map-4.5.5-300.fc24.x86_64 of=/dev/null
1952+0 records in
1952+0 records out
999424 bytes (999 kB, 976 KiB) copied, 0.001174 s, 851 MB/s
[root@camshaft ~] 2017-09-18 13:37:14#



Regards,
Ashish

On Fri, Sep 1, 2017 at 10:09 AM, John Ferlan <jferlan@redhat.com> wrote:

> From: Ashish Mittal <Ashish.Mittal@veritas.com>
>
> Alter qemu command line generation in order to possibly add TLS for
> a suitably configured domain.
>
> Sample TLS args generated by libvirt -
>
>     -object tls-creds-x509,id=objvirtio-disk0_tls0,dir=/etc/pki/qemu,\
>     endpoint=client,verify-peer=yes \
>     -drive file.driver=vxhs,file.tls-creds=objvirtio-disk0_tls0,\
>     file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc251,\
>     file.server.0.type=tcp,file.server.0.host=192.168.0.1,\
>     file.server.0.port=9999,format=raw,if=none,\
>     id=drive-virtio-disk0,cache=none \
>     -device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
>     id=virtio-disk0
>
> Update the qemuxml2argvtest with a couple of examples. One for a
> simple case and the other a bit more complex where multiple VxHS disks
> are added where at least one uses a VxHS that doesn't require TLS
> credentials and thus sets the domain disk source attribute "tls = 'no'".
>
> Update the hotplug to be able to handle processing the tlsAlias whether
> it's to add the TLS object when hotplugging a disk or to remove the TLS
> object when hot unplugging a disk.  The hot plug/unplug code is largely
> generic, but the addition code does make the VXHS specific checks only
> because it needs to grab the correct config directory and generate the
> object as the command line would do.
>
> Signed-off-by: Ashish Mittal <Ashish.Mittal@veritas.com>
> Signed-off-by: John Ferlan <jferlan@redhat.com>
> ---
>  src/qemu/qemu_block.c                              |  8 +++
>  src/qemu/qemu_command.c                            | 29 +++++++++
>  src/qemu/qemu_hotplug.c                            | 73
> ++++++++++++++++++++++
>  ...-disk-drive-network-tlsx509-multidisk-vxhs.args | 43 +++++++++++++
>  ...v-disk-drive-network-tlsx509-multidisk-vxhs.xml | 50 +++++++++++++++
>  ...muxml2argv-disk-drive-network-tlsx509-vxhs.args | 30 +++++++++
>  tests/qemuxml2argvtest.c                           |  7 +++
>  7 files changed, 240 insertions(+)
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.args
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.xml
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-vxhs.args
>
> diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
> index f5269fb..be4e8fa 100644
> --- a/src/qemu/qemu_block.c
> +++ b/src/qemu/qemu_block.c
> @@ -495,16 +495,24 @@ qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr
> src)
>          return NULL;
>      }
>
> +    if (src->haveTLS == VIR_TRISTATE_BOOL_YES && !src->tlsAlias) {
> +        virReportError(VIR_ERR_INVALID_ARG, "%s",
> +                       _("VxHS disk does not have TLS alias set"));
> +        return NULL;
> +    }
> +
>      if (!(server = qemuBlockStorageSourceBuildHostsJSONSocketAddress(src,
> true)))
>          return NULL;
>
>      /* VxHS disk specification example:
>       * { driver:"vxhs",
> +     *   [tls-creds:"objvirtio-disk0_tls0",]
>       *   vdisk-id:"eb90327c-8302-4725-4e85ed4dc251",
>       *   server:[{type:"tcp", host:"1.2.3.4", port:9999}]}
>       */
>      if (virJSONValueObjectCreate(&ret,
>                                   "s:driver", protocol,
> +                                 "S:tls-creds", src->tlsAlias,
>                                   "s:vdisk-id", src->path,
>                                   "a:server", server, NULL) < 0)
>          virJSONValueFree(server);
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index b9e2ab3..d6b04a3 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -791,6 +791,32 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd,
>  }
>
>
> +/* qemuBuildDiskTLSx509CommandLine:
> + *
> + * Add TLS object if the disk uses a secure communication channel
> + *
> + * Returns 0 on success, -1 w/ error on some sort of failure.
> + */
> +static int
> +qemuBuildDiskTLSx509CommandLine(virCommandPtr cmd,
> +                                virQEMUDriverConfigPtr cfg,
> +                                virDomainDiskDefPtr disk,
> +                                virQEMUCapsPtr qemuCaps)
> +{
> +    virStorageSourcePtr src = disk->src;
> +
> +    /* other protocols may be added later */
> +    if (src->protocol == VIR_STORAGE_NET_PROTOCOL_VXHS &&
> +        disk->src->haveTLS == VIR_TRISTATE_BOOL_YES) {
> +        return qemuBuildTLSx509CommandLine(cmd, cfg->vxhsTLSx509certdir,
> +                                          false, true, false,
> +                                          disk->info.alias, qemuCaps);
> +    }
> +
> +    return 0;
> +}
> +
> +
>  static char *
>  qemuBuildNetworkDriveURI(virStorageSourcePtr src,
>                           qemuDomainSecretInfoPtr secinfo)
> @@ -2218,6 +2244,9 @@ qemuBuildDiskDriveCommandLine(virCommandPtr cmd,
>          if (qemuBuildDiskSecinfoCommandLine(cmd, encinfo) < 0)
>              return -1;
>
> +        if (qemuBuildDiskTLSx509CommandLine(cmd, cfg, disk, qemuCaps) <
> 0)
> +            return -1;
> +
>          virCommandAddArg(cmd, "-drive");
>
>          if (!(optstr = qemuBuildDriveStr(disk, cfg, driveBoot, qemuCaps)))
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 9611df5..4c1074d 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -152,6 +152,55 @@ qemuDomainPrepareDisk(virQEMUDriverPtr driver,
>
>
>  static int
> +qemuDomainAddDiskTLSObject(virQEMUDriverPtr driver,
> +                           virDomainObjPtr vm,
> +                           virDomainDiskDefPtr disk,
> +                           char **tlsAlias)
> +{
> +    int ret = -1;
> +    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +    virStorageSourcePtr src = disk->src;
> +    virJSONValuePtr tlsProps = NULL;
> +
> +    /* NB: This may alter haveTLS based on cfg */
> +    qemuDomainPrepareDiskSourceTLS(src, disk->info.alias, cfg);
> +
> +    if (src->haveTLS != VIR_TRISTATE_BOOL_YES) {
> +        ret = 0;
> +        goto cleanup;
> +    }
> +
> +    /* Initial implementation doesn't require/use a secret to decrypt
> +     * a server certificate, so there's no need to manage a tlsSecAlias
> +     * and tlsSecProps. See qemuDomainAddChardevTLSObjects for the
> +     * methodology required to add a secret object. */
> +
> +    /* For a VxHS environment, create a TLS object for the client to
> +     * connect to the VxHS server. */
> +    if (src->type == VIR_STORAGE_TYPE_NETWORK &&
> +        src->protocol == VIR_STORAGE_NET_PROTOCOL_VXHS &&
> +        qemuDomainGetTLSObjects(priv->qemuCaps, NULL,
> +                                cfg->vxhsTLSx509certdir, false, true,
> +                                disk->info.alias, &tlsProps, tlsAlias,
> +                                NULL, NULL) < 0)
> +        goto cleanup;
> +
> +    if (qemuDomainAddTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE,
> +                                NULL, NULL, *tlsAlias, &tlsProps) < 0)
> +        goto cleanup;
> +
> +    ret = 0;
> +
> + cleanup:
> +    virJSONValueFree(tlsProps);
> +    virObjectUnref(cfg);
> +
> +    return ret;
> +}
> +
> +
> +static int
>  qemuHotplugWaitForTrayEject(virQEMUDriverPtr driver,
>                              virDomainObjPtr vm,
>                              virDomainDiskDefPtr disk,
> @@ -315,6 +364,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>      char *devstr = NULL;
>      char *drivestr = NULL;
>      char *drivealias = NULL;
> +    char *tlsAlias = NULL;
>      bool releaseaddr = false;
>      bool driveAdded = false;
>      bool secobjAdded = false;
> @@ -372,6 +422,9 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>      if (encinfo && qemuBuildSecretInfoProps(encinfo, &encobjProps) < 0)
>          goto error;
>
> +    if (qemuDomainAddDiskTLSObject(driver, vm, disk, &tlsAlias) < 0)
> +        goto error;
> +
>      if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
>          goto error;
>
> @@ -422,6 +475,7 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>      ret = 0;
>
>   cleanup:
> +    VIR_FREE(tlsAlias);
>      virJSONValueFree(secobjProps);
>      virJSONValueFree(encobjProps);
>      qemuDomainSecretDiskDestroy(disk);
> @@ -453,6 +507,8 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
>      virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
>
>   error:
> +    qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, NULL,
> tlsAlias);
> +
>      if (releaseaddr)
>          qemuDomainReleaseDeviceAddress(vm, &disk->info, src);
>
> @@ -611,6 +667,7 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
>      virErrorPtr orig_err;
>      char *drivestr = NULL;
>      char *devstr = NULL;
> +    char *tlsAlias = NULL;
>      bool driveAdded = false;
>      bool encobjAdded = false;
>      bool secobjAdded = false;
> @@ -667,6 +724,9 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
>      if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0,
> priv->qemuCaps)))
>          goto error;
>
> +    if (qemuDomainAddDiskTLSObject(driver, vm, disk, &tlsAlias) < 0)
> +        goto error;
> +
>      if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
>          goto error;
>
> @@ -712,6 +772,7 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
>      ret = 0;
>
>   cleanup:
> +    VIR_FREE(tlsAlias);
>      virJSONValueFree(secobjProps);
>      virJSONValueFree(encobjProps);
>      qemuDomainSecretDiskDestroy(disk);
> @@ -740,6 +801,8 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
>      virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
>
>   error:
> +    qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, NULL,
> tlsAlias);
> +
>      ignore_value(qemuDomainPrepareDisk(driver, vm, disk, NULL, true));
>      goto cleanup;
>  }
> @@ -756,6 +819,7 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr
> driver,
>      char *drivealias = NULL;
>      char *drivestr = NULL;
>      char *devstr = NULL;
> +    char *tlsAlias = NULL;
>      bool driveAdded = false;
>      virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
>      const char *src = virDomainDiskGetSource(disk);
> @@ -780,6 +844,9 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr
> driver,
>      if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
>          goto error;
>
> +    if (qemuDomainAddDiskTLSObject(driver, vm, disk, &tlsAlias) < 0)
> +        goto error;
> +
>      if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
>          goto error;
>
> @@ -810,6 +877,7 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr
> driver,
>      ret = 0;
>
>   cleanup:
> +    VIR_FREE(tlsAlias);
>      if (ret < 0 && releaseaddr)
>          virDomainUSBAddressRelease(priv->usbaddrs, &disk->info);
>      VIR_FREE(devstr);
> @@ -833,6 +901,8 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr
> driver,
>      virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
>
>   error:
> +    qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, NULL,
> tlsAlias);
> +
>      ignore_value(qemuDomainPrepareDisk(driver, vm, disk, NULL, true));
>      goto cleanup;
>  }
> @@ -3710,6 +3780,9 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
>          ignore_value(qemuMonitorDelObject(priv->mon, encAlias));
>      VIR_FREE(encAlias);
>
> +    if (disk->src->tlsAlias)
> +        ignore_value(qemuMonitorDelObject(priv->mon,
> disk->src->tlsAlias));
> +
>      if (qemuDomainObjExitMonitor(driver, vm) < 0)
>          return -1;
>
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.args b/tests/qemuxml2argvdata/
> qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.args
> new file mode 100644
> index 0000000..dceae52
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.args
> @@ -0,0 +1,43 @@
> +LC_ALL=C \
> +PATH=/bin \
> +HOME=/home/test \
> +USER=test \
> +LOGNAME=test \
> +QEMU_AUDIO_DRV=none \
> +/usr/bin/qemu-system-x86_64 \
> +-name QEMUGuest1 \
> +-S \
> +-M pc \
> +-cpu qemu32 \
> +-m 214 \
> +-smp 1,sockets=1,cores=1,threads=1 \
> +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
> +-nographic \
> +-nodefaults \
> +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/
> monitor.sock,\
> +server,nowait \
> +-mon chardev=charmonitor,id=monitor,mode=readline \
> +-no-acpi \
> +-boot c \
> +-usb \
> +-object tls-creds-x509,id=objvirtio-disk0_tls0,dir=/etc/pki/qemu,\
> +endpoint=client,verify-peer=yes \
> +-drive file.driver=vxhs,file.tls-creds=objvirtio-disk0_tls0,\
> +file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc251,file.
> server.0.type=tcp,\
> +file.server.0.host=192.168.0.1,file.server.0.port=9999,
> format=raw,if=none,\
> +id=drive-virtio-disk0,cache=none \
> +-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
> +id=virtio-disk0 \
> +-object tls-creds-x509,id=objvirtio-disk1_tls0,dir=/etc/pki/qemu,\
> +endpoint=client,verify-peer=yes \
> +-drive file.driver=vxhs,file.tls-creds=objvirtio-disk1_tls0,\
> +file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc252,file.
> server.0.type=tcp,\
> +file.server.0.host=192.168.0.2,file.server.0.port=9999,
> format=raw,if=none,\
> +id=drive-virtio-disk1,cache=none \
> +-device virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk1,\
> +id=virtio-disk1 \
> +-drive file.driver=vxhs,file.vdisk-id=eb90327c-8302-4725-9e1b-
> 4e85ed4dc253,\
> +file.server.0.type=tcp,file.server.0.host=192.168.0.3,
> file.server.0.port=9999,\
> +format=raw,if=none,id=drive-virtio-disk2,cache=none \
> +-device virtio-blk-pci,bus=pci.0,addr=0x6,drive=drive-virtio-disk2,\
> +id=virtio-disk2
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.xml b/tests/qemuxml2argvdata/
> qemuxml2argv-disk-drive-network-tlsx509-multidisk-vxhs.xml
> new file mode 100644
> index 0000000..a66e81f
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-multidisk-vxhs.xml
> @@ -0,0 +1,50 @@
> +<domain type='qemu'>
> +  <name>QEMUGuest1</name>
> +  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
> +  <memory unit='KiB'>219136</memory>
> +  <currentMemory unit='KiB'>219136</currentMemory>
> +  <vcpu placement='static'>1</vcpu>
> +  <os>
> +    <type arch='i686' machine='pc'>hvm</type>
> +    <boot dev='hd'/>
> +  </os>
> +  <clock offset='utc'/>
> +  <on_poweroff>destroy</on_poweroff>
> +  <on_reboot>restart</on_reboot>
> +  <on_crash>destroy</on_crash>
> +  <devices>
> +    <emulator>/usr/bin/qemu-system-x86_64</emulator>
> +    <disk type='network' device='disk'>
> +      <driver name='qemu' type='raw' cache='none'/>
> +      <source protocol='vxhs' name='eb90327c-8302-4725-9e1b-
> 4e85ed4dc251'>
> +        <host name='192.168.0.1' port='9999'/>
> +      </source>
> +      <target dev='vda' bus='virtio'/>
> +      <serial>eb90327c-8302-4725-9e1b-4e85ed4dc251</serial>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
> function='0x0'/>
> +    </disk>
> +    <disk type='network' device='disk'>
> +      <driver name='qemu' type='raw' cache='none'/>
> +      <source protocol='vxhs' name='eb90327c-8302-4725-9e1b-
> 4e85ed4dc252'>
> +        <host name='192.168.0.2' port='9999'/>
> +      </source>
> +      <target dev='vdb' bus='virtio'/>
> +      <serial>eb90327c-8302-4725-9e1b-4e85ed4dc252</serial>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x05'
> function='0x0'/>
> +    </disk>
> +    <disk type='network' device='disk'>
> +      <driver name='qemu' type='raw' cache='none'/>
> +      <source protocol='vxhs' name='eb90327c-8302-4725-9e1b-4e85ed4dc253'
> tls='no'>
> +        <host name='192.168.0.3' port='9999'/>
> +      </source>
> +      <target dev='vdc' bus='virtio'/>
> +      <serial>eb90327c-8302-4725-9e1b-4e85ed4dc252</serial>
> +      <address type='pci' domain='0x0000' bus='0x00' slot='0x06'
> function='0x0'/>
> +    </disk>
> +    <controller type='usb' index='0'/>
> +    <controller type='pci' index='0' model='pci-root'/>
> +    <input type='mouse' bus='ps2'/>
> +    <input type='keyboard' bus='ps2'/>
> +    <memballoon model='none'/>
> +  </devices>
> +</domain>
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args
> b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args
> new file mode 100644
> index 0000000..5308a16
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-
> network-tlsx509-vxhs.args
> @@ -0,0 +1,30 @@
> +LC_ALL=C \
> +PATH=/bin \
> +HOME=/home/test \
> +USER=test \
> +LOGNAME=test \
> +QEMU_AUDIO_DRV=none \
> +/usr/bin/qemu-system-x86_64 \
> +-name QEMUGuest1 \
> +-S \
> +-M pc \
> +-cpu qemu32 \
> +-m 214 \
> +-smp 1,sockets=1,cores=1,threads=1 \
> +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
> +-nographic \
> +-nodefaults \
> +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/
> monitor.sock,\
> +server,nowait \
> +-mon chardev=charmonitor,id=monitor,mode=readline \
> +-no-acpi \
> +-boot c \
> +-usb \
> +-object tls-creds-x509,id=objvirtio-disk0_tls0,dir=/etc/pki/qemu,\
> +endpoint=client,verify-peer=yes \
> +-drive file.driver=vxhs,file.tls-creds=objvirtio-disk0_tls0,\
> +file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc251,file.
> server.0.type=tcp,\
> +file.server.0.host=192.168.0.1,file.server.0.port=9999,
> format=raw,if=none,\
> +id=drive-virtio-disk0,cache=none \
> +-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
> +id=virtio-disk0
> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
> index b92ded8..0366dc3 100644
> --- a/tests/qemuxml2argvtest.c
> +++ b/tests/qemuxml2argvtest.c
> @@ -932,6 +932,13 @@ mymain(void)
>      DO_TEST("disk-drive-network-rbd-ipv6", NONE);
>      DO_TEST_FAILURE("disk-drive-network-rbd-no-colon", NONE);
>      DO_TEST("disk-drive-network-vxhs", QEMU_CAPS_VXHS);
> +    driver.config->vxhsTLS = 1;
> +    DO_TEST("disk-drive-network-tlsx509-vxhs", QEMU_CAPS_VXHS,
> +            QEMU_CAPS_OBJECT_TLS_CREDS_X509);
> +    DO_TEST("disk-drive-network-tlsx509-multidisk-vxhs", QEMU_CAPS_VXHS,
> +            QEMU_CAPS_OBJECT_TLS_CREDS_X509);
> +    driver.config->vxhsTLS = 0;
> +    VIR_FREE(driver.config->vxhsTLSx509certdir);
>      DO_TEST("disk-drive-no-boot",
>              QEMU_CAPS_BOOTINDEX);
>      DO_TEST_PARSE_ERROR("disk-device-lun-type-invalid",
> --
> 2.9.5
>
>
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list