diff --git a/dashboard/app/config_stub.go b/dashboard/app/config_stub.go index 0c68453a..932ebf32 100644 --- a/dashboard/app/config_stub.go +++ b/dashboard/app/config_stub.go @@ -2,6 +2,7 @@ // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. // +build !aetest +// +build package dash diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index 055a7466..1bdc6bfb 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -15,6 +15,7 @@ import ( "strings" "unsafe" + "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/prog" "github.com/google/syzkaller/sys/targets" ) @@ -521,7 +522,7 @@ func (ctx *context) preprocessCommonHeader(commonHeader string) (string, error) } defines = append(defines, ctx.sysTarget.CArch...) - cmd := exec.Command("cpp", "-nostdinc", "-undef", "-fdirectives-only", "-dDI", "-E", "-P", "-") + cmd := osutil.Command("cpp", "-nostdinc", "-undef", "-fdirectives-only", "-dDI", "-E", "-P", "-") for _, def := range defines { cmd.Args = append(cmd.Args, "-D"+def) } @@ -580,10 +581,10 @@ func Build(target *prog.Target, lang, src string) (string, error) { // We do generate uint64's for syscall arguments that overflow longs on 32-bit archs. flags = append(flags, "-Wno-overflow") } - out, err := exec.Command(compiler, append(flags, "-static")...).CombinedOutput() + out, err := osutil.Command(compiler, append(flags, "-static")...).CombinedOutput() if err != nil { // Some distributions don't have static libraries. - out, err = exec.Command(compiler, flags...).CombinedOutput() + out, err = osutil.Command(compiler, flags...).CombinedOutput() } if err != nil { os.Remove(bin.Name()) @@ -599,7 +600,7 @@ var NoCompilerErr = errors.New("no target compiler") // Format reformats C source using clang-format. func Format(src []byte) ([]byte, error) { stdout, stderr := new(bytes.Buffer), new(bytes.Buffer) - cmd := exec.Command("clang-format", "-assume-filename=/src.c", "-style", style) + cmd := osutil.Command("clang-format", "-assume-filename=/src.c", "-style", style) cmd.Stdin = bytes.NewReader(src) cmd.Stdout = stdout cmd.Stderr = stderr diff --git a/pkg/git/git.go b/pkg/git/git.go index 0178a300..e4a54f71 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -8,7 +8,6 @@ import ( "bytes" "fmt" "os" - "os/exec" "regexp" "strings" "time" @@ -154,13 +153,13 @@ var commitPrefixes = []string{ func Patch(dir string, patch []byte) error { // Do --dry-run first to not mess with partially consistent state. - cmd := exec.Command("patch", "-p1", "--force", "--ignore-whitespace", "--dry-run") + cmd := osutil.Command("patch", "-p1", "--force", "--ignore-whitespace", "--dry-run") cmd.Stdin = bytes.NewReader(patch) cmd.Dir = dir if output, err := cmd.CombinedOutput(); err != nil { // If it reverses clean, then it's already applied // (seems to be the easiest way to detect it). - cmd = exec.Command("patch", "-p1", "--force", "--ignore-whitespace", "--reverse", "--dry-run") + cmd = osutil.Command("patch", "-p1", "--force", "--ignore-whitespace", "--reverse", "--dry-run") cmd.Stdin = bytes.NewReader(patch) cmd.Dir = dir if _, err := cmd.CombinedOutput(); err == nil { @@ -169,7 +168,7 @@ func Patch(dir string, patch []byte) error { return fmt.Errorf("failed to apply patch:\n%s", output) } // Now apply for real. - cmd = exec.Command("patch", "-p1", "--force", "--ignore-whitespace") + cmd = osutil.Command("patch", "-p1", "--force", "--ignore-whitespace") cmd.Stdin = bytes.NewReader(patch) cmd.Dir = dir if output, err := cmd.CombinedOutput(); err != nil { diff --git a/pkg/ipc/ipc.go b/pkg/ipc/ipc.go index e77b0ace..2f1cf3ef 100644 --- a/pkg/ipc/ipc.go +++ b/pkg/ipc/ipc.go @@ -584,7 +584,7 @@ func makeCommand(pid int, bin []string, config Config, inFile *os.File, outFile c.readDone = make(chan []byte, 1) c.exited = make(chan struct{}) - cmd := exec.Command(bin[0], bin[1:]...) + cmd := osutil.Command(bin[0], bin[1:]...) if inFile != nil && outFile != nil { cmd.ExtraFiles = []*os.File{inFile, outFile} } diff --git a/pkg/kernel/kernel.go b/pkg/kernel/kernel.go index 5b93ebaa..2ec57354 100644 --- a/pkg/kernel/kernel.go +++ b/pkg/kernel/kernel.go @@ -61,12 +61,14 @@ func CreateImage(kernelDir, userspaceDir, cmdlineFile, sysctlFile, image, sshkey return fmt.Errorf("failed to write script file: %v", err) } bzImage := filepath.Join(kernelDir, filepath.FromSlash("arch/x86/boot/bzImage")) - env := []string{ - "SYZ_CMDLINE_FILE=" + osutil.Abs(cmdlineFile), - "SYZ_SYSCTL_FILE=" + osutil.Abs(sysctlFile), - } - _, err = osutil.RunCmdEnv(time.Hour, env, tempDir, scriptFile, userspaceDir, bzImage) - if err != nil { + cmd := osutil.Command(scriptFile, userspaceDir, bzImage) + cmd.Dir = tempDir + cmd.Env = append([]string{}, os.Environ()...) + cmd.Env = append(cmd.Env, + "SYZ_CMDLINE_FILE="+osutil.Abs(cmdlineFile), + "SYZ_SYSCTL_FILE="+osutil.Abs(sysctlFile), + ) + if _, err = osutil.Run(time.Hour, cmd); err != nil { return fmt.Errorf("image build failed: %v", err) } if err := osutil.CopyFile(filepath.Join(tempDir, "disk.raw"), image); err != nil { diff --git a/pkg/osutil/osutil.go b/pkg/osutil/osutil.go index 46919a6c..6f06fb4a 100644 --- a/pkg/osutil/osutil.go +++ b/pkg/osutil/osutil.go @@ -21,40 +21,45 @@ const ( // RunCmd runs "bin args..." in dir with timeout and returns its output. func RunCmd(timeout time.Duration, dir, bin string, args ...string) ([]byte, error) { - return runCmd(timeout, nil, dir, bin, args...) -} - -// RunCmdEnv is the same as RunCmd but also appends env. -func RunCmdEnv(timeout time.Duration, env []string, dir, bin string, args ...string) ([]byte, error) { - return runCmd(timeout, env, dir, bin, args...) -} - -func runCmd(timeout time.Duration, env []string, dir, bin string, args ...string) ([]byte, error) { - output := new(bytes.Buffer) - cmd := exec.Command(bin, args...) + cmd := Command(bin, args...) cmd.Dir = dir + return Run(timeout, cmd) +} + +// Run runs cmd with the specified timeout. +// Returns combined output. If the command fails, err includes output. +func Run(timeout time.Duration, cmd *exec.Cmd) ([]byte, error) { + output := new(bytes.Buffer) cmd.Stdout = output cmd.Stderr = output - cmd.Env = append([]string{}, os.Environ()...) - cmd.Env = append(cmd.Env, env...) if err := cmd.Start(); err != nil { - return nil, fmt.Errorf("failed to start %v %+v: %v", bin, args, err) + return nil, fmt.Errorf("failed to start %v %+v: %v", cmd.Path, cmd.Args, err) } done := make(chan bool) + timer := time.NewTimer(timeout) go func() { select { - case <-time.After(time.Hour): + case <-timer.C: cmd.Process.Kill() case <-done: + timer.Stop() } }() defer close(done) if err := cmd.Wait(); err != nil { - return nil, fmt.Errorf("failed to run %v %+v: %v\n%v", bin, args, err, output.String()) + return nil, fmt.Errorf("failed to run %v %+v: %v\n%v", + cmd.Path, cmd.Args, err, output.String()) } return output.Bytes(), nil } +// Command is similar to os/exec.Command, but also sets PDEATHSIG on linux. +func Command(bin string, args ...string) *exec.Cmd { + cmd := exec.Command(bin, args...) + setPdeathsig(cmd) + return cmd +} + // IsExist returns true if the file name exists. func IsExist(name string) bool { _, err := os.Stat(name) diff --git a/pkg/osutil/osutil_akaros.go b/pkg/osutil/osutil_akaros.go index d2107b9b..6a69cc03 100644 --- a/pkg/osutil/osutil_akaros.go +++ b/pkg/osutil/osutil_akaros.go @@ -1,12 +1,13 @@ // Copyright 2017 syzkaller project authors. All rights reserved. // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. -// +build akaros +// +build akaros,!appengine package osutil import ( "os" + "os/exec" ) func HandleInterrupts(shutdown chan struct{}) { @@ -17,3 +18,6 @@ func UmountAll(dir string) { func prolongPipe(r, w *os.File) { } + +func setPdeathsig(cmd *exec.Cmd) { +} diff --git a/pkg/osutil/osutil_appengine.go b/pkg/osutil/osutil_appengine.go new file mode 100644 index 00000000..2fc10761 --- /dev/null +++ b/pkg/osutil/osutil_appengine.go @@ -0,0 +1,13 @@ +// Copyright 2017 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +// +build appengine + +package osutil + +import ( + "os/exec" +) + +func setPdeathsig(cmd *exec.Cmd) { +} diff --git a/pkg/osutil/osutil_bsd.go b/pkg/osutil/osutil_bsd.go index 652a00a3..c955fdd7 100644 --- a/pkg/osutil/osutil_bsd.go +++ b/pkg/osutil/osutil_bsd.go @@ -1,12 +1,13 @@ // Copyright 2017 syzkaller project authors. All rights reserved. // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. -// +build freebsd netbsd +// +build freebsd,!appengine netbsd,!appengine package osutil import ( "os" + "os/exec" ) func UmountAll(dir string) { @@ -14,3 +15,6 @@ func UmountAll(dir string) { func prolongPipe(r, w *os.File) { } + +func setPdeathsig(cmd *exec.Cmd) { +} diff --git a/pkg/osutil/osutil_darwin.go b/pkg/osutil/osutil_darwin.go index fa6e3f59..1ade9c12 100644 --- a/pkg/osutil/osutil_darwin.go +++ b/pkg/osutil/osutil_darwin.go @@ -1,11 +1,17 @@ // Copyright 2017 syzkaller project authors. All rights reserved. // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. +// +build !appengine + package osutil import ( "os" + "os/exec" ) func prolongPipe(r, w *os.File) { } + +func setPdeathsig(cmd *exec.Cmd) { +} diff --git a/pkg/osutil/osutil_fuchsia.go b/pkg/osutil/osutil_fuchsia.go index e0a1f5fc..de3827b1 100644 --- a/pkg/osutil/osutil_fuchsia.go +++ b/pkg/osutil/osutil_fuchsia.go @@ -1,13 +1,14 @@ // Copyright 2017 syzkaller project authors. All rights reserved. // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. -// +build fuchsia +// +build fuchsia,!appengine package osutil import ( "fmt" "os" + "os/exec" ) func HandleInterrupts(shutdown chan struct{}) { @@ -35,3 +36,6 @@ func ProcessSignal(p *os.Process, sig int) bool { func prolongPipe(r, w *os.File) { } + +func setPdeathsig(cmd *exec.Cmd) { +} diff --git a/pkg/osutil/osutil_linux.go b/pkg/osutil/osutil_linux.go index 81fc7482..0a84f3f1 100644 --- a/pkg/osutil/osutil_linux.go +++ b/pkg/osutil/osutil_linux.go @@ -8,6 +8,7 @@ package osutil import ( "io/ioutil" "os" + "os/exec" "path/filepath" "syscall" "unsafe" @@ -26,6 +27,12 @@ func UmountAll(dir string) { } } +func setPdeathsig(cmd *exec.Cmd) { + cmd.SysProcAttr = &syscall.SysProcAttr{ + Pdeathsig: syscall.SIGKILL, + } +} + func prolongPipe(r, w *os.File) { for sz := 128 << 10; sz <= 2<<20; sz *= 2 { syscall.Syscall(syscall.SYS_FCNTL, w.Fd(), syscall.F_SETPIPE_SZ, uintptr(sz)) diff --git a/pkg/osutil/osutil_windows.go b/pkg/osutil/osutil_windows.go index 9919689d..4a00fe0c 100644 --- a/pkg/osutil/osutil_windows.go +++ b/pkg/osutil/osutil_windows.go @@ -1,11 +1,14 @@ // Copyright 2017 syzkaller project authors. All rights reserved. // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. +// +build !appengine + package osutil import ( "fmt" "os" + "os/exec" "syscall" ) @@ -33,3 +36,6 @@ func ProcessExitStatus(ps *os.ProcessState) int { func ProcessSignal(p *os.Process, sig int) bool { return false } + +func setPdeathsig(cmd *exec.Cmd) { +} diff --git a/pkg/symbolizer/nm.go b/pkg/symbolizer/nm.go index 217536cf..72e5db79 100644 --- a/pkg/symbolizer/nm.go +++ b/pkg/symbolizer/nm.go @@ -6,8 +6,9 @@ package symbolizer import ( "bufio" "bytes" - "os/exec" "strconv" + + "github.com/google/syzkaller/pkg/osutil" ) type Symbol struct { @@ -17,7 +18,7 @@ type Symbol struct { // ReadSymbols returns list of text symbols in the binary bin. func ReadSymbols(bin string) (map[string][]Symbol, error) { - cmd := exec.Command("nm", "-nS", bin) + cmd := osutil.Command("nm", "-nS", bin) stdout, err := cmd.StdoutPipe() if err != nil { return nil, err diff --git a/pkg/symbolizer/symbolizer.go b/pkg/symbolizer/symbolizer.go index 07356a48..f6c6dbe7 100644 --- a/pkg/symbolizer/symbolizer.go +++ b/pkg/symbolizer/symbolizer.go @@ -12,6 +12,8 @@ import ( "os/exec" "strconv" "strings" + + "github.com/google/syzkaller/pkg/osutil" ) type Symbolizer struct { @@ -63,7 +65,7 @@ func (s *Symbolizer) getSubprocess(bin string) (*subprocess, error) { if sub := s.subprocs[bin]; sub != nil { return sub, nil } - cmd := exec.Command("addr2line", "-afi", "-e", bin) + cmd := osutil.Command("addr2line", "-afi", "-e", bin) stdin, err := cmd.StdinPipe() if err != nil { return nil, err diff --git a/sys/syz-extract/fetch.go b/sys/syz-extract/fetch.go index 44b82cf8..034084aa 100644 --- a/sys/syz-extract/fetch.go +++ b/sys/syz-extract/fetch.go @@ -8,13 +8,14 @@ import ( "fmt" "io/ioutil" "os" - "os/exec" "regexp" "strconv" "strings" "text/template" + "time" "github.com/google/syzkaller/pkg/compiler" + "github.com/google/syzkaller/pkg/osutil" ) func extract(info *compiler.ConstInfo, cc string, args []string, addSource string, declarePrintf bool) (map[string]uint64, map[string]bool, error) { @@ -64,7 +65,7 @@ func extract(info *compiler.ConstInfo, cc string, args []string, addSource strin } defer os.Remove(bin) - out, err = exec.Command(bin).CombinedOutput() + out, err = osutil.Command(bin).CombinedOutput() if err != nil { return nil, nil, fmt.Errorf("failed to run flags binary: %v\n%v", err, string(out)) } @@ -124,8 +125,7 @@ func compile(cc string, args []string, data *CompileData) (bin string, out []byt "-o", binFile.Name(), "-w", }...) - cmd := exec.Command(cc, args...) - out, err = cmd.CombinedOutput() + out, err = osutil.RunCmd(time.Minute, "", cc, args...) if err != nil { os.Remove(binFile.Name()) return "", out, err diff --git a/syz-ci/managercmd.go b/syz-ci/managercmd.go index db321523..77339e5c 100644 --- a/syz-ci/managercmd.go +++ b/syz-ci/managercmd.go @@ -10,6 +10,7 @@ import ( "time" . "github.com/google/syzkaller/pkg/log" + "github.com/google/syzkaller/pkg/osutil" ) // ManagerCmd encapsulates a single instance of syz-manager process. @@ -74,7 +75,7 @@ func (mc *ManagerCmd) loop() { if err != nil { Logf(0, "%v: failed to create manager log: %v", mc.name, err) } else { - cmd = exec.Command(mc.bin, mc.args...) + cmd = osutil.Command(mc.bin, mc.args...) cmd.Stdout = logfile cmd.Stderr = logfile err := cmd.Start() diff --git a/syz-ci/syzupdater.go b/syz-ci/syzupdater.go index dcfe13d3..7bce21e6 100644 --- a/syz-ci/syzupdater.go +++ b/syz-ci/syzupdater.go @@ -231,12 +231,15 @@ func (upd *SyzUpdater) build() error { } for target := range upd.targets { parts := strings.Split(target, "/") - env := []string{ - "TARGETOS=" + parts[0], - "TARGETVMARCH=" + parts[1], - "TARGETARCH=" + parts[2], - } - if _, err := osutil.RunCmdEnv(time.Hour, env, upd.syzkallerDir, "make", "target"); err != nil { + cmd := osutil.Command("make", "target") + cmd.Dir = upd.syzkallerDir + cmd.Env = append([]string{}, os.Environ()...) + cmd.Env = append(cmd.Env, + "TARGETOS="+parts[0], + "TARGETVMARCH="+parts[1], + "TARGETARCH="+parts[2], + ) + if _, err := osutil.Run(time.Hour, cmd); err != nil { return fmt.Errorf("build failed: %v", err) } } diff --git a/syz-manager/cover.go b/syz-manager/cover.go index d6d90dc6..945945c0 100644 --- a/syz-manager/cover.go +++ b/syz-manager/cover.go @@ -10,13 +10,14 @@ import ( "html/template" "io" "io/ioutil" - "os/exec" "sort" "strconv" "strings" + "time" "github.com/google/syzkaller/pkg/cover" . "github.com/google/syzkaller/pkg/log" + "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/pkg/symbolizer" ) @@ -220,9 +221,9 @@ func getVmOffset(vmlinux string) (uint32, error) { if v, ok := vmOffsets[vmlinux]; ok { return v, nil } - out, err := exec.Command("readelf", "-SW", vmlinux).CombinedOutput() + out, err := osutil.RunCmd(time.Hour, "readelf", "-SW", vmlinux) if err != nil { - return 0, fmt.Errorf("readelf failed: %v\n%s", err, out) + return 0, err } s := bufio.NewScanner(bytes.NewReader(out)) var addr uint32 @@ -308,7 +309,7 @@ func uncoveredPcsInFuncs(vmlinux string, pcs []uint64) ([]uint64, error) { // coveredPCs returns list of PCs of __sanitizer_cov_trace_pc calls in binary bin. func coveredPCs(bin string) ([]uint64, error) { - cmd := exec.Command("objdump", "-d", "--no-show-raw-insn", bin) + cmd := osutil.Command("objdump", "-d", "--no-show-raw-insn", bin) stdout, err := cmd.StdoutPipe() if err != nil { return nil, err diff --git a/vm/adb/adb.go b/vm/adb/adb.go index fb9cd93b..19a9aa68 100644 --- a/vm/adb/adb.go +++ b/vm/adb/adb.go @@ -185,7 +185,7 @@ func findConsoleImpl(adb, dev string) (string, error) { } time.Sleep(500 * time.Millisecond) unique := fmt.Sprintf(">>>%v<<<", dev) - cmd := exec.Command(adb, "-s", dev, "shell", "echo", "\"", unique, "\"", ">", "/dev/kmsg") + cmd := osutil.Command(adb, "-s", dev, "shell", "echo", "\"", unique, "\"", ">", "/dev/kmsg") if out, err := cmd.CombinedOutput(); err != nil { return "", fmt.Errorf("failed to run adb shell: %v\n%s", err, out) } @@ -239,7 +239,7 @@ func (inst *instance) adb(args ...string) ([]byte, error) { } defer wpipe.Close() defer rpipe.Close() - cmd := exec.Command(inst.adbBin, append([]string{"-s", inst.device}, args...)...) + cmd := osutil.Command(inst.adbBin, append([]string{"-s", inst.device}, args...)...) cmd.Stdout = wpipe cmd.Stderr = wpipe if err := cmd.Start(); err != nil { @@ -405,7 +405,7 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin if inst.debug { Logf(0, "starting: adb shell %v", command) } - adb := exec.Command(inst.adbBin, "-s", inst.device, "shell", "cd /data; "+command) + adb := osutil.Command(inst.adbBin, "-s", inst.device, "shell", "cd /data; "+command) adb.Stdout = adbWpipe adb.Stderr = adbWpipe if err := adb.Start(); err != nil { diff --git a/vm/gce/gce.go b/vm/gce/gce.go index fc087b27..165ffe4c 100644 --- a/vm/gce/gce.go +++ b/vm/gce/gce.go @@ -19,7 +19,6 @@ import ( "io" "io/ioutil" "os" - "os/exec" "path/filepath" "time" @@ -131,7 +130,7 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) { name := fmt.Sprintf("%v-%v", pool.env.Name, index) // Create SSH key for the instance. gceKey := filepath.Join(workdir, "key") - keygen := exec.Command("ssh-keygen", "-t", "rsa", "-b", "2048", "-N", "", "-C", "syzkaller", "-f", gceKey) + keygen := osutil.Command("ssh-keygen", "-t", "rsa", "-b", "2048", "-N", "", "-C", "syzkaller", "-f", gceKey) if out, err := keygen.CombinedOutput(); err != nil { return nil, fmt.Errorf("failed to execute ssh-keygen: %v\n%s", err, out) } @@ -210,7 +209,7 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin conAddr := fmt.Sprintf("%v.%v.%v.syzkaller.port=1@ssh-serialport.googleapis.com", inst.GCE.ProjectID, inst.GCE.ZoneID, inst.name) conArgs := append(sshArgs(inst.debug, inst.gceKey, "-p", 9600), conAddr) - con := exec.Command("ssh", conArgs...) + con := osutil.Command("ssh", conArgs...) con.Env = []string{} con.Stdout = conWpipe con.Stderr = conWpipe @@ -289,7 +288,7 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin } } args := append(sshArgs(inst.debug, inst.sshKey, "-p", 22), inst.sshUser+"@"+inst.name, command) - ssh := exec.Command("ssh", args...) + ssh := osutil.Command("ssh", args...) ssh.Stdout = sshWpipe ssh.Stderr = sshWpipe if err := ssh.Start(); err != nil { diff --git a/vm/isolated/isolated.go b/vm/isolated/isolated.go index 39d7378b..581e33f6 100644 --- a/vm/isolated/isolated.go +++ b/vm/isolated/isolated.go @@ -8,7 +8,6 @@ import ( "io" "io/ioutil" "os" - "os/exec" "path/filepath" "time" @@ -124,7 +123,7 @@ func (inst *instance) ssh(command string) ([]byte, error) { if inst.debug { Logf(0, "running command: ssh %#v", args) } - cmd := exec.Command("ssh", args...) + cmd := osutil.Command("ssh", args...) cmd.Stdout = wpipe cmd.Stderr = wpipe if err := cmd.Start(); err != nil { @@ -231,7 +230,7 @@ func (inst *instance) Copy(hostSrc string) (string, error) { vmDst := filepath.Join(inst.cfg.Target_Dir, baseName) inst.ssh("pkill -9 '" + baseName + "'; rm -f '" + vmDst + "'") args := append(inst.sshArgs("-P"), hostSrc, inst.target+":"+vmDst) - cmd := exec.Command("scp", args...) + cmd := osutil.Command("scp", args...) if inst.debug { Logf(0, "running command: scp %#v", args) cmd.Stdout = os.Stdout @@ -280,7 +279,7 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin if inst.debug { Logf(0, "running command: ssh %#v", args) } - cmd := exec.Command("ssh", args...) + cmd := osutil.Command("ssh", args...) cmd.Stdout = wpipe cmd.Stderr = wpipe if err := cmd.Start(); err != nil { diff --git a/vm/kvm/kvm.go b/vm/kvm/kvm.go index c404ba91..63487035 100644 --- a/vm/kvm/kvm.go +++ b/vm/kvm/kvm.go @@ -114,7 +114,7 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) { os.RemoveAll(inst.sandboxPath) os.Remove(inst.sandboxPath + ".sock") - out, err := exec.Command(inst.cfg.Lkvm, "setup", sandbox).CombinedOutput() + out, err := osutil.Command(inst.cfg.Lkvm, "setup", sandbox).CombinedOutput() if err != nil { return nil, fmt.Errorf("failed to lkvm setup: %v\n%s", err, out) } @@ -128,7 +128,7 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) { return nil, fmt.Errorf("failed to create pipe: %v", err) } - inst.lkvm = exec.Command("taskset", "-c", strconv.Itoa(index%runtime.NumCPU()), + inst.lkvm = osutil.Command("taskset", "-c", strconv.Itoa(index%runtime.NumCPU()), inst.cfg.Lkvm, "sandbox", "--disk", inst.sandbox, "--kernel", inst.cfg.Kernel, diff --git a/vm/odroid/odroid.go b/vm/odroid/odroid.go index 2d1f0482..f6593422 100644 --- a/vm/odroid/odroid.go +++ b/vm/odroid/odroid.go @@ -138,7 +138,7 @@ func (inst *instance) ssh(command string) ([]byte, error) { if inst.debug { Logf(0, "running command: ssh %#v", args) } - cmd := exec.Command("ssh", args...) + cmd := osutil.Command("ssh", args...) cmd.Stdout = wpipe cmd.Stderr = wpipe if err := cmd.Start(); err != nil { @@ -297,7 +297,7 @@ func (inst *instance) Copy(hostSrc string) (string, error) { basePath := "/data/" vmDst := filepath.Join(basePath, filepath.Base(hostSrc)) args := append(inst.sshArgs("-P"), hostSrc, "root@"+inst.cfg.Slave_Addr+":"+vmDst) - cmd := exec.Command("scp", args...) + cmd := osutil.Command("scp", args...) if inst.debug { Logf(0, "running command: scp %#v", args) cmd.Stdout = os.Stdout @@ -338,7 +338,7 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin if inst.debug { Logf(0, "running command: ssh %#v", args) } - cmd := exec.Command("ssh", args...) + cmd := osutil.Command("ssh", args...) cmd.Stdout = wpipe cmd.Stderr = wpipe if err := cmd.Start(); err != nil { diff --git a/vm/qemu/qemu.go b/vm/qemu/qemu.go index 831e646e..147be890 100644 --- a/vm/qemu/qemu.go +++ b/vm/qemu/qemu.go @@ -156,9 +156,9 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) { if pool.env.Image == "9p" { sshkey = filepath.Join(workdir, "key") sshuser = "root" - keygen := exec.Command("ssh-keygen", "-t", "rsa", "-b", "2048", "-N", "", "-C", "", "-f", sshkey) - if out, err := keygen.CombinedOutput(); err != nil { - return nil, fmt.Errorf("failed to execute ssh-keygen: %v\n%s", err, out) + if _, err := osutil.RunCmd(10*time.Minute, "ssh-keygen", "-t", "rsa", "-b", "2048", + "-N", "", "-C", "", "-f", sshkey); err != nil { + return nil, err } initFile := filepath.Join(workdir, "init.sh") if err := osutil.WriteExecFile(initFile, []byte(strings.Replace(initScript, "{{KEY}}", sshkey, -1))); err != nil { @@ -311,7 +311,7 @@ func (inst *instance) Boot() error { if inst.debug { Logf(0, "running command: %v %#v", inst.cfg.Qemu, args) } - qemu := exec.Command(inst.cfg.Qemu, args...) + qemu := osutil.Command(inst.cfg.Qemu, args...) qemu.Stdout = inst.wpipe qemu.Stderr = inst.wpipe if err := qemu.Start(); err != nil { @@ -397,7 +397,7 @@ func (inst *instance) Copy(hostSrc string) (string, error) { } vmDst := filepath.Join(basePath, filepath.Base(hostSrc)) args := append(inst.sshArgs("-P"), hostSrc, inst.sshuser+"@localhost:"+vmDst) - cmd := exec.Command("scp", args...) + cmd := osutil.Command("scp", args...) if inst.debug { Logf(0, "running command: scp %#v", args) cmd.Stdout = os.Stdout @@ -433,7 +433,7 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin if inst.debug { Logf(0, "running command: ssh %#v", args) } - cmd := exec.Command("ssh", args...) + cmd := osutil.Command("ssh", args...) cmd.Stdout = wpipe cmd.Stderr = wpipe if err := cmd.Start(); err != nil { diff --git a/vm/vmimpl/console.go b/vm/vmimpl/console.go index 7059221d..53075820 100644 --- a/vm/vmimpl/console.go +++ b/vm/vmimpl/console.go @@ -83,7 +83,7 @@ func OpenRemoteConsole(bin string, args ...string) (rc io.ReadCloser, err error) return nil, err } args = append(args, "dmesg -w") - cmd := exec.Command(bin, args...) + cmd := osutil.Command(bin, args...) cmd.Stdout = wpipe cmd.Stderr = wpipe if err := cmd.Start(); err != nil {