Installing an unstripped boot loader on softraid on sparc64 fails
without proper error message.
Make BIOCINSTALLBOOT return a proper errno, make installboot(8) use it
to provide proper usage errors plus unique code paths for debugging.
At first, I made sr_ioctl_installboot() use sr_error() in the relevant
spot and this made the kernel print my errors, however the following
piece in softraid.c:sr_bio_handler() means using sr_error() will hide
the error code from the ioctl(2) call, i.e. installboot(8) would
report no error message on stderr and exit zero:
if (sc->sc_status.bs_msg_count > 0)
rv = 0;
So instead, use a proper errno that yields a simple
# ./obj/installboot sd2 /usr/mdec/bootblk /ofwboot.new
installboot.sr: softraid installboot failed: File too large
Background: I built ofwboot on one machine ("make" without
"make install", then copy obj/ofwboot over), the resulting executable
was not stripped during build (happens during "make install") and was
about twice as big:
# ls -l /ofwboot*
-rw-r--r-- 1 root wheel 106688 May 23 22:42 /ofwboot
-rwxr-xr-x 1 kn wheel 272452 May 24 00:20 /ofwboot.new
-rwxr-xr-x 1 root wheel 106752 May 24 01:21 /ofwboot.new.strip
It took me longer than anticipated to find out that installboot(8)
fails beause my new boot loader was too big:
# installboot sd2 /usr/mdec/bootblk /ofwboot.new
installboot: softraid installboot failed
# installboot -v sd2 /usr/mdec/bootblk /ofwboot.new
Using / as root
installing bootstrap on /dev/rsd2c
using first-stage /usr/mdec/bootblk, second-stage /ofwboot.new
boot block is 6882 bytes (14 blocks @ 512 bytes = 7168 bytes)
sd2: softraid volume with 1 disk(s)
sd2: installing boot loader on softraid volume
installboot: softraid installboot failed
That's it, no details or additional messages from the kernel.
While this was primarily my own fault, perhaps there are more legitimate
reasons foor bootblk/ofwboot builds to exceed their maximum size.
Feedback? OK?
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c
index dce30576d..8fab24ecc 100644
--- a/sys/dev/softraid.c
+++ b/sys/dev/softraid.c
@@ -3704,11 +3704,11 @@ sr_ioctl_installboot(struct sr_softc *sc, struct
sr_discipline *sd,
goto done;
}
- if (bb->bb_bootblk_size > SR_BOOT_BLOCKS_SIZE * DEV_BSIZE)
- goto done;
-
- if (bb->bb_bootldr_size > SR_BOOT_LOADER_SIZE * DEV_BSIZE)
+ if (bb->bb_bootblk_size > SR_BOOT_BLOCKS_SIZE * DEV_BSIZE ||
+ bb->bb_bootldr_size > SR_BOOT_LOADER_SIZE * DEV_BSIZE) {
+ rv = EFBIG;
goto done;
+ }
secsize = sd->sd_meta->ssdi.ssd_secsize;
diff --git a/usr.sbin/installboot/sparc64_softraid.c
b/usr.sbin/installboot/sparc64_softraid.c
index 776cf4a64..851c48a19 100644
--- a/usr.sbin/installboot/sparc64_softraid.c
+++ b/usr.sbin/installboot/sparc64_softraid.c
@@ -96,6 +96,6 @@ sr_install_bootldr(int devfd, char *dev)
fprintf(stderr, "%s: installing boot loader on "
"softraid volume\n", dev);
if (ioctl(devfd, BIOCINSTALLBOOT, &bb) == -1)
- errx(1, "softraid installboot failed");
+ err(1, "softraid installboot failed");
}
}