Skip to content
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

runc doesn't pass SIGINT to underlying process #1624

Open
qingyunha opened this issue Oct 28, 2017 · 2 comments
Open

runc doesn't pass SIGINT to underlying process #1624

qingyunha opened this issue Oct 28, 2017 · 2 comments

Comments

@qingyunha
Copy link

qingyunha commented Oct 28, 2017

I think signal handler is here.

    for s := range h.signals {
        switch s {
        case unix.SIGWINCH:
            // Ignore errors resizing, as above.
            _ = tty.resize()
        case unix.SIGCHLD:
            exits, err := h.reap()
            if err != nil {
                logrus.Error(err)
            }
            for _, e := range exits {
                logrus.WithFields(logrus.Fields{
                    "pid":    e.pid,
                    "status": e.status,
                }).Debug("process exited")
                if e.pid == pid1 {
                    // call Wait() on the process even though we already have the exit
                    // status because we must ensure that any of the go specific process
                    // fun such as flushing pipes are complete before we return.
                    process.Wait()
                    if h.notifySocket != nil {
                        h.notifySocket.Close()
                    }
                    return e.status, nil
                }
            }
        default:
            logrus.Debugf("sending signal to process %s", s)
            if err := unix.Kill(pid1, s.(syscall.Signal)); err != nil {
                logrus.Error(err)
            }
        }
    }

so the SIGINT will send to pid1. Right?

But when I run runc --log /dev/stderr --debug run xxx, then kill -SIGINT runc. I didn't see log sending signal to process as I expected. runc just exit and leave container process running in some case.

Other signals than SIGINT will do that. I am confused about this, please help me.

@qingyunha
Copy link
Author

the strace output when I kill SIGTTIN and SIGINT

[pid  7031] --- SIGTTIN {si_signo=SIGTTIN, si_code=SI_USER, si_pid=7065, si_uid=0} ---                                                                                                        
[pid  7031] rt_sigreturn({mask=[SYS]})  = 202                                                                                                                                                 
[pid  7032] sched_yield()               = 0                                                                                                                                                   
[pid  7032] epoll_wait(4,  <unfinished ...>                                                                                                                                                   
[pid  7033] epoll_wait(4,  <unfinished ...>                                                                                                                                                   
[pid  7032] <... epoll_wait resumed> [], 128, 0) = 0                                           
[pid  7044] fcntl(3, F_GETFL <unfinished ...>  
[pid  7033] <... epoll_wait resumed> [], 128, 0) = 0
[pid  7044] <... fcntl resumed> )       = 0x109c01 (flags O_WRONLY|O_APPEND|O_NONBLOCK|O_SYNC|O_LARGEFILE)                                                                                    
[pid  7044] fcntl(3, F_SETFL, O_WRONLY|O_APPEND|O_SYNC|O_LARGEFILE) = 0
[pid  7044] ioctl(3, TCGETS, {B38400 opost -isig -icanon -echo ...}) = 0
[pid  7044] write(3, "\33[37mDEBU\33[0m[0054] sending sign"..., 67) = 67
[pid  7044] kill(7039, SIGTTIN)         = 0                                                    
[pid  7044] epoll_wait(4, [{EPOLLOUT, {u32=258010880, u64=140707681595136}}], 128, 0) = 1
[pid  7036] <... epoll_wait resumed> [{EPOLLIN|EPOLLOUT, {u32=7, u64=7}}], 128, -1) = 1
[pid  7036] epoll_wait(9,  <unfinished ...>    
[pid  7044] epoll_wait(4, [], 128, 0)   = 0                                                    
[pid  7044] read(7,  <unfinished ...>          
[pid  7033] epoll_wait(4,  <unfinished ...>    
[pid  7044] <... read resumed> "get signal stopped (tty input)\n", 32768) = 31
[pid  7033] <... epoll_wait resumed> [], 128, 0) = 0
[pid  7044] write(1, "get signal stopped (tty input)\n", 31) = 31
[pid  7044] read(7, 0xc4201ca000, 32768) = -1 EAGAIN (Resource temporarily unavailable)
[pid  7044] epoll_wait(4, [{EPOLLOUT, {u32=258010880, u64=140707681595136}}], 128, 0) = 1
[pid  7032] epoll_wait(4, [], 128, 0)   = 0    
[pid  7044] epoll_wait(4, [], 128, 0)   = 0    
                                               
                                               
                                               
[pid  7031] --- SIGINT {si_signo=SIGINT, si_code=SI_USER, si_pid=7072, si_uid=0} ---
[pid  7031] rt_sigreturn({mask=[SYS]} <unfinished ...>
[pid  7032] epoll_wait(4, [], 128, 0)   = 0
[pid  7044] epoll_wait(4, [], 128, 0)   = 0
[pid  7033] ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...} <unfinished ...>
[pid  7031] <... rt_sigreturn resumed> ) = 202
[pid  7033] <... ioctl resumed> )       = 0
[pid  7033] exit_group(0 <unfinished ...>
[pid  7034] <... read resumed> <unfinished ...>) = ?
[pid  7033] <... exit_group resumed>)   = ?
[pid  7034] +++ exited with 0 +++
[pid  7035] +++ exited with 0 +++
[pid  7036] <... epoll_wait resumed> <unfinished ...>) = ?
[pid  7033] +++ exited with 0 +++
[pid  7044] +++ exited with 0 +++
[pid  7036] +++ exited with 0 +++
[pid  7032] +++ exited with 0 +++
+++ exited with 0 +++

@qingyunha qingyunha changed the title question: How runc handle SIGINT runc doesn't pass SIGINT to underlying process Oct 29, 2017
@qingyunha
Copy link
Author

There is another signal handler in https://github.com/opencontainers/runc/blob/master/tty.go#L105 that cause runc exit immediately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant