Files
kata-containers/virtcontainers/qemu_amd64.go
Samuel Ortiz 24eff72d82 virtcontainers: Initial import
This is a virtcontainers 1.0.8 import into Kata Containers runtime.

virtcontainers is a Go library designed to manage hardware virtualized
pods and containers. It is the core Clear Containers framework and will
become the core Kata Containers framework, as discussed at
https://github.com/kata-containers/runtime/issues/33

Some more more pointers:

virtcontainers README, including some design and architecure notes:
https://github.com/containers/virtcontainers/blob/master/README.md

virtcontainers 1.0 API:
https://github.com/containers/virtcontainers/blob/master/documentation/api/1.0/api.md

Fixes #40

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
2018-03-13 00:49:46 +01:00

220 lines
4.8 KiB
Go

//
// Copyright (c) 2018 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package virtcontainers
import (
"fmt"
"os"
govmmQemu "github.com/intel/govmm/qemu"
)
type qemuAmd64 struct {
// inherit from qemuArchBase, overwrite methods if needed
qemuArchBase
}
const defaultQemuPath = "/usr/bin/qemu-system-x86_64"
const defaultQemuMachineType = QemuPC
const defaultQemuMachineOptions = "accel=kvm,kernel_irqchip,nvdimm"
const defaultPCBridgeBus = "pci.0"
var qemuPaths = map[string]string{
QemuPCLite: "/usr/bin/qemu-lite-system-x86_64",
QemuPC: defaultQemuPath,
QemuQ35: defaultQemuPath,
}
var kernelParams = []Param{
{"root", "/dev/pmem0p1"},
{"rootflags", "dax,data=ordered,errors=remount-ro rw"},
{"rootfstype", "ext4"},
{"tsc", "reliable"},
{"no_timer_check", ""},
{"rcupdate.rcu_expedited", "1"},
{"i8042.direct", "1"},
{"i8042.dumbkbd", "1"},
{"i8042.nopnp", "1"},
{"i8042.noaux", "1"},
{"noreplace-smp", ""},
{"reboot", "k"},
{"console", "hvc0"},
{"console", "hvc1"},
{"iommu", "off"},
{"cryptomgr.notests", ""},
{"net.ifnames", "0"},
{"pci", "lastbus=0"},
}
var supportedQemuMachines = []govmmQemu.Machine{
{
Type: QemuPCLite,
Options: defaultQemuMachineOptions,
},
{
Type: QemuPC,
Options: defaultQemuMachineOptions,
},
{
Type: QemuQ35,
Options: defaultQemuMachineOptions,
},
}
// returns the maximum number of vCPUs supported
func maxQemuVCPUs() uint32 {
return uint32(240)
}
func newQemuArch(machineType string) qemuArch {
if machineType == "" {
machineType = defaultQemuMachineType
}
return &qemuAmd64{
qemuArchBase{
machineType: machineType,
qemuPaths: qemuPaths,
supportedQemuMachines: supportedQemuMachines,
kernelParamsNonDebug: kernelParamsNonDebug,
kernelParamsDebug: kernelParamsDebug,
kernelParams: kernelParams,
},
}
}
func (q *qemuAmd64) capabilities() capabilities {
var caps capabilities
// Only pc machine type supports hotplugging drives
if q.machineType == QemuPC {
caps.setBlockDeviceHotplugSupport()
}
return caps
}
func (q *qemuAmd64) bridges(number uint32) []Bridge {
var bridges []Bridge
var bt bridgeType
switch q.machineType {
case QemuQ35:
// currently only pci bridges are supported
// qemu-2.10 will introduce pcie bridges
fallthrough
case QemuPC:
bt = pciBridge
default:
return nil
}
for i := uint32(0); i < number; i++ {
bridges = append(bridges, Bridge{
Type: bt,
ID: fmt.Sprintf("%s-bridge-%d", bt, i),
Address: make(map[uint32]string),
})
}
return bridges
}
func (q *qemuAmd64) cpuModel() string {
cpuModel := defaultCPUModel
if q.nestedRun {
cpuModel += ",pmu=off"
}
return cpuModel
}
func (q *qemuAmd64) memoryTopology(memoryMb, hostMemoryMb uint64) govmmQemu.Memory {
// NVDIMM device needs memory space 1024MB
// See https://github.com/clearcontainers/runtime/issues/380
memoryOffset := 1024
// add 1G memory space for nvdimm device (vm guest image)
memMax := fmt.Sprintf("%dM", hostMemoryMb+uint64(memoryOffset))
mem := fmt.Sprintf("%dM", memoryMb)
memory := govmmQemu.Memory{
Size: mem,
Slots: defaultMemSlots,
MaxMem: memMax,
}
return memory
}
func (q *qemuAmd64) appendImage(devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) {
imageFile, err := os.Open(path)
if err != nil {
return nil, err
}
defer func() { _ = imageFile.Close() }()
imageStat, err := imageFile.Stat()
if err != nil {
return nil, err
}
object := govmmQemu.Object{
Driver: govmmQemu.NVDIMM,
Type: govmmQemu.MemoryBackendFile,
DeviceID: "nv0",
ID: "mem0",
MemPath: path,
Size: (uint64)(imageStat.Size()),
}
devices = append(devices, object)
return devices, nil
}
// appendBridges appends to devices the given bridges
func (q *qemuAmd64) appendBridges(devices []govmmQemu.Device, bridges []Bridge) []govmmQemu.Device {
bus := defaultPCBridgeBus
if q.machineType == QemuQ35 {
bus = defaultBridgeBus
}
for idx, b := range bridges {
t := govmmQemu.PCIBridge
if b.Type == pcieBridge {
t = govmmQemu.PCIEBridge
}
devices = append(devices,
govmmQemu.BridgeDevice{
Type: t,
Bus: bus,
ID: b.ID,
// Each bridge is required to be assigned a unique chassis id > 0
Chassis: (idx + 1),
SHPC: true,
},
)
}
return devices
}