Hardware RAID volume bootpaths are similar to Fibre channel ones in that they use the disk's WWID (lower 16 bit only) as SCSI target, e.g.
/pci@400/pci@2/pci@0/pci@e/scsi@0/disk@w3aa32290d5dcd16c,0:a Currently device_register() does recognise devices with their WWN as target but only continues to nail_bootdev() them if their lun and port match as well. Diff below makes device_register() look at the bootpath's partition and --in lack of a better criterium-- the device name as well to test for hardware RAIDs. But to be able to match the partition, partition index calculation must be deferred from bootpath_build() to diskconf() so it becomes possible to check whether partition "a" (index 0) has been specified in the bootpath - this is currently not possible because the partition gets turned into an index right away which makes it indistinguishable from val[2]'s default initialised value. As a bonus, this now makes also makes the kernel print back the bootpath correctly with regard to "a" partitions: bootpath: /pci@400,0/pci@2,0/pci@0,0/pci@e,0/scsi@0,0/disk@3aa32290d5dcd16c,0:a root on sd0a (5eb46f4312eeecb7.a) swap on sd0b dump on sd0b Is there a better way to detect hardware RAIDs as such? 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 26 Dec 2019 05:56:20 -0000 @@ -525,7 +525,7 @@ bootpath_build(void) * be an ethernet media specification, so be * sure to skip all letters. */ - bp->val[2] = *++cp - 'a'; + bp->val[2] = *++cp; while (*cp != '\0' && *cp != '/') cp++; } @@ -611,7 +611,7 @@ bootpath_print(struct bootpath *bp) 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(":%c", (int)bp->val[2]); bp++; } printf("\n"); @@ -813,7 +813,7 @@ diskconf(void) bootdv = mpath_bootdv(bootdv); #endif - setroot(bootdv, bp->val[2], RB_USERREQ | RB_HALT); + setroot(bootdv, bp->val[2] - 'a', RB_USERREQ | RB_HALT); dumpconf(); } @@ -1453,7 +1453,9 @@ device_register(struct device *dev, void (struct scsibus_softc *)dev->dv_parent; u_int target = bp->val[0]; u_int lun = bp->val[1]; + int partition = bp->val[2]; + /* Is target a full WWN/WWID? */ if (bp->val[0] & 0xffffffff00000000 && bp->val[0] != -1) { /* Fibre channel? */ if (bp->val[0] == sl->port_wwn && lun == sl->lun) { @@ -1468,6 +1470,12 @@ device_register(struct device *dev, void sl->id->d_type == DEVID_NAA && memcmp(sl->id + 1, &bp->val[0], 8) == 0) nail_bootdev(dev, bp); + + /* Hardware RAID? */ + /* XXX: how to detect properly? */ + if (strcmp(devname, "sd") == 0 && partition != 0) { + nail_bootdev(dev, bp); + } return; }