Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
virtcontainers/cli: refactor code
Browse files Browse the repository at this point in the history
Fixes #302

Signed-off-by: Nitesh Konkar [email protected]
  • Loading branch information
nitkon committed May 31, 2018
1 parent 9fb0b33 commit 4276c0c
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 137 deletions.
72 changes: 70 additions & 2 deletions cli/kata-check.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@

package main

/*
#include <linux/kvm.h>
const int ioctl_KVM_CREATE_VM = KVM_CREATE_VM;
*/
import "C"

import (
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"syscall"

vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -51,6 +59,11 @@ var (
modInfoCmd = "modinfo"
)

// variables rather than consts to allow tests to modify them
var (
kvmDevice = "/dev/kvm"
)

// getCPUInfo returns details of the first CPU read from the specified cpuinfo file
func getCPUInfo(cpuInfoFile string) (string, error) {
text, err := getFileContents(cpuInfoFile)
Expand Down Expand Up @@ -222,9 +235,9 @@ func checkKernelModules(modules map[string]kernelModule, handler kernelParamHand
return count, nil
}

// hostIsVMContainerCapable checks to see if the host is theoretically capable
// genericHostIsVMContainerCapable checks to see if the host is theoretically capable
// of creating a VM container.
func hostIsVMContainerCapable(details vmContainerCapableDetails) error {
func genericHostIsVMContainerCapable(details vmContainerCapableDetails) error {
cpuinfo, err := getCPUInfo(details.cpuInfoFile)
if err != nil {
return err
Expand Down Expand Up @@ -293,3 +306,58 @@ var kataCheckCLICommand = cli.Command{
return nil
},
}

func genericArchKernelParamHandler(onVMM bool, fields logrus.Fields, msg string) bool {
param, ok := fields["parameter"].(string)
if !ok {
return false
}

// This option is not required when
// already running under a hypervisor.
if param == "unrestricted_guest" && onVMM {
kataLog.WithFields(fields).Warn(kernelPropertyCorrect)
return true
}

if param == "nested" {
kataLog.WithFields(fields).Warn(msg)
return true
}

// don't ignore the error
return false
}

// genericKvmIsUsable determines if it will be possible to create a full virtual machine
// by creating a minimal VM and then deleting it.
func genericKvmIsUsable() error {
flags := syscall.O_RDWR | syscall.O_CLOEXEC

f, err := syscall.Open(kvmDevice, flags, 0)
if err != nil {
return err
}
defer syscall.Close(f)

fieldLogger := kataLog.WithField("check-type", "full")

fieldLogger.WithField("device", kvmDevice).Info("device available")

vm, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
uintptr(f),
uintptr(C.ioctl_KVM_CREATE_VM),
0)
if errno != 0 {
if errno == syscall.EBUSY {
fieldLogger.WithField("reason", "another hypervisor running").Error("cannot create VM")
}

return errno
}
defer syscall.Close(int(vm))

fieldLogger.WithField("feature", "create-vm").Info("feature available")

return nil
}
69 changes: 8 additions & 61 deletions cli/kata-check_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,10 @@

package main

/*
#include <linux/kvm.h>
const int ioctl_KVM_CREATE_VM = KVM_CREATE_VM;
*/
import "C"

import (
"syscall"

"github.com/sirupsen/logrus"
)

// variables rather than consts to allow tests to modify them
var (
kvmDevice = "/dev/kvm"
)

// archRequiredCPUFlags maps a CPU flag value to search for and a
// human-readable description of that value.
var archRequiredCPUFlags = map[string]string{
Expand Down Expand Up @@ -66,58 +52,19 @@ var archRequiredKernelModules = map[string]kernelModule{
// kvmIsUsable determines if it will be possible to create a full virtual machine
// by creating a minimal VM and then deleting it.
func kvmIsUsable() error {
flags := syscall.O_RDWR | syscall.O_CLOEXEC

f, err := syscall.Open(kvmDevice, flags, 0)
if err != nil {
return err
}
defer syscall.Close(f)

fieldLogger := kataLog.WithField("check-type", "full")

fieldLogger.WithField("device", kvmDevice).Info("device available")

vm, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
uintptr(f),
uintptr(C.ioctl_KVM_CREATE_VM),
0)
if errno != 0 {
if errno == syscall.EBUSY {
fieldLogger.WithField("reason", "another hypervisor running").Error("cannot create VM")
}

return errno
}
defer syscall.Close(int(vm))

fieldLogger.WithField("feature", "create-vm").Info("feature available")

return nil
return genericKvmIsUsable()
}

func archHostCanCreateVMContainer() error {
return kvmIsUsable()
}

func archKernelParamHandler(onVMM bool, fields logrus.Fields, msg string) bool {
param, ok := fields["parameter"].(string)
if !ok {
return false
}

// This option is not required when
// already running under a hypervisor.
if param == "unrestricted_guest" && onVMM {
kataLog.WithFields(fields).Warn(kernelPropertyCorrect)
return true
}

if param == "nested" {
kataLog.WithFields(fields).Warn(msg)
return true
}
// hostIsVMContainerCapable checks to see if the host is theoretically capable
// of creating a VM container.
func hostIsVMContainerCapable(details vmContainerCapableDetails) error {
return genericHostIsVMContainerCapable(details)
}

// don't ignore the error
return false
func archKernelParamHandler(onVMM bool, fields logrus.Fields, msg string) bool {
return genericArchKernelParamHandler(onVMM, fields, msg)
}
22 changes: 22 additions & 0 deletions cli/kata-check_arm64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) 2018 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//

package main

// kvmIsUsable determines if it will be possible to create a full virtual machine
// by creating a minimal VM and then deleting it.
func kvmIsUsable() error {
return genericKvmIsUsable()
}

func archHostCanCreateVMContainer() error {
return kvmIsUsable()
}

// hostIsVMContainerCapable checks to see if the host is theoretically capable
// of creating a VM container.
func hostIsVMContainerCapable(details vmContainerCapableDetails) error {
return genericHostIsVMContainerCapable(details)
}
78 changes: 78 additions & 0 deletions virtcontainers/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -926,3 +927,80 @@ func (q *qemu) addDevice(devInfo interface{}, devType deviceType) error {
func (q *qemu) getSandboxConsole(sandboxID string) (string, error) {
return utils.BuildSocketPath(runStoragePath, sandboxID, defaultConsole)
}

// genericAppendBridges appends to devices the given bridges
func genericAppendBridges(devices []govmmQemu.Device, bridges []Bridge, machineType string) []govmmQemu.Device {
bus := defaultPCBridgeBus
if machineType == QemuQ35 {
bus = defaultBridgeBus
}

for idx, b := range bridges {
t := govmmQemu.PCIBridge
if b.Type == pcieBridge {
t = govmmQemu.PCIEBridge
}

bridges[idx].Addr = bridgePCIStartAddr + idx

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,
Addr: strconv.FormatInt(int64(bridges[idx].Addr), 10),
},
)
}

return devices
}

func genericBridges(number uint32, machineType string) []Bridge {
var bridges []Bridge
var bt bridgeType

switch 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 genericMemoryTopology(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
}
Loading

0 comments on commit 4276c0c

Please sign in to comment.