Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 8 Jul 2011 20:41:13 +0000 (UTC)
From:      Matthew D Fleming <mdf@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r223876 - in head: share/man/man9 sys/kern
Message-ID:  <201107082041.p68KfDps040441@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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
       ( (<float> "%") | (<integer> "*" ) )*
       <type>
       [ "(" <integer> ")" ]
+      [ "[pid " <integer> "]" ]
 
   <float> ::
       <integer> [ "." <integer> ] |
@@ -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 <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
+#include <sys/proc.h>
 #include <sys/sbuf.h>
 
 #include <machine/stdarg.h>
@@ -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
 	 *     ( (<float> "%") | (<integer> "*" ) )*
 	 *     <type>
 	 *     [ "(" <integer> ")" ]
+	 *     [ "[pid " <integer> "]" ]
 	 */
 
 	/* ( (<float> "%") | (<integer> "*" ) )* */
@@ -500,6 +507,17 @@ parse_term(struct fail_point_entries *en
 	if (*p++ != ')')
 		return (NULL);
 
+	/* [ "[pid " <integer> "]" ] */
+#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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107082041.p68KfDps040441>