Date: Thu, 20 Jul 2023 21:37:45 -0500 From: Mike Karels <mike@karels.net> To: Mateusz Guzik <mjguzik@gmail.com> Cc: Current FreeBSD <freebsd-current@freebsd.org> Subject: Re: confusion about root partition causes panic during startup Message-ID: <202307210237.36L2bjqk049891@mail2.karels.net> In-Reply-To: Your message of Thu, 20 Jul 2023 23:13:31 %2B0200. <CAGudoHEgVf6=kFrrCQjce0wjVRQgWJZyZ-bWDz87gse9qFgJQA@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Mateusz Guzik <mjguzik@gmail.com> wrote: > On 7/20/23, Mike Karels <mike@karels.net> wrote: > > I installed an additional NVME drive on a system, and then booted. It > > turns > > out that the new drive became nda0, renumbering the other drives. The > > loader > > found the correct partition to boot (the only choice), and loaded the > > kernel > > correctly. However, /etc/fstab still had the old name (nvd1p2), which= is > > now drive 2. I expected it to drop into single user, but instead the > > system > > panicked in vfs_mountroot_shuffle trying to switch root devices (see > > below). > > It doesn't seem that having the wrong root device in /etc/fstab should > > cause > > a panic; it makes it harder to patch the system. I was unable to get = the > > system to boot using boot-to-single-user or setting currdev, but I man= aged > > to remember doing "boot -a" from a loader prompt to get the system to = ask > > the root device before mounting it. I can easily reproduce this to te= st. > > Probably the NDFREE_PNBUF() shouldn't happen if namei() returned an er= ror. > > > ye, this should do it (untested): > diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c > index 956d29e3f084..85398ff781e4 100644 > --- a/sys/kern/vfs_mountroot.c > +++ b/sys/kern/vfs_mountroot.c > @@ -352,13 +352,13 @@ vfs_mountroot_shuffle(struct thread *td, struct > mount *mpdevfs) > NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fsp= ath); > error =3D namei(&nd); > if (error) { > - NDFREE_PNBUF(&nd); > fspath =3D "/mnt"; > NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSP= ACE, > fspath); > error =3D namei(&nd); > } > if (!error) { > + NDFREE_PNBUF(&nd); > vp =3D nd.ni_vp; > error =3D (vp->v_type =3D=3D VDIR) ? 0 : ENOTDIR= ; > if (!error) > @@ -376,7 +376,6 @@ vfs_mountroot_shuffle(struct thread *td, struct > mount *mpdevfs) > } else > vput(vp); > } > - NDFREE_PNBUF(&nd); > if (error) > printf("mountroot: unable to remount previous ro= ot " > @@ -387,6 +386,7 @@ vfs_mountroot_shuffle(struct thread *td, struct > mount *mpdevfs) > NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, "/dev"); > error =3D namei(&nd); > if (!error) { > + NDFREE_PNBUF(&nd); > vp =3D nd.ni_vp; > error =3D (vp->v_type =3D=3D VDIR) ? 0 : ENOTDIR; > if (!error) That was missing the last change, and tabs were expanded. I put it in by hand, and the patch works, at least to avoid this panic. It still insisted on remounting root on nda1p2, which is not a root file system. Remounting /dev still failed without panicking, then it panicked because there was no /sbin/init. Apparently it is necessary to use "boot -a" in this situation. Too bad the loader option menu doesn't include that. Just to be clear what I tested, my patch follows. Mike diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c index 956d29e3f084..b08b2a3200f8 100644 --- a/sys/kern/vfs_mountroot.c +++ b/sys/kern/vfs_mountroot.c @@ -352,13 +352,13 @@ vfs_mountroot_shuffle(struct thread *td, struct moun= t *mpdevfs) NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath); error =3D namei(&nd); if (error) { - NDFREE_PNBUF(&nd); fspath =3D "/mnt"; NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath); error =3D namei(&nd); } if (!error) { + NDFREE_PNBUF(&nd); vp =3D nd.ni_vp; error =3D (vp->v_type =3D=3D VDIR) ? 0 : ENOTDIR; if (!error) @@ -376,7 +376,6 @@ vfs_mountroot_shuffle(struct thread *td, struct mount = *mpdevfs) } else vput(vp); } - NDFREE_PNBUF(&nd); = if (error) printf("mountroot: unable to remount previous root " @@ -387,6 +386,7 @@ vfs_mountroot_shuffle(struct thread *td, struct mount = *mpdevfs) NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, "/dev"); error =3D namei(&nd); if (!error) { + NDFREE_PNBUF(&nd); vp =3D nd.ni_vp; error =3D (vp->v_type =3D=3D VDIR) ? 0 : ENOTDIR; if (!error) @@ -413,7 +413,6 @@ vfs_mountroot_shuffle(struct thread *td, struct mount = *mpdevfs) if (error) printf("mountroot: unable to remount devfs under /dev " "(error %d)\n", error); - NDFREE_PNBUF(&nd); = if (mporoot =3D=3D mpdevfs) { vfs_unbusy(mpdevfs);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202307210237.36L2bjqk049891>