git: 4453ec5b8716 - main - reboot: Default to a clean shutdown
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 10 Dec 2025 14:46:55 UTC
The branch main has been updated by des:
URL: https://cgit.FreeBSD.org/src/commit/?id=4453ec5b8716bc465ff5192986099dc75d1f2ce7
commit 4453ec5b8716bc465ff5192986099dc75d1f2ce7
Author: Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-12-10 14:45:57 +0000
Commit: Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-12-10 14:45:57 +0000
reboot: Default to a clean shutdown
* If invoked as fasthalt or fastboot, behavior is unchanged.
* If not invoked as fasthalt or fastboot, we simply signal init(8),
just like shutdown(8) does, instead of taking the system down
ourselves.
* Since only init can handle the RB_REROOT case, the -r flag is not
supported in fast mode.
* Update the usage string to correctly reflect the program being run
(fast or normal; halt, boot, or nextboot) and the options available
in each case.
* Update the manual page to make the distinction between normal and
fast mode clear, better explain what shutdown(8) still does that
reboot(8) does not, and add a historical note explaining what the
difference between the two used to be.
MFC after: 1 month
Relnotes: yes
Reviewed by: imp
Differential Revision: https://reviews.freebsd.org/D54117
---
sbin/reboot/reboot.8 | 62 ++++++++++++++++++++++++++++++++++++++--------------
sbin/reboot/reboot.c | 58 ++++++++++++++++++++++++++++++++++--------------
2 files changed, 88 insertions(+), 32 deletions(-)
diff --git a/sbin/reboot/reboot.8 b/sbin/reboot/reboot.8
index 1bbc39d52be4..4d35336efefb 100644
--- a/sbin/reboot/reboot.8
+++ b/sbin/reboot/reboot.8
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd April 12, 2025
+.Dd December 8, 2025
.Dt REBOOT 8
.Os
.Sh NAME
@@ -60,16 +60,25 @@ The
.Nm halt
and
.Nm
-utilities flush the file system cache to disk, send all running processes
-a
+utilities stop and restart the system, respectively.
+.Pp
+Both utilities have two distinct modes of operation.
+In normal mode, they send a signal to the
+.Xr init 8
+process, which shuts down running services and stops or restarts the
+system.
+In fast mode, they flush the file system cache to disk, send all
+running processes a
.Dv SIGTERM
(and subsequently a
.Dv SIGKILL )
-and, respectively, halt or restart the system.
-The action is logged, including entering a shutdown record into the user
-accounting database.
+and stop or restart the system themselves.
+Services are killed, not shut down, which may result in data loss.
.Pp
-The options are as follows:
+In either mode, the action is logged, including entering a shutdown
+record into the user accounting database.
+.Pp
+The following options are available:
.Bl -tag -width indent
.It Fl c
The system will turn off the power and then turn it back on if it can.
@@ -111,14 +120,17 @@ Care should be taken if
contains any characters that are special to the shell or loader's configuration
parsing code.
.It Fl f
-Force reboot.
+Forced mode.
Normally,
+.Nm halt
+or
.Nm
checks for the presence of the next kernel,
and absence of the
.Pa /var/run/noshutdown
file.
-Without this flag, reboot is denied if one of the conditions failed.
+Without this flag, the operation is rejected if one of these checks
+fails.
.It Fl k Ar kname
Boot the specified kernel
.Ar kname
@@ -195,17 +207,20 @@ The
.Nm fasthalt
and
.Nm fastboot
-utilities are nothing more than aliases for the
+utilities invoke
.Nm halt
and
-.Nm
-utilities.
+.Nm ,
+respectively, in fast mode.
.Pp
-Normally, the
+The
.Xr shutdown 8
-utility is used when the system needs to be halted or restarted, giving
-users advance warning of their impending doom and cleanly terminating
-specific programs.
+utility can be used to not only stop or restart the system right away,
+but also schedule a stop or restart in the future, and will, unlike
+.Nm halt
+and
+.Nm ,
+give users advance warning of their impending doom.
.Sh EXAMPLES
Replace current root filesystem with UFS mounted from
.Pa /dev/ada0s1a :
@@ -236,3 +251,18 @@ A
.Nm
utility appeared in
.Bx 4.0 .
+.Pp
+Historically, the
+.Xr shutdown 8
+utility was used when the system needed to be halted or restarted
+cleanly in the normal course of operations, and the
+.Nm halt
+and
+.Nm
+utilities were blunt instruments used only in single-user mode or if
+exceptional circumstances made a normal shutdown impractical.
+As other operating systems did away with this distinction, and it
+became clear that many users were unaware of it and were using
+.Nm
+in the belief that it performed a clean shutdown, it was rewritten to
+conform to that expectation.
diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c
index 59ae83ef6f6a..a147b7e08a95 100644
--- a/sbin/reboot/reboot.c
+++ b/sbin/reboot/reboot.c
@@ -59,6 +59,7 @@ extern char **environ;
static void usage(void) __dead2;
static uint64_t get_pageins(void);
+static bool dofast;
static bool dohalt;
static bool donextboot;
@@ -229,6 +230,24 @@ add_env(char **env, const char *key, const char *value)
free(oldenv);
}
+static void
+shutdown(int howto)
+{
+ char sigstr[SIG2STR_MAX];
+ int signo =
+ howto & RB_HALT ? SIGUSR1 :
+ howto & RB_POWEROFF ? SIGUSR2 :
+ howto & RB_POWERCYCLE ? SIGWINCH :
+ howto & RB_REROOT ? SIGEMT :
+ SIGINT;
+
+ (void)sig2str(signo, sigstr);
+ BOOTTRACE("SIG%s to init(8)...", sigstr);
+ if (kill(1, signo) == -1)
+ err(1, "SIG%s init", sigstr);
+ exit(0);
+}
+
/*
* Different options are valid for different programs.
*/
@@ -239,18 +258,24 @@ int
main(int argc, char *argv[])
{
struct utmpx utx;
- const struct passwd *pw;
struct stat st;
+ const struct passwd *pw;
+ const char *progname, *user;
+ const char *kernel = NULL, *getopts = GETOPT_REBOOT;
+ char *env = NULL, *v;
+ uint64_t pageins;
int ch, howto = 0, i, sverrno;
bool aflag, Dflag, fflag, lflag, Nflag, nflag, qflag;
- uint64_t pageins;
- const char *user, *kernel = NULL, *getopts = GETOPT_REBOOT;
- char *env = NULL, *v;
- if (strstr(getprogname(), "halt") != NULL) {
+ progname = getprogname();
+ if (strncmp(progname, "fast", 4) == 0) {
+ dofast = true;
+ progname += 4;
+ }
+ if (strcmp(progname, "halt") == 0) {
dohalt = true;
howto = RB_HALT;
- } else if (strcmp(getprogname(), "nextboot") == 0) {
+ } else if (strcmp(progname, "nextboot") == 0) {
donextboot = true;
getopts = GETOPT_NEXTBOOT; /* Note: reboot's extra opts return '?' */
} else {
@@ -331,6 +356,8 @@ main(int argc, char *argv[])
errx(1, "-c and -p cannot be used together");
if ((howto & RB_REROOT) != 0 && howto != RB_REROOT)
errx(1, "-r cannot be used with -c, -d, -n, or -p");
+ if ((howto & RB_REROOT) != 0 && dofast)
+ errx(1, "-r cannot be performed in fast mode");
if ((howto & RB_REROOT) != 0 && kernel != NULL)
errx(1, "-r and -k cannot be used together, there is no next kernel");
@@ -438,14 +465,10 @@ main(int argc, char *argv[])
(void)signal(SIGPIPE, SIG_IGN);
/*
- * Only init(8) can perform rerooting.
+ * Common case: clean shutdown.
*/
- if (howto & RB_REROOT) {
- if (kill(1, SIGEMT) == -1)
- err(1, "SIGEMT init");
-
- return (0);
- }
+ if (!dofast)
+ shutdown(howto);
/* Just stop init -- if we fail, we'll restart it. */
BOOTTRACE("SIGTSTP to init(8)...");
@@ -507,9 +530,12 @@ usage(void)
fprintf(stderr, "usage: nextboot [-aDf] "
"[-e name=value] [-k kernel] [-o options]\n");
} else {
- fprintf(stderr, dohalt ?
- "usage: halt [-clNnpq] [-k kernel]\n" :
- "usage: reboot [-cdlNnpqr] [-k kernel]\n");
+ fprintf(stderr, "usage: %s%s [-%sflNnpq%s] "
+ "[-e name=value] [-k kernel] [-o options]\n",
+ dofast ? "fast" : "",
+ dohalt ? "halt" : dofast ? "boot" : "reboot",
+ dohalt ? "D" : "cDd",
+ dohalt || dofast ? "" : "r");
}
exit(1);
}