|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 24/31] libxl_qmp_ev: Respond to QMP greeting
Slight change in the infrastructure to allow to send a buffer before any
command that would already been prepared.
qmp_capabilities needs to be the first command sent.
Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
tools/libxl/libxl_qmp.c | 87 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 82 insertions(+), 5 deletions(-)
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index db07c1822a..adf466e4c4 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -1387,6 +1387,8 @@ struct libxl__ev_qmp_state {
unsigned int last_id_used;
/* Indicate that QEMU is ready to respond to command. */
bool ready;
+ /* Allow to commands while !ready, to respond to QMP greeting. */
+ int priority_send;
LIBXL_TAILQ_HEAD(libxl__qmp_tx_bufs, libxl__qmp_tx_buf) tx_buf;
LIBXL_TAILQ_HEAD(libxl__ev_qmps, libxl__ev_qmp) qmp_events;
@@ -1398,7 +1400,8 @@ static int ev_qmp_queue_command(libxl__gc *gc,
libxl__ev_qmp_state *qmp,
const char *cmd,
const libxl__json_object *args,
- libxl__carefd *efd)
+ libxl__carefd *efd,
+ bool high_priority)
{
char *buf = NULL;
size_t len;
@@ -1414,12 +1417,78 @@ static int ev_qmp_queue_command(libxl__gc *gc,
out->buf = buf;
out->len = len;
out->efd = efd;
- LIBXL_TAILQ_INSERT_TAIL(&qmp->tx_buf, out, entry);
+ if (high_priority) {
+ /* qmp_capabilities cmd need to be send out first */
+ LIBXL_TAILQ_INSERT_HEAD(&qmp->tx_buf, out, entry);
+ qmp->priority_send += 1;
+ } else {
+ LIBXL_TAILQ_INSERT_TAIL(&qmp->tx_buf, out, entry);
+ }
libxl__ev_fd_modify(gc, &qmp->efd, qmp->efd.events | POLLOUT);
return 0;
}
+/* QMP greeting response */
+typedef struct {
+ libxl__ev_qmp ev;
+ libxl__ev_qmp_state *qmp;
+} ev_qmp_greeting_state;
+static void ev_qmp_callback_capabilities(libxl__egc *egc,
+ libxl__ev_qmp *ev,
+ const libxl__json_object *o,
+ libxl__qmp_error_class error)
+{
+ EGC_GC;
+ ev_qmp_greeting_state *qegs = CONTAINER_OF(ev, *qegs, ev);
+ libxl__ev_qmp_state *qmp = qegs->qmp;
+
+ CTX_LOCK;
+ qmp->ready = true;
+
+ /* Allow potential command to be sent */
+ libxl__ev_fd_modify(gc, &qmp->efd, qmp->efd.events | POLLOUT);
+
+ CTX_UNLOCK;
+
+ libxl__ev_qmp_deregister(gc, ev);
+
+ free(qegs);
+}
+
+static int ev_qmp_callback_greeting(libxl__egc *egc,
+ libxl__ev_qmp_state *qmp)
+{
+ EGC_GC;
+ ev_qmp_greeting_state *qegs;
+ int rc;
+
+ /* Will be freed in callback */
+ qegs = libxl__malloc(NOGC, sizeof(*qegs));
+
+ libxl__ev_qmp_init(&qegs->ev);
+
+ /* Do part of libxl__ev_qmp_register as this is the only time where the
+ * argument high_priority is true. */
+
+ qegs->qmp = qmp;
+ qegs->ev.domid = qmp->domid;
+ qegs->ev.callback = ev_qmp_callback_capabilities;
+ rc = ev_qmp_queue_command(gc, qmp, "qmp_capabilities", NULL, NULL, true);
+ if (rc)
+ goto out;
+ qegs->ev.id = qmp->last_id_used;
+
+ CTX_LOCK;
+ LIBXL_TAILQ_INSERT_TAIL(&qmp->qmp_events, &qegs->ev, entry);
+ CTX_UNLOCK;
+
+out:
+ if (rc)
+ free(qegs);
+ return rc;
+}
+
/*
* Handle messages received from QMP server
*/
@@ -1501,7 +1570,8 @@ static void ev_qmp_handle_message(libxl__egc *egc,
switch (type) {
case LIBXL__QMP_MESSAGE_TYPE_QMP:
- /* greeting message */
+ /* On the greeting message from the server, call qmp_capabilities */
+ ev_qmp_callback_greeting(egc, qmp);
return;
case LIBXL__QMP_MESSAGE_TYPE_RETURN:
case LIBXL__QMP_MESSAGE_TYPE_ERROR:
@@ -1673,7 +1743,9 @@ static int ev_qmp_callback_writable(libxl__egc *egc,
libxl__qmp_tx_buf *buf;
int rc;
- if (!qmp->ready) {
+ /* Don't send anything until connected, unless there is the response to the
+ * greeting message */
+ if (!qmp->ready && !qmp->priority_send) {
return 0;
}
@@ -1701,6 +1773,9 @@ static int ev_qmp_callback_writable(libxl__egc *egc,
free(buf->buf);
free(buf);
+ if (!qmp->ready && qmp->priority_send)
+ qmp->priority_send -= 1;
+
out:
return 1;
}
@@ -1771,6 +1846,7 @@ static void libxl__ev_qmp_state_init(libxl__ev_qmp_state
*qmp)
LIBXL_TAILQ_INIT(&qmp->bufs);
qmp->last_id_used = 0;
qmp->ready = false;
+ qmp->priority_send = 0;
LIBXL_TAILQ_INIT(&qmp->tx_buf);
LIBXL_TAILQ_INIT(&qmp->qmp_events);
}
@@ -1878,6 +1954,7 @@ void libxl__ev_qmp_stop(libxl__gc *gc,
libxl__ev_qmp_state *qmp)
LIBXL_TAILQ_INIT(&qmp->qmp_events);
qmp->ready = false;
+ qmp->priority_send = 0;
libxl__ev_fd_deregister(gc, &qmp->efd);
libxl__carefd_close(qmp->cfd);
@@ -1917,7 +1994,7 @@ int libxl__ev_qmp_register(libxl__gc *gc, libxl__ev_qmp
*ev,
goto out;
}
- rc = ev_qmp_queue_command(gc, qmp, cmd, args, ev->efd);
+ rc = ev_qmp_queue_command(gc, qmp, cmd, args, ev->efd, false);
if (rc)
goto out;
--
Anthony PERARD
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |