summaryrefslogtreecommitdiffstats
path: root/src/systemctl/systemctl-start-unit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemctl/systemctl-start-unit.c')
-rw-r--r--src/systemctl/systemctl-start-unit.c65
1 files changed, 53 insertions, 12 deletions
diff --git a/src/systemctl/systemctl-start-unit.c b/src/systemctl/systemctl-start-unit.c
index d08e363c9f..c40e807212 100644
--- a/src/systemctl/systemctl-start-unit.c
+++ b/src/systemctl/systemctl-start-unit.c
@@ -176,6 +176,43 @@ fail:
return r;
}
+static int enqueue_marked_jobs(
+ sd_bus *bus,
+ BusWaitForJobs *w) {
+
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ int r;
+
+ log_debug("%s dbus call org.freedesktop.systemd1.Manager EnqueueMarkedJobs()",
+ arg_dry_run ? "Would execute" : "Executing");
+
+ if (arg_dry_run)
+ return 0;
+
+ r = bus_call_method(bus, bus_systemd_mgr, "EnqueueMarkedJobs", &error, &reply, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to start jobs: %s", bus_error_message(&error, r));
+
+ _cleanup_strv_free_ char **paths = NULL;
+ r = sd_bus_message_read_strv(reply, &paths);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ if (w) {
+ char **path;
+
+ STRV_FOREACH(path, paths) {
+ log_debug("Adding %s to the set", *path);
+ r = bus_wait_for_jobs_add(w, *path);
+ if (r < 0)
+ return log_error_errno(r, "Failed to watch job %s: %m", *path);
+ }
+ }
+
+ return 0;
+}
+
const struct action_metadata action_table[_ACTION_MAX] = {
[ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
[ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
@@ -265,7 +302,7 @@ int start_unit(int argc, char *argv[], void *userdata) {
job_type = "start";
mode = "isolate";
suffix = ".target";
- } else {
+ } else if (!arg_marked) {
/* A command in style of "systemctl start <unit1> <unit2> …", "sysemctl stop <unit1> <unit2> …" and so on */
method = verb_to_method(argv[0]);
job_type = verb_to_job_type(argv[0]);
@@ -289,7 +326,7 @@ int start_unit(int argc, char *argv[], void *userdata) {
names = strv_new(one_name);
if (!names)
return log_oom();
- } else {
+ } else if (!arg_marked) {
bool expanded;
r = expand_unit_names(bus, strv_skip(argv, 1), suffix, &names, &expanded);
@@ -322,19 +359,23 @@ int start_unit(int argc, char *argv[], void *userdata) {
return log_error_errno(r, "Failed to allocate unit watch context: %m");
}
- STRV_FOREACH(name, names) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ if (arg_marked)
+ ret = enqueue_marked_jobs(bus, w);
- r = start_unit_one(bus, method, job_type, *name, mode, &error, w, wu);
- if (ret == EXIT_SUCCESS && r < 0)
- ret = translate_bus_error_to_exit_status(r, &error);
+ else
+ STRV_FOREACH(name, names) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- if (r >= 0 && streq(method, "StopUnit")) {
- r = strv_push(&stopped_units, *name);
- if (r < 0)
- return log_oom();
+ r = start_unit_one(bus, method, job_type, *name, mode, &error, w, wu);
+ if (ret == EXIT_SUCCESS && r < 0)
+ ret = translate_bus_error_to_exit_status(r, &error);
+
+ if (r >= 0 && streq(method, "StopUnit")) {
+ r = strv_push(&stopped_units, *name);
+ if (r < 0)
+ return log_oom();
+ }
}
- }
if (!arg_no_block) {
const char* extra_args[4];