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 |