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 ¶
- Constants
- func LaunchCustomQemu(ctx context.Context, path string, params []string, fds []*os.File, ...) (string, error)
- func LaunchQemu(config Config, logger QMPLog) (string, error)
- func QMPStart(ctx context.Context, socket string, cfg QMPConfig, ...) (*QMP, *QMPVersion, error)
- type BlockDevice
- type BlockDeviceAIO
- type BlockDeviceFormat
- type BlockDeviceInterface
- type CharDevice
- type CharDeviceBackend
- type Config
- type Device
- type DeviceDriver
- type FSDevice
- type FSDriver
- type Kernel
- type Knobs
- type Machine
- type Memory
- type NetDevice
- type NetDeviceType
- type Object
- type ObjectType
- type QMP
- func (q *QMP) ExecuteBlockdevAdd(ctx context.Context, device, blockdevID string) error
- func (q *QMP) ExecuteCont(ctx context.Context) error
- func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, bus string) error
- func (q *QMP) ExecuteDeviceDel(ctx context.Context, devID string) error
- func (q *QMP) ExecuteQMPCapabilities(ctx context.Context) error
- func (q *QMP) ExecuteQuit(ctx context.Context) error
- func (q *QMP) ExecuteStop(ctx context.Context) error
- func (q *QMP) ExecuteSystemPowerdown(ctx context.Context) error
- func (q *QMP) ExecuteXBlockdevDel(ctx context.Context, blockdevID string) error
- func (q *QMP) Shutdown()
- type QMPConfig
- type QMPEvent
- type QMPLog
- type QMPSocket
- type QMPSocketType
- type QMPVersion
- type RTC
- type RTCBaseType
- type RTCClock
- type RTCDriftFix
- type SMP
- type SecurityModelType
- type SerialDevice
Examples ¶
Constants ¶
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" )
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" )
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" )
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 ¶
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 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 ¶
QemuParams returns the qemu parameters built out of this filesystem device.
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 ¶
QemuParams returns the qemu parameters built out of this network device.
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 ¶
QemuParams returns the qemu parameters built out of this Object device.
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 ¶
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 ¶
ExecuteCont sends the cont command to the instance.
func (*QMP) ExecuteDeviceAdd ¶
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 ¶
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 ¶
ExecuteQMPCapabilities executes the qmp_capabilities command on the instance.
func (*QMP) ExecuteQuit ¶
ExecuteQuit sends the quit command to the instance, terminating the QMP instance immediately.
func (*QMP) ExecuteStop ¶
ExecuteStop sends the stop command to the instance.
func (*QMP) ExecuteSystemPowerdown ¶
ExecuteSystemPowerdown sends the system_powerdown command to the instance. This function will block until the SHUTDOWN event is received.
func (*QMP) ExecuteXBlockdevDel ¶
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.
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 ¶
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.
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.