[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 |