[libvirt] [PATCH v5 5/9] Add TLS support for Veritas HyperScale (VxHS) block device protocol

Ashish Mittal ashmit602 at gmail.com
Tue Aug 29 06:39:29 UTC 2017


The following describes the behavior of TLS for VxHS block device:

(1) Two new options have been added in /etc/libvirt/qemu.conf
    to control TLS behavior with VxHS block devices
    "vxhs_tls" and "vxhs_tls_x509_cert_dir".
(2) Setting "vxhs_tls=1" in /etc/libvirt/qemu.conf will enable
    TLS for VxHS block devices.
(3) "vxhs_tls_x509_cert_dir" can be set to the full path where the
    TLS certificates and keys are saved. If this value is missing,
    the "default_tls_x509_cert_dir" will be used instead.
(4) If the value of "vxhs_tls" is set to 1, TLS creds will be added
    automatically on the qemu command line for every VxHS
    block device.
(5) With "vxhs_tls=1", TLS may selectively be disabled on individual
    VxHS disks by specifying tls='no' in the device domain
    specification.
(6) Valid values for domain TLS setting are tls='yes|no'.
(7) tls='yes' can only be specified if "vxhs_tls" is enabled.
    Specifying tls='yes' when "vxhs_tls=0" results in an error.

QEMU changes for VxHS (including TLS support) are already upstream.

Sample TLS args generated by libvirt -
-object tls-creds-x509,id=objvxhs_tls0,dir=/usr/local/etc/pki/qemu,\
endpoint=client,verify-peer=yes \
-drive file.driver=vxhs,file.tls-creds=objvxhs_tls0,\
file.vdisk-id=eb90327c-8302-4725-9e1b-4e85ed4dc251,\
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

Signed-off-by: Ashish Mittal <Ashish.Mittal at veritas.com>
---
v5 changelog:
(1) The v4 3/3 patch has been split into smaller chunks.
(2) Functionally there are no changes in TLS code yet.

TODO: Changes to TLS functionality are pending.

 docs/schemas/domaincommon.rng |  5 ++++
 src/conf/domain_conf.c        | 19 ++++++++++++
 src/qemu/qemu_block.c         | 42 +++++++++++++++++++--------
 src/qemu/qemu_command.c       | 67 +++++++++++++++++++++++++++++++++++++++++++
 src/util/virstoragefile.c     | 13 +++++++++
 src/util/virstoragefile.h     |  9 ++++++
 6 files changed, 143 insertions(+), 12 deletions(-)

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 458b8d8..af38c9a 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1651,6 +1651,11 @@
       </attribute>
       <attribute name="name"/>
         <ref name="diskSourceNetworkHost"/>
+        <optional>
+          <attribute name="tls">
+            <ref name="virYesNo"/>
+          </attribute>
+        </optional>
     </element>
   </define>
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5bad397..f3fb3d0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8017,6 +8017,7 @@ virDomainDiskSourceParse(xmlNodePtr node,
     int ret = -1;
     char *protocol = NULL;
     xmlNodePtr saveNode = ctxt->node;
+    char *haveTLS = NULL;
 
     ctxt->node = node;
 
@@ -8050,6 +8051,19 @@ virDomainDiskSourceParse(xmlNodePtr node,
             goto cleanup;
         }
 
+        /* Check tls=yes|no domain setting for the block device */
+        /* At present only VxHS. Other block devices may be added later */
+        if ((haveTLS = virXMLPropString(node, "tls")) &&
+            src->protocol == VIR_STORAGE_NET_PROTOCOL_VXHS) {
+            if ((src->haveTLS =
+                virTristateBoolTypeFromString(haveTLS)) <= 0) {
+                virReportError(VIR_ERR_XML_ERROR,
+                           _("unknown VxHS 'tls' setting '%s'"),
+                           haveTLS);
+                goto cleanup;
+            }
+        }
+
         /* for historical reasons the volume name for gluster volume is stored
          * as a part of the path. This is hard to work with when dealing with
          * relative names. Split out the volume into a separate variable */
@@ -8105,6 +8119,7 @@ virDomainDiskSourceParse(xmlNodePtr node,
 
  cleanup:
     VIR_FREE(protocol);
+    VIR_FREE(haveTLS);
     ctxt->node = saveNode;
     return ret;
 }
@@ -21534,6 +21549,10 @@ virDomainDiskSourceFormatNetwork(virBufferPtr buf,
 
     VIR_FREE(path);
 
+    if (src->haveTLS != VIR_TRISTATE_BOOL_ABSENT)
+        virBufferAsprintf(buf, " tls='%s'",
+                          virTristateBoolTypeToString(src->haveTLS));
+
     if (src->nhosts == 0 && !src->snapshot && !src->configFile) {
         virBufferAddLit(buf, "/>\n");
     } else {
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index a4d0160..766d07f 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -519,20 +519,38 @@ qemuBlockStorageSourceGetVxHSProps(virStorageSourcePtr src)
     if (!(server = qemuBuildVxHSDriveJSONHost(src)))
         return NULL;
 
-    /* VxHS disk specification example:
-     * { driver:"vxhs",
-     *   vdisk-id:"eb90327c-8302-4725-4e85ed4dc251",
-     *   server.host:"1.2.3.4",
-     *   server.port:1234}
-     */
-    if (virJSONValueObjectCreate(&ret,
-                                 "s:driver", protocol,
-                                 "s:vdisk-id", src->path,
-                                 "a:server", server, NULL) < 0) {
-        virJSONValueFree(server);
-        ret = NULL;
+    if (src->addTLS == true) {
+        char *objalias = NULL;
+
+        if (!(objalias = qemuAliasTLSObjFromSrcAlias("vxhs")))
+            goto cleanup;
+
+        if (virJSONValueObjectCreate(&ret,
+                                     "s:driver", protocol,
+                                     "s:tls-creds", objalias,
+                                     "s:vdisk-id", src->path,
+                                     "a:server", server, NULL) < 0) {
+            virJSONValueFree(server);
+            ret = NULL;
+        }
+        VIR_FREE(objalias);
+    } else {
+        /* VxHS disk specification example:
+         * { driver:"vxhs",
+         *   vdisk-id:"eb90327c-8302-4725-4e85ed4dc251",
+         *   server.host:"1.2.3.4",
+         *   server.port:1234}
+         */
+        if (virJSONValueObjectCreate(&ret,
+                                     "s:driver", protocol,
+                                     "s:vdisk-id", src->path,
+                                     "a:server", server, NULL) < 0) {
+            virJSONValueFree(server);
+            ret = NULL;
+        }
     }
 
+ cleanup:
     return ret;
 }
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0fd2674..384a489 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -791,6 +791,70 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd,
 }
 
 
+
+/* qemuBuildDiskVxHSTLSinfoCommandLine:
+ * @cmd: Pointer to the command string
+ * @cfg: Pointer to the qemu driver config
+ * @disk: The disk we are processing
+ * @qemuCaps: qemu capabilities object
+ *
+ * Check if the VxHS disk meets all the criteria to enable TLS.
+ * If yes, add a new TLS object and mention it's ID on the disk
+ * command line.
+ *
+ * Returns 0 on success, -1 w/ error on some sort of failure.
+ */
+static int
+qemuBuildDiskVxHSTLSinfoCommandLine(virCommandPtr cmd,
+                                    virQEMUDriverConfigPtr cfg,
+                                    virDomainDiskDefPtr disk,
+                                    virQEMUCapsPtr qemuCaps)
+{
+    int ret = 0;
+
+    if (cfg->vxhsTLS  == true && disk->src->haveTLS != VIR_TRISTATE_BOOL_NO) {
+            disk->src->addTLS = true;
+            ret = qemuBuildTLSx509CommandLine(cmd, cfg->vxhsTLSx509certdir,
+                                              false,
+                                              true,
+                                              false,
+                                              "vxhs",
+                                              qemuCaps);
+    } else if (cfg->vxhsTLS  == false &&
+               disk->src->haveTLS == VIR_TRISTATE_BOOL_YES) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("Please enable VxHS specific TLS options in the qemu "
+                         "conf file before using TLS in VxHS device domain "
+                         "specification"));
+        ret = -1;
+    }
+
+    return ret;
+}
+
+
+/* qemuBuildDiskTLSinfoCommandLine:
+ *
+ * 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
+qemuBuildDiskTLSinfoCommandLine(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)
+        return qemuBuildDiskVxHSTLSinfoCommandLine(cmd, cfg, disk, qemuCaps);
+
+    return 0;
+}
+
+
 static char *
 qemuBuildNetworkDriveURI(virStorageSourcePtr src,
                          qemuDomainSecretInfoPtr secinfo)
@@ -2218,6 +2282,9 @@ qemuBuildDiskDriveCommandLine(virCommandPtr cmd,
         if (qemuBuildDiskSecinfoCommandLine(cmd, encinfo) < 0)
             return -1;
 
+        if (qemuBuildDiskTLSinfoCommandLine(cmd, cfg, disk, qemuCaps) < 0)
+            return -1;
+
         virCommandAddArg(cmd, "-drive");
 
         if (!(optstr = qemuBuildDriveStr(disk, cfg, driveBoot, qemuCaps)))
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index e9a59e0..d4f0fdb 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -2039,6 +2039,8 @@ virStorageSourceCopy(const virStorageSource *src,
     ret->physical = src->physical;
     ret->readonly = src->readonly;
     ret->shared = src->shared;
+    ret->haveTLS = src->haveTLS;
+    ret->addTLS = src->addTLS;
 
     /* storage driver metadata are not copied */
     ret->drv = NULL;
@@ -3219,6 +3221,7 @@ virStorageSourceParseBackingJSONVxHS(virStorageSourcePtr src,
 {
     const char *vdisk_id = virJSONValueObjectGetString(json, "vdisk-id");
     virJSONValuePtr server = virJSONValueObjectGetObject(json, "server");
+    const char *haveTLS = virJSONValueObjectGetString(json, "tls");
 
     if (!vdisk_id || !server) {
         virReportError(VIR_ERR_INVALID_ARG, "%s",
@@ -3227,6 +3230,16 @@ virStorageSourceParseBackingJSONVxHS(virStorageSourcePtr src,
         return -1;
     }
 
+    if (haveTLS) {
+        if ((src->haveTLS =
+            virTristateBoolTypeFromString(haveTLS)) <= 0) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("unknown VxHS 'tls' setting '%s'"),
+                           haveTLS);
+            return -1;
+        }
+    }
+
     src->type = VIR_STORAGE_TYPE_NETWORK;
     src->protocol = VIR_STORAGE_NET_PROTOCOL_VXHS;
 
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index f7e897f..0f363a7 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -281,6 +281,15 @@ struct _virStorageSource {
     /* metadata that allows identifying given storage source */
     char *nodeformat;  /* name of the format handler object */
     char *nodestorage; /* name of the storage object */
+
+    /* This is the domain specific setting.
+     * It may be absent */
+    int haveTLS; /* enum virTristateBool */
+
+    /* This should be set to "true" only when TLS creds are to be added for
+     * the device. For e.g. this could be based on a combination of
+     * global conf setting + domain specific setting */
+    bool addTLS;
 };
 
 
-- 
2.5.5




More information about the libvir-list mailing list