!130 kata-containers:update to 3.2.0

From: @Vanient 
Reviewed-by: @flyflyflypeng 
Signed-off-by: @flyflyflypeng
This commit is contained in:
openeuler-ci-bot 2024-02-20 03:49:02 +00:00 committed by Gitee
commit 07ae06b3c0
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
43 changed files with 36 additions and 9297 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
kata-containers-3.2.0-vendor.tar.gz filter=lfs diff=lfs merge=lfs -text

View File

@ -7,8 +7,8 @@ if [[ -f ./patch_flag ]];then
exit 0
fi
tar -zxvf kata-containers-2.1.0.tar.gz
cp -rf ./kata-containers-2.1.0/* ./
tar -zxvf kata-containers-3.2.0.tar.gz
cp -rf ./kata-containers-3.2.0/* ./
cat ./series.conf | while read line
do
if [[ $line == '' || $line =~ ^\s*# ]]; then

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8b1a5424a14389860bf34779da3f6475dbc12a8540f17c1166ebf7d45637eeac
size 371103955

View File

@ -1,8 +1,8 @@
#needsrootforbuild
%global debug_package %{nil}
%define VERSION 2.1.0
%define RELEASE 33
%define VERSION 3.2.0
%define RELEASE 1
Name: kata-containers
Version: %{VERSION}
@ -23,7 +23,7 @@ This is core component of Kata Container, to make it work, you need a isulad/doc
%prep
%setup -T -c -a 0 -n kata_integration
%setup -T -c -a 1 -n kata-containers-%{version}
%setup -T -c -a 1 -n kata-containers
%setup -T -c -a 2 -n kernel
# extract the kata_integration.tar.gz file
@ -46,16 +46,15 @@ cd %{_builddir}/kernel/linux/
make olddefconfig
make %{?_smp_mflags}
mv %{_builddir}/kata-containers-%{version} %{_builddir}/kata-containers
cd %{_builddir}/kata-containers/
sh -x apply-patches
tar -xzf kata-containers-%{version}-vendor.tar.gz
cd %{_builddir}/kata-containers/src/runtime
make clean
make
cd %{_builddir}/kata-containers/src/agent
mkdir vendor && tar -xzf %{_builddir}/kata-containers/vendor.tar.gz -C vendor/
cp -f ./vendor/version.rs ./src/
cp %{_builddir}/kata-containers/version.rs ./src/
cat > .cargo/config << EOF
[build]
rustflags = ["-Clink-arg=-s","-Clink-arg=-lgcc","-Clink-arg=-lfdt"]
@ -84,11 +83,9 @@ install -p -m 755 -D %{_builddir}/kernel/linux/arch/arm64/boot/Image %{buildroot
cd %{_builddir}/kata_integration
mkdir -p -m 750 %{buildroot}/usr/bin
install -p -m 750 %{_builddir}/kata-containers/src/runtime/kata-runtime %{buildroot}/usr/bin/
install -p -m 750 %{_builddir}/kata-containers/src/runtime/kata-netmon %{buildroot}/usr/bin/
install -p -m 750 %{_builddir}/kata-containers/src/runtime/kata-monitor %{buildroot}/usr/bin/
install -p -m 750 %{_builddir}/kata-containers/src/runtime/containerd-shim-kata-v2 %{buildroot}/usr/bin/
install -p -m 640 -D %{_builddir}/kata-containers/src/runtime/cli/config/configuration-qemu.toml %{buildroot}/usr/share/defaults/kata-containers/configuration.toml
install -p -m 640 -D %{_builddir}/kata-containers/src/runtime/cli/config/configuration-stratovirt.toml %{buildroot}/usr/share/defaults/kata-containers/configuration-stratovirt.toml
install -p -m 640 -D %{_builddir}/kata-containers/src/runtime/config/configuration-qemu.toml %{buildroot}/usr/share/defaults/kata-containers/configuration.toml
install -p -m 640 ./build/kata-containers-initrd.img %{buildroot}/var/lib/kata/
mkdir -p -m 750 %{buildroot}/usr/share/defaults/kata-containers/
strip %{buildroot}/usr/bin/kata*
@ -98,17 +95,21 @@ strip %{buildroot}/usr/bin/containerd-shim-kata-v2
%files
/usr/bin/kata-runtime
/usr/bin/kata-netmon
/usr/bin/kata-monitor
/usr/bin/containerd-shim-kata-v2
/var/lib/kata/kernel
/var/lib/kata/kata-containers-initrd.img
%config(noreplace) /usr/share/defaults/kata-containers/configuration.toml
%config(noreplace) /usr/share/defaults/kata-containers/configuration-stratovirt.toml
%doc
%changelog
* Tue Feb 2024 Vanient <xidanni1@huawei.com> - 3.2.0-1
- Type:feature
- ID:NA
- SUG:NA
- DESC:update to 3.2.0
* Tue Sep 2023 xiadanni <xiadanni1@huawei.com> - 2.1.0-33
- Type:bugfix
- ID:NA

View File

@ -1,837 +0,0 @@
From f56d66f196bee808526e86df2c3c063a887c6fef Mon Sep 17 00:00:00 2001
From: Wei Gao <gaowei66@huawei.com>
Date: Sat, 7 Aug 2021 10:39:11 +0800
Subject: [PATCH 1/6] runtime: add support of new sandbox hypervisor type
StratoVirt.
Signed-off-by: Wei Gao <gaowei66@huawei.com>
---
src/runtime/pkg/katautils/config.go | 96 +++-
src/runtime/virtcontainers/hypervisor.go | 12 +
src/runtime/virtcontainers/stratovirt.go | 642 +++++++++++++++++++++++
3 files changed, 749 insertions(+), 1 deletion(-)
create mode 100644 src/runtime/virtcontainers/stratovirt.go
diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go
index 6114aa39..f94ac4fd 100644
--- a/src/runtime/pkg/katautils/config.go
+++ b/src/runtime/pkg/katautils/config.go
@@ -50,6 +50,7 @@ const (
clhHypervisorTableType = "clh"
qemuHypervisorTableType = "qemu"
acrnHypervisorTableType = "acrn"
+ stratovirtHypervisorTable = "stratovirt"
// the maximum amount of PCI bridges that can be cold plugged in a VM
maxPCIBridges uint32 = 5
@@ -870,6 +871,96 @@ func newClhHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
}, nil
}
+func newStratovirtHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
+ hypervisor, err := h.path()
+ if err != nil {
+ return vc.HypervisorConfig{}, err
+ }
+
+ kernel, err := h.kernel()
+ if err != nil {
+ return vc.HypervisorConfig{}, err
+ }
+
+ initrd, image, err := h.getInitrdAndImage()
+ if err != nil {
+ return vc.HypervisorConfig{}, err
+ }
+
+ if image != "" && initrd != "" {
+ return vc.HypervisorConfig{},
+ errors.New("having both an image and an initrd defined in the configuration file is not supported")
+ }
+
+ if image == "" && initrd == "" {
+ return vc.HypervisorConfig{},
+ errors.New("either image or initrd must be defined in the configuration file")
+ }
+
+ kernelParams := h.kernelParams()
+ machineType := h.machineType()
+
+ blockDriver, err := h.blockDeviceDriver()
+ if err != nil {
+ return vc.HypervisorConfig{}, err
+ }
+
+ sharedFS, err := h.sharedFS()
+ if err != nil {
+ return vc.HypervisorConfig{}, err
+ }
+
+ if sharedFS == config.VirtioFS && h.VirtioFSDaemon == "" {
+ return vc.HypervisorConfig{},
+ errors.New("cannot enable virtio-fs without daemon path in configuration file")
+ }
+
+ if vSock, err := utils.SupportsVsocks(); !vSock {
+ return vc.HypervisorConfig{}, err
+ }
+
+ return vc.HypervisorConfig{
+ HypervisorPath: hypervisor,
+ HypervisorPathList: h.HypervisorPathList,
+ KernelPath: kernel,
+ InitrdPath: initrd,
+ ImagePath: image,
+ KernelParams: vc.DeserializeParams(strings.Fields(kernelParams)),
+ HypervisorMachineType: machineType,
+ NumVCPUs: h.defaultVCPUs(),
+ DefaultMaxVCPUs: h.defaultMaxVCPUs(),
+ MemorySize: h.defaultMemSz(),
+ MemSlots: h.defaultMemSlots(),
+ MemOffset: h.defaultMemOffset(),
+ EntropySource: h.GetEntropySource(),
+ EntropySourceList: h.EntropySourceList,
+ DefaultBridges: h.defaultBridges(),
+ DisableBlockDeviceUse: h.DisableBlockDeviceUse,
+ SharedFS: sharedFS,
+ VirtioFSDaemon: h.VirtioFSDaemon,
+ VirtioFSDaemonList: h.VirtioFSDaemonList,
+ VirtioFSCacheSize: h.VirtioFSCacheSize,
+ VirtioFSCache: h.defaultVirtioFSCache(),
+ VirtioFSExtraArgs: h.VirtioFSExtraArgs,
+ FileBackedMemRootDir: h.FileBackedMemRootDir,
+ FileBackedMemRootList: h.FileBackedMemRootList,
+ Mlock: !h.Swap,
+ Debug: h.Debug,
+ DisableNestingChecks: h.DisableNestingChecks,
+ BlockDeviceDriver: blockDriver,
+ BlockDeviceCacheSet: h.BlockDeviceCacheSet,
+ BlockDeviceCacheDirect: h.BlockDeviceCacheDirect,
+ BlockDeviceCacheNoflush: h.BlockDeviceCacheNoflush,
+ EnableIOThreads: h.EnableIOThreads,
+ DisableVhostNet: h.DisableVhostNet,
+ EnableVhostUserStore: h.EnableVhostUserStore,
+ VhostUserStorePath: h.vhostUserStorePath(),
+ VhostUserStorePathList: h.VhostUserStorePathList,
+ GuestHookPath: h.guestHookPath(),
+ EnableAnnotations: h.EnableAnnotations,
+ }, nil
+}
+
func newFactoryConfig(f factory) (oci.FactoryConfig, error) {
if f.TemplatePath == "" {
f.TemplatePath = defaultTemplatePath
@@ -903,6 +994,9 @@ func updateRuntimeConfigHypervisor(configPath string, tomlConf tomlConfig, confi
case clhHypervisorTableType:
config.HypervisorType = vc.ClhHypervisor
hConfig, err = newClhHypervisorConfig(hypervisor)
+ case stratovirtHypervisorTable:
+ config.HypervisorType = vc.StratovirtHypervisor
+ hConfig, err = newStratovirtHypervisorConfig(hypervisor)
}
if err != nil {
@@ -1287,7 +1381,7 @@ func checkHypervisorConfig(config vc.HypervisorConfig) error {
memSizeMB := int64(config.MemorySize)
if memSizeMB == 0 {
- return errors.New("VM memory cannot be zero")
+ return errors.New(fmt.Sprintf("The VM memory cannot be zero, %s", config.ImagePath))
}
mb := int64(1024 * 1024)
diff --git a/src/runtime/virtcontainers/hypervisor.go b/src/runtime/virtcontainers/hypervisor.go
index 767215b6..615baa80 100644
--- a/src/runtime/virtcontainers/hypervisor.go
+++ b/src/runtime/virtcontainers/hypervisor.go
@@ -44,6 +44,9 @@ const (
// ClhHypervisor is the ICH hypervisor.
ClhHypervisor HypervisorType = "clh"
+ // StratovirtHypervisor is the StratoVirt hypervisor
+ StratovirtHypervisor HypervisorType = "stratovirt"
+
// MockHypervisor is a mock hypervisor for testing purposes
MockHypervisor HypervisorType = "mock"
)
@@ -159,6 +162,9 @@ func (hType *HypervisorType) Set(value string) error {
case "clh":
*hType = ClhHypervisor
return nil
+ case "stratovirt":
+ *hType = StratovirtHypervisor
+ return nil
case "mock":
*hType = MockHypervisor
return nil
@@ -178,6 +184,8 @@ func (hType *HypervisorType) String() string {
return string(AcrnHypervisor)
case ClhHypervisor:
return string(ClhHypervisor)
+ case StratovirtHypervisor:
+ return string(StratovirtHypervisor)
case MockHypervisor:
return string(MockHypervisor)
default:
@@ -207,6 +215,10 @@ func newHypervisor(hType HypervisorType) (hypervisor, error) {
return &cloudHypervisor{
store: store,
}, nil
+ case StratovirtHypervisor:
+ return &stratovirt{
+ store: store,
+ }, nil
case MockHypervisor:
return &mockHypervisor{}, nil
default:
diff --git a/src/runtime/virtcontainers/stratovirt.go b/src/runtime/virtcontainers/stratovirt.go
new file mode 100644
index 00000000..4fec96d3
--- /dev/null
+++ b/src/runtime/virtcontainers/stratovirt.go
@@ -0,0 +1,642 @@
+package virtcontainers
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "syscall"
+ "time"
+
+ govmmQemu "github.com/kata-containers/govmm/qemu"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+
+ "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
+ persistapi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/api"
+ "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
+ "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
+ "go.opentelemetry.io/otel"
+ otelLabel "go.opentelemetry.io/otel/label"
+ otelTrace "go.opentelemetry.io/otel/trace"
+)
+
+const defaultDummyMac = "22:33:44:aa:bb:"
+const mmioBlkCount = 4
+const mmioNetCount = 2
+const randomDevice = "/dev/urandom"
+
+type stratovirtDev struct {
+ dev interface{}
+ devType deviceType
+}
+
+type stratovirt struct {
+ id string
+ ctx context.Context
+ sandbox *Sandbox
+ store persistapi.PersistDriver
+ config HypervisorConfig
+ pid int
+ consolePath string
+ socketPath string
+ qmpMonitorCh qmpChannel
+ devices []stratovirtDev
+ HotpluggedVCPUs []CPUDevice
+ mmioBlkSlots [mmioBlkCount]bool
+ mmioNetSlots [mmioNetCount]bool
+}
+
+func (s *stratovirt) Logger() *logrus.Entry {
+ return virtLog.WithField("subsystem", "stratovirt")
+}
+
+func (s *stratovirt) trace(parent context.Context, name string) (otelTrace.Span, context.Context) {
+ if parent == nil {
+ s.Logger().WithField("type", "bug").Error("trace called before context set")
+ parent = context.Background()
+ }
+
+ tracer := otel.Tracer("kata")
+ ctx, span := tracer.Start(parent, name, otelTrace.WithAttributes(otelLabel.String("source", "runtime"), otelLabel.String("package", "virtcontainers"), otelLabel.String("subsystem", "hypervisor"), otelLabel.String("type", "stratovirt"), otelLabel.String("sandbox_id", s.id)))
+
+ return span, ctx
+}
+
+func (s *stratovirt) getKernelCmdLine(useImage bool) string {
+ var params []string
+
+ if useImage {
+ params = append(params, "root=/dev/vda")
+ }
+
+ params = append(params, "pci=off")
+ params = append(params, "reboot=k")
+ params = append(params, "panic=1")
+ params = append(params, "iommu=off")
+ params = append(params, "acpi=off")
+ params = append(params, "quiet")
+ params = append(params, "agent.use_vsock=true")
+ params = append(params, "random.trust_cpu=on")
+ params = append(params, "rw")
+ params = append(params, SerializeParams(s.config.KernelParams, "=")...)
+
+ return strings.Join(params, " ")
+}
+
+func (s *stratovirt) hypervisorConfig() HypervisorConfig {
+ return s.config
+}
+
+func (s *stratovirt) createSandbox(ctx context.Context, id string, networkNS NetworkNamespace, hypervisorConfig *HypervisorConfig) error {
+ s.ctx = ctx
+
+ var span otelTrace.Span
+ span, _ = s.trace(ctx, "createSandbox")
+ defer span.End()
+
+ s.id = id
+ s.config = *hypervisorConfig
+
+ s.socketPath = filepath.Join(s.store.RunVMStoragePath(), id, "qmp.sock")
+ s.consolePath = filepath.Join(s.store.RunVMStoragePath(), id, "console.sock")
+ s.qmpMonitorCh = qmpChannel{
+ ctx: s.ctx,
+ path: s.socketPath,
+ }
+
+ return nil
+}
+
+func (s *stratovirt) waitSandBoxStarted(timeout int) error {
+ timeStart := time.Now()
+ for {
+ err := s.qmpSetup()
+ if err == nil {
+ break
+ }
+
+ if int(time.Since(timeStart).Seconds()) > timeout {
+ return fmt.Errorf("Failed to connect to StratoVirt instance (timeout %ds): %v", timeout, err)
+ }
+
+ time.Sleep(time.Duration(50) * time.Millisecond)
+ }
+
+ if err := s.qmpMonitorCh.qmp.ExecuteQMPCapabilities(s.qmpMonitorCh.ctx); err != nil {
+ s.Logger().WithError(err).Error(qmpCapErrMsg)
+ return err
+ }
+
+ return nil
+}
+
+func (s *stratovirt) startSandbox(ctx context.Context, timeout int) error {
+ span, _ := s.trace(ctx, "startSandbox")
+ defer span.End()
+
+ var params []string
+ var use_image bool
+ params = append(params, "-name", fmt.Sprintf("sandbox-%s", s.id))
+ params = append(params, "-qmp", fmt.Sprintf("unix:%s,server,nowait", s.socketPath))
+
+ if kernelPath, err := s.config.KernelAssetPath(); err == nil {
+ params = append(params, "-kernel", kernelPath)
+ }
+
+ initrdPath, err := s.config.InitrdAssetPath()
+ if err != nil {
+ return err
+ }
+
+ if initrdPath == "" {
+ imagePath, err := s.config.ImageAssetPath()
+ if err != nil {
+ return err
+ }
+ use_image = true
+ s.mmioBlkSlots[0] = true
+ params = append(params, "-device", "virtio-blk-device,drive=rootfs")
+ params = append(params, "-drive", fmt.Sprintf("id=rootfs,file=%s,direct=off", imagePath))
+ } else {
+ use_image = false
+ params = append(params, "-initrd", initrdPath)
+ }
+
+ params = append(params, "-append", s.getKernelCmdLine(use_image))
+ params = append(params, "-smp", fmt.Sprintf("%d", s.config.NumVCPUs))
+ params = append(params, "-m", fmt.Sprintf("%d", uint64(s.config.MemorySize)))
+ params = append(params, "-device", "virtio-serial-device")
+ params = append(params, "-device", "virtconsole,chardev=charconsole0,id=virtioconsole0")
+ params = append(params, "-object", fmt.Sprintf("rng-random,id=objrng0,filename=%s", randomDevice))
+ params = append(params, "-device", "virtio-rng-device,rng=objrng0")
+ params = append(params, "-chardev", fmt.Sprintf("socket,id=charconsole0,path=%s,server,nowait", s.consolePath))
+ params = append(params, "-pidfile", filepath.Join(s.store.RunVMStoragePath(), s.id, "pid"))
+
+ // add devices to cmdline
+ for _, d := range s.devices {
+ switch v := d.dev.(type) {
+ case Endpoint:
+ name := v.Name()
+ mac := v.HardwareAddr()
+ tapName := v.NetworkPair().TapInterface.TAPIface.Name
+ params = append(params, "-device", fmt.Sprintf("virtio-net-device,netdev=%s,id=%s,mac=%s", name, name, mac))
+ params = append(params, "-netdev", fmt.Sprintf("tap,id=%s,ifname=%s", name, tapName))
+ case config.BlockDrive:
+ id := v.ID
+ path := v.File
+ params = append(params, "-device", fmt.Sprintf("virtio-blk-device, drive=%s", id))
+ params = append(params, "-drive", fmt.Sprintf("id=%s,file=%s", id, path))
+ case types.VSock:
+ v.VhostFd.Close()
+ params = append(params, "-device", fmt.Sprintf("vhost-vsock-device,id=vsock-id,guest-cid=%d", v.ContextID))
+ default:
+ s.Logger().Error("Adding device type is unsupported")
+ }
+ }
+
+ // daemonize
+ params = append(params, "-daemonize")
+
+ // append logfile only on debug
+ if s.config.Debug {
+ dir := filepath.Join(s.store.RunVMStoragePath(), s.id)
+ params = append(params, "-D", fmt.Sprintf("%s/stratovirt.log", dir))
+ }
+
+ dir := filepath.Join(s.store.RunVMStoragePath(), s.id)
+ err = os.MkdirAll(dir, DirMode)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ if err != nil {
+ if err := os.RemoveAll(dir); err != nil {
+ s.Logger().WithError(err).Error("Fail to clean up vm dir %s", dir)
+ }
+ }
+ }()
+
+ binPath, err := s.config.HypervisorAssetPath()
+ if err != nil {
+ s.Logger().WithField("Fail to get hypervisor bin path", err).Error()
+ return err
+ }
+
+ cmd := exec.CommandContext(s.ctx, binPath, params...)
+ s.Logger().Info("StratoVirt start with params: ", cmd)
+
+ if err := cmd.Start(); err != nil {
+ s.Logger().WithField("Error starting hypervisor, please check the params", err).Error()
+ return err
+ }
+ s.pid = cmd.Process.Pid
+
+ if err = s.waitSandBoxStarted(timeout); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (s *stratovirt) stopSandbox(ctx context.Context, force bool) error {
+ span, _ := s.trace(ctx, "stopSandbox")
+ defer span.End()
+
+ defer func() {
+ dir := filepath.Join(s.store.RunVMStoragePath(), s.id)
+ link, _ := filepath.EvalSymlinks(dir)
+
+ if err := os.RemoveAll(dir); err != nil {
+ s.Logger().WithError(err).Warnf("Failed to clean up vm dir %s", dir)
+ }
+
+ if link != dir && link != "" {
+ if err := os.RemoveAll(link); err != nil {
+ s.Logger().WithError(err).WithField("link", link).Warn("Failed to remove vm path link %s", link)
+ }
+ }
+ }()
+
+ if !force {
+ err := s.qmpSetup()
+ if err != nil {
+ return err
+ }
+
+ err = s.qmpMonitorCh.qmp.ExecuteQuit(s.qmpMonitorCh.ctx)
+ if err != nil {
+ s.Logger().WithError(err).Error("Fail to execute qmp: QUIT")
+ return err
+ }
+ } else {
+ if s.pid > 0 {
+ syscall.Kill(s.pid, syscall.SIGKILL)
+ }
+ }
+ return nil
+}
+
+func (s *stratovirt) pauseSandbox(ctx context.Context) error {
+ return nil
+}
+
+func (s *stratovirt) saveSandbox() error {
+ return nil
+}
+
+func (s *stratovirt) resumeSandbox(ctx context.Context) error {
+ return nil
+}
+
+func (s *stratovirt) addDevice(ctx context.Context, devInfo interface{}, devType deviceType) error {
+ span, _ := s.trace(ctx, "addDevice")
+ defer span.End()
+
+ dev := stratovirtDev{
+ dev: devInfo,
+ devType: devType,
+ }
+ s.devices = append(s.devices, dev)
+
+ return nil
+}
+
+func (s *stratovirt) getDevSlot(Name string, isPut bool) (slot int, err error) {
+ Name = filepath.Base(strings.ToLower(Name))
+
+ if strings.HasPrefix(Name, "eth") {
+ idxStr := strings.TrimPrefix(Name, "eth")
+ if idxStr == Name {
+ return 0, fmt.Errorf("Could not parse idx from Name %q", Name)
+ }
+
+ idx, err := strconv.Atoi(idxStr)
+ if err != nil {
+ return 0, fmt.Errorf("Could not convert to int from Str %q", idxStr)
+ }
+
+ if !isPut && s.mmioNetSlots[idx] {
+ return 0, fmt.Errorf("GetDevSlot failed, slot is being used %q", idxStr)
+ }
+ s.mmioNetSlots[idx] = !isPut
+
+ return idx, nil
+ } else if strings.HasPrefix(Name, "vd") {
+ charStr := strings.TrimPrefix(Name, "vd")
+ if charStr == Name {
+ return 0, fmt.Errorf("Could not parse idx from Name %q", Name)
+ }
+
+ char := []rune(charStr)
+ idx := int(char[0] - 'a')
+
+ if !isPut && s.mmioBlkSlots[idx] {
+ return 0, fmt.Errorf("GetDevSlot failed, slot is being used %q", charStr)
+ }
+ s.mmioBlkSlots[idx] = !isPut
+
+ return idx, nil
+ }
+
+ return 0, fmt.Errorf("GetDevSlot failed, Name is invalid %q", Name)
+}
+
+func (s *stratovirt) hotplugNet(endpoint Endpoint, op operation) (err error) {
+ err = s.qmpSetup()
+ if err != nil {
+ return err
+ }
+ var tap TapInterface
+
+ switch endpoint.Type() {
+ case VethEndpointType:
+ drive := endpoint.(*VethEndpoint)
+ tap = drive.NetPair.TapInterface
+ case TapEndpointType:
+ drive := endpoint.(*TapEndpoint)
+ tap = drive.TapInterface
+ default:
+ return fmt.Errorf("Endpoint is not supported")
+ }
+
+ switch op {
+ case addDevice:
+ var (
+ VMFdNames []string
+ VhostFdNames []string
+ )
+ for i, VMFd := range tap.VMFds {
+ fdName := fmt.Sprintf("fd%d", i)
+ if err := s.qmpMonitorCh.qmp.ExecuteGetFD(s.qmpMonitorCh.ctx, fdName, VMFd); err != nil {
+ return err
+ }
+ VMFdNames = append(VMFdNames, fdName)
+ }
+ for i, VhostFd := range tap.VhostFds {
+ fdName := fmt.Sprintf("vhostfd%d", i)
+ if err := s.qmpMonitorCh.qmp.ExecuteGetFD(s.qmpMonitorCh.ctx, fdName, VhostFd); err != nil {
+ return err
+ }
+ VhostFd.Close()
+ VhostFdNames = append(VhostFdNames, fdName)
+ }
+
+ slot, err := s.getDevSlot(endpoint.Name(), false)
+ if err != nil {
+ return fmt.Errorf("Could not get unused slot for %q", endpoint.Name())
+ }
+
+ if len(VMFdNames) != 0 || len(VhostFdNames) != 0 {
+ if err := s.qmpMonitorCh.qmp.ExecuteNetdevAddByFds(s.qmpMonitorCh.ctx, "tap", tap.ID, VMFdNames, VhostFdNames); err != nil {
+ s.getDevSlot(endpoint.Name(), true)
+ return err
+ }
+ } else {
+ if err := s.qmpMonitorCh.qmp.ExecuteNetdevAdd(s.qmpMonitorCh.ctx, "tap", tap.ID, tap.TAPIface.Name, "no", "no", 0); err != nil {
+ s.getDevSlot(endpoint.Name(), true)
+ return err
+ }
+ }
+ if err := s.qmpMonitorCh.qmp.ExecuteNetPCIDeviceAdd(s.qmpMonitorCh.ctx, tap.Name, tap.ID, endpoint.HardwareAddr(), fmt.Sprintf("%d", slot), "", "", 0, false); err != nil {
+ s.getDevSlot(endpoint.Name(), true)
+ return err
+ }
+ case removeDevice:
+ if err := s.qmpMonitorCh.qmp.ExecuteDeviceDel(s.qmpMonitorCh.ctx, tap.ID); err != nil {
+ return err
+ }
+ if err := s.qmpMonitorCh.qmp.ExecuteNetdevDel(s.qmpMonitorCh.ctx, tap.ID); err != nil {
+ return err
+ }
+ default:
+ return fmt.Errorf("Operation is not supported")
+ }
+
+ return nil
+}
+
+func (s *stratovirt) hotplugBlk(drive *config.BlockDrive, op operation) (err error) {
+ err = s.qmpSetup()
+ if err != nil {
+ return err
+ }
+
+ switch op {
+ case addDevice:
+ driver := "virtio-blk-pci"
+ slot, err := s.getDevSlot(drive.VirtPath, false)
+ if err != nil {
+ return fmt.Errorf("Could not get unused slot for %q", drive.VirtPath)
+ }
+
+ if err := s.qmpMonitorCh.qmp.ExecuteBlockdevAdd(s.qmpMonitorCh.ctx, drive.File, drive.ID, false); err != nil {
+ s.getDevSlot(drive.VirtPath, true)
+ return err
+ }
+
+ if err := s.qmpMonitorCh.qmp.ExecutePCIDeviceAdd(s.qmpMonitorCh.ctx, drive.ID, drive.ID, driver, fmt.Sprintf("%d", slot), "", "", 0, true, false); err != nil {
+ s.getDevSlot(drive.VirtPath, true)
+ return err
+ }
+ case removeDevice:
+ if err := s.qmpMonitorCh.qmp.ExecuteDeviceDel(s.qmpMonitorCh.ctx, drive.ID); err != nil {
+ return err
+ }
+ if err := s.qmpMonitorCh.qmp.ExecuteBlockdevDel(s.qmpMonitorCh.ctx, drive.ID); err != nil {
+ return err
+ }
+
+ s.getDevSlot(drive.VirtPath, true)
+ default:
+ return fmt.Errorf("Operation is not supported")
+ }
+
+ return nil
+}
+
+func (s *stratovirt) hotplugAddDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
+ span, _ := s.trace(ctx, "hotplugAddDevice")
+ defer span.End()
+
+ switch devType {
+ case netDev:
+ return nil, s.hotplugNet(devInfo.(Endpoint), addDevice)
+ case blockDev:
+ return nil, s.hotplugBlk(devInfo.(*config.BlockDrive), addDevice)
+ default:
+ return nil, fmt.Errorf("Hotplug add device failed: unsupported device type '%v'", devType)
+ }
+}
+
+func (s *stratovirt) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
+ span, _ := s.trace(ctx, "hotplugRemoveDevice")
+ defer span.End()
+
+ switch devType {
+ case netDev:
+ return nil, s.hotplugNet(devInfo.(Endpoint), removeDevice)
+ case blockDev:
+ return nil, s.hotplugBlk(devInfo.(*config.BlockDrive), removeDevice)
+ default:
+ return nil, fmt.Errorf("Hotplug remove device: unsupported device type '%v'", devType)
+ }
+}
+
+func (s *stratovirt) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, memoryDevice, error) {
+ return 0, memoryDevice{}, nil
+}
+
+func (s *stratovirt) resizeVCPUs(ctx context.Context, reqVCPUs uint32) (currentVCPUs uint32, newVCPUs uint32, err error) {
+ return 0, 0, nil
+}
+
+func (s *stratovirt) getSandboxConsole(ctx context.Context, id string) (string, string, error) {
+ span, _ := s.trace(ctx, "getSandboxConsole")
+ defer span.End()
+
+ var consolePath string
+ if s.config.Debug {
+ consolePath = s.consolePath
+ } else {
+ consolePath = ""
+ }
+ consoleURL, err := utils.BuildSocketPath(consolePath)
+ if err != nil {
+ return consoleProtoUnix, "", err
+ }
+ return consoleProtoUnix, consoleURL, nil
+
+}
+
+func (s *stratovirt) disconnect(ctx context.Context) {
+ span, _ := s.trace(ctx, "disconnect")
+ defer span.End()
+
+ s.qmpTeardown()
+}
+
+func (s *stratovirt) capabilities(ctx context.Context) types.Capabilities {
+ span, _ := s.trace(ctx, "capabilities")
+ defer span.End()
+
+ var caps types.Capabilities
+ caps.SetBlockDeviceHotplugSupport()
+
+ return caps
+}
+
+func (s *stratovirt) qmpTeardown() {
+ if s.qmpMonitorCh.qmp != nil {
+ s.qmpMonitorCh.qmp.Shutdown()
+ <-s.qmpMonitorCh.disconn
+ s.qmpMonitorCh.qmp = nil
+ s.qmpMonitorCh.disconn = nil
+ }
+}
+
+func (s *stratovirt) qmpSetup() error {
+ s.qmpTeardown()
+
+ cfg := govmmQemu.QMPConfig{Logger: newQMPLogger()}
+
+ // Auto-closed by QMPStart().
+ disconnectCh := make(chan struct{})
+
+ qmp, _, err := govmmQemu.QMPStart(s.qmpMonitorCh.ctx, s.qmpMonitorCh.path, cfg, disconnectCh)
+ if err != nil {
+ s.Logger().WithError(err).Error("Failed to connect to StratoVirt instance")
+ return err
+ }
+
+ s.qmpMonitorCh.qmp = qmp
+ s.qmpMonitorCh.disconn = disconnectCh
+
+ return nil
+}
+
+func (s *stratovirt) getThreadIDs(ctx context.Context) (vcpuThreadIDs, error) {
+ span, _ := s.trace(ctx, "getThreadIDs")
+ defer span.End()
+
+ tid := vcpuThreadIDs{}
+ if err := s.qmpSetup(); err != nil {
+ return tid, err
+ }
+
+ cpuInfos, err := s.qmpMonitorCh.qmp.ExecQueryCpus(s.qmpMonitorCh.ctx)
+ if err != nil {
+ s.Logger().WithError(err).Error("Failed to query cpu infos")
+ return tid, err
+ }
+
+ tid.vcpus = make(map[int]int, len(cpuInfos))
+ for _, i := range cpuInfos {
+ if i.ThreadID > 0 {
+ tid.vcpus[i.CPU] = i.ThreadID
+ }
+ }
+ return tid, nil
+}
+
+func (s *stratovirt) cleanup(ctx context.Context) error {
+ span, _ := s.trace(ctx, "cleanup")
+ defer span.End()
+
+ s.qmpTeardown()
+
+ return nil
+}
+
+func (s *stratovirt) getPids() []int {
+ return []int{s.pid}
+}
+
+func (s *stratovirt) getVirtioFsPid() *int {
+ return nil
+}
+
+func (s *stratovirt) fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig, j []byte) error {
+ return errors.New("stratovirt is not supported by VM cache")
+}
+
+func (s *stratovirt) toGrpc(ctx context.Context) ([]byte, error) {
+ return nil, errors.New("stratovirt is not supported by VM cache")
+}
+
+func (s *stratovirt) check() error {
+ if err := syscall.Kill(s.pid, syscall.Signal(0)); err != nil {
+ return errors.Wrapf(err, "Failed to ping StratoVirt process")
+ }
+
+ return nil
+}
+
+func (s *stratovirt) generateSocket(id string) (interface{}, error) {
+ return generateVMSocket(id, s.store.RunVMStoragePath())
+}
+
+func (s *stratovirt) isRateLimiterBuiltin() bool {
+ return true
+}
+
+func (s *stratovirt) save() (p persistapi.HypervisorState) {
+ pids := s.getPids()
+ p.Pid = pids[0]
+ p.Type = string(StratovirtHypervisor)
+ return
+}
+
+func (s *stratovirt) load(p persistapi.HypervisorState) {
+ s.pid = p.Pid
+
+ return
+}
+
+func (s *stratovirt) setSandbox(sandbox *Sandbox) {
+ s.sandbox = sandbox
+ return
+}
--
2.21.1 (Apple Git-122.3)

View File

@ -1,174 +0,0 @@
From 1ffd95187a61582e858dd37c0ab434d3159a0f52 Mon Sep 17 00:00:00 2001
From: Wei Gao <gaowei66@huawei.com>
Date: Mon, 9 Aug 2021 14:26:35 +0800
Subject: [PATCH 2/6] agent: add support of new sandbox hypervisor kind
StratoVirt.
1. add new grpc interface `UpdateInterfaceHwAddrByName`.
2. comment out rescan_pci temporarily.
Signed-off-by: Wei Gao <gaowei66@huawei.com>
---
src/agent/protocols/protos/agent.proto | 5 +++
src/agent/src/netlink.rs | 31 ++++++++++++++++
src/agent/src/rpc.rs | 51 +++++++++++++++++++++++++-
3 files changed, 85 insertions(+), 2 deletions(-)
diff --git a/src/agent/protocols/protos/agent.proto b/src/agent/protocols/protos/agent.proto
index 6cbf5a28..e00f5c63 100644
--- a/src/agent/protocols/protos/agent.proto
+++ b/src/agent/protocols/protos/agent.proto
@@ -46,6 +46,7 @@ service AgentService {
// networking
rpc UpdateInterface(UpdateInterfaceRequest) returns (types.Interface);
+ rpc UpdateInterfaceHwAddrByName(UpdateInterfaceHwAddrByNameRequest) returns (types.Interface);
rpc UpdateRoutes(UpdateRoutesRequest) returns (Routes);
rpc ListInterfaces(ListInterfacesRequest) returns(Interfaces);
rpc ListRoutes(ListRoutesRequest) returns (Routes);
@@ -308,6 +309,10 @@ message UpdateInterfaceRequest {
types.Interface interface = 1;
}
+message UpdateInterfaceHwAddrByNameRequest {
+ types.Interface interface = 1;
+}
+
message UpdateRoutesRequest {
Routes routes = 1;
}
diff --git a/src/agent/src/netlink.rs b/src/agent/src/netlink.rs
index 3ab6dbaa..82632d1b 100644
--- a/src/agent/src/netlink.rs
+++ b/src/agent/src/netlink.rs
@@ -104,6 +104,29 @@ impl Handle {
Ok(())
}
+ pub async fn update_interface_hw_addr_by_name(&mut self, iface: &Interface) -> Result<()> {
+ let link = self.find_link(LinkFilter::Name(&iface.name)).await?;
+
+ // Delete all addresses associated with the link
+ let addresses = self
+ .list_addresses(AddressFilter::LinkIndex(link.index()))
+ .await?;
+ self.delete_addresses(addresses).await?;
+
+ if iface.IPAddresses.len() == 0 {
+ self.enable_link(link.index(), false).await?;
+ }
+
+ // Update hardware mac address
+ let mac_addr = parse_mac_address(iface.get_hwAddr())
+ .with_context(|| format!("Failed to parse MAC address: {}", iface.get_hwAddr()))?;
+ self.link_set_hw_addr(link.index(), mac_addr)
+ .await
+ .with_context(|| format!("Could not set {:?} to {}", mac_addr, link.name()))?;
+
+ Ok(())
+ }
+
pub async fn handle_localhost(&self) -> Result<()> {
let link = self.find_link(LinkFilter::Name("lo")).await?;
self.enable_link(link.index(), true).await?;
@@ -216,6 +239,14 @@ impl Handle {
Ok(())
}
+ async fn link_set_hw_addr(&self, link_index: u32, hw_addr: [u8; 6]) -> Result<()> {
+ let link_req = self.handle.link().set(link_index);
+ let set_req = link_req.address(hw_addr.to_vec());
+ set_req.execute().await?;
+
+ Ok(())
+ }
+
async fn query_routes(
&self,
ip_version: Option<IpVersion>,
diff --git a/src/agent/src/rpc.rs b/src/agent/src/rpc.rs
index 92025af3..2cc1c983 100644
--- a/src/agent/src/rpc.rs
+++ b/src/agent/src/rpc.rs
@@ -40,7 +40,7 @@ use nix::sys::stat;
use nix::unistd::{self, Pid};
use rustjail::process::ProcessOperations;
-use crate::device::{add_devices, rescan_pci_bus, update_device_cgroup};
+use crate::device::{add_devices, update_device_cgroup};
use crate::linux_abi::*;
use crate::metrics::get_metrics;
use crate::mount::{add_storages, remove_mounts, BareMount, STORAGE_HANDLER_LIST};
@@ -123,7 +123,9 @@ impl AgentService {
// re-scan PCI bus
// looking for hidden devices
- rescan_pci_bus().context("Could not rescan PCI bus")?;
+ // FIXME: Comment out this code temporarily, because once the PCIBus is scanned,
+ // the device hot-plug event is lost
+ // rescan_pci_bus().context("Could not rescan PCI bus")?;
// Some devices need some extra processing (the ones invoked with
// --device for instance), and that's what this call is doing. It
@@ -797,6 +799,34 @@ impl protocols::agent_ttrpc::AgentService for AgentService {
Ok(interface)
}
+ async fn update_interface_hw_addr_by_name(
+ &self,
+ _ctx: &TtrpcContext,
+ req: protocols::agent::UpdateInterfaceHwAddrByNameRequest,
+ ) -> ttrpc::Result<Interface> {
+ let interface = req.interface.into_option().ok_or_else(|| {
+ ttrpc_error(
+ ttrpc::Code::INVALID_ARGUMENT,
+ "empty update interface request".to_string(),
+ )
+ })?;
+
+ self.sandbox
+ .lock()
+ .await
+ .rtnl
+ .update_interface_hw_addr_by_name(&interface)
+ .await
+ .map_err(|e| {
+ ttrpc_error(
+ ttrpc::Code::INTERNAL,
+ format!("update interface hw addr: {:?}", e),
+ )
+ })?;
+
+ Ok(interface)
+ }
+
async fn update_routes(
&self,
_ctx: &TtrpcContext,
@@ -1670,6 +1700,23 @@ mod tests {
assert!(result.is_err(), "expected update interface to fail");
}
+ #[tokio::test]
+ async fn test_update_interface_hw_addr_by_name() {
+ let logger = slog::Logger::root(slog::Discard, o!());
+ let sandbox = Sandbox::new(&logger).unwrap();
+
+ let agent_service = Box::new(AgentService {
+ sandbox: Arc::new(Mutex::new(sandbox)),
+ });
+
+ let req = protocols::agent::UpdateInterfaceHwAddrByNameRequest::default();
+ let ctx = mk_ttrpc_context();
+
+ let result = agent_service.update_interface_hw_addr_by_name(&ctx, req).await;
+
+ assert!(result.is_err(), "expected update interface to fail");
+ }
+
#[tokio::test]
async fn test_update_routes() {
let logger = slog::Logger::root(slog::Discard, o!());
--
2.21.1 (Apple Git-122.3)

View File

@ -1,542 +0,0 @@
From 950c0db14a9a9baccefd83e87893d7f40c2bd13d Mon Sep 17 00:00:00 2001
From: Wei Gao <gaowei66@huawei.com>
Date: Mon, 9 Aug 2021 14:47:19 +0800
Subject: [PATCH 4/6] configuration: add configuration generator for hypervisor
type stratovirt.
Signed-off-by: Wei Gao <gaowei66@huawei.com>
---
src/runtime/.gitignore | 1 +
src/runtime/Makefile | 40 +-
src/runtime/arch/amd64-options.mk | 3 +
src/runtime/arch/arm64-options.mk | 3 +
.../config/configuration-stratovirt.toml.in | 356 ++++++++++++++++++
5 files changed, 402 insertions(+), 1 deletion(-)
create mode 100644 src/runtime/cli/config/configuration-stratovirt.toml.in
diff --git a/src/runtime/.gitignore b/src/runtime/.gitignore
index 52b9e4e5..0a630a07 100644
--- a/src/runtime/.gitignore
+++ b/src/runtime/.gitignore
@@ -10,6 +10,7 @@ coverage.html
/cli/config/configuration-fc.toml
/cli/config/configuration-qemu.toml
/cli/config/configuration-clh.toml
+/cli/config/configuration-stratovirt.toml
/cli/config-generated.go
/cli/containerd-shim-kata-v2/config-generated.go
/cli/coverage.html
diff --git a/src/runtime/Makefile b/src/runtime/Makefile
index 4a69c05c..ea2cd296 100644
--- a/src/runtime/Makefile
+++ b/src/runtime/Makefile
@@ -74,6 +74,7 @@ QEMUBINDIR := $(PREFIXDEPS)/bin
CLHBINDIR := $(PREFIXDEPS)/bin
FCBINDIR := $(PREFIXDEPS)/bin
ACRNBINDIR := $(PREFIXDEPS)/bin
+STRATOVIRTBINDIR := $(PREFIXDEPS)/bin
SYSCONFDIR := /etc
LOCALSTATEDIR := /var
@@ -93,6 +94,7 @@ GENERATED_VARS = \
CONFIG_QEMU_IN \
CONFIG_CLH_IN \
CONFIG_FC_IN \
+ CONFIG_STRATOVIRT_IN \
$(USER_VARS)
SCRIPTS += $(COLLECT_SCRIPT)
SCRIPTS_DIR := $(BINDIR)
@@ -116,12 +118,13 @@ HYPERVISOR_ACRN = acrn
HYPERVISOR_FC = firecracker
HYPERVISOR_QEMU = qemu
HYPERVISOR_CLH = cloud-hypervisor
+HYPERVISOR_STRATOVIRT = stratovirt
# Determines which hypervisor is specified in $(CONFIG_FILE).
DEFAULT_HYPERVISOR ?= $(HYPERVISOR_QEMU)
# List of hypervisors this build system can generate configuration for.
-HYPERVISORS := $(HYPERVISOR_ACRN) $(HYPERVISOR_FC) $(HYPERVISOR_QEMU) $(HYPERVISOR_CLH)
+HYPERVISORS := $(HYPERVISOR_ACRN) $(HYPERVISOR_FC) $(HYPERVISOR_QEMU) $(HYPERVISOR_CLH) $(HYPERVISOR_STRATOVIRT)
QEMUPATH := $(QEMUBINDIR)/$(QEMUCMD)
QEMUVALIDHYPERVISORPATHS := [\"$(QEMUPATH)\"]
@@ -141,6 +144,9 @@ ACRNVALIDHYPERVISORPATHS := [\"$(ACRNPATH)\"]
ACRNCTLPATH := $(ACRNBINDIR)/$(ACRNCTLCMD)
ACRNVALIDCTLPATHS := [\"$(ACRNCTLPATH)\"]
+STRATOVIRTPATH = $(STRATOVIRTBINDIR)/$(STRATOVIRTCMD)
+STRATOVIRTVALIDHYPERVISORPATHS := [\"$(STRATOVIRTPATH)\"]
+
NETMONCMD := $(BIN_PREFIX)-netmon
NETMONPATH := $(PKGLIBEXECDIR)/$(NETMONCMD)
@@ -267,6 +273,29 @@ ifneq (,$(CLHCMD))
KERNELPATH_CLH = $(KERNELDIR)/$(KERNEL_NAME_CLH)
endif
+ifneq (,$(STRATOVIRTCMD))
+ KNOWN_HYPERVISORS += $(HYPERVISOR_STRATOVIRT)
+
+ CONFIG_FILE_STRATOVIRT = configuration-stratovirt.toml
+ CONFIG_STRATOVIRT = $(CLI_DIR)/config/$(CONFIG_FILE_STRATOVIRT)
+ CONFIG_STRATOVIRT_IN = $(CONFIG_STRATOVIRT).in
+
+ CONFIG_PATH_STRATOVIRT = $(abspath $(CONFDIR)/$(CONFIG_FILE_STRATOVIRT))
+ CONFIG_PATHS += $(CONFIG_PATH_STRATOVIRT)
+
+ SYSCONFIG_STRATOVIRT = $(abspath $(SYSCONFDIR)/$(CONFIG_FILE_STRATOVIRT))
+ SYSCONFIG_PATHS += $(SYSCONFIG_STRATOVIRT)
+
+ CONFIGS += $(CONFIG_STRATOVIRT)
+
+ # stratovirt-specific options (all should be suffixed by "_STRATOVIRT")
+ DEFBLOCKSTORAGEDRIVER_STRATOVIRT := virtio-mmio
+ DEFNETWORKMODEL_STRATOVIRT := none
+ KENRELTYPE_STRATOVIRT = uncompressed
+ KERNEL_NAME_STRATOVIRT = $(call MAKE_KERNEL_NAME,$(KENRELTYPE_STRATOVIRT))
+ KERNELPATH_STRATOVIRT = $(KERNELDIR)/$(KERNEL_NAME_STRATOVIRT)
+endif
+
ifneq (,$(FCCMD))
KNOWN_HYPERVISORS += $(HYPERVISOR_FC)
@@ -363,6 +392,7 @@ USER_VARS += BINDIR
USER_VARS += CONFIG_ACRN_IN
USER_VARS += CONFIG_CLH_IN
USER_VARS += CONFIG_FC_IN
+USER_VARS += CONFIG_STRATOVIRT_IN
USER_VARS += CONFIG_PATH
USER_VARS += CONFIG_QEMU_IN
USER_VARS += DESTDIR
@@ -382,6 +412,8 @@ USER_VARS += FCPATH
USER_VARS += FCVALIDHYPERVISORPATHS
USER_VARS += FCJAILERPATH
USER_VARS += FCVALIDJAILERPATHS
+USER_VARS += STRATOVIRTPATH
+USER_VARS += STRATOVIRTVALIDHYPERVISORPATHS
USER_VARS += SYSCONFIG
USER_VARS += IMAGENAME
USER_VARS += IMAGEPATH
@@ -395,6 +427,7 @@ USER_VARS += KERNELPATH_ACRN
USER_VARS += KERNELPATH
USER_VARS += KERNELPATH_CLH
USER_VARS += KERNELPATH_FC
+USER_VARS += KERNELPATH_STRATOVIRT
USER_VARS += KERNELVIRTIOFSPATH
USER_VARS += FIRMWAREPATH
USER_VARS += MACHINEACCELERATORS
@@ -434,12 +467,14 @@ USER_VARS += DEFNETWORKMODEL_ACRN
USER_VARS += DEFNETWORKMODEL_CLH
USER_VARS += DEFNETWORKMODEL_FC
USER_VARS += DEFNETWORKMODEL_QEMU
+USER_VARS += DEFNETWORKMODEL_STRATOVIRT
USER_VARS += DEFDISABLEGUESTSECCOMP
USER_VARS += DEFAULTEXPFEATURES
USER_VARS += DEFDISABLEBLOCK
USER_VARS += DEFBLOCKSTORAGEDRIVER_ACRN
USER_VARS += DEFBLOCKSTORAGEDRIVER_FC
USER_VARS += DEFBLOCKSTORAGEDRIVER_QEMU
+USER_VARS += DEFBLOCKSTORAGEDRIVER_STRATOVIRT
USER_VARS += DEFSHAREDFS_QEMU_VIRTIOFS
USER_VARS += DEFVIRTIOFSDAEMON
USER_VARS += DEFVALIDVIRTIOFSDAEMONPATHS
@@ -773,6 +808,9 @@ ifneq (,$(findstring $(HYPERVISOR_FC),$(KNOWN_HYPERVISORS)))
endif
ifneq (,$(findstring $(HYPERVISOR_ACRN),$(KNOWN_HYPERVISORS)))
@printf "\t$(HYPERVISOR_ACRN) hypervisor path (ACRNPATH) : %s\n" $(abspath $(ACRNPATH))
+endif
+ifneq (,$(findstring $(HYPERVISOR_STRATOVIRT),$(KNOWN_HYPERVISORS)))
+ @printf "\t$(HYPERVISOR_STRATOVIRT) hypervisor path (STRATOVIRTPATH) : %s\n" $(abspath $(STRATOVIRTPATH))
endif
@printf "\tassets path (PKGDATADIR) : %s\n" $(abspath $(PKGDATADIR))
@printf "\tshim path (PKGLIBEXECDIR) : %s\n" $(abspath $(PKGLIBEXECDIR))
diff --git a/src/runtime/arch/amd64-options.mk b/src/runtime/arch/amd64-options.mk
index 83af8cc0..ff2af9e6 100644
--- a/src/runtime/arch/amd64-options.mk
+++ b/src/runtime/arch/amd64-options.mk
@@ -23,3 +23,6 @@ ACRNCTLCMD := acrnctl
# cloud-hypervisor binary name
CLHCMD := cloud-hypervisor
+
+# stratovirt binary name
+STRATOVIRTCMD := stratovirt
\ No newline at end of file
diff --git a/src/runtime/arch/arm64-options.mk b/src/runtime/arch/arm64-options.mk
index ad5ef5d4..2ad3f657 100644
--- a/src/runtime/arch/arm64-options.mk
+++ b/src/runtime/arch/arm64-options.mk
@@ -19,3 +19,6 @@ FCJAILERCMD := jailer
# cloud-hypervisor binary name
CLHCMD := cloud-hypervisor
+
+# stratovirt binary name
+STRATOVIRTCMD := stratovirt
\ No newline at end of file
diff --git a/src/runtime/cli/config/configuration-stratovirt.toml.in b/src/runtime/cli/config/configuration-stratovirt.toml.in
new file mode 100644
index 00000000..5c83c3c9
--- /dev/null
+++ b/src/runtime/cli/config/configuration-stratovirt.toml.in
@@ -0,0 +1,356 @@
+# Copyright (c) 2017-2019 Intel Corporation
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+# XXX: WARNING: this file is auto-generated.
+# XXX:
+# XXX: Source file: "@CONFIG_STRATOVIRT_IN@"
+# XXX: Project:
+# XXX: Name: @PROJECT_NAME@
+# XXX: Type: @PROJECT_TYPE@
+
+[hypervisor.stratovirt]
+path = "@STRATOVIRTPATH@"
+kernel = "@KERNELPATH_STRATOVIRT@"
+image = "@IMAGEPATH@"
+
+# List of valid annotation names for the hypervisor
+# Each member of the list is a regular expression, which is the base name
+# of the annotation, e.g. "path" for io.katacontainers.config.hypervisor.path"
+enable_annotations = @DEFENABLEANNOTATIONS@
+
+# List of valid annotations values for the hypervisor
+# Each member of the list is a path pattern as described by glob(3).
+# The default if not set is empty (all annotations rejected.)
+# Your distribution recommends: @STRATOVIRTVALIDHYPERVISORPATHS@
+valid_hypervisor_paths = @STRATOVIRTVALIDHYPERVISORPATHS@
+
+# Optional space-separated list of options to pass to the guest kernel.
+# For example, use `kernel_params = "vsyscall=emulate"` if you are having
+# trouble running pre-2.15 glibc.
+#
+# WARNING: - any parameter specified here will take priority over the default
+# parameter value of the same name used to start the virtual machine.
+# Do not set values here unless you understand the impact of doing so as you
+# may stop the virtual machine from booting.
+# To see the list of default parameters, enable hypervisor debug, create a
+# container and look for 'default-kernel-parameters' log entries.
+kernel_params = "@KERNELPARAMS@"
+
+# Default number of vCPUs per SB/VM:
+# unspecified or 0 --> will be set to @DEFVCPUS@
+# < 0 --> will be set to the actual number of physical cores
+# > 0 <= number of physical cores --> will be set to the specified number
+# > number of physical cores --> will be set to the actual number of physical cores
+default_vcpus = 1
+
+# Default maximum number of vCPUs per SB/VM:
+# unspecified or == 0 --> will be set to the actual number of physical cores or to the maximum number
+# of vCPUs supported by KVM if that number is exceeded
+# > 0 <= number of physical cores --> will be set to the specified number
+# > number of physical cores --> will be set to the actual number of physical cores or to the maximum number
+# of vCPUs supported by KVM if that number is exceeded
+# WARNING: Depending of the architecture, the maximum number of vCPUs supported by KVM is used when
+# the actual number of physical cores is greater than it.
+# WARNING: Be aware that this value impacts the virtual machine's memory footprint and CPU
+# the hotplug functionality. For example, `default_maxvcpus = 240` specifies that until 240 vCPUs
+# can be added to a SB/VM, but the memory footprint will be big. Another example, with
+# `default_maxvcpus = 8` the memory footprint will be small, but 8 will be the maximum number of
+# vCPUs supported by the SB/VM. In general, we recommend that you do not edit this variable,
+# unless you know what are you doing.
+# NOTICE: on arm platform with gicv2 interrupt controller, set it to 8.
+default_maxvcpus = @DEFMAXVCPUS@
+
+# Bridges can be used to hot plug devices.
+# Limitations:
+# * Currently only pci bridges are supported
+# * Until 30 devices per bridge can be hot plugged.
+# * Until 5 PCI bridges can be cold plugged per VM.
+# This limitation could be a bug in the kernel
+# Default number of bridges per SB/VM:
+# unspecified or 0 --> will be set to @DEFBRIDGES@
+# > 1 <= 5 --> will be set to the specified number
+# > 5 --> will be set to 5
+default_bridges = @DEFBRIDGES@
+
+# Default memory size in MiB for SB/VM.
+# If unspecified then it will be set @DEFMEMSZ@ MiB.
+default_memory = @DEFMEMSZ@
+#
+# Default memory slots per SB/VM.
+# If unspecified then it will be set @DEFMEMSLOTS@.
+# This is will determine the times that memory will be hotadded to sandbox/VM.
+# memory_slots = @DEFMEMSLOTS@
+
+# The size in MiB will be plused to max memory of hypervisor.
+# It is the memory address space for the NVDIMM devie.
+# If set block storage driver (block_device_driver) to "nvdimm",
+# should set memory_offset to the size of block device.
+# Default 0
+# memory_offset = 0
+
+# Disable block device from being used for a container's rootfs.
+# In case of a storage driver like devicemapper where a container's
+# root file system is backed by a block device, the block device is passed
+# directly to the hypervisor for performance reasons.
+# This flag prevents the block device from being passed to the hypervisor,
+# 9pfs is used instead to pass the rootfs.
+disable_block_device_use = @DEFDISABLEBLOCK@
+
+# Block storage driver to be used for the hypervisor in case the container
+# rootfs is backed by a block device. This is virtio-scsi, virtio-blk
+# or nvdimm.
+block_device_driver = "@DEFBLOCKSTORAGEDRIVER_STRATOVIRT@"
+
+# Specifies cache-related options will be set to block devices or not.
+# Default false
+#block_device_cache_set = true
+
+# Specifies cache-related options for block devices.
+# Denotes whether use of O_DIRECT (bypass the host page cache) is enabled.
+# Default false
+# block_device_cache_direct = true
+
+# Specifies cache-related options for block devices.
+# Denotes whether flush requests for the device are ignored.
+# Default false
+# block_device_cache_noflush = true
+
+# Enable pre allocation of VM RAM, default false
+# Enabling this will result in lower container density
+# as all of the memory will be allocated and locked
+# This is useful when you want to reserve all the memory
+# upfront or in the cases where you want memory latencies
+# to be very predictable
+# Default false
+# enable_mem_prealloc = true
+
+# Enable huge pages for VM RAM, default false
+# Enabling this will result in the VM memory
+# being allocated using huge pages.
+# This is useful when you want to use vhost-user network
+# stacks within the container. This will automatically
+# result in memory pre allocation
+# enable_hugepages = true
+
+# Enable vIOMMU, default false
+# Enabling this will result in the VM having a vIOMMU device
+# This will also add the following options to the kernel's
+# command line: intel_iommu=on,iommu=pt
+# enable_iommu = true
+
+# Enable swap of vm memory. Default false.
+# The behaviour is undefined if mem_prealloc is also set to true
+# enable_swap = true
+
+# This option changes the default hypervisor and kernel parameters
+# to enable debug output where available.
+#
+# Default false
+# enable_debug = true
+
+# Disable the customizations done in the runtime when it detects
+# that it is running on top a VMM. This will result in the runtime
+# behaving as it would when running on bare metal.
+#
+# disable_nesting_checks = true
+
+# This is the msize used for 9p shares. It is the number of bytes
+# used for 9p packet payload.
+# msize_9p =
+
+# VFIO devices are hotplugged on a bridge by default.
+# Enable hotplugging on root bus. This may be required for devices with
+# a large PCI bar, as this is a current limitation with hotplugging on
+# a bridge.
+# Default false
+# hotplug_vfio_on_root_bus = true
+
+#
+# Default entropy source.
+# The path to a host source of entropy (including a real hardware RNG)
+# /dev/urandom and /dev/random are two main options.
+# Be aware that /dev/random is a blocking source of entropy. If the host
+# runs out of entropy, the VMs boot time will increase leading to get startup
+# timeouts.
+# The source of entropy /dev/urandom is non-blocking and provides a
+# generally acceptable source of entropy. It should work well for pretty much
+# all practical purposes.
+# entropy_source= ""
+
+# List of valid annotations values for entropy_source
+# The default if not set is empty (all annotations rejected.)
+# Your distribution recommends: @DEFVALIDENTROPYSOURCES@
+valid_entropy_sources = @DEFVALIDENTROPYSOURCES@
+
+# Path to OCI hook binaries in the *guest rootfs*.
+# This does not affect host-side hooks which must instead be added to
+# the OCI spec passed to the runtime.
+#
+# You can create a rootfs with hooks by customizing the osbuilder scripts:
+# https://github.com/kata-containers/kata-containers/tree/main/tools/osbuilder
+#
+# Hooks must be stored in a subdirectory of guest_hook_path according to their
+# hook type, i.e. "guest_hook_path/{prestart,poststart,poststop}".
+# The agent will scan these directories for executable files and add them, in
+# lexicographical order, to the lifecycle of the guest container.
+# Hooks are executed in the runtime namespace of the guest. See the official documentation:
+# https://github.com/opencontainers/runtime-spec/blob/v1.0.1/config.md#posix-platform-hooks
+# Warnings will be logged if any error is encountered will scanning for hooks,
+# but it will not abort container execution.
+# guest_hook_path = "/usr/share/oci/hooks"
+
+[factory]
+# VM templating support. Once enabled, new VMs are created from template
+# using vm cloning. They will share the same initial kernel, initramfs and
+# agent memory by mapping it readonly. It helps speeding up new container
+# creation and saves a lot of memory if there are many kata containers running
+# on the same host.
+#
+# When disabled, new VMs are created from scratch.
+#
+# Note: Requires "initrd=" to be set ("image=" is not supported).
+#
+# Default false
+#enable_template = true
+
+[agent.@PROJECT_TYPE@]
+# If enabled, make the agent display debug-level messages.
+# (default: disabled)
+#enable_debug = true
+
+# Enable agent tracing.
+#
+# If enabled, the default trace mode is "dynamic" and the
+# default trace type is "isolated". The trace mode and type are set
+# explicity with the `trace_type=` and `trace_mode=` options.
+#
+# Notes:
+#
+# - Tracing is ONLY enabled when `enable_tracing` is set: explicitly
+# setting `trace_mode=` and/or `trace_type=` without setting `enable_tracing`
+# will NOT activate agent tracing.
+#
+# - See https://github.com/kata-containers/agent/blob/master/TRACING.md for
+# full details.
+#
+# (default: disabled)
+#enable_tracing = true
+#
+#trace_mode = "dynamic"
+#trace_type = "isolated"
+
+# Comma separated list of kernel modules and their parameters.
+# These modules will be loaded in the guest kernel using modprobe(8).
+# The following example can be used to load two kernel modules with parameters
+# - kernel_modules=["e1000e InterruptThrottleRate=3000,3000,3000 EEE=1", "i915 enable_ppgtt=0"]
+# The first word is considered as the module name and the rest as its parameters.
+# Container will not be started when:
+# * A kernel module is specified and the modprobe command is not installed in the guest
+# or it fails loading the module.
+# * The module is not available in the guest or it doesn't met the guest kernel
+# requirements, like architecture and version.
+#
+kernel_modules=[]
+
+# Enable debug console.
+
+# If enabled, user can connect guest OS running inside hypervisor
+# through "kata-runtime exec <sandbox-id>" command
+
+#debug_console_enabled = true
+
+# Agent connection dialing timeout value in seconds
+# (default: 30)
+#dial_timeout = 30
+
+[netmon]
+# If enabled, the network monitoring process gets started when the
+# sandbox is created. This allows for the detection of some additional
+# network being added to the existing network namespace, after the
+# sandbox has been created.
+# (default: disabled)
+#enable_netmon = true
+
+# Specify the path to the netmon binary.
+path = "@NETMONPATH@"
+
+# If enabled, netmon messages will be sent to the system log
+# (default: disabled)
+#enable_debug = true
+
+[runtime]
+# If enabled, the runtime will log additional debug messages to the
+# system log
+# (default: disabled)
+#enable_debug = true
+#
+# Internetworking model
+# Determines how the VM should be connected to the
+# the container network interface
+# Options:
+#
+# - macvtap
+# Used when the Container network interface can be bridged using
+# macvtap.
+#
+# - none
+# Used when customize network. Only creates a tap device. No veth pair.
+#
+# - tcfilter
+# Uses tc filter rules to redirect traffic from the network interface
+# provided by plugin to a tap interface connected to the VM.
+#
+internetworking_model="@DEFNETWORKMODEL_STRATOVIRT@"
+
+# disable guest seccomp
+# Determines whether container seccomp profiles are passed to the virtual
+# machine and applied by the kata agent. If set to true, seccomp is not applied
+# within the guest
+# (default: true)
+disable_guest_seccomp=@DEFDISABLEGUESTSECCOMP@
+
+# If enabled, the runtime will create opentracing.io traces and spans.
+# (See https://www.jaegertracing.io/docs/getting-started).
+# (default: disabled)
+#enable_tracing = true
+
+# Set the full url to the Jaeger HTTP Thrift collector.
+# The default if not set will be "http://localhost:14268/api/traces"
+#jaeger_endpoint = ""
+
+# Sets the username to be used if basic auth is required for Jaeger.
+#jaeger_user = ""
+
+# Sets the password to be used if basic auth is required for Jaeger.
+#jaeger_password = ""
+
+# If enabled, the runtime will not create a network namespace for shim and hypervisor processes.
+# This option may have some potential impacts to your host. It should only be used when you know what you're doing.
+# `disable_new_netns` conflicts with `enable_netmon`
+# `disable_new_netns` conflicts with `internetworking_model=tcfilter` and `internetworking_model=macvtap`. It works only
+# with `internetworking_model=none`. The tap device will be in the host network namespace and can connect to a bridge
+# (like OVS) directly.
+# If you are using docker, `disable_new_netns` only works with `docker run --net=none`
+# (default: false)
+#disable_new_netns = true
+
+# if enable, the runtime will add all the kata processes inside one dedicated cgroup.
+# The container cgroups in the host are not created, just one single cgroup per sandbox.
+# The runtime caller is free to restrict or collect cgroup stats of the overall Kata sandbox.
+# The sandbox cgroup path is the parent cgroup of a container with the PodSandbox annotation.
+# The sandbox cgroup is constrained if there is no container type annotation.
+# See: https://godoc.org/github.com/kata-containers/runtime/virtcontainers#ContainerType
+sandbox_cgroup_only=@DEFSANDBOXCGROUPONLY@
+
+# Enabled experimental feature list, format: ["a", "b"].
+# Experimental features are features not stable enough for production,
+# they may break compatibility, and are prepared for a big version bump.
+# Supported experimental features:
+# (default: [])
+experimental=@DEFAULTEXPFEATURES@
+
+# If enabled, user can run pprof tools with shim v2 process through kata-monitor.
+# (default: false)
+# enable_pprof = true
--
2.21.1 (Apple Git-122.3)

View File

@ -1,655 +0,0 @@
From 45c8e108497eb93d69afd38e6281b837e65cf3ec Mon Sep 17 00:00:00 2001
From: Wei Gao <gaowei66@huawei.com>
Date: Mon, 9 Aug 2021 14:55:41 +0800
Subject: [PATCH 5/6] runtime: add the secure component "ozone" support for
hypervisor type stratovirt.
Signed-off-by: Wei Gao <gaowei66@huawei.com>
---
src/runtime/Makefile | 4 +
src/runtime/arch/amd64-options.mk | 4 +-
src/runtime/arch/arm64-options.mk | 4 +-
.../config/configuration-stratovirt.toml.in | 10 +
.../pkg/katautils/config-settings.go.in | 1 +
src/runtime/pkg/katautils/config.go | 18 +
src/runtime/virtcontainers/hypervisor.go | 3 +
src/runtime/virtcontainers/persist.go | 1 +
.../virtcontainers/persist/api/config.go | 3 +
src/runtime/virtcontainers/stratovirt.go | 309 ++++++++++++++----
10 files changed, 292 insertions(+), 65 deletions(-)
diff --git a/src/runtime/Makefile b/src/runtime/Makefile
index ea2cd296..745bcc10 100644
--- a/src/runtime/Makefile
+++ b/src/runtime/Makefile
@@ -146,6 +146,8 @@ ACRNVALIDCTLPATHS := [\"$(ACRNCTLPATH)\"]
STRATOVIRTPATH = $(STRATOVIRTBINDIR)/$(STRATOVIRTCMD)
STRATOVIRTVALIDHYPERVISORPATHS := [\"$(STRATOVIRTPATH)\"]
+STRATOVIRTOZONEPATH = $(STRATOVIRTBINDIR)/$(STRATOVIRTOZONECMD)
+STRATOVIRTVALIDOZONEPATHS = [\"$(STRATOVIRTOZONEPATH)\"]
NETMONCMD := $(BIN_PREFIX)-netmon
NETMONPATH := $(PKGLIBEXECDIR)/$(NETMONCMD)
@@ -414,6 +416,8 @@ USER_VARS += FCJAILERPATH
USER_VARS += FCVALIDJAILERPATHS
USER_VARS += STRATOVIRTPATH
USER_VARS += STRATOVIRTVALIDHYPERVISORPATHS
+USER_VARS += STRATOVIRTOZONEPATH
+USER_VARS += STRATOVIRTVALIDOZONEPATHS
USER_VARS += SYSCONFIG
USER_VARS += IMAGENAME
USER_VARS += IMAGEPATH
diff --git a/src/runtime/arch/amd64-options.mk b/src/runtime/arch/amd64-options.mk
index ff2af9e6..4c6c329a 100644
--- a/src/runtime/arch/amd64-options.mk
+++ b/src/runtime/arch/amd64-options.mk
@@ -25,4 +25,6 @@ ACRNCTLCMD := acrnctl
CLHCMD := cloud-hypervisor
# stratovirt binary name
-STRATOVIRTCMD := stratovirt
\ No newline at end of file
+STRATOVIRTCMD := stratovirt
+# stratovirt's ozone binary name
+STRATOVIRTOZONECMD := ozone
\ No newline at end of file
diff --git a/src/runtime/arch/arm64-options.mk b/src/runtime/arch/arm64-options.mk
index 2ad3f657..5dfa2c80 100644
--- a/src/runtime/arch/arm64-options.mk
+++ b/src/runtime/arch/arm64-options.mk
@@ -21,4 +21,6 @@ FCJAILERCMD := jailer
CLHCMD := cloud-hypervisor
# stratovirt binary name
-STRATOVIRTCMD := stratovirt
\ No newline at end of file
+STRATOVIRTCMD := stratovirt
+# stratovirt's ozone binary name
+STRATOVIRTOZONECMD := ozone
\ No newline at end of file
diff --git a/src/runtime/cli/config/configuration-stratovirt.toml.in b/src/runtime/cli/config/configuration-stratovirt.toml.in
index 5c83c3c9..b557b71f 100644
--- a/src/runtime/cli/config/configuration-stratovirt.toml.in
+++ b/src/runtime/cli/config/configuration-stratovirt.toml.in
@@ -26,6 +26,16 @@ enable_annotations = @DEFENABLEANNOTATIONS@
# Your distribution recommends: @STRATOVIRTVALIDHYPERVISORPATHS@
valid_hypervisor_paths = @STRATOVIRTVALIDHYPERVISORPATHS@
+# Path for the ozone specific to stratovirt
+# If the ozone path is set, stratovirt will be launched in
+# ozone secure environment. It is disabled by default.
+# ozone_path = "@STRATOVIRTOZONEPATH@"
+
+# List of valid ozone path values for the hypervisor
+# Each member of the list can be a regular expression
+# The default if not set is empty (all annotations rejected.)
+# valid_jailer_paths = @STRATOVIRTVALIDOZONEPATHS@
+
# Optional space-separated list of options to pass to the guest kernel.
# For example, use `kernel_params = "vsyscall=emulate"` if you are having
# trouble running pre-2.15 glibc.
diff --git a/src/runtime/pkg/katautils/config-settings.go.in b/src/runtime/pkg/katautils/config-settings.go.in
index 7cd9138b..c168c608 100644
--- a/src/runtime/pkg/katautils/config-settings.go.in
+++ b/src/runtime/pkg/katautils/config-settings.go.in
@@ -17,6 +17,7 @@ var defaultInitrdPath = "/usr/share/kata-containers/kata-containers-initrd.img"
var defaultFirmwarePath = ""
var defaultMachineAccelerators = ""
var defaultCPUFeatures = ""
+var defaultOzonePath = "/usr/bin/ozone"
var systemdUnitName = "kata-containers.target"
const defaultKernelParams = ""
diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go
index f94ac4fd..828c2a43 100644
--- a/src/runtime/pkg/katautils/config.go
+++ b/src/runtime/pkg/katautils/config.go
@@ -92,6 +92,7 @@ type hypervisor struct {
FileBackedMemRootDir string `toml:"file_mem_backend"`
GuestHookPath string `toml:"guest_hook_path"`
GuestMemoryDumpPath string `toml:"guest_memory_dump_path"`
+ OzonePath string `toml:"ozone_path"`
HypervisorPathList []string `toml:"valid_hypervisor_paths"`
JailerPathList []string `toml:"valid_jailer_paths"`
CtlPathList []string `toml:"valid_ctlpaths"`
@@ -452,6 +453,16 @@ func (h hypervisor) getInitrdAndImage() (initrd string, image string, err error)
return
}
+func (h hypervisor) ozonePath() (string, error) {
+ p := h.OzonePath
+
+ if h.OzonePath == "" {
+ return "", nil
+ }
+
+ return ResolvePath(p)
+}
+
func (h hypervisor) getRxRateLimiterCfg() uint64 {
return h.RxRateLimiterMaxRate
}
@@ -877,6 +888,11 @@ func newStratovirtHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
return vc.HypervisorConfig{}, err
}
+ ozone, err := h.ozonePath()
+ if err != nil {
+ return vc.HypervisorConfig{}, err
+ }
+
kernel, err := h.kernel()
if err != nil {
return vc.HypervisorConfig{}, err
@@ -925,6 +941,7 @@ func newStratovirtHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
KernelPath: kernel,
InitrdPath: initrd,
ImagePath: image,
+ OzonePath: ozone,
KernelParams: vc.DeserializeParams(strings.Fields(kernelParams)),
HypervisorMachineType: machineType,
NumVCPUs: h.defaultVCPUs(),
@@ -1155,6 +1172,7 @@ func GetDefaultHypervisorConfig() vc.HypervisorConfig {
RxRateLimiterMaxRate: defaultRxRateLimiterMaxRate,
TxRateLimiterMaxRate: defaultTxRateLimiterMaxRate,
SGXEPCSize: defaultSGXEPCSize,
+ OzonePath: defaultOzonePath,
}
}
diff --git a/src/runtime/virtcontainers/hypervisor.go b/src/runtime/virtcontainers/hypervisor.go
index 615baa80..04e14b4e 100644
--- a/src/runtime/virtcontainers/hypervisor.go
+++ b/src/runtime/virtcontainers/hypervisor.go
@@ -302,6 +302,9 @@ type HypervisorConfig struct {
// JailerPathList is the list of jailer paths names allowed in annotations
JailerPathList []string
+ // OzonePath is the ozone executable host path.
+ OzonePath string
+
// BlockDeviceDriver specifies the driver to be used for block device
// either VirtioSCSI or VirtioBlock with the default driver being defaultBlockDriver
BlockDeviceDriver string
diff --git a/src/runtime/virtcontainers/persist.go b/src/runtime/virtcontainers/persist.go
index 203495e8..ae499c97 100644
--- a/src/runtime/virtcontainers/persist.go
+++ b/src/runtime/virtcontainers/persist.go
@@ -219,6 +219,7 @@ func (s *Sandbox) dumpConfig(ss *persistapi.SandboxState) {
HypervisorCtlPathList: sconfig.HypervisorConfig.HypervisorCtlPathList,
JailerPath: sconfig.HypervisorConfig.JailerPath,
JailerPathList: sconfig.HypervisorConfig.JailerPathList,
+ OzonePath: sconfig.HypervisorConfig.OzonePath,
BlockDeviceDriver: sconfig.HypervisorConfig.BlockDeviceDriver,
HypervisorMachineType: sconfig.HypervisorConfig.HypervisorMachineType,
MemoryPath: sconfig.HypervisorConfig.MemoryPath,
diff --git a/src/runtime/virtcontainers/persist/api/config.go b/src/runtime/virtcontainers/persist/api/config.go
index 3bd5567d..88903723 100644
--- a/src/runtime/virtcontainers/persist/api/config.go
+++ b/src/runtime/virtcontainers/persist/api/config.go
@@ -76,6 +76,9 @@ type HypervisorConfig struct {
// JailerPathList is the list of jailer paths names allowed in annotations
JailerPathList []string
+ // OzonePath is the ozone executable host path.
+ OzonePath string
+
// BlockDeviceDriver specifies the driver to be used for block device
// either VirtioSCSI or VirtioBlock with the default driver being defaultBlockDriver
BlockDeviceDriver string
diff --git a/src/runtime/virtcontainers/stratovirt.go b/src/runtime/virtcontainers/stratovirt.go
index 0f473e31..47daa817 100644
--- a/src/runtime/virtcontainers/stratovirt.go
+++ b/src/runtime/virtcontainers/stratovirt.go
@@ -3,6 +3,7 @@ package virtcontainers
import (
"context"
"fmt"
+ "io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -24,10 +25,15 @@ import (
otelTrace "go.opentelemetry.io/otel/trace"
)
-const defaultDummyMac = "22:33:44:aa:bb:"
-const mmioBlkCount = 4
-const mmioNetCount = 2
-const randomDevice = "/dev/urandom"
+const (
+ apiSocket = "qmp.socket"
+ debugSocket = "console.socket"
+ ozoneBaseDir = "/srv/ozone/stratovirt"
+ defaultDummyMac = "22:33:44:aa:bb:"
+ mmioBlkCount = 4
+ mmioNetCount = 2
+ randomDevice = "/dev/urandom"
+)
type stratovirtDev struct {
dev interface{}
@@ -40,10 +46,19 @@ type stratovirt struct {
sandbox *Sandbox
store persistapi.PersistDriver
config HypervisorConfig
+ rootfsPath string
+ kernelPath string
pid int
consolePath string
socketPath string
+ netNSPath string
qmpMonitorCh qmpChannel
+ ozoneRoot string
+ ozoneRes []string
+ useOzone bool
+ useImage bool
+ pidfile string
+ logfile string
devices []stratovirtDev
HotpluggedVCPUs []CPUDevice
mmioBlkSlots [mmioBlkCount]bool
@@ -66,10 +81,10 @@ func (s *stratovirt) trace(parent context.Context, name string) (otelTrace.Span,
return span, ctx
}
-func (s *stratovirt) getKernelCmdLine(useImage bool) string {
+func (s *stratovirt) getKernelCmdLine() string {
var params []string
- if useImage {
+ if s.useImage {
params = append(params, "root=/dev/vda")
}
@@ -100,14 +115,49 @@ func (s *stratovirt) createSandbox(ctx context.Context, id string, networkNS Net
s.id = id
s.config = *hypervisorConfig
-
- s.socketPath = filepath.Join(s.store.RunVMStoragePath(), id, "qmp.sock")
- s.consolePath = filepath.Join(s.store.RunVMStoragePath(), id, "console.sock")
+ if s.config.OzonePath == "" {
+ s.useOzone = false
+ s.pidfile = filepath.Join(s.store.RunVMStoragePath(), s.id, "pid")
+ s.logfile = filepath.Join(s.store.RunVMStoragePath(), s.id, "/stratovirt.log")
+ s.socketPath = filepath.Join(s.store.RunVMStoragePath(), id, apiSocket)
+ s.consolePath = filepath.Join(s.store.RunVMStoragePath(), id, debugSocket)
+ } else {
+ s.useOzone = true
+ s.ozoneRoot = filepath.Join(ozoneBaseDir, s.id)
+ s.pidfile = filepath.Join(s.ozoneRoot, "pid")
+ s.logfile = filepath.Join(s.ozoneRoot, "stratovirt.log")
+ s.socketPath = filepath.Join(s.ozoneRoot, apiSocket)
+ s.consolePath = filepath.Join(s.ozoneRoot, debugSocket)
+ }
+ s.netNSPath = networkNS.NetNsPath
s.qmpMonitorCh = qmpChannel{
ctx: s.ctx,
path: s.socketPath,
}
+ if kernelPath, err := s.config.KernelAssetPath(); err == nil {
+ s.kernelPath = kernelPath
+ s.ozoneRes = append(s.ozoneRes, s.kernelPath)
+ }
+
+ initrdPath, err := s.config.InitrdAssetPath()
+ if err != nil {
+ return err
+ }
+
+ if initrdPath == "" {
+ imagePath, err := s.config.ImageAssetPath()
+ if err != nil {
+ return err
+ }
+ s.useImage = true
+ s.rootfsPath = imagePath
+ } else {
+ s.useImage = false
+ s.rootfsPath = initrdPath
+ }
+ s.ozoneRes = append(s.ozoneRes, s.rootfsPath)
+
return nil
}
@@ -134,48 +184,43 @@ func (s *stratovirt) waitSandBoxStarted(timeout int) error {
return nil
}
-func (s *stratovirt) startSandbox(ctx context.Context, timeout int) error {
- span, _ := s.trace(ctx, "startSandbox")
- defer span.End()
-
+func (s *stratovirt) createbaseParams() []string {
var params []string
- var use_image bool
+
params = append(params, "-name", fmt.Sprintf("sandbox-%s", s.id))
- params = append(params, "-qmp", fmt.Sprintf("unix:%s,server,nowait", s.socketPath))
+ params = append(params, "-append", s.getKernelCmdLine())
+ params = append(params, "-smp", fmt.Sprintf("%d", s.config.NumVCPUs))
+ params = append(params, "-m", fmt.Sprintf("%d", uint64(s.config.MemorySize)))
+ params = append(params, "-device", "virtio-serial-device")
+ params = append(params, "-device", "virtconsole,chardev=charconsole0,id=virtioconsole0")
+ params = append(params, "-object", fmt.Sprintf("rng-random,id=objrng0,filename=%s", randomDevice))
+ params = append(params, "-device", "virtio-rng-device,rng=objrng0")
- if kernelPath, err := s.config.KernelAssetPath(); err == nil {
- params = append(params, "-kernel", kernelPath)
- }
+ // daemonize
+ params = append(params, "-daemonize")
- initrdPath, err := s.config.InitrdAssetPath()
- if err != nil {
- return err
+ return params
+}
+
+func (s *stratovirt) createOzoneParams(params []string) ([]string, error) {
+ params = append(params, "-qmp", fmt.Sprintf("unix:%s,server,nowait", apiSocket))
+ params = append(params, "-chardev", fmt.Sprintf("socket,id=charconsole0,path=%s,server,nowait", debugSocket))
+ params = append(params, "-kernel", filepath.Base(s.kernelPath))
+ params = append(params, "-pidfile", filepath.Base(s.pidfile))
+
+ // append logfile only on debug
+ if s.config.Debug {
+ params = append(params, "-D", filepath.Base(s.logfile))
}
- if initrdPath == "" {
- imagePath, err := s.config.ImageAssetPath()
- if err != nil {
- return err
- }
- use_image = true
+ if s.useImage {
s.mmioBlkSlots[0] = true
params = append(params, "-device", "virtio-blk-device,drive=rootfs")
- params = append(params, "-drive", fmt.Sprintf("id=rootfs,file=%s,direct=off", imagePath))
+ params = append(params, "-drive", fmt.Sprintf("id=rootfs,file=%s,direct=off", filepath.Base(s.rootfsPath)))
} else {
- use_image = false
- params = append(params, "-initrd", initrdPath)
+ params = append(params, "-initrd", filepath.Base(s.rootfsPath))
}
- params = append(params, "-append", s.getKernelCmdLine(use_image))
- params = append(params, "-smp", fmt.Sprintf("%d", s.config.NumVCPUs))
- params = append(params, "-m", fmt.Sprintf("%d", uint64(s.config.MemorySize)))
- params = append(params, "-device", "virtio-serial-device")
- params = append(params, "-device", "virtconsole,chardev=charconsole0,id=virtioconsole0")
- params = append(params, "-object", fmt.Sprintf("rng-random,id=objrng0,filename=%s", randomDevice))
- params = append(params, "-device", "virtio-rng-device,rng=objrng0")
- params = append(params, "-chardev", fmt.Sprintf("socket,id=charconsole0,path=%s,server,nowait", s.consolePath))
- params = append(params, "-pidfile", filepath.Join(s.store.RunVMStoragePath(), s.id, "pid"))
-
// add devices to cmdline
for _, d := range s.devices {
switch v := d.dev.(type) {
@@ -188,8 +233,9 @@ func (s *stratovirt) startSandbox(ctx context.Context, timeout int) error {
case config.BlockDrive:
id := v.ID
path := v.File
- params = append(params, "-device", fmt.Sprintf("virtio-blk-device, drive=%s", id))
- params = append(params, "-drive", fmt.Sprintf("id=%s,file=%s", id, path))
+ s.ozoneRes = append(s.ozoneRes, path)
+ params = append(params, "-device", fmt.Sprintf("virtio-blk-device,drive=%s", id))
+ params = append(params, "-drive", fmt.Sprintf("id=%s,file=%s", id, filepath.Base(path)))
case types.VSock:
v.VhostFd.Close()
params = append(params, "-device", fmt.Sprintf("vhost-vsock-device,id=vsock-id,guest-cid=%d", v.ContextID))
@@ -198,42 +244,125 @@ func (s *stratovirt) startSandbox(ctx context.Context, timeout int) error {
}
}
- // daemonize
- params = append(params, "-daemonize")
+ return params, nil
+}
+
+func (s *stratovirt) createParams(params []string) ([]string, error) {
+ params = append(params, "-qmp", fmt.Sprintf("unix:%s,server,nowait", s.socketPath))
+ params = append(params, "-chardev", fmt.Sprintf("socket,id=charconsole0,path=%s,server,nowait", s.consolePath))
+ params = append(params, "-kernel", s.kernelPath)
+ params = append(params, "-pidfile", s.pidfile)
// append logfile only on debug
if s.config.Debug {
- dir := filepath.Join(s.store.RunVMStoragePath(), s.id)
- params = append(params, "-D", fmt.Sprintf("%s/stratovirt.log", dir))
+ params = append(params, "-D", s.logfile)
+ }
+
+ if s.useImage {
+ s.mmioBlkSlots[0] = true
+ params = append(params, "-device", "virtio-blk-device,drive=rootfs")
+ params = append(params, "-drive", fmt.Sprintf("id=rootfs,file=%s,direct=off", s.rootfsPath))
+ } else {
+ params = append(params, "-initrd", s.rootfsPath)
}
- dir := filepath.Join(s.store.RunVMStoragePath(), s.id)
- err = os.MkdirAll(dir, DirMode)
+ // add devices to cmdline
+ for _, d := range s.devices {
+ switch v := d.dev.(type) {
+ case Endpoint:
+ name := v.Name()
+ mac := v.HardwareAddr()
+ tapName := v.NetworkPair().TapInterface.TAPIface.Name
+ params = append(params, "-device", fmt.Sprintf("virtio-net-device,netdev=%s,id=%s,mac=%s", name, name, mac))
+ params = append(params, "-netdev", fmt.Sprintf("tap,id=%s,ifname=%s", name, tapName))
+ case config.BlockDrive:
+ id := v.ID
+ path := v.File
+ params = append(params, "-device", fmt.Sprintf("virtio-blk-device,drive=%s", id))
+ params = append(params, "-drive", fmt.Sprintf("id=%s,file=%s", id, path))
+ case types.VSock:
+ v.VhostFd.Close()
+ params = append(params, "-device", fmt.Sprintf("vhost-vsock-device,id=vsock-id,guest-cid=%d", v.ContextID))
+ default:
+ s.Logger().Error("Adding device type is unsupported")
+ }
+ }
+
+ return params, nil
+}
+
+func (s *stratovirt) startSandbox(ctx context.Context, timeout int) error {
+ span, _ := s.trace(ctx, "startSandbox")
+ defer span.End()
+
+ var err error
+ var cmd *exec.Cmd
+
+ params := s.createbaseParams()
+
+ stratovirtBinPath, err := s.config.HypervisorAssetPath()
if err != nil {
return err
}
- defer func() {
+
+ if s.useOzone {
+ var ozoneParams []string
+ extend_params, err := s.createOzoneParams(params)
if err != nil {
- if err := os.RemoveAll(dir); err != nil {
- s.Logger().WithError(err).Error("Fail to clean up vm dir %s", dir)
+ return err
+ }
+ ozoneParams = append(ozoneParams, "-exec-file", stratovirtBinPath)
+ ozoneParams = append(ozoneParams, "-name", s.id)
+ ozoneParams = append(ozoneParams, "-gid", "0")
+ ozoneParams = append(ozoneParams, "-uid", "0")
+ if s.netNSPath != "" {
+ ozoneParams = append(ozoneParams, "-netns", s.netNSPath)
+ }
+
+ ozoneParams = append(ozoneParams, "-source")
+ ozoneParams = append(ozoneParams, s.ozoneRes...)
+
+ defer func() {
+ if err != nil {
+ ozoneParams = append(ozoneParams, "-clean-resource")
+ cmd = exec.CommandContext(s.ctx, s.config.OzonePath, ozoneParams...)
+ if err := cmd.Run(); err != nil {
+ s.Logger().WithError(err).Error("Failed to clean up ozone dir %s", s.ozoneRoot)
+ }
}
+ }()
+
+ ozoneParams = append(ozoneParams, "--")
+ ozoneParams = append(ozoneParams, extend_params...)
+ cmd = exec.CommandContext(s.ctx, s.config.OzonePath, ozoneParams...)
+ s.Logger().Info("StratoVirt/Ozone start with params: ", cmd)
+ } else {
+ params, err = s.createParams(params)
+ if err != nil {
+ return err
}
- }()
- binPath, err := s.config.HypervisorAssetPath()
- if err != nil {
- s.Logger().WithField("Fail to get hypervisor bin path", err).Error()
- return err
- }
+ dir := filepath.Join(s.store.RunVMStoragePath(), s.id)
+ err = os.MkdirAll(dir, DirMode)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ if err != nil {
+ if err := os.RemoveAll(dir); err != nil {
+ s.Logger().WithError(err).Error("Fail to clean up vm dir %s", dir)
+ }
+ }
+ }()
- cmd := exec.CommandContext(s.ctx, binPath, params...)
- s.Logger().Info("StratoVirt start with params: ", cmd)
+ cmd = exec.CommandContext(s.ctx, stratovirtBinPath, params...)
+ s.Logger().Info("StratoVirt start with params: ", cmd)
+ }
if err := cmd.Start(); err != nil {
s.Logger().WithField("Error starting hypervisor, please check the params", err).Error()
return err
}
- s.pid = cmd.Process.Pid
if err = s.waitSandBoxStarted(timeout); err != nil {
return err
@@ -420,6 +549,7 @@ func (s *stratovirt) hotplugNet(ctx context.Context, endpoint Endpoint, op opera
}
func (s *stratovirt) hotplugBlk(drive *config.BlockDrive, op operation) (err error) {
+ var filePath string
err = s.qmpSetup()
if err != nil {
return err
@@ -427,13 +557,18 @@ func (s *stratovirt) hotplugBlk(drive *config.BlockDrive, op operation) (err err
switch op {
case addDevice:
- driver := "virtio-blk-pci"
+ driver := "virtio-blk-mmio"
+ if s.useOzone {
+ filePath, err = s.updateOzoneRes(drive.File, true)
+ } else {
+ filePath = drive.File
+ }
slot, err := s.getDevSlot(drive.VirtPath, false)
if err != nil {
return fmt.Errorf("Could not get unused slot for %q", drive.VirtPath)
}
- if err := s.qmpMonitorCh.qmp.ExecuteBlockdevAdd(s.qmpMonitorCh.ctx, drive.File, drive.ID, false); err != nil {
+ if err := s.qmpMonitorCh.qmp.ExecuteBlockdevAdd(s.qmpMonitorCh.ctx, filePath, drive.ID, false); err != nil {
s.getDevSlot(drive.VirtPath, true)
return err
}
@@ -443,6 +578,9 @@ func (s *stratovirt) hotplugBlk(drive *config.BlockDrive, op operation) (err err
return err
}
case removeDevice:
+ if s.useOzone {
+ s.updateOzoneRes(drive.File, false)
+ }
if err := s.qmpMonitorCh.qmp.ExecuteDeviceDel(s.qmpMonitorCh.ctx, drive.ID); err != nil {
return err
}
@@ -582,17 +720,62 @@ func (s *stratovirt) getThreadIDs(ctx context.Context) (vcpuThreadIDs, error) {
return tid, nil
}
+func (s *stratovirt) updateOzoneRes(src string, add bool) (string, error) {
+ dst := filepath.Join(s.ozoneRoot, filepath.Base(src))
+ if add {
+ if err := bindMount(context.Background(), src, dst, false, "slave"); err != nil {
+ s.Logger().WithField("bindMount failed", err).Error()
+ return "", err
+ }
+ } else {
+ syscall.Unmount(dst, syscall.MNT_DETACH)
+ }
+ return filepath.Base(src), nil
+}
+
+func (s *stratovirt) cleanOzoneRes() {
+ s.updateOzoneRes(s.rootfsPath, false)
+ s.updateOzoneRes(s.kernelPath, false)
+
+ if err := os.RemoveAll(s.ozoneRoot); err != nil {
+ s.Logger().WithField("cleanupOzone failed", err).Error()
+ }
+}
+
func (s *stratovirt) cleanup(ctx context.Context) error {
span, _ := s.trace(ctx, "cleanup")
defer span.End()
s.qmpTeardown()
+ if s.useOzone {
+ s.cleanOzoneRes()
+ }
return nil
}
func (s *stratovirt) getPids() []int {
- return []int{s.pid}
+ var pids []int
+ if s.pid != 0 {
+ pids = append(pids, s.pid)
+ } else {
+ pid, err := ioutil.ReadFile(s.pidfile)
+ if err != nil {
+ s.Logger().WithError(err).Error("Read pid file failed.")
+ return []int{0}
+ }
+
+ p, err := strconv.Atoi(strings.Trim(string(pid), "\n\t "))
+ if err != nil {
+ s.Logger().WithError(err).Error("Get pid from pid file failed.")
+ return []int{0}
+ }
+
+ pids = append(pids, p)
+ s.pid = p
+ }
+
+ return pids
}
func (s *stratovirt) getVirtioFsPid() *int {
--
2.21.1 (Apple Git-122.3)

View File

@ -1,295 +0,0 @@
From 77ed6fefe70edde63b01d797b76f389bc82bb1a0 Mon Sep 17 00:00:00 2001
From: Wei Gao <gaowei66@huawei.com>
Date: Mon, 9 Aug 2021 14:57:06 +0800
Subject: [PATCH 6/6] factory: add the template factory support for hypervisor
type stratovirt.
Signed-off-by: Wei Gao <gaowei66@huawei.com>
---
src/runtime/pkg/katautils/config.go | 2 +-
.../factory/template/template.go | 21 +++--
src/runtime/virtcontainers/kata_agent.go | 7 +-
src/runtime/virtcontainers/stratovirt.go | 89 +++++++++++++++++--
src/runtime/virtcontainers/vm.go | 28 ++++--
5 files changed, 125 insertions(+), 22 deletions(-)
diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go
index 828c2a43..718677b4 100644
--- a/src/runtime/pkg/katautils/config.go
+++ b/src/runtime/pkg/katautils/config.go
@@ -1363,7 +1363,7 @@ func checkNetNsConfig(config oci.RuntimeConfig) error {
// checkFactoryConfig ensures the VM factory configuration is valid.
func checkFactoryConfig(config oci.RuntimeConfig) error {
if config.FactoryConfig.Template {
- if config.HypervisorConfig.InitrdPath == "" {
+ if config.HypervisorConfig.InitrdPath == "" && (config.HypervisorType != vc.StratovirtHypervisor) {
return errors.New("Factory option enable_template requires an initrd image")
}
}
diff --git a/src/runtime/virtcontainers/factory/template/template.go b/src/runtime/virtcontainers/factory/template/template.go
index 66070126..02497097 100644
--- a/src/runtime/virtcontainers/factory/template/template.go
+++ b/src/runtime/virtcontainers/factory/template/template.go
@@ -96,11 +96,15 @@ func (t *template) prepareTemplateFiles() error {
if err != nil {
return err
}
- flags := uintptr(syscall.MS_NOSUID | syscall.MS_NODEV)
- opts := fmt.Sprintf("size=%dM", t.config.HypervisorConfig.MemorySize+templateDeviceStateSize)
- if err = syscall.Mount("tmpfs", t.statePath, "tmpfs", flags, opts); err != nil {
- t.close()
- return err
+
+ // If use hypervisor stratovirt, no need to create template path with ramdisk.
+ if t.config.HypervisorType != vc.StratovirtHypervisor {
+ flags := uintptr(syscall.MS_NOSUID | syscall.MS_NODEV)
+ opts := fmt.Sprintf("size=%dM", t.config.HypervisorConfig.MemorySize+templateDeviceStateSize)
+ if err = syscall.Mount("tmpfs", t.statePath, "tmpfs", flags, opts); err != nil {
+ t.close()
+ return err
+ }
}
f, err := os.Create(t.statePath + "/memory")
if err != nil {
@@ -126,8 +130,11 @@ func (t *template) createTemplateVM(ctx context.Context) error {
}
defer vm.Stop(ctx)
- if err = vm.Disconnect(ctx); err != nil {
- return err
+ // Create template on hypervisor stratovirt, don't have connection with agent.
+ if config.HypervisorType != vc.StratovirtHypervisor {
+ if err = vm.Disconnect(ctx); err != nil {
+ return err
+ }
}
// Sleep a bit to let the agent grpc server clean up
diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go
index 13d31658..bc882c70 100644
--- a/src/runtime/virtcontainers/kata_agent.go
+++ b/src/runtime/virtcontainers/kata_agent.go
@@ -1306,8 +1306,11 @@ func (k *kataAgent) buildContainerRootfs(ctx context.Context, sandbox *Sandbox,
// TODO: remove dependency on shared fs path. shared fs is just one kind of storage source.
// we should not always use shared fs path for all kinds of storage. Instead, all storage
// should be bind mounted to a tmpfs path for containers to use.
- if err := os.MkdirAll(filepath.Join(getMountPath(c.sandbox.id), c.id, c.rootfsSuffix), DirMode); err != nil {
- return nil, err
+ // If boot from template on stratovirt, no need to mkdir mount path.
+ if !((sandbox.config.HypervisorType == StratovirtHypervisor) && sandbox.config.HypervisorConfig.BootFromTemplate) {
+ if err := os.MkdirAll(filepath.Join(getMountPath(c.sandbox.id), c.id, c.rootfsSuffix), DirMode); err != nil {
+ return nil, err
+ }
}
return rootfs, nil
}
diff --git a/src/runtime/virtcontainers/stratovirt.go b/src/runtime/virtcontainers/stratovirt.go
index 47daa817..e9b2ba85 100644
--- a/src/runtime/virtcontainers/stratovirt.go
+++ b/src/runtime/virtcontainers/stratovirt.go
@@ -48,6 +48,7 @@ type stratovirt struct {
config HypervisorConfig
rootfsPath string
kernelPath string
+ templatePath string
pid int
consolePath string
socketPath string
@@ -115,7 +116,7 @@ func (s *stratovirt) createSandbox(ctx context.Context, id string, networkNS Net
s.id = id
s.config = *hypervisorConfig
- if s.config.OzonePath == "" {
+ if (s.config.OzonePath == "") || s.config.BootToBeTemplate {
s.useOzone = false
s.pidfile = filepath.Join(s.store.RunVMStoragePath(), s.id, "pid")
s.logfile = filepath.Join(s.store.RunVMStoragePath(), s.id, "/stratovirt.log")
@@ -129,6 +130,20 @@ func (s *stratovirt) createSandbox(ctx context.Context, id string, networkNS Net
s.socketPath = filepath.Join(s.ozoneRoot, apiSocket)
s.consolePath = filepath.Join(s.ozoneRoot, debugSocket)
}
+
+ if s.config.VMid != "" && s.useOzone {
+ // Make sure the symlinks do not exist
+ os.RemoveAll(s.ozoneRoot)
+ ozoneVmRoot := filepath.Join(ozoneBaseDir, s.config.VMid)
+ if err := os.Symlink(ozoneVmRoot, s.ozoneRoot); err != nil {
+ return err
+ }
+ }
+
+ if s.config.BootFromTemplate || s.config.BootToBeTemplate {
+ s.templatePath = strings.Replace(s.config.DevicesStatePath, "/state", "", -1)
+ }
+
s.netNSPath = networkNS.NetNsPath
s.qmpMonitorCh = qmpChannel{
ctx: s.ctx,
@@ -221,6 +236,12 @@ func (s *stratovirt) createOzoneParams(params []string) ([]string, error) {
params = append(params, "-initrd", filepath.Base(s.rootfsPath))
}
+ // handle boot from template
+ if s.config.BootFromTemplate {
+ s.ozoneRes = append(s.ozoneRes, s.templatePath)
+ params = append(params, "-incoming", fmt.Sprintf("file:%s", filepath.Base(s.templatePath)))
+ }
+
// add devices to cmdline
for _, d := range s.devices {
switch v := d.dev.(type) {
@@ -266,6 +287,11 @@ func (s *stratovirt) createParams(params []string) ([]string, error) {
params = append(params, "-initrd", s.rootfsPath)
}
+ // handle boot from template
+ if s.config.BootFromTemplate {
+ params = append(params, "-incoming", fmt.Sprintf("file:%s", s.templatePath))
+ }
+
// add devices to cmdline
for _, d := range s.devices {
switch v := d.dev.(type) {
@@ -410,14 +436,55 @@ func (s *stratovirt) stopSandbox(ctx context.Context, force bool) error {
}
func (s *stratovirt) pauseSandbox(ctx context.Context) error {
- return nil
+ span, _ := s.trace(ctx, "pauseSandbox")
+ defer span.End()
+
+ return s.togglePauseSandbox(ctx, true)
}
func (s *stratovirt) saveSandbox() error {
+ s.Logger().Info("save sandbox")
+
+ err := s.qmpSetup()
+ if err != nil {
+ return err
+ }
+
+ // BootToBeTemplate sets the VM to be a template that other VMs can can clone from.
+ // We would want to bypass shared memory when saving VM to local file through migrate.
+ if s.config.BootToBeTemplate {
+ err = s.qmpMonitorCh.qmp.ExecSetMigrateArguments(s.qmpMonitorCh.ctx, fmt.Sprintf("file:%s", s.templatePath))
+ if err != nil {
+ s.Logger().WithError(err).Error("exec migration")
+ return err
+ }
+ }
+
return nil
}
func (s *stratovirt) resumeSandbox(ctx context.Context) error {
+ span, _ := s.trace(ctx, "resumeSandbox")
+ defer span.End()
+
+ return s.togglePauseSandbox(ctx, false)
+}
+
+func (s *stratovirt) togglePauseSandbox(ctx context.Context, pause bool) error {
+ span, _ := s.trace(ctx, "togglePauseSandbox")
+ defer span.End()
+
+ err := s.qmpSetup()
+ if err != nil {
+ return err
+ }
+
+ if pause {
+ s.qmpMonitorCh.qmp.ExecuteStop(s.qmpMonitorCh.ctx)
+ } else {
+ s.qmpMonitorCh.qmp.ExecuteCont(s.qmpMonitorCh.ctx)
+ }
+
return nil
}
@@ -734,11 +801,23 @@ func (s *stratovirt) updateOzoneRes(src string, add bool) (string, error) {
}
func (s *stratovirt) cleanOzoneRes() {
- s.updateOzoneRes(s.rootfsPath, false)
- s.updateOzoneRes(s.kernelPath, false)
+ // Umount all resource in ozoneRoot
+ if dir, err := ioutil.ReadDir(s.ozoneRoot); err == nil {
+ for _, file := range dir {
+ syscall.Unmount(filepath.Join(s.ozoneRoot, file.Name()), syscall.MNT_DETACH)
+ }
+ }
if err := os.RemoveAll(s.ozoneRoot); err != nil {
- s.Logger().WithField("cleanupOzone failed", err).Error()
+ s.Logger().WithField("cleanup Ozone failed", err).Error()
+ }
+
+ // If have VMid, the VM is boot from template. ozoneVmRoot also need clean.
+ if s.config.VMid != "" {
+ ozoneVmRoot := filepath.Join(ozoneBaseDir, s.config.VMid)
+ if err := os.RemoveAll(ozoneVmRoot); err != nil {
+ s.Logger().WithField("cleanup Ozone failed", err).Error()
+ }
}
}
diff --git a/src/runtime/virtcontainers/vm.go b/src/runtime/virtcontainers/vm.go
index e6f02b6e..c4f9df73 100644
--- a/src/runtime/virtcontainers/vm.go
+++ b/src/runtime/virtcontainers/vm.go
@@ -142,13 +142,19 @@ func NewVM(ctx context.Context, config VMConfig) (*VM, error) {
}()
// 4. check agent aliveness
- // VMs booted from template are paused, do not check
- if !config.HypervisorConfig.BootFromTemplate {
+ // On hypervisor StratoVirt, VMs booted from template are running, check agent
+ // On other hypervisors, VMs booted from template are paused, do not check
+ if config.HypervisorType == StratovirtHypervisor {
+ if !config.HypervisorConfig.BootToBeTemplate {
+ virtLog.WithField("vm", id).Info("check agent status")
+ err = agent.check(ctx)
+ }
+ } else if !config.HypervisorConfig.BootFromTemplate {
virtLog.WithField("vm", id).Info("check agent status")
err = agent.check(ctx)
- if err != nil {
- return nil, err
- }
+ }
+ if err != nil {
+ return nil, err
}
return &VM{
@@ -329,9 +335,16 @@ func (v *VM) assignSandbox(s *Sandbox) error {
// - link 9pfs share path from sandbox dir (/run/kata-containers/shared/sandboxes/sbid/) to vm dir (/run/vc/vm/vmid/shared/)
vmSharePath := buildVMSharePath(v.id, v.store.RunVMStoragePath())
- vmSockDir := filepath.Join(v.store.RunVMStoragePath(), v.id)
sbSharePath := getMountPath(s.id)
- sbSockDir := filepath.Join(v.store.RunVMStoragePath(), s.id)
+ var vmSockDir string
+ var sbSockDir string
+ if v.hypervisor.hypervisorConfig().OzonePath != "" {
+ vmSockDir = filepath.Join(ozoneBaseDir, v.id)
+ sbSockDir = filepath.Join(ozoneBaseDir, s.id)
+ } else {
+ vmSockDir = filepath.Join(v.store.RunVMStoragePath(), v.id)
+ sbSockDir = filepath.Join(v.store.RunVMStoragePath(), s.id)
+ }
v.logger().WithFields(logrus.Fields{
"vmSharePath": vmSharePath,
@@ -359,6 +372,7 @@ func (v *VM) assignSandbox(s *Sandbox) error {
s.hypervisor = v.hypervisor
s.config.HypervisorConfig.VMid = v.id
+ s.config.HypervisorConfig.BootFromTemplate = true
return nil
}
--
2.21.1 (Apple Git-122.3)

View File

@ -1,224 +0,0 @@
From d4605dafaa9c326a5cf24c28d0c1efe6c9997f49 Mon Sep 17 00:00:00 2001
From: holyfei <yangfeiyu20092010@163.com>
Date: Sat, 21 Aug 2021 17:08:46 +0800
Subject: [PATCH] kata-containers: support with iSulad
reason: support with iSulad
Signed-off-by: holyfei <yangfeiyu20092010@163.com>
---
src/agent/rustjail/src/cgroups/fs/mod.rs | 2 +-
src/runtime/containerd-shim-v2/container.go | 9 +++
src/runtime/containerd-shim-v2/service.go | 55 +++++++++++++++++++
src/runtime/containerd-shim-v2/start.go | 10 ++++
.../containerd/runtime/v2/shim/shim.go | 8 ++-
5 files changed, 81 insertions(+), 3 deletions(-)
diff --git a/src/agent/rustjail/src/cgroups/fs/mod.rs b/src/agent/rustjail/src/cgroups/fs/mod.rs
index 7f41cb4..6c3bb32 100644
--- a/src/agent/rustjail/src/cgroups/fs/mod.rs
+++ b/src/agent/rustjail/src/cgroups/fs/mod.rs
@@ -369,7 +369,7 @@ fn set_memory_resources(cg: &cgroups::Cgroup, memory: &LinuxMemory, update: bool
if let Some(swappiness) = memory.swappiness {
if (0..=100).contains(&swappiness) {
mem_controller.set_swappiness(swappiness as u64)?;
- } else {
+ } else if swappiness != -1 {
return Err(anyhow!(
"invalid value:{}. valid memory swappiness range is 0-100",
swappiness
diff --git a/src/runtime/containerd-shim-v2/container.go b/src/runtime/containerd-shim-v2/container.go
index faea0e2..d563888 100644
--- a/src/runtime/containerd-shim-v2/container.go
+++ b/src/runtime/containerd-shim-v2/container.go
@@ -7,10 +7,13 @@ package containerdshim
import (
"io"
+ "os"
+ "path"
"time"
"github.com/containerd/containerd/api/types/task"
"github.com/containerd/containerd/errdefs"
+ cdshim "github.com/containerd/containerd/runtime/v2/shim"
taskAPI "github.com/containerd/containerd/runtime/v2/task"
"github.com/opencontainers/runtime-spec/specs-go"
@@ -37,6 +40,8 @@ type container struct {
status task.Status
terminal bool
mounted bool
+ exitFifo string
+ exitFd *os.File
}
func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.ContainerType, spec *specs.Spec, mounted bool) (*container, error) {
@@ -49,6 +54,9 @@ func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.Con
spec = &specs.Spec{}
}
+ dir := os.Getenv(cdshim.ExitFifoDir)
+ exitFifo := path.Join(dir, r.ID, exitFifoName)
+
c := &container{
s: s,
spec: spec,
@@ -65,6 +73,7 @@ func newContainer(s *service, r *taskAPI.CreateTaskRequest, containerType vc.Con
exitCh: make(chan uint32, 1),
stdinCloser: make(chan struct{}),
mounted: mounted,
+ exitFifo: exitFifo,
}
return c, nil
}
diff --git a/src/runtime/containerd-shim-v2/service.go b/src/runtime/containerd-shim-v2/service.go
index 1003f8e..e13283c 100644
--- a/src/runtime/containerd-shim-v2/service.go
+++ b/src/runtime/containerd-shim-v2/service.go
@@ -6,13 +6,16 @@
package containerdshim
import (
+ "bytes"
"context"
+ "encoding/binary"
"io/ioutil"
"os"
sysexec "os/exec"
"sync"
"syscall"
"time"
+ "unsafe"
eventstypes "github.com/containerd/containerd/api/events"
"github.com/containerd/containerd/api/types/task"
@@ -51,6 +54,8 @@ const (
// A time span used to wait for publish a containerd event,
// once it costs a longer time than timeOut, it will be canceld.
timeOut = 5 * time.Second
+
+ exitFifoName = "exit_fifo"
)
var (
@@ -1019,6 +1024,10 @@ func (s *service) Wait(ctx context.Context, r *taskAPI.WaitRequest) (_ *taskAPI.
func (s *service) processExits() {
for e := range s.ec {
s.checkProcesses(e)
+
+ if os.Getenv(cdshim.ExitFifoDir) != "" {
+ s.closeExitFifo(e)
+ }
}
}
@@ -1070,3 +1079,49 @@ func (s *service) getContainerStatus(containerID string) (task.Status, error) {
return status, nil
}
+
+func isBigEndian() (ret bool) {
+ i := int(0x1)
+ bs := (*[int(unsafe.Sizeof(i))]byte)(unsafe.Pointer(&i))
+ return bs[0] == 0
+}
+
+func (s *service) closeExitFifo(e exit) {
+ if e.execid != "" {
+ // not a container, no need to close exit fifo
+ return
+ }
+
+ var ret uint32
+ var nativeEndian binary.ByteOrder
+
+ s.mu.Lock()
+ c, err := s.getContainer(e.id)
+ s.mu.Unlock()
+
+ if err != nil {
+ logrus.WithError(err).Errorf("Process container:%v exit fifo failed", e.id)
+ return
+ }
+
+ ret = <-c.exitCh
+ // refill the exitCh with the container process's exit code in case
+ // there were other waits on this process.
+ c.exitCh <- ret
+
+ if isBigEndian() {
+ nativeEndian = binary.BigEndian
+ } else {
+ nativeEndian = binary.LittleEndian
+ }
+
+ bytesBuffer := bytes.NewBuffer([]byte{})
+ binary.Write(bytesBuffer, nativeEndian, &ret)
+
+ _, err = c.exitFd.Write(bytesBuffer.Bytes())
+ if err != nil {
+ logrus.WithError(err).Error("write exit fifo failed")
+ }
+
+ c.exitFd.Close()
+}
diff --git a/src/runtime/containerd-shim-v2/start.go b/src/runtime/containerd-shim-v2/start.go
index 72420e4..e89dc48 100644
--- a/src/runtime/containerd-shim-v2/start.go
+++ b/src/runtime/containerd-shim-v2/start.go
@@ -8,8 +8,11 @@ package containerdshim
import (
"context"
"fmt"
+ "golang.org/x/sys/unix"
+ "os"
"github.com/containerd/containerd/api/types/task"
+ cdshim "github.com/containerd/containerd/runtime/v2/shim"
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
)
@@ -59,6 +62,13 @@ func startContainer(ctx context.Context, s *service, c *container) error {
c.status = task.StatusRunning
+ if os.Getenv(cdshim.ExitFifoDir) != "" {
+ c.exitFd, err = os.OpenFile(c.exitFifo, unix.O_WRONLY|unix.O_NONBLOCK|unix.O_CLOEXEC, 0)
+ if err != nil {
+ return err
+ }
+ }
+
stdin, stdout, stderr, err := s.sandbox.IOStream(c.id, c.id)
if err != nil {
return err
diff --git a/src/runtime/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go b/src/runtime/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
index d60d496..946c386 100644
--- a/src/runtime/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
+++ b/src/runtime/vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
@@ -84,6 +84,8 @@ var (
action string
)
+var ExitFifoDir = "EXIT_FIFO_DIR"
+
func parseFlags() {
flag.BoolVar(&debugFlag, "debug", false, "enable debug output in logs")
flag.StringVar(&namespaceFlag, "namespace", "", "namespace that owns the shim")
@@ -198,8 +200,10 @@ func run(id string, initFunc Init, config Config) error {
}
return nil
default:
- if err := setLogger(ctx, idFlag); err != nil {
- return err
+ if os.Getenv("EXIT_FIFO_DIR") == "" {
+ if err := setLogger(ctx, idFlag); err != nil {
+ return err
+ }
}
client := NewShimClient(ctx, service, signals)
return client.Serve()
--
2.23.0

View File

@ -1,29 +0,0 @@
From 5ee8e64c8c620f02cb580f1f3349ae63660ca34c Mon Sep 17 00:00:00 2001
From: holyfei <yangfeiyu20092010@163.com>
Date: Mon, 27 Sep 2021 11:03:58 +0800
Subject: [PATCH] kata-containers: adpat with iSulad
reason: chmod the exec fifo to 644, isula start container
and need the permission
Signed-off-by: holyfei <yangfeiyu20092010@163.com>
---
src/agent/rustjail/src/container.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/agent/rustjail/src/container.rs b/src/agent/rustjail/src/container.rs
index 748ee486..5113a482 100644
--- a/src/agent/rustjail/src/container.rs
+++ b/src/agent/rustjail/src/container.rs
@@ -822,7 +822,7 @@ impl BaseContainer for LinuxContainer {
if stat::stat(fifo_file.as_str()).is_ok() {
return Err(anyhow!("exec fifo exists"));
}
- unistd::mkfifo(fifo_file.as_str(), Mode::from_bits(0o622).unwrap())?;
+ unistd::mkfifo(fifo_file.as_str(), Mode::from_bits(0o644).unwrap())?;
fifofd = fcntl::open(
fifo_file.as_str(),
--
2.23.0

View File

@ -1,27 +0,0 @@
From c563b455e3bb0cebfbe2a77c8d5ebac36aac3c76 Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Thu, 4 Nov 2021 19:58:33 +0800
Subject: [PATCH] kata-runtime: fix kata-runtime hungs when qemu process is D/T
state
Signed-off-by: jikui <jikui2@huawei.com>
---
src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go b/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go
index 97e9245..325250d 100644
--- a/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go
+++ b/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go
@@ -717,6 +717,8 @@ func QMPStart(ctx context.Context, socket string, cfg QMPConfig, disconnectedCh
if q.version == nil {
return nil, nil, fmt.Errorf("failed to find QMP version information")
}
+ case <-time.After(15 * time.Second):
+ return nil, nil, fmt.Errorf("qmp start time out")
}
return q, q.version, nil
--
2.25.1

View File

@ -1,115 +0,0 @@
From c355523761598154653466033a1d88643d3fd3df Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Thu, 4 Nov 2021 20:27:22 +0800
Subject: [PATCH] kata-runtime: fix kata-runtime skip read lines in
/proc/mounts file problem
Signed-off-by: jikui <jikui2@huawei.com>
---
.../virtcontainers/utils/utils_linux.go | 61 +++++++++++--------
1 file changed, 36 insertions(+), 25 deletions(-)
diff --git a/src/runtime/virtcontainers/utils/utils_linux.go b/src/runtime/virtcontainers/utils/utils_linux.go
index 3c14e0c..c6dbd0a 100644
--- a/src/runtime/virtcontainers/utils/utils_linux.go
+++ b/src/runtime/virtcontainers/utils/utils_linux.go
@@ -7,15 +7,18 @@ package utils
import (
"bufio"
+ "bytes"
"crypto/rand"
"fmt"
"io"
+ "io/ioutil"
"math/big"
"os"
"strings"
"syscall"
"unsafe"
+ "github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)
@@ -93,6 +96,7 @@ const (
procMountsFile = "/proc/mounts"
fieldsPerLine = 6
+ maxRetryTimes = 5
vfioAPSysfsDir = "vfio_ap"
)
@@ -110,37 +114,44 @@ func GetDevicePathAndFsType(mountPoint string) (devicePath, fsType string, err e
return
}
- var file *os.File
+ var retry int = 0
- file, err = os.Open(procMountsFile)
- if err != nil {
- return
- }
-
- defer file.Close()
-
- reader := bufio.NewReader(file)
- for {
- var line string
-
- line, err = reader.ReadString('\n')
- if err == io.EOF {
- err = fmt.Errorf("Mount %s not found", mountPoint)
+ for retry <= maxRetryTimes {
+ var content []byte
+ content, err = ioutil.ReadFile(procMountsFile)
+ if err != nil {
return
}
-
- fields := strings.Fields(line)
- if len(fields) != fieldsPerLine {
- err = fmt.Errorf("Incorrect no of fields (expected %d, got %d)) :%s", fieldsPerLine, len(fields), line)
- return
+ bytesReader := bytes.NewReader(content)
+ reader := bufio.NewReader(bytesReader)
+
+ for {
+ var line string
+
+ line, err = reader.ReadString('\n')
+ if err == io.EOF {
+ err = fmt.Errorf("Mount %s not found", mountPoint)
+ break
+ }
+
+ fields := strings.Fields(line)
+ if len(fields) != fieldsPerLine {
+ err = fmt.Errorf("Incorrect no of fields (expected %d, got %d)) :%s", fieldsPerLine, len(fields), line)
+ return
+ }
+
+ if mountPoint == fields[procPathIndex] {
+ devicePath = fields[procDeviceIndex]
+ fsType = fields[procTypeIndex]
+ return
+ }
}
-
- if mountPoint == fields[procPathIndex] {
- devicePath = fields[procDeviceIndex]
- fsType = fields[procTypeIndex]
- return
+ retry = retry + 1
+ if retry <= maxRetryTimes {
+ logrus.Warnf("can not find %s in %s, retry %d times again......", mountPoint, procMountsFile, retry)
}
}
+ return "", "", fmt.Errorf("retry %d times fail to get devicePath adn fs type", maxRetryTimes)
}
// IsAPVFIOMediatedDevice decides whether a device is a VFIO-AP device
--
2.25.1

View File

@ -1,52 +0,0 @@
From 0797bf1fec9c40b67f2770bc8778e8eaee1657c8 Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Fri, 5 Nov 2021 11:35:25 +0800
Subject: [PATCH] kata-runtime: keep the process name of qemu same as
configured path
Signed-off-by: jikui <jikui2@huawei.com>
---
src/runtime/pkg/katautils/config.go | 7 ++++++-
src/runtime/pkg/katautils/config_test.go | 4 ++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go
index 718677b..e0ebc84 100644
--- a/src/runtime/pkg/katautils/config.go
+++ b/src/runtime/pkg/katautils/config.go
@@ -172,7 +172,12 @@ func (h hypervisor) path() (string, error) {
p = defaultHypervisorPath
}
- return ResolvePath(p)
+ absolutePath, err := filepath.Abs(p)
+ if err != nil {
+ return "", err
+ }
+
+ return absolutePath, nil
}
func (h hypervisor) ctlpath() (string, error) {
diff --git a/src/runtime/pkg/katautils/config_test.go b/src/runtime/pkg/katautils/config_test.go
index 0d02534..84b7843 100644
--- a/src/runtime/pkg/katautils/config_test.go
+++ b/src/runtime/pkg/katautils/config_test.go
@@ -983,12 +983,12 @@ func TestHypervisorDefaultsHypervisor(t *testing.T) {
assert.NoError(err)
assert.Equal(p, defaultHypervisorPath, "default hypervisor path wrong")
- // test path resolution
+ // test path resolution, just return the absolute path instead of resolved path
defaultHypervisorPath = testHypervisorLinkPath
h = hypervisor{}
p, err = h.path()
assert.NoError(err)
- assert.Equal(p, testHypervisorPath)
+ assert.Equal(p, testHypervisorLinkPath)
}
func TestHypervisorDefaultsKernel(t *testing.T) {
--
2.25.1

View File

@ -1,56 +0,0 @@
From e8e8e05538bf2c7bd8feebc44d4a960f453d21e1 Mon Sep 17 00:00:00 2001
From: holyfei <yangfeiyu20092010@163.com>
Date: Sat, 20 Nov 2021 17:04:39 +0800
Subject: [PATCH] kata-containers: modify kernel and image path in
configuration.toml
Signed-off-by: holyfei <yangfeiyu20092010@163.com>
---
src/runtime/Makefile | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/runtime/Makefile b/src/runtime/Makefile
index 745bcc1..68e60ee 100644
--- a/src/runtime/Makefile
+++ b/src/runtime/Makefile
@@ -49,6 +49,8 @@ BINLIBEXECLIST :=
BIN_PREFIX = $(PROJECT_TYPE)
PROJECT_DIR = $(PROJECT_TAG)
IMAGENAME = $(PROJECT_TAG).img
+KERNEL_PATH = /var/lib/kata/kernel
+IMAGE_PATH = /var/lib/kata/kata-containers-initrd.img
TARGET = $(BIN_PREFIX)-runtime
TARGET_OUTPUT = $(CURDIR)/$(TARGET)
@@ -108,7 +110,7 @@ PKGLIBEXECDIR := $(LIBEXECDIR)/$(PROJECT_DIR)
KERNELDIR := $(PKGDATADIR)
-IMAGEPATH := $(PKGDATADIR)/$(IMAGENAME)
+IMAGEPATH := $(IMAGE_PATH)
FIRMWAREPATH :=
# Name of default configuration file the runtime will use.
@@ -248,8 +250,7 @@ ifneq (,$(QEMUCMD))
DEFBLOCKSTORAGEDRIVER_QEMU := virtio-scsi
DEFNETWORKMODEL_QEMU := tcfilter
KERNELTYPE = uncompressed
- KERNELNAME = $(call MAKE_KERNEL_NAME,$(KERNELTYPE))
- KERNELPATH = $(KERNELDIR)/$(KERNELNAME)
+ KERNELPATH = $(KERNEL_PATH)
endif
ifneq (,$(CLHCMD))
@@ -294,8 +295,7 @@ ifneq (,$(STRATOVIRTCMD))
DEFBLOCKSTORAGEDRIVER_STRATOVIRT := virtio-mmio
DEFNETWORKMODEL_STRATOVIRT := none
KENRELTYPE_STRATOVIRT = uncompressed
- KERNEL_NAME_STRATOVIRT = $(call MAKE_KERNEL_NAME,$(KENRELTYPE_STRATOVIRT))
- KERNELPATH_STRATOVIRT = $(KERNELDIR)/$(KERNEL_NAME_STRATOVIRT)
+ KERNELPATH_STRATOVIRT = $(KERNEL_PATH)
endif
ifneq (,$(FCCMD))
--
2.27.0

View File

@ -1,63 +0,0 @@
From 13aec526360797b3bce776f35b7e5f5976961b47 Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Fri, 5 Nov 2021 11:46:17 +0800
Subject: [PATCH] kata-runtime: increase delete cgroup retry times
Signed-off-by: jikui <jikui2@huawei.com>
---
.../vendor/github.com/containerd/cgroups/cgroup.go | 4 ++--
.../vendor/github.com/containerd/cgroups/utils.go | 9 ++++++---
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/runtime/vendor/github.com/containerd/cgroups/cgroup.go b/src/runtime/vendor/github.com/containerd/cgroups/cgroup.go
index 5386668..69612b0 100644
--- a/src/runtime/vendor/github.com/containerd/cgroups/cgroup.go
+++ b/src/runtime/vendor/github.com/containerd/cgroups/cgroup.go
@@ -223,7 +223,7 @@ func (c *cgroup) Delete() error {
return err
}
if err := d.Delete(sp); err != nil {
- errors = append(errors, string(s.Name()))
+ errors = append(errors, fmt.Sprintf("delete %s get error: %v", string(s.Name()), err.Error()))
}
continue
}
@@ -234,7 +234,7 @@ func (c *cgroup) Delete() error {
}
path := p.Path(sp)
if err := remove(path); err != nil {
- errors = append(errors, path)
+ errors = append(errors, fmt.Sprintf("remove path %s get error: %v", path, err.Error()))
}
}
}
diff --git a/src/runtime/vendor/github.com/containerd/cgroups/utils.go b/src/runtime/vendor/github.com/containerd/cgroups/utils.go
index 8a97d04..82dbe2d 100644
--- a/src/runtime/vendor/github.com/containerd/cgroups/utils.go
+++ b/src/runtime/vendor/github.com/containerd/cgroups/utils.go
@@ -99,16 +99,19 @@ func defaults(root string) ([]Subsystem, error) {
// retrying the remove after a exp timeout
func remove(path string) error {
delay := 10 * time.Millisecond
- for i := 0; i < 5; i++ {
+ var err error
+ var count int = 0
+ for i := 0; i < 10; i++ {
if i != 0 {
time.Sleep(delay)
delay *= 2
}
- if err := os.RemoveAll(path); err == nil {
+ if err = os.RemoveAll(path); err == nil {
return nil
}
+ count++
}
- return fmt.Errorf("cgroups: unable to remove path %q", path)
+ return fmt.Errorf("cgroups: unable to remove path %q, err: %v, count:%d", path, err, count)
}
// readPids will read all the pids of processes in a cgroup by the provided path
--
2.25.1

View File

@ -1,33 +0,0 @@
From b654687f88281d1dfbbb6c8ede65aa53ec105122 Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Fri, 5 Nov 2021 11:55:24 +0800
Subject: [PATCH] kata-runtime: fix umount container rootfs dir return invalid
argument error
Signed-off-by: jikui <jikui2@huawei.com>
---
src/runtime/virtcontainers/container.go | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/runtime/virtcontainers/container.go b/src/runtime/virtcontainers/container.go
index 6e8e1ba..224f096 100644
--- a/src/runtime/virtcontainers/container.go
+++ b/src/runtime/virtcontainers/container.go
@@ -1035,8 +1035,12 @@ func (c *Container) stop(ctx context.Context, force bool) error {
return err
}
- if err := bindUnmountContainerRootfs(ctx, getMountPath(c.sandbox.id), c.id); err != nil && !force {
- return err
+ // umount container rootfs dir only if container use 9p
+ // to bind mount host container rootfs to 9p shared dir
+ if c.state.BlockDeviceID == "" {
+ if err := bindUnmountContainerRootfs(c.ctx, getMountPath(c.sandbox.id), c.id); err != nil && !force {
+ return err
+ }
}
if err := c.detachDevices(ctx); err != nil && !force {
--
2.25.1

View File

@ -1,33 +0,0 @@
From fe490b4d63871f91c17ad72afef38a3227c8b4d3 Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Fri, 5 Nov 2021 12:06:11 +0800
Subject: [PATCH] kata-runtime: truncate the log.json file before kata-runtime
subcommand executed
Signed-off-by: jikui <jikui2@huawei.com>
---
src/runtime/cli/main.go | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/runtime/cli/main.go b/src/runtime/cli/main.go
index 27757c0..7c77764 100644
--- a/src/runtime/cli/main.go
+++ b/src/runtime/cli/main.go
@@ -252,6 +252,14 @@ func beforeSubcommands(c *cli.Context) error {
ignoreConfigLogs = true
} else {
if path := c.GlobalString("log"); path != "" {
+ // since we have redirect the kata-runtime log to /var/log/messages, and avoid the
+ // path of log.json file to be large in the tmpfs, so we truncate the log.json file
+ // every time before subcommand is executed.
+ if path != "/dev/null" && katautils.FileExists(path) {
+ if err := os.Truncate(path, 0); err != nil {
+ return err
+ }
+ }
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0640)
if err != nil {
return err
--
2.25.1

View File

@ -1,248 +0,0 @@
From 420cb51b47e19556c35423354102fdc3a4d041f0 Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Fri, 5 Nov 2021 16:29:40 +0800
Subject: [PATCH] kata-runtime: validate sandbox cpu and memory size
Signed-off-by: jikui <jikui2@huawei.com>
---
src/runtime/pkg/katautils/config.go | 39 +++++++++++++++++--
src/runtime/pkg/katautils/config_test.go | 5 +--
src/runtime/virtcontainers/pkg/oci/utils.go | 10 ++---
src/runtime/virtcontainers/utils/utils.go | 42 +++++++++++++++++++++
4 files changed, 85 insertions(+), 11 deletions(-)
diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go
index e0ebc84..e523ed3 100644
--- a/src/runtime/pkg/katautils/config.go
+++ b/src/runtime/pkg/katautils/config.go
@@ -11,7 +11,6 @@ import (
"fmt"
"io/ioutil"
"path/filepath"
- goruntime "runtime"
"strings"
"github.com/BurntSushi/toml"
@@ -311,7 +310,7 @@ func (h hypervisor) GetEntropySource() string {
}
func (h hypervisor) defaultVCPUs() uint32 {
- numCPUs := goruntime.NumCPU()
+ numCPUs := utils.GetPhysicalCPUNumber()
if h.NumVCPUs < 0 || h.NumVCPUs > int32(numCPUs) {
return uint32(numCPUs)
@@ -323,8 +322,22 @@ func (h hypervisor) defaultVCPUs() uint32 {
return uint32(h.NumVCPUs)
}
+func (h hypervisor) checkVCPUs() error {
+ numCPUs := utils.GetPhysicalCPUNumber()
+
+ if h.NumVCPUs <= 0 {
+ return fmt.Errorf("invalid vcpus in configuration.toml! vcpus must larger than 0")
+ }
+
+ if h.NumVCPUs > int32(numCPUs) {
+ return fmt.Errorf("invalid vcpus in configuration.toml! vcpus must smaller than max CPUs: %d in machine", numCPUs)
+ }
+
+ return nil
+}
+
func (h hypervisor) defaultMaxVCPUs() uint32 {
- numcpus := uint32(goruntime.NumCPU())
+ numcpus := uint32(utils.GetPhysicalCPUNumber())
maxvcpus := vc.MaxQemuVCPUs()
reqVCPUs := h.DefaultMaxVCPUs
@@ -350,6 +363,18 @@ func (h hypervisor) defaultMemSz() uint32 {
return h.MemorySize
}
+func (h hypervisor) checkMemSz() error {
+ if h.MemorySize < utils.MinMemorySizeInMB {
+ return fmt.Errorf("invalid memory size! Memory size must larger than %d MB", utils.MinMemorySizeInMB)
+ }
+
+ if h.MemorySize > utils.MaxMemorySizeInMB {
+ return fmt.Errorf("invalid memory size, memory size must smaller than %d MB", utils.MaxMemorySizeInMB)
+ }
+
+ return nil
+}
+
func (h hypervisor) defaultMemSlots() uint32 {
slots := h.MemSlots
if slots == 0 {
@@ -665,6 +690,14 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
return vc.HypervisorConfig{}, err
}
+ if err = h.checkVCPUs(); err != nil {
+ return vc.HypervisorConfig{}, err
+ }
+
+ if err = h.checkMemSz(); err != nil {
+ return vc.HypervisorConfig{}, err
+ }
+
rxRateLimiterMaxRate := h.getRxRateLimiterCfg()
txRateLimiterMaxRate := h.getTxRateLimiterCfg()
diff --git a/src/runtime/pkg/katautils/config_test.go b/src/runtime/pkg/katautils/config_test.go
index 84b7843..3782268 100644
--- a/src/runtime/pkg/katautils/config_test.go
+++ b/src/runtime/pkg/katautils/config_test.go
@@ -14,7 +14,6 @@ import (
"path"
"path/filepath"
"reflect"
- goruntime "runtime"
"strings"
"syscall"
"testing"
@@ -155,7 +154,7 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config testRuntimeConf
KernelParams: vc.DeserializeParams(strings.Fields(kernelParams)),
HypervisorMachineType: machineType,
NumVCPUs: defaultVCPUCount,
- DefaultMaxVCPUs: uint32(goruntime.NumCPU()),
+ DefaultMaxVCPUs: uint32(utils.GetPhysicalCPUNumber()),
MemorySize: defaultMemSize,
DisableBlockDeviceUse: disableBlockDevice,
BlockDeviceDriver: defaultBlockDeviceDriver,
@@ -918,7 +917,7 @@ func TestNewClhHypervisorConfig(t *testing.T) {
func TestHypervisorDefaults(t *testing.T) {
assert := assert.New(t)
- numCPUs := goruntime.NumCPU()
+ numCPUs := utils.GetPhysicalCPUNumber()
h := hypervisor{}
diff --git a/src/runtime/virtcontainers/pkg/oci/utils.go b/src/runtime/virtcontainers/pkg/oci/utils.go
index efaee4a..ea46ab7 100644
--- a/src/runtime/virtcontainers/pkg/oci/utils.go
+++ b/src/runtime/virtcontainers/pkg/oci/utils.go
@@ -12,15 +12,12 @@ import (
"fmt"
"path/filepath"
"regexp"
- goruntime "runtime"
"strconv"
"strings"
"syscall"
criContainerdAnnotations "github.com/containerd/cri-containerd/pkg/annotations"
crioAnnotations "github.com/cri-o/cri-o/pkg/annotations"
- specs "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/api/resource"
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
@@ -29,6 +26,9 @@ import (
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
dockershimAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations/dockershim"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
+ "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
+ specs "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/sirupsen/logrus"
)
type annotationContainerType struct {
@@ -656,7 +656,7 @@ func addHypervisorCPUOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig) e
return fmt.Errorf("Error encountered parsing annotation default_vcpus: %v, please specify numeric value", err)
}
- numCPUs := goruntime.NumCPU()
+ numCPUs := utils.GetPhysicalCPUNumber()
if uint32(vcpus) > uint32(numCPUs) {
return fmt.Errorf("Number of cpus %d specified in annotation default_vcpus is greater than the number of CPUs %d on the system", vcpus, numCPUs)
@@ -671,7 +671,7 @@ func addHypervisorCPUOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig) e
return fmt.Errorf("Error encountered parsing annotation for default_maxvcpus: %v, please specify positive numeric value", err)
}
- numCPUs := goruntime.NumCPU()
+ numCPUs := utils.GetPhysicalCPUNumber()
max := uint32(maxVCPUs)
if max > uint32(numCPUs) {
diff --git a/src/runtime/virtcontainers/utils/utils.go b/src/runtime/virtcontainers/utils/utils.go
index e49f55a..7023318 100644
--- a/src/runtime/virtcontainers/utils/utils.go
+++ b/src/runtime/virtcontainers/utils/utils.go
@@ -6,12 +6,14 @@
package utils
import (
+ "bufio"
"crypto/rand"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
+ "strings"
"syscall"
"time"
@@ -28,11 +30,26 @@ const fileMode0755 = os.FileMode(0755)
// MibToBytesShift the number to shift needed to convert MiB to Bytes
const MibToBytesShift = 20
+const (
+ // Min needed memory size to start a Kata VM
+ MinMemorySizeInMB = 300
+ MinMemorySizeInByte = MinMemorySizeInMB << MibToBytesShift
+
+ // Max support memory size in the Kata VM
+ MaxMemorySizeInMB = 512 * 1024
+ MaxMemorySizeInByte = MaxMemorySizeInMB << MibToBytesShift
+)
+
// MaxSocketPathLen is the effective maximum Unix domain socket length.
//
// See unix(7).
const MaxSocketPathLen = 107
+const (
+ procCPUInfoPath = "/proc/cpuinfo"
+ processorIdentifier = "processor"
+)
+
// VHostVSockDevicePath path to vhost-vsock device
var VHostVSockDevicePath = "/dev/vhost-vsock"
@@ -390,3 +407,28 @@ outer:
return nil
}
+
+// GetPhysicalCPUNumber return the number of the CPUs in the physical machine
+func GetPhysicalCPUNumber() int {
+ f, err := os.Open(procCPUInfoPath)
+ if err != nil {
+ return 0
+ }
+ defer f.Close()
+
+ cpuNum := 0
+ s := bufio.NewScanner(f)
+ for s.Scan() {
+ if err := s.Err(); err != nil {
+ return 0
+ }
+
+ fields := strings.Fields(s.Text())
+ if len(fields) > 0 {
+ if fields[0] == processorIdentifier {
+ cpuNum++
+ }
+ }
+ }
+ return cpuNum
+}
--
2.25.1

View File

@ -1,26 +0,0 @@
From 514a0a19e5f37458d1a7e44c8b2fb4bff3b12d5b Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Fri, 5 Nov 2021 16:40:05 +0800
Subject: [PATCH] kata-runtime: fix delete sandbox failed problem
Signed-off-by: jikui <jikui2@huawei.com>
---
src/runtime/virtcontainers/sandbox.go | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/runtime/virtcontainers/sandbox.go b/src/runtime/virtcontainers/sandbox.go
index 33ae6f0..09cb2eb 100644
--- a/src/runtime/virtcontainers/sandbox.go
+++ b/src/runtime/virtcontainers/sandbox.go
@@ -1114,6 +1114,8 @@ func (s *Sandbox) CreateContainer(ctx context.Context, contConfig ContainerConfi
if len(s.config.Containers) > 0 {
// delete container config
s.config.Containers = s.config.Containers[:len(s.config.Containers)-1]
+ // need to flush change to persist storage
+ _ = s.storeSandbox(ctx)
}
}
}()
--
2.25.1

View File

@ -1,38 +0,0 @@
From 8251be558d6824fa1dce37836b7f1d6ec6be6e9f Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Tue, 30 Nov 2021 10:36:27 +0800
Subject: [PATCH] kata-runtime: check VFIO when create device
Signed-off-by: jikui <jikui2@huawei.com>
---
src/runtime/virtcontainers/device/manager/manager.go | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/runtime/virtcontainers/device/manager/manager.go b/src/runtime/virtcontainers/device/manager/manager.go
index 4515609..3afc148 100644
--- a/src/runtime/virtcontainers/device/manager/manager.go
+++ b/src/runtime/virtcontainers/device/manager/manager.go
@@ -10,6 +10,7 @@ import (
"context"
"encoding/hex"
"errors"
+ "fmt"
"sync"
"github.com/sirupsen/logrus"
@@ -116,7 +117,11 @@ func (dm *deviceManager) createDevice(devInfo config.DeviceInfo) (dev api.Device
}()
if existingDev := dm.findDeviceByMajorMinor(devInfo.Major, devInfo.Minor); existingDev != nil {
- return existingDev, nil
+ if isVFIO(devInfo.HostPath) {
+ return nil, fmt.Errorf("device %s is replicated in the same Pod!", devInfo.ContainerPath)
+ } else {
+ return existingDev, nil
+ }
}
// device ID must be generated by manager instead of device itself
--
2.25.1

View File

@ -1,76 +0,0 @@
From 51e17297b61fdb9ec560bae2f6c36003c8ebdfc0 Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Tue, 30 Nov 2021 11:29:50 +0800
Subject: [PATCH] kata-runtime: do not delete the exist tap device in the host
Signed-off-by: jikui <jikui2@huawei.com>
---
src/runtime/virtcontainers/tap_endpoint.go | 16 +++++++++++++---
src/runtime/virtcontainers/veth_endpoint.go | 3 +++
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/runtime/virtcontainers/tap_endpoint.go b/src/runtime/virtcontainers/tap_endpoint.go
index 9617945..5eafd15 100644
--- a/src/runtime/virtcontainers/tap_endpoint.go
+++ b/src/runtime/virtcontainers/tap_endpoint.go
@@ -80,7 +80,7 @@ func (endpoint *TapEndpoint) Detach(ctx context.Context, netNsCreated bool, netN
networkLogger().WithField("endpoint-type", TapEndpointType).Info("Detaching endpoint")
return doNetNS(netNsPath, func(_ ns.NetNS) error {
- return unTapNetwork(endpoint.TapInterface.TAPIface.Name)
+ return unTapNetwork(endpoint)
})
}
@@ -94,6 +94,9 @@ func (endpoint *TapEndpoint) HotAttach(ctx context.Context, h hypervisor) error
if _, err := h.hotplugAddDevice(ctx, endpoint, netDev); err != nil {
networkLogger().WithError(err).Error("Error attach tap ep")
+ if errUnTap := unTapNetwork(endpoint); errUnTap != nil {
+ networkLogger().WithError(errUnTap).Errorf("Error rollback tap %s", endpoint.TapInterface.TAPIface.Name)
+ }
return err
}
return nil
@@ -103,7 +106,7 @@ func (endpoint *TapEndpoint) HotAttach(ctx context.Context, h hypervisor) error
func (endpoint *TapEndpoint) HotDetach(ctx context.Context, h hypervisor, netNsCreated bool, netNsPath string) error {
networkLogger().Info("Hot detaching tap endpoint")
if err := doNetNS(netNsPath, func(_ ns.NetNS) error {
- return unTapNetwork(endpoint.TapInterface.TAPIface.Name)
+ return unTapNetwork(endpoint)
}); err != nil {
networkLogger().WithError(err).Warn("Error un-bridging tap ep")
}
@@ -174,7 +177,14 @@ func tapNetwork(endpoint *TapEndpoint, numCPUs uint32, disableVhostNet bool) err
return nil
}
-func unTapNetwork(name string) error {
+func unTapNetwork(endpoint *TapEndpoint) error {
+ // length of VMFDs == 0 means that the endpoint is already exist in the host,
+ // no created by kata, so we don't need to remove it when detach
+ if len(endpoint.TapInterface.VMFds) == 0 {
+ return nil
+ }
+
+ name := endpoint.TapInterface.TAPIface.Name
netHandle, err := netlink.NewHandle()
if err != nil {
return err
diff --git a/src/runtime/virtcontainers/veth_endpoint.go b/src/runtime/virtcontainers/veth_endpoint.go
index f93ca21..5f2435c 100644
--- a/src/runtime/virtcontainers/veth_endpoint.go
+++ b/src/runtime/virtcontainers/veth_endpoint.go
@@ -124,6 +124,9 @@ func (endpoint *VethEndpoint) HotAttach(ctx context.Context, h hypervisor) error
if _, err := h.hotplugAddDevice(ctx, endpoint, netDev); err != nil {
networkLogger().WithError(err).Error("Error attach virtual ep")
+ if errDisconn := xDisconnectVMNetwork(endpoint); errDisconn != nil {
+ networkLogger().WithError(errDisconn).Error("Error rollback virtual ep")
+ }
return err
}
return nil
--
2.25.1

View File

@ -1,33 +0,0 @@
From 39ac2f6929aea7e404c4597683e43fba7949964c Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Tue, 30 Nov 2021 11:47:36 +0800
Subject: [PATCH] kata-runtime: do not ignore updateInterface return error
Signed-off-by: jikui <jikui2@huawei.com>
---
src/runtime/virtcontainers/kata_agent.go | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go
index 607f1c8..19d09bb 100644
--- a/src/runtime/virtcontainers/kata_agent.go
+++ b/src/runtime/virtcontainers/kata_agent.go
@@ -620,7 +620,15 @@ func (k *kataAgent) updateInterface(ctx context.Context, ifc *pbTypes.Interface)
"interface-requested": fmt.Sprintf("%+v", ifc),
"resulting-interface": fmt.Sprintf("%+v", resultingInterface),
}).WithError(err).Error("update interface request failed")
+ return nil, err
+ }
+
+ // need to judege resultingInterface is not nil, otherwise may cause
+ // deference nil pointer panic problem
+ if resultingInterface == nil {
+ return nil, fmt.Errorf("resultingInterface should not be nil")
}
+
if resultInterface, ok := resultingInterface.(*pbTypes.Interface); ok {
return resultInterface, err
}
--
2.25.1

View File

@ -1,45 +0,0 @@
From 1bb584ac783d057b64058b02cc96c1c67dd7bf30 Mon Sep 17 00:00:00 2001
From: jikui <jikui2@huawei.com>
Date: Tue, 30 Nov 2021 12:02:42 +0800
Subject: [PATCH] kata-runtime: fix the block device not remove in devManager
Signed-off-by: jikui <jikui2@huawei.com>
---
src/runtime/virtcontainers/container.go | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/runtime/virtcontainers/container.go b/src/runtime/virtcontainers/container.go
index 224f096..dd4317e 100644
--- a/src/runtime/virtcontainers/container.go
+++ b/src/runtime/virtcontainers/container.go
@@ -1302,6 +1302,7 @@ func (c *Container) plugDevice(ctx context.Context, devicePath string) error {
}
if c.checkBlockDeviceSupport(ctx) && stat.Mode&unix.S_IFBLK == unix.S_IFBLK {
+ var err error
b, err := c.sandbox.devManager.NewDevice(config.DeviceInfo{
HostPath: devicePath,
ContainerPath: filepath.Join(kataGuestSharedDir(), c.id),
@@ -1313,10 +1314,18 @@ func (c *Container) plugDevice(ctx context.Context, devicePath string) error {
return fmt.Errorf("device manager failed to create rootfs device for %q: %v", devicePath, err)
}
+ defer func() {
+ if err != nil {
+ if newErr := c.sandbox.devManager.RemoveDevice(b.DeviceID()); newErr != nil {
+ c.Logger().WithError(newErr).Error("fail rollback to remove block device")
+ }
+ }
+ }()
+
c.state.BlockDeviceID = b.DeviceID()
// attach rootfs device
- if err := c.sandbox.devManager.AttachDevice(ctx, b.DeviceID(), c.sandbox); err != nil {
+ if err = c.sandbox.devManager.AttachDevice(ctx, b.DeviceID(), c.sandbox); err != nil {
return err
}
}
--
2.25.1

View File

@ -1,40 +0,0 @@
From c9e8df6902ecd72223a3837de953233f00f94093 Mon Sep 17 00:00:00 2001
From: holyfei <yangfeiyu20092010@163.com>
Date: Fri, 10 Dec 2021 09:43:30 +0800
Subject: [PATCH] kata-containers: modify stratovirt config file
Signed-off-by: holyfei <yangfeiyu20092010@163.com>
---
src/runtime/Makefile | 2 +-
src/runtime/cli/config/configuration-stratovirt.toml.in | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/runtime/Makefile b/src/runtime/Makefile
index 68e60ee..ff93ab3 100644
--- a/src/runtime/Makefile
+++ b/src/runtime/Makefile
@@ -293,7 +293,7 @@ ifneq (,$(STRATOVIRTCMD))
# stratovirt-specific options (all should be suffixed by "_STRATOVIRT")
DEFBLOCKSTORAGEDRIVER_STRATOVIRT := virtio-mmio
- DEFNETWORKMODEL_STRATOVIRT := none
+ DEFNETWORKMODEL_STRATOVIRT := tcfilter
KENRELTYPE_STRATOVIRT = uncompressed
KERNELPATH_STRATOVIRT = $(KERNEL_PATH)
endif
diff --git a/src/runtime/cli/config/configuration-stratovirt.toml.in b/src/runtime/cli/config/configuration-stratovirt.toml.in
index b557b71..753e3dc 100644
--- a/src/runtime/cli/config/configuration-stratovirt.toml.in
+++ b/src/runtime/cli/config/configuration-stratovirt.toml.in
@@ -13,7 +13,7 @@
[hypervisor.stratovirt]
path = "@STRATOVIRTPATH@"
kernel = "@KERNELPATH_STRATOVIRT@"
-image = "@IMAGEPATH@"
+initrd = "@IMAGEPATH@"
# List of valid annotation names for the hypervisor
# Each member of the list is a regular expression, which is the base name
--
2.27.0

View File

@ -1,243 +0,0 @@
From 1f83147653208f01effab0cf89209b8454d15f03 Mon Sep 17 00:00:00 2001
From: "Xinle.Guo" <guoxinle1@huawei.com>
Date: Mon, 10 Jan 2022 10:49:44 +0800
Subject: [PATCH 1/5] stratovirt: update configuration toml file
1.Adapt to default machine type as microvm.
2.Add more configuration items.
3.Modify toml file format.
Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
---
src/runtime/Makefile | 2 +
.../config/configuration-stratovirt.toml.in | 67 ++++++++++++-------
2 files changed, 46 insertions(+), 23 deletions(-)
diff --git a/src/runtime/Makefile b/src/runtime/Makefile
index ff93ab3..bade196 100644
--- a/src/runtime/Makefile
+++ b/src/runtime/Makefile
@@ -292,6 +292,7 @@ ifneq (,$(STRATOVIRTCMD))
CONFIGS += $(CONFIG_STRATOVIRT)
# stratovirt-specific options (all should be suffixed by "_STRATOVIRT")
+ DEFMACHINETYPE_STRATOVIRT := microvm
DEFBLOCKSTORAGEDRIVER_STRATOVIRT := virtio-mmio
DEFNETWORKMODEL_STRATOVIRT := tcfilter
KENRELTYPE_STRATOVIRT = uncompressed
@@ -437,6 +438,7 @@ USER_VARS += FIRMWAREPATH
USER_VARS += MACHINEACCELERATORS
USER_VARS += CPUFEATURES
USER_VARS += DEFMACHINETYPE_CLH
+USER_VARS += DEFMACHINETYPE_STRATOVIRT
USER_VARS += KERNELPARAMS
USER_VARS += LIBEXECDIR
USER_VARS += LOCALSTATEDIR
diff --git a/src/runtime/cli/config/configuration-stratovirt.toml.in b/src/runtime/cli/config/configuration-stratovirt.toml.in
index 753e3dc..db46665 100644
--- a/src/runtime/cli/config/configuration-stratovirt.toml.in
+++ b/src/runtime/cli/config/configuration-stratovirt.toml.in
@@ -14,6 +14,8 @@
path = "@STRATOVIRTPATH@"
kernel = "@KERNELPATH_STRATOVIRT@"
initrd = "@IMAGEPATH@"
+#image = "/var/lib/kata/kata-containers-rootfs.img"
+machine_type = "@DEFMACHINETYPE_STRATOVIRT@"
# List of valid annotation names for the hypervisor
# Each member of the list is a regular expression, which is the base name
@@ -29,12 +31,12 @@ valid_hypervisor_paths = @STRATOVIRTVALIDHYPERVISORPATHS@
# Path for the ozone specific to stratovirt
# If the ozone path is set, stratovirt will be launched in
# ozone secure environment. It is disabled by default.
-# ozone_path = "@STRATOVIRTOZONEPATH@"
+#ozone_path = "@STRATOVIRTOZONEPATH@"
# List of valid ozone path values for the hypervisor
# Each member of the list can be a regular expression
# The default if not set is empty (all annotations rejected.)
-# valid_jailer_paths = @STRATOVIRTVALIDOZONEPATHS@
+#valid_jailer_paths = @STRATOVIRTVALIDOZONEPATHS@
# Optional space-separated list of options to pass to the guest kernel.
# For example, use `kernel_params = "vsyscall=emulate"` if you are having
@@ -87,18 +89,18 @@ default_bridges = @DEFBRIDGES@
# Default memory size in MiB for SB/VM.
# If unspecified then it will be set @DEFMEMSZ@ MiB.
default_memory = @DEFMEMSZ@
-#
+
# Default memory slots per SB/VM.
# If unspecified then it will be set @DEFMEMSLOTS@.
# This is will determine the times that memory will be hotadded to sandbox/VM.
-# memory_slots = @DEFMEMSLOTS@
+#memory_slots = @DEFMEMSLOTS@
# The size in MiB will be plused to max memory of hypervisor.
# It is the memory address space for the NVDIMM devie.
# If set block storage driver (block_device_driver) to "nvdimm",
# should set memory_offset to the size of block device.
# Default 0
-# memory_offset = 0
+#memory_offset = 0
# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
@@ -108,6 +110,14 @@ default_memory = @DEFMEMSZ@
# 9pfs is used instead to pass the rootfs.
disable_block_device_use = @DEFDISABLEBLOCK@
+# Shared file system type:
+# - virtio-fs (default)
+# - virtio-9p
+shared_fs = "virtio-fs"
+
+# Path to vhost-user-fs daemon.
+virtio_fs_daemon = "/usr/bin/vhost_user_fs"
+
# Block storage driver to be used for the hypervisor in case the container
# rootfs is backed by a block device. This is virtio-scsi, virtio-blk
# or nvdimm.
@@ -120,12 +130,17 @@ block_device_driver = "@DEFBLOCKSTORAGEDRIVER_STRATOVIRT@"
# Specifies cache-related options for block devices.
# Denotes whether use of O_DIRECT (bypass the host page cache) is enabled.
# Default false
-# block_device_cache_direct = true
+#block_device_cache_direct = true
# Specifies cache-related options for block devices.
# Denotes whether flush requests for the device are ignored.
# Default false
-# block_device_cache_noflush = true
+#block_device_cache_noflush = true
+
+# Enable iothreads to be used. This causes IO to be
+# handled in a separate IO thread. This is currently only implemented
+# for virtio blk.
+#enable_iothreads = true
# Enable pre allocation of VM RAM, default false
# Enabling this will result in lower container density
@@ -134,7 +149,7 @@ block_device_driver = "@DEFBLOCKSTORAGEDRIVER_STRATOVIRT@"
# upfront or in the cases where you want memory latencies
# to be very predictable
# Default false
-# enable_mem_prealloc = true
+#enable_mem_prealloc = true
# Enable huge pages for VM RAM, default false
# Enabling this will result in the VM memory
@@ -142,42 +157,48 @@ block_device_driver = "@DEFBLOCKSTORAGEDRIVER_STRATOVIRT@"
# This is useful when you want to use vhost-user network
# stacks within the container. This will automatically
# result in memory pre allocation
-# enable_hugepages = true
+#enable_hugepages = true
# Enable vIOMMU, default false
# Enabling this will result in the VM having a vIOMMU device
# This will also add the following options to the kernel's
# command line: intel_iommu=on,iommu=pt
-# enable_iommu = true
+#enable_iommu = true
# Enable swap of vm memory. Default false.
# The behaviour is undefined if mem_prealloc is also set to true
-# enable_swap = true
+#enable_swap = true
# This option changes the default hypervisor and kernel parameters
# to enable debug output where available.
#
# Default false
-# enable_debug = true
+#enable_debug = true
# Disable the customizations done in the runtime when it detects
# that it is running on top a VMM. This will result in the runtime
# behaving as it would when running on bare metal.
#
-# disable_nesting_checks = true
+#disable_nesting_checks = true
# This is the msize used for 9p shares. It is the number of bytes
# used for 9p packet payload.
-# msize_9p =
+#msize_9p =
# VFIO devices are hotplugged on a bridge by default.
# Enable hotplugging on root bus. This may be required for devices with
# a large PCI bar, as this is a current limitation with hotplugging on
# a bridge.
# Default false
-# hotplug_vfio_on_root_bus = true
+#hotplug_vfio_on_root_bus = true
+
+# Before hot plugging a PCIe device, you need to add a pcie_root_port device.
+# Use this parameter when using some large PCI bar devices, such as Nvidia GPU
+# The value means the number of pcie_root_port
+# This value is valid when hotplug_vfio_on_root_bus is true and machine_type is "q35"
+# Default 0
+pcie_root_port = 2
-#
# Default entropy source.
# The path to a host source of entropy (including a real hardware RNG)
# /dev/urandom and /dev/random are two main options.
@@ -187,7 +208,7 @@ block_device_driver = "@DEFBLOCKSTORAGEDRIVER_STRATOVIRT@"
# The source of entropy /dev/urandom is non-blocking and provides a
# generally acceptable source of entropy. It should work well for pretty much
# all practical purposes.
-# entropy_source= ""
+entropy_source= "@DEFENTROPYSOURCE@"
# List of valid annotations values for entropy_source
# The default if not set is empty (all annotations rejected.)
@@ -209,7 +230,7 @@ valid_entropy_sources = @DEFVALIDENTROPYSOURCES@
# https://github.com/opencontainers/runtime-spec/blob/v1.0.1/config.md#posix-platform-hooks
# Warnings will be logged if any error is encountered will scanning for hooks,
# but it will not abort container execution.
-# guest_hook_path = "/usr/share/oci/hooks"
+#guest_hook_path = "/usr/share/oci/hooks"
[factory]
# VM templating support. Once enabled, new VMs are created from template
@@ -312,14 +333,14 @@ path = "@NETMONPATH@"
# Uses tc filter rules to redirect traffic from the network interface
# provided by plugin to a tap interface connected to the VM.
#
-internetworking_model="@DEFNETWORKMODEL_STRATOVIRT@"
+internetworking_model = "@DEFNETWORKMODEL_STRATOVIRT@"
# disable guest seccomp
# Determines whether container seccomp profiles are passed to the virtual
# machine and applied by the kata agent. If set to true, seccomp is not applied
# within the guest
# (default: true)
-disable_guest_seccomp=@DEFDISABLEGUESTSECCOMP@
+disable_guest_seccomp = @DEFDISABLEGUESTSECCOMP@
# If enabled, the runtime will create opentracing.io traces and spans.
# (See https://www.jaegertracing.io/docs/getting-started).
@@ -352,15 +373,15 @@ disable_guest_seccomp=@DEFDISABLEGUESTSECCOMP@
# The sandbox cgroup path is the parent cgroup of a container with the PodSandbox annotation.
# The sandbox cgroup is constrained if there is no container type annotation.
# See: https://godoc.org/github.com/kata-containers/runtime/virtcontainers#ContainerType
-sandbox_cgroup_only=@DEFSANDBOXCGROUPONLY@
+sandbox_cgroup_only = @DEFSANDBOXCGROUPONLY@
# Enabled experimental feature list, format: ["a", "b"].
# Experimental features are features not stable enough for production,
# they may break compatibility, and are prepared for a big version bump.
# Supported experimental features:
# (default: [])
-experimental=@DEFAULTEXPFEATURES@
+experimental = @DEFAULTEXPFEATURES@
# If enabled, user can run pprof tools with shim v2 process through kata-monitor.
# (default: false)
-# enable_pprof = true
+#enable_pprof = true
--
2.20.1.windows.1

View File

@ -1,235 +0,0 @@
From 37c4a009a6ea9028e237f849e7b27a15c602113e Mon Sep 17 00:00:00 2001
From: "Xinle.Guo" <guoxinle1@huawei.com>
Date: Tue, 11 Jan 2022 10:44:53 +0800
Subject: [PATCH] stratovirt: add struct `vmConfig` and methods to get all
parameters of VM
Defines `vmConfig` struct to containes all configuration items that
virtual machine needs. Provides methods to get VM paramters,
including name, UUID, cpu, memory, kernel, devices, etc.
Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
---
src/runtime/virtcontainers/stratovirt.go | 197 ++++++++++++++++++++++-
1 file changed, 189 insertions(+), 8 deletions(-)
diff --git a/src/runtime/virtcontainers/stratovirt.go b/src/runtime/virtcontainers/stratovirt.go
index e9b2ba8..7e32a8a 100644
--- a/src/runtime/virtcontainers/stratovirt.go
+++ b/src/runtime/virtcontainers/stratovirt.go
@@ -26,15 +26,196 @@ import (
)
const (
- apiSocket = "qmp.socket"
- debugSocket = "console.socket"
- ozoneBaseDir = "/srv/ozone/stratovirt"
- defaultDummyMac = "22:33:44:aa:bb:"
- mmioBlkCount = 4
- mmioNetCount = 2
- randomDevice = "/dev/urandom"
+ defaultStratoVirt = "/usr/bin/stratovirt"
+ ozoneBaseDir = "/srv/ozone/stratovirt"
+ defaultStratoVirtMachineType = "microvm"
+ defaultKernelParames = "console=hvc0 reboot=k panic=1 agent.use_vsock=true ramdom.trust_cpu=on rw"
+ defaultMicroVMParames = "pci=off iommu=off acpi=off"
+ apiSocket = "qmp.socket"
+ debugSocket = "console.socket"
+ virtiofsSocket = "virtiofs_kata.sock"
+ iothreadID = "iothread_block"
+ mmioBlkCount = 4
+ mmioNetCount = 2
)
+const (
+ WaitSandboxTimeoutSecs = 15
+ MachineTypeMicrovm = "microvm"
+)
+
+// VirtioDev is the StratoVirt device interface.
+type VirtioDev interface {
+ getParams(config *vmConfig) []string
+}
+
+type inComing struct {
+ path string
+ bootFromTemplate bool
+}
+
+type Ozone struct {
+ ozoneRoot string
+ ozoneRes []string
+ consolePath string
+ kernelPath string
+ initrdPath string
+ pidFile string
+ logFile string
+ qmpSocketPath string
+}
+
+// vmConfig keeps the custom settings and paramters to start virtual machine.
+type vmConfig struct {
+ name string
+ uuid string
+ machineType string
+ vmPath string
+ smp uint32
+ memory uint64
+ kernelPath string
+ params string
+ rootfsPath string
+ initrdPath string
+ rootBus types.Bridge
+ devices []VirtioDev
+ IOThread bool
+ PFlash []string
+ pidFile string
+ logFile string
+ qmpSocketPath govmmQemu.QMPSocket
+ consolePath string
+ fsSockPath string
+ incoming inComing
+ daemonize bool
+ useOzone bool
+ Ozone Ozone
+}
+
+func (c *vmConfig) appendName(params *[]string) {
+ if c.name == "" {
+ return
+ }
+ *params = append(*params, "-name", c.name)
+}
+
+func (c *vmConfig) appendUUID(params *[]string) {
+ if c.uuid == "" {
+ return
+ }
+ *params = append(*params, "-uuid", c.uuid)
+}
+
+func (c *vmConfig) appendMachine(params *[]string) {
+ if c.machineType == "" {
+ return
+ }
+ *params = append(*params, "-machine", fmt.Sprintf("type=%s,dump-guest-core=off,mem-share=on", c.machineType))
+}
+
+func (c *vmConfig) appendCPU(params *[]string) {
+ if c.smp == 0 {
+ return
+ }
+ *params = append(*params, "-smp", strconv.Itoa(int(c.smp)))
+}
+
+func (c *vmConfig) appendMemory(params *[]string) {
+ if c.memory == 0 {
+ return
+ }
+ *params = append(*params, "-m", strconv.Itoa(int(c.memory)))
+}
+
+func (c *vmConfig) appendKernel(params *[]string) {
+ var ozone Ozone
+ if c.kernelPath == "" {
+ return
+ }
+
+ if c.useOzone {
+ ozone = c.Ozone
+ *params = append(*params, "-kernel", ozone.kernelPath)
+ } else {
+ *params = append(*params, "-kernel", c.kernelPath)
+ }
+
+ if c.initrdPath != "" {
+ if c.useOzone {
+ *params = append(*params, "-initrd", ozone.initrdPath)
+ } else {
+ *params = append(*params, "-initrd", c.initrdPath)
+ }
+ }
+
+ if c.params != "" {
+ *params = append(*params, "-append", c.params)
+ }
+}
+
+func (c *vmConfig) appendIOThreads(params *[]string) {
+ if c.IOThread {
+ *params = append(*params, "-object", fmt.Sprintf("iothread,id=%s", iothreadID))
+ }
+}
+
+func (c *vmConfig) appendDevices(params *[]string) {
+ for _, d := range c.devices {
+ *params = append(*params, d.getParams(c)...)
+ }
+}
+
+func (c *vmConfig) appendPFlash(params *[]string) {
+ for _, p := range c.PFlash {
+ if p != "" {
+ *params = append(*params, "-drive", p)
+ }
+ }
+}
+
+func (c *vmConfig) appendPidFile(params *[]string) {
+ if c.pidFile == "" {
+ return
+ }
+
+ if c.useOzone {
+ *params = append(*params, "-pidfile", c.Ozone.pidFile)
+ } else {
+ *params = append(*params, "-pidfile", c.pidFile)
+ }
+}
+
+func (c *vmConfig) appendLogFile(params *[]string) {
+ if c.logFile == "" {
+ return
+ }
+
+ if c.useOzone {
+ *params = append(*params, "-D", c.Ozone.logFile)
+ } else {
+ *params = append(*params, "-D", c.logFile)
+ }
+}
+
+func (c *vmConfig) appendQMPSocket(params *[]string) {
+ qmpInfo := c.qmpSocketPath
+ qmpParams := append([]string{}, fmt.Sprintf("%s:", qmpInfo.Type))
+ if c.useOzone {
+ qmpParams = append(qmpParams, c.Ozone.qmpSocketPath)
+ } else {
+ qmpParams = append(qmpParams, qmpInfo.Name)
+ }
+ qmpParams = append(qmpParams, ",server")
+ qmpParams = append(qmpParams, ",nowait")
+ *params = append(*params, "-qmp", strings.Join(qmpParams, ""))
+}
+
+func (c *vmConfig) appendIncoming(params *[]string) {
+ if c.incoming.path != "" && c.incoming.bootFromTemplate {
+ *params = append(*params, "-incoming", fmt.Sprintf("file:%s", c.incoming.path))
+ }
+}
+
type stratovirtDev struct {
dev interface{}
devType deviceType
@@ -208,7 +389,7 @@ func (s *stratovirt) createbaseParams() []string {
params = append(params, "-m", fmt.Sprintf("%d", uint64(s.config.MemorySize)))
params = append(params, "-device", "virtio-serial-device")
params = append(params, "-device", "virtconsole,chardev=charconsole0,id=virtioconsole0")
- params = append(params, "-object", fmt.Sprintf("rng-random,id=objrng0,filename=%s", randomDevice))
+ params = append(params, "-object", fmt.Sprintf("rng-random,id=objrng0,filename=%s", s.config.EntropySource))
params = append(params, "-device", "virtio-rng-device,rng=objrng0")
// daemonize
--
2.20.1.windows.1

View File

@ -1,771 +0,0 @@
From 8c0dd0f91366910b3029cb982a3cb807bdbb34cf Mon Sep 17 00:00:00 2001
From: "Xinle.Guo" <guoxinle1@huawei.com>
Date: Fri, 14 Jan 2022 17:07:37 +0800
Subject: [PATCH] stratovirt: add a standard virtual machine sandbox type to
kata container
Because stratovirt supports both microVM and standardVM
architectures, adapts two sandbox types for kata container.
Besides basic features, it also support virtio-fs, hotplug
VFIO, support more devices.
Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
---
src/runtime/pkg/katautils/config.go | 1 +
src/runtime/virtcontainers/stratovirt.go | 482 ++++++++++++++++++++---
2 files changed, 438 insertions(+), 45 deletions(-)
diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go
index e523ed3..b04cdee 100644
--- a/src/runtime/pkg/katautils/config.go
+++ b/src/runtime/pkg/katautils/config.go
@@ -1007,6 +1007,7 @@ func newStratovirtHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
BlockDeviceCacheDirect: h.BlockDeviceCacheDirect,
BlockDeviceCacheNoflush: h.BlockDeviceCacheNoflush,
EnableIOThreads: h.EnableIOThreads,
+ PCIeRootPort: h.PCIeRootPort,
DisableVhostNet: h.DisableVhostNet,
EnableVhostUserStore: h.EnableVhostUserStore,
VhostUserStorePath: h.vhostUserStorePath(),
diff --git a/src/runtime/virtcontainers/stratovirt.go b/src/runtime/virtcontainers/stratovirt.go
index 4fcfb94..ffe8965 100644
--- a/src/runtime/virtcontainers/stratovirt.go
+++ b/src/runtime/virtcontainers/stratovirt.go
@@ -14,14 +14,14 @@ import (
"time"
govmmQemu "github.com/kata-containers/govmm/qemu"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
-
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
persistapi "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist/api"
+ vcTypes "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/types"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/uuid"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"go.opentelemetry.io/otel"
otelLabel "go.opentelemetry.io/otel/label"
otelTrace "go.opentelemetry.io/otel/trace"
@@ -44,6 +44,11 @@ const (
const (
WaitSandboxTimeoutSecs = 15
MachineTypeMicrovm = "microvm"
+ MachineTypeQ35 = "q35"
+ MachineTypeVirt = "virt"
+ RootPortPrefix = "pcie"
+ Q35PFlashCode = "/usr/share/edk2/ovmf/OVMF_CODE.fd"
+ VirtPFlashCode = "/usr/share/edk2/aarch64/QEMU_EFI-pflash.raw"
MmioBus VirtioDriver = "mmio"
PciBus VirtioDriver = "pci"
)
@@ -67,6 +72,42 @@ func (d VirtioDriver) getDriver(config *vmConfig) VirtioDriver {
}
}
+type rootPortDevice struct {
+ id string
+ port string
+ bus string
+ slot int
+ plugged bool
+ addedDev string
+}
+
+func (r rootPortDevice) isVaild() bool {
+ if r.id == "" || r.port == "" {
+ return false
+ }
+ return true
+}
+
+func (r rootPortDevice) getParams(config *vmConfig) []string {
+ if !r.isVaild() {
+ return nil
+ }
+
+ var params []string
+ var devParams []Param
+ devParams = append(devParams, Param{"id", r.id})
+ devParams = append(devParams, Param{"port", r.port})
+ if r.bus == "" {
+ r.bus = "pcie.0"
+ }
+ devParams = append(devParams, Param{"bus", r.bus})
+ devParams = append(devParams, Param{"addr", fmt.Sprintf("%d", r.slot)})
+
+ driver := "pcie-root-port"
+ params = append(params, "-device", fmt.Sprintf("%s,%s", driver, strings.Join(SerializeParams(devParams, "="), ",")))
+ return params
+}
+
type blkDevice struct {
id string
filePath string
@@ -179,6 +220,56 @@ func (n netDevice) getParams(config *vmConfig) []string {
return params
}
+type virtioFs struct {
+ driver VirtioDriver
+ backend string
+ charID string
+ charDev string
+ tag string
+ deviceID string
+ bus string
+ addr string
+}
+
+var virtiofsDriver = map[VirtioDriver]string{
+ MmioBus: "vhost-user-fs-device",
+ PciBus: "vhost-user-fs-pci",
+}
+
+func (v virtioFs) isVaild() bool {
+ if v.charID == "" || v.charDev == "" || v.deviceID == "" {
+ return false
+ }
+ return true
+}
+
+func (v virtioFs) getParams(config *vmConfig) []string {
+ if !v.isVaild() {
+ return nil
+ }
+
+ var params []string
+ var charParams []Param
+ var fsParams []Param
+
+ charParams = append(charParams, Param{"id", v.charID})
+ charParams = append(charParams, Param{"path", config.fsSockPath})
+
+ v.driver = v.driver.getDriver(config)
+ driver := virtiofsDriver[v.driver]
+ fsParams = append(fsParams, Param{"chardev", v.charDev})
+ fsParams = append(fsParams, Param{"tag", v.tag})
+ fsParams = append(fsParams, Param{"id", v.deviceID})
+ if v.bus != "" {
+ fsParams = append(fsParams, Param{"bus", v.bus})
+ fsParams = append(fsParams, Param{"addr", v.addr})
+ }
+
+ params = append(params, "-chardev", fmt.Sprintf("%s,%s,server,nowait", v.backend, strings.Join(SerializeParams(charParams, "="), ",")))
+ params = append(params, "-device", fmt.Sprintf("%s,%s", driver, strings.Join(SerializeParams(fsParams, "="), ",")))
+ return params
+}
+
type vhostVsock struct {
driver VirtioDriver
id string
@@ -442,6 +533,12 @@ func (c *vmConfig) appendDevices(params *[]string) {
for _, d := range c.devices {
*params = append(*params, d.getParams(c)...)
}
+
+ if c.machineType == MachineTypeMicrovm {
+ return
+ }
+ // Add flag to unplug devices from their root port faster.
+ *params = append(*params, "-global", "pcie-root-port.fast-unplug=1")
}
func (c *vmConfig) appendPFlash(params *[]string) {
@@ -499,6 +596,8 @@ func (c *vmConfig) appendIncoming(params *[]string) {
type State struct {
mmioBlkSlots [mmioBlkCount]bool
mmioNetSlots [mmioNetCount]bool
+ // The list of RootPorts that can be hot-added.
+ rootPort []rootPortDevice
pid int
virtiofsPid int
}
@@ -558,6 +657,26 @@ func (s *stratovirt) getKernelParams(machineType string, initrdPath string) (str
return strings.Join(params, " "), nil
}
+func (s *stratovirt) getPFlash(machineType string) ([]string, error) {
+ if s.config.PFlash != nil {
+ return s.config.PFlash, nil
+ }
+
+ var PFlash []string
+ switch machineType {
+ case MachineTypeQ35:
+ PFlash = append(PFlash, fmt.Sprintf("file=%s,if=pflash,unit=0", Q35PFlashCode))
+ case MachineTypeVirt:
+ PFlash = append(PFlash, fmt.Sprintf("file=%s,if=pflash,unit=0", VirtPFlashCode))
+ case MachineTypeMicrovm:
+ return nil, nil
+ default:
+ return nil, fmt.Errorf("failed to match machine type %s", machineType)
+ }
+
+ return PFlash, nil
+}
+
func (s *stratovirt) createQMPSocket(vmPath string) govmmQemu.QMPSocket {
socketPath := filepath.Join(vmPath, apiSocket)
@@ -590,6 +709,34 @@ func (s *stratovirt) createDevices() []VirtioDev {
}
}
+ // Create root port for all devices that need to be hot-added.
+ if s.vmConfig.machineType != MachineTypeMicrovm && s.config.PCIeRootPort > 0 {
+ devices = s.appendRootPort(ctx, devices)
+ }
+
+ return devices
+}
+
+func (s *stratovirt) appendRootPort(ctx context.Context, devices []VirtioDev) []VirtioDev {
+ number := s.config.PCIeRootPort
+
+ for i := uint32(1); i < number+1; i++ {
+ addr, err := s.vmConfig.rootBus.AddDevice(ctx, fmt.Sprintf("%s.%d", RootPortPrefix, i))
+ if err != nil {
+ return devices
+ }
+
+ rp := rootPortDevice{
+ id: fmt.Sprintf("%s.%d", RootPortPrefix, i),
+ port: fmt.Sprintf("%d", i),
+ bus: defaultBridgeBus,
+ slot: int(addr),
+ addedDev: "",
+ }
+ s.state.rootPort = append(s.state.rootPort, rp)
+ devices = append(devices, rp)
+ }
+
return devices
}
@@ -729,6 +876,38 @@ func (s *stratovirt) appendNetwork(ctx context.Context, devices []VirtioDev, end
return devices
}
+func (s *stratovirt) appendVirtioFs(ctx context.Context, devices []VirtioDev, volume types.Volume) []VirtioDev {
+ if s.config.SharedFS != config.VirtioFS {
+ return devices
+ }
+
+ var bus string
+ var addr uint32
+ var err error
+ name := "virtio_fs"
+
+ if s.vmConfig.machineType != MachineTypeMicrovm {
+ bus = "pcie.0"
+ addr, err = s.vmConfig.rootBus.AddDevice(ctx, name)
+ if err != nil {
+ return devices
+ }
+ }
+
+ devices = append(devices, virtioFs{
+ backend: "socket",
+ // Virtio-fs must be bound to unique charDev, it uses the same name.
+ charID: name,
+ charDev: name,
+ tag: volume.MountTag,
+ deviceID: "virtio-fs0",
+ bus: bus,
+ addr: fmt.Sprintf("%d", addr),
+ })
+
+ return devices
+}
+
func (s *stratovirt) setVMConfig(id string, hypervisorConfig *HypervisorConfig) error {
span, _ := s.trace(s.ctx, "setStratoVirtUp")
defer span.End()
@@ -765,7 +944,10 @@ func (s *stratovirt) setVMConfig(id string, hypervisorConfig *HypervisorConfig)
return err
}
- var PFlash []string
+ PFlash, err := s.getPFlash(machineType)
+ if err != nil {
+ return err
+ }
vmPath := filepath.Join(s.store.RunVMStoragePath(), s.id)
qmpSocket := s.createQMPSocket(vmPath)
@@ -852,8 +1034,33 @@ func (s *stratovirt) setOzone() error {
return nil
}
-func (s *stratovirt) hypervisorConfig() HypervisorConfig {
- return s.config
+// Virtio fs daemon is a shared file system that lets VM access a directory
+// tree on the host.
+func (s *stratovirt) setupVirtioFs() error {
+ if !s.config.DisableBlockDeviceUse || s.config.SharedFS != config.VirtioFS {
+ return nil
+ }
+
+ if _, err := os.Stat(s.config.VirtioFSDaemon); os.IsNotExist(err) {
+ return fmt.Errorf("virtiofsd path (%s) does not exist", s.config.VirtioFSDaemon)
+ }
+
+ args := []string{
+ "-socket-path", filepath.Join(s.vmConfig.vmPath, "virtiofs_kata.sock"),
+ "-source", getSharePath(s.id)}
+ if len(s.config.VirtioFSExtraArgs) != 0 {
+ args = append(args, s.config.VirtioFSExtraArgs...)
+ }
+
+ cmd := exec.Command(s.config.VirtioFSDaemon, args...)
+ s.Logger().Info("Virtiofsd start with cmd: ", cmd)
+
+ if err := cmd.Start(); err != nil {
+ return fmt.Errorf("failed to strat virtiofsd: %v", cmd)
+ }
+
+ s.state.virtiofsPid = cmd.Process.Pid
+ return nil
}
// Get StratoVirt binary path.
@@ -873,6 +1080,10 @@ func (s *stratovirt) binPath() (string, error) {
return path, nil
}
+func (s *stratovirt) hypervisorConfig() HypervisorConfig {
+ return s.config
+}
+
func (s *stratovirt) createSandbox(ctx context.Context, id string, networkNS NetworkNamespace, hypervisorConfig *HypervisorConfig) error {
var span otelTrace.Span
span, _ = s.trace(ctx, "createSandbox")
@@ -1000,6 +1211,10 @@ func (s *stratovirt) startSandbox(ctx context.Context, timeout int) error {
}
}()
+ if err = s.setupVirtioFs(); err != nil {
+ return err
+ }
+
var params []string
s.createBaseParams(s.vmConfig, &params)
@@ -1134,28 +1349,29 @@ func (s *stratovirt) addDevice(ctx context.Context, devInfo interface{}, devType
s.vmConfig.devices = s.appendNetwork(ctx, s.vmConfig.devices, v)
case config.BlockDrive:
s.vmConfig.devices = s.appendBlock(ctx, s.vmConfig.devices)
+ case types.Volume:
+ s.vmConfig.devices = s.appendVirtioFs(ctx, s.vmConfig.devices, v)
default:
s.Logger().WithField("dev-type", v).Warn("Could not append device: unsupported device type")
}
return nil
}
-func (s *stratovirt) getDevSlot(Name string, isPut bool) (slot int, err error) {
+func (s *stratovirt) setupMmioSlot(Name string, isPut bool) (int, error) {
Name = filepath.Base(strings.ToLower(Name))
-
if strings.HasPrefix(Name, "eth") {
idxStr := strings.TrimPrefix(Name, "eth")
if idxStr == Name {
- return 0, fmt.Errorf("Could not parse idx from Name %q", Name)
+ return 0, fmt.Errorf("could not parse idx from name %q", Name)
}
idx, err := strconv.Atoi(idxStr)
if err != nil {
- return 0, fmt.Errorf("Could not convert to int from Str %q", idxStr)
+ return 0, fmt.Errorf("could not convert to int from str %q", idxStr)
}
if !isPut && s.state.mmioNetSlots[idx] {
- return 0, fmt.Errorf("GetDevSlot failed, slot is being used %q", idxStr)
+ return 0, fmt.Errorf("failed to setup mmio slot, slot is being used %q", idxStr)
}
s.state.mmioNetSlots[idx] = !isPut
@@ -1163,25 +1379,80 @@ func (s *stratovirt) getDevSlot(Name string, isPut bool) (slot int, err error) {
} else if strings.HasPrefix(Name, "vd") {
charStr := strings.TrimPrefix(Name, "vd")
if charStr == Name {
- return 0, fmt.Errorf("Could not parse idx from Name %q", Name)
+ return 0, fmt.Errorf("could not parse idx from name %q", Name)
}
char := []rune(charStr)
idx := int(char[0] - 'a')
if !isPut && s.state.mmioBlkSlots[idx] {
- return 0, fmt.Errorf("GetDevSlot failed, slot is being used %q", charStr)
+ return 0, fmt.Errorf("failed to setup mmio slot, slot is being used %q", charStr)
}
s.state.mmioBlkSlots[idx] = !isPut
return idx, nil
}
- return 0, fmt.Errorf("GetDevSlot failed, Name is invalid %q", Name)
+ return 0, fmt.Errorf("failed to setup mmio slot , Name is invalid %q", Name)
+}
+
+func (s *stratovirt) setupPciSlot(Name string, isPut bool) (string, int, error) {
+ rootports := &s.state.rootPort
+ if len(*rootports) == 0 {
+ return "", 0, fmt.Errorf("failed to get available address from bridges")
+ }
+
+ for i, rootport := range *rootports {
+ if !isPut && !rootport.plugged && rootport.addedDev == "" {
+ (*rootports)[i].plugged = true
+ (*rootports)[i].addedDev = Name
+ return rootport.id, rootport.slot, nil
+ } else if isPut && rootport.plugged && rootport.addedDev == Name {
+ (*rootports)[i].plugged = false
+ (*rootports)[i].addedDev = ""
+ return rootport.id, rootport.slot, nil
+ }
+ }
+
+ return "", 0, fmt.Errorf("no more bridge slots available")
+}
+
+func (s *stratovirt) getDevSlot(Name string) (string, int, error) {
+ if s.config.HypervisorMachineType == MachineTypeMicrovm {
+ slot, err := s.setupMmioSlot(Name, false)
+ if err != nil {
+ return "", 0, err
+ }
+
+ return "", slot, nil
+ }
+
+ bus, slot, err := s.setupPciSlot(Name, false)
+ if err != nil {
+ return "pcie.0", 0, err
+ }
+
+ return bus, slot, nil
+}
+
+func (s *stratovirt) delDevSlot(Name string) error {
+ if s.vmConfig.machineType == MachineTypeMicrovm {
+ if _, err := s.setupMmioSlot(Name, true); err != nil {
+ return err
+ }
+
+ return nil
+ }
+
+ if _, _, err := s.setupPciSlot(Name, true); err != nil {
+ return err
+ }
+
+ return nil
}
-func (s *stratovirt) hotplugNet(ctx context.Context, endpoint Endpoint, op operation) (err error) {
- err = s.qmpSetup()
+func (s *stratovirt) hotplugNet(ctx context.Context, endpoint Endpoint, op operation) error {
+ err := s.qmpSetup()
if err != nil {
return err
}
@@ -1198,6 +1469,14 @@ func (s *stratovirt) hotplugNet(ctx context.Context, endpoint Endpoint, op opera
return fmt.Errorf("Endpoint is not supported")
}
+ defer func() {
+ if err != nil {
+ if errDel := s.delDevSlot(endpoint.Name()); errDel != nil {
+ s.Logger().WithError(errDel).Warnf("Failed to delete device slot.")
+ }
+ }
+ }()
+
switch op {
case addDevice:
var (
@@ -1220,27 +1499,51 @@ func (s *stratovirt) hotplugNet(ctx context.Context, endpoint Endpoint, op opera
VhostFdNames = append(VhostFdNames, fdName)
}
- slot, err := s.getDevSlot(endpoint.Name(), false)
+ bus, slot, err := s.getDevSlot(endpoint.Name())
if err != nil {
- return fmt.Errorf("Could not get unused slot for %q", endpoint.Name())
+ return fmt.Errorf("could not get unused slot for %q", endpoint.Name())
}
if len(VMFdNames) != 0 || len(VhostFdNames) != 0 {
if err := s.qmpMonitorCh.qmp.ExecuteNetdevAddByFds(s.qmpMonitorCh.ctx, "tap", tap.ID, VMFdNames, VhostFdNames); err != nil {
- s.getDevSlot(endpoint.Name(), true)
return err
}
} else {
if err := s.qmpMonitorCh.qmp.ExecuteNetdevAdd(s.qmpMonitorCh.ctx, "tap", tap.ID, tap.TAPIface.Name, "no", "no", 0); err != nil {
- s.getDevSlot(endpoint.Name(), true)
return err
}
}
- if err := s.qmpMonitorCh.qmp.ExecuteNetPCIDeviceAdd(s.qmpMonitorCh.ctx, tap.Name, tap.ID, endpoint.HardwareAddr(), fmt.Sprintf("%d", slot), "", "", 0, false); err != nil {
- s.getDevSlot(endpoint.Name(), true)
+
+ // The slot of net device that hotplugged to the root port
+ // must be zero.
+ devAddr := "0x0.0x0"
+ if s.vmConfig.machineType == MachineTypeMicrovm {
+ devAddr = fmt.Sprintf("%d", slot)
+ } else {
+ bridgeSlot, err := vcTypes.PciSlotFromInt(slot)
+ if err != nil {
+ return err
+ }
+
+ devSlot, err := vcTypes.PciSlotFromString("0")
+ if err != nil {
+ return err
+ }
+
+ pciPath, err := vcTypes.PciPathFromSlots(bridgeSlot, devSlot)
+ if err != nil {
+ return err
+ }
+ endpoint.SetPciPath(pciPath)
+ }
+
+ if err := s.qmpMonitorCh.qmp.ExecuteNetPCIDeviceAdd(s.qmpMonitorCh.ctx, tap.ID, tap.ID, endpoint.HardwareAddr(), devAddr, bus, "", 0, false); err != nil {
return err
}
case removeDevice:
+ if errDel := s.delDevSlot(endpoint.Name()); errDel != nil {
+ s.Logger().WithError(errDel).Warnf("Failed to delete device slot.")
+ }
if err := s.qmpMonitorCh.qmp.ExecuteDeviceDel(s.qmpMonitorCh.ctx, tap.ID); err != nil {
return err
}
@@ -1248,58 +1551,134 @@ func (s *stratovirt) hotplugNet(ctx context.Context, endpoint Endpoint, op opera
return err
}
default:
- return fmt.Errorf("Operation is not supported")
+ return fmt.Errorf("operation is not supported")
}
return nil
}
-func (s *stratovirt) hotplugBlk(drive *config.BlockDrive, op operation) (err error) {
- var filePath string
- err = s.qmpSetup()
+func (s *stratovirt) hotplugBlk(ctx context.Context, drive *config.BlockDrive, op operation) error {
+ err := s.qmpSetup()
if err != nil {
return err
}
+ driver := "virtio-blk-pci"
+ if s.vmConfig.machineType == MachineTypeMicrovm {
+ driver = "virtio-blk-mmio"
+ }
+
+ defer func() {
+ if err != nil {
+ s.qmpMonitorCh.qmp.ExecuteBlockdevDel(s.qmpMonitorCh.ctx, drive.ID)
+ if errDel := s.delDevSlot(drive.VirtPath); errDel != nil {
+ s.Logger().WithError(errDel).Warnf("Failed to delete device slot.")
+ }
+ }
+ }()
+
switch op {
case addDevice:
- driver := "virtio-blk-mmio"
+ filePath := drive.File
if s.vmConfig.useOzone {
filePath, err = s.updateOzoneRes(drive.File, true)
- if err != nil {
- return fmt.Errorf("Failed to update ozone resources")
- }
- } else {
- filePath = drive.File
- }
- slot, err := s.getDevSlot(drive.VirtPath, false)
- if err != nil {
- return fmt.Errorf("Could not get unused slot for %q", drive.VirtPath)
}
if err := s.qmpMonitorCh.qmp.ExecuteBlockdevAdd(s.qmpMonitorCh.ctx, filePath, drive.ID, false); err != nil {
- s.getDevSlot(drive.VirtPath, true)
return err
}
- if err := s.qmpMonitorCh.qmp.ExecutePCIDeviceAdd(s.qmpMonitorCh.ctx, drive.ID, drive.ID, driver, fmt.Sprintf("%d", slot), "", "", 0, true, false); err != nil {
- s.getDevSlot(drive.VirtPath, true)
+ bus, slot, err := s.getDevSlot(drive.VirtPath)
+ if err != nil {
+ return err
+ }
+
+ // The slot of block device that hotplugged to the root port
+ // must be zero.
+ devAddr := "0x0.0x0"
+ if s.vmConfig.machineType == MachineTypeMicrovm {
+ devAddr = fmt.Sprintf("%d", slot)
+ } else {
+ bridgeSlot, err := vcTypes.PciSlotFromInt(slot)
+ if err != nil {
+ return err
+ }
+
+ devSlot, err := vcTypes.PciSlotFromString("0")
+ if err != nil {
+ return err
+ }
+
+ drive.PCIPath, err = vcTypes.PciPathFromSlots(bridgeSlot, devSlot)
+ if err != nil {
+ return err
+ }
+ }
+
+ if err := s.qmpMonitorCh.qmp.ExecutePCIDeviceAdd(s.qmpMonitorCh.ctx, drive.ID, drive.ID, driver, devAddr, bus, "", 0, false, false); err != nil {
return err
}
case removeDevice:
if s.vmConfig.useOzone {
s.updateOzoneRes(drive.File, false)
}
+
+ if errDel := s.delDevSlot(drive.VirtPath); errDel != nil {
+ s.Logger().WithError(errDel).Warnf("Failed to delete device slot.")
+ }
if err := s.qmpMonitorCh.qmp.ExecuteDeviceDel(s.qmpMonitorCh.ctx, drive.ID); err != nil {
return err
}
if err := s.qmpMonitorCh.qmp.ExecuteBlockdevDel(s.qmpMonitorCh.ctx, drive.ID); err != nil {
return err
}
+ default:
+ return fmt.Errorf("operation is not supported %d", op)
+ }
+
+ return nil
+}
+
+func (s *stratovirt) hotplugVFIO(ctx context.Context, device *config.VFIODev, op operation) error {
+ err := s.qmpSetup()
+ if err != nil {
+ return err
+ }
+
+ defer func() {
+ if err != nil {
+ if errDel := s.delDevSlot(device.ID); errDel != nil {
+ s.Logger().WithError(errDel).Warnf("Failed to delete device slot.")
+ }
+ }
+ }()
- s.getDevSlot(drive.VirtPath, true)
+ switch op {
+ case addDevice:
+ var bus string
+ // The slot of block device that hotplugged to the root port
+ // must be zero.
+ devAddr := "0x0.0x0"
+ // The vfio device BDF format is 0000:1a:00.3
+ device.BDF = "0000:" + device.BDF
+
+ bus, _, err = s.getDevSlot(device.ID)
+ if err != nil {
+ return err
+ }
+
+ if err = s.qmpMonitorCh.qmp.ExecutePCIVFIODeviceAdd(s.qmpMonitorCh.ctx, device.ID, device.BDF, devAddr, bus, ""); err != nil {
+ return err
+ }
+ case removeDevice:
+ if errDel := s.delDevSlot(device.ID); errDel != nil {
+ s.Logger().WithError(errDel).Warnf("Failed to delete device slot.")
+ }
+ if err := s.qmpMonitorCh.qmp.ExecuteDeviceDel(s.qmpMonitorCh.ctx, device.ID); err != nil {
+ return err
+ }
default:
- return fmt.Errorf("Operation is not supported")
+ return fmt.Errorf("operation is not supported %d", op)
}
return nil
@@ -1313,9 +1692,11 @@ func (s *stratovirt) hotplugAddDevice(ctx context.Context, devInfo interface{},
case netDev:
return nil, s.hotplugNet(ctx, devInfo.(Endpoint), addDevice)
case blockDev:
- return nil, s.hotplugBlk(devInfo.(*config.BlockDrive), addDevice)
+ return nil, s.hotplugBlk(ctx, devInfo.(*config.BlockDrive), addDevice)
+ case vfioDev:
+ return nil, s.hotplugVFIO(ctx, devInfo.(*config.VFIODev), addDevice)
default:
- return nil, fmt.Errorf("Hotplug add device failed: unsupported device type '%v'", devType)
+ return nil, fmt.Errorf("hotplug add device failed: unsupported device type '%v'", devType)
}
}
@@ -1327,9 +1708,11 @@ func (s *stratovirt) hotplugRemoveDevice(ctx context.Context, devInfo interface{
case netDev:
return nil, s.hotplugNet(ctx, devInfo.(Endpoint), removeDevice)
case blockDev:
- return nil, s.hotplugBlk(devInfo.(*config.BlockDrive), removeDevice)
+ return nil, s.hotplugBlk(ctx, devInfo.(*config.BlockDrive), removeDevice)
+ case vfioDev:
+ return nil, s.hotplugVFIO(ctx, devInfo.(*config.VFIODev), removeDevice)
default:
- return nil, fmt.Errorf("Hotplug remove device: unsupported device type '%v'", devType)
+ return nil, fmt.Errorf("hotplug remove device: unsupported device type '%v'", devType)
}
}
@@ -1371,6 +1754,10 @@ func (s *stratovirt) capabilities(ctx context.Context) types.Capabilities {
var caps types.Capabilities
caps.SetBlockDeviceHotplugSupport()
+ if s.config.DisableBlockDeviceUse && s.config.SharedFS == config.VirtioFS {
+ caps.SetFsSharingSupport()
+ }
+
return caps
}
@@ -1510,6 +1897,9 @@ func (s *stratovirt) getPids() []int {
pids = append(pids, s.state.pid)
+ if s.state.virtiofsPid != 0 {
+ pids = append(pids, s.state.virtiofsPid)
+ }
return pids
}
@@ -1544,12 +1934,14 @@ func (s *stratovirt) isRateLimiterBuiltin() bool {
func (s *stratovirt) save() (p persistapi.HypervisorState) {
pids := s.getPids()
p.Pid = pids[0]
+ p.VirtiofsdPid = s.state.virtiofsPid
p.Type = string(StratovirtHypervisor)
return
}
func (s *stratovirt) load(p persistapi.HypervisorState) {
s.state.pid = p.Pid
+ s.state.virtiofsPid = p.VirtiofsdPid
}
func (s *stratovirt) setSandbox(sandbox *Sandbox) {
--
2.20.1.windows.1

View File

@ -1,46 +0,0 @@
From 9ac9c120a51663fa98ef25d721c321e5d16b3859 Mon Sep 17 00:00:00 2001
From: "Xinle.Guo" <guoxinle1@huawei.com>
Date: Sat, 26 Feb 2022 17:25:11 +0800
Subject: [PATCH] stratovirt: fix the problem that fails to plug net device
In kernel, hot plug pcie device needs to sleep 100ms to avoid
misoperation. Kata 1.x version agent monitor the plug event to
make sure plug device success. But kata 2.x does not provide
method. It may failed to get net device after plug the device.
Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
---
src/runtime/virtcontainers/stratovirt.go | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/runtime/virtcontainers/stratovirt.go b/src/runtime/virtcontainers/stratovirt.go
index ffe8965..27b45b7 100644
--- a/src/runtime/virtcontainers/stratovirt.go
+++ b/src/runtime/virtcontainers/stratovirt.go
@@ -39,6 +39,7 @@ const (
iothreadID = "iothread_block"
mmioBlkCount = 4
mmioNetCount = 2
+ hotPlugDelayTime = 200
)
const (
@@ -1540,6 +1541,7 @@ func (s *stratovirt) hotplugNet(ctx context.Context, endpoint Endpoint, op opera
if err := s.qmpMonitorCh.qmp.ExecuteNetPCIDeviceAdd(s.qmpMonitorCh.ctx, tap.ID, tap.ID, endpoint.HardwareAddr(), devAddr, bus, "", 0, false); err != nil {
return err
}
+ time.Sleep(time.Millisecond * hotPlugDelayTime)
case removeDevice:
if errDel := s.delDevSlot(endpoint.Name()); errDel != nil {
s.Logger().WithError(errDel).Warnf("Failed to delete device slot.")
@@ -1670,6 +1672,7 @@ func (s *stratovirt) hotplugVFIO(ctx context.Context, device *config.VFIODev, op
if err = s.qmpMonitorCh.qmp.ExecutePCIVFIODeviceAdd(s.qmpMonitorCh.ctx, device.ID, device.BDF, devAddr, bus, ""); err != nil {
return err
}
+ time.Sleep(time.Millisecond * hotPlugDelayTime)
case removeDevice:
if errDel := s.delDevSlot(device.ID); errDel != nil {
s.Logger().WithError(errDel).Warnf("Failed to delete device slot.")
--
2.20.1.windows.1

View File

@ -1,78 +0,0 @@
From 769af40220ea3d7b87173f11c135e651076e14ee Mon Sep 17 00:00:00 2001
From: "Xinle.Guo" <guoxinle1@huawei.com>
Date: Wed, 2 Mar 2022 09:41:49 +0800
Subject: [PATCH] stratovirt: provide a way to dynomically obtain firmware
For stratovirt, it requires firmware to boot. The default
path is `/usr/share/edk2/xxx/pflash`. Now, we provides a
way to set path in configuration.toml file
Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
---
src/runtime/cli/config/configuration-stratovirt.toml.in | 4 ++++
src/runtime/pkg/katautils/config.go | 6 ++++++
src/runtime/virtcontainers/stratovirt.go | 7 ++++---
3 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/src/runtime/cli/config/configuration-stratovirt.toml.in b/src/runtime/cli/config/configuration-stratovirt.toml.in
index db46665..519c390 100644
--- a/src/runtime/cli/config/configuration-stratovirt.toml.in
+++ b/src/runtime/cli/config/configuration-stratovirt.toml.in
@@ -28,6 +28,10 @@ enable_annotations = @DEFENABLEANNOTATIONS@
# Your distribution recommends: @STRATOVIRTVALIDHYPERVISORPATHS@
valid_hypervisor_paths = @STRATOVIRTVALIDHYPERVISORPATHS@
+# Path to the firmware.
+# If you want that qemu uses the default firmware leave this option empty
+firmware = "@FIRMWAREPATH@"
+
# Path for the ozone specific to stratovirt
# If the ozone path is set, stratovirt will be launched in
# ozone secure environment. It is disabled by default.
diff --git a/src/runtime/pkg/katautils/config.go b/src/runtime/pkg/katautils/config.go
index b04cdee..cdc9d7a 100644
--- a/src/runtime/pkg/katautils/config.go
+++ b/src/runtime/pkg/katautils/config.go
@@ -951,6 +951,11 @@ func newStratovirtHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
errors.New("either image or initrd must be defined in the configuration file")
}
+ firmware, err := h.firmware()
+ if err != nil {
+ return vc.HypervisorConfig{}, err
+ }
+
kernelParams := h.kernelParams()
machineType := h.machineType()
@@ -979,6 +984,7 @@ func newStratovirtHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
KernelPath: kernel,
InitrdPath: initrd,
ImagePath: image,
+ FirmwarePath: firmware,
OzonePath: ozone,
KernelParams: vc.DeserializeParams(strings.Fields(kernelParams)),
HypervisorMachineType: machineType,
diff --git a/src/runtime/virtcontainers/stratovirt.go b/src/runtime/virtcontainers/stratovirt.go
index 27b45b7..d2b2233 100644
--- a/src/runtime/virtcontainers/stratovirt.go
+++ b/src/runtime/virtcontainers/stratovirt.go
@@ -659,11 +659,12 @@ func (s *stratovirt) getKernelParams(machineType string, initrdPath string) (str
}
func (s *stratovirt) getPFlash(machineType string) ([]string, error) {
- if s.config.PFlash != nil {
- return s.config.PFlash, nil
+ var PFlash []string
+ if s.config.FirmwarePath != "" {
+ PFlash = append(PFlash, fmt.Sprintf("file=%s,if=pflash,unit=0", s.config.FirmwarePath))
+ return PFlash, nil
}
- var PFlash []string
switch machineType {
case MachineTypeQ35:
PFlash = append(PFlash, fmt.Sprintf("file=%s,if=pflash,unit=0", Q35PFlashCode))
--
2.20.1.windows.1

View File

@ -1,95 +0,0 @@
From c455ef6f406ba317af76b48ff79db131d0594bc1 Mon Sep 17 00:00:00 2001
From: "Xinle.Guo" <guoxinle1@huawei.com>
Date: Fri, 18 Mar 2022 10:49:35 +0800
Subject: [PATCH] stratovirt: fix the problem that add more than 16 root port
devices
It will failed to start StratoVirt sandbox if pcie root prot is set
more than 16. The reason is that StratoVirt can only distinguish
hexadecimal device address number.
Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
---
src/runtime/virtcontainers/stratovirt.go | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/runtime/virtcontainers/stratovirt.go b/src/runtime/virtcontainers/stratovirt.go
index d2b2233..98a702a 100644
--- a/src/runtime/virtcontainers/stratovirt.go
+++ b/src/runtime/virtcontainers/stratovirt.go
@@ -102,7 +102,7 @@ func (r rootPortDevice) getParams(config *vmConfig) []string {
r.bus = "pcie.0"
}
devParams = append(devParams, Param{"bus", r.bus})
- devParams = append(devParams, Param{"addr", fmt.Sprintf("%d", r.slot)})
+ devParams = append(devParams, Param{"addr", fmt.Sprintf("0x%x", r.slot)})
driver := "pcie-root-port"
params = append(params, "-device", fmt.Sprintf("%s,%s", driver, strings.Join(SerializeParams(devParams, "="), ",")))
@@ -721,6 +721,9 @@ func (s *stratovirt) createDevices() []VirtioDev {
func (s *stratovirt) appendRootPort(ctx context.Context, devices []VirtioDev) []VirtioDev {
number := s.config.PCIeRootPort
+ if number > 20 {
+ number = 20
+ }
for i := uint32(1); i < number+1; i++ {
addr, err := s.vmConfig.rootBus.AddDevice(ctx, fmt.Sprintf("%s.%d", RootPortPrefix, i))
@@ -765,7 +768,7 @@ func (s *stratovirt) appendBlock(ctx context.Context, devices []VirtioDev) []Vir
filePath: s.vmConfig.rootfsPath,
deviceID: "virtio-blk0",
bus: bus,
- addr: fmt.Sprintf("%d", addr),
+ addr: fmt.Sprintf("0x%x", addr),
iothread: iothread,
})
@@ -791,7 +794,7 @@ func (s *stratovirt) appendRng(ctx context.Context, devices []VirtioDev) []Virti
rng: "objrng0",
deviceID: "virtio-rng0",
bus: bus,
- addr: fmt.Sprintf("%d", addr),
+ addr: fmt.Sprintf("0x%x", addr),
})
return devices
@@ -818,7 +821,7 @@ func (s *stratovirt) appendConsole(ctx context.Context, devices []VirtioDev) []V
charDev: "charconsole0",
deviceID: "virtio-console0",
bus: bus,
- addr: fmt.Sprintf("%d", addr),
+ addr: fmt.Sprintf("0x%x", addr),
})
return devices
@@ -841,7 +844,7 @@ func (s *stratovirt) appendVhostVsock(ctx context.Context, devices []VirtioDev,
id: "vsock-id",
guestID: fmt.Sprintf("%d", vsock.ContextID),
bus: bus,
- addr: fmt.Sprintf("%d", addr),
+ addr: fmt.Sprintf("0x%x", addr),
})
return devices
@@ -872,7 +875,7 @@ func (s *stratovirt) appendNetwork(ctx context.Context, devices []VirtioDev, end
deviceID: name,
bus: bus,
mac: endpoint.HardwareAddr(),
- addr: fmt.Sprintf("%d", addr),
+ addr: fmt.Sprintf("0x%x", addr),
})
return devices
@@ -904,7 +907,7 @@ func (s *stratovirt) appendVirtioFs(ctx context.Context, devices []VirtioDev, vo
tag: volume.MountTag,
deviceID: "virtio-fs0",
bus: bus,
- addr: fmt.Sprintf("%d", addr),
+ addr: fmt.Sprintf("0x%x", addr),
})
return devices
--
2.20.1.windows.1

View File

@ -1,38 +0,0 @@
From 2da8be5657f219de41e11917cb916895934749b8 Mon Sep 17 00:00:00 2001
From: chengzrz <czrzrichard@gmail.com>
Date: Mon, 22 Aug 2022 19:19:52 +0800
Subject: [PATCH] use host_device blockdev adding
ExecuteBlockdevAdd() and ExecuteBlockdevAddWithCache() both appear to be
intended to create block devices in the guest which backend onto a block
device in the host. That seems to be the way that Kata always uses it.
However blockdevAddBaseArgs(), used by both those functions always uses the
"file" driver, which is only intended for use with regular file backends.
Use of the "file" driver for host block devices was deprecated in qemu-3.0,
and has been removed entirely in qemu-6.0 (commit 8d17adf34f5). We should
be using the "host_device" driver instead.
reference: https://github.com/kata-containers/kata-containers/commit/1b021929864fa45b643d9603d6615cc4b86235d7
Signed-off-by: chengzrz <czrzrichard@gmail.com>
---
src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go b/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go
index 97e924559..0e0337dbf 100644
--- a/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go
+++ b/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go
@@ -775,7 +775,7 @@ func (q *QMP) blockdevAddBaseArgs(device, blockdevID string, ro bool) (map[strin
"driver": "raw",
"read-only": ro,
"file": map[string]interface{}{
- "driver": "file",
+ "driver": "host_device",
"filename": device,
},
}
--
2.25.1

View File

@ -1,33 +0,0 @@
From 0c9c5ca20b6aeae5e550decfd3540b389fb02cb5 Mon Sep 17 00:00:00 2001
From: chengzrz <czrzrichard@gmail.com>
Date: Tue, 23 Aug 2022 15:30:05 +0800
Subject: [PATCH] add explicit on after kernel_irqchip
Kata uses the 'kernel_irqchip' machine option to qemu. By default it
uses it in what qemu calls the "short-form boolean" with no parameter.
That style was deprecated by qemu between 5.2 and 6.0 (commit
ccd3b3b8112b) and effectively removed entirely between 6.0 and 6.1
(commit d8fb7d0969d5).
reference:https://github.com/kata-containers/kata-containers/commit/316509566966e4c9b3fd9ba3521554b384fdbf88
Signed-off-by: chengzrz <czrzrichard@gmail.com>
---
src/runtime/virtcontainers/qemu_amd64.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/runtime/virtcontainers/qemu_amd64.go b/src/runtime/virtcontainers/qemu_amd64.go
index 1a045fae0..bc598c653 100644
--- a/src/runtime/virtcontainers/qemu_amd64.go
+++ b/src/runtime/virtcontainers/qemu_amd64.go
@@ -27,7 +27,7 @@ const (
defaultQemuMachineType = QemuPC
- defaultQemuMachineOptions = "accel=kvm,kernel_irqchip"
+ defaultQemuMachineOptions = "accel=kvm,kernel_irqchip=on"
qmpMigrationWaitTimeout = 5 * time.Second
)
--
2.25.1

View File

@ -1,67 +0,0 @@
From e3296a68f7fa270d72605dfd4eb40b1081a79969 Mon Sep 17 00:00:00 2001
From: chengzrz <czrzrichard@gmail.com>
Date: Fri, 2 Sep 2022 15:10:26 +0800
Subject: [PATCH] qmp: Don't use deprecated 'props' field for object-add
Use of the 'props' argument to 'object-add' has been deprecated since QEMU
5.0 (commit 5f07c4d60d09) in favor of flattening the properties directly
into the 'object-add' arguments. Support for 'props' is removed entirely
in qemu 6.0 (commit 50243407457a).
reference:https://github.com/kata-containers/kata-containers/commit/d27256f8635d3fa382d6cbd9f3a60f601773c4dc
Signed-off-by: chengzrz <czrzrichard@gmail.com>
---
.../kata-containers/govmm/qemu/qmp.go | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go b/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go
index 97e9245..91dd732 100644
--- a/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go
+++ b/src/runtime/vendor/github.com/kata-containers/govmm/qemu/qmp.go
@@ -1387,17 +1387,16 @@ func (q *QMP) ExecQueryCpusFast(ctx context.Context) ([]CPUInfoFast, error) {
// ExecMemdevAdd adds size of MiB memory device to the guest
func (q *QMP) ExecMemdevAdd(ctx context.Context, qomtype, id, mempath string, size int, share bool, driver, driverID string) error {
- props := map[string]interface{}{"size": uint64(size) << 20}
args := map[string]interface{}{
"qom-type": qomtype,
"id": id,
- "props": props,
+ "size": uint64(size) << 20,
}
if mempath != "" {
- props["mem-path"] = mempath
+ args["mem-path"] = mempath
}
if share {
- props["share"] = true
+ args["share"] = true
}
err := q.executeCommand(ctx, "object-add", args, nil)
if err != nil {
@@ -1439,17 +1438,14 @@ func (q *QMP) ExecuteNVDIMMDeviceAdd(ctx context.Context, id, mempath string, si
args := map[string]interface{}{
"qom-type": "memory-backend-file",
"id": "nvdimmbackmem" + id,
- "props": map[string]interface{}{
- "mem-path": mempath,
- "size": size,
- "share": true,
- },
+ "mem-path": mempath,
+ "size": size,
+ "share": true,
}
if q.version.Major > 4 || (q.version.Major == 4 && q.version.Minor >= 1) {
if pmem != nil {
- props := args["props"].(map[string]interface{})
- props["pmem"] = *pmem
+ args["pmem"] = *pmem
}
}
--
2.25.1

View File

@ -1,57 +0,0 @@
From 443e65326eeccb3a4ad8170670d56c32931215f9 Mon Sep 17 00:00:00 2001
From: Vanient <xiadanni1@huawei.com>
Date: Thu, 8 Sep 2022 21:44:13 +0800
Subject: [PATCH] optimize compile options
Signed-off-by: Vanient <xiadanni1@huawei.com>
---
src/runtime/Makefile | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/src/runtime/Makefile b/src/runtime/Makefile
index bade196..ad421d9 100644
--- a/src/runtime/Makefile
+++ b/src/runtime/Makefile
@@ -566,7 +566,11 @@ monitor: $(MONITOR_OUTPUT)
netmon: $(NETMON_TARGET_OUTPUT)
$(NETMON_TARGET_OUTPUT): $(SOURCES) VERSION
- $(QUIET_BUILD)(cd $(NETMON_DIR) && go build $(BUILDFLAGS) -o $@ -ldflags "-X main.version=$(VERSION)" $(KATA_LDFLAGS))
+ $(QUIET_BUILD)(cd $(NETMON_DIR) && \
+ CGO_CFLAGS="-fstack-protector-strong -fPIE -D_FORTIFY_SOURCE=2 -O2" \
+ CGO_LDFLAGS_ALLOW="-Wl,-z,relro,-z,now" \
+ CGO_LDFLAGS="-Wl,-z,relro,-z,now -Wl,-z,noexecstack" \
+ go build $(BUILDFLAGS) -o $@ -ldflags "-linkmode=external -X main.version=$(VERSION)" $(KATA_LDFLAGS))
runtime: $(TARGET_OUTPUT) $(CONFIGS)
.DEFAULT: default
@@ -605,15 +609,23 @@ GENERATED_FILES += $(GENERATED_CONFIG)
GENERATED_FILES += pkg/katautils/config-settings.go
$(TARGET_OUTPUT): $(SOURCES) $(GENERATED_FILES) $(MAKEFILE_LIST) | show-summary
- $(QUIET_BUILD)(cd $(CLI_DIR) && go build $(KATA_LDFLAGS) $(BUILDFLAGS) -o $@ .)
+ $(QUIET_BUILD)(cd $(CLI_DIR) && \
+ CGO_CFLAGS="-fstack-protector-strong -fPIE -D_FORTIFY_SOURCE=2 -O2" \
+ CGO_LDFLAGS_ALLOW="-Wl,-z,relro,-z,now" \
+ CGO_LDFLAGS="-Wl,-z,relro,-z,now -Wl,-z,noexecstack" \
+ go build -ldflags "-linkmode=external" $(KATA_LDFLAGS) $(BUILDFLAGS) -o $@ .)
$(SHIMV2_OUTPUT): $(SOURCES) $(GENERATED_FILES) $(MAKEFILE_LIST)
$(QUIET_BUILD)(cd $(SHIMV2_DIR)/ && ln -fs $(GENERATED_CONFIG))
- $(QUIET_BUILD)(cd $(SHIMV2_DIR)/ && go build $(KATA_LDFLAGS) $(BUILDFLAGS) -o $@ .)
+ $(QUIET_BUILD)(cd $(SHIMV2_DIR)/ && \
+ CGO_CFLAGS="-fstack-protector-strong -fPIE -D_FORTIFY_SOURCE=2 -O2" \
+ CGO_LDFLAGS_ALLOW="-Wl,-z,relro,-z,now" \
+ CGO_LDFLAGS="-Wl,-z,relro,-z,now -Wl,-z,noexecstack" \
+ go build -ldflags "-linkmode=external" $(KATA_LDFLAGS) $(BUILDFLAGS) -o $@ .)
$(MONITOR_OUTPUT): $(SOURCES) $(GENERATED_FILES) $(MAKEFILE_LIST) .git-commit
$(QUIET_BUILD)(cd $(MONITOR_DIR)/ && CGO_ENABLED=0 go build \
- --ldflags "-X main.GitCommit=$(shell cat .git-commit)" $(BUILDFLAGS) -buildmode=exe -o $@ .)
+ --ldflags "-linkmode=external -X main.GitCommit=$(shell cat .git-commit)" $(BUILDFLAGS) -o $@ .)
.PHONY: \
check \
--
2.27.0

View File

@ -1,39 +0,0 @@
From 59cf9bfb95386f123190eff58d50e99ec1ec5ea7 Mon Sep 17 00:00:00 2001
From: Keqian Zhu <zhukeqian1@huawei.com>
Date: Tue, 20 Dec 2022 14:14:46 +0800
Subject: [PATCH] stratovirt: Append readonly option when get pflash cmdline
All Stratovirt VM shares the same pflash file by default, and file can only be
shared readonly for safety.
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
---
src/runtime/virtcontainers/stratovirt.go | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/runtime/virtcontainers/stratovirt.go b/src/runtime/virtcontainers/stratovirt.go
index 98a702a..7b01c76 100644
--- a/src/runtime/virtcontainers/stratovirt.go
+++ b/src/runtime/virtcontainers/stratovirt.go
@@ -661,15 +661,15 @@ func (s *stratovirt) getKernelParams(machineType string, initrdPath string) (str
func (s *stratovirt) getPFlash(machineType string) ([]string, error) {
var PFlash []string
if s.config.FirmwarePath != "" {
- PFlash = append(PFlash, fmt.Sprintf("file=%s,if=pflash,unit=0", s.config.FirmwarePath))
+ PFlash = append(PFlash, fmt.Sprintf("file=%s,if=pflash,unit=0,readonly=true", s.config.FirmwarePath))
return PFlash, nil
}
switch machineType {
case MachineTypeQ35:
- PFlash = append(PFlash, fmt.Sprintf("file=%s,if=pflash,unit=0", Q35PFlashCode))
+ PFlash = append(PFlash, fmt.Sprintf("file=%s,if=pflash,unit=0,readonly=true", Q35PFlashCode))
case MachineTypeVirt:
- PFlash = append(PFlash, fmt.Sprintf("file=%s,if=pflash,unit=0", VirtPFlashCode))
+ PFlash = append(PFlash, fmt.Sprintf("file=%s,if=pflash,unit=0,readonly=true", VirtPFlashCode))
case MachineTypeMicrovm:
return nil, nil
default:
--
2.33.0

View File

@ -1,111 +0,0 @@
From b5ce74b04b457d54104113c6fc7e507ead3ac26d Mon Sep 17 00:00:00 2001
From: Vanient <xiadanni1@huawei.com>
Date: Mon, 4 Sep 2023 15:36:45 +0800
Subject: [PATCH] update cgroup-rs crate
update cgroup-rs crate to fix "unable to write to a control group file"
Signed-off-by: Vanient <xiadanni1@huawei.com>
---
src/agent/Cargo.lock | 25 +++++++++++++++++++------
src/agent/Cargo.toml | 2 +-
src/agent/rustjail/Cargo.toml | 2 +-
3 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/src/agent/Cargo.lock b/src/agent/Cargo.lock
index 87807a3..799eec1 100644
--- a/src/agent/Cargo.lock
+++ b/src/agent/Cargo.lock
@@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+version = 3
+
[[package]]
name = "addr2line"
version = "0.14.0"
@@ -147,13 +149,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cgroups-rs"
-version = "0.2.5"
+version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4cec688ee0fcd143ffd7893ce2c9857bfc656eb1f2a27202244b72f08f5f8ed"
+checksum = "3845d8ddaca63e9975f07b7a32262afe284561c2f0f620aa968913a65f671fd2"
dependencies = [
"libc",
"log",
- "nix 0.20.0",
+ "nix 0.24.3",
"regex",
]
@@ -510,9 +512,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.91"
+version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"
+checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "libflate"
@@ -727,6 +729,17 @@ dependencies = [
"libc",
]
+[[package]]
+name = "nix"
+version = "0.24.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
+dependencies = [
+ "bitflags",
+ "cfg-if 1.0.0",
+ "libc",
+]
+
[[package]]
name = "ntapi"
version = "0.3.6"
@@ -877,7 +890,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "059a34f111a9dee2ce1ac2826a68b24601c4298cfeb1a587c3cb493d5ab46f52"
dependencies = [
"libc",
- "nix 0.19.1",
+ "nix 0.20.0",
]
[[package]]
diff --git a/src/agent/Cargo.toml b/src/agent/Cargo.toml
index 195b53b..3405827 100644
--- a/src/agent/Cargo.toml
+++ b/src/agent/Cargo.toml
@@ -45,7 +45,7 @@ tempfile = "3.1.0"
prometheus = { version = "0.9.0", features = ["process"] }
procfs = "0.7.9"
anyhow = "1.0.32"
-cgroups = { package = "cgroups-rs", version = "0.2.5" }
+cgroups = { package = "cgroups-rs", version = "0.2.11" }
[workspace]
members = [
diff --git a/src/agent/rustjail/Cargo.toml b/src/agent/rustjail/Cargo.toml
index 55e59f4..7d59d2b 100644
--- a/src/agent/rustjail/Cargo.toml
+++ b/src/agent/rustjail/Cargo.toml
@@ -23,7 +23,7 @@ scan_fmt = "0.2"
regex = "1.1"
path-absolutize = "1.2.0"
anyhow = "1.0.32"
-cgroups = { package = "cgroups-rs", version = "0.2.5" }
+cgroups = { package = "cgroups-rs", version = "0.2.11" }
tempfile = "3.1.0"
rlimit = "0.5.3"
--
2.33.0

View File

@ -1,35 +0,0 @@
0001-runtime-add-support-of-new-sandbox-hypervisor-type-S.patch
0002-agent-add-support-of-new-sandbox-hypervisor-kind-Str.patch
0003-runtime-implement-updateInterfaceHwAddrByName-interf.patch
0004-configuration-add-configuration-generator-for-hyperv.patch
0005-runtime-add-the-secure-component-ozone-support-for-h.patch
0006-factory-add-the-template-factory-support-for-hypervi.patch
0007-kata-containers-support-with-iSulad.patch
0008-kata-containers-adpat-with-iSulad.patch
0009-kata-containers-fix-kata-runtime-hungs-when-qemu-proces.patch
0010-kata-containers-fix-kata-runtime-skip-read-lines-in-pro.patch
0011-kata-containers-keep-the-process-name-of-qemu-same-as-c.patch
0012-kata-containers-modify-kernel-and-image-path-in-conf.patch
0013-kata-containers-increase-delete-cgroup-retry-times.patch
0014-kata-containers-fix-umount-container-rootfs-dir-return-.patch
0015-kata-containers-truncate-the-log.json-file-before-kata-.patch
0016-kata-containers-validate-sandbox-cpu-and-memory-size.patch
0017-kata-containers-fix-delete-sandbox-failed-problem.patch
0018-kata-containers-check-VFIO-when-create-device.patch
0019-kata-containers-do-not-delete-the-exist-tap-device-in-t.patch
0020-kata-containers-do-not-ignore-updateInterface-return-er.patch
0021-kata-containers-fix-the-block-device-not-remove-in-devM.patch
0022-kata-containers-modify-stratovirt-config-file.patch
0023-stratovirt-update-configuration-toml-file.patch
0024-stratovirt-add-struct-vmConfig-and-methods-to-get-al.patch
0025-stratovirt-refactor-hypervisor-type-stratovirt-and-i.patch
0026-stratovirt-add-a-standard-virtual-machine-sandbox-ty.patch
0027-stratovirt-fix-the-problem-that-fails-to-plug-net-de.patch
0028-stratovirt-provide-a-way-to-dynomically-obtain-firmw.patch
0029-stratovirt-fix-the-problem-that-add-more-than-16-roo.patch
0030-use-host_device-blockdev-adding.patch
0031-add-explicit-on-after-kernel_irqchip.patch
0032-qmp-Don-t-use-deprecated-props-field-for-object-add.patch
0033-optimize-compile-options.patch
0034-stratovirt-Append-readonly-option-when-get-pflash-cm.patch
0035-update-cgroup-rs-crate.patch

Binary file not shown.

18
version.rs Normal file
View File

@ -0,0 +1,18 @@
// Copyright (c) 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
//
// WARNING: This file is auto-generated - DO NOT EDIT!
//
#![allow(dead_code)]
pub const AGENT_VERSION: &str = "3.2.0";
pub const API_VERSION: &str = "0.0.1";
pub const VERSION_COMMIT: &str = "3.2.0-15e85b8ce740faf026e7d72d0d950cd9e0bbfc1d";
pub const GIT_COMMIT: &str = "15e85b8ce740faf026e7d72d0d950cd9e0bbfc1d";
pub const AGENT_NAME: &str = "kata-agent";
pub const AGENT_DIR: &str = "/usr/bin";
pub const AGENT_PATH: &str = "/usr/bin/kata-agent";