The branch main has been updated by des:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=4453ec5b8716bc465ff5192986099dc75d1f2ce7

commit 4453ec5b8716bc465ff5192986099dc75d1f2ce7
Author:     Dag-Erling Smørgrav <[email protected]>
AuthorDate: 2025-12-10 14:45:57 +0000
Commit:     Dag-Erling Smørgrav <[email protected]>
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);
 }

Reply via email to