]> git.ipfire.org Git - pakfire.git/commitdiff
jail: Use new log streamer
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 5 Oct 2024 16:56:18 +0000 (16:56 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 5 Oct 2024 16:56:18 +0000 (16:56 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/jail.c

index f95c361f2dc739d415fbf2270c8d7e3423089ca2..38d80c6f9e3dc942f466ffad2c9da66db24282cc 100644 (file)
@@ -56,6 +56,7 @@
 #include <pakfire/arch.h>
 #include <pakfire/cgroup.h>
 #include <pakfire/jail.h>
+#include <pakfire/log_stream.h>
 #include <pakfire/logging.h>
 #include <pakfire/mount.h>
 #include <pakfire/pakfire.h>
@@ -179,22 +180,12 @@ struct pakfire_jail_exec {
        // Log pipes
        struct pakfire_jail_pipes {
                // Logging
-               int log_INFO[2];
-               int log_ERROR[2];
+               struct pakfire_log_stream* INFO;
+               struct pakfire_log_stream* ERROR;
 #ifdef ENABLE_DEBUG
-               int log_DEBUG[2];
+               struct pakfire_log_stream* DEBUG;
 #endif /* ENABLE_DEBUG */
-       } pipes;
-
-       // Log buffers
-       struct pakfire_jail_buffers {
-               // Logging
-               struct pakfire_log_buffer log_INFO;
-               struct pakfire_log_buffer log_ERROR;
-#ifdef ENABLE_DEBUG
-               struct pakfire_log_buffer log_DEBUG;
-#endif /* ENABLE_DEBUG */
-       } buffers;
+       } log;
 
        struct pakfire_cgroup* cgroup;
        struct pakfire_cgroup_stats cgroup_stats;
@@ -550,21 +541,20 @@ PAKFIRE_EXPORT void pakfire_jail_set_stdout_callback(struct pakfire_jail* jail,
 */
 static void pakfire_jail_log_redirect(void* data, int priority, const char* file,
                int line, const char* fn, const char* format, va_list args) {
-       struct pakfire_jail_pipes* pipes = (struct pakfire_jail_pipes*)data;
-       int fd;
+       struct pakfire_jail_exec* ctx = data;
 
        switch (priority) {
                case LOG_INFO:
-                       fd = pipes->log_INFO[1];
+                       pakfire_log_stream_write(ctx->log.INFO, format, args);
                        break;
 
                case LOG_ERR:
-                       fd = pipes->log_ERROR[1];
+                       pakfire_log_stream_write(ctx->log.ERROR, format, args);
                        break;
 
 #ifdef ENABLE_DEBUG
                case LOG_DEBUG:
-                       fd = pipes->log_DEBUG[1];
+                       pakfire_log_stream_write(ctx->log.DEBUG, format, args);
                        break;
 #endif /* ENABLE_DEBUG */
 
@@ -572,17 +562,6 @@ static void pakfire_jail_log_redirect(void* data, int priority, const char* file
                default:
                        return;
        }
-
-       // End if we do not have a file descriptor to write to
-       if (fd < 0)
-               return;
-
-       // Optionally log the function name
-       if (fn)
-               dprintf(fd, "%s: ", fn);
-
-       // Send the log message
-       vdprintf(fd, format, args);
 }
 
 static int pakfire_jail_fill_buffer(struct pakfire_jail* jail, int fd, struct pakfire_log_buffer* buffer) {
@@ -695,39 +674,30 @@ static int pakfire_jail_drain_buffer(struct pakfire_jail* jail, int fd, struct p
 }
 
 /*
-       Passes any log messages on to the default pakfire log callback
+       Passes any log messages on to the context logger
 */
-static int pakfire_jail_log(struct pakfire_ctx* ctx, struct pakfire_jail* jail,
-               void* data, const char* line, size_t length) {
-       int* priority = data;
-
-       if (pakfire_ctx_get_log_level(jail->ctx) >= *priority)
-               pakfire_ctx_log(jail->ctx, *priority, NULL, 0, NULL, "%.*s", (int)length, line);
+static int pakfire_jail_INFO(struct pakfire_log_stream* stream, const char* line, size_t length, void* data) {
+       struct pakfire_jail* jail = data;
 
+       CTX_INFO(jail->ctx, "%.*s", (int)length, line);
        return 0;
 }
 
-/*
-       This function reads as much data as it can from the file descriptor.
-       If it finds a whole line in it, it will send it to the logger and repeat the process.
-       If not newline character is found, it will try to read more data until it finds one.
-*/
-static int pakfire_jail_handle_log(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx,
-               int fd, struct pakfire_log_buffer* buffer, pakfire_jail_stdout_callback callback, void* data) {
-       int r;
+static int pakfire_jail_ERROR(struct pakfire_log_stream* stream, const char* line, size_t length, void* data) {
+       struct pakfire_jail* jail = data;
 
-       // Fill up buffer from fd
-       r = pakfire_jail_fill_buffer(jail, fd, buffer);
-       if (r)
-               return r;
+       CTX_ERROR(jail->ctx, "%.*s", (int)length, line);
+       return 0;
+}
 
-       // Drain the buffer
-       r = pakfire_jail_drain_buffer_with_callback(jail, buffer, callback, data);
-       if (r)
-               return r;
+#ifdef ENABLE_DEBUG
+static int pakfire_jail_DEBUG(struct pakfire_log_stream* stream, const char* line, size_t length, void* data) {
+       struct pakfire_jail* jail = data;
 
+       CTX_DEBUG(jail->ctx, "%.*s", (int)length, line);
        return 0;
 }
+#endif /* ENABLE_DEBUG */
 
 static int pakfire_jail_stream_stdin(struct pakfire_jail* jail,
                struct pakfire_jail_exec* ctx, const int fd) {
@@ -828,16 +798,6 @@ static int pakfire_jail_send_fd(struct pakfire_jail* jail, int socket, int fd) {
        return 0;
 }
 
-static int pakfire_jail_setup_pipe(struct pakfire_jail* jail, int (*fds)[2], const int flags) {
-       int r = pipe2(*fds, flags);
-       if (r < 0) {
-               CTX_ERROR(jail->ctx, "Could not setup pipe: %m\n");
-               return 1;
-       }
-
-       return 0;
-}
-
 static void pakfire_jail_close_pipe(struct pakfire_jail* jail, int fds[2]) {
        for (unsigned int i = 0; i < 2; i++)
                if (fds[i] >= 0)
@@ -1175,13 +1135,6 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec
        // Timer
        const int timerfd = pakfire_jail_create_timer(jail);
 
-       // Logging
-       const int log_INFO  = pakfire_jail_get_pipe_to_read(jail, &ctx->pipes.log_INFO);
-       const int log_ERROR = pakfire_jail_get_pipe_to_read(jail, &ctx->pipes.log_ERROR);
-#ifdef ENABLE_DEBUG
-       const int log_DEBUG = pakfire_jail_get_pipe_to_read(jail, &ctx->pipes.log_DEBUG);
-#endif /* ENABLE_DEBUG */
-
        // Make a list of all file descriptors we are interested in
        const struct pakfire_wait_fds {
                const int fd;
@@ -1193,13 +1146,6 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec
                // Child Process
                { ctx->pidfd, EPOLLIN },
 
-               // Log Pipes
-               { log_INFO, EPOLLIN },
-               { log_ERROR, EPOLLIN },
-#ifdef ENABLE_DEBUG
-               { log_DEBUG, EPOLLIN },
-#endif /* ENABLE_DEBUG */
-
                // UNIX Domain Socket
                { socket_recv, EPOLLIN },
 
@@ -1345,35 +1291,6 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec
                                        }
                                }
 
-                       // Handle log INFO messages
-                       } else if (log_INFO == fd) {
-                               if (e & EPOLLIN) {
-                                       r = pakfire_jail_handle_log(jail, ctx, fd, &ctx->buffers.log_INFO,
-                                               pakfire_jail_log, &ctx->buffers.log_INFO.priority);
-                                       if (r)
-                                               goto ERROR;
-                               }
-
-                       // Handle log ERROR messages
-                       } else if (log_ERROR == fd) {
-                               if (e & EPOLLIN) {
-                                       r = pakfire_jail_handle_log(jail, ctx, fd, &ctx->buffers.log_ERROR,
-                                               pakfire_jail_log, &ctx->buffers.log_ERROR.priority);
-                                       if (r)
-                                               goto ERROR;
-                               }
-
-#ifdef ENABLE_DEBUG
-                       // Handle log DEBUG messages
-                       } else if (log_DEBUG == fd) {
-                               if (e & EPOLLIN) {
-                                       r = pakfire_jail_handle_log(jail, ctx, fd, &ctx->buffers.log_DEBUG,
-                                               pakfire_jail_log, &ctx->buffers.log_DEBUG.priority);
-                                       if (r)
-                                               goto ERROR;
-                               }
-#endif /* ENABLE_DEBUG */
-
                        // Log a message for anything else
                        } else {
                                CTX_DEBUG(jail->ctx, "Received invalid file descriptor %d\n", fd);
@@ -2077,7 +1994,7 @@ static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exe
        int r;
 
        // Redirect any logging to our log pipe
-       pakfire_ctx_set_log_callback(jail->ctx, pakfire_jail_log_redirect, &ctx->pipes);
+       pakfire_ctx_set_log_callback(jail->ctx, pakfire_jail_log_redirect, ctx);
 
        // Fetch my own PID
        pid_t pid = getpid();
@@ -2235,11 +2152,19 @@ static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exe
        // Close the socket
        close(socket_send);
 
-       // Close other end of log pipes
-       close(ctx->pipes.log_INFO[0]);
-       close(ctx->pipes.log_ERROR[0]);
+       // Setup logging
+       r = pakfire_log_stream_in_child(ctx->log.INFO);
+       if (r)
+               return r;
+
+       r = pakfire_log_stream_in_child(ctx->log.ERROR);
+       if (r)
+               return r;
+
 #ifdef ENABLE_DEBUG
-       close(ctx->pipes.log_DEBUG[0]);
+       r = pakfire_log_stream_in_child(ctx->log.DEBUG);
+       if (r)
+               return r;
 #endif /* ENABLE_DEBUG */
 
        // Reset open file limit (http://0pointer.net/blog/file-descriptor-limits.html)
@@ -2311,30 +2236,6 @@ PAKFIRE_EXPORT int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv
 
                .socket = { -1, -1 },
 
-               .pipes = {
-                       .log_INFO  = { -1, -1 },
-                       .log_ERROR = { -1, -1 },
-#ifdef ENABLE_DEBUG
-                       .log_DEBUG = { -1, -1 },
-#endif /* ENABLE_DEBUG */
-               },
-
-               .buffers = {
-                       .log_INFO = {
-                               .priority = LOG_INFO,
-                       },
-
-                       .log_ERROR = {
-                               .priority = LOG_ERR,
-                       },
-
-#ifdef ENABLE_DEBUG
-                       .log_DEBUG = {
-                               .priority = LOG_DEBUG,
-                       },
-#endif /* ENABLE_DEBUG */
-               },
-
                .pidfd = -1,
 
                // PTY
@@ -2384,18 +2285,18 @@ PAKFIRE_EXPORT int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv
 
        // Setup pipes for logging
        // INFO
-       r = pakfire_jail_setup_pipe(jail, &ctx.pipes.log_INFO, O_CLOEXEC);
+       r = pakfire_log_stream_create(&ctx.log.INFO, jail->ctx, pakfire_jail_INFO, jail);
        if (r)
                goto ERROR;
 
        // ERROR
-       r = pakfire_jail_setup_pipe(jail, &ctx.pipes.log_ERROR, O_CLOEXEC);
+       r = pakfire_log_stream_create(&ctx.log.ERROR, jail->ctx, pakfire_jail_ERROR, jail);
        if (r)
                goto ERROR;
 
 #ifdef ENABLE_DEBUG
        // DEBUG
-       r = pakfire_jail_setup_pipe(jail, &ctx.pipes.log_DEBUG, O_CLOEXEC);
+       r = pakfire_log_stream_create(&ctx.log.DEBUG, jail->ctx, pakfire_jail_DEBUG, jail);
        if (r)
                goto ERROR;
 #endif /* ENABLE_DEBUG */
@@ -2506,10 +2407,15 @@ ERROR:
                close(ctx.pidfd);
        if (ctx.pty.master.fd >= 0)
                close(ctx.pty.master.fd);
-       pakfire_jail_close_pipe(jail, ctx.pipes.log_INFO);
-       pakfire_jail_close_pipe(jail, ctx.pipes.log_ERROR);
+
+       // Logging
+       if (ctx.log.INFO)
+               pakfire_log_stream_unref(ctx.log.INFO);
+       if (ctx.log.ERROR)
+               pakfire_log_stream_unref(ctx.log.ERROR);
 #ifdef ENABLE_DEBUG
-       pakfire_jail_close_pipe(jail, ctx.pipes.log_DEBUG);
+       if (ctx.log.DEBUG)
+               pakfire_log_stream_unref(ctx.log.DEBUG);
 #endif /* ENABLE_DEBUG */
        pakfire_jail_close_pipe(jail, ctx.socket);