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
-# $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
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
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:
-/* $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>
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)