From: Willy Tarreau Date: Wed, 7 Sep 2011 21:21:03 +0000 (+0200) Subject: [MEDIUM] stats: offer the possibility to kill a session from the CLI X-Git-Tag: v1.5-dev8~114 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a295edc51c970ea83f1a61139920c0545f670b4c;p=thirdparty%2Fhaproxy.git [MEDIUM] stats: offer the possibility to kill a session from the CLI It's now possible to issue "shutdown session 0xXXXXXXXX" and have this session immediately killed. Useful for long-running fantoms. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index a8647467bb..a1fa9baf57 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -9830,6 +9830,14 @@ shutdown frontend This command is restricted and can only be issued on sockets configured for level "admin". +shutdown session + Immediately terminate the session matching the specified session identifier. + This identifier is the first field at the beginning of the lines in the dumps + of "show sess" (it corresponds to the session pointer). This can be used to + terminate a long-running session without waiting for a timeout or when an + endless transfer is ongoing. Such terminated sessions are reported with a 'K' + flag in the logs. + /* * Local variables: * fill-column: 79 diff --git a/src/dumpstats.c b/src/dumpstats.c index 3c21906917..f388e1c6de 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -82,11 +82,11 @@ static const char stats_sock_usage_msg[] = " get weight : report a server's current weight\n" " set weight : change a server's weight\n" " set timeout : change a timeout setting\n" - " disable : put a server or frontend in maintenance mode\n" - " enable : re-enable a server or frontend which is in maintenance mode\n" - " shutdown : irreversibly stop a frontend (eg: to release listening ports)\n" " set maxconn : change a maxconn setting\n" " set rate-limit : change a rate limiting value\n" + " disable : put a server or frontend in maintenance mode\n" + " enable : re-enable a server or frontend which is in maintenance mode\n" + " shutdown : kill a session or a frontend (eg:to release listening ports)\n" ""; static const char stats_permission_denied_msg[] = @@ -1311,8 +1311,41 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line) stop_proxy(px); return 1; } + else if (strcmp(args[1], "session") == 0) { + struct session *sess, *ptr; + + if (s->listener->perm.ux.level < ACCESS_LVL_ADMIN) { + si->applet.ctx.cli.msg = stats_permission_denied_msg; + si->applet.st0 = STAT_CLI_PRINT; + return 1; + } + + if (!*args[2]) { + si->applet.ctx.cli.msg = "Session pointer expected (use 'show sess').\n"; + si->applet.st0 = STAT_CLI_PRINT; + return 1; + } + + ptr = (void *)strtoul(args[2], NULL, 0); + + /* first, look for the requested session in the session table */ + list_for_each_entry(sess, &sessions, list) { + if (sess == ptr) + break; + } + + /* do we have the session ? */ + if (sess != ptr) { + si->applet.ctx.cli.msg = "No such session (use 'show sess').\n"; + si->applet.st0 = STAT_CLI_PRINT; + return 1; + } + + session_shutdown(sess, SN_ERR_KILLED); + return 1; + } else { /* unknown "disable" parameter */ - si->applet.ctx.cli.msg = "'shutdown' only supports 'frontend'.\n"; + si->applet.ctx.cli.msg = "'shutdown' only supports 'frontend' and 'session'.\n"; si->applet.st0 = STAT_CLI_PRINT; return 1; }