2015-10-12 08:16:57 +00:00
|
|
|
// Copyright 2015 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 vm
|
|
|
|
|
|
|
|
import (
|
2015-12-23 18:11:29 +00:00
|
|
|
"errors"
|
2015-10-12 08:16:57 +00:00
|
|
|
"fmt"
|
2016-08-28 17:21:57 +00:00
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"syscall"
|
2015-12-23 18:11:29 +00:00
|
|
|
"time"
|
2015-10-12 08:16:57 +00:00
|
|
|
)
|
|
|
|
|
2015-12-23 18:11:29 +00:00
|
|
|
// Instance represents a Linux VM or a remote physical machine.
|
2015-10-12 08:16:57 +00:00
|
|
|
type Instance interface {
|
2016-01-11 16:33:44 +00:00
|
|
|
// Copy copies a hostSrc file into vm and returns file name in vm.
|
|
|
|
Copy(hostSrc string) (string, error)
|
|
|
|
|
|
|
|
// Forward setups forwarding from within VM to host port port
|
|
|
|
// and returns address to use in VM.
|
|
|
|
Forward(port int) (string, error)
|
|
|
|
|
2015-12-23 18:11:29 +00:00
|
|
|
// Run runs cmd inside of the VM (think of ssh cmd).
|
|
|
|
// outc receives combined cmd and kernel console output.
|
|
|
|
// errc receives either command Wait return error or vm.TimeoutErr.
|
|
|
|
Run(timeout time.Duration, command string) (outc <-chan []byte, errc <-chan error, err error)
|
2016-01-11 16:33:44 +00:00
|
|
|
|
2015-12-23 18:11:29 +00:00
|
|
|
// Close stops and destroys the VM.
|
|
|
|
Close()
|
2015-10-12 08:16:57 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 10:47:37 +00:00
|
|
|
type Config struct {
|
2016-08-30 12:33:39 +00:00
|
|
|
Name string
|
|
|
|
Index int
|
|
|
|
Workdir string
|
|
|
|
Bin string
|
|
|
|
Initrd string
|
|
|
|
Kernel string
|
|
|
|
Cmdline string
|
|
|
|
Image string
|
|
|
|
Sshkey string
|
|
|
|
Executor string
|
|
|
|
Device string
|
|
|
|
Cpu int
|
|
|
|
Mem int
|
|
|
|
Debug bool
|
2015-10-19 10:47:37 +00:00
|
|
|
}
|
|
|
|
|
2015-12-23 18:11:29 +00:00
|
|
|
type ctorFunc func(cfg *Config) (Instance, error)
|
2015-10-12 08:16:57 +00:00
|
|
|
|
|
|
|
var ctors = make(map[string]ctorFunc)
|
|
|
|
|
|
|
|
func Register(typ string, ctor ctorFunc) {
|
|
|
|
ctors[typ] = ctor
|
|
|
|
}
|
|
|
|
|
2015-12-23 18:11:29 +00:00
|
|
|
// Create creates and boots a new VM instance.
|
|
|
|
func Create(typ string, cfg *Config) (Instance, error) {
|
2015-10-12 08:16:57 +00:00
|
|
|
ctor := ctors[typ]
|
|
|
|
if ctor == nil {
|
|
|
|
return nil, fmt.Errorf("unknown instance type '%v'", typ)
|
|
|
|
}
|
2015-12-23 18:11:29 +00:00
|
|
|
return ctor(cfg)
|
2015-10-12 08:16:57 +00:00
|
|
|
}
|
2015-12-23 18:11:29 +00:00
|
|
|
|
2016-08-28 17:21:57 +00:00
|
|
|
func LongPipe() (io.ReadCloser, io.WriteCloser, error) {
|
|
|
|
r, w, err := os.Pipe()
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, fmt.Errorf("failed to create pipe: %v", err)
|
|
|
|
}
|
|
|
|
for sz := 128 << 10; sz <= 2<<20; sz *= 2 {
|
|
|
|
syscall.Syscall(syscall.SYS_FCNTL, w.Fd(), syscall.F_SETPIPE_SZ, uintptr(sz))
|
|
|
|
}
|
|
|
|
return r, w, err
|
|
|
|
}
|
|
|
|
|
2016-08-30 13:19:28 +00:00
|
|
|
var TimeoutErr = errors.New("timeout")
|