Currently the QEMU driver will reconnect to running guests during libvirtd
startup. To support the ability to launch a fully supported guest externally
to the main libvirtd daemon, this adds a QEMU specific public API
virDomainQemuReconnect(conn, name, flags);
This accepts a domain name, and simply runs the normal reconnect logic that
the QEMU driver would do at startup.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
include/libvirt/libvirt-qemu.h | 4 ++++
src/driver-hypervisor.h | 5 +++++
src/libvirt-qemu.c | 48 ++++++++++++++++++++++++++++++++++++++++++
src/libvirt_qemu.syms | 5 +++++
src/remote/qemu_protocol.x | 18 +++++++++++++++-
src/remote/remote_driver.c | 1 +
6 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/include/libvirt/libvirt-qemu.h b/include/libvirt/libvirt-qemu.h
index 2bb8ee8685..0d38d2f9f8 100644
--- a/include/libvirt/libvirt-qemu.h
+++ b/include/libvirt/libvirt-qemu.h
@@ -44,6 +44,10 @@ virDomainPtr virDomainQemuAttach(virConnectPtr domain,
unsigned int pid_value,
unsigned int flags);
+virDomainPtr virDomainQemuReconnect(virConnectPtr domain,
+ const char *name,
+ unsigned int flags);
+
typedef enum {
VIR_DOMAIN_QEMU_AGENT_COMMAND_MIN = -2,
VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK = -2,
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index ce0e2b2525..2e923e730f 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -848,6 +848,10 @@ typedef virDomainPtr
(*virDrvDomainQemuAttach)(virConnectPtr conn,
unsigned int pid_value,
unsigned int flags);
+typedef virDomainPtr
+(*virDrvDomainQemuReconnect)(virConnectPtr conn,
+ const char *name,
+ unsigned int flags);
typedef int
(*virDrvConnectDomainQemuMonitorEventRegister)(virConnectPtr conn,
@@ -1463,6 +1467,7 @@ struct _virHypervisorDriver {
virDrvDomainSnapshotDelete domainSnapshotDelete;
virDrvDomainQemuMonitorCommand domainQemuMonitorCommand;
virDrvDomainQemuAttach domainQemuAttach;
+ virDrvDomainQemuReconnect domainQemuReconnect;
virDrvDomainQemuAgentCommand domainQemuAgentCommand;
virDrvConnectDomainQemuMonitorEventRegister connectDomainQemuMonitorEventRegister;
virDrvConnectDomainQemuMonitorEventDeregister
connectDomainQemuMonitorEventDeregister;
diff --git a/src/libvirt-qemu.c b/src/libvirt-qemu.c
index 43f63839eb..c5859cf312 100644
--- a/src/libvirt-qemu.c
+++ b/src/libvirt-qemu.c
@@ -164,6 +164,54 @@ virDomainQemuAttach(virConnectPtr conn,
return NULL;
}
+/**
+ * virDomainQemuReconnect:
+ * @conn: pointer to a hypervisor connection
+ * @name: the libvirt guest name
+ * @flags: optional flags, currently unused
+ *
+ * This API is QEMU specific, so it will only work with hypervisor
+ * connections to the QEMU driver.
+ *
+ * This API will attach to an QEMU process that a separate libvirt
+ * helper has launched. The external QEMU must fully follow the
+ * normal libvirt QEMU configuration.
+ *
+ * If successful, then the guest will appear in the list of running
+ * domains for this connection, and other APIs should operate
+ * normally (provided the above requirements were honored).
+ *
+ * Returns a new domain object on success, NULL otherwise
+ */
+virDomainPtr
+virDomainQemuReconnect(virConnectPtr conn,
+ const char *name,
+ unsigned int flags)
+{
+ VIR_DEBUG("conn=%p, name=%s, flags=0x%x", conn, name, flags);
+
+ virResetLastError();
+
+ virCheckConnectReturn(conn, NULL);
+ virCheckNonNullArgGoto(name, error);
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if (conn->driver->domainQemuReconnect) {
+ virDomainPtr ret;
+ ret = conn->driver->domainQemuReconnect(conn, name, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
/**
* virDomainQemuAgentCommand:
diff --git a/src/libvirt_qemu.syms b/src/libvirt_qemu.syms
index 3a297e3a2b..a109fcc0d0 100644
--- a/src/libvirt_qemu.syms
+++ b/src/libvirt_qemu.syms
@@ -30,3 +30,8 @@ LIBVIRT_QEMU_1.2.3 {
virConnectDomainQemuMonitorEventDeregister;
virConnectDomainQemuMonitorEventRegister;
} LIBVIRT_QEMU_0.10.0;
+
+LIBVIRT_QEMU_4.1.0 {
+ global:
+ virDomainQemuReconnect;
+} LIBVIRT_QEMU_1.2.3;
diff --git a/src/remote/qemu_protocol.x b/src/remote/qemu_protocol.x
index f6b88a984c..b5307bf9dd 100644
--- a/src/remote/qemu_protocol.x
+++ b/src/remote/qemu_protocol.x
@@ -82,6 +82,15 @@ struct qemu_domain_monitor_event_msg {
remote_string details;
};
+struct qemu_domain_reconnect_args {
+ remote_nonnull_string name;
+ unsigned int flags;
+};
+
+struct qemu_domain_reconnect_ret {
+ remote_nonnull_domain dom;
+};
+
/* Define the program number, protocol version and procedure numbers here. */
const QEMU_PROGRAM = 0x20008087;
const QEMU_PROTOCOL_VERSION = 1;
@@ -154,5 +163,12 @@ enum qemu_procedure {
* @generate: both
* @acl: none
*/
- QEMU_PROC_DOMAIN_MONITOR_EVENT = 6
+ QEMU_PROC_DOMAIN_MONITOR_EVENT = 6,
+
+ /**
+ * @generate: both
+ * @acl: domain:start
+ * @acl: domain:write
+ */
+ QEMU_PROC_DOMAIN_RECONNECT = 7
};
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index f8fa64af99..b76242fe2e 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8431,6 +8431,7 @@ static virHypervisorDriver hypervisor_driver = {
.domainSnapshotDelete = remoteDomainSnapshotDelete, /* 0.8.0 */
.domainQemuMonitorCommand = remoteDomainQemuMonitorCommand, /* 0.8.3 */
.domainQemuAttach = remoteDomainQemuAttach, /* 0.9.4 */
+ .domainQemuReconnect = remoteDomainQemuReconnect, /* 4.1.0 */
.domainQemuAgentCommand = remoteDomainQemuAgentCommand, /* 0.10.0 */
.connectDomainQemuMonitorEventRegister = remoteConnectDomainQemuMonitorEventRegister,
/* 1.2.3 */
.connectDomainQemuMonitorEventDeregister =
remoteConnectDomainQemuMonitorEventDeregister, /* 1.2.3 */
--
2.14.3