Allow regenerating the statedump of a running session
authorJulien Desfossez <jdesfossez@efficios.com>
Tue, 5 Jul 2016 14:54:36 +0000 (10:54 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 6 Jul 2016 18:26:16 +0000 (14:26 -0400)
The "lttng regenerate statedump" command can be used to regenerate the
statedump of a running session whenever needed. This is particularly
useful in snapshot and trace-file rotation modes where the original
statedump may be lost.

Signed-off-by: Julien Desfossez <jdesfossez@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
13 files changed:
include/lttng/lttng-error.h
include/lttng/lttng.h
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/cmd.h
src/bin/lttng-sessiond/main.c
src/bin/lttng-sessiond/ust-app.c
src/bin/lttng-sessiond/ust-app.h
src/bin/lttng/commands/regenerate.c
src/common/error.c
src/common/kernel-ctl/kernel-ctl.c
src/common/kernel-ctl/kernel-ctl.h
src/common/sessiond-comm/sessiond-comm.h
src/lib/lttng-ctl/lttng-ctl.c

index 72194ef2c99af143abff81763d2f14932dc5cf7f..df59f8f7b04c77f1a29e9fc09b160aab04d93f68 100644 (file)
@@ -142,6 +142,8 @@ enum lttng_error_code {
        LTTNG_ERR_LIVE_SESSION           = 119, /* Live session unsupported */
        LTTNG_ERR_PER_PID_SESSION        = 120, /* Per-PID sessions unsupported */
        LTTNG_ERR_KERN_CONTEXT_UNAVAILABLE = 121, /* Context unavailable on this kernel */
+       LTTNG_ERR_REGEN_STATEDUMP_FAIL   = 122, /* Failed to regenerate the state dump */
+       LTTNG_ERR_REGEN_STATEDUMP_NOMEM   = 123, /* Failed to regenerate the state dump, not enough memory */
 
        /* MUST be last element */
        LTTNG_ERR_NR,                           /* Last element */
index 09aa969f57f87345d34a43aa27366e717fab5c54..d37d6c06510528423025fd4ba250fb87651e83cd 100644 (file)
@@ -173,6 +173,15 @@ extern int lttng_metadata_regenerate(const char *session_name);
  */
 extern int lttng_regenerate_metadata(const char *session_name);
 
+/*
+ * Trigger the regeneration of the statedump for a session. The new statedump
+ * information is appended to the currently active trace, the session needs to
+ * be active.
+ *
+ * Return 0 on success, a negative LTTng error code on error.
+ */
+extern int lttng_regenerate_statedump(const char *session_name);
+
 #ifdef __cplusplus
 }
 #endif
index bd63389ee94b510986c545644017607a35106152..a57afe2c3016be26e9b378d9f42996bbc6cd7545 100644 (file)
@@ -3539,6 +3539,61 @@ end:
        return ret;
 }
 
+/*
+ * Command LTTNG_REGENERATE_STATEDUMP from the lttng-ctl library.
+ *
+ * Ask the tracer to regenerate a new statedump.
+ *
+ * Return 0 on success or else a LTTNG_ERR code.
+ */
+int cmd_regenerate_statedump(struct ltt_session *session)
+{
+       int ret;
+
+       assert(session);
+
+       if (!session->active) {
+               ret = LTTNG_ERR_SESSION_NOT_STARTED;
+               goto end;
+       }
+       ret = 0;
+
+       if (session->kernel_session) {
+               ret = kernctl_session_regenerate_statedump(
+                               session->kernel_session->fd);
+               /*
+                * Currently, the statedump in kernel can only fail if out
+                * of memory.
+                */
+               if (ret < 0) {
+                       if (ret == -ENOMEM) {
+                               ret = LTTNG_ERR_REGEN_STATEDUMP_NOMEM;
+                       } else {
+                               ret = LTTNG_ERR_REGEN_STATEDUMP_FAIL;
+                       }
+                       ERR("Failed to regenerate the kernel statedump");
+                       goto end;
+               }
+       }
+
+       if (session->ust_session) {
+               ret = ust_app_regenerate_statedump_all(session->ust_session);
+               /*
+                * Currently, the statedump in UST always returns 0.
+                */
+               if (ret < 0) {
+                       ret = LTTNG_ERR_REGEN_STATEDUMP_FAIL;
+                       ERR("Failed to regenerate the UST statedump");
+                       goto end;
+               }
+       }
+       DBG("Cmd regenerate statedump for session %s", session->name);
+       ret = LTTNG_OK;
+
+end:
+       return ret;
+}
+
 /*
  * Send relayd sockets from snapshot output to consumer. Ignore request if the
  * snapshot output is *not* set with a remote destination.
index 320d717a39e28da651ea1d8a1bea8f5ce431237e..975a7f10f53110e84a485309c08f9d7407e291b8 100644 (file)
@@ -111,5 +111,6 @@ int cmd_snapshot_record(struct ltt_session *session,
 int cmd_set_session_shm_path(struct ltt_session *session,
                const char *shm_path);
 int cmd_regenerate_metadata(struct ltt_session *session);
+int cmd_regenerate_statedump(struct ltt_session *session);
 
 #endif /* CMD_H */
index afd0cc6e14f3cdf5d9ff6793ad4c0d60b917adcc..67df2fa2fbd0d5fd92545955327ba3bd81ba0f0d 100644 (file)
@@ -3005,6 +3005,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock,
        case LTTNG_SAVE_SESSION:
        case LTTNG_SET_SESSION_SHM_PATH:
        case LTTNG_REGENERATE_METADATA:
+       case LTTNG_REGENERATE_STATEDUMP:
                need_domain = 0;
                break;
        default:
@@ -4120,6 +4121,11 @@ error_add_context:
                ret = cmd_regenerate_metadata(cmd_ctx->session);
                break;
        }
+       case LTTNG_REGENERATE_STATEDUMP:
+       {
+               ret = cmd_regenerate_statedump(cmd_ctx->session);
+               break;
+       }
        default:
                ret = LTTNG_ERR_UND;
                break;
index f30df2097fd36aea2b03d2f30f96d791226dc1a9..47bd04cd837d76c2ecc8f4588ca7077d7581de49 100644 (file)
@@ -6148,3 +6148,69 @@ end:
        rcu_read_unlock();
        return ret;
 }
+
+static
+int ust_app_regenerate_statedump(struct ltt_ust_session *usess,
+               struct ust_app *app)
+{
+       int ret = 0;
+       struct ust_app_session *ua_sess;
+
+       DBG("Regenerating the metadata for ust app pid %d", app->pid);
+
+       rcu_read_lock();
+
+       ua_sess = lookup_session_by_app(usess, app);
+       if (ua_sess == NULL) {
+               /* The session is in teardown process. Ignore and continue. */
+               goto end;
+       }
+
+       pthread_mutex_lock(&ua_sess->lock);
+
+       if (ua_sess->deleted) {
+               goto end_unlock;
+       }
+
+       pthread_mutex_lock(&app->sock_lock);
+       ret = ustctl_regenerate_statedump(app->sock, ua_sess->handle);
+       pthread_mutex_unlock(&app->sock_lock);
+
+end_unlock:
+       pthread_mutex_unlock(&ua_sess->lock);
+
+end:
+       rcu_read_unlock();
+       health_code_update();
+       return ret;
+}
+
+/*
+ * Regenerate the statedump for each app in the session.
+ */
+int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess)
+{
+       int ret = 0;
+       struct lttng_ht_iter iter;
+       struct ust_app *app;
+
+       DBG("Regenerating the metadata for all UST apps");
+
+       rcu_read_lock();
+
+       cds_lfht_for_each_entry(ust_app_ht->ht, &iter.iter, app, pid_n.node) {
+               if (!app->compatible) {
+                       continue;
+               }
+
+               ret = ust_app_regenerate_statedump(usess, app);
+               if (ret < 0) {
+                       /* Continue to the next app even on error */
+                       continue;
+               }
+       }
+
+       rcu_read_unlock();
+
+       return 0;
+}
index d02f353c856a985b7a97737a230f1b0f07946492..8369d149cf59d0902e31de83e99b7377ad792d01 100644 (file)
@@ -352,6 +352,7 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess,
                struct ltt_ust_channel *uchan,
                struct consumer_output *consumer,
                int overwrite, uint64_t *discarded, uint64_t *lost);
+int ust_app_regenerate_statedump_all(struct ltt_ust_session *usess);
 
 static inline
 int ust_app_supported(void)
@@ -583,6 +584,11 @@ int ust_app_pid_get_channel_runtime_stats(struct ltt_ust_session *usess,
 {
        return 0;
 }
+static inline
+int ust_app_regenerate_metadata_all(struct ltt_ust_session *usess)
+{
+       return 0;
+}
 
 #endif /* HAVE_LIBLTTNG_UST_CTL */
 
index c64d8fe530c8b9d0e6ac2f94e655ba7193efe56f..5c982c8a68752ef440c462f4f1fd5eb97790ff01 100644 (file)
@@ -32,6 +32,7 @@ static char *opt_session_name;
 static char *session_name = NULL;
 
 static int regenerate_metadata(int argc, const char **argv);
+static int regenerate_statedump(int argc, const char **argv);
 
 enum {
        OPT_HELP = 1,
@@ -52,6 +53,7 @@ static struct poptOption long_options[] = {
 
 static struct cmd_struct actions[] = {
        { "metadata", regenerate_metadata },
+       { "statedump", regenerate_statedump },
        { NULL, NULL }  /* Array closure */
 };
 
@@ -88,6 +90,23 @@ end:
        return ret;
 }
 
+static int regenerate_statedump(int argc, const char **argv)
+{
+       int ret;
+
+       if (argc > 1) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+       ret = lttng_regenerate_statedump(session_name);
+       if (ret == 0) {
+               MSG("State dump successfully regenerated for session %s", session_name);
+       }
+
+end:
+       return ret;
+}
+
 static int handle_command(const char **argv)
 {
        struct cmd_struct *cmd;
index bc42577bda42d78b10f1f37189847d0cb392f993..d3d952a7de810d3ab0f52d19a8ee805ba2a9c236 100644 (file)
@@ -183,6 +183,8 @@ static const char *error_string_array[] = {
        [ ERROR_INDEX(LTTNG_ERR_LIVE_SESSION) ] = "Live sessions are not supported",
        [ ERROR_INDEX(LTTNG_ERR_PER_PID_SESSION) ] = "Per-PID tracing sessions are not supported",
        [ ERROR_INDEX(LTTNG_ERR_KERN_CONTEXT_UNAVAILABLE) ] = "Context unavailable on this kernel",
+       [ ERROR_INDEX(LTTNG_ERR_REGEN_STATEDUMP_FAIL) ] = "Failed to regenerate the state dump",
+       [ ERROR_INDEX(LTTNG_ERR_REGEN_STATEDUMP_NOMEM) ] = "Failed to regenerate the state dump, not enough memory",
 
        /* Last element */
        [ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code"
index e1de0e71561fd891b6f363b93ffb47cd55ee714f..1c2ab61886c824d62389efa39d777f162bb59c36 100644 (file)
@@ -230,6 +230,11 @@ int kernctl_session_regenerate_metadata(int fd)
        return LTTNG_IOCTL_CHECK(fd, LTTNG_KERNEL_SESSION_METADATA_REGEN);
 }
 
+int kernctl_session_regenerate_statedump(int fd)
+{
+       return LTTNG_IOCTL_CHECK(fd, LTTNG_KERNEL_SESSION_STATEDUMP);
+}
+
 int kernctl_create_stream(int fd)
 {
        return compat_ioctl_no_arg(fd, LTTNG_KERNEL_OLD_STREAM,
index f30e6f3b42415416e83c1d63d21c0bb79f37022f..7c25a17c35e69378074ad812c7413d926e8ae7ba 100644 (file)
@@ -66,6 +66,7 @@ int kernctl_untrack_pid(int fd, int pid);
 int kernctl_list_tracker_pids(int fd);
 
 int kernctl_session_regenerate_metadata(int fd);
+int kernctl_session_regenerate_statedump(int fd);
 
 /* Buffer operations */
 
index 29740c1d0061af15cac53b672df22375baaa3e90..628b1ea674d96a15964b932b58bafaa09fac3f9b 100644 (file)
@@ -95,6 +95,7 @@ enum lttcomm_sessiond_command {
        LTTNG_LIST_TRACKER_PIDS             = 34,
        LTTNG_SET_SESSION_SHM_PATH          = 40,
        LTTNG_REGENERATE_METADATA           = 41,
+       LTTNG_REGENERATE_STATEDUMP          = 42,
 };
 
 enum lttcomm_relayd_command {
index 8c78e1c199d4a8837b882e573262dad69748bdca..bcd59f0c637979cccb09ce923db97d9146e35508 100644 (file)
@@ -2418,6 +2418,36 @@ int lttng_metadata_regenerate(const char *session_name)
        return lttng_regenerate_metadata(session_name);
 }
 
+/*
+ * Regenerate the statedump of a session.
+ * Return 0 on success, a negative error code on error.
+ */
+int lttng_regenerate_statedump(const char *session_name)
+{
+       int ret;
+       struct lttcomm_session_msg lsm;
+
+       if (!session_name) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+       lsm.cmd_type = LTTNG_REGENERATE_STATEDUMP;
+
+       lttng_ctl_copy_string(lsm.session.name, session_name,
+                       sizeof(lsm.session.name));
+
+       ret = lttng_ctl_ask_sessiond(&lsm, NULL);
+       if (ret < 0) {
+               goto end;
+       }
+
+       ret = 0;
+end:
+       return ret;
+}
+
 /*
  * lib constructor.
  */
This page took 0.034197 seconds and 5 git commands to generate.