[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.
This commit is contained in:
Willy Tarreau 2008-11-23 19:53:55 +01:00
parent 0a5d5ddeb9
commit f54f8bdd8d
5 changed files with 20 additions and 5 deletions

View File

@ -3,7 +3,7 @@
This file defines everything related to sessions. This file defines everything related to sessions.
Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, version 2.1 License as published by the Free Software Foundation, version 2.1
@ -27,6 +27,7 @@
#include <types/session.h> #include <types/session.h>
extern struct pool_head *pool2_session; extern struct pool_head *pool2_session;
extern struct list sessions;
void session_free(struct session *s); void session_free(struct session *s);

View File

@ -3,7 +3,7 @@
This file defines everything related to sessions. This file defines everything related to sessions.
Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, version 2.1 License as published by the Free Software Foundation, version 2.1
@ -152,6 +152,7 @@ enum {
* server should eventually be released. * server should eventually be released.
*/ */
struct session { struct session {
struct list list; /* position in global sessions list */
struct task *task; /* the task associated with this session */ struct task *task; /* the task associated with this session */
/* application specific below */ /* application specific below */
struct proxy *fe; /* the proxy this session depends on for the client side */ struct proxy *fe; /* the proxy this session depends on for the client side */

View File

@ -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. * 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 * 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. * to an accept. It tries to accept as many connections as possible.
@ -106,6 +106,8 @@ int event_accept(int fd) {
goto out_close; goto out_close;
} }
LIST_ADDQ(&sessions, &s->list);
s->flags = 0; s->flags = 0;
s->term_trace = 0; s->term_trace = 0;
@ -455,6 +457,7 @@ int event_accept(int fd) {
out_free_task: out_free_task:
pool_free2(pool2_task, t); pool_free2(pool2_task, t);
out_free_session: out_free_session:
LIST_DEL(&s->list);
pool_free2(pool2_session, s); pool_free2(pool2_session, s);
out_close: out_close:
close(cfd); close(cfd);

View File

@ -411,12 +411,15 @@ int uxst_event_accept(int fd) {
return 0; return 0;
} }
LIST_ADDQ(&sessions, &s->list);
s->flags = 0; s->flags = 0;
s->term_trace = 0; s->term_trace = 0;
if ((t = pool_alloc2(pool2_task)) == NULL) { if ((t = pool_alloc2(pool2_task)) == NULL) {
Alert("out of memory in uxst_event_accept().\n"); Alert("out of memory in uxst_event_accept().\n");
close(cfd); close(cfd);
LIST_DEL(&s->list);
pool_free2(pool2_session, s); pool_free2(pool2_session, s);
return 0; return 0;
} }
@ -428,6 +431,7 @@ int uxst_event_accept(int fd) {
Alert("accept(): not enough free sockets. Raise -n argument. Giving up.\n"); Alert("accept(): not enough free sockets. Raise -n argument. Giving up.\n");
close(cfd); close(cfd);
pool_free2(pool2_task, t); pool_free2(pool2_task, t);
LIST_DEL(&s->list);
pool_free2(pool2_session, s); pool_free2(pool2_session, s);
return 0; 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"); Alert("accept(): cannot set the socket in non blocking mode. Giving up\n");
close(cfd); close(cfd);
pool_free2(pool2_task, t); pool_free2(pool2_task, t);
LIST_DEL(&s->list);
pool_free2(pool2_session, s); pool_free2(pool2_session, s);
return 0; return 0;
} }
@ -467,6 +472,7 @@ int uxst_event_accept(int fd) {
if ((s->req = pool_alloc2(pool2_buffer)) == NULL) { /* no memory */ if ((s->req = pool_alloc2(pool2_buffer)) == NULL) { /* no memory */
close(cfd); /* nothing can be done for this fd without memory */ close(cfd); /* nothing can be done for this fd without memory */
pool_free2(pool2_task, t); pool_free2(pool2_task, t);
LIST_DEL(&s->list);
pool_free2(pool2_session, s); pool_free2(pool2_session, s);
return 0; return 0;
} }
@ -475,6 +481,7 @@ int uxst_event_accept(int fd) {
pool_free2(pool2_buffer, s->req); pool_free2(pool2_buffer, s->req);
close(cfd); /* nothing can be done for this fd without memory */ close(cfd); /* nothing can be done for this fd without memory */
pool_free2(pool2_task, t); pool_free2(pool2_task, t);
LIST_DEL(&s->list);
pool_free2(pool2_session, s); pool_free2(pool2_session, s);
return 0; return 0;
} }
@ -577,7 +584,7 @@ static int process_uxst_cli(struct session *t)
buffer_shutr(req); buffer_shutr(req);
t->cli_state = CL_STSHUTR; t->cli_state = CL_STSHUTR;
return 1; return 1;
} }
/* last server read and buffer empty */ /* last server read and buffer empty */
else if ((s == SV_STSHUTR || s == SV_STCLOSE) && (rep->flags & BF_EMPTY)) { else if ((s == SV_STSHUTR || s == SV_STCLOSE) && (rep->flags & BF_EMPTY)) {
EV_FD_CLR(t->cli_fd, DIR_WR); 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; t->flags |= SN_FINST_D;
} }
return 1; return 1;
} }
/* write timeout */ /* write timeout */
else if (tick_is_expired(rep->wex, now_ms)) { else if (tick_is_expired(rep->wex, now_ms)) {
EV_FD_CLR(t->cli_fd, DIR_WR); EV_FD_CLR(t->cli_fd, DIR_WR);

View File

@ -26,6 +26,7 @@
struct pool_head *pool2_session; struct pool_head *pool2_session;
struct list sessions;
/* /*
* frees the context associated to a session. It must have been removed first. * 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_requri, txn->uri);
pool_free2(pool2_capture, txn->cli_cookie); pool_free2(pool2_capture, txn->cli_cookie);
pool_free2(pool2_capture, txn->srv_cookie); pool_free2(pool2_capture, txn->srv_cookie);
LIST_DEL(&s->list);
pool_free2(pool2_session, s); pool_free2(pool2_session, s);
/* We may want to free the maximum amount of pools if the proxy is stopping */ /* 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. */ /* perform minimal intializations, report 0 in case of error, 1 if OK. */
int init_session() int init_session()
{ {
LIST_INIT(&sessions);
pool2_session = create_pool("session", sizeof(struct session), MEM_F_SHARED); pool2_session = create_pool("session", sizeof(struct session), MEM_F_SHARED);
return pool2_session != NULL; return pool2_session != NULL;
} }