From owner-svn-src-head@FreeBSD.ORG Fri Jul 8 20:41:16 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DD27910656B6; Fri, 8 Jul 2011 20:41:13 +0000 (UTC) (envelope-from mdf@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2C77F8FC14; Fri, 8 Jul 2011 20:41:13 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p68KfDnV040444; Fri, 8 Jul 2011 20:41:13 GMT (envelope-from mdf@svn.freebsd.org) Received: (from mdf@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p68KfDps040441; Fri, 8 Jul 2011 20:41:13 GMT (envelope-from mdf@svn.freebsd.org) Message-Id: <201107082041.p68KfDps040441@svn.freebsd.org> From: Matthew D Fleming Date: Fri, 8 Jul 2011 20:41:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r223876 - in head: share/man/man9 sys/kern X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Jul 2011 20:41:16 -0000 Author: mdf Date: Fri Jul 8 20:41:12 2011 New Revision: 223876 URL: http://svn.freebsd.org/changeset/base/223876 Log: Add an option to have a fail point term only execute when run by a specified pid. This is helpful for automated testing involving a global knob that would otherwise be executed by many other threads. MFC after: 1 week Modified: head/share/man/man9/fail.9 head/sys/kern/kern_fail.c Modified: head/share/man/man9/fail.9 ============================================================================== --- head/share/man/man9/fail.9 Fri Jul 8 20:41:07 2011 (r223875) +++ head/share/man/man9/fail.9 Fri Jul 8 20:41:12 2011 (r223876) @@ -116,6 +116,7 @@ The sysctl variable may be set using the ( ( "%") | ( "*" ) )* [ "(" ")" ] + [ "[pid " "]" ] :: [ "." ] | @@ -161,6 +162,10 @@ For the purpose of this operator, the re are the only types that cascade. A return() term only cascades if the code executes, and a print() term only cascades when passed a non-zero argument. +A pid can optionally be specified. +The fail point term is only executed when invoked by a process with a +matching p_pid. +.Pp .Sh EXAMPLES .Bl -tag .It Sy sysctl debug.fail_point.foobar="2.1%return(5)" @@ -181,6 +186,8 @@ After that, 1/1000th of the time, return Return 5 for 1 in 1000 executions, but only 5 times total. .It Sy sysctl debug.fail_point.foobar="1%*sleep(50)" 1/100th of the time, sleep 50ms. +.It Sy sysctl debug.fail_point.foobar="1*return(5)[pid 1234]" +Return 5 once, when pid 1234 executes the fail point. .El .Sh AUTHORS .An -nosplit Modified: head/sys/kern/kern_fail.c ============================================================================== --- head/sys/kern/kern_fail.c Fri Jul 8 20:41:07 2011 (r223875) +++ head/sys/kern/kern_fail.c Fri Jul 8 20:41:12 2011 (r223876) @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -114,7 +115,7 @@ struct fail_point_entry { int fe_arg; /**< argument to type (e.g. return value) */ int fe_prob; /**< likelihood of firing in millionths */ int fe_count; /**< number of times to fire, 0 means always */ - + pid_t fe_pid; /**< only fail for this process */ TAILQ_ENTRY(fail_point_entry) fe_entries; /**< next entry in fail point */ }; @@ -227,6 +228,8 @@ fail_point_eval_nontrivial(struct fail_p if (ent->fe_prob < PROB_MAX && ent->fe_prob < random() % PROB_MAX) continue; + if (ent->fe_pid != NO_PID && ent->fe_pid != curproc->p_pid) + continue; switch (ent->fe_type) { case FAIL_POINT_PANIC: @@ -315,6 +318,8 @@ fail_point_get(struct fail_point *fp, st sbuf_printf(sb, "%s", fail_type_strings[ent->fe_type].name); if (ent->fe_arg) sbuf_printf(sb, "(%d)", ent->fe_arg); + if (ent->fe_pid != NO_PID) + sbuf_printf(sb, "[pid %d]", ent->fe_pid); if (TAILQ_NEXT(ent, fe_entries)) sbuf_printf(sb, "->"); } @@ -451,6 +456,7 @@ parse_term(struct fail_point_entries *en ent = fp_malloc(sizeof *ent, M_WAITOK | M_ZERO); ent->fe_prob = PROB_MAX; + ent->fe_pid = NO_PID; TAILQ_INSERT_TAIL(ents, ent, fe_entries); /* @@ -458,6 +464,7 @@ parse_term(struct fail_point_entries *en * ( ( "%") | ( "*" ) )* * * [ "(" ")" ] + * [ "[pid " "]" ] */ /* ( ( "%") | ( "*" ) )* */ @@ -500,6 +507,17 @@ parse_term(struct fail_point_entries *en if (*p++ != ')') return (NULL); + /* [ "[pid " "]" ] */ +#define PID_STRING "[pid " + if (strncmp(p, PID_STRING, sizeof(PID_STRING) - 1) != 0) + return (p); + p += sizeof(PID_STRING) - 1; + if (!isdigit(*p)) + return (NULL); + ent->fe_pid = strtol(p, &p, 0); + if (*p++ != ']') + return (NULL); + return (p); }