diff --git a/Gopkg.lock b/Gopkg.lock index a4834521..baf894b7 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -4,7 +4,7 @@ [[projects]] name = "github.com/ciao-project/ciao" packages = ["qemu"] - revision = "b2a8a2ecea1318ae28a0861191ec385532491b5a" + revision = "c6ea21083acc969871d86f012b465ea09d0cf1c4" [[projects]] name = "github.com/clearcontainers/proxy" diff --git a/vendor/github.com/ciao-project/ciao/packages.json b/vendor/github.com/ciao-project/ciao/packages.json index da2e5662..be720c84 100644 --- a/vendor/github.com/ciao-project/ciao/packages.json +++ b/vendor/github.com/ciao-project/ciao/packages.json @@ -86,7 +86,7 @@ }, "github.com/vishvananda/netlink": { "url": "https://github.com/vishvananda/netlink.git", - "version": "1890b34", + "version": "c2a3de3", "license": "Apache v2.0" }, "github.com/vishvananda/netns": { @@ -104,6 +104,11 @@ "version": "198e27a", "license": "BSD (3 clause)" }, + "golang.org/x/sys/unix": { + "url": "https://github.com/golang/sys", + "version": "665f652", + "license": "BSD (3 clause)" + }, "gopkg.in/yaml.v2": { "url": "https://gopkg.in/yaml.v2", "version": "a5b47d3", diff --git a/vendor/github.com/ciao-project/ciao/qemu/examples_test.go b/vendor/github.com/ciao-project/ciao/qemu/examples_test.go index bc06f520..35373cc1 100644 --- a/vendor/github.com/ciao-project/ciao/qemu/examples_test.go +++ b/vendor/github.com/ciao-project/ciao/qemu/examples_test.go @@ -41,7 +41,7 @@ func Example() { // 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) + _, err := qemu.LaunchCustomQemu(context.Background(), "", params, nil, nil, nil) if err != nil { panic(err) } diff --git a/vendor/github.com/ciao-project/ciao/qemu/image.go b/vendor/github.com/ciao-project/ciao/qemu/image.go index 9b456872..4f064c68 100644 --- a/vendor/github.com/ciao-project/ciao/qemu/image.go +++ b/vendor/github.com/ciao-project/ciao/qemu/image.go @@ -23,6 +23,7 @@ import ( "os" "os/exec" "path" + "syscall" ) // CreateCloudInitISO creates a cloud-init ConfigDrive ISO image. This is @@ -34,8 +35,10 @@ import ( // isoPath contains the desired path of the ISO image to be created. The // userdata and metadata parameters are byte slices that contain the // ConfigDrive userdata and metadata that will be stored with the ISO image. +// The attrs parameter can be used to control aspects of the newly created +// qemu process, such as the user and group under which it runs. It may be nil. func CreateCloudInitISO(ctx context.Context, scratchDir, isoPath string, - userData, metaData []byte) error { + userData, metaData []byte, attr *syscall.SysProcAttr) error { configDrivePath := path.Join(scratchDir, "clr-cloud-init") dataDirPath := path.Join(configDrivePath, "openstack", "latest") metaDataPath := path.Join(dataDirPath, "meta_data.json") @@ -63,6 +66,7 @@ func CreateCloudInitISO(ctx context.Context, scratchDir, isoPath string, cmd := exec.CommandContext(ctx, "xorriso", "-as", "mkisofs", "-R", "-V", "config-2", "-o", isoPath, configDrivePath) + cmd.SysProcAttr = attr err = cmd.Run() if err != nil { return fmt.Errorf("Unable to create cloudinit iso image %v", err) diff --git a/vendor/github.com/ciao-project/ciao/qemu/qemu.go b/vendor/github.com/ciao-project/ciao/qemu/qemu.go index 0e70793f..a342a432 100644 --- a/vendor/github.com/ciao-project/ciao/qemu/qemu.go +++ b/vendor/github.com/ciao-project/ciao/qemu/qemu.go @@ -31,6 +31,7 @@ import ( "os/exec" "strconv" "strings" + "syscall" "context" ) @@ -425,7 +426,8 @@ type NetDevice struct { // FDs represents the list of already existing file descriptors to be used. // This is mostly useful for mq support. - FDs []*os.File + FDs []*os.File + VhostFDs []*os.File // VHost enables virtio device emulation from the host kernel instead of from qemu. VHost bool @@ -511,8 +513,17 @@ func (netdev NetDevice) QemuNetdevParams(config *Config) []string { netdevParams = append(netdevParams, netdev.Type.QemuNetdevParam()) netdevParams = append(netdevParams, fmt.Sprintf(",id=%s", netdev.ID)) + if netdev.VHost == true { netdevParams = append(netdevParams, ",vhost=on") + if len(netdev.VhostFDs) > 0 { + var fdParams []string + qemuFDs := config.appendFDs(netdev.VhostFDs) + for _, fd := range qemuFDs { + fdParams = append(fdParams, fmt.Sprintf("%d", fd)) + } + netdevParams = append(netdevParams, fmt.Sprintf(",vhostfds=%s", strings.Join(fdParams, ":"))) + } } if len(netdev.FDs) > 0 { @@ -1286,7 +1297,8 @@ func LaunchQemu(config Config, logger QMPLog) (string, error) { config.appendKernel() config.appendBios() - return LaunchCustomQemu(config.Ctx, config.Path, config.qemuParams, config.fds, logger) + return LaunchCustomQemu(config.Ctx, config.Path, config.qemuParams, + config.fds, nil, logger) } // LaunchCustomQemu can be used to launch a new qemu instance. @@ -1297,16 +1309,19 @@ func LaunchQemu(config Config, logger QMPLog) (string, error) { // 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 +// params 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. +// process. The attrs parameter can be used to control aspects of the +// newly created qemu process, such as the user and group under which it +// runs. It may be nil. // // 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 LaunchCustomQemu(ctx context.Context, path string, params []string, fds []*os.File, logger QMPLog) (string, error) { +func LaunchCustomQemu(ctx context.Context, path string, params []string, fds []*os.File, + attr *syscall.SysProcAttr, logger QMPLog) (string, error) { if logger == nil { logger = qmpNullLogger{} } @@ -1323,6 +1338,8 @@ func LaunchCustomQemu(ctx context.Context, path string, params []string, fds []* cmd.ExtraFiles = fds } + cmd.SysProcAttr = attr + var stderr bytes.Buffer cmd.Stderr = &stderr logger.Infof("launching qemu with: %v", params) diff --git a/vendor/github.com/ciao-project/ciao/qemu/qmp.go b/vendor/github.com/ciao-project/ciao/qemu/qmp.go index ec291044..72ab89b6 100644 --- a/vendor/github.com/ciao-project/ciao/qemu/qmp.go +++ b/vendor/github.com/ciao-project/ciao/qemu/qmp.go @@ -691,3 +691,34 @@ func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver } return q.executeCommand(ctx, "device_add", args, nil) } + +// ExecuteVFIODeviceAdd adds a VFIO device to a QEMU instance +// using the device_add command. devID is the id of the device to add. +// Must be valid QMP identifier. bdf is the PCI bus-device-function +// of the pci device. +func (q *QMP) ExecuteVFIODeviceAdd(ctx context.Context, devID, bdf string) error { + args := map[string]interface{}{ + "id": devID, + "driver": "vfio-pci", + "host": bdf, + } + return q.executeCommand(ctx, "device_add", args, nil) +} + +// ExecutePCIVFIODeviceAdd adds a VFIO device to a QEMU instance using the device_add command. +// This function can be used to hot plug VFIO devices on PCI(E) bridges, unlike +// ExecuteVFIODeviceAdd this function receives the bus and the device address on its parent bus. +// bus is optional. devID is the id of the device to add.Must be valid QMP identifier. bdf is the +// PCI bus-device-function of the pci device. +func (q *QMP) ExecutePCIVFIODeviceAdd(ctx context.Context, devID, bdf, addr, bus string) error { + args := map[string]interface{}{ + "id": devID, + "driver": "vfio-pci", + "host": bdf, + "addr": addr, + } + if bus != "" { + args["bus"] = bus + } + return q.executeCommand(ctx, "device_add", args, nil) +}