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
This commit is contained in:
+46
-16
@@ -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.
|
||||
|
||||
+42
-16
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user