[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v3 31/31] libxl: QEMU startup sync based on QMP



This is only activated when dm_restrict=1, as explained in the previous
patch "libxl_dm: Pre-open QMP socket for QEMU"

Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
 tools/libxl/libxl_dm.c       |  7 ++++++
 tools/libxl/libxl_exec.c     | 44 ++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.h |  5 ++++
 3 files changed, 56 insertions(+)

diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 10b35d822a..4e89e09fc8 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -2398,6 +2398,13 @@ retry_transaction:
     spawn->failure_cb = device_model_startup_failed;
     spawn->detached_cb = device_model_detached;
 
+    spawn->qmp_domid = INVALID_DOMID;
+    if (dm_monitor_fd >= 0) {
+        /* There is a valid QMP socket available now, have libxl__spawn_spawn
+         * use it to find out when QEMU is ready */
+        spawn->qmp_domid = domid;
+    }
+
     rc = libxl__spawn_spawn(egc, spawn);
     if (rc < 0)
         goto out_close;
diff --git a/tools/libxl/libxl_exec.c b/tools/libxl/libxl_exec.c
index 02e6c917f0..e61297ed2f 100644
--- a/tools/libxl/libxl_exec.c
+++ b/tools/libxl/libxl_exec.c
@@ -258,6 +258,9 @@ err:
 /* Event callbacks. */
 static void spawn_watch_event(libxl__egc *egc, libxl__xswait_state *xswa,
                               int rc, const char *xsdata);
+static void spawn_qmp_callback(libxl__egc *egc, libxl__ev_qmp *ev,
+                               const libxl__json_object *response,
+                               libxl__qmp_error_class error);
 static void spawn_middle_death(libxl__egc *egc, libxl__ev_child *childw,
                                pid_t pid, int status);
 
@@ -272,6 +275,7 @@ void libxl__spawn_init(libxl__spawn_state *ss)
 {
     libxl__ev_child_init(&ss->mid);
     libxl__xswait_init(&ss->xswait);
+    libxl__ev_qmp_init(&ss->ev_qmp);
 }
 
 int libxl__spawn_spawn(libxl__egc *egc, libxl__spawn_state *ss)
@@ -291,6 +295,11 @@ int libxl__spawn_spawn(libxl__egc *egc, libxl__spawn_state 
*ss)
     ss->xswait.callback = spawn_watch_event;
     rc = libxl__xswait_start(gc, &ss->xswait);
     if (rc) goto out_err;
+    if (ss->qmp_domid != INVALID_DOMID) {
+        rc = libxl__ev_qmp_register(gc, &ss->ev_qmp, spawn_qmp_callback,
+                                    ss->qmp_domid, "query-status", NULL);
+        if (rc) goto out_err;
+    }
 
     pid_t middle = libxl__ev_child_fork(gc, &ss->mid, spawn_middle_death);
     if (middle ==-1) { rc = ERROR_FAIL; goto out_err; }
@@ -347,6 +356,7 @@ static void spawn_cleanup(libxl__gc *gc, libxl__spawn_state 
*ss)
 {
     assert(!libxl__ev_child_inuse(&ss->mid));
     libxl__xswait_stop(gc, &ss->xswait);
+    libxl__ev_qmp_deregister(gc, &ss->ev_qmp);
 }
 
 static void spawn_detach(libxl__gc *gc, libxl__spawn_state *ss)
@@ -359,6 +369,7 @@ static void spawn_detach(libxl__gc *gc, libxl__spawn_state 
*ss)
     assert(libxl__ev_child_inuse(&ss->mid));
     assert(ss->detaching || ss->rc);
     libxl__xswait_stop(gc, &ss->xswait);
+    libxl__ev_qmp_deregister(gc, &ss->ev_qmp);
 
     pid_t child = ss->mid.pid;
     r = kill(child, SIGKILL);
@@ -399,6 +410,39 @@ static void spawn_watch_event(libxl__egc *egc, 
libxl__xswait_state *xswa,
     ss->confirm_cb(egc, ss, p); /* must be last */
 }
 
+static void spawn_qmp_callback(libxl__egc *egc, libxl__ev_qmp *ev,
+                               const libxl__json_object *response,
+                               libxl__qmp_error_class error)
+{
+    EGC_GC;
+    libxl__spawn_state *ss = CONTAINER_OF(ev, *ss, ev_qmp);
+    const libxl__json_object *o;
+    const char *status;
+
+    if (error) {
+        goto failed;
+    }
+    o = libxl__json_map_get("status", response, JSON_STRING);
+    if (!o) {
+        LOGD(DEBUG, ev->domid, "QMP unexpected response");
+        goto failed;
+    }
+    status = libxl__json_object_get_string(o);
+    if (!strcmp(status, "running")) {
+        /* success */
+    } else {
+        LOGD(DEBUG, ev->domid, "Unexpected QEMU status: %s", status);
+        goto failed;
+    }
+
+    ss->confirm_cb(egc, ss, status); /* must be last */
+    return;
+
+failed:
+    LOGD(ERROR, ev->domid, "QEMU did not start properly");
+    spawn_fail(egc, ss, ERROR_FAIL); /* must be last */
+}
+
 static void spawn_middle_death(libxl__egc *egc, libxl__ev_child *childw,
                                pid_t pid, int status)
     /* On entry, is Attached or Detaching */
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 371b27e866..61cc8c9f0c 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1603,11 +1603,16 @@ struct libxl__spawn_state {
     libxl__spawn_confirm_cb *confirm_cb;
     libxl__spawn_detached_cb *detached_cb;
 
+    /* If qmp_domid != INVALID_DOMID, then libxl__spawn_spawn will also use QMP
+     * to find out when the process is started */
+    uint32_t qmp_domid;
+
     /* remaining fields are private to libxl_spawn_... */
     int detaching; /* we are in Detaching */
     int rc; /* might be non-0 whenever we are not Idle */
     libxl__ev_child mid; /* always in use whenever we are not Idle */
     libxl__xswait_state xswait;
+    libxl__ev_qmp ev_qmp;
 };
 
 static inline int libxl__spawn_inuse(const libxl__spawn_state *ss)
-- 
Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.