diff --git a/CHANGELOG b/CHANGELOG index 2efba8092..c3c20461c 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 a4bbf01ca..ad825212d 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 @@ There are only a few command line options : -N -d starts in foregreound with debugging mode enabled -D starts in daemon mode + -p 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 @@ the following ones : - daemon - debug - quiet + - pidfile 1.1) Event logging ------------------ @@ -231,6 +234,28 @@ Example : 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 $( -d active le mode debug -D passe en daemon + -p 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 @@ support - daemon - debug - quiet + - pidfile 1.1) Journalisation des événements ---------------------------------- @@ -199,7 +202,7 @@ Exemple : 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 @@ probl 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 @@ Exemple : 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 $(" @@ -15,6 +15,10 @@ function do_help { 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 776a23521..bdee43d2d 100644 --- a/haproxy.c +++ b/haproxy.c @@ -53,8 +53,8 @@ #include #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 @@ static struct { 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 @@ void usage(char *name) { #if STATTIME > 0 "sl" #endif - "D ] [ -n ] [ -N ]\n" + "D ] [ -n ] [ -N ] [ -p ]\n" " -v displays version\n" " -d enters debug mode\n" #if STATTIME > 0 @@ -687,7 +688,8 @@ void usage(char *name) { " -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 @@ int event_srv_chk_w(int fd) { #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 @@ int cfg_parse_global(char *file, int linenum, char **args) { } 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 @@ void init(int argc, char **argv) { 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< 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 start_proxies() { int main(int argc, char **argv) { + FILE *pidfile = NULL; init(argc, argv); if (global.mode & MODE_QUIET) { @@ -5824,7 +5846,17 @@ int main(int argc, char **argv) { 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 @@ int main(int argc, char **argv) { } 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 */