After all this slowcgi timeout fixing, here a similar thing for bgplgd(8).
If the timeout fires, kill the bgpctl command first with SIGTERM then with
SIGKILL. If the kill fails, close and cleanup the connection.
I also reduced the timeout to a more reasonable 30sec. Lets see how that
goes. This will abort full show rib commands but nobody should use those
anyway.
--
:wq Claudio
Index: slowcgi.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgplgd/slowcgi.c,v
retrieving revision 1.2
diff -u -p -r1.2 slowcgi.c
--- slowcgi.c 8 Jul 2022 08:48:56 -0000 1.2
+++ slowcgi.c 12 Aug 2022 10:50:57 -0000
@@ -45,7 +45,7 @@
#include "bgplgd.h"
#include "http.h"
-#define TIMEOUT_DEFAULT 120
+#define TIMEOUT_DEFAULT 30
#define WWW_USER "www"
#define BGPLGD_USER "_bgplgd"
@@ -106,20 +106,21 @@ struct request {
struct event tmo;
struct event script_ev;
struct event script_err_ev;
- int fd;
+ struct fcgi_response_head response_head;
+ struct env_head env;
uint8_t buf[FCGI_RECORD_SIZE];
size_t buf_pos;
size_t buf_len;
- struct fcgi_response_head response_head;
- struct env_head env;
+ int fd;
int env_count;
+ int inflight_fds_accounted;
pid_t command_pid;
int command_status;
int script_flags;
uint16_t id;
uint8_t request_started;
uint8_t request_done;
- int inflight_fds_accounted;
+ uint8_t timeout_fired;
};
LIST_HEAD(requests_head, request);
@@ -220,6 +221,7 @@ usage(void)
}
struct timeval timeout = { TIMEOUT_DEFAULT, 0 };
+struct timeval kill_timeout = { 5, 0 };
struct slowcgi_proc slowcgi_proc;
int debug = 0;
int on = 1;
@@ -497,7 +499,35 @@ slowcgi_accept(int fd, short events, voi
void
slowcgi_timeout(int fd, short events, void *arg)
{
- cleanup_request((struct request*) arg);
+ struct request *c = arg;
+ int sig = SIGTERM;
+
+ if (c->script_flags & SCRIPT_DONE)
+ return;
+
+ ldebug("timeout fired");
+
+ if (c->timeout_fired)
+ sig = SIGKILL;
+
+ if (kill(c->command_pid, sig) == -1) {
+ lwarn("kill child %i after timeout", c->command_pid);
+ if (event_initialized(&c->script_ev)) {
+ close(EVENT_FD(&c->script_ev));
+ event_del(&c->script_ev);
+ }
+ if (event_initialized(&c->script_err_ev)) {
+ close(EVENT_FD(&c->script_err_ev));
+ event_del(&c->script_err_ev);
+ }
+
+ c->command_status = SIGALRM;
+ c->script_flags = STDOUT_DONE | STDERR_DONE | SCRIPT_DONE;
+ create_end_record(c);
+ }
+
+ if (c->timeout_fired++ == 0)
+ evtimer_add(&c->tmo, &kill_timeout);
}
void
@@ -527,7 +557,7 @@ slowcgi_sig_handler(int sig, short event
c->command_status = WEXITSTATUS(status);
ldebug("exit %s%d",
- WIFSIGNALED(status) ? "signal" : "",
+ WIFSIGNALED(status) ? "signal " : "",
c->command_status);
c->script_flags |= SCRIPT_DONE;