ask_password_agent_open();
}
-#ifdef HAVE_LOGIND
static void polkit_agent_open_if_enabled(void) {
/* Open the polkit agent as a child process if necessary */
polkit_agent_open();
}
-#endif
+
+static OutputFlags get_output_flags(void) {
+ return
+ arg_all * OUTPUT_SHOW_ALL |
+ arg_full * OUTPUT_FULL_WIDTH |
+ (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
+ on_tty() * OUTPUT_COLOR |
+ !arg_quiet * OUTPUT_WARN_CUTOFF;
+}
static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
assert(error);
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;
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)
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;
}
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;
}
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;
+ _cleanup_strv_free_ char **load_error = 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_get_property_strv(
+ 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);
+
+ 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;
}
assert(bus);
ask_password_agent_open_if_enabled();
+ polkit_agent_open_if_enabled();
if (arg_action == ACTION_SYSTEMCTL) {
enum action action;
return -EPERM;
}
+ if (a == ACTION_REBOOT) {
+ r = update_reboot_param_file(args[1]);
+ if (r < 0)
+ return r;
+ }
+
if (arg_force >= 2 &&
(a == ACTION_HALT ||
a == ACTION_POWEROFF ||
assert(bus);
assert(args);
+ polkit_agent_open_if_enabled();
+
if (!arg_kill_who)
arg_kill_who = "all";
/* Swap */
const char *what;
+ /* CGroup */
+ uint64_t memory_current;
+ uint64_t memory_limit;
+
LIST_HEAD(ExecStatusInfo, exec);
} UnitStatusInfo;
char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
char since2[FORMAT_TIMESTAMP_MAX], *s2;
const char *path;
- int flags =
- arg_all * OUTPUT_SHOW_ALL |
- (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
- on_tty() * OUTPUT_COLOR |
- !arg_quiet * OUTPUT_WARN_CUTOFF |
- arg_full * OUTPUT_FULL_WIDTH;
char **t, **t2;
assert(i);
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->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))) {
if (i->control_pid > 0)
extra[k++] = i->control_pid;
- show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
+ show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
}
}
if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
- show_journal_by_unit(stdout,
- i->id,
- arg_output,
- 0,
- i->inactive_exit_timestamp_monotonic,
- arg_lines,
- getuid(),
- flags | OUTPUT_BEGIN_NEWLINE,
- arg_scope == UNIT_FILE_SYSTEM,
- ellipsized);
+ show_journal_by_unit(
+ stdout,
+ i->id,
+ arg_output,
+ 0,
+ i->inactive_exit_timestamp_monotonic,
+ arg_lines,
+ getuid(),
+ get_output_flags() | OUTPUT_BEGIN_NEWLINE,
+ SD_JOURNAL_LOCAL_ONLY,
+ arg_scope == UNIT_FILE_SYSTEM,
+ ellipsized);
}
if (i->need_daemon_reload)
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;
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,
+ };
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;
}
printf(" CGroup: %s\n", mi.control_group ?: "/");
if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
- int flags =
- arg_all * OUTPUT_SHOW_ALL |
- (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
- on_tty() * OUTPUT_COLOR |
- !arg_quiet * OUTPUT_WARN_CUTOFF |
- arg_full * OUTPUT_FULL_WIDTH;
-
static const char prefix[] = " ";
unsigned c;
else
c = 0;
- show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
+ show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
}
free(mi.state);
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;
}
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;
char **i;
int r;
+ polkit_agent_open_if_enabled();
+
r = sd_bus_message_new_method_call(
bus,
&m,
const char *path;
int r;
+ polkit_agent_open_if_enabled();
+
if (strv_length(args) > 1)
n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
else
assert(args);
+ polkit_agent_open_if_enabled();
+
r = expand_names(bus, args + 1, ".snapshot", &names);
if (r < 0)
log_error_errno(r, "Failed to expand names: %m");
const char *method;
int r;
+ polkit_agent_open_if_enabled();
+
if (arg_action == ACTION_RELOAD)
method = "Reload";
else if (arg_action == ACTION_REEXEC)
if (strv_length(args) <= 1)
return daemon_reload(bus, args);
+ polkit_agent_open_if_enabled();
+
r = expand_names(bus, args + 1, NULL, &names);
if (r < 0)
log_error_errno(r, "Failed to expand names: %m");
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. */
bool send_force = true, send_preset_mode = false;
const char *method;
+ polkit_agent_open_if_enabled();
+
if (streq(verb, "enable")) {
method = "EnableUnitFiles";
expect_carries_install_info = true;
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ polkit_agent_open_if_enabled();
+
r = sd_bus_message_new_method_call(
bus,
&m,
_cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ polkit_agent_open_if_enabled();
+
r = sd_bus_message_new_method_call(
bus,
&m,
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;
}
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;
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;
}
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"
" based on preset configuration\n"
" preset-all Enable/disable all unit files based on\n"
" preset configuration\n"
- " is-enabled NAME... Check whether unit files are enabled\n\n"
+ " is-enabled NAME... Check whether unit files are enabled\n"
" mask NAME... Mask one or more units\n"
" unmask NAME... Unmask one or more units\n"
" link PATH... Link one or more units files into\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"
" edit NAME... Edit one or more unit files\n"
- "\n"
+ " get-default Get the name of the default target\n"
+ " set-default NAME Set the default target\n\n"
"Machine Commands:\n"
" list-machines [PATTERN...] List local containers and host\n\n"
"Job Commands:\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 },
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);