r6 - trunk

des at projects.linpro.no des at projects.linpro.no
Fri Feb 10 17:05:32 CET 2006


Author: des
Date: 2006-02-10 17:05:32 +0100 (Fri, 10 Feb 2006)
New Revision: 6

Added:
   trunk/log.h
   trunk/system-common.c
   trunk/system-linux-gnu.c
   trunk/system.h
Modified:
   trunk/Makefile.am
   trunk/configure.ac
   trunk/connection.c
   trunk/connection.h
   trunk/listener.c
   trunk/listener.h
   trunk/log.c
   trunk/request.c
   trunk/request.h
   trunk/varnish.c
   trunk/varnish.h
Log:
Disentangle listener and connection, allowing the struct definitions to move
out of the headers into the code, reducing header dependencies.
Add code to detect the number of CPU cores on Linux.
Fork as many listening child processes as we have CPU cores.
Add timestamps and the current PID to log messages.

Modified: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/Makefile.am	2006-02-10 16:05:32 UTC (rev 6)
@@ -7,4 +7,6 @@
 	listener.c \
 	log.c \
 	request.c \
+	system-common.c \
+	system- at target_os@.c \
 	varnish.c

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/configure.ac	2006-02-10 16:05:32 UTC (rev 6)
@@ -35,6 +35,8 @@
 
 # Checks for header files.
 AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_HEADER_TIME
 AC_CHECK_HEADERS([sys/socket.h])
 AC_CHECK_HEADERS([netinet/in.h])
 AC_CHECK_HEADERS([stddef.h])

Modified: trunk/connection.c
===================================================================
--- trunk/connection.c	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/connection.c	2006-02-10 16:05:32 UTC (rev 6)
@@ -11,8 +11,66 @@
 #include <unistd.h>
 
 #include "varnish.h"
+#include "log.h"
 #include "connection.h"
 
+struct connection {
+	int sd;
+	struct sockaddr_storage addr;
+};
+
+/*
+ * Accepts a connection from the provided listening descriptor.  Does not
+ * loop to handle EINTR or other similar conditions.
+ */
+connection_t *
+connection_accept(int ld)
+{
+	connection_t *c;
+	socklen_t len;
+
+	if ((c = calloc(1, sizeof *c)) == NULL)
+		return (NULL);
+
+	len = sizeof c->addr;
+	if ((c->sd = accept(ld, (struct sockaddr *)&c->addr, &len)) == -1) {
+		free(c);
+		return (NULL);
+	}
+	switch (c->addr.ss_family) {
+#if defined(AF_INET6)
+	case AF_INET6: {
+		struct sockaddr_in6 *addr =
+		    (struct sockaddr_in6 *)&c->addr;
+		uint16_t *ip = (uint16_t *)&addr->sin6_addr;
+
+		log_info("%s(): [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]:%u",
+		    __func__,
+		    ntohs(ip[0]), ntohs(ip[1]),
+		    ntohs(ip[2]), ntohs(ip[3]),
+		    ntohs(ip[4]), ntohs(ip[5]),
+		    ntohs(ip[6]), ntohs(ip[7]),
+		    ntohs(addr->sin6_port));
+		break;
+	}
+#endif
+	case AF_INET: {
+		struct sockaddr_in *addr =
+		    (struct sockaddr_in *)&c->addr;
+		uint8_t *ip = (uint8_t *)&addr->sin_addr;
+
+		log_info("%s(): %u.%u.%u.%u:%u",
+		    __func__,
+		    ip[0], ip[1], ip[2], ip[3],
+		    ntohs(addr->sin_port));
+		break;
+	}
+	default:
+		LOG_UNREACHABLE();
+	}
+	return (c);
+}
+
 void
 connection_destroy(struct connection *c)
 {

Modified: trunk/connection.h
===================================================================
--- trunk/connection.h	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/connection.h	2006-02-10 16:05:32 UTC (rev 6)
@@ -5,9 +5,9 @@
 #ifndef CONNECTION_H_INCLUDED
 #define CONNECTION_H_INCLUDED
 
-struct connection {
-	int sd;
-	struct sockaddr_storage addr;
-};
+typedef struct connection connection_t;
 
+connection_t *connection_accept(int ld);
+void connection_destroy(connection_t *c);
+
 #endif

Modified: trunk/listener.c
===================================================================
--- trunk/listener.c	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/listener.c	2006-02-10 16:05:32 UTC (rev 6)
@@ -13,9 +13,15 @@
 #include <unistd.h>
 
 #include "varnish.h"
-#include "listener.h"
 #include "connection.h"
+#include "listener.h"
+#include "log.h"
 
+struct listener {
+	int sd;
+	struct sockaddr_storage addr;
+};
+
 /*
  * Create a socket that listens on the specified port.  We use an IPv6 TCP
  * socket and clear the IPV6_V6ONLY option to accept IPv4 connections on
@@ -83,50 +89,14 @@
 	free(l);
 }
 
-struct connection *
+connection_t *
 listener_accept(struct listener *l)
 {
-	struct connection *c;
-	socklen_t len;
+	connection_t *c;
 
-	c = calloc(1, sizeof *c);
 	for (;;) {
-		len = sizeof c->addr;
-		c->sd = accept(l->sd, (struct sockaddr *)&c->addr, &len);
-		if (c->sd != -1) {
-			switch (c->addr.ss_family) {
-#if defined(AF_INET6)
-			case AF_INET6: {
-				struct sockaddr_in6 *addr =
-				    (struct sockaddr_in6 *)&c->addr;
-				uint16_t *ip = (uint16_t *)&addr->sin6_addr;
-
-				log_info("%s(): [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]:%u",
-				    __func__,
-				    ntohs(ip[0]), ntohs(ip[1]),
-				    ntohs(ip[2]), ntohs(ip[3]),
-				    ntohs(ip[4]), ntohs(ip[5]),
-				    ntohs(ip[6]), ntohs(ip[7]),
-				    ntohs(addr->sin6_port));
-				break;
-			}
-#endif
-			case AF_INET: {
-				struct sockaddr_in *addr =
-				    (struct sockaddr_in *)&c->addr;
-				uint8_t *ip = (uint8_t *)&addr->sin_addr;
-
-				log_info("%s(): %u.%u.%u.%u:%u",
-				    __func__,
-				    ip[0], ip[1], ip[2], ip[3],
-				    ntohs(addr->sin_port));
-				break;
-			}
-			default:
-				LOG_UNREACHABLE();
-			}
+		if ((c = connection_accept(l->sd)) != NULL)
 			return (c);
-		}
 		if (errno != EINTR) {
 			log_syserr("accept()");
 			free(c);

Modified: trunk/listener.h
===================================================================
--- trunk/listener.h	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/listener.h	2006-02-10 16:05:32 UTC (rev 6)
@@ -5,9 +5,12 @@
 #ifndef LISTENER_H_INCLUDED
 #define LISTENER_H_INCLUDED
 
-struct listener {
-	int sd;
-	struct sockaddr_storage addr;
-};
+#include "connection.h"
 
+typedef struct listener listener_t;
+
+listener_t *listener_create(int port);
+void listener_destroy(listener_t *l);
+connection_t *listener_accept(listener_t *l);
+
 #endif

Modified: trunk/log.c
===================================================================
--- trunk/log.c	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/log.c	2006-02-10 16:05:32 UTC (rev 6)
@@ -2,20 +2,41 @@
  * $Id$
  */
 
+#include <sys/types.h>
 #include <sys/signal.h>
+#include <sys/time.h>
 
 #include <errno.h>
 #include <signal.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
 #include <unistd.h>
 
 #include "varnish.h"
+#include "log.h"
+#include "system.h"
 
 static void
+timestamp(void)
+{
+	struct timeval now;
+
+	if (gettimeofday(&now, NULL) == -1)
+		now.tv_sec = now.tv_usec = 0;
+	fprintf(stderr, "%lu.%06lu [%lu] ",
+	    (unsigned long)now.tv_sec,
+	    (unsigned long)now.tv_usec,
+	    (unsigned long)sys.pid);
+}
+
+static void
 emit(const char *fmt, va_list ap)
 {
+	timestamp();
 	vfprintf(stderr, fmt, ap);
 	fprintf(stderr, "\n");
 }
@@ -30,6 +51,7 @@
 #else
 	snprintf(errstr, sizeof errstr, "%s", strerror(errno));
 #endif
+	timestamp();
 	vfprintf(stderr, fmt, ap);
 	fprintf(stderr, ": %s\n", errstr);
 }

Added: trunk/log.h
===================================================================
--- trunk/log.h	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/log.h	2006-02-10 16:05:32 UTC (rev 6)
@@ -0,0 +1,19 @@
+/*
+ * $Id$
+ */
+
+#ifndef LOG_H_INCLUDED
+#define LOG_H_INCLUDED
+
+
+void log_info(const char *fmt, ...);
+void log_err(const char *fmt, ...);
+void log_syserr(const char *fmt, ...);
+void log_panic(const char *fmt, ...);
+void log_syspanic(const char *fmt, ...);
+
+#define LOG_UNREACHABLE() \
+	log_panic("%s(%d): %s(): unreachable code reached", \
+	    __FILE__, __LINE__, __func__)
+
+#endif

Modified: trunk/request.c
===================================================================
--- trunk/request.c	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/request.c	2006-02-10 16:05:32 UTC (rev 6)
@@ -5,8 +5,14 @@
 #include <stdlib.h>
 
 #include "varnish.h"
+#include "connection.h"
+#include "log.h"
 #include "request.h"
 
+struct request {
+	connection_t *conn;
+};
+
 request_t *
 request_wait(connection_t *c, unsigned int timeout)
 {

Modified: trunk/request.h
===================================================================
--- trunk/request.h	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/request.h	2006-02-10 16:05:32 UTC (rev 6)
@@ -5,8 +5,9 @@
 #ifndef REQUEST_H_INCLUDED
 #define REQUEST_H_INCLUDED
 
-struct request {
-	struct connection *conn;
-};
+typedef struct request request_t;
 
+request_t *request_wait(connection_t *c, unsigned int timeout);
+void request_destroy(request_t *r);
+
 #endif

Added: trunk/system-common.c
===================================================================
--- trunk/system-common.c	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/system-common.c	2006-02-10 16:05:32 UTC (rev 6)
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ */
+
+#include <sys/types.h>
+
+#include <unistd.h>
+
+#include "varnish.h"
+#include "system.h"
+
+system_t sys;
+
+/*
+ * gather system information at startup
+ */
+void
+system_init(void)
+{
+	sys.pid = getpid();
+	system_init_ncpu();
+}
+
+/*
+ * fork() wrapper, updates sys.pid
+ */
+pid_t
+system_fork(void)
+{
+	pid_t pid;
+
+	if ((pid = fork()) == 0)
+		sys.pid = getpid();
+	return (pid);
+}


Property changes on: trunk/system-common.c
___________________________________________________________________
Name: svn:keywords
   + Id

Added: trunk/system-linux-gnu.c
===================================================================
--- trunk/system-linux-gnu.c	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/system-linux-gnu.c	2006-02-10 16:05:32 UTC (rev 6)
@@ -0,0 +1,31 @@
+/*
+ * $Id$
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#include "varnish.h"
+#include "log.h"
+#include "system.h"
+
+void
+system_init_ncpu(void)
+{
+	FILE *cpuinfo;
+	char line[256];
+	int n;
+
+	sys.ncpu = 0;
+	if ((cpuinfo = fopen("/proc/cpuinfo", "r")) == NULL)
+		return;
+	while (fgets(line, sizeof line, cpuinfo) != NULL) {
+		if (sscanf(line, "processor : %d", &n) == 1)
+			sys.ncpu++;
+	}
+	fclose(cpuinfo);
+	if (sys.ncpu == 0)
+		sys.ncpu = 1;
+	log_info("%d cpu(s)", sys.ncpu);
+}


Property changes on: trunk/system-linux-gnu.c
___________________________________________________________________
Name: svn:keywords
   + Id

Added: trunk/system.h
===================================================================
--- trunk/system.h	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/system.h	2006-02-10 16:05:32 UTC (rev 6)
@@ -0,0 +1,21 @@
+/*
+ * $Id$
+ */
+
+#ifndef SYSTEM_H_INCLUDED
+#define SYSTEM_H_INCLUDED
+
+typedef struct system system_t;
+
+struct system {
+	int ncpu;
+	pid_t pid;
+};
+
+extern system_t sys;
+
+void system_init_ncpu(void);
+void system_init(void);
+pid_t system_fork(void);
+
+#endif


Property changes on: trunk/system.h
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: trunk/varnish.c
===================================================================
--- trunk/varnish.c	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/varnish.c	2006-02-10 16:05:32 UTC (rev 6)
@@ -2,29 +2,70 @@
  * $Id$
  */
 
+#include <sys/wait.h>
+
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 
 #include "varnish.h"
+#include "connection.h"
+#include "listener.h"
+#include "log.h"
+#include "request.h"
+#include "system.h"
 
 static void
-varnish(void)
+varnish_child(listener_t *l)
 {
-	listener_t *l;
 	connection_t *c;
 	request_t *r;
 
-	l = listener_create(8080);
 	while ((c = listener_accept(l)) != NULL) {
 		r = request_wait(c, 0);
 		/* ... */
 		request_destroy(r);
 		connection_destroy(c);
 	}
+	LOG_UNREACHABLE();
 }
 
 static void
+varnish(void)
+{
+	listener_t *l;
+	int i, status;
+	pid_t pid;
+
+	system_init();
+	log_info("starting Varnish");
+	l = listener_create(8080);
+	for (i = 0; i < sys.ncpu; ++i) {
+		switch ((pid = system_fork())) {
+		case -1:
+			log_panic("fork()");
+			break;
+		case 0:
+			varnish_child(l);
+			_exit(1);
+			break;
+		default:
+			log_info("forked child %lu", (unsigned long)pid);
+			break;
+		}
+	}
+	for (;;) {
+		if ((pid = wait(&status)) == -1) {
+			if (errno == ECHILD)
+				return;
+		} else {
+			log_info("child %lu exited", (unsigned long)pid);
+		}
+	}
+}
+
+static void
 usage(void)
 {
 	fprintf(stderr, "usage: varnish\n");
@@ -50,6 +91,5 @@
 
 	varnish();
 
-	LOG_UNREACHABLE();
 	exit(1);
 }

Modified: trunk/varnish.h
===================================================================
--- trunk/varnish.h	2006-02-10 16:05:07 UTC (rev 5)
+++ trunk/varnish.h	2006-02-10 16:05:32 UTC (rev 6)
@@ -7,32 +7,4 @@
 
 #include "config.h"
 
-/* opaque structures */
-typedef struct listener listener_t;
-typedef struct connection connection_t;
-typedef struct request request_t;
-
-/* connection.c */
-void connection_destroy(connection_t *c);
-
-/* listener.c */
-listener_t *listener_create(int port);
-void listener_destroy(listener_t *l);
-connection_t *listener_accept(listener_t *l);
-
-/* log.c */
-void log_info(const char *fmt, ...);
-void log_err(const char *fmt, ...);
-void log_syserr(const char *fmt, ...);
-void log_panic(const char *fmt, ...);
-void log_syspanic(const char *fmt, ...);
-
-#define LOG_UNREACHABLE() \
-	log_panic("%s(%d): %s(): unreachable code reached", \
-	    __FILE__, __LINE__, __func__)
-
-/* request.c */
-request_t *request_wait(connection_t *c, unsigned int timeout);
-void request_destroy(request_t *r);
-
 #endif




More information about the varnish-commit mailing list