pkg/osutil: don't leace runaway processes

When manager is stopped there are sometimes runaway qemu
processes still running. Set PDEATHSIG for all subprocesses.
We never need child processes outliving parents.
This commit is contained in:
Dmitry Vyukov 2017-11-16 12:42:30 +01:00
parent 4bc654f911
commit c4d43f4773
26 changed files with 133 additions and 75 deletions

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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}
}

View File

@ -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 {

View File

@ -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)

View File

@ -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) {
}

View File

@ -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) {
}

View File

@ -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) {
}

View File

@ -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) {
}

View File

@ -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) {
}

View File

@ -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))

View File

@ -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) {
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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)
}
}

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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,

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {