func (a *Agent) Prepare() { if state.Local() { err := createCleanDir(a.dir) if err != nil { log.Fatal(err) } } log.Printf("Going to run %s as %s", a.Name, a.args) }
func (a *Agent) start() { if a.cmd != nil { log.Fatal("Cannot call start(): program already running!") } if a.killcount > 0 { return } cmd := exec.Command(a.args[0], a.args[1:]...) stdout, err := cmd.StdoutPipe() if err != nil { log.Fatal("Unable to open pipe to stdout: %v", err) } stderr, err := cmd.StderrPipe() if err != nil { log.Fatal("Unable to open pipe to stderr: %v", err) } if state.Local() { cmd.Dir = a.dir } go copyLines(a.Name, stdout) go copyLines(a.Name, stderr) log.Printf("Starting %v", a) err = cmd.Start() if err != nil { log.Fatalf("Could't spawn %v: %s", a, err) } go func() { err := cmd.Wait() a.Lock() defer a.Unlock() // Not the active command if a.cmd != cmd { return } var d string if err != nil { d = fmt.Sprintf("Command exited unexpectedly: %s (%s)", cmd, err) } else { d = fmt.Sprintf("Command exited unexpectedly (but cleanly!): %s", cmd) } state.RecordDisqualifier(d) state.WaitGroup().Exit() }() a.cmd = cmd }
func (a *Agent) Freeze() { a.Lock() defer a.Unlock() if a.stopcount == 0 && a.cmd != nil { if state.Local() { a.cmd.Process.Signal(syscall.SIGTSTP) } else { file, err := os.Open(a.freezefile) if err != nil { log.Printf("freeze error: %v", err) return } file.WriteString("FROZEN\n") file.Close() } } a.stopcount++ }
func NewAgent(i uint) *Agent { args := make([]string, 0) var container string if !state.Local() { // Run under LXC remotely homedir := fmt.Sprintf("/home/%s", state.Username()) container = state.ContainerIds()[i] args = append(args, "lxc-attach", "-n", container, "--clear-env", "--", "/ctf3/shell.sh", state.Username(), homedir, ) } args = append(args, state.Sqlcluster()) args = append(args, "-l", SocketName(i), "-d", ContainerWorkingDir(i)) if i != 0 { args = append(args, "--join="+SocketName(0)) } args = append(args, state.Args()...) cs, err := unix.Encode(SocketPath(i, i)) if err != nil { log.Fatalf("Couldn't create node %d: %s", i, err) } return &Agent{ Name: NodeName(i), ConnectionString: cs, args: args, dir: WorkingDir(i), // This is going to contain nonsense if container is empty, but // it won't matter freezefile: "/sys/fs/cgroup/freezer/lxc/" + container + "/freezer.state", } }
func (a *Agent) Thaw() { a.Lock() defer a.Unlock() a.stopcount-- if a.stopcount == 0 && a.cmd == nil { a.start() } else if a.stopcount == 0 { if state.Local() { a.cmd.Process.Signal(syscall.SIGCONT) } else { file, err := os.Open(a.freezefile) if err != nil { log.Printf("thaw error: %v", err) return } file.WriteString("THAWED\n") file.Close() } } }