> Date: Thu, 26 Dec 2019 07:38:47 +0100 > From: Klemens Nanni <k...@openbsd.org> > > 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;
What happens if the bootpath doesn't specify a partition? Currently we end up with bp->val[2] being zero in that case, which means we end up booting from 'a' which is the default partition. So I think you need to check for that case when you call setroot(). However, that means the partition != 0 check is probably meaningless... Also note that booting by WWWN isn't just for fibre-channel and hardware RAID. It works for single disks as well on some controllers. Why does matching the LUN fail? If I read the code correctly, you'll end up with bp->val[1] = 0. What is the value of sl->lun?