* released 1.1.27
* the configurable HTTP health check introduced in 1.1.23 revealed a shameful
bug : the code still assumed that HTTP requests were the same size as the
original ones (22 bytes), and failed if they were not.
* added support for pidfiles.
diff --git a/CHANGELOG b/CHANGELOG
index 2efba80..c3c2046 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,12 @@
ChangeLog :
===========
+2003/10/27 : 1.1.27
+ - the configurable HTTP health check introduced in 1.1.23 revealed a shameful
+ bug : the code still assumed that HTTP requests were the same size as the
+ original ones (22 bytes), and failed if they were not.
+ - added support for pidfiles.
+
2003/10/22 : 1.1.26
- the fix introduced in 1.1.25 for client timeouts while waiting for servers
broke almost all compatibility with POST requests, because the proxy
diff --git a/doc/haproxy-en.txt b/doc/haproxy-en.txt
index a4bbf01..ad82521 100644
--- a/doc/haproxy-en.txt
+++ b/doc/haproxy-en.txt
@@ -1,9 +1,9 @@
H A - P r o x y
---------------
- version 1.1.25
+ version 1.1.27
willy tarreau
- 2003/10/15
+ 2003/10/27
============
| Abstract |
@@ -35,6 +35,8 @@
-N <high limit for the per-proxy number of simultaneous connections>
-d starts in foregreound with debugging mode enabled
-D starts in daemon mode
+ -p <pidfile> asks the process to write down each of its children's
+ pids to this file in daemon mode.
-s shows statistics (only if compiled in)
-l shows even more statistics (implies '-s')
@@ -92,6 +94,7 @@
- daemon
- debug
- quiet
+ - pidfile <file>
1.1) Event logging
------------------
@@ -231,6 +234,28 @@
nbproc 2
+1.6) Helping process management
+-------------------------------
+Haproxy now supports the notion of pidfile. If the '-p' command line argument,
+or the 'pidfile' global option is followed with a file name, this file will be
+removed, then filled with all children's pids, one per line (only in daemon
+mode). This file is NOT within the chroot, which allows to work with a readonly
+ chroot. It will be owned by the user starting the process, and will have
+permissions 0644.
+
+Example :
+---------
+
+ global
+ daemon
+ quiet
+ nbproc 2
+ pidfile /var/run/haproxy-private.pid
+
+ # to stop only those processes among others :
+ # kill $(</var/run/haproxy-private.pid)
+
+
2) Declaration of a listening service
=====================================
diff --git a/doc/haproxy-fr.txt b/doc/haproxy-fr.txt
index 596531d..f1b08e8 100644
--- a/doc/haproxy-fr.txt
+++ b/doc/haproxy-fr.txt
@@ -1,9 +1,9 @@
H A - P r o x y
---------------
- version 1.1.25
+ version 1.1.27
willy tarreau
- 2003/10/15
+ 2003/10/27
================
| Introduction |
@@ -37,6 +37,8 @@
-N <nombre maximal de connexions simultanées par proxy>
-d active le mode debug
-D passe en daemon
+ -p <fichier> indique au processus père qu'il doit écrire les PIDs de ses
+ fils dans ce fichier en mode démon.
-s affiche les statistiques (si option compilée)
-l ajoute des informations aux statistiques
@@ -95,6 +97,7 @@
- daemon
- debug
- quiet
+ - pidfile <fichier>
1.1) Journalisation des événements
----------------------------------
@@ -199,7 +202,7 @@
gid 30000
chroot /var/chroot/haproxy
-1.4) modes de fonctionnement
+1.4) Modes de fonctionnement
----------------------------
Le service peut fonctionner dans plusieurs modes :
- avant- / arrière-plan
@@ -222,7 +225,7 @@
entre les clients et les serveurs. Ce mode est incompatible avec les options
'daemon' et 'quiet' pour des raisons de bon sens.
-1.5) accroissement de la capacité de traitement
+1.5) Accroissement de la capacité de traitement
-----------------------------------------------
Sur des machines multi-processeurs, il peut sembler gâché de n'utiliser qu'un
processeur pour effectuer les tâches de relayage, même si les charges
@@ -241,6 +244,29 @@
quiet
nbproc 2
+1.6) Simplification de la gestion des processus
+-----------------------------------------------
+Haproxy supporte dorénavant la notion de fichiers de pid (-> pidfiles). Si le
+paramètre '-p' de ligne de commande, ou l'option globale 'pidfile' sont suivis
+d'un nom de fichier, alors ce fichier sera supprimé puis recréé et contiendra
+le numéro de PID des processus fils, à raison d'un par ligne (valable
+uniquement en mode démon). Ce fichier n'est PAS relatif au cloisonnement chroot
+afin de rester compatible avec un répertoire protégé en lecture seule. Il
+appartiendra à l'utilisateur ayant lancé le processus, et disposera des droits
+0644.
+
+Exemple :
+---------
+
+ global
+ daemon
+ quiet
+ nbproc 2
+ pidfile /var/run/haproxy-private.pid
+
+ # pour stopper seulement ces processus parmi d'autres :
+ # kill $(</var/run/haproxy-private.pid)
+
2) Définition d'un service en écoute
====================================
diff --git a/examples/config.rc.haproxy b/examples/config.rc.haproxy
index 067f07a..5340495 100644
--- a/examples/config.rc.haproxy
+++ b/examples/config.rc.haproxy
@@ -1,3 +1,6 @@
-service haproxy
- config /etc/haproxy/haproxy.cfg
+service haproxy ext
+ config /etc/haproxy/haproxy-ext.cfg
+
+service haproxy int
+ config /etc/haproxy/haproxy-int.cfg
diff --git a/examples/init.haproxy.flx0 b/examples/init.haproxy.flx0
index aa5f0cb..4b73bd8 100644
--- a/examples/init.haproxy.flx0
+++ b/examples/init.haproxy.flx0
@@ -4,7 +4,7 @@
option config standard_option /etc/haproxy/haproxy.cfg
option bin reserved_option /usr/sbin/haproxy
-option cmdline reserved_option '$bin -q -D -f ${opt_config}'
+option cmdline reserved_option '$bin -f ${opt_config} -p ${pidfile} -D -q'
function do_help {
echo "Usage: ${0##*/} <status|start|stop|help>"
@@ -15,6 +15,10 @@
exit 1
}
+# assign default values to options and variables before parsing the cfg file
+function fct_begin_section {
+ pidfile="/var/run/haproxy${2:+-$2}.pid"
+}
load_config
diff --git a/haproxy.c b/haproxy.c
index 776a235..bdee43d 100644
--- a/haproxy.c
+++ b/haproxy.c
@@ -53,8 +53,8 @@
#include <linux/netfilter_ipv4.h>
#endif
-#define HAPROXY_VERSION "1.1.26"
-#define HAPROXY_DATE "2003/10/22"
+#define HAPROXY_VERSION "1.1.27"
+#define HAPROXY_DATE "2003/10/27"
/* this is for libc5 for example */
#ifndef TCP_NODELAY
@@ -491,6 +491,7 @@
int maxsock; /* max # of sockets */
int mode;
char *chroot;
+ char *pidfile;
int logfac1, logfac2;
int loglev1, loglev2;
struct sockaddr_in logsrv1, logsrv2;
@@ -677,7 +678,7 @@
#if STATTIME > 0
"sl"
#endif
- "D ] [ -n <maxconn> ] [ -N <maxpconn> ]\n"
+ "D ] [ -n <maxconn> ] [ -N <maxpconn> ] [ -p <pidfile> ]\n"
" -v displays version\n"
" -d enters debug mode\n"
#if STATTIME > 0
@@ -687,7 +688,8 @@
" -D goes daemon ; implies -q\n"
" -q quiet mode : don't display messages\n"
" -n sets the maximum total # of connections (%d)\n"
- " -N sets the default, per-proxy maximum # of connections (%d)\n\n",
+ " -N sets the default, per-proxy maximum # of connections (%d)\n"
+ " -p writes pids of all children to this file\n\n",
name, DEFAULT_MAXCONN, cfg_maxpconn);
exit(1);
}
@@ -2226,7 +2228,7 @@
#else
ret = send(fd, s->proxy->check_req, s->proxy->check_len, MSG_DONTWAIT | MSG_NOSIGNAL);
#endif
- if (ret == 22) {
+ if (ret == s->proxy->check_len) {
FD_SET(fd, StaticReadEvent); /* prepare for reading reply */
FD_CLR(fd, StaticWriteEvent); /* nothing more to write */
return 0;
@@ -4337,6 +4339,17 @@
}
global.chroot = strdup(args[1]);
}
+ else if (!strcmp(args[0], "pidfile")) {
+ if (global.pidfile != NULL) {
+ Alert("parsing [%s:%d] : '%s' already specified. Continuing.\n", file, linenum, args[0]);
+ return 0;
+ }
+ if (*(args[1]) == 0) {
+ Alert("parsing [%s:%d] : '%s' expects a file name as an argument.\n", file, linenum, args[0]);
+ return -1;
+ }
+ global.pidfile = strdup(args[1]);
+ }
else if (!strcmp(args[0], "log")) { /* syslog server address */
struct sockaddr_in *sa;
int facility, level;
@@ -5614,6 +5627,7 @@
int arg_mode = 0; /* MODE_DEBUG, ... */
char *old_argv = *argv;
char *tmp;
+ char *cfg_pidfile = NULL;
int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
if (1<<INTBITS != sizeof(int)*8) {
@@ -5661,6 +5675,7 @@
case 'n' : cfg_maxconn = atol(*argv); break;
case 'N' : cfg_maxpconn = atol(*argv); break;
case 'f' : cfg_cfgfile = *argv; break;
+ case 'p' : cfg_pidfile = *argv; break;
default: usage(old_argv);
}
}
@@ -5683,6 +5698,12 @@
if (cfg_maxconn > 0)
global.maxconn = cfg_maxconn;
+ if (cfg_pidfile) {
+ if (global.pidfile)
+ free(global.pidfile);
+ global.pidfile = strdup(cfg_pidfile);
+ }
+
if (global.maxconn == 0)
global.maxconn = DEFAULT_MAXCONN;
@@ -5802,6 +5823,7 @@
int main(int argc, char **argv) {
+ FILE *pidfile = NULL;
init(argc, argv);
if (global.mode & MODE_QUIET) {
@@ -5824,7 +5846,17 @@
if (start_proxies() < 0)
exit(1);
- /* open log files */
+ /* open log & pid files before the chroot */
+ if (global.mode & MODE_DAEMON && global.pidfile != NULL) {
+ int pidfd;
+ unlink(global.pidfile);
+ pidfd = open(global.pidfile, O_CREAT | O_WRONLY | O_TRUNC, 0644);
+ if (pidfd < 0) {
+ Alert("[%s.main()] Cannot create pidfile %s\n", argv[0], global.pidfile);
+ exit(1);
+ }
+ pidfile = fdopen(pidfd, "w");
+ }
/* chroot if needed */
if (global.chroot != NULL) {
@@ -5859,7 +5891,16 @@
}
else if (ret == 0) /* child breaks here */
break;
+ if (pidfile != NULL) {
+ fprintf(pidfile, "%d\n", ret);
+ fflush(pidfile);
+ }
}
+ /* close the pidfile both in children and father */
+ if (pidfile != NULL)
+ fclose(pidfile);
+ free(global.pidfile);
+
if (proc == global.nbproc)
exit(0); /* parent must leave */