diff options
| author | oster <oster@NetBSD.org> | 2004-11-16 16:45:51 +0000 |
|---|---|---|
| committer | oster <oster@NetBSD.org> | 2004-11-16 16:45:51 +0000 |
| commit | d7e754c41da2eeab50196f671b81a1704c3d5f76 (patch) | |
| tree | 2d6c6ada2965e2384f18c6325a87e90e96242d0f /sys/dev/raidframe | |
| parent | 297b6b1873abca623e18eb7abe790925ac90712a (diff) | |
On an idea from Thor (tls@), do not fail a component if doing so would
render the RAID set completely dead. Instead, we retry the IO a
maximum of RF_RETRY_THRESHOLD times (currently '5'), and then just
return an IO error if the IO fails. This should reduce the damage
caused by having multiple disks appear to fail when the culprit is
really something else (power, controllers, etc.)
Diffstat (limited to 'sys/dev/raidframe')
| -rw-r--r-- | sys/dev/raidframe/rf_desc.h | 3 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_driver.c | 5 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_driver.h | 6 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_netbsdkintf.c | 11 | ||||
| -rw-r--r-- | sys/dev/raidframe/rf_states.c | 24 |
5 files changed, 35 insertions, 14 deletions
diff --git a/sys/dev/raidframe/rf_desc.h b/sys/dev/raidframe/rf_desc.h index 99cbd6b9427..c9450cd38b7 100644 --- a/sys/dev/raidframe/rf_desc.h +++ b/sys/dev/raidframe/rf_desc.h @@ -1,4 +1,4 @@ -/* $NetBSD: rf_desc.h,v 1.14 2004/06/02 22:58:28 drochner Exp $ */ +/* $NetBSD: rf_desc.h,v 1.15 2004/11/16 16:45:51 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -78,6 +78,7 @@ struct RF_RaidAccessDesc_s { * RAID operation has gotten */ const RF_AccessState_t *states; /* array of states to be run */ int status; /* pass/fail status of the last operation */ + int numRetries; /* number of times this IO has been attempted */ RF_DagList_t *dagList; /* list of dag lists, one list per stripe */ RF_VoidPointerListElem_t *iobufs; /* iobufs that need to be cleaned up at the end of this IO */ diff --git a/sys/dev/raidframe/rf_driver.c b/sys/dev/raidframe/rf_driver.c index 1df8daf0442..81b7f090cd2 100644 --- a/sys/dev/raidframe/rf_driver.c +++ b/sys/dev/raidframe/rf_driver.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_driver.c,v 1.104 2004/06/29 17:09:01 oster Exp $ */ +/* $NetBSD: rf_driver.c,v 1.105 2004/11/16 16:45:51 oster Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. * All rights reserved. @@ -73,7 +73,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.104 2004/06/29 17:09:01 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.105 2004/11/16 16:45:51 oster Exp $"); #include "opt_raid_diagnostic.h" @@ -573,6 +573,7 @@ rf_AllocRaidAccDesc(RF_Raid_t *raidPtr, RF_IoType_t type, desc->dagList = NULL; desc->status = 0; + desc->numRetries = 0; #if RF_ACC_TRACE > 0 memset((char *) &desc->tracerec, 0, sizeof(RF_AccTraceEntry_t)); #endif diff --git a/sys/dev/raidframe/rf_driver.h b/sys/dev/raidframe/rf_driver.h index 293cf6589c3..4a4464d7848 100644 --- a/sys/dev/raidframe/rf_driver.h +++ b/sys/dev/raidframe/rf_driver.h @@ -1,4 +1,4 @@ -/* $NetBSD: rf_driver.h,v 1.12 2004/06/02 22:58:30 drochner Exp $ */ +/* $NetBSD: rf_driver.h,v 1.13 2004/11/16 16:45:52 oster Exp $ */ /* * rf_driver.h */ @@ -37,6 +37,10 @@ #include "rf_threadstuff.h" #include "rf_netbsd.h" +#ifndef RF_RETRY_THRESHOLD +#define RF_RETRY_THRESHOLD 5 +#endif + RF_DECLARE_EXTERN_MUTEX(rf_printf_mutex) int rf_BootRaidframe(void); int rf_UnbootRaidframe(void); diff --git a/sys/dev/raidframe/rf_netbsdkintf.c b/sys/dev/raidframe/rf_netbsdkintf.c index d0cdb194dd9..39c329d48dd 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.182 2004/10/28 07:07:44 yamt Exp $ */ +/* $NetBSD: rf_netbsdkintf.c,v 1.183 2004/11/16 16:45:51 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.182 2004/10/28 07:07:44 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.183 2004/11/16 16:45:51 oster Exp $"); #include <sys/param.h> #include <sys/errno.h> @@ -1947,8 +1947,11 @@ KernelWakeupFunc(struct buf *vbp) if (bp->b_flags & B_ERROR) { /* Mark the disk as dead */ /* but only mark it once... */ - if (queue->raidPtr->Disks[queue->col].status == - rf_ds_optimal) { + /* and only if it wouldn't leave this RAID set + completely broken */ + if ((queue->raidPtr->Disks[queue->col].status == + rf_ds_optimal) && (queue->raidPtr->numFailures < + queue->raidPtr->Layout.map->faultsTolerated)) { printf("raid%d: IO Error. Marking %s as failed.\n", queue->raidPtr->raidid, queue->raidPtr->Disks[queue->col].devname); diff --git a/sys/dev/raidframe/rf_states.c b/sys/dev/raidframe/rf_states.c index 677776dd050..620d3959e64 100644 --- a/sys/dev/raidframe/rf_states.c +++ b/sys/dev/raidframe/rf_states.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_states.c,v 1.35 2004/03/23 13:09:18 oster Exp $ */ +/* $NetBSD: rf_states.c,v 1.36 2004/11/16 16:45:52 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.35 2004/03/23 13:09:18 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.36 2004/11/16 16:45:52 oster Exp $"); #include <sys/errno.h> @@ -512,13 +512,18 @@ rf_State_CreateDAG(RF_RaidAccessDesc_t *desc) desc->status = 0; /* good status */ - if (selectStatus) { + if (selectStatus || (desc->numRetries > RF_RETRY_THRESHOLD)) { /* failed to create a dag */ /* this happens when there are too many faults or incomplete * dag libraries */ - printf("raid%d: failed to create a dag. " - "Too many component failures.\n", - desc->raidPtr->raidid); + if (selectStatus) { + printf("raid%d: failed to create a dag. " + "Too many component failures.\n", + desc->raidPtr->raidid); + } else { + printf("raid%d: IO failed after %d retries.\n", + desc->raidPtr->raidid, RF_RETRY_THRESHOLD); + } desc->status = 1; /* bad status */ /* skip straight to rf_State_Cleanup() */ @@ -624,6 +629,13 @@ rf_State_ProcessDAG(RF_RaidAccessDesc_t *desc) rf_FreeDAGList(temp); } rf_MarkFailuresInASMList(raidPtr, asmh); + + /* note the retry so that we'll bail in + rf_State_CreateDAG() once we've retired + the IO RF_RETRY_THRESHOLD times */ + + desc->numRetries++; + /* back up to rf_State_CreateDAG */ desc->state = desc->state - 2; return RF_FALSE; |
