aboutsummaryrefslogtreecommitdiffstats
path: root/vm
diff options
context:
space:
mode:
authorGreg Steuck <greg@nest.cx>2023-04-23 16:58:17 +0100
committerGreg Steuck <blackgnezdo@gmail.com>2023-04-26 03:07:55 -0700
commit5c302a80a185bd3c33d70c2085aec5a1b807bc84 (patch)
tree8267bf5d96dc82c4f664247ae33e6fd449fb1c04 /vm
parent8d843721a64966f1b78b0398b301470f4b3c8555 (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')
-rw-r--r--vm/vmm/vmm.go83
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])
-}