summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Galbavy <peter@cvs.openbsd.org>2000-08-08 16:07:46 +0000
committerPeter Galbavy <peter@cvs.openbsd.org>2000-08-08 16:07:46 +0000
commit32fe17a663470bcff500ec1d022251eb5521ca1d (patch)
treea9d50274c1f5d004d13fa30644899af9b22328ee
parentba14061bb6dd00dd21fcd589dca3d5be75d8f752 (diff)
sync RAIDframe with Gre Oster's work for NetBSD.
This update incorporates changes since January 2000. RAID1 and RAID5 tested for functionality matching the 2.7 code. A number of bug fixes (including stopping a parity rebuild when unconfiguring) have been included. See Greg's RAIDframe info page: http://www.cs.usask.ca/staff/oster/raid.html The RAID_AUTOCONFIG feature set does *NOT* yet work. These features require more work throughout the boot system and as such are a big task. IMPORTANT: As with anything that is this near live data on your systems, please test carefully with existing configurations before deploying in a live system. Feedback via sendbug or mail direct to peter@wonderland.org is appreciated.
-rw-r--r--sys/dev/raidframe/rf_archs.h8
-rw-r--r--sys/dev/raidframe/rf_copyback.c29
-rw-r--r--sys/dev/raidframe/rf_dagfuncs.c32
-rw-r--r--sys/dev/raidframe/rf_dagfuncs.h11
-rw-r--r--sys/dev/raidframe/rf_decluster.c9
-rw-r--r--sys/dev/raidframe/rf_diskqueue.c131
-rw-r--r--sys/dev/raidframe/rf_diskqueue.h51
-rw-r--r--sys/dev/raidframe/rf_disks.c402
-rw-r--r--sys/dev/raidframe/rf_disks.h55
-rw-r--r--sys/dev/raidframe/rf_driver.c111
-rw-r--r--sys/dev/raidframe/rf_driver.h76
-rw-r--r--sys/dev/raidframe/rf_evenodd_dagfuncs.c14
-rw-r--r--sys/dev/raidframe/rf_fifo.c90
-rw-r--r--sys/dev/raidframe/rf_general.h8
-rw-r--r--sys/dev/raidframe/rf_kintf.h16
-rw-r--r--sys/dev/raidframe/rf_layout.c4
-rw-r--r--sys/dev/raidframe/rf_layout.h6
-rw-r--r--sys/dev/raidframe/rf_map.c5
-rw-r--r--sys/dev/raidframe/rf_netbsd.h58
-rw-r--r--sys/dev/raidframe/rf_netbsdkintf.c1388
-rw-r--r--sys/dev/raidframe/rf_nwayxor.c118
-rw-r--r--sys/dev/raidframe/rf_openbsd.h53
-rw-r--r--sys/dev/raidframe/rf_openbsdkintf.c1433
-rw-r--r--sys/dev/raidframe/rf_paritylogDiskMgr.c139
-rw-r--r--sys/dev/raidframe/rf_paritylogging.c26
-rw-r--r--sys/dev/raidframe/rf_parityscan.c9
-rw-r--r--sys/dev/raidframe/rf_raid.h25
-rw-r--r--sys/dev/raidframe/rf_raidframe.h19
-rw-r--r--sys/dev/raidframe/rf_reconbuffer.c7
-rw-r--r--sys/dev/raidframe/rf_reconstruct.c49
-rw-r--r--sys/dev/raidframe/rf_reconstruct.h6
-rw-r--r--sys/dev/raidframe/rf_revent.c44
-rw-r--r--sys/dev/raidframe/rf_shutdown.c9
-rw-r--r--sys/dev/raidframe/rf_threadstuff.h7
34 files changed, 3399 insertions, 1049 deletions
diff --git a/sys/dev/raidframe/rf_archs.h b/sys/dev/raidframe/rf_archs.h
index 765b577477f..700746d15f0 100644
--- a/sys/dev/raidframe/rf_archs.h
+++ b/sys/dev/raidframe/rf_archs.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_archs.h,v 1.4 2000/01/11 18:02:20 peter Exp $ */
-/* $NetBSD: rf_archs.h,v 1.7 2000/01/08 03:49:37 oster Exp $ */
+/* $OpenBSD: rf_archs.h,v 1.5 2000/08/08 16:07:38 peter Exp $ */
+/* $NetBSD: rf_archs.h,v 1.9 2000/03/04 03:27:13 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -67,10 +67,6 @@
#define RF_MEMORY_REDZONES 0
#define RF_RECON_STATS 1
-#define RF_INCLUDE_QUEUE_RANDOM 0
-
-#define RF_KEEP_DISKSTATS 1
-
#include "rf_options.h"
#endif /* !_RF__RF_ARCHS_H_ */
diff --git a/sys/dev/raidframe/rf_copyback.c b/sys/dev/raidframe/rf_copyback.c
index f0da14587c3..025aaaca293 100644
--- a/sys/dev/raidframe/rf_copyback.c
+++ b/sys/dev/raidframe/rf_copyback.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_copyback.c,v 1.5 2000/01/11 18:02:20 peter Exp $ */
-/* $NetBSD: rf_copyback.c,v 1.12 2000/01/09 01:29:28 oster Exp $ */
+/* $OpenBSD: rf_copyback.c,v 1.6 2000/08/08 16:07:39 peter Exp $ */
+/* $NetBSD: rf_copyback.c,v 1.14 2000/03/07 02:59:50 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -101,6 +101,8 @@ rf_CopybackReconstructedData(raidPtr)
struct vattr va;
struct proc *proc;
+ int ac;
+
done = 0;
fcol = 0;
for (frow = 0; frow < raidPtr->numRow; frow++) {
@@ -129,11 +131,15 @@ rf_CopybackReconstructedData(raidPtr)
if (raidPtr->raid_cinfo[frow][fcol].ci_vp != NULL) {
printf("Closed the open device: %s\n",
raidPtr->Disks[frow][fcol].devname);
- VOP_UNLOCK(raidPtr->raid_cinfo[frow][fcol].ci_vp, 0, proc);
- (void) vn_close(raidPtr->raid_cinfo[frow][fcol].ci_vp,
- FREAD | FWRITE, proc->p_ucred, proc);
+ vp = raidPtr->raid_cinfo[frow][fcol].ci_vp;
+ ac = raidPtr->Disks[frow][fcol].auto_configured;
+ rf_close_component(raidPtr, vp, ac);
raidPtr->raid_cinfo[frow][fcol].ci_vp = NULL;
+
}
+ /* note that this disk was *not* auto_configured (any longer) */
+ raidPtr->Disks[frow][fcol].auto_configured = 0;
+
printf("About to (re-)open the device: %s\n",
raidPtr->Disks[frow][fcol].devname);
@@ -234,17 +240,12 @@ rf_CopybackReconstructedData(raidPtr)
raidread_component_label( raidPtr->raid_cinfo[frow][fcol].ci_dev,
raidPtr->raid_cinfo[frow][fcol].ci_vp,
&c_label);
-
- c_label.version = RF_COMPONENT_LABEL_VERSION;
- c_label.mod_counter = raidPtr->mod_counter;
- c_label.serial_number = raidPtr->serial_number;
+
+ raid_init_component_label( raidPtr, &c_label );
+
c_label.row = frow;
c_label.column = fcol;
- c_label.num_rows = raidPtr->numRow;
- c_label.num_columns = raidPtr->numCol;
- c_label.clean = RF_RAID_DIRTY;
- c_label.status = rf_ds_optimal;
-
+
raidwrite_component_label( raidPtr->raid_cinfo[frow][fcol].ci_dev,
raidPtr->raid_cinfo[frow][fcol].ci_vp,
&c_label);
diff --git a/sys/dev/raidframe/rf_dagfuncs.c b/sys/dev/raidframe/rf_dagfuncs.c
index 741687a04d5..d3e35553d0a 100644
--- a/sys/dev/raidframe/rf_dagfuncs.c
+++ b/sys/dev/raidframe/rf_dagfuncs.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_dagfuncs.c,v 1.4 2000/01/07 14:50:20 peter Exp $ */
-/* $NetBSD: rf_dagfuncs.c,v 1.5 1999/08/26 02:40:28 oster Exp $ */
+/* $OpenBSD: rf_dagfuncs.c,v 1.5 2000/08/08 16:07:39 peter Exp $ */
+/* $NetBSD: rf_dagfuncs.c,v 1.6 2000/03/30 12:45:40 augustss Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -637,14 +637,14 @@ rf_bxor(src, dest, len, bp)
*/
int
rf_longword_bxor(src, dest, len, bp)
- register unsigned long *src;
- register unsigned long *dest;
+ unsigned long *src;
+ unsigned long *dest;
int len; /* longwords */
void *bp;
{
- register unsigned long *end = src + len;
- register unsigned long d0, d1, d2, d3, s0, s1, s2, s3; /* temps */
- register unsigned long *pg_src, *pg_dest; /* per-page source/dest
+ unsigned long *end = src + len;
+ unsigned long d0, d1, d2, d3, s0, s1, s2, s3; /* temps */
+ unsigned long *pg_src, *pg_dest; /* per-page source/dest
* pointers */
int longs_this_time;/* # longwords to xor in the current iteration */
@@ -714,15 +714,15 @@ rf_longword_bxor(src, dest, len, bp)
*/
int
rf_longword_bxor3(dst, a, b, c, len, bp)
- register unsigned long *dst;
- register unsigned long *a;
- register unsigned long *b;
- register unsigned long *c;
+ unsigned long *dst;
+ unsigned long *a;
+ unsigned long *b;
+ unsigned long *c;
int len; /* length in longwords */
void *bp;
{
unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
- register unsigned long *pg_a, *pg_b, *pg_c, *pg_dst; /* per-page source/dest
+ unsigned long *pg_a, *pg_b, *pg_c, *pg_dst; /* per-page source/dest
* pointers */
int longs_this_time;/* # longs to xor in the current iteration */
char dst_is_a = 0;
@@ -879,10 +879,10 @@ rf_longword_bxor3(dst, a, b, c, len, bp)
int
rf_bxor3(dst, a, b, c, len, bp)
- register unsigned char *dst;
- register unsigned char *a;
- register unsigned char *b;
- register unsigned char *c;
+ unsigned char *dst;
+ unsigned char *a;
+ unsigned char *b;
+ unsigned char *c;
unsigned long len;
void *bp;
{
diff --git a/sys/dev/raidframe/rf_dagfuncs.h b/sys/dev/raidframe/rf_dagfuncs.h
index 0382fab2455..7114fd5f164 100644
--- a/sys/dev/raidframe/rf_dagfuncs.h
+++ b/sys/dev/raidframe/rf_dagfuncs.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_dagfuncs.h,v 1.2 1999/02/16 00:02:32 niklas Exp $ */
-/* $NetBSD: rf_dagfuncs.h,v 1.3 1999/02/05 00:06:08 oster Exp $ */
+/* $OpenBSD: rf_dagfuncs.h,v 1.3 2000/08/08 16:07:39 peter Exp $ */
+/* $NetBSD: rf_dagfuncs.h,v 1.4 2000/03/30 13:39:07 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -61,11 +61,10 @@ rf_XorIntoBuffer(RF_Raid_t * raidPtr, RF_PhysDiskAddr_t * pda, char *srcbuf,
char *targbuf, void *bp);
int rf_bxor(char *src, char *dest, int len, void *bp);
int
-rf_longword_bxor(register unsigned long *src, register unsigned long *dest,
- int len, void *bp);
+rf_longword_bxor(unsigned long *src, unsigned long *dest, int len, void *bp);
int
-rf_longword_bxor3(register unsigned long *dest, register unsigned long *a,
- register unsigned long *b, register unsigned long *c, int len, void *bp);
+rf_longword_bxor3(unsigned long *dest, unsigned long *a, unsigned long *b,
+ unsigned long *c, int len, void *bp);
int
rf_bxor3(unsigned char *dst, unsigned char *a, unsigned char *b,
unsigned char *c, unsigned long len, void *bp);
diff --git a/sys/dev/raidframe/rf_decluster.c b/sys/dev/raidframe/rf_decluster.c
index 43a5f3a5c34..3cae0d27f59 100644
--- a/sys/dev/raidframe/rf_decluster.c
+++ b/sys/dev/raidframe/rf_decluster.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_decluster.c,v 1.3 2000/01/07 14:50:21 peter Exp $ */
-/* $NetBSD: rf_decluster.c,v 1.4 1999/08/13 03:41:56 oster Exp $ */
+/* $OpenBSD: rf_decluster.c,v 1.4 2000/08/08 16:07:40 peter Exp $ */
+/* $NetBSD: rf_decluster.c,v 1.5 2000/03/07 01:54:29 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -556,11 +556,6 @@ rf_decluster_adjust_params(
RF_StripeNum_t * base_suid)
{
RF_DeclusteredConfigInfo_t *info = (RF_DeclusteredConfigInfo_t *) layoutPtr->layoutSpecificInfo;
-#if (defined(__NetBSD__) || defined (__OpenBSD__)) && defined(_KERNEL)
- /* Nothing! */
-#else
- char pc = layoutPtr->map->parityConfig;
-#endif
if (*SUID >= info->FullTableLimitSUID) {
/* new full table size is size of last full table on disk */
diff --git a/sys/dev/raidframe/rf_diskqueue.c b/sys/dev/raidframe/rf_diskqueue.c
index a4811343f7e..d324f43fadc 100644
--- a/sys/dev/raidframe/rf_diskqueue.c
+++ b/sys/dev/raidframe/rf_diskqueue.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_diskqueue.c,v 1.5 2000/01/11 18:02:21 peter Exp $ */
-/* $NetBSD: rf_diskqueue.c,v 1.8 2000/01/07 03:43:39 oster Exp $ */
+/* $OpenBSD: rf_diskqueue.c,v 1.6 2000/08/08 16:07:40 peter Exp $ */
+/* $NetBSD: rf_diskqueue.c,v 1.13 2000/03/04 04:22:34 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -27,7 +27,7 @@
* rights to redistribute these changes.
*/
-/****************************************************************************************
+/****************************************************************************
*
* rf_diskqueue.c -- higher-level disk queue code
*
@@ -35,32 +35,36 @@
* routines. The code here implements thread scheduling, synchronization,
* and locking ops (see below) on top of the lower-level queueing code.
*
- * to support atomic RMW, we implement "locking operations". When a locking op
- * is dispatched to the lower levels of the driver, the queue is locked, and no further
- * I/Os are dispatched until the queue receives & completes a corresponding "unlocking
- * operation". This code relies on the higher layers to guarantee that a locking
- * op will always be eventually followed by an unlocking op. The model is that
- * the higher layers are structured so locking and unlocking ops occur in pairs, i.e.
- * an unlocking op cannot be generated until after a locking op reports completion.
- * There is no good way to check to see that an unlocking op "corresponds" to the
- * op that currently has the queue locked, so we make no such attempt. Since by
- * definition there can be only one locking op outstanding on a disk, this should
- * not be a problem.
+ * to support atomic RMW, we implement "locking operations". When a
+ * locking op is dispatched to the lower levels of the driver, the
+ * queue is locked, and no further I/Os are dispatched until the queue
+ * receives & completes a corresponding "unlocking operation". This
+ * code relies on the higher layers to guarantee that a locking op
+ * will always be eventually followed by an unlocking op. The model
+ * is that the higher layers are structured so locking and unlocking
+ * ops occur in pairs, i.e. an unlocking op cannot be generated until
+ * after a locking op reports completion. There is no good way to
+ * check to see that an unlocking op "corresponds" to the op that
+ * currently has the queue locked, so we make no such attempt. Since
+ * by definition there can be only one locking op outstanding on a
+ * disk, this should not be a problem.
*
- * In the kernel, we allow multiple I/Os to be concurrently dispatched to the disk
- * driver. In order to support locking ops in this environment, when we decide to
- * do a locking op, we stop dispatching new I/Os and wait until all dispatched I/Os
- * have completed before dispatching the locking op.
+ * In the kernel, we allow multiple I/Os to be concurrently dispatched
+ * to the disk driver. In order to support locking ops in this
+ * environment, when we decide to do a locking op, we stop dispatching
+ * new I/Os and wait until all dispatched I/Os have completed before
+ * dispatching the locking op.
*
- * Unfortunately, the code is different in the 3 different operating states
- * (user level, kernel, simulator). In the kernel, I/O is non-blocking, and
- * we have no disk threads to dispatch for us. Therefore, we have to dispatch
- * new I/Os to the scsi driver at the time of enqueue, and also at the time
- * of completion. At user level, I/O is blocking, and so only the disk threads
- * may dispatch I/Os. Thus at user level, all we can do at enqueue time is
- * enqueue and wake up the disk thread to do the dispatch.
+ * Unfortunately, the code is different in the 3 different operating
+ * states (user level, kernel, simulator). In the kernel, I/O is
+ * non-blocking, and we have no disk threads to dispatch for us.
+ * Therefore, we have to dispatch new I/Os to the scsi driver at the
+ * time of enqueue, and also at the time of completion. At user
+ * level, I/O is blocking, and so only the disk threads may dispatch
+ * I/Os. Thus at user level, all we can do at enqueue time is enqueue
+ * and wake up the disk thread to do the dispatch.
*
- ***************************************************************************************/
+ ****************************************************************************/
#include "rf_types.h"
#include "rf_threadstuff.h"
@@ -77,31 +81,23 @@
#include "rf_cvscan.h"
#include "rf_sstf.h"
#include "rf_fifo.h"
+#include "rf_kintf.h"
static int init_dqd(RF_DiskQueueData_t *);
static void clean_dqd(RF_DiskQueueData_t *);
static void rf_ShutdownDiskQueueSystem(void *);
-/* From rf_kintf.c */
-int rf_DispatchKernelIO(RF_DiskQueue_t *, RF_DiskQueueData_t *);
-
#define Dprintf1(s,a) if (rf_queueDebug) rf_debug_printf(s,(void *)((unsigned long)a),NULL,NULL,NULL,NULL,NULL,NULL,NULL)
#define Dprintf2(s,a,b) if (rf_queueDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),NULL,NULL,NULL,NULL,NULL,NULL)
#define Dprintf3(s,a,b,c) if (rf_queueDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),NULL,NULL,NULL,NULL,NULL)
-#define Dprintf4(s,a,b,c,d) if (rf_queueDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),(void *)((unsigned long)d),NULL,NULL,NULL,NULL)
-#define Dprintf5(s,a,b,c,d,e) if (rf_queueDebug) rf_debug_printf(s,(void *)((unsigned long)a),(void *)((unsigned long)b),(void *)((unsigned long)c),(void *)((unsigned long)d),(void *)((unsigned long)e),NULL,NULL,NULL)
-
-
-#define SIGNAL_DISK_QUEUE(_q_,_wh_)
-#define WAIT_DISK_QUEUE(_q_,_wh_)
-/*****************************************************************************************
+/*****************************************************************************
*
- * the disk queue switch defines all the functions used in the different queueing
- * disciplines
- * queue ID, init routine, enqueue routine, dequeue routine
+ * the disk queue switch defines all the functions used in the
+ * different queueing disciplines queue ID, init routine, enqueue
+ * routine, dequeue routine
*
- ****************************************************************************************/
+ ****************************************************************************/
static RF_DiskQueueSW_t diskqueuesw[] = {
{"fifo", /* FIFO */
@@ -139,15 +135,6 @@ static RF_DiskQueueSW_t diskqueuesw[] = {
rf_CscanPeek,
rf_SstfPromote},
-#if !defined(_KERNEL) && RF_INCLUDE_QUEUE_RANDOM > 0
- /* to make a point to Chris :-> */
- {"random", /* random */
- rf_FifoCreate,
- rf_FifoEnqueue,
- rf_RandomDequeue,
- rf_RandomPeek,
- rf_FifoPromote},
-#endif /* !_KERNEL && RF_INCLUDE_QUEUE_RANDOM > 0 */
};
#define NUM_DISK_QUEUE_TYPES (sizeof(diskqueuesw)/sizeof(RF_DiskQueueSW_t))
@@ -163,9 +150,9 @@ static int
init_dqd(dqd)
RF_DiskQueueData_t *dqd;
{
- /* XXX not sure if the following malloc is appropriate... probably not
- * quite... */
- dqd->bp = (struct buf *) malloc(sizeof(struct buf), M_RAIDFRAME, M_NOWAIT);
+
+ dqd->bp = (struct buf *) malloc(sizeof(struct buf),
+ M_RAIDFRAME, M_NOWAIT);
if (dqd->bp == NULL) {
return (ENOMEM);
}
@@ -181,24 +168,20 @@ clean_dqd(dqd)
free(dqd->bp, M_RAIDFRAME);
}
/* configures a single disk queue */
-int config_disk_queue(RF_Raid_t *, RF_DiskQueue_t *, RF_RowCol_t,
- RF_RowCol_t, RF_DiskQueueSW_t *,
- RF_SectorCount_t, dev_t, int,
- RF_ShutdownList_t **,
- RF_AllocListElem_t *);
+
int
-config_disk_queue(
- RF_Raid_t * raidPtr,
- RF_DiskQueue_t * diskqueue,
- RF_RowCol_t r, /* row & col -- debug only. BZZT not any
+rf_ConfigureDiskQueue(
+ RF_Raid_t * raidPtr,
+ RF_DiskQueue_t * diskqueue,
+ RF_RowCol_t r, /* row & col -- debug only. BZZT not any
* more... */
- RF_RowCol_t c,
- RF_DiskQueueSW_t * p,
- RF_SectorCount_t sectPerDisk,
- dev_t dev,
- int maxOutstanding,
- RF_ShutdownList_t ** listp,
- RF_AllocListElem_t * clList)
+ RF_RowCol_t c,
+ RF_DiskQueueSW_t * p,
+ RF_SectorCount_t sectPerDisk,
+ dev_t dev,
+ int maxOutstanding,
+ RF_ShutdownList_t ** listp,
+ RF_AllocListElem_t * clList)
{
int rc;
@@ -284,6 +267,7 @@ rf_ConfigureDiskQueues(
RF_ERRORMSG2("Unknown queue type \"%s\". Using %s\n", cfgPtr->diskQueueType, diskqueuesw[0].queueType);
p = &diskqueuesw[0];
}
+ raidPtr->qType = p;
RF_CallocAndAdd(diskQueues, raidPtr->numRow, sizeof(RF_DiskQueue_t *), (RF_DiskQueue_t **), raidPtr->cleanupList);
if (diskQueues == NULL) {
return (ENOMEM);
@@ -297,9 +281,12 @@ rf_ConfigureDiskQueues(
if (diskQueues[r] == NULL)
return (ENOMEM);
for (c = 0; c < raidPtr->numCol; c++) {
- rc = config_disk_queue(raidPtr, &diskQueues[r][c], r, c, p,
- raidPtr->sectorsPerDisk, raidPtr->Disks[r][c].dev,
- cfgPtr->maxOutstandingDiskReqs, listp, raidPtr->cleanupList);
+ rc = rf_ConfigureDiskQueue(raidPtr, &diskQueues[r][c],
+ r, c, p,
+ raidPtr->sectorsPerDisk,
+ raidPtr->Disks[r][c].dev,
+ cfgPtr->maxOutstandingDiskReqs,
+ listp, raidPtr->cleanupList);
if (rc)
return (rc);
}
@@ -307,7 +294,7 @@ rf_ConfigureDiskQueues(
spareQueues = &raidPtr->Queues[0][raidPtr->numCol];
for (r = 0; r < raidPtr->numSpare; r++) {
- rc = config_disk_queue(raidPtr, &spareQueues[r],
+ rc = rf_ConfigureDiskQueue(raidPtr, &spareQueues[r],
0, raidPtr->numCol + r, p,
raidPtr->sectorsPerDisk,
raidPtr->Disks[0][raidPtr->numCol + r].dev,
diff --git a/sys/dev/raidframe/rf_diskqueue.h b/sys/dev/raidframe/rf_diskqueue.h
index 09d90dcefac..fb8e09927bd 100644
--- a/sys/dev/raidframe/rf_diskqueue.h
+++ b/sys/dev/raidframe/rf_diskqueue.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_diskqueue.h,v 1.3 2000/01/11 18:02:21 peter Exp $ */
-/* $NetBSD: rf_diskqueue.h,v 1.4 2000/01/08 23:02:16 oster Exp $ */
+/* $OpenBSD: rf_diskqueue.h,v 1.4 2000/08/08 16:07:40 peter Exp $ */
+/* $NetBSD: rf_diskqueue.h,v 1.5 2000/02/13 04:53:57 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -178,21 +178,36 @@ rf_DiskIOPromote(RF_DiskQueue_t * queue, RF_StripeNum_t parityStripeID,
RF_ReconUnitNum_t which_ru);
RF_DiskQueueData_t *
-rf_CreateDiskQueueData(RF_IoType_t typ,
- RF_SectorNum_t ssect, RF_SectorCount_t nsect, caddr_t buf,
- RF_StripeNum_t parityStripeID, RF_ReconUnitNum_t which_ru,
- int (*wakeF) (void *, int),
- void *arg, RF_DiskQueueData_t * next, RF_AccTraceEntry_t * tracerec,
- void *raidPtr, RF_DiskQueueDataFlags_t flags, void *kb_proc);
-
- RF_DiskQueueData_t *rf_CreateDiskQueueDataFull(RF_IoType_t typ,
- RF_SectorNum_t ssect, RF_SectorCount_t nsect, caddr_t buf,
- RF_StripeNum_t parityStripeID, RF_ReconUnitNum_t which_ru,
- int (*wakeF) (void *, int),
- void *arg, RF_DiskQueueData_t * next, RF_AccTraceEntry_t * tracerec,
- int priority, int (*AuxFunc) (void *,...), caddr_t buf2,
- void *raidPtr, RF_DiskQueueDataFlags_t flags, void *kb_proc);
-
- void rf_FreeDiskQueueData(RF_DiskQueueData_t * p);
+rf_CreateDiskQueueData(RF_IoType_t typ, RF_SectorNum_t ssect,
+ RF_SectorCount_t nsect, caddr_t buf,
+ RF_StripeNum_t parityStripeID,
+ RF_ReconUnitNum_t which_ru,
+ int (*wakeF) (void *, int),
+ void *arg, RF_DiskQueueData_t * next,
+ RF_AccTraceEntry_t * tracerec,
+ void *raidPtr, RF_DiskQueueDataFlags_t flags,
+ void *kb_proc);
+
+RF_DiskQueueData_t *
+rf_CreateDiskQueueDataFull(RF_IoType_t typ, RF_SectorNum_t ssect,
+ RF_SectorCount_t nsect, caddr_t buf,
+ RF_StripeNum_t parityStripeID,
+ RF_ReconUnitNum_t which_ru,
+ int (*wakeF) (void *, int),
+ void *arg, RF_DiskQueueData_t * next,
+ RF_AccTraceEntry_t * tracerec,
+ int priority, int (*AuxFunc) (void *,...),
+ caddr_t buf2, void *raidPtr,
+ RF_DiskQueueDataFlags_t flags, void *kb_proc);
+
+void
+rf_FreeDiskQueueData(RF_DiskQueueData_t * p);
+
+int
+rf_ConfigureDiskQueue(RF_Raid_t *, RF_DiskQueue_t *, RF_RowCol_t,
+ RF_RowCol_t, RF_DiskQueueSW_t *,
+ RF_SectorCount_t, dev_t, int,
+ RF_ShutdownList_t **,
+ RF_AllocListElem_t *);
#endif /* !_RF__RF_DISKQUEUE_H_ */
diff --git a/sys/dev/raidframe/rf_disks.c b/sys/dev/raidframe/rf_disks.c
index a598a218919..80aaffd87d8 100644
--- a/sys/dev/raidframe/rf_disks.c
+++ b/sys/dev/raidframe/rf_disks.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_disks.c,v 1.5 2000/01/11 18:02:21 peter Exp $ */
-/* $NetBSD: rf_disks.c,v 1.14 2000/01/09 01:29:28 oster Exp $ */
+/* $OpenBSD: rf_disks.c,v 1.6 2000/08/08 16:07:40 peter Exp $ */
+/* $NetBSD: rf_disks.c,v 1.31 2000/06/02 01:17:14 oster Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -75,6 +75,12 @@
#include "rf_options.h"
#include "rf_kintf.h"
+#if defined(__NetBSD__)
+#include "rf_netbsd.h"
+#elif defined(__OpenBSD__)
+#include "rf_openbsd.h"
+#endif
+
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
@@ -85,9 +91,11 @@
#include <sys/vnode.h>
#endif
-/* XXX these should be in a header file somewhere */
-void rf_UnconfigureVnodes( RF_Raid_t * );
-int rf_CheckLabels( RF_Raid_t *, RF_Config_t *);
+static int rf_AllocDiskStructures(RF_Raid_t *, RF_Config_t *);
+static void rf_print_label_status( RF_Raid_t *, int, int, char *,
+ RF_ComponentLabel_t *);
+static int rf_check_label_vitals( RF_Raid_t *, int, int, char *,
+ RF_ComponentLabel_t *, int, int );
#define DPRINTF6(a,b,c,d,e,f) if (rf_diskDebug) printf(a,b,c,d,e,f)
#define DPRINTF7(a,b,c,d,e,f,g) if (rf_diskDebug) printf(a,b,c,d,e,f,g)
@@ -116,54 +124,23 @@ rf_ConfigureDisks( listp, raidPtr, cfgPtr )
RF_RowCol_t r, c;
int bs, ret;
unsigned i, count, foundone = 0, numFailuresThisRow;
- int num_rows_done, num_cols_done;
int force;
- num_rows_done = 0;
- num_cols_done = 0;
force = cfgPtr->force;
- RF_CallocAndAdd(disks, raidPtr->numRow, sizeof(RF_RaidDisk_t *),
- (RF_RaidDisk_t **), raidPtr->cleanupList);
- if (disks == NULL) {
- ret = ENOMEM;
+ ret = rf_AllocDiskStructures(raidPtr, cfgPtr);
+ if (ret)
goto fail;
- }
- raidPtr->Disks = disks;
- /* get space for the device-specific stuff... */
- RF_CallocAndAdd(raidPtr->raid_cinfo, raidPtr->numRow,
- sizeof(struct raidcinfo *), (struct raidcinfo **),
- raidPtr->cleanupList);
- if (raidPtr->raid_cinfo == NULL) {
- ret = ENOMEM;
- goto fail;
- }
+ disks = raidPtr->Disks;
+
for (r = 0; r < raidPtr->numRow; r++) {
numFailuresThisRow = 0;
- /* We allocate RF_MAXSPARE on the first row so that we
- have room to do hot-swapping of spares */
- RF_CallocAndAdd(disks[r], raidPtr->numCol
- + ((r == 0) ? RF_MAXSPARE : 0),
- sizeof(RF_RaidDisk_t), (RF_RaidDisk_t *),
- raidPtr->cleanupList);
- if (disks[r] == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- /* get more space for device specific stuff.. */
- RF_CallocAndAdd(raidPtr->raid_cinfo[r],
- raidPtr->numCol + ((r == 0) ? raidPtr->numSpare : 0),
- sizeof(struct raidcinfo), (struct raidcinfo *),
- raidPtr->cleanupList);
- if (raidPtr->raid_cinfo[r] == NULL) {
- ret = ENOMEM;
- goto fail;
- }
for (c = 0; c < raidPtr->numCol; c++) {
ret = rf_ConfigureDisk(raidPtr,
&cfgPtr->devnames[r][c][0],
&disks[r][c], r, c);
+
if (ret)
goto fail;
@@ -186,14 +163,12 @@ rf_ConfigureDisks( listp, raidPtr, cfgPtr )
(long int) disks[r][c].numBlocks *
disks[r][c].blockSize / 1024 / 1024);
}
- num_cols_done++;
}
/* XXX fix for n-fault tolerant */
/* XXX this should probably check to see how many failures
we can handle for this configuration! */
if (numFailuresThisRow > 0)
raidPtr->status[r] = rf_rs_degraded;
- num_rows_done++;
}
/* all disks must be the same size & have the same block size, bs must
* be a power of 2 */
@@ -340,11 +315,289 @@ fail:
*/
rf_UnconfigureVnodes( raidPtr );
-
+
return (ret);
}
+static int
+rf_AllocDiskStructures(raidPtr, cfgPtr)
+ RF_Raid_t *raidPtr;
+ RF_Config_t *cfgPtr;
+{
+ RF_RaidDisk_t **disks;
+ int ret;
+ int r;
+ RF_CallocAndAdd(disks, raidPtr->numRow, sizeof(RF_RaidDisk_t *),
+ (RF_RaidDisk_t **), raidPtr->cleanupList);
+ if (disks == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ raidPtr->Disks = disks;
+ /* get space for the device-specific stuff... */
+ RF_CallocAndAdd(raidPtr->raid_cinfo, raidPtr->numRow,
+ sizeof(struct raidcinfo *), (struct raidcinfo **),
+ raidPtr->cleanupList);
+ if (raidPtr->raid_cinfo == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ for (r = 0; r < raidPtr->numRow; r++) {
+ /* We allocate RF_MAXSPARE on the first row so that we
+ have room to do hot-swapping of spares */
+ RF_CallocAndAdd(disks[r], raidPtr->numCol
+ + ((r == 0) ? RF_MAXSPARE : 0),
+ sizeof(RF_RaidDisk_t), (RF_RaidDisk_t *),
+ raidPtr->cleanupList);
+ if (disks[r] == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ /* get more space for device specific stuff.. */
+ RF_CallocAndAdd(raidPtr->raid_cinfo[r],
+ raidPtr->numCol + ((r == 0) ? raidPtr->numSpare : 0),
+ sizeof(struct raidcinfo), (struct raidcinfo *),
+ raidPtr->cleanupList);
+ if (raidPtr->raid_cinfo[r] == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ }
+ return(0);
+fail:
+ rf_UnconfigureVnodes( raidPtr );
+
+ return(ret);
+}
+
+
+/* configure a single disk during auto-configuration at boot */
+int
+rf_AutoConfigureDisks(raidPtr, cfgPtr, auto_config)
+ RF_Raid_t *raidPtr;
+ RF_Config_t *cfgPtr;
+ RF_AutoConfig_t *auto_config;
+{
+ RF_RaidDisk_t **disks;
+ RF_RaidDisk_t *diskPtr;
+ RF_RowCol_t r, c;
+ RF_SectorCount_t min_numblks = (RF_SectorCount_t) 0x7FFFFFFFFFFFLL;
+ int bs, ret;
+ int numFailuresThisRow;
+ int force;
+ RF_AutoConfig_t *ac;
+ int parity_good;
+ int mod_counter;
+ int mod_counter_found;
+
+#if DEBUG
+ printf("Starting autoconfiguration of RAID set...\n");
+#endif
+ force = cfgPtr->force;
+
+ ret = rf_AllocDiskStructures(raidPtr, cfgPtr);
+ if (ret)
+ goto fail;
+
+ disks = raidPtr->Disks;
+
+ /* assume the parity will be fine.. */
+ parity_good = RF_RAID_CLEAN;
+
+ /* Check for mod_counters that are too low */
+ mod_counter_found = 0;
+ ac = auto_config;
+ while(ac!=NULL) {
+ if (mod_counter_found==0) {
+ mod_counter = ac->clabel->mod_counter;
+ mod_counter_found = 1;
+ } else {
+ if (ac->clabel->mod_counter > mod_counter) {
+ mod_counter = ac->clabel->mod_counter;
+ }
+ }
+ ac->flag = 0; /* clear the general purpose flag */
+ ac = ac->next;
+ }
+
+ for (r = 0; r < raidPtr->numRow; r++) {
+ numFailuresThisRow = 0;
+ for (c = 0; c < raidPtr->numCol; c++) {
+ diskPtr = &disks[r][c];
+
+ /* find this row/col in the autoconfig */
+#if DEBUG
+ printf("Looking for %d,%d in autoconfig\n",r,c);
+#endif
+ ac = auto_config;
+ while(ac!=NULL) {
+ if (ac->clabel==NULL) {
+ /* big-time bad news. */
+ goto fail;
+ }
+ if ((ac->clabel->row == r) &&
+ (ac->clabel->column == c) &&
+ (ac->clabel->mod_counter == mod_counter)) {
+ /* it's this one... */
+ /* flag it as 'used', so we don't
+ free it later. */
+ ac->flag = 1;
+#if DEBUG
+ printf("Found: %s at %d,%d\n",
+ ac->devname,r,c);
+#endif
+
+ break;
+ }
+ ac=ac->next;
+ }
+
+ if (ac==NULL) {
+ /* we didn't find an exact match with a
+ correct mod_counter above... can we
+ find one with an incorrect mod_counter
+ to use instead? (this one, if we find
+ it, will be marked as failed once the
+ set configures)
+ */
+
+ ac = auto_config;
+ while(ac!=NULL) {
+ if (ac->clabel==NULL) {
+ /* big-time bad news. */
+ goto fail;
+ }
+ if ((ac->clabel->row == r) &&
+ (ac->clabel->column == c)) {
+ /* it's this one...
+ flag it as 'used', so we
+ don't free it later. */
+ ac->flag = 1;
+#if DEBUG
+ printf("Found(low mod_counter): %s at %d,%d\n",
+ ac->devname,r,c);
+#endif
+
+ break;
+ }
+ ac=ac->next;
+ }
+ }
+
+
+
+ if (ac!=NULL) {
+ /* Found it. Configure it.. */
+ diskPtr->blockSize = ac->clabel->blockSize;
+ diskPtr->numBlocks = ac->clabel->numBlocks;
+ /* Note: rf_protectedSectors is already
+ factored into numBlocks here */
+ raidPtr->raid_cinfo[r][c].ci_vp = ac->vp;
+ raidPtr->raid_cinfo[r][c].ci_dev = ac->dev;
+
+ memcpy(&raidPtr->raid_cinfo[r][c].ci_label,
+ ac->clabel, sizeof(*ac->clabel));
+ sprintf(diskPtr->devname, "/dev/%s",
+ ac->devname);
+
+ /* note the fact that this component was
+ autoconfigured. You'll need this info
+ later. Trust me :) */
+ diskPtr->auto_configured = 1;
+ diskPtr->dev = ac->dev;
+
+ /*
+ * we allow the user to specify that
+ * only a fraction of the disks should
+ * be used this is just for debug: it
+ * speeds up the parity scan
+ */
+
+ diskPtr->numBlocks = diskPtr->numBlocks *
+ rf_sizePercentage / 100;
+
+ /* XXX these will get set multiple times,
+ but since we're autoconfiguring, they'd
+ better be always the same each time!
+ If not, this is the least of your worries */
+
+ bs = diskPtr->blockSize;
+ min_numblks = diskPtr->numBlocks;
+
+ /* this gets done multiple times, but that's
+ fine -- the serial number will be the same
+ for all components, guaranteed */
+ raidPtr->serial_number =
+ ac->clabel->serial_number;
+ /* check the last time the label
+ was modified */
+ if (ac->clabel->mod_counter !=
+ mod_counter) {
+ /* Even though we've filled in all
+ of the above, we don't trust
+ this component since it's
+ modification counter is not
+ in sync with the rest, and we really
+ consider it to be failed. */
+ disks[r][c].status = rf_ds_failed;
+ numFailuresThisRow++;
+ } else {
+ if (ac->clabel->clean !=
+ RF_RAID_CLEAN) {
+ parity_good = RF_RAID_DIRTY;
+ }
+ }
+ } else {
+ /* Didn't find it at all!!
+ Component must really be dead */
+ disks[r][c].status = rf_ds_failed;
+ sprintf(disks[r][c].devname,"component%d",
+ r * raidPtr->numCol + c);
+ numFailuresThisRow++;
+ }
+ }
+ /* XXX fix for n-fault tolerant */
+ /* XXX this should probably check to see how many failures
+ we can handle for this configuration! */
+ if (numFailuresThisRow > 0)
+ raidPtr->status[r] = rf_rs_degraded;
+ }
+
+ /* close the device for the ones that didn't get used */
+
+ ac = auto_config;
+ while(ac!=NULL) {
+ if (ac->flag == 0) {
+ VOP_CLOSE(ac->vp, FREAD, NOCRED, 0);
+ vput(ac->vp);
+ ac->vp = NULL;
+#if DEBUG
+ printf("Released %s from auto-config set.\n",
+ ac->devname);
+#endif
+ }
+ ac = ac->next;
+ }
+
+ raidPtr->mod_counter = mod_counter;
+
+ /* note the state of the parity, if any */
+ raidPtr->parity_good = parity_good;
+ raidPtr->sectorsPerDisk = min_numblks;
+ raidPtr->logBytesPerSector = ffs(bs) - 1;
+ raidPtr->bytesPerSector = bs;
+ raidPtr->sectorMask = bs - 1;
+ return (0);
+
+fail:
+
+ rf_UnconfigureVnodes( raidPtr );
+
+ return (ret);
+
+}
/* configure a single disk in the array */
int
@@ -407,10 +660,13 @@ rf_ConfigureDisk(raidPtr, buf, diskPtr, row, col)
diskPtr->blockSize = dpart.disklab->d_secsize;
diskPtr->numBlocks = dpart.part->p_size - rf_protectedSectors;
-
+ diskPtr->partitionSize = dpart.part->p_size;
+
raidPtr->raid_cinfo[row][col].ci_vp = vp;
raidPtr->raid_cinfo[row][col].ci_dev = va.va_rdev;
+ /* This component was not automatically configured */
+ diskPtr->auto_configured = 0;
diskPtr->dev = va.va_rdev;
/* we allow the user to specify that only a fraction of the
@@ -422,9 +678,6 @@ rf_ConfigureDisk(raidPtr, buf, diskPtr, row, col)
return (0);
}
-static void rf_print_label_status( RF_Raid_t *, int, int, char *,
- RF_ComponentLabel_t *);
-
static void
rf_print_label_status( raidPtr, row, column, dev_name, ci_label )
RF_Raid_t *raidPtr;
@@ -446,8 +699,6 @@ rf_print_label_status( raidPtr, row, column, dev_name, ci_label )
ci_label->clean ? "Yes" : "No", ci_label->status );
}
-static int rf_check_label_vitals( RF_Raid_t *, int, int, char *,
- RF_ComponentLabel_t *, int, int );
static int rf_check_label_vitals( raidPtr, row, column, dev_name, ci_label,
serial_number, mod_counter )
RF_Raid_t *raidPtr;
@@ -764,13 +1015,6 @@ rf_CheckLabels( raidPtr, cfgPtr )
return(fatal_error);
}
-int config_disk_queue(RF_Raid_t *, RF_DiskQueue_t *, RF_RowCol_t,
- RF_RowCol_t, RF_DiskQueueSW_t *,
- RF_SectorCount_t, dev_t, int,
- RF_ShutdownList_t **,
- RF_AllocListElem_t *);
-
-int rf_add_hot_spare(RF_Raid_t *, RF_SingleComponent_t *);
int
rf_add_hot_spare(raidPtr, sparePtr)
RF_Raid_t *raidPtr;
@@ -782,8 +1026,10 @@ rf_add_hot_spare(raidPtr, sparePtr)
unsigned int bs;
int spare_number;
+#if 0
printf("Just in rf_add_hot_spare: %d\n",raidPtr->numSpare);
printf("Num col: %d\n",raidPtr->numCol);
+#endif
if (raidPtr->numSpare >= RF_MAXSPARE) {
RF_ERRORMSG1("Too many spares: %d\n", raidPtr->numSpare);
return(EINVAL);
@@ -843,12 +1089,13 @@ rf_add_hot_spare(raidPtr, sparePtr)
}
spareQueues = &raidPtr->Queues[0][raidPtr->numCol];
- ret = config_disk_queue( raidPtr, &spareQueues[spare_number],
+ ret = rf_ConfigureDiskQueue( raidPtr, &spareQueues[spare_number],
0, raidPtr->numCol + spare_number,
- raidPtr->Queues[0][0].qPtr, /* XXX */
+ raidPtr->qType,
raidPtr->sectorsPerDisk,
- raidPtr->Disks[0][raidPtr->numCol + spare_number].dev,
- raidPtr->Queues[0][0].maxOutstanding, /* XXX */
+ raidPtr->Disks[0][raidPtr->numCol +
+ spare_number].dev,
+ raidPtr->maxOutstanding,
&raidPtr->shutdownList,
raidPtr->cleanupList);
@@ -892,3 +1139,36 @@ rf_remove_hot_spare(raidPtr,sparePtr)
return (0);
#endif
}
+
+int
+rf_delete_component(raidPtr,component)
+ RF_Raid_t *raidPtr;
+ RF_SingleComponent_t *component;
+{
+ RF_RaidDisk_t *disks;
+
+ if ((component->row < 0) ||
+ (component->row >= raidPtr->numRow) ||
+ (component->column < 0) ||
+ (component->column >= raidPtr->numCol)) {
+ return(EINVAL);
+ }
+
+ disks = &raidPtr->Disks[component->row][component->column];
+
+ /* 1. This component must be marked as 'failed' */
+
+ return(EINVAL); /* Not implemented yet. */
+}
+
+int
+rf_incorporate_hot_spare(raidPtr,component)
+ RF_Raid_t *raidPtr;
+ RF_SingleComponent_t *component;
+{
+
+ /* Issues here include how to 'move' this in if there is IO
+ taking place (e.g. component queues and such) */
+
+ return(EINVAL); /* Not implemented yet. */
+}
diff --git a/sys/dev/raidframe/rf_disks.h b/sys/dev/raidframe/rf_disks.h
index bb3e551396d..bb15d365b5e 100644
--- a/sys/dev/raidframe/rf_disks.h
+++ b/sys/dev/raidframe/rf_disks.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_disks.h,v 1.3 1999/07/30 14:45:32 peter Exp $ */
-/* $NetBSD: rf_disks.h,v 1.4 1999/02/24 00:00:03 oster Exp $ */
+/* $OpenBSD: rf_disks.h,v 1.4 2000/08/08 16:07:40 peter Exp $ */
+/* $NetBSD: rf_disks.h,v 1.8 2000/03/27 03:25:17 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -39,6 +39,12 @@
#include "rf_archs.h"
#include "rf_types.h"
+#if defined(__NetBSD__)
+#include "rf_netbsd.h"
+#elif defined(__OpenBSD__)
+#include "rf_openbsd.h"
+#endif
+
/*
* A physical disk can be in one of several states:
* IF YOU ADD A STATE, CHECK TO SEE IF YOU NEED TO MODIFY RF_DEAD_DISK() BELOW.
@@ -68,16 +74,10 @@ struct RF_RaidDisk_s {
RF_SectorCount_t numBlocks; /* number of blocks, obtained via READ
* CAPACITY */
int blockSize;
- /* XXX the following is needed since we seem to need SIMULATE defined
- * in order to get user-land stuff to compile, but we *don't* want this
- * in the structure for the user-land utilities, as the kernel doesn't
- * know about it!! (and it messes up the size of the structure, so
- * there is a communication problem between the kernel and the
- * userland utils :-( GO */
-#if RF_KEEP_DISKSTATS > 0
- RF_uint64 nreads;
- RF_uint64 nwrites;
-#endif /* RF_KEEP_DISKSTATS > 0 */
+ RF_SectorCount_t partitionSize; /* The *actual* and *full* size of
+ the partition, from the disklabel */
+ int auto_configured;/* 1 if this component was autoconfigured.
+ 0 otherwise. */
dev_t dev;
};
/*
@@ -92,14 +92,27 @@ typedef void RF_DiskOp_t;
((_dstat_) == rf_ds_reconstructing) || ((_dstat_) == rf_ds_failed) || \
((_dstat_) == rf_ds_dist_spared))
-int
-rf_ConfigureDisks(RF_ShutdownList_t ** listp, RF_Raid_t * raidPtr,
- RF_Config_t * cfgPtr);
-int
-rf_ConfigureSpareDisks(RF_ShutdownList_t ** listp, RF_Raid_t * raidPtr,
- RF_Config_t * cfgPtr);
-int
-rf_ConfigureDisk(RF_Raid_t * raidPtr, char *buf, RF_RaidDisk_t * diskPtr,
- RF_RowCol_t row, RF_RowCol_t col);
+#ifdef _KERNEL
+#if defined(__NetBSD__)
+#include "rf_netbsd.h"
+#elif defined(__OpenBSD__)
+#include "rf_openbsd.h"
+#endif
+
+int rf_ConfigureDisks(RF_ShutdownList_t ** listp, RF_Raid_t * raidPtr,
+ RF_Config_t * cfgPtr);
+int rf_ConfigureSpareDisks(RF_ShutdownList_t ** listp, RF_Raid_t * raidPtr,
+ RF_Config_t * cfgPtr);
+int rf_ConfigureDisk(RF_Raid_t * raidPtr, char *buf, RF_RaidDisk_t * diskPtr,
+ RF_RowCol_t row, RF_RowCol_t col);
+int rf_AutoConfigureDisks(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr,
+ RF_AutoConfig_t *auto_config);
+int rf_CheckLabels( RF_Raid_t *, RF_Config_t *);
+int rf_add_hot_spare(RF_Raid_t *raidPtr, RF_SingleComponent_t *sparePtr);
+int rf_remove_hot_spare(RF_Raid_t *raidPtr, RF_SingleComponent_t *sparePtr);
+int rf_delete_component(RF_Raid_t *raidPtr, RF_SingleComponent_t *component);
+int rf_incorporate_hot_spare(RF_Raid_t *raidPtr,
+ RF_SingleComponent_t *component);
+#endif /* _KERNEL */
#endif /* !_RF__RF_DISKS_H_ */
diff --git a/sys/dev/raidframe/rf_driver.c b/sys/dev/raidframe/rf_driver.c
index 95ef423ecf1..40d6191a4c4 100644
--- a/sys/dev/raidframe/rf_driver.c
+++ b/sys/dev/raidframe/rf_driver.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_driver.c,v 1.8 2000/01/11 18:02:21 peter Exp $ */
-/* $NetBSD: rf_driver.c,v 1.27 2000/01/09 03:44:33 oster Exp $ */
+/* $OpenBSD: rf_driver.c,v 1.9 2000/08/08 16:07:40 peter Exp $ */
+/* $NetBSD: rf_driver.c,v 1.37 2000/06/04 02:05:13 oster Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -140,8 +140,6 @@ static void clean_rad(RF_RaidAccessDesc_t *);
static void rf_ShutdownRDFreeList(void *);
static int rf_ConfigureRDFreeList(RF_ShutdownList_t **);
-void rf_UnconfigureVnodes( RF_Raid_t * );
-
RF_DECLARE_MUTEX(rf_printf_mutex) /* debug only: avoids interleaved
* printfs by different stripes */
@@ -268,9 +266,16 @@ rf_Shutdown(raidPtr)
}
RF_FREELIST_DO_UNLOCK(rf_rad_freelist);
+ /* Wait for any parity re-writes to stop... */
+ while (raidPtr->parity_rewrite_in_progress) {
+ printf("Waiting for parity re-write to exit...\n");
+ tsleep(&raidPtr->parity_rewrite_in_progress, PRIBIO,
+ "rfprwshutdown", 0);
+ }
+
raidPtr->valid = 0;
- rf_update_component_labels(raidPtr);
+ rf_update_component_labels(raidPtr, RF_FINAL_COMPONENT_UPDATE);
rf_UnconfigureVnodes(raidPtr);
@@ -281,44 +286,6 @@ rf_Shutdown(raidPtr)
return (0);
}
-void
-rf_UnconfigureVnodes( raidPtr )
- RF_Raid_t *raidPtr;
-{
- int r,c;
- struct proc *p;
-
- /* We take this opportunity to close the vnodes like we should.. */
-
- p = raidPtr->engine_thread;
-
- for (r = 0; r < raidPtr->numRow; r++) {
- for (c = 0; c < raidPtr->numCol; c++) {
- printf("Closing vnode for row: %d col: %d\n", r, c);
- if (raidPtr->raid_cinfo[r][c].ci_vp) {
- VOP_UNLOCK(raidPtr->raid_cinfo[r][c].ci_vp, 0, p);
- (void) vn_close(raidPtr->raid_cinfo[r][c].ci_vp,
- FREAD | FWRITE, p->p_ucred, p);
- raidPtr->raid_cinfo[r][c].ci_vp = NULL;
- } else {
- printf("vnode was NULL\n");
- }
-
- }
- }
- for (r = 0; r < raidPtr->numSpare; r++) {
- printf("Closing vnode for spare: %d\n", r);
- if (raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp) {
- VOP_UNLOCK(raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp, 0, p);
- (void) vn_close(raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp,
- FREAD | FWRITE, p->p_ucred, p);
- raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp = NULL;
- } else {
- printf("vnode was NULL\n");
- }
- }
-}
-
#define DO_INIT_CONFIGURE(f) { \
rc = f (&globalShutdown); \
if (rc) { \
@@ -366,14 +333,18 @@ rf_UnconfigureVnodes( raidPtr )
}
int
-rf_Configure(raidPtr, cfgPtr)
+rf_Configure(raidPtr, cfgPtr, ac)
RF_Raid_t *raidPtr;
RF_Config_t *cfgPtr;
+ RF_AutoConfig_t *ac;
{
RF_RowCol_t row, col;
int i, rc;
- int unit;
+ /* XXX This check can probably be removed now, since
+ RAIDFRAME_CONFIGURRE now checks to make sure that the
+ RAID set is not already valid
+ */
if (raidPtr->valid) {
RF_ERRORMSG("RAIDframe configuration not shut down. Aborting configure.\n");
return (EINVAL);
@@ -389,15 +360,17 @@ rf_Configure(raidPtr, cfgPtr)
return (rc);
}
/* initialize globals */
- printf("RAIDFRAME: protectedSectors is %ld\n", rf_protectedSectors);
+ printf("RAIDFRAME: protectedSectors is %ld\n",
+ rf_protectedSectors);
rf_clear_debug_print_buffer();
DO_INIT_CONFIGURE(rf_ConfigureAllocList);
+
/*
- * Yes, this does make debugging general to the whole system instead
- * of being array specific. Bummer, drag.
- */
+ * Yes, this does make debugging general to the whole
+ * system instead of being array specific. Bummer, drag.
+ */
rf_ConfigureDebug(cfgPtr);
DO_INIT_CONFIGURE(rf_ConfigureDebugMem);
DO_INIT_CONFIGURE(rf_ConfigureAccessTrace);
@@ -419,15 +392,6 @@ rf_Configure(raidPtr, cfgPtr)
}
RF_UNLOCK_MUTEX(configureMutex);
- /*
- * Null out the entire raid descriptor to avoid problems when we reconfig.
- * This also clears the valid bit.
- */
- /* XXX this clearing should be moved UP to outside of here.... that,
- * or rf_Configure() needs to take more arguments... XXX */
- unit = raidPtr->raidid;
- bzero((char *) raidPtr, sizeof(RF_Raid_t));
- raidPtr->raidid = unit;
DO_RAID_MUTEX(&raidPtr->mutex);
/* set up the cleanup list. Do this after ConfigureDebug so that
* value of memDebug will be set */
@@ -488,8 +452,16 @@ rf_Configure(raidPtr, cfgPtr)
DO_RAID_COND(&raidPtr->waitForReconCond);
DO_RAID_MUTEX(&raidPtr->recon_done_proc_mutex);
- DO_RAID_INIT_CONFIGURE(rf_ConfigureDisks);
- DO_RAID_INIT_CONFIGURE(rf_ConfigureSpareDisks);
+
+ if (ac!=NULL) {
+ /* We have an AutoConfig structure.. Don't do the
+ normal disk configuration... call the auto config
+ stuff */
+ rf_AutoConfigureDisks(raidPtr, cfgPtr, ac);
+ } else {
+ DO_RAID_INIT_CONFIGURE(rf_ConfigureDisks);
+ DO_RAID_INIT_CONFIGURE(rf_ConfigureSpareDisks);
+ }
/* do this after ConfigureDisks & ConfigureSpareDisks to be sure dev
* no. is set */
DO_RAID_INIT_CONFIGURE(rf_ConfigureDiskQueues);
@@ -507,6 +479,19 @@ rf_Configure(raidPtr, cfgPtr)
}
}
+ raidPtr->numNewFailures = 0;
+ raidPtr->copyback_in_progress = 0;
+ raidPtr->parity_rewrite_in_progress = 0;
+ raidPtr->recon_in_progress = 0;
+ raidPtr->maxOutstanding = cfgPtr->maxOutstandingDiskReqs;
+
+ /* autoconfigure and root_partition will actually get filled in
+ after the config is done */
+ raidPtr->autoconfigure = 0;
+ raidPtr->root_partition = 0;
+ raidPtr->last_unit = raidPtr->raidid;
+ raidPtr->config_order = 0;
+
if (rf_keepAccTotals) {
raidPtr->keep_acc_totals = 1;
}
@@ -735,6 +720,7 @@ rf_SetReconfiguredMode(raidPtr, row, col)
raidPtr->numFailures++;
raidPtr->Disks[row][col].status = rf_ds_dist_spared;
raidPtr->status[row] = rf_rs_reconfigured;
+ rf_update_component_labels(raidPtr, RF_NORMAL_COMPONENT_UPDATE);
/* install spare table only if declustering + distributed sparing
* architecture. */
if (raidPtr->Layout.map->flags & RF_BD_DECLUSTERED)
@@ -758,6 +744,7 @@ rf_FailDisk(
raidPtr->numFailures++;
raidPtr->Disks[frow][fcol].status = rf_ds_failed;
raidPtr->status[frow] = rf_rs_degraded;
+ rf_update_component_labels(raidPtr, RF_NORMAL_COMPONENT_UPDATE);
RF_UNLOCK_MUTEX(raidPtr->mutex);
if (initRecon)
rf_ReconstructFailedDisk(raidPtr, frow, fcol);
@@ -796,12 +783,12 @@ rf_SuspendNewRequestsAndWait(raidPtr)
if (raidPtr->waiting_for_quiescence) {
raidPtr->access_suspend_release = 0;
while (!raidPtr->access_suspend_release) {
- printf("Suspending: Waiting for Quiesence\n");
+ printf("Suspending: Waiting for Quiescence\n");
WAIT_FOR_QUIESCENCE(raidPtr);
raidPtr->waiting_for_quiescence = 0;
}
}
- printf("Quiesence reached..\n");
+ printf("Quiescence reached..\n");
RF_UNLOCK_MUTEX(raidPtr->access_suspend_mutex);
return (raidPtr->waiting_for_quiescence);
diff --git a/sys/dev/raidframe/rf_driver.h b/sys/dev/raidframe/rf_driver.h
index 50eccc9491e..6e29c3c6d6c 100644
--- a/sys/dev/raidframe/rf_driver.h
+++ b/sys/dev/raidframe/rf_driver.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_driver.h,v 1.2 1999/02/16 00:02:41 niklas Exp $ */
-/* $NetBSD: rf_driver.h,v 1.3 1999/02/05 00:06:11 oster Exp $ */
+/* $OpenBSD: rf_driver.h,v 1.3 2000/08/08 16:07:41 peter Exp $ */
+/* $NetBSD: rf_driver.h,v 1.4 2000/02/13 04:53:57 oster Exp $ */
/*
* rf_driver.h
*/
@@ -36,33 +36,49 @@
#include "rf_threadstuff.h"
#include "rf_types.h"
-RF_DECLARE_EXTERN_MUTEX(rf_printf_mutex)
- int rf_BootRaidframe(void);
- int rf_UnbootRaidframe(void);
- int rf_Shutdown(RF_Raid_t * raidPtr);
- int rf_Configure(RF_Raid_t * raidPtr, RF_Config_t * cfgPtr);
- RF_RaidAccessDesc_t *rf_AllocRaidAccDesc(RF_Raid_t * raidPtr, RF_IoType_t type,
- RF_RaidAddr_t raidAddress, RF_SectorCount_t numBlocks, caddr_t bufPtr,
- void *bp, RF_DagHeader_t ** paramDAG, RF_AccessStripeMapHeader_t ** paramASM,
- RF_RaidAccessFlags_t flags, void (*cbF) (struct buf *), void *cbA,
- RF_AccessState_t * states);
- void rf_FreeRaidAccDesc(RF_RaidAccessDesc_t * desc);
- int rf_DoAccess(RF_Raid_t * raidPtr, RF_IoType_t type, int async_flag,
- RF_RaidAddr_t raidAddress, RF_SectorCount_t numBlocks, caddr_t bufPtr,
- void *bp_in, RF_DagHeader_t ** paramDAG,
- RF_AccessStripeMapHeader_t ** paramASM, RF_RaidAccessFlags_t flags,
- RF_RaidAccessDesc_t ** paramDesc, void (*cbF) (struct buf *), void *cbA);
- int rf_SetReconfiguredMode(RF_Raid_t * raidPtr, RF_RowCol_t row,
- RF_RowCol_t col);
- int rf_FailDisk(RF_Raid_t * raidPtr, RF_RowCol_t frow, RF_RowCol_t fcol,
- int initRecon);
- void rf_SignalQuiescenceLock(RF_Raid_t * raidPtr, RF_RaidReconDesc_t * reconDesc);
- int rf_SuspendNewRequestsAndWait(RF_Raid_t * raidPtr);
- void rf_ResumeNewRequests(RF_Raid_t * raidPtr);
- void rf_StartThroughputStats(RF_Raid_t * raidPtr);
- void rf_StartUserStats(RF_Raid_t * raidPtr);
- void rf_StopUserStats(RF_Raid_t * raidPtr);
- void rf_UpdateUserStats(RF_Raid_t * raidPtr, int rt, int numsect);
- void rf_PrintUserStats(RF_Raid_t * raidPtr);
+#if defined(__NetBSD__)
+#include "rf_netbsd.h"
+#elif defined(__OpenBSD__)
+#include "rf_openbsd.h"
+#endif
+#if _KERNEL
+RF_DECLARE_EXTERN_MUTEX(rf_printf_mutex)
+int rf_BootRaidframe(void);
+int rf_UnbootRaidframe(void);
+int rf_Shutdown(RF_Raid_t * raidPtr);
+int rf_Configure(RF_Raid_t * raidPtr, RF_Config_t * cfgPtr,
+ RF_AutoConfig_t *ac);
+RF_RaidAccessDesc_t *rf_AllocRaidAccDesc(RF_Raid_t * raidPtr, RF_IoType_t type,
+ RF_RaidAddr_t raidAddress,
+ RF_SectorCount_t numBlocks,
+ caddr_t bufPtr,
+ void *bp, RF_DagHeader_t ** paramDAG,
+ RF_AccessStripeMapHeader_t ** paramASM,
+ RF_RaidAccessFlags_t flags,
+ void (*cbF) (struct buf *),
+ void *cbA,
+ RF_AccessState_t * states);
+void rf_FreeRaidAccDesc(RF_RaidAccessDesc_t * desc);
+int rf_DoAccess(RF_Raid_t * raidPtr, RF_IoType_t type, int async_flag,
+ RF_RaidAddr_t raidAddress, RF_SectorCount_t numBlocks,
+ caddr_t bufPtr, void *bp_in, RF_DagHeader_t ** paramDAG,
+ RF_AccessStripeMapHeader_t ** paramASM,
+ RF_RaidAccessFlags_t flags,
+ RF_RaidAccessDesc_t ** paramDesc,
+ void (*cbF) (struct buf *), void *cbA);
+int rf_SetReconfiguredMode(RF_Raid_t * raidPtr, RF_RowCol_t row,
+ RF_RowCol_t col);
+int rf_FailDisk(RF_Raid_t * raidPtr, RF_RowCol_t frow, RF_RowCol_t fcol,
+ int initRecon);
+void rf_SignalQuiescenceLock(RF_Raid_t * raidPtr,
+ RF_RaidReconDesc_t * reconDesc);
+int rf_SuspendNewRequestsAndWait(RF_Raid_t * raidPtr);
+void rf_ResumeNewRequests(RF_Raid_t * raidPtr);
+void rf_StartThroughputStats(RF_Raid_t * raidPtr);
+void rf_StartUserStats(RF_Raid_t * raidPtr);
+void rf_StopUserStats(RF_Raid_t * raidPtr);
+void rf_UpdateUserStats(RF_Raid_t * raidPtr, int rt, int numsect);
+void rf_PrintUserStats(RF_Raid_t * raidPtr);
+#endif /* _KERNEL */
#endif /* !_RF__RF_DRIVER_H_ */
diff --git a/sys/dev/raidframe/rf_evenodd_dagfuncs.c b/sys/dev/raidframe/rf_evenodd_dagfuncs.c
index 0ea277c2c9c..7617b8241a3 100644
--- a/sys/dev/raidframe/rf_evenodd_dagfuncs.c
+++ b/sys/dev/raidframe/rf_evenodd_dagfuncs.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_evenodd_dagfuncs.c,v 1.5 2000/01/11 18:02:22 peter Exp $ */
-/* $NetBSD: rf_evenodd_dagfuncs.c,v 1.4 2000/01/07 03:41:00 oster Exp $ */
+/* $OpenBSD: rf_evenodd_dagfuncs.c,v 1.6 2000/08/08 16:07:41 peter Exp $ */
+/* $NetBSD: rf_evenodd_dagfuncs.c,v 1.6 2000/03/30 12:45:40 augustss Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -314,11 +314,11 @@ rf_e_EncOneSect(
#if RF_EO_MATRIX_DIM > 17
int shortsPerEU = bytesPerEU / sizeof(short);
short *destShortBuf, *srcShortBuf1, *srcShortBuf2;
- register short temp1;
+ short temp1;
#elif RF_EO_MATRIX_DIM == 17
int longsPerEU = bytesPerEU / sizeof(long);
long *destLongBuf, *srcLongBuf1, *srcLongBuf2;
- register long temp1;
+ long temp1;
#endif
#if RF_EO_MATRIX_DIM > 17
@@ -473,7 +473,7 @@ rf_doubleEOdecode(
int shortsPerEU = bytesPerEU / sizeof(short);
short *rrdbuf_current, *pbuf_current, *ebuf_current;
short *dest_smaller, *dest_smaller_current, *dest_larger, *dest_larger_current;
- register short *temp;
+ short *temp;
short *P;
RF_ASSERT(bytesPerEU % sizeof(short) == 0);
@@ -483,7 +483,7 @@ rf_doubleEOdecode(
int longsPerEU = bytesPerEU / sizeof(long);
long *rrdbuf_current, *pbuf_current, *ebuf_current;
long *dest_smaller, *dest_smaller_current, *dest_larger, *dest_larger_current;
- register long *temp;
+ long *temp;
long *P;
RF_ASSERT(bytesPerEU % sizeof(long) == 0);
@@ -713,7 +713,7 @@ rf_EvenOddDoubleRecoveryFunc(node)
startSector = fsuoff[0];
endSector = fsuend[0];
- /* find out the the column of failed disk being accessed */
+ /* find out the column of failed disk being accessed */
fcol[0] = rf_EUCol(layoutPtr, pda->raidAddress);
/* find out the other failed colume not accessed */
diff --git a/sys/dev/raidframe/rf_fifo.c b/sys/dev/raidframe/rf_fifo.c
index 411f1b65cc8..4e37d7e36a0 100644
--- a/sys/dev/raidframe/rf_fifo.c
+++ b/sys/dev/raidframe/rf_fifo.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_fifo.c,v 1.4 2000/01/11 18:02:22 peter Exp $ */
-/* $NetBSD: rf_fifo.c,v 1.4 2000/01/08 23:45:05 oster Exp $ */
+/* $OpenBSD: rf_fifo.c,v 1.5 2000/08/08 16:07:41 peter Exp $ */
+/* $NetBSD: rf_fifo.c,v 1.5 2000/03/04 03:27:13 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -147,92 +147,6 @@ rf_FifoDequeue(q_in)
}
return (nd);
}
-/* This never gets used!! No loss (I hope) if we don't include it... GO */
-#if !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(_KERNEL)
-
-static RF_DiskQueueData_t *
-n_in_q(headp, tailp, countp, n, deq)
- RF_DiskQueueData_t **headp;
- RF_DiskQueueData_t **tailp;
- int *countp;
- int n;
- int deq;
-{
- RF_DiskQueueData_t *r, *s;
- int i;
-
- for (s = NULL, i = n, r = *headp; r; s = r, r = r->next) {
- if (i == 0)
- break;
- i--;
- }
- RF_ASSERT(r != NULL);
- if (deq == 0)
- return (r);
- if (s) {
- s->next = r->next;
- } else {
- *headp = r->next;
- }
- if (*tailp == r)
- *tailp = s;
- (*countp)--;
- return (r);
-}
-#endif
-
-#if !defined(_KERNEL) && RF_INCLUDE_QUEUE_RANDOM > 0
-RF_DiskQueueData_t *
-rf_RandomPeek(q_in)
- void *q_in;
-{
- RF_FifoHeader_t *q = (RF_FifoHeader_t *) q_in;
- RF_DiskQueueData_t *req;
- int n;
-
- if (q->hq_head) {
- n = q->rval % q->hq_count;
- req = n_in_q(&q->hq_head, &q->hq_tail, &q->hq_count, n, 0);
- } else {
- RF_ASSERT(q->hq_count == 0);
- if (q->lq_head == NULL) {
- RF_ASSERT(q->lq_count == 0);
- return (NULL);
- }
- n = q->rval % q->lq_count;
- req = n_in_q(&q->lq_head, &q->lq_tail, &q->lq_count, n, 0);
- }
- RF_ASSERT((q->hq_count + q->lq_count) == req->queue->queueLength);
- RF_ASSERT(req != NULL);
- return (req);
-}
-
-RF_DiskQueueData_t *
-rf_RandomDequeue(q_in)
- void *q_in;
-{
- RF_FifoHeader_t *q = (RF_FifoHeader_t *) q_in;
- RF_DiskQueueData_t *req;
- int n;
-
- if (q->hq_head) {
- n = q->rval % q->hq_count;
- q->rval = (long) RF_STATIC_RANDOM();
- req = n_in_q(&q->hq_head, &q->hq_tail, &q->hq_count, n, 1);
- } else {
- RF_ASSERT(q->hq_count == 0);
- if (q->lq_head == NULL) {
- RF_ASSERT(q->lq_count == 0);
- return (NULL);
- }
- n = q->rval % q->lq_count;
- q->rval = (long) RF_STATIC_RANDOM();
- req = n_in_q(&q->lq_head, &q->lq_tail, &q->lq_count, n, 1);
- }
- RF_ASSERT((q->hq_count + q->lq_count) == (req->queue->queueLength - 1));
- return (req);
-}
-#endif /* !_KERNEL && RF_INCLUDE_QUEUE_RANDOM > 0 */
/* Return ptr to item at head of queue. Used to examine request
* info without actually dequeueing the request.
diff --git a/sys/dev/raidframe/rf_general.h b/sys/dev/raidframe/rf_general.h
index 7e4b9a1ade6..c69d97088a8 100644
--- a/sys/dev/raidframe/rf_general.h
+++ b/sys/dev/raidframe/rf_general.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_general.h,v 1.3 2000/01/07 14:50:21 peter Exp $ */
-/* $NetBSD: rf_general.h,v 1.4 1999/12/07 02:40:28 oster Exp $ */
+/* $OpenBSD: rf_general.h,v 1.4 2000/08/08 16:07:41 peter Exp $ */
+/* $NetBSD: rf_general.h,v 1.5 2000/03/03 02:04:48 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -46,9 +46,7 @@
#define RF_ERRORMSG1(s,a) printf((s),(a))
#define RF_ERRORMSG2(s,a,b) printf((s),(a),(b))
#define RF_ERRORMSG3(s,a,b,c) printf((s),(a),(b),(c))
-#define RF_ERRORMSG4(s,a,b,c,d) printf((s),(a),(b),(c),(d))
-#define RF_ERRORMSG5(s,a,b,c,d,e) printf((s),(a),(b),(c),(d),(e))
-#define perror(x)
+
extern char rf_panicbuf[];
#define RF_PANIC() {sprintf(rf_panicbuf,"raidframe error at line %d file %s",__LINE__,__FILE__); panic(rf_panicbuf);}
diff --git a/sys/dev/raidframe/rf_kintf.h b/sys/dev/raidframe/rf_kintf.h
index 00f3fd8bbd4..65e5c88c07a 100644
--- a/sys/dev/raidframe/rf_kintf.h
+++ b/sys/dev/raidframe/rf_kintf.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_kintf.h,v 1.5 2000/01/11 18:02:22 peter Exp $ */
-/* $NetBSD: rf_kintf.h,v 1.7 2000/01/09 01:29:27 oster Exp $ */
+/* $OpenBSD: rf_kintf.h,v 1.6 2000/08/08 16:07:41 peter Exp $ */
+/* $NetBSD: rf_kintf.h,v 1.14 2000/06/04 02:05:13 oster Exp $ */
/*
* rf_kintf.h
*
@@ -43,9 +43,15 @@ int rf_DispatchKernelIO(RF_DiskQueue_t * queue, RF_DiskQueueData_t * req);
int raidwrite_component_label(dev_t, struct vnode *, RF_ComponentLabel_t *);
int raidread_component_label(dev_t, struct vnode *, RF_ComponentLabel_t *);
-void rf_update_component_labels( RF_Raid_t *);
-int raidlookup __P((char *, struct proc *, struct vnode **));
+
+#define RF_NORMAL_COMPONENT_UPDATE 0
+#define RF_FINAL_COMPONENT_UPDATE 1
+void rf_update_component_labels(RF_Raid_t *, int);
+int raidlookup(char *, struct proc *, struct vnode **);
int raidmarkclean(dev_t dev, struct vnode *b_vp, int);
int raidmarkdirty(dev_t dev, struct vnode *b_vp, int);
-
+void raid_init_component_label(RF_Raid_t *, RF_ComponentLabel_t *);
+void rf_print_component_label(RF_ComponentLabel_t *);
+void rf_UnconfigureVnodes( RF_Raid_t * );
+void rf_close_component( RF_Raid_t *, struct vnode *, int);
#endif /* _RF__RF_KINTF_H_ */
diff --git a/sys/dev/raidframe/rf_layout.c b/sys/dev/raidframe/rf_layout.c
index 3b337687a72..de80c0096b6 100644
--- a/sys/dev/raidframe/rf_layout.c
+++ b/sys/dev/raidframe/rf_layout.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_layout.c,v 1.3 1999/07/30 14:45:32 peter Exp $ */
-/* $NetBSD: rf_layout.c,v 1.4 1999/07/19 01:35:19 oster Exp $ */
+/* $OpenBSD: rf_layout.c,v 1.4 2000/08/08 16:07:42 peter Exp $ */
+/* $NetBSD: rf_layout.c,v 1.6 2000/04/17 19:35:12 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
diff --git a/sys/dev/raidframe/rf_layout.h b/sys/dev/raidframe/rf_layout.h
index d2b7cbc7c2a..a368fc8663a 100644
--- a/sys/dev/raidframe/rf_layout.h
+++ b/sys/dev/raidframe/rf_layout.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_layout.h,v 1.3 1999/08/04 13:10:54 peter Exp $ */
-/* $NetBSD: rf_layout.h,v 1.3 1999/02/05 00:06:12 oster Exp $ */
+/* $OpenBSD: rf_layout.h,v 1.4 2000/08/08 16:07:42 peter Exp $ */
+/* $NetBSD: rf_layout.h,v 1.4 2000/05/23 00:44:38 thorpej Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -49,7 +49,7 @@
typedef struct RF_LayoutSW_s {
RF_ParityConfig_t parityConfig;
- char *configName;
+ const char *configName;
#ifndef _KERNEL
/* layout-specific parsing */
diff --git a/sys/dev/raidframe/rf_map.c b/sys/dev/raidframe/rf_map.c
index afe37457e99..db5d6c7fd1c 100644
--- a/sys/dev/raidframe/rf_map.c
+++ b/sys/dev/raidframe/rf_map.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_map.c,v 1.3 2000/01/07 14:50:21 peter Exp $ */
-/* $NetBSD: rf_map.c,v 1.4 1999/08/13 03:41:56 oster Exp $ */
+/* $OpenBSD: rf_map.c,v 1.4 2000/08/08 16:07:42 peter Exp $ */
+/* $NetBSD: rf_map.c,v 1.5 2000/06/29 00:22:27 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -269,7 +269,6 @@ rf_MarkFailuresInASMList(raidPtr, asm_h)
RF_MAX_FAILED_PDA * sizeof(RF_PhysDiskAddr_t *));
for (pda = asmap->physInfo; pda; pda = pda->next) {
if (RF_DEAD_DISK(disks[pda->row][pda->col].status)) {
- printf("DEAD DISK BOGUSLY DETECTED!!\n");
asmap->numDataFailed++;
asmap->failedPDAs[asmap->numFailedPDAs] = pda;
asmap->numFailedPDAs++;
diff --git a/sys/dev/raidframe/rf_netbsd.h b/sys/dev/raidframe/rf_netbsd.h
index b69f2f78c1e..0f3a18d3811 100644
--- a/sys/dev/raidframe/rf_netbsd.h
+++ b/sys/dev/raidframe/rf_netbsd.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_netbsd.h,v 1.4 1999/08/02 12:29:31 peter Exp $ */
-/* $NetBSD: rf_netbsd.h,v 1.6 1999/05/13 21:46:17 ad Exp $ */
+/* $OpenBSD: rf_netbsd.h,v 1.5 2000/08/08 16:07:42 peter Exp $ */
+/* $NetBSD: rf_netbsd.h,v 1.12 2000/05/28 22:53:49 oster Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -69,6 +69,33 @@ typedef struct RF_ComponentLabel_s {
int num_columns; /* number of columns in this RAID set */
int clean; /* 1 when clean, 0 when dirty */
int status; /* rf_ds_optimal, rf_ds_dist_spared, whatever. */
+ /* stuff that will be in version 2 of the label */
+ int sectPerSU; /* Sectors per Stripe Unit */
+ int SUsPerPU; /* Stripe Units per Parity Units */
+ int SUsPerRU; /* Stripe Units per Reconstruction Units */
+ int parityConfig; /* '0' == RAID0, '1' == RAID1, etc. */
+ int maxOutstanding; /* maxOutstanding disk requests */
+ int blockSize; /* size of component block.
+ (disklabel->d_secsize) */
+ int numBlocks; /* number of blocks on this component. May
+ be smaller than the partition size. */
+ int partitionSize; /* number of blocks on this *partition*.
+ Must exactly match the partition size
+ from the disklabel. */
+ int future_use[33]; /* Future expansion */
+ int autoconfigure; /* automatically configure this RAID set.
+ 0 == no, 1 == yes */
+ int root_partition; /* Use this set as /
+ 0 == no, 1 == yes*/
+ int last_unit; /* last unit number (e.g. 0 for /dev/raid0)
+ of this component. Used for autoconfigure
+ only. */
+ int config_order; /* 0 .. n. The order in which the component
+ should be auto-configured. E.g. 0 is will
+ done first, (and would become raid0).
+ This may be in conflict with last_unit!!?! */
+ /* Not currently used. */
+ int future_use2[44]; /* More future expansion */
} RF_ComponentLabel_t;
typedef struct RF_SingleComponent_s {
@@ -79,11 +106,6 @@ typedef struct RF_SingleComponent_s {
#ifdef _KERNEL
-/* XXX this is *not* the place for these... */
-int rf_add_hot_spare(RF_Raid_t *raidPtr, RF_SingleComponent_t *sparePtr);
-int rf_remove_hot_spare(RF_Raid_t *raidPtr, RF_SingleComponent_t *sparePtr);
-
-
struct raidcinfo {
struct vnode *ci_vp; /* component device's vnode */
dev_t ci_dev; /* component device's dev_t */
@@ -93,6 +115,26 @@ int rf_remove_hot_spare(RF_Raid_t *raidPtr, RF_SingleComponent_t *sparePtr);
char *ci_path; /* path to component */
size_t ci_pathlen; /* length of component path */
#endif
-};
+ };
+
+
+/* XXX probably belongs in a different .h file. */
+typedef struct RF_AutoConfig_s {
+ char devname[56]; /* the name of this component */
+ int flag; /* a general-purpose flag */
+ dev_t dev; /* the device for this component */
+ struct vnode *vp; /* Mr. Vnode Pointer */
+ RF_ComponentLabel_t *clabel; /* the label */
+ struct RF_AutoConfig_s *next; /* the next autoconfig structure
+ in this set. */
+} RF_AutoConfig_t;
+
+typedef struct RF_ConfigSet_s {
+ struct RF_AutoConfig_s *ac; /* all of the autoconfig structures for
+ this config set. */
+ int rootable; /* Set to 1 if this set can be root */
+ struct RF_ConfigSet_s *next;
+} RF_ConfigSet_t;
+
#endif /* _KERNEL */
#endif /* _RF__RF_NETBSDSTUFF_H_ */
diff --git a/sys/dev/raidframe/rf_netbsdkintf.c b/sys/dev/raidframe/rf_netbsdkintf.c
index 2ad2de25273..61f855fdaaa 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.46 2000/01/09 03:39:13 oster Exp $ */
+/* $NetBSD: rf_netbsdkintf.c,v 1.93 2000/07/14 15:26:29 oster Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -133,8 +133,10 @@
#include <sys/lock.h>
#include <sys/buf.h>
#include <sys/user.h>
+#include <sys/reboot.h>
#include "raid.h"
+#include "opt_raid_autoconfig.h"
#include "rf_raid.h"
#include "rf_raidframe.h"
#include "rf_copyback.h"
@@ -151,6 +153,7 @@
#include "rf_parityscan.h"
#include "rf_debugprint.h"
#include "rf_threadstuff.h"
+#include "rf_configure.h"
int rf_kdebug_level = 0;
@@ -176,7 +179,7 @@ static void InitBP(struct buf * bp, struct vnode *, unsigned rw_flag,
RF_SectorCount_t numSect, caddr_t buf,
void (*cbFunc) (struct buf *), void *cbArg,
int logBytesPerSector, struct proc * b_proc);
-static int raidinit __P((dev_t, RF_Raid_t *, int));
+static void raidinit __P((RF_Raid_t *));
void raidattach __P((int));
int raidsize __P((dev_t));
@@ -204,17 +207,17 @@ struct raidbuf {
#define RAIDPUTBUF(rs, cbp) pool_put(&(rs)->sc_cbufpool, cbp)
/* XXX Not sure if the following should be replacing the raidPtrs above,
- or if it should be used in conjunction with that... */
+ or if it should be used in conjunction with that...
+*/
struct raid_softc {
int sc_flags; /* flags */
int sc_cflags; /* configuration flags */
size_t sc_size; /* size of the raid device */
- dev_t sc_dev; /* our device.. */
char sc_xname[20]; /* XXX external name */
struct disk sc_dkdev; /* generic disk device info */
struct pool sc_cbufpool; /* component buffer pool */
- struct buf buf_queue; /* used for the device queue */
+ struct buf_queue buf_queue; /* used for the device queue */
};
/* sc_flags */
#define RAIDF_INITED 0x01 /* unit has been initialized */
@@ -224,7 +227,7 @@ struct raid_softc {
#define RAIDF_LOCKED 0x80 /* unit is locked */
#define raidunit(x) DISKUNIT(x)
-static int numraid = 0;
+int numraid = 0;
/*
* Allow RAIDOUTSTANDING number of simultaneous IO's to this RAID device.
@@ -262,6 +265,9 @@ static int raidlock __P((struct raid_softc *));
static void raidunlock __P((struct raid_softc *));
static void rf_markalldirty __P((RF_Raid_t *));
+void rf_mountroot_hook __P((struct device *));
+
+struct device *raidrootdev;
void rf_ReconThread __P((struct rf_recon_req *));
/* XXX what I want is: */
@@ -269,6 +275,26 @@ void rf_ReconThread __P((struct rf_recon_req *));
void rf_RewriteParityThread __P((RF_Raid_t *raidPtr));
void rf_CopybackThread __P((RF_Raid_t *raidPtr));
void rf_ReconstructInPlaceThread __P((struct rf_recon_req *));
+void rf_buildroothack __P((void *));
+
+RF_AutoConfig_t *rf_find_raid_components __P((void));
+RF_ConfigSet_t *rf_create_auto_sets __P((RF_AutoConfig_t *));
+static int rf_does_it_fit __P((RF_ConfigSet_t *,RF_AutoConfig_t *));
+static int rf_reasonable_label __P((RF_ComponentLabel_t *));
+void rf_create_configuration __P((RF_AutoConfig_t *,RF_Config_t *,
+ RF_Raid_t *));
+int rf_set_autoconfig __P((RF_Raid_t *, int));
+int rf_set_rootpartition __P((RF_Raid_t *, int));
+void rf_release_all_vps __P((RF_ConfigSet_t *));
+void rf_cleanup_config_set __P((RF_ConfigSet_t *));
+int rf_have_enough_components __P((RF_ConfigSet_t *));
+int rf_auto_config_set __P((RF_ConfigSet_t *, int *));
+
+static int raidautoconfig = 0; /* Debugging, mostly. Set to 0 to not
+ allow autoconfig to take place.
+ Note that this is overridden by having
+ RAID_AUTOCONFIG as an option in the
+ kernel config file. */
void
raidattach(num)
@@ -276,6 +302,8 @@ raidattach(num)
{
int raidID;
int i, rc;
+ RF_AutoConfig_t *ac_list; /* autoconfig list */
+ RF_ConfigSet_t *config_sets;
#ifdef DEBUG
printf("raidattach: Asked for %d units\n", num);
@@ -289,6 +317,8 @@ raidattach(num)
}
/* This is where all the initialization stuff gets done. */
+ numraid = num;
+
/* Make some space for requested number of units... */
RF_Calloc(raidPtrs, num, sizeof(RF_Raid_t *), (RF_Raid_t **));
@@ -303,7 +333,7 @@ raidattach(num)
rf_sparet_wait_queue = rf_sparet_resp_queue = NULL;
- for (i = 0; i < numraid; i++)
+ for (i = 0; i < num; i++)
raidPtrs[i] = NULL;
rc = rf_BootRaidframe();
if (rc == 0)
@@ -316,15 +346,30 @@ raidattach(num)
raid_softc = (struct raid_softc *)
malloc(num * sizeof(struct raid_softc),
- M_RAIDFRAME, M_NOWAIT);
+ M_RAIDFRAME, M_NOWAIT);
if (raid_softc == NULL) {
printf("WARNING: no memory for RAIDframe driver\n");
return;
}
- numraid = num;
+
bzero(raid_softc, num * sizeof(struct raid_softc));
+ raidrootdev = (struct device *)malloc(num * sizeof(struct device),
+ M_RAIDFRAME, M_NOWAIT);
+ if (raidrootdev == NULL) {
+ panic("No memory for RAIDframe driver!!?!?!\n");
+ }
+
for (raidID = 0; raidID < num; raidID++) {
+ BUFQ_INIT(&raid_softc[raidID].buf_queue);
+
+ raidrootdev[raidID].dv_class = DV_DISK;
+ raidrootdev[raidID].dv_cfdata = NULL;
+ raidrootdev[raidID].dv_unit = raidID;
+ raidrootdev[raidID].dv_parent = NULL;
+ raidrootdev[raidID].dv_flags = 0;
+ sprintf(raidrootdev[raidID].dv_xname,"raid%d",raidID);
+
raid_softc[raidID].buf_queue.b_actf = NULL;
raid_softc[raidID].buf_queue.b_actb =
&raid_softc[raidID].buf_queue.b_actf;
@@ -336,6 +381,90 @@ raidattach(num)
return;
}
}
+
+#if RAID_AUTOCONFIG
+ raidautoconfig = 1;
+#endif
+
+if (raidautoconfig) {
+ /* 1. locate all RAID components on the system */
+
+#if DEBUG
+ printf("Searching for raid components...\n");
+#endif
+ ac_list = rf_find_raid_components();
+
+ /* 2. sort them into their respective sets */
+
+ config_sets = rf_create_auto_sets(ac_list);
+
+ /* 3. evaluate each set and configure the valid ones
+ This gets done in rf_buildroothack() */
+
+ /* schedule the creation of the thread to do the
+ "/ on RAID" stuff */
+
+ kthread_create(rf_buildroothack,config_sets);
+
+#if 0
+ mountroothook_establish(rf_mountroot_hook, &raidrootdev[0]);
+#endif
+}
+
+}
+
+void
+rf_buildroothack(arg)
+ void *arg;
+{
+ RF_ConfigSet_t *config_sets = arg;
+ RF_ConfigSet_t *cset;
+ RF_ConfigSet_t *next_cset;
+ int retcode;
+ int raidID;
+ int rootID;
+ int num_root;
+
+ num_root = 0;
+ cset = config_sets;
+ while(cset != NULL ) {
+ next_cset = cset->next;
+ if (rf_have_enough_components(cset) &&
+ cset->ac->clabel->autoconfigure==1) {
+ retcode = rf_auto_config_set(cset,&raidID);
+ if (!retcode) {
+ if (cset->rootable) {
+ rootID = raidID;
+ num_root++;
+ }
+ } else {
+ /* The autoconfig didn't work :( */
+#if DEBUG
+ printf("Autoconfig failed with code %d for raid%d\n", retcode, raidID);
+#endif
+ rf_release_all_vps(cset);
+ }
+ } else {
+ /* we're not autoconfiguring this set...
+ release the associated resources */
+ rf_release_all_vps(cset);
+ }
+ /* cleanup */
+ rf_cleanup_config_set(cset);
+ cset = next_cset;
+ }
+ if (boothowto & RB_ASKNAME) {
+ /* We don't auto-config... */
+ } else {
+ /* They didn't ask, and we found something bootable... */
+
+ if (num_root == 1) {
+ booted_device = &raidrootdev[rootID];
+ } else if (num_root > 1) {
+ /* we can't guess.. require the user to answer... */
+ boothowto |= RB_ASKNAME;
+ }
+ }
}
@@ -504,7 +633,11 @@ raidclose(dev, flags, fmt, p)
Device shutdown has taken care of setting the
clean bits if RAIDF_INITED is not set
mark things as clean... */
- rf_update_component_labels( raidPtrs[unit] );
+#if 0
+ printf("Last one on raid%d. Updating status.\n",unit);
+#endif
+ rf_update_component_labels(raidPtrs[unit],
+ RF_FINAL_COMPONENT_UPDATE);
}
raidunlock(rs);
@@ -514,15 +647,14 @@ raidclose(dev, flags, fmt, p)
void
raidstrategy(bp)
- register struct buf *bp;
+ struct buf *bp;
{
- register int s;
+ int s;
unsigned int raidID = raidunit(bp->b_dev);
RF_Raid_t *raidPtr;
struct raid_softc *rs = &raid_softc[raidID];
struct disklabel *lp;
- struct buf *dp;
int wlabel;
if ((rs->sc_flags & RAIDF_INITED) ==0) {
@@ -572,13 +704,8 @@ raidstrategy(bp)
bp->b_resid = 0;
/* stuff it onto our queue */
+ BUFQ_INSERT_TAIL(&rs->buf_queue, bp);
- dp = &rs->buf_queue;
- bp->b_actf = NULL;
- bp->b_actb = dp->b_actb;
- *dp->b_actb = bp;
- dp->b_actb = &bp->b_actf;
-
raidstart(raidPtrs[raidID]);
splx(s);
@@ -642,6 +769,7 @@ raidioctl(dev, cmd, data, flag, p)
struct raid_softc *rs;
RF_Config_t *k_cfg, *u_cfg;
RF_Raid_t *raidPtr;
+ RF_RaidDisk_t *diskPtr;
RF_AccTotals_t *totals;
RF_DeviceConfig_t *d_cfg, **ucfgp;
u_char *specific_buf;
@@ -649,12 +777,13 @@ raidioctl(dev, cmd, data, flag, p)
int row;
int column;
struct rf_recon_req *rrcopy, *rr;
- RF_ComponentLabel_t *component_label;
+ RF_ComponentLabel_t *clabel;
RF_ComponentLabel_t ci_label;
- RF_ComponentLabel_t **c_label_ptr;
+ RF_ComponentLabel_t **clabel_ptr;
RF_SingleComponent_t *sparePtr,*componentPtr;
RF_SingleComponent_t hot_spare;
RF_SingleComponent_t component;
+ RF_ProgressInfo_t progressInfo, **progressInfoPtr;
int i, j, d;
if (unit >= numraid)
@@ -692,6 +821,7 @@ raidioctl(dev, cmd, data, flag, p)
case RAIDFRAME_FAIL_DISK:
case RAIDFRAME_COPYBACK:
case RAIDFRAME_CHECK_RECON_STATUS:
+ case RAIDFRAME_CHECK_RECON_STATUS_EXT:
case RAIDFRAME_GET_COMPONENT_LABEL:
case RAIDFRAME_SET_COMPONENT_LABEL:
case RAIDFRAME_ADD_HOT_SPARE:
@@ -700,7 +830,13 @@ raidioctl(dev, cmd, data, flag, p)
case RAIDFRAME_REBUILD_IN_PLACE:
case RAIDFRAME_CHECK_PARITY:
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
+ case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
case RAIDFRAME_CHECK_COPYBACK_STATUS:
+ case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
+ case RAIDFRAME_SET_AUTOCONFIG:
+ case RAIDFRAME_SET_ROOT:
+ case RAIDFRAME_DELETE_COMPONENT:
+ case RAIDFRAME_INCORPORATE_HOT_SPARE:
if ((rs->sc_flags & RAIDF_INITED) == 0)
return (ENXIO);
}
@@ -709,6 +845,13 @@ raidioctl(dev, cmd, data, flag, p)
/* configure the system */
case RAIDFRAME_CONFIGURE:
+
+ if (raidPtr->valid) {
+ /* There is a valid RAID set running on this unit! */
+ printf("raid%d: Device already configured!\n",unit);
+ return(EINVAL);
+ }
+
/* copy-in the configuration information */
/* data points to a pointer to the configuration structure */
@@ -759,24 +902,24 @@ raidioctl(dev, cmd, data, flag, p)
/* configure the system */
+ /*
+ * Clear the entire RAID descriptor, just to make sure
+ * there is no stale data left in the case of a
+ * reconfiguration
+ */
+ bzero((char *) raidPtr, sizeof(RF_Raid_t));
raidPtr->raidid = unit;
- retcode = rf_Configure(raidPtr, k_cfg);
+ retcode = rf_Configure(raidPtr, k_cfg, NULL);
if (retcode == 0) {
/* allow this many simultaneous IO's to
this RAID device */
raidPtr->openings = RAIDOUTSTANDING;
-
- /* XXX should be moved to rf_Configure() */
-
- raidPtr->copyback_in_progress = 0;
- raidPtr->parity_rewrite_in_progress = 0;
- raidPtr->recon_in_progress = 0;
-
- retcode = raidinit(dev, raidPtr, unit);
- rf_markalldirty( raidPtr );
+
+ raidinit(raidPtr);
+ rf_markalldirty(raidPtr);
}
/* free the buffers. No return code here. */
if (k_cfg->layoutSpecificSize) {
@@ -820,49 +963,49 @@ raidioctl(dev, cmd, data, flag, p)
return (retcode);
case RAIDFRAME_GET_COMPONENT_LABEL:
- c_label_ptr = (RF_ComponentLabel_t **) data;
+ clabel_ptr = (RF_ComponentLabel_t **) data;
/* need to read the component label for the disk indicated
- by row,column in component_label */
+ by row,column in clabel */
/* For practice, let's get it directly fromdisk, rather
than from the in-core copy */
- RF_Malloc( component_label, sizeof( RF_ComponentLabel_t ),
+ RF_Malloc( clabel, sizeof( RF_ComponentLabel_t ),
(RF_ComponentLabel_t *));
- if (component_label == NULL)
+ if (clabel == NULL)
return (ENOMEM);
- bzero((char *) component_label, sizeof(RF_ComponentLabel_t));
+ bzero((char *) clabel, sizeof(RF_ComponentLabel_t));
- retcode = copyin( *c_label_ptr, component_label,
+ retcode = copyin( *clabel_ptr, clabel,
sizeof(RF_ComponentLabel_t));
if (retcode) {
- RF_Free( component_label, sizeof(RF_ComponentLabel_t));
+ RF_Free( clabel, sizeof(RF_ComponentLabel_t));
return(retcode);
}
- row = component_label->row;
- column = component_label->column;
+ row = clabel->row;
+ column = clabel->column;
if ((row < 0) || (row >= raidPtr->numRow) ||
- (column < 0) || (column >= raidPtr->numCol)) {
- RF_Free( component_label, sizeof(RF_ComponentLabel_t));
+ (column < 0) || (column >= raidPtr->numCol +
+ raidPtr->numSpare)) {
+ RF_Free( clabel, sizeof(RF_ComponentLabel_t));
return(EINVAL);
}
- raidread_component_label(
- raidPtr->Disks[row][column].dev,
- raidPtr->raid_cinfo[row][column].ci_vp,
- component_label );
+ raidread_component_label(raidPtr->Disks[row][column].dev,
+ raidPtr->raid_cinfo[row][column].ci_vp,
+ clabel );
- retcode = copyout((caddr_t) component_label,
- (caddr_t) *c_label_ptr,
+ retcode = copyout((caddr_t) clabel,
+ (caddr_t) *clabel_ptr,
sizeof(RF_ComponentLabel_t));
- RF_Free( component_label, sizeof(RF_ComponentLabel_t));
+ RF_Free( clabel, sizeof(RF_ComponentLabel_t));
return (retcode);
case RAIDFRAME_SET_COMPONENT_LABEL:
- component_label = (RF_ComponentLabel_t *) data;
+ clabel = (RF_ComponentLabel_t *) data;
/* XXX check the label for valid stuff... */
/* Note that some things *should not* get modified --
@@ -871,18 +1014,18 @@ raidioctl(dev, cmd, data, flag, p)
*/
printf("Got component label:\n");
- printf("Version: %d\n",component_label->version);
- printf("Serial Number: %d\n",component_label->serial_number);
- printf("Mod counter: %d\n",component_label->mod_counter);
- printf("Row: %d\n", component_label->row);
- printf("Column: %d\n", component_label->column);
- printf("Num Rows: %d\n", component_label->num_rows);
- printf("Num Columns: %d\n", component_label->num_columns);
- printf("Clean: %d\n", component_label->clean);
- printf("Status: %d\n", component_label->status);
-
- row = component_label->row;
- column = component_label->column;
+ printf("Version: %d\n",clabel->version);
+ printf("Serial Number: %d\n",clabel->serial_number);
+ printf("Mod counter: %d\n",clabel->mod_counter);
+ printf("Row: %d\n", clabel->row);
+ printf("Column: %d\n", clabel->column);
+ printf("Num Rows: %d\n", clabel->num_rows);
+ printf("Num Columns: %d\n", clabel->num_columns);
+ printf("Clean: %d\n", clabel->clean);
+ printf("Status: %d\n", clabel->status);
+
+ row = clabel->row;
+ column = clabel->column;
if ((row < 0) || (row >= raidPtr->numRow) ||
(column < 0) || (column >= raidPtr->numCol)) {
@@ -890,16 +1033,19 @@ raidioctl(dev, cmd, data, flag, p)
}
/* XXX this isn't allowed to do anything for now :-) */
+
+ /* XXX and before it is, we need to fill in the rest
+ of the fields!?!?!?! */
#if 0
raidwrite_component_label(
raidPtr->Disks[row][column].dev,
raidPtr->raid_cinfo[row][column].ci_vp,
- component_label );
+ clabel );
#endif
return (0);
case RAIDFRAME_INIT_LABELS:
- component_label = (RF_ComponentLabel_t *) data;
+ clabel = (RF_ComponentLabel_t *) data;
/*
we only want the serial number from
the above. We get all the rest of the information
@@ -907,19 +1053,16 @@ raidioctl(dev, cmd, data, flag, p)
set.
*/
- raidPtr->serial_number = component_label->serial_number;
- /* current version number */
- ci_label.version = RF_COMPONENT_LABEL_VERSION;
- ci_label.serial_number = component_label->serial_number;
- ci_label.mod_counter = raidPtr->mod_counter;
- ci_label.num_rows = raidPtr->numRow;
- ci_label.num_columns = raidPtr->numCol;
- ci_label.clean = RF_RAID_DIRTY; /* not clean */
- ci_label.status = rf_ds_optimal; /* "It's good!" */
+ raidPtr->serial_number = clabel->serial_number;
+
+ raid_init_component_label(raidPtr, &ci_label);
+ ci_label.serial_number = clabel->serial_number;
for(row=0;row<raidPtr->numRow;row++) {
ci_label.row = row;
for(column=0;column<raidPtr->numCol;column++) {
+ diskPtr = &raidPtr->Disks[row][column];
+ ci_label.partitionSize = diskPtr->partitionSize;
ci_label.column = column;
raidwrite_component_label(
raidPtr->Disks[row][column].dev,
@@ -929,6 +1072,17 @@ raidioctl(dev, cmd, data, flag, p)
}
return (retcode);
+ case RAIDFRAME_SET_AUTOCONFIG:
+ d = rf_set_autoconfig(raidPtr, *(int *) data);
+ printf("New autoconfig value is: %d\n", d);
+ *(int *) data = d;
+ return (retcode);
+
+ case RAIDFRAME_SET_ROOT:
+ d = rf_set_rootpartition(raidPtr, *(int *) data);
+ printf("New rootpartition value is: %d\n", d);
+ *(int *) data = d;
+ return (retcode);
/* initialize all parity */
case RAIDFRAME_REWRITEPARITY:
@@ -953,13 +1107,26 @@ raidioctl(dev, cmd, data, flag, p)
case RAIDFRAME_ADD_HOT_SPARE:
sparePtr = (RF_SingleComponent_t *) data;
memcpy( &hot_spare, sparePtr, sizeof(RF_SingleComponent_t));
- printf("Adding spare\n");
retcode = rf_add_hot_spare(raidPtr, &hot_spare);
return(retcode);
case RAIDFRAME_REMOVE_HOT_SPARE:
return(retcode);
+ case RAIDFRAME_DELETE_COMPONENT:
+ componentPtr = (RF_SingleComponent_t *)data;
+ memcpy( &component, componentPtr,
+ sizeof(RF_SingleComponent_t));
+ retcode = rf_delete_component(raidPtr, &component);
+ return(retcode);
+
+ case RAIDFRAME_INCORPORATE_HOT_SPARE:
+ componentPtr = (RF_SingleComponent_t *)data;
+ memcpy( &component, componentPtr,
+ sizeof(RF_SingleComponent_t));
+ retcode = rf_incorporate_hot_spare(raidPtr, &component);
+ return(retcode);
+
case RAIDFRAME_REBUILD_IN_PLACE:
if (raidPtr->Layout.map->faultsTolerated == 0) {
@@ -1117,22 +1284,65 @@ raidioctl(dev, cmd, data, flag, p)
*(int *) data = raidPtr->reconControl[row]->percentComplete;
return (0);
+ case RAIDFRAME_CHECK_RECON_STATUS_EXT:
+ progressInfoPtr = (RF_ProgressInfo_t **) data;
+ row = 0; /* XXX we only consider a single row... */
+ if (raidPtr->status[row] != rf_rs_reconstructing) {
+ progressInfo.remaining = 0;
+ progressInfo.completed = 100;
+ progressInfo.total = 100;
+ } else {
+ progressInfo.total =
+ raidPtr->reconControl[row]->numRUsTotal;
+ progressInfo.completed =
+ raidPtr->reconControl[row]->numRUsComplete;
+ progressInfo.remaining = progressInfo.total -
+ progressInfo.completed;
+ }
+ retcode = copyout((caddr_t) &progressInfo,
+ (caddr_t) *progressInfoPtr,
+ sizeof(RF_ProgressInfo_t));
+ return (retcode);
+
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
if (raidPtr->Layout.map->faultsTolerated == 0) {
- /* This makes no sense on a RAID 0 */
- return(EINVAL);
+ /* This makes no sense on a RAID 0, so tell the
+ user it's done. */
+ *(int *) data = 100;
+ return(0);
}
if (raidPtr->parity_rewrite_in_progress == 1) {
- *(int *) data = 100 * raidPtr->parity_rewrite_stripes_done / raidPtr->Layout.numStripe;
+ *(int *) data = 100 *
+ raidPtr->parity_rewrite_stripes_done /
+ raidPtr->Layout.numStripe;
} else {
*(int *) data = 100;
}
return (0);
+ case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
+ progressInfoPtr = (RF_ProgressInfo_t **) data;
+ if (raidPtr->parity_rewrite_in_progress == 1) {
+ progressInfo.total = raidPtr->Layout.numStripe;
+ progressInfo.completed =
+ raidPtr->parity_rewrite_stripes_done;
+ progressInfo.remaining = progressInfo.total -
+ progressInfo.completed;
+ } else {
+ progressInfo.remaining = 0;
+ progressInfo.completed = 100;
+ progressInfo.total = 100;
+ }
+ retcode = copyout((caddr_t) &progressInfo,
+ (caddr_t) *progressInfoPtr,
+ sizeof(RF_ProgressInfo_t));
+ return (retcode);
+
case RAIDFRAME_CHECK_COPYBACK_STATUS:
if (raidPtr->Layout.map->faultsTolerated == 0) {
/* This makes no sense on a RAID 0 */
- return(EINVAL);
+ *(int *) data = 100;
+ return(0);
}
if (raidPtr->copyback_in_progress == 1) {
*(int *) data = 100 * raidPtr->copyback_stripes_done / raidPtr->Layout.numStripe;
@@ -1141,6 +1351,23 @@ raidioctl(dev, cmd, data, flag, p)
}
return (0);
+ case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
+ progressInfoPtr = (RF_ProgressInfo_t **) data;
+ if (raidPtr->copyback_in_progress == 1) {
+ progressInfo.total = raidPtr->Layout.numStripe;
+ progressInfo.completed =
+ raidPtr->copyback_stripes_done;
+ progressInfo.remaining = progressInfo.total -
+ progressInfo.completed;
+ } else {
+ progressInfo.remaining = 0;
+ progressInfo.completed = 100;
+ progressInfo.total = 100;
+ }
+ retcode = copyout((caddr_t) &progressInfo,
+ (caddr_t) *progressInfoPtr,
+ sizeof(RF_ProgressInfo_t));
+ return (retcode);
/* the sparetable daemon calls this to wait for the kernel to
* need a spare table. this ioctl does not return until a
@@ -1266,16 +1493,14 @@ raidioctl(dev, cmd, data, flag, p)
RAIDframe device. */
-static int
-raidinit(dev, raidPtr, unit)
- dev_t dev;
+static void
+raidinit(raidPtr)
RF_Raid_t *raidPtr;
- int unit;
{
- int retcode;
struct raid_softc *rs;
+ int unit;
- retcode = 0;
+ unit = raidPtr->raidid;
rs = &raid_softc[unit];
pool_init(&rs->sc_cbufpool, sizeof(struct raidbuf), 0,
@@ -1299,9 +1524,7 @@ raidinit(dev, raidPtr, unit)
* protectedSectors, as used in RAIDframe. */
rs->sc_size = raidPtr->totalSectors;
- rs->sc_dev = dev;
- return (retcode);
}
/* wake up the daemon & tell it to get us a spare table
@@ -1360,32 +1583,30 @@ raidstart(raidPtr)
struct raid_softc *rs;
int do_async;
struct buf *bp;
- struct buf *dp;
unit = raidPtr->raidid;
rs = &raid_softc[unit];
+ /* quick check to see if anything has died recently */
+ RF_LOCK_MUTEX(raidPtr->mutex);
+ if (raidPtr->numNewFailures > 0) {
+ rf_update_component_labels(raidPtr,
+ RF_NORMAL_COMPONENT_UPDATE);
+ raidPtr->numNewFailures--;
+ }
+ RF_UNLOCK_MUTEX(raidPtr->mutex);
+
/* Check to see if we're at the limit... */
RF_LOCK_MUTEX(raidPtr->mutex);
while (raidPtr->openings > 0) {
RF_UNLOCK_MUTEX(raidPtr->mutex);
/* get the next item, if any, from the queue */
- dp = &rs->buf_queue;
- bp = dp->b_actf;
- if (bp == NULL) {
+ if ((bp = BUFQ_FIRST(&rs->buf_queue)) == NULL) {
/* nothing more to do */
return;
}
-
- /* update structures */
- dp = bp->b_actf;
- if (dp != NULL) {
- dp->b_actb = bp->b_actb;
- } else {
- rs->buf_queue.b_actb = bp->b_actb;
- }
- *bp->b_actb = dp;
+ BUFQ_REMOVE(&rs->buf_queue, bp);
/* Ok, for the bp we have here, bp->b_blkno is relative to the
* partition.. Need to make it absolute to the underlying
@@ -1456,13 +1677,12 @@ raidstart(raidPtr)
need to be? */
- retcode = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ?
- RF_IO_TYPE_READ : RF_IO_TYPE_WRITE,
- do_async, raid_addr, num_blocks,
- bp->b_un.b_addr, bp, NULL, NULL,
- RF_DAG_NONBLOCKING_IO, NULL, NULL, NULL);
-
-
+ retcode = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ?
+ RF_IO_TYPE_READ : RF_IO_TYPE_WRITE,
+ do_async, raid_addr, num_blocks,
+ bp->b_data, bp, NULL, NULL,
+ RF_DAG_NONBLOCKING_IO, NULL, NULL, NULL);
+
RF_LOCK_MUTEX(raidPtr->mutex);
}
RF_UNLOCK_MUTEX(raidPtr->mutex);
@@ -1600,7 +1820,7 @@ KernelWakeupFunc(vbp)
struct buf *bp;
struct raid_softc *rs;
int unit;
- register int s;
+ int s;
s = splbio();
db1_printf(("recovering the request queue:\n"));
@@ -1649,7 +1869,7 @@ KernelWakeupFunc(vbp)
rf_ds_failed;
queue->raidPtr->status[queue->row] = rf_rs_degraded;
queue->raidPtr->numFailures++;
- /* XXX here we should bump the version number for each component, and write that data out */
+ queue->raidPtr->numNewFailures++;
} else { /* Disk is already dead... */
/* printf("Disk already marked as dead!\n"); */
}
@@ -1677,18 +1897,19 @@ KernelWakeupFunc(vbp)
* initialize a buf structure for doing an I/O in the kernel.
*/
static void
-InitBP(
- struct buf * bp,
- struct vnode * b_vp,
- unsigned rw_flag,
- dev_t dev,
- RF_SectorNum_t startSect,
- RF_SectorCount_t numSect,
- caddr_t buf,
- void (*cbFunc) (struct buf *),
- void *cbArg,
- int logBytesPerSector,
- struct proc * b_proc)
+InitBP(bp, b_vp, rw_flag, dev, startSect, numSect, buf, cbFunc, cbArg,
+ logBytesPerSector, b_proc)
+ struct buf *bp;
+ struct vnode *b_vp;
+ unsigned rw_flag;
+ dev_t dev;
+ RF_SectorNum_t startSect;
+ RF_SectorCount_t numSect;
+ caddr_t buf;
+ void (*cbFunc) (struct buf *);
+ void *cbArg;
+ int logBytesPerSector;
+ struct proc *b_proc;
{
/* bp->b_flags = B_PHYS | rw_flag; */
bp->b_flags = B_CALL | rw_flag; /* XXX need B_PHYS here too??? */
@@ -1696,7 +1917,7 @@ InitBP(
bp->b_bufsize = bp->b_bcount;
bp->b_error = 0;
bp->b_dev = dev;
- bp->b_un.b_addr = buf;
+ bp->b_data = buf;
bp->b_blkno = startSect;
bp->b_resid = bp->b_bcount; /* XXX is this right!??!?!! */
if (bp->b_bcount == 0) {
@@ -1911,11 +2132,11 @@ raidunlock(rs)
int
raidmarkclean(dev_t dev, struct vnode *b_vp, int mod_counter)
{
- RF_ComponentLabel_t component_label;
- raidread_component_label(dev, b_vp, &component_label);
- component_label.mod_counter = mod_counter;
- component_label.clean = RF_RAID_CLEAN;
- raidwrite_component_label(dev, b_vp, &component_label);
+ RF_ComponentLabel_t clabel;
+ raidread_component_label(dev, b_vp, &clabel);
+ clabel.mod_counter = mod_counter;
+ clabel.clean = RF_RAID_CLEAN;
+ raidwrite_component_label(dev, b_vp, &clabel);
return(0);
}
@@ -1923,20 +2144,20 @@ raidmarkclean(dev_t dev, struct vnode *b_vp, int mod_counter)
int
raidmarkdirty(dev_t dev, struct vnode *b_vp, int mod_counter)
{
- RF_ComponentLabel_t component_label;
- raidread_component_label(dev, b_vp, &component_label);
- component_label.mod_counter = mod_counter;
- component_label.clean = RF_RAID_DIRTY;
- raidwrite_component_label(dev, b_vp, &component_label);
+ RF_ComponentLabel_t clabel;
+ raidread_component_label(dev, b_vp, &clabel);
+ clabel.mod_counter = mod_counter;
+ clabel.clean = RF_RAID_DIRTY;
+ raidwrite_component_label(dev, b_vp, &clabel);
return(0);
}
/* ARGSUSED */
int
-raidread_component_label(dev, b_vp, component_label)
+raidread_component_label(dev, b_vp, clabel)
dev_t dev;
struct vnode *b_vp;
- RF_ComponentLabel_t *component_label;
+ RF_ComponentLabel_t *clabel;
{
struct buf *bp;
int error;
@@ -1959,22 +2180,15 @@ raidread_component_label(dev, b_vp, component_label)
error = biowait(bp);
if (!error) {
- memcpy(component_label, bp->b_un.b_addr,
+ memcpy(clabel, bp->b_data,
sizeof(RF_ComponentLabel_t));
#if 0
- printf("raidread_component_label: got component label:\n");
- printf("Version: %d\n",component_label->version);
- printf("Serial Number: %d\n",component_label->serial_number);
- printf("Mod counter: %d\n",component_label->mod_counter);
- printf("Row: %d\n", component_label->row);
- printf("Column: %d\n", component_label->column);
- printf("Num Rows: %d\n", component_label->num_rows);
- printf("Num Columns: %d\n", component_label->num_columns);
- printf("Clean: %d\n", component_label->clean);
- printf("Status: %d\n", component_label->status);
+ rf_print_component_label( clabel );
#endif
} else {
+#if 0
printf("Failed to read RAID component label!\n");
+#endif
}
bp->b_flags = B_INVAL | B_AGE;
@@ -1983,10 +2197,10 @@ raidread_component_label(dev, b_vp, component_label)
}
/* ARGSUSED */
int
-raidwrite_component_label(dev, b_vp, component_label)
+raidwrite_component_label(dev, b_vp, clabel)
dev_t dev;
struct vnode *b_vp;
- RF_ComponentLabel_t *component_label;
+ RF_ComponentLabel_t *clabel;
{
struct buf *bp;
int error;
@@ -2001,26 +2215,28 @@ raidwrite_component_label(dev, b_vp, component_label)
bp->b_flags = B_BUSY | B_WRITE;
bp->b_resid = RF_COMPONENT_INFO_SIZE / DEV_BSIZE;
- memset( bp->b_un.b_addr, 0, RF_COMPONENT_INFO_SIZE );
+ memset(bp->b_data, 0, RF_COMPONENT_INFO_SIZE );
- memcpy( bp->b_un.b_addr, component_label, sizeof(RF_ComponentLabel_t));
+ memcpy(bp->b_data, clabel, sizeof(RF_ComponentLabel_t));
(*bdevsw[major(bp->b_dev)].d_strategy)(bp);
error = biowait(bp);
bp->b_flags = B_INVAL | B_AGE;
brelse(bp);
if (error) {
+#if 1
printf("Failed to write RAID component info!\n");
+#endif
}
return(error);
}
void
-rf_markalldirty( raidPtr )
+rf_markalldirty(raidPtr)
RF_Raid_t *raidPtr;
{
- RF_ComponentLabel_t c_label;
+ RF_ComponentLabel_t clabel;
int r,c;
raidPtr->mod_counter++;
@@ -2030,19 +2246,19 @@ rf_markalldirty( raidPtr )
raidread_component_label(
raidPtr->Disks[r][c].dev,
raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
- if (c_label.status == rf_ds_spared) {
+ &clabel);
+ if (clabel.status == rf_ds_spared) {
/* XXX do something special...
but whatever you do, don't
try to access it!! */
} else {
#if 0
- c_label.status =
+ clabel.status =
raidPtr->Disks[r][c].status;
raidwrite_component_label(
raidPtr->Disks[r][c].dev,
raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
+ &clabel);
#endif
raidmarkdirty(
raidPtr->Disks[r][c].dev,
@@ -2088,21 +2304,21 @@ rf_markalldirty( raidPtr )
raidread_component_label(
raidPtr->Disks[r][sparecol].dev,
raidPtr->raid_cinfo[r][sparecol].ci_vp,
- &c_label);
+ &clabel);
/* make sure status is noted */
- c_label.version = RF_COMPONENT_LABEL_VERSION;
- c_label.mod_counter = raidPtr->mod_counter;
- c_label.serial_number = raidPtr->serial_number;
- c_label.row = srow;
- c_label.column = scol;
- c_label.num_rows = raidPtr->numRow;
- c_label.num_columns = raidPtr->numCol;
- c_label.clean = RF_RAID_DIRTY; /* changed in a bit*/
- c_label.status = rf_ds_optimal;
+ clabel.version = RF_COMPONENT_LABEL_VERSION;
+ clabel.mod_counter = raidPtr->mod_counter;
+ clabel.serial_number = raidPtr->serial_number;
+ clabel.row = srow;
+ clabel.column = scol;
+ clabel.num_rows = raidPtr->numRow;
+ clabel.num_columns = raidPtr->numCol;
+ clabel.clean = RF_RAID_DIRTY; /* changed in a bit*/
+ clabel.status = rf_ds_optimal;
raidwrite_component_label(
raidPtr->Disks[r][sparecol].dev,
raidPtr->raid_cinfo[r][sparecol].ci_vp,
- &c_label);
+ &clabel);
raidmarkclean( raidPtr->Disks[r][sparecol].dev,
raidPtr->raid_cinfo[r][sparecol].ci_vp);
}
@@ -2113,10 +2329,11 @@ rf_markalldirty( raidPtr )
void
-rf_update_component_labels( raidPtr )
+rf_update_component_labels(raidPtr, final)
RF_Raid_t *raidPtr;
+ int final;
{
- RF_ComponentLabel_t c_label;
+ RF_ComponentLabel_t clabel;
int sparecol;
int r,c;
int i,j;
@@ -2136,43 +2353,26 @@ rf_update_component_labels( raidPtr )
raidread_component_label(
raidPtr->Disks[r][c].dev,
raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
+ &clabel);
/* make sure status is noted */
- c_label.status = rf_ds_optimal;
+ clabel.status = rf_ds_optimal;
+ /* bump the counter */
+ clabel.mod_counter = raidPtr->mod_counter;
+
raidwrite_component_label(
raidPtr->Disks[r][c].dev,
raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
- if (raidPtr->parity_good == RF_RAID_CLEAN) {
- raidmarkclean(
- raidPtr->Disks[r][c].dev,
- raidPtr->raid_cinfo[r][c].ci_vp,
- raidPtr->mod_counter);
+ &clabel);
+ if (final == RF_FINAL_COMPONENT_UPDATE) {
+ if (raidPtr->parity_good == RF_RAID_CLEAN) {
+ raidmarkclean(
+ raidPtr->Disks[r][c].dev,
+ raidPtr->raid_cinfo[r][c].ci_vp,
+ raidPtr->mod_counter);
+ }
}
}
/* else we don't touch it.. */
-#if 0
- else if (raidPtr->Disks[r][c].status !=
- rf_ds_failed) {
- raidread_component_label(
- raidPtr->Disks[r][c].dev,
- raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
- /* make sure status is noted */
- c_label.status =
- raidPtr->Disks[r][c].status;
- raidwrite_component_label(
- raidPtr->Disks[r][c].dev,
- raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
- if (raidPtr->parity_good == RF_RAID_CLEAN) {
- raidmarkclean(
- raidPtr->Disks[r][c].dev,
- raidPtr->raid_cinfo[r][c].ci_vp,
- raidPtr->mod_counter);
- }
- }
-#endif
}
}
@@ -2201,34 +2401,96 @@ rf_update_component_labels( raidPtr )
}
}
+ /* XXX shouldn't *really* need this... */
raidread_component_label(
raidPtr->Disks[0][sparecol].dev,
raidPtr->raid_cinfo[0][sparecol].ci_vp,
- &c_label);
+ &clabel);
/* make sure status is noted */
- c_label.version = RF_COMPONENT_LABEL_VERSION;
- c_label.mod_counter = raidPtr->mod_counter;
- c_label.serial_number = raidPtr->serial_number;
- c_label.row = srow;
- c_label.column = scol;
- c_label.num_rows = raidPtr->numRow;
- c_label.num_columns = raidPtr->numCol;
- c_label.clean = RF_RAID_DIRTY; /* changed in a bit*/
- c_label.status = rf_ds_optimal;
+
+ raid_init_component_label(raidPtr, &clabel);
+
+ clabel.mod_counter = raidPtr->mod_counter;
+ clabel.row = srow;
+ clabel.column = scol;
+ clabel.status = rf_ds_optimal;
+
raidwrite_component_label(
raidPtr->Disks[0][sparecol].dev,
raidPtr->raid_cinfo[0][sparecol].ci_vp,
- &c_label);
- if (raidPtr->parity_good == RF_RAID_CLEAN) {
- raidmarkclean( raidPtr->Disks[0][sparecol].dev,
- raidPtr->raid_cinfo[0][sparecol].ci_vp,
- raidPtr->mod_counter);
+ &clabel);
+ if (final == RF_FINAL_COMPONENT_UPDATE) {
+ if (raidPtr->parity_good == RF_RAID_CLEAN) {
+ raidmarkclean( raidPtr->Disks[0][sparecol].dev,
+ raidPtr->raid_cinfo[0][sparecol].ci_vp,
+ raidPtr->mod_counter);
+ }
}
}
}
/* printf("Component labels updated\n"); */
}
+void
+rf_close_component(raidPtr, vp, auto_configured)
+ RF_Raid_t *raidPtr;
+ struct vnode *vp;
+ int auto_configured;
+{
+ struct proc *p;
+
+ p = raidPtr->engine_thread;
+
+ if (vp != NULL) {
+ if (auto_configured == 1) {
+ VOP_CLOSE(vp, FREAD, NOCRED, 0);
+ vput(vp);
+
+ } else {
+ VOP_UNLOCK(vp, 0);
+ (void) vn_close(vp, FREAD | FWRITE, p->p_ucred, p);
+ }
+ } else {
+ printf("vnode was NULL\n");
+ }
+}
+
+
+void
+rf_UnconfigureVnodes(raidPtr)
+ RF_Raid_t *raidPtr;
+{
+ int r,c;
+ struct proc *p;
+ struct vnode *vp;
+ int acd;
+
+
+ /* We take this opportunity to close the vnodes like we should.. */
+
+ p = raidPtr->engine_thread;
+
+ for (r = 0; r < raidPtr->numRow; r++) {
+ for (c = 0; c < raidPtr->numCol; c++) {
+ printf("Closing vnode for row: %d col: %d\n", r, c);
+ vp = raidPtr->raid_cinfo[r][c].ci_vp;
+ acd = raidPtr->Disks[r][c].auto_configured;
+ rf_close_component(raidPtr, vp, acd);
+ raidPtr->raid_cinfo[r][c].ci_vp = NULL;
+ raidPtr->Disks[r][c].auto_configured = 0;
+ }
+ }
+ for (r = 0; r < raidPtr->numSpare; r++) {
+ printf("Closing vnode for spare: %d\n", r);
+ vp = raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp;
+ acd = raidPtr->Disks[0][raidPtr->numCol + r].auto_configured;
+ rf_close_component(raidPtr, vp, acd);
+ raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp = NULL;
+ raidPtr->Disks[0][raidPtr->numCol + r].auto_configured = 0;
+ }
+}
+
+
void
rf_ReconThread(req)
struct rf_recon_req *req;
@@ -2274,6 +2536,11 @@ rf_RewriteParityThread(raidPtr)
}
raidPtr->parity_rewrite_in_progress = 0;
+ /* Anyone waiting for us to stop? If so, inform them... */
+ if (raidPtr->waitShutdown) {
+ wakeup(&raidPtr->parity_rewrite_in_progress);
+ }
+
/* That's all... */
kthread_exit(0); /* does not return */
}
@@ -2315,3 +2582,700 @@ rf_ReconstructInPlaceThread(req)
/* That's all... */
kthread_exit(0); /* does not return */
}
+
+void
+rf_mountroot_hook(dev)
+ struct device *dev;
+{
+
+}
+
+
+RF_AutoConfig_t *
+rf_find_raid_components()
+{
+ struct devnametobdevmaj *dtobdm;
+ struct vnode *vp;
+ struct disklabel label;
+ struct device *dv;
+ char *cd_name;
+ dev_t dev;
+ int error;
+ int i;
+ int good_one;
+ RF_ComponentLabel_t *clabel;
+ RF_AutoConfig_t *ac_list;
+ RF_AutoConfig_t *ac;
+
+
+ /* initialize the AutoConfig list */
+ ac_list = NULL;
+
+if (raidautoconfig) {
+
+ /* we begin by trolling through *all* the devices on the system */
+
+ for (dv = alldevs.tqh_first; dv != NULL;
+ dv = dv->dv_list.tqe_next) {
+
+ /* we are only interested in disks... */
+ if (dv->dv_class != DV_DISK)
+ continue;
+
+ /* we don't care about floppies... */
+ if (!strcmp(dv->dv_cfdata->cf_driver->cd_name,"fd")) {
+ continue;
+ }
+
+ /* need to find the device_name_to_block_device_major stuff */
+ cd_name = dv->dv_cfdata->cf_driver->cd_name;
+ dtobdm = dev_name2blk;
+ while (dtobdm->d_name && strcmp(dtobdm->d_name, cd_name)) {
+ dtobdm++;
+ }
+
+ /* get a vnode for the raw partition of this disk */
+
+ dev = MAKEDISKDEV(dtobdm->d_maj, dv->dv_unit, RAW_PART);
+ if (bdevvp(dev, &vp))
+ panic("RAID can't alloc vnode");
+
+ error = VOP_OPEN(vp, FREAD, NOCRED, 0);
+
+ if (error) {
+ /* "Who cares." Continue looking
+ for something that exists*/
+ vput(vp);
+ continue;
+ }
+
+ /* Ok, the disk exists. Go get the disklabel. */
+ error = VOP_IOCTL(vp, DIOCGDINFO, (caddr_t)&label,
+ FREAD, NOCRED, 0);
+ if (error) {
+ /*
+ * XXX can't happen - open() would
+ * have errored out (or faked up one)
+ */
+ printf("can't get label for dev %s%c (%d)!?!?\n",
+ dv->dv_xname, 'a' + RAW_PART, error);
+ }
+
+ /* don't need this any more. We'll allocate it again
+ a little later if we really do... */
+ VOP_CLOSE(vp, FREAD, NOCRED, 0);
+ vput(vp);
+
+ for (i=0; i < label.d_npartitions; i++) {
+ /* We only support partitions marked as RAID */
+ if (label.d_partitions[i].p_fstype != FS_RAID)
+ continue;
+
+ dev = MAKEDISKDEV(dtobdm->d_maj, dv->dv_unit, i);
+ if (bdevvp(dev, &vp))
+ panic("RAID can't alloc vnode");
+
+ error = VOP_OPEN(vp, FREAD, NOCRED, 0);
+ if (error) {
+ /* Whatever... */
+ vput(vp);
+ continue;
+ }
+
+ good_one = 0;
+
+ clabel = (RF_ComponentLabel_t *)
+ malloc(sizeof(RF_ComponentLabel_t),
+ M_RAIDFRAME, M_NOWAIT);
+ if (clabel == NULL) {
+ /* XXX CLEANUP HERE */
+ printf("RAID auto config: out of memory!\n");
+ return(NULL); /* XXX probably should panic? */
+ }
+
+ if (!raidread_component_label(dev, vp, clabel)) {
+ /* Got the label. Does it look reasonable? */
+ if (rf_reasonable_label(clabel) &&
+ (clabel->partitionSize <=
+ label.d_partitions[i].p_size)) {
+#if DEBUG
+ printf("Component on: %s%c: %d\n",
+ dv->dv_xname, 'a'+i,
+ label.d_partitions[i].p_size);
+ rf_print_component_label(clabel);
+#endif
+ /* if it's reasonable, add it,
+ else ignore it. */
+ ac = (RF_AutoConfig_t *)
+ malloc(sizeof(RF_AutoConfig_t),
+ M_RAIDFRAME,
+ M_NOWAIT);
+ if (ac == NULL) {
+ /* XXX should panic?? */
+ return(NULL);
+ }
+
+ sprintf(ac->devname, "%s%c",
+ dv->dv_xname, 'a'+i);
+ ac->dev = dev;
+ ac->vp = vp;
+ ac->clabel = clabel;
+ ac->next = ac_list;
+ ac_list = ac;
+ good_one = 1;
+ }
+ }
+ if (!good_one) {
+ /* cleanup */
+ free(clabel, M_RAIDFRAME);
+ VOP_CLOSE(vp, FREAD, NOCRED, 0);
+ vput(vp);
+ }
+ }
+ }
+}
+return(ac_list);
+}
+
+static int
+rf_reasonable_label(clabel)
+ RF_ComponentLabel_t *clabel;
+{
+
+ if (((clabel->version==RF_COMPONENT_LABEL_VERSION_1) ||
+ (clabel->version==RF_COMPONENT_LABEL_VERSION)) &&
+ ((clabel->clean == RF_RAID_CLEAN) ||
+ (clabel->clean == RF_RAID_DIRTY)) &&
+ clabel->row >=0 &&
+ clabel->column >= 0 &&
+ clabel->num_rows > 0 &&
+ clabel->num_columns > 0 &&
+ clabel->row < clabel->num_rows &&
+ clabel->column < clabel->num_columns &&
+ clabel->blockSize > 0 &&
+ clabel->numBlocks > 0) {
+ /* label looks reasonable enough... */
+ return(1);
+ }
+ return(0);
+}
+
+
+void
+rf_print_component_label(clabel)
+ RF_ComponentLabel_t *clabel;
+{
+ printf(" Row: %d Column: %d Num Rows: %d Num Columns: %d\n",
+ clabel->row, clabel->column,
+ clabel->num_rows, clabel->num_columns);
+ printf(" Version: %d Serial Number: %d Mod Counter: %d\n",
+ clabel->version, clabel->serial_number,
+ clabel->mod_counter);
+ printf(" Clean: %s Status: %d\n",
+ clabel->clean ? "Yes" : "No", clabel->status );
+ printf(" sectPerSU: %d SUsPerPU: %d SUsPerRU: %d\n",
+ clabel->sectPerSU, clabel->SUsPerPU, clabel->SUsPerRU);
+ printf(" RAID Level: %c blocksize: %d numBlocks: %d\n",
+ (char) clabel->parityConfig, clabel->blockSize,
+ clabel->numBlocks);
+ printf(" Autoconfig: %s\n", clabel->autoconfigure ? "Yes" : "No" );
+ printf(" Contains root partition: %s\n",
+ clabel->root_partition ? "Yes" : "No" );
+ printf(" Last configured as: raid%d\n", clabel->last_unit );
+#if 0
+ printf(" Config order: %d\n", clabel->config_order);
+#endif
+
+}
+
+RF_ConfigSet_t *
+rf_create_auto_sets(ac_list)
+ RF_AutoConfig_t *ac_list;
+{
+ RF_AutoConfig_t *ac;
+ RF_ConfigSet_t *config_sets;
+ RF_ConfigSet_t *cset;
+ RF_AutoConfig_t *ac_next;
+
+
+ config_sets = NULL;
+
+ /* Go through the AutoConfig list, and figure out which components
+ belong to what sets. */
+ ac = ac_list;
+ while(ac!=NULL) {
+ /* we're going to putz with ac->next, so save it here
+ for use at the end of the loop */
+ ac_next = ac->next;
+
+ if (config_sets == NULL) {
+ /* will need at least this one... */
+ config_sets = (RF_ConfigSet_t *)
+ malloc(sizeof(RF_ConfigSet_t),
+ M_RAIDFRAME, M_NOWAIT);
+ if (config_sets == NULL) {
+ panic("rf_create_auto_sets: No memory!\n");
+ }
+ /* this one is easy :) */
+ config_sets->ac = ac;
+ config_sets->next = NULL;
+ config_sets->rootable = 0;
+ ac->next = NULL;
+ } else {
+ /* which set does this component fit into? */
+ cset = config_sets;
+ while(cset!=NULL) {
+ if (rf_does_it_fit(cset, ac)) {
+ /* looks like it matches... */
+ ac->next = cset->ac;
+ cset->ac = ac;
+ break;
+ }
+ cset = cset->next;
+ }
+ if (cset==NULL) {
+ /* didn't find a match above... new set..*/
+ cset = (RF_ConfigSet_t *)
+ malloc(sizeof(RF_ConfigSet_t),
+ M_RAIDFRAME, M_NOWAIT);
+ if (cset == NULL) {
+ panic("rf_create_auto_sets: No memory!\n");
+ }
+ cset->ac = ac;
+ ac->next = NULL;
+ cset->next = config_sets;
+ cset->rootable = 0;
+ config_sets = cset;
+ }
+ }
+ ac = ac_next;
+ }
+
+
+ return(config_sets);
+}
+
+static int
+rf_does_it_fit(cset, ac)
+ RF_ConfigSet_t *cset;
+ RF_AutoConfig_t *ac;
+{
+ RF_ComponentLabel_t *clabel1, *clabel2;
+
+ /* If this one matches the *first* one in the set, that's good
+ enough, since the other members of the set would have been
+ through here too... */
+ /* note that we are not checking partitionSize here..
+
+ Note that we are also not checking the mod_counters here.
+ If everything else matches execpt the mod_counter, that's
+ good enough for this test. We will deal with the mod_counters
+ a little later in the autoconfiguration process.
+
+ (clabel1->mod_counter == clabel2->mod_counter) &&
+
+ The reason we don't check for this is that failed disks
+ will have lower modification counts. If those disks are
+ not added to the set they used to belong to, then they will
+ form their own set, which may result in 2 different sets,
+ for example, competing to be configured at raid0, and
+ perhaps competing to be the root filesystem set. If the
+ wrong ones get configured, or both attempt to become /,
+ weird behaviour and or serious lossage will occur. Thus we
+ need to bring them into the fold here, and kick them out at
+ a later point.
+
+ */
+
+ clabel1 = cset->ac->clabel;
+ clabel2 = ac->clabel;
+ if ((clabel1->version == clabel2->version) &&
+ (clabel1->serial_number == clabel2->serial_number) &&
+ (clabel1->num_rows == clabel2->num_rows) &&
+ (clabel1->num_columns == clabel2->num_columns) &&
+ (clabel1->sectPerSU == clabel2->sectPerSU) &&
+ (clabel1->SUsPerPU == clabel2->SUsPerPU) &&
+ (clabel1->SUsPerRU == clabel2->SUsPerRU) &&
+ (clabel1->parityConfig == clabel2->parityConfig) &&
+ (clabel1->maxOutstanding == clabel2->maxOutstanding) &&
+ (clabel1->blockSize == clabel2->blockSize) &&
+ (clabel1->numBlocks == clabel2->numBlocks) &&
+ (clabel1->autoconfigure == clabel2->autoconfigure) &&
+ (clabel1->root_partition == clabel2->root_partition) &&
+ (clabel1->last_unit == clabel2->last_unit) &&
+ (clabel1->config_order == clabel2->config_order)) {
+ /* if it get's here, it almost *has* to be a match */
+ } else {
+ /* it's not consistent with somebody in the set..
+ punt */
+ return(0);
+ }
+ /* all was fine.. it must fit... */
+ return(1);
+}
+
+int
+rf_have_enough_components(cset)
+ RF_ConfigSet_t *cset;
+{
+ RF_AutoConfig_t *ac;
+ RF_AutoConfig_t *auto_config;
+ RF_ComponentLabel_t *clabel;
+ int r,c;
+ int num_rows;
+ int num_cols;
+ int num_missing;
+ int mod_counter;
+ int mod_counter_found;
+ int even_pair_failed;
+ char parity_type;
+
+
+ /* check to see that we have enough 'live' components
+ of this set. If so, we can configure it if necessary */
+
+ num_rows = cset->ac->clabel->num_rows;
+ num_cols = cset->ac->clabel->num_columns;
+ parity_type = cset->ac->clabel->parityConfig;
+
+ /* XXX Check for duplicate components!?!?!? */
+
+ /* Determine what the mod_counter is supposed to be for this set. */
+
+ mod_counter_found = 0;
+ ac = cset->ac;
+ while(ac!=NULL) {
+ if (mod_counter_found==0) {
+ mod_counter = ac->clabel->mod_counter;
+ mod_counter_found = 1;
+ } else {
+ if (ac->clabel->mod_counter > mod_counter) {
+ mod_counter = ac->clabel->mod_counter;
+ }
+ }
+ ac = ac->next;
+ }
+
+ num_missing = 0;
+ auto_config = cset->ac;
+
+ for(r=0; r<num_rows; r++) {
+ even_pair_failed = 0;
+ for(c=0; c<num_cols; c++) {
+ ac = auto_config;
+ while(ac!=NULL) {
+ if ((ac->clabel->row == r) &&
+ (ac->clabel->column == c) &&
+ (ac->clabel->mod_counter == mod_counter)) {
+ /* it's this one... */
+#if DEBUG
+ printf("Found: %s at %d,%d\n",
+ ac->devname,r,c);
+#endif
+ break;
+ }
+ ac=ac->next;
+ }
+ if (ac==NULL) {
+ /* Didn't find one here! */
+ /* special case for RAID 1, especially
+ where there are more than 2
+ components (where RAIDframe treats
+ things a little differently :( ) */
+ if (parity_type == '1') {
+ if (c%2 == 0) { /* even component */
+ even_pair_failed = 1;
+ } else { /* odd component. If
+ we're failed, and
+ so is the even
+ component, it's
+ "Good Night, Charlie" */
+ if (even_pair_failed == 1) {
+ return(0);
+ }
+ }
+ } else {
+ /* normal accounting */
+ num_missing++;
+ }
+ }
+ if ((parity_type == '1') && (c%2 == 1)) {
+ /* Just did an even component, and we didn't
+ bail.. reset the even_pair_failed flag,
+ and go on to the next component.... */
+ even_pair_failed = 0;
+ }
+ }
+ }
+
+ clabel = cset->ac->clabel;
+
+ if (((clabel->parityConfig == '0') && (num_missing > 0)) ||
+ ((clabel->parityConfig == '4') && (num_missing > 1)) ||
+ ((clabel->parityConfig == '5') && (num_missing > 1))) {
+ /* XXX this needs to be made *much* more general */
+ /* Too many failures */
+ return(0);
+ }
+ /* otherwise, all is well, and we've got enough to take a kick
+ at autoconfiguring this set */
+ return(1);
+}
+
+void
+rf_create_configuration(ac,config,raidPtr)
+ RF_AutoConfig_t *ac;
+ RF_Config_t *config;
+ RF_Raid_t *raidPtr;
+{
+ RF_ComponentLabel_t *clabel;
+ int i;
+
+ clabel = ac->clabel;
+
+ /* 1. Fill in the common stuff */
+ config->numRow = clabel->num_rows;
+ config->numCol = clabel->num_columns;
+ config->numSpare = 0; /* XXX should this be set here? */
+ config->sectPerSU = clabel->sectPerSU;
+ config->SUsPerPU = clabel->SUsPerPU;
+ config->SUsPerRU = clabel->SUsPerRU;
+ config->parityConfig = clabel->parityConfig;
+ /* XXX... */
+ strcpy(config->diskQueueType,"fifo");
+ config->maxOutstandingDiskReqs = clabel->maxOutstanding;
+ config->layoutSpecificSize = 0; /* XXX ?? */
+
+ while(ac!=NULL) {
+ /* row/col values will be in range due to the checks
+ in reasonable_label() */
+ strcpy(config->devnames[ac->clabel->row][ac->clabel->column],
+ ac->devname);
+ ac = ac->next;
+ }
+
+ for(i=0;i<RF_MAXDBGV;i++) {
+ config->debugVars[i][0] = NULL;
+ }
+}
+
+int
+rf_set_autoconfig(raidPtr, new_value)
+ RF_Raid_t *raidPtr;
+ int new_value;
+{
+ RF_ComponentLabel_t clabel;
+ struct vnode *vp;
+ dev_t dev;
+ int row, column;
+
+ raidPtr->autoconfigure = new_value;
+ for(row=0; row<raidPtr->numRow; row++) {
+ for(column=0; column<raidPtr->numCol; column++) {
+ if (raidPtr->Disks[row][column].status ==
+ rf_ds_optimal) {
+ dev = raidPtr->Disks[row][column].dev;
+ vp = raidPtr->raid_cinfo[row][column].ci_vp;
+ raidread_component_label(dev, vp, &clabel);
+ clabel.autoconfigure = new_value;
+ raidwrite_component_label(dev, vp, &clabel);
+ }
+ }
+ }
+ return(new_value);
+}
+
+int
+rf_set_rootpartition(raidPtr, new_value)
+ RF_Raid_t *raidPtr;
+ int new_value;
+{
+ RF_ComponentLabel_t clabel;
+ struct vnode *vp;
+ dev_t dev;
+ int row, column;
+
+ raidPtr->root_partition = new_value;
+ for(row=0; row<raidPtr->numRow; row++) {
+ for(column=0; column<raidPtr->numCol; column++) {
+ if (raidPtr->Disks[row][column].status ==
+ rf_ds_optimal) {
+ dev = raidPtr->Disks[row][column].dev;
+ vp = raidPtr->raid_cinfo[row][column].ci_vp;
+ raidread_component_label(dev, vp, &clabel);
+ clabel.root_partition = new_value;
+ raidwrite_component_label(dev, vp, &clabel);
+ }
+ }
+ }
+ return(new_value);
+}
+
+void
+rf_release_all_vps(cset)
+ RF_ConfigSet_t *cset;
+{
+ RF_AutoConfig_t *ac;
+
+ ac = cset->ac;
+ while(ac!=NULL) {
+ /* Close the vp, and give it back */
+ if (ac->vp) {
+ VOP_CLOSE(ac->vp, FREAD, NOCRED, 0);
+ vput(ac->vp);
+ ac->vp = NULL;
+ }
+ ac = ac->next;
+ }
+}
+
+
+void
+rf_cleanup_config_set(cset)
+ RF_ConfigSet_t *cset;
+{
+ RF_AutoConfig_t *ac;
+ RF_AutoConfig_t *next_ac;
+
+ ac = cset->ac;
+ while(ac!=NULL) {
+ next_ac = ac->next;
+ /* nuke the label */
+ free(ac->clabel, M_RAIDFRAME);
+ /* cleanup the config structure */
+ free(ac, M_RAIDFRAME);
+ /* "next.." */
+ ac = next_ac;
+ }
+ /* and, finally, nuke the config set */
+ free(cset, M_RAIDFRAME);
+}
+
+
+void
+raid_init_component_label(raidPtr, clabel)
+ RF_Raid_t *raidPtr;
+ RF_ComponentLabel_t *clabel;
+{
+ /* current version number */
+ clabel->version = RF_COMPONENT_LABEL_VERSION;
+ clabel->serial_number = raidPtr->serial_number;
+ clabel->mod_counter = raidPtr->mod_counter;
+ clabel->num_rows = raidPtr->numRow;
+ clabel->num_columns = raidPtr->numCol;
+ clabel->clean = RF_RAID_DIRTY; /* not clean */
+ clabel->status = rf_ds_optimal; /* "It's good!" */
+
+ clabel->sectPerSU = raidPtr->Layout.sectorsPerStripeUnit;
+ clabel->SUsPerPU = raidPtr->Layout.SUsPerPU;
+ clabel->SUsPerRU = raidPtr->Layout.SUsPerRU;
+
+ clabel->blockSize = raidPtr->bytesPerSector;
+ clabel->numBlocks = raidPtr->sectorsPerDisk;
+
+ /* XXX not portable */
+ clabel->parityConfig = raidPtr->Layout.map->parityConfig;
+ clabel->maxOutstanding = raidPtr->maxOutstanding;
+ clabel->autoconfigure = raidPtr->autoconfigure;
+ clabel->root_partition = raidPtr->root_partition;
+ clabel->last_unit = raidPtr->raidid;
+ clabel->config_order = raidPtr->config_order;
+}
+
+int
+rf_auto_config_set(cset,unit)
+ RF_ConfigSet_t *cset;
+ int *unit;
+{
+ RF_Raid_t *raidPtr;
+ RF_Config_t *config;
+ int raidID;
+ int retcode;
+
+ printf("RAID autoconfigure\n");
+
+ retcode = 0;
+ *unit = -1;
+
+ /* 1. Create a config structure */
+
+ config = (RF_Config_t *)malloc(sizeof(RF_Config_t),
+ M_RAIDFRAME,
+ M_NOWAIT);
+ if (config==NULL) {
+ printf("Out of mem!?!?\n");
+ /* XXX do something more intelligent here. */
+ return(1);
+ }
+
+ memset(config, 0, sizeof(RF_Config_t));
+
+ /* XXX raidID needs to be set correctly.. */
+
+ /*
+ 2. Figure out what RAID ID this one is supposed to live at
+ See if we can get the same RAID dev that it was configured
+ on last time..
+ */
+
+ raidID = cset->ac->clabel->last_unit;
+ if ((raidID < 0) || (raidID >= numraid)) {
+ /* let's not wander off into lala land. */
+ raidID = numraid - 1;
+ }
+ if (raidPtrs[raidID]->valid != 0) {
+
+ /*
+ Nope... Go looking for an alternative...
+ Start high so we don't immediately use raid0 if that's
+ not taken.
+ */
+
+ for(raidID = numraid; raidID >= 0; raidID--) {
+ if (raidPtrs[raidID]->valid == 0) {
+ /* can use this one! */
+ break;
+ }
+ }
+ }
+
+ if (raidID < 0) {
+ /* punt... */
+ printf("Unable to auto configure this set!\n");
+ printf("(Out of RAID devs!)\n");
+ return(1);
+ }
+ printf("Configuring raid%d:\n",raidID);
+ raidPtr = raidPtrs[raidID];
+
+ /* XXX all this stuff should be done SOMEWHERE ELSE! */
+ raidPtr->raidid = raidID;
+ raidPtr->openings = RAIDOUTSTANDING;
+
+ /* 3. Build the configuration structure */
+ rf_create_configuration(cset->ac, config, raidPtr);
+
+ /* 4. Do the configuration */
+ retcode = rf_Configure(raidPtr, config, cset->ac);
+
+ if (retcode == 0) {
+
+ raidinit(raidPtrs[raidID]);
+
+ rf_markalldirty(raidPtrs[raidID]);
+ raidPtrs[raidID]->autoconfigure = 1; /* XXX do this here? */
+ if (cset->ac->clabel->root_partition==1) {
+ /* everything configured just fine. Make a note
+ that this set is eligible to be root. */
+ cset->rootable = 1;
+ /* XXX do this here? */
+ raidPtrs[raidID]->root_partition = 1;
+ }
+ }
+
+ /* 5. Cleanup */
+ free(config, M_RAIDFRAME);
+
+ *unit = raidID;
+ return(retcode);
+}
diff --git a/sys/dev/raidframe/rf_nwayxor.c b/sys/dev/raidframe/rf_nwayxor.c
index 465827aeabc..df7604650fb 100644
--- a/sys/dev/raidframe/rf_nwayxor.c
+++ b/sys/dev/raidframe/rf_nwayxor.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_nwayxor.c,v 1.2 1999/02/16 00:03:00 niklas Exp $ */
-/* $NetBSD: rf_nwayxor.c,v 1.3 1999/02/05 00:06:13 oster Exp $ */
+/* $OpenBSD: rf_nwayxor.c,v 1.3 2000/08/08 16:07:43 peter Exp $ */
+/* $NetBSD: rf_nwayxor.c,v 1.4 2000/03/30 12:45:41 augustss Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -74,10 +74,10 @@ rf_nWayXor1(src_rbs, dest_rb, len)
RF_ReconBuffer_t *dest_rb;
int len;
{
- register unsigned long *src = (unsigned long *) src_rbs[0]->buffer;
- register unsigned long *dest = (unsigned long *) dest_rb->buffer;
- register unsigned long *end = src + len;
- register unsigned long d0, d1, d2, d3, s0, s1, s2, s3;
+ unsigned long *src = (unsigned long *) src_rbs[0]->buffer;
+ unsigned long *dest = (unsigned long *) dest_rb->buffer;
+ unsigned long *end = src + len;
+ unsigned long d0, d1, d2, d3, s0, s1, s2, s3;
callcount[1]++;
while (len >= 4) {
@@ -108,10 +108,10 @@ rf_nWayXor2(src_rbs, dest_rb, len)
RF_ReconBuffer_t *dest_rb;
int len;
{
- register unsigned long *dst = (unsigned long *) dest_rb->buffer;
- register unsigned long *a = dst;
- register unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
- register unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
+ unsigned long *dst = (unsigned long *) dest_rb->buffer;
+ unsigned long *a = dst;
+ unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
+ unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
callcount[2]++;
@@ -201,10 +201,10 @@ rf_nWayXor3(src_rbs, dest_rb, len)
RF_ReconBuffer_t *dest_rb;
int len;
{
- register unsigned long *dst = (unsigned long *) dest_rb->buffer;
- register unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
- register unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
- register unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
+ unsigned long *dst = (unsigned long *) dest_rb->buffer;
+ unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
+ unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
+ unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
callcount[3]++;
@@ -231,11 +231,11 @@ rf_nWayXor4(src_rbs, dest_rb, len)
RF_ReconBuffer_t *dest_rb;
int len;
{
- register unsigned long *dst = (unsigned long *) dest_rb->buffer;
- register unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
- register unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
- register unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
- register unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
+ unsigned long *dst = (unsigned long *) dest_rb->buffer;
+ unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
+ unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
+ unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
+ unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
callcount[4]++;
@@ -263,12 +263,12 @@ rf_nWayXor5(src_rbs, dest_rb, len)
RF_ReconBuffer_t *dest_rb;
int len;
{
- register unsigned long *dst = (unsigned long *) dest_rb->buffer;
- register unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
- register unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
- register unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
- register unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
- register unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
+ unsigned long *dst = (unsigned long *) dest_rb->buffer;
+ unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
+ unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
+ unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
+ unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
+ unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
callcount[5]++;
@@ -297,13 +297,13 @@ rf_nWayXor6(src_rbs, dest_rb, len)
RF_ReconBuffer_t *dest_rb;
int len;
{
- register unsigned long *dst = (unsigned long *) dest_rb->buffer;
- register unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
- register unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
- register unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
- register unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
- register unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
- register unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
+ unsigned long *dst = (unsigned long *) dest_rb->buffer;
+ unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
+ unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
+ unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
+ unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
+ unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
+ unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
callcount[6]++;
@@ -333,14 +333,14 @@ rf_nWayXor7(src_rbs, dest_rb, len)
RF_ReconBuffer_t *dest_rb;
int len;
{
- register unsigned long *dst = (unsigned long *) dest_rb->buffer;
- register unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
- register unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
- register unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
- register unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
- register unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
- register unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
- register unsigned long *h = (unsigned long *) src_rbs[6]->buffer;
+ unsigned long *dst = (unsigned long *) dest_rb->buffer;
+ unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
+ unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
+ unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
+ unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
+ unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
+ unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
+ unsigned long *h = (unsigned long *) src_rbs[6]->buffer;
unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
callcount[7]++;
@@ -371,15 +371,15 @@ rf_nWayXor8(src_rbs, dest_rb, len)
RF_ReconBuffer_t *dest_rb;
int len;
{
- register unsigned long *dst = (unsigned long *) dest_rb->buffer;
- register unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
- register unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
- register unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
- register unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
- register unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
- register unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
- register unsigned long *h = (unsigned long *) src_rbs[6]->buffer;
- register unsigned long *i = (unsigned long *) src_rbs[7]->buffer;
+ unsigned long *dst = (unsigned long *) dest_rb->buffer;
+ unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
+ unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
+ unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
+ unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
+ unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
+ unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
+ unsigned long *h = (unsigned long *) src_rbs[6]->buffer;
+ unsigned long *i = (unsigned long *) src_rbs[7]->buffer;
unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
callcount[8]++;
@@ -412,16 +412,16 @@ rf_nWayXor9(src_rbs, dest_rb, len)
RF_ReconBuffer_t *dest_rb;
int len;
{
- register unsigned long *dst = (unsigned long *) dest_rb->buffer;
- register unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
- register unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
- register unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
- register unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
- register unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
- register unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
- register unsigned long *h = (unsigned long *) src_rbs[6]->buffer;
- register unsigned long *i = (unsigned long *) src_rbs[7]->buffer;
- register unsigned long *j = (unsigned long *) src_rbs[8]->buffer;
+ unsigned long *dst = (unsigned long *) dest_rb->buffer;
+ unsigned long *b = (unsigned long *) src_rbs[0]->buffer;
+ unsigned long *c = (unsigned long *) src_rbs[1]->buffer;
+ unsigned long *d = (unsigned long *) src_rbs[2]->buffer;
+ unsigned long *e = (unsigned long *) src_rbs[3]->buffer;
+ unsigned long *f = (unsigned long *) src_rbs[4]->buffer;
+ unsigned long *g = (unsigned long *) src_rbs[5]->buffer;
+ unsigned long *h = (unsigned long *) src_rbs[6]->buffer;
+ unsigned long *i = (unsigned long *) src_rbs[7]->buffer;
+ unsigned long *j = (unsigned long *) src_rbs[8]->buffer;
unsigned long a0, a1, a2, a3, b0, b1, b2, b3;
callcount[9]++;
diff --git a/sys/dev/raidframe/rf_openbsd.h b/sys/dev/raidframe/rf_openbsd.h
index 59feb987ed3..17333cb9647 100644
--- a/sys/dev/raidframe/rf_openbsd.h
+++ b/sys/dev/raidframe/rf_openbsd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rf_openbsd.h,v 1.3 1999/07/30 14:45:32 peter Exp $ */
+/* $OpenBSD: rf_openbsd.h,v 1.4 2000/08/08 16:07:43 peter Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -105,6 +105,33 @@ typedef struct RF_ComponentLabel_s {
int num_columns; /* number of columns in this RAID set */
int clean; /* 1 when clean, 0 when dirty */
int status; /* rf_ds_optimal, rf_ds_dist_spared, whatever. */
+ /* stuff that will be in version 2 of the label */
+ int sectPerSU; /* Sectors per Stripe Unit */
+ int SUsPerPU; /* Stripe Units per Parity Units */
+ int SUsPerRU; /* Stripe Units per Reconstruction Units */
+ int parityConfig; /* '0' == RAID0, '1' == RAID1, etc. */
+ int maxOutstanding; /* maxOutstanding disk requests */
+ int blockSize; /* size of component block.
+ (disklabel->d_secsize) */
+ int numBlocks; /* number of blocks on this component. May
+ be smaller than the partition size. */
+ int partitionSize; /* number of blocks on this *partition*.
+ Must exactly match the partition size
+ from the disklabel. */
+ int future_use[33]; /* Future expansion */
+ int autoconfigure; /* automatically configure this RAID set.
+ 0 == no, 1 == yes */
+ int root_partition; /* Use this set as /
+ 0 == no, 1 == yes*/
+ int last_unit; /* last unit number (e.g. 0 for /dev/raid0)
+ of this component. Used for autoconfigure
+ only. */
+ int config_order; /* 0 .. n. The order in which the component
+ should be auto-configured. E.g. 0 is will
+ done first, (and would become raid0).
+ This may be in conflict with last_unit!!?! */
+ /* Not currently used. */
+ int future_use2[44]; /* More future expansion */
} RF_ComponentLabel_t;
typedef struct RF_SingleComponent_s {
@@ -115,11 +142,6 @@ typedef struct RF_SingleComponent_s {
#ifdef _KERNEL
-/* XXX this is *not* the place for these... */
-int rf_add_hot_spare(RF_Raid_t *raidPtr, RF_SingleComponent_t *sparePtr);
-int rf_remove_hot_spare(RF_Raid_t *raidPtr, RF_SingleComponent_t *sparePtr);
-
-
struct raidcinfo {
struct vnode *ci_vp; /* component device's vnode */
dev_t ci_dev; /* component device's dev_t */
@@ -131,5 +153,24 @@ struct raidcinfo {
#endif
};
+/* XXX probably belongs in a different .h file. */
+typedef struct RF_AutoConfig_s {
+ char devname[56]; /* the name of this component */
+ int flag; /* a general-purpose flag */
+ dev_t dev; /* the device for this component */
+ struct vnode *vp; /* Mr. Vnode Pointer */
+ RF_ComponentLabel_t *clabel; /* the label */
+ struct RF_AutoConfig_s *next; /* the next autoconfig structure
+ in this set. */
+} RF_AutoConfig_t;
+
+typedef struct RF_ConfigSet_s {
+ struct RF_AutoConfig_s *ac; /* all of the autoconfig structures for
+ this config set. */
+ int rootable; /* Set to 1 if this set can be root */
+ struct RF_ConfigSet_s *next;
+} RF_ConfigSet_t;
+
+
#endif /* _KERNEL */
#endif /* _RF__RF_OPENBSD_H_ */
diff --git a/sys/dev/raidframe/rf_openbsdkintf.c b/sys/dev/raidframe/rf_openbsdkintf.c
index 8ad4dc3364c..268eff0a015 100644
--- a/sys/dev/raidframe/rf_openbsdkintf.c
+++ b/sys/dev/raidframe/rf_openbsdkintf.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_openbsdkintf.c,v 1.9 2000/01/11 18:02:22 peter Exp $ */
-/* $NetBSD: rf_netbsdkintf.c,v 1.46 2000/01/09 03:39:13 oster Exp $ */
+/* $OpenBSD: rf_openbsdkintf.c,v 1.10 2000/08/08 16:07:43 peter Exp $ */
+/* $NetBSD: rf_netbsdkintf.c,v 1.93 2000/07/14 15:26:29 oster Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -130,6 +130,7 @@
#include <sys/lock.h>
#include <sys/buf.h>
#include <sys/user.h>
+#include <sys/reboot.h>
#include "raid.h"
#include "rf_raid.h"
@@ -148,6 +149,7 @@
#include "rf_parityscan.h"
#include "rf_debugprint.h"
#include "rf_threadstuff.h"
+#include "rf_configure.h"
int rf_kdebug_level = 0;
@@ -172,7 +174,7 @@ void rf_KernelWakeupFunc __P((struct buf *));
void rf_InitBP __P((struct buf *, struct vnode *, unsigned, dev_t,
RF_SectorNum_t, RF_SectorCount_t, caddr_t, void (*)(struct buf *),
void *, int, struct proc *));
-static int raidinit __P((dev_t, RF_Raid_t *, int));
+static void raidinit __P((RF_Raid_t *));
void raidattach __P((int));
int raidsize __P((dev_t));
@@ -199,16 +201,15 @@ struct raidbuf {
/*
* XXX Not sure if the following should be replacing the raidPtrs above,
- * or if it should be used in conjunction with that...
- */
+ or if it should be used in conjunction with that...
+*/
struct raid_softc {
int sc_flags; /* flags */
int sc_cflags; /* configuration flags */
size_t sc_size; /* size of the raid device */
- dev_t sc_dev; /* our device..*/
char sc_xname[20]; /* XXX external name */
struct disk sc_dkdev; /* generic disk device info */
- struct buf buf_queue; /* used for the device queue */
+ struct buf sc_q; /* used for the device queue */
};
/* sc_flags */
@@ -219,7 +220,7 @@ struct raid_softc {
#define RAIDF_LOCKED 0x80 /* unit is locked */
#define raidunit(x) DISKUNIT(x)
-static int numraid = 0;
+int numraid = 0;
/*
* Allow RAIDOUTSTANDING number of simultaneous IO's to this RAID device.
@@ -257,6 +258,9 @@ int raidlock __P((struct raid_softc *));
void raidunlock __P((struct raid_softc *));
void rf_markalldirty __P((RF_Raid_t *));
+void rf_mountroot_hook __P((struct device *));
+
+struct device *raidrootdev;
void rf_ReconThread __P((struct rf_recon_req *));
/* XXX what I want is: */
@@ -264,6 +268,30 @@ void rf_ReconThread __P((struct rf_recon_req *));
void rf_RewriteParityThread __P((RF_Raid_t *raidPtr));
void rf_CopybackThread __P((RF_Raid_t *raidPtr));
void rf_ReconstructInPlaceThread __P((struct rf_recon_req *));
+#ifdef RAID_AUTOCONFIG
+void rf_buildroothack __P((void *));
+static int rf_reasonable_label __P((RF_ComponentLabel_t *));
+#endif
+
+RF_AutoConfig_t *rf_find_raid_components __P((void));
+RF_ConfigSet_t *rf_create_auto_sets __P((RF_AutoConfig_t *));
+static int rf_does_it_fit __P((RF_ConfigSet_t *,RF_AutoConfig_t *));
+void rf_create_configuration __P((RF_AutoConfig_t *,RF_Config_t *,
+ RF_Raid_t *));
+int rf_set_autoconfig __P((RF_Raid_t *, int));
+int rf_set_rootpartition __P((RF_Raid_t *, int));
+void rf_release_all_vps __P((RF_ConfigSet_t *));
+void rf_cleanup_config_set __P((RF_ConfigSet_t *));
+int rf_have_enough_components __P((RF_ConfigSet_t *));
+int rf_auto_config_set __P((RF_ConfigSet_t *, int *));
+
+#ifdef RAID_AUTOCONFIG
+static int raidautoconfig = 0; /* Debugging, mostly. Set to 0 to not
+ allow autoconfig to take place.
+ Note that this is overridden by having
+ RAID_AUTOCONFIG as an option in the
+ kernel config file. */
+#endif
void
raidattach(num)
@@ -271,6 +299,10 @@ raidattach(num)
{
int raidID;
int i, rc;
+#ifdef RAID_AUTOCONFIG
+ RF_AutoConfig_t *ac_list; /* autoconfig list */
+ RF_ConfigSet_t *config_sets;
+#endif
db1_printf(("raidattach: Asked for %d units\n", num));
@@ -283,6 +315,8 @@ raidattach(num)
/* This is where all the initialization stuff gets done. */
+ numraid = num;
+
/* Make some space for requested number of units... */
RF_Calloc(raidPtrs, num, sizeof(RF_Raid_t *), (RF_Raid_t **));
if (raidPtrs == NULL) {
@@ -296,7 +330,7 @@ raidattach(num)
rf_sparet_wait_queue = rf_sparet_resp_queue = NULL;
- for (i = 0; i < numraid; i++)
+ for (i = 0; i < num; i++)
raidPtrs[i] = NULL;
rc = rf_BootRaidframe();
if (rc == 0)
@@ -310,18 +344,33 @@ raidattach(num)
*/
raid_softc = (struct raid_softc *)
- malloc(num * sizeof (struct raid_softc), M_RAIDFRAME, M_NOWAIT);
+ malloc(num * sizeof(struct raid_softc),
+ M_RAIDFRAME, M_NOWAIT);
if (raid_softc == NULL) {
printf("WARNING: no memory for RAIDframe driver\n");
return;
}
- numraid = num;
+
bzero(raid_softc, num * sizeof (struct raid_softc));
+ raidrootdev = (struct device *)malloc(num * sizeof(struct device),
+ M_RAIDFRAME, M_NOWAIT);
+ if (raidrootdev == NULL) {
+ panic("No memory for RAIDframe driver!!?!?!\n");
+ }
+
for (raidID = 0; raidID < num; raidID++) {
- raid_softc[raidID].buf_queue.b_actf = NULL;
- raid_softc[raidID].buf_queue.b_actb =
- &raid_softc[raidID].buf_queue.b_actf;
+#if 0
+ SIMPLEQ_INIT(&raid_softc[raidID].sc_q);
+#endif
+
+ raidrootdev[raidID].dv_class = DV_DISK;
+ raidrootdev[raidID].dv_cfdata = NULL;
+ raidrootdev[raidID].dv_unit = raidID;
+ raidrootdev[raidID].dv_parent = NULL;
+ raidrootdev[raidID].dv_flags = 0;
+ sprintf(raidrootdev[raidID].dv_xname,"raid%d",raidID);
+
RF_Calloc(raidPtrs[raidID], 1, sizeof (RF_Raid_t),
(RF_Raid_t *));
if (raidPtrs[raidID] == NULL) {
@@ -330,7 +379,93 @@ raidattach(num)
return;
}
}
+
+#if RAID_AUTOCONFIG
+ raidautoconfig = 1;
+
+if (raidautoconfig) {
+ /* 1. locate all RAID components on the system */
+
+#if DEBUG
+ printf("Searching for raid components...\n");
+#endif
+ ac_list = rf_find_raid_components();
+
+ /* 2. sort them into their respective sets */
+
+ config_sets = rf_create_auto_sets(ac_list);
+
+ /* 3. evaluate each set and configure the valid ones
+ This gets done in rf_buildroothack() */
+
+ /* schedule the creation of the thread to do the
+ "/ on RAID" stuff */
+
+ kthread_create(rf_buildroothack, config_sets, NULL, "raidauto");
+
+#if 0
+ mountroothook_establish(rf_mountroot_hook, &raidrootdev[0]);
+#endif
+}
+#endif
+
+}
+
+#ifdef RAID_AUTOCONFIG
+void
+rf_buildroothack(arg)
+ void *arg;
+{
+ RF_ConfigSet_t *config_sets = arg;
+ RF_ConfigSet_t *cset;
+ RF_ConfigSet_t *next_cset;
+ int retcode;
+ int raidID;
+ int rootID;
+ int num_root;
+
+ num_root = 0;
+ cset = config_sets;
+ while(cset != NULL ) {
+ next_cset = cset->next;
+ if (rf_have_enough_components(cset) &&
+ cset->ac->clabel->autoconfigure==1) {
+ retcode = rf_auto_config_set(cset,&raidID);
+ if (!retcode) {
+ if (cset->rootable) {
+ rootID = raidID;
+ num_root++;
+ }
+ } else {
+ /* The autoconfig didn't work :( */
+#if DEBUG
+ printf("Autoconfig failed with code %d for raid%d\n", retcode, raidID);
+#endif
+ rf_release_all_vps(cset);
+ }
+ } else {
+ /* we're not autoconfiguring this set...
+ release the associated resources */
+ rf_release_all_vps(cset);
+ }
+ /* cleanup */
+ rf_cleanup_config_set(cset);
+ cset = next_cset;
+ }
+ if (boothowto & RB_ASKNAME) {
+ /* We don't auto-config... */
+ } else {
+ /* They didn't ask, and we found something bootable... */
+
+ if (num_root == 1) {
+ booted_device = &raidrootdev[rootID];
+ } else if (num_root > 1) {
+ /* we can't guess.. require the user to answer... */
+ boothowto |= RB_ASKNAME;
+ }
+ }
}
+#endif
int
raidsize(dev)
@@ -496,7 +631,11 @@ raidclose(dev, flags, fmt, p)
Device shutdown has taken care of setting the
clean bits if RAIDF_INITED is not set
mark things as clean... */
- rf_update_component_labels( raidPtrs[unit] );
+#if 0
+ printf("Last one on raid%d. Updating status.\n",unit);
+#endif
+ rf_update_component_labels(raidPtrs[unit],
+ RF_FINAL_COMPONENT_UPDATE);
}
raidunlock(rs);
@@ -513,7 +652,6 @@ raidstrategy(bp)
RF_Raid_t *raidPtr;
struct raid_softc *rs = &raid_softc[raidID];
struct disklabel *lp;
- struct buf *dp;
int wlabel;
if ((rs->sc_flags & RAIDF_INITED) ==0) {
@@ -563,14 +701,10 @@ raidstrategy(bp)
bp->b_resid = 0;
- /* stuff it onto our queue */
+ bp->b_actf = rs->sc_q.b_actf;
+ rs->sc_q.b_actf = bp;
+ rs->sc_q.b_active++;
- dp = &rs->buf_queue;
- bp->b_actf = NULL;
- bp->b_actb = dp->b_actb;
- *dp->b_actb = bp;
- dp->b_actb = &bp->b_actf;
-
raidstart(raidPtrs[raidID]);
splx(s);
@@ -634,6 +768,7 @@ raidioctl(dev, cmd, data, flag, p)
struct raid_softc *rs;
RF_Config_t *k_cfg, *u_cfg;
RF_Raid_t *raidPtr;
+ RF_RaidDisk_t *diskPtr;
RF_AccTotals_t *totals;
RF_DeviceConfig_t *d_cfg, **ucfgp;
u_char *specific_buf;
@@ -641,12 +776,13 @@ raidioctl(dev, cmd, data, flag, p)
int row;
int column;
struct rf_recon_req *rrcopy, *rr;
- RF_ComponentLabel_t *component_label;
+ RF_ComponentLabel_t *clabel;
RF_ComponentLabel_t ci_label;
- RF_ComponentLabel_t **c_label_ptr;
+ RF_ComponentLabel_t **clabel_ptr;
RF_SingleComponent_t *sparePtr,*componentPtr;
RF_SingleComponent_t hot_spare;
RF_SingleComponent_t component;
+ RF_ProgressInfo_t progressInfo, **progressInfoPtr;
int i, j, d;
if (unit >= numraid)
@@ -673,6 +809,7 @@ raidioctl(dev, cmd, data, flag, p)
case DIOCWDINFO:
case DIOCGPART:
case DIOCWLABEL:
+ case DIOCGPDINFO:
case RAIDFRAME_SHUTDOWN:
case RAIDFRAME_REWRITEPARITY:
case RAIDFRAME_GET_INFO:
@@ -683,6 +820,7 @@ raidioctl(dev, cmd, data, flag, p)
case RAIDFRAME_FAIL_DISK:
case RAIDFRAME_COPYBACK:
case RAIDFRAME_CHECK_RECON_STATUS:
+ case RAIDFRAME_CHECK_RECON_STATUS_EXT:
case RAIDFRAME_GET_COMPONENT_LABEL:
case RAIDFRAME_SET_COMPONENT_LABEL:
case RAIDFRAME_ADD_HOT_SPARE:
@@ -691,7 +829,13 @@ raidioctl(dev, cmd, data, flag, p)
case RAIDFRAME_REBUILD_IN_PLACE:
case RAIDFRAME_CHECK_PARITY:
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
+ case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
case RAIDFRAME_CHECK_COPYBACK_STATUS:
+ case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
+ case RAIDFRAME_SET_AUTOCONFIG:
+ case RAIDFRAME_SET_ROOT:
+ case RAIDFRAME_DELETE_COMPONENT:
+ case RAIDFRAME_INCORPORATE_HOT_SPARE:
if ((rs->sc_flags & RAIDF_INITED) == 0)
return (ENXIO);
}
@@ -699,6 +843,13 @@ raidioctl(dev, cmd, data, flag, p)
switch (cmd) {
/* Configure the system */
case RAIDFRAME_CONFIGURE:
+
+ if (raidPtr->valid) {
+ /* There is a valid RAID set running on this unit! */
+ printf("raid%d: Device already configured!\n",unit);
+ return(EINVAL);
+ }
+
/*
* Copy-in the configuration information
* data points to a pointer to the configuration structure.
@@ -749,25 +900,26 @@ raidioctl(dev, cmd, data, flag, p)
* Store the sum of all the bytes in the last byte?
*/
+ /*
+ * Clear the entire RAID descriptor, just to make sure
+ * there is no stale data left in the case of a
+ * reconfiguration
+ */
+ bzero((char *) raidPtr, sizeof(RF_Raid_t));
+
/* configure the system */
raidPtr->raidid = unit;
- retcode = rf_Configure(raidPtr, k_cfg);
+ retcode = rf_Configure(raidPtr, k_cfg, NULL);
if (retcode == 0) {
/* allow this many simultaneous IO's to
this RAID device */
raidPtr->openings = RAIDOUTSTANDING;
-
- /* XXX should be moved to rf_Configure() */
-
- raidPtr->copyback_in_progress = 0;
- raidPtr->parity_rewrite_in_progress = 0;
- raidPtr->recon_in_progress = 0;
-
- retcode = raidinit(dev, raidPtr, unit);
- rf_markalldirty( raidPtr );
+
+ raidinit(raidPtr);
+ rf_markalldirty(raidPtr);
}
/* Free the buffers. No return code here. */
@@ -811,29 +963,29 @@ raidioctl(dev, cmd, data, flag, p)
return (retcode);
case RAIDFRAME_GET_COMPONENT_LABEL:
- c_label_ptr = (RF_ComponentLabel_t **) data;
+ clabel_ptr = (RF_ComponentLabel_t **) data;
/* need to read the component label for the disk indicated
- by row,column in component_label */
+ by row,column in clabel */
/* For practice, let's get it directly fromdisk, rather
than from the in-core copy */
- RF_Malloc( component_label, sizeof( RF_ComponentLabel_t ),
+ RF_Malloc( clabel, sizeof( RF_ComponentLabel_t ),
(RF_ComponentLabel_t *));
- if (component_label == NULL)
+ if (clabel == NULL)
return (ENOMEM);
- bzero((char *) component_label, sizeof(RF_ComponentLabel_t));
+ bzero((char *) clabel, sizeof(RF_ComponentLabel_t));
- retcode = copyin( *c_label_ptr, component_label,
+ retcode = copyin( *clabel_ptr, clabel,
sizeof(RF_ComponentLabel_t));
if (retcode) {
- RF_Free( component_label, sizeof(RF_ComponentLabel_t));
+ RF_Free( clabel, sizeof(RF_ComponentLabel_t));
return(retcode);
}
- row = component_label->row;
- column = component_label->column;
+ row = clabel->row;
+ column = clabel->column;
if ((row < 0) || (row >= raidPtr->numRow) ||
(column < 0) || (column >= raidPtr->numCol)) {
@@ -843,16 +995,16 @@ raidioctl(dev, cmd, data, flag, p)
raidread_component_label(
raidPtr->Disks[row][column].dev,
raidPtr->raid_cinfo[row][column].ci_vp,
- component_label );
+ clabel );
- retcode = copyout((caddr_t) component_label,
- (caddr_t) *c_label_ptr,
+ retcode = copyout((caddr_t) clabel,
+ (caddr_t) *clabel_ptr,
sizeof(RF_ComponentLabel_t));
- RF_Free( component_label, sizeof(RF_ComponentLabel_t));
+ RF_Free( clabel, sizeof(RF_ComponentLabel_t));
return (retcode);
case RAIDFRAME_SET_COMPONENT_LABEL:
- component_label = (RF_ComponentLabel_t *) data;
+ clabel = (RF_ComponentLabel_t *) data;
/* XXX check the label for valid stuff... */
/* Note that some things *should not* get modified --
@@ -861,22 +1013,22 @@ raidioctl(dev, cmd, data, flag, p)
*/
printf("Got component label:\n");
- printf("Version: %d\n",component_label->version);
- printf("Serial Number: %d\n",component_label->serial_number);
- printf("Mod counter: %d\n",component_label->mod_counter);
- printf("Row: %d\n", component_label->row);
- printf("Column: %d\n", component_label->column);
- printf("Num Rows: %d\n", component_label->num_rows);
- printf("Num Columns: %d\n", component_label->num_columns);
- printf("Clean: %d\n", component_label->clean);
- printf("Status: %d\n", component_label->status);
-
- row = component_label->row;
- column = component_label->column;
+ printf("Version: %d\n",clabel->version);
+ printf("Serial Number: %d\n",clabel->serial_number);
+ printf("Mod counter: %d\n",clabel->mod_counter);
+ printf("Row: %d\n", clabel->row);
+ printf("Column: %d\n", clabel->column);
+ printf("Num Rows: %d\n", clabel->num_rows);
+ printf("Num Columns: %d\n", clabel->num_columns);
+ printf("Clean: %d\n", clabel->clean);
+ printf("Status: %d\n", clabel->status);
+
+ row = clabel->row;
+ column = clabel->column;
if ((row < 0) || (row >= raidPtr->numRow) ||
(column < 0) || (column >= raidPtr->numCol)) {
- RF_Free( component_label, sizeof(RF_ComponentLabel_t));
+ RF_Free( clabel, sizeof(RF_ComponentLabel_t));
return(EINVAL);
}
@@ -885,12 +1037,12 @@ raidioctl(dev, cmd, data, flag, p)
raidwrite_component_label(
raidPtr->Disks[row][column].dev,
raidPtr->raid_cinfo[row][column].ci_vp,
- component_label );
+ clabel );
#endif
return (0);
case RAIDFRAME_INIT_LABELS:
- component_label = (RF_ComponentLabel_t *) data;
+ clabel = (RF_ComponentLabel_t *) data;
/*
we only want the serial number from
the above. We get all the rest of the information
@@ -898,19 +1050,16 @@ raidioctl(dev, cmd, data, flag, p)
set.
*/
- raidPtr->serial_number = component_label->serial_number;
- /* current version number */
- ci_label.version = RF_COMPONENT_LABEL_VERSION;
- ci_label.serial_number = component_label->serial_number;
- ci_label.mod_counter = raidPtr->mod_counter;
- ci_label.num_rows = raidPtr->numRow;
- ci_label.num_columns = raidPtr->numCol;
- ci_label.clean = RF_RAID_DIRTY; /* not clean */
- ci_label.status = rf_ds_optimal; /* "It's good!" */
+ raidPtr->serial_number = clabel->serial_number;
+
+ raid_init_component_label(raidPtr, &ci_label);
+ ci_label.serial_number = clabel->serial_number;
for(row=0;row<raidPtr->numRow;row++) {
ci_label.row = row;
for(column=0;column<raidPtr->numCol;column++) {
+ diskPtr = &raidPtr->Disks[row][column];
+ ci_label.partitionSize = diskPtr->partitionSize;
ci_label.column = column;
raidwrite_component_label(
raidPtr->Disks[row][column].dev,
@@ -940,18 +1089,42 @@ raidioctl(dev, cmd, data, flag, p)
raidPtr,"raid_parity");
return (retcode);
+ case RAIDFRAME_SET_AUTOCONFIG:
+ d = rf_set_autoconfig(raidPtr, *(int *) data);
+ printf("New autoconfig value is: %d\n", d);
+ *(int *) data = d;
+ return (retcode);
+
+ case RAIDFRAME_SET_ROOT:
+ d = rf_set_rootpartition(raidPtr, *(int *) data);
+ printf("New rootpartition value is: %d\n", d);
+ *(int *) data = d;
+ return (retcode);
case RAIDFRAME_ADD_HOT_SPARE:
sparePtr = (RF_SingleComponent_t *) data;
memcpy( &hot_spare, sparePtr, sizeof(RF_SingleComponent_t));
- printf("Adding spare\n");
retcode = rf_add_hot_spare(raidPtr, &hot_spare);
return(retcode);
case RAIDFRAME_REMOVE_HOT_SPARE:
return(retcode);
+ case RAIDFRAME_DELETE_COMPONENT:
+ componentPtr = (RF_SingleComponent_t *)data;
+ memcpy( &component, componentPtr,
+ sizeof(RF_SingleComponent_t));
+ retcode = rf_delete_component(raidPtr, &component);
+ return(retcode);
+
+ case RAIDFRAME_INCORPORATE_HOT_SPARE:
+ componentPtr = (RF_SingleComponent_t *)data;
+ memcpy( &component, componentPtr,
+ sizeof(RF_SingleComponent_t));
+ retcode = rf_incorporate_hot_spare(raidPtr, &component);
+ return(retcode);
+
case RAIDFRAME_REBUILD_IN_PLACE:
if (raidPtr->Layout.map->faultsTolerated == 0) {
@@ -1096,8 +1269,10 @@ raidioctl(dev, cmd, data, flag, p)
/* Return the percentage completion of reconstruction */
case RAIDFRAME_CHECK_RECON_STATUS:
if (raidPtr->Layout.map->faultsTolerated == 0) {
- /* This makes no sense on a RAID 0 */
- return(EINVAL);
+ /* This makes no sense on a RAID 0, so tell the
+ user it's done. */
+ *(int *) data = 100;
+ return(0);
}
row = 0; /* XXX we only consider a single row... */
if (raidPtr->status[row] != rf_rs_reconstructing)
@@ -1106,22 +1281,66 @@ raidioctl(dev, cmd, data, flag, p)
*(int *)data =
raidPtr->reconControl[row]->percentComplete;
return (0);
+
+ case RAIDFRAME_CHECK_RECON_STATUS_EXT:
+ progressInfoPtr = (RF_ProgressInfo_t **) data;
+ row = 0; /* XXX we only consider a single row... */
+ if (raidPtr->status[row] != rf_rs_reconstructing) {
+ progressInfo.remaining = 0;
+ progressInfo.completed = 100;
+ progressInfo.total = 100;
+ } else {
+ progressInfo.total =
+ raidPtr->reconControl[row]->numRUsTotal;
+ progressInfo.completed =
+ raidPtr->reconControl[row]->numRUsComplete;
+ progressInfo.remaining = progressInfo.total -
+ progressInfo.completed;
+ }
+ retcode = copyout((caddr_t) &progressInfo,
+ (caddr_t) *progressInfoPtr,
+ sizeof(RF_ProgressInfo_t));
+ return (retcode);
+
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
if (raidPtr->Layout.map->faultsTolerated == 0) {
- /* This makes no sense on a RAID 0 */
- return(EINVAL);
+ /* This makes no sense on a RAID 0, so tell the
+ user it's done. */
+ *(int *) data = 100;
+ return(0);
}
if (raidPtr->parity_rewrite_in_progress == 1) {
- *(int *) data = 100 * raidPtr->parity_rewrite_stripes_done / raidPtr->Layout.numStripe;
+ *(int *) data = 100 *
+ raidPtr->parity_rewrite_stripes_done /
+ raidPtr->Layout.numStripe;
} else {
*(int *) data = 100;
}
return (0);
+ case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
+ progressInfoPtr = (RF_ProgressInfo_t **) data;
+ if (raidPtr->parity_rewrite_in_progress == 1) {
+ progressInfo.total = raidPtr->Layout.numStripe;
+ progressInfo.completed =
+ raidPtr->parity_rewrite_stripes_done;
+ progressInfo.remaining = progressInfo.total -
+ progressInfo.completed;
+ } else {
+ progressInfo.remaining = 0;
+ progressInfo.completed = 100;
+ progressInfo.total = 100;
+ }
+ retcode = copyout((caddr_t) &progressInfo,
+ (caddr_t) *progressInfoPtr,
+ sizeof(RF_ProgressInfo_t));
+ return (retcode);
+
case RAIDFRAME_CHECK_COPYBACK_STATUS:
if (raidPtr->Layout.map->faultsTolerated == 0) {
/* This makes no sense on a RAID 0 */
- return(EINVAL);
+ *(int *) data = 100;
+ return(0);
}
if (raidPtr->copyback_in_progress == 1) {
*(int *) data = 100 * raidPtr->copyback_stripes_done / raidPtr->Layout.numStripe;
@@ -1130,6 +1349,24 @@ raidioctl(dev, cmd, data, flag, p)
}
return (0);
+ case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
+ progressInfoPtr = (RF_ProgressInfo_t **) data;
+ if (raidPtr->copyback_in_progress == 1) {
+ progressInfo.total = raidPtr->Layout.numStripe;
+ progressInfo.completed =
+ raidPtr->copyback_stripes_done;
+ progressInfo.remaining = progressInfo.total -
+ progressInfo.completed;
+ } else {
+ progressInfo.remaining = 0;
+ progressInfo.completed = 100;
+ progressInfo.total = 100;
+ }
+ retcode = copyout((caddr_t) &progressInfo,
+ (caddr_t) *progressInfoPtr,
+ sizeof(RF_ProgressInfo_t));
+ return (retcode);
+
#if 0
case RAIDFRAME_SPARET_WAIT:
/*
@@ -1250,10 +1487,11 @@ raidioctl(dev, cmd, data, flag, p)
#if 0
case DIOCGDEFLABEL:
+#endif
+ case DIOCGPDINFO:
raidgetdefaultlabel(raidPtr, rs,
(struct disklabel *) data);
break;
-#endif
default:
@@ -1266,16 +1504,14 @@ raidioctl(dev, cmd, data, flag, p)
* raidinit -- complete the rest of the initialization for the
* RAIDframe device.
*/
-int
-raidinit(dev, raidPtr, unit)
- dev_t dev;
+static void
+raidinit(raidPtr)
RF_Raid_t *raidPtr;
- int unit;
{
- int retcode;
struct raid_softc *rs;
+ int unit;
- retcode = 0;
+ unit = raidPtr->raidid;
rs = &raid_softc[unit];
@@ -1299,8 +1535,6 @@ raidinit(dev, raidPtr, unit)
* protectedSectors, as used in RAIDframe.
*/
rs->sc_size = raidPtr->totalSectors;
- rs->sc_dev = dev;
- return (retcode);
}
/*
@@ -1361,34 +1595,31 @@ raidstart(raidPtr)
struct raid_softc *rs;
int do_async;
struct buf *bp;
- struct buf *dp;
unit = raidPtr->raidid;
rs = &raid_softc[unit];
-
+ /* quick check to see if anything has died recently */
+ RF_LOCK_MUTEX(raidPtr->mutex);
+ if (raidPtr->numNewFailures > 0) {
+ rf_update_component_labels(raidPtr,
+ RF_NORMAL_COMPONENT_UPDATE);
+ raidPtr->numNewFailures--;
+ }
+ RF_UNLOCK_MUTEX(raidPtr->mutex);
+
/* Check to see if we're at the limit... */
RF_LOCK_MUTEX(raidPtr->mutex);
while (raidPtr->openings > 0) {
RF_UNLOCK_MUTEX(raidPtr->mutex);
- /* get the next item, if any, from the queue */
- dp = &rs->buf_queue;
- bp = dp->b_actf;
+ bp = rs->sc_q.b_actf;
if (bp == NULL) {
/* nothing more to do */
return;
}
-
- /* update structures */
- dp = bp->b_actf;
- if (dp != NULL) {
- dp->b_actb = bp->b_actb;
- } else {
- rs->buf_queue.b_actb = bp->b_actb;
- }
- *bp->b_actb = dp;
-
+ rs->sc_q.b_actf = bp->b_actf;
+
/* Ok, for the bp we have here, bp->b_blkno is relative to the
* partition.. Need to make it absolute to the underlying
* device.. */
@@ -1457,14 +1688,12 @@ raidstart(raidPtr)
/* XXX we're still at splbio() here... do we *really*
need to be? */
-
retcode = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ?
RF_IO_TYPE_READ : RF_IO_TYPE_WRITE,
do_async, raid_addr, num_blocks,
- bp->b_un.b_addr, bp, NULL, NULL,
+ bp->b_data, bp, NULL, NULL,
RF_DAG_NONBLOCKING_IO, NULL, NULL, NULL);
-
RF_LOCK_MUTEX(raidPtr->mutex);
}
RF_UNLOCK_MUTEX(raidPtr->mutex);
@@ -1671,7 +1900,7 @@ rf_KernelWakeupFunc(vbp)
rf_ds_failed;
queue->raidPtr->status[queue->row] = rf_rs_degraded;
queue->raidPtr->numFailures++;
- /* XXX here we should bump the version number for each component, and write that data out */
+ queue->raidPtr->numNewFailures++;
} else {
/* Disk is already dead... */
/* printf("Disk already marked as dead!\n"); */
@@ -1716,7 +1945,7 @@ rf_InitBP(bp, b_vp, rw_flag, dev, startSect, numSect, buf, cbFunc, cbArg,
bp->b_bufsize = bp->b_bcount;
bp->b_error = 0;
bp->b_dev = dev;
- bp->b_un.b_addr = buf;
+ bp->b_data = buf;
bp->b_blkno = startSect;
bp->b_resid = bp->b_bcount; /* XXX is this right!??!?!! */
if (bp->b_bcount == 0) {
@@ -1761,7 +1990,6 @@ raidgetdefaultlabel(raidPtr, rs, lp)
lp->d_magic = DISKMAGIC;
lp->d_magic2 = DISKMAGIC;
lp->d_checksum = dkcksum(rs->sc_dkdev.dk_label);
-
}
/*
@@ -1778,6 +2006,8 @@ raidgetdisklabel(dev)
struct disklabel *lp = rs->sc_dkdev.dk_label;
struct cpu_disklabel *clp = rs->sc_dkdev.dk_cpulabel;
RF_Raid_t *raidPtr;
+ int i;
+ struct partition *pp;
db1_printf(("Getting the disklabel...\n"));
@@ -1790,34 +2020,33 @@ raidgetdisklabel(dev)
/*
* Call the generic disklabel extraction routine.
*/
- errstring = readdisklabel(RAIDLABELDEV(dev), raidstrategy,
- rs->sc_dkdev.dk_label, rs->sc_dkdev.dk_cpulabel, 0);
- if (errstring)
- raidmakedisklabel(rs);
- else {
- int i;
- struct partition *pp;
+ errstring = readdisklabel(RAIDLABELDEV(dev), raidstrategy, lp,
+ rs->sc_dkdev.dk_cpulabel, 0);
+ if (errstring) {
+ printf("%s: %s\n", rs->sc_xname, errstring);
+ return;
+ /*raidmakedisklabel(rs); */
+ }
- /*
- * Sanity check whether the found disklabel is valid.
- *
- * This is necessary since total size of the raid device
- * may vary when an interleave is changed even though exactly
- * same componets are used, and old disklabel may used
- * if that is found.
- */
- if (lp->d_secperunit != rs->sc_size)
- printf("WARNING: %s: "
- "total sector size in disklabel (%d) != "
- "the size of raid (%ld)\n", rs->sc_xname,
- lp->d_secperunit, (long) rs->sc_size);
- for (i = 0; i < lp->d_npartitions; i++) {
- pp = &lp->d_partitions[i];
- if (pp->p_offset + pp->p_size > rs->sc_size)
- printf("WARNING: %s: end of partition `%c' "
- "exceeds the size of raid (%ld)\n",
- rs->sc_xname, 'a' + i, (long) rs->sc_size);
- }
+ /*
+ * Sanity check whether the found disklabel is valid.
+ *
+ * This is necessary since total size of the raid device
+ * may vary when an interleave is changed even though exactly
+ * same componets are used, and old disklabel may used
+ * if that is found.
+ */
+ if (lp->d_secperunit != rs->sc_size)
+ printf("WARNING: %s: "
+ "total sector size in disklabel (%d) != "
+ "the size of raid (%ld)\n", rs->sc_xname,
+ lp->d_secperunit, (long) rs->sc_size);
+ for (i = 0; i < lp->d_npartitions; i++) {
+ pp = &lp->d_partitions[i];
+ if (pp->p_offset + pp->p_size > rs->sc_size)
+ printf("WARNING: %s: end of partition `%c' "
+ "exceeds the size of raid (%ld)\n",
+ rs->sc_xname, 'a' + i, (long) rs->sc_size);
}
}
@@ -1933,11 +2162,11 @@ raidunlock(rs)
int
raidmarkclean(dev_t dev, struct vnode *b_vp, int mod_counter)
{
- RF_ComponentLabel_t component_label;
- raidread_component_label(dev, b_vp, &component_label);
- component_label.mod_counter = mod_counter;
- component_label.clean = RF_RAID_CLEAN;
- raidwrite_component_label(dev, b_vp, &component_label);
+ RF_ComponentLabel_t clabel;
+ raidread_component_label(dev, b_vp, &clabel);
+ clabel.mod_counter = mod_counter;
+ clabel.clean = RF_RAID_CLEAN;
+ raidwrite_component_label(dev, b_vp, &clabel);
return(0);
}
@@ -1945,20 +2174,20 @@ raidmarkclean(dev_t dev, struct vnode *b_vp, int mod_counter)
int
raidmarkdirty(dev_t dev, struct vnode *b_vp, int mod_counter)
{
- RF_ComponentLabel_t component_label;
- raidread_component_label(dev, b_vp, &component_label);
- component_label.mod_counter = mod_counter;
- component_label.clean = RF_RAID_DIRTY;
- raidwrite_component_label(dev, b_vp, &component_label);
+ RF_ComponentLabel_t clabel;
+ raidread_component_label(dev, b_vp, &clabel);
+ clabel.mod_counter = mod_counter;
+ clabel.clean = RF_RAID_DIRTY;
+ raidwrite_component_label(dev, b_vp, &clabel);
return(0);
}
/* ARGSUSED */
int
-raidread_component_label(dev, b_vp, component_label)
+raidread_component_label(dev, b_vp, clabel)
dev_t dev;
struct vnode *b_vp;
- RF_ComponentLabel_t *component_label;
+ RF_ComponentLabel_t *clabel;
{
struct buf *bp;
int error;
@@ -1981,22 +2210,15 @@ raidread_component_label(dev, b_vp, component_label)
error = biowait(bp);
if (!error) {
- memcpy(component_label, bp->b_un.b_addr,
+ memcpy(clabel, bp->b_data,
sizeof(RF_ComponentLabel_t));
#if 0
- printf("raidread_component_label: got component label:\n");
- printf("Version: %d\n",component_label->version);
- printf("Serial Number: %d\n",component_label->serial_number);
- printf("Mod counter: %d\n",component_label->mod_counter);
- printf("Row: %d\n", component_label->row);
- printf("Column: %d\n", component_label->column);
- printf("Num Rows: %d\n", component_label->num_rows);
- printf("Num Columns: %d\n", component_label->num_columns);
- printf("Clean: %d\n", component_label->clean);
- printf("Status: %d\n", component_label->status);
+ rf_print_component_label( clabel );
#endif
} else {
+#if 0
printf("Failed to read RAID component label!\n");
+#endif
}
bp->b_flags = B_INVAL | B_AGE;
@@ -2005,10 +2227,10 @@ raidread_component_label(dev, b_vp, component_label)
}
/* ARGSUSED */
int
-raidwrite_component_label(dev, b_vp, component_label)
+raidwrite_component_label(dev, b_vp, clabel)
dev_t dev;
struct vnode *b_vp;
- RF_ComponentLabel_t *component_label;
+ RF_ComponentLabel_t *clabel;
{
struct buf *bp;
int error;
@@ -2023,26 +2245,28 @@ raidwrite_component_label(dev, b_vp, component_label)
bp->b_flags = B_BUSY | B_WRITE;
bp->b_resid = RF_COMPONENT_INFO_SIZE / DEV_BSIZE;
- memset( bp->b_un.b_addr, 0, RF_COMPONENT_INFO_SIZE );
+ memset(bp->b_data, 0, RF_COMPONENT_INFO_SIZE );
- memcpy( bp->b_un.b_addr, component_label, sizeof(RF_ComponentLabel_t));
+ memcpy(bp->b_data, clabel, sizeof(RF_ComponentLabel_t));
(*bdevsw[major(bp->b_dev)].d_strategy)(bp);
error = biowait(bp);
bp->b_flags = B_INVAL | B_AGE;
brelse(bp);
if (error) {
+#if 1
printf("Failed to write RAID component info!\n");
+#endif
}
return(error);
}
void
-rf_markalldirty( raidPtr )
+rf_markalldirty(raidPtr)
RF_Raid_t *raidPtr;
{
- RF_ComponentLabel_t c_label;
+ RF_ComponentLabel_t clabel;
int r,c;
raidPtr->mod_counter++;
@@ -2052,19 +2276,19 @@ rf_markalldirty( raidPtr )
raidread_component_label(
raidPtr->Disks[r][c].dev,
raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
- if (c_label.status == rf_ds_spared) {
+ &clabel);
+ if (clabel.status == rf_ds_spared) {
/* XXX do something special...
but whatever you do, don't
try to access it!! */
} else {
#if 0
- c_label.status =
+ clabel.status =
raidPtr->Disks[r][c].status;
raidwrite_component_label(
raidPtr->Disks[r][c].dev,
raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
+ &clabel);
#endif
raidmarkdirty(
raidPtr->Disks[r][c].dev,
@@ -2110,21 +2334,21 @@ rf_markalldirty( raidPtr )
raidread_component_label(
raidPtr->Disks[r][sparecol].dev,
raidPtr->raid_cinfo[r][sparecol].ci_vp,
- &c_label);
+ &clabel);
/* make sure status is noted */
- c_label.version = RF_COMPONENT_LABEL_VERSION;
- c_label.mod_counter = raidPtr->mod_counter;
- c_label.serial_number = raidPtr->serial_number;
- c_label.row = srow;
- c_label.column = scol;
- c_label.num_rows = raidPtr->numRow;
- c_label.num_columns = raidPtr->numCol;
- c_label.clean = RF_RAID_DIRTY; /* changed in a bit*/
- c_label.status = rf_ds_optimal;
+ clabel.version = RF_COMPONENT_LABEL_VERSION;
+ clabel.mod_counter = raidPtr->mod_counter;
+ clabel.serial_number = raidPtr->serial_number;
+ clabel.row = srow;
+ clabel.column = scol;
+ clabel.num_rows = raidPtr->numRow;
+ clabel.num_columns = raidPtr->numCol;
+ clabel.clean = RF_RAID_DIRTY; /* changed in a bit*/
+ clabel.status = rf_ds_optimal;
raidwrite_component_label(
raidPtr->Disks[r][sparecol].dev,
raidPtr->raid_cinfo[r][sparecol].ci_vp,
- &c_label);
+ &clabel);
raidmarkclean( raidPtr->Disks[r][sparecol].dev,
raidPtr->raid_cinfo[r][sparecol].ci_vp);
}
@@ -2135,10 +2359,11 @@ rf_markalldirty( raidPtr )
void
-rf_update_component_labels( raidPtr )
+rf_update_component_labels(raidPtr, final)
RF_Raid_t *raidPtr;
+ int final;
{
- RF_ComponentLabel_t c_label;
+ RF_ComponentLabel_t clabel;
int sparecol;
int r,c;
int i,j;
@@ -2158,43 +2383,26 @@ rf_update_component_labels( raidPtr )
raidread_component_label(
raidPtr->Disks[r][c].dev,
raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
+ &clabel);
/* make sure status is noted */
- c_label.status = rf_ds_optimal;
+ clabel.status = rf_ds_optimal;
+ /* bump the counter */
+ clabel.mod_counter = raidPtr->mod_counter;
+
raidwrite_component_label(
raidPtr->Disks[r][c].dev,
raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
- if (raidPtr->parity_good == RF_RAID_CLEAN) {
- raidmarkclean(
- raidPtr->Disks[r][c].dev,
- raidPtr->raid_cinfo[r][c].ci_vp,
- raidPtr->mod_counter);
+ &clabel);
+ if (final == RF_FINAL_COMPONENT_UPDATE) {
+ if (raidPtr->parity_good == RF_RAID_CLEAN) {
+ raidmarkclean(
+ raidPtr->Disks[r][c].dev,
+ raidPtr->raid_cinfo[r][c].ci_vp,
+ raidPtr->mod_counter);
+ }
}
}
/* else we don't touch it.. */
-#if 0
- else if (raidPtr->Disks[r][c].status !=
- rf_ds_failed) {
- raidread_component_label(
- raidPtr->Disks[r][c].dev,
- raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
- /* make sure status is noted */
- c_label.status =
- raidPtr->Disks[r][c].status;
- raidwrite_component_label(
- raidPtr->Disks[r][c].dev,
- raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
- if (raidPtr->parity_good == RF_RAID_CLEAN) {
- raidmarkclean(
- raidPtr->Disks[r][c].dev,
- raidPtr->raid_cinfo[r][c].ci_vp,
- raidPtr->mod_counter);
- }
- }
-#endif
}
}
@@ -2223,34 +2431,96 @@ rf_update_component_labels( raidPtr )
}
}
+ /* XXX shouldn't *really* need this... */
raidread_component_label(
raidPtr->Disks[0][sparecol].dev,
raidPtr->raid_cinfo[0][sparecol].ci_vp,
- &c_label);
+ &clabel);
/* make sure status is noted */
- c_label.version = RF_COMPONENT_LABEL_VERSION;
- c_label.mod_counter = raidPtr->mod_counter;
- c_label.serial_number = raidPtr->serial_number;
- c_label.row = srow;
- c_label.column = scol;
- c_label.num_rows = raidPtr->numRow;
- c_label.num_columns = raidPtr->numCol;
- c_label.clean = RF_RAID_DIRTY; /* changed in a bit*/
- c_label.status = rf_ds_optimal;
+
+ raid_init_component_label(raidPtr, &clabel);
+
+ clabel.mod_counter = raidPtr->mod_counter;
+ clabel.row = srow;
+ clabel.column = scol;
+ clabel.status = rf_ds_optimal;
+
raidwrite_component_label(
raidPtr->Disks[0][sparecol].dev,
raidPtr->raid_cinfo[0][sparecol].ci_vp,
- &c_label);
- if (raidPtr->parity_good == RF_RAID_CLEAN) {
- raidmarkclean( raidPtr->Disks[0][sparecol].dev,
- raidPtr->raid_cinfo[0][sparecol].ci_vp,
- raidPtr->mod_counter);
+ &clabel);
+ if (final == RF_FINAL_COMPONENT_UPDATE) {
+ if (raidPtr->parity_good == RF_RAID_CLEAN) {
+ raidmarkclean( raidPtr->Disks[0][sparecol].dev,
+ raidPtr->raid_cinfo[0][sparecol].ci_vp,
+ raidPtr->mod_counter);
+ }
}
}
}
/* printf("Component labels updated\n"); */
}
+void
+rf_close_component(raidPtr, vp, auto_configured)
+ RF_Raid_t *raidPtr;
+ struct vnode *vp;
+ int auto_configured;
+{
+ struct proc *p;
+
+ p = raidPtr->engine_thread;
+
+ if (vp != NULL) {
+ if (auto_configured == 1) {
+ VOP_CLOSE(vp, FREAD, NOCRED, 0);
+ vput(vp);
+
+ } else {
+ VOP_UNLOCK(vp, 0, p);
+ (void) vn_close(vp, FREAD | FWRITE, p->p_ucred, p);
+ }
+ } else {
+ printf("vnode was NULL\n");
+ }
+}
+
+
+void
+rf_UnconfigureVnodes(raidPtr)
+ RF_Raid_t *raidPtr;
+{
+ int r,c;
+ struct proc *p;
+ struct vnode *vp;
+ int acd;
+
+
+ /* We take this opportunity to close the vnodes like we should.. */
+
+ p = raidPtr->engine_thread;
+
+ for (r = 0; r < raidPtr->numRow; r++) {
+ for (c = 0; c < raidPtr->numCol; c++) {
+ printf("Closing vnode for row: %d col: %d\n", r, c);
+ vp = raidPtr->raid_cinfo[r][c].ci_vp;
+ acd = raidPtr->Disks[r][c].auto_configured;
+ rf_close_component(raidPtr, vp, acd);
+ raidPtr->raid_cinfo[r][c].ci_vp = NULL;
+ raidPtr->Disks[r][c].auto_configured = 0;
+ }
+ }
+ for (r = 0; r < raidPtr->numSpare; r++) {
+ printf("Closing vnode for spare: %d\n", r);
+ vp = raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp;
+ acd = raidPtr->Disks[0][raidPtr->numCol + r].auto_configured;
+ rf_close_component(raidPtr, vp, acd);
+ raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp = NULL;
+ raidPtr->Disks[0][raidPtr->numCol + r].auto_configured = 0;
+ }
+}
+
+
void
rf_ReconThread(req)
struct rf_recon_req *req;
@@ -2296,6 +2566,11 @@ rf_RewriteParityThread(raidPtr)
}
raidPtr->parity_rewrite_in_progress = 0;
+ /* Anyone waiting for us to stop? If so, inform them... */
+ if (raidPtr->waitShutdown) {
+ wakeup(&raidPtr->parity_rewrite_in_progress);
+ }
+
/* That's all... */
kthread_exit(0); /* does not return */
}
@@ -2337,3 +2612,705 @@ rf_ReconstructInPlaceThread(req)
/* That's all... */
kthread_exit(0); /* does not return */
}
+
+void
+rf_mountroot_hook(dev)
+ struct device *dev;
+{
+
+}
+
+
+RF_AutoConfig_t *
+rf_find_raid_components()
+{
+#ifdef RAID_AUTOCONFIG
+ struct devnametobdevmaj *dtobdm;
+ struct vnode *vp;
+ struct disklabel label;
+ struct device *dv;
+ char *cd_name;
+ dev_t dev;
+ int error;
+ int i;
+ int good_one;
+ RF_ComponentLabel_t *clabel;
+ RF_AutoConfig_t *ac;
+#endif
+ RF_AutoConfig_t *ac_list;
+
+
+ /* initialize the AutoConfig list */
+ ac_list = NULL;
+
+#if RAID_AUTOCONFIG
+if (raidautoconfig) {
+
+ /* we begin by trolling through *all* the devices on the system */
+
+ for (dv = alldevs.tqh_first; dv != NULL;
+ dv = dv->dv_list.tqe_next) {
+
+ /* we are only interested in disks... */
+ if (dv->dv_class != DV_DISK)
+ continue;
+
+ /* we don't care about floppies... */
+ if (!strcmp(dv->dv_cfdata->cf_driver->cd_name,"fd")) {
+ continue;
+ }
+
+ /* need to find the device_name_to_block_device_major stuff */
+ cd_name = dv->dv_cfdata->cf_driver->cd_name;
+ dtobdm = dev_name2blk;
+ while (dtobdm->d_name && strcmp(dtobdm->d_name, cd_name)) {
+ dtobdm++;
+ }
+
+ /* get a vnode for the raw partition of this disk */
+
+ dev = MAKEDISKDEV(dtobdm->d_maj, dv->dv_unit, RAW_PART);
+ if (bdevvp(dev, &vp))
+ panic("RAID can't alloc vnode");
+
+ error = VOP_OPEN(vp, FREAD, NOCRED, 0);
+
+ if (error) {
+ /* "Who cares." Continue looking
+ for something that exists*/
+ vput(vp);
+ continue;
+ }
+
+ /* Ok, the disk exists. Go get the disklabel. */
+ error = VOP_IOCTL(vp, DIOCGDINFO, (caddr_t)&label,
+ FREAD, NOCRED, 0);
+ if (error) {
+ /*
+ * XXX can't happen - open() would
+ * have errored out (or faked up one)
+ */
+ printf("can't get label for dev %s%c (%d)!?!?\n",
+ dv->dv_xname, 'a' + RAW_PART, error);
+ }
+
+ /* don't need this any more. We'll allocate it again
+ a little later if we really do... */
+ VOP_CLOSE(vp, FREAD, NOCRED, 0);
+ vput(vp);
+
+ for (i=0; i < label.d_npartitions; i++) {
+ /* We only support partitions marked as RAID */
+ if (label.d_partitions[i].p_fstype != FS_RAID)
+ continue;
+
+ dev = MAKEDISKDEV(dtobdm->d_maj, dv->dv_unit, i);
+ if (bdevvp(dev, &vp))
+ panic("RAID can't alloc vnode");
+
+ error = VOP_OPEN(vp, FREAD, NOCRED, 0);
+ if (error) {
+ /* Whatever... */
+ vput(vp);
+ continue;
+ }
+
+ good_one = 0;
+
+ clabel = (RF_ComponentLabel_t *)
+ malloc(sizeof(RF_ComponentLabel_t),
+ M_RAIDFRAME, M_NOWAIT);
+ if (clabel == NULL) {
+ /* XXX CLEANUP HERE */
+ printf("RAID auto config: out of memory!\n");
+ return(NULL); /* XXX probably should panic? */
+ }
+
+ if (!raidread_component_label(dev, vp, clabel)) {
+ /* Got the label. Does it look reasonable? */
+ if (rf_reasonable_label(clabel) &&
+ (clabel->partitionSize <=
+ label.d_partitions[i].p_size)) {
+#if DEBUG
+ printf("Component on: %s%c: %d\n",
+ dv->dv_xname, 'a'+i,
+ label.d_partitions[i].p_size);
+ rf_print_component_label(clabel);
+#endif
+ /* if it's reasonable, add it,
+ else ignore it. */
+ ac = (RF_AutoConfig_t *)
+ malloc(sizeof(RF_AutoConfig_t),
+ M_RAIDFRAME,
+ M_NOWAIT);
+ if (ac == NULL) {
+ /* XXX should panic?? */
+ return(NULL);
+ }
+
+ sprintf(ac->devname, "%s%c",
+ dv->dv_xname, 'a'+i);
+ ac->dev = dev;
+ ac->vp = vp;
+ ac->clabel = clabel;
+ ac->next = ac_list;
+ ac_list = ac;
+ good_one = 1;
+ }
+ }
+ if (!good_one) {
+ /* cleanup */
+ free(clabel, M_RAIDFRAME);
+ VOP_CLOSE(vp, FREAD, NOCRED, 0);
+ vput(vp);
+ }
+ }
+ }
+}
+#endif
+return(ac_list);
+}
+
+#ifdef RAID_AUTOCONFIG
+static int
+rf_reasonable_label(clabel)
+ RF_ComponentLabel_t *clabel;
+{
+
+ if (((clabel->version==RF_COMPONENT_LABEL_VERSION_1) ||
+ (clabel->version==RF_COMPONENT_LABEL_VERSION)) &&
+ ((clabel->clean == RF_RAID_CLEAN) ||
+ (clabel->clean == RF_RAID_DIRTY)) &&
+ clabel->row >=0 &&
+ clabel->column >= 0 &&
+ clabel->num_rows > 0 &&
+ clabel->num_columns > 0 &&
+ clabel->row < clabel->num_rows &&
+ clabel->column < clabel->num_columns &&
+ clabel->blockSize > 0 &&
+ clabel->numBlocks > 0) {
+ /* label looks reasonable enough... */
+ return(1);
+ }
+ return(0);
+}
+#endif
+
+void
+rf_print_component_label(clabel)
+ RF_ComponentLabel_t *clabel;
+{
+ printf(" Row: %d Column: %d Num Rows: %d Num Columns: %d\n",
+ clabel->row, clabel->column,
+ clabel->num_rows, clabel->num_columns);
+ printf(" Version: %d Serial Number: %d Mod Counter: %d\n",
+ clabel->version, clabel->serial_number,
+ clabel->mod_counter);
+ printf(" Clean: %s Status: %d\n",
+ clabel->clean ? "Yes" : "No", clabel->status );
+ printf(" sectPerSU: %d SUsPerPU: %d SUsPerRU: %d\n",
+ clabel->sectPerSU, clabel->SUsPerPU, clabel->SUsPerRU);
+ printf(" RAID Level: %c blocksize: %d numBlocks: %d\n",
+ (char) clabel->parityConfig, clabel->blockSize,
+ clabel->numBlocks);
+ printf(" Autoconfig: %s\n", clabel->autoconfigure ? "Yes" : "No" );
+ printf(" Contains root partition: %s\n",
+ clabel->root_partition ? "Yes" : "No" );
+ printf(" Last configured as: raid%d\n", clabel->last_unit );
+#if 0
+ printf(" Config order: %d\n", clabel->config_order);
+#endif
+
+}
+
+RF_ConfigSet_t *
+rf_create_auto_sets(ac_list)
+ RF_AutoConfig_t *ac_list;
+{
+ RF_AutoConfig_t *ac;
+ RF_ConfigSet_t *config_sets;
+ RF_ConfigSet_t *cset;
+ RF_AutoConfig_t *ac_next;
+
+
+ config_sets = NULL;
+
+ /* Go through the AutoConfig list, and figure out which components
+ belong to what sets. */
+ ac = ac_list;
+ while(ac!=NULL) {
+ /* we're going to putz with ac->next, so save it here
+ for use at the end of the loop */
+ ac_next = ac->next;
+
+ if (config_sets == NULL) {
+ /* will need at least this one... */
+ config_sets = (RF_ConfigSet_t *)
+ malloc(sizeof(RF_ConfigSet_t),
+ M_RAIDFRAME, M_NOWAIT);
+ if (config_sets == NULL) {
+ panic("rf_create_auto_sets: No memory!\n");
+ }
+ /* this one is easy :) */
+ config_sets->ac = ac;
+ config_sets->next = NULL;
+ config_sets->rootable = 0;
+ ac->next = NULL;
+ } else {
+ /* which set does this component fit into? */
+ cset = config_sets;
+ while(cset!=NULL) {
+ if (rf_does_it_fit(cset, ac)) {
+ /* looks like it matches... */
+ ac->next = cset->ac;
+ cset->ac = ac;
+ break;
+ }
+ cset = cset->next;
+ }
+ if (cset==NULL) {
+ /* didn't find a match above... new set..*/
+ cset = (RF_ConfigSet_t *)
+ malloc(sizeof(RF_ConfigSet_t),
+ M_RAIDFRAME, M_NOWAIT);
+ if (cset == NULL) {
+ panic("rf_create_auto_sets: No memory!\n");
+ }
+ cset->ac = ac;
+ ac->next = NULL;
+ cset->next = config_sets;
+ cset->rootable = 0;
+ config_sets = cset;
+ }
+ }
+ ac = ac_next;
+ }
+
+
+ return(config_sets);
+}
+
+static int
+rf_does_it_fit(cset, ac)
+ RF_ConfigSet_t *cset;
+ RF_AutoConfig_t *ac;
+{
+ RF_ComponentLabel_t *clabel1, *clabel2;
+
+ /* If this one matches the *first* one in the set, that's good
+ enough, since the other members of the set would have been
+ through here too... */
+ /* note that we are not checking partitionSize here..
+
+ Note that we are also not checking the mod_counters here.
+ If everything else matches execpt the mod_counter, that's
+ good enough for this test. We will deal with the mod_counters
+ a little later in the autoconfiguration process.
+
+ (clabel1->mod_counter == clabel2->mod_counter) &&
+
+ The reason we don't check for this is that failed disks
+ will have lower modification counts. If those disks are
+ not added to the set they used to belong to, then they will
+ form their own set, which may result in 2 different sets,
+ for example, competing to be configured at raid0, and
+ perhaps competing to be the root filesystem set. If the
+ wrong ones get configured, or both attempt to become /,
+ weird behaviour and or serious lossage will occur. Thus we
+ need to bring them into the fold here, and kick them out at
+ a later point.
+
+ */
+
+ clabel1 = cset->ac->clabel;
+ clabel2 = ac->clabel;
+ if ((clabel1->version == clabel2->version) &&
+ (clabel1->serial_number == clabel2->serial_number) &&
+ (clabel1->num_rows == clabel2->num_rows) &&
+ (clabel1->num_columns == clabel2->num_columns) &&
+ (clabel1->sectPerSU == clabel2->sectPerSU) &&
+ (clabel1->SUsPerPU == clabel2->SUsPerPU) &&
+ (clabel1->SUsPerRU == clabel2->SUsPerRU) &&
+ (clabel1->parityConfig == clabel2->parityConfig) &&
+ (clabel1->maxOutstanding == clabel2->maxOutstanding) &&
+ (clabel1->blockSize == clabel2->blockSize) &&
+ (clabel1->numBlocks == clabel2->numBlocks) &&
+ (clabel1->autoconfigure == clabel2->autoconfigure) &&
+ (clabel1->root_partition == clabel2->root_partition) &&
+ (clabel1->last_unit == clabel2->last_unit) &&
+ (clabel1->config_order == clabel2->config_order)) {
+ /* if it get's here, it almost *has* to be a match */
+ } else {
+ /* it's not consistent with somebody in the set..
+ punt */
+ return(0);
+ }
+ /* all was fine.. it must fit... */
+ return(1);
+}
+
+int
+rf_have_enough_components(cset)
+ RF_ConfigSet_t *cset;
+{
+ RF_AutoConfig_t *ac;
+ RF_AutoConfig_t *auto_config;
+ RF_ComponentLabel_t *clabel;
+ int r,c;
+ int num_rows;
+ int num_cols;
+ int num_missing;
+ int mod_counter;
+ int mod_counter_found;
+ int even_pair_failed;
+ char parity_type;
+
+
+ /* check to see that we have enough 'live' components
+ of this set. If so, we can configure it if necessary */
+
+ num_rows = cset->ac->clabel->num_rows;
+ num_cols = cset->ac->clabel->num_columns;
+ parity_type = cset->ac->clabel->parityConfig;
+
+ /* XXX Check for duplicate components!?!?!? */
+
+ /* Determine what the mod_counter is supposed to be for this set. */
+
+ mod_counter_found = 0;
+ ac = cset->ac;
+ while(ac!=NULL) {
+ if (mod_counter_found==0) {
+ mod_counter = ac->clabel->mod_counter;
+ mod_counter_found = 1;
+ } else {
+ if (ac->clabel->mod_counter > mod_counter) {
+ mod_counter = ac->clabel->mod_counter;
+ }
+ }
+ ac = ac->next;
+ }
+
+ num_missing = 0;
+ auto_config = cset->ac;
+
+ for(r=0; r<num_rows; r++) {
+ even_pair_failed = 0;
+ for(c=0; c<num_cols; c++) {
+ ac = auto_config;
+ while(ac!=NULL) {
+ if ((ac->clabel->row == r) &&
+ (ac->clabel->column == c) &&
+ (ac->clabel->mod_counter == mod_counter)) {
+ /* it's this one... */
+#if DEBUG
+ printf("Found: %s at %d,%d\n",
+ ac->devname,r,c);
+#endif
+ break;
+ }
+ ac=ac->next;
+ }
+ if (ac==NULL) {
+ /* Didn't find one here! */
+ /* special case for RAID 1, especially
+ where there are more than 2
+ components (where RAIDframe treats
+ things a little differently :( ) */
+ if (parity_type == '1') {
+ if (c%2 == 0) { /* even component */
+ even_pair_failed = 1;
+ } else { /* odd component. If
+ we're failed, and
+ so is the even
+ component, it's
+ "Good Night, Charlie" */
+ if (even_pair_failed == 1) {
+ return(0);
+ }
+ }
+ } else {
+ /* normal accounting */
+ num_missing++;
+ }
+ }
+ if ((parity_type == '1') && (c%2 == 1)) {
+ /* Just did an even component, and we didn't
+ bail.. reset the even_pair_failed flag,
+ and go on to the next component.... */
+ even_pair_failed = 0;
+ }
+ }
+ }
+
+ clabel = cset->ac->clabel;
+
+ if (((clabel->parityConfig == '0') && (num_missing > 0)) ||
+ ((clabel->parityConfig == '4') && (num_missing > 1)) ||
+ ((clabel->parityConfig == '5') && (num_missing > 1))) {
+ /* XXX this needs to be made *much* more general */
+ /* Too many failures */
+ return(0);
+ }
+ /* otherwise, all is well, and we've got enough to take a kick
+ at autoconfiguring this set */
+ return(1);
+}
+
+void
+rf_create_configuration(ac,config,raidPtr)
+ RF_AutoConfig_t *ac;
+ RF_Config_t *config;
+ RF_Raid_t *raidPtr;
+{
+ RF_ComponentLabel_t *clabel;
+ int i;
+
+ clabel = ac->clabel;
+
+ /* 1. Fill in the common stuff */
+ config->numRow = clabel->num_rows;
+ config->numCol = clabel->num_columns;
+ config->numSpare = 0; /* XXX should this be set here? */
+ config->sectPerSU = clabel->sectPerSU;
+ config->SUsPerPU = clabel->SUsPerPU;
+ config->SUsPerRU = clabel->SUsPerRU;
+ config->parityConfig = clabel->parityConfig;
+ /* XXX... */
+ strcpy(config->diskQueueType,"fifo");
+ config->maxOutstandingDiskReqs = clabel->maxOutstanding;
+ config->layoutSpecificSize = 0; /* XXX ?? */
+
+ while(ac!=NULL) {
+ /* row/col values will be in range due to the checks
+ in reasonable_label() */
+ strcpy(config->devnames[ac->clabel->row][ac->clabel->column],
+ ac->devname);
+ ac = ac->next;
+ }
+
+ for(i=0;i<RF_MAXDBGV;i++) {
+ config->debugVars[i][0] = NULL;
+ }
+}
+
+int
+rf_set_autoconfig(raidPtr, new_value)
+ RF_Raid_t *raidPtr;
+ int new_value;
+{
+ RF_ComponentLabel_t clabel;
+ struct vnode *vp;
+ dev_t dev;
+ int row, column;
+
+ raidPtr->autoconfigure = new_value;
+ for(row=0; row<raidPtr->numRow; row++) {
+ for(column=0; column<raidPtr->numCol; column++) {
+ if (raidPtr->Disks[row][column].status ==
+ rf_ds_optimal) {
+ dev = raidPtr->Disks[row][column].dev;
+ vp = raidPtr->raid_cinfo[row][column].ci_vp;
+ raidread_component_label(dev, vp, &clabel);
+ clabel.autoconfigure = new_value;
+ raidwrite_component_label(dev, vp, &clabel);
+ }
+ }
+ }
+ return(new_value);
+}
+
+int
+rf_set_rootpartition(raidPtr, new_value)
+ RF_Raid_t *raidPtr;
+ int new_value;
+{
+ RF_ComponentLabel_t clabel;
+ struct vnode *vp;
+ dev_t dev;
+ int row, column;
+
+ raidPtr->root_partition = new_value;
+ for(row=0; row<raidPtr->numRow; row++) {
+ for(column=0; column<raidPtr->numCol; column++) {
+ if (raidPtr->Disks[row][column].status ==
+ rf_ds_optimal) {
+ dev = raidPtr->Disks[row][column].dev;
+ vp = raidPtr->raid_cinfo[row][column].ci_vp;
+ raidread_component_label(dev, vp, &clabel);
+ clabel.root_partition = new_value;
+ raidwrite_component_label(dev, vp, &clabel);
+ }
+ }
+ }
+ return(new_value);
+}
+
+void
+rf_release_all_vps(cset)
+ RF_ConfigSet_t *cset;
+{
+ RF_AutoConfig_t *ac;
+
+ ac = cset->ac;
+ while(ac!=NULL) {
+ /* Close the vp, and give it back */
+ if (ac->vp) {
+ VOP_CLOSE(ac->vp, FREAD, NOCRED, 0);
+ vput(ac->vp);
+ ac->vp = NULL;
+ }
+ ac = ac->next;
+ }
+}
+
+
+void
+rf_cleanup_config_set(cset)
+ RF_ConfigSet_t *cset;
+{
+ RF_AutoConfig_t *ac;
+ RF_AutoConfig_t *next_ac;
+
+ ac = cset->ac;
+ while(ac!=NULL) {
+ next_ac = ac->next;
+ /* nuke the label */
+ free(ac->clabel, M_RAIDFRAME);
+ /* cleanup the config structure */
+ free(ac, M_RAIDFRAME);
+ /* "next.." */
+ ac = next_ac;
+ }
+ /* and, finally, nuke the config set */
+ free(cset, M_RAIDFRAME);
+}
+
+
+void
+raid_init_component_label(raidPtr, clabel)
+ RF_Raid_t *raidPtr;
+ RF_ComponentLabel_t *clabel;
+{
+ /* current version number */
+ clabel->version = RF_COMPONENT_LABEL_VERSION;
+ clabel->serial_number = raidPtr->serial_number;
+ clabel->mod_counter = raidPtr->mod_counter;
+ clabel->num_rows = raidPtr->numRow;
+ clabel->num_columns = raidPtr->numCol;
+ clabel->clean = RF_RAID_DIRTY; /* not clean */
+ clabel->status = rf_ds_optimal; /* "It's good!" */
+
+ clabel->sectPerSU = raidPtr->Layout.sectorsPerStripeUnit;
+ clabel->SUsPerPU = raidPtr->Layout.SUsPerPU;
+ clabel->SUsPerRU = raidPtr->Layout.SUsPerRU;
+
+ clabel->blockSize = raidPtr->bytesPerSector;
+ clabel->numBlocks = raidPtr->sectorsPerDisk;
+
+ /* XXX not portable */
+ clabel->parityConfig = raidPtr->Layout.map->parityConfig;
+ clabel->maxOutstanding = raidPtr->maxOutstanding;
+ clabel->autoconfigure = raidPtr->autoconfigure;
+ clabel->root_partition = raidPtr->root_partition;
+ clabel->last_unit = raidPtr->raidid;
+ clabel->config_order = raidPtr->config_order;
+}
+
+int
+rf_auto_config_set(cset,unit)
+ RF_ConfigSet_t *cset;
+ int *unit;
+{
+ RF_Raid_t *raidPtr;
+ RF_Config_t *config;
+ int raidID;
+ int retcode;
+
+ printf("RAID autoconfigure\n");
+
+ retcode = 0;
+ *unit = -1;
+
+ /* 1. Create a config structure */
+
+ config = (RF_Config_t *)malloc(sizeof(RF_Config_t),
+ M_RAIDFRAME,
+ M_NOWAIT);
+ if (config==NULL) {
+ printf("Out of mem!?!?\n");
+ /* XXX do something more intelligent here. */
+ return(1);
+ }
+
+ memset(config, 0, sizeof(RF_Config_t));
+
+ /* XXX raidID needs to be set correctly.. */
+
+ /*
+ 2. Figure out what RAID ID this one is supposed to live at
+ See if we can get the same RAID dev that it was configured
+ on last time..
+ */
+
+ raidID = cset->ac->clabel->last_unit;
+ if ((raidID < 0) || (raidID >= numraid)) {
+ /* let's not wander off into lala land. */
+ raidID = numraid - 1;
+ }
+ if (raidPtrs[raidID]->valid != 0) {
+
+ /*
+ Nope... Go looking for an alternative...
+ Start high so we don't immediately use raid0 if that's
+ not taken.
+ */
+
+ for(raidID = numraid; raidID >= 0; raidID--) {
+ if (raidPtrs[raidID]->valid == 0) {
+ /* can use this one! */
+ break;
+ }
+ }
+ }
+
+ if (raidID < 0) {
+ /* punt... */
+ printf("Unable to auto configure this set!\n");
+ printf("(Out of RAID devs!)\n");
+ return(1);
+ }
+ printf("Configuring raid%d:\n",raidID);
+ raidPtr = raidPtrs[raidID];
+
+ /* XXX all this stuff should be done SOMEWHERE ELSE! */
+ raidPtr->raidid = raidID;
+ raidPtr->openings = RAIDOUTSTANDING;
+
+ /* 3. Build the configuration structure */
+ rf_create_configuration(cset->ac, config, raidPtr);
+
+ /* 4. Do the configuration */
+ retcode = rf_Configure(raidPtr, config, cset->ac);
+
+ if (retcode == 0) {
+
+ raidinit(raidPtrs[raidID]);
+
+ rf_markalldirty(raidPtrs[raidID]);
+ raidPtrs[raidID]->autoconfigure = 1; /* XXX do this here? */
+ if (cset->ac->clabel->root_partition==1) {
+ /* everything configured just fine. Make a note
+ that this set is eligible to be root. */
+ cset->rootable = 1;
+ /* XXX do this here? */
+ raidPtrs[raidID]->root_partition = 1;
+ }
+ }
+
+ /* 5. Cleanup */
+ free(config, M_RAIDFRAME);
+
+ *unit = raidID;
+ return(retcode);
+}
diff --git a/sys/dev/raidframe/rf_paritylogDiskMgr.c b/sys/dev/raidframe/rf_paritylogDiskMgr.c
index 41c3417c175..6914b19e535 100644
--- a/sys/dev/raidframe/rf_paritylogDiskMgr.c
+++ b/sys/dev/raidframe/rf_paritylogDiskMgr.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_paritylogDiskMgr.c,v 1.4 2000/01/11 18:02:22 peter Exp $ */
-/* $NetBSD: rf_paritylogDiskMgr.c,v 1.7 2000/01/08 01:18:36 oster Exp $ */
+/* $OpenBSD: rf_paritylogDiskMgr.c,v 1.5 2000/08/08 16:07:43 peter Exp $ */
+/* $NetBSD: rf_paritylogDiskMgr.c,v 1.10 2000/01/15 01:57:57 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -74,7 +74,7 @@ AcquireReintBuffer(pool)
pool->availBuffersIndex = 0;
RF_UNLOCK_MUTEX(pool->mutex);
} else {
- RF_PANIC(); /* should never happen in currect config,
+ RF_PANIC(); /* should never happen in correct config,
* single reint */
RF_WAIT_COND(pool->cond, pool->mutex);
}
@@ -117,19 +117,23 @@ ReadRegionLog(
*
* NON-BLOCKING */
- RF_AccTraceEntry_t tracerec;
+ RF_AccTraceEntry_t *tracerec;
RF_DagNode_t *rrd_rdNode;
/* create DAG to read region log from disk */
rf_MakeAllocList(*rrd_alloclist);
- *rrd_dag_h = rf_MakeSimpleDAG(raidPtr, 1, 0, regionBuffer, rf_DiskReadFunc, rf_DiskReadUndoFunc,
- "Rrl", *rrd_alloclist, RF_DAG_FLAGS_NONE, RF_IO_NORMAL_PRIORITY);
+ *rrd_dag_h = rf_MakeSimpleDAG(raidPtr, 1, 0, regionBuffer,
+ rf_DiskReadFunc, rf_DiskReadUndoFunc,
+ "Rrl", *rrd_alloclist,
+ RF_DAG_FLAGS_NONE,
+ RF_IO_NORMAL_PRIORITY);
/* create and initialize PDA for the core log */
/* RF_Malloc(*rrd_pda, sizeof(RF_PhysDiskAddr_t), (RF_PhysDiskAddr_t
* *)); */
*rrd_pda = rf_AllocPDAList(1);
- rf_MapLogParityLogging(raidPtr, regionID, 0, &((*rrd_pda)->row), &((*rrd_pda)->col), &((*rrd_pda)->startSector));
+ rf_MapLogParityLogging(raidPtr, regionID, 0, &((*rrd_pda)->row),
+ &((*rrd_pda)->col), &((*rrd_pda)->startSector));
(*rrd_pda)->numSector = raidPtr->regionInfo[regionID].capacity;
if ((*rrd_pda)->next) {
@@ -137,13 +141,15 @@ ReadRegionLog(
printf("set rrd_pda->next to NULL\n");
}
/* initialize DAG parameters */
- bzero((char *) &tracerec, sizeof(tracerec));
- (*rrd_dag_h)->tracerec = &tracerec;
+ RF_Malloc(tracerec,sizeof(RF_AccTraceEntry_t), (RF_AccTraceEntry_t *));
+ bzero((char *) tracerec, sizeof(RF_AccTraceEntry_t));
+ (*rrd_dag_h)->tracerec = tracerec;
rrd_rdNode = (*rrd_dag_h)->succedents[0]->succedents[0];
rrd_rdNode->params[0].p = *rrd_pda;
/* rrd_rdNode->params[1] = regionBuffer; */
rrd_rdNode->params[2].v = 0;
- rrd_rdNode->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, 0);
+ rrd_rdNode->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY,
+ 0, 0, 0);
/* launch region log read dag */
rf_DispatchDAG(*rrd_dag_h, (void (*) (void *)) rf_MCPairWakeupFunc,
@@ -162,7 +168,7 @@ WriteCoreLog(
RF_PhysDiskAddr_t ** fwr_pda)
{
RF_RegionId_t regionID = log->regionID;
- RF_AccTraceEntry_t tracerec;
+ RF_AccTraceEntry_t *tracerec;
RF_SectorNum_t regionOffset;
RF_DagNode_t *fwr_wrNode;
@@ -173,7 +179,8 @@ WriteCoreLog(
/* create DAG to write a core log to a region log disk */
rf_MakeAllocList(*fwr_alloclist);
- *fwr_dag_h = rf_MakeSimpleDAG(raidPtr, 1, 0, log->bufPtr, rf_DiskWriteFunc, rf_DiskWriteUndoFunc,
+ *fwr_dag_h = rf_MakeSimpleDAG(raidPtr, 1, 0, log->bufPtr,
+ rf_DiskWriteFunc, rf_DiskWriteUndoFunc,
"Wcl", *fwr_alloclist, RF_DAG_FLAGS_NONE, RF_IO_NORMAL_PRIORITY);
/* create and initialize PDA for the region log */
@@ -181,17 +188,21 @@ WriteCoreLog(
* *)); */
*fwr_pda = rf_AllocPDAList(1);
regionOffset = log->diskOffset;
- rf_MapLogParityLogging(raidPtr, regionID, regionOffset, &((*fwr_pda)->row), &((*fwr_pda)->col), &((*fwr_pda)->startSector));
+ rf_MapLogParityLogging(raidPtr, regionID, regionOffset,
+ &((*fwr_pda)->row), &((*fwr_pda)->col),
+ &((*fwr_pda)->startSector));
(*fwr_pda)->numSector = raidPtr->numSectorsPerLog;
/* initialize DAG parameters */
- bzero((char *) &tracerec, sizeof(tracerec));
- (*fwr_dag_h)->tracerec = &tracerec;
+ RF_Malloc(tracerec,sizeof(RF_AccTraceEntry_t), (RF_AccTraceEntry_t *));
+ bzero((char *) tracerec, sizeof(RF_AccTraceEntry_t));
+ (*fwr_dag_h)->tracerec = tracerec;
fwr_wrNode = (*fwr_dag_h)->succedents[0]->succedents[0];
fwr_wrNode->params[0].p = *fwr_pda;
/* fwr_wrNode->params[1] = log->bufPtr; */
fwr_wrNode->params[2].v = 0;
- fwr_wrNode->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, 0);
+ fwr_wrNode->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY,
+ 0, 0, 0);
/* launch the dag to write the core log to disk */
rf_DispatchDAG(*fwr_dag_h, (void (*) (void *)) rf_MCPairWakeupFunc,
@@ -214,19 +225,23 @@ ReadRegionParity(
*
* NON-BLOCKING */
- RF_AccTraceEntry_t tracerec;
+ RF_AccTraceEntry_t *tracerec;
RF_DagNode_t *prd_rdNode;
/* create DAG to read region parity from disk */
rf_MakeAllocList(*prd_alloclist);
- *prd_dag_h = rf_MakeSimpleDAG(raidPtr, 1, 0, NULL, rf_DiskReadFunc, rf_DiskReadUndoFunc,
- "Rrp", *prd_alloclist, RF_DAG_FLAGS_NONE, RF_IO_NORMAL_PRIORITY);
+ *prd_dag_h = rf_MakeSimpleDAG(raidPtr, 1, 0, NULL, rf_DiskReadFunc,
+ rf_DiskReadUndoFunc, "Rrp",
+ *prd_alloclist, RF_DAG_FLAGS_NONE,
+ RF_IO_NORMAL_PRIORITY);
/* create and initialize PDA for region parity */
/* RF_Malloc(*prd_pda, sizeof(RF_PhysDiskAddr_t), (RF_PhysDiskAddr_t
* *)); */
*prd_pda = rf_AllocPDAList(1);
- rf_MapRegionParity(raidPtr, regionID, &((*prd_pda)->row), &((*prd_pda)->col), &((*prd_pda)->startSector), &((*prd_pda)->numSector));
+ rf_MapRegionParity(raidPtr, regionID, &((*prd_pda)->row),
+ &((*prd_pda)->col), &((*prd_pda)->startSector),
+ &((*prd_pda)->numSector));
if (rf_parityLogDebug)
printf("[reading %d sectors of parity from region %d]\n",
(int) (*prd_pda)->numSector, regionID);
@@ -235,13 +250,15 @@ ReadRegionParity(
printf("set prd_pda->next to NULL\n");
}
/* initialize DAG parameters */
- bzero((char *) &tracerec, sizeof(tracerec));
- (*prd_dag_h)->tracerec = &tracerec;
+ RF_Malloc(tracerec,sizeof(RF_AccTraceEntry_t), (RF_AccTraceEntry_t *));
+ bzero((char *) tracerec, sizeof(RF_AccTraceEntry_t));
+ (*prd_dag_h)->tracerec = tracerec;
prd_rdNode = (*prd_dag_h)->succedents[0]->succedents[0];
prd_rdNode->params[0].p = *prd_pda;
prd_rdNode->params[1].p = parityBuffer;
prd_rdNode->params[2].v = 0;
- prd_rdNode->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, 0);
+ prd_rdNode->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY,
+ 0, 0, 0);
if (rf_validateDAGDebug)
rf_ValidateDAG(*prd_dag_h);
/* launch region parity read dag */
@@ -264,28 +281,35 @@ WriteRegionParity(
*
* NON-BLOCKING */
- RF_AccTraceEntry_t tracerec;
+ RF_AccTraceEntry_t *tracerec;
RF_DagNode_t *pwr_wrNode;
/* create DAG to write region log from disk */
rf_MakeAllocList(*pwr_alloclist);
- *pwr_dag_h = rf_MakeSimpleDAG(raidPtr, 1, 0, parityBuffer, rf_DiskWriteFunc, rf_DiskWriteUndoFunc,
- "Wrp", *pwr_alloclist, RF_DAG_FLAGS_NONE, RF_IO_NORMAL_PRIORITY);
+ *pwr_dag_h = rf_MakeSimpleDAG(raidPtr, 1, 0, parityBuffer,
+ rf_DiskWriteFunc, rf_DiskWriteUndoFunc,
+ "Wrp", *pwr_alloclist,
+ RF_DAG_FLAGS_NONE,
+ RF_IO_NORMAL_PRIORITY);
/* create and initialize PDA for region parity */
/* RF_Malloc(*pwr_pda, sizeof(RF_PhysDiskAddr_t), (RF_PhysDiskAddr_t
* *)); */
*pwr_pda = rf_AllocPDAList(1);
- rf_MapRegionParity(raidPtr, regionID, &((*pwr_pda)->row), &((*pwr_pda)->col), &((*pwr_pda)->startSector), &((*pwr_pda)->numSector));
+ rf_MapRegionParity(raidPtr, regionID, &((*pwr_pda)->row),
+ &((*pwr_pda)->col), &((*pwr_pda)->startSector),
+ &((*pwr_pda)->numSector));
/* initialize DAG parameters */
- bzero((char *) &tracerec, sizeof(tracerec));
- (*pwr_dag_h)->tracerec = &tracerec;
+ RF_Malloc(tracerec,sizeof(RF_AccTraceEntry_t), (RF_AccTraceEntry_t *));
+ bzero((char *) tracerec, sizeof(RF_AccTraceEntry_t));
+ (*pwr_dag_h)->tracerec = tracerec;
pwr_wrNode = (*pwr_dag_h)->succedents[0]->succedents[0];
pwr_wrNode->params[0].p = *pwr_pda;
/* pwr_wrNode->params[1] = parityBuffer; */
pwr_wrNode->params[2].v = 0;
- pwr_wrNode->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY, 0, 0, 0);
+ pwr_wrNode->params[3].v = RF_CREATE_PARAM3(RF_IO_NORMAL_PRIORITY,
+ 0, 0, 0);
/* launch the dag to write region parity to disk */
rf_DispatchDAG(*pwr_dag_h, (void (*) (void *)) rf_MCPairWakeupFunc,
@@ -325,7 +349,8 @@ FlushLogsToDisk(
if (rf_parityLogDebug)
printf("[initiating write of core log for region %d]\n", regionID);
fwr_mcpair->flag = RF_FALSE;
- WriteCoreLog(log, fwr_mcpair, raidPtr, &fwr_dag_h, &fwr_alloclist, &fwr_pda);
+ WriteCoreLog(log, fwr_mcpair, raidPtr, &fwr_dag_h,
+ &fwr_alloclist, &fwr_pda);
/* wait for the DAG to complete */
while (!fwr_mcpair->flag)
@@ -358,9 +383,14 @@ ReintegrateRegion(
RF_PhysDiskAddr_t *rrd_pda, *prd_pda, *pwr_pda;
caddr_t parityBuffer, regionBuffer = NULL;
- /* Reintegrate a region (regionID). 1. acquire region and parity
- * buffers 2. read log from disk 3. read parity from disk 4. apply log
- * to parity 5. apply core log to parity 6. write new parity to disk
+ /* Reintegrate a region (regionID).
+ *
+ * 1. acquire region and parity buffers
+ * 2. read log from disk
+ * 3. read parity from disk
+ * 4. apply log to parity
+ * 5. apply core log to parity
+ * 6. write new parity to disk
*
* BLOCKING */
@@ -369,22 +399,25 @@ ReintegrateRegion(
/* initiate read of region parity */
if (rf_parityLogDebug)
- printf("[initiating read of parity for region %d]\n", regionID);
+ printf("[initiating read of parity for region %d]\n",regionID);
parityBuffer = AcquireReintBuffer(&raidPtr->parityBufferPool);
prd_mcpair = rf_AllocMCPair();
RF_LOCK_MUTEX(prd_mcpair->mutex);
prd_mcpair->flag = RF_FALSE;
- ReadRegionParity(regionID, prd_mcpair, parityBuffer, raidPtr, &prd_dag_h, &prd_alloclist, &prd_pda);
+ ReadRegionParity(regionID, prd_mcpair, parityBuffer, raidPtr,
+ &prd_dag_h, &prd_alloclist, &prd_pda);
/* if region log nonempty, initiate read */
if (raidPtr->regionInfo[regionID].diskCount > 0) {
if (rf_parityLogDebug)
- printf("[initiating read of disk log for region %d]\n", regionID);
+ printf("[initiating read of disk log for region %d]\n",
+ regionID);
regionBuffer = AcquireReintBuffer(&raidPtr->regionBufferPool);
rrd_mcpair = rf_AllocMCPair();
RF_LOCK_MUTEX(rrd_mcpair->mutex);
rrd_mcpair->flag = RF_FALSE;
- ReadRegionLog(regionID, rrd_mcpair, regionBuffer, raidPtr, &rrd_dag_h, &rrd_alloclist, &rrd_pda);
+ ReadRegionLog(regionID, rrd_mcpair, regionBuffer, raidPtr,
+ &rrd_dag_h, &rrd_alloclist, &rrd_pda);
}
/* wait on read of region parity to complete */
while (!prd_mcpair->flag) {
@@ -421,11 +454,13 @@ ReintegrateRegion(
}
/* write reintegrated parity to disk */
if (rf_parityLogDebug)
- printf("[initiating write of parity for region %d]\n", regionID);
+ printf("[initiating write of parity for region %d]\n",
+ regionID);
pwr_mcpair = rf_AllocMCPair();
RF_LOCK_MUTEX(pwr_mcpair->mutex);
pwr_mcpair->flag = RF_FALSE;
- WriteRegionParity(regionID, pwr_mcpair, parityBuffer, raidPtr, &pwr_dag_h, &pwr_alloclist, &pwr_pda);
+ WriteRegionParity(regionID, pwr_mcpair, parityBuffer, raidPtr,
+ &pwr_dag_h, &pwr_alloclist, &pwr_pda);
while (!pwr_mcpair->flag)
RF_WAIT_COND(pwr_mcpair->cond, pwr_mcpair->mutex);
RF_UNLOCK_MUTEX(pwr_mcpair->mutex);
@@ -476,10 +511,17 @@ ReintegrateLogs(
/* remove all items which are blocked on reintegration of this
* region */
RF_LOCK_MUTEX(raidPtr->parityLogDiskQueue.mutex);
- logData = rf_SearchAndDequeueParityLogData(raidPtr, regionID, &raidPtr->parityLogDiskQueue.reintBlockHead, &raidPtr->parityLogDiskQueue.reintBlockTail, RF_TRUE);
+ logData = rf_SearchAndDequeueParityLogData(raidPtr, regionID,
+ &raidPtr->parityLogDiskQueue.reintBlockHead,
+ &raidPtr->parityLogDiskQueue.reintBlockTail,
+ RF_TRUE);
logDataList = logData;
while (logData) {
- logData->next = rf_SearchAndDequeueParityLogData(raidPtr, regionID, &raidPtr->parityLogDiskQueue.reintBlockHead, &raidPtr->parityLogDiskQueue.reintBlockTail, RF_TRUE);
+ logData->next = rf_SearchAndDequeueParityLogData(
+ raidPtr, regionID,
+ &raidPtr->parityLogDiskQueue.reintBlockHead,
+ &raidPtr->parityLogDiskQueue.reintBlockTail,
+ RF_TRUE);
logData = logData->next;
}
RF_UNLOCK_MUTEX(raidPtr->parityLogDiskQueue.mutex);
@@ -530,7 +572,8 @@ rf_ShutdownLogging(RF_Raid_t * raidPtr)
if (rf_forceParityLogReint) {
for (regionID = 0; regionID < rf_numParityRegions; regionID++) {
RF_LOCK_MUTEX(raidPtr->regionInfo[regionID].mutex);
- raidPtr->regionInfo[regionID].loggingEnabled = RF_FALSE;
+ raidPtr->regionInfo[regionID].loggingEnabled =
+ RF_FALSE;
log = raidPtr->regionInfo[regionID].coreLog;
raidPtr->regionInfo[regionID].coreLog = NULL;
diskCount = raidPtr->regionInfo[regionID].diskCount;
@@ -553,6 +596,7 @@ rf_ParityLoggingDiskManager(RF_Raid_t * raidPtr)
{
RF_ParityLog_t *reintQueue, *flushQueue;
int workNeeded, done = RF_FALSE;
+ int s;
/* Main program for parity logging disk thread. This routine waits
* for work to appear in either the flush or reintegration queues and
@@ -561,6 +605,8 @@ rf_ParityLoggingDiskManager(RF_Raid_t * raidPtr)
*
* BLOCKING */
+ s = splbio();
+
RF_LOCK_MUTEX(raidPtr->parityLogDiskQueue.mutex);
/*
@@ -599,7 +645,7 @@ rf_ParityLoggingDiskManager(RF_Raid_t * raidPtr)
/* empty flushQueue, using free'd log buffers to
* process bufTail */
if (flushQueue)
- FlushLogsToDisk(raidPtr, flushQueue);
+ FlushLogsToDisk(raidPtr, flushQueue);
/* empty reintQueue, flushing from reintTail as we go */
if (reintQueue)
@@ -624,7 +670,8 @@ rf_ParityLoggingDiskManager(RF_Raid_t * raidPtr)
/* thread enabled, no work needed, so sleep */
if (rf_parityLogDebug)
printf("[parity logging disk manager sleeping]\n");
- RF_WAIT_COND(raidPtr->parityLogDiskQueue.cond, raidPtr->parityLogDiskQueue.mutex);
+ RF_WAIT_COND(raidPtr->parityLogDiskQueue.cond,
+ raidPtr->parityLogDiskQueue.mutex);
if (rf_parityLogDebug)
printf("[parity logging disk manager just woke up]\n");
flushQueue = raidPtr->parityLogDiskQueue.flushQueue;
@@ -642,6 +689,8 @@ rf_ParityLoggingDiskManager(RF_Raid_t * raidPtr)
RF_UNLOCK_MUTEX(raidPtr->parityLogDiskQueue.mutex);
RF_SIGNAL_COND(raidPtr->parityLogDiskQueue.cond);
+ splx(s);
+
/*
* In the Net- & OpenBSD kernel, the thread must exit; returning would
* cause the proc trampoline to attempt to return to userspace.
diff --git a/sys/dev/raidframe/rf_paritylogging.c b/sys/dev/raidframe/rf_paritylogging.c
index 65877664637..c0a04bbd062 100644
--- a/sys/dev/raidframe/rf_paritylogging.c
+++ b/sys/dev/raidframe/rf_paritylogging.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_paritylogging.c,v 1.4 2000/01/11 18:02:22 peter Exp $ */
-/* $NetBSD: rf_paritylogging.c,v 1.8 2000/01/09 04:35:13 oster Exp $ */
+/* $OpenBSD: rf_paritylogging.c,v 1.5 2000/08/08 16:07:44 peter Exp $ */
+/* $NetBSD: rf_paritylogging.c,v 1.10 2000/02/12 16:06:27 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -201,6 +201,8 @@ rf_ConfigureParityLogging(
raidPtr->numParityLogs = rf_numParityRegions;
/* create region information structs */
+ printf("Allocating %d bytes for in-core parity region info\n",
+ (int) (rf_numParityRegions * sizeof(RF_RegionInfo_t)));
RF_Malloc(raidPtr->regionInfo,
(rf_numParityRegions * sizeof(RF_RegionInfo_t)),
(RF_RegionInfo_t *));
@@ -223,6 +225,10 @@ rf_ConfigureParityLogging(
regionParityRange++; */
/* build pool of unused parity logs */
+ printf("Allocating %d bytes for %d parity logs\n",
+ raidPtr->numParityLogs * raidPtr->numSectorsPerLog *
+ raidPtr->bytesPerSector,
+ raidPtr->numParityLogs);
RF_Malloc(raidPtr->parityLogBufferHeap, raidPtr->numParityLogs *
raidPtr->numSectorsPerLog * raidPtr->bytesPerSector,
(caddr_t));
@@ -326,6 +332,9 @@ rf_ConfigureParityLogging(
raidPtr->regionBufferPool.totalBuffers;
raidPtr->regionBufferPool.availBuffersIndex = 0;
raidPtr->regionBufferPool.emptyBuffersIndex = 0;
+ printf("Allocating %d bytes for regionBufferPool\n",
+ (int) (raidPtr->regionBufferPool.totalBuffers *
+ sizeof(caddr_t)));
RF_Malloc(raidPtr->regionBufferPool.buffers,
raidPtr->regionBufferPool.totalBuffers * sizeof(caddr_t),
(caddr_t *));
@@ -335,6 +344,9 @@ rf_ConfigureParityLogging(
return (ENOMEM);
}
for (i = 0; i < raidPtr->regionBufferPool.totalBuffers; i++) {
+ printf("Allocating %d bytes for regionBufferPool#%d\n",
+ (int) (raidPtr->regionBufferPool.bufferSize *
+ sizeof(char)), i);
RF_Malloc(raidPtr->regionBufferPool.buffers[i],
raidPtr->regionBufferPool.bufferSize * sizeof(char),
(caddr_t));
@@ -390,6 +402,10 @@ rf_ConfigureParityLogging(
raidPtr->parityBufferPool.totalBuffers;
raidPtr->parityBufferPool.availBuffersIndex = 0;
raidPtr->parityBufferPool.emptyBuffersIndex = 0;
+ printf("Allocating %d bytes for parityBufferPool of %d units\n",
+ (int) (raidPtr->parityBufferPool.totalBuffers *
+ sizeof(caddr_t)),
+ raidPtr->parityBufferPool.totalBuffers );
RF_Malloc(raidPtr->parityBufferPool.buffers,
raidPtr->parityBufferPool.totalBuffers * sizeof(caddr_t),
(caddr_t *));
@@ -399,6 +415,9 @@ rf_ConfigureParityLogging(
return (ENOMEM);
}
for (i = 0; i < raidPtr->parityBufferPool.totalBuffers; i++) {
+ printf("Allocating %d bytes for parityBufferPool#%d\n",
+ (int) (raidPtr->parityBufferPool.bufferSize *
+ sizeof(char)),i);
RF_Malloc(raidPtr->parityBufferPool.buffers[i],
raidPtr->parityBufferPool.bufferSize * sizeof(char),
(caddr_t));
@@ -514,6 +533,9 @@ rf_ConfigureParityLogging(
RF_ASSERT(raidPtr->regionInfo[i].parityStartAddr +
raidPtr->regionInfo[i].numSectorsParity <=
raidPtr->sectorsPerDisk);
+ printf("Allocating %d bytes for region %d\n",
+ (int) (raidPtr->regionInfo[i].capacity *
+ sizeof(RF_DiskMap_t)), i);
RF_Malloc(raidPtr->regionInfo[i].diskMap,
(raidPtr->regionInfo[i].capacity *
sizeof(RF_DiskMap_t)),
diff --git a/sys/dev/raidframe/rf_parityscan.c b/sys/dev/raidframe/rf_parityscan.c
index c139ef39504..3a46b610d53 100644
--- a/sys/dev/raidframe/rf_parityscan.c
+++ b/sys/dev/raidframe/rf_parityscan.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_parityscan.c,v 1.5 2000/01/07 14:50:22 peter Exp $ */
-/* $NetBSD: rf_parityscan.c,v 1.8 2000/01/05 02:57:28 oster Exp $ */
+/* $OpenBSD: rf_parityscan.c,v 1.6 2000/08/08 16:07:44 peter Exp $ */
+/* $NetBSD: rf_parityscan.c,v 1.9 2000/05/28 03:00:31 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -90,6 +90,11 @@ rf_RewriteParity(raidPtr)
for (i = 0; i < raidPtr->totalSectors &&
rc <= RF_PARITY_CORRECTED;
i += layoutPtr->dataSectorsPerStripe) {
+ if (raidPtr->waitShutdown) {
+ /* Someone is pulling the plug on this set...
+ abort the re-write */
+ return (1);
+ }
asm_h = rf_MapAccess(raidPtr, i,
layoutPtr->dataSectorsPerStripe,
NULL, RF_DONT_REMAP);
diff --git a/sys/dev/raidframe/rf_raid.h b/sys/dev/raidframe/rf_raid.h
index 8efbc6639ee..a78b4a41841 100644
--- a/sys/dev/raidframe/rf_raid.h
+++ b/sys/dev/raidframe/rf_raid.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_raid.h,v 1.5 2000/01/07 14:50:22 peter Exp $ */
-/* $NetBSD: rf_raid.h,v 1.8 2000/01/05 02:57:29 oster Exp $ */
+/* $OpenBSD: rf_raid.h,v 1.6 2000/08/08 16:07:44 peter Exp $ */
+/* $NetBSD: rf_raid.h,v 1.12 2000/02/24 17:12:10 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -64,7 +64,8 @@
#define RF_MAX_DISKS 128 /* max disks per array */
#define RF_DEV2RAIDID(_dev) (DISKUNIT(_dev))
-#define RF_COMPONENT_LABEL_VERSION 1
+#define RF_COMPONENT_LABEL_VERSION_1 1
+#define RF_COMPONENT_LABEL_VERSION 2
#define RF_RAID_DIRTY 0
#define RF_RAID_CLEAN 1
@@ -123,6 +124,8 @@ struct RF_Raid_s {
RF_RaidLayout_t Layout; /* all information related to layout */
RF_RaidDisk_t **Disks; /* all information related to physical disks */
RF_DiskQueue_t **Queues;/* all information related to disk queues */
+ RF_DiskQueueSW_t *qType;/* pointer to the DiskQueueSW used for the
+ component queues. */
/* NOTE: This is an anchor point via which the queues can be
* accessed, but the enqueue/dequeue routines in diskqueue.c use a
* local copy of this pointer for the actual accesses. */
@@ -135,6 +138,8 @@ struct RF_Raid_s {
RF_LockTableEntry_t *lockTable; /* stripe-lock table */
RF_LockTableEntry_t *quiesceLock; /* quiesnce table */
int numFailures; /* total number of failures in the array */
+ int numNewFailures; /* number of *new* failures (that havn't
+ caused a mod_counter update */
int parity_good; /* !0 if parity is known to be correct */
int serial_number; /* a "serial number" for this set */
@@ -145,6 +150,20 @@ struct RF_Raid_s {
simultaneously (high-level - not a
per-component limit)*/
+ int maxOutstanding; /* maxOutstanding requests (per-component) */
+ int autoconfigure; /* automatically configure this RAID set.
+ 0 == no, 1 == yes */
+ int root_partition; /* Use this set as /
+ 0 == no, 1 == yes*/
+ int last_unit; /* last unit number (e.g. 0 for /dev/raid0)
+ of this component. Used for autoconfigure
+ only. */
+ int config_order; /* 0 .. n. The order in which the component
+ should be auto-configured. E.g. 0 is will
+ done first, (and would become raid0).
+ This may be in conflict with last_unit!!?! */
+ /* Not currently used. */
+
/*
* Cleanup stuff
*/
diff --git a/sys/dev/raidframe/rf_raidframe.h b/sys/dev/raidframe/rf_raidframe.h
index bf24693d663..f92a2d6540e 100644
--- a/sys/dev/raidframe/rf_raidframe.h
+++ b/sys/dev/raidframe/rf_raidframe.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_raidframe.h,v 1.4 2000/01/07 14:50:22 peter Exp $ */
-/* $NetBSD: rf_raidframe.h,v 1.8 2000/01/05 02:57:29 oster Exp $ */
+/* $OpenBSD: rf_raidframe.h,v 1.5 2000/08/08 16:07:44 peter Exp $ */
+/* $NetBSD: rf_raidframe.h,v 1.11 2000/05/28 00:48:31 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -81,6 +81,12 @@ typedef struct RF_DeviceConfig_s {
} RF_DeviceConfig_t;
+typedef struct RF_ProgressInfo_s {
+ RF_uint64 remaining;
+ RF_uint64 completed;
+ RF_uint64 total;
+} RF_ProgressInfo_t;
+
/* flags that can be put in the rf_recon_req structure */
#define RF_FDFLAGS_NONE 0x0 /* just fail the disk */
#define RF_FDFLAGS_RECON 0x1 /* fail and initiate recon */
@@ -135,4 +141,13 @@ typedef struct RF_DeviceConfig_s {
#define RAIDFRAME_CHECK_PARITY _IOWR ('r', 25, int)
#define RAIDFRAME_CHECK_PARITYREWRITE_STATUS _IOWR ('r', 26, int)
#define RAIDFRAME_CHECK_COPYBACK_STATUS _IOWR ('r', 27, int)
+#define RAIDFRAME_SET_AUTOCONFIG _IOWR ('r', 28, int)
+#define RAIDFRAME_SET_ROOT _IOWR ('r', 29, int)
+#define RAIDFRAME_DELETE_COMPONENT _IOW ('r', 30, RF_SingleComponent_t)
+#define RAIDFRAME_INCORPORATE_HOT_SPARE _IOW ('r', 31, RF_SingleComponent_t)
+/* 'Extended' status versions */
+#define RAIDFRAME_CHECK_RECON_STATUS_EXT _IOWR('r', 32, RF_ProgressInfo_t *)
+#define RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT _IOWR ('r', 33, RF_ProgressInfo_t *)
+#define RAIDFRAME_CHECK_COPYBACK_STATUS_EXT _IOWR ('r', 34, RF_ProgressInfo_t *)
+
#endif /* !_RF__RF_RAIDFRAME_H_ */
diff --git a/sys/dev/raidframe/rf_reconbuffer.c b/sys/dev/raidframe/rf_reconbuffer.c
index 011060ef6db..d1ec64672d5 100644
--- a/sys/dev/raidframe/rf_reconbuffer.c
+++ b/sys/dev/raidframe/rf_reconbuffer.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_reconbuffer.c,v 1.2 1999/02/16 00:03:20 niklas Exp $ */
-/* $NetBSD: rf_reconbuffer.c,v 1.3 1999/02/05 00:06:16 oster Exp $ */
+/* $OpenBSD: rf_reconbuffer.c,v 1.3 2000/08/08 16:07:44 peter Exp $ */
+/* $NetBSD: rf_reconbuffer.c,v 1.4 2000/03/13 23:52:36 soren Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -298,8 +298,7 @@ rf_MultiWayReconXor(raidPtr, pssPtr)
nWayXorFuncs[numBufs] (pssPtr->rbufsForXor, targetRbuf, numBytes / sizeof(long));
/* release all the reconstruction buffers except the last one, which
- * belongs to the the disk who's submission caused this XOR to take
- * place */
+ * belongs to the disk whose submission caused this XOR to take place */
for (i = 0; i < numBufs - 1; i++) {
if (rbufs[i]->type == RF_RBUF_TYPE_FLOATING)
rf_ReleaseFloatingReconBuffer(raidPtr, rbufs[i]->row, rbufs[i]);
diff --git a/sys/dev/raidframe/rf_reconstruct.c b/sys/dev/raidframe/rf_reconstruct.c
index e731bcc42a3..47884abd0c8 100644
--- a/sys/dev/raidframe/rf_reconstruct.c
+++ b/sys/dev/raidframe/rf_reconstruct.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_reconstruct.c,v 1.8 2000/01/11 18:02:23 peter Exp $ */
-/* $NetBSD: rf_reconstruct.c,v 1.14 2000/01/09 03:14:33 oster Exp $ */
+/* $OpenBSD: rf_reconstruct.c,v 1.9 2000/08/08 16:07:45 peter Exp $ */
+/* $NetBSD: rf_reconstruct.c,v 1.26 2000/06/04 02:05:13 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -345,15 +345,13 @@ rf_ReconstructFailedDiskBasic(raidPtr, row, col)
raidPtr->raid_cinfo[srow][scol].ci_vp,
&c_label);
- c_label.version = RF_COMPONENT_LABEL_VERSION;
- c_label.mod_counter = raidPtr->mod_counter;
- c_label.serial_number = raidPtr->serial_number;
+ raid_init_component_label( raidPtr, &c_label);
c_label.row = row;
c_label.column = col;
- c_label.num_rows = raidPtr->numRow;
- c_label.num_columns = raidPtr->numCol;
c_label.clean = RF_RAID_DIRTY;
c_label.status = rf_ds_optimal;
+
+ /* XXXX MORE NEEDED HERE */
raidwrite_component_label(
raidPtr->raid_cinfo[srow][scol].ci_dev,
@@ -391,6 +389,7 @@ rf_ReconstructInPlace(raidPtr, row, col)
struct vattr va;
struct proc *proc;
int retcode;
+ int ac;
lp = raidPtr->Layout.map;
if (lp->SubmitReconBuffer) {
@@ -425,6 +424,8 @@ rf_ReconstructInPlace(raidPtr, row, col)
raidPtr->numFailures++;
raidPtr->Disks[row][col].status = rf_ds_failed;
raidPtr->status[row] = rf_rs_degraded;
+ rf_update_component_labels(raidPtr,
+ RF_NORMAL_COMPONENT_UPDATE);
}
while (raidPtr->reconInProgress) {
@@ -467,11 +468,14 @@ rf_ReconstructInPlace(raidPtr, row, col)
if (raidPtr->raid_cinfo[row][col].ci_vp != NULL) {
printf("Closing the open device: %s\n",
raidPtr->Disks[row][col].devname);
- VOP_UNLOCK(raidPtr->raid_cinfo[row][col].ci_vp, 0, proc);
- (void) vn_close(raidPtr->raid_cinfo[row][col].ci_vp,
- FREAD | FWRITE, proc->p_ucred, proc);
+ vp = raidPtr->raid_cinfo[row][col].ci_vp;
+ ac = raidPtr->Disks[row][col].auto_configured;
+ rf_close_component(raidPtr, vp, ac);
raidPtr->raid_cinfo[row][col].ci_vp = NULL;
}
+ /* note that this disk was *not* auto_configured (any longer)*/
+ raidPtr->Disks[row][col].auto_configured = 0;
+
printf("About to (re-)open the device for rebuilding: %s\n",
raidPtr->Disks[row][col].devname);
@@ -575,16 +579,11 @@ rf_ReconstructInPlace(raidPtr, row, col)
raidread_component_label(raidPtr->raid_cinfo[row][col].ci_dev,
raidPtr->raid_cinfo[row][col].ci_vp,
&c_label);
-
- c_label.version = RF_COMPONENT_LABEL_VERSION;
- c_label.mod_counter = raidPtr->mod_counter;
- c_label.serial_number = raidPtr->serial_number;
+
+ raid_init_component_label(raidPtr, &c_label);
+
c_label.row = row;
c_label.column = col;
- c_label.num_rows = raidPtr->numRow;
- c_label.num_columns = raidPtr->numCol;
- c_label.clean = RF_RAID_DIRTY;
- c_label.status = rf_ds_optimal;
raidwrite_component_label(raidPtr->raid_cinfo[row][col].ci_dev,
raidPtr->raid_cinfo[row][col].ci_vp,
@@ -685,7 +684,14 @@ rf_ContinueReconstructFailedDisk(reconDesc)
if (rf_ProcessReconEvent(raidPtr, row, event))
reconDesc->numDisksDone++;
- raidPtr->reconControl[row]->percentComplete = 100 - (rf_UnitsLeftToReconstruct(mapPtr) * 100 / mapPtr->totalRUs);
+ raidPtr->reconControl[row]->numRUsTotal =
+ mapPtr->totalRUs;
+ raidPtr->reconControl[row]->numRUsComplete =
+ mapPtr->totalRUs -
+ rf_UnitsLeftToReconstruct(mapPtr);
+
+ raidPtr->reconControl[row]->percentComplete =
+ (raidPtr->reconControl[row]->numRUsComplete * 100 / raidPtr->reconControl[row]->numRUsTotal);
if (rf_prReconSched) {
rf_PrintReconSchedule(raidPtr->reconControl[row]->reconMap, &(raidPtr->reconControl[row]->starttime));
}
@@ -748,7 +754,8 @@ rf_ContinueReconstructFailedDisk(reconDesc)
rf_ResumeNewRequests(raidPtr);
- printf("Reconstruction of disk at row %d col %d completed and spare disk reassigned\n", row, col);
+ printf("Reconstruction of disk at row %d col %d completed\n",
+ row, col);
xor_s = raidPtr->accumXorTimeUs / 1000000;
xor_resid_us = raidPtr->accumXorTimeUs % 1000000;
printf("Recon time was %d.%06d seconds, accumulated XOR time was %ld us (%ld.%06ld)\n",
@@ -897,7 +904,7 @@ rf_ProcessReconEvent(raidPtr, frow, event)
* head-separation wait request and return.
*
* ctrl->{ru_count, curPSID, diskOffset} and
- * rbuf->failedDiskSectorOffset are maintained to point the the unit
+ * rbuf->failedDiskSectorOffset are maintained to point to the unit
* we're currently accessing. Note that this deviates from the
* standard C idiom of having counters point to the next thing to be
* accessed. This allows us to easily retry when we're blocked by
diff --git a/sys/dev/raidframe/rf_reconstruct.h b/sys/dev/raidframe/rf_reconstruct.h
index 8b087f514c0..8a0842ce867 100644
--- a/sys/dev/raidframe/rf_reconstruct.h
+++ b/sys/dev/raidframe/rf_reconstruct.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_reconstruct.h,v 1.3 1999/07/30 14:45:33 peter Exp $ */
-/* $NetBSD: rf_reconstruct.h,v 1.4 1999/03/02 03:18:48 oster Exp $ */
+/* $OpenBSD: rf_reconstruct.h,v 1.4 2000/08/08 16:07:45 peter Exp $ */
+/* $NetBSD: rf_reconstruct.h,v 1.5 2000/05/28 00:48:30 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -128,6 +128,8 @@ struct RF_ReconCtrl_s {
RF_StripeNum_t lastPSID;/* the ID of the last parity stripe we want
* reconstructed */
int percentComplete;/* percentage completion of reconstruction */
+ int numRUsComplete; /* number of Reconstruction Units done */
+ int numRUsTotal; /* total number of Reconstruction Units */
/* reconstruction event queue */
RF_ReconEvent_t *eventQueue; /* queue of pending reconstruction
diff --git a/sys/dev/raidframe/rf_revent.c b/sys/dev/raidframe/rf_revent.c
index bc9dad41174..e664e361110 100644
--- a/sys/dev/raidframe/rf_revent.c
+++ b/sys/dev/raidframe/rf_revent.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_revent.c,v 1.8 2000/01/11 14:38:59 peter Exp $ */
-/* $NetBSD: rf_revent.c,v 1.6 2000/01/07 03:56:14 oster Exp $ */
+/* $OpenBSD: rf_revent.c,v 1.9 2000/08/08 16:07:45 peter Exp $ */
+/* $NetBSD: rf_revent.c,v 1.7 2000/05/30 02:04:29 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -48,10 +48,10 @@ static RF_FreeList_t *rf_revent_freelist;
#include <sys/proc.h>
+#include <sys/kernel.h>
-extern int hz;
-
-#define DO_WAIT(_rc) tsleep(&(_rc)->eventQueue, PRIBIO, "raidframe eventq", 0)
+#define DO_WAIT(_rc) \
+ tsleep(&(_rc)->eventQueue, PRIBIO, "raidframe eventq", 0)
#define DO_SIGNAL(_rc) wakeup(&(_rc)->eventQueue)
@@ -90,11 +90,10 @@ rf_ConfigureReconEvent(listp)
(RF_ReconEvent_t *));
return (0);
}
-/* returns the next reconstruction event, blocking the calling thread until
- * one becomes available
- */
-/* will now return null if it is blocked or will return an event if it is not */
+/* returns the next reconstruction event, blocking the calling thread
+ * until one becomes available. will now return null if it is blocked
+ * or will return an event if it is not */
RF_ReconEvent_t *
rf_GetNextReconEvent(reconDesc, row, continueFunc, continueArg)
@@ -109,13 +108,14 @@ rf_GetNextReconEvent(reconDesc, row, continueFunc, continueArg)
RF_ASSERT(row >= 0 && row <= raidPtr->numRow);
RF_LOCK_MUTEX(rctrl->eq_mutex);
- RF_ASSERT((rctrl->eventQueue == NULL) == (rctrl->eq_count == 0)); /* q null and count==0
- * must be equivalent
- * conditions */
+ /* q null and count==0 must be equivalent conditions */
+ RF_ASSERT((rctrl->eventQueue == NULL) == (rctrl->eq_count == 0));
rctrl->continueFunc = continueFunc;
rctrl->continueArg = continueArg;
+ /* mpsleep timeout value: secs = timo_val/hz. 'ticks' here is
+ defined as cycle-counter ticks, not softclock ticks */
#define MAX_RECON_EXEC_USECS (100 * 1000) /* 100 ms */
#define RECON_DELAY_MS 25
@@ -131,15 +131,18 @@ rf_GetNextReconEvent(reconDesc, row, continueFunc, continueArg)
RF_ETIMER_STOP(reconDesc->recon_exec_timer);
RF_ETIMER_EVAL(reconDesc->recon_exec_timer);
- reconDesc->reconExecTicks += RF_ETIMER_VAL_US(reconDesc->recon_exec_timer);
+ reconDesc->reconExecTicks +=
+ RF_ETIMER_VAL_US(reconDesc->recon_exec_timer);
if (reconDesc->reconExecTicks > reconDesc->maxReconExecTicks)
- reconDesc->maxReconExecTicks = reconDesc->reconExecTicks;
+ reconDesc->maxReconExecTicks =
+ reconDesc->reconExecTicks;
if (reconDesc->reconExecTicks >= MAX_RECON_EXEC_USECS) {
/* we've been running too long - sleep */
#if RF_RECON_STATS > 0
reconDesc->numReconExecDelays++;
#endif /* RF_RECON_STATS > 0 */
- status = tsleep(&reconDesc->reconExecTicks, PRIBIO, "recon delay", RECON_TIMO);
+ status = tsleep(&reconDesc->reconExecTicks,
+ PRIBIO, "recon delay", RECON_TIMO);
RF_ASSERT(status == EWOULDBLOCK);
reconDesc->reconExecTicks = 0;
}
@@ -159,9 +162,9 @@ rf_GetNextReconEvent(reconDesc, row, continueFunc, continueArg)
rctrl->eventQueue = event->next;
event->next = NULL;
rctrl->eq_count--;
- RF_ASSERT((rctrl->eventQueue == NULL) == (rctrl->eq_count == 0)); /* q null and count==0
- * must be equivalent
- * conditions */
+
+ /* q null and count==0 must be equivalent conditions */
+ RF_ASSERT((rctrl->eventQueue == NULL) == (rctrl->eq_count == 0));
RF_UNLOCK_MUTEX(rctrl->eq_mutex);
return (event);
}
@@ -182,9 +185,8 @@ rf_CauseReconEvent(raidPtr, row, col, arg, type)
}
RF_ASSERT(row >= 0 && row <= raidPtr->numRow && col >= 0 && col <= raidPtr->numCol);
RF_LOCK_MUTEX(rctrl->eq_mutex);
- RF_ASSERT((rctrl->eventQueue == NULL) == (rctrl->eq_count == 0)); /* q null and count==0
- * must be equivalent
- * conditions */
+ /* q null and count==0 must be equivalent conditions */
+ RF_ASSERT((rctrl->eventQueue == NULL) == (rctrl->eq_count == 0));
event->next = rctrl->eventQueue;
rctrl->eventQueue = event;
rctrl->eq_count++;
diff --git a/sys/dev/raidframe/rf_shutdown.c b/sys/dev/raidframe/rf_shutdown.c
index 9e776b90958..293ead367e6 100644
--- a/sys/dev/raidframe/rf_shutdown.c
+++ b/sys/dev/raidframe/rf_shutdown.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_shutdown.c,v 1.3 2000/01/11 18:02:23 peter Exp $ */
-/* $NetBSD: rf_shutdown.c,v 1.5 2000/01/08 22:57:31 oster Exp $ */
+/* $OpenBSD: rf_shutdown.c,v 1.4 2000/08/08 16:07:45 peter Exp $ */
+/* $NetBSD: rf_shutdown.c,v 1.6 2000/01/13 23:41:18 oster Exp $ */
/*
* rf_shutdown.c
*/
@@ -60,7 +60,10 @@ _rf_ShutdownCreate(
* Have to directly allocate memory here, since we start up before
* and shutdown after RAIDframe internal allocation system.
*/
- ent = (RF_ShutdownList_t *) malloc(sizeof(RF_ShutdownList_t), M_RAIDFRAME, M_WAITOK);
+ /* ent = (RF_ShutdownList_t *) malloc(sizeof(RF_ShutdownList_t),
+ M_RAIDFRAME, M_WAITOK); */
+ ent = (RF_ShutdownList_t *) malloc(sizeof(RF_ShutdownList_t),
+ M_RAIDFRAME, M_NOWAIT);
if (ent == NULL)
return (ENOMEM);
ent->cleanup = cleanup;
diff --git a/sys/dev/raidframe/rf_threadstuff.h b/sys/dev/raidframe/rf_threadstuff.h
index 033999efa6c..a54ad90c223 100644
--- a/sys/dev/raidframe/rf_threadstuff.h
+++ b/sys/dev/raidframe/rf_threadstuff.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_threadstuff.h,v 1.5 2000/01/11 18:02:23 peter Exp $ */
-/* $NetBSD: rf_threadstuff.h,v 1.7 2000/01/09 01:34:29 oster Exp $ */
+/* $OpenBSD: rf_threadstuff.h,v 1.6 2000/08/08 16:07:45 peter Exp $ */
+/* $NetBSD: rf_threadstuff.h,v 1.8 2000/06/11 03:35:38 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -86,9 +86,6 @@ typedef void *RF_ThreadArg_t;
/*
* In Net- and OpenBSD, kernel threads are simply processes which share several
* substructures and never run in userspace.
- *
- * XXX Note, Net- and OpenBSD does not yet have a wakeup_one(), so we always
- * XXX get Thundering Herd when a condition occurs.
*/
#define RF_WAIT_COND(_c_,_m_) { \
RF_UNLOCK_MUTEX(_m_); \