From owner-svn-src-stable-9@FreeBSD.ORG Fri Oct 26 16:07:54 2012 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 42500397; Fri, 26 Oct 2012 16:07:54 +0000 (UTC) (envelope-from obrien@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 278D28FC12; Fri, 26 Oct 2012 16:07:54 +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 q9QG7sEq035741; Fri, 26 Oct 2012 16:07:54 GMT (envelope-from obrien@svn.freebsd.org) Received: (from obrien@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q9QG7raE035736; Fri, 26 Oct 2012 16:07:53 GMT (envelope-from obrien@svn.freebsd.org) Message-Id: <201210261607.q9QG7raE035736@svn.freebsd.org> From: "David E. O'Brien" Date: Fri, 26 Oct 2012 16:07:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r242142 - in stable/9: sys/dev/filemon tools/regression/filemon X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Oct 2012 16:07:54 -0000 Author: obrien Date: Fri Oct 26 16:07:53 2012 New Revision: 242142 URL: http://svn.freebsd.org/changeset/base/242142 Log: MFC: r242137: Iterate rather than use recursion. We can blow out the kernel stack if there is a long chain of fork(2)s. Added: stable/9/tools/regression/filemon/timed-forkb.c - copied unchanged from r242137, head/tools/regression/filemon/timed-forkb.c Modified: stable/9/sys/dev/filemon/filemon_wrapper.c stable/9/tools/regression/filemon/Makefile Directory Properties: stable/9/ (props changed) stable/9/sys/ (props changed) stable/9/sys/dev/ (props changed) stable/9/tools/ (props changed) Modified: stable/9/sys/dev/filemon/filemon_wrapper.c ============================================================================== --- stable/9/sys/dev/filemon/filemon_wrapper.c Fri Oct 26 16:06:26 2012 (r242141) +++ stable/9/sys/dev/filemon/filemon_wrapper.c Fri Oct 26 16:07:53 2012 (r242142) @@ -82,15 +82,14 @@ filemon_pid_check(struct proc *p) { struct filemon *filemon; - TAILQ_FOREACH(filemon, &filemons_inuse, link) { - if (p->p_pid == filemon->pid) - return (filemon); + while (p->p_pptr) { + TAILQ_FOREACH(filemon, &filemons_inuse, link) { + if (p->p_pid == filemon->pid) + return (filemon); + } + p = p->p_pptr; } - - if (p->p_pptr == NULL) - return (NULL); - - return (filemon_pid_check(p->p_pptr)); + return (NULL); } static void Modified: stable/9/tools/regression/filemon/Makefile ============================================================================== --- stable/9/tools/regression/filemon/Makefile Fri Oct 26 16:06:26 2012 (r242141) +++ stable/9/tools/regression/filemon/Makefile Fri Oct 26 16:07:53 2012 (r242142) @@ -1,15 +1,33 @@ # $FreeBSD$ -PROG= filemontest +BINS= \ + filemontest \ + timed-forkb + +bins: filemontest timed-forkb +all: bins NO_MAN= WARNS?= 6 CFLAGS+= -I${.CURDIR}/../../../sys +# Should be "WITHOUT_CTF=" below, but stupid infastrurture fails: +# "/usr/share/mk/bsd.own.mk", line 489: WITH_CTF and WITHOUT_CTF can't both be set. +WITHOUT_CDDL= + +CLEANFILES+= ${BINS} + +tests: bins + kldstat | grep filemon + ${MAKE} test + ./timed-forkb + @echo "filemon(4) tests passed." + # Cannot use .OBJDIR -- 'filemontest' expects 'test_script.sh' in . -test: ${PROG} clean-test -.for BIN in ${PROG} ${PROG}32 +#FILEMONTEST32= filemontest32 +test: filemontest clean-test +.for BIN in filemontest ${FILEMONTEST32} cd ${.CURDIR} ; \ for A in 1 2 3 4 5 6 7 8 9 0; do \ for B in 1 2 3 4 5 6 7 8 9 0; do \ Copied: stable/9/tools/regression/filemon/timed-forkb.c (from r242137, head/tools/regression/filemon/timed-forkb.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/9/tools/regression/filemon/timed-forkb.c Fri Oct 26 16:07:53 2012 (r242142, copy of r242137, head/tools/regression/filemon/timed-forkb.c) @@ -0,0 +1,177 @@ +/*- + * Copyright (c) 2012 David O'Brien + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef SLEEP +#define SLEEP 20 /* seconds */ +#endif + +int verbose; + +static void +usage(void) +{ + fprintf(stderr, "usage: %s\n", getprogname()); + fprintf(stderr, "\t\t-n : length of fork(2) chain\n"); + fprintf(stderr, "\t\t-t : limit run-time seconds\n"); + exit(1); + /* NOTREACHED */ +} + +void term(int); +void +term(int signum) +{ + + if (getpid() == getpgrp() || verbose) { + fprintf(stderr, + "pid %d pgroup %d (ppid %d): Received SIGTERM(%d), exiting...\n", + getpid(), getpgrp(), getppid(), signum); + } + exit(1); +} + +void angel_of_mercy(int); +void +angel_of_mercy(int sig __unused) +{ + + signal(SIGALRM, SIG_IGN); /* ignore this signal */ + printf("Master process: alarmed waking up\n"); + killpg(0, SIGTERM); + return; +} + +int bombing_run(unsigned, int); +int +bombing_run(unsigned chainlen, int stime) +{ + struct rusage ru; + pid_t pid, cpid; + int status; + + if (chainlen) { + switch (pid = fork()) { + case -1: + errx(1, "%s: can't fork", __func__); + + case 0: + /* This is the code the child runs. */ + bombing_run(--chainlen, stime); + break; + + default: + /* This is the code the parent runs. */ + if (getpid() == getpgrp()) { + signal(SIGALRM, angel_of_mercy); + alarm(stime); // time for bombing run... + cpid = wait4(pid, &status, 0, &ru); + alarm(0); + printf( + "Cleanly shutting down - pid %d pgroup %d (ppid %d)\n", + getpid(), getpgrp(), getppid()); + } else { + cpid = wait4(pid, &status, 0, &ru); + } + } + } + + return 0; +} + +int +main(int argc, char *argv[]) +{ + time_t start /*,tvec*/; + char *endptr, *ctm; + size_t len; + int nflag, tflag; + int ch, k, maxprocperuid; + + (void)signal(SIGTERM, term); + + nflag = 0; + tflag = SLEEP; + + start = time(NULL); + ctm = ctime(&start); + ctm[24] = '\0'; // see: man 3 ctime + fprintf(stderr, "*** fork() generation started on \"%s\" ***\n", ctm); + + while ((ch = getopt(argc, argv, "n:t:v")) != -1) + switch (ch) { + case 'n': + nflag = strtol(optarg, &endptr, 10); + if (nflag <= 0 || *endptr != '\0') + errx(1, "illegal number, -n argument -- %s", + optarg); + break; + case 't': + tflag = strtol(optarg, &endptr, 10); + if (tflag <= 0 || *endptr != '\0') + errx(1, "illegal number, -t argument -- %s", + optarg); + break; + case 'v': + ++verbose; + break; + default: + usage(); + } + argv += optind; + + if (!nflag) { + len = sizeof(maxprocperuid); + k = sysctlbyname("kern.maxprocperuid", &maxprocperuid, &len, + NULL, 0); + assert(k != ENOMEM); + /* Try to allow a shell to still be started. */ + nflag = maxprocperuid - 10; + } + + // Ensure a unique process group to make killing all children easier. + setpgrp(0,0); + printf(" pid %d pgroup %d (ppid %d), %d fork chain over %d sec\n", + getpid(), getpgrp(), getppid(), nflag - 1, tflag); + + return bombing_run(nflag, tflag); +}