qemu

package
v0.0.0-...-3c0cf66 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 9, 2016 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package qemu provides methods and types for launching and managing QEMU instances. Instances can be launched with the LaunchQemu function and managed thereafter via QMPStart and the QMP object that this function returns. To manage a qemu instance after it has been launched you need to pass the -qmp option during launch requesting the qemu instance to create a QMP unix domain manageent socket, e.g., -qmp unix:/tmp/qmp-socket,server,nowait. For more information see the example below.

Example
package main

import (
	"time"

	"context"

	"github.com/01org/ciao/qemu"
)

func main() {
	params := make([]string, 0, 32)

	// Rootfs
	params = append(params, "-drive", "file=/tmp/image.qcow2,if=virtio,aio=threads,format=qcow2")
	// Network
	params = append(params, "-net", "nic,model=virtio", "-net", "user")
	// kvm
	params = append(params, "-enable-kvm", "-cpu", "host")
	// qmp socket
	params = append(params, "-daemonize", "-qmp", "unix:/tmp/qmp-socket,server,nowait")
	// resources
	params = append(params, "-m", "370", "-smp", "cpus=2")

	// LaunchCustomQemu should return as soon as the instance has launched as we
	// are using the --daemonize flag.  It will set up a unix domain socket
	// called /tmp/qmp-socket that we can use to manage the instance.
	_, err := qemu.LaunchCustomQemu(context.Background(), "", params, nil, nil)
	if err != nil {
		panic(err)
	}

	// This channel will be closed when the instance dies.
	disconnectedCh := make(chan struct{})

	// Set up our options.  We don't want any logging or to receive any events.
	cfg := qemu.QMPConfig{}

	// Start monitoring the qemu instance.  This functon will block until we have
	// connect to the QMP socket and received the welcome message.
	q, _, err := qemu.QMPStart(context.Background(), "/tmp/qmp-socket", cfg, disconnectedCh)
	if err != nil {
		panic(err)
	}

	// This has to be the first command executed in a QMP session.
	err = q.ExecuteQMPCapabilities(context.Background())
	if err != nil {
		panic(err)
	}

	// Let's try to shutdown the VM.  If it hasn't shutdown in 10 seconds we'll
	// send a quit message.
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	err = q.ExecuteSystemPowerdown(ctx)
	cancel()
	if err != nil {
		err = q.ExecuteQuit(context.Background())
		if err != nil {
			panic(err)
		}
	}

	q.Shutdown()

	// disconnectedCh is closed when the VM exits. This line blocks until this
	// event occurs.
	<-disconnectedCh
}
Output:

Index

Examples

Constants

View Source
const (
	// NVDIMM is the Non Volatile DIMM device driver.
	NVDIMM DeviceDriver = "nvdimm"

	// Virtio9P is the 9pfs device driver.
	Virtio9P = "virtio-9p-pci"

	// VirtioNet is the virt-io networking device driver.
	VirtioNet = "virtio-net"

	// VirtioSerial is the serial device driver.
	VirtioSerial = "virtio-serial-pci"

	// VirtioBlock is the block device driver.
	VirtioBlock = "virtio-blk"

	// Console is the console device driver.
	Console = "virtconsole"

	// VirtioSerialPort is the serial port device driver.
	VirtioSerialPort = "virtserialport"
)
View Source
const (
	// Local is the local qemu filesystem driver.
	Local FSDriver = "local"

	// Handle is the handle qemu filesystem driver.
	Handle = "handle"

	// Proxy is the proxy qemu filesystem driver.
	Proxy = "proxy"
)
View Source
const (
	// None is like passthrough without failure reports.
	None SecurityModelType = "none"

	// PassThrough uses the same credentials on both the host and guest.
	PassThrough = "passthrough"

	// MappedXattr stores some files attributes as extended attributes.
	MappedXattr = "mapped-xattr"

	// MappedFile stores some files attributes in the .virtfs directory.
	MappedFile = "mapped-file"
)
View Source
const (
	// Pipe creates a 2 way connection to the guest.
	Pipe CharDeviceBackend = "pipe"

	// Socket creates a 2 way stream socket (TCP or Unix).
	Socket = "socket"

	// CharConsole sends traffic from the guest to QEMU's standard output.
	CharConsole = "console"

	// Serial sends traffic from the guest to a serial device on the host.
	Serial = "serial"

	// TTY is an alias for Serial.
	TTY = "tty"

	// PTY creates a new pseudo-terminal on the host and connect to it.
	PTY = "pty"
)

Variables

This section is empty.

Functions

func LaunchCustomQemu

func LaunchCustomQemu(ctx context.Context, path string, params []string, fds []*os.File, logger QMPLog) (string, error)

LaunchCustomQemu can be used to launch a new qemu instance.

The path parameter is used to pass the qemu executable path.

The ctx parameter is not currently used but has been added so that the signature of this function will not need to change when launch cancellation is implemented.

config.qemuParams is a slice of options to pass to qemu-system-x86_64 and fds is a list of open file descriptors that are to be passed to the spawned qemu process.

This function writes its log output via logger parameter.

The function will block until the launched qemu process exits. "", nil will be returned if the launch succeeds. Otherwise a string containing the contents of stderr + a Go error object will be returned.

func LaunchQemu

func LaunchQemu(config Config, logger QMPLog) (string, error)

LaunchQemu can be used to launch a new qemu instance.

The Config parameter contains a set of qemu parameters and settings.

This function writes its log output via logger parameter.

The function will block until the launched qemu process exits. "", nil will be returned if the launch succeeds. Otherwise a string containing the contents of stderr + a Go error object will be returned.

func QMPStart

func QMPStart(ctx context.Context, socket string, cfg QMPConfig, disconnectedCh chan struct{}) (*QMP, *QMPVersion, error)

QMPStart connects to a unix domain socket maintained by a QMP instance. It waits to receive the QMP welcome message via the socket and spawns some go routines to manage the socket. The function returns a *QMP which can be used by callers to send commands to the QEMU instance or to close the socket and all the go routines that have been spawned to monitor it. A *QMPVersion is also returned. This structure contains the version and capabilities information returned by the QEMU instance in its welcome message.

socket contains the path to the domain socket. cfg contains some options that can be specified by the caller, namely where the qemu package should send logs and QMP events. disconnectedCh is a channel that must be supplied by the caller. It is closed when an error occurs openning or writing to or reading from the unix domain socket. This implies that the QEMU instance that opened the socket has closed.

If this function returns without error, callers should call QMP.Shutdown when they wish to stop monitoring the QMP instance. This is not strictly necessary if the QEMU instance exits and the disconnectedCh is closed, but doing so will not cause any problems.

Commands can be sent to the QEMU instance via the QMP.Execute methods. These commands are executed serially, even if the QMP.Execute methods are called from different go routines. The QMP.Execute methods will block until they have received a success or failure message from QMP, i.e., {"return": {}} or {"error":{}}, and in some cases certain events are received.

Types

type BlockDevice

type BlockDevice struct {
	Driver    DeviceDriver
	ID        string
	File      string
	Interface BlockDeviceInterface
	AIO       BlockDeviceAIO
	Format    BlockDeviceFormat
	SCSI      bool
	WCE       bool
}

BlockDevice represents a qemu block device.

func (BlockDevice) QemuParams

func (blkdev BlockDevice) QemuParams(config *Config) []string

QemuParams returns the qemu parameters built out of this block device.

func (BlockDevice) Valid

func (blkdev BlockDevice) Valid() bool

Valid returns true if the BlockDevice structure is valid and complete.

type BlockDeviceAIO

type BlockDeviceAIO string

BlockDeviceAIO defines the type of asynchronous I/O the block device should use.

const (
	// Threads is the pthread asynchronous I/O implementation.
	Threads BlockDeviceAIO = "threads"

	// Native is the pthread asynchronous I/O implementation.
	Native = "native"
)

type BlockDeviceFormat

type BlockDeviceFormat string

BlockDeviceFormat defines the image format used on a block device.

const (
	// QCOW2 is the Qemu Copy On Write v2 image format.
	QCOW2 BlockDeviceFormat = "qcow2"
)

type BlockDeviceInterface

type BlockDeviceInterface string

BlockDeviceInterface defines the type of interface the device is connected to.

const (
	// NoInterface for block devices with no interfaces.
	NoInterface BlockDeviceInterface = "none"

	// SCSI represents a SCSI block device interface.
	SCSI = "scsi"
)

type CharDevice

type CharDevice struct {
	Backend CharDeviceBackend

	// Driver is the qemu device driver
	Driver DeviceDriver

	// Bus is the serial bus associated to this device.
	Bus string

	// DeviceID is the user defined device ID.
	DeviceID string

	ID   string
	Path string
	Name string
}

CharDevice represents a qemu character device.

func (CharDevice) QemuParams

func (cdev CharDevice) QemuParams(config *Config) []string

QemuParams returns the qemu parameters built out of this character device.

func (CharDevice) Valid

func (cdev CharDevice) Valid() bool

Valid returns true if the CharDevice structure is valid and complete.

type CharDeviceBackend

type CharDeviceBackend string

CharDeviceBackend is the character device backend for qemu

type Config

type Config struct {
	// Path is the qemu binary path.
	Path string

	// Ctx is not used at the moment.
	Ctx context.Context

	// Name is the qemu guest name
	Name string

	// UUID is the qemu process UUID.
	UUID string

	// CPUModel is the CPU model to be used by qemu.
	CPUModel string

	// Machine
	Machine Machine

	// QMPSockets is a slice of QMP socket description.
	QMPSockets []QMPSocket

	// Devices is a list of devices for qemu to create and drive.
	Devices []Device

	// RTC is the qemu Real Time Clock configuration
	RTC RTC

	// VGA is the qemu VGA mode.
	VGA string

	// Kernel is the guest kernel configuration.
	Kernel Kernel

	// Memory is the guest memory configuration.
	Memory Memory

	// SMP is the quest multi processors configuration.
	SMP SMP

	// GlobalParam is the -global parameter.
	GlobalParam string

	// Knobs is a set of qemu boolean settings.
	Knobs Knobs
	// contains filtered or unexported fields
}

Config is the qemu configuration structure. It allows for passing custom settings and parameters to the qemu API.

type Device

type Device interface {
	Valid() bool
	QemuParams(config *Config) []string
}

Device is the qemu device interface.

type DeviceDriver

type DeviceDriver string

DeviceDriver is the device driver string.

type FSDevice

type FSDevice struct {
	// Driver is the qemu device driver
	Driver DeviceDriver

	// FSDriver is the filesystem driver backend.
	FSDriver FSDriver

	// ID is the filesystem identifier.
	ID string

	// Path is the host root path for this filesystem.
	Path string

	// MountTag is the device filesystem mount point tag.
	MountTag string

	// SecurityModel is the security model for this filesystem device.
	SecurityModel SecurityModelType
}

FSDevice represents a qemu filesystem configuration.

func (FSDevice) QemuParams

func (fsdev FSDevice) QemuParams(config *Config) []string

QemuParams returns the qemu parameters built out of this filesystem device.

func (FSDevice) Valid

func (fsdev FSDevice) Valid() bool

Valid returns true if the FSDevice structure is valid and complete.

type FSDriver

type FSDriver string

FSDriver represents a qemu filesystem driver.

type Kernel

type Kernel struct {
	// Path is the guest kernel path on the host filesystem.
	Path string

	// Params is the kernel parameters string.
	Params string
}

Kernel is the guest kernel configuration structure.

type Knobs

type Knobs struct {
	// NoUserConfig prevents qemu from loading user config files.
	NoUserConfig bool

	// NoDefaults prevents qemu from creating default devices.
	NoDefaults bool

	// NoGraphic completely disables graphic output.
	NoGraphic bool

	// Daemonize will turn the qemu process into a daemon
	Daemonize bool
}

Knobs regroups a set of qemu boolean settings

type Machine

type Machine struct {
	// Type is the machine type to be used by qemu.
	Type string

	// Acceleration are the machine acceleration options to be used by qemu.
	Acceleration string
}

Machine describes the machine type qemu will emulate.

type Memory

type Memory struct {
	// Size is the amount of memory made available to the guest.
	// It should be suffixed with M or G for sizes in megabytes or
	// gigabytes respectively.
	Size string

	// Slots is the amount of memory slots made available to the guest.
	Slots uint8

	// MaxMem is the maximum amount of memory that can be made available
	// to the guest through e.g. hot pluggable memory.
	MaxMem string
}

Memory is the guest memory configuration structure.

type NetDevice

type NetDevice struct {
	// Type is the netdev type (e.g. tap).
	Type NetDeviceType

	// Driver is the qemu device driver
	Driver DeviceDriver

	// ID is the netdevice identifier.
	ID string

	// IfName is the interface name,
	IFName string

	// DownScript is the tap interface deconfiguration script.
	DownScript string

	// Script is the tap interface configuration script.
	Script string

	// FDs represents the list of already existing file descriptors to be used.
	// This is mostly useful for mq support.
	FDs []*os.File

	// VHost enables virtio device emulation from the host kernel instead of from qemu.
	VHost bool

	// MACAddress is the networking device interface MAC address.
	MACAddress string
}

NetDevice represents a guest networking device

func (NetDevice) QemuParams

func (netdev NetDevice) QemuParams(config *Config) []string

QemuParams returns the qemu parameters built out of this network device.

func (NetDevice) Valid

func (netdev NetDevice) Valid() bool

Valid returns true if the NetDevice structure is valid and complete.

type NetDeviceType

type NetDeviceType string

NetDeviceType is a qemu networing device type.

const (
	// TAP is a TAP networking device type.
	TAP NetDeviceType = "tap"

	// MACVTAP is a MAC virtual TAP networking device type.
	MACVTAP = "macvtap"
)

type Object

type Object struct {
	// Driver is the qemu device driver
	Driver DeviceDriver

	// Type is the qemu object type.
	Type ObjectType

	// ID is the user defined object ID.
	ID string

	// DeviceID is the user defined device ID.
	DeviceID string

	// MemPath is the object's memory path.
	// This is only relevant for memory objects
	MemPath string

	// Size is the object size in bytes
	Size uint64
}

Object is a qemu object representation.

func (Object) QemuParams

func (object Object) QemuParams(config *Config) []string

QemuParams returns the qemu parameters built out of this Object device.

func (Object) Valid

func (object Object) Valid() bool

Valid returns true if the Object structure is valid and complete.

type ObjectType

type ObjectType string

ObjectType is a string representing a qemu object type.

const (
	// MemoryBackendFile represents a guest memory mapped file.
	MemoryBackendFile ObjectType = "memory-backend-file"
)

type QMP

type QMP struct {
	// contains filtered or unexported fields
}

QMP is a structure that contains the internal state used by startQMPLoop and the go routines it spwans. All the contents of this structure are private.

func (*QMP) ExecuteBlockdevAdd

func (q *QMP) ExecuteBlockdevAdd(ctx context.Context, device, blockdevID string) error

ExecuteBlockdevAdd sends a blockdev-add to the QEMU instance. device is the path of the device to add, e.g., /dev/rdb0, and blockdevID is an identifier used to name the device. As this identifier will be passed directly to QMP, it must obey QMP's naming rules, e,g., it must start with a letter.

func (*QMP) ExecuteCont

func (q *QMP) ExecuteCont(ctx context.Context) error

ExecuteCont sends the cont command to the instance.

func (*QMP) ExecuteDeviceAdd

func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, bus string) error

ExecuteDeviceAdd adds the guest portion of a device to a QEMU instance using the device_add command. blockdevID should match the blockdevID passed to a previous call to ExecuteBlockdevAdd. devID is the id of the device to add. Both strings must be valid QMP identifiers. driver is the name of the driver,e.g., virtio-blk-pci, and bus is the name of the bus. bus is optional.

func (*QMP) ExecuteDeviceDel

func (q *QMP) ExecuteDeviceDel(ctx context.Context, devID string) error

ExecuteDeviceDel deletes guest portion of a QEMU device by sending a device_del command. devId is the identifier of the device to delete. Typically it would match the devID parameter passed to an earlier call to ExecuteDeviceAdd. It must be a valid QMP identidier.

This method blocks until a DEVICE_DELETED event is received for devID.

func (*QMP) ExecuteQMPCapabilities

func (q *QMP) ExecuteQMPCapabilities(ctx context.Context) error

ExecuteQMPCapabilities executes the qmp_capabilities command on the instance.

func (*QMP) ExecuteQuit

func (q *QMP) ExecuteQuit(ctx context.Context) error

ExecuteQuit sends the quit command to the instance, terminating the QMP instance immediately.

func (*QMP) ExecuteStop

func (q *QMP) ExecuteStop(ctx context.Context) error

ExecuteStop sends the stop command to the instance.

func (*QMP) ExecuteSystemPowerdown

func (q *QMP) ExecuteSystemPowerdown(ctx context.Context) error

ExecuteSystemPowerdown sends the system_powerdown command to the instance. This function will block until the SHUTDOWN event is received.

func (*QMP) ExecuteXBlockdevDel

func (q *QMP) ExecuteXBlockdevDel(ctx context.Context, blockdevID string) error

ExecuteXBlockdevDel deletes a block device by sending a x-blockdev-del command. blockdevID is the id of the block device to be deleted. Typically, this will match the id passed to ExecuteBlockdevAdd. It must be a valid QMP id.

func (*QMP) Shutdown

func (q *QMP) Shutdown()

Shutdown closes the domain socket used to monitor a QEMU instance and terminates all the go routines spawned by QMPStart to manage that instance. QMP.Shutdown does not shut down the running instance. Calling QMP.Shutdown will result in the disconnectedCh channel being closed, indicating that we have lost connection to the QMP instance. In this case it does not indicate that the instance has quit.

QMP.Shutdown should not be called concurrently with other QMP methods. It should not be called twice on the same QMP instance.

Calling QMP.Shutdown after the disconnectedCh channel is closed is permitted but will not have any effect.

type QMPConfig

type QMPConfig struct {
	// eventCh can be specified by clients who wish to receive QMP
	// events.
	EventCh chan<- QMPEvent

	// logger is used by the qmpStart function and all the go routines
	// it spawns to log information.
	Logger QMPLog
}

QMPConfig is a configuration structure that can be used to specify a logger and a channel to which logs and QMP events are to be sent. If neither of these fields are specified, or are set to nil, no logs will be written and no QMP events will be reported to the client.

type QMPEvent

type QMPEvent struct {
	// The name of the event, e.g., DEVICE_DELETED
	Name string

	// The data associated with the event.  The contents of this map are
	// unprocessed by the qemu package.  It is simply the result of
	// unmarshalling the QMP json event.  Here's an example map
	// map[string]interface{}{
	//	"driver": "virtio-blk-pci",
	//	"drive":  "drive_3437843748734873483",
	// }
	Data map[string]interface{}

	// The event's timestamp converted to a time.Time object.
	Timestamp time.Time
}

QMPEvent contains a single QMP event, sent on the QMPConfig.EventCh channel.

type QMPLog

type QMPLog interface {
	// V returns true if the given argument is less than or equal
	// to the implementation's defined verbosity level.
	V(int32) bool

	// Infof writes informational output to the log.  A newline will be
	// added to the output if one is not provided.
	Infof(string, ...interface{})

	// Warningf writes warning output to the log.  A newline will be
	// added to the output if one is not provided.
	Warningf(string, ...interface{})

	// Errorf writes error output to the log.  A newline will be
	// added to the output if one is not provided.
	Errorf(string, ...interface{})
}

QMPLog is a logging interface used by the qemu package to log various interesting pieces of information. Rather than introduce a dependency on a given logging package, qemu presents this interface that allows clients to provide their own logging type which they can use to seamlessly integrate qemu's logs into their own logs. A QMPLog implementation can be specified in the QMPConfig structure.

type QMPSocket

type QMPSocket struct {
	// Type is the socket type (e.g. "unix").
	Type QMPSocketType

	// Name is the socket name.
	Name string

	// Server tells if this is a server socket.
	Server bool

	// NoWait tells if qemu should block waiting for a client to connect.
	NoWait bool
}

QMPSocket represents a qemu QMP socket configuration.

func (QMPSocket) Valid

func (qmp QMPSocket) Valid() bool

Valid returns true if the QMPSocket structure is valid and complete.

type QMPSocketType

type QMPSocketType string

QMPSocketType is the type of socket used for QMP communication.

const (
	// Unix socket for QMP.
	Unix QMPSocketType = "unix"
)

type QMPVersion

type QMPVersion struct {
	Major        int
	Minor        int
	Micro        int
	Capabilities []string
}

QMPVersion contains the version number and the capabailities of a QEMU instance, as reported in the QMP greeting message.

type RTC

type RTC struct {
	// Base is the RTC start time.
	Base RTCBaseType

	// Clock is the is the RTC clock driver.
	Clock RTCClock

	// DriftFix is the drift fixing mechanism.
	DriftFix RTCDriftFix
}

RTC represents a qemu Real Time Clock configuration.

func (RTC) Valid

func (rtc RTC) Valid() bool

Valid returns true if the RTC structure is valid and complete.

type RTCBaseType

type RTCBaseType string

RTCBaseType is the qemu RTC base time type.

const (
	// UTC is the UTC base time for qemu RTC.
	UTC RTCBaseType = "utc"

	// LocalTime is the local base time for qemu RTC.
	LocalTime = "localtime"
)

type RTCClock

type RTCClock string

RTCClock is the qemu RTC clock type.

const (
	// Host is for using the host clock as a reference.
	Host RTCClock = "host"

	// VM is for using the guest clock as a reference
	VM = "vm"
)

type RTCDriftFix

type RTCDriftFix string

RTCDriftFix is the qemu RTC drift fix type.

const (
	// Slew is the qemu RTC Drift fix mechanism.
	Slew RTCDriftFix = "slew"

	// NoDriftFix means we don't want/need to fix qemu's RTC drift.
	NoDriftFix = "none"
)

type SMP

type SMP struct {
	// CPUs is the number of VCPUs made available to qemu.
	CPUs uint32

	// Cores is the number of cores made available to qemu.
	Cores uint32

	// Threads is the number of threads made available to qemu.
	Threads uint32

	// Sockets is the number of sockets made available to qemu.
	Sockets uint32
}

SMP is the multi processors configuration structure.

type SecurityModelType

type SecurityModelType string

SecurityModelType is a qemu filesystem security model type.

type SerialDevice

type SerialDevice struct {
	// Driver is the qemu device driver
	Driver DeviceDriver

	// ID is the serial device identifier.
	ID string
}

SerialDevice represents a qemu serial device.

func (SerialDevice) QemuParams

func (dev SerialDevice) QemuParams(config *Config) []string

QemuParams returns the qemu parameters built out of this serial device.

func (SerialDevice) Valid

func (dev SerialDevice) Valid() bool

Valid returns true if the SerialDevice structure is valid and complete.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL