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 ---