[MAJOR] delay registering of listener sockets at startup

Some pollers such as kqueue lose their FD across fork(), meaning that
the registered file descriptors are lost too. Now when the proxies are
started by start_proxies(), the file descriptors are not registered yet,
leaving enough time for the fork() to take place and to get a new pollfd.
It will be the first call to maintain_proxies that will register them.
diff --git a/src/ev_epoll.c b/src/ev_epoll.c
index 6931a0c..e37fe0d 100644
--- a/src/ev_epoll.c
+++ b/src/ev_epoll.c
@@ -297,6 +297,21 @@
 }
 
 /*
+ * Check that the poller works.
+ * Returns 1 if OK, otherwise 0.
+ */
+REGPRM1 static int epoll_test(struct poller *p)
+{
+	int fd;
+
+	fd = epoll_create(global.maxsock + 1);
+	if (fd < 0)
+		return 0;
+	close(fd);
+	return 1;
+}
+
+/*
  * The only exported function. Returns 1.
  */
 int epoll_register(struct poller *p)
@@ -305,6 +320,7 @@
 	p->pref = 300;
 	p->private = NULL;
 
+	p->test = epoll_test;
 	p->init = epoll_init;
 	p->term = epoll_term;
 	p->poll = epoll_poll;
diff --git a/src/ev_kqueue.c b/src/ev_kqueue.c
index 3958343..3654994 100644
--- a/src/ev_kqueue.c
+++ b/src/ev_kqueue.c
@@ -198,18 +198,48 @@
 }
 
 /*
+ * Check that the poller works.
+ * Returns 1 if OK, otherwise 0.
+ */
+REGPRM1 static int kqueue_test(struct poller *p)
+{
+	int fd;
+
+	fd = kqueue();
+	if (fd < 0)
+		return 0;
+	close(fd);
+	return 1;
+}
+
+/*
+ * Recreate the kqueue file descriptor after a fork(). Returns 1 if OK,
+ * otherwise 0. Note that some pollers need to be reopened after a fork()
+ * (such as kqueue), and some others may fail to do so in a chroot.
+ */
+REGPRM1 static int kqueue_fork(struct poller *p)
+{
+	close(kqueue_fd);
+	kqueue_fd = kqueue();
+	if (kqueue_fd < 0)
+		return 0;
+	return 1;
+}
+
+/*
  * The only exported function. Returns 1.
  */
-//int kqueue_native_register(struct poller *p)
 int kqueue_register(struct poller *p)
 {
 	p->name = "kqueue";
 	p->pref = 300;
 	p->private = NULL;
 
+	p->test = kqueue_test;
 	p->init = kqueue_init;
 	p->term = kqueue_term;
 	p->poll = kqueue_poll;
+	p->fork = kqueue_fork;
 
 	p->is_set  = __fd_is_set;
 	p->cond_s = p->set = __fd_set;
diff --git a/src/ev_poll.c b/src/ev_poll.c
index 06adeb4..1dbf228 100644
--- a/src/ev_poll.c
+++ b/src/ev_poll.c
@@ -205,6 +205,15 @@
 }
 
 /*
+ * Check that the poller works.
+ * Returns 1 if OK, otherwise 0.
+ */
+REGPRM1 static int poll_test(struct poller *p)
+{
+	return 1;
+}
+
+/*
  * The only exported function. Returns 1.
  */
 int poll_register(struct poller *p)
@@ -213,6 +222,7 @@
 	p->pref = 200;
 	p->private = NULL;
 
+	p->test = poll_test;
 	p->init = poll_init;
 	p->term = poll_term;
 	p->poll = poll_poll;
diff --git a/src/ev_select.c b/src/ev_select.c
index c5dbedf..6c1a132 100644
--- a/src/ev_select.c
+++ b/src/ev_select.c
@@ -205,6 +205,15 @@
 }
 
 /*
+ * Check that the poller works.
+ * Returns 1 if OK, otherwise 0.
+ */
+REGPRM1 static int select_test(struct poller *p)
+{
+	return 1;
+}
+
+/*
  * The only exported function. Returns 1.
  */
 int select_register(struct poller *p)
@@ -213,6 +222,7 @@
 	p->pref = 150;
 	p->private = NULL;
 
+	p->test = select_test;
 	p->init = select_init;
 	p->term = select_term;
 	p->poll = select_poll;
diff --git a/src/fd.c b/src/fd.c
index 15a01cc..5ddfebd 100644
--- a/src/fd.c
+++ b/src/fd.c
@@ -10,6 +10,7 @@
  *
  */
 
+#include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -123,6 +124,75 @@
 }
 
 /*
+ * Lists the known pollers on <out>.
+ * Should be performed only before initialization.
+ */
+int list_pollers(FILE *out)
+{
+	int p;
+	int last, next;
+	int usable;
+	struct poller *bp;
+
+	fprintf(out, "Available polling systems :\n");
+
+	usable = 0;
+	bp = NULL;
+	last = next = -1;
+	while (1) {
+		for (p = 0; p < nbpollers; p++) {
+			if (!bp || (pollers[p].pref > bp->pref))
+				bp = &pollers[p];
+			if ((next < 0 || pollers[p].pref > next)
+			    && (last < 0 || pollers[p].pref < last))
+				next = pollers[p].pref;
+		}
+
+		if (next == -1)
+			break;
+
+		for (p = 0; p < nbpollers; p++) {
+			if (pollers[p].pref == next) {
+				fprintf(out, " %10s : ", pollers[p].name);
+				if (pollers[p].pref == 0)
+					fprintf(out, "disabled, ");
+				else
+					fprintf(out, "pref=%3d, ", pollers[p].pref);
+				if (pollers[p].test(&pollers[p])) {
+					fprintf(out, " test result OK");
+					if (next > 0)
+						usable++;
+				} else
+					fprintf(out, " test result FAILED");
+				fprintf(out, "\n");
+			}
+		}
+		last = next;
+		next = -1;
+	};
+	fprintf(out, "Total: %d (%d usable), will use %s.\n", nbpollers, usable, bp ? bp->name : "none");
+	return 0;
+}
+
+/*
+ * Some pollers may lose their connection after a fork(). It may be necessary
+ * to create initialize part of them again. Returns 0 in case of failure,
+ * otherwise 1. The fork() function may be NULL if unused. In case of error,
+ * the the current poller is destroyed and the caller is responsible for trying
+ * another one by calling init_pollers() again.
+ */
+int fork_poller()
+{
+	if (cur_poller.fork) {
+		if (cur_poller.fork(&cur_poller))
+			return 1;
+		cur_poller.term(&cur_poller);
+		return 0;
+	}
+	return 1;
+}
+
+/*
  * Local variables:
  *  c-indent-level: 8
  *  c-basic-offset: 8
diff --git a/src/haproxy.c b/src/haproxy.c
index 37d4b59..5ddf935 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -540,12 +540,15 @@
 
 	/* Note: we could disable any poller by name here */
 
+	if (global.mode & (MODE_VERBOSE|MODE_DEBUG))
+		list_pollers(stderr);
+
 	if (!init_pollers()) {
-		Alert("No polling mechanism available\n");
+		Alert("No polling mechanism available.\n");
 		exit(1);
 	}
-	if (global.mode & MODE_DEBUG) {
-		printf("Note: using %s() as the polling mechanism.\n", cur_poller.name);
+	if (global.mode & (MODE_VERBOSE|MODE_DEBUG)) {
+		printf("Using %s() as the polling mechanism.\n", cur_poller.name);
 	}
 
 }
@@ -909,6 +912,7 @@
 		}
 		pid = getpid(); /* update child's pid */
 		setsid();
+		fork_poller();
 	}
 
 	/*
diff --git a/src/proxy.c b/src/proxy.c
index ff3cdc7..a5431c2 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -54,9 +54,14 @@
 
 
 /*
- * this function starts all the proxies. Its return value is composed from
- * ERR_NONE, ERR_RETRYABLE and ERR_FATAL. Retryable errors will only be printed
- * if <verbose> is not zero.
+ * This function creates all proxy sockets. It should be done very early,
+ * typically before privileges are dropped. The sockets will be registered
+ * but not added to any fd_set, in order not to loose them across the fork().
+ * The proxies also start in IDLE state, meaning that it will be
+ * maintain_proxies that will finally complete their loading.
+ *
+ * Its return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL.
+ * Retryable errors will only be printed if <verbose> is not zero.
  */
 int start_proxies(int verbose)
 {
@@ -147,13 +152,12 @@
 			fdtab[fd].cb[DIR_RD].b = fdtab[fd].cb[DIR_WR].b = NULL;
 			fdtab[fd].owner = (struct task *)curproxy; /* reference the proxy instead of a task */
 			fdtab[fd].state = FD_STLISTEN;
-			EV_FD_SET(fd, DIR_RD);
 			fd_insert(fd);
 			listeners++;
 		}
 
 		if (!pxerr) {
-			curproxy->state = PR_STRUN;
+			curproxy->state = PR_STIDLE;
 			send_log(curproxy, LOG_NOTICE, "Proxy %s started.\n", curproxy->id);
 		}
 	}