logd: Limit ustream write buffer with configurable value
Gocool..
gokulmrt at gmail.com
Tue Jul 20 02:51:32 PDT 2021
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 at 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;
More information about the openwrt-devel
mailing list