github.com/MerlinKodo/gvisor@v0.0.0-20231110090155-957f62ecf90e/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/MerlinKodo/gvisor/runsc/cmd/util" 24 "github.com/MerlinKodo/gvisor/runsc/config" 25 "github.com/MerlinKodo/gvisor/runsc/container" 26 "github.com/MerlinKodo/gvisor/runsc/flag" 27 "github.com/google/subcommands" 28 "golang.org/x/sys/unix" 29 ) 30 31 // Kill implements subcommands.Command for the "kill" command. 32 type Kill struct { 33 all bool 34 pid int 35 } 36 37 // Name implements subcommands.Command.Name. 38 func (*Kill) Name() string { 39 return "kill" 40 } 41 42 // Synopsis implements subcommands.Command.Synopsis. 43 func (*Kill) Synopsis() string { 44 return "sends a signal to the container" 45 } 46 47 // Usage implements subcommands.Command.Usage. 48 func (*Kill) Usage() string { 49 return `kill <container id> [signal]` 50 } 51 52 // SetFlags implements subcommands.Command.SetFlags. 53 func (k *Kill) SetFlags(f *flag.FlagSet) { 54 f.BoolVar(&k.all, "all", false, "send the specified signal to all processes inside the container") 55 f.IntVar(&k.pid, "pid", 0, "send the specified signal to a specific process. pid is relative to the root PID namespace") 56 } 57 58 // Execute implements subcommands.Command.Execute. 59 func (k *Kill) Execute(_ context.Context, f *flag.FlagSet, args ...any) subcommands.ExitStatus { 60 if f.NArg() == 0 || f.NArg() > 2 { 61 f.Usage() 62 return subcommands.ExitUsageError 63 } 64 65 id := f.Arg(0) 66 conf := args[0].(*config.Config) 67 68 if k.pid != 0 && k.all { 69 util.Fatalf("it is invalid to specify both --all and --pid") 70 } 71 72 c, err := container.Load(conf.RootDir, container.FullID{ContainerID: id}, container.LoadOpts{}) 73 if err != nil { 74 util.Fatalf("loading container: %v", err) 75 } 76 77 // The OCI command-line spec says that the signal should be specified 78 // via a flag, but runc (and things that call runc) pass it as an 79 // argument. 80 signal := f.Arg(1) 81 if signal == "" { 82 signal = "TERM" 83 } 84 85 sig, err := parseSignal(signal) 86 if err != nil { 87 util.Fatalf("%v", err) 88 } 89 90 if k.pid != 0 { 91 if err := c.SignalProcess(sig, int32(k.pid)); err != nil { 92 util.Fatalf("failed to signal pid %d: %v", k.pid, err) 93 } 94 } else { 95 if err := c.SignalContainer(sig, k.all); err != nil { 96 util.Fatalf("%v", err) 97 } 98 } 99 return subcommands.ExitSuccess 100 } 101 102 func parseSignal(s string) (unix.Signal, error) { 103 n, err := strconv.Atoi(s) 104 if err == nil { 105 sig := unix.Signal(n) 106 for _, msig := range signalMap { 107 if sig == msig { 108 return sig, nil 109 } 110 } 111 return -1, fmt.Errorf("unknown signal %q", s) 112 } 113 if sig, ok := signalMap[strings.TrimPrefix(strings.ToUpper(s), "SIG")]; ok { 114 return sig, nil 115 } 116 return -1, fmt.Errorf("unknown signal %q", s) 117 } 118 119 var signalMap = map[string]unix.Signal{ 120 "ABRT": unix.SIGABRT, 121 "ALRM": unix.SIGALRM, 122 "BUS": unix.SIGBUS, 123 "CHLD": unix.SIGCHLD, 124 "CLD": unix.SIGCLD, 125 "CONT": unix.SIGCONT, 126 "FPE": unix.SIGFPE, 127 "HUP": unix.SIGHUP, 128 "ILL": unix.SIGILL, 129 "INT": unix.SIGINT, 130 "IO": unix.SIGIO, 131 "IOT": unix.SIGIOT, 132 "KILL": unix.SIGKILL, 133 "PIPE": unix.SIGPIPE, 134 "POLL": unix.SIGPOLL, 135 "PROF": unix.SIGPROF, 136 "PWR": unix.SIGPWR, 137 "QUIT": unix.SIGQUIT, 138 "SEGV": unix.SIGSEGV, 139 "STKFLT": unix.SIGSTKFLT, 140 "STOP": unix.SIGSTOP, 141 "SYS": unix.SIGSYS, 142 "TERM": unix.SIGTERM, 143 "TRAP": unix.SIGTRAP, 144 "TSTP": unix.SIGTSTP, 145 "TTIN": unix.SIGTTIN, 146 "TTOU": unix.SIGTTOU, 147 "URG": unix.SIGURG, 148 "USR1": unix.SIGUSR1, 149 "USR2": unix.SIGUSR2, 150 "VTALRM": unix.SIGVTALRM, 151 "WINCH": unix.SIGWINCH, 152 "XCPU": unix.SIGXCPU, 153 "XFSZ": unix.SIGXFSZ, 154 }