aboutsummaryrefslogtreecommitdiffstats
path: root/vm
diff options
context:
space:
mode:
authorkalder <61064868+kalder@users.noreply.github.com>2022-04-05 08:09:30 -0700
committerGitHub <noreply@github.com>2022-04-05 17:09:30 +0200
commit0127c10f4e2a3b229d30b1269c38d841d76e1390 (patch)
treec0dbc36c1d7c7efb3168ff8f55d375ab96e2caad /vm
parent5915c2cba1e553cdb54725d05895213c1046ac61 (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.go126
-rw-r--r--vm/vm.go1
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
+}
diff --git a/vm/vm.go b/vm/vm.go
index 5f481f0a3..518319521 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -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"