Session create/release tested.
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 23 Aug 2011 15:34:14 +0000 (11:34 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 23 Aug 2011 15:34:14 +0000 (11:34 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/lttng-ust-comm.h
include/ust/lttng-tracer.h [new file with mode: 0644]
include/ust/lttng-ust-abi.h
liblttng-ust-comm/lttng-ust-comm.c
libust/ltt-events.c
libust/lttng-ust-abi.c
libust/lttng-ust-comm.c
tests/hello/hello.c

index 6914cc2a4dbad8dd43dbcb1108fb383c21be56f9..b594367ddd3b6a65c9f5fb1ccdc7e1a6b09b9f8e 100644 (file)
@@ -48,7 +48,6 @@
 
 enum lttcomm_ust_command {
        UST_CREATE_SESSION,
-       UST_RELEASE_SESSION,
        UST_VERSION,
        UST_LIST_TRACEPOINTS,
        UST_WAIT_QUIESCENT,
@@ -57,21 +56,18 @@ enum lttcomm_ust_command {
        /* Apply on session handle */
        UST_METADATA,   /* release with UST_RELEASE_CHANNEL */
        UST_CHANNEL,
-       UST_RELEASE_CHANNEL,
        UST_SESSION_START,
        UST_SESSION_STOP,
 
        /* Apply on channel handle */
        UST_STREAM,
-       UST_RELEASE_STREAM,
        UST_EVENT,
-       UST_RELEASE_EVENT,
 
        /* Apply on event and channel handle */
        UST_CONTEXT,
-       UST_RELEASE_CONTEXT,
 
        /* Apply on event, channel and session handle */
+       UST_RELEASE,
        UST_ENABLE,
        UST_DISABLE,
 };
diff --git a/include/ust/lttng-tracer.h b/include/ust/lttng-tracer.h
new file mode 100644 (file)
index 0000000..18739e2
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _LTTNG_TRACER_H
+#define _LTTNG_TRACER_H
+
+/*
+ * Copyright (C) 2005-2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This contains the core definitions for the Linux Trace Toolkit.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+/* Align data on its natural alignment */
+#define RING_BUFFER_ALIGN
+#endif
+
+#define LTTNG_UST_VERSION 0
+#define LTTNG_UST_PATCHLEVEL 9
+#define LTTNG_UST_SUBLEVEL 1
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#ifdef RING_BUFFER_ALIGN
+#define lttng_alignof(type)    __alignof__(type)
+#else
+#define lttng_alignof(type)    1
+#endif
+
+#define lttng_is_signed_type(type)           (((type)(-1)) < 0)
+
+#endif /* _LTTNG_TRACER_CORE_H */
index 16c49d1665da1f059fe59ec8df4dee367906362c..62f9d6cf3ada03dfd7559920d0f3c92d0918fa98 100644 (file)
@@ -94,5 +94,8 @@ struct lttng_ust_context {
 #define LTTNG_UST_DISABLE                      _UST_CMD(0x81)
 
 void lttng_ust_abi_exit(void);
+int lttng_abi_create_session(void);
+int objd_unref(int id);
+void ltt_events_exit(void);
 
 #endif /* _LTTNG_UST_ABI_H */
index 214f6e45024562ca4762bcc153344cea4ff70fbe..0ce9fc87a293b4457ee29d027caf6f65954c172b 100644 (file)
@@ -273,7 +273,14 @@ ssize_t lttcomm_send_unix_sock(int sock, void *buf, size_t len)
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;
 
-       ret = sendmsg(sock, &msg, 0);
+       /*
+        * Using the MSG_NOSIGNAL when sending data from sessiond to
+        * libust, so libust does not receive an unhandled SIGPIPE or
+        * SIGURG. The sessiond receiver side can be made more resilient
+        * by ignoring SIGPIPE, but we don't have this luxury on the
+        * libust side.
+        */
+       ret = sendmsg(sock, &msg, MSG_NOSIGNAL);
        if (ret < 0) {
                perror("sendmsg");
        }
index 8f9b7ed26410248176ec6174ce5101790bb3be23..c99b6689200b3c8775569d8bafe05a1d1d088072 100644 (file)
@@ -50,10 +50,10 @@ struct ltt_session *ltt_session_create(void)
 {
        struct ltt_session *session;
 
-       pthread_mutex_lock(&sessions_mutex);
        session = zmalloc(sizeof(struct ltt_session));
        if (!session)
                return NULL;
+       pthread_mutex_lock(&sessions_mutex);
        CDS_INIT_LIST_HEAD(&session->chan);
        CDS_INIT_LIST_HEAD(&session->events);
        uuid_generate(session->uuid);
@@ -870,8 +870,7 @@ void ltt_transport_unregister(struct ltt_transport *transport)
        pthread_mutex_unlock(&sessions_mutex);
 }
 
-static
-void __attribute__((destructor)) ltt_events_exit(void)
+void ltt_events_exit(void)
 {
        struct ltt_session *session, *tmpsession;
 
index fee3d0750022becad801f34979a62e11224bcf0c..dca010c9f97353c68011eac4cab506f23d089804 100644 (file)
@@ -153,11 +153,12 @@ void objd_ref(int id)
        obj->u.s.f_count++;
 }
 
-static
-void objd_unref(int id)
+int objd_unref(int id)
 {
        struct obj *obj = _objd_get(id);
 
+       if (!obj)
+               return -EINVAL;
        if (!(--obj->u.s.f_count)) {
                const struct objd_ops *ops = objd_ops(id);
 
@@ -165,6 +166,7 @@ void objd_unref(int id)
                        ops->release(id);
                objd_free(id);
        }
+       return 0;
 }
 
 static
@@ -189,7 +191,6 @@ enum channel_type {
        METADATA_CHANNEL,
 };
 
-static
 int lttng_abi_create_session(void)
 {
        struct ltt_session *session;
@@ -396,7 +397,12 @@ int lttng_abi_create_channel(int session_objd,
        return chan_objd;
 
 chan_error:
-       objd_unref(chan_objd);
+       {
+               int err;
+
+               err = objd_unref(chan_objd);
+               assert(!err);
+       }
 objd_error:
        return ret;
 }
@@ -454,17 +460,20 @@ long lttng_session_cmd(int objd, unsigned int cmd, unsigned long arg)
  * individual file is released).
  */
 static
-int lttng_session_release(int objd)
+int lttng_release_session(int objd)
 {
        struct ltt_session *session = objd_private(objd);
 
-       if (session)
+       if (session) {
                ltt_session_destroy(session);
-       return 0;
+               return 0;
+       } else {
+               return -EINVAL;
+       }
 }
 
 static const struct objd_ops lttng_session_ops = {
-       .release = lttng_session_release,
+       .release = lttng_release_session,
        .cmd = lttng_session_cmd,
 };
 
@@ -527,7 +536,12 @@ int lttng_abi_create_event(int channel_objd,
        return event_objd;
 
 event_error:
-       objd_unref(event_objd);
+       {
+               int err;
+
+               err = objd_unref(event_objd);
+               assert(!err);
+       }
 objd_error:
        return ret;
 }
@@ -639,7 +653,7 @@ int lttng_channel_release(int objd)
        struct ltt_channel *channel = objd_private(objd);
 
        if (channel)
-               objd_unref(channel->session->objd);
+               return objd_unref(channel->session->objd);
        return 0;
 }
 
@@ -694,7 +708,7 @@ int lttng_event_release(int objd)
        struct ltt_event *event = objd_private(objd);
 
        if (event)
-               objd_unref(event->chan->objd);
+               return objd_unref(event->chan->objd);
        return 0;
 }
 
@@ -706,6 +720,5 @@ static const struct objd_ops lttng_event_ops = {
 
 void lttng_ust_abi_exit(void)
 {
-       /* TODO: teardown socket */
        objd_table_destroy();
 }
index c9cb777709dab0d84ffffebe26352fcfdfbde563..41d1280c8fe901dcf506ae608758b71789c2499c 100644 (file)
 #include <lttng-ust-comm.h>
 #include <ust/usterr-signal-safe.h>
 #include <pthread.h>
+#include <assert.h>
+
+/*
+ * communication thread mutex. Held when handling a command, also held
+ * by fork() to deal with removal of threads, and by exit path.
+ */
+static pthread_mutex_t lttng_ust_comm_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* Should the ust comm thread quit ? */
+static int lttng_ust_comm_should_quit;
+
+/*
+ * Info about socket and associated listener thread.
+ */
+struct sock_info {
+       char sock_path[PATH_MAX];
+       int socket;
+       pthread_t ust_listener; /* listener thread */
+};
 
 /* Socket from app (connect) to session daemon (listen) for communication */
-static char global_apps_sock_path[PATH_MAX] = DEFAULT_GLOBAL_APPS_UNIX_SOCK;
-static pthread_t global_ust_listener;
+struct sock_info global_apps = {
+       .sock_path = DEFAULT_GLOBAL_APPS_UNIX_SOCK,
+       .socket = -1,
+};
 
 /* TODO: allow global_apps_sock_path override */
 
-static char local_apps_sock_path[PATH_MAX];
-static pthread_t local_ust_listener;
+struct sock_info local_apps = {
+       .socket = -1,
+};
 
 static
 int setup_local_apps_socket(void)
@@ -45,7 +67,7 @@ int setup_local_apps_socket(void)
        home_dir = (const char *) getenv("HOME");
        if (!home_dir)
                return -ENOENT;
-       snprintf(local_apps_sock_path, PATH_MAX,
+       snprintf(local_apps.sock_path, PATH_MAX,
                 DEFAULT_HOME_APPS_UNIX_SOCK, home_dir);
        return 0;
 }
@@ -72,12 +94,18 @@ int register_app_to_sessiond(int socket)
        return ret;
 }
 
-
 static
 int handle_message(int sock, struct lttcomm_ust_msg *lum)
 {
        ssize_t len;
-       int ret;
+       int ret = 0;
+
+       pthread_mutex_lock(&lttng_ust_comm_mutex);
+
+       if (lttng_ust_comm_should_quit) {
+               ret = 0;
+               goto end;
+       }
 
        switch (lum->cmd_type) {
        case UST_CREATE_SESSION:
@@ -88,56 +116,120 @@ int handle_message(int sock, struct lttcomm_ust_msg *lum)
                memset(&lur, 0, sizeof(lur));
                lur.cmd_type = UST_CREATE_SESSION;
 
-               /* ... */
-               ret = 0;
-
-               if (!ret)
+               ret = lttng_abi_create_session();
+               if (ret >= 0) {
+                       lur.ret_val = ret;
                        lur.ret_code = LTTCOMM_OK;
-               else
+               } else {
                        lur.ret_code = LTTCOMM_SESSION_FAIL;
-               lur.ret_val = 42;
+               }
                len = lttcomm_send_unix_sock(sock, &lur, sizeof(lur));
                switch (len) {
                case sizeof(lur):
-                       printf("message successfully sent\n");
+                       DBG("message successfully sent");
                        break;
                case -1:
                        if (errno == ECONNRESET) {
                                printf("remote end closed connection\n");
-                               return 0;
+                               ret = 0;
+                               goto end;
                        }
-                       return -1;
+                       ret = -1;
+                       goto end;
                default:
                        printf("incorrect message size: %zd\n", len);
-                       return -1;
+                       ret = -1;
+                       goto end;
+               }
+               break;
+       }
+       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;
+               }
+               len = lttcomm_send_unix_sock(sock, &lur, sizeof(lur));
+               switch (len) {
+               case sizeof(lur):
+                       DBG("message successfully sent\n");
+                       break;
+               case -1:
+                       if (errno == ECONNRESET) {
+                               printf("remote end closed connection\n");
+                               ret = 0;
+                               goto end;
+                       }
+                       ret = -1;
+                       goto end;
+               default:
+                       printf("incorrect message size: %zd\n", len);
+                       ret = -1;
+                       goto end;
                }
                break;
        }
        default:
                ERR("Unimplemented command %d", (int) lum->cmd_type);
-               return -1;
+               ret = -1;
+               goto end;
        }
-       return 0;
+end:
+       pthread_mutex_unlock(&lttng_ust_comm_mutex);
+       return ret;
 }
 
+/*
+ * This thread does not allocate any resource, except within
+ * handle_message, within mutex protection. This mutex protects against
+ * fork and exit.
+ * The other moment it allocates resources is at socket connexion, which
+ * is also protected by the mutex.
+ */
 static
 void *ust_listener_thread(void *arg)
 {
-       const char *sock_path = (const char *) arg;
-       int sock;
-       int ret;
+       struct sock_info *sock_info = arg;
+       int sock, ret;
 
        /* Restart trying to connect to the session daemon */
 restart:
+       pthread_mutex_lock(&lttng_ust_comm_mutex);
+
+       if (lttng_ust_comm_should_quit) {
+               pthread_mutex_unlock(&lttng_ust_comm_mutex);
+               goto quit;
+       }
 
+       if (sock_info->socket != -1) {
+               ret = close(sock_info->socket);
+               if (ret) {
+                       ERR("Error closing local apps socket");
+               }
+               sock_info->socket = -1;
+       }
        /* Check for sessiond availability with pipe TODO */
 
        /* Register */
-       ret = lttcomm_connect_unix_sock(sock_path);
+       ret = lttcomm_connect_unix_sock(sock_info->sock_path);
        if (ret < 0) {
                ERR("Error connecting to global apps socket");
+               pthread_mutex_unlock(&lttng_ust_comm_mutex);
+               goto restart;
+       } else {
+               sock_info->socket = sock = ret;
+               pthread_mutex_unlock(&lttng_ust_comm_mutex);
        }
-       sock = ret;
+
        ret = register_app_to_sessiond(sock);
        if (ret < 0) {
                ERR("Error registering app to local apps socket");
@@ -174,11 +266,8 @@ restart:
 
        }
 end:
-       ret = close(sock);
-       if (ret) {
-               ERR("Error closing local apps socket");
-       }
        goto restart;   /* try to reconnect */
+quit:
        return NULL;
 }
 
@@ -195,17 +284,16 @@ void __attribute__((constructor)) lttng_ust_comm_init(void)
 
        init_usterr();
 
-       /* Connect to the per-user (local) sessiond apps socket */
        ret = setup_local_apps_socket();
        if (ret) {
                ERR("Error setting up to local apps socket");
        }
 #if 0
-       ret = pthread_create(&global_ust_listener, NULL,
-                       ust_listener_thread, global_apps_sock_path);
+       ret = pthread_create(&global_apps.ust_listener, NULL,
+                       ust_listener_thread, &global_apps);
 #endif //0
-       ret = pthread_create(&local_ust_listener, NULL,
-                       ust_listener_thread, local_apps_sock_path);
+       ret = pthread_create(&local_apps.ust_listener, NULL,
+                       ust_listener_thread, &local_apps);
 }
 
 void __attribute__((destructor)) lttng_ust_comm_exit(void)
@@ -217,13 +305,37 @@ void __attribute__((destructor)) lttng_ust_comm_exit(void)
         * A) we don't want to hang application teardown.
         * B) the thread is not allocating any resource.
         */
-       ret = pthread_cancel(global_ust_listener);
+
+       /*
+        * Require the communication thread to quit. Synchronize with
+        * mutexes to ensure it is not in a mutex critical section when
+        * pthread_cancel is later called.
+        */
+       pthread_mutex_lock(&lttng_ust_comm_mutex);
+       lttng_ust_comm_should_quit = 1;
+       pthread_mutex_unlock(&lttng_ust_comm_mutex);
+
+#if 0
+       ret = pthread_cancel(global_apps.ust_listener);
        if (ret) {
                ERR("Error cancelling global ust listener thread");
        }
-       ret = pthread_cancel(local_ust_listener);
+#endif //0
+       if (global_apps.socket != -1) {
+               ret = close(global_apps.socket);
+               assert(!ret);
+       }
+
+       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);
+       }
+
        lttng_ust_abi_exit();
+       ltt_events_exit();
 }
index 9cbe149bc7465fc09b27b5b36ad4ea5bcbff1d7b..e8eb78efc93adc2779f681825aca79e95adec909 100644 (file)
@@ -40,6 +40,7 @@ int init_int_handler(void)
        int result;
        struct sigaction act;
 
+       memset(&act, 0, sizeof(act));
        result = sigemptyset(&act.sa_mask);
        if (result == -1) {
                perror("sigemptyset");
This page took 0.03236 seconds and 4 git commands to generate.