garden-runc-release
garden-runc-release copied to clipboard
Use containerd-style stdin closer instead of exponential backoff stdin close
In order to address containerd processes hanging forever when stdin is provided (see here and here), we are closing the stdin of a process immediately after we start it.
We have recently realised that this might not be the best solution as there might be a user process that sleeps for a while and then starts reading from stdin. We suspect that such a process would never get the stdin contents as stdin would be closed at the time the process reads from it. We should probably implement something similar to what containerd does in their stdin closer that is a wrapper over stdin that closes it whenever EOF is reached.
Some concerns though:
- Is it really true that a process that reads from stdin a while after being started would not get stdin content (as stdin has been closed)
- If we used the stdin closer, what would happen if a process is provided with stdin but never cares to read from stdin? Would it hang forever as stdin is never closed as EOF is never reached?
Runtime Tracker story for this issue has been created: https://www.pivotaltracker.com/story/show/180812123
Some findings I found looking into the concerns:
- Is it really true that a process that reads from stdin a while after being started would not get stdin content (as stdin has been closed)
According to https://man7.org/linux/man-pages/man3/stdio.3.html, stdin is a stream and if it is closed, one should get some sort of error depending on how the error handling is implemented in a programming language (for example, in Java, you will get an
IOException
.
Output streams are flushed (any unwritten buffer contents are transferred to the host environment) before the stream is disassociated from the file. The value of a pointer to a FILE object is indeterminate after a file is closed (garbage).
- If we used the stdin closer, what would happen if a process is provided with stdin but never cares to read from stdin? Would it hang forever as stdin is never closed as EOF is never reached? If I'm understanding https://www.man7.org/linux/man-pages/man7/pipe.7.html correctly, if a process does not read stdin, then it cannot reach EOF so the process should hang indefinitely. However, it is not possible to check if a process is specifically reading from a file or not. We can only check if stdin has reached EOF.
With that, would it make sense to let a process start, check if the file it is interested in can be read, and if so, check for EOF in stdin periodically and then close the process after a set amount of time? I also think this is a scenario where it's better to either close the process immediately as implemented or check for EOF in stdin (and potentially having the process hang).