[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 14/31] libxl_qmp_ev: Introduce libxl__ev_qmp_start() to connect to QMP
This is a first patch to implement libxl__ev_qmp, it only connect to the QMP socket of QEMU and register a callback that does nothing. Callback functions will be implemented in following patches. Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- TODO: This would probably needs to have a list in CTX, with state for different domid. --- tools/libxl/libxl.c | 4 ++ tools/libxl/libxl_internal.h | 8 +++ tools/libxl/libxl_qmp.c | 106 +++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index b41ade9fda..b3fb8c1f8b 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -162,6 +162,10 @@ int libxl_ctx_free(libxl_ctx *ctx) assert(!libxl__ev_fd_isregistered(&ctx->evtchn_efd)); assert(!libxl__ev_fd_isregistered(&ctx->sigchld_selfpipe_efd)); + libxl__ev_qmp_stop(gc, ctx->qmp_ev); + free(ctx->qmp_ev); + ctx->qmp_ev = NULL; + /* Now there should be no more events requested from the application: */ assert(LIBXL_LIST_EMPTY(&ctx->efds)); diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 12bbfe4a63..d9eebfd98b 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -201,6 +201,7 @@ typedef struct libxl__ao libxl__ao; typedef struct libxl__aop_occurred libxl__aop_occurred; typedef struct libxl__osevent_hook_nexus libxl__osevent_hook_nexus; typedef struct libxl__osevent_hook_nexi libxl__osevent_hook_nexi; +typedef struct libxl__ev_qmp_state libxl__ev_qmp_state; typedef struct libxl__domain_create_state libxl__domain_create_state; typedef void libxl__domain_create_cb(struct libxl__egc *egc, @@ -503,6 +504,9 @@ struct libxl__ctx { LIBXL_LIST_ENTRY(libxl_ctx) sigchld_users_entry; libxl_version_info version_info; + + // FIXME: May need a list, with on state for each domid + libxl__ev_qmp_state *qmp_ev; }; /* @@ -4418,6 +4422,10 @@ static inline bool libxl__string_is_default(char **s) { return *s == NULL; } + +_hidden libxl__ev_qmp_state *libxl__ev_qmp_start(libxl__gc *gc, uint32_t domid); +/* Allow to disconnect from a QMP server and free ressources */ +_hidden void libxl__ev_qmp_stop(libxl__gc *, libxl__ev_qmp_state *qmp); #endif /* diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c index 9f4c3f5c20..077cac9c8a 100644 --- a/tools/libxl/libxl_qmp.c +++ b/tools/libxl/libxl_qmp.c @@ -1351,6 +1351,112 @@ int libxl__qmp_initializations(libxl__gc *gc, uint32_t domid, return ret; } +/* ------------ Implementation of libxl__ev_qmp ---------------- */ + +struct libxl__ev_qmp_state { + libxl__carefd *cfd; + libxl__ev_fd efd; + uint32_t domid; +}; + +static void ev_qmp_fd_callback(libxl__egc *egc, libxl__ev_fd *ev_fd, + int fd, short events, short revents) +{ +} + +static void libxl__ev_qmp_state_init(libxl__ev_qmp_state *qmp) +{ + qmp->domid = INVALID_DOMID; + qmp->cfd = NULL; + libxl__ev_fd_init(&qmp->efd); +} + +libxl__ev_qmp_state *libxl__ev_qmp_start(libxl__gc *gc, uint32_t domid) +{ + int rc, r; + struct sockaddr_un un; + const char *qmp_socket_path; + libxl__ev_qmp_state *qmp; + + CTX_LOCK; + + if (!CTX->qmp_ev) { + qmp = libxl__malloc(NOGC, sizeof(*qmp)); + CTX->qmp_ev = qmp; + libxl__ev_qmp_state_init(qmp); + } else { + qmp = CTX->qmp_ev; + } + + if (libxl__ev_fd_isregistered(&qmp->efd)) { + LOG(DEBUG, "reusing connection: %d == %d", domid, qmp->domid); + assert(domid == qmp->domid); + rc = 0; + goto out; + } + + qmp->domid = domid; + + qmp_socket_path = GCSPRINTF("%s/qmp-libxl-%d", + libxl__run_dir_path(), domid); + + LOGD(DEBUG, domid, "Starting new QMP event handler"); + libxl__carefd_begin(); + qmp->cfd = libxl__carefd_opened(CTX, socket(AF_UNIX, SOCK_STREAM, 0)); + if (!qmp->cfd) { + LOGED(ERROR, domid, "socket() failed"); + rc = ERROR_FAIL; + goto out; + } + rc = libxl_fd_set_nonblock(CTX, libxl__carefd_fd(qmp->cfd), 1); + if (rc) + goto out; + + if (sizeof(un.sun_path) <= strlen(qmp_socket_path)) { + rc = -1; + goto out; + } + memset(&un, 0, sizeof(un)); + un.sun_family = AF_UNIX; + assert(strlen(qmp_socket_path) <= sizeof(un.sun_path)); + strncpy(un.sun_path, qmp_socket_path, sizeof(un.sun_path)); + + r = connect(libxl__carefd_fd(qmp->cfd), + (struct sockaddr *) &un, sizeof(un)); + if (r) { + LOGED(ERROR, domid, "Failed to connect to QMP socket %s", + qmp_socket_path); + rc = ERROR_FAIL; + goto out; + } + + rc = libxl__ev_fd_register(gc, &qmp->efd, + ev_qmp_fd_callback, + libxl__carefd_fd(qmp->cfd), + POLLIN); + +out: + if (rc) + libxl__ev_qmp_stop(gc, qmp); + CTX_UNLOCK; + return qmp; +} + +void libxl__ev_qmp_stop(libxl__gc *gc, libxl__ev_qmp_state *qmp) +{ + if (!qmp) + return; + + CTX_LOCK; + + LOGD(DEBUG, qmp->domid, "Stopping QMP handler"); + + libxl__ev_fd_deregister(gc, &qmp->efd); + libxl__carefd_close(qmp->cfd); + qmp->cfd = NULL; + + CTX_UNLOCK; +} /* * Local variables: * mode: C -- 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 |