Basic PoC for DLog stdout redirector
authorMichal Bloch <m.bloch@samsung.com>
Mon, 8 Feb 2021 14:06:03 +0000 (15:06 +0100)
committerŁukasz Stelmach <l.stelmach@samsung.com>
Fri, 22 Mar 2024 13:48:10 +0000 (14:48 +0100)
Set Standard{Output,Error}=dlog in a service file,
or DefaultStandard{Output,Error}=dlog for global.

Note that setting the global default should only
really be done if DLog is working under the Android
Logger backend, since the Pipe backend daemon is
not really available early on which can make early
daemons fail.

Change-Id: Icf7224d1fabd4cdb45971ac9314ed4d19d220bbb
Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
meson.build
meson_options.txt
packaging/systemd.spec
src/core/exec-invoke.c
src/core/execute.c
src/core/execute.h
src/core/meson.build

index 3a9a791..65ea8e8 100644 (file)
@@ -1125,6 +1125,10 @@ else
         conf.set10('BPF_FRAMEWORK', deps_found)
 endif
 
+libdlog_redirect_stdout = dependency('dlog-redirect-stdout',
+                                     required : get_option('dlog-redirect-stdout'))
+conf.set10('HAVE_LIBDLOG_REDIRECT', libdlog_redirect_stdout.found())
+
 libmount = dependency('mount',
                       version : fuzzer_build ? '>= 0' : '>= 2.30')
 
index 71555c8..3e0441a 100644 (file)
@@ -517,3 +517,6 @@ option('bpf-compiler', type : 'combo', choices : ['clang', 'gcc'],
     description: 'compiler used to build BPF programs')
 option('bpf-framework', type : 'feature', deprecated : { 'true' : 'enabled', 'false' : 'disabled' },
     description: 'build BPF programs from source code in restricted C')
+
+option('dlog-redirect-stdout', type : 'feature', value : 'enabled',
+    description: 'support for stdout redirection from services do dlog')
index f739966..00dbfa0 100644 (file)
@@ -84,6 +84,7 @@ BuildRequires:  pkgconfig(liblzma)
 BuildRequires:  pkgconfig(libkmod)
 BuildRequires:  pkgconfig(mount)
 BuildRequires:  pkgconfig(libdbuspolicy1)
+BuildRequires:  pkgconfig(dlog-redirect-stdout)
 BuildRequires:  meson
 BuildRequires:  acl
 BuildRequires:  python
index fcee53e..7ed8261 100644 (file)
@@ -5,6 +5,10 @@
 #include <sys/mount.h>
 #include <sys/prctl.h>
 
+#if HAVE_LIBDLOG_REDIRECT
+#include <dlog/dlog-redirect-stdout.h>
+#endif
+
 #if HAVE_PAM
 #include <security/pam_appl.h>
 #include <security/pam_misc.h>
@@ -178,18 +182,26 @@ static bool exec_context_needs_term(const ExecContext *c) {
         return !!c->tty_path;
 }
 
-static int open_null_as(int flags, int nfd) {
+static int open_device_as(const char* devname, int flags, int nfd) {
         int fd;
 
         assert(nfd >= 0);
 
-        fd = open("/dev/null", flags|O_NOCTTY);
+        fd = open(devname, flags|O_NOCTTY);
         if (fd < 0)
                 return -errno;
 
         return move_fd(fd, nfd, false);
 }
 
+static int open_null_as(int flags, int nfd) {
+        return open_device_as("/dev/null", flags, nfd);
+}
+
+static int open_kmsg_as(int flags, int nfd) {
+        return open_device_as("/dev/kmsg", flags, nfd);
+}
+
 static int connect_journal_socket(
                 int fd,
                 const char *log_namespace,
@@ -504,6 +516,30 @@ static bool can_inherit_stderr_from_stdout(
         return true;
 }
 
+#if HAVE_LIBDLOG_REDIRECT
+static int wire_up_dlog(int fileno, const char *ident)
+{
+        /* NB: dlogutil has FOO* tag filtering wildcards but not *FOO
+         * therefore the STDFOO part of the final tag goes in front.
+         *
+         * The tag can nominally be longer than 128 but dlogutil will
+         * not print a longer one anyway and it's good to limit overhead */
+        char tag[128];
+        int priority;
+
+        if (fileno == STDERR_FILENO) {
+                priority = 6; // ERROR
+                snprintf(tag, sizeof tag, "STDERR_%s", ident);
+        } else {
+                priority = 4; // INFO
+                snprintf(tag, sizeof tag, "STDOUT_%s", ident);
+        }
+
+        return connect_dlog(2, // SYSTEM dlog buffer (consider also 0 for generic MAIN buffer)
+                fileno, tag, priority);
+}
+#endif
+
 static int setup_output(
                 const ExecContext *context,
                 const ExecParameters *params,
@@ -624,6 +660,26 @@ static int setup_output(
                 }
                 return r;
 
+#if HAVE_LIBDLOG_REDIRECT
+        case EXEC_OUTPUT_DLOG:
+                r = wire_up_dlog(fileno, ident);
+                return r < 0 ? r : fileno;
+
+        case EXEC_OUTPUT_DLOG_OR_NULL:
+                r = wire_up_dlog(fileno, ident);
+                if (r >= 0)
+                        return fileno;
+                else
+                        return open_null_as(O_WRONLY, fileno);
+
+        case EXEC_OUTPUT_DLOG_OR_KMSG:
+                r = wire_up_dlog(fileno, ident);
+                if (r >= 0)
+                        return fileno;
+                else
+                        return open_kmsg_as(O_WRONLY, fileno);
+#endif
+
         case EXEC_OUTPUT_SOCKET:
                 assert(socket_fd >= 0);
 
index 7c7837e..33b3aa0 100644 (file)
@@ -2676,6 +2676,11 @@ static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
         [EXEC_OUTPUT_FILE] = "file",
         [EXEC_OUTPUT_FILE_APPEND] = "append",
         [EXEC_OUTPUT_FILE_TRUNCATE] = "truncate",
+#if HAVE_LIBDLOG_REDIRECT
+        [EXEC_OUTPUT_DLOG] = "dlog",
+        [EXEC_OUTPUT_DLOG_OR_NULL] = "dlog|null",
+        [EXEC_OUTPUT_DLOG_OR_KMSG] = "dlog|kmsg",
+#endif
 };
 
 DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
index b1dc247..b9b41df 100644 (file)
@@ -67,6 +67,11 @@ typedef enum ExecOutput {
         EXEC_OUTPUT_FILE,
         EXEC_OUTPUT_FILE_APPEND,
         EXEC_OUTPUT_FILE_TRUNCATE,
+#if HAVE_LIBDLOG_REDIRECT
+        EXEC_OUTPUT_DLOG,
+        EXEC_OUTPUT_DLOG_OR_NULL,
+        EXEC_OUTPUT_DLOG_OR_KMSG,
+#endif
         _EXEC_OUTPUT_MAX,
         _EXEC_OUTPUT_INVALID = -EINVAL,
 } ExecOutput;
index 0b04b5d..9adafdf 100644 (file)
@@ -126,6 +126,7 @@ libcore = shared_library(
                         libblkid,
                         libcap,
                         libdl,
+                        libdlog_redirect_stdout,
                         libkmod,
                         libm,
                         libmount,