[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 23/31] libxl_qmp_ev: Handle messages from QEMU
This will handle messages received, and call callbacks registered via libxl__ev_qmp_register(). This also print error messages from QMP on behalf of the callback. Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- Should we let callbacks print error messages themself? They already have the error class, which is often GenericError, a human readable error message. --- tools/libxl/libxl_qmp.c | 100 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c index 0e7ec54b9f..db07c1822a 100644 --- a/tools/libxl/libxl_qmp.c +++ b/tools/libxl/libxl_qmp.c @@ -1420,6 +1420,101 @@ static int ev_qmp_queue_command(libxl__gc *gc, return 0; } +/* + * Handle messages received from QMP server + */ + +static void ev_qmp_handle_return(libxl__egc *egc, + libxl__ev_qmp_state *qmp, + const libxl__json_object *resp, + libxl__qmp_message_type type) +{ + EGC_GC; + const libxl__json_object *o; + int id; + libxl__ev_qmp *ev; + const libxl__json_object *ret; + libxl__qmp_error_class error_class = 0; + + o = libxl__json_map_get("id", resp, JSON_INTEGER); + if (!o) { + const char *error_desc; + + /* unexpected message, attempt to find an error description */ + o = libxl__json_map_get("error", resp, JSON_MAP); + o = libxl__json_map_get("desc", o, JSON_STRING); + error_desc = libxl__json_object_get_string(o); + if (error_desc) + LOGD(ERROR, qmp->domid, "%s", error_desc); + else + LOGD(ERROR, qmp->domid, "Received unexpected message: %s", + libxl__json_object_to_json(gc, resp)); + return; + } + + id = libxl__json_object_get_integer(o); + LIBXL_TAILQ_FOREACH(ev, &qmp->qmp_events, entry) { + if (ev->id == id) + break; + } + if (!ev) + /* callback not found */ + return; + + switch (type) { + case LIBXL__QMP_MESSAGE_TYPE_RETURN: { + ret = libxl__json_map_get("return", resp, JSON_ANY); + break; + } + case LIBXL__QMP_MESSAGE_TYPE_ERROR: { + const char *s; + const libxl__json_object *err; + + error_class = LIBXL__QMP_ERROR_CLASS_UNKNOWN; + err = libxl__json_map_get("error", resp, JSON_MAP); + o = libxl__json_map_get("class", err, JSON_STRING); + s = libxl__json_object_get_string(o); + if (s) + libxl__qmp_error_class_from_string(s, &error_class); + + o = libxl__json_map_get("desc", err, JSON_STRING); + s = libxl__json_object_get_string(o); + if (s) + LOGD(ERROR, qmp->domid, "%s", s); + + ret = NULL; + break; + } + default: + abort(); + } + ev->id = -1; + ev->callback(egc, ev, ret, error_class); +} + +static void ev_qmp_handle_message(libxl__egc *egc, + libxl__ev_qmp_state *qmp, + const libxl__json_object *resp) +{ + EGC_GC; + libxl__qmp_message_type type = qmp_response_type(resp); + + switch (type) { + case LIBXL__QMP_MESSAGE_TYPE_QMP: + /* greeting message */ + return; + case LIBXL__QMP_MESSAGE_TYPE_RETURN: + case LIBXL__QMP_MESSAGE_TYPE_ERROR: + ev_qmp_handle_return(egc, qmp, resp, type); + return; + case LIBXL__QMP_MESSAGE_TYPE_EVENT: + /* Event are ignored */ + return; + case LIBXL__QMP_MESSAGE_TYPE_INVALID: + return; + } +} + static int ev_qmp_callback_readable(libxl__egc *egc, libxl__ev_qmp_state *qmp, int fd) { @@ -1557,6 +1652,8 @@ static int ev_qmp_callback_readable(libxl__egc *egc, libxl__ev_qmp_state *qmp, LOG_QMP("JSON object received: %s", libxl__json_object_to_json(gc, o)); + ev_qmp_handle_message(egc, qmp, o); + /* check if there is another message received at the same time */ if (buf) { end = strstr(buf->buf + buf->consumed, "\r\n"); @@ -1762,6 +1859,9 @@ void libxl__ev_qmp_stop(libxl__gc *gc, libxl__ev_qmp_state *qmp) LOGD(DEBUG, qmp->domid, "Stopping QMP handler"); + /* There should be no more events requested */ + assert(LIBXL_TAILQ_EMPTY(&qmp->qmp_events)); + LIBXL_TAILQ_FOREACH_SAFE(buf, &qmp->bufs, entry, tbuf) free(buf); LIBXL_TAILQ_INIT(&qmp->bufs); -- 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 |