Add create session snapshot API in lttng-sessiond
authorDavid Goulet <dgoulet@efficios.com>
Mon, 8 Jul 2013 19:19:12 +0000 (15:19 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Fri, 12 Jul 2013 15:05:02 +0000 (11:05 -0400)
This commit adds the "lttng_create_session_snapshot()" call to the API
which will create on the session daemon a session in snapshot mode
meaning that all channel will be in overwrite mode and mmap output.

Signed-off-by: David Goulet <dgoulet@efficios.com>
13 files changed:
include/lttng/lttng.h
src/bin/lttng-sessiond/channel.c
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/cmd.h
src/bin/lttng-sessiond/main.c
src/bin/lttng-sessiond/session.h
src/bin/lttng-sessiond/snapshot.h
src/bin/lttng-sessiond/trace-kernel.h
src/bin/lttng-sessiond/trace-ust.h
src/bin/lttng/commands/snapshot.c
src/common/defaults.h
src/common/sessiond-comm/sessiond-comm.h
src/lib/lttng-ctl/lttng-ctl.c

index 3e7fb63169e83b780ad247a3fda616bbade91050..9e3924e67656bf174dc373beb689078d715bc510 100644 (file)
@@ -390,6 +390,21 @@ extern void lttng_destroy_handle(struct lttng_handle *handle);
  */
 extern int lttng_create_session(const char *name, const char *url);
 
+/*
+ * Create a tracing session that will exclusively be used for snapshot meaning
+ * the session will be in no output mode and every channel enabled for that
+ * session will be set in overwrite mode and in mmap output since splice is not
+ * supported.
+ *
+ * If an url is given, it will be used to create a default snapshot output
+ * using it as a destination. If NULL, no output will be defined and an
+ * add-output call will be needed.
+ *
+ * Name can't be NULL.
+ */
+extern int lttng_create_session_snapshot(const char *name,
+               const char *snapshot_url);
+
 /*
  * Destroy a tracing session.
  *
index d826125c9b8c7acaf5a57f294aeb7d29f78803ea..984576edc2e03b68595348f643dfa2e9c19ebdbb 100644 (file)
@@ -184,6 +184,12 @@ int channel_kernel_create(struct ltt_kernel_session *ksession,
                attr = defattr;
        }
 
+       if (ksession->snapshot_mode) {
+               /* Force channel attribute for snapshot mode. */
+               attr->attr.overwrite = 1;
+               attr->attr.output = LTTNG_EVENT_MMAP;
+       }
+
        /* Channel not found, creating it */
        ret = kernel_create_channel(ksession, attr);
        if (ret < 0) {
@@ -263,6 +269,12 @@ int channel_ust_create(struct ltt_ust_session *usess,
                attr = defattr;
        }
 
+       if (usess->snapshot_mode) {
+               /* Force channel attribute for snapshot mode. */
+               attr->attr.overwrite = 1;
+               attr->attr.output = LTTNG_EVENT_MMAP;
+       }
+
        /*
         * Validate UST buffer size and number of buffers: must both be power of 2
         * and nonzero. We validate right here for UST, because applications will
index a6a81c5dbd79989b474ffa1ee5b5d3c5edc83389..60a4ef2fbd95a9a5d5af29e6b509902ca801a29f 100644 (file)
@@ -1743,6 +1743,72 @@ find_error:
        return ret;
 }
 
+/*
+ * Command LTTNG_CREATE_SESSION_SNAPSHOT processed by the client thread.
+ */
+int cmd_create_session_snapshot(char *name, struct lttng_uri *uris,
+               size_t nb_uri, lttng_sock_cred *creds)
+{
+       int ret;
+       struct ltt_session *session;
+       struct snapshot_output *new_output = NULL;
+
+       assert(name);
+       assert(creds);
+
+       /*
+        * Create session in no output mode with URIs set to NULL. The uris we've
+        * received are for a default snapshot output if one.
+        */
+       ret = cmd_create_session_uri(name, NULL, 0, creds);
+       if (ret != LTTNG_OK) {
+               goto error;
+       }
+
+       /* Get the newly created session pointer back. This should NEVER fail. */
+       session = session_find_by_name(name);
+       assert(session);
+
+       /* Flag session for snapshot mode. */
+       session->snapshot_mode = 1;
+
+       /* Skip snapshot output creation if no URI is given. */
+       if (nb_uri == 0) {
+               goto end;
+       }
+
+       new_output = snapshot_output_alloc();
+       if (!new_output) {
+               ret = LTTNG_ERR_NOMEM;
+               goto error_snapshot_alloc;
+       }
+
+       ret = snapshot_output_init_with_uri(DEFAULT_SNAPSHOT_MAX_SIZE, NULL,
+                       uris, nb_uri, session->consumer, new_output, &session->snapshot);
+       if (ret < 0) {
+               if (ret == -ENOMEM) {
+                       ret = LTTNG_ERR_NOMEM;
+               } else {
+                       ret = LTTNG_ERR_INVALID;
+               }
+               goto error_snapshot;
+       }
+
+       rcu_read_lock();
+       snapshot_add_output(&session->snapshot, new_output);
+       rcu_read_unlock();
+
+end:
+       return LTTNG_OK;
+
+error_snapshot:
+       snapshot_output_destroy(new_output);
+error_snapshot_alloc:
+       session_destroy(session);
+error:
+       return ret;
+}
+
 /*
  * Command LTTNG_DESTROY_SESSION processed by the client thread.
  */
index 5be1688c9c97b502bd3292820741a618eb3afa61..830d8216aa87225a26e327927140805b0769bc03 100644 (file)
@@ -30,6 +30,8 @@ void cmd_init(void);
 /* Session commands */
 int cmd_create_session_uri(char *name, struct lttng_uri *uris,
                size_t nb_uri, lttng_sock_cred *creds);
+int cmd_create_session_snapshot(char *name, struct lttng_uri *uris,
+               size_t nb_uri, lttng_sock_cred *creds);
 int cmd_destroy_session(struct ltt_session *session, int wpipe);
 
 /* Channel commands */
index 048c1e16d83feb66ff4c499470189e655e163727..1d047fd85240582854f5a6c50744b23ce7ac4cb1 100644 (file)
@@ -2428,6 +2428,7 @@ static int create_ust_session(struct ltt_session *session,
        lus->uid = session->uid;
        lus->gid = session->gid;
        lus->output_traces = session->output_traces;
+       lus->snapshot_mode = session->snapshot_mode;
        session->ust_session = lus;
 
        /* Copy session output to the newly created UST session */
@@ -2485,6 +2486,7 @@ static int create_kernel_session(struct ltt_session *session)
        session->kernel_session->uid = session->uid;
        session->kernel_session->gid = session->gid;
        session->kernel_session->output_traces = session->output_traces;
+       session->kernel_session->snapshot_mode = session->snapshot_mode;
 
        return LTTNG_OK;
 
@@ -2540,6 +2542,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock,
 
        switch (cmd_ctx->lsm->cmd_type) {
        case LTTNG_CREATE_SESSION:
+       case LTTNG_CREATE_SESSION_SNAPSHOT:
        case LTTNG_DESTROY_SESSION:
        case LTTNG_LIST_SESSIONS:
        case LTTNG_LIST_DOMAINS:
@@ -2602,6 +2605,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock,
        /* Commands that DO NOT need a session. */
        switch (cmd_ctx->lsm->cmd_type) {
        case LTTNG_CREATE_SESSION:
+       case LTTNG_CREATE_SESSION_SNAPSHOT:
        case LTTNG_CALIBRATE:
        case LTTNG_LIST_SESSIONS:
        case LTTNG_LIST_TRACEPOINTS:
@@ -3293,6 +3297,45 @@ skip_domain:
                                cmd_ctx->lsm->u.snapshot_record.wait);
                break;
        }
+       case LTTNG_CREATE_SESSION_SNAPSHOT:
+       {
+               size_t nb_uri, len;
+               struct lttng_uri *uris = NULL;
+
+               nb_uri = cmd_ctx->lsm->u.uri.size;
+               len = nb_uri * sizeof(struct lttng_uri);
+
+               if (nb_uri > 0) {
+                       uris = zmalloc(len);
+                       if (uris == NULL) {
+                               ret = LTTNG_ERR_FATAL;
+                               goto error;
+                       }
+
+                       /* Receive variable len data */
+                       DBG("Waiting for %zu URIs from client ...", nb_uri);
+                       ret = lttcomm_recv_unix_sock(sock, uris, len);
+                       if (ret <= 0) {
+                               DBG("No URIs received from client... continuing");
+                               *sock_error = 1;
+                               ret = LTTNG_ERR_SESSION_FAIL;
+                               free(uris);
+                               goto error;
+                       }
+
+                       if (nb_uri == 1 && uris[0].dtype != LTTNG_DST_PATH) {
+                               DBG("Creating session with ONE network URI is a bad call");
+                               ret = LTTNG_ERR_SESSION_FAIL;
+                               free(uris);
+                               goto error;
+                       }
+               }
+
+               ret = cmd_create_session_snapshot(cmd_ctx->lsm->session.name, uris,
+                               nb_uri, &cmd_ctx->creds);
+               free(uris);
+               break;
+       }
        default:
                ret = LTTNG_ERR_UND;
                break;
index 7b927efe1103aa8950c16530f86a3ec5582497e8..0fd2fb16a4dc416c73784611300085651ce857fc 100644 (file)
@@ -93,6 +93,12 @@ struct ltt_session {
        struct snapshot snapshot;
        /* Indicate if the session has to output the traces or not. */
        unsigned int output_traces;
+       /*
+        * This session is in snapshot mode. This means that every channel enabled
+        * will be set in overwrite mode and mmap. It is considered exclusively for
+        * snapshot purposes.
+        */
+       unsigned int snapshot_mode;
 };
 
 /* Prototypes */
index bf594b5fe3f79d7cb3bd99cdd67afec2b483a9a5..44d2ae7f5ba283039f9d9cb4ea9933834ad17af0 100644 (file)
@@ -69,6 +69,10 @@ int snapshot_output_init(uint64_t max_size, const char *name,
                const char *ctrl_url, const char *data_url,
                struct consumer_output *consumer, struct snapshot_output *output,
                struct snapshot *snapshot);
+int snapshot_output_init_with_uri(uint64_t max_size, const char *name,
+               struct lttng_uri *uris, size_t nb_uri,
+               struct consumer_output *consumer, struct snapshot_output *output,
+               struct snapshot *snapshot);
 struct snapshot_output *snapshot_find_output_by_id(uint32_t id,
                struct snapshot *snapshot);
 
index 68301967a15f7cae616f85f24b42afc2c9f83fe7..5502e42bdb4d8304186779eae182548a10574537 100644 (file)
@@ -113,6 +113,7 @@ struct ltt_kernel_session {
        unsigned int started;
        /* Tell or not if the session has to output the traces. */
        unsigned int output_traces;
+       unsigned int snapshot_mode;
 };
 
 /*
index 0dac36b213f5d76f7f82c4c1b8c677e5d3b79c0e..5ca7964ea40c074e853e4a49cd7c28f37a28cab4 100644 (file)
@@ -107,6 +107,7 @@ struct ltt_ust_session {
        uint64_t used_channel_id;
        /* Tell or not if the session has to output the traces. */
        unsigned int output_traces;
+       unsigned int snapshot_mode;
 };
 
 /*
index 2a223d44509721fedbdbcbe6bc2f3c12da72828a..0c15dbb70fa5f6b8f2adb8f314d9db4b4b773432 100644 (file)
@@ -343,8 +343,6 @@ static int record(const char *url)
        } else if (opt_ctrl_url) {
                MSG("Snapshot written to ctrl: %s, data: %s", opt_ctrl_url,
                                opt_data_url);
-       } else {
-               MSG("Snapshot written in session directory.");
        }
 
 error:
index 388b9f0d78348b54ed97889139b69a720d2ebb7e..242be1e7266fd1118728e671e26d4d24d7c7e29a 100644 (file)
 #define DEFAULT_UST_STREAM_FD_NUM                      2 /* Number of fd per UST stream. */
 
 #define DEFAULT_SNAPSHOT_NAME                          "snapshot"
+#define DEFAULT_SNAPSHOT_MAX_SIZE                      0 /* Unlimited. */
 
 extern size_t default_channel_subbuf_size;
 extern size_t default_metadata_subbuf_size;
index b76135e2cf08f2b21a2356a3bbef33aca21ae5a1..2ee761749558ebe8e169e38d2c2859bedb9f5506 100644 (file)
@@ -87,6 +87,7 @@ enum lttcomm_sessiond_command {
        LTTNG_SNAPSHOT_DEL_OUTPUT           = 26,
        LTTNG_SNAPSHOT_LIST_OUTPUT          = 27,
        LTTNG_SNAPSHOT_RECORD               = 28,
+       LTTNG_CREATE_SESSION_SNAPSHOT       = 29,
 };
 
 enum lttcomm_relayd_command {
index 3863aa1ceb9de16836d4edc6c55d908fd289e08f..d8d5db6c7ff6838d087309c421c83cb919e0758c 100644 (file)
@@ -1547,6 +1547,41 @@ int lttng_data_pending(const char *session_name)
        return ret;
 }
 
+/*
+ * Create a session exclusively used for snapshot.
+ *
+ * Returns LTTNG_OK on success or a negative error code.
+ */
+int lttng_create_session_snapshot(const char *name, const char *snapshot_url)
+{
+       int ret;
+       ssize_t size;
+       struct lttcomm_session_msg lsm;
+       struct lttng_uri *uris = NULL;
+
+       if (name == NULL) {
+               return -LTTNG_ERR_INVALID;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+
+       lsm.cmd_type = LTTNG_CREATE_SESSION_SNAPSHOT;
+       lttng_ctl_copy_string(lsm.session.name, name, sizeof(lsm.session.name));
+
+       size = uri_parse_str_urls(snapshot_url, NULL, &uris);
+       if (size < 0) {
+               return -LTTNG_ERR_INVALID;
+       }
+
+       lsm.u.uri.size = size;
+
+       ret = lttng_ctl_ask_sessiond_varlen(&lsm, uris,
+                       sizeof(struct lttng_uri) * size, NULL);
+
+       free(uris);
+       return ret;
+}
+
 /*
  * lib constructor
  */
This page took 0.033425 seconds and 4 git commands to generate.