github.com/hinshun/containerd@v0.2.7/containerd-shim/process_linux.go (about) 1 // +build !solaris 2 3 package main 4 5 import ( 6 "fmt" 7 "io" 8 "os/exec" 9 "syscall" 10 "time" 11 12 "github.com/tonistiigi/fifo" 13 "golang.org/x/net/context" 14 ) 15 16 // setPDeathSig sets the parent death signal to SIGKILL so that if the 17 // shim dies the container process also dies. 18 func setPDeathSig() *syscall.SysProcAttr { 19 return &syscall.SysProcAttr{ 20 Pdeathsig: syscall.SIGKILL, 21 } 22 } 23 24 // openIO opens the pre-created fifo's for use with the container 25 // in RDWR so that they remain open if the other side stops listening 26 func (p *process) openIO() error { 27 p.stdio = &stdio{} 28 var ( 29 uid = p.state.RootUID 30 gid = p.state.RootGID 31 ) 32 33 ctx, _ := context.WithTimeout(context.Background(), 15*time.Second) 34 35 stdinCloser, err := fifo.OpenFifo(ctx, p.state.Stdin, syscall.O_WRONLY|syscall.O_NONBLOCK, 0) 36 if err != nil { 37 return err 38 } 39 p.stdinCloser = stdinCloser 40 41 if p.state.Terminal { 42 master, console, err := newConsole(uid, gid) 43 if err != nil { 44 return err 45 } 46 p.console = master 47 p.consolePath = console 48 stdin, err := fifo.OpenFifo(ctx, p.state.Stdin, syscall.O_RDONLY, 0) 49 if err != nil { 50 return err 51 } 52 go io.Copy(master, stdin) 53 stdoutw, err := fifo.OpenFifo(ctx, p.state.Stdout, syscall.O_WRONLY, 0) 54 if err != nil { 55 return err 56 } 57 stdoutr, err := fifo.OpenFifo(ctx, p.state.Stdout, syscall.O_RDONLY, 0) 58 if err != nil { 59 return err 60 } 61 p.Add(1) 62 go func() { 63 io.Copy(stdoutw, master) 64 master.Close() 65 stdoutr.Close() 66 stdoutw.Close() 67 p.Done() 68 }() 69 return nil 70 } 71 i, err := p.initializeIO(uid) 72 if err != nil { 73 return err 74 } 75 p.shimIO = i 76 // non-tty 77 for name, dest := range map[string]func(wc io.WriteCloser, rc io.Closer){ 78 p.state.Stdout: func(wc io.WriteCloser, rc io.Closer) { 79 p.Add(1) 80 go func() { 81 io.Copy(wc, i.Stdout) 82 p.Done() 83 wc.Close() 84 rc.Close() 85 }() 86 }, 87 p.state.Stderr: func(wc io.WriteCloser, rc io.Closer) { 88 p.Add(1) 89 go func() { 90 io.Copy(wc, i.Stderr) 91 p.Done() 92 wc.Close() 93 rc.Close() 94 }() 95 }, 96 } { 97 fw, err := fifo.OpenFifo(ctx, name, syscall.O_WRONLY, 0) 98 if err != nil { 99 return fmt.Errorf("containerd-shim: opening %s failed: %s", name, err) 100 } 101 fr, err := fifo.OpenFifo(ctx, name, syscall.O_RDONLY, 0) 102 if err != nil { 103 return fmt.Errorf("containerd-shim: opening %s failed: %s", name, err) 104 } 105 dest(fw, fr) 106 } 107 108 f, err := fifo.OpenFifo(ctx, p.state.Stdin, syscall.O_RDONLY, 0) 109 if err != nil { 110 return fmt.Errorf("containerd-shim: opening %s failed: %s", p.state.Stdin, err) 111 } 112 go func() { 113 io.Copy(i.Stdin, f) 114 i.Stdin.Close() 115 f.Close() 116 }() 117 118 return nil 119 } 120 121 func (p *process) killAll() error { 122 if !p.state.Exec { 123 cmd := exec.Command(p.runtime, append(p.state.RuntimeArgs, "kill", "--all", p.id, "SIGKILL")...) 124 cmd.SysProcAttr = setPDeathSig() 125 out, err := cmd.CombinedOutput() 126 if err != nil { 127 return fmt.Errorf("%s: %v", out, err) 128 } 129 } 130 return nil 131 }