rf_driver.c revision 1.136.12.2 1 1.136.12.2 thorpej /* $NetBSD: rf_driver.c,v 1.136.12.2 2021/08/01 22:42:31 thorpej Exp $ */
2 1.9 oster /*-
3 1.9 oster * Copyright (c) 1999 The NetBSD Foundation, Inc.
4 1.9 oster * All rights reserved.
5 1.9 oster *
6 1.9 oster * This code is derived from software contributed to The NetBSD Foundation
7 1.9 oster * by Greg Oster
8 1.9 oster *
9 1.9 oster * Redistribution and use in source and binary forms, with or without
10 1.9 oster * modification, are permitted provided that the following conditions
11 1.9 oster * are met:
12 1.9 oster * 1. Redistributions of source code must retain the above copyright
13 1.9 oster * notice, this list of conditions and the following disclaimer.
14 1.9 oster * 2. Redistributions in binary form must reproduce the above copyright
15 1.9 oster * notice, this list of conditions and the following disclaimer in the
16 1.9 oster * documentation and/or other materials provided with the distribution.
17 1.9 oster *
18 1.9 oster * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 1.9 oster * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 1.9 oster * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 1.9 oster * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 1.9 oster * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 1.9 oster * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 1.9 oster * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 1.9 oster * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 1.9 oster * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 1.9 oster * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 1.9 oster * POSSIBILITY OF SUCH DAMAGE.
29 1.9 oster */
30 1.9 oster
31 1.1 oster /*
32 1.1 oster * Copyright (c) 1995 Carnegie-Mellon University.
33 1.1 oster * All rights reserved.
34 1.1 oster *
35 1.1 oster * Author: Mark Holland, Khalil Amiri, Claudson Bornstein, William V. Courtright II,
36 1.1 oster * Robby Findler, Daniel Stodolsky, Rachad Youssef, Jim Zelenka
37 1.1 oster *
38 1.1 oster * Permission to use, copy, modify and distribute this software and
39 1.1 oster * its documentation is hereby granted, provided that both the copyright
40 1.1 oster * notice and this permission notice appear in all copies of the
41 1.1 oster * software, derivative works or modified versions, and any portions
42 1.1 oster * thereof, and that both notices appear in supporting documentation.
43 1.1 oster *
44 1.1 oster * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
45 1.1 oster * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
46 1.1 oster * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
47 1.1 oster *
48 1.1 oster * Carnegie Mellon requests users of this software to return to
49 1.1 oster *
50 1.1 oster * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
51 1.1 oster * School of Computer Science
52 1.1 oster * Carnegie Mellon University
53 1.1 oster * Pittsburgh PA 15213-3890
54 1.1 oster *
55 1.1 oster * any improvements or extensions that they make and grant Carnegie the
56 1.1 oster * rights to redistribute these changes.
57 1.1 oster */
58 1.1 oster
59 1.1 oster /******************************************************************************
60 1.1 oster *
61 1.1 oster * rf_driver.c -- main setup, teardown, and access routines for the RAID driver
62 1.1 oster *
63 1.1 oster * all routines are prefixed with rf_ (raidframe), to avoid conficts.
64 1.1 oster *
65 1.1 oster ******************************************************************************/
66 1.1 oster
67 1.44 lukem
68 1.44 lukem #include <sys/cdefs.h>
69 1.136.12.2 thorpej __KERNEL_RCSID(0, "$NetBSD: rf_driver.c,v 1.136.12.2 2021/08/01 22:42:31 thorpej Exp $");
70 1.71 martin
71 1.119 ad #ifdef _KERNEL_OPT
72 1.71 martin #include "opt_raid_diagnostic.h"
73 1.119 ad #endif
74 1.1 oster
75 1.1 oster #include <sys/param.h>
76 1.1 oster #include <sys/systm.h>
77 1.1 oster #include <sys/ioctl.h>
78 1.1 oster #include <sys/fcntl.h>
79 1.1 oster #include <sys/vnode.h>
80 1.1 oster
81 1.1 oster
82 1.1 oster #include "rf_archs.h"
83 1.1 oster #include "rf_threadstuff.h"
84 1.1 oster
85 1.1 oster #include <sys/errno.h>
86 1.1 oster
87 1.1 oster #include "rf_raid.h"
88 1.1 oster #include "rf_dag.h"
89 1.1 oster #include "rf_aselect.h"
90 1.1 oster #include "rf_diskqueue.h"
91 1.1 oster #include "rf_parityscan.h"
92 1.1 oster #include "rf_alloclist.h"
93 1.1 oster #include "rf_dagutils.h"
94 1.1 oster #include "rf_utils.h"
95 1.1 oster #include "rf_etimer.h"
96 1.1 oster #include "rf_acctrace.h"
97 1.1 oster #include "rf_general.h"
98 1.1 oster #include "rf_desc.h"
99 1.1 oster #include "rf_states.h"
100 1.1 oster #include "rf_decluster.h"
101 1.1 oster #include "rf_map.h"
102 1.1 oster #include "rf_revent.h"
103 1.1 oster #include "rf_callback.h"
104 1.1 oster #include "rf_engine.h"
105 1.1 oster #include "rf_mcpair.h"
106 1.1 oster #include "rf_nwayxor.h"
107 1.1 oster #include "rf_copyback.h"
108 1.1 oster #include "rf_driver.h"
109 1.1 oster #include "rf_options.h"
110 1.1 oster #include "rf_shutdown.h"
111 1.24 oster #include "rf_kintf.h"
112 1.122 jld #include "rf_paritymap.h"
113 1.1 oster
114 1.1 oster #include <sys/buf.h>
115 1.1 oster
116 1.61 oster #ifndef RF_ACCESS_DEBUG
117 1.61 oster #define RF_ACCESS_DEBUG 0
118 1.61 oster #endif
119 1.61 oster
120 1.1 oster /* rad == RF_RaidAccessDesc_t */
121 1.1 oster #define RF_MAX_FREE_RAD 128
122 1.88 oster #define RF_MIN_FREE_RAD 32
123 1.1 oster
124 1.1 oster /* main configuration routines */
125 1.1 oster static int raidframe_booted = 0;
126 1.1 oster
127 1.6 oster static void rf_ConfigureDebug(RF_Config_t * cfgPtr);
128 1.1 oster static void set_debug_option(char *name, long val);
129 1.1 oster static void rf_UnconfigureArray(void);
130 1.1 oster static void rf_ShutdownRDFreeList(void *);
131 1.136.12.2 thorpej static int rf_ConfigureRDFreeList(RF_ShutdownList_t **, RF_Raid_t *, RF_Config_t *);
132 1.1 oster
133 1.126 mrg rf_declare_mutex2(rf_printf_mutex); /* debug only: avoids interleaved
134 1.6 oster * printfs by different stripes */
135 1.1 oster
136 1.127 mrg #define SIGNAL_QUIESCENT_COND(_raid_) \
137 1.127 mrg rf_broadcast_cond2((_raid_)->access_suspend_cv)
138 1.1 oster #define WAIT_FOR_QUIESCENCE(_raid_) \
139 1.127 mrg rf_wait_cond2((_raid_)->access_suspend_cv, \
140 1.127 mrg (_raid_)->access_suspend_mutex)
141 1.1 oster
142 1.9 oster static int configureCount = 0; /* number of active configurations */
143 1.9 oster static int isconfigged = 0; /* is basic raidframe (non per-array)
144 1.116 oster * stuff configured */
145 1.125 mrg static rf_declare_mutex2(configureMutex); /* used to lock the configuration
146 1.125 mrg * stuff */
147 1.9 oster static RF_ShutdownList_t *globalShutdown; /* non array-specific
148 1.9 oster * stuff */
149 1.1 oster
150 1.136.12.2 thorpej static int rf_ConfigureRDFreeList(RF_ShutdownList_t ** listp, RF_Raid_t *raidPtr, RF_Config_t *cfgPtr);
151 1.103 oster static int rf_AllocEmergBuffers(RF_Raid_t *);
152 1.103 oster static void rf_FreeEmergBuffers(RF_Raid_t *);
153 1.130 mrg static void rf_destroy_mutex_cond(RF_Raid_t *);
154 1.130 mrg static void rf_alloc_mutex_cond(RF_Raid_t *);
155 1.1 oster
156 1.1 oster /* called at system boot time */
157 1.107 perry int
158 1.132 pgoyette rf_BootRaidframe(bool boot)
159 1.1 oster {
160 1.1 oster
161 1.132 pgoyette if (boot) {
162 1.132 pgoyette if (raidframe_booted)
163 1.132 pgoyette return (EBUSY);
164 1.132 pgoyette raidframe_booted = 1;
165 1.132 pgoyette rf_init_mutex2(configureMutex, IPL_NONE);
166 1.132 pgoyette configureCount = 0;
167 1.132 pgoyette isconfigged = 0;
168 1.132 pgoyette globalShutdown = NULL;
169 1.132 pgoyette } else {
170 1.132 pgoyette rf_destroy_mutex2(configureMutex);
171 1.132 pgoyette raidframe_booted = 0;
172 1.132 pgoyette }
173 1.6 oster return (0);
174 1.1 oster }
175 1.1 oster
176 1.1 oster /*
177 1.1 oster * Called whenever an array is shutdown
178 1.1 oster */
179 1.107 perry static void
180 1.121 cegger rf_UnconfigureArray(void)
181 1.1 oster {
182 1.1 oster
183 1.125 mrg rf_lock_mutex2(configureMutex);
184 1.6 oster if (--configureCount == 0) { /* if no active configurations, shut
185 1.6 oster * everything down */
186 1.129 yamt rf_destroy_mutex2(rf_printf_mutex);
187 1.6 oster isconfigged = 0;
188 1.92 oster rf_ShutdownList(&globalShutdown);
189 1.6 oster
190 1.6 oster /*
191 1.6 oster * We must wait until now, because the AllocList module
192 1.6 oster * uses the DebugMem module.
193 1.6 oster */
194 1.60 oster #if RF_DEBUG_MEM
195 1.6 oster if (rf_memDebug)
196 1.6 oster rf_print_unfreed();
197 1.60 oster #endif
198 1.6 oster }
199 1.125 mrg rf_unlock_mutex2(configureMutex);
200 1.9 oster }
201 1.9 oster
202 1.1 oster /*
203 1.1 oster * Called to shut down an array.
204 1.1 oster */
205 1.107 perry int
206 1.80 oster rf_Shutdown(RF_Raid_t *raidPtr)
207 1.1 oster {
208 1.100 oster
209 1.6 oster if (!raidPtr->valid) {
210 1.6 oster RF_ERRORMSG("Attempt to shut down unconfigured RAIDframe driver. Aborting shutdown\n");
211 1.6 oster return (EINVAL);
212 1.6 oster }
213 1.6 oster /*
214 1.6 oster * wait for outstanding IOs to land
215 1.6 oster * As described in rf_raid.h, we use the rad_freelist lock
216 1.6 oster * to protect the per-array info about outstanding descs
217 1.6 oster * since we need to do freelist locking anyway, and this
218 1.6 oster * cuts down on the amount of serialization we've got going
219 1.6 oster * on.
220 1.6 oster */
221 1.126 mrg rf_lock_mutex2(raidPtr->rad_lock);
222 1.6 oster if (raidPtr->waitShutdown) {
223 1.126 mrg rf_unlock_mutex2(raidPtr->rad_lock);
224 1.6 oster return (EBUSY);
225 1.6 oster }
226 1.6 oster raidPtr->waitShutdown = 1;
227 1.6 oster while (raidPtr->nAccOutstanding) {
228 1.126 mrg rf_wait_cond2(raidPtr->outstandingCond, raidPtr->rad_lock);
229 1.6 oster }
230 1.35 oster
231 1.35 oster /* Wait for any parity re-writes to stop... */
232 1.35 oster while (raidPtr->parity_rewrite_in_progress) {
233 1.120 oster printf("raid%d: Waiting for parity re-write to exit...\n",
234 1.120 oster raidPtr->raidid);
235 1.134 mrg rf_wait_cond2(raidPtr->parity_rewrite_cv, raidPtr->rad_lock);
236 1.35 oster }
237 1.134 mrg rf_unlock_mutex2(raidPtr->rad_lock);
238 1.6 oster
239 1.120 oster /* Wait for any reconstruction to stop... */
240 1.128 mrg rf_lock_mutex2(raidPtr->mutex);
241 1.120 oster while (raidPtr->reconInProgress) {
242 1.120 oster printf("raid%d: Waiting for reconstruction to stop...\n",
243 1.120 oster raidPtr->raidid);
244 1.128 mrg rf_wait_cond2(raidPtr->waitForReconCond, raidPtr->mutex);
245 1.120 oster }
246 1.128 mrg rf_unlock_mutex2(raidPtr->mutex);
247 1.120 oster
248 1.6 oster raidPtr->valid = 0;
249 1.6 oster
250 1.122 jld if (raidPtr->parity_map != NULL)
251 1.122 jld rf_paritymap_detach(raidPtr);
252 1.122 jld
253 1.37 oster rf_update_component_labels(raidPtr, RF_FINAL_COMPONENT_UPDATE);
254 1.6 oster
255 1.7 oster rf_UnconfigureVnodes(raidPtr);
256 1.7 oster
257 1.103 oster rf_FreeEmergBuffers(raidPtr);
258 1.100 oster
259 1.7 oster rf_ShutdownList(&raidPtr->shutdownList);
260 1.7 oster
261 1.130 mrg rf_destroy_mutex_cond(raidPtr);
262 1.128 mrg
263 1.7 oster rf_UnconfigureArray();
264 1.7 oster
265 1.7 oster return (0);
266 1.7 oster }
267 1.1 oster
268 1.6 oster
269 1.1 oster #define DO_INIT_CONFIGURE(f) { \
270 1.1 oster rc = f (&globalShutdown); \
271 1.1 oster if (rc) { \
272 1.1 oster RF_ERRORMSG2("RAIDFRAME: failed %s with %d\n", RF_STRING(f), rc); \
273 1.1 oster rf_ShutdownList(&globalShutdown); \
274 1.1 oster configureCount--; \
275 1.125 mrg rf_unlock_mutex2(configureMutex); \
276 1.129 yamt rf_destroy_mutex2(rf_printf_mutex); \
277 1.1 oster return(rc); \
278 1.1 oster } \
279 1.1 oster }
280 1.1 oster
281 1.1 oster #define DO_RAID_FAIL() { \
282 1.12 oster rf_UnconfigureVnodes(raidPtr); \
283 1.103 oster rf_FreeEmergBuffers(raidPtr); \
284 1.1 oster rf_ShutdownList(&raidPtr->shutdownList); \
285 1.1 oster rf_UnconfigureArray(); \
286 1.130 mrg rf_destroy_mutex_cond(raidPtr); \
287 1.1 oster }
288 1.1 oster
289 1.1 oster #define DO_RAID_INIT_CONFIGURE(f) { \
290 1.1 oster rc = f (&raidPtr->shutdownList, raidPtr, cfgPtr); \
291 1.1 oster if (rc) { \
292 1.1 oster RF_ERRORMSG2("RAIDFRAME: failed %s with %d\n", RF_STRING(f), rc); \
293 1.1 oster DO_RAID_FAIL(); \
294 1.1 oster return(rc); \
295 1.1 oster } \
296 1.1 oster }
297 1.1 oster
298 1.107 perry int
299 1.80 oster rf_Configure(RF_Raid_t *raidPtr, RF_Config_t *cfgPtr, RF_AutoConfig_t *ac)
300 1.6 oster {
301 1.72 oster RF_RowCol_t col;
302 1.103 oster int rc;
303 1.136.12.1 thorpej bool swapped = false;
304 1.136.12.1 thorpej bool first = true;
305 1.6 oster
306 1.125 mrg rf_lock_mutex2(configureMutex);
307 1.6 oster configureCount++;
308 1.6 oster if (isconfigged == 0) {
309 1.126 mrg rf_init_mutex2(rf_printf_mutex, IPL_VM);
310 1.75 oster
311 1.6 oster /* initialize globals */
312 1.6 oster DO_INIT_CONFIGURE(rf_ConfigureAllocList);
313 1.28 oster
314 1.6 oster /*
315 1.28 oster * Yes, this does make debugging general to the whole
316 1.107 perry * system instead of being array specific. Bummer, drag.
317 1.28 oster */
318 1.6 oster rf_ConfigureDebug(cfgPtr);
319 1.6 oster DO_INIT_CONFIGURE(rf_ConfigureDebugMem);
320 1.87 oster #if RF_ACC_TRACE > 0
321 1.6 oster DO_INIT_CONFIGURE(rf_ConfigureAccessTrace);
322 1.87 oster #endif
323 1.6 oster DO_INIT_CONFIGURE(rf_ConfigureNWayXor);
324 1.6 oster DO_INIT_CONFIGURE(rf_ConfigureDAGFuncs);
325 1.6 oster DO_INIT_CONFIGURE(rf_ConfigureCopyback);
326 1.6 oster isconfigged = 1;
327 1.6 oster }
328 1.125 mrg rf_unlock_mutex2(configureMutex);
329 1.6 oster
330 1.130 mrg rf_alloc_mutex_cond(raidPtr);
331 1.130 mrg
332 1.6 oster /* set up the cleanup list. Do this after ConfigureDebug so that
333 1.6 oster * value of memDebug will be set */
334 1.6 oster
335 1.6 oster rf_MakeAllocList(raidPtr->cleanupList);
336 1.6 oster if (raidPtr->cleanupList == NULL) {
337 1.6 oster DO_RAID_FAIL();
338 1.6 oster return (ENOMEM);
339 1.6 oster }
340 1.86 oster rf_ShutdownCreate(&raidPtr->shutdownList,
341 1.86 oster (void (*) (void *)) rf_FreeAllocList,
342 1.86 oster raidPtr->cleanupList);
343 1.86 oster
344 1.6 oster raidPtr->numCol = cfgPtr->numCol;
345 1.6 oster raidPtr->numSpare = cfgPtr->numSpare;
346 1.6 oster
347 1.72 oster raidPtr->status = rf_rs_optimal;
348 1.72 oster raidPtr->reconControl = NULL;
349 1.107 perry
350 1.136.12.2 thorpej DO_RAID_INIT_CONFIGURE(rf_ConfigureMapModule);
351 1.136.12.2 thorpej DO_RAID_INIT_CONFIGURE(rf_ConfigureReconEvent);
352 1.136.12.2 thorpej DO_RAID_INIT_CONFIGURE(rf_ConfigureCallback);
353 1.136.12.2 thorpej DO_RAID_INIT_CONFIGURE(rf_ConfigureRDFreeList);
354 1.136.12.2 thorpej DO_RAID_INIT_CONFIGURE(rf_ConfigureStripeLockFreeList);
355 1.136.12.2 thorpej DO_RAID_INIT_CONFIGURE(rf_ConfigureMCPair);
356 1.136.12.2 thorpej DO_RAID_INIT_CONFIGURE(rf_ConfigureDAGs);
357 1.136.12.2 thorpej DO_RAID_INIT_CONFIGURE(rf_ConfigureReconstruction);
358 1.136.12.2 thorpej DO_RAID_INIT_CONFIGURE(rf_ConfigureDiskQueueSystem);
359 1.136.12.2 thorpej DO_RAID_INIT_CONFIGURE(rf_ConfigurePSStatus);
360 1.136.12.2 thorpej
361 1.6 oster DO_RAID_INIT_CONFIGURE(rf_ConfigureEngine);
362 1.6 oster DO_RAID_INIT_CONFIGURE(rf_ConfigureStripeLocks);
363 1.6 oster
364 1.6 oster raidPtr->nAccOutstanding = 0;
365 1.6 oster raidPtr->waitShutdown = 0;
366 1.6 oster
367 1.28 oster if (ac!=NULL) {
368 1.28 oster /* We have an AutoConfig structure.. Don't do the
369 1.28 oster normal disk configuration... call the auto config
370 1.28 oster stuff */
371 1.28 oster rf_AutoConfigureDisks(raidPtr, cfgPtr, ac);
372 1.28 oster } else {
373 1.28 oster DO_RAID_INIT_CONFIGURE(rf_ConfigureDisks);
374 1.28 oster DO_RAID_INIT_CONFIGURE(rf_ConfigureSpareDisks);
375 1.28 oster }
376 1.6 oster /* do this after ConfigureDisks & ConfigureSpareDisks to be sure dev
377 1.6 oster * no. is set */
378 1.6 oster DO_RAID_INIT_CONFIGURE(rf_ConfigureDiskQueues);
379 1.6 oster
380 1.6 oster DO_RAID_INIT_CONFIGURE(rf_ConfigureLayout);
381 1.6 oster
382 1.136.12.2 thorpej
383 1.136.12.2 thorpej
384 1.136.12.2 thorpej
385 1.110 oster /* Initialize per-RAID PSS bits */
386 1.110 oster rf_InitPSStatus(raidPtr);
387 1.6 oster
388 1.82 oster #if RF_INCLUDE_CHAINDECLUSTER > 0
389 1.72 oster for (col = 0; col < raidPtr->numCol; col++) {
390 1.72 oster /*
391 1.72 oster * XXX better distribution
392 1.72 oster */
393 1.72 oster raidPtr->hist_diskreq[col] = 0;
394 1.6 oster }
395 1.82 oster #endif
396 1.30 oster raidPtr->numNewFailures = 0;
397 1.28 oster raidPtr->copyback_in_progress = 0;
398 1.28 oster raidPtr->parity_rewrite_in_progress = 0;
399 1.66 oster raidPtr->adding_hot_spare = 0;
400 1.28 oster raidPtr->recon_in_progress = 0;
401 1.128 mrg
402 1.29 oster raidPtr->maxOutstanding = cfgPtr->maxOutstandingDiskReqs;
403 1.29 oster
404 1.107 perry /* autoconfigure and root_partition will actually get filled in
405 1.29 oster after the config is done */
406 1.29 oster raidPtr->autoconfigure = 0;
407 1.29 oster raidPtr->root_partition = 0;
408 1.29 oster raidPtr->last_unit = raidPtr->raidid;
409 1.29 oster raidPtr->config_order = 0;
410 1.6 oster
411 1.6 oster if (rf_keepAccTotals) {
412 1.6 oster raidPtr->keep_acc_totals = 1;
413 1.6 oster }
414 1.1 oster
415 1.97 oster /* Allocate a bunch of buffers to be used in low-memory conditions */
416 1.97 oster raidPtr->iobuf = NULL;
417 1.103 oster
418 1.107 perry rc = rf_AllocEmergBuffers(raidPtr);
419 1.103 oster if (rc) {
420 1.103 oster printf("raid%d: Unable to allocate emergency buffers.\n",
421 1.103 oster raidPtr->raidid);
422 1.103 oster DO_RAID_FAIL();
423 1.103 oster return(rc);
424 1.103 oster }
425 1.103 oster
426 1.122 jld /* Set up parity map stuff, if applicable. */
427 1.122 jld #ifndef RF_NO_PARITY_MAP
428 1.122 jld rf_paritymap_attach(raidPtr, cfgPtr->force);
429 1.122 jld #endif
430 1.122 jld
431 1.103 oster raidPtr->valid = 1;
432 1.103 oster
433 1.103 oster printf("raid%d: %s\n", raidPtr->raidid,
434 1.103 oster raidPtr->Layout.map->configName);
435 1.103 oster printf("raid%d: Components:", raidPtr->raidid);
436 1.103 oster
437 1.103 oster for (col = 0; col < raidPtr->numCol; col++) {
438 1.136.12.1 thorpej RF_ComponentLabel_t *clabel;
439 1.136.12.1 thorpej bool compswapped;
440 1.136.12.1 thorpej
441 1.103 oster printf(" %s", raidPtr->Disks[col].devname);
442 1.103 oster if (RF_DEAD_DISK(raidPtr->Disks[col].status)) {
443 1.103 oster printf("[**FAILED**]");
444 1.103 oster }
445 1.136.12.1 thorpej clabel = raidget_component_label(raidPtr, col);
446 1.136.12.1 thorpej compswapped = clabel->version ==
447 1.136.12.1 thorpej bswap32(RF_COMPONENT_LABEL_VERSION);
448 1.136.12.1 thorpej if (first)
449 1.136.12.1 thorpej swapped = compswapped;
450 1.136.12.1 thorpej else if (swapped != compswapped)
451 1.136.12.1 thorpej printf("raid%d: Component %d has different endian "
452 1.136.12.1 thorpej "than first component.", raidPtr->raidid, col);
453 1.103 oster }
454 1.103 oster printf("\n");
455 1.117 sborrill printf("raid%d: Total Sectors: %" PRIu64 " (%" PRIu64 " MB)\n",
456 1.103 oster raidPtr->raidid,
457 1.117 sborrill raidPtr->totalSectors,
458 1.117 sborrill (raidPtr->totalSectors / 1024 *
459 1.103 oster (1 << raidPtr->logBytesPerSector) / 1024));
460 1.136.12.1 thorpej if (swapped)
461 1.136.12.1 thorpej printf("raid%d: Using swapped-endian component labels.\n",
462 1.136.12.1 thorpej raidPtr->raidid);
463 1.103 oster
464 1.103 oster return (0);
465 1.103 oster }
466 1.103 oster
467 1.103 oster
468 1.103 oster /*
469 1.103 oster
470 1.103 oster Routines to allocate and free the "emergency buffers" for a given
471 1.103 oster RAID set. These emergency buffers will be used when the kernel runs
472 1.107 perry out of kernel memory.
473 1.107 perry
474 1.103 oster */
475 1.103 oster
476 1.107 perry static int
477 1.103 oster rf_AllocEmergBuffers(RF_Raid_t *raidPtr)
478 1.103 oster {
479 1.103 oster void *tmpbuf;
480 1.103 oster RF_VoidPointerListElem_t *vple;
481 1.103 oster int i;
482 1.103 oster
483 1.97 oster /* XXX next line needs tuning... */
484 1.97 oster raidPtr->numEmergencyBuffers = 10 * raidPtr->numCol;
485 1.97 oster #if DEBUG
486 1.97 oster printf("raid%d: allocating %d buffers of %d bytes.\n",
487 1.97 oster raidPtr->raidid,
488 1.107 perry raidPtr->numEmergencyBuffers,
489 1.107 perry (int)(raidPtr->Layout.sectorsPerStripeUnit <<
490 1.97 oster raidPtr->logBytesPerSector));
491 1.97 oster #endif
492 1.97 oster for (i = 0; i < raidPtr->numEmergencyBuffers; i++) {
493 1.107 perry tmpbuf = malloc( raidPtr->Layout.sectorsPerStripeUnit <<
494 1.107 perry raidPtr->logBytesPerSector,
495 1.111 oster M_RAIDFRAME, M_WAITOK);
496 1.97 oster if (tmpbuf) {
497 1.136.12.2 thorpej vple = rf_AllocVPListElem(raidPtr);
498 1.99 oster vple->p= tmpbuf;
499 1.99 oster vple->next = raidPtr->iobuf;
500 1.99 oster raidPtr->iobuf = vple;
501 1.97 oster raidPtr->iobuf_count++;
502 1.97 oster } else {
503 1.97 oster printf("raid%d: failed to allocate emergency buffer!\n",
504 1.97 oster raidPtr->raidid);
505 1.111 oster return 1;
506 1.97 oster }
507 1.97 oster }
508 1.97 oster
509 1.99 oster /* XXX next line needs tuning too... */
510 1.99 oster raidPtr->numEmergencyStripeBuffers = 10;
511 1.99 oster for (i = 0; i < raidPtr->numEmergencyStripeBuffers; i++) {
512 1.99 oster tmpbuf = malloc( raidPtr->numCol * (raidPtr->Layout.sectorsPerStripeUnit <<
513 1.99 oster raidPtr->logBytesPerSector),
514 1.111 oster M_RAIDFRAME, M_WAITOK);
515 1.99 oster if (tmpbuf) {
516 1.136.12.2 thorpej vple = rf_AllocVPListElem(raidPtr);
517 1.99 oster vple->p= tmpbuf;
518 1.99 oster vple->next = raidPtr->stripebuf;
519 1.99 oster raidPtr->stripebuf = vple;
520 1.99 oster raidPtr->stripebuf_count++;
521 1.99 oster } else {
522 1.99 oster printf("raid%d: failed to allocate emergency stripe buffer!\n",
523 1.99 oster raidPtr->raidid);
524 1.111 oster return 1;
525 1.99 oster }
526 1.99 oster }
527 1.107 perry
528 1.103 oster return (0);
529 1.103 oster }
530 1.99 oster
531 1.103 oster static void
532 1.103 oster rf_FreeEmergBuffers(RF_Raid_t *raidPtr)
533 1.103 oster {
534 1.103 oster RF_VoidPointerListElem_t *tmp;
535 1.99 oster
536 1.103 oster /* Free the emergency IO buffers */
537 1.103 oster while (raidPtr->iobuf != NULL) {
538 1.103 oster tmp = raidPtr->iobuf;
539 1.103 oster raidPtr->iobuf = raidPtr->iobuf->next;
540 1.103 oster free(tmp->p, M_RAIDFRAME);
541 1.136.12.2 thorpej rf_FreeVPListElem(raidPtr,tmp);
542 1.103 oster }
543 1.52 oster
544 1.103 oster /* Free the emergency stripe buffers */
545 1.103 oster while (raidPtr->stripebuf != NULL) {
546 1.103 oster tmp = raidPtr->stripebuf;
547 1.103 oster raidPtr->stripebuf = raidPtr->stripebuf->next;
548 1.103 oster free(tmp->p, M_RAIDFRAME);
549 1.136.12.2 thorpej rf_FreeVPListElem(raidPtr, tmp);
550 1.52 oster }
551 1.103 oster }
552 1.50 oster
553 1.1 oster
554 1.107 perry static void
555 1.136.12.2 thorpej rf_ShutdownRDFreeList(void *arg)
556 1.1 oster {
557 1.136.12.2 thorpej RF_Raid_t *raidPtr;
558 1.136.12.2 thorpej
559 1.136.12.2 thorpej raidPtr = (RF_Raid_t *) arg;
560 1.136.12.2 thorpej
561 1.136.12.2 thorpej pool_destroy(&raidPtr->pools.rad);
562 1.1 oster }
563 1.1 oster
564 1.107 perry static int
565 1.136.12.2 thorpej rf_ConfigureRDFreeList(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
566 1.136.12.2 thorpej RF_Config_t *cfgPtr)
567 1.1 oster {
568 1.1 oster
569 1.136.12.2 thorpej rf_pool_init(raidPtr, raidPtr->poolNames.rad, &raidPtr->pools.rad, sizeof(RF_RaidAccessDesc_t),
570 1.136.12.2 thorpej "rad", RF_MIN_FREE_RAD, RF_MAX_FREE_RAD);
571 1.136.12.2 thorpej rf_ShutdownCreate(listp, rf_ShutdownRDFreeList, raidPtr);
572 1.6 oster return (0);
573 1.6 oster }
574 1.6 oster
575 1.6 oster RF_RaidAccessDesc_t *
576 1.80 oster rf_AllocRaidAccDesc(RF_Raid_t *raidPtr, RF_IoType_t type,
577 1.80 oster RF_RaidAddr_t raidAddress, RF_SectorCount_t numBlocks,
578 1.114 christos void *bufPtr, void *bp, RF_RaidAccessFlags_t flags,
579 1.102 drochner const RF_AccessState_t *states)
580 1.6 oster {
581 1.6 oster RF_RaidAccessDesc_t *desc;
582 1.6 oster
583 1.136.12.2 thorpej desc = pool_get(&raidPtr->pools.rad, PR_WAITOK);
584 1.73 oster
585 1.126 mrg rf_lock_mutex2(raidPtr->rad_lock);
586 1.6 oster if (raidPtr->waitShutdown) {
587 1.6 oster /*
588 1.6 oster * Actually, we're shutting the array down. Free the desc
589 1.6 oster * and return NULL.
590 1.6 oster */
591 1.73 oster
592 1.126 mrg rf_unlock_mutex2(raidPtr->rad_lock);
593 1.136.12.2 thorpej pool_put(&raidPtr->pools.rad, desc);
594 1.6 oster return (NULL);
595 1.6 oster }
596 1.6 oster raidPtr->nAccOutstanding++;
597 1.73 oster
598 1.126 mrg rf_unlock_mutex2(raidPtr->rad_lock);
599 1.6 oster
600 1.6 oster desc->raidPtr = (void *) raidPtr;
601 1.6 oster desc->type = type;
602 1.6 oster desc->raidAddress = raidAddress;
603 1.6 oster desc->numBlocks = numBlocks;
604 1.6 oster desc->bufPtr = bufPtr;
605 1.6 oster desc->bp = bp;
606 1.6 oster desc->flags = flags;
607 1.6 oster desc->states = states;
608 1.6 oster desc->state = 0;
609 1.99 oster desc->dagList = NULL;
610 1.6 oster
611 1.6 oster desc->status = 0;
612 1.105 oster desc->numRetries = 0;
613 1.87 oster #if RF_ACC_TRACE > 0
614 1.135 christos memset(&desc->tracerec, 0, sizeof(desc->tracerec));
615 1.87 oster #endif
616 1.41 oster desc->callbackFunc = NULL;
617 1.41 oster desc->callbackArg = NULL;
618 1.6 oster desc->next = NULL;
619 1.99 oster desc->iobufs = NULL;
620 1.99 oster desc->stripebufs = NULL;
621 1.99 oster
622 1.6 oster return (desc);
623 1.6 oster }
624 1.6 oster
625 1.107 perry void
626 1.80 oster rf_FreeRaidAccDesc(RF_RaidAccessDesc_t *desc)
627 1.6 oster {
628 1.6 oster RF_Raid_t *raidPtr = desc->raidPtr;
629 1.85 oster RF_DagList_t *dagList, *temp;
630 1.99 oster RF_VoidPointerListElem_t *tmp;
631 1.6 oster
632 1.6 oster RF_ASSERT(desc);
633 1.6 oster
634 1.85 oster /* Cleanup the dagList(s) */
635 1.85 oster dagList = desc->dagList;
636 1.85 oster while(dagList != NULL) {
637 1.85 oster temp = dagList;
638 1.85 oster dagList = dagList->next;
639 1.136.12.2 thorpej rf_FreeDAGList(raidPtr, temp);
640 1.85 oster }
641 1.85 oster
642 1.99 oster while (desc->iobufs) {
643 1.99 oster tmp = desc->iobufs;
644 1.99 oster desc->iobufs = desc->iobufs->next;
645 1.99 oster rf_FreeIOBuffer(raidPtr, tmp);
646 1.99 oster }
647 1.99 oster
648 1.99 oster while (desc->stripebufs) {
649 1.99 oster tmp = desc->stripebufs;
650 1.99 oster desc->stripebufs = desc->stripebufs->next;
651 1.99 oster rf_FreeStripeBuffer(raidPtr, tmp);
652 1.99 oster }
653 1.99 oster
654 1.136.12.2 thorpej pool_put(&raidPtr->pools.rad, desc);
655 1.126 mrg rf_lock_mutex2(raidPtr->rad_lock);
656 1.6 oster raidPtr->nAccOutstanding--;
657 1.6 oster if (raidPtr->waitShutdown) {
658 1.126 mrg rf_signal_cond2(raidPtr->outstandingCond);
659 1.6 oster }
660 1.126 mrg rf_unlock_mutex2(raidPtr->rad_lock);
661 1.1 oster }
662 1.1 oster /*********************************************************************
663 1.1 oster * Main routine for performing an access.
664 1.1 oster * Accesses are retried until a DAG can not be selected. This occurs
665 1.1 oster * when either the DAG library is incomplete or there are too many
666 1.1 oster * failures in a parity group.
667 1.80 oster *
668 1.136.12.2 thorpej * type should be read or write. bp_in is a buf pointer. void *to
669 1.136.12.2 thorpej * facilitate ignoring it outside the kernel
670 1.1 oster ********************************************************************/
671 1.107 perry int
672 1.136.12.2 thorpej rf_DoAccess(RF_Raid_t * raidPtr, RF_IoType_t type, RF_RaidAddr_t raidAddress, RF_SectorCount_t numBlocks,
673 1.114 christos void *bufPtr, struct buf *bp, RF_RaidAccessFlags_t flags)
674 1.1 oster {
675 1.6 oster RF_RaidAccessDesc_t *desc;
676 1.114 christos void *lbufPtr = bufPtr;
677 1.6 oster
678 1.6 oster raidAddress += rf_raidSectorOffset;
679 1.6 oster
680 1.61 oster #if RF_ACCESS_DEBUG
681 1.6 oster if (rf_accessDebug) {
682 1.1 oster
683 1.6 oster printf("logBytes is: %d %d %d\n", raidPtr->raidid,
684 1.6 oster raidPtr->logBytesPerSector,
685 1.6 oster (int) rf_RaidAddressToByte(raidPtr, numBlocks));
686 1.22 oster printf("raid%d: %s raidAddr %d (stripeid %d-%d) numBlocks %d (%d bytes) buf 0x%lx\n", raidPtr->raidid,
687 1.6 oster (type == RF_IO_TYPE_READ) ? "READ" : "WRITE", (int) raidAddress,
688 1.6 oster (int) rf_RaidAddressToStripeID(&raidPtr->Layout, raidAddress),
689 1.6 oster (int) rf_RaidAddressToStripeID(&raidPtr->Layout, raidAddress + numBlocks - 1),
690 1.6 oster (int) numBlocks,
691 1.6 oster (int) rf_RaidAddressToByte(raidPtr, numBlocks),
692 1.6 oster (long) bufPtr);
693 1.6 oster }
694 1.61 oster #endif
695 1.1 oster
696 1.6 oster desc = rf_AllocRaidAccDesc(raidPtr, type, raidAddress,
697 1.41 oster numBlocks, lbufPtr, bp, flags, raidPtr->Layout.map->states);
698 1.1 oster
699 1.6 oster if (desc == NULL) {
700 1.6 oster return (ENOMEM);
701 1.6 oster }
702 1.87 oster #if RF_ACC_TRACE > 0
703 1.6 oster RF_ETIMER_START(desc->tracerec.tot_timer);
704 1.87 oster #endif
705 1.3 explorer
706 1.122 jld if (raidPtr->parity_map != NULL &&
707 1.122 jld type == RF_IO_TYPE_WRITE)
708 1.122 jld rf_paritymap_begin(raidPtr->parity_map, raidAddress,
709 1.122 jld numBlocks);
710 1.122 jld
711 1.6 oster rf_ContinueRaidAccess(desc);
712 1.1 oster
713 1.6 oster return (0);
714 1.1 oster }
715 1.46 oster #if 0
716 1.1 oster /* force the array into reconfigured mode without doing reconstruction */
717 1.107 perry int
718 1.80 oster rf_SetReconfiguredMode(RF_Raid_t *raidPtr, int col)
719 1.6 oster {
720 1.6 oster if (!(raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE)) {
721 1.6 oster printf("Can't set reconfigured mode in dedicated-spare array\n");
722 1.6 oster RF_PANIC();
723 1.6 oster }
724 1.128 mrg rf_lock_mutex2(raidPtr->mutex);
725 1.6 oster raidPtr->numFailures++;
726 1.72 oster raidPtr->Disks[col].status = rf_ds_dist_spared;
727 1.72 oster raidPtr->status = rf_rs_reconfigured;
728 1.37 oster rf_update_component_labels(raidPtr, RF_NORMAL_COMPONENT_UPDATE);
729 1.6 oster /* install spare table only if declustering + distributed sparing
730 1.6 oster * architecture. */
731 1.6 oster if (raidPtr->Layout.map->flags & RF_BD_DECLUSTERED)
732 1.72 oster rf_InstallSpareTable(raidPtr, col);
733 1.128 mrg rf_unlock_mutex2(raidPtr->mutex);
734 1.6 oster return (0);
735 1.1 oster }
736 1.46 oster #endif
737 1.1 oster
738 1.107 perry int
739 1.80 oster rf_FailDisk(RF_Raid_t *raidPtr, int fcol, int initRecon)
740 1.6 oster {
741 1.98 oster
742 1.98 oster /* need to suspend IO's here -- if there are DAGs in flight
743 1.107 perry and we pull the rug out from under ci_vp, Bad Things
744 1.98 oster can happen. */
745 1.98 oster
746 1.98 oster rf_SuspendNewRequestsAndWait(raidPtr);
747 1.98 oster
748 1.128 mrg rf_lock_mutex2(raidPtr->mutex);
749 1.72 oster if (raidPtr->Disks[fcol].status != rf_ds_failed) {
750 1.68 oster /* must be failing something that is valid, or else it's
751 1.107 perry already marked as failed (in which case we don't
752 1.68 oster want to mark it failed again!) */
753 1.68 oster raidPtr->numFailures++;
754 1.72 oster raidPtr->Disks[fcol].status = rf_ds_failed;
755 1.107 perry raidPtr->status = rf_rs_degraded;
756 1.68 oster }
757 1.128 mrg rf_unlock_mutex2(raidPtr->mutex);
758 1.107 perry
759 1.37 oster rf_update_component_labels(raidPtr, RF_NORMAL_COMPONENT_UPDATE);
760 1.107 perry
761 1.107 perry /* Close the component, so that it's not "locked" if someone
762 1.56 oster else want's to use it! */
763 1.56 oster
764 1.72 oster rf_close_component(raidPtr, raidPtr->raid_cinfo[fcol].ci_vp,
765 1.72 oster raidPtr->Disks[fcol].auto_configured);
766 1.65 oster
767 1.128 mrg rf_lock_mutex2(raidPtr->mutex);
768 1.72 oster raidPtr->raid_cinfo[fcol].ci_vp = NULL;
769 1.56 oster
770 1.107 perry /* Need to mark the component as not being auto_configured
771 1.56 oster (in case it was previously). */
772 1.56 oster
773 1.72 oster raidPtr->Disks[fcol].auto_configured = 0;
774 1.128 mrg rf_unlock_mutex2(raidPtr->mutex);
775 1.98 oster /* now we can allow IO to continue -- we'll be suspending it
776 1.98 oster again in rf_ReconstructFailedDisk() if we have to.. */
777 1.98 oster
778 1.98 oster rf_ResumeNewRequests(raidPtr);
779 1.56 oster
780 1.6 oster if (initRecon)
781 1.72 oster rf_ReconstructFailedDisk(raidPtr, fcol);
782 1.6 oster return (0);
783 1.1 oster }
784 1.1 oster /* releases a thread that is waiting for the array to become quiesced.
785 1.1 oster * access_suspend_mutex should be locked upon calling this
786 1.1 oster */
787 1.107 perry void
788 1.80 oster rf_SignalQuiescenceLock(RF_Raid_t *raidPtr)
789 1.6 oster {
790 1.61 oster #if RF_DEBUG_QUIESCE
791 1.6 oster if (rf_quiesceDebug) {
792 1.107 perry printf("raid%d: Signalling quiescence lock\n",
793 1.22 oster raidPtr->raidid);
794 1.6 oster }
795 1.61 oster #endif
796 1.6 oster raidPtr->access_suspend_release = 1;
797 1.6 oster
798 1.6 oster if (raidPtr->waiting_for_quiescence) {
799 1.6 oster SIGNAL_QUIESCENT_COND(raidPtr);
800 1.6 oster }
801 1.1 oster }
802 1.1 oster /* suspends all new requests to the array. No effect on accesses that are in flight. */
803 1.107 perry int
804 1.80 oster rf_SuspendNewRequestsAndWait(RF_Raid_t *raidPtr)
805 1.6 oster {
806 1.61 oster #if RF_DEBUG_QUIESCE
807 1.6 oster if (rf_quiesceDebug)
808 1.53 oster printf("raid%d: Suspending new reqs\n", raidPtr->raidid);
809 1.61 oster #endif
810 1.127 mrg rf_lock_mutex2(raidPtr->access_suspend_mutex);
811 1.6 oster raidPtr->accesses_suspended++;
812 1.6 oster raidPtr->waiting_for_quiescence = (raidPtr->accs_in_flight == 0) ? 0 : 1;
813 1.6 oster
814 1.6 oster if (raidPtr->waiting_for_quiescence) {
815 1.6 oster raidPtr->access_suspend_release = 0;
816 1.6 oster while (!raidPtr->access_suspend_release) {
817 1.93 oster #if RF_DEBUG_QUIESCE
818 1.53 oster printf("raid%d: Suspending: Waiting for Quiescence\n",
819 1.53 oster raidPtr->raidid);
820 1.93 oster #endif
821 1.6 oster WAIT_FOR_QUIESCENCE(raidPtr);
822 1.6 oster raidPtr->waiting_for_quiescence = 0;
823 1.6 oster }
824 1.6 oster }
825 1.93 oster #if RF_DEBUG_QUIESCE
826 1.53 oster printf("raid%d: Quiescence reached..\n", raidPtr->raidid);
827 1.93 oster #endif
828 1.1 oster
829 1.127 mrg rf_unlock_mutex2(raidPtr->access_suspend_mutex);
830 1.6 oster return (raidPtr->waiting_for_quiescence);
831 1.1 oster }
832 1.1 oster /* wake up everyone waiting for quiescence to be released */
833 1.107 perry void
834 1.80 oster rf_ResumeNewRequests(RF_Raid_t *raidPtr)
835 1.6 oster {
836 1.136 christos RF_CallbackFuncDesc_t *t, *cb;
837 1.6 oster
838 1.61 oster #if RF_DEBUG_QUIESCE
839 1.6 oster if (rf_quiesceDebug)
840 1.116 oster printf("raid%d: Resuming new requests\n", raidPtr->raidid);
841 1.61 oster #endif
842 1.6 oster
843 1.127 mrg rf_lock_mutex2(raidPtr->access_suspend_mutex);
844 1.6 oster raidPtr->accesses_suspended--;
845 1.6 oster if (raidPtr->accesses_suspended == 0)
846 1.6 oster cb = raidPtr->quiesce_wait_list;
847 1.6 oster else
848 1.6 oster cb = NULL;
849 1.6 oster raidPtr->quiesce_wait_list = NULL;
850 1.127 mrg rf_unlock_mutex2(raidPtr->access_suspend_mutex);
851 1.6 oster
852 1.6 oster while (cb) {
853 1.6 oster t = cb;
854 1.6 oster cb = cb->next;
855 1.6 oster (t->callbackFunc) (t->callbackArg);
856 1.136.12.2 thorpej rf_FreeCallbackFuncDesc(raidPtr, t);
857 1.6 oster }
858 1.1 oster }
859 1.1 oster /*****************************************************************************************
860 1.1 oster *
861 1.1 oster * debug routines
862 1.1 oster *
863 1.1 oster ****************************************************************************************/
864 1.1 oster
865 1.107 perry static void
866 1.80 oster set_debug_option(char *name, long val)
867 1.6 oster {
868 1.6 oster RF_DebugName_t *p;
869 1.6 oster
870 1.6 oster for (p = rf_debugNames; p->name; p++) {
871 1.6 oster if (!strcmp(p->name, name)) {
872 1.6 oster *(p->ptr) = val;
873 1.6 oster printf("[Set debug variable %s to %ld]\n", name, val);
874 1.6 oster return;
875 1.6 oster }
876 1.6 oster }
877 1.6 oster RF_ERRORMSG1("Unknown debug string \"%s\"\n", name);
878 1.1 oster }
879 1.1 oster
880 1.1 oster
881 1.1 oster /* would like to use sscanf here, but apparently not available in kernel */
882 1.1 oster /*ARGSUSED*/
883 1.107 perry static void
884 1.80 oster rf_ConfigureDebug(RF_Config_t *cfgPtr)
885 1.6 oster {
886 1.6 oster char *val_p, *name_p, *white_p;
887 1.6 oster long val;
888 1.6 oster int i;
889 1.6 oster
890 1.6 oster rf_ResetDebugOptions();
891 1.131 msaitoh for (i = 0; i < RF_MAXDBGV && cfgPtr->debugVars[i][0]; i++) {
892 1.6 oster name_p = rf_find_non_white(&cfgPtr->debugVars[i][0]);
893 1.6 oster white_p = rf_find_white(name_p); /* skip to start of 2nd
894 1.6 oster * word */
895 1.6 oster val_p = rf_find_non_white(white_p);
896 1.6 oster if (*val_p == '0' && *(val_p + 1) == 'x')
897 1.6 oster val = rf_htoi(val_p + 2);
898 1.6 oster else
899 1.6 oster val = rf_atoi(val_p);
900 1.6 oster *white_p = '\0';
901 1.6 oster set_debug_option(name_p, val);
902 1.6 oster }
903 1.1 oster }
904 1.39 oster
905 1.39 oster void
906 1.108 christos rf_print_panic_message(int line, const char *file)
907 1.39 oster {
908 1.133 maya kern_assert("raidframe error at line %d file %s", line, file);
909 1.39 oster }
910 1.39 oster
911 1.62 oster #ifdef RAID_DIAGNOSTIC
912 1.39 oster void
913 1.108 christos rf_print_assert_panic_message(int line, const char *file, const char *condition)
914 1.39 oster {
915 1.133 maya kern_assert("raidframe error at line %d file %s (failed asserting %s)\n",
916 1.133 maya line, file, condition);
917 1.58 oster }
918 1.62 oster #endif
919 1.58 oster
920 1.58 oster void
921 1.108 christos rf_print_unable_to_init_mutex(const char *file, int line, int rc)
922 1.58 oster {
923 1.58 oster RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d\n",
924 1.58 oster file, line, rc);
925 1.58 oster }
926 1.58 oster
927 1.58 oster void
928 1.108 christos rf_print_unable_to_add_shutdown(const char *file, int line, int rc)
929 1.58 oster {
930 1.58 oster RF_ERRORMSG3("Unable to add to shutdown list file %s line %d rc=%d\n",
931 1.58 oster file, line, rc);
932 1.1 oster }
933 1.130 mrg
934 1.130 mrg static void
935 1.130 mrg rf_alloc_mutex_cond(RF_Raid_t *raidPtr)
936 1.130 mrg {
937 1.130 mrg
938 1.130 mrg rf_init_mutex2(raidPtr->mutex, IPL_VM);
939 1.130 mrg
940 1.130 mrg rf_init_cond2(raidPtr->outstandingCond, "rfocond");
941 1.134 mrg rf_init_cond2(raidPtr->parity_rewrite_cv, "rfprwshutdown");
942 1.130 mrg rf_init_mutex2(raidPtr->rad_lock, IPL_VM);
943 1.130 mrg
944 1.130 mrg rf_init_mutex2(raidPtr->access_suspend_mutex, IPL_VM);
945 1.130 mrg rf_init_cond2(raidPtr->access_suspend_cv, "rfquiesce");
946 1.130 mrg
947 1.130 mrg rf_init_cond2(raidPtr->waitForReconCond, "rfrcnw");
948 1.130 mrg
949 1.130 mrg rf_init_cond2(raidPtr->adding_hot_spare_cv, "raidhs");
950 1.130 mrg }
951 1.130 mrg
952 1.130 mrg static void
953 1.130 mrg rf_destroy_mutex_cond(RF_Raid_t *raidPtr)
954 1.130 mrg {
955 1.130 mrg
956 1.130 mrg rf_destroy_cond2(raidPtr->waitForReconCond);
957 1.130 mrg rf_destroy_cond2(raidPtr->adding_hot_spare_cv);
958 1.130 mrg
959 1.130 mrg rf_destroy_mutex2(raidPtr->access_suspend_mutex);
960 1.130 mrg rf_destroy_cond2(raidPtr->access_suspend_cv);
961 1.130 mrg
962 1.134 mrg rf_destroy_cond2(raidPtr->parity_rewrite_cv);
963 1.130 mrg rf_destroy_cond2(raidPtr->outstandingCond);
964 1.130 mrg rf_destroy_mutex2(raidPtr->rad_lock);
965 1.130 mrg
966 1.130 mrg rf_destroy_mutex2(raidPtr->mutex);
967 1.130 mrg }
968