diff options
| author | oster <oster@NetBSD.org> | 2007-10-05 01:40:04 +0000 |
|---|---|---|
| committer | oster <oster@NetBSD.org> | 2007-10-05 01:40:04 +0000 |
| commit | 8b11ddb95cea0e8ab747ebc691147917518fd397 (patch) | |
| tree | ee259eff33c2aa711cb0256d1ef1130f6673694b /sys/dev/raidframe | |
| parent | c8c5d830fc5256ab2b431d09efaa9b4711bc0c63 (diff) | |
Implement dumping kernel cores to RAID 1 sets. The component used
for the dump is selected in this order of preference:
1) the master
2) a used_spare of the master
3) the slave
4) a used_spare of the slave
Diffstat (limited to 'sys/dev/raidframe')
| -rw-r--r-- | sys/dev/raidframe/rf_netbsdkintf.c | 142 |
1 files changed, 136 insertions, 6 deletions
diff --git a/sys/dev/raidframe/rf_netbsdkintf.c b/sys/dev/raidframe/rf_netbsdkintf.c index 6c0362cd6e9..d86c73d50f3 100644 --- a/sys/dev/raidframe/rf_netbsdkintf.c +++ b/sys/dev/raidframe/rf_netbsdkintf.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_netbsdkintf.c,v 1.230 2007/07/29 12:50:22 ad Exp $ */ +/* $NetBSD: rf_netbsdkintf.c,v 1.231 2007/10/05 01:40:04 oster Exp $ */ /*- * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. * All rights reserved. @@ -146,7 +146,7 @@ ***********************************************************/ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.230 2007/07/29 12:50:22 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.231 2007/10/05 01:40:04 oster Exp $"); #include <sys/param.h> #include <sys/errno.h> @@ -584,11 +584,141 @@ raidsize(dev_t dev) } int -raiddump(dev_t dev, daddr_t blkno, void *va, - size_t size) +raiddump(dev_t dev, daddr_t blkno, void *va, size_t size) { - /* Not implemented. */ - return ENXIO; + int unit = raidunit(dev); + struct raid_softc *rs; + const struct bdevsw *bdev; + struct disklabel *lp; + RF_Raid_t *raidPtr; + daddr_t offset; + int part, c, sparecol, j, scol, dumpto; + int error = 0; + + if (unit >= numraid) + return (ENXIO); + + rs = &raid_softc[unit]; + raidPtr = raidPtrs[unit]; + + if ((rs->sc_flags & RAIDF_INITED) == 0) + return ENXIO; + + /* we only support dumping to RAID 1 sets */ + if (raidPtr->Layout.numDataCol != 1 || + raidPtr->Layout.numParityCol != 1) + return EINVAL; + + + if ((error = raidlock(rs)) != 0) + return error; + + if (size % DEV_BSIZE != 0) { + error = EINVAL; + goto out; + } + + if (blkno + size / DEV_BSIZE > rs->sc_size) { + printf("%s: blkno (%" PRIu64 ") + size / DEV_BSIZE (%zu) > " + "sc->sc_size (%" PRIu64 ")\n", __func__, blkno, + size / DEV_BSIZE, rs->sc_size); + error = EINVAL; + goto out; + } + + part = DISKPART(dev); + lp = rs->sc_dkdev.dk_label; + offset = lp->d_partitions[part].p_offset + RF_PROTECTED_SECTORS; + + /* figure out what device is alive.. */ + + /* + Look for a component to dump to. The preference for the + component to dump to is as follows: + 1) the master + 2) a used_spare of the master + 3) the slave + 4) a used_spare of the slave + */ + + dumpto = -1; + for (c = 0; c < raidPtr->numCol; c++) { + if (raidPtr->Disks[c].status == rf_ds_optimal) { + /* this might be the one */ + dumpto = c; + break; + } + } + + /* + At this point we have possibly selected a live master or a + live slave. We now check to see if there is a spared + master (or a spared slave), if we didn't find a live master + or a live slave. + */ + + for (c = 0; c < raidPtr->numSpare; c++) { + sparecol = raidPtr->numCol + c; + if (raidPtr->Disks[sparecol].status == rf_ds_used_spare) { + /* How about this one? */ + scol = -1; + for(j=0;j<raidPtr->numCol;j++) { + if (raidPtr->Disks[j].spareCol == sparecol) { + scol = j; + break; + } + } + if (scol == 0) { + /* + We must have found a spared master! + We'll take that over anything else + found so far. (We couldn't have + found a real master before, since + this is a used spare, and it's + saying that it's replacing the + master.) On reboot (with + autoconfiguration turned on) + sparecol will become the 1st + component (component0) of this set. + */ + dumpto = sparecol; + break; + } else if (scol != -1) { + /* + Must be a spared slave. We'll dump + to that if we havn't found anything + else so far. + */ + if (dumpto == -1) + dumpto = sparecol; + } + } + } + + if (dumpto == -1) { + /* we couldn't find any live components to dump to!?!? + */ + error = EINVAL; + goto out; + } + + bdev = bdevsw_lookup(raidPtr->Disks[dumpto].dev); + + /* + Note that blkno is relative to this particular partition. + By adding the offset of this partition in the RAID + set, and also adding RF_PROTECTED_SECTORS, we get a + value that is relative to the partition used for the + underlying component. + */ + + error = (*bdev->d_dump)(raidPtr->Disks[dumpto].dev, + blkno + offset, va, size); + +out: + raidunlock(rs); + + return error; } /* ARGSUSED */ int |
