Proposal to enhance boot path selections

Paul Goyette <[email protected]>
Newsgroups gmane.os.netbsd.ports.x86-64,gmane.os.netbsd.devel.kernel,gmane.os.netbsd.ports.i386
Message-ID <[email protected]>
It has been pointed out to me (privately) that the recent changes I
made to the biosboot and efiboot code may introduce some confusion
regarding which paths are searched for the boot code.  Particularly,
prior to the recent changes one might well use a "naked" boot command
for a primary normal boot, and use /onetbsd (or /netbsd.old or
anything with a leading slash) to request booting from a previous
kernel.

With the recent changes, specifying /onetbsd will only look for a
kernel in /onetbsd and /onetbsd.gz (both being regular files);  it
will not look in /onetbsd/kernel or /onetbsd/kernel.gz as might be
expected.

If one is accustomed to booting with the leading slash it could be
disconcerting (or worse) to not having ingrained muscle-memory boot
the old kernel as expected.

So, I propose that the attached patches be made to the path selection
code.  Simply stated, a leading slash '/' character in the specified
boot name will no longer prevent treating the boot name as a kernel
directory name.  Other embedded slash characters (and multiple leading
slashes) will still prevent using the specified name as a kernel
directory name.  So, for example, ``boot /old/netbsd'' will _not_
attempt to boot /old/netbsd/kernel or /old/netbsd/kernel.gz (with
or without the leading slash.)

I've tested this in qemu for both i38 and amd64 biosboot, and tested
on bare-metal amd64[*] efiboot, and it works well.  The changes are
very localized and affect only the command_boot() code, and that code
is affected only when an explicit argument is given to the boot
command.  A "naked" boot command is not affected by these changes.

[*] For the bare-metal testing I made sure to have a second bootable
media, just in case something broke.  I did not have to resort to the
backup.  :-)

+---------------------+--------------------------+----------------------+
| Paul Goyette (.sig) | PGP Key fingerprint:     | E-mail addresses:    |
| (Retired)           | 1B11 1849 721C 56C8 F63A | [email protected]    |
| Software Developer  | 6E2E 05FD 15CE 9F2D 5102 | [email protected]  |
| & Network Engineer  |                          | [email protected] |
+---------------------+--------------------------+----------------------+
BOOTNAMES.patch (text/plain, 2.2 KB)
Index: boot/boot2.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/boot/boot2.c,v
retrieving revision 1.86
diff -u -p -r1.86 boot2.c
--- boot/boot2.c	6 May 2025 18:16:12 -0000	1.86
+++ boot/boot2.c	11 May 2025 05:01:43 -0000
@@ -489,14 +489,18 @@ command_boot(char *arg)
 	if (!parseboot(arg, &filename, &howto))
 		return;
 
-	if (filename != NULL) {
+	if (filename != NULL && filename[0] != '\0') {
 		/* try old locations first to assist atf test beds */
 		snprintf(path, sizeof(path) - 4, "%s", filename);
 		bootit2(path, sizeof(path), howto);
 
-		/* now treat given filename as a directory */
-		if (strchr(filename, '/') == NULL) {
-			snprintf(path, sizeof(path) - 4, "%s/kernel", filename);
+		/*
+		 * now treat given filename as a directory unless there
+		 * is already an embedded path-name separator '/' present
+		 */
+		if (strchr(filename + 1, '/') == NULL) {
+			snprintf(path, sizeof(path) - 4, "%s/kernel",
+			    filename);
 			bootit2(path, sizeof(path), howto);
 		}
 	} else {
Index: efiboot/boot.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/efiboot/boot.c,v
retrieving revision 1.29
diff -u -p -r1.29 boot.c
--- efiboot/boot.c	30 Apr 2025 06:24:47 -0000	1.29
+++ efiboot/boot.c	11 May 2025 05:01:43 -0000
@@ -464,14 +464,18 @@ command_boot(char *arg)
 	if (!parseboot(arg, &filename, &howto))
 		return;
 
-	if (filename != NULL) {
+	if (filename != NULL && filename[0] != '\0') {
 		/* try old locations first to appease atf test beds */
 		snprintf(path, sizeof(path) - 4, "%s", filename);
 		bootit2(path, sizeof(path), howto);
 
-		/* now treat given filename as a directory name */
-		if (strchr(filename, '/') == NULL) {
-			snprintf(path, sizeof(path) - 4, "%s/kernel", filename);
+		/*
+		 * now treat given filename as a directory unless there
+		 * is already an embedded path-name separator '/' present
+		 */
+		if (strchr(filename + 1, '/') == NULL) {
+			snprintf(path, sizeof(path) - 4, "%s/kernel",
+			    filename);
 			bootit2(path, sizeof(path), howto);
 		}
 	} else {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.