All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>
To: xen-devel@lists.xenproject.org
Cc: "Wei Liu" <wei.liu2@citrix.com>,
	"Ian Jackson" <ian.jackson@eu.citrix.com>,
	"Marek Marczykowski-Górecki" <marmarek@invisiblethingslab.com>
Subject: [PATCH v3 12/17] libxl: use vchan for QMP access with Linux stubdomain, libxl__ev_qmp_* version
Date: Mon, 28 Jan 2019 22:30:29 +0100	[thread overview]
Message-ID: <29dfd94db70671c2ef32aa3bccb338360f2c0c7d.1548710973.git-series.marmarek@invisiblethingslab.com> (raw)
In-Reply-To: <cover.8f900c4839866ee551e8ebf221cfc7b9310cecd6.1548710973.git-series.marmarek@invisiblethingslab.com>
In-Reply-To: <cover.8f900c4839866ee551e8ebf221cfc7b9310cecd6.1548710973.git-series.marmarek@invisiblethingslab.com>

Access to QMP of QEMU in Linux stubdomain is possible over vchan
connection. Add appropriate handling in libxl__ev_qmp_* API, keeping all the
asynchronous properties.
Since only one client can be connected to vchan server at the same time
and it is not enforced by the libxenvchan itself, additional client-side
locking is needed. Note that qemu supports only one simultaneous client
on a control socket anyway (but in UNIX socket case, it enforce it
server-side), so it doesn't add any extra limitation.

Regarding pipe to self:
Vchan issue notification about incoming data (or space for it)
only once - even if there is more data to read, FD returned by
libxenvchan_fd_for_select() will not be readable. Similar to buffer
space - there is one notification if more data can be written, but FD
isn't considered "writable" after libxenvchan_wait() call, even if in
fact there is a buffer space.
There are two situations where it is problematic:
 - some QMP message results in a user callback and processing further
   messages must stop (even if more data is already available in vchan
   buffer)
 - data is scheduled to write after a buffer space notification; this
   may result from either delayed libxl__ev_qmp_send() call, or internal
   state change

To avoid the above problems, use pipe to self to schedule vchan data
processing, even if vchan would not issue notification itself.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
TODO:
 - handle locking for vchan access - a lockfile + flock comes to mind,
   but there is no async provisioning for it in libxl

Changes in v3:
 - new patch, in place of "libxl: access QMP socket via console for
   qemu-in-stubdomain"
---
 tools/Rules.mk               |   4 +-
 tools/libxl/Makefile         |   2 +-
 tools/libxl/libxl_dm.c       |   2 +-
 tools/libxl/libxl_internal.h |   7 +-
 tools/libxl/libxl_qmp.c      | 293 +++++++++++++++++++++++++++++++++++-
 5 files changed, 301 insertions(+), 7 deletions(-)

diff --git a/tools/Rules.mk b/tools/Rules.mk
index 68f2ed7..12b3129 100644
--- a/tools/Rules.mk
+++ b/tools/Rules.mk
@@ -187,8 +187,8 @@ SHLIB_libblktapctl  =
 PKG_CONFIG_REMOVE += xenblktapctl
 endif
 
-CFLAGS_libxenlight = -I$(XEN_XENLIGHT) $(CFLAGS_libxenctrl) $(CFLAGS_xeninclude)
-SHDEPS_libxenlight = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libblktapctl)
+CFLAGS_libxenlight = -I$(XEN_XENLIGHT) $(CFLAGS_libxenctrl) $(CFLAGS_xeninclude) $(CFLAGS_libxenvchan)
+SHDEPS_libxenlight = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libblktapctl) $(SHLIB_libxenvchan)
 LDLIBS_libxenlight = $(SHDEPS_libxenlight) $(XEN_XENLIGHT)/libxenlight$(libextension)
 SHLIB_libxenlight  = $(SHDEPS_libxenlight) -Wl,-rpath-link=$(XEN_XENLIGHT)
 
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 6da342e..55b0b63 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -24,6 +24,7 @@ LIBXL_LIBS = $(LDLIBS_libxentoollog) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl)
 ifeq ($(CONFIG_LIBNL),y)
 LIBXL_LIBS += $(LIBNL3_LIBS)
 endif
+LIBXL_LIBS += $(LDLIBS_libxenvchan)
 
 CFLAGS_LIBXL += $(CFLAGS_libxentoollog)
 CFLAGS_LIBXL += $(CFLAGS_libxentoolcore)
@@ -35,6 +36,7 @@ CFLAGS_LIBXL += $(CFLAGS_libblktapctl)
 ifeq ($(CONFIG_LIBNL),y)
 CFLAGS_LIBXL += $(LIBNL3_CFLAGS)
 endif
+CFLAGS_LIBXL += $(CFLAGS_libxenvchan)
 CFLAGS_LIBXL += -Wshadow
 
 LIBXL_LIBS-$(CONFIG_ARM) += -lfdt
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 6cfc256..b9a53f3 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -1180,7 +1180,7 @@ 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 */
+    /* QMP access to qemu running in stubdomain is done over vchan, not local socket */
     if (!is_stubdom) {
         flexarray_append(dm_args, "-chardev");
         if (state->dm_monitor_fd >= 0) {
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 0095835..9a903a5 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -57,6 +57,7 @@
 #include <xenctrl.h>
 #include <xenguest.h>
 #include <xc_dom.h>
+#include <libxenvchan.h>
 
 #include <xen-tools/libs.h>
 
@@ -509,6 +510,12 @@ struct libxl__ev_qmp {
     libxl__carefd *cfd;
     libxl__ev_fd efd;
     libxl__qmp_state state;
+    /* pipe to wake itself if there is more data in vchan */
+    libxl__carefd *pipe_cfd_read;
+    libxl__carefd *pipe_cfd_write;
+    libxl__ev_fd pipe_efd;
+    struct libxenvchan *vchan;
+    libxl__xswait_state xswait;
     int id;
     int next_id;        /* next id to use */
     /* receive buffer */
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index a235095..45b9f74 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -1466,6 +1466,14 @@ static void dm_state_saved(libxl__egc *egc, libxl__ev_qmp *ev,
 
 /* prototypes */
 
+static int qmp_ev_connect_vchan(libxl__gc *gc, libxl__ev_qmp *ev);
+static void qmp_vchan_watch_callback(libxl__egc *egc,
+      libxl__xswait_state *xswa, int rc, const char *data);
+static void qmp_ev_vchan_fd_callback(libxl__egc *egc, libxl__ev_fd *ev_fd,
+                               int fd, short events, short revents);
+static void qmp_ev_vchan_pipe_fd_callback(libxl__egc *egc, libxl__ev_fd *ev_fd,
+                                          int fd, short events, short revents);
+static void qmp_ev_vchan_schedule_wakeup(libxl__ev_qmp *ev);
 static void qmp_ev_fd_callback(libxl__egc *egc, libxl__ev_fd *ev_fd,
                                int fd, short events, short revents);
 static int qmp_ev_callback_writable(libxl__gc *gc,
@@ -1491,6 +1499,17 @@ static void qmp_ev_ensure_reading_writing(libxl__gc *gc, libxl__ev_qmp *ev)
     else if ((ev->state == qmp_state_waiting_reply) && ev->msg)
         events |= POLLOUT;
 
+    if (ev->vchan || ev->xswait.what) {
+        if (ev->vchan &&
+                libxenvchan_buffer_space(ev->vchan) &&
+                (events & POLLOUT)) {
+            /* If vchan notification about available buffer space was received
+             * already, it won't be dispatched again, trigger it manually. */
+            qmp_ev_vchan_schedule_wakeup(ev);
+        }
+        return;
+    }
+
     libxl__ev_fd_modify(gc, &ev->efd, events);
 }
 
@@ -1564,6 +1583,8 @@ static int qmp_error_class_to_libxl_error_code(libxl__gc *gc,
 
 /* Setup connection */
 
+/*   - QMP over unix socket */
+
 static int qmp_ev_connect(libxl__gc *gc, libxl__ev_qmp *ev)
     /* disconnected -> connecting but with `msg` free
      * on error: broken */
@@ -1575,6 +1596,10 @@ static int qmp_ev_connect(libxl__gc *gc, libxl__ev_qmp *ev)
 
     assert(ev->state == qmp_state_disconnected);
 
+    /* use vchan connection for stubdomain */
+    if (libxl_get_stubdom_id(CTX, ev->domid))
+        return qmp_ev_connect_vchan(gc, ev);
+
     qmp_socket_path = libxl__qemu_qmp_path(gc, ev->domid);
 
     LOGD(DEBUG, ev->domid, "Connecting to %s", qmp_socket_path);
@@ -1618,6 +1643,106 @@ out:
     return rc;
 }
 
+/*   - QMP over vchan */
+
+static int qmp_ev_connect_vchan(libxl__gc *gc, libxl__ev_qmp *ev)
+    /* disconnected -> connecting but with `msg` free
+     * on error: broken */
+{
+    int dm_domid;
+    int rc;
+
+    assert(ev->state == qmp_state_disconnected);
+
+    dm_domid = libxl_get_stubdom_id(CTX, ev->domid);
+    assert(dm_domid != 0);
+
+    ev->xswait.ao = ev->ao;
+    ev->xswait.what = GCSPRINTF("qmp vchan for %u", ev->domid);
+    ev->xswait.path = DEVICE_MODEL_XS_PATH(gc, dm_domid, ev->domid, "/qmp-vchan");
+    ev->xswait.timeout_ms = LIBXL_STUBDOM_START_TIMEOUT * 1000;
+    ev->xswait.callback = qmp_vchan_watch_callback;
+
+    LOGD(DEBUG, ev->domid, "Connecting to vchan at %s", ev->xswait.path);
+
+    rc = libxl__xswait_start(gc, &ev->xswait);
+    if (rc) goto out;
+
+    qmp_ev_set_state(gc, ev, qmp_state_connecting);
+
+    return 0;
+
+out:
+    return rc;
+}
+
+static void qmp_vchan_watch_callback(libxl__egc *egc,
+      libxl__xswait_state *xswa, int rc, const char *data)
+{
+    libxl__ev_qmp *ev = CONTAINER_OF(xswa, *ev, xswait);
+    STATE_AO_GC(ev->ao);
+    int dm_domid = libxl_get_stubdom_id(CTX, ev->domid);
+    int pipe_fd[2];
+
+    if (!rc) {
+        ev->vchan = libxenvchan_client_init(CTX->lg, dm_domid, ev->xswait.path);
+        if (ev->vchan) {
+            /* ok */
+            libxl__xswait_stop(gc, &ev->xswait);
+
+            ev->vchan->blocking = 0;
+
+            rc = libxl__ev_fd_register(gc, &ev->efd, qmp_ev_vchan_fd_callback,
+                    libxenvchan_fd_for_select(ev->vchan), POLLIN);
+            if (rc)
+                goto error;
+
+            libxl__carefd_begin();
+            rc = pipe(pipe_fd);
+            if (!rc) {
+                ev->pipe_cfd_read = libxl__carefd_record(CTX, pipe_fd[0]);
+                ev->pipe_cfd_write = libxl__carefd_record(CTX, pipe_fd[1]);
+            }
+            libxl__carefd_unlock();
+            if (rc) {
+                LOGED(ERROR, ev->domid, "pipe() failed");
+                rc = ERROR_FAIL;
+                goto error;
+            }
+            if (!ev->pipe_cfd_read || !ev->pipe_cfd_write) {
+                LOGED(ERROR, ev->domid, "pipe FD registration failed");
+                rc = ERROR_FAIL;
+                goto error;
+            }
+            rc = libxl__ev_fd_register(gc, &ev->pipe_efd, qmp_ev_vchan_pipe_fd_callback,
+                    libxl__carefd_fd(ev->pipe_cfd_read), POLLIN);
+            if (rc)
+                goto error;
+        } else if (errno == ENOENT) {
+            /* not ready yet, wait */
+            return;
+        } else {
+            LOGED(ERROR, ev->domid, "Connection to qmp vchan for %u failed", ev->domid);
+            rc = ERROR_FAIL;
+        }
+    }
+
+    if (!rc)
+        return;
+
+error:
+
+    if (rc==ERROR_TIMEDOUT || rc==ERROR_ABORTED)
+        LOGD(ERROR, ev->domid, "Connection to qmp vchan for %u timed out", ev->domid);
+
+    /* On error, deallocate all private ressources */
+    libxl__ev_qmp_dispose(gc, ev);
+
+    /* And tell libxl__ev_qmp user about the error */
+    ev->callback(egc, ev, NULL, rc); /* must be last */
+}
+
+
 /* QMP FD callbacks */
 
 static void qmp_ev_fd_callback(libxl__egc *egc, libxl__ev_fd *ev_fd,
@@ -1690,6 +1815,105 @@ error:
     ev->callback(egc, ev, NULL, rc); /* must be last */
 }
 
+/* Make sure vchan events will be handled even if no new notification is sent.
+ */
+static void qmp_ev_vchan_schedule_wakeup(libxl__ev_qmp *ev)
+{
+    assert(ev->pipe_cfd_write);
+    write(libxl__carefd_fd(ev->pipe_cfd_write), ".", 1);
+}
+
+static int qmp_ev_vchan_handle_read_write(libxl__egc *egc, libxl__ev_qmp *ev)
+{
+    int rc;
+    STATE_AO_GC(ev->ao);
+
+    rc = qmp_ev_callback_readable(egc, ev, -1);
+    if (rc)
+        /* returns both rc values -ERROR_* and 1 */
+        return rc;
+
+    if (ev->tx_buf || ((ev->state == qmp_state_waiting_reply) && ev->msg)) {
+        rc = qmp_ev_callback_writable(gc, ev, -1);
+        if (rc)
+            return rc;
+    }
+    return 0;
+}
+
+static void qmp_ev_vchan_fd_callback(libxl__egc *egc, libxl__ev_fd *ev_fd,
+                               int fd, short events, short revents)
+    /* On entry, ev_fd is (of course) Active.  The ev_qmp may be in any
+     * state where this is permitted.  qmp_ev_vchan_fd_callback will do the work
+     * necessary to make progress, depending on the current state, and make
+     * the appropriate state transitions and callbacks.  */
+{
+    libxl__ev_qmp *ev = CONTAINER_OF(ev_fd, *ev, efd);
+    STATE_AO_GC(ev->ao);
+    int rc;
+
+    assert(ev->vchan);
+
+    if (revents & ~(POLLIN)) {
+        LOGD(ERROR, ev->domid,
+             "unexpected poll event 0x%x on QMP vchan FD (expected POLLIN)",
+            revents);
+        rc = ERROR_FAIL;
+        goto error;
+    }
+
+    if (revents & POLLIN) {
+        libxenvchan_wait(ev->vchan);
+        rc = qmp_ev_vchan_handle_read_write(egc, ev);
+        if (rc < 0)
+            goto error;
+    }
+
+    return;
+
+error:
+    assert(rc);
+
+    LOGD(ERROR, ev->domid,
+         "Error happened with the QMP connection to QEMU");
+
+    /* On error, deallocate all private ressources */
+    libxl__ev_qmp_dispose(gc, ev);
+
+    /* And tell libxl__ev_qmp user about the error */
+    ev->callback(egc, ev, NULL, rc); /* must be last */
+}
+
+static void qmp_ev_vchan_pipe_fd_callback(libxl__egc *egc, libxl__ev_fd *ev_fd,
+                                          int fd, short events, short revents)
+{
+    char buf[1];
+    int rc = 0;
+    libxl__ev_qmp *ev = CONTAINER_OF(ev_fd, *ev, pipe_efd);
+    STATE_AO_GC(ev->ao);
+
+    if (revents & POLLIN) {
+        read(fd, buf, 1);
+        rc = qmp_ev_vchan_handle_read_write(egc, ev);
+        if (rc < 0)
+            goto error;
+    }
+
+    return;
+
+error:
+    assert(rc);
+
+    LOGD(ERROR, ev->domid,
+         "Error happened with the QMP connection to QEMU");
+
+    /* On error, deallocate all private ressources */
+    libxl__ev_qmp_dispose(gc, ev);
+
+    /* And tell libxl__ev_qmp user about the error */
+    ev->callback(egc, ev, NULL, rc); /* must be last */
+}
+
 static int qmp_ev_callback_writable(libxl__gc *gc,
                                     libxl__ev_qmp *ev, int fd)
     /* on entry: !disconnected
@@ -1725,6 +1949,13 @@ static int qmp_ev_callback_writable(libxl__gc *gc,
         ev->payload_fd >= 0 &&
         ev->tx_buf_off == 0) {
 
+        /* sending FDs not supported over vchan */
+        if (ev->vchan) {
+            /* XXX should it be assert? */
+            LOGED(ERROR, ev->domid, "Sending FD over vchan connection not supported");
+            return ERROR_NI;
+        }
+
         rc = libxl__sendmsg_fds(gc, fd, ev->tx_buf[ev->tx_buf_off],
                                 1, &ev->payload_fd, "QMP socket");
         /* Check for EWOULDBLOCK, and return to try again later */
@@ -1737,7 +1968,16 @@ static int qmp_ev_callback_writable(libxl__gc *gc,
 
     while (ev->tx_buf_off < ev->tx_buf_len) {
         ssize_t max_write = ev->tx_buf_len - ev->tx_buf_off;
-        r = write(fd, ev->tx_buf + ev->tx_buf_off, max_write);
+        if (ev->vchan) {
+            r = libxenvchan_write(ev->vchan, ev->tx_buf + ev->tx_buf_off, max_write);
+            /* libxenvchan_write returns 0 if no space left, translate to EWOULDBLOCK */
+            if (r == 0) {
+                r = -1;
+                errno = EWOULDBLOCK;
+            }
+        } else {
+            r = write(fd, ev->tx_buf + ev->tx_buf_off, max_write);
+        }
         if (r < 0) {
             if (errno == EINTR)
                 continue;
@@ -1790,6 +2030,24 @@ static int qmp_ev_callback_readable(libxl__egc *egc,
             else if (rc)
                 return rc;
 
+            /*
+             * When adding support for multiple simultaneousl requests (or events),
+             * possibly multiple responses will be already waiting in vchan
+             * buffer. 'ev' can't be touched here after calling user callback,
+             * so remaining messages may be processed in the next callback
+             * (qmp_ev_fd_callback/qmp_ev_vchan_fd_callback). But if at this
+             * point all the data is already in vchan buffer and qemu will not
+             * write anything more, no vchan notification will be issued
+             * (ev->efd will not report POLLIN). Because of this, the callback
+             * will need to be triggered the other way:
+             *
+             * if (ev->vchan && libxenvchan_data_ready(ev->vchan))
+             *     qmp_ev_vchan_schedule_wakeup(ev);
+             *
+             * With only one qmp request pending, this isn't needed, as if user
+             * callback is called, there are no more (interesting) messages in
+             * the vchan buffer (there was only one).
+             */
             /* Must be last and return when the user callback is called */
             rc = qmp_ev_handle_message(egc, ev, o);
             if (rc)
@@ -1811,8 +2069,18 @@ static int qmp_ev_callback_readable(libxl__egc *egc,
             ev->rx_buf = libxl__realloc(gc, ev->rx_buf, ev->rx_buf_size);
         }
 
-        r = read(fd, ev->rx_buf + ev->rx_buf_used,
-                 ev->rx_buf_size - ev->rx_buf_used);
+        if (ev->vchan) {
+            r = libxenvchan_read(ev->vchan, ev->rx_buf + ev->rx_buf_used,
+                    ev->rx_buf_size - ev->rx_buf_used);
+            /* translate r == 0 to EWOULDBLOCK */
+            if (r == 0) {
+                r = -1;
+                errno = EWOULDBLOCK;
+            }
+        } else {
+            r = read(fd, ev->rx_buf + ev->rx_buf_used,
+                     ev->rx_buf_size - ev->rx_buf_used);
+        }
         if (r < 0) {
             if (errno == EINTR)
                 continue;
@@ -2098,7 +2366,14 @@ void libxl__ev_qmp_init(libxl__ev_qmp *ev)
     ev->next_id = 0x786c7100;
 
     ev->cfd = NULL;
+    ev->pipe_cfd_read = NULL;
+    ev->pipe_cfd_write = NULL;
+    ev->vchan = NULL;
+    libxl__xswait_init(&ev->xswait);
+    ev->xswait.what = NULL;
+    ev->xswait.path = NULL;
     libxl__ev_fd_init(&ev->efd);
+    libxl__ev_fd_init(&ev->pipe_efd);
     ev->state = qmp_state_disconnected;
     ev->id = 0;
 
@@ -2162,7 +2437,17 @@ void libxl__ev_qmp_dispose(libxl__gc *gc, libxl__ev_qmp *ev)
     LOGD(DEBUG, ev->domid, " ev %p", ev);
 
     libxl__ev_fd_deregister(gc, &ev->efd);
-    libxl__carefd_close(ev->cfd);
+    if (ev->vchan)
+        libxenvchan_close(ev->vchan);
+    else
+        libxl__carefd_close(ev->cfd);
+    if (ev->pipe_cfd_read) {
+        libxl__ev_fd_deregister(gc, &ev->pipe_efd);
+        libxl__carefd_close(ev->pipe_cfd_read);
+    }
+    if (ev->pipe_cfd_write) {
+        libxl__carefd_close(ev->pipe_cfd_write);
+    }
 
     libxl__ev_qmp_init(ev);
 }
-- 
git-series 0.9.1

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

  parent reply	other threads:[~2019-01-28 21:31 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-28 21:30 [PATCH v3 00/17] Add support for qemu-xen runnning in a Linux-based stubdomain Marek Marczykowski-Górecki
2019-01-28 21:30 ` [PATCH v3 01/17] Document ioemu MiniOS stubdomain protocol Marek Marczykowski-Górecki
2019-02-12 10:52   ` Wei Liu
2019-01-28 21:30 ` [PATCH v3 02/17] Document ioemu Linux " Marek Marczykowski-Górecki
2019-02-21 15:39   ` Wei Liu
2019-02-21 17:08     ` Marek Marczykowski-Górecki
2019-02-21 17:31       ` Wei Liu
2019-02-21 18:17         ` Marek Marczykowski-Górecki
2019-01-28 21:30 ` [PATCH v3 03/17] libxl: fix qemu-trad cmdline for no sdl/vnc case Marek Marczykowski-Górecki
2019-01-28 21:30 ` [PATCH v3 04/17] libxl: Allow running qemu-xen in stubdomain Marek Marczykowski-Górecki
2019-02-21 16:01   ` Wei Liu
2019-02-21 17:06     ` Marek Marczykowski-Górecki
2019-02-21 17:58       ` Wei Liu
2019-01-28 21:30 ` [PATCH v3 05/17] libxl: Handle Linux stubdomain specific QEMU options Marek Marczykowski-Górecki
2019-02-21 16:02   ` Wei Liu
2019-01-28 21:30 ` [PATCH v3 06/17] libxl: write qemu arguments into separate xenstore keys Marek Marczykowski-Górecki
2019-02-21 16:02   ` Wei Liu
2019-01-28 21:30 ` [PATCH v3 07/17] libxl: create vkb device only for guests with graphics output Marek Marczykowski-Górecki
2019-02-21 16:02   ` Wei Liu
2019-01-28 21:30 ` [PATCH v3 08/17] xl: add stubdomain related options to xl config parser Marek Marczykowski-Górecki
2019-02-21 16:02   ` Wei Liu
2019-01-28 21:30 ` [PATCH v3 09/17] tools/libvchan: notify server when client is connected Marek Marczykowski-Górecki
2019-02-21 16:02   ` Wei Liu
2019-01-28 21:30 ` [PATCH v3 10/17] libxl: typo fix in comment Marek Marczykowski-Górecki
2019-02-21 16:02   ` Wei Liu
2019-01-28 21:30 ` [PATCH v3 11/17] libxl: move xswait declaration up in libxl_internal.h Marek Marczykowski-Górecki
2019-02-21 16:02   ` Wei Liu
2019-01-28 21:30 ` Marek Marczykowski-Górecki [this message]
2019-01-28 21:30 ` [PATCH v3 13/17] libxl: use vchan for QMP access with Linux stubdomain, non-async version Marek Marczykowski-Górecki
2019-01-28 21:30 ` [PATCH v3 14/17] libxl: add save/restore support for qemu-xen in stubdomain Marek Marczykowski-Górecki
2019-01-28 21:30 ` [PATCH v3 15/17] tools: add missing libxenvchan cflags Marek Marczykowski-Górecki
2019-02-21 16:05   ` Wei Liu
2019-01-28 21:30 ` [PATCH v3 16/17] libxl: add locking for libvchan QMP connection Marek Marczykowski-Górecki
2019-01-28 21:30 ` [PATCH v3 17/17] libxl: require qemu in dom0 even if stubdomain is in use Marek Marczykowski-Górecki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=29dfd94db70671c2ef32aa3bccb338360f2c0c7d.1548710973.git-series.marmarek@invisiblethingslab.com \
    --to=marmarek@invisiblethingslab.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.