systemctl: print next timer trigger time with the status verb (#6242)
authorGiedrius Statkevičius <giedriuswork@gmail.com>
Tue, 4 Jul 2017 21:51:02 +0000 (00:51 +0300)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 4 Jul 2017 21:51:02 +0000 (17:51 -0400)
It is useful to know when a timer will trigger next when looking at a
timer status message so calculate and print that information.

Closes #5738.

Example output:
$ systemctl status dnf-makecache.timer
● dnf-makecache.timer - dnf makecache timer
   Loaded: loaded (/usr/lib/systemd/system/dnf-makecache.timer; enabled; vendor preset: enabled)
   Active: active (waiting) since Tue 2017-07-04 17:24:02 EDT; 24min ago
  Trigger: Tue 2017-07-04 18:15:56 EDT; 27min left

src/systemctl/systemctl.c

index 4c5b14b..f5402f0 100644 (file)
@@ -3818,6 +3818,8 @@ typedef struct UnitStatusInfo {
         bool failed_assert_negate;
         const char *failed_assert;
         const char *failed_assert_parameter;
+        usec_t next_elapse_real;
+        usec_t next_elapse_monotonic;
 
         /* Socket */
         unsigned n_accepted;
@@ -3987,6 +3989,31 @@ static void print_status_info(
         else
                 printf("\n");
 
+        if (endswith(i->id, ".timer")) {
+                char tstamp1[FORMAT_TIMESTAMP_RELATIVE_MAX],
+                     tstamp2[FORMAT_TIMESTAMP_MAX];
+                char *next_rel_time, *next_time;
+                dual_timestamp nw, next = {i->next_elapse_real,
+                                           i->next_elapse_monotonic};
+                usec_t next_elapse;
+
+                printf("  Trigger: ");
+
+                dual_timestamp_get(&nw);
+                next_elapse = calc_next_elapse(&nw, &next);
+                next_rel_time = format_timestamp_relative(tstamp1,
+                                                          sizeof(tstamp1),
+                                                          next_elapse);
+                next_time = format_timestamp(tstamp2,
+                                             sizeof(tstamp2),
+                                             next_elapse);
+
+                if (next_time && next_rel_time)
+                        printf("%s; %s\n", next_time, next_rel_time);
+                else
+                        printf("n/a\n");
+        }
+
         if (!i->condition_result && i->condition_timestamp > 0) {
                 UnitCondition *c;
                 int n = 0;
@@ -4424,6 +4451,10 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *
                         i->tasks_max = u;
                 else if (streq(name, "CPUUsageNSec"))
                         i->cpu_usage_nsec = u;
+                else if (streq(name, "NextElapseUSecMonotonic"))
+                        i->next_elapse_monotonic = u;
+                else if (streq(name, "NextElapseUSecRealtime"))
+                        i->next_elapse_real = u;
 
                 break;
         }