Skip to content

Random hang in logd #8

Description

@sidepipe

I'm seeing a random lockup in logd. Unfortunately this renders the system pretty much unusable, since then anything that writes to the log also freezes ( including login ).

I haven't been able to reliably replicate it, but it occasionally happens during system boot, so I changed the startup to detect the lock and reboot if it didn't happen... this would trigger the issue after many reboots. That way I managed to get a core dump by sending SIGABRT, and found that the lock was in read() called from ustream_fd_read_pending() from uloop_run_events().

A cursory look, without really understanding all of the pieces involved, leads me to think that the code is written assuming that the pipe opened in read_log() is set as non blocking, though the lock in read() suggests that it actually isn't, so just as a test I tried:

--- ubox.orig/log/logd.c        2025-10-30 11:10:12.000000000 +0000
+++ ubox/log/logd.c     2026-06-29 11:44:06.873768158 +0100
@@ -14,8 +14,8 @@
 #include <sys/types.h>
 #include <pwd.h>
 #include <stdio.h>
-#include <unistd.h>
 #include <syslog.h>
+#include <fcntl.h>
 #include <unistd.h>
 
 #include <linux/types.h>
@@ -122,7 +122,8 @@ read_log(struct ubus_context *ctx, struc
 
        l = log_list(count, NULL);
        if (stream) {
-               if (pipe(fds) == -1) {
+               if ((pipe(fds) == -1) || (fcntl(fds[0], F_SETFL, fcntl(fds[0], F_GETFL, 0) | O_NONBLOCK) == -1) ||
+                       (fcntl(fds[1], F_SETFL, fcntl(fds[1], F_GETFL, 0) | O_NONBLOCK) == -1)) {
                        fprintf(stderr, "logd: failed to create pipe: %m\n");
                        return -1;
                }

I've now rebooted my test box many times and not seen the lock, and AFAICT there doesn't seem to be any adverse effect from doing this ( such as increased CPU use, implying that the theory about the code expecting non blocking operation is probably true ).

Whilst the above seems to work, as I say I don't know enough about all of the various parts, and honestly don't have the time to work it all out. Seems odd that code written for a non-blocking socket doesn't actually set the socket non-blocking, so I'm assuming that the above fix isn't "correct" in that sense, but if the socket is meant to be blocking then the implication is that poll() is called before read() somewhere and there's a race which means that occasionally the data is eaten up between the two ( which would explain the randomness here ).

Anyway - hopefully someone who knows the code can investigate further.

I'm using:
ubox PKG_SOURCE_DATE:=2025-10-30
libubox PKG_SOURCE_DATE:=2025-07-23
ustream-ssl PKG_SOURCE_DATE:=2024-07-28

Note that I've been testing against 24.10.5, hence the older ustream, so it's possible that something has changed in there to fix this issue, but I don't think the ustream code is really involved too much with this and anyway has hardly changed in the last couple of years.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions