]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
analyze: optionally, show more than one elapse time for calendar expressions
authorLennart Poettering <lennart@poettering.net>
Thu, 21 Feb 2019 11:07:05 +0000 (12:07 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 22 Feb 2019 08:10:54 +0000 (09:10 +0100)
man/systemd-analyze.xml
src/analyze/analyze.c

index 7becf0133e9eaa670fbfee292bd6af86b5c13bce..774449d5a000010ff6d3457d54e499b8679db4dc 100644 (file)
@@ -251,11 +251,14 @@ NAutoVTs=8
     All units files present in the directories containing the command line arguments will
     be used in preference to the other paths.</para>
 
-    <para><command>systemd-analyze calendar</command> will parse and normalize repetitive calendar time events, and
-    will calculate when they will elapse next. This takes the same input as the <varname>OnCalendar=</varname> setting
-    in <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>, following the
-    syntax described in
-    <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
+    <para><command>systemd-analyze calendar</command> will parse and normalize repetitive calendar time
+    events, and will calculate when they will elapse next. This takes the same input as the
+    <varname>OnCalendar=</varname> setting in
+    <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+    following the syntax described in
+    <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>. By
+    default, only the next time the calendar expression will elapse is shown; use
+    <option>--iterations=</option> to show the specified number of next times the expression elapses.</para>
 
     <para><command>systemd-analyze service-watchdogs</command>
     prints the current state of service runtime watchdogs of the <command>systemd</command> daemon.
@@ -401,6 +404,13 @@ NAutoVTs=8
         the specified root path <replaceable>PATH</replaceable>.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--iterations=<replaceable>NUMBER</replaceable></option></term>
+
+        <listitem><para>When used with the <command>calendar</command> command, show the specified number of
+        iterations the specified calendar expression will elapse next. Defaults to 1.</para></listitem>
+      </varlistentry>
+
       <xi:include href="user-system-options.xml" xpointer="host" />
       <xi:include href="user-system-options.xml" xpointer="machine" />
 
index 6fa6ef93cce4e44dc7b8844ae2a32b9a83f2cb68..064525d64d31c2e7ecb2a064451eeceeb039c1db 100644 (file)
@@ -78,6 +78,7 @@ static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
 static bool arg_man = true;
 static bool arg_generators = false;
 static const char *arg_root = NULL;
+static unsigned arg_iterations = 1;
 
 STATIC_DESTRUCTOR_REGISTER(arg_dot_from_patterns, strv_freep);
 STATIC_DESTRUCTOR_REGISTER(arg_dot_to_patterns, strv_freep);
@@ -1680,7 +1681,7 @@ static int test_calendar(int argc, char *argv[], void *userdata) {
         STRV_FOREACH(p, strv_skip(argv, 1)) {
                 _cleanup_(calendar_spec_freep) CalendarSpec *spec = NULL;
                 _cleanup_free_ char *t = NULL;
-                usec_t next;
+                unsigned i;
 
                 r = calendar_spec_from_string(*p, &spec);
                 if (r < 0) {
@@ -1705,21 +1706,42 @@ static int test_calendar(int argc, char *argv[], void *userdata) {
 
                 printf("Normalized form: %s\n", t);
 
-                r = calendar_spec_next_usec(spec, n, &next);
-                if (r == -ENOENT)
-                        printf("    Next elapse: never\n");
-                else if (r < 0) {
-                        ret = log_error_errno(r, "Failed to determine next elapse for '%s': %m", *p);
-                        continue;
-                } else {
+                for (i = 0; i < arg_iterations; i++) {
                         char buffer[CONST_MAX(FORMAT_TIMESTAMP_MAX, FORMAT_TIMESTAMP_RELATIVE_MAX)];
+                        usec_t next;
+
+                        r = calendar_spec_next_usec(spec, n, &next);
+                        if (r == -ENOENT) {
+                                if (i > 0)
+                                        break;
+
+                                printf("    Next elapse: never\n");
+                                return ret;
+                        }
+                        if (r < 0) {
+                                ret = log_error_errno(r, "Failed to determine next elapse for '%s': %m", *p);
+                                break;
+                        }
+
+                        if (i == 0)
+                                printf("    Next elapse: %s\n", format_timestamp(buffer, sizeof(buffer), next));
+                        else {
+                                int k = DECIMAL_STR_WIDTH(i+1);
 
-                        printf("    Next elapse: %s\n", format_timestamp(buffer, sizeof(buffer), next));
+                                if (k < 8)
+                                        k = 8 - k;
+                                else
+                                        k = 0;
+
+                                printf("%*sIter. #%u: %s\n", k, "", i+1, format_timestamp(buffer, sizeof(buffer), next));
+                        }
 
                         if (!in_utc_timezone())
                                 printf("       (in UTC): %s\n", format_timestamp_utc(buffer, sizeof(buffer), next));
 
                         printf("       From now: %s\n", format_timestamp_relative(buffer, sizeof(buffer), next));
+
+                        n = next;
                 }
 
                 if (*(p+1))
@@ -1827,6 +1849,7 @@ static int help(int argc, char *argv[], void *userdata) {
                "                           earlier than the latest in the branch\n"
                "     --man[=BOOL]          Do [not] check for existence of man pages\n"
                "     --generators[=BOOL]   Do [not] run unit generators (requires privileges)\n"
+               "     --iterations=N        Show the specified number of iterations\n"
                "\nCommands:\n"
                "  time                     Print time spent in the kernel\n"
                "  blame                    Print list of running units ordered by time to init\n"
@@ -1870,6 +1893,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_NO_PAGER,
                 ARG_MAN,
                 ARG_GENERATORS,
+                ARG_ITERATIONS,
         };
 
         static const struct option options[] = {
@@ -1889,6 +1913,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "generators",   optional_argument, NULL, ARG_GENERATORS       },
                 { "host",         required_argument, NULL, 'H'                  },
                 { "machine",      required_argument, NULL, 'M'                  },
+                { "iterations",   required_argument, NULL, ARG_ITERATIONS       },
                 {}
         };
 
@@ -1988,6 +2013,13 @@ static int parse_argv(int argc, char *argv[]) {
 
                         break;
 
+                case ARG_ITERATIONS:
+                        r = safe_atou(optarg, &arg_iterations);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse iterations: %s", optarg);
+
+                        break;
+
                 case '?':
                         return -EINVAL;