]> git.ipfire.org Git - telemetry.git/commitdiff
command: Kill commands after 30 seconds
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 6 Oct 2025 16:59:01 +0000 (16:59 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 6 Oct 2025 16:59:01 +0000 (16:59 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/daemon/command.c
src/daemon/command.h

index 4481f9ea85f3f526b1a4683d4b45ae97b23462a3..5fdd2fe6886b99e97ac3a9666a09808991d89ad0 100644 (file)
 
 #include "command.h"
 #include "ctx.h"
+#include "time.h"
 #include "util.h"
 
+// By default, commands are being killed after 30 seconds
+#define DEFAULT_TIMEOUT        SEC_TO_USEC(30)
+
 struct collecty_command {
        collecty_ctx* ctx;
        int nrefs;
@@ -43,6 +47,9 @@ struct collecty_command {
        // Loop
        sd_event* loop;
 
+       // Timeout
+       uint64_t timeout;
+
        // pidfd
        int pidfd;
 
@@ -71,6 +78,7 @@ struct collecty_command {
                sd_event_source* stdout;
                sd_event_source* stderr;
                sd_event_source* exit;
+               sd_event_source* timeout;
        } events;
 };
 
@@ -78,6 +86,10 @@ static inline int clone3(struct clone_args* args, size_t size) {
        return syscall(__NR_clone3, args, size);
 }
 
+static inline int pidfd_send_signal(int pidfd, int sig, siginfo_t* info, unsigned int flags) {
+       return syscall(SYS_pidfd_send_signal, pidfd, sig, info, flags);
+}
+
 static void collecty_command_close_pipe(int fds[2]) {
        for (unsigned int i = 0; i < 2; i++) {
                if (fds[i] >= 0) {
@@ -105,6 +117,8 @@ static void collecty_command_free(collecty_command* self) {
                free(self->stderr.buffer);
 
        // Free events
+       if (self->events.timeout)
+               sd_event_source_unref(self->events.timeout);
        if (self->events.exit)
                sd_event_source_unref(self->events.exit);
        if (self->events.stdout)
@@ -143,6 +157,9 @@ int collecty_command_create(collecty_command** command,
        // Fetch a reference to the event loop
        self->loop = collecty_daemon_loop(daemon);
 
+       // Set default timeout
+       self->timeout = DEFAULT_TIMEOUT;
+
        // Initialize pidfd
        self->pidfd = -EBADF;
 
@@ -202,6 +219,10 @@ collecty_command* collecty_command_unref(collecty_command* self) {
        return NULL;
 }
 
+void collecty_command_set_timeout(collecty_command* self, uint64_t timeout) {
+       self->timeout = timeout;
+}
+
 void collecty_command_on_success(collecty_command* self,
                collecty_command_success_callback callback, void* data) {
        self->callbacks.on_success = callback;
@@ -358,6 +379,27 @@ ERROR:
        return r;
 }
 
+static int collecty_command_timeout(sd_event_source* source, uint64_t usec, void* data) {
+       collecty_command* self = data;
+       int r;
+
+       // Log action
+       DEBUG(self->ctx, "Command has timed out\n");
+
+       // Skip this if we don't have a pidfd
+       if (self->pidfd < 0)
+               return 0;
+
+       // Send SIGKILL to the command
+       r = pidfd_send_signal(self->pidfd, SIGKILL, NULL, 0);
+       if (r < 0) {
+               ERROR(self->ctx, "Failed to kill command: %m\n");
+               return -errno;
+       }
+
+       return 0;
+}
+
 static int collecty_command_parent(collecty_command* self) {
        int fd = -EBADF;
        int r;
@@ -394,7 +436,15 @@ static int collecty_command_parent(collecty_command* self) {
                }
        }
 
-       DEBUG(self->ctx, "Parent has finished\n");
+       // Set the timeout
+       if (self->timeout) {
+               r = sd_event_add_time_relative(self->loop, &self->events.timeout,
+                               CLOCK_MONOTONIC, self->timeout, 0, collecty_command_timeout, self);
+               if (r < 0) {
+                       ERROR(self->ctx, "Failed to setup timer: %s\n", strerror(-r));
+                       return r;
+               }
+       }
 
        return r;
 }
index 1864e3107bb936b5aceba393bd47fb0e340d773a..46bfa1ed427e956a03b4cc1ac2fe11823e86be67 100644 (file)
@@ -32,6 +32,9 @@ int collecty_command_create(collecty_command** command,
 collecty_command* collecty_command_ref(collecty_command* self);
 collecty_command* collecty_command_unref(collecty_command* self);
 
+// Timeout
+void collecty_command_set_timeout(collecty_command* self, uint64_t timeout);
+
 typedef int (*collecty_command_success_callback)(collecty_ctx* ctx,
        int rc, const char* output, const size_t length, void* data);