From 052769196da1ac4ed5f102b0832b0548b4e1ed0f Mon Sep 17 00:00:00 2001 From: Julio Montes Date: Wed, 25 Jul 2018 09:04:29 -0500 Subject: [PATCH] virtcontainers: implement function to cold plug vsocks `appendVSockPCI` function can be used to cold plug vocks, vhost file descriptor holds the context ID and it's inherit by QEMU process, ID must be unique and disable-modern prevents qemu from relying on fast MMIO. Signed-off-by: Julio Montes --- virtcontainers/qemu.go | 15 +++++++++++++++ virtcontainers/qemu_arch_base.go | 17 +++++++++++++++++ virtcontainers/qemu_test.go | 22 ++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index 1d84fa88d..143a5922c 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -62,6 +62,10 @@ type qemu struct { state QemuState arch qemuArch + + // fds is a list of file descriptors inherited by QEMU process + // they'll be closed once QEMU process is running + fds []*os.File } const ( @@ -497,6 +501,14 @@ func (q *qemu) startSandbox() error { q.Logger().WithField("default-kernel-parameters", formatted).Debug() } + defer func() { + for _, fd := range q.fds { + if err := fd.Close(); err != nil { + q.Logger().WithError(err).Error("After launching Qemu") + } + } + }() + strErr, err := govmmQemu.LaunchQemu(q.qemuConfig, newQMPLogger()) if err != nil { return fmt.Errorf("%s", strErr) @@ -956,6 +968,9 @@ func (q *qemu) addDevice(devInfo interface{}, devType deviceType) error { q.qemuConfig.Devices = q.arch.append9PVolume(q.qemuConfig.Devices, v) case Socket: q.qemuConfig.Devices = q.arch.appendSocket(q.qemuConfig.Devices, v) + case kataVSOCK: + q.fds = append(q.fds, v.vhostFd) + q.qemuConfig.Devices = q.arch.appendVSockPCI(q.qemuConfig.Devices, v) case Endpoint: q.qemuConfig.Devices = q.arch.appendNetwork(q.qemuConfig.Devices, v) case deviceDrivers.Drive: diff --git a/virtcontainers/qemu_arch_base.go b/virtcontainers/qemu_arch_base.go index e0188c4d3..730023e7f 100644 --- a/virtcontainers/qemu_arch_base.go +++ b/virtcontainers/qemu_arch_base.go @@ -68,6 +68,9 @@ type qemuArch interface { // appendSocket appends a socket to devices appendSocket(devices []govmmQemu.Device, socket Socket) []govmmQemu.Device + // appendVSockPCI appends a vsock PCI to devices + appendVSockPCI(devices []govmmQemu.Device, vsock kataVSOCK) []govmmQemu.Device + // appendNetwork appends a endpoint device to devices appendNetwork(devices []govmmQemu.Device, endpoint Endpoint) []govmmQemu.Device @@ -389,6 +392,20 @@ func (q *qemuArchBase) appendSocket(devices []govmmQemu.Device, socket Socket) [ return devices } +func (q *qemuArchBase) appendVSockPCI(devices []govmmQemu.Device, vsock kataVSOCK) []govmmQemu.Device { + devices = append(devices, + govmmQemu.VSOCKDevice{ + ID: fmt.Sprintf("vsock-%d", vsock.contextID), + ContextID: vsock.contextID, + VHostFD: vsock.vhostFd, + DisableModern: q.nestedRun, + }, + ) + + return devices + +} + func networkModelToQemuType(model NetInterworkingModel) govmmQemu.NetDeviceType { switch model { case NetXConnectBridgedModel: diff --git a/virtcontainers/qemu_test.go b/virtcontainers/qemu_test.go index 55b443ea7..2d6d82155 100644 --- a/virtcontainers/qemu_test.go +++ b/virtcontainers/qemu_test.go @@ -246,6 +246,28 @@ func TestQemuAddDeviceSerialPortDev(t *testing.T) { testQemuAddDevice(t, socket, serialPortDev, expectedOut) } +func TestQemuAddDeviceKataVSOCK(t *testing.T) { + contextID := uint32(3) + port := uint32(1024) + vHostFD := os.NewFile(1, "vsock") + + expectedOut := []govmmQemu.Device{ + govmmQemu.VSOCKDevice{ + ID: fmt.Sprintf("vsock-%d", contextID), + ContextID: contextID, + VHostFD: vHostFD, + }, + } + + vsock := kataVSOCK{ + contextID: contextID, + port: port, + vhostFd: vHostFD, + } + + testQemuAddDevice(t, vsock, vSockPCIDev, expectedOut) +} + func TestQemuGetSandboxConsole(t *testing.T) { q := &qemu{} sandboxID := "testSandboxID"