diff --git a/BUILD_MESON b/BUILD_MESON index e2ffcae9..f5ee0bfa 100644 --- a/BUILD_MESON +++ b/BUILD_MESON @@ -53,7 +53,7 @@ This command configures a "build directory" in "builddir/". You can choose anoth desired, but don't use a directory that is part of the Dinit source tree such as build/ or src/. The "meson setup" command will prepare to build Dinit including the dinit daemon, dinitctl utility -and the shutdown/reboot/halt utilities by default. Tests will not be built. If you wish to change +and the shutdown/reboot/soft-reboot/halt utilities by default. Tests will not be built. If you wish to change the build options, see the next section. Once "meson setup" has completed successfully, you can compile Dinit with: diff --git a/configure b/configure index 210f71b0..9cc1e5b0 100755 --- a/configure +++ b/configure @@ -143,9 +143,9 @@ Installation directories: Optional options: --enable-strip Strip debug information in installation process [Enabled] --disable-strip Don't strip debug information in installation process - --shutdown-prefix=PREFIX Name prefix for shutdown, poweroff, reboot, halt programs [] - --enable-shutdown Build shutdown, poweroff, reboot, halt programs [Enabled only on Linux systems] - --disable-shutdown Don't build shutdown, poweroff, reboot, halt programs + --shutdown-prefix=PREFIX Name prefix for shutdown, poweroff, reboot, soft-reboot, halt programs [] + --enable-shutdown Build shutdown, poweroff, reboot, soft-reboot, halt programs [Enabled only on Linux systems] + --disable-shutdown Don't build shutdown, poweroff, reboot, soft-reboot, halt programs --enable-cgroups Enable Cgroups support [Enabled only on Linux based systems] --disable-cgroups Disable Cgroups support --enable-utmpx Enable manipulating the utmp/utmpx database via the related POSIX functions [guessed] diff --git a/doc/manpages/Makefile b/doc/manpages/Makefile index eed817fb..94092927 100644 --- a/doc/manpages/Makefile +++ b/doc/manpages/Makefile @@ -15,6 +15,7 @@ ifeq ($(BUILD_SHUTDOWN),yes) ln -sf "$(SHUTDOWN_PREFIX)shutdown.8" "$(DESTDIR)$(MANDIR)/man8/$(SHUTDOWN_PREFIX)halt.8" ln -sf "$(SHUTDOWN_PREFIX)shutdown.8" "$(DESTDIR)$(MANDIR)/man8/$(SHUTDOWN_PREFIX)reboot.8" ln -sf "$(SHUTDOWN_PREFIX)shutdown.8" "$(DESTDIR)$(MANDIR)/man8/$(SHUTDOWN_PREFIX)poweroff.8" + ln -sf "$(SHUTDOWN_PREFIX)shutdown.8" "$(DESTDIR)$(MANDIR)/man8/$(SHUTDOWN_PREFIX)soft-reboot.8" endif clean: diff --git a/doc/manpages/meson.build b/doc/manpages/meson.build index 7dcf4879..c8c951ff 100644 --- a/doc/manpages/meson.build +++ b/doc/manpages/meson.build @@ -41,7 +41,7 @@ if shutdown_built install: true, install_dir: join_paths(mandir, section) ) - foreach shutdown_man: ['reboot.8', 'halt.8', 'poweroff.8'] + foreach shutdown_man: ['reboot.8', 'soft-reboot.8', 'halt.8', 'poweroff.8'] install_symlink( shutdown_prefix + shutdown_man, pointing_to: shutdown_prefix + 'shutdown.8', diff --git a/doc/manpages/shutdown.8.m4 b/doc/manpages/shutdown.8.m4 index abd864d0..d0eefad7 100644 --- a/doc/manpages/shutdown.8.m4 +++ b/doc/manpages/shutdown.8.m4 @@ -1,7 +1,7 @@ changequote(`@@@',`$$$')dnl @@@.TH SHUTDOWN "8" "$$$MONTH YEAR@@@" "Dinit $$$VERSION@@@" "Dinit \- service management system" .SH NAME -$$$SHUTDOWN_PREFIX@@@shutdown, $$$SHUTDOWN_PREFIX@@@halt, $$$SHUTDOWN_PREFIX@@@poweroff, $$$SHUTDOWN_PREFIX@@@reboot \- system shutdown +$$$SHUTDOWN_PREFIX@@@shutdown, $$$SHUTDOWN_PREFIX@@@halt, $$$SHUTDOWN_PREFIX@@@poweroff, $$$SHUTDOWN_PREFIX@@@reboot, $$$SHUTDOWN_PREFIX@@@soft-reboot \- system shutdown .\" .SH SYNOPSIS .\" @@ -14,13 +14,15 @@ $$$SHUTDOWN_PREFIX@@@shutdown, $$$SHUTDOWN_PREFIX@@@halt, $$$SHUTDOWN_PREFIX@@@p \fB$$$SHUTDOWN_PREFIX@@@poweroff\fR [\fIoptions...\fR] .br \fB$$$SHUTDOWN_PREFIX@@@reboot\fR [\fIoptions...\fR] +.br +\fB$$$SHUTDOWN_PREFIX@@@soft-reboot\fR [\fIoptions...\fR] .\" .SH DESCRIPTION .\" This manual page is for the shutdown utility included with the \fBDinit\fR service manager package. See \fBdinit\fR(8). -The $$$SHUTDOWN_PREFIX@@@shutdown, $$$SHUTDOWN_PREFIX@@@reboot, $$$SHUTDOWN_PREFIX@@@poweroff and $$$SHUTDOWN_PREFIX@@@halt +The $$$SHUTDOWN_PREFIX@@@shutdown, $$$SHUTDOWN_PREFIX@@@reboot, $$$SHUTDOWN_PREFIX@@@soft-reboot, $$$SHUTDOWN_PREFIX@@@poweroff and $$$SHUTDOWN_PREFIX@@@halt commands can be used to instruct the service manager daemon to perform a service rollback and then to shutdown the system. They can also perform shutdown directly, without service rollback. @@ -38,6 +40,10 @@ Display brief help text and then exit. Request a shutdown followed by restart. This is the default if executed as \fB$$$SHUTDOWN_PREFIX@@@reboot\fR. .TP +\fB\-s\fP +Restart all user-space services without restarting kernel. This is the default if executed as +\fB$$$SHUTDOWN_PREFIX@@@soft-reboot\fR. +.TP \fB\-h\fP Shutdown and then halt the system (without powering down). .TP diff --git a/meson_options.txt b/meson_options.txt index 608137b5..617669ec 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -8,7 +8,7 @@ option( 'shutdown-prefix', type : 'string', value : '', - description : 'Name prefix for "shutdown", "halt" and "reboot" commands (if they are built).' + description : 'Name prefix for "shutdown", "halt", "soft-reboot" and "reboot" commands (if they are built).' ) option( 'dinit-control-socket-path', @@ -89,5 +89,5 @@ option( 'build-shutdown', type : 'feature', value : 'auto', - description : 'Building shutdown/reboot/halt or not.' + description : 'Building shutdown/reboot/soft-reboot/halt or not.' ) diff --git a/src/Makefile b/src/Makefile index 87befd29..93b7913a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -55,6 +55,7 @@ install: all ifeq ($(BUILD_SHUTDOWN),yes) ln -sf $(SHUTDOWN) $(DESTDIR)$(SBINDIR)/$(SHUTDOWN_PREFIX)halt ln -sf $(SHUTDOWN) $(DESTDIR)$(SBINDIR)/$(SHUTDOWN_PREFIX)reboot + ln -sf $(SHUTDOWN) $(DESTDIR)$(SBINDIR)/$(SHUTDOWN_PREFIX)soft-reboot ln -sf $(SHUTDOWN) $(DESTDIR)$(SBINDIR)/$(SHUTDOWN_PREFIX)poweroff endif diff --git a/src/control.cc b/src/control.cc index ef59cfce..834fe8c6 100644 --- a/src/control.cc +++ b/src/control.cc @@ -81,7 +81,7 @@ bool control_conn_t::process_packet() } if (contains({shutdown_type_t::REMAIN, shutdown_type_t::HALT, - shutdown_type_t::POWEROFF, shutdown_type_t::REBOOT}, rbuf[1])) { + shutdown_type_t::POWEROFF, shutdown_type_t::REBOOT, shutdown_type_t::SOFTREBOOT}, rbuf[1])) { auto sd_type = static_cast(rbuf[1]); services->stop_all_services(sd_type); diff --git a/src/dinit.cc b/src/dinit.cc index 17c4b105..e7cb465b 100644 --- a/src/dinit.cc +++ b/src/dinit.cc @@ -192,6 +192,7 @@ namespace { // These need to be at namespace scope to prevent causing stack allocations when using them: constexpr auto shutdown_exec = literal(SBINDIR) + "/" + SHUTDOWN_PREFIX + "shutdown"; + constexpr auto dinit_exec = literal(SBINDIR) + "/" + "dinit"; constexpr auto error_exec_sd = literal("Error executing ") + shutdown_exec + ": "; } @@ -684,6 +685,9 @@ int dinit_main(int argc, char **argv) if (shutdown_type == shutdown_type_t::REBOOT) { log_msg_end(" Will reboot."); } + if (shutdown_type == shutdown_type_t::SOFTREBOOT) { + log_msg_end(" Will soft-reboot."); + } else if (shutdown_type == shutdown_type_t::HALT) { log_msg_end(" Will halt."); } @@ -696,6 +700,15 @@ int dinit_main(int argc, char **argv) close_control_socket(); if (am_system_mgr) { + if (shutdown_type == shutdown_type_t::SOFTREBOOT) { + sync(); // Sync to minimise data loss if user elects to power off / hard reset + execv(dinit_exec, argv); + + // reboot if soft-reboot fails + log(loglevel_t::ERROR, "Could not restart dinit. Will attempt reboot."); + shutdown_type = shutdown_type_t::REBOOT; + } + if (shutdown_type == shutdown_type_t::NONE) { // Services all stopped but there was no shutdown issued. Inform user, wait for ack, and // re-start boot sequence. diff --git a/src/includes/service-constants.h b/src/includes/service-constants.h index 5e38b8ce..2787c15e 100644 --- a/src/includes/service-constants.h +++ b/src/includes/service-constants.h @@ -41,7 +41,8 @@ enum class shutdown_type_t { REMAIN, // Continue running with no services HALT, // Halt system without powering down POWEROFF, // Power off system - REBOOT // Reboot system + REBOOT, // Reboot system + SOFTREBOOT // Reboot dinit }; /* Reasons for why service stopped */ diff --git a/src/meson.build b/src/meson.build index 3602e698..e0cdb784 100644 --- a/src/meson.build +++ b/src/meson.build @@ -66,7 +66,7 @@ if build_shutdown.auto() and platform == 'linux' or build_shutdown.enabled() 'shutdown.cc', kwargs: misc_args ) - foreach exec: ['reboot', 'halt', 'poweroff'] + foreach exec: ['reboot', 'soft-reboot', 'halt', 'poweroff'] install_symlink( shutdown_prefix + exec, pointing_to: shutdown_prefix + 'shutdown', diff --git a/src/shutdown.cc b/src/shutdown.cc index 24c6375f..080b9dc1 100644 --- a/src/shutdown.cc +++ b/src/shutdown.cc @@ -279,6 +279,9 @@ int main(int argc, char **argv) else if (strcmp(argv[i], "-p") == 0) { shutdown_type = shutdown_type_t::POWEROFF; } + else if (strcmp(argv[i], "-s") == 0) { + shutdown_type = shutdown_type_t::SOFTREBOOT; + } else if (strcmp(argv[i], "--use-passed-cfd") == 0) { use_passed_cfd = true; } @@ -297,6 +300,7 @@ int main(int argc, char **argv) cout << execname << " : shutdown the system\n" " --help : show this help\n" " -r : reboot\n" + " -s : soft-reboot\n" " -h : halt system\n" " -p : power down (default)\n" " --use-passed-cfd : use the socket file descriptor identified by the DINIT_CS_FD\n"