github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/runsc/cmd/kill.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package cmd 16 17 import ( 18 "context" 19 "fmt" 20 "strconv" 21 "strings" 22 23 "github.com/google/subcommands" 24 "golang.org/x/sys/unix" 25 "github.com/SagerNet/gvisor/runsc/config" 26 "github.com/SagerNet/gvisor/runsc/container" 27 "github.com/SagerNet/gvisor/runsc/flag" 28 ) 29 30 // Kill implements subcommands.Command for the "kill" command. 31 type Kill struct { 32 all bool 33 pid int 34 } 35 36 // Name implements subcommands.Command.Name. 37 func (*Kill) Name() string { 38 return "kill" 39 } 40 41 // Synopsis implements subcommands.Command.Synopsis. 42 func (*Kill) Synopsis() string { 43 return "sends a signal to the container" 44 } 45 46 // Usage implements subcommands.Command.Usage. 47 func (*Kill) Usage() string { 48 return `kill <container id> [signal]` 49 } 50 51 // SetFlags implements subcommands.Command.SetFlags. 52 func (k *Kill) SetFlags(f *flag.FlagSet) { 53 f.BoolVar(&k.all, "all", false, "send the specified signal to all processes inside the container") 54 f.IntVar(&k.pid, "pid", 0, "send the specified signal to a specific process. pid is relative to the root PID namespace") 55 } 56 57 // Execute implements subcommands.Command.Execute. 58 func (k *Kill) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus { 59 if f.NArg() == 0 || f.NArg() > 2 { 60 f.Usage() 61 return subcommands.ExitUsageError 62 } 63 64 id := f.Arg(0) 65 conf := args[0].(*config.Config) 66 67 if k.pid != 0 && k.all { 68 Fatalf("it is invalid to specify both --all and --pid") 69 } 70 71 c, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) 72 if err != nil { 73 Fatalf("loading container: %v", err) 74 } 75 76 // The OCI command-line spec says that the signal should be specified 77 // via a flag, but runc (and things that call runc) pass it as an 78 // argument. 79 signal := f.Arg(1) 80 if signal == "" { 81 signal = "TERM" 82 } 83 84 sig, err := parseSignal(signal) 85 if err != nil { 86 Fatalf("%v", err) 87 } 88 89 if k.pid != 0 { 90 if err := c.SignalProcess(sig, int32(k.pid)); err != nil { 91 Fatalf("failed to signal pid %d: %v", k.pid, err) 92 } 93 } else { 94 if err := c.SignalContainer(sig, k.all); err != nil { 95 Fatalf("%v", err) 96 } 97 } 98 return subcommands.ExitSuccess 99 } 100 101 func parseSignal(s string) (unix.Signal, error) { 102 n, err := strconv.Atoi(s) 103 if err == nil { 104 sig := unix.Signal(n) 105 for _, msig := range signalMap { 106 if sig == msig { 107 return sig, nil 108 } 109 } 110 return -1, fmt.Errorf("unknown signal %q", s) 111 } 112 if sig, ok := signalMap[strings.TrimPrefix(strings.ToUpper(s), "SIG")]; ok { 113 return sig, nil 114 } 115 return -1, fmt.Errorf("unknown signal %q", s) 116 } 117 118 var signalMap = map[string]unix.Signal{ 119 "ABRT": unix.SIGABRT, 120 "ALRM": unix.SIGALRM, 121 "BUS": unix.SIGBUS, 122 "CHLD": unix.SIGCHLD, 123 "CLD": unix.SIGCLD, 124 "CONT": unix.SIGCONT, 125 "FPE": unix.SIGFPE, 126 "HUP": unix.SIGHUP, 127 "ILL": unix.SIGILL, 128 "INT": unix.SIGINT, 129 "IO": unix.SIGIO, 130 "IOT": unix.SIGIOT, 131 "KILL": unix.SIGKILL, 132 "PIPE": unix.SIGPIPE, 133 "POLL": unix.SIGPOLL, 134 "PROF": unix.SIGPROF, 135 "PWR": unix.SIGPWR, 136 "QUIT": unix.SIGQUIT, 137 "SEGV": unix.SIGSEGV, 138 "STKFLT": unix.SIGSTKFLT, 139 "STOP": unix.SIGSTOP, 140 "SYS": unix.SIGSYS, 141 "TERM": unix.SIGTERM, 142 "TRAP": unix.SIGTRAP, 143 "TSTP": unix.SIGTSTP, 144 "TTIN": unix.SIGTTIN, 145 "TTOU": unix.SIGTTOU, 146 "URG": unix.SIGURG, 147 "USR1": unix.SIGUSR1, 148 "USR2": unix.SIGUSR2, 149 "VTALRM": unix.SIGVTALRM, 150 "WINCH": unix.SIGWINCH, 151 "XCPU": unix.SIGXCPU, 152 "XFSZ": unix.SIGXFSZ, 153 }