rotation-api: introduce rotation schedule descriptors
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.c
index 65a24e4dcdbd492e3abe14969a6f92be45e5486c..ba7dd3d4dd9452b92328547f7f09e24a7e389cf1 100644 (file)
@@ -4799,15 +4799,19 @@ end:
  * Command LTTNG_ROTATION_SET_SCHEDULE from the lttng-ctl library.
  *
  * Configure the automatic rotation parameters.
- * Set to -1ULL to disable them.
+ * 'activate' to true means activate the rotation schedule type with 'new_value'.
+ * 'activate' to false means deactivate the rotation schedule and validate that
+ * 'new_value' has the same value as the currently active value.
  *
- * Return 0 on success or else an LTTNG_ERR code.
+ * Return 0 on success or else a positive LTTNG_ERR code.
  */
 int cmd_rotation_set_schedule(struct ltt_session *session,
-               uint64_t timer_us, uint64_t size,
+               bool activate, enum lttng_rotation_schedule_type schedule_type,
+               uint64_t new_value,
                struct notification_thread_handle *notification_thread_handle)
 {
        int ret;
+       uint64_t *parameter_value;
 
        assert(session);
 
@@ -4815,71 +4819,116 @@ int cmd_rotation_set_schedule(struct ltt_session *session,
 
        if (session->live_timer || session->snapshot_mode ||
                        !session->output_traces) {
+               DBG("Failing ROTATION_SET_SCHEDULE command as the rotation feature is not available for this session");
                ret = LTTNG_ERR_ROTATION_NOT_AVAILABLE;
                goto end;
        }
 
-       /* Trying to override an already active timer. */
-       if (timer_us && timer_us != -1ULL && session->rotate_timer_period) {
-               ret = LTTNG_ERR_ROTATION_TIMER_SET;
+       switch (schedule_type) {
+       case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD:
+               parameter_value = &session->rotate_size;
+               break;
+       case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC:
+               parameter_value = &session->rotate_timer_period;
+               if (new_value >= UINT_MAX) {
+                       DBG("Failing ROTATION_SET_SCHEDULE command as the value requested for a periodic rotation schedule is invalid: %" PRIu64 " > %u (UINT_MAX)",
+                                       new_value, UINT_MAX);
+                       ret = LTTNG_ERR_INVALID;
+                       goto end;
+               }
+               break;
+       default:
+               WARN("Failing ROTATION_SET_SCHEDULE command on unknown schedule type");
+               ret = LTTNG_ERR_INVALID;
                goto end;
-       /* Trying to disable an inactive timer. */
-       } else if (timer_us == -1ULL && !session->rotate_timer_period) {
-               ret = LTTNG_ERR_ROTATION_NO_TIMER_SET;
+       }
+
+       /* Improper use of the API. */
+       if (new_value == -1ULL) {
+               WARN("Failing ROTATION_SET_SCHEDULE command as the value requested is -1");
+               ret = LTTNG_ERR_INVALID;
                goto end;
        }
 
-       if (size && size != -1ULL && session->rotate_size) {
-               ret = LTTNG_ERR_ROTATION_SIZE_SET;
+       /*
+        * As indicated in struct ltt_session's comments, a value of == 0 means
+        * this schedule rotation type is not in use.
+        *
+        * Reject the command if we were asked to activate a schedule that was
+        * already active.
+        */
+       if (activate && *parameter_value != 0) {
+               DBG("Failing ROTATION_SET_SCHEDULE (activate) command as the schedule is already active");
+               ret = LTTNG_ERR_ROTATION_SCHEDULE_SET;
                goto end;
-       } else if (size == -1ULL && !session->rotate_size) {
-               ret = LTTNG_ERR_ROTATION_NO_SIZE_SET;
+       }
+
+       /*
+        * Reject the command if we were asked to deactivate a schedule that was
+        * not active.
+        */
+       if (!activate && *parameter_value == 0) {
+               DBG("Failing ROTATION_SET_SCHEDULE (deactivate) command as the schedule is already inactive");
+               ret = LTTNG_ERR_ROTATION_SCHEDULE_NOT_SET;
                goto end;
        }
 
-       if (timer_us && !session->rotate_timer_period) {
-               if (timer_us > UINT_MAX) {
-                       ret = LTTNG_ERR_INVALID;
-                       goto end;
-               }
+       /*
+        * Reject the command if we were asked to deactivate a schedule that
+        * doesn't exist.
+        */
+       if (!activate && *parameter_value != new_value) {
+               DBG("Failing ROTATION_SET_SCHEDULE (deactivate) command as an inexistant schedule was provided");
+               ret = LTTNG_ERR_ROTATION_SCHEDULE_NOT_SET;
+               goto end;
+       }
 
-               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);
+       *parameter_value = activate ? new_value : 0;
+
+       switch (schedule_type) {
+       case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC:
+               if (activate && session->active) {
+                       /*
+                        * Only start the timer if the session is active,
+                        * otherwise it will be started when the session starts.
+                        */
+                       ret = sessiond_rotate_timer_start(session, new_value);
                        if (ret) {
-                               ERR("Failed to enable rotate timer");
+                               ERR("Failed to enable session rotation timer in ROTATION_SET_SCHEDULE command");
                                ret = LTTNG_ERR_UNK;
                                goto end;
                        }
+               } else {
+                       ret = sessiond_rotate_timer_stop(session);
+                       if (ret) {
+                               ERR("Failed to disable session rotation timer in ROTATION_SET_SCHEDULE command");
+                               ret = LTTNG_ERR_UNK;
+                       }
                }
-       } else if (timer_us == -1ULL && session->rotate_timer_period > 0) {
-               sessiond_rotate_timer_stop(session);
-               session->rotate_timer_period = 0;
-       }
-
-       if (size > 0) {
-               if (size == -1ULL) {
-                       ret = unsubscribe_session_consumed_size_rotation(session,
-                                       notification_thread_handle);
+               break;
+       case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD:
+               if (activate) {
+                       ret = subscribe_session_consumed_size_rotation(session,
+                                       new_value, notification_thread_handle);
                        if (ret) {
+                               ERR("Failed to enable consumed-size notification in ROTATION_SET_SCHEDULE command");
                                ret = LTTNG_ERR_UNK;
                                goto end;
                        }
-                       session->rotate_size = 0;
                } else {
-                       ret = subscribe_session_consumed_size_rotation(session,
-                                       size, notification_thread_handle);
+                       ret = unsubscribe_session_consumed_size_rotation(session,
+                                       notification_thread_handle);
                        if (ret) {
-                               PERROR("Subscribe to session usage");
+                               ERR("Failed to disable consumed-size notification in ROTATION_SET_SCHEDULE command");
                                ret = LTTNG_ERR_UNK;
                                goto end;
                        }
-                       session->rotate_size = size;
+
                }
+               break;
+       default:
+               /* Would have been caught before. */
+               abort();
        }
 
        ret = LTTNG_OK;
This page took 0.026109 seconds and 5 git commands to generate.