kern_fail.c (0894a9bca6ac7c9a06d0c33daee62ff5db47ef19) | kern_fail.c (b5bd50ae40085c9fa935b1e89f5c70eb0558bbf7) |
---|---|
1/*- 2 * Copyright (c) 2009 Isilon Inc http://www.isilon.com/ 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 46 unchanged lines hidden (view full) --- 55#include <sys/ctype.h> 56#include <sys/errno.h> 57#include <sys/fail.h> 58#include <sys/kernel.h> 59#include <sys/libkern.h> 60#include <sys/lock.h> 61#include <sys/malloc.h> 62#include <sys/mutex.h> | 1/*- 2 * Copyright (c) 2009 Isilon Inc http://www.isilon.com/ 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 46 unchanged lines hidden (view full) --- 55#include <sys/ctype.h> 56#include <sys/errno.h> 57#include <sys/fail.h> 58#include <sys/kernel.h> 59#include <sys/libkern.h> 60#include <sys/lock.h> 61#include <sys/malloc.h> 62#include <sys/mutex.h> |
63#include <sys/proc.h> |
|
63#include <sys/sbuf.h> 64 65#include <machine/stdarg.h> 66 67#ifdef ILOG_DEFINE_FOR_FILE 68ILOG_DEFINE_FOR_FILE(L_ISI_FAIL_POINT, L_ILOG, fail_point); 69#endif 70 --- 38 unchanged lines hidden (view full) --- 109 * Internal structure tracking a single term of a complete failpoint. 110 * @ingroup failpoint_private 111 */ 112struct fail_point_entry { 113 enum fail_point_t fe_type; /**< type of entry */ 114 int fe_arg; /**< argument to type (e.g. return value) */ 115 int fe_prob; /**< likelihood of firing in millionths */ 116 int fe_count; /**< number of times to fire, 0 means always */ | 64#include <sys/sbuf.h> 65 66#include <machine/stdarg.h> 67 68#ifdef ILOG_DEFINE_FOR_FILE 69ILOG_DEFINE_FOR_FILE(L_ISI_FAIL_POINT, L_ILOG, fail_point); 70#endif 71 --- 38 unchanged lines hidden (view full) --- 110 * Internal structure tracking a single term of a complete failpoint. 111 * @ingroup failpoint_private 112 */ 113struct fail_point_entry { 114 enum fail_point_t fe_type; /**< type of entry */ 115 int fe_arg; /**< argument to type (e.g. return value) */ 116 int fe_prob; /**< likelihood of firing in millionths */ 117 int fe_count; /**< number of times to fire, 0 means always */ |
117 | 118 pid_t fe_pid; /**< only fail for this process */ |
118 TAILQ_ENTRY(fail_point_entry) fe_entries; /**< next entry in fail point */ 119}; 120 121static inline void 122fail_point_sleep(struct fail_point *fp, struct fail_point_entry *ent, 123 int msecs, enum fail_point_return_code *pret) 124{ 125 /* convert from millisecs to ticks, rounding up */ --- 96 unchanged lines hidden (view full) --- 222 FP_LOCK(); 223 224 TAILQ_FOREACH_SAFE(ent, &fp->fp_entries, fe_entries, next) { 225 int cont = 0; /* don't continue by default */ 226 227 if (ent->fe_prob < PROB_MAX && 228 ent->fe_prob < random() % PROB_MAX) 229 continue; | 119 TAILQ_ENTRY(fail_point_entry) fe_entries; /**< next entry in fail point */ 120}; 121 122static inline void 123fail_point_sleep(struct fail_point *fp, struct fail_point_entry *ent, 124 int msecs, enum fail_point_return_code *pret) 125{ 126 /* convert from millisecs to ticks, rounding up */ --- 96 unchanged lines hidden (view full) --- 223 FP_LOCK(); 224 225 TAILQ_FOREACH_SAFE(ent, &fp->fp_entries, fe_entries, next) { 226 int cont = 0; /* don't continue by default */ 227 228 if (ent->fe_prob < PROB_MAX && 229 ent->fe_prob < random() % PROB_MAX) 230 continue; |
231 if (ent->fe_pid != NO_PID && ent->fe_pid != curproc->p_pid) 232 continue; |
|
230 231 switch (ent->fe_type) { 232 case FAIL_POINT_PANIC: 233 panic("fail point %s panicking", fp->fp_name); 234 /* NOTREACHED */ 235 236 case FAIL_POINT_RETURN: 237 if (return_value != NULL) --- 72 unchanged lines hidden (view full) --- 310 } 311 sbuf_printf(sb, "%%"); 312 } 313 if (ent->fe_count > 0) 314 sbuf_printf(sb, "%d*", ent->fe_count); 315 sbuf_printf(sb, "%s", fail_type_strings[ent->fe_type].name); 316 if (ent->fe_arg) 317 sbuf_printf(sb, "(%d)", ent->fe_arg); | 233 234 switch (ent->fe_type) { 235 case FAIL_POINT_PANIC: 236 panic("fail point %s panicking", fp->fp_name); 237 /* NOTREACHED */ 238 239 case FAIL_POINT_RETURN: 240 if (return_value != NULL) --- 72 unchanged lines hidden (view full) --- 313 } 314 sbuf_printf(sb, "%%"); 315 } 316 if (ent->fe_count > 0) 317 sbuf_printf(sb, "%d*", ent->fe_count); 318 sbuf_printf(sb, "%s", fail_type_strings[ent->fe_type].name); 319 if (ent->fe_arg) 320 sbuf_printf(sb, "(%d)", ent->fe_arg); |
321 if (ent->fe_pid != NO_PID) 322 sbuf_printf(sb, "[pid %d]", ent->fe_pid); |
|
318 if (TAILQ_NEXT(ent, fe_entries)) 319 sbuf_printf(sb, "->"); 320 } 321 if (TAILQ_EMPTY(&fp->fp_entries)) 322 sbuf_printf(sb, "off"); 323 324 FP_UNLOCK(); 325} --- 120 unchanged lines hidden (view full) --- 446 */ 447static char * 448parse_term(struct fail_point_entries *ents, char *p) 449{ 450 struct fail_point_entry *ent; 451 452 ent = fp_malloc(sizeof *ent, M_WAITOK | M_ZERO); 453 ent->fe_prob = PROB_MAX; | 323 if (TAILQ_NEXT(ent, fe_entries)) 324 sbuf_printf(sb, "->"); 325 } 326 if (TAILQ_EMPTY(&fp->fp_entries)) 327 sbuf_printf(sb, "off"); 328 329 FP_UNLOCK(); 330} --- 120 unchanged lines hidden (view full) --- 451 */ 452static char * 453parse_term(struct fail_point_entries *ents, char *p) 454{ 455 struct fail_point_entry *ent; 456 457 ent = fp_malloc(sizeof *ent, M_WAITOK | M_ZERO); 458 ent->fe_prob = PROB_MAX; |
459 ent->fe_pid = NO_PID; |
|
454 TAILQ_INSERT_TAIL(ents, ent, fe_entries); 455 456 /* 457 * <term> :: 458 * ( (<float> "%") | (<integer> "*" ) )* 459 * <type> 460 * [ "(" <integer> ")" ] | 460 TAILQ_INSERT_TAIL(ents, ent, fe_entries); 461 462 /* 463 * <term> :: 464 * ( (<float> "%") | (<integer> "*" ) )* 465 * <type> 466 * [ "(" <integer> ")" ] |
467 * [ "[pid " <integer> "]" ] |
|
461 */ 462 463 /* ( (<float> "%") | (<integer> "*" ) )* */ 464 while (isdigit(*p) || *p == '.') { 465 int units, decimal; 466 467 p = parse_number(&units, &decimal, p); 468 if (p == NULL) --- 26 unchanged lines hidden (view full) --- 495 return p; 496 p++; 497 if (!isdigit(*p) && *p != '-') 498 return (NULL); 499 ent->fe_arg = strtol(p, &p, 0); 500 if (*p++ != ')') 501 return (NULL); 502 | 468 */ 469 470 /* ( (<float> "%") | (<integer> "*" ) )* */ 471 while (isdigit(*p) || *p == '.') { 472 int units, decimal; 473 474 p = parse_number(&units, &decimal, p); 475 if (p == NULL) --- 26 unchanged lines hidden (view full) --- 502 return p; 503 p++; 504 if (!isdigit(*p) && *p != '-') 505 return (NULL); 506 ent->fe_arg = strtol(p, &p, 0); 507 if (*p++ != ')') 508 return (NULL); 509 |
510 /* [ "[pid " <integer> "]" ] */ 511#define PID_STRING "[pid " 512 if (strncmp(p, PID_STRING, sizeof(PID_STRING) - 1) != 0) 513 return (p); 514 p += sizeof(PID_STRING) - 1; 515 if (!isdigit(*p)) 516 return (NULL); 517 ent->fe_pid = strtol(p, &p, 0); 518 if (*p++ != ']') 519 return (NULL); 520 |
|
503 return (p); 504} 505 506/** 507 * Internal helper function to parse a numeric for a failpoint term. 508 */ 509static char * 510parse_number(int *out_units, int *out_decimal, char *p) --- 83 unchanged lines hidden --- | 521 return (p); 522} 523 524/** 525 * Internal helper function to parse a numeric for a failpoint term. 526 */ 527static char * 528parse_number(int *out_units, int *out_decimal, char *p) --- 83 unchanged lines hidden --- |