summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Deval <tdeval@cvs.openbsd.org>2001-12-29 21:51:19 +0000
committerThierry Deval <tdeval@cvs.openbsd.org>2001-12-29 21:51:19 +0000
commit964e9e640612bb9fc98b99bf2aaf60770ac83eb8 (patch)
tree18491c777f12628e0ab2cbe6e1d643094487eb9d
parentd9ddae19b8207c9f6b31d3af76064047a9aedce5 (diff)
Enable the RAIDFrame auto-configuration feature.
This permits one to setup a kernel able to automatically retrieve, during boot, the raid configuration from disks previously used in a RAIDFrame set. Moreover, one can define a raid set to contain a bootable partition that will be mounted on / before the system has started. A new RAID_AUTOCONFIG kernel option is used, in conjunction with the raid pseudo-device, to activate the feature. ok drahn@, deraadt@
-rw-r--r--sys/dev/raidframe/rf_engine.c127
-rw-r--r--sys/dev/raidframe/rf_kintf.h5
-rw-r--r--sys/dev/raidframe/rf_openbsdkintf.c416
-rw-r--r--sys/dev/raidframe/rf_states.c13
4 files changed, 449 insertions, 112 deletions
diff --git a/sys/dev/raidframe/rf_engine.c b/sys/dev/raidframe/rf_engine.c
index 5482dd5bac5..9c641334c1c 100644
--- a/sys/dev/raidframe/rf_engine.c
+++ b/sys/dev/raidframe/rf_engine.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_engine.c,v 1.6 2001/09/20 17:02:31 mpech Exp $ */
-/* $NetBSD: rf_engine.c,v 1.9 2000/01/08 22:57:31 oster Exp $ */
+/* $OpenBSD: rf_engine.c,v 1.7 2001/12/29 21:51:18 tdeval Exp $ */
+/* $NetBSD: rf_engine.c,v 1.10 2000/08/20 16:51:03 thorpej Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -67,7 +67,14 @@
#include "rf_shutdown.h"
#include "rf_raid.h"
-static void DAGExecutionThread(RF_ThreadArg_t arg);
+#ifdef RAID_AUTOCONFIG
+#define RF_ENGINE_PID 10
+extern int numraid;
+extern pid_t lastpid;
+static void **rf_startuphook_cookie;
+void DAGExecutionThread_pre(RF_ThreadArg_t arg);
+#endif /* RAID_AUTOCONFIG */
+void DAGExecutionThread(RF_ThreadArg_t arg);
#define DO_INIT(_l_,_r_) { \
int _rc; \
@@ -86,14 +93,28 @@ static void DAGExecutionThread(RF_ThreadArg_t arg);
/*
* XXX Is this spl-ing really necessary?
*/
-#define DO_LOCK(_r_) { ks = splbio(); RF_LOCK_MUTEX((_r_)->node_queue_mutex); }
-#define DO_UNLOCK(_r_) { RF_UNLOCK_MUTEX((_r_)->node_queue_mutex); splx(ks); }
-#define DO_WAIT(_r_) tsleep(&(_r_)->node_queue, PRIBIO, "raidframe nq",0)
-#define DO_SIGNAL(_r_) wakeup(&(_r_)->node_queue)
+#define DO_LOCK(_r_) \
+do { \
+ ks = splbio(); \
+ RF_LOCK_MUTEX((_r_)->node_queue_mutex); \
+} while (0)
-static void rf_ShutdownEngine(void *);
+#define DO_UNLOCK(_r_) \
+do { \
+ RF_UNLOCK_MUTEX((_r_)->node_queue_mutex); \
+ splx(ks); \
+} while (0)
-static void
+#define DO_WAIT(_r_) \
+ RF_WAIT_COND((_r_)->node_queue, (_r_)->node_queue_mutex)
+
+/* XXX RF_SIGNAL_COND? */
+#define DO_SIGNAL(_r_) \
+ RF_BROADCAST_COND((_r_)->node_queue)
+
+void rf_ShutdownEngine(void *);
+
+void
rf_ShutdownEngine(arg)
void *arg;
{
@@ -111,6 +132,7 @@ rf_ConfigureEngine(
RF_Config_t * cfgPtr)
{
int rc;
+ char raidname[16];
DO_INIT(listp, raidPtr);
@@ -127,21 +149,37 @@ rf_ConfigureEngine(
if (rf_engineDebug) {
printf("raid%d: Creating engine thread\n", raidPtr->raidid);
}
- if (RF_CREATE_THREAD(raidPtr->engine_thread, DAGExecutionThread, raidPtr,"raid")) {
- RF_ERRORMSG("RAIDFRAME: Unable to create engine thread\n");
- return (ENOMEM);
- }
- if (rf_engineDebug) {
- printf("raid%d: Created engine thread\n", raidPtr->raidid);
+#ifdef RAID_AUTOCONFIG
+ if (initproc == NULL) {
+ if (rf_startuphook_cookie == NULL) {
+ rf_startuphook_cookie =
+ malloc(numraid * sizeof(void*),
+ M_RAIDFRAME, M_NOWAIT);
+ if (rf_startuphook_cookie == NULL)
+ return (ENOMEM);
+ bzero(rf_startuphook_cookie, numraid * sizeof(void*));
+ }
+ rf_startuphook_cookie[raidPtr->raidid] =
+ startuphook_establish(DAGExecutionThread_pre, raidPtr);
+ } else {
+#endif /* RAID_AUTOCONFIG */
+ snprintf(&raidname[0], 16, "raid%d", raidPtr->raidid);
+ if (RF_CREATE_THREAD(raidPtr->engine_thread,
+ DAGExecutionThread, raidPtr, &raidname[0])) {
+ RF_ERRORMSG("RAIDFRAME: Unable to create engine thread\n");
+ return (ENOMEM);
+ }
+ if (rf_engineDebug) {
+ printf("raid%d: Created engine thread\n", raidPtr->raidid);
+ }
+ RF_THREADGROUP_STARTED(&raidPtr->engine_tg);
+#ifdef RAID_AUTOCONFIG
}
- RF_THREADGROUP_STARTED(&raidPtr->engine_tg);
+#endif
/* XXX something is missing here... */
#ifdef debug
printf("Skipping the WAIT_START!!\n");
#endif
-#if 0
- RF_THREADGROUP_WAIT_START(&raidPtr->engine_tg);
-#endif
/* engine thread is now running and waiting for work */
if (rf_engineDebug) {
printf("raid%d: Engine thread running and waiting for events\n", raidPtr->raidid);
@@ -267,7 +305,7 @@ FireNode(RF_DagNode_t * node)
node->dagHdr->raidPtr->raidid,
(unsigned long) node, node->name);
}
- if (node->flags & RF_DAGNODE_FLAG_YIELD)
+ if (node->flags & RF_DAGNODE_FLAG_YIELD) {
#if (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(_KERNEL)
/* thread_block(); */
/* printf("Need to block the thread here...\n"); */
@@ -276,6 +314,7 @@ FireNode(RF_DagNode_t * node)
#else
thread_block();
#endif
+ }
(*(node->undoFunc)) (node);
break;
default:
@@ -704,7 +743,49 @@ rf_DispatchDAG(
* characteristics from the aio_completion_thread.
*/
-static void
+#ifdef RAID_AUTOCONFIG
+void
+DAGExecutionThread_pre(RF_ThreadArg_t arg)
+{
+ RF_Raid_t *raidPtr;
+ char raidname[16];
+ int len;
+ pid_t oldpid = lastpid;
+
+ raidPtr = (RF_Raid_t *) arg;
+
+ if (rf_startuphook_cookie && rf_startuphook_cookie[raidPtr->raidid])
+ startuphook_disestablish(rf_startuphook_cookie[raidPtr->raidid]);
+
+ if (rf_engineDebug) {
+ printf("raid%d: Creating engine thread\n", raidPtr->raidid);
+ }
+ lastpid = -2;
+
+ len = sprintf(&raidname[0], "raid%d", raidPtr->raidid);
+#ifdef DIAGNOSTIC
+ if (len >= sizeof(raidname))
+ panic("raidname expansion too long.");
+#endif /* DIAGNOSTIC */
+
+ if (RF_CREATE_THREAD(raidPtr->engine_thread, DAGExecutionThread,
+ raidPtr, &raidname[0])) {
+ RF_ERRORMSG("RAIDFRAME: Unable to create engine thread\n");
+ return;
+ }
+ LIST_REMOVE(raidPtr->engine_thread, p_hash);
+ raidPtr->engine_thread->p_pid = RF_ENGINE_PID + raidPtr->raidid;
+ LIST_INSERT_HEAD(PIDHASH(RF_ENGINE_PID + raidPtr->raidid),
+ raidPtr->engine_thread, p_hash);
+ lastpid = oldpid;
+ if (rf_engineDebug) {
+ printf("raid%d: Created engine thread\n", raidPtr->raidid);
+ }
+ RF_THREADGROUP_STARTED(&raidPtr->engine_tg);
+}
+#endif /* RAID_AUTOCONFIG */
+
+void
DAGExecutionThread(RF_ThreadArg_t arg)
{
RF_DagNode_t *nd, *local_nq, *term_nq, *fire_nq;
@@ -714,6 +795,10 @@ DAGExecutionThread(RF_ThreadArg_t arg)
raidPtr = (RF_Raid_t *) arg;
+ while (!(&raidPtr->engine_tg)->created)
+ (void) tsleep((void*)&(&raidPtr->engine_tg)->created, PWAIT,
+ "raidinit", 0);
+
if (rf_engineDebug) {
printf("raid%d: Engine thread is running\n", raidPtr->raidid);
}
diff --git a/sys/dev/raidframe/rf_kintf.h b/sys/dev/raidframe/rf_kintf.h
index 65e5c88c07a..9b71fea32dc 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.6 2000/08/08 16:07:41 peter Exp $ */
-/* $NetBSD: rf_kintf.h,v 1.14 2000/06/04 02:05:13 oster Exp $ */
+/* $OpenBSD: rf_kintf.h,v 1.7 2001/12/29 21:51:18 tdeval Exp $ */
+/* $NetBSD: rf_kintf.h,v 1.15 2000/10/20 02:24:45 oster Exp $ */
/*
* rf_kintf.h
*
@@ -54,4 +54,5 @@ 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);
+void rf_disk_unbusy(RF_RaidAccessDesc_t *);
#endif /* _RF__RF_KINTF_H_ */
diff --git a/sys/dev/raidframe/rf_openbsdkintf.c b/sys/dev/raidframe/rf_openbsdkintf.c
index 8889dc70e96..b1f536952b0 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.11 2001/12/08 22:10:01 tdeval Exp $ */
-/* $NetBSD: rf_netbsdkintf.c,v 1.93 2000/07/14 15:26:29 oster Exp $ */
+/* $OpenBSD: rf_openbsdkintf.c,v 1.12 2001/12/29 21:51:18 tdeval Exp $ */
+/* $NetBSD: rf_netbsdkintf.c,v 1.109 2001/07/27 03:30:07 oster Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -117,6 +117,7 @@
#include <sys/errno.h>
#include <sys/param.h>
+#include <sys/pool.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/disk.h>
@@ -138,6 +139,7 @@
#include "rf_copyback.h"
#include "rf_dag.h"
#include "rf_dagflags.h"
+#include "rf_desc.h"
#include "rf_diskqueue.h"
#include "rf_acctrace.h"
#include "rf_etimer.h"
@@ -174,7 +176,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 void raidinit __P((RF_Raid_t *));
+void raidinit __P((RF_Raid_t *));
void raidattach __P((int));
int raidsize __P((dev_t));
@@ -196,8 +198,8 @@ struct raidbuf {
RF_DiskQueueData_t *req;/* the request that this was part of.. */
};
-#define RAIDGETBUF() malloc(sizeof (struct raidbuf), M_RAIDFRAME, M_NOWAIT)
-#define RAIDPUTBUF(buf) free(buf, M_RAIDFRAME)
+#define RAIDGETBUF(rs) pool_get(&(rs)->sc_cbufpool, PR_NOWAIT)
+#define RAIDPUTBUF(rs, cbp) pool_put(&(rs)->sc_cbufpool, cbp)
/*
* Some port (like i386) use a swapgeneric that wants to snoop around
@@ -218,6 +220,7 @@ struct raid_softc {
size_t sc_size; /* size of the raid 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 sc_q; /* used for the device queue */
};
@@ -232,6 +235,22 @@ struct raid_softc {
int numraid = 0;
/*
+ * Here we define a cfattach structure for inserting any new raid device
+ * into the device tree. This is needed by some archs that look for
+ * bootable devices in there.
+ */
+int rf_probe __P((struct device *, void *, void *));
+void rf_attach __P((struct device *, struct device *, void *));
+int rf_detach __P((struct device *, int));
+int rf_activate __P((struct device *, enum devact));
+void rf_zeroref __P((struct device *));
+
+struct cfattach raid_ca = {
+ sizeof(struct raid_softc), rf_probe, rf_attach,
+ rf_detach, rf_activate, rf_zeroref
+};
+
+/*
* Allow RAIDOUTSTANDING number of simultaneous IO's to this RAID device.
* Be aware that large numbers can allow the driver to consume a lot of
* kernel memory, especially on writes, and in degraded mode reads.
@@ -257,6 +276,7 @@ int numraid = 0;
/* declared here, and made public, for the benefit of KVM stuff.. */
struct raid_softc *raid_softc;
+struct raid_softc **raid_scPtrs;
void raidgetdefaultlabel
__P((RF_Raid_t *, struct raid_softc *, struct disklabel *));
@@ -271,6 +291,9 @@ void rf_mountroot_hook __P((struct device *));
struct device *raidrootdev;
+int findblkmajor __P((struct device *dv));
+char *findblkname __P((int));
+
void rf_ReconThread __P((struct rf_recon_req *));
/* XXX what I want is: */
/*void rf_ReconThread __P((RF_Raid_t *raidPtr)); */
@@ -279,12 +302,12 @@ 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 *));
+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 *));
+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));
@@ -302,6 +325,45 @@ static int raidautoconfig = 0; /* Debugging, mostly. Set to 0 to not
kernel config file. */
#endif
+int
+rf_probe(parent, match_, aux)
+ struct device *parent;
+ void *match_;
+ void *aux;
+{
+ return 0;
+}
+
+void
+rf_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ /* struct raid_softc *raid = (void *)self; */
+}
+
+int
+rf_detach(self, flags)
+ struct device *self;
+ int flags;
+{
+ return 0;
+}
+
+int
+rf_activate(self, act)
+ struct device *self;
+ enum devact act;
+{
+ return 0;
+}
+
+void
+rf_zeroref(self)
+ struct device *self;
+{
+}
+
void
raidattach(num)
int num;
@@ -362,6 +424,16 @@ raidattach(num)
bzero(raid_softc, num * sizeof (struct raid_softc));
+ raid_scPtrs = (struct raid_softc **)
+ malloc(num * sizeof(struct raid_softc *),
+ M_RAIDFRAME, M_NOWAIT);
+ if (raid_scPtrs == NULL) {
+ printf("WARNING: no memory for RAIDframe driver\n");
+ return;
+ }
+
+ bzero(raid_scPtrs, num * sizeof (struct raid_softc *));
+
raidrootdev = (struct device *)malloc(num * sizeof(struct device),
M_RAIDFRAME, M_NOWAIT);
if (raidrootdev == NULL) {
@@ -389,13 +461,16 @@ raidattach(num)
}
}
-#if RAID_AUTOCONFIG
+ raid_cd.cd_devs = (void **) raid_scPtrs;
+ raid_cd.cd_ndevs = num;
+
+#ifdef RAID_AUTOCONFIG
raidautoconfig = 1;
if (raidautoconfig) {
/* 1. locate all RAID components on the system */
-#if DEBUG
+#ifdef DEBUG
printf("Searching for raid components...\n");
#endif
ac_list = rf_find_raid_components();
@@ -410,7 +485,7 @@ if (raidautoconfig) {
/* schedule the creation of the thread to do the
"/ on RAID" stuff */
- kthread_create(rf_buildroothack, config_sets, NULL, "raidauto");
+ rf_buildroothack(config_sets);
#if 0
mountroothook_establish(rf_mountroot_hook, &raidrootdev[0]);
@@ -432,7 +507,9 @@ rf_buildroothack(arg)
int raidID;
int rootID;
int num_root;
+ int majdev;
+ rootID = 0;
num_root = 0;
cset = config_sets;
while(cset != NULL ) {
@@ -443,11 +520,14 @@ rf_buildroothack(arg)
if (!retcode) {
if (cset->rootable) {
rootID = raidID;
+#ifdef DEBUG
+ printf("eligible root device %d: raid%d\n", num_root, rootID);
+#endif /* DEBUG */
num_root++;
}
} else {
/* The autoconfig didn't work :( */
-#if DEBUG
+#ifdef DEBUG
printf("Autoconfig failed with code %d for raid%d\n", retcode, raidID);
#endif
rf_release_all_vps(cset);
@@ -467,7 +547,13 @@ rf_buildroothack(arg)
/* They didn't ask, and we found something bootable... */
if (num_root == 1) {
- booted_device = &raidrootdev[rootID];
+ majdev = findblkmajor(&raidrootdev[rootID]);
+ if (majdev < 0)
+ boothowto |= RB_ASKNAME;
+ else {
+ rootdev = MAKEDISKDEV(majdev,rootID,0);
+ boothowto |= RB_DFLTROOT;
+ }
} else if (num_root > 1) {
/* we can't guess.. require the user to answer... */
boothowto |= RB_ASKNAME;
@@ -645,6 +731,24 @@ raidclose(dev, flags, fmt, p)
#endif
rf_update_component_labels(raidPtrs[unit],
RF_FINAL_COMPONENT_UPDATE);
+#if 0
+ if (doing_shutdown) {
+/* #endif */
+ /* last one, and we're going down, so
+ lights out for this RAID set too. */
+ error = rf_Shutdown(raidPtrs[unit]);
+ pool_destroy(&rs->sc_cbufpool);
+
+ /* It's no longer initialized... */
+ rs->sc_flags &= ~RAIDF_INITED;
+
+ /* config_detach the device. */
+ config_detach(device_lookup(&raid_cd, unit), 0);
+
+ disk_detach(&rs->sc_dkdev);
+/* #if 0 */
+ }
+#endif
}
raidunlock(rs);
@@ -665,7 +769,7 @@ raidstrategy(bp)
if ((rs->sc_flags & RAIDF_INITED) ==0) {
bp->b_error = ENXIO;
- bp->b_flags = B_ERROR;
+ bp->b_flags |= B_ERROR;
bp->b_resid = bp->b_bcount;
biodone(bp);
return;
@@ -961,9 +1065,14 @@ raidioctl(dev, cmd, data, flag, p)
retcode = rf_Shutdown(raidPtr);
+ pool_destroy(&rs->sc_cbufpool);
+
/* It's no longer initialized... */
rs->sc_flags &= ~RAIDF_INITED;
+ /* config_detach the device. */
+ config_detach(device_lookup(&raid_cd, unit), 0);
+
/* Detach the disk. */
disk_detach(&rs->sc_dkdev);
@@ -1068,12 +1177,15 @@ raidioctl(dev, cmd, data, flag, p)
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,
- raidPtr->raid_cinfo[row][column].ci_vp,
- &ci_label );
+ if (!RF_DEAD_DISK(diskPtr->status)) {
+ ci_label.partitionSize =
+ diskPtr->partitionSize;
+ ci_label.column = column;
+ raidwrite_component_label(
+ raidPtr->Disks[row][column].dev,
+ raidPtr->raid_cinfo[row][column].ci_vp,
+ &ci_label );
+ }
}
}
@@ -1098,6 +1210,7 @@ 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);
@@ -1212,6 +1325,7 @@ raidioctl(dev, cmd, data, flag, p)
case RAIDFRAME_CHECK_PARITY:
*(int *) data = raidPtr->parity_good;
return (0);
+
case RAIDFRAME_RESET_ACCTOTALS:
bzero(&raidPtr->acc_totals, sizeof(raidPtr->acc_totals));
return (0);
@@ -1229,7 +1343,7 @@ raidioctl(dev, cmd, data, flag, p)
*(int *) data = raidPtr->totalSectors;
return (0);
- /* fail a disk & optionally start reconstruction */
+ /* fail a disk & optionally start reconstruction */
case RAIDFRAME_FAIL_DISK:
rr = (struct rf_recon_req *)data;
@@ -1255,10 +1369,10 @@ raidioctl(dev, cmd, data, flag, p)
rrcopy,"raid_recon");
return (0);
- /*
- * Invoke a copyback operation after recon on whatever
- * disk needs it, if any.
- */
+ /*
+ * Invoke a copyback operation after recon on whatever
+ * disk needs it, if any.
+ */
case RAIDFRAME_COPYBACK:
if (raidPtr->Layout.map->faultsTolerated == 0) {
/* This makes no sense on a RAID 0!! */
@@ -1274,8 +1388,8 @@ raidioctl(dev, cmd, data, flag, p)
rf_CopybackThread,
raidPtr,"raid_copyback");
return (retcode);
-
- /* Return the percentage completion of reconstruction */
+
+ /* 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, so tell the
@@ -1352,7 +1466,8 @@ raidioctl(dev, cmd, data, flag, p)
return(0);
}
if (raidPtr->copyback_in_progress == 1) {
- *(int *) data = 100 * raidPtr->copyback_stripes_done / raidPtr->Layout.numStripe;
+ *(int *) data = 100 * raidPtr->copyback_stripes_done /
+ raidPtr->Layout.numStripe;
} else {
*(int *) data = 100;
}
@@ -1441,8 +1556,8 @@ raidioctl(dev, cmd, data, flag, p)
return (retcode);
#endif
+ /* fall through to the os-specific code below */
default:
- /* fall through to the os-specific code below */
break;
}
@@ -1465,13 +1580,17 @@ raidioctl(dev, cmd, data, flag, p)
case DIOCWDINFO:
case DIOCSDINFO:
+ {
+ struct disklabel *lp;
+ lp = (struct disklabel *)data;
+
if ((error = raidlock(rs)) != 0)
return (error);
rs->sc_flags |= RAIDF_LABELLING;
error = setdisklabel(rs->sc_dkdev.dk_label,
- (struct disklabel *)data, 0, rs->sc_dkdev.dk_cpulabel);
+ lp, 0, rs->sc_dkdev.dk_cpulabel);
if (error == 0) {
if (cmd == DIOCWDINFO)
error = writedisklabel(RAIDLABELDEV(dev),
@@ -1486,6 +1605,7 @@ raidioctl(dev, cmd, data, flag, p)
if (error)
return (error);
break;
+ }
case DIOCWLABEL:
if (*(int *)data != 0)
@@ -1494,18 +1614,14 @@ raidioctl(dev, cmd, data, flag, p)
rs->sc_flags &= ~RAIDF_WLABEL;
break;
-#if 0
- case DIOCGDEFLABEL:
-#endif
case DIOCGPDINFO:
- raidgetdefaultlabel(raidPtr, rs,
- (struct disklabel *) data);
+ raidgetdefaultlabel(raidPtr, rs, (struct disklabel *) data);
break;
-
default:
retcode = ENOTTY;
}
+
return (retcode);
}
@@ -1513,16 +1629,20 @@ raidioctl(dev, cmd, data, flag, p)
* raidinit -- complete the rest of the initialization for the
* RAIDframe device.
*/
-static void
+void
raidinit(raidPtr)
RF_Raid_t *raidPtr;
{
struct raid_softc *rs;
- int unit;
+ struct cfdata *cf;
+ int unit;
unit = raidPtr->raidid;
rs = &raid_softc[unit];
+ pool_init(&rs->sc_cbufpool, sizeof(struct raidbuf), 0,
+ 0, 0, "raidpl", 0, NULL, NULL, M_RAIDFRAME);
+
/* XXX should check return code first... */
rs->sc_flags |= RAIDF_INITED;
@@ -1544,6 +1664,24 @@ raidinit(raidPtr)
* protectedSectors, as used in RAIDframe.
*/
rs->sc_size = raidPtr->totalSectors;
+
+ /*
+ * config_attach the raid device into the device tree.
+ * For autoconf rootdev selection...
+ */
+ cf = malloc(sizeof(struct cfdata), M_RAIDFRAME, M_NOWAIT);
+ if (cf == NULL) {
+ printf("WARNING: no memory for cfdata struct\n");
+ return;
+ }
+ bzero(cf, sizeof(struct cfdata));
+
+ cf->cf_attach = &raid_ca;
+ cf->cf_driver = &raid_cd;
+ cf->cf_unit = unit;
+
+ config_attach(NULL, cf, NULL, NULL);
+ printf("\n"); /* pretty up config_attach()'s output. */
}
/*
@@ -1691,11 +1829,13 @@ raidstart(raidPtr)
*/
do_async = 1;
- /* don't ever condition on bp->b_flags & B_WRITE.
- * always condition on B_READ instead */
+ disk_busy(&rs->sc_dkdev);
/* XXX we're still at splbio() here... do we *really*
- need to be? */
+ * need to be? */
+
+ /* don't ever condition on bp->b_flags & B_WRITE.
+ * always condition on B_READ instead */
retcode = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ?
RF_IO_TYPE_READ : RF_IO_TYPE_WRITE,
@@ -1742,9 +1882,6 @@ rf_DispatchKernelIO(queue, req)
rs = &raid_softc[unit];
- /* XXX is this the right place? */
- disk_busy(&rs->sc_dkdev);
-
bp = req->bp;
#if 1
@@ -1763,7 +1900,7 @@ rf_DispatchKernelIO(queue, req)
}
#endif
- raidbp = RAIDGETBUF();
+ raidbp = RAIDGETBUF(rs);
raidbp->rf_flags = 0; /* XXX not really used anywhere... */
@@ -1917,12 +2054,7 @@ rf_KernelWakeupFunc(vbp)
}
rs = &raid_softc[unit];
- RAIDPUTBUF(raidbp);
-
- if (bp->b_resid==0) {
- /* XXX is this the right place for a disk_unbusy()??!??!?!? */
- disk_unbusy(&rs->sc_dkdev, (bp->b_bcount - bp->b_resid));
- }
+ RAIDPUTBUF(rs, raidbp);
rf_DiskIOComplete(queue, req, (bp->b_flags & B_ERROR) ? 1 : 0);
(req->CompleteFunc)(req->argument, (bp->b_flags & B_ERROR) ? 1 : 0);
@@ -1979,7 +2111,7 @@ raidgetdefaultlabel(raidPtr, rs, lp)
lp->d_secperunit = raidPtr->totalSectors;
lp->d_secsize = raidPtr->bytesPerSector;
lp->d_nsectors = raidPtr->Layout.dataSectorsPerStripe;
- lp->d_ntracks = 1;
+ lp->d_ntracks = 4 * raidPtr->numCol;
lp->d_ncylinders = raidPtr->totalSectors /
(lp->d_nsectors * lp->d_ntracks);
lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
@@ -2204,6 +2336,12 @@ raidread_component_label(dev, b_vp, clabel)
/* XXX should probably ensure that we don't try to do this if
someone has changed rf_protected_sectors. */
+ if (b_vp == NULL) {
+ /* For whatever reason, this component is not valid.
+ Don't try to read a component label from it. */
+ return(EINVAL);
+ }
+
/* get a block of the appropriate size... */
bp = geteblk((int)RF_COMPONENT_INFO_SIZE);
bp->b_dev = dev;
@@ -2211,7 +2349,7 @@ raidread_component_label(dev, b_vp, clabel)
/* get our ducks in a row for the read */
bp->b_blkno = RF_COMPONENT_INFO_OFFSET / DEV_BSIZE;
bp->b_bcount = RF_COMPONENT_INFO_SIZE;
- bp->b_flags = B_BUSY | B_READ;
+ bp->b_flags |= B_READ;
bp->b_resid = RF_COMPONENT_INFO_SIZE / DEV_BSIZE;
(*bdevsw[major(bp->b_dev)].d_strategy)(bp);
@@ -2230,7 +2368,6 @@ raidread_component_label(dev, b_vp, clabel)
#endif
}
- bp->b_flags = B_INVAL | B_AGE;
brelse(bp);
return(error);
}
@@ -2251,7 +2388,7 @@ raidwrite_component_label(dev, b_vp, clabel)
/* get our ducks in a row for the write */
bp->b_blkno = RF_COMPONENT_INFO_OFFSET / DEV_BSIZE;
bp->b_bcount = RF_COMPONENT_INFO_SIZE;
- bp->b_flags = B_BUSY | B_WRITE;
+ bp->b_flags |= B_WRITE;
bp->b_resid = RF_COMPONENT_INFO_SIZE / DEV_BSIZE;
memset(bp->b_data, 0, RF_COMPONENT_INFO_SIZE );
@@ -2260,7 +2397,6 @@ raidwrite_component_label(dev, b_vp, clabel)
(*bdevsw[major(bp->b_dev)].d_strategy)(bp);
error = biowait(bp);
- bp->b_flags = B_INVAL | B_AGE;
brelse(bp);
if (error) {
#if 1
@@ -2281,7 +2417,9 @@ rf_markalldirty(raidPtr)
raidPtr->mod_counter++;
for (r = 0; r < raidPtr->numRow; r++) {
for (c = 0; c < raidPtr->numCol; c++) {
- if (raidPtr->Disks[r][c].status != rf_ds_failed) {
+ /* we don't want to touch (at all) a disk that has
+ failed */
+ if (!RF_DEAD_DISK(raidPtr->Disks[r][c].status)) {
raidread_component_label(
raidPtr->Disks[r][c].dev,
raidPtr->raid_cinfo[r][c].ci_vp,
@@ -2478,12 +2616,13 @@ rf_close_component(raidPtr, vp, auto_configured)
{
struct proc *p;
- p = raidPtr->engine_thread;
+ if ((p = raidPtr->engine_thread) == NULL)
+ p = curproc;
if (vp != NULL) {
if (auto_configured == 1) {
- VOP_CLOSE(vp, FREAD, NOCRED, 0);
- vput(vp);
+ VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, 0);
+ vrele(vp);
} else {
VOP_UNLOCK(vp, 0, p);
@@ -2500,15 +2639,12 @@ 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);
@@ -2634,11 +2770,10 @@ RF_AutoConfig_t *
rf_find_raid_components()
{
#ifdef RAID_AUTOCONFIG
- struct devnametobdevmaj *dtobdm;
+ int major;
struct vnode *vp;
struct disklabel label;
struct device *dv;
- char *cd_name;
dev_t dev;
int error;
int i;
@@ -2652,9 +2787,7 @@ rf_find_raid_components()
/* initialize the AutoConfig list */
ac_list = NULL;
-#if RAID_AUTOCONFIG
-if (raidautoconfig) {
-
+#ifdef RAID_AUTOCONFIG
/* we begin by trolling through *all* the devices on the system */
for (dv = alldevs.tqh_first; dv != NULL;
@@ -2670,15 +2803,11 @@ if (raidautoconfig) {
}
/* 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++;
- }
+ major = findblkmajor(dv);
/* get a vnode for the raw partition of this disk */
- dev = MAKEDISKDEV(dtobdm->d_maj, dv->dv_unit, RAW_PART);
+ dev = MAKEDISKDEV(major, dv->dv_unit, RAW_PART);
if (bdevvp(dev, &vp))
panic("RAID can't alloc vnode");
@@ -2705,15 +2834,24 @@ if (raidautoconfig) {
/* 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);
+ VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, 0);
+ vrele(vp);
for (i=0; i < label.d_npartitions; i++) {
- /* We only support partitions marked as RAID */
+ /* We only support partitions marked as RAID. */
+ /* Aside on sparc/sparc64 where FS_RAID doesn't */
+ /* fit in the SUN disklabel and we need to look */
+ /* into each and every partition !!! */
+#if !defined(__sparc__) && !defined(__sparc64__) && !defined(__sun3__)
if (label.d_partitions[i].p_fstype != FS_RAID)
continue;
+#else /* !__sparc__ && !__sparc64__ && !__sun3__ */
+ if (label.d_partitions[i].p_fstype == FS_SWAP ||
+ label.d_partitions[i].p_fstype == FS_UNUSED)
+ continue;
+#endif /* __sparc__ || __sparc64__ || __sun3__ */
- dev = MAKEDISKDEV(dtobdm->d_maj, dv->dv_unit, i);
+ dev = MAKEDISKDEV(major, dv->dv_unit, i);
if (bdevvp(dev, &vp))
panic("RAID can't alloc vnode");
@@ -2740,7 +2878,7 @@ if (raidautoconfig) {
if (rf_reasonable_label(clabel) &&
(clabel->partitionSize <=
label.d_partitions[i].p_size)) {
-#if DEBUG
+#ifdef DEBUG
printf("Component on: %s%c: %d\n",
dv->dv_xname, 'a'+i,
label.d_partitions[i].p_size);
@@ -2770,18 +2908,17 @@ if (raidautoconfig) {
if (!good_one) {
/* cleanup */
free(clabel, M_RAIDFRAME);
- VOP_CLOSE(vp, FREAD, NOCRED, 0);
- vput(vp);
+ VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, 0);
+ vrele(vp);
}
}
}
-}
#endif
return(ac_list);
}
#ifdef RAID_AUTOCONFIG
-static int
+int
rf_reasonable_label(clabel)
RF_ComponentLabel_t *clabel;
{
@@ -2899,7 +3036,7 @@ rf_create_auto_sets(ac_list)
return(config_sets);
}
-static int
+int
rf_does_it_fit(cset, ac)
RF_ConfigSet_t *cset;
RF_AutoConfig_t *ac;
@@ -2987,6 +3124,7 @@ rf_have_enough_components(cset)
/* Determine what the mod_counter is supposed to be for this set. */
mod_counter_found = 0;
+ mod_counter = 0;
ac = cset->ac;
while(ac!=NULL) {
if (mod_counter_found==0) {
@@ -3012,7 +3150,7 @@ rf_have_enough_components(cset)
(ac->clabel->column == c) &&
(ac->clabel->mod_counter == mod_counter)) {
/* it's this one... */
-#if DEBUG
+#ifdef DEBUG
printf("Found: %s at %d,%d\n",
ac->devname,r,c);
#endif
@@ -3101,6 +3239,101 @@ rf_create_configuration(ac,config,raidPtr)
for(i=0;i<RF_MAXDBGV;i++) {
config->debugVars[i][0] = NULL;
}
+
+#ifdef RAID_DEBUG_ALL
+#ifdef RF_DBG_OPTION
+#undef RF_DBG_OPTION
+#endif
+
+#ifdef __STDC__
+#define RF_DBG_OPTION(_option_,_val_) \
+ snprintf(&(config->debugVars[i++][0]), 50, \
+ "%s %ld", #_option_, _val_);
+#else /* __STDC__ */
+#define RF_DBG_OPTION(_option_,_val_) \
+ snprintf(&(config->debugVars[i++][0]), 50, \
+ "%s %ld", "/**/_option_/**/", _val_);
+#endif /* __STDC__ */
+
+ i = 0;
+
+/* RF_DBG_OPTION(accessDebug, 0) */
+/* RF_DBG_OPTION(accessTraceBufSize, 0) */
+ RF_DBG_OPTION(cscanDebug, 1) /* debug CSCAN sorting */
+ RF_DBG_OPTION(dagDebug, 1)
+/* RF_DBG_OPTION(debugPrintUseBuffer, 0) */
+ RF_DBG_OPTION(degDagDebug, 1)
+ RF_DBG_OPTION(disableAsyncAccs, 1)
+ RF_DBG_OPTION(diskDebug, 1)
+ RF_DBG_OPTION(enableAtomicRMW, 0) /* this debug var enables
+ * locking of the disk arm
+ * during small-write
+ * operations. Setting this
+ * variable to anything other
+ * than 0 will result in
+ * deadlock. (wvcii) */
+ RF_DBG_OPTION(engineDebug, 1)
+ RF_DBG_OPTION(fifoDebug, 1) /* debug fifo queueing */
+/* RF_DBG_OPTION(floatingRbufDebug, 1) */
+/* RF_DBG_OPTION(forceHeadSepLimit, -1) */
+/* RF_DBG_OPTION(forceNumFloatingReconBufs, -1) */ /* wire down number of
+ * extra recon buffers
+ * to use */
+/* RF_DBG_OPTION(keepAccTotals, 1) */ /* turn on keep_acc_totals */
+ RF_DBG_OPTION(lockTableSize, RF_DEFAULT_LOCK_TABLE_SIZE)
+ RF_DBG_OPTION(mapDebug, 1)
+ RF_DBG_OPTION(maxNumTraces, -1)
+
+/* RF_DBG_OPTION(memChunkDebug, 1) */
+/* RF_DBG_OPTION(memDebug, 1) */
+/* RF_DBG_OPTION(memDebugAddress, 1) */
+/* RF_DBG_OPTION(numBufsToAccumulate, 1) */ /* number of buffers to
+ * accumulate before
+ * doing XOR */
+ RF_DBG_OPTION(prReconSched, 0)
+ RF_DBG_OPTION(printDAGsDebug, 1)
+ RF_DBG_OPTION(printStatesDebug, 1)
+ RF_DBG_OPTION(protectedSectors, 64L) /* # of sectors at start
+ * of disk to exclude
+ * from RAID address
+ * space */
+ RF_DBG_OPTION(pssDebug, 1)
+ RF_DBG_OPTION(queueDebug, 1)
+ RF_DBG_OPTION(quiesceDebug, 1)
+ RF_DBG_OPTION(raidSectorOffset, 0) /* added to all incoming sectors
+ * to debug alignment problems */
+ RF_DBG_OPTION(reconDebug, 1)
+ RF_DBG_OPTION(reconbufferDebug, 1)
+ RF_DBG_OPTION(scanDebug, 1) /* debug SCAN sorting */
+ RF_DBG_OPTION(showXorCallCounts, 0) /* show n-way Xor call counts */
+ RF_DBG_OPTION(shutdownDebug, 1) /* show shutdown calls */
+ RF_DBG_OPTION(sizePercentage, 100)
+ RF_DBG_OPTION(sstfDebug, 1) /* turn on debugging info for sstf
+ * queueing */
+ RF_DBG_OPTION(stripeLockDebug, 1)
+ RF_DBG_OPTION(suppressLocksAndLargeWrites, 0)
+ RF_DBG_OPTION(suppressTraceDelays, 0)
+ RF_DBG_OPTION(useMemChunks, 1)
+ RF_DBG_OPTION(validateDAGDebug, 1)
+ RF_DBG_OPTION(validateVisitedDebug, 1) /* XXX turn to zero by
+ * default? */
+ RF_DBG_OPTION(verifyParityDebug, 1)
+ RF_DBG_OPTION(debugKernelAccess, 1) /* DoAccessKernel debugging */
+
+#if 0 /* RF_INCLUDE_PARITYLOGGING > 0 */
+ RF_DBG_OPTION(forceParityLogReint, 0)
+ RF_DBG_OPTION(numParityRegions, 0) /* number of regions in the
+ * array */
+ RF_DBG_OPTION(numReintegrationThreads, 1)
+ RF_DBG_OPTION(parityLogDebug, 1) /* if nonzero, enables debugging
+ * of parity logging */
+ RF_DBG_OPTION(totalInCoreLogCapacity, 1024 * 1024) /* target bytes
+ * available for
+ * in-core
+ * logs */
+#endif /* RF_INCLUDE_PARITYLOGGING > 0 */
+
+#endif /* RAID_DEBUG_ALL */
}
int
@@ -3166,7 +3399,7 @@ rf_release_all_vps(cset)
/* Close the vp, and give it back */
if (ac->vp) {
VOP_CLOSE(ac->vp, FREAD, NOCRED, 0);
- vput(ac->vp);
+ vrele(ac->vp);
ac->vp = NULL;
}
ac = ac->next;
@@ -3275,7 +3508,7 @@ rf_auto_config_set(cset,unit)
not taken.
*/
- for(raidID = numraid; raidID >= 0; raidID--) {
+ for(raidID = numraid - 1; raidID >= 0; raidID--) {
if (raidPtrs[raidID]->valid == 0) {
/* can use this one! */
break;
@@ -3323,3 +3556,14 @@ rf_auto_config_set(cset,unit)
*unit = raidID;
return(retcode);
}
+
+void
+rf_disk_unbusy(desc)
+ RF_RaidAccessDesc_t *desc;
+{
+ struct buf *bp;
+
+ bp = (struct buf *)desc->bp;
+ disk_unbusy(&raid_softc[desc->raidPtr->raidid].sc_dkdev,
+ (bp->b_bcount - bp->b_resid));
+}
diff --git a/sys/dev/raidframe/rf_states.c b/sys/dev/raidframe/rf_states.c
index 994902e8067..b7470a8e190 100644
--- a/sys/dev/raidframe/rf_states.c
+++ b/sys/dev/raidframe/rf_states.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: rf_states.c,v 1.6 2000/01/11 18:02:23 peter Exp $ */
-/* $NetBSD: rf_states.c,v 1.13 2000/01/09 00:00:18 oster Exp $ */
+/* $OpenBSD: rf_states.c,v 1.7 2001/12/29 21:51:18 tdeval Exp $ */
+/* $NetBSD: rf_states.c,v 1.15 2000/10/20 02:24:45 oster Exp $ */
/*
* Copyright (c) 1995 Carnegie-Mellon University.
* All rights reserved.
@@ -204,6 +204,12 @@ rf_State_LastState(RF_RaidAccessDesc_t * desc)
wakeup(desc->bp);
/*
+ * That's all the IO for this one... unbusy the 'disk'.
+ */
+
+ rf_disk_unbusy(desc);
+
+ /*
* Wakeup any requests waiting to go.
*/
@@ -216,6 +222,7 @@ rf_State_LastState(RF_RaidAccessDesc_t * desc)
/* printf("Calling biodone on 0x%x\n",desc->bp); */
biodone(desc->bp); /* access came through ioctl */
+
if (callbackFunc)
callbackFunc(callbackArg);
rf_FreeRaidAccDesc(desc);
@@ -445,7 +452,7 @@ rf_State_CreateDAG(RF_RaidAccessDesc_t * desc)
/* failed to create a dag */
/* this happens when there are too many faults or incomplete
* dag libraries */
- printf("[Failed to create a DAG\n]");
+ printf("[Failed to create a DAG]\n");
RF_PANIC();
} else {
/* bind dags to desc */