summaryrefslogtreecommitdiffstats
path: root/src/systemctl/systemctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemctl/systemctl.c')
-rw-r--r--src/systemctl/systemctl.c57
1 files changed, 41 insertions, 16 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index dd6f6c9..0ca76ac 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -8,6 +8,7 @@
#include "build.h"
#include "bus-util.h"
+#include "capsule-util.h"
#include "dissect-image.h"
#include "install.h"
#include "main-func.h"
@@ -63,6 +64,7 @@
#include "systemctl.h"
#include "terminal-util.h"
#include "time-util.h"
+#include "user-util.h"
#include "verbs.h"
#include "virt.h"
@@ -103,6 +105,7 @@ bool arg_kill_value_set = false;
char *arg_root = NULL;
char *arg_image = NULL;
usec_t arg_when = 0;
+bool arg_stdin = false;
const char *arg_reboot_argument = NULL;
enum action arg_action = ACTION_SYSTEMCTL;
BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
@@ -249,6 +252,8 @@ static int systemctl_help(void) {
" soft-reboot Shut down and reboot userspace\n"
" exit [EXIT_CODE] Request user instance or container exit\n"
" switch-root [ROOT [INIT]] Change to a different root file system\n"
+ " sleep Put the system to sleep (through one of\n"
+ " the operations below)\n"
" suspend Suspend the system\n"
" hibernate Hibernate the system\n"
" hybrid-sleep Hibernate and suspend the system\n"
@@ -259,6 +264,7 @@ static int systemctl_help(void) {
" --version Show package version\n"
" --system Connect to system manager\n"
" --user Connect to user service manager\n"
+ " -C --capsule=NAME Connect to service manager of specified capsule\n"
" -H --host=[USER@]HOST Operate on remote host\n"
" -M --machine=CONTAINER Operate on a local container\n"
" -t --type=TYPE List units of a particular type\n"
@@ -272,6 +278,8 @@ static int systemctl_help(void) {
" -l --full Don't ellipsize unit names on output\n"
" -r --recursive Show unit list of host and local containers\n"
" --reverse Show reverse dependencies with 'list-dependencies'\n"
+ " --before Show units ordered before with 'list-dependencies'\n"
+ " --after Show units ordered after with 'list-dependencies'\n"
" --with-dependencies Show unit dependencies with 'status', 'cat',\n"
" 'list-units', and 'list-unit-files'.\n"
" --job-mode=MODE Specify how to deal with already queued jobs, when\n"
@@ -297,8 +305,10 @@ static int systemctl_help(void) {
" --no-warn Suppress several warnings shown by default\n"
" --wait For (re)start, wait until service stopped again\n"
" For is-system-running, wait until startup is completed\n"
+ " For kill, wait until service stopped\n"
" --no-block Do not wait until operation finished\n"
" --no-wall Don't send wall message before halt/power-off/reboot\n"
+ " --message=MESSAGE Specify human readable reason for system shutdown\n"
" --no-reload Don't reload daemon after en-/dis-abling unit files\n"
" --legend=BOOL Enable/disable the legend (column headers and hints)\n"
" --no-pager Do not pipe output into a pager\n"
@@ -326,6 +336,8 @@ static int systemctl_help(void) {
" Boot into boot loader menu on next boot\n"
" --boot-loader-entry=NAME\n"
" Boot into a specific boot loader entry on next boot\n"
+ " --reboot-argument=ARG\n"
+ " Specify argument string to pass to reboot()\n"
" --plain Print unit dependencies as a list instead of a tree\n"
" --timestamp=FORMAT Change format of printed timestamps (pretty, unix,\n"
" us, utc, us+utc)\n"
@@ -335,6 +347,7 @@ static int systemctl_help(void) {
" --drop-in=NAME Edit unit files using the specified drop-in file name\n"
" --when=TIME Schedule halt/power-off/reboot/kexec action after\n"
" a certain timestamp\n"
+ " --stdin Read contents of edited file from stdin\n"
"\nSee the %2$s for details.\n",
program_invocation_short_name,
link,
@@ -461,6 +474,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
ARG_NO_WARN,
ARG_DROP_IN,
ARG_WHEN,
+ ARG_STDIN,
};
static const struct option options[] = {
@@ -485,6 +499,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
{ "user", no_argument, NULL, ARG_USER },
{ "system", no_argument, NULL, ARG_SYSTEM },
{ "global", no_argument, NULL, ARG_GLOBAL },
+ { "capsule", required_argument, NULL, 'C' },
{ "wait", no_argument, NULL, ARG_WAIT },
{ "no-block", no_argument, NULL, ARG_NO_BLOCK },
{ "legend", required_argument, NULL, ARG_LEGEND },
@@ -527,6 +542,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
{ "marked", no_argument, NULL, ARG_MARKED },
{ "drop-in", required_argument, NULL, ARG_DROP_IN },
{ "when", required_argument, NULL, ARG_WHEN },
+ { "stdin", no_argument, NULL, ARG_STDIN },
{}
};
@@ -538,7 +554,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
/* We default to allowing interactive authorization only in systemctl (not in the legacy commands) */
arg_ask_password = true;
- while ((c = getopt_long(argc, argv, "ht:p:P:alqfs:H:M:n:o:iTr.::", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "hC:t:p:P:alqfs:H:M:n:o:iTr.::", options, NULL)) >= 0)
switch (c) {
@@ -673,6 +689,18 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
arg_runtime_scope = RUNTIME_SCOPE_GLOBAL;
break;
+ case 'C':
+ r = capsule_name_is_valid(optarg);
+ if (r < 0)
+ return log_error_errno(r, "Unable to validate capsule name '%s': %m", optarg);
+ if (r == 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid capsule name: %s", optarg);
+
+ arg_host = optarg;
+ arg_transport = BUS_TRANSPORT_CAPSULE;
+ arg_runtime_scope = RUNTIME_SCOPE_USER;
+ break;
+
case ARG_WAIT:
arg_wait = true;
break;
@@ -1017,6 +1045,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
+ case ARG_STDIN:
+ arg_stdin = true;
+ break;
+
case '.':
/* Output an error mimicking getopt, and print a hint afterwards */
log_error("%s: invalid option -- '.'", program_invocation_name);
@@ -1067,7 +1099,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
}
if (arg_image && arg_root)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Please specify either --root= or --image=, the combination of both is not supported.");
return 1;
}
@@ -1107,15 +1140,8 @@ int systemctl_dispatch_parse_argv(int argc, char *argv[]) {
*
* Also see redirect_telinit() in src/core/main.c. */
- if (sd_booted() > 0) {
- arg_action = _ACTION_INVALID;
- return telinit_parse_argv(argc, argv);
- } else {
- /* Hmm, so some other init system is running, we need to forward this request to it.
- */
- arg_action = ACTION_TELINIT;
- return 1;
- }
+ arg_action = _ACTION_INVALID; /* telinit_parse_argv() will figure out the actual action we'll execute */
+ return telinit_parse_argv(argc, argv);
} else if (invoked_as(argv, "runlevel")) {
arg_action = ACTION_RUNLEVEL;
@@ -1179,6 +1205,7 @@ static int systemctl_main(int argc, char *argv[]) {
{ "reboot", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special },
{ "kexec", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special },
{ "soft-reboot", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special },
+ { "sleep", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special },
{ "suspend", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special },
{ "hibernate", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special },
{ "hybrid-sleep", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special },
@@ -1265,7 +1292,8 @@ static int run(int argc, char *argv[]) {
DISSECT_IMAGE_GENERIC_ROOT |
DISSECT_IMAGE_REQUIRE_ROOT |
DISSECT_IMAGE_RELAX_VAR_CHECK |
- DISSECT_IMAGE_VALIDATE_OS,
+ DISSECT_IMAGE_VALIDATE_OS |
+ DISSECT_IMAGE_ALLOW_USERSPACE_VERITY,
&mounted_dir,
/* ret_dir_fd= */ NULL,
&loop_device);
@@ -1318,11 +1346,8 @@ static int run(int argc, char *argv[]) {
r = runlevel_main();
break;
- case ACTION_TELINIT:
- r = exec_telinit(argv);
- break;
-
case ACTION_EXIT:
+ case ACTION_SLEEP:
case ACTION_SUSPEND:
case ACTION_HIBERNATE:
case ACTION_HYBRID_SLEEP: