mwrap (Perl version) user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
* [PATCH 0/3] more rproxy+httpd tweaks
@ 2022-12-16 22:57 Eric Wong
  2022-12-16 22:57 ` [PATCH 1/3] rproxy: manpage updates Eric Wong
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Eric Wong @ 2022-12-16 22:57 UTC (permalink / raw)
  To: mwrap-perl

Stale sockets are ugly, some mitigations to deal with them

Eric Wong (3):
  rproxy: manpage updates
  httpd: more thorough unlinking of stale sockets
  rproxy: more thorough connectivity check

 httpd.h                   | 51 ++++++++++++++++++++++++---------------
 lib/Devel/Mwrap/Rproxy.pm | 10 +++++---
 mwrap_core.h              |  3 +--
 script/mwrap-rproxy       |  9 ++++++-
 4 files changed, 47 insertions(+), 26 deletions(-)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] rproxy: manpage updates
  2022-12-16 22:57 [PATCH 0/3] more rproxy+httpd tweaks Eric Wong
@ 2022-12-16 22:57 ` Eric Wong
  2022-12-16 22:57 ` [PATCH 2/3] httpd: more thorough unlinking of stale sockets Eric Wong
  2022-12-16 22:57 ` [PATCH 3/3] rproxy: more thorough connectivity check Eric Wong
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2022-12-16 22:57 UTC (permalink / raw)
  To: mwrap-perl

Fix the comment regarding --no-deflate and describe PLACK_ENV, too.
---
 script/mwrap-rproxy | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/script/mwrap-rproxy b/script/mwrap-rproxy
index da5379a..af5bdf9 100644
--- a/script/mwrap-rproxy
+++ b/script/mwrap-rproxy
@@ -74,7 +74,7 @@ environment (see L<mwrap-perl(1p)>).
 =item --no-deflate
 
 L<Plack::Middleware::Deflater(3pm)> is loaded by default if available.
-Using C<--no-deflate> will save CPU cycles at the expe
+Using C<--no-deflate> will save CPU cycles at the expense of bandwidth.
 
 =back
 
@@ -87,6 +87,8 @@ mwrap-rproxy supports systemd (and compatible) socket activation via
 C<LISTEN_PID> and C<LISTEN_FDS> variables.  See L<systemd.socket(5)>
 and L<sd_listen_fds(3)>.
 
+C<PLACK_ENV> is also supported as described by L<plackup(1p)>
+
 =head1 CONTACT
 
 Feedback welcome via plain-text mail to L<mailto:mwrap-perl@80x24.org>

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] httpd: more thorough unlinking of stale sockets
  2022-12-16 22:57 [PATCH 0/3] more rproxy+httpd tweaks Eric Wong
  2022-12-16 22:57 ` [PATCH 1/3] rproxy: manpage updates Eric Wong
@ 2022-12-16 22:57 ` Eric Wong
  2022-12-16 22:57 ` [PATCH 3/3] rproxy: more thorough connectivity check Eric Wong
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2022-12-16 22:57 UTC (permalink / raw)
  To: mwrap-perl

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

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] rproxy: more thorough connectivity check
  2022-12-16 22:57 [PATCH 0/3] more rproxy+httpd tweaks Eric Wong
  2022-12-16 22:57 ` [PATCH 1/3] rproxy: manpage updates Eric Wong
  2022-12-16 22:57 ` [PATCH 2/3] httpd: more thorough unlinking of stale sockets Eric Wong
@ 2022-12-16 22:57 ` Eric Wong
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Wong @ 2022-12-16 22:57 UTC (permalink / raw)
  To: mwrap-perl

Sometimes, stale sockets can stick around and the PID gets
recycled by a different process, so ensure we can actually
connect to it before listing it.
---
 lib/Devel/Mwrap/Rproxy.pm | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/lib/Devel/Mwrap/Rproxy.pm b/lib/Devel/Mwrap/Rproxy.pm
index 76b7d7f..6db72e6 100644
--- a/lib/Devel/Mwrap/Rproxy.pm
+++ b/lib/Devel/Mwrap/Rproxy.pm
@@ -41,11 +41,15 @@ sub list {
 	open(my $fh, '+>', \(my $str)) or die "open: $!";
 	print $fh '<html><head><title>', $t, '</title></head><body><pre>', $t,
 		"\n\n";
-	opendir(my $dh, $self->{socket_dir}) or return r(500, "socket_dir: $!");
-	my @pids = grep(/\A[0-9]+\.sock\z/, readdir($dh));
-	for (@pids) {
+	my $dir = $self->{socket_dir};
+	opendir(my $dh, $dir) or return r(500, "socket_dir: $!");
+	my @socks = grep(/\A[0-9]+\.sock\z/, readdir($dh));
+	my %o = (Type => SOCK_STREAM, Peer => undef);
+	for (@socks) {
+		$o{Peer} = "$dir/$_";
 		substr($_, -5, 5, ''); # chop off .sock
 		my $cmd = $valid_pid->($_) // next;
+		my $c = IO::Socket::UNIX->new(%o) // next;
 		print $fh qq(<a\nhref="./$_/">$_</a>/);
 		$_ .= '/each/2000';
 		say $fh qq(<a\nhref="./), $_, qq(">each/2000</a>\t), $cmd;

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-12-16 22:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-16 22:57 [PATCH 0/3] more rproxy+httpd tweaks Eric Wong
2022-12-16 22:57 ` [PATCH 1/3] rproxy: manpage updates Eric Wong
2022-12-16 22:57 ` [PATCH 2/3] httpd: more thorough unlinking of stale sockets Eric Wong
2022-12-16 22:57 ` [PATCH 3/3] rproxy: more thorough connectivity check Eric Wong

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mwrap-perl.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).