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