Fix -r on multi-chunk softraid volumes
authorkn <kn@openbsd.org>
Mon, 5 Sep 2022 11:12:20 +0000 (11:12 +0000)
committerkn <kn@openbsd.org>
Mon, 5 Sep 2022 11:12:20 +0000 (11:12 +0000)
Running installboot(8) on softraid(4) volumes means installing stages on
every softraid chunk.

The overall idea is the same, but MD implementations differ.

sparc64_softraid.c's sr_install_bootblk() reuses sparc64_installboot.c's
md_installboot() for this.

For sparc64, md_installboot() does the copy of stage 2, usually
/usr/mdec/ofwboot to /ofwboot, so when `-r root' is passed, it prefixes the
file path with "root".

For single-disk installations (plain-disk and single-chunk softraid) this is
fine, but as soon as multiple chunks are used, md_installboot() currently
prefixes the path each time, obviously resulting in invalid paths starting
with the second run.

Other architectures do reuse md_installboot() as well but either don't do
such a copy or implement the prefixing differently -- plus they must support
softraid in the firt place to be able to hit this type of bug.

With this fixed, regress/usr.sbin/installboot finally passes on sparc64 and
installboot no longer fails at the end of a fresh installation onto softraid
with multiple chunks.

"looks correct" miod

regress/usr.sbin/installboot/Makefile
usr.sbin/installboot/sparc64_installboot.c

index 01b4571..07cc998 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.18 2022/09/04 08:24:09 kn Exp $
+#      $OpenBSD: Makefile,v 1.19 2022/09/05 11:12:20 kn Exp $
 
 INSTALLBOOT ?=         /usr/sbin/installboot
 DRY_RUN =              ${INSTALLBOOT} -n
@@ -43,7 +43,6 @@ STAGEDIR =            /usr/mdec
 STAGEFILES =           ${STAGENAMES:=${STAGEDIR}/%}
 
 .if ${USE_SOFTRAID:L} == "yes"
-# installboot(8) behaviour for multi-chunk softraid(4) differs across platforms
 NDISKS ?=              1 2
 .else
 NDISKS =               1
@@ -121,7 +120,6 @@ dry-default:
 dry-root:
        ${SUDO} ${DRY_RUN} -r/ -- "$$(<${ROOTDEVFILE})"
 
-# XXX fails with NDISKS > 1 on sparc64, 1 <= NDISKS <= 4 works on amd64
 root:
        ${SUDO} ${REAL_RUN} -r ${MOUNTPOINT} "$$(<${ROOTDEVFILE})"
 root-stages:
index f2a87c2..4996f88 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sparc64_installboot.c,v 1.10 2022/08/31 19:40:37 kn Exp $     */
+/*     $OpenBSD: sparc64_installboot.c,v 1.11 2022/09/05 11:12:20 kn Exp $     */
 
 /*
  * Copyright (c) 2012, 2013 Joel Sing <jsing@openbsd.org>
@@ -97,10 +97,17 @@ md_prepareboot(int devfd, char *dev)
 void
 md_installboot(int devfd, char *dev)
 {
+       static int prefixed = 0;
+
        /* XXX - is this necessary? */
        sync();
 
-       bootldr = fileprefix(root, bootldr);
+       /*
+        * sr_install_bootblk() calls md_installboot() for every softraid chunk
+        * but the path must be prefixed only once.
+        */
+       if (!prefixed++)
+               bootldr = fileprefix(root, bootldr);
        if (bootldr == NULL)
                exit(1);
        if (verbose)