diff options
| author | Greg Steuck <greg@nest.cx> | 2023-04-23 16:58:17 +0100 |
|---|---|---|
| committer | Greg Steuck <blackgnezdo@gmail.com> | 2023-04-26 03:07:55 -0700 |
| commit | 5c302a80a185bd3c33d70c2085aec5a1b807bc84 (patch) | |
| tree | 8267bf5d96dc82c4f664247ae33e6fd449fb1c04 /vm/vmm | |
| parent | 8d843721a64966f1b78b0398b301470f4b3c8555 (diff) | |
vm/vmm: adapt to recent vmctl changes
The flags now must precede the VM id. The IP address can no longer be
determined by looking at the VM output which was previously possible
due to dhclient printing it. Now that we don't have dhclient we
instead look up the VM id in vmctl status output and the VM IP
uses a fixed pattern.
With the two changes I can run syz-manager and it gets far enough to
report missing coverage.
Diffstat (limited to 'vm/vmm')
| -rw-r--r-- | vm/vmm/vmm.go | 83 |
1 files changed, 30 insertions, 53 deletions
diff --git a/vm/vmm/vmm.go b/vm/vmm/vmm.go index 9872e4d50..3cee24d53 100644 --- a/vm/vmm/vmm.go +++ b/vm/vmm/vmm.go @@ -21,6 +21,9 @@ import ( "github.com/google/syzkaller/vm/vmimpl" ) +// Locates the VM id which is used for VM address. +var vmctlStatusRegex = regexp.MustCompile(`^\s+([0-9]+)\b.*\brunning`) + func init() { vmimpl.Register("vmm", ctor, true) } @@ -52,8 +55,6 @@ type instance struct { consolew io.WriteCloser } -var ipRegex = regexp.MustCompile(`bound to (([0-9]+\.){3}3)`) - func ctor(env *vmimpl.Env) (vmimpl.Pool, error) { cfg := &Config{ Count: 1, @@ -116,12 +117,13 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) { // 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") + inst.vmctl("stop", "-f", "-w", inst.vmName) time.Sleep(3 * time.Second) createArgs := []string{ - "create", inst.image, + "create", "-b", pool.env.Image, + inst.image, } if _, err := inst.vmctl(createArgs...); err != nil { return nil, err @@ -148,7 +150,7 @@ func (inst *instance) Boot() error { return err } startArgs := []string{ - "start", inst.vmName, + "start", "-b", inst.cfg.Kernel, "-d", inst.image, "-m", fmt.Sprintf("%vM", inst.cfg.Mem), @@ -158,6 +160,7 @@ func (inst *instance) Boot() error { if inst.cfg.Template != "" { startArgs = append(startArgs, "-t", inst.cfg.Template) } + startArgs = append(startArgs, inst.vmName) if inst.debug { log.Logf(0, "running command: vmctl %#v", startArgs) } @@ -178,55 +181,37 @@ func (inst *instance) Boot() error { inr.Close() inst.merger.Add("console", outr) - var bootOutput []byte - bootOutputStop := make(chan bool) - ipch := make(chan string, 1) - go func() { - gotip := false - for { - select { - case out := <-inst.merger.Output: - bootOutput = append(bootOutput, out...) - case <-bootOutputStop: - bootOutputStop <- true - return - } - if gotip { - continue - } - if ip := parseIP(bootOutput); ip != "" { - ipch <- ip - gotip = true - } - } - }() - - 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 - return vmimpl.BootError{Title: "no IP found", Output: bootOutput} + inst.sshhost, err = inst.lookupSSHAddress() + if err != nil { + return err } if err := vmimpl.WaitForSSH(inst.debug, 20*time.Minute, inst.sshhost, inst.sshkey, inst.sshuser, inst.os, inst.sshport, nil); err != nil { - bootOutputStop <- true - <-bootOutputStop - return vmimpl.BootError{Title: err.Error(), Output: bootOutput} + out := <-inst.merger.Output + return vmimpl.BootError{Title: err.Error(), Output: out} } - bootOutputStop <- true - <-bootOutputStop return nil } +func (inst *instance) lookupSSHAddress() (string, error) { + out, err := inst.vmctl("status", inst.vmName) + if err != nil { + return "", err + } + lines := strings.Split(out, "\n") + if len(lines) < 2 { + return "", vmimpl.BootError{Title: "Unexpected vmctl status output", Output: []byte(out)} + } + matches := vmctlStatusRegex.FindStringSubmatch(lines[1]) + if len(matches) < 2 { + return "", vmimpl.BootError{Title: "Unexpected vmctl status output", Output: []byte(out)} + } + return fmt.Sprintf("100.64.%s.3", matches[1]), nil +} + func (inst *instance) Close() { - inst.vmctl("stop", inst.vmName, "-f") + inst.vmctl("stop", "-f", inst.vmName) if inst.consolew != nil { inst.consolew.Close() } @@ -332,11 +317,3 @@ func (inst *instance) vmctl(args ...string) (string, error) { } return string(out), nil } - -func parseIP(output []byte) string { - matches := ipRegex.FindSubmatch(output) - if len(matches) < 2 { - return "" - } - return string(matches[1]) -} |
