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 | p...@whooppee.com    |
| Software Developer  | 6E2E 05FD 15CE 9F2D 5102 | pgoye...@netbsd.org  |
| & Network Engineer  |                          | pgoyett...@gmail.com |
+---------------------+--------------------------+----------------------+
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 {

Reply via email to