Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/inetd Improve kqueue(2) utilization:



details:   https://anonhg.NetBSD.org/src/rev/c7d57d964629
branches:  trunk
changeset: 542984:c7d57d964629
user:      tron <tron%NetBSD.org@localhost>
date:      Thu Feb 13 11:47:27 2003 +0000

description:
Improve kqueue(2) utilization:
- Don't invoke kevent(2) for every single event change. Instead collect
  event changes and try to do them in the event loop.
- Handle signals via kevent(2) to avoid race conditions for SIGHUP (which
  probably exist in the select(2) based implementation, too).

diffstat:

 usr.sbin/inetd/inetd.c |  432 +++++++++++++++++++++++-------------------------
 1 files changed, 206 insertions(+), 226 deletions(-)

diffs (truncated from 874 to 300 lines):

diff -r afc2025448ca -r c7d57d964629 usr.sbin/inetd/inetd.c
--- a/usr.sbin/inetd/inetd.c    Thu Feb 13 09:53:20 2003 +0000
+++ b/usr.sbin/inetd/inetd.c    Thu Feb 13 11:47:27 2003 +0000
@@ -1,12 +1,12 @@
-/*     $NetBSD: inetd.c,v 1.86 2003/02/12 10:03:47 tron Exp $  */
+/*     $NetBSD: inetd.c,v 1.87 2003/02/13 11:47:27 tron Exp $  */
 
 /*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
- * NASA Ames Research Center.
+ * NASA Ames Research Center and by Matthias Scheler.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -77,7 +77,7 @@
 #if 0
 static char sccsid[] = "@(#)inetd.c    8.4 (Berkeley) 4/13/94";
 #else
-__RCSID("$NetBSD: inetd.c,v 1.86 2003/02/12 10:03:47 tron Exp $");
+__RCSID("$NetBSD: inetd.c,v 1.87 2003/02/13 11:47:27 tron Exp $");
 #endif
 #endif /* not lint */
 
@@ -271,6 +271,8 @@
 
 #define        SIGBLOCK        (sigmask(SIGCHLD)|sigmask(SIGHUP)|sigmask(SIGALRM))
 
+#define        A_CNT(a)        (sizeof (a) / sizeof (a[0]))
+
 int    debug;
 #ifdef LIBWRAP
 int    lflag;
@@ -295,6 +297,9 @@
 struct rlimit  rlim_ofile;
 #endif
 
+struct kevent  changebuf[64];
+size_t         changes;
+
 struct servtab {
        char    *se_hostaddr;           /* host address to listen on */
        char    *se_service;            /* name of service */
@@ -349,52 +354,52 @@
 #define ISMUXPLUS(sep) ((sep)->se_type == MUXPLUS_TYPE)
 
 
-void           chargen_dg(int, struct servtab *);
-void           chargen_stream(int, struct servtab *);
-void           close_sep(struct servtab *);
-void           config(int);
-void           daytime_dg(int, struct servtab *);
-void           daytime_stream(int, struct servtab *);
-void           discard_dg(int, struct servtab *);
-void           discard_stream(int, struct servtab *);
-void           echo_dg(int, struct servtab *);
-void           echo_stream(int, struct servtab *);
-void           endconfig(void);
-struct servtab *enter(struct servtab *);
-void           freeconfig(struct servtab *);
-struct servtab *getconfigent(void);
-void           goaway(int);
-void           machtime_dg(int, struct servtab *);
-void           machtime_stream(int, struct servtab *);
-char          *newstr(char *);
-char          *nextline(FILE *);
-void           print_service(char *, struct servtab *);
-void           reapchild(int);
-void           retry(int);
-void           run_service(int, struct servtab *);
-int            setconfig(void);
-void           setup(struct servtab *);
-char          *sskip(char **);
-char          *skip(char **);
-void           tcpmux(int, struct servtab *);
-void           usage(void);
-void           register_rpc(struct servtab *);
-void           unregister_rpc(struct servtab *);
-void           bump_nofile(void);
-void           inetd_setproctitle(char *, int);
-void           initring(void);
-uint32_t       machtime(void);
-int            port_good_dg(struct sockaddr *);
-int            dg_broadcast(struct in_addr *);
+static void    chargen_dg(int, struct servtab *);
+static void    chargen_stream(int, struct servtab *);
+static void    close_sep(struct servtab *);
+static void    config(void);
+static void    daytime_dg(int, struct servtab *);
+static void    daytime_stream(int, struct servtab *);
+static void    discard_dg(int, struct servtab *);
+static void    discard_stream(int, struct servtab *);
+static void    echo_dg(int, struct servtab *);
+static void    echo_stream(int, struct servtab *);
+static void    endconfig(void);
+static struct servtab *enter(struct servtab *);
+static void    freeconfig(struct servtab *);
+static struct servtab *getconfigent(void);
+static void    goaway(void);
+static void    machtime_dg(int, struct servtab *);
+static void    machtime_stream(int, struct servtab *);
+static char    *newstr(char *);
+static char    *nextline(FILE *);
+static void    print_service(char *, struct servtab *);
+static void    reapchild(void);
+static void    retry(void);
+static void    run_service(int, struct servtab *);
+static int     setconfig(void);
+static void    setup(struct servtab *);
+static char    *sskip(char **);
+static char    *skip(char **);
+static void    tcpmux(int, struct servtab *);
+static void    usage(void);
+static void    register_rpc(struct servtab *);
+static void    unregister_rpc(struct servtab *);
+static void    bump_nofile(void);
+static void    inetd_setproctitle(char *, int);
+static void    initring(void);
+static uint32_t        machtime(void);
+static int     port_good_dg(struct sockaddr *);
+static int     dg_broadcast(struct in_addr *);
 static int     my_kevent(const struct kevent *, size_t, struct kevent *,
                size_t);
+static struct kevent * allocchange(void);
 static int     getline(int, char *, int);
-int            main(int, char *[]);
-void           spawn(struct servtab *, int);
+static void    spawn(struct servtab *, int);
 #ifdef MULOG
-void           dolog(struct servtab *, int);
+static void    dolog(struct servtab *, int);
 static void    timeout(int);
-char           *rfc931_name(struct sockaddr *, int);
+static char    *rfc931_name(struct sockaddr *, int);
 #endif
 
 struct biltin {
@@ -441,14 +446,13 @@
 #define NUMINT (sizeof(intab) / sizeof(struct inent))
 char   *CONFIG = _PATH_INETDCONF;
 
+static int my_signals[] = { SIGALRM, SIGHUP, SIGCHLD, SIGTERM, SIGINT };
+
 int
-main(argc, argv)
-       int argc;
-       char *argv[];
+main(int argc, char *argv[])
 {
-       struct servtab *sep;
-       struct sigvec sv;
-       int ch;
+       int             ch, n, reload = 1;
+       struct kevent   *ev;
 
        while ((ch = getopt(argc, argv,
 #ifdef LIBWRAP
@@ -477,7 +481,7 @@
        if (argc > 0)
                CONFIG = argv[0];
 
-       if (debug == 0)
+       if (!debug)
                daemon(0, 0);
        openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON);
        pidfile(NULL);
@@ -498,26 +502,23 @@
        }
 #endif
 
-       memset(&sv, 0, sizeof(sv));
-       sv.sv_mask = SIGBLOCK;
-       sv.sv_handler = retry;
-       sigvec(SIGALRM, &sv, NULL);
-       config(SIGHUP);
-       sv.sv_handler = config;
-       sigvec(SIGHUP, &sv, NULL);
-       sv.sv_handler = reapchild;
-       sigvec(SIGCHLD, &sv, NULL);
-       sv.sv_handler = goaway;
-       sigvec(SIGTERM, &sv, NULL);
-       sv.sv_handler = goaway;
-       sigvec(SIGINT, &sv, NULL);
-       sv.sv_mask = 0L;
-       sv.sv_handler = SIG_IGN;
-       sigvec(SIGPIPE, &sv, NULL);
+       for (n = 0; n < A_CNT(my_signals); n++) {
+               (void) signal(my_signals[n], SIG_IGN);
+               ev = allocchange();
+               EV_SET(ev, my_signals[n], EVFILT_SIGNAL, EV_ADD | EV_ENABLE,
+                   0, 0, NULL);
+       }
+       (void) signal(SIGPIPE, SIG_IGN);
 
        for (;;) {
-               int             n, ctrl;
-               struct kevent   ev[256], *evp;
+               int             ctrl;
+               struct kevent   eventbuf[64];
+               struct servtab  *sep;
+
+               if (reload) {
+                       reload = 0;
+                       config();
+               }
 
                if (nsock == 0) {
                        (void) sigblock(SIGBLOCK);
@@ -525,13 +526,33 @@
                                sigpause(0L);
                        (void) sigsetmask(0L);
                }
-               n = my_kevent(NULL, 0, ev, sizeof(ev) / sizeof(ev[0]));
-               for (evp = ev; n > 0; evp++, n--) {
-                       if (evp->filter != EVFILT_READ)
+               n = my_kevent(changebuf, changes, eventbuf, A_CNT(eventbuf));
+               changes = 0;
+
+               for (ev = eventbuf; n > 0; ev++, n--) {
+                       if (ev->filter == EVFILT_SIGNAL) {
+                               switch (ev->ident) {
+                               case SIGALRM:
+                                       retry();
+                                       break;
+                               case SIGCHLD:
+                                       reapchild();
+                                       break;
+                               case SIGTERM:
+                               case SIGINT:
+                                       goaway();
+                                       break;
+                               case SIGHUP:
+                                       reload = 1;
+                                       break;
+                               }
                                continue;
-                       sep = (struct servtab *)evp->udata;
+                       }
+                       if (ev->filter != EVFILT_READ)
+                               continue;
+                       sep = (struct servtab *)ev->udata;
                        /* Paranoia */
-                       if (sep->se_fd != evp->ident)
+                       if (ev->ident != sep->se_fd)
                                continue;
                        if (debug)
                                fprintf(stderr, "someone wants %s\n", sep->se_service);
@@ -556,10 +577,8 @@
        }
 }
 
-void
-spawn(sep, ctrl)
-       struct servtab *sep;
-       int ctrl;
+static void
+spawn(struct servtab *sep, int ctrl)
 {
        int dofork;
        pid_t pid;
@@ -607,12 +626,12 @@
                        return;
                }
                if (pid != 0 && sep->se_wait) {
-                       struct kevent   ev;
+                       struct kevent   *ev;
 
                        sep->se_wait = pid;
-                       EV_SET(&ev, sep->se_fd, EVFILT_READ,
+                       ev = allocchange();
+                       EV_SET(ev, sep->se_fd, EVFILT_READ,
                            EV_DELETE, 0, 0, 0);
-                       (void) my_kevent(&ev, 1, NULL, 0);
                        nsock--;
                }
                if (pid == 0) {
@@ -634,10 +653,8 @@
                close(ctrl);
 }
 
-void
-run_service(ctrl, sep)
-       int ctrl;
-       struct servtab *sep;
+static void
+run_service(int ctrl, struct servtab *sep)
 {
        struct passwd *pwd;
        struct group *grp = NULL;       /* XXX gcc */
@@ -747,9 +764,8 @@
        }
 }
 
-void
-reapchild(signo)
-       int signo;



Home | Main Index | Thread Index | Old Index