[libvirt] [PATCH 3/5] qemu: add a public API to trigger QEMU driver to connect to running guest

Daniel P. Berrange posted 5 patches 7 years, 4 months ago
[libvirt] [PATCH 3/5] qemu: add a public API to trigger QEMU driver to connect to running guest
Posted by Daniel P. Berrange 7 years, 4 months ago
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@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

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 3/5] qemu: add a public API to trigger QEMU driver to connect to running guest
Posted by John Ferlan 7 years, 4 months ago

On 12/20/2017 11:47 AM, Daniel P. Berrange wrote:
> 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@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(-)
> 

Build for me failed on this patch during build of various
src/*_protocol_struct files:

--- qemu_protocol-structs	2016-01-13 07:49:19.459819838 -0500
+++ qemu_protocol-struct-t3	2017-12-21 13:42:37.836063667 -0500
@@ -47,6 +47,13 @@
         u_int                      micros;
         remote_string              details;
 };
+struct qemu_domain_reconnect_args {
+        remote_nonnull_string      name;
+        u_int                      flags;
+};
+struct qemu_domain_reconnect_ret {
+        remote_nonnull_domain      dom;
+};
 enum qemu_procedure {
         QEMU_PROC_DOMAIN_MONITOR_COMMAND = 1,
         QEMU_PROC_DOMAIN_ATTACH = 2,
@@ -54,4 +61,5 @@
         QEMU_PROC_CONNECT_DOMAIN_MONITOR_EVENT_REGISTER = 4,
         QEMU_PROC_CONNECT_DOMAIN_MONITOR_EVENT_DEREGISTER = 5,
         QEMU_PROC_DOMAIN_MONITOR_EVENT = 6,
+        QEMU_PROC_DOMAIN_RECONNECT = 7,
 };


Otherwise, looks reasonable/right to me.

John

> 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 */
> 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list