On a T4-2 with hardware RAID using the internal controller, booting from
logical volumes requires a bootpath as follows[0]:

        /pci@400/pci@2/pci@0/pci@e/scsi@0/disk@w3aa32290d5dcd16c,0:a

This is how I currently boot the machine:

        {0} ok nvalias raid /pci@400/...
        {0} boot raid

Our kernel parses the entire bootpath into its own structure in
bootpath_build() and resembles it later on in bootpath_print().  With
above string from firmware, this results in

        ...
        softraid0 at root
        scsibus5 at softraid0: 256 targets
        bootpath: 
/pci@400,0/pci@2,0/pci@0,0/pci@e,0/scsi@0,0/disk@3aa32290d5dcd16c,0
        root device:

Note how for each path element it prints the optional values even though
they did not occur in the original bootpath;  ":a" is missing also.


Diff below makes the code clearer with regard to optional values stored
in the bootpath structure's val[] member and fixes it to print ":a"
values such as mine.

":a" corresponding to val[2] = 0 wouldn't be printed as val[] is zero
initialised and our parsing code turns 'a' into 0 which leaves the
printing code unable to differentiate between default and actual value.

So, since val[] is only ever filled with hexadecimal values, initialise
it to -1 as clear indicator.

As val[1] and/or val[2] being set implies val[0] being set, reflect this
in the printing code and print optional values only if set.

This yields the following bootpath:

        bootpath: /pci@400/pci@2/pci@0/pci@e/scsi@0/disk@3aa32290d5dcd16c,0:a

Note how it is now identical to the original one, except for the omitted
"w" between "disk@" and the volume's WWID (another particularity).


Feedback? OK?

NB: I think the existing code is incorrect for bootpaths _not_ containing
any "@": bootpath_build() won't either val[1] or val[2] but set only set
val[0] to -1;  in bootpath_print() if val[0] is -1 val[1] is used but
will always be zero (due to bp being bzero()'ed).  This is covered in my
diff and cannot happen.

0: https://jp.fujitsu.com/platform/server/sparc/manual/en/c120-e679/14.2.12.html


Index: sparc64/autoconf.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/sparc64/autoconf.c,v
retrieving revision 1.133
diff -u -p -r1.133 autoconf.c
--- sparc64/autoconf.c  15 Oct 2019 05:21:16 -0000      1.133
+++ sparc64/autoconf.c  25 Dec 2019 21:51:48 -0000
@@ -513,6 +513,11 @@ bootpath_build(void)
                while (*cp != '@' && *cp != '/' && *cp != '\0')
                        *pp++ = *cp++;
                *pp = '\0';
+               /*
+                * Indicate the absence of optional values by initializing val[]
+                * to -1 as 0 might be a legit value.
+                */
+               bp->val[0] = bp->val[1] = bp->val[2] = -1;
                if (*cp == '@') {
                        cp = str2hex(++cp, &bp->val[0]);
                        if (*cp == ',')
@@ -529,9 +534,6 @@ bootpath_build(void)
                                while (*cp != '\0' && *cp != '/')
                                        cp++;
                        }
-               } else {
-                       bp->val[0] = -1; /* no #'s: assume unit 0, no
-                                           sbus offset/address */
                }
                ++bp;
                ++nbootpath;
@@ -606,12 +608,14 @@ bootpath_print(struct bootpath *bp)
 {
        printf("bootpath: ");
        while (bp->name[0]) {
-               if (bp->val[0] == -1)
-                       printf("/%s%lx", bp->name, bp->val[1]);
-               else
-                       printf("/%s@%lx,%lx", bp->name, bp->val[0], bp->val[1]);
-               if (bp->val[2] != 0)
-                       printf(":%c", (int)bp->val[2] + 'a');
+               printf("/%s", bp->name);
+               if (bp->val[0] != -1) {
+                       printf("@%lx", bp->val[0]);
+                       if (bp->val[1] != -1)
+                               printf(",%lx", bp->val[1]);
+                       if (bp->val[2] != -1)
+                               printf(":%c", (int)bp->val[2] + 'a');
+               }
                bp++;
        }
        printf("\n");

Reply via email to