From: Michael Tremer Date: Sat, 5 Oct 2024 17:27:16 +0000 (+0000) Subject: jail: Move the timer into the event loop X-Git-Tag: 0.9.30~1145 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=54d93f51d0b6ebd927d33dfe329df16f0d6772f9;p=pakfire.git jail: Move the timer into the event loop Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index a4a0499d6..dfc50278f 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -133,7 +132,7 @@ struct pakfire_jail { int nice; // Timeout - struct itimerspec timeout; + uint64_t timeout; // CGroup struct pakfire_cgroup* cgroup; @@ -189,6 +188,9 @@ struct pakfire_jail_exec { #endif /* ENABLE_DEBUG */ } log; + // Timeout + sd_event_source* timeout; + struct pakfire_cgroup* cgroup; struct pakfire_cgroup_stats cgroup_stats; @@ -478,7 +480,7 @@ PAKFIRE_EXPORT int pakfire_jail_import_env(struct pakfire_jail* jail, const char PAKFIRE_EXPORT int pakfire_jail_set_timeout( struct pakfire_jail* jail, unsigned int timeout) { // Store value - jail->timeout.it_value.tv_sec = timeout; + jail->timeout = timeout; if (timeout > 0) CTX_DEBUG(jail->ctx, "Timeout set to %u second(s)\n", timeout); @@ -488,36 +490,6 @@ PAKFIRE_EXPORT int pakfire_jail_set_timeout( return 0; } -static int pakfire_jail_create_timer(struct pakfire_jail* jail) { - int r; - - // Nothing to do if no timeout has been set - if (!jail->timeout.it_value.tv_sec) - return -1; - - // Create a new timer - const int fd = timerfd_create(CLOCK_MONOTONIC, 0); - if (fd < 0) { - CTX_ERROR(jail->ctx, "Could not create timer: %m\n"); - goto ERROR; - } - - // Arm timer - r = timerfd_settime(fd, 0, &jail->timeout, NULL); - if (r) { - CTX_ERROR(jail->ctx, "Could not arm timer: %m\n"); - goto ERROR; - } - - return fd; - -ERROR: - if (fd >= 0) - close(fd); - - return -1; -} - /* Standard Input */ @@ -1125,23 +1097,16 @@ static int pakfire_jail_forward_pty(struct pakfire_jail* jail, struct pakfire_ja static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx) { int epollfd = -1; struct epoll_event events[EPOLL_MAX_EVENTS]; - char garbage[8]; int r = 0; // Fetch the UNIX domain socket const int socket_recv = pakfire_jail_get_pipe_to_read(jail, &ctx->socket); - // Timer - const int timerfd = pakfire_jail_create_timer(jail); - // Make a list of all file descriptors we are interested in const struct pakfire_wait_fds { const int fd; const int events; } fds[] = { - // Timer - { timerfd, EPOLLIN }, - // UNIX Domain Socket { socket_recv, EPOLLIN }, @@ -1228,32 +1193,6 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec goto ERROR; } - // Handle timer events - } else if (timerfd == fd) { - if (e & EPOLLIN) { - CTX_DEBUG(jail->ctx, "Timer event received\n"); - - // Disarm the timer - r = read(timerfd, garbage, sizeof(garbage)); - if (r < 1) { - CTX_ERROR(jail->ctx, "Could not disarm timer: %m\n"); - r = 1; - goto ERROR; - } - - // Terminate the process if it hasn't already ended - if (!ended) { - CTX_DEBUG(jail->ctx, "Terminating process...\n"); - - // Send SIGTERM to the process - r = pidfd_send_signal(ctx->pidfd, SIGKILL, NULL, 0); - if (r) { - CTX_ERROR(jail->ctx, "Could not kill process: %m\n"); - goto ERROR; - } - } - } - // Handle socket messages } else if (socket_recv == fd) { if (e & EPOLLIN) { @@ -1293,8 +1232,6 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec ERROR: if (epollfd >= 0) close(epollfd); - if (timerfd >= 0) - close(timerfd); // Restore any changed terminal attributes if (ctx->pty.stdin.fd >= 0) @@ -1844,6 +1781,27 @@ static int pakfire_jail_wait_for_signal(struct pakfire_jail* jail, int fd) { return r; } +/* + Called when the timer has expired. +*/ +static int pakfire_jail_timer(sd_event_source* s, uint64_t usec, void* data) { + struct pakfire_jail_exec* ctx = data; + struct pakfire_jail* jail = ctx->jail; + int r; + + CTX_DEBUG(jail->ctx, "Timer has fired...\n"); + + // Send SIGTERM to the process + r = pidfd_send_signal(ctx->pidfd, SIGTERM, NULL, 0); + if (r) + CTX_ERROR(jail->ctx, "Could not send SIGTERM to the process: %m\n"); + + return r; +} + +/* + Called when the child process has exited. +*/ static int pakfire_jail_exited(sd_event_source* source, const siginfo_t* si, void* data) { struct pakfire_jail_exec* ctx = data; struct pakfire_jail* jail = ctx->jail; @@ -2320,6 +2278,16 @@ PAKFIRE_EXPORT int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv goto ERROR; #endif /* ENABLE_DEBUG */ + // Setup the timer + if (jail->timeout) { + r = sd_event_add_time_relative(ctx.loop, &ctx.timeout, CLOCK_MONOTONIC, + jail->timeout * 1000000, 0, pakfire_jail_timer, &ctx); + if (r < 0) { + CTX_ERROR(jail->ctx, "Could not setup timer: %s\n", strerror(-r)); + goto ERROR; + } + } + // Configure child process struct clone_args args = { .flags =