diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-09-20 19:44:50 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-09-20 19:44:50 +0200 |
| commit | 2d41b5d964069b07448877b6e71701b4f0a37517 (patch) | |
| tree | 3fd5a9943dc1051d7bdb369d506ebfe44808ec23 /vm/vmm | |
| parent | 3c8de4d9413406706f3a5b816f2aa25f506745fc (diff) | |
vm/vmm: recover from vmctl errors faster
vmctl start periodically fails with:
vmctl: start vm command failed: Operation already in progress
So try to sleep for a bit after vmctl stop.
And detect when vmctl start terminates prematurely
to avoid 10 minute timeout for ip extraction.
Diffstat (limited to 'vm/vmm')
| -rw-r--r-- | vm/vmm/vmm.go | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/vm/vmm/vmm.go b/vm/vmm/vmm.go index 05387c5f1..ad5c31d87 100644 --- a/vm/vmm/vmm.go +++ b/vm/vmm/vmm.go @@ -115,7 +115,13 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) { merger: vmimpl.NewOutputMerger(tee), } - inst.vmctl("stop", inst.vmName, "-f", "-w") // in case it's still running from the previous run + // Stop the instance from the previous run in case it's still running. + // This is racy even with -w flag, start periodically fails with: + // vmctl: start vm command failed: Operation already in progress + // So also sleep for a bit. + inst.vmctl("stop", inst.vmName, "-f", "-w") + time.Sleep(3 * time.Second) + closeInst := inst defer func() { if closeInst != nil { @@ -199,6 +205,10 @@ func (inst *instance) Boot() error { select { case ip := <-ipch: inst.sshhost = ip + case <-inst.merger.Err: + bootOutputStop <- true + <-bootOutputStop + return vmimpl.BootError{Title: "vmm exited", Output: bootOutput} case <-time.After(10 * time.Minute): bootOutputStop <- true <-bootOutputStop @@ -303,11 +313,9 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin } func (inst *instance) Diagnose() bool { - // TODO(dvyukov): this does not work because console asks for login: - // OpenBSD/amd64 (syzkaller.my.domain) (tty00) - // login: trace - // Password: - // Login incorrect + // Note: this only works if kernel actually paniced and kernel shows panic console. + // If kernel just hanged, we've lost connection or detected some non-panic error, + // console still shows normal login prompt. for _, c := range []string{"\n", "trace\n", "show registers\n"} { inst.consolew.Write([]byte(c)) time.Sleep(1 * time.Second) |
