Message ID | CAFGbXD6YmYgh0pK_rdTGU4Zob+QCkv2XUw5XF5uGMREh268Kuw@mail.gmail.com |
---|---|
State | Needs Review / ACK |
Headers | show |
Series | logd: Limit ustream write buffer with configurable value | expand |
On 7/20/21 11:51 AM, Gocool.. wrote: > 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'. Instead of providing the limit on the command line, would it make more sense to use a reasonable default? > > Similar ticket has been reported in, > https://github.com/openwrt/packages/issues/5604 > > Signed-off-by: gokulnathan <gokulmrt@gmail.com> Please use your real name. The patch is whitespace damaged, please use git send-email to sedn the patch: https://openwrt.org/submitting-patches > > 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 >
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) {
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 <gokulmrt@gmail.com> 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;