kata-containers/patches/0005-runtime-add-the-secure-component-ozone-support-for-h.patch
Wei Gao e299de34ba kata-containers: adapt with iSulad and support for new hypervisor type "stratovirt"
reason: adapt with iSulad and support for new hypervisor type "stratovirt"

Signed-off-by: holyfei <yangfeiyu20092010@163.com>
2021-08-23 18:50:26 +08:00

656 lines
23 KiB
Diff

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)