diff options
Diffstat (limited to 'src/systemctl/systemctl.c')
-rw-r--r-- | src/systemctl/systemctl.c | 99 |
1 files changed, 74 insertions, 25 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index af5b18c0ed..4fd8d7ba27 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); @@ -204,6 +206,9 @@ static int acquire_bus(BusFocus focus, sd_bus **ret) { if (arg_transport != BUS_TRANSPORT_LOCAL) focus = BUS_FULL; + if (getenv_bool("SYSTEMCTL_FORCE_BUS") > 0) + focus = BUS_FULL; + if (!busses[focus]) { bool user; @@ -2192,12 +2197,49 @@ finish: return r; } +static int 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) + return log_debug_errno(r, "Failed to get waiting jobs for job %" PRIu32, id); + + r = sd_bus_message_enter_container(reply, 'a', "(usssoo)"); + if (r < 0) + return bus_log_parse_error(r); + + 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) + return bus_log_parse_error(r); + + r = sd_bus_message_exit_container(reply); + if (r < 0) + return bus_log_parse_error(r); + + return 0; +} + 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; @@ -2259,6 +2301,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", "\twaiting for job"); + if (arg_jobs_before) + output_waiting_jobs(bus, j->id, "GetJobBefore", "\tblocking job"); } if (!arg_no_legend) { @@ -2327,7 +2374,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; } @@ -2432,17 +2479,24 @@ static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **un assert(unit_path); STRV_FOREACH(p, lp->search_path) { - _cleanup_free_ char *path; + _cleanup_free_ char *path = NULL, *lpath = NULL; + int r; path = path_join(arg_root, *p, unit_name); if (!path) return log_oom(); - if (access(path, F_OK) == 0) { - *unit_path = path; - path = NULL; - return 1; - } + r = chase_symlinks(path, arg_root, &lpath); + if (r == -ENOENT) + continue; + if (r == -ENOMEM) + return log_oom(); + if (r < 0) + return log_error_errno(r, "Failed to access path '%s': %m", path); + + *unit_path = lpath; + lpath = NULL; + return 1; } return 0; @@ -2509,10 +2563,6 @@ static int unit_find_paths( if (!names) return log_oom(); - r = set_put(names, unit_name); - if (r < 0) - return log_error_errno(r, "Failed to add unit name: %m"); - r = unit_file_find_path(lp, unit_name, &path); if (r < 0) return r; @@ -2530,6 +2580,10 @@ static int unit_find_paths( } } + r = set_put(names, basename(path)); + if (r < 0) + return log_error_errno(r, "Failed to add unit name: %m"); + if (dropin_paths) { r = unit_file_find_dropin_paths(lp->search_path, NULL, names, &dropins); if (r < 0) @@ -6735,9 +6789,9 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) { if (path) { if (arg_full) - r = unit_file_create_copy(&lp, *name, path, &new_path, &tmp_path); + r = unit_file_create_copy(&lp, basename(path), path, &new_path, &tmp_path); else - r = unit_file_create_new(&lp, *name, ".d/override.conf", &new_path, &tmp_path); + r = unit_file_create_new(&lp, basename(path), ".d/override.conf", &new_path, &tmp_path); } else r = unit_file_create_new(&lp, *name, NULL, &new_path, &tmp_path); if (r < 0) @@ -7214,14 +7268,12 @@ static int systemctl_parse_argv(int argc, char *argv[]) { return -EINVAL; } - p = optarg; - for (;;) { + for (p = optarg;;) { _cleanup_free_ char *type = NULL; r = extract_first_word(&p, &type, ",", 0); if (r < 0) return log_error_errno(r, "Failed to parse type: %s", optarg); - if (r == 0) break; @@ -7263,15 +7315,13 @@ static int systemctl_parse_argv(int argc, char *argv[]) { arg_properties = new0(char*, 1); if (!arg_properties) return log_oom(); - } else { - p = optarg; - for (;;) { + } else + for (p = optarg;;) { _cleanup_free_ char *prop = NULL; r = extract_first_word(&p, &prop, ",", 0); if (r < 0) return log_error_errno(r, "Failed to parse property: %s", optarg); - if (r == 0) break; @@ -7280,7 +7330,6 @@ static int systemctl_parse_argv(int argc, char *argv[]) { prop = NULL; } - } /* If the user asked for a particular * property, show it to him, even if it is @@ -7300,10 +7349,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: @@ -7457,14 +7508,12 @@ static int systemctl_parse_argv(int argc, char *argv[]) { return -EINVAL; } - p = optarg; - for (;;) { + for (p = optarg;;) { _cleanup_free_ char *s = NULL; r = extract_first_word(&p, &s, ",", 0); if (r < 0) return log_error_errno(r, "Failed to parse signal: %s", optarg); - if (r == 0) break; |