aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vm/cuttlefish/cuttlefish.go42
-rw-r--r--vm/gce/gce.go77
2 files changed, 67 insertions, 52 deletions
diff --git a/vm/cuttlefish/cuttlefish.go b/vm/cuttlefish/cuttlefish.go
index ccea7c7e7..f6f61ee16 100644
--- a/vm/cuttlefish/cuttlefish.go
+++ b/vm/cuttlefish/cuttlefish.go
@@ -15,13 +15,15 @@ import (
"path/filepath"
"time"
- "github.com/google/syzkaller/pkg/log"
+ "github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/pkg/report"
+ "github.com/google/syzkaller/vm/gce"
"github.com/google/syzkaller/vm/vmimpl"
)
const (
- deviceRoot = "/data/fuzz"
+ deviceRoot = "/data/fuzz"
+ consoleReadCmd = "tail -f cuttlefish/instances/cvd-1/kernel.log"
)
func init() {
@@ -30,16 +32,19 @@ func init() {
type Pool struct {
env *vmimpl.Env
- gcePool vmimpl.Pool
+ gcePool *gce.Pool
}
type instance struct {
+ name string
+ sshKey string
+ sshUser string
debug bool
gceInst vmimpl.Instance
}
func ctor(env *vmimpl.Env) (vmimpl.Pool, error) {
- gcePool, err := vmimpl.Types["gce"].Ctor(env)
+ gcePool, err := gce.Ctor(env, consoleReadCmd)
if err != nil {
return nil, fmt.Errorf("failed to create underlying GCE pool: %s", err)
}
@@ -63,6 +68,9 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) {
}
inst := &instance{
+ name: fmt.Sprintf("%v-%v", pool.env.Name, index),
+ sshKey: pool.env.SSHKey,
+ sshUser: pool.env.SSHUser,
debug: pool.env.Debug,
gceInst: gceInst,
}
@@ -94,24 +102,18 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) {
return inst, nil
}
-func (inst *instance) runOnHost(timeout time.Duration, cmd string) error {
- outc, errc, err := inst.gceInst.Run(timeout, nil, cmd)
- if err != nil {
- return fmt.Errorf("failed to run command: %s", err)
+func (inst *instance) sshArgs(command string) []string {
+ sshArgs := append(vmimpl.SSHArgs(inst.debug, inst.sshKey, 22), inst.sshUser+"@"+inst.name)
+ if inst.sshUser != "root" {
+ return append(sshArgs, "sudo", "bash", "-c", "'"+command+"'")
}
+ return append(sshArgs, command)
+}
- for {
- select {
- case <-vmimpl.Shutdown:
- return nil
- case err := <-errc:
- return err
- case out, ok := <-outc:
- if ok && inst.debug {
- log.Logf(1, "%s", out)
- }
- }
- }
+func (inst *instance) runOnHost(timeout time.Duration, command string) error {
+ _, err := osutil.RunCmd(timeout, "/root", "ssh", inst.sshArgs(command)...)
+
+ return err
}
func (inst *instance) Copy(hostSrc string) (string, error) {
diff --git a/vm/gce/gce.go b/vm/gce/gce.go
index ef213d12e..ba05af51b 100644
--- a/vm/gce/gce.go
+++ b/vm/gce/gce.go
@@ -49,26 +49,32 @@ type Config struct {
}
type Pool struct {
- env *vmimpl.Env
- cfg *Config
- GCE *gce.Context
+ env *vmimpl.Env
+ cfg *Config
+ GCE *gce.Context
+ consoleReadCmd string // optional: command to read non-standard kernel console
}
type instance struct {
- env *vmimpl.Env
- cfg *Config
- GCE *gce.Context
- debug bool
- name string
- ip string
- gceKey string // per-instance private ssh key associated with the instance
- sshKey string // ssh key
- sshUser string
- closed chan bool
- consolew io.WriteCloser
+ env *vmimpl.Env
+ cfg *Config
+ GCE *gce.Context
+ debug bool
+ name string
+ ip string
+ gceKey string // per-instance private ssh key associated with the instance
+ sshKey string // ssh key
+ sshUser string
+ closed chan bool
+ consolew io.WriteCloser
+ consoleReadCmd string // optional: command to read non-standard kernel console
}
func ctor(env *vmimpl.Env) (vmimpl.Pool, error) {
+ return Ctor(env, "")
+}
+
+func Ctor(env *vmimpl.Env, consoleReadCmd string) (*Pool, error) {
if env.Name == "" {
return nil, fmt.Errorf("config param name is empty (required for GCE)")
}
@@ -123,9 +129,10 @@ func ctor(env *vmimpl.Env) (vmimpl.Pool, error) {
}
}
pool := &Pool{
- cfg: cfg,
- env: env,
- GCE: GCE,
+ cfg: cfg,
+ env: env,
+ GCE: GCE,
+ consoleReadCmd: consoleReadCmd,
}
return pool, nil
}
@@ -182,16 +189,17 @@ func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) {
}
ok = true
inst := &instance{
- env: pool.env,
- cfg: pool.cfg,
- debug: pool.env.Debug,
- GCE: pool.GCE,
- name: name,
- ip: ip,
- gceKey: gceKey,
- sshKey: sshKey,
- sshUser: sshUser,
- closed: make(chan bool),
+ env: pool.env,
+ cfg: pool.cfg,
+ debug: pool.env.Debug,
+ GCE: pool.GCE,
+ name: name,
+ ip: ip,
+ gceKey: gceKey,
+ sshKey: sshKey,
+ sshUser: sshUser,
+ closed: make(chan bool),
+ consoleReadCmd: pool.consoleReadCmd,
}
return inst, nil
}
@@ -224,11 +232,16 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin
return nil, nil, err
}
- conAddr := fmt.Sprintf("%v.%v.%v.syzkaller.port=1@ssh-serialport.googleapis.com",
- inst.GCE.ProjectID, inst.GCE.ZoneID, inst.name)
- conArgs := append(vmimpl.SSHArgs(inst.debug, inst.gceKey, 9600), conAddr)
- // TODO: remove this later (see also a comment in getSerialPortOutput).
- conArgs = append(conArgs, "-o", "HostKeyAlgorithms=+ssh-rsa")
+ var conArgs []string
+ if inst.consoleReadCmd == "" {
+ conAddr := fmt.Sprintf("%v.%v.%v.syzkaller.port=1@ssh-serialport.googleapis.com",
+ inst.GCE.ProjectID, inst.GCE.ZoneID, inst.name)
+ conArgs = append(vmimpl.SSHArgs(inst.debug, inst.gceKey, 9600), conAddr)
+ // TODO: remove this later (see also a comment in getSerialPortOutput).
+ conArgs = append(conArgs, "-o", "HostKeyAlgorithms=+ssh-rsa")
+ } else {
+ conArgs = inst.sshArgs(inst.consoleReadCmd)
+ }
con := osutil.Command("ssh", conArgs...)
con.Env = []string{}
con.Stdout = conWpipe