[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.