diff options
| -rw-r--r-- | vm/adb/adb.go | 38 | ||||
| -rw-r--r-- | vm/isolated/isolated.go | 38 | ||||
| -rw-r--r-- | vm/vmimpl/vmimpl.go | 44 |
3 files changed, 46 insertions, 74 deletions
diff --git a/vm/adb/adb.go b/vm/adb/adb.go index 21fd5f741..e6908a9aa 100644 --- a/vm/adb/adb.go +++ b/vm/adb/adb.go @@ -422,41 +422,5 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin merger.Add("console", tty) merger.Add("adb", adbRpipe) - errc := make(chan error, 1) - signal := func(err error) { - select { - case errc <- err: - default: - } - } - - go func() { - select { - case <-time.After(timeout): - signal(vmimpl.ErrTimeout) - case <-stop: - signal(vmimpl.ErrTimeout) - case <-inst.closed: - if inst.debug { - log.Logf(0, "instance closed") - } - signal(fmt.Errorf("instance closed")) - case err := <-merger.Err: - adb.Process.Kill() - tty.Close() - merger.Wait() - if cmdErr := adb.Wait(); cmdErr == nil { - // If the command exited successfully, we got EOF error from merger. - // But in this case no error has happened and the EOF is expected. - err = nil - } - signal(err) - return - } - adb.Process.Kill() - tty.Close() - merger.Wait() - adb.Wait() - }() - return merger.Output, errc, nil + return vmimpl.Multiplex(adb, merger, tty, timeout, stop, inst.closed, inst.debug) } diff --git a/vm/isolated/isolated.go b/vm/isolated/isolated.go index 4a6bf7fe6..86adb80dc 100644 --- a/vm/isolated/isolated.go +++ b/vm/isolated/isolated.go @@ -305,43 +305,7 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin merger.Add("dmesg", dmesg) merger.Add("ssh", rpipe) - errc := make(chan error, 1) - signal := func(err error) { - select { - case errc <- err: - default: - } - } - - go func() { - select { - case <-time.After(timeout): - signal(vmimpl.ErrTimeout) - case <-stop: - signal(vmimpl.ErrTimeout) - case <-inst.closed: - if inst.debug { - log.Logf(0, "instance closed") - } - signal(fmt.Errorf("instance closed")) - case err := <-merger.Err: - cmd.Process.Kill() - dmesg.Close() - merger.Wait() - if cmdErr := cmd.Wait(); cmdErr == nil { - // If the command exited successfully, we got EOF error from merger. - // But in this case no error has happened and the EOF is expected. - err = nil - } - signal(err) - return - } - cmd.Process.Kill() - dmesg.Close() - merger.Wait() - cmd.Wait() - }() - return merger.Output, errc, nil + return vmimpl.Multiplex(cmd, merger, dmesg, timeout, stop, inst.closed, inst.debug) } func (inst *instance) sshArgs(portArg string) []string { diff --git a/vm/vmimpl/vmimpl.go b/vm/vmimpl/vmimpl.go index 4565d173e..a4dba2f65 100644 --- a/vm/vmimpl/vmimpl.go +++ b/vm/vmimpl/vmimpl.go @@ -10,7 +10,11 @@ package vmimpl import ( "errors" "fmt" + "io" + "os/exec" "time" + + "github.com/google/syzkaller/pkg/log" ) // Pool represents a set of test machines (VMs, physical devices, etc) of particular type. @@ -93,3 +97,43 @@ var ( ) type ctorFunc func(env *Env) (Pool, error) + +func Multiplex(cmd *exec.Cmd, merger *OutputMerger, console io.Closer, timeout time.Duration, + stop, closed <-chan bool, debug bool) (<-chan []byte, <-chan error, error) { + errc := make(chan error, 1) + signal := func(err error) { + select { + case errc <- err: + default: + } + } + go func() { + select { + case <-time.After(timeout): + signal(ErrTimeout) + case <-stop: + signal(ErrTimeout) + case <-closed: + if debug { + log.Logf(0, "instance closed") + } + signal(fmt.Errorf("instance closed")) + case err := <-merger.Err: + cmd.Process.Kill() + console.Close() + merger.Wait() + if cmdErr := cmd.Wait(); cmdErr == nil { + // If the command exited successfully, we got EOF error from merger. + // But in this case no error has happened and the EOF is expected. + err = nil + } + signal(err) + return + } + cmd.Process.Kill() + console.Close() + merger.Wait() + cmd.Wait() + }() + return merger.Output, errc, nil +} |
