#include <sys/reboot.h>
#include <linux/reboot.h>
-#include <sys/syscall.h>
#include <stdio.h>
#include <getopt.h>
#include <locale.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
-#include <sys/ioctl.h>
-#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
-#include <sys/stat.h>
#include <stddef.h>
-#include <sys/prctl.h>
-#include <fnmatch.h>
#include "sd-daemon.h"
#include "sd-shutdown.h"
#include "cgroup-util.h"
#include "list.h"
#include "path-lookup.h"
-#include "conf-parser.h"
#include "exit-status.h"
#include "build.h"
#include "unit-name.h"
}
static bool output_show_unit(const UnitInfo *u, char **patterns) {
- if (!strv_isempty(patterns)) {
- char **pattern;
-
- STRV_FOREACH(pattern, patterns)
- if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
- goto next;
+ if (!strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
return false;
- }
-next:
if (arg_types) {
const char *dot;
n_shown++;
- if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
+ if (STR_IN_SET(u->load_state, "error", "not-found", "masked") && !arg_plain) {
on_loaded = ansi_highlight_red();
on_circle = ansi_highlight_yellow();
off_loaded = off_circle = ansi_highlight_off();
circle = true;
- }
-
- if (streq(u->active_state, "failed")) {
+ } else if (streq(u->active_state, "failed") && !arg_plain) {
on_circle = on_active = ansi_highlight_red();
off_circle = off_active = ansi_highlight_off();
circle = true;
}
static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
- if (!strv_isempty(patterns)) {
- char **pattern;
-
- STRV_FOREACH(pattern, patterns)
- if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
- goto next;
+ if (!strv_fnmatch_or_empty(patterns, basename(u->path), FNM_NOESCAPE))
return false;
- }
-next:
if (!strv_isempty(arg_types)) {
const char *dot;
return false;
}
- if (!strv_isempty(arg_states)) {
- if (!strv_find(arg_states, unit_file_state_to_string(u->state)))
- return false;
- }
+ if (!strv_isempty(arg_states) &&
+ !strv_find(arg_states, unit_file_state_to_string(u->state)))
+ return false;
return true;
}
static int list_unit_files(sd_bus *bus, char **args) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ UnitFileList *units = NULL;
UnitFileList *unit;
size_t size = 0;
assert(c <= n_units);
hashmap_free(h);
} else {
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
STRV_FOREACH(c, deps) {
- int state;
-
if (strv_contains(*units, *c)) {
if (!arg_plain) {
r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
continue;
}
- state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
- if (state > 0)
- printf("%s%s%s ", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
- else
- printf("%s%s%s ", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
+ if (arg_plain)
+ printf(" ");
+ else {
+ int state;
+ const char *on;
+
+ state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
+ on = state > 0 ? ansi_highlight_green() : ansi_highlight_red();
+ printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
+ }
r = list_dependencies_print(*c, level, branches, c[1] == NULL);
if (r < 0)
}
static bool output_show_machine(const char *name, char **patterns) {
- char **i;
-
- assert(name);
-
- if (strv_isempty(patterns))
- return true;
-
- STRV_FOREACH(i, patterns)
- if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
- return true;
-
- return false;
+ return strv_fnmatch_or_empty(patterns, name, FNM_NOESCAPE);
}
static int get_machine_list(
failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
- if (!arg_no_legend && !streq_ptr(m->state, "running"))
+ if (!arg_plain && !streq_ptr(m->state, "running"))
circle_len = 2;
}
static int get_default(sd_bus *bus, char **args) {
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_free_ char *_path = NULL;
const char *path;
int r;
path = _path;
} else {
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
r = 0;
} else {
- _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
- r = sd_bus_message_new_method_call(
+ polkit_agent_open_if_enabled();
+
+ r = sd_bus_call_method(
bus,
- &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "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);
+ "SetDefaultTarget",
+ &error,
+ &reply,
+ "sb", unit, 1);
if (r < 0) {
log_error("Failed to set default target: %s", bus_error_message(&error, -r));
return r;
assert(n == 0 || jobs);
if (n == 0) {
- on = ansi_highlight_green();
- off = ansi_highlight_off();
+ if (!arg_no_legend) {
+ on = ansi_highlight_green();
+ off = ansi_highlight_off();
- printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
+ printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
+ }
return;
}
}
static bool output_show_job(struct job_info *job, char **patterns) {
- char **pattern;
-
- assert(job);
-
- if (strv_isempty(patterns))
- return true;
-
- STRV_FOREACH(pattern, patterns)
- if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
- return true;
- return false;
+ return strv_fnmatch_or_empty(patterns, job->name, FNM_NOESCAPE);
}
static int list_jobs(sd_bus *bus, char **args) {
}
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;
if (strv_length(args) <= 1)
return daemon_reload(bus, args);
+ polkit_agent_open_if_enabled();
+
STRV_FOREACH(name, args+1) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
uint32_t id;
int q;
if (q < 0)
return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
- q = sd_bus_message_new_method_call(
+ q = sd_bus_call_method(
bus,
- &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "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);
+ "CancelJob",
+ &error,
+ NULL,
+ "u", id);
if (q < 0) {
log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
if (r == 0)
return 0;
}
-static int unit_find_paths(sd_bus *bus,
- const char *unit_name,
- bool avoid_bus_cache,
- LookupPaths *lp,
- char **fragment_path,
- char ***dropin_paths) {
+static int unit_find_paths(
+ sd_bus *bus,
+ const char *unit_name,
+ bool avoid_bus_cache,
+ LookupPaths *lp,
+ char **fragment_path,
+ char ***dropin_paths) {
+
+ _cleanup_free_ char *path = NULL;
+ _cleanup_strv_free_ char **dropins = NULL;
int r;
/**
if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *unit_load_error = NULL;
_cleanup_free_ char *unit = NULL;
- _cleanup_free_ char *path = NULL;
- _cleanup_strv_free_ char **dropins = NULL;
+ char *unit_load_error_name, *unit_load_error_message;
unit = unit_dbus_path_from_name(unit_name);
if (!unit)
if (need_daemon_reload(bus, unit_name) > 0)
warn_unit_file_changed(unit_name);
- r = sd_bus_get_property_string(
+ r = sd_bus_get_property(
bus,
"org.freedesktop.systemd1",
unit,
"org.freedesktop.systemd1.Unit",
- "FragmentPath",
+ "LoadError",
&error,
- &path);
+ &unit_load_error,
+ "(ss)");
if (r < 0)
- return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
+ return log_error_errno(r, "Failed to get LoadError: %s", bus_error_message(&error, r));
+
+ r = sd_bus_message_read(
+ unit_load_error,
+ "(ss)",
+ &unit_load_error_name,
+ &unit_load_error_message);
+ if (r < 0)
+ return bus_log_parse_error(r);
- r = sd_bus_get_property_strv(
+ if (!isempty(unit_load_error_name)) {
+ log_error("Unit %s is not loaded: %s", unit_name, unit_load_error_message);
+ return 0;
+ }
+
+ r = sd_bus_get_property_string(
bus,
"org.freedesktop.systemd1",
unit,
"org.freedesktop.systemd1.Unit",
- "DropInPaths",
+ "FragmentPath",
&error,
- &dropins);
+ &path);
if (r < 0)
- return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
-
- r = 0;
- if (!isempty(path)) {
- *fragment_path = path;
- path = NULL;
- r = 1;
- }
+ return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
- if (dropin_paths && !strv_isempty(dropins)) {
- *dropin_paths = dropins;
- dropins = NULL;
- r = 1;
+ if (dropin_paths) {
+ r = sd_bus_get_property_strv(
+ bus,
+ "org.freedesktop.systemd1",
+ unit,
+ "org.freedesktop.systemd1.Unit",
+ "DropInPaths",
+ &error,
+ &dropins);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
}
} else {
_cleanup_set_free_ Set *names;
if (r < 0)
return r;
- r = unit_file_find_path(lp, unit_name, fragment_path);
+ r = unit_file_find_path(lp, unit_name, &path);
if (r < 0)
return r;
return log_oom();
if (!streq(template, unit_name)) {
- r = unit_file_find_path(lp, template, fragment_path);
+ r = unit_file_find_path(lp, template, &path);
if (r < 0)
return r;
}
}
- if (dropin_paths)
- r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, dropin_paths);
+ if (dropin_paths) {
+ r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, &dropins);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ r = 0;
+
+ if (!isempty(path)) {
+ *fragment_path = path;
+ path = NULL;
+ r = 1;
+ }
+
+ if (dropin_paths && !strv_isempty(dropins)) {
+ *dropin_paths = dropins;
+ dropins = NULL;
+ r = 1;
}
+ if (r == 0)
+ log_error("No files found for %s.", unit_name);
+
return r;
}
sd_bus_error *error,
BusWaitForJobs *w) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
const char *path;
int r;
log_debug("Calling manager for %s on %s, %s", method, name, mode);
- r = sd_bus_message_new_method_call(
+ r = sd_bus_call_method(
bus,
- &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- 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);
+ method,
+ error,
+ &reply,
+ "ss", name, mode);
if (r < 0) {
const char *verb;
[ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
[ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
[ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
- [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
- [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
- [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
- [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
+ [ACTION_RUNLEVEL2] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
+ [ACTION_RUNLEVEL3] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
+ [ACTION_RUNLEVEL4] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
+ [ACTION_RUNLEVEL5] = { SPECIAL_GRAPHICAL_TARGET, NULL, "isolate" },
[ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
[ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
[ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
if (!sv)
return log_oom();
+ if ((pid_t) pid < 0)
+ return log_error_errno(ERANGE, "Bad PID %"PRIu32": %m", pid);
+
if (!strv_contains(sv,
a == ACTION_HALT ||
a == ACTION_POWEROFF ||
user = uid_to_name(uid);
log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
- who, pid, strna(comm), strna(user), why);
+ who, (pid_t) pid, strna(comm), strna(user), why);
c++;
}
return -EPERM;
}
+ if (a == ACTION_REBOOT && args[1]) {
+ r = update_reboot_param_file(args[1]);
+ if (r < 0)
+ return r;
+ }
+
if (arg_force >= 2 &&
(a == ACTION_HALT ||
a == ACTION_POWEROFF ||
}
static int kill_unit(sd_bus *bus, char **args) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_strv_free_ char **names = NULL;
char **name;
int r, q;
log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- q = sd_bus_message_new_method_call(
+ q = sd_bus_call_method(
bus,
- &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "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);
+ "KillUnit",
+ &error,
+ NULL,
+ "ssi", *names, arg_kill_who, arg_signal);
if (q < 0) {
log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
if (r == 0)
/* Swap */
const char *what;
+ /* CGroup */
+ uint64_t memory_current;
+ uint64_t memory_limit;
+ uint64_t cpu_usage_nsec;
+
LIST_HEAD(ExecStatusInfo, exec);
} UnitStatusInfo;
continue;
argv = strv_join(p->argv, " ");
- printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
+ printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
good = is_clean_exit_lsb(p->code, p->status, NULL);
if (!good) {
if (i->status_errno > 0)
printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
+ if (i->memory_current != (uint64_t) -1) {
+ char buf[FORMAT_BYTES_MAX];
+
+ printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
+
+ if (i->memory_limit != (uint64_t) -1)
+ printf(" (limit: %s)\n", format_bytes(buf, sizeof(buf), i->memory_limit));
+ else
+ printf("\n");
+ }
+
+ if (i->cpu_usage_nsec != (uint64_t) -1) {
+ char buf[FORMAT_TIMESPAN_MAX];
+ printf(" CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
+ }
+
if (i->control_group &&
(i->main_pid > 0 || i->control_pid > 0 ||
((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
i->condition_timestamp = (usec_t) u;
else if (streq(name, "AssertTimestamp"))
i->assert_timestamp = (usec_t) u;
+ else if (streq(name, "MemoryCurrent"))
+ i->memory_current = u;
+ else if (streq(name, "MemoryLimit"))
+ i->memory_limit = u;
+ else if (streq(name, "CPUUsageNSec"))
+ i->cpu_usage_nsec = u;
break;
}
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- UnitStatusInfo info = {};
+ UnitStatusInfo info = {
+ .memory_current = (uint64_t) -1,
+ .memory_limit = (uint64_t) -1,
+ .cpu_usage_nsec = (uint64_t) -1,
+ };
ExecStatusInfo *p;
int r;
&reply,
"u", pid);
if (r < 0) {
- log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
+ log_error("Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
return r;
}
r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
if (r < 0)
- return log_error_errno(r, "Failed to lookup unit lookup paths: %m");
+ return log_error_errno(r, "Failed to query unit lookup paths: %m");
return 0;
}
+static int cat_file(const char *filename, bool newline) {
+ _cleanup_close_ int fd;
+
+ fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0)
+ return -errno;
+
+ printf("%s%s# %s%s\n",
+ newline ? "\n" : "",
+ ansi_highlight_blue(),
+ filename,
+ ansi_highlight_off());
+ fflush(stdout);
+
+ return copy_bytes(fd, STDOUT_FILENO, (off_t) -1, false);
+}
+
static int cat(sd_bus *bus, char **args) {
_cleanup_free_ char *user_home = NULL;
_cleanup_free_ char *user_runtime = NULL;
assert(args);
+ if (arg_transport != BUS_TRANSPORT_LOCAL) {
+ log_error("Cannot remotely cat units");
+ return -EINVAL;
+ }
+
r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
if (r < 0)
return r;
r = expand_names(bus, args + 1, NULL, &names);
if (r < 0)
- log_error_errno(r, "Failed to expand names: %m");
+ return log_error_errno(r, "Failed to expand names: %m");
avoid_bus_cache = !bus || avoid_bus();
r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
if (r < 0)
return r;
- else if (r == 0) {
- log_warning("Unit %s does not have any files on disk", *name);
- continue;
- }
+ else if (r == 0)
+ return -ENOENT;
if (first)
first = false;
puts("");
if (fragment_path) {
- printf("%s# %s%s\n",
- ansi_highlight_blue(),
- fragment_path,
- ansi_highlight_off());
- fflush(stdout);
-
- r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
- if (r < 0) {
- log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
- continue;
- }
+ r = cat_file(fragment_path, false);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
}
STRV_FOREACH(path, dropin_paths) {
- printf("%s%s# %s%s\n",
- isempty(fragment_path) && path == dropin_paths ? "" : "\n",
- ansi_highlight_blue(),
- *path,
- ansi_highlight_off());
- fflush(stdout);
-
- r = copy_file_fd(*path, STDOUT_FILENO, false);
- if (r < 0) {
- log_warning_errno(r, "Failed to cat %s: %m", *path);
- continue;
- }
+ r = cat_file(*path, path == dropin_paths);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to cat %s: %m", *path);
}
}
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 *m = NULL, *reply = NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
_cleanup_free_ char *n = NULL, *id = NULL;
const char *path;
int r;
if (!n)
return log_oom();
- r = sd_bus_message_new_method_call(
+ r = sd_bus_call_method(
bus,
- &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "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);
+ "CreateSnapshot",
+ &error,
+ &reply,
+ "sb", n, false);
if (r < 0) {
log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
return r;
}
static int delete_snapshot(sd_bus *bus, char **args) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_strv_free_ char **names = NULL;
char **name;
int r;
log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
int q;
- q = sd_bus_message_new_method_call(
+ q = sd_bus_call_method(
bus,
- &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "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);
+ "RemoveSnapshot",
+ &error,
+ NULL,
+ "s", *name);
if (q < 0) {
log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
if (r == 0)
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_message_new_method_call(
+ r = sd_bus_call_method(
bus,
- &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- 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);
+ method,
+ &error,
+ NULL,
+ NULL);
if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
/* There's always a fallback possible for
* legacy actions. */
}
static int reset_failed(sd_bus *bus, char **args) {
- _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_strv_free_ char **names = NULL;
char **name;
int r, q;
log_error_errno(r, "Failed to expand names: %m");
STRV_FOREACH(name, names) {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
- q = sd_bus_message_new_method_call(
+ q = sd_bus_call_method(
bus,
- &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "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);
+ "ResetFailedUnit",
+ &error,
+ NULL,
+ "s", *name);
if (q < 0) {
log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
if (r == 0)
if (init) {
const char *root_systemd_path = NULL, *root_init_path = NULL;
- root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
- root_init_path = strappenda(root, "/", init);
+ root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
+ root_init_path = strjoina(root, "/", init);
/* If the passed init is actually the same as the
* systemd binary, then let's suppress it. */
assert(bus);
assert(args);
+ polkit_agent_open_if_enabled();
+
method = streq(args[0], "set-environment")
? "SetEnvironment"
: "UnsetEnvironment";
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);
assert(bus);
assert(args);
+ polkit_agent_open_if_enabled();
+
r = sd_bus_message_new_method_call(
bus,
&m,
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 {
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);
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 = 0;
} else {
- _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
polkit_agent_open_if_enabled();
- r = sd_bus_message_new_method_call(
+ r = sd_bus_call_method(
bus,
- &m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
- "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,
+ "PresetAllUnitFiles",
+ &error,
+ &reply,
"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;
r = tempfn_random(new_path, &t);
if (r < 0)
- return log_error_errno(r, "Failed to determine temporary filename for %s: %m", new_path);
+ return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
r = mkdir_parents(new_path, 0755);
if (r < 0) {
- log_error_errno(r, "Failed to create directories for %s: %m", new_path);
+ log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
free(t);
return r;
}
- r = copy_file(original_path, t, 0, 0644);
+ r = copy_file(original_path, t, 0, 0644, 0);
if (r == -ENOENT) {
r = touch(t);
if (r < 0) {
- log_error_errno(r, "Failed to create temporary file %s: %m", t);
+ log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
free(t);
return r;
}
} else if (r < 0) {
- log_error_errno(r, "Failed to copy %s to %s: %m", original_path, t);
+ log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
free(t);
return r;
}
return 0;
}
-
static int unit_file_create_dropin(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_new_path, char **ret_tmp_path) {
char *tmp_new_path, *ending;
char *tmp_tmp_path;
assert(ret_new_path);
assert(ret_tmp_path);
- ending = strappenda(unit_name, ".d/override.conf");
+ ending = strjoina(unit_name, ".d/override.conf");
r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
if (r < 0)
return r;
return 0;
}
-static int unit_file_create_copy(const char *unit_name,
- const char *fragment_path,
- const char *user_home,
- const char *user_runtime,
- char **ret_new_path,
- char **ret_tmp_path) {
+static int unit_file_create_copy(
+ const char *unit_name,
+ const char *fragment_path,
+ const char *user_home,
+ const char *user_runtime,
+ char **ret_new_path,
+ char **ret_tmp_path) {
+
char *tmp_new_path;
char *tmp_tmp_path;
int r;
if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
char response;
- r = ask_char(&response, "yn", "%s already exists, are you sure to overwrite it with %s? [(y)es, (n)o] ", tmp_new_path, fragment_path);
+ r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
if (r < 0) {
free(tmp_new_path);
return r;
r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
if (r < 0) {
- log_error_errno(r, "Failed to create temporary file for %s: %m", tmp_new_path);
+ log_error_errno(r, "Failed to create temporary file for \"%s\": %m", tmp_new_path);
free(tmp_new_path);
return r;
}
if (pid == 0) {
const char **args;
- char **backup_editors = STRV_MAKE("nano", "vim", "vi");
char *editor;
- char **tmp_path, **original_path, **p;
+ char **tmp_path, **original_path, *p;
unsigned i = 1;
size_t argc;
execvp(editor, (char* const*) args);
}
- STRV_FOREACH(p, backup_editors) {
- args[0] = *p;
- execvp(*p, (char* const*) args);
+ FOREACH_STRING(p, "nano", "vim", "vi") {
+ args[0] = p;
+ execvp(p, (char* const*) args);
/* We do not fail if the editor doesn't exist
* because we want to try each one of them before
* failing.
}
}
- log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR or $EDITOR or $VISUAL.");
+ log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
_exit(EXIT_FAILURE);
}
r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
if (r < 0)
return r;
- else if (r == 0 || !path)
+ else if (r == 0)
+ return -ENOENT;
+ else if (!path) {
// FIXME: support units with path==NULL (no FragmentPath)
- return log_error_errno(ENOENT, "Unit %s not found, cannot edit.", *name);
+ log_error("No fragment exists for %s.", *name);
+ return -ENOENT;
+ }
if (arg_full)
r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
assert(args);
if (!on_tty()) {
- log_error("Cannot edit units if we are not on a tty");
+ log_error("Cannot edit units if not on a tty");
return -EINVAL;
}
if (r < 0)
return log_error_errno(r, "Failed to expand names: %m");
- if (!names) {
- log_error("No unit name found by expanding names");
- return -ENOENT;
- }
-
r = find_paths_to_edit(bus, names, &paths);
if (r < 0)
return r;
- if (strv_isempty(paths)) {
- log_error("Cannot find any units to edit");
+ if (strv_isempty(paths))
return -ENOENT;
- }
r = run_editor(paths);
if (r < 0)
* It's useful if the user wants to cancel its modification
*/
if (null_or_empty_path(*tmp)) {
- log_warning("Edition of %s canceled: temporary file empty", *original);
+ log_warning("Editing \"%s\" canceled: temporary file is empty", *original);
continue;
}
r = rename(*tmp, *original);
if (r < 0) {
- r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
+ r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
goto end;
}
}
" Operate on remote host\n"
" -M --machine=CONTAINER\n"
" Operate on local container\n"
- " -t --type=TYPE List only units of a particular type\n"
- " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
+ " -t --type=TYPE List units of a particular type\n"
+ " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
" -p --property=NAME Show only properties by this name\n"
" -a --all Show all loaded units/properties, including dead/empty\n"
" ones. To list all units installed on the system, use\n"
" -q --quiet Suppress output\n"
" --no-block Do not wait until operation finished\n"
" --no-wall Don't send wall message before halt/power-off/reboot\n"
- " --no-reload When enabling/disabling unit files, don't reload daemon\n"
- " configuration\n"
+ " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
" --no-legend Do not print a legend (column headers and hints)\n"
" --no-pager Do not pipe output into a pager\n"
" --no-ask-password\n"
" --runtime Enable unit files only temporarily until next reboot\n"
" -f --force When enabling unit files, override existing symlinks\n"
" When shutting down, execute action immediately\n"
- " --preset-mode= Specifies whether fully apply presets, or only enable,\n"
- " or only disable\n"
+ " --preset-mode= Apply only enable, only disable, or all presets\n"
" --root=PATH Enable unit files in the specified root directory\n"
" -n --lines=INTEGER Number of journal entries to show\n"
- " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
- " verbose, export, json, json-pretty, json-sse, cat)\n"
+ " -o --output=STRING Change journal output mode (short, short-iso,\n"
+ " short-precise, short-monotonic, verbose,\n"
+ " export, json, json-pretty, json-sse, cat)\n"
" --plain Print unit dependencies as a list instead of a tree\n\n"
"Unit Commands:\n"
" list-units [PATTERN...] List loaded units\n"
" show-environment Dump environment\n"
" set-environment NAME=VALUE... Set one or more environment variables\n"
" unset-environment NAME... Unset one or more environment variables\n"
- " import-environment NAME... Import all, one or more environment variables\n\n"
+ " import-environment [NAME...] Import all or some environment variables\n\n"
"Manager Lifecycle Commands:\n"
" daemon-reload Reload systemd manager configuration\n"
" daemon-reexec Reexecute systemd manager\n\n"
{ "import-environment", MORE, 1, import_environment},
{ "halt", EQUAL, 1, start_special, FORCE },
{ "poweroff", EQUAL, 1, start_special, FORCE },
- { "reboot", EQUAL, 1, start_special, FORCE },
+ { "reboot", MORE, 1, start_special, FORCE },
{ "kexec", EQUAL, 1, start_special },
{ "suspend", EQUAL, 1, start_special },
{ "hibernate", EQUAL, 1, start_special },
}
}
+ /* Increase max number of open files to 16K if we can, we
+ * might needs this when browsing journal files, which might
+ * be split up into many files. */
+ setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
+
return verb->dispatch(bus, argv + optind);
}
goto finish;
}
- /* Increase max number of open files to 16K if we can, we
- * might needs this when browsing journal files, which might
- * be split up into many files. */
- setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
-
if (!avoid_bus())
r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
+ if (bus)
+ sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
+
/* systemctl_main() will print an error message for the bus
* connection, but only if it needs to */