Fix: Subdirectory handling for lttng and sessiond
authorDavid Goulet <dgoulet@efficios.com>
Thu, 16 Aug 2012 18:57:13 +0000 (14:57 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Thu, 16 Aug 2012 23:28:29 +0000 (19:28 -0400)
The subdirectory creation was not right for a number of scenarios. With
this commit, if the user defines a path (either local or remote), the
session name will NOT be added to the path.

To handle the timestamp creation of the directory, a hidden function was
added to the lttng-ctl (meaning not visible through lttng.h) which takes
the date and time as a string and append it to the URI subdirectory if
none was provided for a network destination. This function is declared
as extern in the lttng client so it could link to it through the
liblttng-ctl (_lttng_create_session_ext).

It allows the timestamp of a session to be created on the client side
and keep the lttng_create_session() behavior intact meaning if a path is
define by the user when using the API directly, the traces are written
in that path without an extra session name directory.

There is one case where the timestamp is generated on the daemon side.
When creating a session with a local filesystem destination and then
switching to a network consumer, at that time the timestamp is
generated.

The real problematic, and why this has been done this way, is because we
can't transfer the timestamp between the client and the session daemon.
The only possible way that could be achieve right now is by parsing the
subdirectory of the URI containing the session name and timestamp
appended. This could be error prone and bring false negative.

CC: Julien Desfossez <julien.desfossez@efficios.com>
Signed-off-by: David Goulet <dgoulet@efficios.com>
src/bin/lttng-sessiond/Makefile.am
src/bin/lttng-sessiond/main.c
src/bin/lttng-sessiond/session.c
src/bin/lttng/commands/create.c
src/common/defaults.h
src/lib/lttng-ctl/lttng-ctl.c
tests/tools/Makefile.am

index 9b6c4b057a8c112fd9a126847b0fc9106a2036ce..de5a252caddb17a8f476883d279d30c1e67fe4e4 100644 (file)
@@ -13,11 +13,11 @@ lttng_sessiond_SOURCES = utils.c utils.h \
                        channel.c channel.h \
                        event.c event.h \
                        shm.c shm.h \
+                       consumer.c consumer.h \
                        session.c session.h \
                        modprobe.c modprobe.h kern-modules.h \
                        lttng-ust-ctl.h lttng-ust-abi.h \
                        fd-limit.c fd-limit.h \
-                       consumer.c consumer.h \
                        kernel-consumer.c kernel-consumer.h \
                        consumer.h filter.c filter.h \
                        health.c health.h
index 2b40e7aec4af9107542a0e4cf91be66db8fed75e..f24b317d02a89e5bedf8baee7d1a671076b95022 100644 (file)
@@ -2186,6 +2186,54 @@ error:
        return ret;
 }
 
+/*
+ * Set consumer subdirectory using the session name and a generated datetime if
+ * needed. This is appended to the current subdirectory.
+ */
+static int set_consumer_subdir(struct consumer_output *consumer,
+               const char *session_name)
+{
+       int ret = 0;
+       unsigned int have_default_name = 0;
+       char datetime[16], tmp_path[PATH_MAX];
+       time_t rawtime;
+       struct tm *timeinfo;
+
+       assert(consumer);
+       assert(session_name);
+
+       memset(tmp_path, 0, sizeof(tmp_path));
+
+       /* Flag if we have a default session. */
+       if (strncmp(session_name, DEFAULT_SESSION_NAME "-",
+                               strlen(DEFAULT_SESSION_NAME) + 1) == 0) {
+               have_default_name = 1;
+       } else {
+               /* Get date and time for session path */
+               time(&rawtime);
+               timeinfo = localtime(&rawtime);
+               strftime(datetime, sizeof(datetime), "%Y%m%d-%H%M%S", timeinfo);
+       }
+
+       if (have_default_name) {
+               ret = snprintf(tmp_path, sizeof(tmp_path),
+                               "%s/%s", consumer->subdir, session_name);
+       } else {
+               ret = snprintf(tmp_path, sizeof(tmp_path),
+                               "%s/%s-%s/", consumer->subdir, session_name, datetime);
+       }
+       if (ret < 0) {
+               PERROR("snprintf session name date");
+               goto error;
+       }
+
+       strncpy(consumer->subdir, tmp_path, sizeof(consumer->subdir));
+       DBG2("Consumer subdir set to %s", consumer->subdir);
+
+error:
+       return ret;
+}
+
 /*
  * Copy consumer output from the tracing session to the domain session. The
  * function also applies the right modification on a per domain basis for the
@@ -2222,6 +2270,12 @@ static int copy_session_consumer(int domain, struct ltt_session *session)
                goto error;
        }
 
+       ret = set_consumer_subdir(session->consumer, session->name);
+       if (ret < 0) {
+               ret = LTTCOMM_FATAL;
+               goto error;
+       }
+
        /* Append correct directory to subdir */
        strncat(consumer->subdir, dir_name, sizeof(consumer->subdir));
        DBG3("Copy session consumer subdir %s", consumer->subdir);
@@ -2614,9 +2668,9 @@ error:
  * domain adding the default trace directory.
  */
 static int add_uri_to_consumer(struct consumer_output *consumer,
-               struct lttng_uri *uri, int domain)
+               struct lttng_uri *uri, int domain, const char *session_name)
 {
-       int ret;
+       int ret = LTTCOMM_OK;
        const char *default_trace_dir;
 
        assert(uri);
@@ -2654,10 +2708,18 @@ static int add_uri_to_consumer(struct consumer_output *consumer,
                        goto error;
                }
 
-               /* On a new subdir, reappend the default trace dir. */
-               if (strlen(uri->subdir) != 0) {
-                       strncat(consumer->subdir, default_trace_dir,
-                                       sizeof(consumer->subdir));
+               if (uri->stype == LTTNG_STREAM_CONTROL && strlen(uri->subdir) == 0) {
+                       ret = set_consumer_subdir(consumer, session_name);
+                       if (ret < 0) {
+                               ret = LTTCOMM_FATAL;
+                               goto error;
+                       }
+               }
+
+               if (uri->stype == LTTNG_STREAM_CONTROL) {
+                       /* On a new subdir, reappend the default trace dir. */
+                       strncat(consumer->subdir, default_trace_dir, sizeof(consumer->subdir));
+                       DBG3("Append domain trace name to subdir %s", consumer->subdir);
                }
 
                break;
@@ -3496,135 +3558,158 @@ error:
 }
 
 /*
- * Command LTTNG_CREATE_SESSION processed by the client thread.
+ * Command LTTNG_SET_CONSUMER_URI processed by the client thread.
  */
-static int cmd_create_session_uri(char *name, struct lttng_uri *uris,
-               size_t nb_uri, lttng_sock_cred *creds)
+static int cmd_set_consumer_uri(int domain, struct ltt_session *session,
+               size_t nb_uri, struct lttng_uri *uris)
 {
-       int ret, have_default_name = 0;
-       char *path = NULL, datetime[16];
-       struct ltt_session *session;
+       int ret, i;
+       struct ltt_kernel_session *ksess = session->kernel_session;
+       struct ltt_ust_session *usess = session->ust_session;
        struct consumer_output *consumer = NULL;
-       struct lttng_uri *ctrl_uri, *data_uri = NULL;
-       time_t rawtime;
-       struct tm *timeinfo;
-
-       assert(name);
 
-       /* Flag if we have a default session. */
-       if (strncmp(name, DEFAULT_SESSION_NAME,
-                               strlen(DEFAULT_SESSION_NAME)) == 0) {
-               have_default_name = 1;
-       } else {
-               /* Get date and time for session path */
-               time(&rawtime);
-               timeinfo = localtime(&rawtime);
-               strftime(datetime, sizeof(datetime), "%Y%m%d-%H%M%S", timeinfo);
-       }
-
-       /*
-        * Verify if the session already exist
-        *
-        * XXX: There is no need for the session lock list here since the caller
-        * (process_client_msg) is holding it. We might want to change that so a
-        * single command does not lock the entire session list.
-        */
-       session = session_find_by_name(name);
-       if (session != NULL) {
-               ret = LTTCOMM_EXIST_SESS;
-               goto consumer_error;
-       }
+       assert(session);
+       assert(uris);
+       assert(nb_uri > 0);
 
-       /* Create default consumer output for the session not yet created. */
-       consumer = consumer_create_output(CONSUMER_DST_LOCAL);
-       if (consumer == NULL) {
-               ret = LTTCOMM_FATAL;
-               goto consumer_error;
+       /* Can't enable consumer after session started. */
+       if (session->enabled) {
+               ret = LTTCOMM_TRACE_ALREADY_STARTED;
+               goto error;
        }
 
-       /* Add session name and data to the consumer subdir */
-       if (have_default_name) {
-               ret = snprintf(consumer->subdir, sizeof(consumer->subdir), "/%s",
-                               name);
-       } else {
-               ret = snprintf(consumer->subdir, sizeof(consumer->subdir), "/%s-%s",
-                               name, datetime);
-       }
-       if (ret < 0) {
-               PERROR("snprintf consumer subdir");
+       if (!session->start_consumer) {
+               ret = LTTCOMM_NO_CONSUMER;
                goto error;
        }
-       DBG2("Consumer subdir set to '%s'", consumer->subdir);
 
        /*
-        * This means that the lttng_create_session call was called with the _path_
-        * argument set to NULL.
+        * This case switch makes sure the domain session has a temporary consumer
+        * so the URL can be set.
         */
-       if (uris == NULL) {
+       switch (domain) {
+       case 0:
+               /* Code flow error. A session MUST always have a consumer object */
+               assert(session->consumer);
                /*
-                * At this point, we'll skip the consumer URI setup and create a
-                * session with a NULL path which will flag the session to NOT spawn a
-                * consumer.
+                * The URL will be added to the tracing session consumer instead of a
+                * specific domain consumer.
                 */
-               DBG("Create session %s with NO uri, skipping consumer setup", name);
-               goto skip_consumer;
-       }
+               consumer = session->consumer;
+               break;
+       case LTTNG_DOMAIN_KERNEL:
+               /* Code flow error if we don't have a kernel session here. */
+               assert(ksess);
 
-       /* TODO: validate URIs */
+               /* Create consumer output if none exists */
+               consumer = ksess->tmp_consumer;
+               if (consumer == NULL) {
+                       consumer = consumer_copy_output(ksess->consumer);
+                       if (consumer == NULL) {
+                               ret = LTTCOMM_FATAL;
+                               goto error;
+                       }
+                       /* Trash the consumer subdir, we are about to set a new one. */
+                       memset(consumer->subdir, 0, sizeof(consumer->subdir));
+                       ksess->tmp_consumer = consumer;
+               }
 
-       ctrl_uri = &uris[0];
-       if (nb_uri > 1) {
-               data_uri = &uris[1];
-       }
+               break;
+       case LTTNG_DOMAIN_UST:
+               /* Code flow error if we don't have a kernel session here. */
+               assert(usess);
 
-       /* Set subdirectory from the ctrl_uri received. */
-       if (strlen(ctrl_uri->subdir) > 0) {
-               strncpy(consumer->subdir, ctrl_uri->subdir, sizeof(consumer->subdir));
-               DBG2("Consumer subdir copy from ctrl_uri '%s'", consumer->subdir);
+               /* Create consumer output if none exists */
+               consumer = usess->tmp_consumer;
+               if (consumer == NULL) {
+                       consumer = consumer_copy_output(usess->consumer);
+                       if (consumer == NULL) {
+                               ret = LTTCOMM_FATAL;
+                               goto error;
+                       }
+                       /* Trash the consumer subdir, we are about to set a new one. */
+                       memset(consumer->subdir, 0, sizeof(consumer->subdir));
+                       usess->tmp_consumer = consumer;
+               }
+
+               break;
        }
 
-       switch (ctrl_uri->dtype) {
-       case LTTNG_DST_IPV4:
-       case LTTNG_DST_IPV6:
-               /*
-                * We MUST have a data_uri set at this point or else there is a code
-                * flow error. The caller should check that.
-                */
-               assert(data_uri);
+       for (i = 0; i < nb_uri; i++) {
+               struct consumer_socket *socket;
+               struct lttng_ht_iter iter;
 
-               /* Set control URI into consumer output object */
-               ret = consumer_set_network_uri(consumer, ctrl_uri);
+               ret = add_uri_to_consumer(consumer, &uris[i], domain, session->name);
                if (ret < 0) {
-                       ret = LTTCOMM_FATAL;
                        goto error;
                }
 
-               /* Set data URI into consumer output object */
-               ret = consumer_set_network_uri(consumer, data_uri);
-               if (ret < 0) {
-                       ret = LTTCOMM_FATAL;
-                       goto error;
+               /*
+                * Don't send relayd socket if URI is NOT remote or if the relayd
+                * sockets for the session are already sent.
+                */
+               if (uris[i].dtype == LTTNG_DST_PATH ||
+                               consumer->dst.net.relayd_socks_sent) {
+                       continue;
                }
 
-               /* Empty path since the session is network */
-               path = "";
-               break;
-       case LTTNG_DST_PATH:
-               /* Very volatile pointer. Only used for the create session. */
-               path = ctrl_uri->dst.path;
-               strncpy(consumer->dst.trace_path, path,
-                               sizeof(consumer->dst.trace_path));
-               break;
+               /* Try to send relayd URI to the consumer if exist. */
+               cds_lfht_for_each_entry(consumer->socks->ht, &iter.iter,
+                               socket, node.node) {
+
+                       /* A socket in the HT should never have a negative fd */
+                       assert(socket->fd >= 0);
+
+                       pthread_mutex_lock(socket->lock);
+                       ret = send_socket_relayd_consumer(domain, session, &uris[i],
+                                       consumer, socket->fd);
+                       pthread_mutex_unlock(socket->lock);
+                       if (ret != LTTCOMM_OK) {
+                               goto error;
+                       }
+               }
        }
 
-       consumer->enabled = 1;
+       /* All good! */
+       ret = LTTCOMM_OK;
+
+error:
+       return ret;
+}
+
+
+/*
+ * Command LTTNG_CREATE_SESSION processed by the client thread.
+ */
+static int cmd_create_session_uri(char *name, struct lttng_uri *uris,
+               size_t nb_uri, lttng_sock_cred *creds)
+{
+       int ret;
+       char *path = NULL;
+       struct ltt_session *session;
+       //struct consumer_output *consumer = NULL;
+       //struct lttng_uri *ctrl_uri, *data_uri = NULL;
+
+       assert(name);
+
+       /*
+        * Verify if the session already exist
+        *
+        * XXX: There is no need for the session lock list here since the caller
+        * (process_client_msg) is holding it. We might want to change that so a
+        * single command does not lock the entire session list.
+        */
+       session = session_find_by_name(name);
+       if (session != NULL) {
+               ret = LTTCOMM_EXIST_SESS;
+               goto find_error;
+       }
 
-skip_consumer:
        /* Create tracing session in the registry */
        ret = session_create(name, path, LTTNG_SOCK_GET_UID_CRED(creds),
                        LTTNG_SOCK_GET_GID_CRED(creds));
        if (ret != LTTCOMM_OK) {
-               goto error;
+               goto session_error;
        }
 
        /*
@@ -3637,32 +3722,43 @@ skip_consumer:
        session = session_find_by_name(name);
        assert(session);
 
-       /* Assign consumer to session */
-       session->consumer = consumer;
+       /* Create default consumer output for the session not yet created. */
+       session->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
+       if (session->consumer == NULL) {
+               ret = LTTCOMM_FATAL;
+               goto consumer_error;
+       }
 
-       /* Set correct path to session */
-       if (have_default_name) {
-               /* We have the default session so the date-time is already appended */
-               ret = snprintf(session->path, sizeof(session->path), "%s/%s",
-                               path, name);
-       } else {
-               ret = snprintf(session->path, sizeof(session->path), "%s/%s-%s",
-                               path, name, datetime);
+       /*
+        * This means that the lttng_create_session call was called with the _path_
+        * argument set to NULL.
+        */
+       if (uris == NULL) {
+               /*
+                * At this point, we'll skip the consumer URI setup and create a
+                * session with a NULL path which will flag the session to NOT spawn a
+                * consumer.
+                */
+               DBG("Create session %s with NO uri, skipping consumer setup", name);
+               goto end;
        }
-       if (ret < 0) {
-               PERROR("snprintf session path");
-               goto session_error;
+
+       session->start_consumer = 1;
+
+       ret = cmd_set_consumer_uri(0, session, nb_uri, uris);
+       if (ret != LTTCOMM_OK) {
+               goto consumer_error;
        }
 
+       session->consumer->enabled = 1;
+
+end:
        return LTTCOMM_OK;
 
-session_error:
-       session_destroy(session);
-error:
-       rcu_read_lock();
-       consumer_destroy_output(consumer);
-       rcu_read_unlock();
 consumer_error:
+       session_destroy(session);
+session_error:
+find_error:
        return ret;
 }
 
@@ -3920,122 +4016,6 @@ error:
        return ret;
 }
 
-/*
- * Command LTTNG_SET_CONSUMER_URI processed by the client thread.
- */
-static int cmd_set_consumer_uri(int domain, struct ltt_session *session,
-               size_t nb_uri, struct lttng_uri *uris)
-{
-       int ret, i;
-       struct ltt_kernel_session *ksess = session->kernel_session;
-       struct ltt_ust_session *usess = session->ust_session;
-       struct consumer_output *consumer = NULL;
-
-       assert(session);
-       assert(uris);
-       assert(nb_uri > 0);
-
-       /* Can't enable consumer after session started. */
-       if (session->enabled) {
-               ret = LTTCOMM_TRACE_ALREADY_STARTED;
-               goto error;
-       }
-
-       if (!session->start_consumer) {
-               ret = LTTCOMM_NO_CONSUMER;
-               goto error;
-       }
-
-       /*
-        * This case switch makes sure the domain session has a temporary consumer
-        * so the URL can be set.
-        */
-       switch (domain) {
-       case 0:
-               /* Code flow error. A session MUST always have a consumer object */
-               assert(session->consumer);
-               /*
-                * The URL will be added to the tracing session consumer instead of a
-                * specific domain consumer.
-                */
-               consumer = session->consumer;
-               break;
-       case LTTNG_DOMAIN_KERNEL:
-               /* Code flow error if we don't have a kernel session here. */
-               assert(ksess);
-
-               /* Create consumer output if none exists */
-               consumer = ksess->tmp_consumer;
-               if (consumer == NULL) {
-                       consumer = consumer_copy_output(ksess->consumer);
-                       if (consumer == NULL) {
-                               ret = LTTCOMM_FATAL;
-                               goto error;
-                       }
-                       ksess->tmp_consumer = consumer;
-               }
-
-               break;
-       case LTTNG_DOMAIN_UST:
-               /* Code flow error if we don't have a kernel session here. */
-               assert(usess);
-
-               /* Create consumer output if none exists */
-               consumer = usess->tmp_consumer;
-               if (consumer == NULL) {
-                       consumer = consumer_copy_output(usess->consumer);
-                       if (consumer == NULL) {
-                               ret = LTTCOMM_FATAL;
-                               goto error;
-                       }
-                       usess->tmp_consumer = consumer;
-               }
-
-               break;
-       }
-
-       for (i = 0; i < nb_uri; i++) {
-               struct consumer_socket *socket;
-               struct lttng_ht_iter iter;
-
-               ret = add_uri_to_consumer(consumer, &uris[i], domain);
-               if (ret < 0) {
-                       goto error;
-               }
-
-               /*
-                * Don't send relayd socket if URI is NOT remote or if the relayd
-                * sockets for the session are already sent.
-                */
-               if (uris[i].dtype == LTTNG_DST_PATH ||
-                               consumer->dst.net.relayd_socks_sent) {
-                       continue;
-               }
-
-               /* Try to send relayd URI to the consumer if exist. */
-               cds_lfht_for_each_entry(consumer->socks->ht, &iter.iter,
-                               socket, node.node) {
-
-                       /* A socket in the HT should never have a negative fd */
-                       assert(socket->fd >= 0);
-
-                       pthread_mutex_lock(socket->lock);
-                       ret = send_socket_relayd_consumer(domain, session, &uris[i],
-                                       consumer, socket->fd);
-                       pthread_mutex_unlock(socket->lock);
-                       if (ret != LTTCOMM_OK) {
-                               goto error;
-                       }
-               }
-       }
-
-       /* All good! */
-       ret = LTTCOMM_OK;
-
-error:
-       return ret;
-}
-
 /*
  * Command LTTNG_DISABLE_CONSUMER processed by the client thread.
  */
@@ -4183,13 +4163,13 @@ static int cmd_enable_consumer(int domain, struct ltt_session *session)
                                goto error;
                        }
 
-                       /* Append default kernel trace dir to subdir */
-                       strncat(ksess->consumer->subdir, DEFAULT_KERNEL_TRACE_DIR,
-                                       sizeof(ksess->consumer->subdir));
-
                        break;
                }
 
+               /* Append default kernel trace dir to subdir */
+               strncat(ksess->consumer->subdir, DEFAULT_KERNEL_TRACE_DIR,
+                               sizeof(ksess->consumer->subdir));
+
                /*
                 * @session-lock
                 * This is race free for now since the session lock is acquired before
@@ -4268,13 +4248,13 @@ static int cmd_enable_consumer(int domain, struct ltt_session *session)
                                goto error;
                        }
 
-                       /* Append default kernel trace dir to subdir */
-                       strncat(usess->consumer->subdir, DEFAULT_UST_TRACE_DIR,
-                                       sizeof(usess->consumer->subdir));
-
                        break;
                }
 
+               /* Append default kernel trace dir to subdir */
+               strncat(usess->consumer->subdir, DEFAULT_UST_TRACE_DIR,
+                               sizeof(usess->consumer->subdir));
+
                /*
                 * @session-lock
                 * This is race free for now since the session lock is acquired before
index e445363ea03d214d90a4f4ded762ad9593d818b1..75fcf4bfded58320ab6723e9ae0e574740107b24 100644 (file)
@@ -149,6 +149,10 @@ int session_destroy(struct ltt_session *session)
        DBG("Destroying session %s", session->name);
        del_session_list(session);
        pthread_mutex_destroy(&session->lock);
+
+       rcu_read_lock();
+       consumer_destroy_output(session->consumer);
+       rcu_read_unlock();
        free(session);
 
        return LTTCOMM_OK;
index 3e7074e02bc0e35f611fb2e9347342159a7234d2..dd10ab22767b8718ef232f4c19656e758b79c9bf 100644 (file)
@@ -60,6 +60,10 @@ static struct poptOption long_options[] = {
        {0, 0, 0, 0, 0, 0, 0}
 };
 
+/* HACK */
+extern int _lttng_create_session_ext(const char *name, const char *url,
+               const char *datetime);
+
 /*
  * usage
  */
@@ -245,8 +249,9 @@ error:
 static int create_session(void)
 {
        int ret;
-       char *session_name, *traces_path = NULL, *alloc_path = NULL;
+       char *session_name = NULL, *traces_path = NULL, *alloc_path = NULL;
        char *alloc_url = NULL, *url = NULL, datetime[16];
+       char session_name_date[NAME_MAX];
        time_t rawtime;
        struct tm *timeinfo;
 
@@ -257,14 +262,26 @@ static int create_session(void)
 
        /* Auto session name creation */
        if (opt_session_name == NULL) {
-               ret = asprintf(&session_name, DEFAULT_SESSION_NAME "%s", datetime);
+               ret = snprintf(session_name_date, sizeof(session_name_date),
+                               DEFAULT_SESSION_NAME "-%s", datetime);
                if (ret < 0) {
-                       PERROR("asprintf session name");
+                       PERROR("snprintf session name");
+                       goto error;
+               }
+               session_name = strdup(DEFAULT_SESSION_NAME);
+               if (session_name == NULL) {
+                       PERROR("strdup session name");
                        goto error;
                }
-               DBG("Auto session name set to %s", session_name);
+               DBG("Auto session name set to %s", session_name_date);
        } else {
                session_name = opt_session_name;
+               ret = snprintf(session_name_date, sizeof(session_name_date),
+                               "%s-%s", session_name, datetime);
+               if (ret < 0) {
+                       PERROR("snprintf session name");
+                       goto error;
+               }
        }
 
        if (opt_no_consumer) {
@@ -300,8 +317,9 @@ static int create_session(void)
                }
                alloc_path = strdup(alloc_path);
 
-               ret = asprintf(&alloc_url, "file://%s/" DEFAULT_TRACE_DIR_NAME,
-                               alloc_path);
+               ret = asprintf(&alloc_url,
+                               "file://%s/" DEFAULT_TRACE_DIR_NAME "/%s",
+                               alloc_path, session_name_date);
                if (ret < 0) {
                        PERROR("asprintf trace dir name");
                        ret = CMD_FATAL;
@@ -312,7 +330,7 @@ static int create_session(void)
                MSG("Trace(s) output set to %s", alloc_url + strlen("file://"));
        }
 
-       ret = lttng_create_session(session_name, url);
+       ret = _lttng_create_session_ext(session_name, url, datetime);
        if (ret < 0) {
                /* Don't set ret so lttng can interpret the sessiond error. */
                switch (-ret) {
@@ -324,7 +342,7 @@ static int create_session(void)
        }
 
        if (opt_session_name == NULL) {
-               MSG("Session created with default name %s", session_name);
+               MSG("Session created with default name %s", session_name_date);
        } else {
                MSG("Session %s created.", session_name);
        }
@@ -349,6 +367,11 @@ static int create_session(void)
                }
        }
 
+       if (opt_session_name == NULL) {
+               free(session_name);
+               session_name = session_name_date;
+       }
+
        /* Init lttng session config */
        ret = config_init(session_name);
        if (ret < 0) {
@@ -356,10 +379,11 @@ static int create_session(void)
                goto error;
        }
 
+
        ret = CMD_SUCCESS;
 
 error:
-       if (opt_session_name == NULL) {
+       if (opt_session_name == NULL && session_name != session_name_date) {
                free(session_name);
        }
 
index 0303c02ae80cee9a42548b8b012b8a19591eb3ae..ad1b708a3a5825be66bc33e864276b3a4d9f7db2 100644 (file)
@@ -48,7 +48,7 @@
  * Default session name for the lttng command line. This default value will
  * get the date and time appended (%Y%m%d-%H%M%S) to it.
  */
-#define DEFAULT_SESSION_NAME                    "auto-"
+#define DEFAULT_SESSION_NAME                    "auto"
 
 /* Default consumer paths */
 #define DEFAULT_CONSUMERD_RUNDIR                "%s"
index 064f739aa329d939ceefd116e5cb09f387ef7a20..f18e8ca07358050f58926faece98fb5a500ce910 100644 (file)
@@ -1496,6 +1496,71 @@ error:
        return ret;
 }
 
+/*
+ * This is an extension of create session that is ONLY and SHOULD only be used
+ * by the lttng command line program. It exists to avoid using URI parsing in
+ * the lttng client.
+ *
+ * We need the date and time for the trace path subdirectory for the case where
+ * the user does NOT define one using either -o or -U. Using the normal
+ * lttng_create_session API call, we have no clue on the session daemon side if
+ * the URL was generated automatically by the client or define by the user.
+ *
+ * So this function "wrapper" is hidden from the public API, takes the datetime
+ * string and appends it if necessary to the URI subdirectory before sending it
+ * to the session daemon.
+ *
+ * With this extra function, the lttng_create_session call behavior is not
+ * changed and the timestamp is appended to the URI on the session daemon side
+ * if necessary.
+ */
+int _lttng_create_session_ext(const char *name, const char *url,
+               const char *datetime)
+{
+       int ret;
+       ssize_t size;
+       struct lttcomm_session_msg lsm;
+       struct lttng_uri *uris = NULL;
+
+       if (name == NULL || datetime == NULL) {
+               return -1;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+
+       lsm.cmd_type = LTTNG_CREATE_SESSION;
+       if (!strncmp(name, DEFAULT_SESSION_NAME, strlen(DEFAULT_SESSION_NAME))) {
+               ret = snprintf(lsm.session.name, sizeof(lsm.session.name), "%s-%s",
+                               name, datetime);
+               if (ret < 0) {
+                       PERROR("snprintf session name datetime");
+                       return -1;
+               }
+       } else {
+               copy_string(lsm.session.name, name, sizeof(lsm.session.name));
+       }
+
+       /* There should never be a data URL */
+       size = parse_str_urls_to_uri(url, NULL, &uris);
+       if (size < 0) {
+               return LTTCOMM_INVALID;
+       }
+
+       lsm.u.uri.size = size;
+
+       if (uris[0].dtype != LTTNG_DST_PATH && strlen(uris[0].subdir) == 0) {
+               ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "/%s-%s", name,
+                               datetime);
+               if (ret < 0) {
+                       PERROR("snprintf uri subdir");
+                       return -1;
+               }
+       }
+
+       return ask_sessiond_varlen(&lsm, uris, sizeof(struct lttng_uri) * size,
+                       NULL);
+}
+
 /*
  * lib constructor
  */
index f4cfe57b9ffa2f332b46038563fd7d084b4c9aaf..074c8ec8f516876426c958429017561af85abd7d 100644 (file)
@@ -8,7 +8,10 @@ EXTRA_DIST = runall.sh
 noinst_PROGRAMS = test_sessions test_kernel_data_trace
 
 UTILS=../utils.h
-SESSIONS=$(top_srcdir)/src/bin/lttng-sessiond/session.c
+SESSIONS=$(top_srcdir)/src/bin/lttng-sessiond/session.c \
+                $(top_srcdir)/src/bin/lttng-sessiond/consumer.c \
+                $(top_srcdir)/src/common/uri.c \
+                $(top_srcdir)/src/common/utils.c
 KERN_DATA_TRACE=$(top_srcdir)/src/bin/lttng-sessiond/trace-kernel.c \
                                $(top_srcdir)/src/bin/lttng-sessiond/consumer.c \
                                $(top_srcdir)/src/common/uri.c \
@@ -19,7 +22,7 @@ SESSIOND_COMM=$(top_builddir)/src/common/sessiond-comm/libsessiond-comm.la
 
 # Tracing sessions unit tests
 test_sessions_SOURCES = test_sessions.c $(UTILS) $(SESSIONS)
-test_sessions_LDADD = $(COMMON) $(HASHTABLE)
+test_sessions_LDADD = $(COMMON) $(HASHTABLE) $(SESSIOND_COMM)
 
 # Kernel trace data unit tests
 test_kernel_data_trace_SOURCES = test_kernel_data_trace.c $(UTILS) $(KERN_DATA_TRACE)
This page took 0.039902 seconds and 4 git commands to generate.