mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-30 09:13:29 +00:00
Hypervisor: UUID fix for acrn hypevisor
This patch adds support for getting the kata UUID from acrn hypervisor and using these UUID to create a VM. Fixes: #1785 Signed-off-by: Vijay Dhanraj <vijay.dhanraj@intel.com>
This commit is contained in:
parent
d3f480dc4c
commit
aa6a16c597
@ -6,6 +6,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
@ -13,6 +14,7 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
vc "github.com/kata-containers/runtime/virtcontainers"
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
||||||
|
"github.com/kata-containers/runtime/virtcontainers/store"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -231,27 +233,36 @@ func acrnIsUsable() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer syscall.Close(f)
|
defer syscall.Close(f)
|
||||||
|
kataLog.WithField("device", acrnDevice).Info("device available")
|
||||||
|
|
||||||
fieldLogger := kataLog.WithField("check-type", "full")
|
acrnInst := vc.Acrn{}
|
||||||
|
vcStore, err := store.NewVCSandboxStore(context.Background(), "kata-check")
|
||||||
fieldLogger.WithField("device", acrnDevice).Info("device available")
|
if err != nil {
|
||||||
|
return err
|
||||||
createVM := acrn_create_vm{
|
|
||||||
uuid: [16]uint8{
|
|
||||||
0xd2, 0x79, 0x54, 0x38, 0x25, 0xd6, 0x11, 0xe8,
|
|
||||||
0x86, 0x4e, 0xcb, 0x7a, 0x18, 0xb3, 0x46, 0x43,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uuidStr, err := acrnInst.GetNextAvailableUUID(vcStore)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
uuid, err := acrnInst.GetACRNUUIDBytes(uuidStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Converting UUID str to bytes failed, Err:%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var createVM acrn_create_vm
|
||||||
|
createVM.uuid = uuid
|
||||||
|
|
||||||
ret, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
|
ret, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
|
||||||
uintptr(f),
|
uintptr(f),
|
||||||
uintptr(ioctl_ACRN_CREATE_VM),
|
uintptr(ioctl_ACRN_CREATE_VM),
|
||||||
uintptr(unsafe.Pointer(&createVM)))
|
uintptr(unsafe.Pointer(&createVM)))
|
||||||
if ret != 0 || errno != 0 {
|
if ret != 0 || errno != 0 {
|
||||||
if errno == syscall.EBUSY {
|
if errno == syscall.EBUSY {
|
||||||
fieldLogger.WithField("reason", "another hypervisor running").Error("cannot create VM")
|
kataLog.WithField("reason", "another hypervisor running").Error("cannot create VM")
|
||||||
}
|
}
|
||||||
fieldLogger.WithFields(logrus.Fields{
|
kataLog.WithFields(logrus.Fields{
|
||||||
"ret": ret,
|
"ret": ret,
|
||||||
"errno": errno,
|
"errno": errno,
|
||||||
}).Info("Create VM Error")
|
}).Info("Create VM Error")
|
||||||
@ -263,14 +274,14 @@ func acrnIsUsable() error {
|
|||||||
uintptr(ioctl_ACRN_DESTROY_VM),
|
uintptr(ioctl_ACRN_DESTROY_VM),
|
||||||
0)
|
0)
|
||||||
if ret != 0 || errno != 0 {
|
if ret != 0 || errno != 0 {
|
||||||
fieldLogger.WithFields(logrus.Fields{
|
kataLog.WithFields(logrus.Fields{
|
||||||
"ret": ret,
|
"ret": ret,
|
||||||
"errno": errno,
|
"errno": errno,
|
||||||
}).Info("Destroy VM Error")
|
}).Info("Destroy VM Error")
|
||||||
return errno
|
return errno
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldLogger.WithField("feature", "create-vm").Info("feature available")
|
kataLog.WithField("feature", "create-vm").Info("feature available")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
opentracing "github.com/opentracing/opentracing-go"
|
opentracing "github.com/opentracing/opentracing-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -21,25 +22,57 @@ import (
|
|||||||
|
|
||||||
"github.com/kata-containers/runtime/virtcontainers/device/config"
|
"github.com/kata-containers/runtime/virtcontainers/device/config"
|
||||||
persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api"
|
persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api"
|
||||||
|
"github.com/kata-containers/runtime/virtcontainers/pkg/uuid"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/store"
|
"github.com/kata-containers/runtime/virtcontainers/store"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/types"
|
"github.com/kata-containers/runtime/virtcontainers/types"
|
||||||
"github.com/kata-containers/runtime/virtcontainers/utils"
|
"github.com/kata-containers/runtime/virtcontainers/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AcrnState keeps Acrn's state
|
// ACRN currently supports only known UUIDs for security
|
||||||
|
// reasons (FuSa). When launching VM, only these pre-defined
|
||||||
|
// UUID should be used else VM launch will fail. The main
|
||||||
|
// of purpose UUID is is not used for image identification
|
||||||
|
// but generating vSeed (virtual seed which takes UUID
|
||||||
|
// as one of the parameter) which is used during VM boot.
|
||||||
|
|
||||||
|
// acrnUUIDsToIdx lists Idx corresponding to the UUID
|
||||||
|
var acrnUUIDsToIdx = map[string]uint8{
|
||||||
|
"a7ada506-1ab0-4b6b-a0da-e513ca9b8c2f": 0,
|
||||||
|
"dbeae168-26e4-4084-9227-622193e56325": 1,
|
||||||
|
"18ed60cd-e9ea-4bf4-8f87-8523fc8347a3": 2,
|
||||||
|
"3f90b6f8-449a-4e72-b99c-063a889fc422": 3,
|
||||||
|
"1ae8587b-e599-4b59-8260-6d14ac166a55": 4,
|
||||||
|
"75f3b94b-49ed-48fc-b019-577ef45adf2b": 5,
|
||||||
|
"ca62cf3c-8359-47e8-a3f7-de2d682dfb02": 6,
|
||||||
|
"e3189497-c3f6-4b97-9e2c-18ac0ab9064d": 7,
|
||||||
|
}
|
||||||
|
|
||||||
|
// acrnIdxToUUIDs lists UUIDs corresponding to the Idx
|
||||||
|
var acrnIdxToUUIDs = map[uint8]string{
|
||||||
|
0: "a7ada506-1ab0-4b6b-a0da-e513ca9b8c2f",
|
||||||
|
1: "dbeae168-26e4-4084-9227-622193e56325",
|
||||||
|
2: "18ed60cd-e9ea-4bf4-8f87-8523fc8347a3",
|
||||||
|
3: "3f90b6f8-449a-4e72-b99c-063a889fc422",
|
||||||
|
4: "1ae8587b-e599-4b59-8260-6d14ac166a55",
|
||||||
|
5: "75f3b94b-49ed-48fc-b019-577ef45adf2b",
|
||||||
|
6: "ca62cf3c-8359-47e8-a3f7-de2d682dfb02",
|
||||||
|
7: "e3189497-c3f6-4b97-9e2c-18ac0ab9064d",
|
||||||
|
}
|
||||||
|
|
||||||
|
// AcrnInfo keeps track of UUID availability
|
||||||
|
type AcrnInfo struct {
|
||||||
|
UUIDAvailability [8]uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// AcrnState keeps track of VM UUID, PID.
|
||||||
type AcrnState struct {
|
type AcrnState struct {
|
||||||
UUID string
|
UUID string
|
||||||
|
PID int
|
||||||
}
|
}
|
||||||
|
|
||||||
// AcrnInfo keeps PID of the hypervisor
|
// Acrn is an Hypervisor interface implementation for the Linux acrn hypervisor.
|
||||||
type AcrnInfo struct {
|
type Acrn struct {
|
||||||
PID int
|
id string
|
||||||
}
|
|
||||||
|
|
||||||
// acrn is an Hypervisor interface implementation for the Linux acrn hypervisor.
|
|
||||||
type acrn struct {
|
|
||||||
id string
|
|
||||||
|
|
||||||
store *store.VCStore
|
store *store.VCStore
|
||||||
config HypervisorConfig
|
config HypervisorConfig
|
||||||
acrnConfig Config
|
acrnConfig Config
|
||||||
@ -49,17 +82,41 @@ type acrn struct {
|
|||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type acrnPlatformInfo struct {
|
||||||
|
cpuNum uint16 //nolint
|
||||||
|
reserved0 [126]uint8 //nolint
|
||||||
|
maxVCPUsPerVM uint16 //nolint
|
||||||
|
maxKataContainers uint8
|
||||||
|
reserved1 [125]uint8 //nolint
|
||||||
|
}
|
||||||
|
|
||||||
|
const acrnDevice = "/dev/acrn_vhm"
|
||||||
|
|
||||||
|
// ioctl_ACRN_CREATE_VM is the IOCTL to create VM in ACRN.
|
||||||
|
// Current Linux mainstream kernel doesn't have support for ACRN.
|
||||||
|
// Due to this several macros are not defined in Linux headers.
|
||||||
|
// Until the support is available, directly use the value instead
|
||||||
|
// of macros.
|
||||||
|
//https://github.com/kata-containers/runtime/issues/1784
|
||||||
|
const ioctl_ACRN_GET_PLATFORM_INFO = 0x43000003 //nolint
|
||||||
|
|
||||||
const (
|
const (
|
||||||
acrnConsoleSocket = "console.sock"
|
acrnConsoleSocket = "console.sock"
|
||||||
acrnStopSandboxTimeoutSecs = 15
|
acrnStopSandboxTimeoutSecs = 15
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//UUIDBusy marks a particular UUID as busy
|
||||||
|
const UUIDBusy = 1
|
||||||
|
|
||||||
|
//UUIDFree marks a particular UUID as free
|
||||||
|
const UUIDFree = 0
|
||||||
|
|
||||||
// agnostic list of kernel parameters
|
// agnostic list of kernel parameters
|
||||||
var acrnDefaultKernelParameters = []Param{
|
var acrnDefaultKernelParameters = []Param{
|
||||||
{"panic", "1"},
|
{"panic", "1"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) kernelParameters() string {
|
func (a *Acrn) kernelParameters() string {
|
||||||
// get a list of arch kernel parameters
|
// get a list of arch kernel parameters
|
||||||
params := a.arch.kernelParameters(a.config.Debug)
|
params := a.arch.kernelParameters(a.config.Debug)
|
||||||
|
|
||||||
@ -79,20 +136,20 @@ func (a *acrn) kernelParameters() string {
|
|||||||
return strings.Join(paramsStr, " ")
|
return strings.Join(paramsStr, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds all capabilities supported by acrn implementation of hypervisor interface
|
// Adds all capabilities supported by Acrn implementation of hypervisor interface
|
||||||
func (a *acrn) capabilities() types.Capabilities {
|
func (a *Acrn) capabilities() types.Capabilities {
|
||||||
span, _ := a.trace("capabilities")
|
span, _ := a.trace("capabilities")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
return a.arch.capabilities()
|
return a.arch.capabilities()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) hypervisorConfig() HypervisorConfig {
|
func (a *Acrn) hypervisorConfig() HypervisorConfig {
|
||||||
return a.config
|
return a.config
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the acrn binary path
|
// get the acrn binary path
|
||||||
func (a *acrn) acrnPath() (string, error) {
|
func (a *Acrn) acrnPath() (string, error) {
|
||||||
p, err := a.config.HypervisorAssetPath()
|
p, err := a.config.HypervisorAssetPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -113,7 +170,7 @@ func (a *acrn) acrnPath() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the ACRNCTL binary path
|
// get the ACRNCTL binary path
|
||||||
func (a *acrn) acrnctlPath() (string, error) {
|
func (a *Acrn) acrnctlPath() (string, error) {
|
||||||
ctlpath, err := a.config.HypervisorCtlAssetPath()
|
ctlpath, err := a.config.HypervisorCtlAssetPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -134,11 +191,11 @@ func (a *acrn) acrnctlPath() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Logger returns a logrus logger appropriate for logging acrn messages
|
// Logger returns a logrus logger appropriate for logging acrn messages
|
||||||
func (a *acrn) Logger() *logrus.Entry {
|
func (a *Acrn) Logger() *logrus.Entry {
|
||||||
return virtLog.WithField("subsystem", "acrn")
|
return virtLog.WithField("subsystem", "acrn")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) trace(name string) (opentracing.Span, context.Context) {
|
func (a *Acrn) trace(name string) (opentracing.Span, context.Context) {
|
||||||
if a.ctx == nil {
|
if a.ctx == nil {
|
||||||
a.Logger().WithField("type", "bug").Error("trace called before context set")
|
a.Logger().WithField("type", "bug").Error("trace called before context set")
|
||||||
a.ctx = context.Background()
|
a.ctx = context.Background()
|
||||||
@ -152,13 +209,13 @@ func (a *acrn) trace(name string) (opentracing.Span, context.Context) {
|
|||||||
return span, ctx
|
return span, ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) memoryTopology() (Memory, error) {
|
func (a *Acrn) memoryTopology() (Memory, error) {
|
||||||
memMb := uint64(a.config.MemorySize)
|
memMb := uint64(a.config.MemorySize)
|
||||||
|
|
||||||
return a.arch.memoryTopology(memMb), nil
|
return a.arch.memoryTopology(memMb), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) appendImage(devices []Device, imagePath string) ([]Device, error) {
|
func (a *Acrn) appendImage(devices []Device, imagePath string) ([]Device, error) {
|
||||||
if imagePath == "" {
|
if imagePath == "" {
|
||||||
return nil, fmt.Errorf("Image path is empty: %s", imagePath)
|
return nil, fmt.Errorf("Image path is empty: %s", imagePath)
|
||||||
}
|
}
|
||||||
@ -180,7 +237,7 @@ func (a *acrn) appendImage(devices []Device, imagePath string) ([]Device, error)
|
|||||||
return devices, nil
|
return devices, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) buildDevices(imagePath string) ([]Device, error) {
|
func (a *Acrn) buildDevices(imagePath string) ([]Device, error) {
|
||||||
var devices []Device
|
var devices []Device
|
||||||
|
|
||||||
if imagePath == "" {
|
if imagePath == "" {
|
||||||
@ -219,7 +276,7 @@ func (a *acrn) buildDevices(imagePath string) ([]Device, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setup sets the Acrn structure up.
|
// setup sets the Acrn structure up.
|
||||||
func (a *acrn) setup(id string, hypervisorConfig *HypervisorConfig, vcStore *store.VCStore) error {
|
func (a *Acrn) setup(id string, hypervisorConfig *HypervisorConfig, vcStore *store.VCStore) error {
|
||||||
span, _ := a.trace("setup")
|
span, _ := a.trace("setup")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -234,24 +291,24 @@ func (a *acrn) setup(id string, hypervisorConfig *HypervisorConfig, vcStore *sto
|
|||||||
a.arch = newAcrnArch(a.config)
|
a.arch = newAcrnArch(a.config)
|
||||||
|
|
||||||
var create bool
|
var create bool
|
||||||
|
var uuid string
|
||||||
|
|
||||||
if a.store != nil { //use old store
|
if a.store != nil { //use old store
|
||||||
if err = a.store.Load(store.Hypervisor, &a.info); err != nil {
|
if err = a.store.Load(store.Hypervisor, &a.state); err != nil {
|
||||||
create = true
|
create = true
|
||||||
}
|
}
|
||||||
} else if a.info.PID == 0 { // new store
|
} else if a.state.UUID == "" { // new store
|
||||||
create = true
|
create = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if create {
|
if create {
|
||||||
// acrn currently supports only known UUIDs for security
|
a.Logger().Debug("Setting UUID")
|
||||||
// reasons (FuSa). When launching VM, only these pre-defined
|
if uuid, err = a.GetNextAvailableUUID(nil); err != nil {
|
||||||
// UUID should be used else VM launch will fail. acrn team is
|
return err
|
||||||
// working on a solution to expose these pre-defined UUIDs
|
}
|
||||||
// to Kata in order for it to launch VMs successfully.
|
a.state.UUID = uuid
|
||||||
// Until this support is available, Kata is limited to
|
Idx := acrnUUIDsToIdx[uuid]
|
||||||
// launch 1 VM (using the default UUID).
|
a.info.UUIDAvailability[Idx] = UUIDBusy
|
||||||
// https://github.com/kata-containers/runtime/issues/1785
|
|
||||||
|
|
||||||
// The path might already exist, but in case of VM templating,
|
// The path might already exist, but in case of VM templating,
|
||||||
// we have to create it since the sandbox has not created it yet.
|
// we have to create it since the sandbox has not created it yet.
|
||||||
@ -259,6 +316,10 @@ func (a *acrn) setup(id string, hypervisorConfig *HypervisorConfig, vcStore *sto
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = a.storeState(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err = a.storeInfo(); err != nil {
|
if err = a.storeInfo(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -267,7 +328,7 @@ func (a *acrn) setup(id string, hypervisorConfig *HypervisorConfig, vcStore *sto
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) createDummyVirtioBlkDev(devices []Device) ([]Device, error) {
|
func (a *Acrn) createDummyVirtioBlkDev(devices []Device) ([]Device, error) {
|
||||||
span, _ := a.trace("createDummyVirtioBlkDev")
|
span, _ := a.trace("createDummyVirtioBlkDev")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -287,7 +348,7 @@ func (a *acrn) createDummyVirtioBlkDev(devices []Device) ([]Device, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createSandbox is the Hypervisor sandbox creation.
|
// createSandbox is the Hypervisor sandbox creation.
|
||||||
func (a *acrn) createSandbox(ctx context.Context, id string, networkNS NetworkNamespace, hypervisorConfig *HypervisorConfig, store *store.VCStore) error {
|
func (a *Acrn) createSandbox(ctx context.Context, id string, networkNS NetworkNamespace, hypervisorConfig *HypervisorConfig, store *store.VCStore) error {
|
||||||
// Save the tracing context
|
// Save the tracing context
|
||||||
a.ctx = ctx
|
a.ctx = ctx
|
||||||
|
|
||||||
@ -319,8 +380,9 @@ func (a *acrn) createSandbox(ctx context.Context, id string, networkNS NetworkNa
|
|||||||
Params: a.kernelParameters(),
|
Params: a.kernelParameters(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disabling UUID check until the below is fixed.
|
if a.state.UUID == "" {
|
||||||
// https://github.com/kata-containers/runtime/issues/1785
|
return fmt.Errorf("ACRN UUID should not be empty")
|
||||||
|
}
|
||||||
|
|
||||||
devices, err := a.buildDevices(imagePath)
|
devices, err := a.buildDevices(imagePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -338,6 +400,7 @@ func (a *acrn) createSandbox(ctx context.Context, id string, networkNS NetworkNa
|
|||||||
}
|
}
|
||||||
|
|
||||||
acrnConfig := Config{
|
acrnConfig := Config{
|
||||||
|
UUID: a.state.UUID,
|
||||||
ACPIVirt: true,
|
ACPIVirt: true,
|
||||||
Path: acrnPath,
|
Path: acrnPath,
|
||||||
CtlPath: acrnctlPath,
|
CtlPath: acrnctlPath,
|
||||||
@ -354,7 +417,7 @@ func (a *acrn) createSandbox(ctx context.Context, id string, networkNS NetworkNa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// startSandbox will start the Sandbox's VM.
|
// startSandbox will start the Sandbox's VM.
|
||||||
func (a *acrn) startSandbox(timeoutSecs int) error {
|
func (a *Acrn) startSandbox(timeoutSecs int) error {
|
||||||
span, _ := a.trace("startSandbox")
|
span, _ := a.trace("startSandbox")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -389,7 +452,7 @@ func (a *acrn) startSandbox(timeoutSecs int) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s", strErr)
|
return fmt.Errorf("%s", strErr)
|
||||||
}
|
}
|
||||||
a.info.PID = PID
|
a.state.PID = PID
|
||||||
|
|
||||||
if err = a.waitSandbox(timeoutSecs); err != nil {
|
if err = a.waitSandbox(timeoutSecs); err != nil {
|
||||||
a.Logger().WithField("acrn wait failed:", err).Debug()
|
a.Logger().WithField("acrn wait failed:", err).Debug()
|
||||||
@ -397,12 +460,15 @@ func (a *acrn) startSandbox(timeoutSecs int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Store VMM information
|
//Store VMM information
|
||||||
return a.store.Store(store.Hypervisor, a.info)
|
if err = a.storeState(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// waitSandbox will wait for the Sandbox's VM to be up and running.
|
// waitSandbox will wait for the Sandbox's VM to be up and running.
|
||||||
func (a *acrn) waitSandbox(timeoutSecs int) error {
|
func (a *Acrn) waitSandbox(timeoutSecs int) error {
|
||||||
span, _ := a.trace("waitSandbox")
|
span, _ := a.trace("waitSandbox")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -416,7 +482,7 @@ func (a *acrn) waitSandbox(timeoutSecs int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stopSandbox will stop the Sandbox's VM.
|
// stopSandbox will stop the Sandbox's VM.
|
||||||
func (a *acrn) stopSandbox() (err error) {
|
func (a *Acrn) stopSandbox() (err error) {
|
||||||
span, _ := a.trace("stopSandbox")
|
span, _ := a.trace("stopSandbox")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -430,7 +496,23 @@ func (a *acrn) stopSandbox() (err error) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
pid := a.info.PID
|
// Mark the UUID as free
|
||||||
|
uuid := a.state.UUID
|
||||||
|
Idx := acrnUUIDsToIdx[uuid]
|
||||||
|
|
||||||
|
if err = a.store.Load(store.UUID, &a.info); err != nil {
|
||||||
|
a.Logger().Info("Failed to load UUID availabiity info")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
a.info.UUIDAvailability[Idx] = UUIDFree
|
||||||
|
|
||||||
|
if err = a.storeInfo(); err != nil {
|
||||||
|
a.Logger().Info("Failed to store UUID availabiity info")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pid := a.state.PID
|
||||||
|
|
||||||
// Check if VM process is running, in case it is not, let's
|
// Check if VM process is running, in case it is not, let's
|
||||||
// return from here.
|
// return from here.
|
||||||
@ -468,7 +550,7 @@ func (a *acrn) stopSandbox() (err error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) updateBlockDevice(drive *config.BlockDrive) error {
|
func (a *Acrn) updateBlockDevice(drive *config.BlockDrive) error {
|
||||||
var err error
|
var err error
|
||||||
if drive.File == "" || drive.Index >= AcrnBlkDevPoolSz {
|
if drive.File == "" || drive.Index >= AcrnBlkDevPoolSz {
|
||||||
return fmt.Errorf("Empty filepath or invalid drive index, Dive ID:%s, Drive Index:%d",
|
return fmt.Errorf("Empty filepath or invalid drive index, Dive ID:%s, Drive Index:%d",
|
||||||
@ -494,7 +576,7 @@ func (a *acrn) updateBlockDevice(drive *config.BlockDrive) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) hotplugAddDevice(devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (a *Acrn) hotplugAddDevice(devInfo interface{}, devType deviceType) (interface{}, error) {
|
||||||
span, _ := a.trace("hotplugAddDevice")
|
span, _ := a.trace("hotplugAddDevice")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -508,7 +590,7 @@ func (a *acrn) hotplugAddDevice(devInfo interface{}, devType deviceType) (interf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) hotplugRemoveDevice(devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (a *Acrn) hotplugRemoveDevice(devInfo interface{}, devType deviceType) (interface{}, error) {
|
||||||
span, _ := a.trace("hotplugRemoveDevice")
|
span, _ := a.trace("hotplugRemoveDevice")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -517,7 +599,7 @@ func (a *acrn) hotplugRemoveDevice(devInfo interface{}, devType deviceType) (int
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) pauseSandbox() error {
|
func (a *Acrn) pauseSandbox() error {
|
||||||
span, _ := a.trace("pauseSandbox")
|
span, _ := a.trace("pauseSandbox")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -526,7 +608,7 @@ func (a *acrn) pauseSandbox() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) resumeSandbox() error {
|
func (a *Acrn) resumeSandbox() error {
|
||||||
span, _ := a.trace("resumeSandbox")
|
span, _ := a.trace("resumeSandbox")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -535,8 +617,8 @@ func (a *acrn) resumeSandbox() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// addDevice will add extra devices to Acrn command line.
|
// addDevice will add extra devices to acrn command line.
|
||||||
func (a *acrn) addDevice(devInfo interface{}, devType deviceType) error {
|
func (a *Acrn) addDevice(devInfo interface{}, devType deviceType) error {
|
||||||
var err error
|
var err error
|
||||||
span, _ := a.trace("addDevice")
|
span, _ := a.trace("addDevice")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
@ -570,14 +652,14 @@ func (a *acrn) addDevice(devInfo interface{}, devType deviceType) error {
|
|||||||
|
|
||||||
// getSandboxConsole builds the path of the console where we can read
|
// getSandboxConsole builds the path of the console where we can read
|
||||||
// logs coming from the sandbox.
|
// logs coming from the sandbox.
|
||||||
func (a *acrn) getSandboxConsole(id string) (string, error) {
|
func (a *Acrn) getSandboxConsole(id string) (string, error) {
|
||||||
span, _ := a.trace("getSandboxConsole")
|
span, _ := a.trace("getSandboxConsole")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
return utils.BuildSocketPath(store.RunVMStoragePath, id, acrnConsoleSocket)
|
return utils.BuildSocketPath(store.RunVMStoragePath, id, acrnConsoleSocket)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) saveSandbox() error {
|
func (a *Acrn) saveSandbox() error {
|
||||||
a.Logger().Info("save sandbox")
|
a.Logger().Info("save sandbox")
|
||||||
|
|
||||||
// Not supported. return success
|
// Not supported. return success
|
||||||
@ -585,14 +667,14 @@ func (a *acrn) saveSandbox() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) disconnect() {
|
func (a *Acrn) disconnect() {
|
||||||
span, _ := a.trace("disconnect")
|
span, _ := a.trace("disconnect")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
// Not supported.
|
// Not supported.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) getThreadIDs() (vcpuThreadIDs, error) {
|
func (a *Acrn) getThreadIDs() (vcpuThreadIDs, error) {
|
||||||
span, _ := a.trace("getThreadIDs")
|
span, _ := a.trace("getThreadIDs")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -602,62 +684,138 @@ func (a *acrn) getThreadIDs() (vcpuThreadIDs, error) {
|
|||||||
return vcpuThreadIDs{}, nil
|
return vcpuThreadIDs{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) resizeMemory(reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, memoryDevice, error) {
|
func (a *Acrn) resizeMemory(reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, memoryDevice, error) {
|
||||||
return 0, memoryDevice{}, nil
|
return 0, memoryDevice{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) resizeVCPUs(reqVCPUs uint32) (currentVCPUs uint32, newVCPUs uint32, err error) {
|
func (a *Acrn) resizeVCPUs(reqVCPUs uint32) (currentVCPUs uint32, newVCPUs uint32, err error) {
|
||||||
return 0, 0, nil
|
return 0, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) cleanup() error {
|
func (a *Acrn) cleanup() error {
|
||||||
span, _ := a.trace("cleanup")
|
span, _ := a.trace("cleanup")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) getPids() []int {
|
func (a *Acrn) getPids() []int {
|
||||||
return []int{a.info.PID}
|
return []int{a.state.PID}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, store *store.VCStore, j []byte) error {
|
func (a *Acrn) fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, store *store.VCStore, j []byte) error {
|
||||||
return errors.New("acrn is not supported by VM cache")
|
return errors.New("acrn is not supported by VM cache")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) toGrpc() ([]byte, error) {
|
func (a *Acrn) toGrpc() ([]byte, error) {
|
||||||
return nil, errors.New("acrn is not supported by VM cache")
|
return nil, errors.New("acrn is not supported by VM cache")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) storeInfo() error {
|
func (a *Acrn) save() (s persistapi.HypervisorState) {
|
||||||
if a.store != nil {
|
s.Pid = a.state.PID
|
||||||
if err := a.store.Store(store.Hypervisor, a.info); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *acrn) save() (s persistapi.HypervisorState) {
|
|
||||||
s.Pid = a.info.PID
|
|
||||||
s.Type = string(AcrnHypervisor)
|
s.Type = string(AcrnHypervisor)
|
||||||
s.UUID = a.state.UUID
|
s.UUID = a.state.UUID
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) load(s persistapi.HypervisorState) {
|
func (a *Acrn) load(s persistapi.HypervisorState) {
|
||||||
a.info.PID = s.Pid
|
a.state.PID = s.Pid
|
||||||
a.state.UUID = s.UUID
|
a.state.UUID = s.UUID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) check() error {
|
func (a *Acrn) check() error {
|
||||||
if err := syscall.Kill(a.info.PID, syscall.Signal(0)); err != nil {
|
if err := syscall.Kill(a.state.PID, syscall.Signal(0)); err != nil {
|
||||||
return errors.Wrapf(err, "failed to ping acrn process")
|
return errors.Wrapf(err, "failed to ping acrn process")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *acrn) generateSocket(id string, useVsock bool) (interface{}, error) {
|
func (a *Acrn) generateSocket(id string, useVsock bool) (interface{}, error) {
|
||||||
return generateVMSocket(id, useVsock)
|
return generateVMSocket(id, useVsock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetACRNUUIDBytes returns UUID bytes that is used for VM creation
|
||||||
|
func (a *Acrn) GetACRNUUIDBytes(uid string) (uuid.UUID, error) {
|
||||||
|
return uuid.Parse(uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNextAvailableUUID returns next available UUID VM creation
|
||||||
|
// If no validl UUIDs are available it returns err.
|
||||||
|
func (a *Acrn) GetNextAvailableUUID(uuidstore *store.VCStore) (string, error) {
|
||||||
|
var MaxVMSupported uint8
|
||||||
|
var Idx uint8
|
||||||
|
var uuidStr string
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if uuidstore == nil {
|
||||||
|
uuidstore = a.store
|
||||||
|
}
|
||||||
|
|
||||||
|
if uuidstore != nil { //use old store
|
||||||
|
if err = uuidstore.Load(store.UUID, &a.info); err != nil {
|
||||||
|
a.Logger().Infof("Load UUID store failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if MaxVMSupported, err = a.GetMaxSupportedACRNVM(); err != nil {
|
||||||
|
return "", fmt.Errorf("IOCTL GetMaxSupportedACRNVM failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
for Idx = 0; Idx < MaxVMSupported; Idx++ {
|
||||||
|
if a.info.UUIDAvailability[Idx] == UUIDFree {
|
||||||
|
uuidStr = acrnIdxToUUIDs[Idx]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if uuidStr == "" {
|
||||||
|
return "", fmt.Errorf("Invalid UUID: Max VMs reached")
|
||||||
|
}
|
||||||
|
|
||||||
|
return uuidStr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMaxSupportedACRNVM checks the max number of VMs that can be
|
||||||
|
// launched from kata-runtime.
|
||||||
|
func (a *Acrn) GetMaxSupportedACRNVM() (uint8, error) {
|
||||||
|
flags := syscall.O_RDWR | syscall.O_CLOEXEC
|
||||||
|
|
||||||
|
f, err := syscall.Open(acrnDevice, flags, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
defer syscall.Close(f)
|
||||||
|
|
||||||
|
var platformInfo acrnPlatformInfo
|
||||||
|
|
||||||
|
ret, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
|
||||||
|
uintptr(f),
|
||||||
|
uintptr(ioctl_ACRN_GET_PLATFORM_INFO),
|
||||||
|
uintptr(unsafe.Pointer(&platformInfo)))
|
||||||
|
if ret != 0 || errno != 0 {
|
||||||
|
return 0, errno
|
||||||
|
}
|
||||||
|
|
||||||
|
return platformInfo.maxKataContainers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Acrn) storeState() error {
|
||||||
|
if a.store != nil {
|
||||||
|
if err := a.store.Store(store.Hypervisor, a.state); err != nil {
|
||||||
|
a.Logger().WithError(err).Error("failed to store acrn state")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Acrn) storeInfo() error {
|
||||||
|
if a.store != nil {
|
||||||
|
if err := a.store.Store(store.UUID, a.info); err != nil {
|
||||||
|
a.Logger().WithError(err).Error("failed to store acrn info")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -8,7 +8,6 @@ package virtcontainers
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -44,7 +43,7 @@ func testAcrnKernelParameters(t *testing.T, kernelParams []Param, debug bool) {
|
|||||||
acrnConfig.Debug = true
|
acrnConfig.Debug = true
|
||||||
}
|
}
|
||||||
|
|
||||||
a := &acrn{
|
a := &Acrn{
|
||||||
config: acrnConfig,
|
config: acrnConfig,
|
||||||
arch: &acrnArchBase{},
|
arch: &acrnArchBase{},
|
||||||
}
|
}
|
||||||
@ -73,7 +72,7 @@ func TestAcrnKernelParameters(t *testing.T) {
|
|||||||
|
|
||||||
func TestAcrnCapabilities(t *testing.T) {
|
func TestAcrnCapabilities(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
a := &acrn{
|
a := &Acrn{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
arch: &acrnArchBase{},
|
arch: &acrnArchBase{},
|
||||||
}
|
}
|
||||||
@ -85,7 +84,7 @@ func TestAcrnCapabilities(t *testing.T) {
|
|||||||
|
|
||||||
func testAcrnAddDevice(t *testing.T, devInfo interface{}, devType deviceType, expected []Device) {
|
func testAcrnAddDevice(t *testing.T, devInfo interface{}, devType deviceType, expected []Device) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
a := &acrn{
|
a := &Acrn{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
arch: &acrnArchBase{},
|
arch: &acrnArchBase{},
|
||||||
}
|
}
|
||||||
@ -139,7 +138,7 @@ func TestAcrnHotplugUnsupportedDeviceType(t *testing.T) {
|
|||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
acrnConfig := newAcrnConfig()
|
acrnConfig := newAcrnConfig()
|
||||||
a := &acrn{
|
a := &Acrn{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
id: "acrnTest",
|
id: "acrnTest",
|
||||||
config: acrnConfig,
|
config: acrnConfig,
|
||||||
@ -156,7 +155,7 @@ func TestAcrnUpdateBlockDeviceInvalidPath(t *testing.T) {
|
|||||||
index := 1
|
index := 1
|
||||||
|
|
||||||
acrnConfig := newAcrnConfig()
|
acrnConfig := newAcrnConfig()
|
||||||
a := &acrn{
|
a := &Acrn{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
id: "acrnBlkTest",
|
id: "acrnBlkTest",
|
||||||
config: acrnConfig,
|
config: acrnConfig,
|
||||||
@ -178,7 +177,7 @@ func TestAcrnUpdateBlockDeviceInvalidIdx(t *testing.T) {
|
|||||||
index := AcrnBlkDevPoolSz + 1
|
index := AcrnBlkDevPoolSz + 1
|
||||||
|
|
||||||
acrnConfig := newAcrnConfig()
|
acrnConfig := newAcrnConfig()
|
||||||
a := &acrn{
|
a := &Acrn{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
id: "acrnBlkTest",
|
id: "acrnBlkTest",
|
||||||
config: acrnConfig,
|
config: acrnConfig,
|
||||||
@ -195,7 +194,7 @@ func TestAcrnUpdateBlockDeviceInvalidIdx(t *testing.T) {
|
|||||||
|
|
||||||
func TestAcrnGetSandboxConsole(t *testing.T) {
|
func TestAcrnGetSandboxConsole(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
a := &acrn{
|
a := &Acrn{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
}
|
}
|
||||||
sandboxID := "testSandboxID"
|
sandboxID := "testSandboxID"
|
||||||
@ -209,7 +208,7 @@ func TestAcrnGetSandboxConsole(t *testing.T) {
|
|||||||
func TestAcrnCreateSandbox(t *testing.T) {
|
func TestAcrnCreateSandbox(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
acrnConfig := newAcrnConfig()
|
acrnConfig := newAcrnConfig()
|
||||||
a := &acrn{}
|
a := &Acrn{}
|
||||||
|
|
||||||
sandbox := &Sandbox{
|
sandbox := &Sandbox{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
@ -219,6 +218,11 @@ func TestAcrnCreateSandbox(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Even though this test doesn't need to create a vcStore,
|
||||||
|
// we are forced to create a vcStore as GetAndSetSandboxBlockIndex()
|
||||||
|
// which is called from createSandbox needs a valid vcStore. vcStore
|
||||||
|
// creation can be removed once https://github.com/kata-containers/runtime/issues/2026
|
||||||
|
// issue is resolved.
|
||||||
vcStore, err := store.NewVCSandboxStore(sandbox.ctx, sandbox.id)
|
vcStore, err := store.NewVCSandboxStore(sandbox.ctx, sandbox.id)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
sandbox.store = vcStore
|
sandbox.store = vcStore
|
||||||
@ -228,12 +232,10 @@ func TestAcrnCreateSandbox(t *testing.T) {
|
|||||||
|
|
||||||
defer globalSandboxList.removeSandbox(sandbox.id)
|
defer globalSandboxList.removeSandbox(sandbox.id)
|
||||||
|
|
||||||
// Create the hypervisor fake binary
|
//set PID to 1 to ignore hypercall to get UUID and set a random UUID
|
||||||
testAcrnPath := filepath.Join(testDir, testHypervisor)
|
a.state.PID = 1
|
||||||
_, err = os.Create(testAcrnPath)
|
a.state.UUID = "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"
|
||||||
assert.NoError(err)
|
err = a.createSandbox(context.Background(), sandbox.id, NetworkNamespace{}, &sandbox.config.HypervisorConfig, nil)
|
||||||
|
|
||||||
err = a.createSandbox(context.Background(), sandbox.id, NetworkNamespace{}, &sandbox.config.HypervisorConfig, sandbox.store)
|
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Exactly(acrnConfig, a.config)
|
assert.Exactly(acrnConfig, a.config)
|
||||||
}
|
}
|
||||||
@ -242,7 +244,7 @@ func TestAcrnMemoryTopology(t *testing.T) {
|
|||||||
mem := uint32(1000)
|
mem := uint32(1000)
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
a := &acrn{
|
a := &Acrn{
|
||||||
arch: &acrnArchBase{},
|
arch: &acrnArchBase{},
|
||||||
config: HypervisorConfig{
|
config: HypervisorConfig{
|
||||||
MemorySize: mem,
|
MemorySize: mem,
|
||||||
|
@ -172,7 +172,7 @@ func newHypervisor(hType HypervisorType) (hypervisor, error) {
|
|||||||
case FirecrackerHypervisor:
|
case FirecrackerHypervisor:
|
||||||
return &firecracker{}, nil
|
return &firecracker{}, nil
|
||||||
case AcrnHypervisor:
|
case AcrnHypervisor:
|
||||||
return &acrn{}, nil
|
return &Acrn{}, nil
|
||||||
case MockHypervisor:
|
case MockHypervisor:
|
||||||
return &mockHypervisor{}, nil
|
return &mockHypervisor{}, nil
|
||||||
default:
|
default:
|
||||||
|
@ -46,6 +46,9 @@ const (
|
|||||||
|
|
||||||
// DevicesFile is the file name storing a container's devices.
|
// DevicesFile is the file name storing a container's devices.
|
||||||
DevicesFile = "devices.json"
|
DevicesFile = "devices.json"
|
||||||
|
|
||||||
|
// uuidFile is the file name storing a guest VM uuid state.
|
||||||
|
uuidFile = "uuid.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DirMode is the permission bits used for creating a directory
|
// DirMode is the permission bits used for creating a directory
|
||||||
@ -63,6 +66,9 @@ const SandboxPathSuffix = "sbs"
|
|||||||
// VMPathSuffix is the suffix used for guest VMs.
|
// VMPathSuffix is the suffix used for guest VMs.
|
||||||
const VMPathSuffix = "vm"
|
const VMPathSuffix = "vm"
|
||||||
|
|
||||||
|
// UUIDPathSuffix is the suffix used for uuid storage
|
||||||
|
const UUIDPathSuffix = "uuid"
|
||||||
|
|
||||||
// ConfigStoragePath is the sandbox configuration directory.
|
// ConfigStoragePath is the sandbox configuration directory.
|
||||||
// It will contain one config.json file for each created sandbox.
|
// It will contain one config.json file for each created sandbox.
|
||||||
var ConfigStoragePath = filepath.Join("/var/lib", StoragePathSuffix, SandboxPathSuffix)
|
var ConfigStoragePath = filepath.Join("/var/lib", StoragePathSuffix, SandboxPathSuffix)
|
||||||
@ -75,6 +81,10 @@ var RunStoragePath = filepath.Join("/run", StoragePathSuffix, SandboxPathSuffix)
|
|||||||
// It will contain all guest vm sockets and shared mountpoints.
|
// It will contain all guest vm sockets and shared mountpoints.
|
||||||
var RunVMStoragePath = filepath.Join("/run", StoragePathSuffix, VMPathSuffix)
|
var RunVMStoragePath = filepath.Join("/run", StoragePathSuffix, VMPathSuffix)
|
||||||
|
|
||||||
|
// VMUUIDStoragePath is the uuid directory.
|
||||||
|
// It will contain all uuid info used by guest vm.
|
||||||
|
var VMUUIDStoragePath = filepath.Join("/var/lib", StoragePathSuffix, UUIDPathSuffix)
|
||||||
|
|
||||||
func itemToFile(item Item) (string, error) {
|
func itemToFile(item Item) (string, error) {
|
||||||
switch item {
|
switch item {
|
||||||
case Configuration:
|
case Configuration:
|
||||||
@ -95,6 +105,8 @@ func itemToFile(item Item) (string, error) {
|
|||||||
return MountsFile, nil
|
return MountsFile, nil
|
||||||
case Devices, DeviceIDs:
|
case Devices, DeviceIDs:
|
||||||
return DevicesFile, nil
|
return DevicesFile, nil
|
||||||
|
case UUID:
|
||||||
|
return uuidFile, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", fmt.Errorf("Unknown item %s", item)
|
return "", fmt.Errorf("Unknown item %s", item)
|
||||||
|
@ -48,6 +48,9 @@ const (
|
|||||||
|
|
||||||
// DeviceIDs represents a set of reference IDs item to be stored.
|
// DeviceIDs represents a set of reference IDs item to be stored.
|
||||||
DeviceIDs
|
DeviceIDs
|
||||||
|
|
||||||
|
// UUID represents a set of uuids item to be stored.
|
||||||
|
UUID
|
||||||
)
|
)
|
||||||
|
|
||||||
func (i Item) String() string {
|
func (i Item) String() string {
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
//
|
//
|
||||||
// VCStore simply dispatches items into the right Store.
|
// VCStore simply dispatches items into the right Store.
|
||||||
type VCStore struct {
|
type VCStore struct {
|
||||||
config, state *Store
|
config, state, uuid *Store
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *VCStore) itemToStore(item Item) *Store {
|
func (s *VCStore) itemToStore(item Item) *Store {
|
||||||
@ -34,6 +34,8 @@ func (s *VCStore) itemToStore(item Item) *Store {
|
|||||||
return s.config
|
return s.config
|
||||||
case State, Network, Hypervisor, Agent, Process, Lock, Mounts, Devices, DeviceIDs:
|
case State, Network, Hypervisor, Agent, Process, Lock, Mounts, Devices, DeviceIDs:
|
||||||
return s.state
|
return s.state
|
||||||
|
case UUID:
|
||||||
|
return s.uuid
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.state
|
return s.state
|
||||||
@ -51,9 +53,15 @@ func NewVCStore(ctx context.Context, configRoot, stateRoot string) (*VCStore, er
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uuid, err := New(ctx, VCStoreUUIDPath())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &VCStore{
|
return &VCStore{
|
||||||
config: config,
|
config: config,
|
||||||
state: state,
|
state: state,
|
||||||
|
uuid: uuid,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +117,7 @@ func (s *VCStore) Delete() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadSandboxState loads an returns a virtcontainer state
|
// LoadState loads an returns a virtcontainer state
|
||||||
func (s *VCStore) LoadState() (types.SandboxState, error) {
|
func (s *VCStore) LoadState() (types.SandboxState, error) {
|
||||||
var state types.SandboxState
|
var state types.SandboxState
|
||||||
|
|
||||||
@ -256,6 +264,11 @@ func SandboxConfigurationItemPath(id string, item Item) (string, error) {
|
|||||||
return filepath.Join(ConfigStoragePath, id, itemFile), nil
|
return filepath.Join(ConfigStoragePath, id, itemFile), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VCStoreUUIDPath returns a virtcontainers runtime uuid URL.
|
||||||
|
func VCStoreUUIDPath() string {
|
||||||
|
return filesystemScheme + "://" + VMUUIDStoragePath
|
||||||
|
}
|
||||||
|
|
||||||
// SandboxRuntimeRoot returns a virtcontainers sandbox runtime root URL.
|
// SandboxRuntimeRoot returns a virtcontainers sandbox runtime root URL.
|
||||||
// This will hold data related to a sandbox run-time state that will not
|
// This will hold data related to a sandbox run-time state that will not
|
||||||
// be persistent across host reboots.
|
// be persistent across host reboots.
|
||||||
|
Loading…
Reference in New Issue
Block a user