From owner-svn-src-head@freebsd.org Wed Jan 1 04:22:05 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 2BB5C1E5AA2; Wed, 1 Jan 2020 04:22:05 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47ndKn0Rr0z438c; Wed, 1 Jan 2020 04:22:05 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0A96124FCF; Wed, 1 Jan 2020 04:22:05 +0000 (UTC) (envelope-from kevans@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0014M4XL085307; Wed, 1 Jan 2020 04:22:04 GMT (envelope-from kevans@FreeBSD.org) Received: (from kevans@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0014M43i084894; Wed, 1 Jan 2020 04:22:04 GMT (envelope-from kevans@FreeBSD.org) Message-Id: <202001010422.0014M43i084894@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kevans set sender to kevans@FreeBSD.org using -f From: Kyle Evans Date: Wed, 1 Jan 2020 04:22:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r356247 - head/usr.sbin/inetd X-SVN-Group: head X-SVN-Commit-Author: kevans X-SVN-Commit-Paths: head/usr.sbin/inetd X-SVN-Commit-Revision: 356247 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 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: Wed, 01 Jan 2020 04:22:05 -0000 Author: kevans Date: Wed Jan 1 04:22:04 2020 New Revision: 356247 URL: https://svnweb.freebsd.org/changeset/base/356247 Log: inetd: track all child pids, regardless of maxchild spec Currently, child pids are only tracked if maxchildren is specified. As a consequence, without a maxchild limit we do not get a notice in syslog on children aborting abnormally. This turns out to be a great debugging aide at times. Children are now tracked in a LIST; the management interface is decidedly less painful when there's no upper bound on the number of entries we may have at the cost of one small allocation per connection. PR: 70335 Modified: head/usr.sbin/inetd/inetd.c head/usr.sbin/inetd/inetd.h Modified: head/usr.sbin/inetd/inetd.c ============================================================================== --- head/usr.sbin/inetd/inetd.c Wed Jan 1 03:59:54 2020 (r356246) +++ head/usr.sbin/inetd/inetd.c Wed Jan 1 04:22:04 2020 (r356247) @@ -922,8 +922,8 @@ flag_signal(int signo) static void addchild(struct servtab *sep, pid_t pid) { - if (sep->se_maxchild <= 0) - return; + struct stabchild *sc; + #ifdef SANITY_CHECK if (SERVTAB_EXCEEDS_LIMIT(sep)) { syslog(LOG_ERR, "%s: %d >= %d", @@ -931,7 +931,15 @@ addchild(struct servtab *sep, pid_t pid) exit(EX_SOFTWARE); } #endif - sep->se_pids[sep->se_numchild++] = pid; + sc = malloc(sizeof(*sc)); + if (sc == NULL) { + syslog(LOG_ERR, "malloc: %m"); + exit(EX_OSERR); + } + memset(sc, 0, sizeof(*sc)); + sc->sc_pid = pid; + LIST_INSERT_HEAD(&sep->se_children, sc, sc_link); + ++sep->se_numchild; if (SERVTAB_AT_LIMIT(sep)) disable(sep); } @@ -939,8 +947,9 @@ addchild(struct servtab *sep, pid_t pid) static void reapchild(void) { - int k, status; + int status; pid_t pid; + struct stabchild *sc; struct servtab *sep; for (;;) { @@ -953,14 +962,17 @@ reapchild(void) WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)); for (sep = servtab; sep; sep = sep->se_next) { - for (k = 0; k < sep->se_numchild; k++) - if (sep->se_pids[k] == pid) + LIST_FOREACH(sc, &sep->se_children, sc_link) { + if (sc->sc_pid == pid) break; - if (k == sep->se_numchild) + } + if (sc == NULL) continue; if (SERVTAB_AT_LIMIT(sep)) enable(sep); - sep->se_pids[k] = sep->se_pids[--sep->se_numchild]; + LIST_REMOVE(sc, sc_link); + free(sc); + --sep->se_numchild; if (WIFSIGNALED(status) || WEXITSTATUS(status)) syslog(LOG_WARNING, "%s[%d]: exited, %s %u", @@ -1032,18 +1044,14 @@ config(void) sep->se_nomapped = new->se_nomapped; sep->se_reset = 1; } - /* copy over outstanding child pids */ - if (sep->se_maxchild > 0 && new->se_maxchild > 0) { - new->se_numchild = sep->se_numchild; - if (new->se_numchild > new->se_maxchild) - new->se_numchild = new->se_maxchild; - memcpy(new->se_pids, sep->se_pids, - new->se_numchild * sizeof(*new->se_pids)); - } - SWAP(pid_t *, sep->se_pids, new->se_pids); - sep->se_maxchild = new->se_maxchild; - sep->se_numchild = new->se_numchild; + + /* + * The children tracked remain; we want numchild to + * still reflect how many jobs are running so we don't + * throw off our accounting. + */ sep->se_maxcpm = new->se_maxcpm; + sep->se_maxchild = new->se_maxchild; resize_conn(sep, new->se_maxperip); sep->se_maxperip = new->se_maxperip; sep->se_bi = new->se_bi; @@ -1949,13 +1957,7 @@ more: else sep->se_maxchild = 1; } - if (sep->se_maxchild > 0) { - sep->se_pids = malloc(sep->se_maxchild * sizeof(*sep->se_pids)); - if (sep->se_pids == NULL) { - syslog(LOG_ERR, "malloc: %m"); - exit(EX_OSERR); - } - } + LIST_INIT(&sep->se_children); argc = 0; for (arg = skip(&cp); cp; arg = skip(&cp)) if (argc < MAXARGV) { @@ -1980,6 +1982,7 @@ more: static void freeconfig(struct servtab *cp) { + struct stabchild *sc; int i; if (cp->se_service) @@ -1996,8 +1999,11 @@ freeconfig(struct servtab *cp) #endif if (cp->se_server) free(cp->se_server); - if (cp->se_pids) - free(cp->se_pids); + while (!LIST_EMPTY(&cp->se_children)) { + sc = LIST_FIRST(&cp->se_children); + LIST_REMOVE(sc, sc_link); + free(sc); + } for (i = 0; i < MAXARGV; i++) if (cp->se_argv[i]) free(cp->se_argv[i]); Modified: head/usr.sbin/inetd/inetd.h ============================================================================== --- head/usr.sbin/inetd/inetd.h Wed Jan 1 03:59:54 2020 (r356246) +++ head/usr.sbin/inetd/inetd.h Wed Jan 1 04:22:04 2020 (r356247) @@ -66,6 +66,11 @@ struct conninfo { #define PERIPSIZE 256 +struct stabchild { + LIST_ENTRY(stabchild) sc_link; + pid_t sc_pid; +}; + struct servtab { char *se_service; /* name of service */ int se_socktype; /* type of socket to use */ @@ -74,7 +79,6 @@ struct servtab { int se_maxchild; /* max number of children */ int se_maxcpm; /* max connects per IP per minute */ int se_numchild; /* current number of children */ - pid_t *se_pids; /* array of child pids */ char *se_user; /* user name to run as */ char *se_group; /* group name to run as */ #ifdef LOGIN_CAP @@ -119,6 +123,7 @@ struct servtab { } se_flags; int se_maxperip; /* max number of children per src */ LIST_HEAD(, conninfo) se_conn[PERIPSIZE]; + LIST_HEAD(, stabchild) se_children; }; #define se_nomapped se_flags.se_nomapped