summaryrefslogtreecommitdiff
path: root/sys/dev/raidframe
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/raidframe')
-rw-r--r--sys/dev/raidframe/rf_diskqueue.c44
-rw-r--r--sys/dev/raidframe/rf_diskqueue.h49
-rw-r--r--sys/dev/raidframe/rf_disks.c193
-rw-r--r--sys/dev/raidframe/rf_disks.h20
-rw-r--r--sys/dev/raidframe/rf_driver.c45
-rw-r--r--sys/dev/raidframe/rf_driver.h69
-rw-r--r--sys/dev/raidframe/rf_kintf.h3
-rw-r--r--sys/dev/raidframe/rf_netbsd.h45
-rw-r--r--sys/dev/raidframe/rf_netbsdkintf.c865
-rw-r--r--sys/dev/raidframe/rf_raid.h5
-rw-r--r--sys/dev/raidframe/rf_raidframe.h4
-rw-r--r--sys/dev/raidframe/rf_reconstruct.c10
12 files changed, 1112 insertions, 240 deletions
diff --git a/sys/dev/raidframe/rf_diskqueue.c b/sys/dev/raidframe/rf_diskqueue.c
index b8e661b28b4..92618c7d2f4 100644
--- a/sys/dev/raidframe/rf_diskqueue.c
+++ b/sys/dev/raidframe/rf_diskqueue.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_diskqueue.c,v 1.8 2000/01/07 03:43:39 oster Exp $ */
+/* $NetBSD: rf_diskqueue.c,v 1.9 2000/02/13 04:53:57 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -164,7 +164,8 @@ init_dqd(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);
}
@@ -180,24 +181,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;
@@ -296,9 +293,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);
}
@@ -306,7 +306,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 e3e54385b0e..7c9a0c0317a 100644
--- a/sys/dev/raidframe/rf_diskqueue.h
+++ b/sys/dev/raidframe/rf_diskqueue.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_diskqueue.h,v 1.4 2000/01/08 23:02:16 oster 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.
@@ -173,21 +173,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 c052ba3edfc..147723230bf 100644
--- a/sys/dev/raidframe/rf_disks.c
+++ b/sys/dev/raidframe/rf_disks.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_disks.c,v 1.14 2000/01/09 01:29:28 oster Exp $ */
+/* $NetBSD: rf_disks.c,v 1.15 2000/02/13 04:53:57 oster Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -74,6 +74,7 @@
#include "rf_general.h"
#include "rf_options.h"
#include "rf_kintf.h"
+#include "rf_netbsd.h"
#include <sys/types.h>
#include <sys/param.h>
@@ -86,6 +87,7 @@
/* 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 *);
#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)
@@ -115,11 +117,8 @@ 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 *),
@@ -160,9 +159,10 @@ rf_ConfigureDisks( listp, raidPtr, cfgPtr )
goto fail;
}
for (c = 0; c < raidPtr->numCol; c++) {
- ret = rf_ConfigureDisk(raidPtr,
- &cfgPtr->devnames[r][c][0],
- &disks[r][c], r, c);
+ ret = rf_ConfigureDisk(raidPtr,
+ &cfgPtr->devnames[r][c][0],
+ &disks[r][c], r, c);
+
if (ret)
goto fail;
@@ -185,14 +185,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
@@ -343,11 +341,176 @@ 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;
+
+#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;
+ 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)) {
+ /* 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) {
+ /* 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);
+ 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;
+ } else {
+ /* Didn't find it!! Component must be dead */
+ disks[r][c].status = rf_ds_failed;
+ 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;
+ }
+
+ 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,7 +570,8 @@ 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;
@@ -764,11 +928,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)
@@ -842,7 +1001,7 @@ 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->sectorsPerDisk,
diff --git a/sys/dev/raidframe/rf_disks.h b/sys/dev/raidframe/rf_disks.h
index 21868d53ce6..a957f1b53fa 100644
--- a/sys/dev/raidframe/rf_disks.h
+++ b/sys/dev/raidframe/rf_disks.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_disks.h,v 1.4 1999/02/24 00:00:03 oster Exp $ */
+/* $NetBSD: rf_disks.h,v 1.5 2000/02/13 04:53:57 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -37,6 +37,7 @@
#include "rf_archs.h"
#include "rf_types.h"
+#include "rf_netbsd.h"
/*
* A physical disk can be in one of several states:
@@ -67,16 +68,8 @@ 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 */
dev_t dev;
};
/*
@@ -91,6 +84,7 @@ typedef void RF_DiskOp_t;
((_dstat_) == rf_ds_reconstructing) || ((_dstat_) == rf_ds_failed) || \
((_dstat_) == rf_ds_dist_spared))
+#ifdef _KERNEL
int
rf_ConfigureDisks(RF_ShutdownList_t ** listp, RF_Raid_t * raidPtr,
RF_Config_t * cfgPtr);
@@ -100,4 +94,8 @@ rf_ConfigureSpareDisks(RF_ShutdownList_t ** listp, RF_Raid_t * raidPtr,
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);
+#endif /* _KERNEL */
#endif /* !_RF__RF_DISKS_H_ */
diff --git a/sys/dev/raidframe/rf_driver.c b/sys/dev/raidframe/rf_driver.c
index 0c0cc1ab8c7..757ccc67a4a 100644
--- a/sys/dev/raidframe/rf_driver.c
+++ b/sys/dev/raidframe/rf_driver.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_driver.c,v 1.27 2000/01/09 03:44:33 oster Exp $ */
+/* $NetBSD: rf_driver.c,v 1.28 2000/02/13 04:53:57 oster Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -370,14 +370,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);
@@ -393,15 +397,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);
@@ -423,15 +429,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 */
@@ -492,8 +489,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);
@@ -511,6 +516,10 @@ rf_Configure(raidPtr, cfgPtr)
}
}
+ raidPtr->copyback_in_progress = 0;
+ raidPtr->parity_rewrite_in_progress = 0;
+ raidPtr->recon_in_progress = 0;
+
if (rf_keepAccTotals) {
raidPtr->keep_acc_totals = 1;
}
diff --git a/sys/dev/raidframe/rf_driver.h b/sys/dev/raidframe/rf_driver.h
index 10402d6c4fd..a2eb166d18d 100644
--- a/sys/dev/raidframe/rf_driver.h
+++ b/sys/dev/raidframe/rf_driver.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_driver.h,v 1.3 1999/02/05 00:06:11 oster Exp $ */
+/* $NetBSD: rf_driver.h,v 1.4 2000/02/13 04:53:57 oster Exp $ */
/*
* rf_driver.h
*/
@@ -34,34 +34,45 @@
#include "rf_threadstuff.h"
#include "rf_types.h"
+#include "rf_netbsd.h"
+#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_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);
-
+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_kintf.h b/sys/dev/raidframe/rf_kintf.h
index afe275ec4ff..9e95c689a98 100644
--- a/sys/dev/raidframe/rf_kintf.h
+++ b/sys/dev/raidframe/rf_kintf.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_kintf.h,v 1.7 2000/01/09 01:29:27 oster Exp $ */
+/* $NetBSD: rf_kintf.h,v 1.8 2000/02/13 04:53:58 oster Exp $ */
/*
* rf_kintf.h
*
@@ -47,5 +47,6 @@ void rf_update_component_labels( RF_Raid_t *);
int raidlookup __P((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 __P((RF_Raid_t *, RF_ComponentLabel_t *));
#endif /* _RF__RF_KINTF_H_ */
diff --git a/sys/dev/raidframe/rf_netbsd.h b/sys/dev/raidframe/rf_netbsd.h
index 309d220bb3b..2022156396b 100644
--- a/sys/dev/raidframe/rf_netbsd.h
+++ b/sys/dev/raidframe/rf_netbsd.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_netbsd.h,v 1.6 1999/05/13 21:46:17 ad Exp $ */
+/* $NetBSD: rf_netbsd.h,v 1.7 2000/02/13 04:53:57 oster Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -68,6 +68,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. (Not currently used) */
+ 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 {
@@ -95,5 +122,21 @@ struct raidcinfo {
};
+
+/* XXX probably belongs in a different .h file. */
+typedef struct RF_AutoConfig_s {
+ char devname[56];
+ dev_t dev;
+ struct vnode *vp;
+ RF_ComponentLabel_t *clabel;
+ struct RF_AutoConfig_s *next;
+ /* LIST_ENTRY(RF_AutoConfig_s) component_list; */
+} RF_AutoConfig_t;
+
+typedef struct RF_ConfigSet_s {
+ struct RF_AutoConfig_s *ac;
+ 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 66fd8f5ea2d..301b749f478 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.47 2000/01/21 23:39:59 thorpej Exp $ */
+/* $NetBSD: rf_netbsdkintf.c,v 1.48 2000/02/13 04:53:57 oster Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -224,7 +224,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 +262,14 @@ 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;
+struct cfdata cf_raidrootdev;
+struct cfdriver cfdrv;
+/* XXX these should be moved up */
+#include "rf_configure.h"
+#include <sys/reboot.h>
void rf_ReconThread __P((struct rf_recon_req *));
/* XXX what I want is: */
@@ -269,6 +277,24 @@ 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));
+void print_component_label __P((RF_ComponentLabel_t *));
+RF_ConfigSet_t *rf_create_auto_sets __P((RF_AutoConfig_t *));
+static int does_it_fit __P((RF_ConfigSet_t *,RF_AutoConfig_t *));
+static int reasonable_label __P((RF_ComponentLabel_t *));
+void 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 release_all_vps __P((RF_ConfigSet_t *));
+void cleanup_config_set __P((RF_ConfigSet_t *));
+
+static int raidautoconfig = 0; /* Debugging, mostly. Set to 0 to not
+ allow autoconfig to take place */
+/* XXX ugly hack. */
+const char *raid_rooty = "raid0";
+extern struct device *booted_device;
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);
@@ -315,8 +343,8 @@ raidattach(num)
* lets us lock the device and what-not when it gets opened. */
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;
@@ -324,8 +352,22 @@ raidattach(num)
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);
+
RF_Calloc(raidPtrs[raidID], 1, sizeof(RF_Raid_t),
(RF_Raid_t *));
if (raidPtrs[raidID] == NULL) {
@@ -334,6 +376,114 @@ raidattach(num)
return;
}
}
+
+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);
+
+ /* 4. make sure we get our mud.. I mean root.. hooks in.. */
+ /* XXXX pick raid0 for now... and this should be only done
+ if we find something that's bootable!!! */
+#if 0
+ mountroothook_establish(rf_mountroot_hook, &raidrootdev[0]);
+#endif
+ if (boothowto & RB_ASKNAME) {
+ /* We don't auto-config... */
+ } else {
+ /* They didn't ask, and we found something bootable... */
+ /* XXX pretend for now.. */
+#if 0
+ booted_device = &raidrootdev[0];
+#endif
+ }
+}
+
+}
+
+void
+rf_buildroothack(arg)
+ void *arg;
+{
+ RF_ConfigSet_t *config_sets = arg;
+ RF_ConfigSet_t *cset;
+ RF_ConfigSet_t *next_cset;
+ RF_Raid_t *raidPtr;
+ RF_Config_t *config;
+ int raidID;
+ int retcode;
+
+ raidID=0;
+ cset = config_sets;
+ while(cset != NULL ) {
+ next_cset = cset->next;
+ if (cset->ac->clabel->autoconfigure==1) {
+ printf("Starting autoconfigure on raid%d\n",raidID);
+ 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;
+ }
+ /* XXX raidID needs to be set correctly.. */
+ raidPtr = raidPtrs[raidID];
+ /* XXX all this stuff should be done SOMEWHERE ELSE! */
+ raidPtr->raidid = raidID;
+ raidPtr->openings = RAIDOUTSTANDING;
+ create_configuration(cset->ac, config, raidPtr);
+ retcode = rf_Configure( raidPtr, config, cset->ac );
+
+ if (retcode == 0) {
+#if DEBUG
+ printf("Calling raidinit()\n");
+#endif
+ /* XXX the 0's below are bogus! */
+ retcode = raidinit(0, raidPtrs[raidID], 0);
+ if (retcode) {
+ printf("init returned: %d\n",retcode);
+ }
+ rf_markalldirty( raidPtrs[raidID] );
+ }
+ raidID++; /* XXX for now.. */
+ free(config, M_RAIDFRAME);
+ } else {
+ /* we're not autoconfiguring this set...
+ release the associated resources */
+#if DEBUG
+ printf("Releasing vp's\n");
+#endif
+ release_all_vps(cset);
+#if DEBUG
+ printf("Done.\n");
+#endif
+ }
+ /* cleanup */
+#if DEBUG
+ printf("Cleaning up config set\n");
+#endif
+ cleanup_config_set(cset);
+#if DEBUG
+ printf("Done cleanup\n");
+#endif
+ cset = next_cset;
+ }
}
@@ -634,6 +784,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,9 +792,9 @@ 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;
@@ -693,6 +844,8 @@ raidioctl(dev, cmd, data, flag, p)
case RAIDFRAME_CHECK_PARITY:
case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
case RAIDFRAME_CHECK_COPYBACK_STATUS:
+ case RAIDFRAME_SET_AUTOCONFIG:
+ case RAIDFRAME_SET_ROOT:
if ((rs->sc_flags & RAIDF_INITED) == 0)
return (ENXIO);
}
@@ -701,6 +854,12 @@ 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);
+ }
+
/* copy-in the configuration information */
/* data points to a pointer to the configuration structure */
@@ -751,22 +910,22 @@ 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 );
}
@@ -812,49 +971,48 @@ 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));
+ 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 --
@@ -863,18 +1021,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)) {
@@ -882,16 +1040,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
@@ -899,19 +1060,17 @@ 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, clabel);
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.blockSize = diskPtr->blockSize;
+ ci_label.numBlocks = diskPtr->numBlocks;
+ ci_label.partitionSize = diskPtr->partitionSize;
ci_label.column = column;
raidwrite_component_label(
raidPtr->Disks[row][column].dev,
@@ -921,6 +1080,17 @@ raidioctl(dev, cmd, data, flag, p)
}
return (retcode);
+ case RAIDFRAME_SET_AUTOCONFIG:
+ d = rf_set_autoconfig(raidPtr, *data);
+ printf("New autoconfig value is: %d\n", d);
+ *data = d;
+ return (retcode);
+
+ case RAIDFRAME_SET_ROOT:
+ d = rf_set_rootpartition(raidPtr, *data);
+ printf("New rootpartition value is: %d\n", d);
+ *data = d;
+ return (retcode);
/* initialize all parity */
case RAIDFRAME_REWRITEPARITY:
@@ -1893,11 +2063,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);
}
@@ -1905,20 +2075,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;
@@ -1941,22 +2111,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_un.b_addr,
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);
+ print_component_label( clabel );
#endif
} else {
+#if 0
printf("Failed to read RAID component label!\n");
+#endif
}
bp->b_flags = B_INVAL | B_AGE;
@@ -1965,10 +2128,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;
@@ -1985,14 +2148,16 @@ raidwrite_component_label(dev, b_vp, component_label)
memset( bp->b_un.b_addr, 0, RF_COMPONENT_INFO_SIZE );
- memcpy( bp->b_un.b_addr, component_label, sizeof(RF_ComponentLabel_t));
+ memcpy( bp->b_un.b_addr, 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);
@@ -2002,7 +2167,7 @@ void
rf_markalldirty( raidPtr )
RF_Raid_t *raidPtr;
{
- RF_ComponentLabel_t c_label;
+ RF_ComponentLabel_t clabel;
int r,c;
raidPtr->mod_counter++;
@@ -2012,19 +2177,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,
@@ -2070,21 +2235,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);
}
@@ -2098,7 +2263,7 @@ void
rf_update_component_labels( raidPtr )
RF_Raid_t *raidPtr;
{
- RF_ComponentLabel_t c_label;
+ RF_ComponentLabel_t clabel;
int sparecol;
int r,c;
int i,j;
@@ -2118,13 +2283,13 @@ 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;
raidwrite_component_label(
raidPtr->Disks[r][c].dev,
raidPtr->raid_cinfo[r][c].ci_vp,
- &c_label);
+ &clabel);
if (raidPtr->parity_good == RF_RAID_CLEAN) {
raidmarkclean(
raidPtr->Disks[r][c].dev,
@@ -2139,14 +2304,14 @@ 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 =
+ 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);
if (raidPtr->parity_good == RF_RAID_CLEAN) {
raidmarkclean(
raidPtr->Disks[r][c].dev,
@@ -2186,21 +2351,21 @@ rf_update_component_labels( raidPtr )
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;
+ 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[0][sparecol].dev,
raidPtr->raid_cinfo[0][sparecol].ci_vp,
- &c_label);
+ &clabel);
if (raidPtr->parity_good == RF_RAID_CLEAN) {
raidmarkclean( raidPtr->Disks[0][sparecol].dev,
raidPtr->raid_cinfo[0][sparecol].ci_vp,
@@ -2297,3 +2462,473 @@ rf_ReconstructInPlaceThread(req)
/* That's all... */
kthread_exit(0); /* does not return */
}
+
+void
+rf_mountroot_hook(dev)
+ struct device *dev;
+{
+#if 1
+ printf("rf_mountroot_hook called for %s\n",dev->dv_xname);
+#endif
+ if (boothowto & RB_ASKNAME) {
+ /* We don't auto-config... */
+ } else {
+ /* They didn't ask, and we found something bootable... */
+ /* XXX pretend for now.. */
+if (raidautoconfig) {
+ rootspec = raid_rooty;
+}
+ }
+}
+
+
+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 (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);
+ 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
+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
+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(" Last configured as: raid%d\n", clabel->last_unit );
+ printf(" Config order: %d\n", clabel->config_order);
+
+}
+
+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;
+ ac->next = NULL;
+ } else {
+ /* which set does this component fit into? */
+ cset = config_sets;
+ while(cset!=NULL) {
+ if (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;
+ config_sets = cset;
+ }
+ }
+ ac = ac_next;
+ }
+
+
+ return(config_sets);
+}
+
+static int
+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... */
+
+ clabel1 = cset->ac->clabel;
+ clabel2 = ac->clabel;
+ if ((clabel1->version == clabel2->version) &&
+ (clabel1->serial_number == clabel2->serial_number) &&
+ (clabel1->mod_counter == clabel2->mod_counter) &&
+ (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);
+}
+
+#if 0
+int have_enough();
+int
+have_enough()
+{
+ /* check to see that we have enough 'live' components
+ of this set. If so, we can configure it if necessary */
+
+}
+#endif
+
+void
+create_configuration(ac,config,raidPtr)
+ RF_AutoConfig_t *ac;
+ RF_Config_t *config;
+ RF_Raid_t *raidPtr;
+{
+ RF_ComponentLabel_t *clabel;
+
+ 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;
+ }
+
+}
+
+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;
+
+ for(row=0; row<raidPtr->numRow; row++) {
+ for(column=0; column<raidPtr->numCol; column++) {
+ 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;
+
+ for(row=0; row<raidPtr->numRow; row++) {
+ for(column=0; column<raidPtr->numCol; column++) {
+ 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
+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 = ac->next;
+ }
+}
+
+
+void
+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 = clabel->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;
+ /* XXX not portable */
+ clabel->parityConfig = raidPtr->Layout.map->parityConfig;
+ /* XXX THIS SHOULD BE SET RIGHT!! */
+ clabel->maxOutstanding = 100;
+ clabel->autoconfigure = 0;
+ clabel->root_partition = 0;
+ clabel->last_unit = raidPtr->raidid;
+}
diff --git a/sys/dev/raidframe/rf_raid.h b/sys/dev/raidframe/rf_raid.h
index dc82e262c5c..ab447cc8fbf 100644
--- a/sys/dev/raidframe/rf_raid.h
+++ b/sys/dev/raidframe/rf_raid.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_raid.h,v 1.8 2000/01/05 02:57:29 oster Exp $ */
+/* $NetBSD: rf_raid.h,v 1.9 2000/02/13 04:53:57 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -59,7 +59,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
diff --git a/sys/dev/raidframe/rf_raidframe.h b/sys/dev/raidframe/rf_raidframe.h
index 0ae2d6f1df2..5772bf9a9f4 100644
--- a/sys/dev/raidframe/rf_raidframe.h
+++ b/sys/dev/raidframe/rf_raidframe.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_raidframe.h,v 1.8 2000/01/05 02:57:29 oster Exp $ */
+/* $NetBSD: rf_raidframe.h,v 1.9 2000/02/13 04:53:58 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -130,4 +130,6 @@ 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)
#endif /* !_RF__RF_RAIDFRAME_H_ */
diff --git a/sys/dev/raidframe/rf_reconstruct.c b/sys/dev/raidframe/rf_reconstruct.c
index 06c42a16138..84f800ead79 100644
--- a/sys/dev/raidframe/rf_reconstruct.c
+++ b/sys/dev/raidframe/rf_reconstruct.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rf_reconstruct.c,v 1.14 2000/01/09 03:14:33 oster Exp $ */
+/* $NetBSD: rf_reconstruct.c,v 1.15 2000/02/13 04:53:57 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -356,15 +356,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,