***/
#include <sys/reboot.h>
+#include <linux/reboot.h>
+#include <sys/syscall.h>
#include <stdio.h>
#include <getopt.h>
#include <locale.h>
" emergency Enter system emergency mode\n"
" halt Shut down and halt the system\n"
" poweroff Shut down and power-off the system\n"
- " reboot Shut down and reboot the system\n"
+ " reboot [ARG] Shut down and reboot the system\n"
" kexec Shut down and reboot the system with kexec\n"
" exit Request user instance exit\n"
" switch-root [ROOT] [INIT] Change to a different root file system\n"
static int halt_help(void) {
- printf("%s [OPTIONS...]\n\n"
+ printf("%s [OPTIONS...]%s\n\n"
"%s the system.\n\n"
" --help Show this help\n"
" --halt Halt the machine\n"
" -d --no-wtmp Don't write wtmp record\n"
" --no-wall Don't send wall message before halt/power-off/reboot\n",
program_invocation_short_name,
+ arg_action == ACTION_REBOOT ? " [ARG]" : "",
arg_action == ACTION_REBOOT ? "Reboot" :
arg_action == ACTION_POWEROFF ? "Power off" :
"Halt");
{ "output", required_argument, NULL, 'o' },
{ "plain", no_argument, NULL, ARG_PLAIN },
{ "state", required_argument, NULL, ARG_STATE },
- { NULL, 0, NULL, 0 }
+ {}
};
int c;
switch (c) {
case 'h':
- systemctl_help();
- return 0;
+ return systemctl_help();
case ARG_VERSION:
puts(PACKAGE_STRING);
return -EINVAL;
default:
- log_error("Unknown option code '%c'.", c);
- return -EINVAL;
+ assert_not_reached("Unhandled option");
}
}
{ "wtmp-only", no_argument, NULL, 'w' },
{ "no-wtmp", no_argument, NULL, 'd' },
{ "no-wall", no_argument, NULL, ARG_NO_WALL },
- { NULL, 0, NULL, 0 }
+ {}
};
- int c, runlevel;
+ int c, r, runlevel;
assert(argc >= 0);
assert(argv);
switch (c) {
case ARG_HELP:
- halt_help();
- return 0;
+ return halt_help();
case ARG_HALT:
arg_action = ACTION_HALT;
return -EINVAL;
default:
- log_error("Unknown option code '%c'.", c);
- return -EINVAL;
+ assert_not_reached("Unhandled option");
}
}
- if (optind < argc) {
+ if (arg_action == ACTION_REBOOT && argc == optind + 1) {
+ r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
+ if (r < 0) {
+ log_error("Failed to write reboot param to "
+ REBOOT_PARAM_FILE": %s", strerror(-r));
+ return r;
+ }
+ } else if (optind < argc) {
log_error("Too many arguments.");
return -EINVAL;
}
{ "reboot", no_argument, NULL, 'r' },
{ "kexec", no_argument, NULL, 'K' }, /* not documented extension */
{ "no-wall", no_argument, NULL, ARG_NO_WALL },
- { NULL, 0, NULL, 0 }
+ {}
};
int c, r;
switch (c) {
case ARG_HELP:
- shutdown_help();
- return 0;
+ return shutdown_help();
case 'H':
arg_action = ACTION_HALT;
return -EINVAL;
default:
- log_error("Unknown option code '%c'.", c);
- return -EINVAL;
+ assert_not_reached("Unhandled option");
}
}
static const struct option options[] = {
{ "help", no_argument, NULL, ARG_HELP },
{ "no-wall", no_argument, NULL, ARG_NO_WALL },
- { NULL, 0, NULL, 0 }
+ {}
};
static const struct {
switch (c) {
case ARG_HELP:
- telinit_help();
- return 0;
+ return telinit_help();
case ARG_NO_WALL:
arg_no_wall = true;
return -EINVAL;
default:
- log_error("Unknown option code '%c'.", c);
- return -EINVAL;
+ assert_not_reached("Unhandled option");
}
}
static const struct option options[] = {
{ "help", no_argument, NULL, ARG_HELP },
- { NULL, 0, NULL, 0 }
+ {}
};
int c;
switch (c) {
case ARG_HELP:
- runlevel_help();
+ return runlevel_help();
return 0;
case '?':
return -EINVAL;
default:
- log_error("Unknown option code '%c'.", c);
- return -EINVAL;
+ assert_not_reached("Unhandled option");
}
}
static _noreturn_ void halt_now(enum action a) {
+ _cleanup_free_ char *param = NULL;
+
/* Make sure C-A-D is handled by the kernel from this
* point on... */
reboot(RB_ENABLE_CAD);
break;
case ACTION_REBOOT:
- log_info("Rebooting.");
- reboot(RB_AUTOBOOT);
+ if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) == 0) {
+ log_info("Rebooting with arg '%s'.", param);
+ syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
+ LINUX_REBOOT_CMD_RESTART2, param);
+ } else {
+ log_info("Rebooting.");
+ reboot(RB_AUTOBOOT);
+ }
break;
default: