#include "bootspec.h"
#include "bus-common-errors.h"
#include "bus-error.h"
+#include "bus-locator.h"
+#include "bus-map-properties.h"
#include "bus-message.h"
+#include "bus-print-properties.h"
#include "bus-unit-procs.h"
#include "bus-unit-util.h"
-#include "bus-util.h"
#include "bus-wait-for-jobs.h"
#include "bus-wait-for-units.h"
#include "cgroup-show.h"
static int arg_signal = SIGTERM;
static char *arg_root = NULL;
static usec_t arg_when = 0;
+static const char *arg_reboot_argument = NULL;
static enum action {
ACTION_SYSTEMCTL,
ACTION_HALT,
}
static int compare_unit_info(const UnitInfo *a, const UnitInfo *b) {
- const char *d1, *d2;
int r;
/* First, order by machine */
- if (!a->machine && b->machine)
- return -1;
- if (a->machine && !b->machine)
- return 1;
- if (a->machine && b->machine) {
- r = strcasecmp(a->machine, b->machine);
- if (r != 0)
- return r;
- }
+ r = strcasecmp_ptr(a->machine, b->machine);
+ if (r != 0)
+ return r;
/* Second, order by unit type */
- d1 = strrchr(a->id, '.');
- d2 = strrchr(b->id, '.');
- if (d1 && d2) {
- r = strcasecmp(d1, d2);
- if (r != 0)
- return r;
- }
+ r = strcasecmp_ptr(strrchr(a->id, '.'), strrchr(b->id, '.'));
+ if (r != 0)
+ return r;
/* Third, order by name */
return strcasecmp(a->id, b->id);
else
r = table_print(table, NULL);
if (r < 0)
- return log_error_errno(r, "Failed to show table: %m");
+ return table_log_print_error(r);
return 0;
}
static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
_cleanup_(table_unrefp) Table *table = NULL;
- const UnitInfo *u;
- int job_count = 0;
int r;
table = table_new("", "unit", "load", "active", "sub", "job", "description");
(void) table_set_empty_string(table, "-");
- for (u = unit_infos; unit_infos && u < unit_infos + c; u++) {
+ int job_count = 0;
+ for (const UnitInfo *u = unit_infos; unit_infos && u < unit_infos + c; u++) {
_cleanup_free_ char *j = NULL;
const char *on_underline = "", *on_loaded = "", *on_active = "";
const char *on_circle = "", *id;
assert(a);
assert(b);
- if (!a->machine && b->machine)
- return -1;
- if (a->machine && !b->machine)
- return 1;
- if (a->machine && b->machine) {
- r = strcasecmp(a->machine, b->machine);
- if (r != 0)
- return r;
- }
+ r = strcasecmp_ptr(a->machine, b->machine);
+ if (r != 0)
+ return r;
r = strcmp(a->path, b->path);
- if (r == 0)
- r = strcmp(a->type, b->type);
+ if (r != 0)
+ return r;
- return r;
+ return strcmp(a->type, b->type);
}
static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
assert(a);
assert(b);
- if (!a->machine && b->machine)
- return -1;
- if (a->machine && !b->machine)
- return 1;
- if (a->machine && b->machine) {
- r = strcasecmp(a->machine, b->machine);
- if (r != 0)
- return r;
- }
+ r = strcasecmp_ptr(a->machine, b->machine);
+ if (r != 0)
+ return r;
r = CMP(a->next_elapse, b->next_elapse);
if (r != 0)
if (ret_dropin_paths) {
r = unit_file_find_dropin_paths(arg_root, lp->search_path, NULL,
".d", ".conf",
- names, &dropins);
+ NULL, names, &dropins);
if (r < 0)
return r;
}
if (r < 0)
return r;
- if (a == ACTION_REBOOT && argc > 1) {
- r = update_reboot_parameter_and_warn(argv[1], false);
- if (r < 0)
- return r;
+ if (a == ACTION_REBOOT) {
+ const char *arg = NULL;
+
+ if (argc > 1) {
+ if (arg_reboot_argument)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Both --reboot-argument= and positional argument passed to reboot command, refusing.");
+
+ log_notice("Positional argument to reboot command is deprecated, please use --reboot-argument= instead. Accepting anyway.");
+ arg = argv[1];
+ } else
+ arg = arg_reboot_argument;
+
+ if (arg) {
+ r = update_reboot_parameter_and_warn(arg, false);
+ if (r < 0)
+ return r;
+ }
} else if (a == ACTION_KEXEC) {
r = load_kexec_kernel();
} else if (STR_IN_SET(name, "SystemCallFilter", "RestrictAddressFamilies")) {
_cleanup_strv_free_ char **l = NULL;
- int whitelist;
+ int allow_list;
r = sd_bus_message_enter_container(m, 'r', "bas");
if (r < 0)
return bus_log_parse_error(r);
- r = sd_bus_message_read(m, "b", &whitelist);
+ r = sd_bus_message_read(m, "b", &allow_list);
if (r < 0)
return bus_log_parse_error(r);
if (r < 0)
return bus_log_parse_error(r);
- if (all || whitelist || !strv_isempty(l)) {
+ if (all || allow_list || !strv_isempty(l)) {
bool first = true;
char **i;
fputc('=', stdout);
}
- if (!whitelist)
+ if (!allow_list)
fputc('~', stdout);
STRV_FOREACH(i, l) {
return 1;
- } else if (contents[0] == SD_BUS_TYPE_BYTE && streq(name, "StandardInputData")) {
+ } else if (contents[0] == SD_BUS_TYPE_BYTE && STR_IN_SET(name, "StandardInputData", "RootHashSignature")) {
_cleanup_free_ char *h = NULL;
const void *p;
size_t sz;
bus_print_property_value(name, expected_value, value, affinity);
return 1;
+ } else if (streq(name, "MountImages")) {
+ _cleanup_free_ char *paths = NULL;
+ const char *source, *dest;
+ int ignore_enoent;
+
+ r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ssb)");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ while ((r = sd_bus_message_read(m, "(ssb)", &source, &dest, &ignore_enoent)) > 0) {
+ _cleanup_free_ char *str = NULL;
+
+ if (isempty(source))
+ continue;
+
+ if (asprintf(&str, "%s%s:%s", ignore_enoent ? "-" : "", source, dest) < 0)
+ return log_oom();
+
+ if (!strextend_with_separator(&paths, " ", str, NULL))
+ return log_oom();
+ }
+ 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);
+
+ if (all || !isempty(paths))
+ bus_print_property_value(name, expected_value, value, strempty(paths));
+
+ return 1;
+
}
break;
" emergency Enter system emergency mode\n"
" halt Shut down and halt the system\n"
" poweroff Shut down and power-off the system\n"
- " reboot [ARG] Shut down and reboot the system\n"
+ " reboot Shut down and reboot the system\n"
" kexec Shut down and reboot the system with kexec\n"
" exit [EXIT_CODE] Request user instance or container exit\n"
" switch-root ROOT [INIT] Change to a different root file system\n"
" -M --machine=CONTAINER Operate on a local container\n"
" -t --type=TYPE List units of a particular type\n"
" --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
- " --failed Shorcut for --state=failed\n"
+ " --failed Shortcut for --state=failed\n"
" -p --property=NAME Show only properties by this name\n"
" -P NAME Equivalent to --value --property=NAME\n"
" -a --all Show all properties/all units currently in memory,\n"
ARG_WITH_DEPENDENCIES,
ARG_WAIT,
ARG_WHAT,
+ ARG_REBOOT_ARG,
};
static const struct option options[] = {
{ "message", required_argument, NULL, ARG_MESSAGE },
{ "show-transaction", no_argument, NULL, 'T' },
{ "what", required_argument, NULL, ARG_WHAT },
+ { "reboot-argument", required_argument, NULL, ARG_REBOOT_ARG },
{}
};
break;
}
+ case ARG_REBOOT_ARG:
+ arg_reboot_argument = optarg;
+ break;
+
case '.':
/* Output an error mimicking getopt, and print a hint afterwards */
log_error("%s: invalid option -- '.'", program_invocation_name);
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
char date[FORMAT_TIMESTAMP_MAX];
const char *action;
+ const char *log_action;
sd_bus *bus;
int r;
switch (arg_action) {
case ACTION_HALT:
action = "halt";
+ log_action = "Shutdown";
break;
case ACTION_POWEROFF:
action = "poweroff";
+ log_action = "Shutdown";
break;
case ACTION_KEXEC:
action = "kexec";
+ log_action = "Reboot via kexec";
break;
case ACTION_EXIT:
action = "exit";
+ log_action = "Shutdown";
break;
case ACTION_REBOOT:
default:
action = "reboot";
+ log_action = "Reboot";
break;
}
return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r));
if (!arg_quiet)
- log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
+ log_info("%s scheduled for %s, use 'shutdown -c' to cancel.", log_action, format_timestamp(date, sizeof(date), arg_when));
return 0;
#else
return log_error_errno(SYNTHETIC_ERRNO(ENOSYS),
int r;
setlocale(LC_ALL, "");
- log_parse_environment();
+ log_parse_environment_cli();
log_open();
/* The journal merging logic potentially needs a lot of fds. */