From 46050b1a32de8dd0a7b65347af630c4a77f433a1 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 23 Aug 2011 14:00:58 -0400 Subject: [PATCH] Implement ioctl-alike communication Signed-off-by: Mathieu Desnoyers --- include/lttng-ust-comm.h | 31 +-------- include/ust/lttng-ust-abi.h | 30 +++++++-- libust/lttng-ust-abi.c | 19 +++--- libust/lttng-ust-comm.c | 129 ++++++++++++++++++++++-------------- 4 files changed, 117 insertions(+), 92 deletions(-) diff --git a/include/lttng-ust-comm.h b/include/lttng-ust-comm.h index b594367d..b73657ec 100644 --- a/include/lttng-ust-comm.h +++ b/include/lttng-ust-comm.h @@ -46,32 +46,6 @@ */ #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 { diff --git a/include/ust/lttng-ust-abi.h b/include/ust/lttng-ust-abi.h index 62f9d6cf..c4d51a39 100644 --- a/include/ust/lttng-ust-abi.h +++ b/include/ust/lttng-ust-abi.h @@ -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 */ diff --git a/libust/lttng-ust-abi.c b/libust/lttng-ust-abi.c index 01512128..5f4ba891 100644 --- a/libust/lttng-ust-abi.c +++ b/libust/lttng-ust-abi.c @@ -37,13 +37,6 @@ * 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, <tng_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) diff --git a/libust/lttng-ust-comm.c b/libust/lttng-ust-comm.c index a41683a4..037b3147 100644 --- a/libust/lttng-ust-comm.c +++ b/libust/lttng-ust-comm.c @@ -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(<tng_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(<tng_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(<tng_ust_comm_mutex); sleep(5); goto restart; - } else { - sock_info->socket = sock = ret; - pthread_mutex_unlock(<tng_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(<tng_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(<tng_ust_comm_mutex); sleep(5); goto restart; } + pthread_mutex_unlock(<tng_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(); -- 2.34.1