From: Willy Tarreau Date: Sun, 23 Nov 2008 18:53:55 +0000 (+0100) Subject: [MINOR] maintain a global session list in order to ease debugging X-Git-Tag: v1.3.16-rc1~142 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f54f8bdd8d2a40417e0fa03bdf8dfa5a4de73cfc;p=thirdparty%2Fhaproxy.git [MINOR] maintain a global session list in order to ease debugging Now the global variable 'sessions' will be a dual-linked list of all known sessions. The list element is set at the beginning of the session so that it's easier to follow them all with gdb. --- diff --git a/include/proto/session.h b/include/proto/session.h index cdd01bf395..0357757102 100644 --- a/include/proto/session.h +++ b/include/proto/session.h @@ -3,7 +3,7 @@ This file defines everything related to sessions. Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 2.1 @@ -27,6 +27,7 @@ #include extern struct pool_head *pool2_session; +extern struct list sessions; void session_free(struct session *s); diff --git a/include/types/session.h b/include/types/session.h index 1177924c57..a92949bc85 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -3,7 +3,7 @@ This file defines everything related to sessions. Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 2.1 @@ -152,6 +152,7 @@ enum { * server should eventually be released. */ struct session { + struct list list; /* position in global sessions list */ struct task *task; /* the task associated with this session */ /* application specific below */ struct proxy *fe; /* the proxy this session depends on for the client side */ diff --git a/src/client.c b/src/client.c index d56a33ec0d..78387a1544 100644 --- a/src/client.c +++ b/src/client.c @@ -53,7 +53,7 @@ void get_frt_addr(struct session *s) /* * FIXME: This should move to the STREAM_SOCK code then split into TCP and HTTP. */ - + /* * this function is called on a read event from a listen socket, corresponding * to an accept. It tries to accept as many connections as possible. @@ -106,6 +106,8 @@ int event_accept(int fd) { goto out_close; } + LIST_ADDQ(&sessions, &s->list); + s->flags = 0; s->term_trace = 0; @@ -455,6 +457,7 @@ int event_accept(int fd) { out_free_task: pool_free2(pool2_task, t); out_free_session: + LIST_DEL(&s->list); pool_free2(pool2_session, s); out_close: close(cfd); diff --git a/src/proto_uxst.c b/src/proto_uxst.c index dc2b93388b..ee684a60d4 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -411,12 +411,15 @@ int uxst_event_accept(int fd) { return 0; } + LIST_ADDQ(&sessions, &s->list); + s->flags = 0; s->term_trace = 0; if ((t = pool_alloc2(pool2_task)) == NULL) { Alert("out of memory in uxst_event_accept().\n"); close(cfd); + LIST_DEL(&s->list); pool_free2(pool2_session, s); return 0; } @@ -428,6 +431,7 @@ int uxst_event_accept(int fd) { Alert("accept(): not enough free sockets. Raise -n argument. Giving up.\n"); close(cfd); pool_free2(pool2_task, t); + LIST_DEL(&s->list); pool_free2(pool2_session, s); return 0; } @@ -436,6 +440,7 @@ int uxst_event_accept(int fd) { Alert("accept(): cannot set the socket in non blocking mode. Giving up\n"); close(cfd); pool_free2(pool2_task, t); + LIST_DEL(&s->list); pool_free2(pool2_session, s); return 0; } @@ -467,6 +472,7 @@ int uxst_event_accept(int fd) { if ((s->req = pool_alloc2(pool2_buffer)) == NULL) { /* no memory */ close(cfd); /* nothing can be done for this fd without memory */ pool_free2(pool2_task, t); + LIST_DEL(&s->list); pool_free2(pool2_session, s); return 0; } @@ -475,6 +481,7 @@ int uxst_event_accept(int fd) { pool_free2(pool2_buffer, s->req); close(cfd); /* nothing can be done for this fd without memory */ pool_free2(pool2_task, t); + LIST_DEL(&s->list); pool_free2(pool2_session, s); return 0; } @@ -577,7 +584,7 @@ static int process_uxst_cli(struct session *t) buffer_shutr(req); t->cli_state = CL_STSHUTR; return 1; - } + } /* last server read and buffer empty */ else if ((s == SV_STSHUTR || s == SV_STCLOSE) && (rep->flags & BF_EMPTY)) { EV_FD_CLR(t->cli_fd, DIR_WR); @@ -607,7 +614,7 @@ static int process_uxst_cli(struct session *t) t->flags |= SN_FINST_D; } return 1; - } + } /* write timeout */ else if (tick_is_expired(rep->wex, now_ms)) { EV_FD_CLR(t->cli_fd, DIR_WR); diff --git a/src/session.c b/src/session.c index fb7de4a3b5..8a46962974 100644 --- a/src/session.c +++ b/src/session.c @@ -26,6 +26,7 @@ struct pool_head *pool2_session; +struct list sessions; /* * frees the context associated to a session. It must have been removed first. @@ -74,6 +75,7 @@ void session_free(struct session *s) pool_free2(pool2_requri, txn->uri); pool_free2(pool2_capture, txn->cli_cookie); pool_free2(pool2_capture, txn->srv_cookie); + LIST_DEL(&s->list); pool_free2(pool2_session, s); /* We may want to free the maximum amount of pools if the proxy is stopping */ @@ -92,6 +94,7 @@ void session_free(struct session *s) /* perform minimal intializations, report 0 in case of error, 1 if OK. */ int init_session() { + LIST_INIT(&sessions); pool2_session = create_pool("session", sizeof(struct session), MEM_F_SHARED); return pool2_session != NULL; }