qemu: Make Config's FDs field private

All file descriptors will come from specific devices configurations, so
this patch:

1) Make the Config FDs file private
2) Provide an appendFDs() method for Config, that takes a slice of
os.File pointers and
   a) Adds them to the Config private fd slice
   b) Return a slice of ints that represent the file descriptors for
      these device specific files, as seen by the qemu process.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz 2016-09-19 12:37:58 +02:00
parent 12f6ebe389
commit db067857bd
2 changed files with 45 additions and 15 deletions

48
qemu.go
View File

@ -46,7 +46,7 @@ type Machine struct {
// Device is the qemu device interface. // Device is the qemu device interface.
type Device interface { type Device interface {
Valid() bool Valid() bool
QemuParams() []string QemuParams(config *Config) []string
} }
// DeviceDriver is the device driver string. // DeviceDriver is the device driver string.
@ -118,7 +118,7 @@ func (object Object) Valid() bool {
} }
// QemuParams returns the qemu parameters built out of this Object device. // QemuParams returns the qemu parameters built out of this Object device.
func (object Object) QemuParams() []string { func (object Object) QemuParams(config *Config) []string {
var objectParams []string var objectParams []string
var deviceParams []string var deviceParams []string
var qemuParams []string var qemuParams []string
@ -207,7 +207,7 @@ func (fsdev FSDevice) Valid() bool {
} }
// QemuParams returns the qemu parameters built out of this filesystem device. // QemuParams returns the qemu parameters built out of this filesystem device.
func (fsdev FSDevice) QemuParams() []string { func (fsdev FSDevice) QemuParams(config *Config) []string {
var fsParams []string var fsParams []string
var deviceParams []string var deviceParams []string
var qemuParams []string var qemuParams []string
@ -294,7 +294,7 @@ func appendCharDevice(params []string, cdev CharDevice) ([]string, error) {
} }
// QemuParams returns the qemu parameters built out of this character device. // QemuParams returns the qemu parameters built out of this character device.
func (cdev CharDevice) QemuParams() []string { func (cdev CharDevice) QemuParams(config *Config) []string {
var cdevParams []string var cdevParams []string
var deviceParams []string var deviceParams []string
var qemuParams []string var qemuParams []string
@ -349,7 +349,7 @@ type NetDevice struct {
// FDs represents the list of already existing file descriptors to be used. // FDs represents the list of already existing file descriptors to be used.
// This is mostly useful for mq support. // This is mostly useful for mq support.
FDs []int FDs []*os.File
// VHost enables virtio device emulation from the host kernel instead of from qemu. // VHost enables virtio device emulation from the host kernel instead of from qemu.
VHost bool VHost bool
@ -375,7 +375,7 @@ func (netdev NetDevice) Valid() bool {
} }
// QemuParams returns the qemu parameters built out of this network device. // QemuParams returns the qemu parameters built out of this network device.
func (netdev NetDevice) QemuParams() []string { func (netdev NetDevice) QemuParams(config *Config) []string {
var netdevParams []string var netdevParams []string
var deviceParams []string var deviceParams []string
var qemuParams []string var qemuParams []string
@ -399,7 +399,9 @@ func (netdev NetDevice) QemuParams() []string {
if len(netdev.FDs) > 0 { if len(netdev.FDs) > 0 {
var fdParams []string var fdParams []string
for _, fd := range netdev.FDs { qemuFDs := config.appendFDs(netdev.FDs)
for _, fd := range qemuFDs {
fdParams = append(fdParams, fmt.Sprintf("%d", fd)) fdParams = append(fdParams, fmt.Sprintf("%d", fd))
} }
@ -438,7 +440,7 @@ func (dev SerialDevice) Valid() bool {
} }
// QemuParams returns the qemu parameters built out of this serial device. // QemuParams returns the qemu parameters built out of this serial device.
func (dev SerialDevice) QemuParams() []string { func (dev SerialDevice) QemuParams(config *Config) []string {
var deviceParams []string var deviceParams []string
var qemuParams []string var qemuParams []string
@ -503,7 +505,7 @@ func (blkdev BlockDevice) Valid() bool {
} }
// QemuParams returns the qemu parameters built out of this block device. // QemuParams returns the qemu parameters built out of this block device.
func (blkdev BlockDevice) QemuParams() []string { func (blkdev BlockDevice) QemuParams(config *Config) []string {
var blkParams []string var blkParams []string
var deviceParams []string var deviceParams []string
var qemuParams []string var qemuParams []string
@ -730,12 +732,32 @@ type Config struct {
// Knobs is a set of qemu boolean settings. // Knobs is a set of qemu boolean settings.
Knobs Knobs Knobs Knobs
// FDs is a list of open file descriptors to be passed to the spawned qemu process // fds is a list of open file descriptors to be passed to the spawned qemu process
FDs []*os.File fds []*os.File
qemuParams []string qemuParams []string
} }
// appendFDs append a list of file descriptors to the qemu configuration and
// returns a slice of offset file descriptors that will be seen by the qemu process.
func (config *Config) appendFDs(fds []*os.File) []int {
var fdInts []int
oldLen := len(config.fds)
config.fds = append(config.fds, fds...)
// The magic 3 offset comes from https://golang.org/src/os/exec/exec.go:
// ExtraFiles specifies additional open files to be inherited by the
// new process. It does not include standard input, standard output, or
// standard error. If non-nil, entry i becomes file descriptor 3+i.
for i := range fds {
fdInts = append(fdInts, oldLen+3+i)
}
return fdInts
}
func (config *Config) appendName() { func (config *Config) appendName() {
if config.Name != "" { if config.Name != "" {
config.qemuParams = append(config.qemuParams, "-name") config.qemuParams = append(config.qemuParams, "-name")
@ -791,7 +813,7 @@ func (config *Config) appendDevices() {
continue continue
} }
config.qemuParams = append(config.qemuParams, d.QemuParams()...) config.qemuParams = append(config.qemuParams, d.QemuParams(config)...)
} }
} }
@ -929,7 +951,7 @@ func LaunchQemu(config Config, logger QMPLog) (string, error) {
config.appendKnobs() config.appendKnobs()
config.appendKernel() config.appendKernel()
return LaunchCustomQemu(config.Ctx, config.Path, config.qemuParams, config.FDs, logger) return LaunchCustomQemu(config.Ctx, config.Path, config.qemuParams, config.fds, logger)
} }
// LaunchCustomQemu can be used to launch a new qemu instance. // LaunchCustomQemu can be used to launch a new qemu instance.

View File

@ -17,6 +17,8 @@
package qemu package qemu
import ( import (
"io/ioutil"
"os"
"strings" "strings"
"testing" "testing"
@ -113,9 +115,15 @@ func TestAppendDeviceFS(t *testing.T) {
testAppend(fsdev, deviceFSString, t) testAppend(fsdev, deviceFSString, t)
} }
var deviceNetworkString = "-device virtio-net,netdev=tap0,mac=01:02:de:ad:be:ef -netdev tap,id=tap0,ifname=ceth0,downscript=no,script=no,fds=8:9:10,vhost=on" var deviceNetworkString = "-device virtio-net,netdev=tap0,mac=01:02:de:ad:be:ef -netdev tap,id=tap0,ifname=ceth0,downscript=no,script=no,fds=3:4,vhost=on"
func TestAppendDeviceNetwork(t *testing.T) { func TestAppendDeviceNetwork(t *testing.T) {
foo, _ := ioutil.TempFile(os.TempDir(), "qemu-ciao-test")
bar, _ := ioutil.TempFile(os.TempDir(), "qemu-ciao-test")
defer os.Remove(foo.Name())
defer os.Remove(bar.Name())
netdev := NetDevice{ netdev := NetDevice{
Driver: VirtioNet, Driver: VirtioNet,
Type: TAP, Type: TAP,
@ -123,7 +131,7 @@ func TestAppendDeviceNetwork(t *testing.T) {
IFName: "ceth0", IFName: "ceth0",
Script: "no", Script: "no",
DownScript: "no", DownScript: "no",
FDs: []int{8, 9, 10}, FDs: []*os.File{foo, bar},
VHost: true, VHost: true,
MACAddress: "01:02:de:ad:be:ef", MACAddress: "01:02:de:ad:be:ef",
} }