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