* released 1.2.1-pre1

* send an EMERG log when no server is available for a given proxy
* added the '-c' command line option to syntactically check the
  configuration file without starting the service.
This commit is contained in:
willy tarreau 2005-12-18 00:48:48 +01:00
parent 8a86dbf30e
commit dd07e97447
3 changed files with 81 additions and 27 deletions

View File

@ -1,6 +1,11 @@
ChangeLog : ChangeLog :
=========== ===========
2004/04/18 : 1.2.1 (1.1.28)
- send an EMERG log when no server is available for a given proxy
- added the '-c' command line option to syntactically check the
configuration file without starting the service.
2003/11/09 : 1.2.0 2003/11/09 : 1.2.0
- the same as 1.1.27 + IPv6 support on the client side - the same as 1.1.27 + IPv6 support on the client side

36
TODO
View File

@ -80,17 +80,25 @@ ok>
5) implémenter "balance source" pour faire un hash sur la source. 5) implémenter "balance source" pour faire un hash sur la source.
permettre de spécifier un masque sur lequel s'applique le hachage, permettre de spécifier un masque sur lequel s'applique le hachage,
ainsi qu'une option pour hacher en fonction de l'adresse dans le ainsi qu'une option pour hacher en fonction de l'adresse dans le
champ "x-forwarded-for". champ "x-forwarded-for". Problème pour le support des pannes: ce
type de hash est utile là où la persistence par cookie ne peut pas
s'appliquer, donc comment faire pour assurer un maximum de persistence
en cas de panne ?
6) possibilité d'un process séparé par listen : 6) possibilité d'un process séparé par listen :
listen XXX listen XXX
fork [ group_id ] fork [ group_id ]
le fait de spécifier group_id fera que toutes les instances utilisant le même le fait de spécifier group_id fera que toutes les instances utilisant le
identifiant de groupe seront gérées par un même processus. même identifiant de groupe seront gérées par un même processus.
-> plus souple et plus compréhensible de faire des sections par processus, -> plus souple et plus compréhensible de faire des sections par processus,
ce qui résoud également le cas ci-dessous ce qui résoud également le cas ci-dessous. Ex:
process_group X
nbproc X
uid X
chroot X
listen ...
7) gérer un chroot/uid/gid différents par process : 7) gérer un chroot/uid/gid différents par process :
listen XXX listen XXX
@ -111,3 +119,23 @@ ok> de forcer la m
ok> ex: option httpchk -> OPTIONS / HTTP/1.0 ok> ex: option httpchk -> OPTIONS / HTTP/1.0
ok> option httpchk /test -> OPTIONS /test HTTP/1.0 ok> option httpchk /test -> OPTIONS /test HTTP/1.0
ok> option httpchk HEAD / HTTP/1.0\nHost:\ www -> tel quel ok> option httpchk HEAD / HTTP/1.0\nHost:\ www -> tel quel
Todo for 1.1
============
* "no more server" alert
* config check
- anti-flapping
Todo for 1.2
============
- direct <server> <regex> <match>
- new config syntax allowing braces to be able to shorten lines
- insert/learn/check/log unique request ID, and add the ability
to block bad responses.
- IPv6 :
* listen [ip4.ip4.ip4.ip4]:port[-port]
* listen [ip6::...ip6]/port[-port]
- server xxx ipv4 | ipv4: | ipv4:port[-port] | ipv6/ | ipv6/port[-port]
- weighted round robin

View File

@ -1,6 +1,6 @@
/* /*
* HA-Proxy : High Availability-enabled HTTP/TCP proxy * HA-Proxy : High Availability-enabled HTTP/TCP proxy
* 2000-2003 - Willy Tarreau - willy AT meta-x DOT org. * 2000-2004 - Willy Tarreau - willy AT meta-x DOT org.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -53,8 +53,8 @@
#include <linux/netfilter_ipv4.h> #include <linux/netfilter_ipv4.h>
#endif #endif
#define HAPROXY_VERSION "1.1.27-ipv6" #define HAPROXY_VERSION "1.2.1"
#define HAPROXY_DATE "2003/11/09" #define HAPROXY_DATE "2004/04/18"
/* this is for libc5 for example */ /* this is for libc5 for example */
#ifndef TCP_NODELAY #ifndef TCP_NODELAY
@ -293,6 +293,7 @@ int strlcpy2(char *dst, const char *src, int size) {
#define MODE_LOG 4 #define MODE_LOG 4
#define MODE_DAEMON 8 #define MODE_DAEMON 8
#define MODE_QUIET 16 #define MODE_QUIET 16
#define MODE_CHECK 32
/* server flags */ /* server flags */
#define SRV_RUNNING 1 /* the server is UP */ #define SRV_RUNNING 1 /* the server is UP */
@ -537,6 +538,9 @@ static regmatch_t pmatch[MAX_MATCH]; /* rm_so, rm_eo for regular expressions */
/* this is used to drain data, and as a temporary buffer for sprintf()... */ /* this is used to drain data, and as a temporary buffer for sprintf()... */
static char trash[BUFSIZE]; static char trash[BUFSIZE];
const int zero = 0;
const int one = 1;
/* /*
* Syslog facilities and levels. Conforming to RFC3164. * Syslog facilities and levels. Conforming to RFC3164.
*/ */
@ -665,7 +669,7 @@ int process_session(struct task *t);
void display_version() { void display_version() {
printf("HA-Proxy version " HAPROXY_VERSION " " HAPROXY_DATE"\n"); printf("HA-Proxy version " HAPROXY_VERSION " " HAPROXY_DATE"\n");
printf("Copyright 2000-2003 Willy Tarreau <willy AT meta-x DOT org>\n\n"); printf("Copyright 2000-2004 Willy Tarreau <w@w.ods.org>\n\n");
} }
/* /*
@ -687,6 +691,7 @@ void usage(char *name) {
#endif #endif
" -D goes daemon ; implies -q\n" " -D goes daemon ; implies -q\n"
" -q quiet mode : don't display messages\n" " -q quiet mode : don't display messages\n"
" -c check mode : only check config file and exit\n"
" -n sets the maximum total # of connections (%d)\n" " -n sets the maximum total # of connections (%d)\n"
" -N sets the default, per-proxy maximum # of connections (%d)\n" " -N sets the default, per-proxy maximum # of connections (%d)\n"
" -p writes pids of all children to this file\n\n", " -p writes pids of all children to this file\n\n",
@ -1446,7 +1451,6 @@ static inline struct server *find_server(struct proxy *px) {
* it's OK, -1 if it's impossible. * it's OK, -1 if it's impossible.
*/ */
int connect_server(struct session *s) { int connect_server(struct session *s) {
int one = 1;
int fd; int fd;
// fprintf(stderr,"connect_server : s=%p\n",s); // fprintf(stderr,"connect_server : s=%p\n",s);
@ -2033,7 +2037,6 @@ int event_accept(int fd) {
struct session *s; struct session *s;
struct task *t; struct task *t;
int cfd; int cfd;
int one = 1;
while (p->nbconn < p->maxconn) { while (p->nbconn < p->maxconn) {
struct sockaddr_storage addr; struct sockaddr_storage addr;
@ -3833,7 +3836,6 @@ int process_chk(struct task *t) {
struct server *s = t->context; struct server *s = t->context;
struct sockaddr_in sa; struct sockaddr_in sa;
int fd = s->curfd; int fd = s->curfd;
int one = 1;
//fprintf(stderr, "process_chk: task=%p\n", t); //fprintf(stderr, "process_chk: task=%p\n", t);
@ -3899,15 +3901,17 @@ int process_chk(struct task *t) {
if (s->health > s->rise) if (s->health > s->rise)
s->health--; /* still good */ s->health--; /* still good */
else { else {
if (s->health == s->rise) {
if (!(global.mode & MODE_QUIET))
Warning("server %s/%s DOWN.\n", s->proxy->id, s->id);
send_log(s->proxy, LOG_ALERT, "Server %s/%s is DOWN.\n", s->proxy->id, s->id);
}
s->health = 0; /* failure */
s->state &= ~SRV_RUNNING; s->state &= ~SRV_RUNNING;
if (s->health == s->rise) {
Warning("Server %s/%s DOWN.\n", s->proxy->id, s->id);
send_log(s->proxy, LOG_ALERT, "Server %s/%s is DOWN.\n", s->proxy->id, s->id);
if (find_server(s->proxy) == NULL) {
Alert("Proxy %s has no server available !\n", s->proxy->id);
send_log(s->proxy, LOG_EMERG, "Proxy %s has no server available !\n", s->proxy->id);
}
}
s->health = 0; /* failure */
} }
//fprintf(stderr, "process_chk: 7\n"); //fprintf(stderr, "process_chk: 7\n");
@ -3922,8 +3926,7 @@ int process_chk(struct task *t) {
s->health++; /* was bad, stays for a while */ s->health++; /* was bad, stays for a while */
if (s->health >= s->rise) { if (s->health >= s->rise) {
if (s->health == s->rise) { if (s->health == s->rise) {
if (!(global.mode & MODE_QUIET)) Warning("server %s/%s UP.\n", s->proxy->id, s->id);
Warning("server %s/%s UP.\n", s->proxy->id, s->id);
send_log(s->proxy, LOG_NOTICE, "Server %s/%s is UP.\n", s->proxy->id, s->id); send_log(s->proxy, LOG_NOTICE, "Server %s/%s is UP.\n", s->proxy->id, s->id);
} }
@ -3941,15 +3944,19 @@ int process_chk(struct task *t) {
if (s->health > s->rise) if (s->health > s->rise)
s->health--; /* still good */ s->health--; /* still good */
else { else {
if (s->health == s->rise) { s->state &= ~SRV_RUNNING;
if (!(global.mode & MODE_QUIET))
Warning("server %s/%s DOWN.\n", s->proxy->id, s->id);
if (s->health == s->rise) {
Warning("Server %s/%s DOWN.\n", s->proxy->id, s->id);
send_log(s->proxy, LOG_ALERT, "Server %s/%s is DOWN.\n", s->proxy->id, s->id); send_log(s->proxy, LOG_ALERT, "Server %s/%s is DOWN.\n", s->proxy->id, s->id);
if (find_server(s->proxy) == NULL) {
Alert("Proxy %s has no server available !\n", s->proxy->id);
send_log(s->proxy, LOG_EMERG, "Proxy %s has no server available !\n", s->proxy->id);
}
} }
s->health = 0; /* failure */ s->health = 0; /* failure */
s->state &= ~SRV_RUNNING;
} }
s->curfd = -1; s->curfd = -1;
//FD_CLR(fd, StaticWriteEvent); //FD_CLR(fd, StaticWriteEvent);
@ -4280,6 +4287,12 @@ void sig_dump_state(int sig) {
} }
s = s->next; s = s->next;
} }
if (find_server(p) == NULL) {
Warning("SIGHUP: proxy %s has no server available !\n", p);
send_log(p, LOG_NOTICE, "SIGHUP: proxy %s has no server available !\n", p);
}
p = p->next; p = p->next;
} }
signal(sig, sig_dump_state); signal(sig, sig_dump_state);
@ -5691,7 +5704,7 @@ void init(int argc, char **argv) {
int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */ int cfg_maxconn = 0; /* # of simultaneous connections, (-n) */
if (1<<INTBITS != sizeof(int)*8) { if (1<<INTBITS != sizeof(int)*8) {
qfprintf(stderr, fprintf(stderr,
"Error: wrong architecture. Recompile so that sizeof(int)=%d\n", "Error: wrong architecture. Recompile so that sizeof(int)=%d\n",
sizeof(int)*8); sizeof(int)*8);
exit(1); exit(1);
@ -5716,6 +5729,8 @@ void init(int argc, char **argv) {
} }
else if (*flag == 'd') else if (*flag == 'd')
arg_mode |= MODE_DEBUG; arg_mode |= MODE_DEBUG;
else if (*flag == 'c')
arg_mode |= MODE_CHECK;
else if (*flag == 'D') else if (*flag == 'D')
arg_mode |= MODE_DAEMON | MODE_QUIET; arg_mode |= MODE_DAEMON | MODE_QUIET;
else if (*flag == 'q') else if (*flag == 'q')
@ -5745,6 +5760,8 @@ void init(int argc, char **argv) {
argv++; argc--; argv++; argc--;
} }
global.mode = (arg_mode & (MODE_DAEMON | MODE_QUIET | MODE_DEBUG));
if (!cfg_cfgfile) if (!cfg_cfgfile)
usage(old_argv); usage(old_argv);
@ -5755,6 +5772,11 @@ void init(int argc, char **argv) {
exit(1); exit(1);
} }
if (arg_mode & MODE_CHECK) {
qfprintf(stdout, "Configuration file is valid : %s\n", cfg_cfgfile);
exit(0);
}
if (cfg_maxconn > 0) if (cfg_maxconn > 0)
global.maxconn = cfg_maxconn; global.maxconn = cfg_maxconn;
@ -5814,7 +5836,6 @@ void init(int argc, char **argv) {
int start_proxies() { int start_proxies() {
struct proxy *curproxy; struct proxy *curproxy;
struct listener *listener; struct listener *listener;
int one = 1;
int fd; int fd;
for (curproxy = proxy; curproxy != NULL; curproxy = curproxy->next) { for (curproxy = proxy; curproxy != NULL; curproxy = curproxy->next) {