sysv-initctl: avoid busy loop without FIFO clients - #1056
Closed
pva wants to merge 1 commit into
Closed
Conversation
sysv-initctl opened /run/initctl with O_RDONLY | O_NONBLOCK and called
read() directly in a loop. Immediately after startup, no client has the
FIFO open for writing, so read() returns zero instead of waiting. The
daemon treated this as a short request and retried continuously,
consuming CPU and flooding syslog with "read: short count".
This can be reproduced on a system using openrc-init by starting the
compatibility daemon without connecting an initctl client:
rc-service sysv-initctl start
pid=$(pgrep -x sysv-initctl)
strace -p "$pid" -e read
top -p "$pid"
Before this change, strace repeatedly reports read() returning zero.
Open the read end nonblocking during setup, keep a dummy write end open,
and then make the reader blocking. This allows the daemon to sleep in
read() while no clients are connected. Mark both descriptors
close-on-exec.
Member
|
this is much of the same logic as openrc-init, so i pushed a commit reusing it also there's no need to repeat the explanation every time, just refer to the old fix |
Contributor
Author
|
@navi-desu Yea, it's a good idea to move code into a helper header. Yet, although the fixes are similar, the triggers are different. In the first case, the issue was triggered by connecting to the socket and sending a signal; here, it is triggered when no listener is present. That's why the descriptions were different. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
sysv-initctl opened /run/initctl with O_RDONLY | O_NONBLOCK and called read() directly in a loop. Immediately after startup, no client has the FIFO open for writing, so read() returns zero instead of waiting. The daemon treated this as a short request and retried continuously, consuming CPU and flooding syslog with "read: short count".
This can be reproduced on a system using openrc-init by starting the compatibility daemon without connecting an initctl client:
Before this change, strace repeatedly reports read() returning zero.
Open the read end nonblocking during setup, keep a dummy write end open, and then make the reader blocking. This allows the daemon to sleep in read() while no clients are connected. Mark both descriptors close-on-exec.