#include "logs-show.h"
#include "socket-util.h"
#include "fileio.h"
+#include "copy.h"
#include "env-util.h"
#include "bus-util.h"
#include "bus-message.h"
static OutputMode arg_output = OUTPUT_SHORT;
static bool arg_plain = false;
-static const struct {
- const char *verb;
- const char *method;
-} unit_actions[] = {
- { "start", "StartUnit" },
- { "stop", "StopUnit" },
- { "condstop", "StopUnit" },
- { "reload", "ReloadUnit" },
- { "restart", "RestartUnit" },
- { "try-restart", "TryRestartUnit" },
- { "condrestart", "TryRestartUnit" },
- { "reload-or-restart", "ReloadOrRestartUnit" },
- { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
- { "condreload", "ReloadOrTryRestartUnit" },
- { "force-reload", "ReloadOrTryRestartUnit" }
-};
-
static bool original_stdout_is_tty;
static int daemon_reload(sd_bus *bus, char **args);
}
static bool output_show_unit(const UnitInfo *u, char **patterns) {
- const char *dot;
-
if (!strv_isempty(patterns)) {
char **pattern;
STRV_FOREACH(pattern, patterns)
if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
- return true;
+ goto next;
return false;
}
- return (!arg_types || ((dot = strrchr(u->id, '.')) &&
- strv_find(arg_types, dot+1))) &&
- (arg_all || !(streq(u->active_state, "inactive")
- || u->following[0]) || u->job_id > 0);
+next:
+ if (arg_types) {
+ const char *dot;
+
+ dot = strrchr(u->id, '.');
+ if (!dot)
+ return false;
+
+ if (!strv_find(arg_types, dot+1))
+ return false;
+ }
+
+ if (arg_all)
+ return true;
+
+ if (u->job_id > 0)
+ return true;
+
+ if (streq(u->active_state, "inactive") || u->following[0])
+ return false;
+
+ return true;
}
static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
r = sd_bus_open_system_container(&container, *i);
if (r < 0) {
- log_error("Failed to connect to container %s: %s", *i, strerror(-r));
+ log_error_errno(r, "Failed to connect to container %s: %m", *i);
continue;
}
}
static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
- const char *dot;
-
if (!strv_isempty(patterns)) {
char **pattern;
STRV_FOREACH(pattern, patterns)
if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
- return true;
+ goto next;
return false;
}
- return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
+next:
+ if (!strv_isempty(arg_types)) {
+ const char *dot;
+
+ dot = strrchr(u->path, '.');
+ if (!dot)
+ return false;
+
+ if (!strv_find(arg_types, dot+1))
+ return false;
+ }
+
+ if (!strv_isempty(arg_states)) {
+ if (!strv_find(arg_states, unit_file_state_to_string(u->state)))
+ return false;
+ }
+
+ return true;
}
static void output_unit_file_list(const UnitFileList *units, unsigned c) {
r = unit_file_get_list(arg_scope, arg_root, h);
if (r < 0) {
unit_file_list_free(h);
- log_error("Failed to get unit file list: %s", strerror(-r));
+ log_error_errno(r, "Failed to get unit file list: %m");
return r;
}
"RequiresOverridable\0"
"Requisite\0"
"RequisiteOverridable\0"
- "Wants\0",
+ "Wants\0"
+ "BindsTo\0",
[DEPENDENCY_REVERSE] = "RequiredBy\0"
"RequiredByOverridable\0"
"WantedBy\0"
- "PartOf\0",
+ "PartOf\0"
+ "BoundBy\0",
[DEPENDENCY_AFTER] = "After\0",
[DEPENDENCY_BEFORE] = "Before\0",
};
if (!bus || avoid_bus()) {
r = unit_file_get_default(arg_scope, arg_root, &_path);
if (r < 0) {
- log_error("Failed to get default target: %s", strerror(-r));
+ log_error_errno(r, "Failed to get default target: %m");
return r;
}
path = _path;
if (!bus || avoid_bus()) {
r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
if (r < 0) {
- log_error("Failed to set default target: %s", strerror(-r));
+ log_error_errno(r, "Failed to set default target: %m");
return r;
}
r = 0;
} else {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- r = sd_bus_call_method(
+ r = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "SetDefaultTarget",
- &error,
- &reply,
- "sb", unit, true);
+ "SetDefaultTarget");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "sb", unit, 1);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) {
log_error("Failed to set default target: %s", bus_error_message(&error, -r));
return r;
static int cancel_job(sd_bus *bus, char **args) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
char **name;
+ int r = 0;
assert(args);
return daemon_reload(bus, args);
STRV_FOREACH(name, args+1) {
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
uint32_t id;
- int r;
+ int q;
- r = safe_atou32(*name, &id);
- if (r < 0) {
- log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
- return r;
+ q = safe_atou32(*name, &id);
+ if (q < 0) {
+ log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
+ return q;
}
- r = sd_bus_call_method(
+ q = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "CancelJob",
- &error,
- NULL,
- "u", id);
- if (r < 0) {
- log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
- return r;
+ "CancelJob");
+ if (q < 0)
+ return bus_log_create_error(q);
+
+ q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (q < 0)
+ return bus_log_create_error(1);
+
+ q = sd_bus_message_append(m, "u", id);
+ if (q < 0)
+ return bus_log_create_error(q);
+
+ q = sd_bus_call(bus, m, 0, &error, NULL);
+ if (q < 0) {
+ log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
+ if (r == 0)
+ r = q;
}
}
- return 0;
+ return r;
}
static int need_daemon_reload(sd_bus *bus, const char *unit) {
else if (streq(d->result, "canceled"))
log_error("Job for %s canceled.", strna(d->name));
else if (streq(d->result, "dependency"))
- log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
+ log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
if (d->name) {
bool quotes;
quotes = chars_intersect(d->name, SHELL_NEED_QUOTES);
- log_error("Job for %s failed. See \"systemctl status %s%s%s\" and \"journalctl -xn\" for details.",
+ log_error("Job for %s failed. See \"systemctl status %s%s%s\" and \"journalctl -xe\" for details.",
d->name,
quotes ? "'" : "", d->name, quotes ? "'" : "");
} else
- log_error("Job failed. See \"journalctl -xn\" for details.");
+ log_error("Job failed. See \"journalctl -xe\" for details.");
}
}
while (!set_isempty(s)) {
q = bus_process_wait(bus);
if (q < 0) {
- log_error("Failed to wait for response: %s", strerror(-q));
+ log_error_errno(q, "Failed to wait for response: %m");
return q;
}
STRV_FOREACH(i, triggered_by) {
r = check_one_unit(bus, *i, "active\0reloading\0", true);
if (r < 0) {
- log_error("Failed to check unit: %s", strerror(-r));
+ log_error_errno(r, "Failed to check unit: %m");
return r;
}
return 0;
}
+static const struct {
+ const char *verb;
+ const char *method;
+} unit_actions[] = {
+ { "start", "StartUnit" },
+ { "stop", "StopUnit" },
+ { "condstop", "StopUnit" },
+ { "reload", "ReloadUnit" },
+ { "restart", "RestartUnit" },
+ { "try-restart", "TryRestartUnit" },
+ { "condrestart", "TryRestartUnit" },
+ { "reload-or-restart", "ReloadOrRestartUnit" },
+ { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
+ { "condreload", "ReloadOrTryRestartUnit" },
+ { "force-reload", "ReloadOrTryRestartUnit" }
+};
+
static const char *verb_to_method(const char *verb) {
uint i;
sd_bus_error *error,
Set *s) {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
const char *path;
int r;
assert(error);
log_debug("Calling manager for %s on %s, %s", method, name, mode);
- r = sd_bus_call_method(
+
+ r = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- method,
- error,
- &reply,
- "ss", name, mode);
+ method);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "ss", name, mode);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, error, &reply);
if (r < 0) {
const char *verb;
static int start_unit(sd_bus *bus, char **args) {
_cleanup_set_free_free_ Set *s = NULL;
_cleanup_strv_free_ char **names = NULL;
- const char *method, *mode, *one_name;
+ const char *method, *mode, *one_name, *suffix = NULL;
char **name;
int r = 0;
method = verb_to_method(args[0]);
action = verb_to_action(args[0]);
- mode = streq(args[0], "isolate") ? "isolate" :
- action_table[action].mode ?: arg_job_mode;
+ if (streq(args[0], "isolate")) {
+ mode = "isolate";
+ suffix = ".target";
+ } else
+ mode = action_table[action].mode ?: arg_job_mode;
one_name = action_table[action].target;
} else {
if (one_name)
names = strv_new(one_name, NULL);
else {
- r = expand_names(bus, args + 1, NULL, &names);
+ r = expand_names(bus, args + 1, suffix, &names);
if (r < 0)
- log_error("Failed to expand names: %s", strerror(-r));
+ log_error_errno(r, "Failed to expand names: %m");
}
if (!arg_no_block) {
r = enable_wait_for_jobs(bus);
if (r < 0) {
- log_error("Could not watch jobs: %s", strerror(-r));
+ log_error_errno(r, "Could not watch jobs: %m");
return r;
}
method,
&error,
NULL,
- "b", true);
+ "b", arg_ask_password);
if (r < 0)
log_error("Failed to execute operation: %s", bus_error_message(&error, r));
r = expand_names(bus, args, NULL, &names);
if (r < 0) {
- log_error("Failed to expand names: %s", strerror(-r));
+ log_error_errno(r, "Failed to expand names: %m");
return r;
}
r = expand_names(bus, args + 1, NULL, &names);
if (r < 0)
- log_error("Failed to expand names: %s", strerror(-r));
+ log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
- q = sd_bus_call_method(
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+
+ q = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "KillUnit",
- &error,
- NULL,
- "ssi", *names, arg_kill_who, arg_signal);
+ "KillUnit");
+ if (q < 0)
+ return bus_log_create_error(q);
+
+ q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (q < 0)
+ return bus_log_create_error(q);
+
+ q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
+ if (q < 0)
+ return bus_log_create_error(q);
+
+ q = sd_bus_call(bus, m, 0, &error, NULL);
if (q < 0) {
- log_error("Failed to kill unit %s: %s",
- *names, bus_error_message(&error, r));
+ log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
if (r == 0)
r = q;
}
bool failed_condition_trigger;
bool failed_condition_negate;
const char *failed_condition;
- const char *failed_condition_param;
+ const char *failed_condition_parameter;
+
+ usec_t assert_timestamp;
+ bool assert_result;
+ bool failed_assert_trigger;
+ bool failed_assert_negate;
+ const char *failed_assert;
+ const char *failed_assert_parameter;
/* Socket */
unsigned n_accepted;
s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
- printf(" start condition failed at %s%s%s\n",
+ printf("Condition: start %scondition failed%s at %s%s%s\n",
+ ansi_highlight_yellow(), ansi_highlight_off(),
s2, s1 ? "; " : "", s1 ? s1 : "");
if (i->failed_condition_trigger)
printf(" none of the trigger conditions were met\n");
printf(" %s=%s%s was not met\n",
i->failed_condition,
i->failed_condition_negate ? "!" : "",
- i->failed_condition_param);
+ i->failed_condition_parameter);
+ }
+
+ if (!i->assert_result && i->assert_timestamp > 0) {
+ s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
+ s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
+
+ printf(" Assert: start %sassertion failed%s at %s%s%s\n",
+ ansi_highlight_red(), ansi_highlight_off(),
+ s2, s1 ? "; " : "", s1 ? s1 : "");
+ if (i->failed_assert_trigger)
+ printf(" none of the trigger assertions were met\n");
+ else if (i->failed_assert)
+ printf(" %s=%s%s was not met\n",
+ i->failed_assert,
+ i->failed_assert_negate ? "!" : "",
+ i->failed_assert_parameter);
}
if (i->sysfs_path)
if (i->main_pid > 0 || i->control_pid > 0) {
if (i->main_pid > 0) {
- printf(" Main PID: %u", (unsigned) i->main_pid);
+ printf(" Main PID: "PID_FMT, i->main_pid);
if (i->running) {
_cleanup_free_ char *comm = NULL;
if (i->control_pid > 0) {
_cleanup_free_ char *c = NULL;
- printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
+ printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
get_process_comm(i->control_pid, &c);
if (c)
i->need_daemon_reload = b;
else if (streq(name, "ConditionResult"))
i->condition_result = b;
+ else if (streq(name, "AssertResult"))
+ i->assert_result = b;
break;
}
i->active_exit_timestamp = (usec_t) u;
else if (streq(name, "ConditionTimestamp"))
i->condition_timestamp = (usec_t) u;
+ else if (streq(name, "AssertTimestamp"))
+ i->assert_timestamp = (usec_t) u;
break;
}
i->failed_condition = cond;
i->failed_condition_trigger = trigger;
i->failed_condition_negate = negate;
- i->failed_condition_param = param;
+ i->failed_condition_parameter = param;
+ }
+ }
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_exit_container(m);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
+ const char *cond, *param;
+ int trigger, negate;
+ int32_t state;
+
+ r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
+ log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
+ if (state < 0 && (!trigger || !i->failed_assert)) {
+ i->failed_assert = cond;
+ i->failed_assert_trigger = trigger;
+ i->failed_assert_negate = negate;
+ i->failed_assert_parameter = param;
}
}
if (r < 0)
return bus_log_parse_error(r);
if (u > 0)
- printf("%s=%u\n", name, (unsigned) u);
+ printf("%s=%"PRIu32"\n", name, u);
else if (arg_all)
printf("%s=\n", name);
tt = strv_join(info.argv, " ");
- printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
+ printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }\n",
name,
strna(info.path),
strna(tt),
yes_no(info.ignore),
strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
- (unsigned) info. pid,
+ info.pid,
sigchld_code_to_string(info.code),
info.status,
info.code == CLD_EXITED ? "" : "/",
r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
if (r < 0) {
- log_error("Failed to read server status: %s", strerror(-r));
+ log_error_errno(r, "Failed to read server status: %m");
return r;
}
r = expand_names(bus, patterns, NULL, &names);
if (r < 0)
- log_error("Failed to expand names: %s", strerror(-r));
+ log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
_cleanup_free_ char *unit;
r = expand_names(bus, args + 1, NULL, &names);
if (r < 0)
- log_error("Failed to expand names: %s", strerror(-r));
+ log_error_errno(r, "Failed to expand names: %m");
pager_open_if_enabled();
STRV_FOREACH(name, names) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_strv_free_ char **dropin_paths = NULL;
- _cleanup_free_ char *fragment_path = NULL;
- _cleanup_free_ char *unit = NULL;
-
+ _cleanup_free_ char *fragment_path = NULL, *unit = NULL;
char **path;
unit = unit_dbus_path_from_name(*name);
ansi_highlight_off());
fflush(stdout);
- r = sendfile_full(STDOUT_FILENO, fragment_path);
+ r = copy_file_fd(fragment_path, STDOUT_FILENO);
if (r < 0) {
- log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
+ log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
continue;
}
}
ansi_highlight_off());
fflush(stdout);
- r = sendfile_full(STDOUT_FILENO, *path);
+ r = copy_file_fd(*path, STDOUT_FILENO);
if (r < 0) {
- log_warning("Failed to cat %s: %s", *path, strerror(-r));
+ log_warning_errno(r, "Failed to cat %s: %m", *path);
continue;
}
}
if (r < 0)
return bus_log_create_error(r);
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (r < 0)
+ return bus_log_create_error(r);
+
n = unit_name_mangle(args[1], MANGLE_NOGLOB);
if (!n)
return log_oom();
static int snapshot(sd_bus *bus, char **args) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
_cleanup_free_ char *n = NULL, *id = NULL;
const char *path;
int r;
if (!n)
return log_oom();
- r = sd_bus_call_method(
+ r = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "CreateSnapshot",
- &error,
- &reply,
- "sb", n, false);
+ "CreateSnapshot");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "sb", n, false);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) {
log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
return r;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_strv_free_ char **names = NULL;
char **name;
- int r, q;
+ int r;
assert(args);
r = expand_names(bus, args + 1, ".snapshot", &names);
if (r < 0)
- log_error("Failed to expand names: %s", strerror(-r));
+ log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
- q = sd_bus_call_method(
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ int q;
+
+ q = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "RemoveSnapshot",
- &error,
- NULL,
- "s", *name);
+ "RemoveSnapshot");
+ if (q < 0)
+ return bus_log_create_error(q);
+
+ q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (q < 0)
+ return bus_log_create_error(q);
+
+ q = sd_bus_message_append(m, "s", *name);
+ if (q < 0)
+ return bus_log_create_error(q);
+
+ q = sd_bus_call(bus, m, 0, &error, NULL);
if (q < 0) {
- log_error("Failed to remove snapshot %s: %s",
- *name, bus_error_message(&error, r));
+ log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
if (r == 0)
r = q;
}
static int daemon_reload(sd_bus *bus, char **args) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
const char *method;
int r;
/* "daemon-reload" */ "Reload";
}
- r = sd_bus_call_method(
+ r = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- method,
- &error,
- NULL,
- NULL);
+ method);
+ if (r < 0)
+ return bus_log_create_error(r);
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, NULL);
if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
/* There's always a fallback possible for
* legacy actions. */
r = expand_names(bus, args + 1, NULL, &names);
if (r < 0)
- log_error("Failed to expand names: %s", strerror(-r));
+ log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
- q = sd_bus_call_method(
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+
+ q = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "ResetFailedUnit",
- &error,
- NULL,
- "s", *name);
+ "ResetFailedUnit");
+ if (q < 0)
+ return bus_log_create_error(q);
+
+ q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (q < 0)
+ return bus_log_create_error(q);
+
+ q = sd_bus_message_append(m, "s", *name);
+ if (q < 0)
+ return bus_log_create_error(q);
+
+ q = sd_bus_call(bus, m, 0, &error, NULL);
if (q < 0) {
- log_error("Failed to reset failed state of unit %s: %s",
- *name, bus_error_message(&error, r));
+ log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
if (r == 0)
r = q;
}
"init", &cmdline_init,
NULL);
if (r < 0)
- log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
+ log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
init = cmdline_init;
}
if (r < 0)
return bus_log_create_error(r);
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (r < 0)
+ return bus_log_create_error(r);
+
r = sd_bus_message_append_strv(m, args + 1);
if (r < 0)
return bus_log_create_error(r);
if (r < 0)
return bus_log_create_error(r);
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (r < 0)
+ return bus_log_create_error(r);
+
if (strv_isempty(args + 1))
r = sd_bus_message_append_strv(m, environ);
else {
j = wait_for_terminate(pid, &status);
if (j < 0) {
- log_error("Failed to wait for child: %s", strerror(-r));
+ log_error_errno(r, "Failed to wait for child: %m");
return j;
}
assert_not_reached("Unknown verb");
if (r < 0) {
- log_error("Operation failed: %s", strerror(-r));
+ log_error_errno(r, "Operation failed: %m");
goto finish;
}
if (r < 0)
return bus_log_create_error(r);
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (r < 0)
+ return bus_log_create_error(r);
+
r = sd_bus_message_append_strv(m, names);
if (r < 0)
return bus_log_create_error(r);
return r;
}
+static int add_dependency(sd_bus *bus, char **args) {
+ _cleanup_strv_free_ char **names = NULL;
+ _cleanup_free_ char *target = NULL;
+ const char *verb = args[0];
+ UnitDependency dep;
+ int r = 0;
+
+ if (!args[1])
+ return 0;
+
+ target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
+ if (!target)
+ return log_oom();
+
+ r = mangle_names(args+2, &names);
+ if (r < 0)
+ return r;
+
+ if (streq(verb, "add-wants"))
+ dep = UNIT_WANTS;
+ else if (streq(verb, "add-requires"))
+ dep = UNIT_REQUIRES;
+ else
+ assert_not_reached("Unknown verb");
+
+ if (!bus || avoid_bus()) {
+ UnitFileChange *changes = NULL;
+ unsigned n_changes = 0;
+
+ r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
+
+ if (r < 0) {
+ log_error_errno(r, "Can't add dependency: %m");
+ return r;
+ }
+
+ if (!arg_quiet)
+ dump_unit_file_changes(changes, n_changes);
+
+ unit_file_changes_free(changes, n_changes);
+
+ } else {
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+
+ r = sd_bus_message_new_method_call(
+ bus,
+ &m,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "AddDependencyUnitFiles");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append_strv(m, names);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
+ if (r < 0) {
+ log_error("Failed to execute operation: %s", bus_error_message(&error, r));
+ return r;
+ }
+
+ r = deserialize_and_dump_unit_file_changes(reply);
+ if (r < 0)
+ return r;
+
+ if (!arg_no_reload)
+ r = daemon_reload(bus, args);
+ else
+ r = 0;
+ }
+
+ return r;
+}
+
static int preset_all(sd_bus *bus, char **args) {
UnitFileChange *changes = NULL;
unsigned n_changes = 0;
r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
if (r < 0) {
- log_error("Operation failed: %s", strerror(-r));
+ log_error_errno(r, "Operation failed: %m");
goto finish;
}
r = 0;
} else {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- r = sd_bus_call_method(
+ r = sd_bus_message_new_method_call(
bus,
+ &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "PresetAllUnitFiles",
- &error,
- &reply,
+ "PresetAllUnitFiles");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(
+ m,
"sbb",
unit_file_preset_mode_to_string(arg_preset_mode),
arg_runtime,
arg_force);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) {
log_error("Failed to execute operation: %s", bus_error_message(&error, r));
return r;
state = unit_file_get_state(arg_scope, arg_root, *name);
if (state < 0) {
- log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
+ log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
return state;
}
if (state == UNIT_FILE_ENABLED ||
state == UNIT_FILE_ENABLED_RUNTIME ||
- state == UNIT_FILE_STATIC)
+ state == UNIT_FILE_STATIC ||
+ state == UNIT_FILE_INDIRECT)
enabled = true;
if (!arg_quiet)
if (r < 0)
return bus_log_parse_error(r);
- if (streq(s, "enabled") ||
- streq(s, "enabled-runtime") ||
- streq(s, "static"))
+ if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
enabled = true;
if (!arg_quiet)
" unmask NAME... Unmask one or more units\n"
" link PATH... Link one or more units files into\n"
" the search path\n"
+ " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
+ " on specified one or more units\n"
+ " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
+ " on specified one or more units\n"
" get-default Get the name of the default target\n"
" set-default NAME Set the default target\n\n"
"Machine Commands:\n"
{ "get-default", EQUAL, 1, get_default, NOBUS },
{ "set-property", MORE, 3, set_property },
{ "is-system-running", EQUAL, 1, is_system_running },
+ { "add-wants", MORE, 3, add_dependency, NOBUS },
+ { "add-requires", MORE, 3, add_dependency, NOBUS },
{}
}, *verb = verbs;
* enable/disable */
if (verb->bus == NOBUS) {
if (!bus && !avoid_bus()) {
- log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
+ log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
return -EIO;
}
}
if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
- log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
+ log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
return -EIO;
}
}
static int halt_now(enum action a) {
-/* Make sure C-A-D is handled by the kernel from this
- * point on... */
+ /* The kernel will automaticall flush ATA disks and suchlike
+ * on reboot(), but the file systems need to be synce'd
+ * explicitly in advance. */
+ sync();
+
+ /* Make sure C-A-D is handled by the kernel from this point
+ * on... */
reboot(RB_ENABLE_CAD);
switch (a) {
m);
if (r < 0)
- log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
+ log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
else {
char date[FORMAT_TIMESTAMP_MAX];
else {
r = utmp_put_shutdown();
if (r < 0)
- log_warning("Failed to write utmp record: %s", strerror(-r));
+ log_warning_errno(r, "Failed to write utmp record: %m");
}
}
return 0;
r = halt_now(arg_action);
- log_error("Failed to reboot: %s", strerror(-r));
+ log_error_errno(r, "Failed to reboot: %m");
return r;
}
r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
if (r < 0)
- log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
+ log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
break;
}