Skip to content

Parent process is not notified about exited child stdin being closed #10066

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
p12tic opened this issue Feb 24, 2024 · 3 comments
Closed

Parent process is not notified about exited child stdin being closed #10066

p12tic opened this issue Feb 24, 2024 · 3 comments
Assignees
Labels
type: bug Something isn't working

Comments

@p12tic
Copy link
Contributor

p12tic commented Feb 24, 2024

Description

The minimized reproduction code below hangs on gVisor. It creates a child process via fork+exec and waits for it to exit including any pending IO operations. On runc the following is returned to epoll_wait of the parent process upon child exit (strace output):

<... epoll_wait resumed>[{events=EPOLLHUP, data={u32=10, u64=10}}, {events=EPOLLHUP, data={u32=8, u64=140733193388040}}, {events=EPOLLERR, data={u32=7, u64=140733193388039}}], 5, -1) = 3

epoll is setup as follows:

epoll_ctl(3, EPOLL_CTL_ADD, 7, {events=EPOLLIN, data={u32=7, u64=140733193388039}}  
epoll_ctl(3, EPOLL_CTL_ADD, 8, {events=EPOLLIN, data={u32=8, u64=140733193388040}}
epoll_ctl(3, EPOLL_CTL_ADD, 10, {events=EPOLLIN, data={u32=10, u64=10}}

Whereas on gVisor the following is observed:

<... epoll_wait resumed>[{events=EPOLLHUP, data={u32=8, u64=140664473911304}}, {events=EPOLLHUP, data={u32=10, u64=10}}], 5, -1) = 2

epoll is setup as follows:

epoll_ctl(3, EPOLL_CTL_ADD, 7, {events=EPOLLIN, data={u32=7, u64=140664473911303}}
epoll_ctl(3, EPOLL_CTL_ADD, 8, {events=EPOLLIN, data={u32=8, u64=140664473911304}}
epoll_ctl(3, EPOLL_CTL_ADD, 10, {events=EPOLLIN, data={u32=10, u64=10}}

The 7, 8, 10 file descriptors refer to pipes to stdin, stdout and stderr of the child process respectively.

As can be seen, on real Linux EPOLLERR is returned for stdin pipe upon child process exit whereas on gVisor this is absent.

Steps to reproduce

sudo podman run -it --runtime=runsc debian:bookworm /bin/bash

In the container:

apt update
apt install -y python3-twisted nano strace
nano bug.py
# <... paste the code snippet below into the file >

# reproduce bug
python3 bug.py

# or, to observe strace output described above:
strace -f python3 bug.py

Test code in Python:


import sys
from twisted.internet import reactor
from twisted.internet import protocol


class LocalPP(protocol.ProcessProtocol):
    def processEnded(self, status):
        print(f"END: {status}")
        super().processEnded(status)
        reactor.stop()


def main():
    cmd = [sys.executable, "-c", "import sys; sys.exit(1)"]
    reactor.spawnProcess(LocalPP(), cmd[0], cmd)
    reactor.run()

if __name__ == '__main__':
    main()

runsc version

runsc version release-20240212.0
spec: 1.1.0-rc.1

docker version (if using docker)

Client:       Podman Engine
Version:      4.7.2
API Version:  4.7.2
Go Version:   go1.21.3
Built:        Thu Jan  1 03:00:00 1970
OS/Arch:      linux/amd64

uname

Linux abcd 6.1.0-15-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.66-1 (2023-12-09) x86_64 GNU/Linux

kubectl (if using Kubernetes)

No response

repo state (if built from source)

No response

runsc debug logs (if available)

No response

@p12tic p12tic added the type: bug Something isn't working label Feb 24, 2024
@avagin
Copy link
Collaborator

avagin commented Mar 5, 2024

epoll_ctl(3, EPOLL_CTL_ADD, 7, {events=EPOLLIN, data={u32=7, u64=140733193388039}}

It is strange that stdin (write-only fd) is polled with EPOLLIN.

@p12tic
Copy link
Contributor Author

p12tic commented Mar 9, 2024

Awesome, thanks for a quick turnaround for this bug.

@p12tic
Copy link
Contributor Author

p12tic commented Mar 9, 2024

@avagin

It is strange that stdin (write-only fd) is polled with EPOLLIN.

The Twisted framework that exposed this bug has some workarounds for bugs in Linux going back to v2.6.11. I wouldn't be surprised if this behavior was some kind of workaround that has never been touched since then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants