If the "logread" process is blocked in write call or stopped by pressing "CTRL+Z", the logd starts to buffer all the messages in the write buffer. Since there is no limit in w.max_buffers, the logd consumes all the system memory at a point of time which triggers Out Of Memory. The ustream write max_buffer is limited with a configurable value parsed through logd with option "-W" and unlimited if value is '0'.
Similar ticket has been reported in, https://github.com/openwrt/packages/issues/5604 Signed-off-by: gokulnathan <gokul...@gmail.com> diff --git a/log/logd.c b/log/logd.c index 5d6c458..7e52820 100644 --- a/log/logd.c +++ b/log/logd.c @@ -33,6 +33,8 @@ static struct blob_buf b; static struct ubus_auto_conn conn; static LIST_HEAD(clients); +static unsigned int log_ustream_max_buffers = 0; + enum { READ_LINES, READ_STREAM, @@ -130,6 +132,11 @@ read_log(struct ubus_context *ctx, struct ubus_object *obj, cl->s.stream.notify_state = client_notify_state; cl->fd = fds[1]; ustream_fd_init(&cl->s, cl->fd); + /* Limit the ustream write max_buffers to avoid infinite memory consumption when no logread happens */ + if (0 != log_ustream_max_buffers) + { + cl->s.stream.w.max_buffers = log_ustream_max_buffers; + } list_add(&cl->list, &clients); while ((!tb[READ_LINES] || count) && l) { blob_buf_init(&b, 0); @@ -243,13 +250,18 @@ main(int argc, char **argv) struct passwd *p = NULL; signal(SIGPIPE, SIG_IGN); - while ((ch = getopt(argc, argv, "S:")) != -1) { + while ((ch = getopt(argc, argv, "S:W:")) != -1) { switch (ch) { case 'S': log_size = atoi(optarg); if (log_size < 1) log_size = 16; break; + case 'W': + log_ustream_max_buffers = atoi(optarg); + if (log_ustream_max_buffers < 1) + log_ustream_max_buffers = 0; + break; } } log_size *= 1024; _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel