r4648 - trunk/varnish-cache/bin/varnishd

phk at varnish-cache.org phk at varnish-cache.org
Thu Apr 8 10:09:44 CEST 2010


Author: phk
Date: 2010-04-08 10:09:43 +0200 (Thu, 08 Apr 2010)
New Revision: 4648

Modified:
   trunk/varnish-cache/bin/varnishd/mgt.h
   trunk/varnish-cache/bin/varnishd/mgt_child.c
   trunk/varnish-cache/bin/varnishd/mgt_cli.c
   trunk/varnish-cache/bin/varnishd/mgt_vcc.c
   trunk/varnish-cache/bin/varnishd/varnishd.c
Log:
We clean the child process of unwanted open filedescriptors, but this can
take time if there are hundreds of thousands of possible filedescriptors.

Instead do it once, right at startup in the manager process, and then
keep track of the fd's we use there, and have the child clean only
up to the max seen, with an allowance for filedescriptors held by
libraries (syslog, resolver, pidfiles etc)

Fixes	#699



Modified: trunk/varnish-cache/bin/varnishd/mgt.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt.h	2010-04-08 07:35:23 UTC (rev 4647)
+++ trunk/varnish-cache/bin/varnishd/mgt.h	2010-04-08 08:09:43 UTC (rev 4648)
@@ -46,6 +46,7 @@
 extern pid_t child_pid;
 void MGT_Run(void);
 void mgt_stop_child(void);
+void mgt_got_fd(int fd);
 
 /* mgt_cli.c */
 

Modified: trunk/varnish-cache/bin/varnishd/mgt_child.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_child.c	2010-04-08 07:35:23 UTC (rev 4647)
+++ trunk/varnish-cache/bin/varnishd/mgt_child.c	2010-04-08 08:09:43 UTC (rev 4648)
@@ -71,6 +71,7 @@
 
 pid_t		child_pid = -1;
 
+
 static struct vbitmap	*fd_map;
 
 static int		child_cli_in = -1;
@@ -98,6 +99,33 @@
 static struct vlu	*vlu;
 
 /*--------------------------------------------------------------------
+ * Track the highest file descriptor the parent knows is being used.
+ *
+ * This allows the child process to clean/close only a small fraction 
+ * of the possible file descriptors after exec(2).
+ *
+ * This is likely to a bit on the low side, as libc and other libraries
+ * has a tendency to cache file descriptors (syslog, resolver, etc.)
+ * so we add a margin of 100 fds.
+ */
+
+static int		mgt_max_fd;
+
+#define CLOSE_FD_UP_TO	(mgt_max_fd + 100)
+
+void
+mgt_got_fd(int fd)
+{
+	/*
+	 * Assert > 0, to catch bogus opens, we know where stdin goes
+	 * in the master process.
+	 */
+	assert(fd > 0);
+	if (fd > mgt_max_fd)
+		mgt_max_fd = fd;
+}
+
+/*--------------------------------------------------------------------
  * A handy little function
  */
 
@@ -270,7 +298,7 @@
 	unsigned u;
 	char *p;
 	struct vev *e;
-	int i, j, cp[2];
+	int i, cp[2];
 
 	if (child_state != CH_STOPPED && child_state != CH_DIED)
 		return;
@@ -337,13 +365,10 @@
 
 		/* Close anything we shouldn't know about */
 		closelog();
-		printf("Closed fds:");
-		j = getdtablesize();
-		for (i = STDERR_FILENO + 1; i < j; i++) {
+		for (i = STDERR_FILENO + 1; i < CLOSE_FD_UP_TO; i++) {
 			if (vbit_test(fd_map, i))
 				continue;
-			if (close(i) == 0)
-				printf(" %d", i);
+			(void)(close(i) == 0);
 		}
 		printf("\n");
 

Modified: trunk/varnish-cache/bin/varnishd/mgt_cli.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_cli.c	2010-04-08 07:35:23 UTC (rev 4647)
+++ trunk/varnish-cache/bin/varnishd/mgt_cli.c	2010-04-08 08:09:43 UTC (rev 4648)
@@ -301,6 +301,7 @@
 		cli_result(cli, CLIS_CANT);
 		return;
 	}
+	mgt_got_fd(fd);
 	CLI_response(fd, cli->challenge, buf);
 	AZ(close(fd));
 	if (strcasecmp(buf, av[2])) {
@@ -488,6 +489,7 @@
 	if (i < 0)
 		return (0);
 
+	mgt_got_fd(i);
 	tn = telnet_new(i);
 	vsb = sock_id("telnet", i);
 	mgt_cli_setup(i, i, 0, vsb_data(vsb), telnet_close, tn);
@@ -508,6 +510,7 @@
 		fprintf(stderr, "Can not open secret-file \"%s\"\n", S_arg);
 		exit (2);
 	}
+	mgt_got_fd(fd);
 	i = read(fd, buf, sizeof buf);
 	if (i == 0) {
 		fprintf(stderr, "Empty secret-file \"%s\"\n", S_arg);
@@ -623,6 +626,8 @@
 	if (s < 0)
 		return (0);
 
+	mgt_got_fd(s);
+
 	M_conn = vev_new();
 	AN(M_conn);
 	M_conn->callback = Marg_poker;

Modified: trunk/varnish-cache/bin/varnishd/mgt_vcc.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_vcc.c	2010-04-08 07:35:23 UTC (rev 4647)
+++ trunk/varnish-cache/bin/varnishd/mgt_vcc.c	2010-04-08 08:09:43 UTC (rev 4648)
@@ -164,6 +164,7 @@
 		fprintf(stderr, "Cannot open %s", vp->sf);
 		exit (1);
 	}
+	mgt_got_fd(fd);
 	l = strlen(csrc);
 	i = write(fd, csrc, l);
 	if (i != l) {

Modified: trunk/varnish-cache/bin/varnishd/varnishd.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/varnishd.c	2010-04-08 07:35:23 UTC (rev 4647)
+++ trunk/varnish-cache/bin/varnishd/varnishd.c	2010-04-08 08:09:43 UTC (rev 4648)
@@ -424,6 +424,15 @@
 	struct pidfh *pfh = NULL;
 	char dirname[1024];
 
+	/*
+	 * Start out by closing all unwanted file descriptors we might
+	 * have inherited from sloppy process control daemons.
+	 */
+	for (o = getdtablesize(); o > STDERR_FILENO; o--)
+		(void)close(o);
+
+	mgt_got_fd(STDERR_FILENO);
+
 	setbuf(stdout, NULL);
 	setbuf(stderr, NULL);
 




More information about the varnish-commit mailing list