Mercurial > illumos > illumos-gate
comparison usr/src/uts/common/fs/zfs/zio_inject.c @ 13869:921a99998bb4
3246 ZFS I/O deadman thread
Reviewed by: Matt Ahrens <matthew.ahrens@delphix.com>
Reviewed by: Eric Schrock <eric.schrock@delphix.com>
Reviewed by: Christopher Siden <chris.siden@delphix.com>
Approved by: Garrett D'Amore <garrett@damore.org>
author | George.Wilson <george.wilson@delphix.com> |
---|---|
date | Mon, 29 Oct 2012 12:08:09 -0500 |
parents | b0fe99c06d14 |
children | d7059eb1884c |
comparison
equal
deleted
inserted
replaced
13868:cba64774a360 | 13869:921a99998bb4 |
---|---|
18 * | 18 * |
19 * CDDL HEADER END | 19 * CDDL HEADER END |
20 */ | 20 */ |
21 /* | 21 /* |
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. | 22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. |
23 * Copyright (c) 2012 by Delphix. All rights reserved. | |
23 */ | 24 */ |
24 | 25 |
25 /* | 26 /* |
26 * ZFS fault injection | 27 * ZFS fault injection |
27 * | 28 * |
145 rw_enter(&inject_lock, RW_READER); | 146 rw_enter(&inject_lock, RW_READER); |
146 | 147 |
147 for (handler = list_head(&inject_handlers); handler != NULL; | 148 for (handler = list_head(&inject_handlers); handler != NULL; |
148 handler = list_next(&inject_handlers, handler)) { | 149 handler = list_next(&inject_handlers, handler)) { |
149 | 150 |
150 /* Ignore errors not destined for this pool */ | 151 if (zio->io_spa != handler->zi_spa || |
151 if (zio->io_spa != handler->zi_spa) | 152 handler->zi_record.zi_cmd != ZINJECT_DATA_FAULT) |
152 continue; | |
153 | |
154 /* Ignore device errors and panic injection */ | |
155 if (handler->zi_record.zi_guid != 0 || | |
156 handler->zi_record.zi_func[0] != '\0' || | |
157 handler->zi_record.zi_duration != 0) | |
158 continue; | 153 continue; |
159 | 154 |
160 /* If this handler matches, return EIO */ | 155 /* If this handler matches, return EIO */ |
161 if (zio_match_handler(&zio->io_logical->io_bookmark, | 156 if (zio_match_handler(&zio->io_logical->io_bookmark, |
162 zio->io_bp ? BP_GET_TYPE(zio->io_bp) : DMU_OT_NONE, | 157 zio->io_bp ? BP_GET_TYPE(zio->io_bp) : DMU_OT_NONE, |
195 for (handler = list_head(&inject_handlers); handler != NULL; | 190 for (handler = list_head(&inject_handlers); handler != NULL; |
196 handler = list_next(&inject_handlers, handler)) { | 191 handler = list_next(&inject_handlers, handler)) { |
197 uint64_t start = handler->zi_record.zi_start; | 192 uint64_t start = handler->zi_record.zi_start; |
198 uint64_t end = handler->zi_record.zi_end; | 193 uint64_t end = handler->zi_record.zi_end; |
199 | 194 |
200 /* Ignore device only faults or panic injection */ | 195 if (handler->zi_record.zi_cmd != ZINJECT_LABEL_FAULT) |
201 if (handler->zi_record.zi_start == 0 || | |
202 handler->zi_record.zi_func[0] != '\0' || | |
203 handler->zi_record.zi_duration != 0) | |
204 continue; | 196 continue; |
205 | 197 |
206 /* | 198 /* |
207 * The injection region is the relative offsets within a | 199 * The injection region is the relative offsets within a |
208 * vdev label. We must determine the label which is being | 200 * vdev label. We must determine the label which is being |
244 rw_enter(&inject_lock, RW_READER); | 236 rw_enter(&inject_lock, RW_READER); |
245 | 237 |
246 for (handler = list_head(&inject_handlers); handler != NULL; | 238 for (handler = list_head(&inject_handlers); handler != NULL; |
247 handler = list_next(&inject_handlers, handler)) { | 239 handler = list_next(&inject_handlers, handler)) { |
248 | 240 |
249 /* | 241 if (handler->zi_record.zi_cmd != ZINJECT_DEVICE_FAULT) |
250 * Ignore label specific faults, panic injection | |
251 * or fake writes | |
252 */ | |
253 if (handler->zi_record.zi_start != 0 || | |
254 handler->zi_record.zi_func[0] != '\0' || | |
255 handler->zi_record.zi_duration != 0) | |
256 continue; | 242 continue; |
257 | 243 |
258 if (vd->vdev_guid == handler->zi_record.zi_guid) { | 244 if (vd->vdev_guid == handler->zi_record.zi_guid) { |
259 if (handler->zi_record.zi_failfast && | 245 if (handler->zi_record.zi_failfast && |
260 (zio == NULL || (zio->io_flags & | 246 (zio == NULL || (zio->io_flags & |
314 | 300 |
315 for (handler = list_head(&inject_handlers); handler != NULL; | 301 for (handler = list_head(&inject_handlers); handler != NULL; |
316 handler = list_next(&inject_handlers, handler)) { | 302 handler = list_next(&inject_handlers, handler)) { |
317 | 303 |
318 /* Ignore errors not destined for this pool */ | 304 /* Ignore errors not destined for this pool */ |
319 if (zio->io_spa != handler->zi_spa) | 305 if (zio->io_spa != handler->zi_spa || |
320 continue; | 306 handler->zi_record.zi_cmd != ZINJECT_IGNORED_WRITES) |
321 | |
322 if (handler->zi_record.zi_duration == 0) | |
323 continue; | 307 continue; |
324 | 308 |
325 /* | 309 /* |
326 * Positive duration implies # of seconds, negative | 310 * Positive duration implies # of seconds, negative |
327 * a number of txgs | 311 * a number of txgs |
353 rw_enter(&inject_lock, RW_READER); | 337 rw_enter(&inject_lock, RW_READER); |
354 | 338 |
355 for (handler = list_head(&inject_handlers); handler != NULL; | 339 for (handler = list_head(&inject_handlers); handler != NULL; |
356 handler = list_next(&inject_handlers, handler)) { | 340 handler = list_next(&inject_handlers, handler)) { |
357 | 341 |
358 /* Ignore errors not destined for this pool */ | 342 if (spa != handler->zi_spa || |
359 if (spa != handler->zi_spa) | 343 handler->zi_record.zi_cmd != ZINJECT_IGNORED_WRITES) |
360 continue; | |
361 | |
362 if (handler->zi_record.zi_duration == 0) | |
363 continue; | 344 continue; |
364 | 345 |
365 if (handler->zi_record.zi_duration > 0) { | 346 if (handler->zi_record.zi_duration > 0) { |
366 VERIFY(handler->zi_record.zi_timer == 0 || | 347 VERIFY(handler->zi_record.zi_timer == 0 || |
367 handler->zi_record.zi_timer + | 348 handler->zi_record.zi_timer + |
377 } | 358 } |
378 | 359 |
379 rw_exit(&inject_lock); | 360 rw_exit(&inject_lock); |
380 } | 361 } |
381 | 362 |
363 uint64_t | |
364 zio_handle_io_delay(zio_t *zio) | |
365 { | |
366 vdev_t *vd = zio->io_vd; | |
367 inject_handler_t *handler; | |
368 uint64_t seconds = 0; | |
369 | |
370 if (zio_injection_enabled == 0) | |
371 return (0); | |
372 | |
373 rw_enter(&inject_lock, RW_READER); | |
374 | |
375 for (handler = list_head(&inject_handlers); handler != NULL; | |
376 handler = list_next(&inject_handlers, handler)) { | |
377 | |
378 if (handler->zi_record.zi_cmd != ZINJECT_DELAY_IO) | |
379 continue; | |
380 | |
381 if (vd->vdev_guid == handler->zi_record.zi_guid) { | |
382 seconds = handler->zi_record.zi_timer; | |
383 break; | |
384 } | |
385 | |
386 } | |
387 rw_exit(&inject_lock); | |
388 return (seconds); | |
389 } | |
390 | |
382 /* | 391 /* |
383 * Create a new handler for the given record. We add it to the list, adding | 392 * Create a new handler for the given record. We add it to the list, adding |
384 * a reference to the spa_t in the process. We increment zio_injection_enabled, | 393 * a reference to the spa_t in the process. We increment zio_injection_enabled, |
385 * which is the switch to trigger all fault injection. | 394 * which is the switch to trigger all fault injection. |
386 */ | 395 */ |