diff --git a/src/basic/proc-cmdline.c b/src/basic/proc-cmdline.c index 4de3480ff0..5b8f3c954b 100644 --- a/src/basic/proc-cmdline.c +++ b/src/basic/proc-cmdline.c @@ -37,6 +37,7 @@ int proc_cmdline_filter_pid1_args(char **argv, char ***ret) { { "no-pager", no_argument, }, { "help", no_argument, }, { "version", no_argument, }, + { "introspect-cli", no_argument, }, { "dump-configuration-items", no_argument, }, { "dump-bus-properties", no_argument, }, { "bus-introspect", required_argument }, diff --git a/src/core/main.c b/src/core/main.c index d27156ec3f..fe7e5d8498 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -51,13 +51,11 @@ #include "fd-util.h" #include "fdset.h" #include "fileio.h" -#include "format-table.h" #include "format-util.h" #include "fs-util.h" #include "glyph-util.h" #include "hash-funcs.h" #include "hashmap.h" -#include "help-util.h" #include "hexdecoct.h" #include "hostname-setup.h" #include "id128-util.h" @@ -119,6 +117,7 @@ #include "unit-name.h" #include "user-util.h" #include "utf8.h" +#include "verbs.h" #include "version.h" #include "virt.h" #include "watchdog.h" @@ -131,6 +130,7 @@ static enum { ACTION_RUN, ACTION_HELP, ACTION_VERSION, + ACTION_INTROSPECT_CLI, ACTION_TEST, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES, @@ -1039,6 +1039,14 @@ static int redirect_telinit(char *argv[], char **args) { strnull(a), strnull(b), strnull(c)); } +COMMAND( + "systemd\0", + "Start and monitor system and user services.", + .man_pages = "systemd.1\0", + .option_namespace = "systemd", + .pager_flags = &arg_pager_flags, +); + static int parse_argv(int argc, char *argv[]) { bool user_arg_seen = false; int r; @@ -1068,6 +1076,10 @@ static int parse_argv(int argc, char *argv[]) { arg_action = ACTION_VERSION; break; + OPTION_COMMON_INTROSPECT_CLI: + arg_action = ACTION_INTROSPECT_CLI; + break; + OPTION_LONG("test", NULL, "Determine initial transaction, dump it and exit"): arg_action = ACTION_TEST; break; @@ -1268,6 +1280,7 @@ static int parse_argv(int argc, char *argv[]) { "Switch -%c is only supported when running as PID 1.", opts.opt->short_code); /* In PID1, do nothing and continue with option parsing. */ break; + OPTION_ERROR: if (getpid_cached() != 1) return -EINVAL; @@ -1290,28 +1303,6 @@ static int parse_argv(int argc, char *argv[]) { return 0; } -static int help(void) { - _cleanup_(table_unrefp) Table *options = NULL; - int r; - - r = option_parser_get_help_table_ns("systemd", &options); - if (r < 0) - return r; - - help_cmdline("[OPTIONS...]"); - help_abstract("Starts and monitors system and user services."); - - printf("\nThis program takes no positional arguments.\n"); - - help_section("Options"); - r = table_print_or_warn(options); - if (r < 0) - return r; - - help_man_page_reference("systemd", "1"); - return 0; -} - static int prepare_reexecute( Manager *m, FILE **ret_f, @@ -3745,18 +3736,23 @@ static int run_systemd(int argc, char *argv[]) { if (r < 0) goto finish; - if (IN_SET(arg_action, ACTION_TEST, ACTION_HELP, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES, ACTION_BUS_INTROSPECT)) + if (IN_SET(arg_action, ACTION_TEST, ACTION_DUMP_CONFIGURATION_ITEMS, ACTION_DUMP_BUS_PROPERTIES, ACTION_BUS_INTROSPECT)) pager_open(arg_pager_flags); if (arg_action != ACTION_RUN) skip_setup = true; if (arg_action == ACTION_HELP) { - retval = help() < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + r = command_print_help_name("systemd"); + retval = r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; goto finish; } else if (arg_action == ACTION_VERSION) { retval = version(); goto finish; + } else if (arg_action == ACTION_INTROSPECT_CLI) { + r = introspect_cli(SD_JSON_FORMAT_OFF); + retval = r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + goto finish; } else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) { unit_dump_config_items(stdout); retval = EXIT_SUCCESS; diff --git a/src/test/test-proc-cmdline.c b/src/test/test-proc-cmdline.c index 69ad4e212f..c43e7fab1d 100644 --- a/src/test/test-proc-cmdline.c +++ b/src/test/test-proc-cmdline.c @@ -271,9 +271,10 @@ TEST(proc_cmdline_filter_pid1_args) { "--log-color\0--log-level\0drop3\0" /* optional argument ("--log-level" is handled as another option) */ "--log-color\0accept5\0" /* optional argument (separated with space) */ "--log-color=drop4\0accept6\0" /* optional argument (concatenated with '=') */ + "--introspect-cli\0accept7\0" /* no argument */ "--log-color\0--\0" /* "--" is _not_ handled as argument, and remaining strings are accepted */ "remaining\0-x\0--foo\0", - STRV_MAKE("accept1", "accept2", "accept3", "accept4", "accept5", "accept6", "remaining", "-x", "--foo")); + STRV_MAKE("accept1", "accept2", "accept3", "accept4", "accept5", "accept6", "accept7", "remaining", "-x", "--foo")); /* test for "--" */ test_proc_cmdline_filter_pid1_args_one("systemd\0" diff --git a/test/units/TEST-74-AUX-UTILS.introspect-cli.sh b/test/units/TEST-74-AUX-UTILS.introspect-cli.sh index 8283d1d2da..78d329bfc5 100755 --- a/test/units/TEST-74-AUX-UTILS.introspect-cli.sh +++ b/test/units/TEST-74-AUX-UTILS.introspect-cli.sh @@ -40,6 +40,7 @@ INTROSPECTABLE=( shutdown storagectl systemctl + systemd systemd-ac-power systemd-analyze systemd-ask-password @@ -205,6 +206,12 @@ fi systemd-id128 --introspect-cli | jq -e \ '.commands[0].verbs | map(.names[0]) | contains(["new", "machine-id", "show", "help"])' +# systemd is optionally a multicall binary that also provides systemd-executor +if [[ "$(readlink "$(command -v systemd-executor)" 2>/dev/null)" == systemd ]]; then + systemd --introspect-cli | jq -e \ + '[.commands[].names[0]] | sort == ["systemd", "systemd-executor"]' +fi + if command -v systemd-mount >/dev/null; then systemd-mount --introspect-cli | jq -e \ '[.commands[].names[0]] | sort == ["systemd-mount", "systemd-umount"]'