aboutsummaryrefslogtreecommitdiffstats
path: root/vm
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-09-20 19:44:50 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-09-20 19:44:50 +0200
commit2d41b5d964069b07448877b6e71701b4f0a37517 (patch)
tree3fd5a9943dc1051d7bdb369d506ebfe44808ec23 /vm
parent3c8de4d9413406706f3a5b816f2aa25f506745fc (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')
-rw-r--r--vm/vmm/vmm.go20
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)