BIOCINSTALLBOOT/sparc64 installboot: EFBIG on too big boot loaders

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

BIOCINSTALLBOOT/sparc64 installboot: EFBIG on too big boot loaders

Klemens Nanni-2
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");
  }
 }

Reply | Threaded
Open this post in threaded view
|

Re: BIOCINSTALLBOOT/sparc64 installboot: EFBIG on too big boot loaders

Klemens Nanni-2
On Mon, Jun 01, 2020 at 11:48:05PM +0200, Klemens Nanni wrote:

> 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.

In a i386 VM with root on crypto softraid, I built a much bigger second
stage boot loader and performed the same tests as on sparc64: i386 does
not try to install the bogus boot code due to checks in i386_softraid.c
up front:

        # ls -l /usr/mdec/boot /boot.efbig
        -r-xr-xr-x  1 root  bin     89728 Jun  5 03:02 /usr/mdec/boot
        -rwxr-xr-x  1 root  wheel  176172 Jun  5 22:16 /boot.efbig
        # installboot -v sd1 /usr/mdec/biosboot /boot.efbig
        Using / as root
        installing bootstrap on /dev/rsd1c
        using first-stage /usr/mdec/biosboot, second-stage /boot.efbig
        sd1: softraid volume with 1 disk(s)
        installboot: boot code will not fit

So for installboot(8) on sparc64 and i386 as the only two users of
BIOCINSTALLBOOT, this makes root on softraid on sparc64 the only use
that actually hits size checks in the ioctl code.


sr_ioctl_installboot() seems inconsistent to me in how it reports some
errors through sr_error() (causing ioctl() to return zero) and returing
proper error codes (causing ioctl() and therefore installboot to fail);

Assuming my EFBIG approach is still sensible (for sparc64), diff below
adjusts the errx() call to err() in installboot for both platforms, even
though i386 never reaches it.

Feedback? OK?


Index: sys/dev/softraid.c
===================================================================
RCS file: /cvs/src/sys/dev/softraid.c,v
retrieving revision 1.401
diff -u -p -r1.401 softraid.c
--- sys/dev/softraid.c 14 Apr 2020 07:38:21 -0000 1.401
+++ sys/dev/softraid.c 5 Jun 2020 20:41:20 -0000
@@ -3704,11 +3704,11 @@ sr_ioctl_installboot(struct sr_softc *sc
  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;
 
Index: usr.sbin/installboot/i386_softraid.c
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/i386_softraid.c,v
retrieving revision 1.15
diff -u -p -r1.15 i386_softraid.c
--- usr.sbin/installboot/i386_softraid.c 9 Mar 2020 06:16:56 -0000 1.15
+++ usr.sbin/installboot/i386_softraid.c 5 Jun 2020 20:39:54 -0000
@@ -177,7 +177,7 @@ 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");
  }
 
  /*
Index: usr.sbin/installboot/sparc64_softraid.c
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/sparc64_softraid.c,v
retrieving revision 1.4
diff -u -p -r1.4 sparc64_softraid.c
--- usr.sbin/installboot/sparc64_softraid.c 28 Jun 2019 13:32:48 -0000 1.4
+++ usr.sbin/installboot/sparc64_softraid.c 5 Jun 2020 20:40:05 -0000
@@ -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");
  }
 }

Reply | Threaded
Open this post in threaded view
|

Re: BIOCINSTALLBOOT/sparc64 installboot: EFBIG on too big boot loaders

Joel Sing-3
On 20-06-05 22:42:17, Klemens Nanni wrote:

> On Mon, Jun 01, 2020 at 11:48:05PM +0200, Klemens Nanni wrote:
> > 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.
>
> In a i386 VM with root on crypto softraid, I built a much bigger second
> stage boot loader and performed the same tests as on sparc64: i386 does
> not try to install the bogus boot code due to checks in i386_softraid.c
> up front:
>
> # ls -l /usr/mdec/boot /boot.efbig
> -r-xr-xr-x  1 root  bin     89728 Jun  5 03:02 /usr/mdec/boot
> -rwxr-xr-x  1 root  wheel  176172 Jun  5 22:16 /boot.efbig
> # installboot -v sd1 /usr/mdec/biosboot /boot.efbig
> Using / as root
> installing bootstrap on /dev/rsd1c
> using first-stage /usr/mdec/biosboot, second-stage /boot.efbig
> sd1: softraid volume with 1 disk(s)
> installboot: boot code will not fit
>
> So for installboot(8) on sparc64 and i386 as the only two users of
> BIOCINSTALLBOOT, this makes root on softraid on sparc64 the only use
> that actually hits size checks in the ioctl code.

Keep in mind that the i386 installboot code is used on both i386
and amd64.

> sr_ioctl_installboot() seems inconsistent to me in how it reports some
> errors through sr_error() (causing ioctl() to return zero) and returing
> proper error codes (causing ioctl() and therefore installboot to fail);

sr_error() is used to add detail - the installboot code should be
checking and handling the case where bs->bs_status is non-zero.
IIRC the reason the ioctl has to succeed for this to work, is that
on failure there is no copyout().

> Assuming my EFBIG approach is still sensible (for sparc64), diff below
> adjusts the errx() call to err() in installboot for both platforms, even
> though i386 never reaches it.
>
> Feedback? OK?

While this works, you would be better off making use of the error
reporting mechanism that exists. A compile tested only diff for
the kernel side is below. A diff to installboot would be needed to
graft some code similar to that in bioctl's bio_status() function.

Index: softraid.c
===================================================================
RCS file: /cvs/src/sys/dev/softraid.c,v
retrieving revision 1.401
diff -u -p -u -p -r1.401 softraid.c
--- softraid.c 14 Apr 2020 07:38:21 -0000 1.401
+++ softraid.c 6 Jun 2020 14:32:56 -0000
@@ -3704,11 +3704,17 @@ sr_ioctl_installboot(struct sr_softc *sc
  goto done;
  }
 
- if (bb->bb_bootblk_size > SR_BOOT_BLOCKS_SIZE * DEV_BSIZE)
+ if (bb->bb_bootblk_size > SR_BOOT_BLOCKS_SIZE * DEV_BSIZE) {
+ sr_error(sc, "boot block is too large (%d > %d)",
+    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_bootldr_size > SR_BOOT_LOADER_SIZE * DEV_BSIZE) {
+ sr_error(sc, "boot loader is too large (%d > %d)",
+    bb->bb_bootldr_size, SR_BOOT_LOADER_SIZE * DEV_BSIZE);
  goto done;
+ }
 
  secsize = sd->sd_meta->ssdi.ssd_secsize;
 

Reply | Threaded
Open this post in threaded view
|

Re: BIOCINSTALLBOOT/sparc64 installboot: EFBIG on too big boot loaders

Klemens Nanni-2
On Sun, Jun 07, 2020 at 12:42:57AM +1000, Joel Sing wrote:
> While this works, you would be better off making use of the error
> reporting mechanism that exists. A compile tested only diff for
> the kernel side is below. A diff to installboot would be needed to
> graft some code similar to that in bioctl's bio_status() function.
Thanks, I didn't even look how bioctl(8) does it; that seems better.

The complete diff for softraid(4), <dev/biovar.h> and installboot(8)
makes sparc64 look like this:

        # ./obj/installboot -v sd2 /usr/mdec/bootblk /ofwboot.big
        Using / as root
        installing bootstrap on /dev/rsd2c
        using first-stage /usr/mdec/bootblk, second-stage /ofwboot.big
        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: boot loader too large (272452 > 163840)
        # echo $?
        1

I ommitted "is" from the kernel message to stay in line with other
"too large" ones in softraid.c.

Contrary to bioctl's bio_status(), installboot's new sr_status() uses
warnx(3) for simplicity and put warnings on stderr (where they belong).

Feedback? OK?


Index: sys/dev/biovar.h
===================================================================
RCS file: /cvs/src/sys/dev/biovar.h,v
retrieving revision 1.45
diff -u -p -r1.45 biovar.h
--- sys/dev/biovar.h 14 Aug 2016 04:08:03 -0000 1.45
+++ sys/dev/biovar.h 7 Jun 2020 11:55:15 -0000
@@ -26,6 +26,9 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef BIOVAR_H
+#define BIOVAR_H
+
 /*
  * Devices getting ioctls through this interface should use ioctl class 'B'
  * and command numbers starting from 32, lower ones are reserved for generic
@@ -305,3 +308,5 @@ void bio_info(struct bio_status *, int,
 void bio_warn(struct bio_status *, int, const char *, ...);
 void bio_error(struct bio_status *, int, const char *, ...);
 #endif
+
+#endif /* BIOVAR_H */
Index: sys/dev/softraid.c
===================================================================
RCS file: /cvs/src/sys/dev/softraid.c,v
retrieving revision 1.401
diff -u -p -r1.401 softraid.c
--- sys/dev/softraid.c 14 Apr 2020 07:38:21 -0000 1.401
+++ sys/dev/softraid.c 7 Jun 2020 11:20:05 -0000
@@ -3704,11 +3704,17 @@ sr_ioctl_installboot(struct sr_softc *sc
  goto done;
  }
 
- if (bb->bb_bootblk_size > SR_BOOT_BLOCKS_SIZE * DEV_BSIZE)
+ if (bb->bb_bootblk_size > SR_BOOT_BLOCKS_SIZE * DEV_BSIZE) {
+ sr_error(sc, "boot block is too large (%d > %d)",
+    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_bootldr_size > SR_BOOT_LOADER_SIZE * DEV_BSIZE) {
+ sr_error(sc, "boot loader is too large (%d > %d)",
+    bb->bb_bootldr_size, SR_BOOT_LOADER_SIZE * DEV_BSIZE);
  goto done;
+ }
 
  secsize = sd->sd_meta->ssdi.ssd_secsize;
 
Index: usr.sbin/installboot/i386_softraid.c
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/i386_softraid.c,v
retrieving revision 1.15
diff -u -p -r1.15 i386_softraid.c
--- usr.sbin/installboot/i386_softraid.c 9 Mar 2020 06:16:56 -0000 1.15
+++ usr.sbin/installboot/i386_softraid.c 7 Jun 2020 12:31:20 -0000
@@ -178,6 +178,7 @@ sr_install_bootldr(int devfd, char *dev)
     "softraid volume\n", dev);
  if (ioctl(devfd, BIOCINSTALLBOOT, &bb) == -1)
  errx(1, "softraid installboot failed");
+ sr_status(&bb.bb_bio.bio_status);
  }
 
  /*
Index: usr.sbin/installboot/installboot.h
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/installboot.h,v
retrieving revision 1.11
diff -u -p -r1.11 installboot.h
--- usr.sbin/installboot/installboot.h 1 Sep 2018 16:55:29 -0000 1.11
+++ usr.sbin/installboot/installboot.h 7 Jun 2020 11:46:52 -0000
@@ -15,6 +15,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <dev/biovar.h>
+
 #include <stdlib.h>
 
 extern int nowrite;
@@ -41,4 +43,5 @@ void md_installboot(int, char *);
 void sr_installboot(int, char *);
 void sr_install_bootblk(int, int, int);
 void sr_install_bootldr(int, char *);
+void sr_status(struct bio_status *);
 #endif
Index: usr.sbin/installboot/softraid.c
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/softraid.c,v
retrieving revision 1.4
diff -u -p -r1.4 softraid.c
--- usr.sbin/installboot/softraid.c 3 Oct 2015 16:56:52 -0000 1.4
+++ usr.sbin/installboot/softraid.c 7 Jun 2020 13:04:24 -0000
@@ -92,3 +92,19 @@ sr_volume(int devfd, char *dev, int *vol
 
  return 1;
 }
+
+void
+sr_status(struct bio_status *bs)
+{
+ int i;
+
+ for (i = 0; i < bs->bs_msg_count; i++)
+ warnx("%s", bs->bs_msgs[i].bm_msg);
+
+ if (bs->bs_status == BIO_STATUS_ERROR) {
+ if (bs->bs_msg_count == 0)
+ errx(1, "unknown error");
+ else
+ exit(1);
+ }
+}
Index: usr.sbin/installboot/sparc64_softraid.c
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/sparc64_softraid.c,v
retrieving revision 1.4
diff -u -p -r1.4 sparc64_softraid.c
--- usr.sbin/installboot/sparc64_softraid.c 28 Jun 2019 13:32:48 -0000 1.4
+++ usr.sbin/installboot/sparc64_softraid.c 7 Jun 2020 12:31:18 -0000
@@ -97,5 +97,6 @@ sr_install_bootldr(int devfd, char *dev)
     "softraid volume\n", dev);
  if (ioctl(devfd, BIOCINSTALLBOOT, &bb) == -1)
  errx(1, "softraid installboot failed");
+ sr_status(&bb.bb_bio.bio_status);
  }
 }

Reply | Threaded
Open this post in threaded view
|

Re: BIOCINSTALLBOOT/sparc64 installboot: EFBIG on too big boot loaders

Klemens Nanni-2
On Sun, Jun 07, 2020 at 03:24:30PM +0200, Klemens Nanni wrote:

> On Sun, Jun 07, 2020 at 12:42:57AM +1000, Joel Sing wrote:
> > While this works, you would be better off making use of the error
> > reporting mechanism that exists. A compile tested only diff for
> > the kernel side is below. A diff to installboot would be needed to
> > graft some code similar to that in bioctl's bio_status() function.
> Thanks, I didn't even look how bioctl(8) does it; that seems better.
>
> The complete diff for softraid(4), <dev/biovar.h> and installboot(8)
> makes sparc64 look like this:
>
> # ./obj/installboot -v sd2 /usr/mdec/bootblk /ofwboot.big
> Using / as root
> installing bootstrap on /dev/rsd2c
> using first-stage /usr/mdec/bootblk, second-stage /ofwboot.big
> 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: boot loader too large (272452 > 163840)
> # echo $?
> 1
>
> I ommitted "is" from the kernel message to stay in line with other
> "too large" ones in softraid.c.
>
> Contrary to bioctl's bio_status(), installboot's new sr_status() uses
> warnx(3) for simplicity and put warnings on stderr (where they belong).
>
> Feedback? OK?
Updated diff after the biovar.h commit.


Index: sys/dev/softraid.c
===================================================================
RCS file: /cvs/src/sys/dev/softraid.c,v
retrieving revision 1.401
diff -u -p -r1.401 softraid.c
--- sys/dev/softraid.c 14 Apr 2020 07:38:21 -0000 1.401
+++ sys/dev/softraid.c 7 Jun 2020 11:20:05 -0000
@@ -3704,11 +3704,17 @@ sr_ioctl_installboot(struct sr_softc *sc
  goto done;
  }
 
- if (bb->bb_bootblk_size > SR_BOOT_BLOCKS_SIZE * DEV_BSIZE)
+ if (bb->bb_bootblk_size > SR_BOOT_BLOCKS_SIZE * DEV_BSIZE) {
+ sr_error(sc, "boot block is too large (%d > %d)",
+    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_bootldr_size > SR_BOOT_LOADER_SIZE * DEV_BSIZE) {
+ sr_error(sc, "boot loader is too large (%d > %d)",
+    bb->bb_bootldr_size, SR_BOOT_LOADER_SIZE * DEV_BSIZE);
  goto done;
+ }
 
  secsize = sd->sd_meta->ssdi.ssd_secsize;
 
Index: usr.sbin/installboot/i386_softraid.c
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/i386_softraid.c,v
retrieving revision 1.15
diff -u -p -r1.15 i386_softraid.c
--- usr.sbin/installboot/i386_softraid.c 9 Mar 2020 06:16:56 -0000 1.15
+++ usr.sbin/installboot/i386_softraid.c 7 Jun 2020 12:31:20 -0000
@@ -178,6 +178,7 @@ sr_install_bootldr(int devfd, char *dev)
     "softraid volume\n", dev);
  if (ioctl(devfd, BIOCINSTALLBOOT, &bb) == -1)
  errx(1, "softraid installboot failed");
+ sr_status(&bb.bb_bio.bio_status);
  }
 
  /*
Index: usr.sbin/installboot/installboot.h
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/installboot.h,v
retrieving revision 1.11
diff -u -p -r1.11 installboot.h
--- usr.sbin/installboot/installboot.h 1 Sep 2018 16:55:29 -0000 1.11
+++ usr.sbin/installboot/installboot.h 7 Jun 2020 11:46:52 -0000
@@ -15,6 +15,8 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <dev/biovar.h>
+
 #include <stdlib.h>
 
 extern int nowrite;
@@ -41,4 +43,5 @@ void md_installboot(int, char *);
 void sr_installboot(int, char *);
 void sr_install_bootblk(int, int, int);
 void sr_install_bootldr(int, char *);
+void sr_status(struct bio_status *);
 #endif
Index: usr.sbin/installboot/softraid.c
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/softraid.c,v
retrieving revision 1.4
diff -u -p -r1.4 softraid.c
--- usr.sbin/installboot/softraid.c 3 Oct 2015 16:56:52 -0000 1.4
+++ usr.sbin/installboot/softraid.c 7 Jun 2020 13:04:24 -0000
@@ -92,3 +92,19 @@ sr_volume(int devfd, char *dev, int *vol
 
  return 1;
 }
+
+void
+sr_status(struct bio_status *bs)
+{
+ int i;
+
+ for (i = 0; i < bs->bs_msg_count; i++)
+ warnx("%s", bs->bs_msgs[i].bm_msg);
+
+ if (bs->bs_status == BIO_STATUS_ERROR) {
+ if (bs->bs_msg_count == 0)
+ errx(1, "unknown error");
+ else
+ exit(1);
+ }
+}
Index: usr.sbin/installboot/sparc64_softraid.c
===================================================================
RCS file: /cvs/src/usr.sbin/installboot/sparc64_softraid.c,v
retrieving revision 1.4
diff -u -p -r1.4 sparc64_softraid.c
--- usr.sbin/installboot/sparc64_softraid.c 28 Jun 2019 13:32:48 -0000 1.4
+++ usr.sbin/installboot/sparc64_softraid.c 7 Jun 2020 12:31:18 -0000
@@ -97,5 +97,6 @@ sr_install_bootldr(int devfd, char *dev)
     "softraid volume\n", dev);
  if (ioctl(devfd, BIOCINSTALLBOOT, &bb) == -1)
  errx(1, "softraid installboot failed");
+ sr_status(&bb.bb_bio.bio_status);
  }
 }