diff options
| author | kalder <61064868+kalder@users.noreply.github.com> | 2022-04-05 08:09:30 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-05 17:09:30 +0200 |
| commit | 0127c10f4e2a3b229d30b1269c38d841d76e1390 (patch) | |
| tree | c0dbc36c1d7c7efb3168ff8f55d375ab96e2caad /vm | |
| parent | 5915c2cba1e553cdb54725d05895213c1046ac61 (diff) | |
vm/cuttlefish: add vm type for cuttlefish on gce
* vm/cuttlefish: add vm type for cuttlefish on gce
This new VM type embeds the existing 'gce' type to start an instance and
then run a Cuttlefish Android VM on it using the 'launch_cvd' binary
installed on it.
This requires us to make a few fields on the 'gce' type visible so that
'cuttlefish' can set them when starting the instance.
The remaining functionality (SSH forwarding, file copying, and running
commands on the nested Android VM will be in following changes.
For more information on Cuttlefish, see:
https://source.android.com/setup/create/cuttlefish
https://android.googlesource.com/device/google/cuttlefish/
* vm/cuttlefish: add vm type for cuttlefish on gce
This new VM type embeds the existing 'gce' type to start an instance and
then run a Cuttlefish Android VM on it using the 'launch_cvd' binary
installed on it.
This requires us to make a few fields on the 'gce' type visible so that
'cuttlefish' can set them when starting the instance.
The remaining functionality (SSH forwarding, file copying, and running
commands on the nested Android VM will be in following changes.
For more information on Cuttlefish, see:
https://source.android.com/setup/create/cuttlefish
https://android.googlesource.com/device/google/cuttlefish/
* vm/cuttlefish: add vm type for cuttlefish on gce
This new VM type embeds the existing 'gce' type to start an instance and
then run a Cuttlefish Android VM on it using the 'launch_cvd' binary
installed on it.
This requires us to make a few fields on the 'gce' type visible so that
'cuttlefish' can set them when starting the instance.
The remaining functionality (SSH forwarding, file copying, and running
commands on the nested Android VM will be in following changes.
For more information on Cuttlefish, see:
https://source.android.com/setup/create/cuttlefish
https://android.googlesource.com/device/google/cuttlefish/
* vm/cuttlefish: fix missed log.Logf(0 call to log.Logf(1
* vm/cuttlefish: remove unneeded log.Logf() calls
These logging for Count() isn't terribly useful since it's a single-line
call with very simple logic.
For the unimplemented methods the log lines have limited utility since
they're already returning error messages which will get logged.
Diffstat (limited to 'vm')
| -rw-r--r-- | vm/cuttlefish/cuttlefish.go | 126 | ||||
| -rw-r--r-- | vm/vm.go | 1 |
2 files changed, 127 insertions, 0 deletions
diff --git a/vm/cuttlefish/cuttlefish.go b/vm/cuttlefish/cuttlefish.go new file mode 100644 index 000000000..501f6079d --- /dev/null +++ b/vm/cuttlefish/cuttlefish.go @@ -0,0 +1,126 @@ +// Copyright 2022 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +// Package cuttlefish allows to use Cuttlefish Android emulators hosted on Google Compute Engine +// (GCE) virtual machines as VMs. It is assumed that syz-manager also runs on GCE as VMs are +// created in the current project/zone. +// +// See https://cloud.google.com/compute/docs for details. +// In particular, how to build GCE-compatible images: +// https://cloud.google.com/compute/docs/tutorials/building-images +package cuttlefish + +import ( + "fmt" + "time" + + "github.com/google/syzkaller/pkg/log" + "github.com/google/syzkaller/pkg/report" + "github.com/google/syzkaller/vm/vmimpl" +) + +func init() { + vmimpl.Register("cuttlefish", ctor, true) +} + +type Pool struct { + env *vmimpl.Env + gcePool vmimpl.Pool +} + +type instance struct { + debug bool + gceInst vmimpl.Instance +} + +func ctor(env *vmimpl.Env) (vmimpl.Pool, error) { + gcePool, err := vmimpl.Types["gce"].Ctor(env) + if err != nil { + return nil, fmt.Errorf("failed to create underlying GCE pool: %s", err) + } + + pool := &Pool{ + env: env, + gcePool: gcePool, + } + + return pool, nil +} + +func (pool *Pool) Count() int { + return pool.gcePool.Count() +} + +func (pool *Pool) Create(workdir string, index int) (vmimpl.Instance, error) { + gceInst, err := pool.gcePool.Create(workdir, index) + if err != nil { + return nil, fmt.Errorf("failed to create underlying gce instance: %s", err) + } + + inst := &instance{ + debug: pool.env.Debug, + gceInst: gceInst, + } + + // Start a Cuttlefish device on the GCE instance + // TODO: pass it the specific kernel artifact using -kernel_path and -initramfs_path flags + if err := inst.runOnHost(10*time.Minute, "./bin/launch_cvd -daemon"); err != nil { + return nil, fmt.Errorf("failed to start cuttlefish: %s", err) + } + + if err := inst.runOnHost(10*time.Minute, "adb wait-for-device"); err != nil { + return nil, fmt.Errorf("failed while waiting for device: %s", err) + } + + if err := inst.runOnHost(5*time.Minute, "adb root"); err != nil { + return nil, fmt.Errorf("failed to get root access to device: %s", err) + } + + 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) + } + + for { + select { + case <-vmimpl.Shutdown: + return nil + case err := <-errc: + if err != nil { + return fmt.Errorf("error while running: %s", err) + } + return nil + case out, ok := <-outc: + if ok && inst.debug { + log.Logf(1, "%s", out) + } + } + } +} + +func (inst *instance) Copy(hostSrc string) (string, error) { + return "", fmt.Errorf("not implemented") +} + +func (inst *instance) Forward(port int) (string, error) { + return "", fmt.Errorf("not implemented") +} + +func (inst *instance) Close() { + // Stop Cuttlefish before shutting down the GCE instance. + inst.runOnHost(10*time.Minute, "./bin/stop_cvd") + inst.gceInst.Close() +} + +func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command string) ( + <-chan []byte, <-chan error, error) { + return nil, nil, fmt.Errorf("not implemented") +} + +func (inst *instance) Diagnose(rep *report.Report) ([]byte, bool) { + return nil, false +} @@ -24,6 +24,7 @@ import ( // Import all VM implementations, so that users only need to import vm. _ "github.com/google/syzkaller/vm/adb" _ "github.com/google/syzkaller/vm/bhyve" + _ "github.com/google/syzkaller/vm/cuttlefish" _ "github.com/google/syzkaller/vm/gce" _ "github.com/google/syzkaller/vm/gvisor" _ "github.com/google/syzkaller/vm/isolated" |
