rotate timer working
authorJulien Desfossez <jdesfossez@efficios.com>
Thu, 21 Sep 2017 21:03:20 +0000 (17:03 -0400)
committerJulien Desfossez <jdesfossez@efficios.com>
Thu, 21 Sep 2017 21:07:14 +0000 (17:07 -0400)
Signed-off-by: Julien Desfossez <jdesfossez@efficios.com>
13 files changed:
include/lttng/lttng-error.h
include/lttng/rotate-internal.h
include/lttng/rotate.h
src/bin/lttng-relayd/main.c
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/cmd.h
src/bin/lttng-sessiond/main.c
src/bin/lttng-sessiond/rotation-thread.c
src/bin/lttng-sessiond/session.h
src/bin/lttng/commands/rotate.c
src/common/error.c
src/common/sessiond-comm/sessiond-comm.h
src/lib/lttng-ctl/rotate.c

index d3bf7214efd30e67a4280e90ca725999e874f5ea..4c71ddccc36ce499045f3dbfaad58e0aabd00e03 100644 (file)
@@ -151,7 +151,9 @@ enum lttng_error_code {
        LTTNG_ERR_COMMAND_CANCELLED      = 128, /* Command cancelled. */
        LTTNG_ERR_ROTATE_PENDING         = 129, /* Rotate already pending for this session. */
        LTTNG_ERR_ROTATE_NOT_AVAILABLE   = 130, /* Rotate feature not available for this type of session (e.g: live) */
-       LTTNG_ERR_ROTATE_NO_DATA        = 131, /* No data to rotate. */
+       LTTNG_ERR_ROTATE_NO_DATA         = 131, /* No data to rotate. */
+       LTTNG_ERR_ROTATE_TIMER_EXISTS    = 132, /* Rotate timer already setup for this session. */
+       LTTNG_ERR_ROTATE_SIZE_EXISTS     = 133, /* Rotate size already setup for this session. */
 
        /* MUST be last element */
        LTTNG_ERR_NR,                           /* Last element */
index 951f09adf997177f04882e89e0cc2c14a2533388..5227c47a5c5455191aeb9b981aa4acde3f8aa232 100644 (file)
  * This is opaque to the public library.
  */
 struct lttng_rotate_session_attr {
-       /*
-        * Session name to rotate.
-        */
+       /* Session name to rotate. */
        char session_name[LTTNG_NAME_MAX];
+       /* For the rotate pending request. */
+       uint64_t rotate_id;
+       /* > 0 if a timer is set. */
+       uint64_t timer_us;
        /*
-        * For the rotate pending request.
+        * > 0 if the session should rotate when it has written that many
+        * bytes.
         */
-       uint64_t rotate_id;
+       uint64_t size;
 } LTTNG_PACKED;
 
 /*
index c340fb1c7c42d19f0729e32e443582a8cb83a699..b4bac221f36664fe138a475de2c249d2c2ac9408 100644 (file)
@@ -18,6 +18,8 @@
 #ifndef LTTNG_ROTATE_H
 #define LTTNG_ROTATE_H
 
+#include <stdint.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -82,6 +84,18 @@ void lttng_rotate_session_attr_destroy(struct lttng_rotate_session_attr *attr);
 int lttng_rotate_session_attr_set_session_name(
        struct lttng_rotate_session_attr *attr, const char *session_name);
 
+/*
+ * Set the timer to periodically rotate the session.
+ */
+void lttng_rotate_session_attr_set_timer(
+               struct lttng_rotate_session_attr *attr, uint64_t timer);
+
+/*
+ * Set the size to rotate the session.
+ */
+void lttng_rotate_session_attr_set_size(
+               struct lttng_rotate_session_attr *attr, uint64_t size);
+
 /*
  * lttng rotate session handle functions.
  */
@@ -131,6 +145,11 @@ extern int lttng_rotate_session(struct lttng_rotate_session_attr *attr,
 extern int lttng_rotate_session_pending(
                struct lttng_rotate_session_handle *rotate_handle);
 
+/*
+ * Configure a session to rotate periodically or based on the size written.
+ */
+extern int lttng_rotate_setup(struct lttng_rotate_session_attr *attr);
+
 #ifdef __cplusplus
 }
 #endif
index d38cdfecb9c6cd6069d848c5e4cfb5566dc9a04e..a296c11e696bf99bb67f518e8ddde66c646a23f4 100644 (file)
@@ -2431,6 +2431,7 @@ static int relay_rotate_rename(struct lttcomm_relayd_hdr *recv_hdr,
                PERROR("Rename completed rotation chunk");
                goto end;
        }
+       ret = 0;
 
 end:
        memset(&reply, 0, sizeof(reply));
index c250c654a35df34f9139a74a319fc95b86b2a429..f2b7163d4a4426fbdd13372089f55f792fde3e66 100644 (file)
@@ -2434,6 +2434,16 @@ int cmd_start_trace(struct ltt_session *session)
                }
        }
 
+       if (session->rotate_timer_period) {
+               ret = sessiond_rotate_timer_start(session,
+                               session->rotate_timer_period);
+               if (ret < 0) {
+                       ERR("Failed to enable rotate timer");
+                       ret = LTTNG_ERR_UNK;
+                       goto error;
+               }
+       }
+
        /* Flag this after a successful start. */
        session->has_been_started = 1;
        session->active = 1;
@@ -2771,6 +2781,10 @@ int cmd_destroy_session(struct ltt_session *session, int wpipe)
                sessiond_timer_rotate_pending_stop(session);
        }
 
+       if (session->rotate_timer_enabled) {
+               sessiond_rotate_timer_stop(session);
+       }
+
        /* Clean kernel session teardown */
        kernel_destroy_session(ksess);
 
@@ -4337,6 +4351,59 @@ end:
        return ret;
 }
 
+/*
+ * Command LTTNG_ROTATE_SETUP from the lttng-ctl library.
+ *
+ * Configure the automatic rotation parameters.
+ *
+ * Return 0 on success or else a LTTNG_ERR code.
+ */
+int cmd_rotate_setup(struct ltt_session *session,
+               uint64_t timer_us, uint64_t size)
+{
+       int ret;
+
+       assert(session);
+
+       DBG("Cmd rotate setup session %s", session->name);
+
+       if (timer_us && session->rotate_timer_period) {
+               ret = LTTNG_ERR_ROTATE_TIMER_EXISTS;
+               goto end;
+       }
+
+       if (size && session->rotate_size) {
+               ret = LTTNG_ERR_ROTATE_SIZE_EXISTS;
+               goto end;
+       }
+
+       if (timer_us && !session->rotate_timer_period) {
+               session->rotate_timer_period = timer_us;
+               /*
+                * Only start the timer if the session is active, otherwise
+                * it will be started when the session starts.
+                */
+               if (session->active) {
+                       ret = sessiond_rotate_timer_start(session, timer_us);
+                       if (ret) {
+                               ERR("Failed to enable rotate timer");
+                               ret = LTTNG_ERR_UNK;
+                               goto end;
+                       }
+               }
+       } else if (timer_us == -1ULL && session->rotate_timer_period > 0) {
+               sessiond_rotate_timer_stop(session);
+       }
+       session->rotate_size = size;
+
+       ret = LTTNG_OK;
+
+       goto end;
+
+end:
+       return ret;
+}
+
 /*
  * Init command subsystem.
  */
index 5cd148949dae0373f2371f60e09d79d53d93acb4..2a66e86fc576aeb13fb665e49865d26799e940cd 100644 (file)
@@ -123,5 +123,7 @@ int cmd_rotate_session(struct ltt_session *session,
 int cmd_rotate_pending(struct ltt_session *session,
                struct lttng_rotate_pending_return **pending_return,
                uint64_t rotate_id);
+int cmd_rotate_setup(struct ltt_session *session, uint64_t timer_us,
+               uint64_t size);
 
 #endif /* CMD_H */
index 0282fac6f843585c474f613aaafb2a045f9fce6d..5f139897309fd29012a3a45823e498fa5ed89a72 100644 (file)
@@ -3130,6 +3130,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int sock,
        case LTTNG_UNREGISTER_TRIGGER:
        case LTTNG_ROTATE_SESSION:
        case LTTNG_ROTATE_PENDING:
+       case LTTNG_ROTATE_SETUP:
                need_domain = 0;
                break;
        default:
@@ -4306,6 +4307,13 @@ error_add_context:
                ret = LTTNG_OK;
                break;
        }
+       case LTTNG_ROTATE_SETUP:
+       {
+               ret = cmd_rotate_setup(cmd_ctx->session,
+                               cmd_ctx->lsm->u.rotate_setup.timer_us,
+                               cmd_ctx->lsm->u.rotate_setup.size);
+               break;
+       }
        default:
                ret = LTTNG_ERR_UND;
                break;
index aeb201d0dc1738adc28c161af71abab2797469f6..d219ca918b48c902c3cb0827fce2fe297aa0f13e 100644 (file)
@@ -401,9 +401,30 @@ int rotate_timer(struct ltt_session *session)
        int ret;
 
        DBG("[rotation-thread] Rotate timer on session %" PRIu64, session->id);
+
+       /*
+        * If the session is stopped, we need to cancel this timer.
+        */
+       pthread_mutex_lock(&session->lock);
+       if (!session->active && session->rotate_timer_enabled) {
+               sessiond_rotate_timer_stop(session);
+       }
+       pthread_mutex_unlock(&session->lock);
+
        ret = cmd_rotate_session(session, NULL);
        fprintf(stderr, "RET ROTATE TIMER: %d\n", ret);
+       if (ret == -LTTNG_ERR_ROTATE_PENDING) {
+               ret = 0;
+               goto end;
+       } else if (ret != LTTNG_OK) {
+               ret = -1;
+               goto end;
+       }
+
 
+       ret = 0;
+
+end:
        return ret;
 }
 
index ece2fc90de4cf6846b99b70e33acfc2d8fa83e1e..640cc57ec7555798b2a2ebb5433c8ea92fe5d90e 100644 (file)
@@ -171,6 +171,8 @@ struct ltt_session {
        /* Timer to periodically rotate a session. */
        bool rotate_timer_enabled;
        timer_t rotate_timer;
+       uint64_t rotate_timer_period;
+       uint64_t rotate_size;
 };
 
 /* Prototypes */
index c2e5580fc56dc68cbbe6a9d4e592aee6e0b38f5b..9248e52a4e61124fb2ce960a2c16b0bf993bd811 100644 (file)
@@ -23,6 +23,8 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <inttypes.h>
+#include <ctype.h>
 
 #include <common/sessiond-comm/sessiond-comm.h>
 #include <common/mi-lttng.h>
@@ -37,6 +39,8 @@ static struct mi_writer *writer;
 enum {
        OPT_HELP = 1,
        OPT_LIST_OPTIONS,
+       OPT_TIMER,
+       OPT_SIZE,
 };
 
 static struct poptOption long_options[] = {
@@ -44,6 +48,9 @@ static struct poptOption long_options[] = {
        {"help",      'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
        {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
        {"no-wait",   'n', POPT_ARG_VAL, &opt_no_wait, 1, 0, 0},
+       {"session",        's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
+       {"timer",   0,   POPT_ARG_INT, 0, OPT_TIMER, 0, 0},
+       {"size",   0,   POPT_ARG_INT, 0, OPT_SIZE, 0, 0},
        {0, 0, 0, 0, 0, 0, 0}
 };
 
@@ -77,10 +84,47 @@ end:
        return ret;
 }
 
-static int rotate_tracing(void)
+static int setup_rotate(char *session_name, uint64_t timer, uint64_t size)
+{
+       int ret = 0;
+       struct lttng_rotate_session_attr *attr = NULL;
+
+       attr = lttng_rotate_session_attr_create();
+       if (!attr) {
+               goto error;
+       }
+
+       ret = lttng_rotate_session_attr_set_session_name(attr, session_name);
+       if (ret < 0) {
+               goto error;
+       }
+
+       lttng_rotate_session_attr_set_timer(attr, timer);
+       lttng_rotate_session_attr_set_size(attr, size);
+
+       if (timer) {
+               DBG("Configuring session %s to rotate every %" PRIu64 " us",
+                               session_name, timer);
+       }
+       if (size) {
+               DBG("Configuring session %s to rotate every %" PRIu64 " bytes written",
+                               session_name, size);
+       }
+
+       ret = lttng_rotate_setup(attr);
+
+       goto end;
+
+error:
+       ret = -1;
+end:
+       return ret;
+}
+
+static int rotate_tracing(char *session_name)
 {
        int ret;
-       char *session_name = NULL, *path = NULL;
+       char *path = NULL;
        struct lttng_rotate_session_attr *attr = NULL;
        struct lttng_rotate_session_handle *handle = NULL;
        enum lttng_rotate_status rotate_status;
@@ -90,15 +134,6 @@ static int rotate_tracing(void)
                goto error;
        }
 
-       if (opt_session_name == NULL) {
-               session_name = get_session_name();
-               if (session_name == NULL) {
-                       goto error;
-               }
-       } else {
-               session_name = opt_session_name;
-       }
-
        ret = lttng_rotate_session_attr_set_session_name(attr, session_name);
        if (ret < 0) {
                goto error;
@@ -194,9 +229,6 @@ static int rotate_tracing(void)
 error:
        ret = CMD_ERROR;
 end:
-       if (opt_session_name == NULL) {
-               free(session_name);
-       }
        lttng_rotate_session_handle_destroy(handle);
        lttng_rotate_session_attr_destroy(attr);
        return ret;
@@ -211,6 +243,9 @@ int cmd_rotate(int argc, const char **argv)
 {
        int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
        static poptContext pc;
+       char *session_name = NULL;
+       char *opt_arg = NULL;
+       uint64_t timer = 0, size = 0;
 
        pc = poptGetContext(NULL, argc, argv, long_options, 0);
        poptReadDefaultConfig(pc, 0);
@@ -223,13 +258,46 @@ int cmd_rotate(int argc, const char **argv)
                case OPT_LIST_OPTIONS:
                        list_cmd_options(stdout, long_options);
                        goto end;
+               case OPT_TIMER:
+               {
+                       errno = 0;
+                       opt_arg = poptGetOptArg(pc);
+                       timer = strtoull(opt_arg, NULL, 0);
+                       if (errno != 0 || !isdigit(opt_arg[0])) {
+                               ERR("Wrong value in --timer parameter: %s", opt_arg);
+                               ret = CMD_ERROR;
+                               goto end;
+                       }
+                       DBG("Rotation timer set to %" PRIu64, timer);
+                       break;
+               }
+               case OPT_SIZE:
+               {
+                       errno = 0;
+                       opt_arg = poptGetOptArg(pc);
+                       size = strtoull(opt_arg, NULL, 0);
+                       if (errno != 0 || !isdigit(opt_arg[0])) {
+                               ERR("Wrong value in --timer parameter: %s", opt_arg);
+                               ret = CMD_ERROR;
+                               goto end;
+                       }
+                       DBG("Rotation size set to %" PRIu64, size);
+                       break;
+               }
                default:
                        ret = CMD_UNDEFINED;
                        goto end;
                }
        }
 
-       opt_session_name = (char*) poptGetArg(pc);
+       if (opt_session_name == NULL) {
+               session_name = get_session_name();
+               if (session_name == NULL) {
+                       goto end;
+               }
+       } else {
+               session_name = opt_session_name;
+       }
 
        /* Mi check */
        if (lttng_opt_mi) {
@@ -267,8 +335,15 @@ int cmd_rotate(int argc, const char **argv)
                }
        }
 
-       command_ret = rotate_tracing();
+       fprintf(stderr, "T: %lu, S: %lu\n", timer, size);
+       /* No config options, just rotate the session now */
+       if (timer == 0 && size == 0) {
+               command_ret = rotate_tracing(session_name);
+       } else {
+               command_ret = setup_rotate(session_name, timer, size);
+       }
        if (command_ret) {
+               ERR("%s", lttng_strerror(command_ret));
                success = 0;
        }
 
@@ -307,5 +382,6 @@ end:
        /* Overwrite ret if an error occurred with start_tracing */
        ret = command_ret ? command_ret : ret;
        poptFreeContext(pc);
+       free(session_name);
        return ret;
 }
index 32631239a1fccd181a6dd999056d2a2184476d2e..e55083efeee609368aa22197f97f91ff773a12fa 100644 (file)
@@ -193,6 +193,8 @@ static const char *error_string_array[] = {
        [ ERROR_INDEX(LTTNG_ERR_ROTATE_PENDING) ] = "Rotate already pending for this session.",
        [ ERROR_INDEX(LTTNG_ERR_ROTATE_NOT_AVAILABLE) ] = "Rotate feature not available for this type of session",
        [ ERROR_INDEX(LTTNG_ERR_ROTATE_NO_DATA) ] = "No trace data to rotate",
+       [ ERROR_INDEX(LTTNG_ERR_ROTATE_TIMER_EXISTS) ] = "Rotate timer already setup for this session",
+       [ ERROR_INDEX(LTTNG_ERR_ROTATE_SIZE_EXISTS) ] = "Rotate size already setup for this session",
 
        /* Last element */
        [ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code"
index 404318bdaf55a348f6d6902de24aa24e4e827d31..c526c45bb49572f1b87b9ba176e0347d84f6d762 100644 (file)
@@ -103,6 +103,7 @@ enum lttcomm_sessiond_command {
        LTTNG_UNREGISTER_TRIGGER            = 44,
        LTTNG_ROTATE_SESSION                = 45,
        LTTNG_ROTATE_PENDING                = 46,
+       LTTNG_ROTATE_SETUP                  = 47,
 };
 
 enum lttcomm_relayd_command {
@@ -333,6 +334,10 @@ struct lttcomm_session_msg {
                struct {
                        uint64_t rotate_id;
                } LTTNG_PACKED rotate_pending;
+               struct {
+                       uint64_t timer_us;
+                       uint64_t size;
+               } LTTNG_PACKED rotate_setup;
        } u;
 } LTTNG_PACKED;
 
index 49d3a26b6d7571310237c5eadc5cf32ccf9283fa..7682fe4581078897ea516836c978c4f8cb8f1b9e 100644 (file)
@@ -63,6 +63,20 @@ error:
        return ret;
 }
 
+void lttng_rotate_session_attr_set_timer(
+               struct lttng_rotate_session_attr *attr,
+               uint64_t timer)
+{
+       attr->timer_us = timer;
+}
+
+void lttng_rotate_session_attr_set_size(
+               struct lttng_rotate_session_attr *attr,
+               uint64_t size)
+{
+       attr->size = size;
+}
+
 enum lttng_rotate_status lttng_rotate_session_get_status(
                struct lttng_rotate_session_handle *rotate_handle)
 {
@@ -211,3 +225,33 @@ end:
        free(pending_return);
        return ret;
 }
+
+/*
+ * Configure the automatic rotate parameters.
+ *
+ * Return 0 on success else a negative LTTng error code.
+ */
+int lttng_rotate_setup(struct lttng_rotate_session_attr *attr)
+{
+       struct lttcomm_session_msg lsm;
+       int ret;
+
+       if (!attr) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+       lsm.cmd_type = LTTNG_ROTATE_SETUP;
+       lttng_ctl_copy_string(lsm.session.name, attr->session_name,
+                       sizeof(lsm.session.name));
+       lsm.u.rotate_setup.timer_us = attr->timer_us;
+       lsm.u.rotate_setup.size = attr->size;
+
+       ret = lttng_ctl_ask_sessiond(&lsm, NULL);
+       fprintf(stderr, "SETUP RET: %d\n", ret);
+
+end:
+       return ret;
+}
+
This page took 0.037699 seconds and 5 git commands to generate.