shutdown: in containers, invoke reboot(2), too. Then fallback to exit() if CAP_SYS_BOOT is missing

The kernel's PID namespaces support reboot(2) just fine, so let's make
use of it if possible.
This commit is contained in:
Lennart Poettering 2012-09-05 15:37:18 -07:00
parent 57371e5829
commit cb7ec5645e

View file

@ -263,14 +263,8 @@ int main(int argc, char *argv[]) {
arguments[2] = NULL;
execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, arguments);
/* If we are in a container, just exit, this will kill our
* container for good. */
if (in_container) {
log_error("Exiting container.");
exit(0);
}
if (access("/run/initramfs/shutdown", X_OK) == 0) {
if (!in_container &&
access("/run/initramfs/shutdown", X_OK) == 0) {
if (prepare_new_root() >= 0 &&
pivot_to_new_root() >= 0) {
@ -280,6 +274,8 @@ int main(int argc, char *argv[]) {
}
if (cmd == LINUX_REBOOT_CMD_KEXEC) {
if (!in_container) {
/* We cheat and exec kexec to avoid doing all its work */
pid_t pid = fork();
@ -294,11 +290,21 @@ int main(int argc, char *argv[]) {
execv(args[0], (char * const *) args);
return EXIT_FAILURE;
}
}
cmd = RB_AUTOBOOT;
}
reboot(cmd);
if (errno == EPERM && in_container) {
/* If we are in a container, and we lacked
* CAP_SYS_BOOT just exit, this will kill our
* container for good. */
log_error("Exiting container.");
exit(0);
}
log_error("Failed to invoke reboot(): %m");
r = -errno;