diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-11-16 16:44:05 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-11-16 17:01:46 +0100 |
commit | 82948f6c8e2fe03aa3859757b92bcadfb66a6a9c (patch) | |
tree | 6efb8396c1ad202869441b41d074084800734ae9 | |
parent | 15ea79f85c3a9b174b6ba14cc9a0f5f482ca1553 (diff) |
systemctl: show waiting jobs when "systemctl list-jobs --after/--before" is called
Let's expose the new bus functions we added in the previous commit in
systemctl.
-rw-r--r-- | man/systemctl.xml | 12 | ||||
-rw-r--r-- | src/systemctl/systemctl.c | 56 |
2 files changed, 66 insertions, 2 deletions
diff --git a/man/systemctl.xml b/man/systemctl.xml index dfa00e0c03..08c3a268bd 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -209,6 +209,10 @@ <varname>RequiresMountsFor=</varname>). Both explicitly and implicitly introduced dependencies are shown with <command>list-dependencies</command>.</para> + + <para>When passed to the <command>list-jobs</command> command, for each printed job show which other jobs are + waiting for it. May be combined with <option>--before</option> to show both the jobs waiting for each job as + well as all jobs each job is waiting for.</para> </listitem> </varlistentry> @@ -220,6 +224,10 @@ units that are ordered after the specified unit. In other words, recursively list units following the <varname>Before=</varname> dependency.</para> + + <para>When passed to the <command>list-jobs</command> command, for each printed job show which other jobs it + is waiting for. May be combined with <option>--after</option> to show both the jobs waiting for each job as + well as all jobs each job is waiting for.</para> </listitem> </varlistentry> @@ -1388,6 +1396,10 @@ kobject-uevent 1 systemd-udevd-kernel.socket systemd-udevd.service <para>List jobs that are in progress. If one or more <replaceable>PATTERN</replaceable>s are specified, only jobs for units matching one of them are shown.</para> + + <para>When combined with <option>--after</option> or <option>--before</option> the list is augmented with + information on which other job each job is waiting for, and which other jobs are waiting for it, see + above.</para> </listitem> </varlistentry> <varlistentry> diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index de7e19725c..db836639b5 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -173,6 +173,8 @@ static OutputMode arg_output = OUTPUT_SHORT; static bool arg_plain = false; static bool arg_firmware_setup = false; static bool arg_now = false; +static bool arg_jobs_before = false; +static bool arg_jobs_after = false; static int daemon_reload(int argc, char *argv[], void* userdata); static int trivial_method(int argc, char *argv[], void *userdata); @@ -2195,12 +2197,55 @@ finish: return r; } +static void output_waiting_jobs(sd_bus *bus, uint32_t id, const char *method, const char *prefix) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + const char *name, *type, *state, *job_path, *unit_path; + uint32_t other_id; + int r; + + assert(bus); + + r = sd_bus_call_method( + bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + method, + &error, + &reply, + "u", id); + if (r < 0) { + log_debug_errno(r, "Failed to get waiting jobs for job %" PRIu32, id); + return; + } + + r = sd_bus_message_enter_container(reply, 'a', "(usssoo)"); + if (r < 0) { + bus_log_parse_error(r); + return; + } + + while ((r = sd_bus_message_read(reply, "(usssoo)", &other_id, &name, &type, &state, &job_path, &unit_path)) > 0) + printf("%s%u (%s/%s)\n", prefix, other_id, name, type); + if (r < 0) { + bus_log_parse_error(r); + return; + } + + r = sd_bus_message_exit_container(reply); + if (r < 0) { + bus_log_parse_error(r); + return; + } +} + struct job_info { uint32_t id; const char *name, *type, *state; }; -static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) { +static void output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n, bool skipped) { unsigned id_len, unit_len, type_len, state_len; const struct job_info *j; const char *on, *off; @@ -2262,6 +2307,11 @@ static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipp on, unit_len, e ? e : j->name, off, type_len, j->type, on, state_len, j->state, off); + + if (arg_jobs_after) + output_waiting_jobs(bus, j->id, "GetJobAfter", "\tA job waits for this job: "); + if (arg_jobs_before) + output_waiting_jobs(bus, j->id, "GetJobBefore", "\tThis job waits for a job: "); } if (!arg_no_legend) { @@ -2330,7 +2380,7 @@ static int list_jobs(int argc, char *argv[], void *userdata) { pager_open(arg_no_pager, false); - output_jobs_list(jobs, c, skipped); + output_jobs_list(bus, jobs, c, skipped); return 0; } @@ -7305,10 +7355,12 @@ static int systemctl_parse_argv(int argc, char *argv[]) { case ARG_AFTER: arg_dependency = DEPENDENCY_AFTER; + arg_jobs_after = true; break; case ARG_BEFORE: arg_dependency = DEPENDENCY_BEFORE; + arg_jobs_before = true; break; case ARG_SHOW_TYPES: |