Implement ioctl-alike communication
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 23 Aug 2011 18:00:58 +0000 (14:00 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 23 Aug 2011 18:00:58 +0000 (14:00 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/lttng-ust-comm.h
include/ust/lttng-ust-abi.h
libust/lttng-ust-abi.c
libust/lttng-ust-comm.c

index b594367ddd3b6a65c9f5fb1ccdc7e1a6b09b9f8e..b73657eca2f4dfe97ddaa74d2bb8c793277df147 100644 (file)
  */
 #define LTTCOMM_ERR_INDEX(code) (code - LTTCOMM_OK)
 
-enum lttcomm_ust_command {
-       UST_CREATE_SESSION,
-       UST_VERSION,
-       UST_LIST_TRACEPOINTS,
-       UST_WAIT_QUIESCENT,
-       UST_CALIBRATE,
-
-       /* Apply on session handle */
-       UST_METADATA,   /* release with UST_RELEASE_CHANNEL */
-       UST_CHANNEL,
-       UST_SESSION_START,
-       UST_SESSION_STOP,
-
-       /* Apply on channel handle */
-       UST_STREAM,
-       UST_EVENT,
-
-       /* Apply on event and channel handle */
-       UST_CONTEXT,
-
-       /* Apply on event, channel and session handle */
-       UST_RELEASE,
-       UST_ENABLE,
-       UST_DISABLE,
-};
-
 /*
  * lttcomm error code.
  */
@@ -136,8 +110,8 @@ enum lttcomm_return_code {
  * Data structure for the commands sent from sessiond to UST.
  */
 struct lttcomm_ust_msg {
-       uint32_t cmd_type;    /* enum lttcomm_ust_command */
        uint32_t handle;
+       uint32_t cmd;
        union {
                struct lttng_ust_tracer_version version;
                struct lttng_ust_channel channel;
@@ -151,7 +125,8 @@ struct lttcomm_ust_msg {
  * cmd_type is sent back in the reply for validation.
  */
 struct lttcomm_ust_reply {
-       uint32_t cmd_type;      /* enum lttcomm_sessiond_command */
+       uint32_t handle;
+       uint32_t cmd;
        uint32_t ret_code;      /* enum enum lttcomm_return_code */
        uint32_t ret_val;       /* return value */
        union {
index 62f9d6cf3ada03dfd7559920d0f3c92d0918fa98..c4d51a3912b90efa3a10b0d5d1f021c3e7536e84 100644 (file)
@@ -65,6 +65,11 @@ struct lttng_ust_context {
 #define _UST_CMDR(minor, type)                 (minor)
 #define _UST_CMDW(minor, type)                 (minor)
 
+/* Handled by object descriptor */
+#define LTTNG_UST_RELEASE                      _UST_CMD(0x1)
+
+/* Handled by object cmd */
+
 /* LTTng-UST commands */
 #define LTTNG_UST_SESSION                      _UST_CMD(0x40)
 #define LTTNG_UST_TRACER_VERSION               \
@@ -72,7 +77,7 @@ struct lttng_ust_context {
 #define LTTNG_UST_TRACEPOINT_LIST              _UST_CMD(0x42)
 #define LTTNG_UST_WAIT_QUIESCENT               _UST_CMD(0x43)
 
-/* Session FD ioctl */
+/* Session FD commands */
 #define LTTNG_UST_METADATA                     \
        _UST_CMDW(0x50, struct lttng_ust_channel)
 #define LTTNG_UST_CHANNEL                      \
@@ -80,22 +85,35 @@ struct lttng_ust_context {
 #define LTTNG_UST_SESSION_START                        _UST_CMD(0x52)
 #define LTTNG_UST_SESSION_STOP                 _UST_CMD(0x53)
 
-/* Channel FD ioctl */
+/* Channel FD commands */
 #define LTTNG_UST_STREAM                       _UST_CMD(0x60)
 #define LTTNG_UST_EVENT                        \
        _UST_CMDW(0x61, struct lttng_ust_event)
 
-/* Event and Channel FD ioctl */
+/* Event and Channel FD commands */
 #define LTTNG_UST_CONTEXT                      \
        _UST_CMDW(0x70, struct lttng_ust_context)
 
-/* Event, Channel and Session ioctl */
+/* Event, Channel and Session commands */
 #define LTTNG_UST_ENABLE                       _UST_CMD(0x80)
 #define LTTNG_UST_DISABLE                      _UST_CMD(0x81)
 
-void lttng_ust_abi_exit(void);
-int lttng_abi_create_session(void);
+#define LTTNG_UST_ROOT_HANDLE  0
+
+struct obj;
+
+struct objd_ops {
+       long (*cmd)(int objd, unsigned int cmd, unsigned long arg);
+       int (*release)(int objd);
+};
+
+/* Create root handle. Always ID 0. */
+int lttng_abi_create_root_handle(void);
+
+const struct objd_ops *objd_ops(int id);
 int objd_unref(int id);
+
+void lttng_ust_abi_exit(void);
 void ltt_events_exit(void);
 
 #endif /* _LTTNG_UST_ABI_H */
index 01512128f24b478e9bea2bef795ba89eb04e97b7..5f4ba8916da496c0f0b0f5867a996e13fa9b39e1 100644 (file)
  * by the caller.
  */
 
-struct obj;
-
-struct objd_ops {
-       long (*cmd)(int objd, unsigned int cmd, unsigned long arg);
-       int (*release)(int objd);
-};
-
 struct obj {
        union {
                struct {
@@ -131,10 +124,10 @@ void objd_set_private(int id, void *private_data)
        obj->u.s.private_data = private_data;
 }
 
-static
 const struct objd_ops *objd_ops(int id)
 {
        struct obj *obj = _objd_get(id);
+
        if (!obj)
                return NULL;
        return obj->u.s.ops;
@@ -213,6 +206,15 @@ enum channel_type {
        METADATA_CHANNEL,
 };
 
+int lttng_abi_create_root_handle(void)
+{
+       int root_handle;
+
+       root_handle = objd_alloc(NULL, &lttng_ops);
+       assert(root_handle == 0);
+       return root_handle;
+}
+
 int lttng_abi_create_session(void)
 {
        struct ltt_session *session;
@@ -355,7 +357,6 @@ create_error:
        return;         /* not allowed to return error */
 }
 
-static
 int lttng_abi_create_channel(int session_objd,
                             struct lttng_ust_channel *chan_param,
                             enum channel_type channel_type)
index a41683a40ce85c68418a77764ef62f75582b89c3..037b314765ab12b6974f1ca26e294d1771fde504 100644 (file)
@@ -45,18 +45,21 @@ struct sock_info {
        char sock_path[PATH_MAX];
        int socket;
        pthread_t ust_listener; /* listener thread */
+       int root_handle;
 };
 
 /* Socket from app (connect) to session daemon (listen) for communication */
 struct sock_info global_apps = {
        .sock_path = DEFAULT_GLOBAL_APPS_UNIX_SOCK,
        .socket = -1,
+       .root_handle = -1,
 };
 
 /* TODO: allow global_apps_sock_path override */
 
 struct sock_info local_apps = {
        .socket = -1,
+       .root_handle = -1,
 };
 
 static
@@ -120,59 +123,76 @@ static
 int handle_message(int sock, struct lttcomm_ust_msg *lum)
 {
        int ret = 0;
+       const struct objd_ops *ops;
+       struct lttcomm_ust_reply lur;
 
        pthread_mutex_lock(&lttng_ust_comm_mutex);
 
+       memset(&lur, 0, sizeof(lur));
+
        if (lttng_ust_comm_should_quit) {
-               ret = 0;
+               ret = -EPERM;
                goto end;
        }
 
-       switch (lum->cmd_type) {
-       case UST_CREATE_SESSION:
-       {
-               struct lttcomm_ust_reply lur;
-
-               DBG("Handling create session message");
-               memset(&lur, 0, sizeof(lur));
-               lur.cmd_type = UST_CREATE_SESSION;
-               ret = lttng_abi_create_session();
-               if (ret >= 0) {
-                       lur.ret_val = ret;
-                       lur.ret_code = LTTCOMM_OK;
-               } else {
-                       lur.ret_code = LTTCOMM_SESSION_FAIL;
-               }
-               ret = send_reply(sock, &lur);
-               break;
+       ops = objd_ops(lum->handle);
+       if (!ops) {
+               ret = -ENOENT;
+               goto end;
        }
-       case UST_RELEASE:
-       {
-               struct lttcomm_ust_reply lur;
-
-               DBG("Handling release message, handle: %d",
-                       lum->handle);
-               memset(&lur, 0, sizeof(lur));
-               lur.cmd_type = UST_RELEASE;
-               ret = objd_unref(lum->handle);
-               if (!ret) {
-                       lur.ret_code = LTTCOMM_OK;
-               } else {
-                       lur.ret_code = LTTCOMM_ERR;
-               }
-               ret = send_reply(sock, &lur);
+
+       switch (lum->cmd) {
+       case LTTNG_UST_RELEASE:
+               if (lum->handle == LTTNG_UST_ROOT_HANDLE)
+                       ret = -EPERM;
+               else
+                       ret = objd_unref(lum->handle);
                break;
-       }
        default:
-               ERR("Unimplemented command %d", (int) lum->cmd_type);
-               ret = -1;
-               goto end;
+               if (ops->cmd)
+                       ret = ops->cmd(lum->handle, lum->cmd,
+                                       (unsigned long) &lum->u);
+               else
+                       ret = -ENOSYS;
+               break;
        }
+
 end:
+       lur.handle = lum->handle;
+       lur.cmd = lum->cmd;
+       lur.ret_val = ret;
+       if (ret >= 0) {
+               lur.ret_code = LTTCOMM_OK;
+       } else {
+               lur.ret_code = LTTCOMM_SESSION_FAIL;
+       }
+       ret = send_reply(sock, &lur);
+
        pthread_mutex_unlock(&lttng_ust_comm_mutex);
        return ret;
 }
 
+static
+void cleanup_sock_info(struct sock_info *sock_info)
+{
+       int ret;
+
+       if (sock_info->socket != -1) {
+               ret = close(sock_info->socket);
+               if (ret) {
+                       ERR("Error closing local apps socket");
+               }
+               sock_info->socket = -1;
+       }
+       if (sock_info->root_handle != -1) {
+               ret = objd_unref(sock_info->root_handle);
+               if (ret) {
+                       ERR("Error unref root handle");
+               }
+               sock_info->root_handle = -1;
+       }
+}
+
 /*
  * This thread does not allocate any resource, except within
  * handle_message, within mutex protection. This mutex protects against
@@ -202,6 +222,7 @@ restart:
                }
                sock_info->socket = -1;
        }
+
        /* Check for sessiond availability with pipe TODO */
 
        /* Register */
@@ -211,22 +232,37 @@ restart:
                pthread_mutex_unlock(&lttng_ust_comm_mutex);
                sleep(5);
                goto restart;
-       } else {
-               sock_info->socket = sock = ret;
-               pthread_mutex_unlock(&lttng_ust_comm_mutex);
+       }
+
+       sock_info->socket = sock = ret;
+
+       /*
+        * Create only one root handle per listener thread for the whole
+        * process lifetime.
+        */
+       if (sock_info->root_handle == -1) {
+               ret = lttng_abi_create_root_handle();
+               if (ret) {
+                       ERR("Error creating root handle");
+                       pthread_mutex_unlock(&lttng_ust_comm_mutex);
+                       goto quit;
+               }
+               sock_info->root_handle = ret;
        }
 
        ret = register_app_to_sessiond(sock);
        if (ret < 0) {
                ERR("Error registering app to local apps socket");
+               pthread_mutex_unlock(&lttng_ust_comm_mutex);
                sleep(5);
                goto restart;
        }
+       pthread_mutex_unlock(&lttng_ust_comm_mutex);
+
        for (;;) {
                ssize_t len;
                struct lttcomm_ust_msg lum;
 
-               /* Receive session handle */
                len = lttcomm_recv_unix_sock(sock, &lum, sizeof(lum));
                switch (len) {
                case 0: /* orderly shutdown */
@@ -307,20 +343,15 @@ void __attribute__((destructor)) lttng_ust_comm_exit(void)
                ERR("Error cancelling global ust listener thread");
        }
 #endif //0
-       if (global_apps.socket != -1) {
-               ret = close(global_apps.socket);
-               assert(!ret);
-       }
+
+       cleanup_sock_info(&global_apps);
 
        ret = pthread_cancel(local_apps.ust_listener);
        if (ret) {
                ERR("Error cancelling local ust listener thread");
        }
 
-       if (local_apps.socket != -1) {
-               ret = close(local_apps.socket);
-               assert(!ret);
-       }
+       cleanup_sock_info(&local_apps);
 
        lttng_ust_abi_exit();
        ltt_events_exit();
This page took 0.030418 seconds and 4 git commands to generate.