Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
send slavefd to the other side when terminal=true
Currently when terminal=true and container side decides to close stdio and also eventually close /dev/console, it effectively looses the slave side of the pty pair, and IO on the master results in EIO If you use EPOLL on all IO we can pretend EIO is ok and continue, but we dont. And moving to EPOLL is not really easy or straighforward. Instead when terminal=true, this patch attempts to send over the valid slavefd when it was opened, and the master side will hold on to it, so no matter what the container side is doing we will always have a valid pty pair. The following Go program simulate the container behavior: ``` package main import ( "fmt" "log" "os" "syscall" "time" ) func main() { console, err := os.OpenFile("/dev/console", os.O_RDWR, 0) if err != nil { log.Fatal(err) } fmt.Fprintln(console, "write before dup /dev/null to stdio") makeNullStdio() fmt.Fprintln(console, "write after dup /dev/null to stdio") console.Close() logf, _ := os.Create("/tmp/logfile") for { console, err = os.OpenFile("/dev/console", os.O_RDWR, 0) if err != nil { fmt.Fprint(logf, err) os.Exit(1) } fmt.Fprintln(console, "open, write to console, and close") console.Close() time.Sleep(time.Second) } } func makeNullStdio() { nullFd, _ := os.OpenFile("/dev/null", os.O_RDWR, 0) defer nullFd.Close() fd := int(nullFd.Fd()) syscall.Dup2(fd, 0) syscall.Dup2(fd, 1) syscall.Dup2(fd, 2) } ``` Without the patch, we have the following output: ``` hanamura# runc run hello write before dup /dev/null to stdio write after dup /dev/null to stdio ``` After the patch ``` hanamura# runc run hello write before dup /dev/null to stdio write after dup /dev/null to stdio open, write to console, and close open, write to console, and close open, write to console, and close ``` Signed-off-by: Daniel Dao <[email protected]>
- Loading branch information