Files
kata-containers/cli/kata-check_ppc64le.go
Nitesh Konkar 11e24aa42d kata-runtime: Return correct kata-env on ppc64le
The contents of /proc/cpuinfo were
trimmed and hence the "model" field could
not be parsed despite being a field in
/proc/cpuinfo. Fix this issue.

Fixes: #1089

Signed-off-by: Nitesh Konkar niteshkonkar@in.ibm.com
2019-01-09 15:18:09 +05:30

175 lines
3.9 KiB
Go

// Copyright (c) 2018 IBM
//
// SPDX-License-Identifier: Apache-2.0
//
package main
import (
"fmt"
"os/exec"
"strings"
"github.com/kata-containers/runtime/pkg/katautils"
"github.com/sirupsen/logrus"
)
const (
cpuFlagsTag = genericCPUFlagsTag
archCPUVendorField = ""
archCPUModelField = "model"
)
var (
ppc64CpuCmd = "ppc64_cpu"
smtStatusOption = "--smt"
_ = genericCPUVendorField
_ = genericCPUModelField
)
// archRequiredCPUFlags maps a CPU flag value to search for and a
// human-readable description of that value.
var archRequiredCPUFlags = map[string]string{}
// archRequiredCPUAttribs maps a CPU (non-CPU flag) attribute value to search for
// and a human-readable description of that value.
var archRequiredCPUAttribs = map[string]string{}
// archRequiredKernelModules maps a required module name to a human-readable
// description of the modules functionality and an optional list of
// required module parameters.
var archRequiredKernelModules = map[string]kernelModule{
"kvm": {
desc: "Kernel-based Virtual Machine",
},
"kvm_hv": {
desc: "Kernel-based Virtual Machine hardware virtualization",
},
}
func setCPUtype() error {
return nil
}
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 {
_, err := getCPUInfo(details.cpuInfoFile)
if err != nil {
return err
}
text, err := katautils.GetFileContents(details.cpuInfoFile)
if err != nil {
return err
}
if strings.Contains(text, "POWER8") {
if !isSMTOff() {
return fmt.Errorf("SMT is not Off. %s", failMessage)
}
}
count, err := checkKernelModules(details.requiredKernelModules, archKernelParamHandler)
if err != nil {
return err
}
if count == 0 {
return nil
}
return fmt.Errorf("ERROR: %s", failMessage)
}
// 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 archKernelParamHandler(onVMM bool, fields logrus.Fields, msg string) bool {
return genericArchKernelParamHandler(onVMM, fields, msg)
}
func getPPC64leCPUInfo(cpuInfoFile string) (string, error) {
text, err := katautils.GetFileContents(cpuInfoFile)
if err != nil {
return "", err
}
if len(strings.TrimSpace(text)) == 0 {
return "", fmt.Errorf("Cannot determine CPU details")
}
return text, nil
}
func getCPUDetails() (vendor, model string, err error) {
if vendor, model, err := genericGetCPUDetails(); err == nil {
return vendor, model, nil
}
cpuinfo, err := getPPC64leCPUInfo(procCPUInfo)
if err != nil {
return "", "", err
}
lines := strings.Split(cpuinfo, "\n")
for _, line := range lines {
if archCPUVendorField != "" {
if strings.HasPrefix(line, archCPUVendorField) {
fields := strings.Split(line, ":")
if len(fields) > 1 {
vendor = strings.TrimSpace(fields[1])
}
}
}
if archCPUModelField != "" {
if strings.HasPrefix(line, archCPUModelField) {
fields := strings.Split(line, ":")
if len(fields) > 1 {
model = strings.TrimSpace(fields[1])
}
}
}
}
if archCPUVendorField != "" && vendor == "" {
return "", "", fmt.Errorf("cannot find vendor field in file %v", procCPUInfo)
}
if archCPUModelField != "" && model == "" {
return "", "", fmt.Errorf("cannot find model field in file %v", procCPUInfo)
}
return vendor, model, nil
}
func isSMTOff() bool {
// Check if the SMT is available and off
cmd := exec.Command(ppc64CpuCmd, smtStatusOption)
additionalEnv := "LANG=C"
cmd.Env = append(cmd.Env, additionalEnv)
out, err := cmd.Output()
if err == nil && strings.TrimRight(string(out), "\n") == "SMT is off" {
return true
} else if err != nil {
kataLog.Warn("ppc64_cpu isn't installed, can't detect SMT")
return true
}
return false
}