containerd version: 1.1.0
Reproducing
Note that we demonstrate this with ctr for ease of use, but we first observed this when using the containerd Go API.
$ ctr -a /path/to/containerd.sock images pull docker.io/library/redis:alpine # pull an image
$ ctr -a /path/to/containerd.sock container create docker.io/library/redis:alpine boo # creat a container
$ ctr -a /path/to/containerd.sock task start boo
Next, exec a process with stdin in the container
echo hi | ctr -a /path/to/containerd.sock task exec boo /bin/cat --exec-id aaaahhhh
Most of the time this will correctly echo "hi" but the process will hang.
Expected behaviour
- I see "hi" on stdout
- The process exits successfully
Details
After some investigation, we've seen that the client side of containerd will create FIFOs for stdin, stdout & stderr, the path to these FIFO's is then passed on to the containerd server. The containerd server will check if the FIFOs exist, and will create the FIFOs if they don't. containerd will then open the stdin FIFOs in WRONLY mode (even if it's already opened on the client side).
When the stdin buffer is exhuasted, we see the EOF event causes the write side of the client pipe to close. However, from the man7 docs on pipes, all of the open fds for a particular pipe opened in write mode need to be closed before the read end of the pipe would receive an EOF on a subsequent read. So, the pipe opened by the server in WRONLY mode would cause a hang when /bin/cat is reading from stdin (a.k.a the read end of the pipe).
Note
We intend to start working on a PR to address in the next few days.
Discovered by @BooleanCat and @yulianedyalkova
containerd version: 1.1.0
Reproducing
Note that we demonstrate this with
ctrfor ease of use, but we first observed this when using the containerd Go API.Next, exec a process with stdin in the container
Most of the time this will correctly echo "hi" but the process will hang.
Expected behaviour
Details
After some investigation, we've seen that the client side of containerd will create FIFOs for stdin, stdout & stderr, the path to these FIFO's is then passed on to the containerd server. The containerd server will check if the FIFOs exist, and will create the FIFOs if they don't. containerd will then open the stdin FIFOs in WRONLY mode (even if it's already opened on the client side).
When the stdin buffer is exhuasted, we see the EOF event causes the write side of the client pipe to close. However, from the man7 docs on pipes, all of the open fds for a particular pipe opened in write mode need to be closed before the read end of the pipe would receive an EOF on a subsequent read. So, the pipe opened by the server in WRONLY mode would cause a hang when /bin/cat is reading from stdin (a.k.a the read end of the pipe).
Note
We intend to start working on a PR to address in the next few days.
Discovered by @BooleanCat and @yulianedyalkova