Skip to content
This repository has been archived by the owner on Apr 3, 2018. It is now read-only.

Commit

Permalink
qemu: Enable specific flags if running on VMM
Browse files Browse the repository at this point in the history
In case our Qemu process runs on a VMM, that is as a nested VM, we
want to add flags "disable-modern=true" and "pmu=off" in order to
disable virtio 1.0 and the power management unit.
That's the only way we have found to prevent our Clear Containers
VM from hanging because of the KVM known bugs.

Notice this patch enables "disable-modern=true" only if the device
is driven by a virtio driver.

Fixes #342

Signed-off-by: Sebastien Boeuf <[email protected]>
  • Loading branch information
Sebastien Boeuf committed Aug 17, 2017
1 parent f7be1c0 commit e99f6b2
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 36 deletions.
54 changes: 37 additions & 17 deletions qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ type qemu struct {
qmpControlCh qmpChannel

qemuConfig ciaoQemu.Config

nestedRun bool
}

const defaultQemuPath = "/usr/bin/qemu-system-x86_64"
Expand Down Expand Up @@ -206,6 +208,7 @@ func (q *qemu) appendVolume(devices []ciaoQemu.Device, volume Volume) []ciaoQemu
Path: volume.HostPath,
MountTag: volume.MountTag,
SecurityModel: ciaoQemu.None,
DisableModern: q.nestedRun,
},
)

Expand All @@ -223,12 +226,13 @@ func (q *qemu) appendBlockDevice(devices []ciaoQemu.Device, drive Drive) []ciaoQ

devices = append(devices,
ciaoQemu.BlockDevice{
Driver: ciaoQemu.VirtioBlock,
ID: drive.ID,
File: drive.File,
AIO: ciaoQemu.Threads,
Format: ciaoQemu.BlockDeviceFormat(drive.Format),
Interface: "none",
Driver: ciaoQemu.VirtioBlock,
ID: drive.ID,
File: drive.File,
AIO: ciaoQemu.Threads,
Format: ciaoQemu.BlockDeviceFormat(drive.Format),
Interface: "none",
DisableModern: q.nestedRun,
},
)

Expand Down Expand Up @@ -259,14 +263,15 @@ func (q *qemu) appendNetworks(devices []ciaoQemu.Device, endpoints []Endpoint) [
for idx, endpoint := range endpoints {
devices = append(devices,
ciaoQemu.NetDevice{
Type: ciaoQemu.TAP,
Driver: ciaoQemu.VirtioNetPCI,
ID: fmt.Sprintf("network-%d", idx),
IFName: endpoint.NetPair.TAPIface.Name,
MACAddress: endpoint.NetPair.TAPIface.HardAddr,
DownScript: "no",
Script: "no",
VHost: true,
Type: ciaoQemu.TAP,
Driver: ciaoQemu.VirtioNetPCI,
ID: fmt.Sprintf("network-%d", idx),
IFName: endpoint.NetPair.TAPIface.Name,
MACAddress: endpoint.NetPair.TAPIface.HardAddr,
DownScript: "no",
Script: "no",
VHost: true,
DisableModern: q.nestedRun,
},
)
}
Expand All @@ -289,6 +294,7 @@ func (q *qemu) appendFSDevices(devices []ciaoQemu.Device, podConfig PodConfig) [
Path: c.RootFs,
MountTag: fmt.Sprintf("ctr-rootfs-%d", idx),
SecurityModel: ciaoQemu.None,
DisableModern: q.nestedRun,
},
)
}
Expand All @@ -303,8 +309,9 @@ func (q *qemu) appendFSDevices(devices []ciaoQemu.Device, podConfig PodConfig) [

func (q *qemu) appendConsoles(devices []ciaoQemu.Device, podConfig PodConfig) []ciaoQemu.Device {
serial := ciaoQemu.SerialDevice{
Driver: ciaoQemu.VirtioSerial,
ID: "serial0",
Driver: ciaoQemu.VirtioSerial,
ID: "serial0",
DisableModern: q.nestedRun,
}

devices = append(devices, serial)
Expand Down Expand Up @@ -425,6 +432,14 @@ func (q *qemu) init(config HypervisorConfig) error {
return err
}

nested, err := RunningOnVMM(procCPUInfo)
if err != nil {
return err
}

virtLog.Info("Running inside a VM = %t", nested)
q.nestedRun = nested

return nil
}

Expand Down Expand Up @@ -569,6 +584,11 @@ func (q *qemu) createPod(podConfig PodConfig) error {
return err
}

cpuModel := "host"
if q.nestedRun {
cpuModel += ",pmu=off"
}

qemuConfig := ciaoQemu.Config{
Name: fmt.Sprintf("pod-%s", podConfig.ID),
UUID: q.forceUUIDFormat(podConfig.ID),
Expand All @@ -578,7 +598,7 @@ func (q *qemu) createPod(podConfig PodConfig) error {
SMP: smp,
Memory: memory,
Devices: devices,
CPUModel: "host",
CPUModel: cpuModel,
Kernel: kernel,
RTC: rtc,
QMPSockets: qmpSockets,
Expand Down
57 changes: 38 additions & 19 deletions qemu_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ func TestQemuBuildKernelParamsFoo(t *testing.T) {
}
}

func testQemuAppend(t *testing.T, structure interface{}, expected []ciaoQemu.Device, devType deviceType) {
func testQemuAppend(t *testing.T, structure interface{}, expected []ciaoQemu.Device, devType deviceType, nestedVM bool) {
var devices []ciaoQemu.Device
q := &qemu{}
q := &qemu{
nestedRun: nestedVM,
}

switch s := structure.(type) {
case Volume:
Expand All @@ -126,6 +128,7 @@ func testQemuAppend(t *testing.T, structure interface{}, expected []ciaoQemu.Dev
func TestQemuAppendVolume(t *testing.T) {
mountTag := "testMountTag"
hostPath := "testHostPath"
nestedVM := true

expectedOut := []ciaoQemu.Device{
ciaoQemu.FSDevice{
Expand All @@ -135,6 +138,7 @@ func TestQemuAppendVolume(t *testing.T) {
Path: hostPath,
MountTag: mountTag,
SecurityModel: ciaoQemu.None,
DisableModern: nestedVM,
},
}

Expand All @@ -143,14 +147,15 @@ func TestQemuAppendVolume(t *testing.T) {
HostPath: hostPath,
}

testQemuAppend(t, volume, expectedOut, -1)
testQemuAppend(t, volume, expectedOut, -1, nestedVM)
}

func TestQemuAppendSocket(t *testing.T) {
deviceID := "channelTest"
id := "charchTest"
hostPath := "/tmp/hyper_test.sock"
name := "sh.hyper.channel.test"
nestedVM := true

expectedOut := []ciaoQemu.Device{
ciaoQemu.CharDevice{
Expand All @@ -170,22 +175,24 @@ func TestQemuAppendSocket(t *testing.T) {
Name: name,
}

testQemuAppend(t, socket, expectedOut, -1)
testQemuAppend(t, socket, expectedOut, -1, nestedVM)
}

func TestQemuAppendBlockDevice(t *testing.T) {
id := "blockDevTest"
file := "/root"
format := "raw"
nestedVM := true

expectedOut := []ciaoQemu.Device{
ciaoQemu.BlockDevice{
Driver: ciaoQemu.VirtioBlock,
ID: id,
File: "/root",
AIO: ciaoQemu.Threads,
Format: ciaoQemu.BlockDeviceFormat(format),
Interface: "none",
Driver: ciaoQemu.VirtioBlock,
ID: id,
File: "/root",
AIO: ciaoQemu.Threads,
Format: ciaoQemu.BlockDeviceFormat(format),
Interface: "none",
DisableModern: nestedVM,
},
}

Expand All @@ -195,7 +202,7 @@ func TestQemuAppendBlockDevice(t *testing.T) {
ID: id,
}

testQemuAppend(t, drive, expectedOut, -1)
testQemuAppend(t, drive, expectedOut, -1, nestedVM)
}

func TestQemuAppendFSDevices(t *testing.T) {
Expand All @@ -204,6 +211,7 @@ func TestQemuAppendFSDevices(t *testing.T) {
contRootFs := "testContRootFs"
volMountTag := "testVolMountTag"
volHostPath := "testVolHostPath"
nestedVM := true

expectedOut := []ciaoQemu.Device{
ciaoQemu.FSDevice{
Expand All @@ -213,6 +221,7 @@ func TestQemuAppendFSDevices(t *testing.T) {
Path: fmt.Sprintf("%s.1", contRootFs),
MountTag: "ctr-rootfs-0",
SecurityModel: ciaoQemu.None,
DisableModern: nestedVM,
},
ciaoQemu.FSDevice{
Driver: ciaoQemu.Virtio9P,
Expand All @@ -221,6 +230,7 @@ func TestQemuAppendFSDevices(t *testing.T) {
Path: fmt.Sprintf("%s.2", contRootFs),
MountTag: "ctr-rootfs-1",
SecurityModel: ciaoQemu.None,
DisableModern: nestedVM,
},
ciaoQemu.FSDevice{
Driver: ciaoQemu.Virtio9P,
Expand All @@ -229,6 +239,7 @@ func TestQemuAppendFSDevices(t *testing.T) {
Path: fmt.Sprintf("%s.1", volHostPath),
MountTag: fmt.Sprintf("%s.1", volMountTag),
SecurityModel: ciaoQemu.None,
DisableModern: nestedVM,
},
ciaoQemu.FSDevice{
Driver: ciaoQemu.Virtio9P,
Expand All @@ -237,6 +248,7 @@ func TestQemuAppendFSDevices(t *testing.T) {
Path: fmt.Sprintf("%s.2", volHostPath),
MountTag: fmt.Sprintf("%s.2", volMountTag),
SecurityModel: ciaoQemu.None,
DisableModern: nestedVM,
},
}

Expand Down Expand Up @@ -268,16 +280,18 @@ func TestQemuAppendFSDevices(t *testing.T) {
Containers: containers,
}

testQemuAppend(t, podConfig, expectedOut, fsDev)
testQemuAppend(t, podConfig, expectedOut, fsDev, nestedVM)
}

func TestQemuAppendConsoles(t *testing.T) {
podID := "testPodID"
nestedVM := true

expectedOut := []ciaoQemu.Device{
ciaoQemu.SerialDevice{
Driver: ciaoQemu.VirtioSerial,
ID: "serial0",
Driver: ciaoQemu.VirtioSerial,
ID: "serial0",
DisableModern: nestedVM,
},
ciaoQemu.CharDevice{
Driver: ciaoQemu.Console,
Expand All @@ -293,7 +307,7 @@ func TestQemuAppendConsoles(t *testing.T) {
Containers: []ContainerConfig{},
}

testQemuAppend(t, podConfig, expectedOut, consoleDev)
testQemuAppend(t, podConfig, expectedOut, consoleDev, nestedVM)
}

func TestQemuAppendImage(t *testing.T) {
Expand Down Expand Up @@ -425,8 +439,10 @@ func TestQemuSetMemoryResources(t *testing.T) {
}
}

func testQemuAddDevice(t *testing.T, devInfo interface{}, devType deviceType, expected []ciaoQemu.Device) {
q := &qemu{}
func testQemuAddDevice(t *testing.T, devInfo interface{}, devType deviceType, expected []ciaoQemu.Device, nestedVM bool) {
q := &qemu{
nestedRun: nestedVM,
}

err := q.addDevice(devInfo, devType)
if err != nil {
Expand All @@ -441,6 +457,7 @@ func testQemuAddDevice(t *testing.T, devInfo interface{}, devType deviceType, ex
func TestQemuAddDeviceFsDev(t *testing.T) {
mountTag := "testMountTag"
hostPath := "testHostPath"
nestedVM := true

expectedOut := []ciaoQemu.Device{
ciaoQemu.FSDevice{
Expand All @@ -450,6 +467,7 @@ func TestQemuAddDeviceFsDev(t *testing.T) {
Path: hostPath,
MountTag: mountTag,
SecurityModel: ciaoQemu.None,
DisableModern: nestedVM,
},
}

Expand All @@ -458,14 +476,15 @@ func TestQemuAddDeviceFsDev(t *testing.T) {
HostPath: hostPath,
}

testQemuAddDevice(t, volume, fsDev, expectedOut)
testQemuAddDevice(t, volume, fsDev, expectedOut, nestedVM)
}

func TestQemuAddDeviceSerialPordDev(t *testing.T) {
deviceID := "channelTest"
id := "charchTest"
hostPath := "/tmp/hyper_test.sock"
name := "sh.hyper.channel.test"
nestedVM := true

expectedOut := []ciaoQemu.Device{
ciaoQemu.CharDevice{
Expand All @@ -485,7 +504,7 @@ func TestQemuAddDeviceSerialPordDev(t *testing.T) {
Name: name,
}

testQemuAddDevice(t, socket, serialPortDev, expectedOut)
testQemuAddDevice(t, socket, serialPortDev, expectedOut, nestedVM)
}

func TestQemuGetPodConsole(t *testing.T) {
Expand Down

0 comments on commit e99f6b2

Please sign in to comment.