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

John Ferlan posted 13 patches 7 years, 8 months ago
There is a newer version of this series
[libvirt] [PATCH v6 11/13] qemu: Add TLS support for Veritas HyperScale (VxHS)
Posted by John Ferlan 7 years, 8 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 simple example.

Signed-off-by: Ashish Mittal <Ashish.Mittal@veritas.com>
Signed-off-by: John Ferlan <jferlan@redhat.com>
---

 This is the remainder of v5 patch5 - the src/qemu/qemu_*.c changes
 in order to add the TLS information to the command line.

 Changes include:

  * Alteration of the alias name to be used. We cannot use a static
    "vxhs" since there will be more than one disk possible. Instead,
    we'll use the disk->info.alias (e.g. virtio-disk0). The diskN will
    always change, so we can be assured of unique alias generation.

  * Do less in qemuBlockStorageSourceGetVxHSProps - make use of the
    fact that proving "S:address" to virJSONValueObjectCreate will
    only add the field if the address is not NULL.

  * qemuBuildDiskTLSx509CommandLine was shortened since the code that
    was in qemuBuildDiskVxHSTLSinfoCommandLine has moved.

  * Since we need the disk->info.alias, we have to pass it in
    qemuBlockStorageSourceGetBackendProps.

  * Cleaned up the *.args output in order to match expectations of
    all the new code.

  * Made sure to use the QEMU_CAPS_VXHS in qemuxml2argvtest

 src/qemu/qemu_block.c                              | 29 ++++++++++++++++++--
 src/qemu/qemu_block.h                              |  3 +-
 src/qemu/qemu_command.c                            | 32 +++++++++++++++++++++-
 ...muxml2argv-disk-drive-network-tlsx509-vxhs.args | 30 ++++++++++++++++++++
 tests/qemuxml2argvtest.c                           |  5 ++++
 5 files changed, 94 insertions(+), 5 deletions(-)
 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 cb765ab..5e65692 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -18,6 +18,7 @@
 
 #include <config.h>
 
+#include "qemu_alias.h"
 #include "qemu_block.h"
 #include "qemu_domain.h"
 
@@ -484,9 +485,12 @@ qemuBlockStorageSourceGetGlusterProps(virStorageSourcePtr src)
 
 static virJSONValuePtr
 qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src,
-                                   virQEMUCapsPtr qemuCaps)
+                                   virQEMUCapsPtr qemuCaps,
+                                   const char *diskAlias)
+
 {
     const char *protocol = virStorageNetProtocolTypeToString(src->protocol);
+    char *objalias = NULL;
     virJSONValuePtr server = NULL;
     virJSONValuePtr ret = NULL;
 
@@ -506,17 +510,34 @@ qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src,
     if (!(server = qemuBlockStorageSourceBuildHostsJSONSocketAddress(src, true)))
         return NULL;
 
+    if (src->haveTLS == VIR_TRISTATE_BOOL_YES) {
+        if (!diskAlias) {
+            virReportError(VIR_ERR_INVALID_ARG, "%s",
+                           _("disk does not have an alias"));
+            return NULL;
+        }
+
+        if (!(objalias = qemuAliasTLSObjFromSrcAlias(diskAlias))) {
+            virJSONValueFree(server);
+            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", objalias,
                                  "s:vdisk-id", src->path,
                                  "a:server", server, NULL) < 0)
         virJSONValueFree(server);
 
+    VIR_FREE(objalias);
+
     return ret;
 }
 
@@ -530,7 +551,8 @@ qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src,
  */
 virJSONValuePtr
 qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
-                                      virQEMUCapsPtr qemuCaps)
+                                      virQEMUCapsPtr qemuCaps,
+                                      const char *diskAlias)
 {
     int actualType = virStorageSourceGetActualType(src);
     virJSONValuePtr fileprops = NULL;
@@ -553,7 +575,8 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
             break;
 
         case VIR_STORAGE_NET_PROTOCOL_VXHS:
-            if (!(fileprops = qemuBlockStorageSourceGetVxHSProps(src, qemuCaps)))
+            if (!(fileprops = qemuBlockStorageSourceGetVxHSProps(src, qemuCaps,
+                                                                 diskAlias)))
                 goto cleanup;
             break;
 
diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
index 90f78e3..3ed1789 100644
--- a/src/qemu/qemu_block.h
+++ b/src/qemu/qemu_block.h
@@ -55,6 +55,7 @@ qemuBlockGetNodeData(virJSONValuePtr data);
 
 virJSONValuePtr
 qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
-                                      virQEMUCapsPtr qemuCaps);
+                                      virQEMUCapsPtr qemuCaps,
+                                      const char *diskAlias);
 
 #endif /* __QEMU_BLOCK_H__ */
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3205a59..b94ed11 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)
@@ -1353,7 +1379,8 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
     int ret = -1;
 
     if (qemuDiskSourceNeedsProps(disk->src) &&
-        !(srcprops = qemuBlockStorageSourceGetBackendProps(disk->src, qemuCaps)))
+        !(srcprops = qemuBlockStorageSourceGetBackendProps(disk->src, qemuCaps,
+                                                           disk->info.alias)))
         goto cleanup;
 
     if (!srcprops &&
@@ -2218,6 +2245,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/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..7be8bf8 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -932,6 +932,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",
-- 
2.9.5

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v6 11/13] qemu: Add TLS support for Veritas HyperScale (VxHS)
Posted by Peter Krempa 7 years, 8 months ago
On Wed, Aug 30, 2017 at 18:46:11 -0400, John Ferlan wrote:
> From: Ashish Mittal <Ashish.Mittal@veritas.com>

[...]

>  src/qemu/qemu_block.c                              | 29 ++++++++++++++++++--
>  src/qemu/qemu_block.h                              |  3 +-
>  src/qemu/qemu_command.c                            | 32 +++++++++++++++++++++-
>  ...muxml2argv-disk-drive-network-tlsx509-vxhs.args | 30 ++++++++++++++++++++
>  tests/qemuxml2argvtest.c                           |  5 ++++
>  5 files changed, 94 insertions(+), 5 deletions(-)
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-tlsx509-vxhs.args

This won't work with disk hotplug. You either need to add code for it
to work properly or add code that specifically disables it.

> diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
> index cb765ab..5e65692 100644
> --- a/src/qemu/qemu_block.c
> +++ b/src/qemu/qemu_block.c
> @@ -18,6 +18,7 @@
>  
>  #include <config.h>
>  
> +#include "qemu_alias.h"
>  #include "qemu_block.h"
>  #include "qemu_domain.h"
>  
> @@ -484,9 +485,12 @@ qemuBlockStorageSourceGetGlusterProps(virStorageSourcePtr src)
>  
>  static virJSONValuePtr
>  qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src,
> -                                   virQEMUCapsPtr qemuCaps)
> +                                   virQEMUCapsPtr qemuCaps,
> +                                   const char *diskAlias)

As I've pointed out elsewhere, the disk alias should not be passed here,
but rather stored in the disk source structure.

>      const char *protocol = virStorageNetProtocolTypeToString(src->protocol);
> +    char *objalias = NULL;
>      virJSONValuePtr server = NULL;
>      virJSONValuePtr ret = NULL;
>  
> @@ -506,17 +510,34 @@ qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src,
>      if (!(server = qemuBlockStorageSourceBuildHostsJSONSocketAddress(src, true)))
>          return NULL;
>  
> +    if (src->haveTLS == VIR_TRISTATE_BOOL_YES) {
> +        if (!diskAlias) {
> +            virReportError(VIR_ERR_INVALID_ARG, "%s",
> +                           _("disk does not have an alias"));
> +            return NULL;
> +        }
> +
> +        if (!(objalias = qemuAliasTLSObjFromSrcAlias(diskAlias))) {
> +            virJSONValueFree(server);
> +            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", objalias,
>                                   "s:vdisk-id", src->path,
>                                   "a:server", server, NULL) < 0)
>          virJSONValueFree(server);
>  
> +    VIR_FREE(objalias);
> +
>      return ret;
>  }
>  
> @@ -530,7 +551,8 @@ qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src,
>   */
>  virJSONValuePtr
>  qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
> -                                      virQEMUCapsPtr qemuCaps)
> +                                      virQEMUCapsPtr qemuCaps,
> +                                      const char *diskAlias)
>  {
>      int actualType = virStorageSourceGetActualType(src);
>      virJSONValuePtr fileprops = NULL;
> @@ -553,7 +575,8 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
>              break;
>  
>          case VIR_STORAGE_NET_PROTOCOL_VXHS:
> -            if (!(fileprops = qemuBlockStorageSourceGetVxHSProps(src, qemuCaps)))
> +            if (!(fileprops = qemuBlockStorageSourceGetVxHSProps(src, qemuCaps,
> +                                                                 diskAlias)))
>                  goto cleanup;
>              break;
>  

[...]

> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 3205a59..b94ed11 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;

Here it looks like a nice place to allocate the secret alias and set it
into 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)
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list