$ echo "show table http_proxy" | socat stdio /tmp/sock1
>>> # table: http_proxy, type: ip, size:204800, used:1
+disable frontend <frontend>
+ Mark the frontend as temporarily stopped. This corresponds to the mode which
+ is used during a soft restart : the frontend releases the port but can be
+ enabled again if needed. This should be used with care as some non-Linux OSes
+ are unable to enable it back. This is intended to be used in environments
+ where stopping a proxy is not even imaginable but a misconfigured proxy must
+ be fixed. That way it's possible to release the port and bind it into another
+ process to restore operations. The frontend will appear with status "STOP"
+ on the stats page.
+
+ The frontend may be specified either by its name or by its numeric ID,
+ prefixed with a sharp ('#').
+
+ This command is restricted and can only be issued on sockets configured for
+ level "admin".
+
disable server <backend>/<server>
Mark the server DOWN for maintenance. In this mode, no more checks will be
performed on the server until it leaves maintenance.
This command is restricted and can only be issued on sockets configured for
level "admin".
+enable frontend <frontend>
+ Resume a frontend which was temporarily stopped. It is possible that some of
+ the listening ports won't be able to bind anymore (eg: if another process
+ took them since the 'disable frontend' operation). If this happens, an error
+ is displayed. Some operating systems might not be able to resume a frontend
+ which was disabled.
+
+ The frontend may be specified either by its name or by its numeric ID,
+ prefixed with a sharp ('#').
+
+ This command is restricted and can only be issued on sockets configured for
+ level "admin".
+
enable server <backend>/<server>
If the server was previously marked as DOWN for maintenance, this marks the
server UP and checks are re-enabled.
| fgrep 'key=' | cut -d' ' -f2 | cut -d= -f2 > abusers-ip.txt
( or | awk '/key/{ print a[split($2,a,"=")]; }' )
+shutdown frontend <frontend>
+ Completely delete the specified frontend. All the ports it was bound to will
+ be released. It will not be possible to enable the frontend anymore after
+ this operation. This is intended to be used in environments where stopping a
+ proxy is not even imaginable but a misconfigured proxy must be fixed. That
+ way it's possible to release the port and bind it into another process to
+ restore operations. The frontend will not appear at all on the stats page
+ once it is terminated.
+
+ The frontend may be specified either by its name or by its numeric ID,
+ prefixed with a sharp ('#').
+
+ This command is restricted and can only be issued on sockets configured for
+ level "admin".
+
/*
* Local variables:
* fill-column: 79
" 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 server : set a server in maintenance mode\n"
- " enable server : re-enable a server that was previously in maintenance mode\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"
"";
si->applet.st0 = STAT_CLI_PRINT;
}
+/* Expects to find a frontend named <arg> and returns it, otherwise displays various
+ * adequate error messages and returns NULL. This function also expects the session
+ * level to be admin.
+ */
+static struct proxy *expect_frontend_admin(struct session *s, struct stream_interface *si, const char *arg)
+{
+ struct proxy *px;
+
+ 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 NULL;
+ }
+
+ if (!*arg) {
+ si->applet.ctx.cli.msg = "A frontend name is expected.\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return NULL;
+ }
+
+ px = findproxy(arg, PR_CAP_FE);
+ if (!px) {
+ si->applet.ctx.cli.msg = "No such frontend.\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return NULL;
+ }
+ return px;
+}
+
/* Processes the stats interpreter on the statistics socket. This function is
* called from an applet running in a stream interface. The function returns 1
* if the request was understood, otherwise zero. It sets si->applet.st0 to a value
struct listener *l;
int v;
- if (s->listener->perm.ux.level < ACCESS_LVL_ADMIN) {
- si->applet.ctx.cli.msg = stats_permission_denied_msg;
- si->applet.st0 = STAT_CLI_PRINT;
+ px = expect_frontend_admin(s, si, args[3]);
+ if (!px)
return 1;
- }
-
- if (!*args[3]) {
- si->applet.ctx.cli.msg = "Frontend name expected.\n";
- si->applet.st0 = STAT_CLI_PRINT;
- return 1;
- }
-
- px = findproxy(args[3], PR_CAP_FE);
- if (!px) {
- si->applet.ctx.cli.msg = "No such frontend.\n";
- si->applet.st0 = STAT_CLI_PRINT;
- return 1;
- }
if (!*args[4]) {
si->applet.ctx.cli.msg = "Integer value expected.\n";
return 1;
}
+ else if (strcmp(args[1], "frontend") == 0) {
+ struct proxy *px;
+
+ px = expect_frontend_admin(s, si, args[2]);
+ if (!px)
+ return 1;
+
+ if (px->state == PR_STSTOPPED) {
+ si->applet.ctx.cli.msg = "Frontend was previously shut down, cannot enable.\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return 1;
+ }
+
+ if (px->state != PR_STPAUSED) {
+ si->applet.ctx.cli.msg = "Frontend is already enabled.\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return 1;
+ }
+
+ if (!resume_proxy(px)) {
+ si->applet.ctx.cli.msg = "Failed to resume frontend, check logs for precise cause (port conflict?).\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return 1;
+ }
+ return 1;
+ }
else { /* unknown "enable" parameter */
- return 0;
+ si->applet.ctx.cli.msg = "'enable' only supports 'frontend' and 'server'.\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return 1;
}
}
else if (strcmp(args[0], "disable") == 0) {
return 1;
}
+ else if (strcmp(args[1], "frontend") == 0) {
+ struct proxy *px;
+
+ px = expect_frontend_admin(s, si, args[2]);
+ if (!px)
+ return 1;
+
+ if (px->state == PR_STSTOPPED) {
+ si->applet.ctx.cli.msg = "Frontend was previously shut down, cannot disable.\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return 1;
+ }
+
+ if (px->state == PR_STPAUSED) {
+ si->applet.ctx.cli.msg = "Frontend is already disabled.\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return 1;
+ }
+
+ if (!pause_proxy(px)) {
+ si->applet.ctx.cli.msg = "Failed to pause frontend, check logs for precise cause.\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return 1;
+ }
+ return 1;
+ }
else { /* unknown "disable" parameter */
- return 0;
+ si->applet.ctx.cli.msg = "'disable' only supports 'frontend' and 'server'.\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return 1;
+ }
+ }
+ else if (strcmp(args[0], "shutdown") == 0) {
+ if (strcmp(args[1], "frontend") == 0) {
+ struct proxy *px;
+
+ px = expect_frontend_admin(s, si, args[2]);
+ if (!px)
+ return 1;
+
+ if (px->state == PR_STSTOPPED) {
+ si->applet.ctx.cli.msg = "Frontend was already shut down.\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return 1;
+ }
+
+ Warning("Proxy %s stopped (FE: %lld conns, BE: %lld conns).\n",
+ px->id, px->fe_counters.cum_conn, px->be_counters.cum_conn);
+ send_log(px, LOG_WARNING, "Proxy %s stopped (FE: %lld conns, BE: %lld conns).\n",
+ px->id, px->fe_counters.cum_conn, px->be_counters.cum_conn);
+ stop_proxy(px);
+ return 1;
+ }
+ else { /* unknown "disable" parameter */
+ si->applet.ctx.cli.msg = "'shutdown' only supports 'frontend'.\n";
+ si->applet.st0 = STAT_CLI_PRINT;
+ return 1;
}
}
else { /* not "show" nor "clear" nor "get" nor "set" nor "enable" nor "disable" */