summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwilly tarreau <willy@wtap.(none)>2005-12-18 01:13:11 +0100
committerwilly tarreau <willy@wtap.(none)>2005-12-18 01:13:11 +0100
commit64a3cc3660fd2b036a4cca533a52e197558e6a72 (patch)
tree76f45d8426e25d66e301fc2b4a19fb0cfaaffc64
parent1c2ad21e0fc3d911520b867e450fd0219529a9ab (diff)
downloadhaproxy-64a3cc3660fd2b036a4cca533a52e197558e6a72.tar.gz
* released 1.2.5 (1.1.31)v1.2.5
* changed the runtime argument to disable epoll() to '-de' * changed the runtime argument to disable poll() to '-dp' * added global options 'nopoll' and 'noepoll' to do the same at the configuration level. * added a 'linux24e' target to the Makefile for Linux 2.4 systems patched to support epoll(). * changed default FD_SETSIZE to 65536 on Solaris (default=1024) * conditionned signals redirection to #ifdef DEBUG_MEMORY
-rw-r--r--CHANGELOG10
-rw-r--r--Makefile18
-rw-r--r--TODO7
-rw-r--r--doc/haproxy-en.txt43
-rw-r--r--doc/haproxy-fr.txt368
-rw-r--r--haproxy.c62
6 files changed, 326 insertions, 182 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 6b129d024..7db21e51e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,16 @@
ChangeLog :
===========
+2005/04/30 : 1.2.5 (1.1.31)
+ - changed the runtime argument to disable epoll() to '-de'
+ - changed the runtime argument to disable poll() to '-dp'
+ - added global options 'nopoll' and 'noepoll' to do the same at the
+ configuration level.
+ - added a 'linux24e' target to the Makefile for Linux 2.4 systems patched to
+ support epoll().
+ - changed default FD_SETSIZE to 65536 on Solaris (default=1024)
+ - conditionned signals redirection to #ifdef DEBUG_MEMORY
+
2005/04/26 : 1.2.5-pre4
- made epoll() support a compile-time option : ENABLE_EPOLL
- provided a very little libc replacement for a possibly missing epoll()
diff --git a/Makefile b/Makefile
index 3991baa4c..c99933af7 100644
--- a/Makefile
+++ b/Makefile
@@ -6,6 +6,7 @@
# correctly defined below.
#TARGET = linux26
TARGET = linux24
+#TARGET = linux24e
#TARGET = linux22
#TARGET = solaris
#TARGET = openbsd
@@ -28,11 +29,15 @@ LD = gcc
PCREDIR := $(shell pcre-config --prefix 2>/dev/null || :)
#PCREDIR=/usr/local
-# This is for Linux 2.6 with netfilter and EPOLL
+# This is for standard Linux 2.6 with netfilter and epoll()
COPTS.linux26 = -DNETFILTER -DENABLE_POLL -DENABLE_EPOLL
LIBS.linux26 =
-# This is for Linux 2.4 with netfilter
+# This is for enhanced Linux 2.4 with netfilter and epoll() patch
+COPTS.linux24e = -DNETFILTER -DENABLE_POLL -DENABLE_EPOLL -DUSE_MY_EPOLL
+LIBS.linux24e =
+
+# This is for standard Linux 2.4 with netfilter but without epoll()
COPTS.linux24 = -DNETFILTER -DENABLE_POLL
LIBS.linux24 =
@@ -41,7 +46,7 @@ COPTS.linux22 = -DUSE_GETSOCKNAME -DENABLE_POLL
LIBS.linux22 =
# This is for Solaris 8
-COPTS.solaris = -fomit-frame-pointer -DSOLARIS -DENABLE_POLL
+COPTS.solaris = -fomit-frame-pointer -DENABLE_POLL -DFD_SETSIZE=65536
LIBS.solaris = -lnsl -lsocket
# This is for OpenBSD 3.0
@@ -63,13 +68,14 @@ COPTS.pcre=-DUSE_PCRE -I$(PCREDIR)/include
LIBS.pcre=-L$(PCREDIR)/lib -lpcreposix -lpcre
# you can enable debug arguments with "DEBUG=-g" or disable them with "DEBUG="
-#DEBUG =
+#DEBUG = -g -DDEBUG_MEMORY
DEBUG = -g
# if small memory footprint is required, you can reduce the buffer size. There
# are 2 buffers per concurrent session, so 16 kB buffers will eat 32 MB memory
-# with 1000 concurrent sessions.
-#SMALL_OPTS = -DBUFSIZE=8192 -DMAXREWRITE=1024
+# with 1000 concurrent sessions. Putting it slightly lower than a page size
+# will avoid the additionnal paramters to overflow a page.
+#SMALL_OPTS = -DBUFSIZE=8100 -DMAXREWRITE=1000
SMALL_OPTS =
# redefine this if you want to add some special PATH to include/libs
diff --git a/TODO b/TODO
index 66a4ec6ac..0ef9fed9b 100644
--- a/TODO
+++ b/TODO
@@ -141,3 +141,10 @@ Todo for 1.2
- option to shutdown(listen_sock) when max connections reached
* epoll
- replace the event scheduler with an O(log(N)) one
+- refine memory management so that the request buffer is only allocated in
+ cli_read() and response buffer during srv_read(). This would protect against
+ attacks with thousands connections : 20000 connections consume 340 MB RSS and
+ 1.3 GB VSZ on Linux. Data should be in a separate buffer to prevent any
+ activity on the buffer's pointers from touching the buffer page itself.
+- make buffer size configurable in global options
+- monitor number of simultaneous sessions in logs (per srv/inst/global)
diff --git a/doc/haproxy-en.txt b/doc/haproxy-en.txt
index 65ebb96d6..d9068a562 100644
--- a/doc/haproxy-en.txt
+++ b/doc/haproxy-en.txt
@@ -4,7 +4,7 @@
-------------------
version 1.2.5
willy tarreau
- 2005/04/24
+ 2005/04/30
============
| Abstract |
@@ -44,6 +44,8 @@ There are only a few command line options :
pids to this file in daemon mode.
-s shows statistics (only if compiled in)
-l shows even more statistics (implies '-s')
+ -de disables use of epoll()
+ -dp disables use of poll()
The maximal number of connections per proxy is used as the default parameter for
@@ -98,6 +100,8 @@ the following ones :
- nbproc <number>
- daemon
- debug
+ - noepoll
+ - nopoll
- quiet
- pidfile <file>
- stats
@@ -264,6 +268,43 @@ Example :
# kill $(</var/run/haproxy-private.pid)
+1.7) Polling mechanisms
+-----------------------
+Starting from version 1.2.5, haproxy supports the poll() and epoll() polling
+mechanisms. On systems where select() is limited by FD_SETSIZE (like Solaris),
+poll() can be an interesting alternative. Performance tests show that Solaris'
+poll() performance does not decay as fast as the numbers of sockets increase,
+making it a safe solution for high loads. However, Solaris already uses poll()
+to emulate select(), so as long as the number of sockets has no reason to go
+higher than FD_SETSIZE, poll() should not provide any better performance. On
+Linux systems with the epoll() patch (or any 2.6 version), haproxy will use
+epoll() which is extremely fast and non dependant on the number of sockets.
+Tests have shown constant performance from 1 to 20000 simultaneous sessions.
+
+Haproxy will use epoll() when available, and will fall back to poll(), then to
+select(). However, if for any reason you need to disable epoll() or poll() (eg.
+because of a bug or just to compare performance), two new global options have
+been created for this matter : 'noepoll' and 'nopoll'.
+
+Example :
+---------
+
+ global
+ # use only select()
+ noepoll
+ nopoll
+
+Note :
+------
+For the sake of configuration file portability, these options are accepted but
+ignored if the poll() or epoll() mechanisms have not been enabled at compile
+time.
+
+To make debugging easier, the '-de' runtime argument disables epoll support and
+the '-dp' argument disables poll support. They are respectively equivalent to
+'noepoll' and 'nopoll'.
+
+
2) Declaration of a listening service
=====================================
diff --git a/doc/haproxy-fr.txt b/doc/haproxy-fr.txt
index 109c45cec..97f0f6f68 100644
--- a/doc/haproxy-fr.txt
+++ b/doc/haproxy-fr.txt
@@ -4,7 +4,7 @@
-------------------
version 1.2.5
willy tarreau
- 2005/04/24
+ 2005/04/30
================
| Introduction |
@@ -13,8 +13,8 @@
HA-Proxy est un relais TCP/HTTP offrant des facilités d'intégration en
environnement hautement disponible. En effet, il est capable de :
- effectuer un aiguillage statique défini par des cookies ;
- - effectuer une répartition de charge avec création de cookies pour assurer la
- persistence de session ;
+ - effectuer une répartition de charge avec création de cookies pour assurer
+ la persistence de session ;
- fournir une visibilité externe de son état de santé ;
- s'arrêter en douceur sans perte brutale de service ;
- modifier/ajouter/supprimer des entêtes dans la requête et la réponse ;
@@ -22,9 +22,9 @@ environnement hautement disponible. En effet, il est capable de :
- utiliser des serveurs de secours lorsque les serveurs principaux sont hors
d'usage.
-Il requiert peu de ressources, et son architecture événementielle mono-processus
-lui permet facilement de gérer plusieurs milliers de connexions simultanées sur
-plusieurs relais sans effondrer le système.
+Il requiert peu de ressources, et son architecture événementielle mono-
+processus lui permet facilement de gérer plusieurs milliers de connexions
+simultanées sur plusieurs relais sans effondrer le système.
===========================
@@ -48,14 +48,17 @@ Les options de lancement sont peu nombreuses :
fils dans ce fichier en mode démon.
-s affiche les statistiques (si option compilée)
-l ajoute des informations aux statistiques
+ -de désactive l'utilisation de epoll()
+ -dp désactive l'utilisation de poll()
-Le nombre maximal de connexion simultanées par proxy est le paramètre par défaut
-pour les proxies pour lesquels ce paramètre n'est pas précisé dans le fichier de
-configuration. Il s'agit du paramètre 'maxconn' dans les sections 'listen'.
+Le nombre maximal de connexion simultanées par proxy est le paramètre par
+défaut pour les proxies pour lesquels ce paramètre n'est pas précisé dans le
+fichier de configuration. Il s'agit du paramètre 'maxconn' dans les sections
+'listen'.
-Le nombre maximal total de connexions simultanées limite le nombre de connexions
-TCP utilisables à un instant donné par le processus, tous proxies confondus. Ce
-paramètre remplace le paramètre 'maxconn' de la section 'global'.
+Le nombre maximal total de connexions simultanées limite le nombre de
+connexions TCP utilisables à un instant donné par le processus, tous proxies
+confondus. Ce paramètre remplace le paramètre 'maxconn' de la section 'global'.
Le mode debug correspond à l'option 'debug' de la section 'global'. Dans ce
mode, toutes les connexions, déconnexions, et tous les échanges d'entêtes HTTP
@@ -74,8 +77,8 @@ Structure
=========
L'analyseur du fichier de configuration ignore des lignes vides, les espaces,
-les tabulations, et tout ce qui est compris entre le symbole '#' (s'il n'est pas
-précédé d'un '\'), et la fin de la ligne, ce qui constitue un commentaire.
+les tabulations, et tout ce qui est compris entre le symbole '#' (s'il n'est
+pas précédé d'un '\'), et la fin de la ligne, ce qui constitue un commentaire.
Le fichier de configuration est découpé en sections répérées par des mots clés
tels que :
@@ -103,6 +106,8 @@ supportés sont :
- nbproc <nombre>
- daemon
- debug
+ - noepoll
+ - nopoll
- quiet
- pidfile <fichier>
@@ -117,9 +122,9 @@ syslog vers un ou deux serveurs. La syntaxe est la suivante :
Les connexions sont envoyées en niveau "info". Les démarrages de service et de
serveurs seront envoyés en "notice", les signaux d'arrêts en "warning" et les
arrêts définitifs de services et de serveurs en "alert". Ceci est valable aussi
-bien pour les proxies que pour les serveurs testés par les proxies. Le paramètre
-optionnel <niveau_max> définit le niveau maximal de traces émises parmi les 8
-valeurs suivantes :
+bien pour les proxies que pour les serveurs testés par les proxies. Le
+paramètre optionnel <niveau_max> définit le niveau maximal de traces émises
+parmi les 8 valeurs suivantes :
emerg, alert, crit, err, warning, notice, info, debug
Par compatibilité avec les versions 1.1.16 et antérieures, la valeur par défaut
@@ -152,8 +157,8 @@ de sockets nécessaires, il faut prendre en compte ces paramètres :
- 1 socket pour chaque serveur en cours de health-check
- 1 socket pour les logs (tous serveurs confondus)
-Dans le cas où chaque proxy n'écoute que sur un couple adresse/port, positionner
-la limite du nombre de descripteurs de fichiers (ulimit -n) à
+Dans le cas où chaque proxy n'écoute que sur un couple adresse/port,
+positionner la limite du nombre de descripteurs de fichiers (ulimit -n) à
(2 * maxconn + nbproxy + nbserveurs + 1). Dans une future version, haproxy sera
capable de positionner lui-même cette limite.
@@ -184,20 +189,23 @@ plusieurs services de nature différente. Pour rendre l'isolement plus robuste,
il est conseillé d'utiliser un répertoire vide, sans aucun droit, et de changer
l'uid du processus de sorte qu'il ne puisse rien faire dans ledit répertoire.
-Remarque: dans le cas où une telle faille serait mise en évidence, il est fort
-probable que les premières tentatives de son exploitation provoquent un arrêt du
+Remarque importante :
+---------------------
+Dans le cas où une telle faille serait mise en évidence, il est fort probable
+que les premières tentatives de son exploitation provoquent un arrêt du
programme, à cause d'un signal de type 'Segmentation Fault', 'Bus Error' ou
-encore 'Illegal Instruction'. Même s'il est vrai que faire tourner le serveur en
-environnement limité réduit les risques d'intrusion, il est parfois bien utile
-dans ces circonstances de connaître les conditions d'apparition du problème, via
-l'obtention d'un fichier 'core'. La plupart des systèmes, pour des raisons de
-sécurité, désactivent la génération du fichier 'core' après un changement
-d'identifiant pour le processus. Il faudra donc soit lancer le processus à
-partir d'un compte utilisateur aux droits réduits (mais ne pouvant pas effectuer
-le chroot), ou bien le faire en root sans réduction des droits (uid 0). Dans ce
-cas, le fichier se trouvera soit dans le répertoire de lancement, soit dans le
-répertoire spécifié après l'option 'chroot'. Ne pas oublier la commande suivante
-pour autoriser la génération du fichier avant de lancer le programme :
+encore 'Illegal Instruction'. Même s'il est vrai que faire tourner le serveur
+en environnement limité réduit les risques d'intrusion, il est parfois bien
+utile dans ces circonstances de connaître les conditions d'apparition du
+problème, via l'obtention d'un fichier 'core'. La plupart des systèmes, pour
+des raisons de sécurité, désactivent la génération du fichier 'core' après un
+changement d'identifiant pour le processus. Il faudra donc soit lancer le
+processus à partir d'un compte utilisateur aux droits réduits (mais ne pouvant
+pas effectuer le chroot), ou bien le faire en root sans réduction des droits
+(uid 0). Dans ce cas, le fichier se trouvera soit dans le répertoire de
+lancement, soit dans le répertoire spécifié après l'option 'chroot'. Ne pas
+oublier la commande suivante pour autoriser la génération du fichier avant de
+lancer le programme :
# ulimit -c unlimited
@@ -215,9 +223,9 @@ Le service peut fonctionner dans plusieurs modes :
- avant- / arrière-plan
- silencieux / normal / debug
-Le mode par défaut est normal, avant-plan, c'est à dire que le programme ne rend
-pas la main une fois lancé. Il ne faut surtout pas le lancer comme ceci dans un
-script de démarrage du système, sinon le système ne finirait pas son
+Le mode par défaut est normal, avant-plan, c'est à dire que le programme ne
+rend pas la main une fois lancé. Il ne faut surtout pas le lancer comme ceci
+dans un script de démarrage du système, sinon le système ne finirait pas son
initialisation. Il faut le mettre en arrière-plan, de sorte qu'il rende la main
au processus appelant. C'est ce que fait l'option 'daemon' de la section
'global', et qui est l'équivalent du paramètre '-D' de la ligne de commande.
@@ -277,6 +285,44 @@ Exemple :
# kill $(</var/run/haproxy-private.pid)
+1.7) Mécanismes de traitements des événements
+---------------------------------------------
+A partir de la version 1.2.5, haproxy supporte les mécanismes poll() et
+epoll(). Sur les systems où select() est limité par FD_SETSIZE (comme Solaris),
+poll() peut être une alternative intéressante. Des tests de performance
+montrent que les performances de poll() ne décroissent pas aussi vite que le
+nombre de sockets augmente, ce qui en fait une solution sûre pour les fortes
+charges. Cela dit, Soalris utilise déjà poll() pour émuler select(), donc tant
+que le nombre de sockets ne dépasse pas FD_SETSIZE, poll() ne devrait pas
+apporter de performances supplémentaires. Sur les systèmes à base Linux
+incluant le patch epoll() (ou tous les Linux 2.6), haproxy utilisera epoll()
+qui est extrèmement rapide indépendamment du nombre de sockets. Les tests sur
+haproxy ont montré une performance constante de 1 à 40000 sessions simultanées.
+
+Haproxy utilisera epoll() lorsqu'il est disponible, et se repliera sur poll(),
+puis en dernier lieu sur select(). Cependant, si pour une raison quelconque il
+s'avérait nécessaire de désactiver epoll() ou poll() (p.ex: à cause d'un bug ou
+juste pour comparer les performances), deux nouvelles options globales ont été
+ajoutées dans ce but : 'noepoll' et 'nopoll'.
+
+Exemple :
+---------
+ global
+ # utiliser seulement select()
+ noepoll
+ nopoll
+
+Remarque :
+----------
+Dans le but d'assurer une portabilité maximale des configurations, ces options
+sont acceptées et ignorées si les mécanismes poll() ou epoll() n'ont pas été
+activés lors de la compilation.
+
+Afin de simplifier la résolution de problèmes, le paramètre '-de' en ligne de
+commande désactive epoll() et le paramètre '-dp' désactive poll(). Ils sont
+respectivement équivalents à 'noepoll' et 'nopoll'.
+
+
2) Définition d'un service en écoute
====================================
@@ -285,9 +331,9 @@ Les sections de service débutent par le mot clé "listen" :
listen <nom_instance> [ <adresse_IP>:<plage_ports>[,...] ]
- <nom_instance> est le nom de l'instance décrite. Ce nom sera envoyé dans les
- logs, donc il est souhaitable d'utiliser un nom relatif au service relayé. Aucun
- test n'est effectué concernant l'unicité de ce nom, qui n'est pas obligatoire,
- mais fortement recommandée.
+ logs, donc il est souhaitable d'utiliser un nom relatif au service relayé.
+ Aucun test n'est effectué concernant l'unicité de ce nom, qui n'est pas
+ obligatoire, mais fortement recommandée.
- <adresse_IP> est l'adresse IP sur laquelle le relais attend ses connexions.
L'absence d'adresse ainsi que l'adresse 0.0.0.0 signifient que les connexions
@@ -304,8 +350,8 @@ Les sections de service débutent par le mot clé "listen" :
<adresse_IP>:<port> consomme une socket, donc un descripteur de fichier.
Le couple <adresse_IP>:<port> doit être unique pour toutes les instances
d'une même machine. L'attachement à un port inférieur à 1024 nécessite un
- niveau de privilège particulier lors du lancement du programme (indépendamment
- du paramètre 'uid' de la section 'global').
+ niveau de privilège particulier lors du lancement du programme
+ (indépendamment du paramètre 'uid' de la section 'global').
- le couple <adresse_IP>:<plage_ports> peut être répété indéfiniment pour
demander au relais d'écouter également sur d'autres adresses et/ou d'autres
@@ -353,9 +399,10 @@ Un service peut fonctionner dans trois modes différents :
Mode TCP
--------
-Dans ce mode, le service relaye, dès leur établissement, les connexions TCP vers
-un ou plusieurs serveurs. Aucun traitement n'est effectué sur le flux. Il s'agit
-simplement d'une association source<adresse:port> -> destination<adresse:port>.
+Dans ce mode, le service relaye, dès leur établissement, les connexions TCP
+vers un ou plusieurs serveurs. Aucun traitement n'est effectué sur le flux. Il
+s'agit simplement d'une association
+ source<adresse:port> -> destination<adresse:port>.
Pour l'utiliser, préciser le mode TCP sous la déclaration du relais.
Exemple :
@@ -414,15 +461,19 @@ Exemple :
2.4) Arrêt en douceur
---------------------
-Il est possible d'arrêter les services en douceur en envoyant un signal SIG_USR1
-au processus relais. Tous les services seront alors mis en phase d'arrêt, mais
-pourront continuer d'accepter des connexions pendant un temps défini par le
-paramètre 'grace' (en millisecondes). Cela permet par exemple, de faire savoir
-rapidement à un répartiteur de charge qu'il ne doit plus utiliser un relais,
-tout en continuant d'assurer le service le temps qu'il s'en rende compte.
-Remarque : les connexions actives ne sont jamais cassées. Dans le pire des cas,
-il faudra attendre en plus leur expiration avant l'arrêt total du processus. La
-valeur par défaut est 0 (pas de grâce, arrêt immédiat de l'écoute).
+Il est possible d'arrêter les services en douceur en envoyant un signal
+SIG_USR1 au processus relais. Tous les services seront alors mis en phase
+d'arrêt, mais pourront continuer d'accepter des connexions pendant un temps
+défini par le paramètre 'grace' (en millisecondes). Cela permet par exemple,
+de faire savoir rapidement à un répartiteur de charge qu'il ne doit plus
+utiliser un relais, tout en continuant d'assurer le service le temps qu'il
+s'en rende compte.
+
+Remarque :
+----------
+Les connexions actives ne sont jamais cassées. Dans le pire des cas, il faudra
+attendre en plus leur expiration avant l'arrêt total du processus. La valeur
+par défaut est 0 (pas de grâce, arrêt immédiat de l'écoute).
Exemple :
---------
@@ -468,11 +519,12 @@ Remarques :
- "contimeout" et "srvtimeout" n'ont pas d'utilité dans le cas du serveur de
type "health".
- sous de fortes charges, ou sur un réseau saturé ou défectueux, il est
- possible de perdre des paquets. Du fait que la première retransmission TCP
- n'ait lieu qu'au bout de 3 secoudes, fixer un timeout de connexion inférieur
- à 3 secondes ne permet pas de se rattraper sur la perte de paquets car la
- session aura été abandonnée avant la première retransmission. Une valeur de
- 4 secondes réduira considérablement le nombre d'échecs de connexion.
+ possible de perdre des paquets. Du fait que la première retransmission
+ TCP n'ait lieu qu'au bout de 3 secoudes, fixer un timeout de connexion
+ inférieur à 3 secondes ne permet pas de se rattraper sur la perte
+ de paquets car la session aura été abandonnée avant la première
+ retransmission. Une valeur de 4 secondes réduira considérablement
+ le nombre d'échecs de connexion.
2.6) Tentatives de reconnexion
------------------------------
@@ -514,12 +566,12 @@ Il est possible de forcer l'adresse utilisée pour établir les connexions vers
les serveurs à l'aide du paramètre "source". Il est même possible de forcer le
port, bien que cette fonctionnalité se limite à des usages très spécifiques.
C'est particulièrement utile en cas d'adressage multiple, et plus généralement
-pour permettre aux serveurs de trouver le chemin de retour dans des contextes de
-routage difficiles. Si l'adresse est '0.0.0.0' ou '*' ou vide, elle sera choisie
-librement par le systeme. Si le port est '0' ou vide, il sera choisi librement
-par le système. Il est à noter que depuis la version 1.1.18, les tests de bon
-fonctionnement des serveurs seront aussi effectués à partir de la source
-spécifiée par ce paramètre.
+pour permettre aux serveurs de trouver le chemin de retour dans des contextes
+de routage difficiles. Si l'adresse est '0.0.0.0' ou '*' ou vide, elle sera
+choisie librement par le systeme. Si le port est '0' ou vide, il sera choisi
+librement par le système. Il est à noter que depuis la version 1.1.18, les
+tests de bon fonctionnement des serveurs seront aussi effectués à partir de la
+source spécifiée par ce paramètre.
Exemples :
----------
@@ -565,9 +617,9 @@ lors d'un accès direct :
cookie SERVERID rewrite
-Pour créer un cookie comportant la valeur attribuée à un serveur lors d'un accès
-en répartition de charge interne. Dans ce cas, il est souhaitable que tous les
-serveurs aient un cookie renseigné. Un serveur non assigné d'un cookie
+Pour créer un cookie comportant la valeur attribuée à un serveur lors d'un
+accès en répartition de charge interne. Dans ce cas, il est souhaitable que
+tous les serveurs aient un cookie renseigné. Un serveur non assigné d'un cookie
retournera un cookie vide (cookie de suppression) :
cookie SERVERID insert
@@ -585,17 +637,17 @@ ajouter le mot clé 'nocache' après 'insert' :
cookie SERVERID insert nocache
-Pour insérer un cookie seulement suite aux requêtes de type POST, ajouter le mot
-clé 'postonly' après 'insert' :
+Pour insérer un cookie seulement suite aux requêtes de type POST, ajouter le
+mot clé 'postonly' après 'insert' :
cookie SERVERID insert postonly
Remarques :
-----------
-- Il est possible de combiner 'insert' avec 'indirect' ou 'rewrite' pour s'adapter
- à des applications générant déjà le cookie, avec un contenu invalide. Il suffit
- pour cela de les spécifier sur la même ligne.
+- Il est possible de combiner 'insert' avec 'indirect' ou 'rewrite' pour
+ s'adapter à des applications générant déjà le cookie, avec un contenu
+ invalide. Il suffit pour cela de les spécifier sur la même ligne.
- dans le cas où 'insert' et 'indirect' sont spécifiés, le cookie n'est jamais
transmis au serveur vu qu'il n'en a pas connaissance et ne pourrait pas le
@@ -719,35 +771,36 @@ Exemples :
3.1) Surveillance des serveurs
------------------------------
-Il est possible de tester l'état des serveurs par établissement de connexion TCP
-ou par envoi d'une requête HTTP. Un serveur hors d'usage ne sera pas utilisé
-dans le processus de répartition de charge interne. Pour activer la surveillance,
-ajouter le mot clé 'check' à la fin de la déclaration du serveur. Il est
-possible de spécifier l'intervalle (en millisecondes) séparant deux tests du
-serveur par le paramètre "inter", le nombre d'échecs acceptés par le paramètre
-"fall", et le nombre de succès avant reprise par le paramètre "rise". Les
-paramètres non précisés prennent les valeurs suivantes par défaut :
+Il est possible de tester l'état des serveurs par établissement de connexion
+TCP ou par envoi d'une requête HTTP. Un serveur hors d'usage ne sera pas
+utilisé dans le processus de répartition de charge interne. Pour activer la
+surveillance, ajouter le mot clé 'check' à la fin de la déclaration du serveur.
+Il est possible de spécifier l'intervalle (en millisecondes) séparant deux
+tests du serveur par le paramètre "inter", le nombre d'échecs acceptés par le
+paramètre "fall", et le nombre de succès avant reprise par le paramètre "rise".
+Les paramètres non précisés prennent les valeurs suivantes par défaut :
- inter : 2000
- rise : 2
- fall : 3
- port : port de connexion du serveur
Le mode par défaut consiste à établir des connexions TCP uniquement. Dans
-certains cas de pannes, des serveurs peuvent continuer à accepter les connexions
-sans les traiter. Depuis la version 1.1.16, haproxy est en mesure d'envoyer des
-requêtes HTTP courtes et très peu coûteuses. Les versions 1.1.16 et 1.1.17
-utilisent "OPTIONS / HTTP/1.0". Dans les versions 1.1.18 à 1.1.20, les requêtes
-ont été changées en "OPTIONS * HTTP/1.0" pour des raisons de contrôle d'accès aux
-ressources. Cependant, cette requête documentée dans la RFC2068 n'est pas
-comprise par tous les serveurs. Donc à partir de la version 1.1.21, la requête
-par défaut est revenue à "OPTIONS / HTTP/1.0", mais il est possible de
-paramétrer la partie URI. Les requêtes OPTIONS présentent l'avantage d'être
-facilement extractibles des logs, et de ne pas induire d'accès aux fichiers côté
-serveur. Seules les réponses 2xx et 3xx sont considérées valides, les autres (y
-compris non-réponses) aboutissent à un échec. Le temps maximal imparti pour une
-réponse est égal à l'intervalle entre deux tests (paramètre "inter"). Pour
-activer ce mode, spécifier l'option "httpchk", éventuellement suivie d'une
-méthode et d'une URI. L'option "httpchk" accepte donc 4 formes :
+certains cas de pannes, des serveurs peuvent continuer à accepter les
+connexions sans les traiter. Depuis la version 1.1.16, haproxy est en mesure
+d'envoyer des requêtes HTTP courtes et très peu coûteuses. Les versions 1.1.16
+et 1.1.17 utilisent "OPTIONS / HTTP/1.0". Dans les versions 1.1.18 à 1.1.20,
+les requêtes ont été changées en "OPTIONS * HTTP/1.0" pour des raisons de
+contrôle d'accès aux ressources. Cependant, cette requête documentée dans la
+RFC2068 n'est pas comprise par tous les serveurs. Donc à partir de la version
+1.1.21, la requête par défaut est revenue à "OPTIONS / HTTP/1.0", mais il est
+possible de paramétrer la partie URI. Les requêtes OPTIONS présentent
+l'avantage d'être facilement extractibles des logs, et de ne pas induire
+d'accès aux fichiers côté serveur. Seules les réponses 2xx et 3xx sont
+considérées valides, les autres (y compris non-réponses) aboutissent à un
+échec. Le temps maximal imparti pour une réponse est égal à l'intervalle entre
+deux tests (paramètre "inter"). Pour activer ce mode, spécifier l'option
+"httpchk", éventuellement suivie d'une méthode et d'une URI. L'option "httpchk"
+accepte donc 4 formes :
- option httpchk -> OPTIONS / HTTP/1.0
- option httpchk URI -> OPTIONS <URI> HTTP/1.0
- option httpchk METH URI -> <METH> <URI> HTTP/1.0
@@ -772,12 +825,12 @@ pour les configurations où le serveur n'a pas de port prédéfini, par exemple
lorsqu'il est déduit du port d'acceptation de la connexion. Pour cela, utiliser
le paramètre 'port' suivi du numéro de port devant répondre aux requêtes.
-Enfin, depuis la version 1.1.17, il est possible de visualiser rapidement l'état
-courant de tous les serveurs. Pour cela, il suffit d'envoyer un signal SIGHUP au
-processus proxy. L'état de tous les serveurs de tous les proxies est envoyé dans
-les logs en niveau "notice", ainsi que sur la sortie d'erreurs si elle est
-active. C'est une bonne raison pour avoir au moins un serveur de logs local en
-niveau notice.
+Enfin, depuis la version 1.1.17, il est possible de visualiser rapidement
+l'état courant de tous les serveurs. Pour cela, il suffit d'envoyer un signal
+SIGHUP au processus proxy. L'état de tous les serveurs de tous les proxies est
+envoyé dans les logs en niveau "notice", ainsi que sur la sortie d'erreurs si
+elle est active. C'est une bonne raison pour avoir au moins un serveur de logs
+local en niveau notice.
Depuis la version 1.1.18 (et 1.2.1), un message d'urgence est envoyé dans les
logs en niveau 'emerg' si tous les serveurs d'une même instance sont tombés,
@@ -890,12 +943,12 @@ Exemple :
server web2 192.168.1.2:80 cookie server02
redispatch # renvoyer vers dispatch si refus de connexion.
-Par défaut (et dans les versions 1.1.16 et antérieures), le paramètre redispatch
-ne s'applique qu'aux échecs de connexion au serveur. Depuis la version 1.1.17,
-il s'applique aussi aux connexions destinées à des serveurs identifiés comme
-hors d'usage par la surveillance. Si l'on souhaite malgré tout qu'un client
-disposant d'un cookie correspondant à un serveur défectueux tente de s'y
-connecter, il faut préciser l'option "persist" :
+Par défaut (et dans les versions 1.1.16 et antérieures), le paramètre
+redispatch ne s'applique qu'aux échecs de connexion au serveur. Depuis la
+version 1.1.17, il s'applique aussi aux connexions destinées à des serveurs
+identifiés comme hors d'usage par la surveillance. Si l'on souhaite malgré
+tout qu'un client disposant d'un cookie correspondant à un serveur défectueux
+tente de s'y connecter, il faut préciser l'option "persist" :
listen http_proxy 0.0.0.0:80
mode http
@@ -918,9 +971,9 @@ la réécriture des entêtes.
---------------------------
4.1.1) Fonctionnement en mode transparent
---------------------------------------
-En mode HTTP, le mot clé 'transparent' permet d'intercepter des sessions routées
-à travers la machine hébergeant le proxy. Dans ce mode, on ne précise pas
-l'adresse de répartition 'dispatch', car celle-ci est tirée de l'adresse
+En mode HTTP, le mot clé 'transparent' permet d'intercepter des sessions
+routées à travers la machine hébergeant le proxy. Dans ce mode, on ne précise
+pas l'adresse de répartition 'dispatch', car celle-ci est tirée de l'adresse
destination de la session détournée. Le système doit permettre de rediriger les
paquets vers un processus local.
@@ -938,9 +991,10 @@ Exemple :
Remarque :
----------
-Si le port n'est pas spécifié sur le serveur, c'est le port auquel s'est adressé
-le client qui sera utilisé. Cela permet de relayer tous les ports TCP d'une même
-adresse avec une même instance et sans utiliser directement le mode transparent.
+Si le port n'est pas spécifié sur le serveur, c'est le port auquel s'est
+adressé le client qui sera utilisé. Cela permet de relayer tous les ports TCP
+d'une même adresse avec une même instance et sans utiliser directement le mode
+transparent.
Exemple :
---------
@@ -1067,16 +1121,16 @@ Exemple :
Le problème de loguer uniquement en fin de session, c'est qu'il est impossible
de savoir ce qui se passe durant de gros transferts ou des sessions longues.
Pour pallier à ce problème, une nouvelle option 'logasap' a été introduite dans
-la version 1.1.28 (1.2.1). Lorsqu'elle est activée, le proxy loguera le plus tôt
-possible, c'est à dire juste avant que ne débutent les transferts de données.
-Cela signifie, dans le cas du TCP, qu'il loguera toujours le résultat de la
-connexion vers le serveur, et dans le cas HTTP, qu'il loguera en fin de
+la version 1.1.28 (1.2.1). Lorsqu'elle est activée, le proxy loguera le plus
+tôt possible, c'est à dire juste avant que ne débutent les transferts de
+données. Cela signifie, dans le cas du TCP, qu'il loguera toujours le résultat
+de la connexion vers le serveur, et dans le cas HTTP, qu'il loguera en fin de
traitement des entêtes de la réponse du serveur, auquel cas le nombre d'octets
représentera la taille des entêtes retournés au client.
-Afin d'éviter toute confusion avec les logs normaux, le temps total de transfert
-et le nombre d'octets transférés sont préfixés d'un signe '+' rappeleant que les
-valeurs réelles sont certainement plus élevées.
+Afin d'éviter toute confusion avec les logs normaux, le temps total de
+transfert et le nombre d'octets transférés sont préfixés d'un signe '+'
+rappeleant que les valeurs réelles sont certainement plus élevées.
Exemple :
---------
@@ -1167,9 +1221,9 @@ Autres cas ('xx' représentant une valeur quelconque à ignorer) :
4.2.4) Conditions de déconnexion
--------------------------------
Les logs TCP et HTTP fournissent un indicateur de complétude de la session.
-C'est un champ de 4 caractères (2 en TCP) précédant la requête HTTP, indiquant :
- - sur le premier caractère, un code précisant le premier événement qui a causé
- la terminaison de la session :
+C'est un champ de 4 caractères (2 en TCP) précédant la requête HTTP, indiquant:
+ - sur le premier caractère, un code précisant le premier événement qui a
+ causé la terminaison de la session :
C : fermeture de la session TCP de la part du client
S : fermeture de la session TCP de la part du serveur, ou refus de connexion
@@ -1206,8 +1260,8 @@ C'est un champ de 4 caractères (2 en TCP) précédant la requête HTTP, indiquant :
serveur correspondant.
- : non appliquable
- - le dernier caractère indique l'éventuel traitement effectué sur un cookie de
- persistence retrourné par le serveur (uniquement en mode HTTP) :
+ - le dernier caractère indique l'éventuel traitement effectué sur un cookie
+ de persistence retrourné par le serveur (uniquement en mode HTTP) :
N : aucun cookie de persistence n'a été fourni par le serveur.
P : un cookie de persistence a été fourni par le serveur et transmis
@@ -1241,9 +1295,9 @@ Exemples :
capture cookie vgnvisitor= len 32
Dans les logs, le champ précédant l'indicateur de complétude contient le cookie
-positionné par le serveur, précédé du cookie positionné par le client. Chacun de
-ces champs est remplacé par le signe "-" lorsqu'aucun cookie n'est fourni par le
-client ou le serveur.
+positionné par le serveur, précédé du cookie positionné par le client. Chacun
+de ces champs est remplacé par le signe "-" lorsqu'aucun cookie n'est fourni
+par le client ou le serveur.
4.2.5) Exemples de logs
-----------------------
@@ -1281,17 +1335,18 @@ client ou le serveur.
- haproxy[18989]: 10.0.0.1:34552 [15/Oct/2003:15:26:31] relais-http Srv1 3183/-1/-1/11215 503 0 - - SC-- "HEAD / HTTP/1.0"
=> La requête client met 3s à entrer (peut-être un problème réseau), et la
connexion ('SC--') vers le serveur échoue au bout de 4 tentatives de 2
- secondes (retries 3 dans la conf), puis un code 503 est retourné au client.
+ secondes (retries 3 dans la conf), puis un code 503 est retourné au
+ client.
4.2.6) Caractères non-imprimables
---------------------------------
Depuis la version 1.1.29, les caractères non-imprimables ne sont plus envoyés
-tels quels dans les lignes de logs, mais inscrits sous la forme de deux chiffres
-hexadécimaux, préfixés du caractère d'échappement '#'. Les seuls caractères
-dorénavant logués tels quels sont compris entre 32 et 126. Bien évidemment, le
-caractère d'échappement '#' est lui-même encodé afin de lever l'ambiguité. Il en
-est de même pour le caractère '"', ainsi que les caractères '{', '|' et '}' pour
-les en-têtes.
+tels quels dans les lignes de logs, mais inscrits sous la forme de deux
+chiffres hexadécimaux, préfixés du caractère d'échappement '#'. Les seuls
+caractères dorénavant logués tels quels sont compris entre 32 et 126. Bien
+évidemment, le caractère d'échappement '#' est lui-même encodé afin de lever
+l'ambiguité. Il en est de même pour le caractère '"', ainsi que les caractères
+'{', '|' et '}' pour les en-têtes.
4.2.7) Journalisation d'en-têtes
--------------------------------
@@ -1300,10 +1355,10 @@ d'en-têtes HTTP dans les logs. On peut aussi bien extraire des en-têtes de la
requête que de la réponse. C'est particulièrement pratique pour savoir à quel
serveur virtuel une requête s'adressait, pour connaitre la longueur des données
émises lors d'un POST, ou encore loguer un identifiant unique de requête
-positionné en amont. Dans la réponse, on peut chercher également à conserver des
-informations relatives à la taille annoncée de la réponse, le fonctionnement
-attendu du cache, ou encore la localisation d'un objet en cas de redirection.
-La syntaxe est la suivante :
+positionné en amont. Dans la réponse, on peut chercher également à conserver
+des informations relatives à la taille annoncée de la réponse, le
+fonctionnement attendu du cache, ou encore la localisation d'un objet en cas
+de redirection. La syntaxe est la suivante :
capture request header <nom> len <longueur max>
capture response header <nom> len <longueur max>
@@ -1322,12 +1377,13 @@ Exemples:
# noter l'URL de redirection
capture response header Location len 20
-Les en-têtes non trouvés sont logués à vide, et si un en-tête apparait plusieurs
-fois, seule la dernière occurence sera conservée. Les en-têtes de requête sont
-regroupés entre deux accolades '{' et '}' dans l'ordre de leur déclaration, et
-chacun séparés par une barre verticale '|', sans aucun espace. Les en-têtes de
-réponse sont présentés de la même manière, mais après un espace suivant le bloc
-d'en-tête de requête. Le tout précède la requête HTTP. Exemple :
+Les en-têtes non trouvés sont logués à vide, et si un en-tête apparait
+plusieurs fois, seule la dernière occurence sera conservée. Les en-têtes de
+requête sont regroupés entre deux accolades '{' et '}' dans l'ordre de leur
+déclaration, et chacun séparés par une barre verticale '|', sans aucun espace.
+Les en-têtes de réponse sont présentés de la même manière, mais après un
+espace suivant le bloc d'en-tête de requête. Le tout précède la requête HTTP.
+Exemple :
Config:
@@ -1350,8 +1406,8 @@ Aug 9 20:30:46 localhost haproxy[2022]: 127.0.0.1:34028 [09/Aug/2004:20:30:46]
----------------------------------
En mode HTTP uniquement, il est possible de remplacer certains en-têtes dans la
requête et/ou la réponse à partir d'expressions régulières. Il est également
-possible de bloquer certaines requêtes en fonction du contenu des en-têtes ou de
-la requête. Une limitation cependant : les en-têtes fournis au milieu de
+possible de bloquer certaines requêtes en fonction du contenu des en-têtes ou
+de la requête. Une limitation cependant : les en-têtes fournis au milieu de
connexions persistentes (keep-alive) ne sont pas vus car ils sont considérés
comme faisant partie des échanges de données consécutifs à la première requête.
Les données ne sont pas affectées, ceci ne s'applique qu'aux en-têtes.
@@ -1517,14 +1573,14 @@ puisse corriger le nom du cookie dans toutes les futures requêtes.
4.5) Protection contre les fuites d'informations du serveur
-----------------------------------------------------------
-Dans les versions 1.1.28 et 1.2.1, une nouvelle option 'checkcache' a été créée.
-Elle sert à inspecter minutieusement les entêtes 'Cache-control', 'Pragma', et
-'Set-cookie' dans les réponses serveur pour déterminer s'il y a un risque de
-cacher un cookie sur un proxy côté client. Quand cette option est activée, les
-seules réponses qui peuvent être retournées au client sont :
+Dans les versions 1.1.28 et 1.2.1, une nouvelle option 'checkcache' a été
+créée. Elle sert à inspecter minutieusement les entêtes 'Cache-control',
+'Pragma', et 'Set-cookie' dans les réponses serveur pour déterminer s'il y a
+un risque de cacher un cookie sur un proxy côté client. Quand cette option est
+activée, les seules réponses qui peuvent être retournées au client sont :
- toutes celles qui n'ont pas d'entête 'Set-cookie' ;
- toutes celles qui ont un code de retour autre que 200, 203, 206, 300, 301,
- 410, sauf si le server a positionné un entête 'Cache-control: public' ;
+ 410, sauf si le serveur a positionné un entête 'Cache-control: public' ;
- celles qui font suite à une requête POST, sauf si le serveur a positionné
un entête 'Cache-control: public' ;
- celles qui ont un entête 'Pragma: no-cache' ;
@@ -1557,7 +1613,7 @@ Certaines situations conduisent à retourner une erreur HTTP au client :
Un message d'erreur succint tiré de la RFC accompagne ces codes de retour.
Cependant, en fonction du type de clientèle, on peut préférer retourner des
-pages personnalisées. Ceci est possible par le biais de la commande "errorloc" :
+pages personnalisées. Ceci est possible par le biais de la commande "errorloc":
errorloc <code_HTTP> <location>
@@ -1595,9 +1651,9 @@ dès que vous savez que vos clients supportent le code de retour HTTP 303.
4.7) Changement des valeurs par défaut
--------------------------------------
-Dans la version 1.1.22 est apparue la notion de valeurs par défaut, ce qui évite
-de répéter des paramètres communs à toutes les instances, tels que les timeouts,
-adresses de log, modes de fonctionnement, etc.
+Dans la version 1.1.22 est apparue la notion de valeurs par défaut, ce qui
+évite de répéter des paramètres communs à toutes les instances, tels que les
+timeouts, adresses de log, modes de fonctionnement, etc.
Les valeurs par défaut sont positionnées dans la dernière section 'defaults'
précédent l'instance qui les utilisera. On peut donc mettre autant de sections
diff --git a/haproxy.c b/haproxy.c
index 63822e503..301ad25e9 100644
--- a/haproxy.c
+++ b/haproxy.c
@@ -77,7 +77,7 @@
#include "include/appsession.h"
#define HAPROXY_VERSION "1.2.5"
-#define HAPROXY_DATE "2005/04/24"
+#define HAPROXY_DATE "2005/04/30"
/* this is for libc5 for example */
#ifndef TCP_NODELAY
@@ -255,9 +255,9 @@ int strlcpy2(char *dst, const char *src, int size) {
#define sizeof_session sizeof(struct session)
#define sizeof_buffer sizeof(struct buffer)
#define sizeof_fdtab sizeof(struct fdtab)
-#define sizeof_curappsession CAPTURE_LEN /* current_session pool */
#define sizeof_requri REQURI_LEN
#define sizeof_capture CAPTURE_LEN
+#define sizeof_curappsession CAPTURE_LEN /* current_session pool */
#define sizeof_appsess sizeof(struct appsessions)
/* different possible states for the sockets */
@@ -287,6 +287,11 @@ int strlcpy2(char *dst, const char *src, int size) {
#define POLL_LOOP_ACTION_RUN 1
#define POLL_LOOP_ACTION_CLEAN 2
+/* poll mechanisms available */
+#define POLL_USE_SELECT (1<<0)
+#define POLL_USE_POLL (1<<1)
+#define POLL_USE_EPOLL (1<<2)
+
/* bits for proxy->options */
#define PR_O_REDISP 0x00000001 /* allow reconnection to dispatch in case of errors */
#define PR_O_TRANSP 0x00000002 /* transparent mode : use original DEST as dispatch */
@@ -622,8 +627,7 @@ static struct {
fd_set *StaticReadEvent,
*StaticWriteEvent;
-int cfg_use_epoll = 0; /* use epoll() instead of select() ? */
-int cfg_use_poll = 0; /* use poll() instead of select() ? */
+int cfg_polling_mechanism = 0; /* POLL_USE_{SELECT|POLL|EPOLL} */
void **pool_session = NULL,
**pool_buffer = NULL,
@@ -823,10 +827,10 @@ void usage(char *name) {
" -N sets the default, per-proxy maximum # of connections (%d)\n"
" -p writes pids of all children to this file\n"
#if defined(ENABLE_EPOLL)
- " -E tries to use epoll() instead of select()\n"
+ " -de disables epoll() usage even when available\n"
#endif
#if defined(ENABLE_POLL)
- " -P tries to use poll() instead of select()\n"
+ " -dp disables poll() usage even when available\n"
#endif
"\n",
name, DEFAULT_MAXCONN, cfg_maxpconn);
@@ -5191,7 +5195,6 @@ int select_loop(int action) {
}
#endif
-
if (next_time > 0) { /* FIXME */
/* Convert to timeval */
/* to avoid eventual select loops due to timer precision */
@@ -5247,10 +5250,10 @@ int select_loop(int action) {
*/
if (fdtab[fd].state == FD_STCLOSE)
continue;
-
+
if (FD_ISSET(fd, ReadEvent))
fdtab[fd].read(fd);
-
+
if (FD_ISSET(fd, WriteEvent))
fdtab[fd].write(fd);
}
@@ -5462,6 +5465,7 @@ void dump(int sig) {
}
}
+#ifdef DEBUG_MEMORY
static void fast_stop(void)
{
struct proxy *p;
@@ -5494,6 +5498,7 @@ void sig_term(int sig) {
/* If we are killed twice, we decide to die*/
signal(sig, SIG_DFL);
}
+#endif
/* returns the pointer to an error in the replacement string, or NULL if OK */
char *chain_regex(struct hdr_exp **head, regex_t *preg, int action, char *replace) {
@@ -5535,6 +5540,12 @@ int cfg_parse_global(char *file, int linenum, char **args) {
else if (!strcmp(args[0], "debug")) {
global.mode |= MODE_DEBUG;
}
+ else if (!strcmp(args[0], "noepoll")) {
+ cfg_polling_mechanism &= ~POLL_USE_EPOLL;
+ }
+ else if (!strcmp(args[0], "nopoll")) {
+ cfg_polling_mechanism &= ~POLL_USE_POLL;
+ }
else if (!strcmp(args[0], "quiet")) {
global.mode |= MODE_QUIET;
}
@@ -7139,6 +7150,14 @@ void init(int argc, char **argv) {
tmp++;
}
+ cfg_polling_mechanism = POLL_USE_SELECT; /* select() is always available */
+#if defined(ENABLE_POLL)
+ cfg_polling_mechanism |= POLL_USE_POLL;
+#endif
+#if defined(ENABLE_EPOLL)
+ cfg_polling_mechanism |= POLL_USE_EPOLL;
+#endif
+
pid = getpid();
progname = *argv;
while ((tmp = strchr(progname, '/')) != NULL)
@@ -7157,12 +7176,12 @@ void init(int argc, char **argv) {
exit(0);
}
#if defined(ENABLE_EPOLL)
- else if (*flag == 'E')
- cfg_use_epoll = 1;
+ else if (*flag == 'd' && flag[1] == 'e')
+ cfg_polling_mechanism &= ~POLL_USE_EPOLL;
#endif
#if defined(ENABLE_POLL)
- else if (*flag == 'P')
- cfg_use_poll = 1;
+ else if (*flag == 'd' && flag[1] == 'p')
+ cfg_polling_mechanism &= ~POLL_USE_POLL;
#endif
else if (*flag == 'V')
arg_mode |= MODE_VERBOSE;
@@ -7501,8 +7520,10 @@ int main(int argc, char **argv) {
signal(SIGQUIT, dump);
signal(SIGUSR1, sig_soft_stop);
signal(SIGHUP, sig_dump_state);
+#ifdef DEBUG_MEMORY
signal(SIGINT, sig_int);
signal(SIGTERM, sig_term);
+#endif
/* on very high loads, a sigpipe sometimes happen just between the
* getsockopt() which tells "it's OK to write", and the following write :-(
@@ -7588,34 +7609,37 @@ int main(int argc, char **argv) {
}
#if defined(ENABLE_EPOLL)
- if (cfg_use_epoll) {
+ if (cfg_polling_mechanism & POLL_USE_EPOLL) {
if (epoll_loop(POLL_LOOP_ACTION_INIT)) {
epoll_loop(POLL_LOOP_ACTION_RUN);
epoll_loop(POLL_LOOP_ACTION_CLEAN);
+ cfg_polling_mechanism &= POLL_USE_EPOLL;
}
else {
- Warning("epoll() is not available. Trying poll() or select() instead.\n");
- cfg_use_epoll = 0;
+ Warning("epoll() is not available. Using poll()/select() instead.\n");
+ cfg_polling_mechanism &= ~POLL_USE_EPOLL;
}
}
#endif
#if defined(ENABLE_POLL)
- if (cfg_use_poll) {
+ if (cfg_polling_mechanism & POLL_USE_POLL) {
if (poll_loop(POLL_LOOP_ACTION_INIT)) {
poll_loop(POLL_LOOP_ACTION_RUN);
poll_loop(POLL_LOOP_ACTION_CLEAN);
+ cfg_polling_mechanism &= POLL_USE_POLL;
}
else {
Warning("poll() is not available. Using select() instead.\n");
- cfg_use_poll = 0;
+ cfg_polling_mechanism &= ~POLL_USE_POLL;
}
}
#endif
- if (!cfg_use_epoll && !cfg_use_poll) {
+ if (cfg_polling_mechanism & POLL_USE_SELECT) {
if (select_loop(POLL_LOOP_ACTION_INIT)) {
select_loop(POLL_LOOP_ACTION_RUN);
select_loop(POLL_LOOP_ACTION_CLEAN);
+ cfg_polling_mechanism &= POLL_USE_SELECT;
}
}