[libvirt] [PATCH v4 10/14] qemu: Add the ability to hotplug the TLS X.509 environment

John Ferlan jferlan at redhat.com
Thu Jun 23 18:06:35 UTC 2016


If the incoming XML defined a path to a TLS X.509 certificate environment,
add the necessary 'tls-creds-x509' object to the VIR_DOMAIN_CHR_TYPE_TCP
character device.

Likewise, if the environment exists the hot unplug needs adjustment as
well.  Note that all the return ret were changed to goto cleanup since
the cfg needs to be unref'd

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/conf/domain_conf.h       |  1 +
 src/qemu/qemu_command.c      |  2 +-
 src/qemu/qemu_command.h      |  8 +++++++
 src/qemu/qemu_hotplug.c      | 57 +++++++++++++++++++++++++++++++++++++-------
 src/qemu/qemu_monitor_json.c |  9 +++++++
 5 files changed, 68 insertions(+), 9 deletions(-)

diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6e81e52..a06281c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1097,6 +1097,7 @@ struct _virDomainChrSourceDef {
             char *service;
             bool listen;
             int protocol;
+            bool tlscreds;
         } tcp;
         struct {
             char *bindHost;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 12f357a..8b0bd90 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -707,7 +707,7 @@ qemuBuildRBDSecinfoURI(virBufferPtr buf,
  *
  * Returns 0 on success, -1 on failure with error set.
  */
-static int
+int
 qemuBuildTLSx509BackendProps(const char *tlspath,
                              bool listen,
                              bool verifypeer,
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index c4d0567..c22a251 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -61,10 +61,18 @@ virCommandPtr qemuBuildCommandLine(virQEMUDriverPtr driver,
                                    const char *domainLibDir)
     ATTRIBUTE_NONNULL(15);
 
+
 /* Generate the object properties for a secret */
 int qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo,
                              virJSONValuePtr *propsret);
 
+/* Generate the object properties for a tls-creds-x509 */
+int qemuBuildTLSx509BackendProps(const char *tlspath,
+                                 bool listen,
+                                 bool verifypeer,
+                                 virQEMUCapsPtr qemuCaps,
+                                 virJSONValuePtr *propsret);
+
 /* Generate '-device' string for chardev device */
 int
 qemuBuildChrDeviceStr(char **deviceStr,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e4cbbf0..8251444 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1518,10 +1518,14 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
                               virDomainChrDefPtr chr)
 {
     int ret = -1, rc;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainDefPtr vmdef = vm->def;
     char *devstr = NULL;
+    virDomainChrSourceDefPtr dev = &chr->source;
     char *charAlias = NULL;
+    virJSONValuePtr props = NULL;
+    char *objAlias = NULL;
     bool need_release = false;
 
     if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
@@ -1545,8 +1549,26 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
     if (qemuDomainChrPreInsert(vmdef, chr) < 0)
         goto cleanup;
 
+    if (cfg->chardevTLS) {
+        if (qemuBuildTLSx509BackendProps(cfg->chardevTLSx509certdir,
+                                         dev->data.tcp.listen,
+                                         cfg->chardevTLSx509verify,
+                                         priv->qemuCaps,
+                                         &props) < 0)
+            goto cleanup;
+
+        if (virAsprintf(&objAlias, "obj%s_tls0", chr->info.alias) < 0)
+            goto cleanup;
+        dev->data.tcp.tlscreds = true;
+    }
+
     qemuDomainObjEnterMonitor(driver, vm);
-    if (qemuMonitorAttachCharDev(priv->mon, charAlias, &chr->source) < 0)
+
+    if (objAlias && qemuMonitorAddObject(priv->mon, "tls-creds-x509",
+                                         objAlias, props) < 0)
+        goto failobject;
+
+    if (qemuMonitorAttachCharDev(priv->mon, charAlias, dev) < 0)
         goto failchardev;
 
     if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
@@ -1564,14 +1586,20 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
         qemuDomainChrInsertPreAllocCleanup(vmdef, chr);
     if (ret < 0 && need_release)
         qemuDomainReleaseDeviceAddress(vm, &chr->info, NULL);
+    VIR_FREE(objAlias);
+    virJSONValueFree(props);
     VIR_FREE(charAlias);
     VIR_FREE(devstr);
+    virObjectUnref(cfg);
     return ret;
 
  failadddev:
     /* detach associated chardev on error */
     qemuMonitorDetachCharDev(priv->mon, charAlias);
  failchardev:
+    /* Remove the object */
+    ignore_value(qemuMonitorDelObject(priv->mon, objAlias));
+ failobject:
     ignore_value(qemuDomainObjExitMonitor(driver, vm));
     goto audit;
 }
@@ -4082,32 +4110,40 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
                               virDomainChrDefPtr chr)
 {
     int ret = -1;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainDefPtr vmdef = vm->def;
     virDomainChrDefPtr tmpChr;
+    char *objAlias = NULL;
     char *devstr = NULL;
 
     if (!(tmpChr = virDomainChrFind(vmdef, chr))) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                        _("device not present in domain configuration"));
-        return ret;
+        goto cleanup;
     }
 
     if (!tmpChr->info.alias && qemuAssignDeviceChrAlias(vmdef, tmpChr, -1) < 0)
-        return ret;
+        goto cleanup;
 
     sa_assert(tmpChr->info.alias);
 
+    if (cfg->chardevTLS &&
+        virAsprintf(&objAlias, "obj%s_tls0", tmpChr->info.alias) < 0)
+        goto cleanup;
+
     if (qemuBuildChrDeviceStr(&devstr, vmdef, chr, priv->qemuCaps) < 0)
-        return ret;
+        goto cleanup;
 
     qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
 
     qemuDomainObjEnterMonitor(driver, vm);
-    if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
-        ignore_value(qemuDomainObjExitMonitor(driver, vm));
-        goto cleanup;
-    }
+    if (objAlias && qemuMonitorDelObject(priv->mon, objAlias) < 0)
+        goto faildel;
+
+    if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0)
+        goto faildel;
+
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         goto cleanup;
 
@@ -4119,7 +4155,12 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
  cleanup:
     qemuDomainResetDeviceRemoval(vm);
     VIR_FREE(devstr);
+    virObjectUnref(cfg);
     return ret;
+
+ faildel:
+    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    goto cleanup;
 }
 
 
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index bb426dc..548ee99 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6131,6 +6131,7 @@ qemuMonitorJSONAttachCharDevCommand(const char *chrID,
     virJSONValuePtr data = NULL;
     virJSONValuePtr addr = NULL;
     const char *backend_type = NULL;
+    char *tlsalias = NULL;
     bool telnet;
 
     if (!(backend = virJSONValueNewObject()) ||
@@ -6176,6 +6177,13 @@ qemuMonitorJSONAttachCharDevCommand(const char *chrID,
             virJSONValueObjectAppendBoolean(data, "telnet", telnet) < 0 ||
             virJSONValueObjectAppendBoolean(data, "server", chr->data.tcp.listen) < 0)
             goto error;
+        if (chr->data.tcp.tlscreds) {
+            if (virAsprintf(&tlsalias, "obj%s_tls0", chrID) < 0)
+                goto error;
+
+            if (virJSONValueObjectAppendString(data, "tls-creds", tlsalias) < 0)
+                goto error;
+        }
         break;
 
     case VIR_DOMAIN_CHR_TYPE_UDP:
@@ -6241,6 +6249,7 @@ qemuMonitorJSONAttachCharDevCommand(const char *chrID,
     return ret;
 
  error:
+    VIR_FREE(tlsalias);
     virJSONValueFree(addr);
     virJSONValueFree(data);
     virJSONValueFree(backend);
-- 
2.5.5




More information about the libvir-list mailing list