github.com/apptainer/singularity@v3.1.1+incompatible/internal/app/singularity/oci_kill_linux.go (about) 1 // Copyright (c) 2018-2019, Sylabs Inc. All rights reserved. 2 // This software is licensed under a 3-clause BSD license. Please consult the 3 // LICENSE.md file distributed with the sources of this project regarding your 4 // rights to use or distribute this software. 5 6 package singularity 7 8 import ( 9 "fmt" 10 "io" 11 "syscall" 12 "time" 13 14 "github.com/sylabs/singularity/internal/pkg/util/signal" 15 "github.com/sylabs/singularity/pkg/ociruntime" 16 "github.com/sylabs/singularity/pkg/util/unix" 17 ) 18 19 // OciKill kills container process 20 func OciKill(containerID string, killSignal string, killTimeout int) error { 21 // send signal to the instance 22 state, err := getState(containerID) 23 if err != nil { 24 return err 25 } 26 27 if state.Status != ociruntime.Created && state.Status != ociruntime.Running { 28 return fmt.Errorf("cannot kill '%s', the state of the container must be created or running", containerID) 29 } 30 31 sig := syscall.SIGTERM 32 33 if killSignal != "" { 34 sig, err = signal.Convert(killSignal) 35 if err != nil { 36 return err 37 } 38 } 39 40 if killTimeout > 0 { 41 c, err := unix.Dial(state.ControlSocket) 42 if err != nil { 43 return fmt.Errorf("failed to connect to control socket") 44 } 45 defer c.Close() 46 47 killed := make(chan bool, 1) 48 49 go func() { 50 // wait runtime close socket connection for ACK 51 d := make([]byte, 1) 52 if _, err := c.Read(d); err == io.EOF { 53 killed <- true 54 } 55 }() 56 57 if err := syscall.Kill(state.Pid, sig); err != nil { 58 return err 59 } 60 61 select { 62 case <-killed: 63 case <-time.After(time.Duration(killTimeout) * time.Second): 64 return syscall.Kill(state.Pid, syscall.SIGKILL) 65 } 66 } else { 67 return syscall.Kill(state.Pid, sig) 68 } 69 70 return nil 71 }