mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-13 04:49:36 +00:00
Merge pull request #1084 from liubin/fix/1081-clean-codes
runtime: clean/refactor code
This commit is contained in:
@@ -1,29 +0,0 @@
|
||||
// Copyright (c) 2016 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package virtcontainers
|
||||
|
||||
// nsenter is a spawner implementation for the nsenter util-linux command.
|
||||
type nsenter struct {
|
||||
ContConfig ContainerConfig
|
||||
}
|
||||
|
||||
const (
|
||||
// NsenterCmd is the command used to start nsenter.
|
||||
nsenterCmd = "nsenter"
|
||||
)
|
||||
|
||||
// formatArgs is the spawner command formatting implementation for nsenter.
|
||||
func (n *nsenter) formatArgs(args []string) ([]string, error) {
|
||||
var newArgs []string
|
||||
pid := "-1"
|
||||
|
||||
// TODO: Retrieve container PID from container ID
|
||||
|
||||
newArgs = append(newArgs, nsenterCmd+" --target "+pid+" --mount --uts --ipc --net --pid")
|
||||
newArgs = append(newArgs, args...)
|
||||
|
||||
return newArgs, nil
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
// Copyright (c) 2016 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package virtcontainers
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func testNsEnterFormatArgs(t *testing.T, args []string, expected string) {
|
||||
nsenter := &nsenter{}
|
||||
|
||||
cmd, err := nsenter.formatArgs(args)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, strings.Join(cmd, " "), expected)
|
||||
}
|
||||
|
||||
func TestNsEnterFormatArgsHello(t *testing.T) {
|
||||
expectedCmd := "nsenter --target -1 --mount --uts --ipc --net --pid echo hello"
|
||||
|
||||
args := []string{"echo", "hello"}
|
||||
|
||||
testNsEnterFormatArgs(t, args, expectedCmd)
|
||||
}
|
@@ -6,29 +6,6 @@
|
||||
|
||||
package nsenter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Filesystems constants.
|
||||
const (
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/magic.h
|
||||
nsFSMagic = 0x6e736673
|
||||
procFSMagic = 0x9fa0
|
||||
|
||||
procRootPath = "/proc"
|
||||
nsDirPath = "ns"
|
||||
taskDirPath = "task"
|
||||
)
|
||||
|
||||
// NSType defines a namespace type.
|
||||
type NSType string
|
||||
|
||||
@@ -47,147 +24,8 @@ const (
|
||||
NSTypeUTS NSType = "uts"
|
||||
)
|
||||
|
||||
// CloneFlagsTable is exported so that consumers of this package don't need
|
||||
// to define this same table again.
|
||||
var CloneFlagsTable = make(map[NSType]int)
|
||||
|
||||
// Namespace describes a namespace that will be entered.
|
||||
type Namespace struct {
|
||||
Path string
|
||||
PID int
|
||||
Type NSType
|
||||
}
|
||||
|
||||
type nsPair struct {
|
||||
targetNS *os.File
|
||||
threadNS *os.File
|
||||
}
|
||||
|
||||
func init() {
|
||||
var ns = map[NSType]int{
|
||||
NSTypeCGroup: unix.CLONE_NEWCGROUP,
|
||||
NSTypeIPC: unix.CLONE_NEWIPC,
|
||||
NSTypeNet: unix.CLONE_NEWNET,
|
||||
NSTypePID: unix.CLONE_NEWPID,
|
||||
NSTypeUTS: unix.CLONE_NEWUTS,
|
||||
}
|
||||
|
||||
for k, v := range ns {
|
||||
if _, err := os.Stat(fmt.Sprint("/proc/self/ns/", string(k))); err == nil {
|
||||
CloneFlagsTable[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getNSPathFromPID(pid int, nsType NSType) string {
|
||||
return filepath.Join(procRootPath, strconv.Itoa(pid), nsDirPath, string(nsType))
|
||||
}
|
||||
|
||||
func getCurrentThreadNSPath(nsType NSType) string {
|
||||
return filepath.Join(procRootPath, strconv.Itoa(os.Getpid()),
|
||||
taskDirPath, strconv.Itoa(unix.Gettid()), nsDirPath, string(nsType))
|
||||
}
|
||||
|
||||
func setNS(nsFile *os.File, nsType NSType) error {
|
||||
if nsFile == nil {
|
||||
return fmt.Errorf("File handler cannot be nil")
|
||||
}
|
||||
|
||||
nsFlag, exist := CloneFlagsTable[nsType]
|
||||
if !exist {
|
||||
return fmt.Errorf("Unknown namespace type %q", nsType)
|
||||
}
|
||||
|
||||
if err := unix.Setns(int(nsFile.Fd()), nsFlag); err != nil {
|
||||
return fmt.Errorf("Error switching to ns %v: %v", nsFile.Name(), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getFileFromNS checks the provided file path actually matches a real
|
||||
// namespace filesystem, and then opens it to return a handler to this
|
||||
// file. This is needed since the system call setns() expects a file
|
||||
// descriptor to enter the given namespace.
|
||||
func getFileFromNS(nsPath string) (*os.File, error) {
|
||||
stat := syscall.Statfs_t{}
|
||||
if err := syscall.Statfs(nsPath, &stat); err != nil {
|
||||
return nil, fmt.Errorf("failed to Statfs %q: %v", nsPath, err)
|
||||
}
|
||||
|
||||
switch stat.Type {
|
||||
case nsFSMagic, procFSMagic:
|
||||
break
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown FS magic on %q: %x", nsPath, stat.Type)
|
||||
}
|
||||
|
||||
file, err := os.Open(nsPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return file, nil
|
||||
}
|
||||
|
||||
// NsEnter executes the passed closure under the given namespace,
|
||||
// restoring the original namespace afterwards.
|
||||
func NsEnter(nsList []Namespace, toRun func() error) error {
|
||||
targetNSList := make(map[NSType]*nsPair)
|
||||
|
||||
// Open all targeted namespaces.
|
||||
for _, ns := range nsList {
|
||||
targetNSPath := ns.Path
|
||||
if targetNSPath == "" {
|
||||
targetNSPath = getNSPathFromPID(ns.PID, ns.Type)
|
||||
}
|
||||
|
||||
targetNS, err := getFileFromNS(targetNSPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open target ns: %v", err)
|
||||
}
|
||||
defer targetNS.Close()
|
||||
|
||||
targetNSList[ns.Type] = &nsPair{
|
||||
targetNS: targetNS,
|
||||
}
|
||||
}
|
||||
|
||||
containedCall := func() error {
|
||||
for nsType := range targetNSList {
|
||||
threadNS, err := getFileFromNS(getCurrentThreadNSPath(nsType))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open current ns: %v", err)
|
||||
}
|
||||
defer threadNS.Close()
|
||||
|
||||
targetNSList[nsType].threadNS = threadNS
|
||||
}
|
||||
|
||||
// Switch to namespaces all at once.
|
||||
for nsType, pair := range targetNSList {
|
||||
// Switch to targeted namespace.
|
||||
if err := setNS(pair.targetNS, nsType); err != nil {
|
||||
return fmt.Errorf("error switching to ns %v: %v", pair.targetNS.Name(), err)
|
||||
}
|
||||
// Switch back to initial namespace after closure return.
|
||||
defer setNS(pair.threadNS, nsType)
|
||||
}
|
||||
|
||||
return toRun()
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
|
||||
var innerError error
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
innerError = containedCall()
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
return innerError
|
||||
}
|
||||
|
@@ -1,240 +0,0 @@
|
||||
// Copyright (c) 2018 Intel Corporation
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
package nsenter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
|
||||
)
|
||||
|
||||
const testPID = 12345
|
||||
|
||||
var tu = ktu.NewTestConstraint(true)
|
||||
|
||||
func TestGetNSPathFromPID(t *testing.T) {
|
||||
for nsType := range CloneFlagsTable {
|
||||
expectedPath := fmt.Sprintf("/proc/%d/ns/%s", testPID, nsType)
|
||||
path := getNSPathFromPID(testPID, nsType)
|
||||
assert.Equal(t, path, expectedPath)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCurrentThreadNSPath(t *testing.T) {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
currentPID := os.Getpid()
|
||||
currentTID := unix.Gettid()
|
||||
for nsType := range CloneFlagsTable {
|
||||
expectedPath := fmt.Sprintf("/proc/%d/task/%d/ns/%s", currentPID, currentTID, nsType)
|
||||
path := getCurrentThreadNSPath(nsType)
|
||||
assert.Equal(t, path, expectedPath)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFileFromNSEmptyNSPathFailure(t *testing.T) {
|
||||
nsFile, err := getFileFromNS("")
|
||||
assert.NotNil(t, err, "Empty path should result as a failure")
|
||||
assert.Nil(t, nsFile, "The file handler returned should be nil")
|
||||
}
|
||||
|
||||
func TestGetFileFromNSNotExistingNSPathFailure(t *testing.T) {
|
||||
nsFile, err := ioutil.TempFile("", "not-existing-ns-path")
|
||||
assert.NoError(t, err)
|
||||
nsFilePath := nsFile.Name()
|
||||
nsFile.Close()
|
||||
|
||||
assert.NoError(t, os.Remove(nsFilePath))
|
||||
|
||||
nsFile, err = getFileFromNS(nsFilePath)
|
||||
assert.NotNil(t, err, "Not existing path should result as a failure")
|
||||
assert.Nil(t, nsFile, "The file handler returned should be nil")
|
||||
}
|
||||
|
||||
func TestGetFileFromNSWrongNSPathFailure(t *testing.T) {
|
||||
nsFile, err := ioutil.TempFile("", "wrong-ns-path")
|
||||
assert.NoError(t, err)
|
||||
nsFilePath := nsFile.Name()
|
||||
nsFile.Close()
|
||||
|
||||
defer os.Remove(nsFilePath)
|
||||
|
||||
nsFile, err = getFileFromNS(nsFilePath)
|
||||
assert.NotNil(t, err, "Should fail because wrong filesystem")
|
||||
assert.Nil(t, nsFile, "The file handler returned should be nil")
|
||||
}
|
||||
|
||||
func TestGetFileFromNSSuccessful(t *testing.T) {
|
||||
for nsType := range CloneFlagsTable {
|
||||
nsFilePath := fmt.Sprintf("/proc/self/ns/%s", string(nsType))
|
||||
nsFile, err := getFileFromNS(nsFilePath)
|
||||
assert.Nil(t, err, "Should have succeeded: %v", err)
|
||||
assert.NotNil(t, nsFile, "The file handler should not be nil")
|
||||
if nsFile != nil {
|
||||
nsFile.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func startSleepBinary(duration int, cloneFlags int) (int, error) {
|
||||
sleepBinName := "sleep"
|
||||
sleepPath, err := exec.LookPath(sleepBinName)
|
||||
if err != nil {
|
||||
return -1, fmt.Errorf("Could not find %q: %v", sleepBinName, err)
|
||||
}
|
||||
|
||||
cmd := exec.Command(sleepPath, strconv.Itoa(duration))
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Cloneflags: uintptr(cloneFlags),
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
return cmd.Process.Pid, nil
|
||||
}
|
||||
|
||||
func TestSetNSNilFileHandlerFailure(t *testing.T) {
|
||||
err := setNS(nil, "")
|
||||
assert.NotNil(t, err, "Should fail because file handler is nil")
|
||||
}
|
||||
|
||||
func TestSetNSUnknownNSTypeFailure(t *testing.T) {
|
||||
file := &os.File{}
|
||||
err := setNS(file, "")
|
||||
assert.NotNil(t, err, "Should fail because unknown ns type")
|
||||
}
|
||||
|
||||
func TestSetNSWrongFileFailure(t *testing.T) {
|
||||
nsFile, err := ioutil.TempFile("", "wrong-ns-path")
|
||||
assert.NoError(t, err)
|
||||
defer func() {
|
||||
nsFilePath := nsFile.Name()
|
||||
nsFile.Close()
|
||||
os.Remove(nsFilePath)
|
||||
}()
|
||||
|
||||
err = setNS(nsFile, NSTypeIPC)
|
||||
assert.NotNil(t, err, "Should fail because file is not a namespace")
|
||||
}
|
||||
|
||||
func supportedNamespaces() []Namespace {
|
||||
var list []Namespace
|
||||
var ns = []Namespace{
|
||||
{Type: NSTypeCGroup},
|
||||
{Type: NSTypeIPC},
|
||||
{Type: NSTypeNet},
|
||||
{Type: NSTypePID},
|
||||
{Type: NSTypeUTS},
|
||||
}
|
||||
|
||||
for _, n := range ns {
|
||||
if _, err := os.Stat(fmt.Sprint("/proc/self/ns/", string(n.Type))); err == nil {
|
||||
list = append(list, n)
|
||||
}
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
func testToRunNil() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestNsEnterEmptyPathAndPIDFromNSListFailure(t *testing.T) {
|
||||
err := NsEnter(supportedNamespaces(), testToRunNil)
|
||||
assert.NotNil(t, err, "Should fail because neither a path nor a PID"+
|
||||
" has been provided by every namespace of the list")
|
||||
}
|
||||
|
||||
func TestNsEnterEmptyNamespaceListSuccess(t *testing.T) {
|
||||
err := NsEnter([]Namespace{}, testToRunNil)
|
||||
assert.Nil(t, err, "Should not fail since closure should return nil: %v", err)
|
||||
}
|
||||
|
||||
func TestNsEnterSuccessful(t *testing.T) {
|
||||
if tu.NotValid(ktu.NeedRoot()) {
|
||||
t.Skip(ktu.TestDisabledNeedRoot)
|
||||
}
|
||||
nsList := supportedNamespaces()
|
||||
sleepDuration := 60
|
||||
|
||||
cloneFlags := 0
|
||||
for _, ns := range nsList {
|
||||
cloneFlags |= CloneFlagsTable[ns.Type]
|
||||
}
|
||||
|
||||
sleepPID, err := startSleepBinary(sleepDuration, cloneFlags)
|
||||
assert.NoError(t, err)
|
||||
defer func() {
|
||||
if sleepPID > 1 {
|
||||
unix.Kill(sleepPID, syscall.SIGKILL)
|
||||
}
|
||||
}()
|
||||
|
||||
for idx := range nsList {
|
||||
nsList[idx].Path = getNSPathFromPID(sleepPID, nsList[idx].Type)
|
||||
nsList[idx].PID = sleepPID
|
||||
}
|
||||
|
||||
var sleepPIDFromNsEnter int
|
||||
|
||||
testToRun := func() error {
|
||||
sleepPIDFromNsEnter, err = startSleepBinary(sleepDuration, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
err = NsEnter(nsList, testToRun)
|
||||
assert.Nil(t, err, "%v", err)
|
||||
|
||||
defer func() {
|
||||
if sleepPIDFromNsEnter > 1 {
|
||||
unix.Kill(sleepPIDFromNsEnter, syscall.SIGKILL)
|
||||
}
|
||||
}()
|
||||
|
||||
for _, ns := range nsList {
|
||||
nsPathEntered := getNSPathFromPID(sleepPIDFromNsEnter, ns.Type)
|
||||
|
||||
// Here we are trying to resolve the path but it fails because
|
||||
// namespaces links don't really exist. For this reason, the
|
||||
// call to EvalSymlinks will fail when it will try to stat the
|
||||
// resolved path found. As we only care about the path, we can
|
||||
// retrieve it from the PathError structure.
|
||||
evalExpectedNSPath, err := filepath.EvalSymlinks(ns.Path)
|
||||
if err != nil {
|
||||
evalExpectedNSPath = err.(*os.PathError).Path
|
||||
}
|
||||
|
||||
// Same thing here, resolving the namespace path.
|
||||
evalNSEnteredPath, err := filepath.EvalSymlinks(nsPathEntered)
|
||||
if err != nil {
|
||||
evalNSEnteredPath = err.(*os.PathError).Path
|
||||
}
|
||||
|
||||
_, evalExpectedNS := filepath.Split(evalExpectedNSPath)
|
||||
_, evalNSEntered := filepath.Split(evalNSEnteredPath)
|
||||
|
||||
assert.Equal(t, evalExpectedNS, evalNSEntered)
|
||||
}
|
||||
}
|
@@ -747,8 +747,7 @@ func (q *qemu) setupVirtioMem() error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = q.qmpSetup()
|
||||
if err != nil {
|
||||
if err = q.qmpSetup(); err != nil {
|
||||
return err
|
||||
}
|
||||
err = q.qmpMonitorCh.qmp.ExecMemdevAdd(q.qmpMonitorCh.ctx, memoryBack, "virtiomem", target, sizeMB, share, "virtio-mem-pci", "virtiomem0")
|
||||
@@ -859,13 +858,12 @@ func (q *qemu) startSandbox(timeout int) error {
|
||||
}
|
||||
|
||||
func (q *qemu) bootFromTemplate() error {
|
||||
err := q.qmpSetup()
|
||||
if err != nil {
|
||||
if err := q.qmpSetup(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer q.qmpShutdown()
|
||||
|
||||
err = q.arch.setIgnoreSharedMemoryMigrationCaps(q.qmpMonitorCh.ctx, q.qmpMonitorCh.qmp)
|
||||
err := q.arch.setIgnoreSharedMemoryMigrationCaps(q.qmpMonitorCh.ctx, q.qmpMonitorCh.qmp)
|
||||
if err != nil {
|
||||
q.Logger().WithError(err).Error("set migration ignore shared memory")
|
||||
return err
|
||||
@@ -961,12 +959,11 @@ func (q *qemu) stopSandbox() error {
|
||||
}
|
||||
}
|
||||
|
||||
err := q.qmpSetup()
|
||||
if err != nil {
|
||||
if err := q.qmpSetup(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = q.qmpMonitorCh.qmp.ExecuteQuit(q.qmpMonitorCh.ctx)
|
||||
err := q.qmpMonitorCh.qmp.ExecuteQuit(q.qmpMonitorCh.ctx)
|
||||
if err != nil {
|
||||
q.Logger().WithError(err).Error("Fail to execute qmp QUIT")
|
||||
return err
|
||||
@@ -1012,22 +1009,15 @@ func (q *qemu) togglePauseSandbox(pause bool) error {
|
||||
span, _ := q.trace("togglePauseSandbox")
|
||||
defer span.Finish()
|
||||
|
||||
err := q.qmpSetup()
|
||||
if err != nil {
|
||||
if err := q.qmpSetup(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if pause {
|
||||
err = q.qmpMonitorCh.qmp.ExecuteStop(q.qmpMonitorCh.ctx)
|
||||
return q.qmpMonitorCh.qmp.ExecuteStop(q.qmpMonitorCh.ctx)
|
||||
} else {
|
||||
err = q.qmpMonitorCh.qmp.ExecuteCont(q.qmpMonitorCh.ctx)
|
||||
return q.qmpMonitorCh.qmp.ExecuteCont(q.qmpMonitorCh.ctx)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *qemu) qmpSetup() error {
|
||||
@@ -1353,15 +1343,14 @@ func (q *qemu) hotplugAddVhostUserBlkDevice(vAttr *config.VhostUserDeviceAttrs,
|
||||
}
|
||||
|
||||
func (q *qemu) hotplugBlockDevice(drive *config.BlockDrive, op operation) error {
|
||||
err := q.qmpSetup()
|
||||
if err != nil {
|
||||
if err := q.qmpSetup(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
devID := "virtio-" + drive.ID
|
||||
|
||||
if op == addDevice {
|
||||
err = q.hotplugAddBlockDevice(drive, op, devID)
|
||||
return q.hotplugAddBlockDevice(drive, op, devID)
|
||||
} else {
|
||||
if q.config.BlockDeviceDriver == config.VirtioBlock {
|
||||
if err := q.arch.removeDeviceFromBridge(drive.ID); err != nil {
|
||||
@@ -1373,17 +1362,12 @@ func (q *qemu) hotplugBlockDevice(drive *config.BlockDrive, op operation) error
|
||||
return err
|
||||
}
|
||||
|
||||
if err := q.qmpMonitorCh.qmp.ExecuteBlockdevDel(q.qmpMonitorCh.ctx, drive.ID); err != nil {
|
||||
return err
|
||||
return q.qmpMonitorCh.qmp.ExecuteBlockdevDel(q.qmpMonitorCh.ctx, drive.ID)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *qemu) hotplugVhostUserDevice(vAttr *config.VhostUserDeviceAttrs, op operation) error {
|
||||
err := q.qmpSetup()
|
||||
if err != nil {
|
||||
if err := q.qmpSetup(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1405,17 +1389,12 @@ func (q *qemu) hotplugVhostUserDevice(vAttr *config.VhostUserDeviceAttrs, op ope
|
||||
return err
|
||||
}
|
||||
|
||||
if err := q.qmpMonitorCh.qmp.ExecuteChardevDel(q.qmpMonitorCh.ctx, vAttr.DevID); err != nil {
|
||||
return err
|
||||
return q.qmpMonitorCh.qmp.ExecuteChardevDel(q.qmpMonitorCh.ctx, vAttr.DevID)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *qemu) hotplugVFIODevice(device *config.VFIODev, op operation) (err error) {
|
||||
err = q.qmpSetup()
|
||||
if err != nil {
|
||||
if err = q.qmpSetup(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1492,12 +1471,8 @@ func (q *qemu) hotplugVFIODevice(device *config.VFIODev, op operation) (err erro
|
||||
}
|
||||
}
|
||||
|
||||
if err := q.qmpMonitorCh.qmp.ExecuteDeviceDel(q.qmpMonitorCh.ctx, devID); err != nil {
|
||||
return err
|
||||
return q.qmpMonitorCh.qmp.ExecuteDeviceDel(q.qmpMonitorCh.ctx, devID)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *qemu) hotAddNetDevice(name, hardAddr string, VMFds, VhostFds []*os.File) error {
|
||||
@@ -1524,8 +1499,7 @@ func (q *qemu) hotAddNetDevice(name, hardAddr string, VMFds, VhostFds []*os.File
|
||||
}
|
||||
|
||||
func (q *qemu) hotplugNetDevice(endpoint Endpoint, op operation) (err error) {
|
||||
err = q.qmpSetup()
|
||||
if err != nil {
|
||||
if err = q.qmpSetup(); err != nil {
|
||||
return err
|
||||
}
|
||||
var tap TapInterface
|
||||
@@ -1587,11 +1561,8 @@ func (q *qemu) hotplugNetDevice(endpoint Endpoint, op operation) (err error) {
|
||||
if err := q.qmpMonitorCh.qmp.ExecuteDeviceDel(q.qmpMonitorCh.ctx, devID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := q.qmpMonitorCh.qmp.ExecuteNetdevDel(q.qmpMonitorCh.ctx, tap.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return q.qmpMonitorCh.qmp.ExecuteNetdevDel(q.qmpMonitorCh.ctx, tap.Name)
|
||||
}
|
||||
|
||||
func (q *qemu) hotplugDevice(devInfo interface{}, devType deviceType, op operation) (interface{}, error) {
|
||||
@@ -1649,8 +1620,7 @@ func (q *qemu) hotplugCPUs(vcpus uint32, op operation) (uint32, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
err := q.qmpSetup()
|
||||
if err != nil {
|
||||
if err := q.qmpSetup(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -1760,8 +1730,7 @@ func (q *qemu) hotplugMemory(memDev *memoryDevice, op operation) (int, error) {
|
||||
memLog := q.Logger().WithField("hotplug", "memory")
|
||||
|
||||
memLog.WithField("hotplug-memory-mb", memDev.sizeMB).Debug("requested memory hotplug")
|
||||
err := q.qmpSetup()
|
||||
if err != nil {
|
||||
if err := q.qmpSetup(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -1934,8 +1903,7 @@ func (q *qemu) getSandboxConsole(id string) (string, string, error) {
|
||||
func (q *qemu) saveSandbox() error {
|
||||
q.Logger().Info("save sandbox")
|
||||
|
||||
err := q.qmpSetup()
|
||||
if err != nil {
|
||||
if err := q.qmpSetup(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1949,7 +1917,7 @@ func (q *qemu) saveSandbox() error {
|
||||
}
|
||||
}
|
||||
|
||||
err = q.qmpMonitorCh.qmp.ExecSetMigrateArguments(q.qmpMonitorCh.ctx, fmt.Sprintf("%s>%s", qmpExecCatCmd, q.config.DevicesStatePath))
|
||||
err := q.qmpMonitorCh.qmp.ExecSetMigrateArguments(q.qmpMonitorCh.ctx, fmt.Sprintf("%s>%s", qmpExecCatCmd, q.config.DevicesStatePath))
|
||||
if err != nil {
|
||||
q.Logger().WithError(err).Error("exec migration")
|
||||
return err
|
||||
@@ -2006,15 +1974,14 @@ func (q *qemu) disconnect() {
|
||||
func (q *qemu) resizeMemory(reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, memoryDevice, error) {
|
||||
|
||||
currentMemory := q.config.MemorySize + uint32(q.state.HotpluggedMemory)
|
||||
err := q.qmpSetup()
|
||||
if err != nil {
|
||||
if err := q.qmpSetup(); err != nil {
|
||||
return 0, memoryDevice{}, err
|
||||
}
|
||||
var addMemDevice memoryDevice
|
||||
if q.config.VirtioMem && currentMemory != reqMemMB {
|
||||
q.Logger().WithField("hotplug", "memory").Debugf("resize memory from %dMB to %dMB", currentMemory, reqMemMB)
|
||||
sizeByte := (reqMemMB - q.config.MemorySize) * 1024 * 1024
|
||||
err = q.qmpMonitorCh.qmp.ExecQomSet(q.qmpMonitorCh.ctx, "virtiomem0", "requested-size", uint64(sizeByte))
|
||||
err := q.qmpMonitorCh.qmp.ExecQomSet(q.qmpMonitorCh.ctx, "virtiomem0", "requested-size", uint64(sizeByte))
|
||||
if err != nil {
|
||||
return 0, memoryDevice{}, err
|
||||
}
|
||||
@@ -2196,8 +2163,7 @@ func (q *qemu) getThreadIDs() (vcpuThreadIDs, error) {
|
||||
defer span.Finish()
|
||||
|
||||
tid := vcpuThreadIDs{}
|
||||
err := q.qmpSetup()
|
||||
if err != nil {
|
||||
if err := q.qmpSetup(); err != nil {
|
||||
return tid, err
|
||||
}
|
||||
|
||||
@@ -2400,8 +2366,7 @@ func (q *qemu) check() error {
|
||||
q.memoryDumpFlag.Lock()
|
||||
defer q.memoryDumpFlag.Unlock()
|
||||
|
||||
err := q.qmpSetup()
|
||||
if err != nil {
|
||||
if err := q.qmpSetup(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user