git: 7cb1a0e6e064 - main - reboot: Don't reboot if the next kernel isn't there

From: Warner Losh <imp_at_FreeBSD.org>
Date: Mon, 12 Feb 2024 18:53:38 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=7cb1a0e6e0643cb80308f45e2cce2d127ada3c8f

commit 7cb1a0e6e0643cb80308f45e2cce2d127ada3c8f
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2024-02-12 18:45:01 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-02-12 18:45:01 +0000

    reboot: Don't reboot if the next kernel isn't there
    
    reboot -k garbage won't boot garbage unless /boot/garbage/kernel is
    there. Refuse to reboot if it is missing, though allow -f to force
    it for special-use cases. This is in keeping with nextboot.sh.
    
    Sponsored by:           Netflix
    Reviewed by:            kevans, kib, markj, emaste
    Differential Revision:  https://reviews.freebsd.org/D43802
---
 sbin/reboot/reboot.8 | 33 +++++++++++++++++++--------------
 sbin/reboot/reboot.c | 21 +++++++++++++++++++--
 2 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/sbin/reboot/reboot.8 b/sbin/reboot/reboot.8
index e9a23ef84d69..0a2fb91b6b0b 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 December 20, 2017
+.Dd February 8, 2024
 .Dt REBOOT 8
 .Os
 .Sh NAME
@@ -36,16 +36,16 @@
 .Nd stopping and restarting the system
 .Sh SYNOPSIS
 .Nm halt
-.Op Fl lNnpq
+.Op Fl flNnpq
 .Op Fl k Ar kernel
 .Nm
-.Op Fl cdlNnpqr
+.Op Fl cdflNnpqr
 .Op Fl k Ar kernel
 .Nm fasthalt
-.Op Fl lNnpq
+.Op Fl flNnpq
 .Op Fl k Ar kernel
 .Nm fastboot
-.Op Fl dlNnpq
+.Op Fl dflNnpq
 .Op Fl k Ar kernel
 .Sh DESCRIPTION
 The
@@ -83,17 +83,22 @@ This option is
 supported only when rebooting, and it has no effect unless a dump
 device has previously been specified with
 .Xr dumpon 8 .
-.It Fl k Ar kernel
-Boot the specified
-.Ar kernel
+.It Fl k Ar kname
+Boot the specified kernel
+.Ar kname
 on the next system boot.
-If the kernel boots successfully, the
+This is a one-shot option, the
 .Em default
-kernel will be booted on successive boots, this is a one-shot option.
-If the boot fails, the system will continue attempting to boot
-.Ar kernel
-until the boot process is interrupted and a valid kernel booted.
-This may change in the future.
+kernel will be booted on successive boots.
+No
+.Nm reboot
+or
+.Nm halt
+will be performed if
+.Em /boot/kname/kernel
+does not exist unless the
+.Fl f
+flag is specified.
 .It Fl l
 The halt or reboot is
 .Em not
diff --git a/sbin/reboot/reboot.c b/sbin/reboot/reboot.c
index 7dcebef69b85..4eb5e8590589 100644
--- a/sbin/reboot/reboot.c
+++ b/sbin/reboot/reboot.c
@@ -32,6 +32,7 @@
 #include <sys/types.h>
 #include <sys/boottrace.h>
 #include <sys/reboot.h>
+#include <sys/stat.h>
 #include <sys/sysctl.h>
 #include <sys/time.h>
 
@@ -59,7 +60,7 @@ main(int argc, char *argv[])
 	struct utmpx utx;
 	const struct passwd *pw;
 	int ch, howto, i, fd, sverrno;
-	bool lflag, nflag, qflag, Nflag;
+	bool fflag, lflag, nflag, qflag, Nflag;
 	uint64_t pageins;
 	const char *user, *kernel = NULL;
 
@@ -68,7 +69,7 @@ main(int argc, char *argv[])
 		howto = RB_HALT;
 	} else
 		howto = 0;
-	lflag = nflag = qflag = Nflag = false;
+	fflag = lflag = nflag = qflag = Nflag = false;
 	while ((ch = getopt(argc, argv, "cdk:lNnpqr")) != -1)
 		switch(ch) {
 		case 'c':
@@ -77,6 +78,9 @@ main(int argc, char *argv[])
 		case 'd':
 			howto |= RB_DUMP;
 			break;
+		case 'f':
+			fflag = true;
+			break;
 		case 'k':
 			kernel = optarg;
 			break;
@@ -130,6 +134,19 @@ main(int argc, char *argv[])
 	}
 
 	if (kernel != NULL) {
+		if (!fflag) {
+			char *k;
+			struct stat sb;
+
+			asprintf(&k, "/boot/%s/kernel", kernel);
+			if (k == NULL)
+				errx(1, "No memory to check %s", kernel);
+			if (stat(k, &sb) != 0)
+				err(1, "stat %s", k);
+			if (!S_ISREG(sb.st_mode))
+				errx(1, "%s is not a file", k);
+			free(k);
+		}
 		fd = open("/boot/nextboot.conf", O_WRONLY | O_CREAT | O_TRUNC,
 		    0444);
 		if (fd > -1) {