Using pipe automatically switches service to block buffering which kind
of breaks our logging. We won't get anything from stdout FD until the
buffer gets filled fully or the service exits. This makes log messages
appear with an unwanted delay.
This change adds a tiny libsetlbf.so switching stdout to line buffering
and uses this lib for every logging-enabled service started by procd.
We don't need any extra change for stderr as it's unbuffered by default.

Signed-off-by: Rafał Miłecki <zaj...@gmail.com>
---
V2: Use strncat for safety
    Use line buffering instead of no buffering
V3: Use asprintf & putenv as suggested byu cyrus
---
 CMakeLists.txt     |  7 +++++++
 service/instance.c | 19 ++++++++++++++++++-
 service/setlbf.c   |  6 ++++++
 3 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 service/setlbf.c

diff --git a/CMakeLists.txt b/CMakeLists.txt
index dfa9413..6af17a3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,6 +10,13 @@ IF(APPLE)
   LINK_DIRECTORIES(/opt/local/lib)
 ENDIF()
 
+
+ADD_LIBRARY(setlbf SHARED service/setlbf.c)
+INSTALL(TARGETS setlbf
+       LIBRARY DESTINATION lib
+)
+
+
 SET(SOURCES procd.c signal.c watchdog.c state.c        inittab.c rcS.c ubus.c 
system.c
        service/service.c service/instance.c service/validate.c 
service/trigger.c service/watch.c
        plug/coldplug.c plug/hotplug.c utils/utils.c)
diff --git a/service/instance.c b/service/instance.c
index 35b2def..0bd0bed 100644
--- a/service/instance.c
+++ b/service/instance.c
@@ -12,6 +12,7 @@
  * GNU General Public License for more details.
  */
 
+#define _GNU_SOURCE
 #include <sys/resource.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -19,6 +20,7 @@
 #include <net/if.h>
 #include <unistd.h>
 #include <stdint.h>
+#include <stdio.h>
 #include <fcntl.h>
 #include <pwd.h>
 #include <libgen.h>
@@ -224,6 +226,9 @@ instance_run(struct service_instance *in, int _stdout, int 
_stderr)
        struct blobmsg_list_node *var;
        struct blob_attr *cur;
        char **argv;
+       char *ld_preload;
+       bool ld_preload_seccomp = false;
+       bool ld_preload_setlbf = false;
        int argc = 1; /* NULL terminated */
        int rem, _stdin;
 
@@ -238,7 +243,19 @@ instance_run(struct service_instance *in, int _stdout, int 
_stderr)
 
        if (!in->trace && !in->has_jail && in->seccomp) {
                setenv("SECCOMP_FILE", in->seccomp, 1);
-               setenv("LD_PRELOAD", "/lib/libpreload-seccomp.so", 1);
+               ld_preload_seccomp = true;
+       }
+       if (_stdout >= 0) {
+               ld_preload_setlbf = true;
+       }
+
+       if (ld_preload_seccomp || ld_preload_setlbf) {
+               int bytes = asprintf(&ld_preload, "LD_PRELOAD=%s%s%s",
+                                    ld_preload_seccomp ? 
"/lib/libpreload-seccomp.so" : "",
+                                    ld_preload_seccomp && ld_preload_setlbf ? 
":" : "",
+                                    ld_preload_setlbf ? "/lib/libsetlbf.so" : 
"");
+               if (bytes)
+                       putenv(ld_preload);
        }
 
        blobmsg_list_for_each(&in->limits, var)
diff --git a/service/setlbf.c b/service/setlbf.c
new file mode 100644
index 0000000..df00366
--- /dev/null
+++ b/service/setlbf.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+static void __attribute__((constructor)) setlbf(void)
+{
+       setlinebuf(stdout);
+}
-- 
1.8.4.5
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to