From 24b034a69eb7d3758db4989542ef719badb97a5a Mon Sep 17 00:00:00 2001 From: oster Date: Fri, 2 Jan 2004 21:41:08 +0000 Subject: Fix the "We panic if we can't create a DAG" problem that's existed ~forever. This requires a number of things: 1) If we can't create a DAG, set desc->numStripes to 0 in rf_SelectAlgorithm. This will ensure that we don't attempt to free any dagArray[] elements in rf_StateCleanup. 2) Modify rf_State_CreateDAG() to not panic in the event of a DAG failure. Instead, set the bp->b_flags and bp->b_error, and set things up to skip to rf_State_Cleanup(). 3) Need to mark desc->status as "bad" so that we actually stop looking for a different DAG. (which we won't find... no matter how many times we try). 4) rf_State_LastState() will then do the biodone(), and return EIO for the IO in question. 5) Remove some " || 1 "'s from ProcessNode(). These were for debugging, and we don't need the failure notices spewing over and over again as the failing DAGs are processed. 6) Needed to change if (asmap->numDataFailed + asmap->numParityFailed > 1) to if ((asmap->numDataFailed + asmap->numParityFailed > 1) || (raidPtr->numFailures > 1)){ in rf_raid5.c so that it doesn't try to return rf_CreateNonRedundantWriteDAG as the creation function. 7) Note that we can't apply the above change to the RAID 1 code as with the silly "fake 2-D" RAID 1 sets, it is possible to have 2 failed components in the RAID 1 set, and that would stop them from working. (I really don't know why/how those "fake 2-D" RAID 1 sets even work with all the "single-fault" assumptions present in the rest of the code.) 8) Needed to protect rf_RAID0DagSelect() in a similar way -- it should return NULL as the createFunc. 9) No point printing out "Multiple disks failed..." a zillion times. --- sys/dev/raidframe/rf_aselect.c | 5 +++-- sys/dev/raidframe/rf_engine.c | 8 ++++---- sys/dev/raidframe/rf_raid0.c | 8 ++++++-- sys/dev/raidframe/rf_raid1.c | 7 ++++--- sys/dev/raidframe/rf_raid5.c | 10 ++++++---- sys/dev/raidframe/rf_states.c | 25 ++++++++++++++++++------- 6 files changed, 41 insertions(+), 22 deletions(-) (limited to 'sys/dev/raidframe') diff --git a/sys/dev/raidframe/rf_aselect.c b/sys/dev/raidframe/rf_aselect.c index 358731c6955..cb44df9b1aa 100644 --- a/sys/dev/raidframe/rf_aselect.c +++ b/sys/dev/raidframe/rf_aselect.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_aselect.c,v 1.10 2003/12/30 21:59:03 oster Exp $ */ +/* $NetBSD: rf_aselect.c,v 1.11 2004/01/02 21:41:08 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -33,7 +33,7 @@ *****************************************************************************/ #include -__KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.10 2003/12/30 21:59:03 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_aselect.c,v 1.11 2004/01/02 21:41:08 oster Exp $"); #include @@ -266,6 +266,7 @@ rf_SelectAlgorithm(RF_RaidAccessDesc_t *desc, RF_RaidAccessFlags_t flags) RF_Free(stripeUnitFuncs, asm_h->numStripes * sizeof(RF_VoidFuncPtr)); RF_Free(asmh_u, asm_h->numStripes * sizeof(RF_AccessStripeMapHeader_t **)); } + desc->numStripes = 0; return (1); } else { /* begin dag creation */ diff --git a/sys/dev/raidframe/rf_engine.c b/sys/dev/raidframe/rf_engine.c index 1177234f204..619981e6162 100644 --- a/sys/dev/raidframe/rf_engine.c +++ b/sys/dev/raidframe/rf_engine.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_engine.c,v 1.30 2004/01/01 19:27:36 oster Exp $ */ +/* $NetBSD: rf_engine.c,v 1.31 2004/01/02 21:41:08 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -55,7 +55,7 @@ ****************************************************************************/ #include -__KERNEL_RCSID(0, "$NetBSD: rf_engine.c,v 1.30 2004/01/01 19:27:36 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_engine.c,v 1.31 2004/01/02 21:41:08 oster Exp $"); #include @@ -624,13 +624,13 @@ ProcessNode(RF_DagNode_t *node, int context) (node->dagHdr->numCommitNodes == 0)) { /* crossed commit barrier */ node->dagHdr->status = rf_rollForward; - if (rf_engineDebug || 1) { + if (rf_engineDebug) { printf("raid%d: node (%s) returned fail, rolling forward\n", raidPtr->raidid, node->name); } } else { /* never reached commit barrier */ node->dagHdr->status = rf_rollBackward; - if (rf_engineDebug || 1) { + if (rf_engineDebug) { printf("raid%d: node (%s) returned fail, rolling backward\n", raidPtr->raidid, node->name); } } diff --git a/sys/dev/raidframe/rf_raid0.c b/sys/dev/raidframe/rf_raid0.c index e6358e8f2b1..1914186bd62 100644 --- a/sys/dev/raidframe/rf_raid0.c +++ b/sys/dev/raidframe/rf_raid0.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_raid0.c,v 1.9 2003/12/30 21:59:03 oster Exp $ */ +/* $NetBSD: rf_raid0.c,v 1.10 2004/01/02 21:41:08 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -33,7 +33,7 @@ ***************************************/ #include -__KERNEL_RCSID(0, "$NetBSD: rf_raid0.c,v 1.9 2003/12/30 21:59:03 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_raid0.c,v 1.10 2004/01/02 21:41:08 oster Exp $"); #include @@ -123,6 +123,10 @@ rf_RAID0DagSelect( RF_AccessStripeMap_t * asmap, RF_VoidFuncPtr * createFunc) { + if (raidPtr->numFailures > 0) { + *createFunc = NULL; + return; + } *createFunc = ((type == RF_IO_TYPE_READ) ? (RF_VoidFuncPtr) rf_CreateFaultFreeReadDAG : (RF_VoidFuncPtr) rf_CreateRAID0WriteDAG); } diff --git a/sys/dev/raidframe/rf_raid1.c b/sys/dev/raidframe/rf_raid1.c index da934f4380d..f6cef9d4259 100644 --- a/sys/dev/raidframe/rf_raid1.c +++ b/sys/dev/raidframe/rf_raid1.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_raid1.c,v 1.15 2003/12/30 21:59:03 oster Exp $ */ +/* $NetBSD: rf_raid1.c,v 1.16 2004/01/02 21:41:08 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -33,7 +33,7 @@ *****************************************************************************/ #include -__KERNEL_RCSID(0, "$NetBSD: rf_raid1.c,v 1.15 2003/12/30 21:59:03 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_raid1.c,v 1.16 2004/01/02 21:41:08 oster Exp $"); #include "rf_raid.h" #include "rf_raid1.h" @@ -178,7 +178,8 @@ rf_RAID1DagSelect(RF_Raid_t *raidPtr, RF_IoType_t type, RF_ASSERT(RF_IO_IS_R_OR_W(type)); if (asmap->numDataFailed + asmap->numParityFailed > 1) { - RF_ERRORMSG("Multiple disks failed in a single group! Aborting I/O operation.\n"); + if (rf_dagDebug) + RF_ERRORMSG("Multiple disks failed in a single group! Aborting I/O operation.\n"); *createFunc = NULL; return; } diff --git a/sys/dev/raidframe/rf_raid5.c b/sys/dev/raidframe/rf_raid5.c index 0541e09758a..1c61f83c59e 100644 --- a/sys/dev/raidframe/rf_raid5.c +++ b/sys/dev/raidframe/rf_raid5.c @@ -1,4 +1,4 @@ -/* $NetBSD: rf_raid5.c,v 1.10 2003/12/30 21:59:03 oster Exp $ */ +/* $NetBSD: rf_raid5.c,v 1.11 2004/01/02 21:41:08 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -33,7 +33,7 @@ *****************************************************************************/ #include -__KERNEL_RCSID(0, "$NetBSD: rf_raid5.c,v 1.10 2003/12/30 21:59:03 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_raid5.c,v 1.11 2004/01/02 21:41:08 oster Exp $"); #include @@ -169,8 +169,10 @@ rf_RaidFiveDagSelect(RF_Raid_t *raidPtr, RF_IoType_t type, RF_ASSERT(RF_IO_IS_R_OR_W(type)); - if (asmap->numDataFailed + asmap->numParityFailed > 1) { - RF_ERRORMSG("Multiple disks failed in a single group! Aborting I/O operation.\n"); + if ((asmap->numDataFailed + asmap->numParityFailed > 1) || + (raidPtr->numFailures > 1)){ + if (rf_dagDebug) + RF_ERRORMSG("Multiple disks failed in a single group! Aborting I/O operation.\n"); *createFunc = NULL; return; } else diff --git a/sys/dev/raidframe/rf_states.c b/sys/dev/raidframe/rf_states.c index 2792995fbad..108711c57b4 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.24 2004/01/01 23:35:08 oster Exp $ */ +/* $NetBSD: rf_states.c,v 1.25 2004/01/02 21:41:08 oster Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -27,7 +27,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.24 2004/01/01 23:35:08 oster Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rf_states.c,v 1.25 2004/01/02 21:41:08 oster Exp $"); #include @@ -189,13 +189,15 @@ rf_ContinueDagAccess(RF_DagList_t *dagList) * all other dags in the desc to execute to * completion. then, free all dags and start over */ desc->status = 1; /* bad status */ - - printf("raid%d: DAG failure: %c addr 0x%lx (%ld) nblk 0x%x (%d) buf 0x%lx\n", +#if 0 + printf("raid%d: DAG failure: %c addr 0x%lx " + "(%ld) nblk 0x%x (%d) buf 0x%lx state %d\n", desc->raidPtr->raidid, desc->type, (long) desc->raidAddress, (long) desc->raidAddress, (int) desc->numBlocks, (int) desc->numBlocks, - (unsigned long) (desc->bufPtr)); + (unsigned long) (desc->bufPtr), desc->state); +#endif } dagList->numDagsDone++; rf_ContinueRaidAccess(desc); @@ -438,6 +440,7 @@ rf_State_CreateDAG(RF_RaidAccessDesc_t *desc) RF_AccTraceEntry_t *tracerec = &desc->tracerec; RF_Etimer_t timer; RF_DagHeader_t *dag_h; + struct buf *bp; int i, selectStatus; /* generate a dag for the access, and fire it off. When the dag @@ -461,8 +464,16 @@ rf_State_CreateDAG(RF_RaidAccessDesc_t *desc) /* failed to create a dag */ /* this happens when there are too many faults or incomplete * dag libraries */ - printf("[Failed to create a DAG]\n"); - RF_PANIC(); + printf("raid%d: failed to create a dag. " + "Too many component failures.\n", + desc->raidPtr->raidid); + + desc->status = 1; /* bad status */ + /* skip straight to rf_State_Cleanup() */ + desc->state = rf_CleanupState; + bp = (struct buf *)desc->bp; + bp->b_flags |= B_ERROR; + bp->b_error = EIO; } else { /* bind dags to desc */ for (i = 0; i < desc->numStripes; i++) { -- cgit