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

[Xen-devel] [RFC PATCH 16/17] libxl: access QMP socket via console for qemu-in-stubdomain



Add support for talking with qemu in stubdomain via QMP connected to a
console. Since a console doesn't have out of band connect/disconnect
signaling, use (new) qmp_reset command at every connect, to force
renegotiation.

This commit doesn't deal with multiple users accessing the same console.
For example all connected libxl users will see responses for commands
send by any user. If commands IDs would be unique (they aren't),
theoretically that wouldn't be a problem. But two instances sending
commands at once is still problematic.
---
 tools/libxl/libxl_dm.c       | 18 ++++++++-----
 tools/libxl/libxl_internal.h |  5 ++--
 tools/libxl/libxl_qmp.c      | 52 +++++++++++++++++++++++++++++++++----
 3 files changed, 62 insertions(+), 13 deletions(-)

diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 11acbea..062020e 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -959,18 +959,23 @@ static int libxl__build_device_model_args_new(libxl__gc 
*gc,
                       "-xen-domid",
                       GCSPRINTF("%d", guest_domid), NULL);
 
-    /* There is currently no way to access the QMP socket in the stubdom */
-    if (!is_stubdom) {
-        flexarray_append(dm_args, "-chardev");
+    flexarray_append(dm_args, "-chardev");
+    /* stubdom + qemu-xen implies linux based stubdom */
+    if (is_stubdom)
+        flexarray_append(dm_args,
+                         GCSPRINTF("serial,id=libxl-cmd,path=/dev/hvc%d",
+                                   STUBDOM_CONSOLE_QMP));
+    else
         flexarray_append(dm_args,
                          GCSPRINTF("socket,id=libxl-cmd,"
                                         "path=%s/qmp-libxl-%d,server,nowait",
                                         libxl__run_dir_path(), guest_domid));
 
-        flexarray_append(dm_args, "-no-shutdown");
-        flexarray_append(dm_args, "-mon");
-        flexarray_append(dm_args, "chardev=libxl-cmd,mode=control");
+    flexarray_append(dm_args, "-no-shutdown");
+    flexarray_append(dm_args, "-mon");
+    flexarray_append(dm_args, "chardev=libxl-cmd,mode=control");
 
+    if (!is_stubdom) {
         flexarray_append(dm_args, "-chardev");
         flexarray_append(dm_args,
                          GCSPRINTF("socket,id=libxenstat-cmd,"
@@ -2132,6 +2137,7 @@ static void spawn_stub_launch_dm(libxl__egc *egc,
         /* STUBDOM_CONSOLE_LOGGING (console 0) is for minios logging
          * STUBDOM_CONSOLE_SAVE (console 1) is for writing the save file
          * STUBDOM_CONSOLE_RESTORE (console 2) is for reading the save file
+         * STUBDOM_CONSOLE_QMP (console 3) is for accessing qmp socket (linux 
stubdom only)
          */
         switch (i) {
             char *filename;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 9a01aa3..2aa8c8a 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -115,8 +115,9 @@
 #define STUBDOM_CONSOLE_LOGGING 0
 #define STUBDOM_CONSOLE_SAVE 1
 #define STUBDOM_CONSOLE_RESTORE 2
-#define STUBDOM_CONSOLE_SERIAL 3
-#define STUBDOM_SPECIAL_CONSOLES 3
+#define STUBDOM_CONSOLE_QMP 3
+#define STUBDOM_CONSOLE_SERIAL 4
+#define STUBDOM_SPECIAL_CONSOLES 4
 #define LIBXL_LINUX_STUBDOM_MEM 128
 #define TAP_DEVICE_SUFFIX "-emu"
 #define DOMID_XS_PATH "domid"
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 0fe4281..8ba558b 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -431,6 +431,16 @@ out:
     return ret;
 }
 
+static int qmp_open_pty(libxl__qmp_handler *qmp, const char *qmp_pty_path)
+{
+    qmp->qmp_fd = open(qmp_pty_path,
+                       O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC);
+    if (qmp->qmp_fd < 0) {
+        return -1;
+    }
+    return 0;
+}
+
 static void qmp_close(libxl__qmp_handler *qmp)
 {
     callback_id_pair *pp = NULL;
@@ -720,15 +730,47 @@ libxl__qmp_handler *libxl__qmp_initialize(libxl__gc *gc, 
uint32_t domid)
     int ret = 0;
     libxl__qmp_handler *qmp = NULL;
     char *qmp_socket;
+    uint32_t dm_domid = libxl_get_stubdom_id(CTX, domid);
 
     qmp = qmp_init_handler(gc, domid);
     if (!qmp) return NULL;
 
-    qmp_socket = GCSPRINTF("%s/qmp-libxl-%d", libxl__run_dir_path(), domid);
-    if ((ret = qmp_open(qmp, qmp_socket, QMP_SOCKET_CONNECT_TIMEOUT)) < 0) {
-        LOGED(ERROR, domid, "Connection error");
-        qmp_free_handler(qmp);
-        return NULL;
+    if (dm_domid) {
+        /* sanity check */
+        if (libxl__stubdomain_version_running(gc, dm_domid) ==
+                LIBXL_STUBDOMAIN_VERSION_MINIOS) {
+            LOGED(ERROR, domid, "QMP socket unsupported for minios 
stubdomain");
+            qmp_free_handler(qmp);
+            return NULL;
+        }
+        ret = libxl_console_get_tty(CTX, dm_domid,
+                                    STUBDOM_CONSOLE_QMP,
+                                    LIBXL_CONSOLE_TYPE_PV,
+                                    &qmp_socket);
+        if (ret) {
+            LOGED(ERROR, domid, "Failed to get QMP tty path");
+            qmp_free_handler(qmp);
+            return NULL;
+        }
+        ret = qmp_open_pty(qmp, qmp_socket);
+        if (ret) {
+            LOGED(ERROR, domid, "Connection error");
+            qmp_free_handler(qmp);
+            return NULL;
+        }
+        ret = qmp_send(qmp, "qmp_reset", NULL, NULL, NULL, NULL);
+        if (ret < 0) {
+            LOGED(ERROR, domid, "Failed to send qmp_reset");
+            qmp_free_handler(qmp);
+            return NULL;
+        }
+    } else {
+        qmp_socket = GCSPRINTF("%s/qmp-libxl-%d", libxl__run_dir_path(), 
domid);
+        if ((ret = qmp_open(qmp, qmp_socket, QMP_SOCKET_CONNECT_TIMEOUT)) < 0) 
{
+            LOGED(ERROR, domid, "Connection error");
+            qmp_free_handler(qmp);
+            return NULL;
+        }
     }
 
     LOGD(DEBUG, domid, "connected to %s", qmp_socket);
-- 
git-series 0.9.1

_______________________________________________
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®.