mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-30 01:02:33 +00:00
vendor: update govmm changes
To include vm factory related commits. Full list:54caf78
(mine/templating, templating) qmp: add hotplug memorye66a9b4
qemu: add appendMemoryKnobs helper8aeca15
qmp: add migrate set argumentsa03d496
qmp: add set migration capabilities0ace417
qemu: allow to set migration incoming723bc5f
qemu: allow to create a stopped guest283d7df
qemu: add file backed memory device support Signed-off-by: Peng Tao <bergwolf@gmail.com>
This commit is contained in:
parent
47dfb7d6da
commit
0f20b6b81b
4
Gopkg.lock
generated
4
Gopkg.lock
generated
@ -91,7 +91,7 @@
|
|||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/intel/govmm"
|
name = "github.com/intel/govmm"
|
||||||
packages = ["qemu"]
|
packages = ["qemu"]
|
||||||
revision = "9cf8ce6c6dda19d4a6d529e73714e231f6156820"
|
revision = "ff2401825e0930811919c86c36d64b113aa00083"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/kata-containers/agent"
|
name = "github.com/kata-containers/agent"
|
||||||
@ -263,6 +263,6 @@
|
|||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "a8e90901b945488c3b660e20c076fce3345dba96b4ec15e7ca00b8a06baa16a3"
|
inputs-digest = "4d57a771261fe6b0e1f86bf2de82f8c39cc0047170f4277754972e2feab4796f"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/intel/govmm"
|
name = "github.com/intel/govmm"
|
||||||
revision = "9cf8ce6c6dda19d4a6d529e73714e231f6156820"
|
revision = "ff2401825e0930811919c86c36d64b113aa00083"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/kata-containers/agent"
|
name = "github.com/kata-containers/agent"
|
||||||
|
35
vendor/github.com/docker/go-units/duration.go
generated
vendored
Normal file
35
vendor/github.com/docker/go-units/duration.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Package units provides helper function to parse and print size and time units
|
||||||
|
// in human-readable format.
|
||||||
|
package units
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HumanDuration returns a human-readable approximation of a duration
|
||||||
|
// (eg. "About a minute", "4 hours ago", etc.).
|
||||||
|
func HumanDuration(d time.Duration) string {
|
||||||
|
if seconds := int(d.Seconds()); seconds < 1 {
|
||||||
|
return "Less than a second"
|
||||||
|
} else if seconds == 1 {
|
||||||
|
return "1 second"
|
||||||
|
} else if seconds < 60 {
|
||||||
|
return fmt.Sprintf("%d seconds", seconds)
|
||||||
|
} else if minutes := int(d.Minutes()); minutes == 1 {
|
||||||
|
return "About a minute"
|
||||||
|
} else if minutes < 46 {
|
||||||
|
return fmt.Sprintf("%d minutes", minutes)
|
||||||
|
} else if hours := int(d.Hours() + 0.5); hours == 1 {
|
||||||
|
return "About an hour"
|
||||||
|
} else if hours < 48 {
|
||||||
|
return fmt.Sprintf("%d hours", hours)
|
||||||
|
} else if hours < 24*7*2 {
|
||||||
|
return fmt.Sprintf("%d days", hours/24)
|
||||||
|
} else if hours < 24*30*2 {
|
||||||
|
return fmt.Sprintf("%d weeks", hours/24/7)
|
||||||
|
} else if hours < 24*365*2 {
|
||||||
|
return fmt.Sprintf("%d months", hours/24/30)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%d years", int(d.Hours())/24/365)
|
||||||
|
}
|
118
vendor/github.com/docker/go-units/ulimit.go
generated
vendored
Normal file
118
vendor/github.com/docker/go-units/ulimit.go
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package units
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ulimit is a human friendly version of Rlimit.
|
||||||
|
type Ulimit struct {
|
||||||
|
Name string
|
||||||
|
Hard int64
|
||||||
|
Soft int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rlimit specifies the resource limits, such as max open files.
|
||||||
|
type Rlimit struct {
|
||||||
|
Type int `json:"type,omitempty"`
|
||||||
|
Hard uint64 `json:"hard,omitempty"`
|
||||||
|
Soft uint64 `json:"soft,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// magic numbers for making the syscall
|
||||||
|
// some of these are defined in the syscall package, but not all.
|
||||||
|
// Also since Windows client doesn't get access to the syscall package, need to
|
||||||
|
// define these here
|
||||||
|
rlimitAs = 9
|
||||||
|
rlimitCore = 4
|
||||||
|
rlimitCPU = 0
|
||||||
|
rlimitData = 2
|
||||||
|
rlimitFsize = 1
|
||||||
|
rlimitLocks = 10
|
||||||
|
rlimitMemlock = 8
|
||||||
|
rlimitMsgqueue = 12
|
||||||
|
rlimitNice = 13
|
||||||
|
rlimitNofile = 7
|
||||||
|
rlimitNproc = 6
|
||||||
|
rlimitRss = 5
|
||||||
|
rlimitRtprio = 14
|
||||||
|
rlimitRttime = 15
|
||||||
|
rlimitSigpending = 11
|
||||||
|
rlimitStack = 3
|
||||||
|
)
|
||||||
|
|
||||||
|
var ulimitNameMapping = map[string]int{
|
||||||
|
//"as": rlimitAs, // Disabled since this doesn't seem usable with the way Docker inits a container.
|
||||||
|
"core": rlimitCore,
|
||||||
|
"cpu": rlimitCPU,
|
||||||
|
"data": rlimitData,
|
||||||
|
"fsize": rlimitFsize,
|
||||||
|
"locks": rlimitLocks,
|
||||||
|
"memlock": rlimitMemlock,
|
||||||
|
"msgqueue": rlimitMsgqueue,
|
||||||
|
"nice": rlimitNice,
|
||||||
|
"nofile": rlimitNofile,
|
||||||
|
"nproc": rlimitNproc,
|
||||||
|
"rss": rlimitRss,
|
||||||
|
"rtprio": rlimitRtprio,
|
||||||
|
"rttime": rlimitRttime,
|
||||||
|
"sigpending": rlimitSigpending,
|
||||||
|
"stack": rlimitStack,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseUlimit parses and returns a Ulimit from the specified string.
|
||||||
|
func ParseUlimit(val string) (*Ulimit, error) {
|
||||||
|
parts := strings.SplitN(val, "=", 2)
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return nil, fmt.Errorf("invalid ulimit argument: %s", val)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, exists := ulimitNameMapping[parts[0]]; !exists {
|
||||||
|
return nil, fmt.Errorf("invalid ulimit type: %s", parts[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
soft int64
|
||||||
|
hard = &soft // default to soft in case no hard was set
|
||||||
|
temp int64
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
switch limitVals := strings.Split(parts[1], ":"); len(limitVals) {
|
||||||
|
case 2:
|
||||||
|
temp, err = strconv.ParseInt(limitVals[1], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hard = &temp
|
||||||
|
fallthrough
|
||||||
|
case 1:
|
||||||
|
soft, err = strconv.ParseInt(limitVals[0], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
if soft > *hard {
|
||||||
|
return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, *hard)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Ulimit{Name: parts[0], Soft: soft, Hard: *hard}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRlimit returns the RLimit corresponding to Ulimit.
|
||||||
|
func (u *Ulimit) GetRlimit() (*Rlimit, error) {
|
||||||
|
t, exists := ulimitNameMapping[u.Name]
|
||||||
|
if !exists {
|
||||||
|
return nil, fmt.Errorf("invalid ulimit name %s", u.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Rlimit{Type: t, Soft: uint64(u.Soft), Hard: uint64(u.Hard)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *Ulimit) String() string {
|
||||||
|
return fmt.Sprintf("%s=%d:%d", u.Name, u.Soft, u.Hard)
|
||||||
|
}
|
107
vendor/github.com/intel/govmm/qemu/qemu.go
generated
vendored
107
vendor/github.com/intel/govmm/qemu/qemu.go
generated
vendored
@ -1126,6 +1126,10 @@ type Memory struct {
|
|||||||
// MaxMem is the maximum amount of memory that can be made available
|
// MaxMem is the maximum amount of memory that can be made available
|
||||||
// to the guest through e.g. hot pluggable memory.
|
// to the guest through e.g. hot pluggable memory.
|
||||||
MaxMem string
|
MaxMem string
|
||||||
|
|
||||||
|
// Path is the file path of the memory device. It points to a local
|
||||||
|
// file path used by FileBackedMem.
|
||||||
|
Path string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kernel is the guest kernel configuration structure.
|
// Kernel is the guest kernel configuration structure.
|
||||||
@ -1167,10 +1171,20 @@ type Knobs struct {
|
|||||||
// MemPrealloc will allocate all the RAM upfront
|
// MemPrealloc will allocate all the RAM upfront
|
||||||
MemPrealloc bool
|
MemPrealloc bool
|
||||||
|
|
||||||
|
// FileBackedMem requires Memory.Size and Memory.Path of the VM to
|
||||||
|
// be set.
|
||||||
|
FileBackedMem bool
|
||||||
|
|
||||||
|
// FileBackedMemShared will set the FileBackedMem device as shared.
|
||||||
|
FileBackedMemShared bool
|
||||||
|
|
||||||
// Mlock will control locking of memory
|
// Mlock will control locking of memory
|
||||||
// Only active when Realtime is set to true
|
// Only active when Realtime is set to true
|
||||||
Mlock bool
|
Mlock bool
|
||||||
|
|
||||||
|
// Stopped will not start guest CPU at startup
|
||||||
|
Stopped bool
|
||||||
|
|
||||||
// Realtime will enable realtime QEMU
|
// Realtime will enable realtime QEMU
|
||||||
Realtime bool
|
Realtime bool
|
||||||
}
|
}
|
||||||
@ -1180,6 +1194,24 @@ type IOThread struct {
|
|||||||
ID string
|
ID string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// MigrationFD is the migration incoming type based on open file descriptor.
|
||||||
|
// Skip default 0 so that it must be set on purpose.
|
||||||
|
MigrationFD = 1
|
||||||
|
// MigrationExec is the migration incoming type based on commands.
|
||||||
|
MigrationExec = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Incoming controls migration source preparation
|
||||||
|
type Incoming struct {
|
||||||
|
// Possible values are MigrationFD, MigrationExec
|
||||||
|
MigrationType int
|
||||||
|
// Only valid if MigrationType == MigrationFD
|
||||||
|
FD *os.File
|
||||||
|
// Only valid if MigrationType == MigrationExec
|
||||||
|
Exec string
|
||||||
|
}
|
||||||
|
|
||||||
// Config is the qemu configuration structure.
|
// Config is the qemu configuration structure.
|
||||||
// It allows for passing custom settings and parameters to the qemu API.
|
// It allows for passing custom settings and parameters to the qemu API.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@ -1231,6 +1263,9 @@ type Config struct {
|
|||||||
// Bios is the -bios parameter
|
// Bios is the -bios parameter
|
||||||
Bios string
|
Bios string
|
||||||
|
|
||||||
|
// Incoming controls migration source preparation
|
||||||
|
Incoming Incoming
|
||||||
|
|
||||||
// fds is a list of open file descriptors to be passed to the spawned qemu process
|
// fds is a list of open file descriptors to be passed to the spawned qemu process
|
||||||
fds []*os.File
|
fds []*os.File
|
||||||
|
|
||||||
@ -1433,23 +1468,7 @@ func (config *Config) appendKernel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) appendKnobs() {
|
func (config *Config) appendMemoryKnobs() {
|
||||||
if config.Knobs.NoUserConfig == true {
|
|
||||||
config.qemuParams = append(config.qemuParams, "-no-user-config")
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.Knobs.NoDefaults == true {
|
|
||||||
config.qemuParams = append(config.qemuParams, "-nodefaults")
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.Knobs.NoGraphic == true {
|
|
||||||
config.qemuParams = append(config.qemuParams, "-nographic")
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.Knobs.Daemonize == true {
|
|
||||||
config.qemuParams = append(config.qemuParams, "-daemonize")
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.Knobs.HugePages == true {
|
if config.Knobs.HugePages == true {
|
||||||
if config.Memory.Size != "" {
|
if config.Memory.Size != "" {
|
||||||
dimmName := "dimm1"
|
dimmName := "dimm1"
|
||||||
@ -1474,7 +1493,42 @@ func (config *Config) appendKnobs() {
|
|||||||
config.qemuParams = append(config.qemuParams, "-device")
|
config.qemuParams = append(config.qemuParams, "-device")
|
||||||
config.qemuParams = append(config.qemuParams, deviceMemParam)
|
config.qemuParams = append(config.qemuParams, deviceMemParam)
|
||||||
}
|
}
|
||||||
|
} else if config.Knobs.FileBackedMem == true {
|
||||||
|
if config.Memory.Size != "" && config.Memory.Path != "" {
|
||||||
|
dimmName := "dimm1"
|
||||||
|
objMemParam := "memory-backend-file,id=" + dimmName + ",size=" + config.Memory.Size + ",mem-path=" + config.Memory.Path
|
||||||
|
if config.Knobs.FileBackedMemShared == true {
|
||||||
|
objMemParam += ",share=on"
|
||||||
|
}
|
||||||
|
numaMemParam := "node,memdev=" + dimmName
|
||||||
|
|
||||||
|
config.qemuParams = append(config.qemuParams, "-object")
|
||||||
|
config.qemuParams = append(config.qemuParams, objMemParam)
|
||||||
|
|
||||||
|
config.qemuParams = append(config.qemuParams, "-numa")
|
||||||
|
config.qemuParams = append(config.qemuParams, numaMemParam)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (config *Config) appendKnobs() {
|
||||||
|
if config.Knobs.NoUserConfig == true {
|
||||||
|
config.qemuParams = append(config.qemuParams, "-no-user-config")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Knobs.NoDefaults == true {
|
||||||
|
config.qemuParams = append(config.qemuParams, "-nodefaults")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Knobs.NoGraphic == true {
|
||||||
|
config.qemuParams = append(config.qemuParams, "-nographic")
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.Knobs.Daemonize == true {
|
||||||
|
config.qemuParams = append(config.qemuParams, "-daemonize")
|
||||||
|
}
|
||||||
|
|
||||||
|
config.appendMemoryKnobs()
|
||||||
|
|
||||||
if config.Knobs.Realtime == true {
|
if config.Knobs.Realtime == true {
|
||||||
config.qemuParams = append(config.qemuParams, "-realtime")
|
config.qemuParams = append(config.qemuParams, "-realtime")
|
||||||
@ -1495,6 +1549,10 @@ func (config *Config) appendKnobs() {
|
|||||||
config.qemuParams = append(config.qemuParams, "mlock=off")
|
config.qemuParams = append(config.qemuParams, "mlock=off")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.Knobs.Stopped == true {
|
||||||
|
config.qemuParams = append(config.qemuParams, "-S")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) appendBios() {
|
func (config *Config) appendBios() {
|
||||||
@ -1513,6 +1571,20 @@ func (config *Config) appendIOThreads() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (config *Config) appendIncoming() {
|
||||||
|
var uri string
|
||||||
|
switch config.Incoming.MigrationType {
|
||||||
|
case MigrationExec:
|
||||||
|
uri = fmt.Sprintf("exec:%s", config.Incoming.Exec)
|
||||||
|
case MigrationFD:
|
||||||
|
chFDs := config.appendFDs([]*os.File{config.Incoming.FD})
|
||||||
|
uri = fmt.Sprintf("fd:%d", chFDs[0])
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
config.qemuParams = append(config.qemuParams, "-S", "-incoming", uri)
|
||||||
|
}
|
||||||
|
|
||||||
// LaunchQemu can be used to launch a new qemu instance.
|
// LaunchQemu can be used to launch a new qemu instance.
|
||||||
//
|
//
|
||||||
// The Config parameter contains a set of qemu parameters and settings.
|
// The Config parameter contains a set of qemu parameters and settings.
|
||||||
@ -1537,6 +1609,7 @@ func LaunchQemu(config Config, logger QMPLog) (string, error) {
|
|||||||
config.appendKernel()
|
config.appendKernel()
|
||||||
config.appendBios()
|
config.appendBios()
|
||||||
config.appendIOThreads()
|
config.appendIOThreads()
|
||||||
|
config.appendIncoming()
|
||||||
|
|
||||||
if err := config.appendCPUs(); err != nil {
|
if err := config.appendCPUs(); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
53
vendor/github.com/intel/govmm/qemu/qmp.go
generated
vendored
53
vendor/github.com/intel/govmm/qemu/qmp.go
generated
vendored
@ -828,3 +828,56 @@ func (q *QMP) ExecuteQueryHotpluggableCPUs(ctx context.Context) ([]HotpluggableC
|
|||||||
|
|
||||||
return cpus, nil
|
return cpus, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExecSetMigrationCaps sets migration capabilities
|
||||||
|
func (q *QMP) ExecSetMigrationCaps(ctx context.Context, caps []map[string]interface{}) error {
|
||||||
|
args := map[string]interface{}{
|
||||||
|
"capabilities": caps,
|
||||||
|
}
|
||||||
|
|
||||||
|
return q.executeCommand(ctx, "migrate-set-capabilities", args, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecSetMigrateArguments sets the command line used for migration
|
||||||
|
func (q *QMP) ExecSetMigrateArguments(ctx context.Context, url string) error {
|
||||||
|
args := map[string]interface{}{
|
||||||
|
"uri": url,
|
||||||
|
}
|
||||||
|
|
||||||
|
return q.executeCommand(ctx, "migrate", args, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecHotplugMemory adds size of MiB memory to the guest
|
||||||
|
func (q *QMP) ExecHotplugMemory(ctx context.Context, qomtype, id, mempath string, size int) error {
|
||||||
|
args := map[string]interface{}{
|
||||||
|
"qom-type": qomtype,
|
||||||
|
"id": id,
|
||||||
|
"props": map[string]interface{}{"size": uint64(size) << 20},
|
||||||
|
}
|
||||||
|
if mempath != "" {
|
||||||
|
args["mem-path"] = mempath
|
||||||
|
}
|
||||||
|
err := q.executeCommand(ctx, "object-add", args, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
q.cfg.Logger.Errorf("Unable to hotplug memory device: %v", err)
|
||||||
|
err = q.executeCommand(ctx, "object-del", map[string]interface{}{"id": id}, nil)
|
||||||
|
if err != nil {
|
||||||
|
q.cfg.Logger.Warningf("Unable to clean up memory object: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
args = map[string]interface{}{
|
||||||
|
"driver": "pc-dimm",
|
||||||
|
"id": "dimm" + id,
|
||||||
|
"memdev": id,
|
||||||
|
}
|
||||||
|
err = q.executeCommand(ctx, "device_add", args, nil)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user