github.com/justinjmoses/evergreen@v0.0.0-20170530173719-1d50e381ff0d/plugin/builtin/shell/subtree_solaris.go (about) 1 package shell 2 3 import ( 4 "fmt" 5 "os" 6 "os/exec" 7 "regexp" 8 "strings" 9 10 "github.com/evergreen-ci/evergreen/plugin" 11 "github.com/mongodb/grip/slogger" 12 ) 13 14 // This is a regex used to extract environment variables from the output of pargs -e 15 // so that we can detect the 'tracer' strings. 16 var pargsEnvPattern = regexp.MustCompile("^\\s*envp\\[\\d+\\]:\\s*(.*)$") 17 18 func trackProcess(key string, pid int, log plugin.Logger) { 19 // trackProcess is a noop on solaris, because we detect all the processes to be killed in 20 // cleanup() and we don't need to do any special bookkeeping up-front. 21 } 22 23 // getEnv returns a slice of environment variables for the given pid, in the form 24 // []string{"VAR1=FOO", "VAR2=BAR", ...} 25 // This function works by calling "pargs -e $pid" and parsing its output. 26 func getEnv(pid int) ([]string, error) { 27 /* In Solaris we extract environment variables by calling 'pargs -e $pid' 28 on each process in the system. The output of pargs looks like: 29 $ pargs -e 499 30 499: /usr/perl5/bin/perl /usr/lib/intrd 31 envp[0]: PATH=/usr/sbin:/usr/bin 32 envp[1]: PWD=/ 33 envp[2]: SHLVL=1 34 */ 35 out, err := exec.Command("pargs", "-e", fmt.Sprintf("%d", pid)).CombinedOutput() 36 if err != nil { 37 // Probably permission denied or process is gone away. 38 return nil, err 39 } 40 lines := strings.Split(string(out), "\n") 41 results := make([]string, 0, len(lines)) 42 for _, line := range lines { 43 if matches := pargsEnvPattern.FindStringSubmatch(line); matches != nil { 44 results = append(results, matches[1]) 45 } 46 } 47 return results, nil 48 } 49 50 func cleanup(key string, log plugin.Logger) error { 51 pids, err := listProc() 52 if err != nil { 53 return err 54 } 55 pidMarker := fmt.Sprintf("EVR_AGENT_PID=%v", os.Getpid()) 56 taskMarker := fmt.Sprintf("EVR_TASK_ID=%v", key) 57 for _, pid := range pids { 58 env, err := getEnv(pid) 59 if err != nil { 60 continue 61 } 62 if envHasMarkers(env, pidMarker, taskMarker) { 63 p := os.Process{} 64 p.Pid = pid 65 if err := p.Kill(); err != nil { 66 log.LogSystem(slogger.INFO, "Cleanup killing %v failed: %v", pid, err) 67 } else { 68 log.LogTask(slogger.INFO, "Cleanup killed process %v", pid) 69 } 70 } 71 } 72 return nil 73 }