]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Add TLS support for Veritas HyperScale (VxHS)
authorAshish Mittal <Ashish.Mittal@veritas.com>
Wed, 30 Aug 2017 15:06:00 +0000 (11:06 -0400)
committerJohn Ferlan <jferlan@redhat.com>
Thu, 28 Sep 2017 13:45:14 +0000 (09:45 -0400)
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.type=tcp,file.server.host=192.168.0.1,\
    file.server.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
src/qemu/qemu_command.c
src/qemu/qemu_hotplug.c
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.xml
tests/qemuxml2argvtest.c
tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-network-tlsx509-vxhs.xml

index 6faecb0aeb41386719aedac132b444b5dfca3947..8d232de3e3b5efcc0ce16d2b169da3f8ab6a5d0d 100644 (file)
@@ -545,11 +545,13 @@ qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src)
 
     /* 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);
index abeb24846816dc1e1f97d3edf12138c3b72ec1e5..4f141e0ac312f012898606fd0d47b0ed9e1d0ecd 100644 (file)
@@ -794,6 +794,35 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd,
 }
 
 
+/* qemuBuildDiskSrcTLSx509CommandLine:
+ *
+ * Add TLS object if the disk src uses a secure communication channel
+ *
+ * Returns 0 on success, -1 w/ error on some sort of failure.
+ */
+static int
+qemuBuildDiskSrcTLSx509CommandLine(virCommandPtr cmd,
+                                   virStorageSourcePtr src,
+                                   const char *srcalias,
+                                   virQEMUCapsPtr qemuCaps)
+{
+
+
+    /* other protocols may be added later */
+    if (src->protocol == VIR_STORAGE_NET_PROTOCOL_VXHS &&
+        src->haveTLS == VIR_TRISTATE_BOOL_YES) {
+        if (!(src->tlsAlias = qemuAliasTLSObjFromSrcAlias(srcalias)))
+            return -1;
+
+        return qemuBuildTLSx509CommandLine(cmd, src->tlsCertdir,
+                                           false, src->tlsVerify,
+                                           false, srcalias, qemuCaps);
+    }
+
+    return 0;
+}
+
+
 static char *
 qemuBuildNetworkDriveURI(virStorageSourcePtr src,
                          qemuDomainSecretInfoPtr secinfo)
@@ -2221,6 +2250,10 @@ qemuBuildDiskDriveCommandLine(virCommandPtr cmd,
         if (qemuBuildDiskSecinfoCommandLine(cmd, encinfo) < 0)
             return -1;
 
+        if (qemuBuildDiskSrcTLSx509CommandLine(cmd, disk->src, disk->info.alias,
+                                               qemuCaps) < 0)
+            return -1;
+
         virCommandAddArg(cmd, "-drive");
 
         if (!(optstr = qemuBuildDriveStr(disk, cfg, driveBoot, qemuCaps)))
index 4913e18e69393f868aba07f62d4bd81e854aac35..b77731df08d601c2b080dabbc1eee78166d9fae0 100644 (file)
@@ -155,6 +155,46 @@ qemuDomainPrepareDisk(virQEMUDriverPtr driver,
 }
 
 
+static int
+qemuDomainAddDiskSrcTLSObject(virQEMUDriverPtr driver,
+                              virDomainObjPtr vm,
+                              virStorageSourcePtr src,
+                              const char *srcalias)
+{
+    int ret = -1;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virJSONValuePtr tlsProps = NULL;
+
+    if (qemuDomainGetTLSObjects(priv->qemuCaps, NULL,
+                                src->tlsCertdir,
+                                false,
+                                src->tlsVerify,
+                                srcalias, &tlsProps, &src->tlsAlias,
+                                NULL, NULL) < 0)
+        goto cleanup;
+
+    if (qemuDomainAddTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE,
+                                NULL, NULL, src->tlsAlias, &tlsProps) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    virJSONValueFree(tlsProps);
+
+    return ret;
+}
+
+
+static void
+qemuDomainDelDiskSrcTLSObject(virQEMUDriverPtr driver,
+                              virDomainObjPtr vm,
+                              virStorageSourcePtr src)
+{
+    qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE, NULL, src->tlsAlias);
+}
+
+
 static int
 qemuHotplugWaitForTrayEject(virQEMUDriverPtr driver,
                             virDomainObjPtr vm,
@@ -376,6 +416,14 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
     if (encinfo && qemuBuildSecretInfoProps(encinfo, &encobjProps) < 0)
         goto error;
 
+    if (qemuDomainPrepareDiskSourceTLS(disk->src, disk->info.alias, cfg) < 0)
+        goto error;
+
+    if (disk->src->haveTLS &&
+        qemuDomainAddDiskSrcTLSObject(driver, vm, disk->src,
+                                      disk->info.alias) < 0)
+        goto error;
+
     if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
         goto error;
 
@@ -453,6 +501,8 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
     virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
 
  error:
+    qemuDomainDelDiskSrcTLSObject(driver, vm, disk->src);
+
     if (releaseaddr)
         qemuDomainReleaseDeviceAddress(vm, &disk->info, src);
 
@@ -667,6 +717,14 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
     if (!(devstr = qemuBuildDriveDevStr(vm->def, disk, 0, priv->qemuCaps)))
         goto error;
 
+    if (qemuDomainPrepareDiskSourceTLS(disk->src, disk->info.alias, cfg) < 0)
+        goto error;
+
+    if (disk->src->haveTLS &&
+        qemuDomainAddDiskSrcTLSObject(driver, vm, disk->src,
+                                      disk->info.alias) < 0)
+        goto error;
+
     if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
         goto error;
 
@@ -737,6 +795,8 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
     virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
 
  error:
+    qemuDomainDelDiskSrcTLSObject(driver, vm, disk->src);
+
     ignore_value(qemuDomainPrepareDisk(driver, vm, disk, NULL, true));
     goto cleanup;
 }
@@ -777,6 +837,14 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver,
     if (qemuAssignDeviceDiskAlias(vm->def, disk, priv->qemuCaps) < 0)
         goto error;
 
+    if (qemuDomainPrepareDiskSourceTLS(disk->src, disk->info.alias, cfg) < 0)
+        goto error;
+
+    if (disk->src->haveTLS &&
+        qemuDomainAddDiskSrcTLSObject(driver, vm, disk->src,
+                                      disk->info.alias) < 0)
+        goto error;
+
     if (!(drivestr = qemuBuildDriveStr(disk, cfg, false, priv->qemuCaps)))
         goto error;
 
@@ -827,6 +895,8 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver,
     virDomainAuditDisk(vm, NULL, disk->src, "attach", false);
 
  error:
+    qemuDomainDelDiskSrcTLSObject(driver, vm, disk->src);
+
     ignore_value(qemuDomainPrepareDisk(driver, vm, disk, NULL, true));
     goto cleanup;
 }
@@ -3679,6 +3749,9 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
         ignore_value(qemuMonitorDelObject(priv->mon, encAlias));
     VIR_FREE(encAlias);
 
+    if (disk->src->haveTLS)
+        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-vxhs.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args
new file mode 100644 (file)
index 0000000..572c9f3
--- /dev/null
@@ -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.type=tcp,\
+file.server.host=192.168.0.1,file.server.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.type=tcp,\
+file.server.host=192.168.0.2,file.server.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.type=tcp,file.server.host=192.168.0.3,file.server.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
index 61b5e2e791c876542cbaefc3c14fa04517f0f995..a66e81f065f3b9d8ba6fe97ac6ac6a6fc9f3e67a 100644 (file)
     <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' tls='yes'>
+      <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'/>
index 70be0c32d05e3b0917bb7fc4f2ea2da031e69657..1958ad4282810bf2f895955035e1503231018be9 100644 (file)
@@ -942,6 +942,11 @@ 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);
+    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",
index 16f0883e04cd407378ab31aaec191cf922470e55..7053affd176399b7b2f5f8d47d6ce95f8b340bcc 100644 (file)
     <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' tls='yes'>
+      <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'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
     </controller>