[PATCH v1] Introduce virDomainReloadTLSCertificates API

Yanzheng (A) yanzheng759 at huawei.com
Thu May 6 03:31:53 UTC 2021


Introduce a new virDomainReloadTLSCertificates API for notify domain
reload its certificates without restart, and avoid service interruption.

Take reload QEMU VNC TLS certificates as an example, we can call:

  virDomainReloadTLSCertificates(dom, VIR_DOMAIN_TLS_CERT_GRAPHICS_VNC)

Then the specified QMP message would be send to QEMU:
{"execute": "display-reload", "arguments":{"type": "vnc", "tls-certs": true}}

Refers:
https://gitlab.com/qemu-project/qemu/-/commit/9cc07651655ee86eca41059f5ead8c4e5607c734
---
include/libvirt/libvirt-domain.h | 17 ++++++++++++++++
src/driver-hypervisor.h          |  5 +++++
src/libvirt-domain.c             | 33 ++++++++++++++++++++++++++++++++
src/qemu/qemu_driver.c           | 11 +++++++++++
src/qemu/qemu_hotplug.c          | 21 ++++++++++++++++++++
src/qemu/qemu_hotplug.h          |  4 ++++
src/qemu/qemu_monitor.c          | 10 ++++++++++
src/qemu/qemu_monitor.h          |  3 +++
src/qemu/qemu_monitor_json.c     | 22 +++++++++++++++++++++
src/qemu/qemu_monitor_json.h     |  3 +++
10 files changed, 129 insertions(+)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index e99bfb7654..aeb33d69d9 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -5152,4 +5152,21 @@ int virDomainStartDirtyRateCalc(virDomainPtr domain,
                                 int seconds,
                                 unsigned int flags);
+/**
+ * virDomainTLSCertificaType:
+ *
+ * the used scene of TLS certificates for doamin.
+ */
+typedef enum {
+    VIR_DOMAIN_TLS_CERT_GRAPHICS_VNC      = 0,
+    VIR_DOMAIN_TLS_CERT_GRAPHICS_SPICE    = 1,
+
+    VIR_DOMAIN_TLS_CERT_LAST
+} virDomainTLSCertificaType;
+
+int
+virDomainReloadTLSCertificates(virDomainPtr domain,
+                               unsigned int type);
+
+
#endif /* LIBVIRT_DOMAIN_H */
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index d642af8a37..8de2bc4137 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -1410,6 +1410,10 @@ typedef int
                                   int seconds,
                                   unsigned int flags);
+typedef int
+(*virDrvDomainReloadTLSCertificates)(virDomainPtr domain,
+                                     unsigned int type);
+
typedef struct _virHypervisorDriver virHypervisorDriver;
 /**
@@ -1676,4 +1680,5 @@ struct _virHypervisorDriver {
     virDrvDomainAuthorizedSSHKeysSet domainAuthorizedSSHKeysSet;
     virDrvDomainGetMessages domainGetMessages;
     virDrvDomainStartDirtyRateCalc domainStartDirtyRateCalc;
+    virDrvDomainReloadTLSCertificates domainiReloadTLSCertificates;
};
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 42c75f6cc5..fb9e5ec2d1 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -13218,3 +13218,36 @@ virDomainStartDirtyRateCalc(virDomainPtr domain,
     virDispatchError(conn);
     return -1;
}
+
+/**
+ * virDomainReloadTLSCertificates:
+ * @domain: a domain object.
+ * @type: a value of virDomainTLSCertificaType
+ *
+ * Notify domain reload its certificates with specified 'type'.
+ *
+ * Returns 0 in case of success, -1 otherwise .
+ */
+int
+virDomainReloadTLSCertificates(virDomainPtr domain,
+                               unsigned int type)
+{
+    virConnectPtr conn;
+    VIR_DOMAIN_DEBUG(domain, "certificate type=%d", type);
+    virResetLastError();
+    virCheckDomainReturn(domain, -1);
+    conn = domain->conn;
+    if (type >= VIR_DOMAIN_TLS_CERT_LAST)
+        goto error;
+    if (conn->driver->domainiReloadTLSCertificates) {
+        int ret;
+        ret = conn->driver->domainiReloadTLSCertificates(domain, type);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+    virReportUnsupportedError();
+ error:
+    virDispatchError(domain->conn);
+    return -1;
+}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c90d52edc0..61cd8cfa24 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20449,6 +20449,16 @@ qemuDomainStartDirtyRateCalc(virDomainPtr dom,
     return ret;
}
+static int
+qemuDomainReloadTLSCertificates(virDomainPtr domain,
+                                unsigned int type)
+{
+    virQEMUDriver *driver = domain->conn->privateData;
+    virDomainObj *vm = qemuDomainObjFromDomain(domain);
+    if (!driver || !vm)
+        return -1;
+    return qemuDomainReloadTLSCerts(driver, vm, type);
+}
 static virHypervisorDriver qemuHypervisorDriver = {
     .name = QEMU_DRIVER_NAME,
@@ -20693,6 +20703,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
     .domainAuthorizedSSHKeysSet = qemuDomainAuthorizedSSHKeysSet, /* 6.10.0 */
     .domainGetMessages = qemuDomainGetMessages, /* 7.1.0 */
     .domainStartDirtyRateCalc = qemuDomainStartDirtyRateCalc, /* 7.2.0 */
+    .domainiReloadTLSCertificates = qemuDomainReloadTLSCertificates, /* 7.2.0 */
};

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 444d89d64a..013d8728a0 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -6704,3 +6704,24 @@ qemuDomainSetVcpuInternal(virQEMUDriver *driver,
     virBitmapFree(livevcpus);
     return ret;
}
+
+int qemuDomainReloadTLSCerts(virQEMUDriverPtr driver,
+                             virDomainObjPtr vm,
+                             int type)
+{
+    int ret = -1;
+    qemuDomainObjPrivate *priv = vm->privateData;
+    /* for now, only VNC is supported */
+    if (type != VIR_DOMAIN_TLS_CERT_GRAPHICS_VNC)
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("invalid certificate type=%d, only support VNC"),
+                       type);
+        return ret;
+    }
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
+        return ret;
+    ret = qemuMonitorReloadTLSCerts(priv->mon, type);
+    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        ret = -1;
+    return ret;
+}
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index df8f76f8d6..44afe23f0a 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -160,3 +160,7 @@ int qemuHotplugAttachDBusVMState(virQEMUDriver *driver,
int qemuHotplugRemoveDBusVMState(virQEMUDriver *driver,
                                  virDomainObj *vm,
                                  qemuDomainAsyncJob asyncJob);
+
+int qemuDomainReloadTLSCerts(virQEMUDriverPtr driver,
+                             virDomainObjPtr vm,
+                             int type);
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 3a7f231ce0..952ef87a6b 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4746,3 +4746,13 @@ qemuMonitorQueryDirtyRate(qemuMonitor *mon,
     return qemuMonitorJSONQueryDirtyRate(mon, info);
}
+
+int
+qemuMonitorReloadTLSCerts(qemuMonitorPtr mon, int type)
+{
+    const char *protocol = qemuMonitorTypeToProtocol(type);
+    if (!protocol)
+        return -1;
+    VIR_DEBUG("protocol=%s", protocol);
+    return qemuMonitorJSONReloadTLSCerts(mon, protocol);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 6a25def78b..a5b702b023 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1496,3 +1496,6 @@ struct _qemuMonitorDirtyRateInfo {
int
qemuMonitorQueryDirtyRate(qemuMonitor *mon,
                           qemuMonitorDirtyRateInfo *info);
+
+int qemuMonitorReloadTLSCerts(qemuMonitorPtr mon,
+                              int type);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 46aa3330a8..d2b06c4703 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -9446,3 +9446,25 @@ qemuMonitorJSONQueryDirtyRate(qemuMonitor *mon,
     return qemuMonitorJSONExtractDirtyRateInfo(data, info);
}
+
+int qemuMonitorJSONReloadTLSCerts(qemuMonitorPtr mon,
+                                  const char *protocol)
+{
+    int ret = -1;
+    virJSONValuePtr reply = NULL;
+    virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("display-reload",
+                                                     "s:type", protocol,
+                                                     "b:tls-certs", 1,
+                                                     NULL);
+    if (!cmd)
+        return -1;
+    if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+        goto cleanup;
+    if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+        goto cleanup;
+    ret = 0;
+ cleanup:
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 01a3ba25f1..d9ad77e873 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -706,3 +706,6 @@ qemuMonitorJSONStartDirtyRateCalc(qemuMonitor *mon,
int
qemuMonitorJSONQueryDirtyRate(qemuMonitor *mon,
                               qemuMonitorDirtyRateInfo *info);
+
+int qemuMonitorJSONReloadTLSCerts(qemuMonitorPtr mon,
+                                  const char *protocol);
--
2.25.1

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20210506/f9fa2699/attachment-0001.htm>


More information about the libvir-list mailing list