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 <zajec5@gmail.com>
Modified to use no buffering to align with stderr. Several cleanups.
Signed-off-by: Steven Barth <steven@midlink.org>
LINK_DIRECTORIES(/opt/local/lib)
ENDIF()
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)
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)
* GNU General Public License for more details.
*/
* GNU General Public License for more details.
*/
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <unistd.h>
#include <stdint.h>
#include <net/if.h>
#include <unistd.h>
#include <stdint.h>
#include <fcntl.h>
#include <pwd.h>
#include <libgen.h>
#include <fcntl.h>
#include <pwd.h>
#include <libgen.h>
struct blobmsg_list_node *var;
struct blob_attr *cur;
char **argv;
struct blobmsg_list_node *var;
struct blob_attr *cur;
char **argv;
int argc = 1; /* NULL terminated */
int rem, _stdin;
int argc = 1; /* NULL terminated */
int rem, _stdin;
+ bool seccomp = !in->trace && !in->has_jail && in->seccomp;
+ bool setlbf = _stdout >= 0;
if (in->nice)
setpriority(PRIO_PROCESS, 0, in->nice);
if (in->nice)
setpriority(PRIO_PROCESS, 0, in->nice);
blobmsg_list_for_each(&in->env, var)
setenv(blobmsg_name(var->data), blobmsg_data(var->data), 1);
blobmsg_list_for_each(&in->env, var)
setenv(blobmsg_name(var->data), blobmsg_data(var->data), 1);
- if (!in->trace && !in->has_jail && in->seccomp) {
setenv("SECCOMP_FILE", in->seccomp, 1);
setenv("SECCOMP_FILE", in->seccomp, 1);
- setenv("LD_PRELOAD", "/lib/libpreload-seccomp.so", 1);
- }
+
+ if ((seccomp || setlbf) && asprintf(&ld_preload, "LD_PRELOAD=%s%s%s",
+ seccomp ? "/lib/libpreload-seccomp.so" : "",
+ seccomp && setlbf ? ":" : "",
+ setlbf ? "/lib/libsetlbf.so" : "") > 0)
+ putenv(ld_preload);
blobmsg_list_for_each(&in->limits, var)
instance_limits(blobmsg_name(var->data), blobmsg_data(var->data));
blobmsg_list_for_each(&in->limits, var)
instance_limits(blobmsg_name(var->data), blobmsg_data(var->data));
--- /dev/null
+#include <stdio.h>
+
+static void __attribute__((constructor)) setlbf(void)
+{
+ setbuf(stdout, NULL);
+}