From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-2.7 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF, UNWANTED_LANGUAGE_BODY shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 1867E1F61C for ; Fri, 16 Dec 2022 22:56:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1671231419; bh=r7yfuPkdBWEL91SkByD9+6K/gmMddTnYjAN8q4+ArPc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=FDn5+14i2tGi3/ad+v64FrJWeA46mQ9sWz+u/ks6LkeBAl6OtRrYQhKGgXqrirGe/ LG2oV/iPBnEGTJeNhQtVzpkWY5qKxaY7hZpjsv686wlXNjXKX8KDP0t+IiIsm01D2U G6/s2Eb5u1Mfl6NeUfk6pkuMOhpqB4y4gxHzYao8= From: Eric Wong To: mwrap-perl@80x24.org Subject: [PATCH 2/3] httpd: more thorough unlinking of stale sockets Date: Fri, 16 Dec 2022 22:57:53 +0000 Message-Id: <20221216225754.96103-3-mwrap-perl@80x24.org> In-Reply-To: <20221216225754.96103-1-mwrap-perl@80x24.org> References: <20221216225754.96103-1-mwrap-perl@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Lets try not to leave stale sockets lying around since they can eat away at inode space. --- httpd.h | 51 +++++++++++++++++++++++++++------------------ mwrap_core.h | 3 +-- script/mwrap-rproxy | 5 +++++ 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/httpd.h b/httpd.h index afce2a1..8e58286 100644 --- a/httpd.h +++ b/httpd.h @@ -1130,6 +1130,31 @@ static void h1d_event_step(struct mw_h1d *h1d) non_fatal_pause(fail_fn); } +static void h1d_unlink(struct mw_h1d *h1d, bool do_close) +{ + union mw_sockaddr sa; + socklen_t len = (socklen_t)sizeof(sa); + + if (h1d->lfd < 0 || !h1d->pid_len) + return; + if (getsockname(h1d->lfd, &sa.any, &len) < 0) { + fprintf(stderr, "getsockname: %m\n"); + return; + } + if (do_close) { /* only safe to close if thread isn't running */ + (void)close(h1d->lfd); + h1d->lfd = -1; + } + + char p[sizeof(h1d->pid_str)]; + int rc = snprintf(p, sizeof(p), "%d", (int)getpid()); + + if (rc == (int)h1d->pid_len && !memcmp(p, h1d->pid_str, rc)) + if (unlink(sa.un.sun_path) && errno != ENOENT) + fprintf(stderr, "unlink(%s): %m\n", sa.un.sun_path); + h1d->pid_len = 0; +} + /* @env is getenv("MWRAP") */ static int h1d_init(struct mw_h1d *h1d, const char *menv) { @@ -1175,7 +1200,7 @@ static int h1d_init(struct mw_h1d *h1d, const char *menv) return fprintf(stderr, "we suck at snprintf: %m\n"); h1d->pid_len = rc - sizeof(".sock") + 1; memcpy(h1d->pid_str, p, h1d->pid_len); - if (unlink(sa.un.sun_path) < 0 && errno != ENOENT) + if (unlink(sa.un.sun_path) && errno != ENOENT) return fprintf(stderr, "unlink(%s): %m\n", sa.un.sun_path); h1d->lfd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (h1d->lfd < 0) @@ -1193,8 +1218,7 @@ static int h1d_init(struct mw_h1d *h1d, const char *menv) CDS_INIT_LIST_HEAD(&h1d->conn); return 0; close_fail: - close(h1d->lfd); - h1d->lfd = -1; + h1d_unlink(h1d, true); return 1; } @@ -1269,19 +1293,7 @@ static void *h1d_run(void *x) /* pthread_create cb */ static void h1d_atexit(void) { - union mw_sockaddr sa; - socklen_t len = (socklen_t)sizeof(sa); - - if (g_h1d.lfd < 0 || !g_h1d.pid_len) - return; - if (getsockname(g_h1d.lfd, &sa.any, &len) < 0) - return; - - char p[sizeof(g_h1d.pid_str)]; - int rc = snprintf(p, sizeof(p), "%d", (int)getpid()); - - if (rc == (int)g_h1d.pid_len && !memcmp(p, g_h1d.pid_str, rc)) - unlink(sa.un.sun_path); + h1d_unlink(&g_h1d, false); } static void h1d_stop_join(struct mw_h1d *h1d) @@ -1321,8 +1333,7 @@ join_thread: fprintf(stderr, "BUG? pthread_join: %s\n", strerror(e)); abort(); } - (void)close(h1d->lfd); - h1d->lfd = -1; + h1d_unlink(h1d, true); } static void h1d_atfork_prepare(void) @@ -1337,9 +1348,9 @@ static void h1d_start(void) /* may be called as pthread_atfork child cb */ int rc = pthread_create(&g_h1d.tid, NULL, h1d_run, &g_h1d); if (rc) { /* non-fatal */ fprintf(stderr, "pthread_create: %s\n", strerror(rc)); - (void)close(g_h1d.lfd); - g_h1d.lfd = -1; g_h1d.alive = 0; + g_h1d.running = 0; + h1d_unlink(&g_h1d, true); } } } diff --git a/mwrap_core.h b/mwrap_core.h index 9e4f065..7681ca5 100644 --- a/mwrap_core.h +++ b/mwrap_core.h @@ -843,8 +843,7 @@ static struct src_loc *src_loc_lookup(const char *str, size_t len) # define O_CLOEXEC 0 #endif static void h1d_atexit(void); -__attribute__ ((destructor)) -static void dump_destructor(void) +__attribute__ ((destructor)) static void mwrap_dtor(void) { const char *opt = getenv("MWRAP"); const char *modes[] = { "a", "a+", "w", "w+", "r+" }; diff --git a/script/mwrap-rproxy b/script/mwrap-rproxy index af5bdf9..96e203e 100644 --- a/script/mwrap-rproxy +++ b/script/mwrap-rproxy @@ -34,6 +34,11 @@ Inherited socket (fd=3) is non-blocking, making it blocking. if ($opt{deflate} && eval { require Plack::Middleware::Deflater } and !$@) { $app = Plack::Middleware::Deflater->wrap($app); } + +# ensure mwrap_dtor() runs if running under mwrap-perl, ourselves +sub sigexit { exit 0 } +$SIG{$_} = \&sigexit for (qw(INT TERM)); + $runner->run($app); __END__ =head1 NAME