mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-11 21:02:34 +00:00
hypervisor: Minimal exports of generic hypervisor internal fields
Export commonly used hypervisor fields and utility functions. These need to be exposed to allow the hypervisor to be consumed externally. Note: This does not change the hypervisor interface definition. Those changes will be separate commits. Signed-off-by: Manohar Castelino <mcastelino@apple.com>
This commit is contained in:
parent
03877f3479
commit
6baf2586ee
@ -344,7 +344,7 @@ func (a *Acrn) createDummyVirtioBlkDev(ctx context.Context, devices []Device) ([
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *Acrn) setConfig(config *HypervisorConfig) error {
|
func (a *Acrn) setConfig(config *HypervisorConfig) error {
|
||||||
if err := config.valid(); err != nil {
|
if err := config.Valid(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,12 +554,12 @@ func (a *Acrn) updateBlockDevice(drive *config.BlockDrive) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Acrn) hotplugAddDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (a *Acrn) hotplugAddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "hotplugAddDevice", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
span, _ := katatrace.Trace(ctx, a.Logger(), "hotplugAddDevice", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
switch devType {
|
switch devType {
|
||||||
case blockDev:
|
case BlockDev:
|
||||||
//The drive placeholder has to exist prior to Update
|
//The drive placeholder has to exist prior to Update
|
||||||
return nil, a.updateBlockDevice(devInfo.(*config.BlockDrive))
|
return nil, a.updateBlockDevice(devInfo.(*config.BlockDrive))
|
||||||
default:
|
default:
|
||||||
@ -568,7 +568,7 @@ func (a *Acrn) hotplugAddDevice(ctx context.Context, devInfo interface{}, devTyp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Acrn) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (a *Acrn) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "hotplugRemoveDevice", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
span, _ := katatrace.Trace(ctx, a.Logger(), "hotplugRemoveDevice", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@ -596,7 +596,7 @@ func (a *Acrn) resumeSandbox(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// addDevice will add extra devices to acrn command line.
|
// addDevice will add extra devices to acrn command line.
|
||||||
func (a *Acrn) addDevice(ctx context.Context, devInfo interface{}, devType deviceType) error {
|
func (a *Acrn) addDevice(ctx context.Context, devInfo interface{}, devType DeviceType) error {
|
||||||
var err error
|
var err error
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "addDevice", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
span, _ := katatrace.Trace(ctx, a.Logger(), "addDevice", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
||||||
defer span.End()
|
defer span.End()
|
||||||
@ -657,18 +657,18 @@ func (a *Acrn) disconnect(ctx context.Context) {
|
|||||||
// Not supported.
|
// Not supported.
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Acrn) getThreadIDs(ctx context.Context) (vcpuThreadIDs, error) {
|
func (a *Acrn) getThreadIDs(ctx context.Context) (VcpuThreadIDs, error) {
|
||||||
span, _ := katatrace.Trace(ctx, a.Logger(), "getThreadIDs", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
span, _ := katatrace.Trace(ctx, a.Logger(), "getThreadIDs", acrnTracingTags, map[string]string{"sandbox_id": a.id})
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
// Not supported. return success
|
// Not supported. return success
|
||||||
//Just allocating an empty map
|
//Just allocating an empty map
|
||||||
|
|
||||||
return vcpuThreadIDs{}, nil
|
return VcpuThreadIDs{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Acrn) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, memoryDevice, error) {
|
func (a *Acrn) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, MemoryDevice, error) {
|
||||||
return 0, memoryDevice{}, nil
|
return 0, MemoryDevice{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Acrn) resizeVCPUs(ctx context.Context, reqVCPUs uint32) (currentVCPUs uint32, newVCPUs uint32, err error) {
|
func (a *Acrn) resizeVCPUs(ctx context.Context, reqVCPUs uint32) (currentVCPUs uint32, newVCPUs uint32, err error) {
|
||||||
|
@ -82,7 +82,7 @@ func TestAcrnCapabilities(t *testing.T) {
|
|||||||
assert.True(caps.IsBlockDeviceHotplugSupported())
|
assert.True(caps.IsBlockDeviceHotplugSupported())
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAcrnAddDevice(t *testing.T, devInfo interface{}, devType deviceType, expected []Device) {
|
func testAcrnAddDevice(t *testing.T, devInfo interface{}, devType DeviceType, expected []Device) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
a := &Acrn{
|
a := &Acrn{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
@ -112,7 +112,7 @@ func TestAcrnAddDeviceSerialPortDev(t *testing.T) {
|
|||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
|
|
||||||
testAcrnAddDevice(t, socket, serialPortDev, expectedOut)
|
testAcrnAddDevice(t, socket, SerialPortDev, expectedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAcrnAddDeviceBlockDev(t *testing.T) {
|
func TestAcrnAddDeviceBlockDev(t *testing.T) {
|
||||||
@ -131,7 +131,7 @@ func TestAcrnAddDeviceBlockDev(t *testing.T) {
|
|||||||
Index: index,
|
Index: index,
|
||||||
}
|
}
|
||||||
|
|
||||||
testAcrnAddDevice(t, drive, blockDev, expectedOut)
|
testAcrnAddDevice(t, drive, BlockDev, expectedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAcrnHotplugUnsupportedDeviceType(t *testing.T) {
|
func TestAcrnHotplugUnsupportedDeviceType(t *testing.T) {
|
||||||
@ -144,7 +144,7 @@ func TestAcrnHotplugUnsupportedDeviceType(t *testing.T) {
|
|||||||
config: acrnConfig,
|
config: acrnConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := a.hotplugAddDevice(a.ctx, &memoryDevice{0, 128, uint64(0), false}, fsDev)
|
_, err := a.hotplugAddDevice(a.ctx, &MemoryDevice{0, 128, uint64(0), false}, FsDev)
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ func (endpoint *BridgedMacvlanEndpoint) Attach(ctx context.Context, s *Sandbox)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.addDevice(ctx, endpoint, netDev)
|
return h.addDevice(ctx, endpoint, NetDev)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detach for the virtual endpoint tears down the tap and bridge
|
// Detach for the virtual endpoint tears down the tap and bridge
|
||||||
|
@ -189,7 +189,7 @@ var clhDebugKernelParams = []Param{
|
|||||||
//###########################################################
|
//###########################################################
|
||||||
|
|
||||||
func (clh *cloudHypervisor) setConfig(config *HypervisorConfig) error {
|
func (clh *cloudHypervisor) setConfig(config *HypervisorConfig) error {
|
||||||
err := config.valid()
|
err := config.Valid()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -251,7 +251,7 @@ func (clh *cloudHypervisor) createSandbox(ctx context.Context, id string, networ
|
|||||||
clh.vmconfig.Memory.Shared = func(b bool) *bool { return &b }(true)
|
clh.vmconfig.Memory.Shared = func(b bool) *bool { return &b }(true)
|
||||||
// Enable hugepages if needed
|
// Enable hugepages if needed
|
||||||
clh.vmconfig.Memory.Hugepages = func(b bool) *bool { return &b }(clh.config.HugePages)
|
clh.vmconfig.Memory.Hugepages = func(b bool) *bool { return &b }(clh.config.HugePages)
|
||||||
hostMemKb, err := getHostMemorySizeKb(procMemInfo)
|
hostMemKb, err := GetHostMemorySizeKb(procMemInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -441,11 +441,11 @@ func (clh *cloudHypervisor) disconnect(ctx context.Context) {
|
|||||||
clh.Logger().WithField("function", "disconnect").Info("Disconnecting Sandbox Console")
|
clh.Logger().WithField("function", "disconnect").Info("Disconnecting Sandbox Console")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (clh *cloudHypervisor) getThreadIDs(ctx context.Context) (vcpuThreadIDs, error) {
|
func (clh *cloudHypervisor) getThreadIDs(ctx context.Context) (VcpuThreadIDs, error) {
|
||||||
|
|
||||||
clh.Logger().WithField("function", "getThreadIDs").Info("get thread ID's")
|
clh.Logger().WithField("function", "getThreadIDs").Info("get thread ID's")
|
||||||
|
|
||||||
var vcpuInfo vcpuThreadIDs
|
var vcpuInfo VcpuThreadIDs
|
||||||
|
|
||||||
vcpuInfo.vcpus = make(map[int]int)
|
vcpuInfo.vcpus = make(map[int]int)
|
||||||
|
|
||||||
@ -550,15 +550,15 @@ func (clh *cloudHypervisor) hotPlugVFIODevice(device *config.VFIODev) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (clh *cloudHypervisor) hotplugAddDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (clh *cloudHypervisor) hotplugAddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
||||||
span, _ := katatrace.Trace(ctx, clh.Logger(), "hotplugAddDevice", clhTracingTags, map[string]string{"sandbox_id": clh.id})
|
span, _ := katatrace.Trace(ctx, clh.Logger(), "hotplugAddDevice", clhTracingTags, map[string]string{"sandbox_id": clh.id})
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
switch devType {
|
switch devType {
|
||||||
case blockDev:
|
case BlockDev:
|
||||||
drive := devInfo.(*config.BlockDrive)
|
drive := devInfo.(*config.BlockDrive)
|
||||||
return nil, clh.hotplugAddBlockDevice(drive)
|
return nil, clh.hotplugAddBlockDevice(drive)
|
||||||
case vfioDev:
|
case VfioDev:
|
||||||
device := devInfo.(*config.VFIODev)
|
device := devInfo.(*config.VFIODev)
|
||||||
return nil, clh.hotPlugVFIODevice(device)
|
return nil, clh.hotPlugVFIODevice(device)
|
||||||
default:
|
default:
|
||||||
@ -567,16 +567,16 @@ func (clh *cloudHypervisor) hotplugAddDevice(ctx context.Context, devInfo interf
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (clh *cloudHypervisor) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (clh *cloudHypervisor) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
||||||
span, _ := katatrace.Trace(ctx, clh.Logger(), "hotplugRemoveDevice", clhTracingTags, map[string]string{"sandbox_id": clh.id})
|
span, _ := katatrace.Trace(ctx, clh.Logger(), "hotplugRemoveDevice", clhTracingTags, map[string]string{"sandbox_id": clh.id})
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
var deviceID string
|
var deviceID string
|
||||||
|
|
||||||
switch devType {
|
switch devType {
|
||||||
case blockDev:
|
case BlockDev:
|
||||||
deviceID = clhDriveIndexToID(devInfo.(*config.BlockDrive).Index)
|
deviceID = clhDriveIndexToID(devInfo.(*config.BlockDrive).Index)
|
||||||
case vfioDev:
|
case VfioDev:
|
||||||
deviceID = devInfo.(*config.VFIODev).ID
|
deviceID = devInfo.(*config.VFIODev).ID
|
||||||
default:
|
default:
|
||||||
clh.Logger().WithFields(log.Fields{"devInfo": devInfo,
|
clh.Logger().WithFields(log.Fields{"devInfo": devInfo,
|
||||||
@ -603,22 +603,22 @@ func (clh *cloudHypervisor) hypervisorConfig() HypervisorConfig {
|
|||||||
return clh.config
|
return clh.config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (clh *cloudHypervisor) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, memoryDevice, error) {
|
func (clh *cloudHypervisor) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, MemoryDevice, error) {
|
||||||
|
|
||||||
// TODO: Add support for virtio-mem
|
// TODO: Add support for virtio-mem
|
||||||
|
|
||||||
if probe {
|
if probe {
|
||||||
return 0, memoryDevice{}, errors.New("probe memory is not supported for cloud-hypervisor")
|
return 0, MemoryDevice{}, errors.New("probe memory is not supported for cloud-hypervisor")
|
||||||
}
|
}
|
||||||
|
|
||||||
if reqMemMB == 0 {
|
if reqMemMB == 0 {
|
||||||
// This is a corner case if requested to resize to 0 means something went really wrong.
|
// This is a corner case if requested to resize to 0 means something went really wrong.
|
||||||
return 0, memoryDevice{}, errors.New("Can not resize memory to 0")
|
return 0, MemoryDevice{}, errors.New("Can not resize memory to 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
info, err := clh.vmInfo()
|
info, err := clh.vmInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, memoryDevice{}, err
|
return 0, MemoryDevice{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
currentMem := utils.MemUnit(info.Config.Memory.Size) * utils.Byte
|
currentMem := utils.MemUnit(info.Config.Memory.Size) * utils.Byte
|
||||||
@ -627,12 +627,12 @@ func (clh *cloudHypervisor) resizeMemory(ctx context.Context, reqMemMB uint32, m
|
|||||||
// Early check to verify if boot memory is the same as requested
|
// Early check to verify if boot memory is the same as requested
|
||||||
if currentMem == newMem {
|
if currentMem == newMem {
|
||||||
clh.Logger().WithField("memory", reqMemMB).Debugf("VM already has requested memory")
|
clh.Logger().WithField("memory", reqMemMB).Debugf("VM already has requested memory")
|
||||||
return uint32(currentMem.ToMiB()), memoryDevice{}, nil
|
return uint32(currentMem.ToMiB()), MemoryDevice{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if currentMem > newMem {
|
if currentMem > newMem {
|
||||||
clh.Logger().Warn("Remove memory is not supported, nothing to do")
|
clh.Logger().Warn("Remove memory is not supported, nothing to do")
|
||||||
return uint32(currentMem.ToMiB()), memoryDevice{}, nil
|
return uint32(currentMem.ToMiB()), MemoryDevice{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
blockSize := utils.MemUnit(memoryBlockSizeMB) * utils.MiB
|
blockSize := utils.MemUnit(memoryBlockSizeMB) * utils.MiB
|
||||||
@ -649,7 +649,7 @@ func (clh *cloudHypervisor) resizeMemory(ctx context.Context, reqMemMB uint32, m
|
|||||||
// to consider the memory request now that is updated to be memory aligned
|
// to consider the memory request now that is updated to be memory aligned
|
||||||
if currentMem == newMem {
|
if currentMem == newMem {
|
||||||
clh.Logger().WithFields(log.Fields{"current-memory": currentMem, "new-memory": newMem}).Debug("VM already has requested memory(after alignment)")
|
clh.Logger().WithFields(log.Fields{"current-memory": currentMem, "new-memory": newMem}).Debug("VM already has requested memory(after alignment)")
|
||||||
return uint32(currentMem.ToMiB()), memoryDevice{}, nil
|
return uint32(currentMem.ToMiB()), MemoryDevice{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cl := clh.client()
|
cl := clh.client()
|
||||||
@ -663,10 +663,10 @@ func (clh *cloudHypervisor) resizeMemory(ctx context.Context, reqMemMB uint32, m
|
|||||||
if _, err = cl.VmResizePut(ctx, resize); err != nil {
|
if _, err = cl.VmResizePut(ctx, resize); err != nil {
|
||||||
clh.Logger().WithError(err).WithFields(log.Fields{"current-memory": currentMem, "new-memory": newMem}).Warnf("failed to update memory %s", openAPIClientError(err))
|
clh.Logger().WithError(err).WithFields(log.Fields{"current-memory": currentMem, "new-memory": newMem}).Warnf("failed to update memory %s", openAPIClientError(err))
|
||||||
err = fmt.Errorf("Failed to resize memory from %d to %d: %s", currentMem, newMem, openAPIClientError(err))
|
err = fmt.Errorf("Failed to resize memory from %d to %d: %s", currentMem, newMem, openAPIClientError(err))
|
||||||
return uint32(currentMem.ToMiB()), memoryDevice{}, openAPIClientError(err)
|
return uint32(currentMem.ToMiB()), MemoryDevice{}, openAPIClientError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return uint32(newMem.ToMiB()), memoryDevice{sizeMB: int(hotplugSize.ToMiB())}, nil
|
return uint32(newMem.ToMiB()), MemoryDevice{SizeMB: int(hotplugSize.ToMiB())}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (clh *cloudHypervisor) resizeVCPUs(ctx context.Context, reqVCPUs uint32) (currentVCPUs uint32, newVCPUs uint32, err error) {
|
func (clh *cloudHypervisor) resizeVCPUs(ctx context.Context, reqVCPUs uint32) (currentVCPUs uint32, newVCPUs uint32, err error) {
|
||||||
@ -778,7 +778,7 @@ func (clh *cloudHypervisor) getVirtioFsPid() *int {
|
|||||||
return &clh.state.VirtiofsdPID
|
return &clh.state.VirtiofsdPID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (clh *cloudHypervisor) addDevice(ctx context.Context, devInfo interface{}, devType deviceType) error {
|
func (clh *cloudHypervisor) addDevice(ctx context.Context, devInfo interface{}, devType DeviceType) error {
|
||||||
span, _ := katatrace.Trace(ctx, clh.Logger(), "addDevice", clhTracingTags, map[string]string{"sandbox_id": clh.id})
|
span, _ := katatrace.Trace(ctx, clh.Logger(), "addDevice", clhTracingTags, map[string]string{"sandbox_id": clh.id})
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
@ -282,13 +282,13 @@ func TestCloudHypervisorResizeMemory(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
args args
|
args args
|
||||||
expectedMemDev memoryDevice
|
expectedMemDev MemoryDevice
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
{"Resize to zero", args{0, 128}, memoryDevice{probe: false, sizeMB: 0}, FAIL},
|
{"Resize to zero", args{0, 128}, MemoryDevice{Probe: false, SizeMB: 0}, FAIL},
|
||||||
{"Resize to aligned size", args{clhConfig.MemorySize + 128, 128}, memoryDevice{probe: false, sizeMB: 128}, PASS},
|
{"Resize to aligned size", args{clhConfig.MemorySize + 128, 128}, MemoryDevice{Probe: false, SizeMB: 128}, PASS},
|
||||||
{"Resize to aligned size", args{clhConfig.MemorySize + 129, 128}, memoryDevice{probe: false, sizeMB: 256}, PASS},
|
{"Resize to aligned size", args{clhConfig.MemorySize + 129, 128}, MemoryDevice{Probe: false, SizeMB: 256}, PASS},
|
||||||
{"Resize to NOT aligned size", args{clhConfig.MemorySize + 125, 128}, memoryDevice{probe: false, sizeMB: 128}, PASS},
|
{"Resize to NOT aligned size", args{clhConfig.MemorySize + 125, 128}, MemoryDevice{Probe: false, SizeMB: 128}, PASS},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
@ -314,7 +314,7 @@ func TestCloudHypervisorResizeMemory(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedMem := clhConfig.MemorySize + uint32(tt.expectedMemDev.sizeMB)
|
expectedMem := clhConfig.MemorySize + uint32(tt.expectedMemDev.SizeMB)
|
||||||
|
|
||||||
if newMem != expectedMem {
|
if newMem != expectedMem {
|
||||||
t.Errorf("cloudHypervisor.resizeMemory() got = %+v, want %+v", newMem, expectedMem)
|
t.Errorf("cloudHypervisor.resizeMemory() got = %+v, want %+v", newMem, expectedMem)
|
||||||
@ -359,13 +359,13 @@ func TestCloudHypervisorHotplugRemoveDevice(t *testing.T) {
|
|||||||
clh.config = clhConfig
|
clh.config = clhConfig
|
||||||
clh.APIClient = &clhClientMock{}
|
clh.APIClient = &clhClientMock{}
|
||||||
|
|
||||||
_, err = clh.hotplugRemoveDevice(context.Background(), &config.BlockDrive{}, blockDev)
|
_, err = clh.hotplugRemoveDevice(context.Background(), &config.BlockDrive{}, BlockDev)
|
||||||
assert.NoError(err, "Hotplug remove block device expected no error")
|
assert.NoError(err, "Hotplug remove block device expected no error")
|
||||||
|
|
||||||
_, err = clh.hotplugRemoveDevice(context.Background(), &config.VFIODev{}, vfioDev)
|
_, err = clh.hotplugRemoveDevice(context.Background(), &config.VFIODev{}, VfioDev)
|
||||||
assert.NoError(err, "Hotplug remove vfio block device expected no error")
|
assert.NoError(err, "Hotplug remove vfio block device expected no error")
|
||||||
|
|
||||||
_, err = clh.hotplugRemoveDevice(context.Background(), nil, netDev)
|
_, err = clh.hotplugRemoveDevice(context.Background(), nil, NetDev)
|
||||||
assert.Error(err, "Hotplug remove pmem block device expected error")
|
assert.Error(err, "Hotplug remove pmem block device expected error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ type firecracker struct {
|
|||||||
|
|
||||||
type firecrackerDevice struct {
|
type firecrackerDevice struct {
|
||||||
dev interface{}
|
dev interface{}
|
||||||
devType deviceType
|
devType DeviceType
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logger returns a logrus logger appropriate for logging firecracker messages
|
// Logger returns a logrus logger appropriate for logging firecracker messages
|
||||||
@ -188,7 +188,7 @@ func (fc *firecracker) truncateID(id string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fc *firecracker) setConfig(config *HypervisorConfig) error {
|
func (fc *firecracker) setConfig(config *HypervisorConfig) error {
|
||||||
err := config.valid()
|
err := config.Valid()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1023,7 +1023,7 @@ func (fc *firecracker) fcUpdateBlockDrive(ctx context.Context, path, id string)
|
|||||||
|
|
||||||
// addDevice will add extra devices to firecracker. Limited to configure before the
|
// addDevice will add extra devices to firecracker. Limited to configure before the
|
||||||
// virtual machine starts. Devices include drivers and network interfaces only.
|
// virtual machine starts. Devices include drivers and network interfaces only.
|
||||||
func (fc *firecracker) addDevice(ctx context.Context, devInfo interface{}, devType deviceType) error {
|
func (fc *firecracker) addDevice(ctx context.Context, devInfo interface{}, devType DeviceType) error {
|
||||||
span, _ := katatrace.Trace(ctx, fc.Logger(), "addDevice", fcTracingTags, map[string]string{"sandbox_id": fc.id})
|
span, _ := katatrace.Trace(ctx, fc.Logger(), "addDevice", fcTracingTags, map[string]string{"sandbox_id": fc.id})
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
@ -1060,7 +1060,7 @@ func (fc *firecracker) addDevice(ctx context.Context, devInfo interface{}, devTy
|
|||||||
|
|
||||||
// hotplugBlockDevice supported in Firecracker VMM
|
// hotplugBlockDevice supported in Firecracker VMM
|
||||||
// hot add or remove a block device.
|
// hot add or remove a block device.
|
||||||
func (fc *firecracker) hotplugBlockDevice(ctx context.Context, drive config.BlockDrive, op operation) (interface{}, error) {
|
func (fc *firecracker) hotplugBlockDevice(ctx context.Context, drive config.BlockDrive, op Operation) (interface{}, error) {
|
||||||
if drive.Swap {
|
if drive.Swap {
|
||||||
return nil, fmt.Errorf("firecracker doesn't support swap")
|
return nil, fmt.Errorf("firecracker doesn't support swap")
|
||||||
}
|
}
|
||||||
@ -1069,7 +1069,7 @@ func (fc *firecracker) hotplugBlockDevice(ctx context.Context, drive config.Bloc
|
|||||||
var err error
|
var err error
|
||||||
driveID := fcDriveIndexToID(drive.Index)
|
driveID := fcDriveIndexToID(drive.Index)
|
||||||
|
|
||||||
if op == addDevice {
|
if op == AddDevice {
|
||||||
//The drive placeholder has to exist prior to Update
|
//The drive placeholder has to exist prior to Update
|
||||||
path, err = fc.fcJailResource(drive.File, driveID)
|
path, err = fc.fcJailResource(drive.File, driveID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1093,13 +1093,13 @@ func (fc *firecracker) hotplugBlockDevice(ctx context.Context, drive config.Bloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hotplugAddDevice supported in Firecracker VMM
|
// hotplugAddDevice supported in Firecracker VMM
|
||||||
func (fc *firecracker) hotplugAddDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (fc *firecracker) hotplugAddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
||||||
span, _ := katatrace.Trace(ctx, fc.Logger(), "hotplugAddDevice", fcTracingTags, map[string]string{"sandbox_id": fc.id})
|
span, _ := katatrace.Trace(ctx, fc.Logger(), "hotplugAddDevice", fcTracingTags, map[string]string{"sandbox_id": fc.id})
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
switch devType {
|
switch devType {
|
||||||
case blockDev:
|
case BlockDev:
|
||||||
return fc.hotplugBlockDevice(ctx, *devInfo.(*config.BlockDrive), addDevice)
|
return fc.hotplugBlockDevice(ctx, *devInfo.(*config.BlockDrive), AddDevice)
|
||||||
default:
|
default:
|
||||||
fc.Logger().WithFields(logrus.Fields{"devInfo": devInfo,
|
fc.Logger().WithFields(logrus.Fields{"devInfo": devInfo,
|
||||||
"deviceType": devType}).Warn("hotplugAddDevice: unsupported device")
|
"deviceType": devType}).Warn("hotplugAddDevice: unsupported device")
|
||||||
@ -1109,13 +1109,13 @@ func (fc *firecracker) hotplugAddDevice(ctx context.Context, devInfo interface{}
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hotplugRemoveDevice supported in Firecracker VMM
|
// hotplugRemoveDevice supported in Firecracker VMM
|
||||||
func (fc *firecracker) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (fc *firecracker) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
||||||
span, _ := katatrace.Trace(ctx, fc.Logger(), "hotplugRemoveDevice", fcTracingTags, map[string]string{"sandbox_id": fc.id})
|
span, _ := katatrace.Trace(ctx, fc.Logger(), "hotplugRemoveDevice", fcTracingTags, map[string]string{"sandbox_id": fc.id})
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
switch devType {
|
switch devType {
|
||||||
case blockDev:
|
case BlockDev:
|
||||||
return fc.hotplugBlockDevice(ctx, *devInfo.(*config.BlockDrive), removeDevice)
|
return fc.hotplugBlockDevice(ctx, *devInfo.(*config.BlockDrive), RemoveDevice)
|
||||||
default:
|
default:
|
||||||
fc.Logger().WithFields(logrus.Fields{"devInfo": devInfo,
|
fc.Logger().WithFields(logrus.Fields{"devInfo": devInfo,
|
||||||
"deviceType": devType}).Error("hotplugRemoveDevice: unsupported device")
|
"deviceType": devType}).Error("hotplugRemoveDevice: unsupported device")
|
||||||
@ -1155,8 +1155,8 @@ func (fc *firecracker) hypervisorConfig() HypervisorConfig {
|
|||||||
return fc.config
|
return fc.config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fc *firecracker) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, memoryDevice, error) {
|
func (fc *firecracker) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, MemoryDevice, error) {
|
||||||
return 0, memoryDevice{}, nil
|
return 0, MemoryDevice{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fc *firecracker) resizeVCPUs(ctx context.Context, reqVCPUs uint32) (currentVCPUs uint32, newVCPUs uint32, err error) {
|
func (fc *firecracker) resizeVCPUs(ctx context.Context, reqVCPUs uint32) (currentVCPUs uint32, newVCPUs uint32, err error) {
|
||||||
@ -1167,8 +1167,8 @@ func (fc *firecracker) resizeVCPUs(ctx context.Context, reqVCPUs uint32) (curren
|
|||||||
//
|
//
|
||||||
// As suggested by https://github.com/firecracker-microvm/firecracker/issues/718,
|
// As suggested by https://github.com/firecracker-microvm/firecracker/issues/718,
|
||||||
// let's use `ps -T -p <pid>` to get fc vcpu info.
|
// let's use `ps -T -p <pid>` to get fc vcpu info.
|
||||||
func (fc *firecracker) getThreadIDs(ctx context.Context) (vcpuThreadIDs, error) {
|
func (fc *firecracker) getThreadIDs(ctx context.Context) (VcpuThreadIDs, error) {
|
||||||
var vcpuInfo vcpuThreadIDs
|
var vcpuInfo VcpuThreadIDs
|
||||||
|
|
||||||
vcpuInfo.vcpus = make(map[int]int)
|
vcpuInfo.vcpus = make(map[int]int)
|
||||||
parent, err := utils.NewProc(fc.info.PID)
|
parent, err := utils.NewProc(fc.info.PID)
|
||||||
|
@ -24,11 +24,11 @@ import (
|
|||||||
// HypervisorType describes an hypervisor type.
|
// HypervisorType describes an hypervisor type.
|
||||||
type HypervisorType string
|
type HypervisorType string
|
||||||
|
|
||||||
type operation int
|
type Operation int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
addDevice operation = iota
|
AddDevice Operation = iota
|
||||||
removeDevice
|
RemoveDevice
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -98,50 +98,50 @@ var commonVirtioblkKernelRootParams = []Param{ //nolint: unused, deadcode, varch
|
|||||||
{"rootfstype", "ext4"},
|
{"rootfstype", "ext4"},
|
||||||
}
|
}
|
||||||
|
|
||||||
// deviceType describes a virtualized device type.
|
// DeviceType describes a virtualized device type.
|
||||||
type deviceType int
|
type DeviceType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ImgDev is the image device type.
|
// ImgDev is the image device type.
|
||||||
imgDev deviceType = iota
|
ImgDev DeviceType = iota
|
||||||
|
|
||||||
// FsDev is the filesystem device type.
|
// FsDev is the filesystem device type.
|
||||||
fsDev
|
FsDev
|
||||||
|
|
||||||
// NetDev is the network device type.
|
// NetDev is the network device type.
|
||||||
netDev
|
NetDev
|
||||||
|
|
||||||
// BlockDev is the block device type.
|
// BlockDev is the block device type.
|
||||||
blockDev
|
BlockDev
|
||||||
|
|
||||||
// SerialPortDev is the serial port device type.
|
// SerialPortDev is the serial port device type.
|
||||||
serialPortDev
|
SerialPortDev
|
||||||
|
|
||||||
// vSockPCIDev is the vhost vsock PCI device type.
|
// VSockPCIDev is the vhost vsock PCI device type.
|
||||||
vSockPCIDev
|
VSockPCIDev
|
||||||
|
|
||||||
// VFIODevice is VFIO device type
|
// VFIODevice is VFIO device type
|
||||||
vfioDev
|
VfioDev
|
||||||
|
|
||||||
// vhostuserDev is a Vhost-user device type
|
// VhostuserDev is a Vhost-user device type
|
||||||
vhostuserDev
|
VhostuserDev
|
||||||
|
|
||||||
// CPUDevice is CPU device type
|
// CPUDevice is CPU device type
|
||||||
cpuDev
|
CpuDev
|
||||||
|
|
||||||
// memoryDevice is memory device type
|
// MemoryDev is memory device type
|
||||||
memoryDev
|
MemoryDev
|
||||||
|
|
||||||
// hybridVirtioVsockDev is a hybrid virtio-vsock device supported
|
// HybridVirtioVsockDev is a hybrid virtio-vsock device supported
|
||||||
// only on certain hypervisors, like firecracker.
|
// only on certain hypervisors, like firecracker.
|
||||||
hybridVirtioVsockDev
|
HybridVirtioVsockDev
|
||||||
)
|
)
|
||||||
|
|
||||||
type memoryDevice struct {
|
type MemoryDevice struct {
|
||||||
slot int
|
Slot int
|
||||||
sizeMB int
|
SizeMB int
|
||||||
addr uint64
|
Addr uint64
|
||||||
probe bool
|
Probe bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set sets an hypervisor type based on the input string.
|
// Set sets an hypervisor type based on the input string.
|
||||||
@ -514,11 +514,11 @@ type HypervisorConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// vcpu mapping from vcpu number to thread number
|
// vcpu mapping from vcpu number to thread number
|
||||||
type vcpuThreadIDs struct {
|
type VcpuThreadIDs struct {
|
||||||
vcpus map[int]int
|
vcpus map[int]int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (conf *HypervisorConfig) checkTemplateConfig() error {
|
func (conf *HypervisorConfig) CheckTemplateConfig() error {
|
||||||
if conf.BootToBeTemplate && conf.BootFromTemplate {
|
if conf.BootToBeTemplate && conf.BootFromTemplate {
|
||||||
return fmt.Errorf("Cannot set both 'to be' and 'from' vm tempate")
|
return fmt.Errorf("Cannot set both 'to be' and 'from' vm tempate")
|
||||||
}
|
}
|
||||||
@ -536,7 +536,7 @@ func (conf *HypervisorConfig) checkTemplateConfig() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (conf *HypervisorConfig) valid() error {
|
func (conf *HypervisorConfig) Valid() error {
|
||||||
if conf.KernelPath == "" {
|
if conf.KernelPath == "" {
|
||||||
return fmt.Errorf("Missing kernel path")
|
return fmt.Errorf("Missing kernel path")
|
||||||
}
|
}
|
||||||
@ -545,7 +545,7 @@ func (conf *HypervisorConfig) valid() error {
|
|||||||
return fmt.Errorf("Missing image and initrd path")
|
return fmt.Errorf("Missing image and initrd path")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := conf.checkTemplateConfig(); err != nil {
|
if err := conf.CheckTemplateConfig(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,7 +590,7 @@ func (conf *HypervisorConfig) AddKernelParam(p Param) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (conf *HypervisorConfig) addCustomAsset(a *types.Asset) error {
|
func (conf *HypervisorConfig) AddCustomAsset(a *types.Asset) error {
|
||||||
if a == nil || a.Path() == "" {
|
if a == nil || a.Path() == "" {
|
||||||
// We did not get a custom asset, we will use the default one.
|
// We did not get a custom asset, we will use the default one.
|
||||||
return nil
|
return nil
|
||||||
@ -744,7 +744,7 @@ func DeserializeParams(parameters []string) []Param {
|
|||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHostMemorySizeKb(memInfoPath string) (uint64, error) {
|
func GetHostMemorySizeKb(memInfoPath string) (uint64, error) {
|
||||||
f, err := os.Open(memInfoPath)
|
f, err := os.Open(memInfoPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -872,7 +872,7 @@ func RunningOnVMM(cpuInfoPath string) (bool, error) {
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHypervisorPid(h hypervisor) int {
|
func GetHypervisorPid(h hypervisor) int {
|
||||||
pids := h.getPids()
|
pids := h.getPids()
|
||||||
if len(pids) == 0 {
|
if len(pids) == 0 {
|
||||||
return 0
|
return 0
|
||||||
@ -905,16 +905,16 @@ type hypervisor interface {
|
|||||||
pauseSandbox(ctx context.Context) error
|
pauseSandbox(ctx context.Context) error
|
||||||
saveSandbox() error
|
saveSandbox() error
|
||||||
resumeSandbox(ctx context.Context) error
|
resumeSandbox(ctx context.Context) error
|
||||||
addDevice(ctx context.Context, devInfo interface{}, devType deviceType) error
|
addDevice(ctx context.Context, devInfo interface{}, devType DeviceType) error
|
||||||
hotplugAddDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error)
|
hotplugAddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error)
|
||||||
hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error)
|
hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error)
|
||||||
resizeMemory(ctx context.Context, memMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, memoryDevice, error)
|
resizeMemory(ctx context.Context, memMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, MemoryDevice, error)
|
||||||
resizeVCPUs(ctx context.Context, vcpus uint32) (uint32, uint32, error)
|
resizeVCPUs(ctx context.Context, vcpus uint32) (uint32, uint32, error)
|
||||||
getSandboxConsole(ctx context.Context, sandboxID string) (string, string, error)
|
getSandboxConsole(ctx context.Context, sandboxID string) (string, string, error)
|
||||||
disconnect(ctx context.Context)
|
disconnect(ctx context.Context)
|
||||||
capabilities(ctx context.Context) types.Capabilities
|
capabilities(ctx context.Context) types.Capabilities
|
||||||
hypervisorConfig() HypervisorConfig
|
hypervisorConfig() HypervisorConfig
|
||||||
getThreadIDs(ctx context.Context) (vcpuThreadIDs, error)
|
getThreadIDs(ctx context.Context) (VcpuThreadIDs, error)
|
||||||
cleanup(ctx context.Context) error
|
cleanup(ctx context.Context) error
|
||||||
// getPids returns a slice of hypervisor related process ids.
|
// getPids returns a slice of hypervisor related process ids.
|
||||||
// The hypervisor pid must be put at index 0.
|
// The hypervisor pid must be put at index 0.
|
||||||
|
@ -88,7 +88,7 @@ func TestNewHypervisorFromUnknownHypervisorType(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testHypervisorConfigValid(t *testing.T, hypervisorConfig *HypervisorConfig, success bool) {
|
func testHypervisorConfigValid(t *testing.T, hypervisorConfig *HypervisorConfig, success bool) {
|
||||||
err := hypervisorConfig.valid()
|
err := hypervisorConfig.Valid()
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
assert.False(success && err != nil)
|
assert.False(success && err != nil)
|
||||||
assert.False(!success && err == nil)
|
assert.False(!success && err == nil)
|
||||||
@ -385,7 +385,7 @@ func TestGetHostMemorySizeKb(t *testing.T) {
|
|||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
file := filepath.Join(dir, "meminfo")
|
file := filepath.Join(dir, "meminfo")
|
||||||
_, err = getHostMemorySizeKb(file)
|
_, err = GetHostMemorySizeKb(file)
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
|
|
||||||
for _, d := range data {
|
for _, d := range data {
|
||||||
@ -393,7 +393,7 @@ func TestGetHostMemorySizeKb(t *testing.T) {
|
|||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
defer os.Remove(file)
|
defer os.Remove(file)
|
||||||
|
|
||||||
hostMemKb, err := getHostMemorySizeKb(file)
|
hostMemKb, err := GetHostMemorySizeKb(file)
|
||||||
|
|
||||||
assert.False((d.expectError && err == nil))
|
assert.False((d.expectError && err == nil))
|
||||||
assert.False((!d.expectError && err != nil))
|
assert.False((!d.expectError && err != nil))
|
||||||
|
@ -103,7 +103,7 @@ func (endpoint *IPVlanEndpoint) Attach(ctx context.Context, s *Sandbox) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.addDevice(ctx, endpoint, netDev)
|
return h.addDevice(ctx, endpoint, NetDev)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detach for the ipvlan endpoint tears down the tap and bridge
|
// Detach for the ipvlan endpoint tears down the tap and bridge
|
||||||
|
@ -432,11 +432,11 @@ func (k *kataAgent) configure(ctx context.Context, h hypervisor, id, sharePath s
|
|||||||
|
|
||||||
switch s := k.vmSocket.(type) {
|
switch s := k.vmSocket.(type) {
|
||||||
case types.VSock:
|
case types.VSock:
|
||||||
if err = h.addDevice(ctx, s, vSockPCIDev); err != nil {
|
if err = h.addDevice(ctx, s, VSockPCIDev); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case types.HybridVSock:
|
case types.HybridVSock:
|
||||||
err = h.addDevice(ctx, s, hybridVirtioVsockDev)
|
err = h.addDevice(ctx, s, HybridVirtioVsockDev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -463,7 +463,7 @@ func (k *kataAgent) configure(ctx context.Context, h hypervisor, id, sharePath s
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.addDevice(ctx, sharedVolume, fsDev)
|
return h.addDevice(ctx, sharedVolume, FsDev)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *kataAgent) configureFromGrpc(ctx context.Context, h hypervisor, id string, config KataAgentConfig) error {
|
func (k *kataAgent) configureFromGrpc(ctx context.Context, h hypervisor, id string, config KataAgentConfig) error {
|
||||||
|
@ -82,7 +82,7 @@ func (endpoint *MacvtapEndpoint) Attach(ctx context.Context, s *Sandbox) error {
|
|||||||
endpoint.VhostFds = vhostFds
|
endpoint.VhostFds = vhostFds
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.addDevice(ctx, endpoint, netDev)
|
return h.addDevice(ctx, endpoint, NetDev)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detach for macvtap endpoint does nothing.
|
// Detach for macvtap endpoint does nothing.
|
||||||
|
@ -31,7 +31,7 @@ func (m *mockHypervisor) hypervisorConfig() HypervisorConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockHypervisor) setConfig(config *HypervisorConfig) error {
|
func (m *mockHypervisor) setConfig(config *HypervisorConfig) error {
|
||||||
if err := config.valid(); err != nil {
|
if err := config.Valid(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,26 +66,26 @@ func (m *mockHypervisor) saveSandbox() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockHypervisor) addDevice(ctx context.Context, devInfo interface{}, devType deviceType) error {
|
func (m *mockHypervisor) addDevice(ctx context.Context, devInfo interface{}, devType DeviceType) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockHypervisor) hotplugAddDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (m *mockHypervisor) hotplugAddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
||||||
switch devType {
|
switch devType {
|
||||||
case cpuDev:
|
case CpuDev:
|
||||||
return devInfo.(uint32), nil
|
return devInfo.(uint32), nil
|
||||||
case memoryDev:
|
case MemoryDev:
|
||||||
memdev := devInfo.(*memoryDevice)
|
memdev := devInfo.(*MemoryDevice)
|
||||||
return memdev.sizeMB, nil
|
return memdev.SizeMB, nil
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockHypervisor) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (m *mockHypervisor) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
||||||
switch devType {
|
switch devType {
|
||||||
case cpuDev:
|
case CpuDev:
|
||||||
return devInfo.(uint32), nil
|
return devInfo.(uint32), nil
|
||||||
case memoryDev:
|
case MemoryDev:
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -95,8 +95,8 @@ func (m *mockHypervisor) getSandboxConsole(ctx context.Context, sandboxID string
|
|||||||
return "", "", nil
|
return "", "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockHypervisor) resizeMemory(ctx context.Context, memMB uint32, memorySectionSizeMB uint32, probe bool) (uint32, memoryDevice, error) {
|
func (m *mockHypervisor) resizeMemory(ctx context.Context, memMB uint32, memorySectionSizeMB uint32, probe bool) (uint32, MemoryDevice, error) {
|
||||||
return 0, memoryDevice{}, nil
|
return 0, MemoryDevice{}, nil
|
||||||
}
|
}
|
||||||
func (m *mockHypervisor) resizeVCPUs(ctx context.Context, cpus uint32) (uint32, uint32, error) {
|
func (m *mockHypervisor) resizeVCPUs(ctx context.Context, cpus uint32) (uint32, uint32, error) {
|
||||||
return 0, 0, nil
|
return 0, 0, nil
|
||||||
@ -105,9 +105,9 @@ func (m *mockHypervisor) resizeVCPUs(ctx context.Context, cpus uint32) (uint32,
|
|||||||
func (m *mockHypervisor) disconnect(ctx context.Context) {
|
func (m *mockHypervisor) disconnect(ctx context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockHypervisor) getThreadIDs(ctx context.Context) (vcpuThreadIDs, error) {
|
func (m *mockHypervisor) getThreadIDs(ctx context.Context) (VcpuThreadIDs, error) {
|
||||||
vcpus := map[int]int{0: os.Getpid()}
|
vcpus := map[int]int{0: os.Getpid()}
|
||||||
return vcpuThreadIDs{vcpus}, nil
|
return VcpuThreadIDs{vcpus}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockHypervisor) cleanup(ctx context.Context) error {
|
func (m *mockHypervisor) cleanup(ctx context.Context) error {
|
||||||
|
@ -59,7 +59,7 @@ func TestMockHypervisorStopSandbox(t *testing.T) {
|
|||||||
func TestMockHypervisorAddDevice(t *testing.T) {
|
func TestMockHypervisorAddDevice(t *testing.T) {
|
||||||
var m *mockHypervisor
|
var m *mockHypervisor
|
||||||
|
|
||||||
assert.NoError(t, m.addDevice(context.Background(), nil, imgDev))
|
assert.NoError(t, m.addDevice(context.Background(), nil, ImgDev))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMockHypervisorGetSandboxConsole(t *testing.T) {
|
func TestMockHypervisorGetSandboxConsole(t *testing.T) {
|
||||||
|
@ -308,7 +308,7 @@ func (q *qemu) cpuTopology() govmmQemu.SMP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hostMemMB() (uint64, error) {
|
func (q *qemu) hostMemMB() (uint64, error) {
|
||||||
hostMemKb, err := getHostMemorySizeKb(procMemInfo)
|
hostMemKb, err := GetHostMemorySizeKb(procMemInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("Unable to read memory info: %s", err)
|
return 0, fmt.Errorf("Unable to read memory info: %s", err)
|
||||||
}
|
}
|
||||||
@ -466,7 +466,7 @@ func (q *qemu) setupFileBackedMem(knobs *govmmQemu.Knobs, memory *govmmQemu.Memo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) setConfig(config *HypervisorConfig) error {
|
func (q *qemu) setConfig(config *HypervisorConfig) error {
|
||||||
err := config.valid()
|
err := config.Valid()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1230,7 +1230,7 @@ func (q *qemu) qmpShutdown() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugAddBlockDevice(ctx context.Context, drive *config.BlockDrive, op operation, devID string) (err error) {
|
func (q *qemu) hotplugAddBlockDevice(ctx context.Context, drive *config.BlockDrive, op Operation, devID string) (err error) {
|
||||||
// drive can be a pmem device, in which case it's used as backing file for a nvdimm device
|
// drive can be a pmem device, in which case it's used as backing file for a nvdimm device
|
||||||
if q.config.BlockDeviceDriver == config.Nvdimm || drive.Pmem {
|
if q.config.BlockDeviceDriver == config.Nvdimm || drive.Pmem {
|
||||||
var blocksize int64
|
var blocksize int64
|
||||||
@ -1351,7 +1351,7 @@ func (q *qemu) hotplugAddBlockDevice(ctx context.Context, drive *config.BlockDri
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugAddVhostUserBlkDevice(ctx context.Context, vAttr *config.VhostUserDeviceAttrs, op operation, devID string) (err error) {
|
func (q *qemu) hotplugAddVhostUserBlkDevice(ctx context.Context, vAttr *config.VhostUserDeviceAttrs, op Operation, devID string) (err error) {
|
||||||
err = q.qmpMonitorCh.qmp.ExecuteCharDevUnixSocketAdd(q.qmpMonitorCh.ctx, vAttr.DevID, vAttr.SocketPath, false, false)
|
err = q.qmpMonitorCh.qmp.ExecuteCharDevUnixSocketAdd(q.qmpMonitorCh.ctx, vAttr.DevID, vAttr.SocketPath, false, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -1392,14 +1392,14 @@ func (q *qemu) hotplugAddVhostUserBlkDevice(ctx context.Context, vAttr *config.V
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugBlockDevice(ctx context.Context, drive *config.BlockDrive, op operation) error {
|
func (q *qemu) hotplugBlockDevice(ctx context.Context, drive *config.BlockDrive, op Operation) error {
|
||||||
if err := q.qmpSetup(); err != nil {
|
if err := q.qmpSetup(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
devID := "virtio-" + drive.ID
|
devID := "virtio-" + drive.ID
|
||||||
|
|
||||||
if op == addDevice {
|
if op == AddDevice {
|
||||||
return q.hotplugAddBlockDevice(ctx, drive, op, devID)
|
return q.hotplugAddBlockDevice(ctx, drive, op, devID)
|
||||||
}
|
}
|
||||||
if !drive.Swap && q.config.BlockDeviceDriver == config.VirtioBlock {
|
if !drive.Swap && q.config.BlockDeviceDriver == config.VirtioBlock {
|
||||||
@ -1415,14 +1415,14 @@ func (q *qemu) hotplugBlockDevice(ctx context.Context, drive *config.BlockDrive,
|
|||||||
return q.qmpMonitorCh.qmp.ExecuteBlockdevDel(q.qmpMonitorCh.ctx, drive.ID)
|
return q.qmpMonitorCh.qmp.ExecuteBlockdevDel(q.qmpMonitorCh.ctx, drive.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugVhostUserDevice(ctx context.Context, vAttr *config.VhostUserDeviceAttrs, op operation) error {
|
func (q *qemu) hotplugVhostUserDevice(ctx context.Context, vAttr *config.VhostUserDeviceAttrs, op Operation) error {
|
||||||
if err := q.qmpSetup(); err != nil {
|
if err := q.qmpSetup(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
devID := "virtio-" + vAttr.DevID
|
devID := "virtio-" + vAttr.DevID
|
||||||
|
|
||||||
if op == addDevice {
|
if op == AddDevice {
|
||||||
switch vAttr.Type {
|
switch vAttr.Type {
|
||||||
case config.VhostUserBlk:
|
case config.VhostUserBlk:
|
||||||
return q.hotplugAddVhostUserBlkDevice(ctx, vAttr, op, devID)
|
return q.hotplugAddVhostUserBlkDevice(ctx, vAttr, op, devID)
|
||||||
@ -1505,7 +1505,7 @@ func (q *qemu) qomGetPciPath(qemuID string) (vcTypes.PciPath, error) {
|
|||||||
return vcTypes.PciPathFromSlots(bridgeSlot, devSlot)
|
return vcTypes.PciPathFromSlots(bridgeSlot, devSlot)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugVFIODevice(ctx context.Context, device *config.VFIODev, op operation) (err error) {
|
func (q *qemu) hotplugVFIODevice(ctx context.Context, device *config.VFIODev, op Operation) (err error) {
|
||||||
if err = q.qmpSetup(); err != nil {
|
if err = q.qmpSetup(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1513,7 +1513,7 @@ func (q *qemu) hotplugVFIODevice(ctx context.Context, device *config.VFIODev, op
|
|||||||
devID := device.ID
|
devID := device.ID
|
||||||
machineType := q.hypervisorConfig().HypervisorMachineType
|
machineType := q.hypervisorConfig().HypervisorMachineType
|
||||||
|
|
||||||
if op == addDevice {
|
if op == AddDevice {
|
||||||
|
|
||||||
buf, _ := json.Marshal(device)
|
buf, _ := json.Marshal(device)
|
||||||
q.Logger().WithFields(logrus.Fields{
|
q.Logger().WithFields(logrus.Fields{
|
||||||
@ -1623,7 +1623,7 @@ func (q *qemu) hotAddNetDevice(name, hardAddr string, VMFds, VhostFds []*os.File
|
|||||||
return q.qmpMonitorCh.qmp.ExecuteNetdevAddByFds(q.qmpMonitorCh.ctx, "tap", name, VMFdNames, VhostFdNames)
|
return q.qmpMonitorCh.qmp.ExecuteNetdevAddByFds(q.qmpMonitorCh.ctx, "tap", name, VMFdNames, VhostFdNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugNetDevice(ctx context.Context, endpoint Endpoint, op operation) (err error) {
|
func (q *qemu) hotplugNetDevice(ctx context.Context, endpoint Endpoint, op Operation) (err error) {
|
||||||
if err = q.qmpSetup(); err != nil {
|
if err = q.qmpSetup(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1641,7 +1641,7 @@ func (q *qemu) hotplugNetDevice(ctx context.Context, endpoint Endpoint, op opera
|
|||||||
}
|
}
|
||||||
|
|
||||||
devID := "virtio-" + tap.ID
|
devID := "virtio-" + tap.ID
|
||||||
if op == addDevice {
|
if op == AddDevice {
|
||||||
if err = q.hotAddNetDevice(tap.Name, endpoint.HardwareAddr(), tap.VMFds, tap.VhostFds); err != nil {
|
if err = q.hotAddNetDevice(tap.Name, endpoint.HardwareAddr(), tap.VMFds, tap.VhostFds); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1698,24 +1698,24 @@ func (q *qemu) hotplugNetDevice(ctx context.Context, endpoint Endpoint, op opera
|
|||||||
return q.qmpMonitorCh.qmp.ExecuteNetdevDel(q.qmpMonitorCh.ctx, tap.Name)
|
return q.qmpMonitorCh.qmp.ExecuteNetdevDel(q.qmpMonitorCh.ctx, tap.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugDevice(ctx context.Context, devInfo interface{}, devType deviceType, op operation) (interface{}, error) {
|
func (q *qemu) hotplugDevice(ctx context.Context, devInfo interface{}, devType DeviceType, op Operation) (interface{}, error) {
|
||||||
switch devType {
|
switch devType {
|
||||||
case blockDev:
|
case BlockDev:
|
||||||
drive := devInfo.(*config.BlockDrive)
|
drive := devInfo.(*config.BlockDrive)
|
||||||
return nil, q.hotplugBlockDevice(ctx, drive, op)
|
return nil, q.hotplugBlockDevice(ctx, drive, op)
|
||||||
case cpuDev:
|
case CpuDev:
|
||||||
vcpus := devInfo.(uint32)
|
vcpus := devInfo.(uint32)
|
||||||
return q.hotplugCPUs(vcpus, op)
|
return q.hotplugCPUs(vcpus, op)
|
||||||
case vfioDev:
|
case VfioDev:
|
||||||
device := devInfo.(*config.VFIODev)
|
device := devInfo.(*config.VFIODev)
|
||||||
return nil, q.hotplugVFIODevice(ctx, device, op)
|
return nil, q.hotplugVFIODevice(ctx, device, op)
|
||||||
case memoryDev:
|
case MemoryDev:
|
||||||
memdev := devInfo.(*memoryDevice)
|
memdev := devInfo.(*MemoryDevice)
|
||||||
return q.hotplugMemory(memdev, op)
|
return q.hotplugMemory(memdev, op)
|
||||||
case netDev:
|
case NetDev:
|
||||||
device := devInfo.(Endpoint)
|
device := devInfo.(Endpoint)
|
||||||
return nil, q.hotplugNetDevice(ctx, device, op)
|
return nil, q.hotplugNetDevice(ctx, device, op)
|
||||||
case vhostuserDev:
|
case VhostuserDev:
|
||||||
vAttr := devInfo.(*config.VhostUserDeviceAttrs)
|
vAttr := devInfo.(*config.VhostUserDeviceAttrs)
|
||||||
return nil, q.hotplugVhostUserDevice(ctx, vAttr, op)
|
return nil, q.hotplugVhostUserDevice(ctx, vAttr, op)
|
||||||
default:
|
default:
|
||||||
@ -1723,12 +1723,12 @@ func (q *qemu) hotplugDevice(ctx context.Context, devInfo interface{}, devType d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugAddDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (q *qemu) hotplugAddDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
||||||
span, ctx := katatrace.Trace(ctx, q.Logger(), "hotplugAddDevice", qemuTracingTags, map[string]string{"sandbox_id": q.id})
|
span, ctx := katatrace.Trace(ctx, q.Logger(), "hotplugAddDevice", qemuTracingTags, map[string]string{"sandbox_id": q.id})
|
||||||
katatrace.AddTag(span, "device", devInfo)
|
katatrace.AddTag(span, "device", devInfo)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
data, err := q.hotplugDevice(ctx, devInfo, devType, addDevice)
|
data, err := q.hotplugDevice(ctx, devInfo, devType, AddDevice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
@ -1736,12 +1736,12 @@ func (q *qemu) hotplugAddDevice(ctx context.Context, devInfo interface{}, devTyp
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType deviceType) (interface{}, error) {
|
func (q *qemu) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, devType DeviceType) (interface{}, error) {
|
||||||
span, ctx := katatrace.Trace(ctx, q.Logger(), "hotplugRemoveDevice", qemuTracingTags, map[string]string{"sandbox_id": q.id})
|
span, ctx := katatrace.Trace(ctx, q.Logger(), "hotplugRemoveDevice", qemuTracingTags, map[string]string{"sandbox_id": q.id})
|
||||||
katatrace.AddTag(span, "device", devInfo)
|
katatrace.AddTag(span, "device", devInfo)
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
data, err := q.hotplugDevice(ctx, devInfo, devType, removeDevice)
|
data, err := q.hotplugDevice(ctx, devInfo, devType, RemoveDevice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
@ -1749,7 +1749,7 @@ func (q *qemu) hotplugRemoveDevice(ctx context.Context, devInfo interface{}, dev
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugCPUs(vcpus uint32, op operation) (uint32, error) {
|
func (q *qemu) hotplugCPUs(vcpus uint32, op Operation) (uint32, error) {
|
||||||
if vcpus == 0 {
|
if vcpus == 0 {
|
||||||
q.Logger().Warnf("cannot hotplug 0 vCPUs")
|
q.Logger().Warnf("cannot hotplug 0 vCPUs")
|
||||||
return 0, nil
|
return 0, nil
|
||||||
@ -1759,7 +1759,7 @@ func (q *qemu) hotplugCPUs(vcpus uint32, op operation) (uint32, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if op == addDevice {
|
if op == AddDevice {
|
||||||
return q.hotplugAddCPUs(vcpus)
|
return q.hotplugAddCPUs(vcpus)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1854,46 +1854,46 @@ func (q *qemu) hotplugRemoveCPUs(amount uint32) (uint32, error) {
|
|||||||
return amount, nil
|
return amount, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugMemory(memDev *memoryDevice, op operation) (int, error) {
|
func (q *qemu) hotplugMemory(memDev *MemoryDevice, op Operation) (int, error) {
|
||||||
|
|
||||||
if !q.arch.supportGuestMemoryHotplug() {
|
if !q.arch.supportGuestMemoryHotplug() {
|
||||||
return 0, noGuestMemHotplugErr
|
return 0, noGuestMemHotplugErr
|
||||||
}
|
}
|
||||||
if memDev.sizeMB < 0 {
|
if memDev.SizeMB < 0 {
|
||||||
return 0, fmt.Errorf("cannot hotplug negative size (%d) memory", memDev.sizeMB)
|
return 0, fmt.Errorf("cannot hotplug negative size (%d) memory", memDev.SizeMB)
|
||||||
}
|
}
|
||||||
memLog := q.Logger().WithField("hotplug", "memory")
|
memLog := q.Logger().WithField("hotplug", "memory")
|
||||||
|
|
||||||
memLog.WithField("hotplug-memory-mb", memDev.sizeMB).Debug("requested memory hotplug")
|
memLog.WithField("hotplug-memory-mb", memDev.SizeMB).Debug("requested memory hotplug")
|
||||||
if err := q.qmpSetup(); err != nil {
|
if err := q.qmpSetup(); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
currentMemory := int(q.config.MemorySize) + q.state.HotpluggedMemory
|
currentMemory := int(q.config.MemorySize) + q.state.HotpluggedMemory
|
||||||
|
|
||||||
if memDev.sizeMB == 0 {
|
if memDev.SizeMB == 0 {
|
||||||
memLog.Debug("hotplug is not required")
|
memLog.Debug("hotplug is not required")
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch op {
|
switch op {
|
||||||
case removeDevice:
|
case RemoveDevice:
|
||||||
memLog.WithField("operation", "remove").Debugf("Requested to remove memory: %d MB", memDev.sizeMB)
|
memLog.WithField("operation", "remove").Debugf("Requested to remove memory: %d MB", memDev.SizeMB)
|
||||||
// Dont fail but warn that this is not supported.
|
// Dont fail but warn that this is not supported.
|
||||||
memLog.Warn("hot-remove VM memory not supported")
|
memLog.Warn("hot-remove VM memory not supported")
|
||||||
return 0, nil
|
return 0, nil
|
||||||
case addDevice:
|
case AddDevice:
|
||||||
memLog.WithField("operation", "add").Debugf("Requested to add memory: %d MB", memDev.sizeMB)
|
memLog.WithField("operation", "add").Debugf("Requested to add memory: %d MB", memDev.SizeMB)
|
||||||
maxMem, err := q.hostMemMB()
|
maxMem, err := q.hostMemMB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't exceed the maximum amount of memory
|
// Don't exceed the maximum amount of memory
|
||||||
if currentMemory+memDev.sizeMB > int(maxMem) {
|
if currentMemory+memDev.SizeMB > int(maxMem) {
|
||||||
// Fixme: return a typed error
|
// Fixme: return a typed error
|
||||||
return 0, fmt.Errorf("Unable to hotplug %d MiB memory, the SB has %d MiB and the maximum amount is %d MiB",
|
return 0, fmt.Errorf("Unable to hotplug %d MiB memory, the SB has %d MiB and the maximum amount is %d MiB",
|
||||||
memDev.sizeMB, currentMemory, maxMem)
|
memDev.SizeMB, currentMemory, maxMem)
|
||||||
}
|
}
|
||||||
memoryAdded, err := q.hotplugAddMemory(memDev)
|
memoryAdded, err := q.hotplugAddMemory(memDev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1906,7 +1906,7 @@ func (q *qemu) hotplugMemory(memDev *memoryDevice, op operation) (int, error) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) hotplugAddMemory(memDev *memoryDevice) (int, error) {
|
func (q *qemu) hotplugAddMemory(memDev *MemoryDevice) (int, error) {
|
||||||
memoryDevices, err := q.qmpMonitorCh.qmp.ExecQueryMemoryDevices(q.qmpMonitorCh.ctx)
|
memoryDevices, err := q.qmpMonitorCh.qmp.ExecQueryMemoryDevices(q.qmpMonitorCh.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("failed to query memory devices: %v", err)
|
return 0, fmt.Errorf("failed to query memory devices: %v", err)
|
||||||
@ -1919,7 +1919,7 @@ func (q *qemu) hotplugAddMemory(memDev *memoryDevice) (int, error) {
|
|||||||
maxSlot = device.Data.Slot
|
maxSlot = device.Data.Slot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memDev.slot = maxSlot + 1
|
memDev.Slot = maxSlot + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
share, target, memoryBack, err := q.getMemArgs()
|
share, target, memoryBack, err := q.getMemArgs()
|
||||||
@ -1927,26 +1927,26 @@ func (q *qemu) hotplugAddMemory(memDev *memoryDevice) (int, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = q.qmpMonitorCh.qmp.ExecHotplugMemory(q.qmpMonitorCh.ctx, memoryBack, "mem"+strconv.Itoa(memDev.slot), target, memDev.sizeMB, share)
|
err = q.qmpMonitorCh.qmp.ExecHotplugMemory(q.qmpMonitorCh.ctx, memoryBack, "mem"+strconv.Itoa(memDev.Slot), target, memDev.SizeMB, share)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
q.Logger().WithError(err).Error("hotplug memory")
|
q.Logger().WithError(err).Error("hotplug memory")
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
// if guest kernel only supports memory hotplug via probe interface, we need to get address of hot-add memory device
|
// if guest kernel only supports memory hotplug via probe interface, we need to get address of hot-add memory device
|
||||||
if memDev.probe {
|
if memDev.Probe {
|
||||||
memoryDevices, err := q.qmpMonitorCh.qmp.ExecQueryMemoryDevices(q.qmpMonitorCh.ctx)
|
memoryDevices, err := q.qmpMonitorCh.qmp.ExecQueryMemoryDevices(q.qmpMonitorCh.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("failed to query memory devices: %v", err)
|
return 0, fmt.Errorf("failed to query memory devices: %v", err)
|
||||||
}
|
}
|
||||||
if len(memoryDevices) != 0 {
|
if len(memoryDevices) != 0 {
|
||||||
q.Logger().WithField("addr", fmt.Sprintf("0x%x", memoryDevices[len(memoryDevices)-1].Data.Addr)).Debug("recently hot-add memory device")
|
q.Logger().WithField("addr", fmt.Sprintf("0x%x", memoryDevices[len(memoryDevices)-1].Data.Addr)).Debug("recently hot-add memory device")
|
||||||
memDev.addr = memoryDevices[len(memoryDevices)-1].Data.Addr
|
memDev.Addr = memoryDevices[len(memoryDevices)-1].Data.Addr
|
||||||
} else {
|
} else {
|
||||||
return 0, fmt.Errorf("failed to probe address of recently hot-add memory device, no device exists")
|
return 0, fmt.Errorf("failed to probe address of recently hot-add memory device, no device exists")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
q.state.HotpluggedMemory += memDev.sizeMB
|
q.state.HotpluggedMemory += memDev.SizeMB
|
||||||
return memDev.sizeMB, nil
|
return memDev.SizeMB, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) pauseSandbox(ctx context.Context) error {
|
func (q *qemu) pauseSandbox(ctx context.Context) error {
|
||||||
@ -1964,7 +1964,7 @@ func (q *qemu) resumeSandbox(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// addDevice will add extra devices to Qemu command line.
|
// addDevice will add extra devices to Qemu command line.
|
||||||
func (q *qemu) addDevice(ctx context.Context, devInfo interface{}, devType deviceType) error {
|
func (q *qemu) addDevice(ctx context.Context, devInfo interface{}, devType DeviceType) error {
|
||||||
var err error
|
var err error
|
||||||
span, _ := katatrace.Trace(ctx, q.Logger(), "addDevice", qemuTracingTags, map[string]string{"sandbox_id": q.id})
|
span, _ := katatrace.Trace(ctx, q.Logger(), "addDevice", qemuTracingTags, map[string]string{"sandbox_id": q.id})
|
||||||
katatrace.AddTag(span, "device", devInfo)
|
katatrace.AddTag(span, "device", devInfo)
|
||||||
@ -2107,23 +2107,23 @@ func (q *qemu) disconnect(ctx context.Context) {
|
|||||||
// the memory to remove has to be at least the size of one slot.
|
// the memory to remove has to be at least the size of one slot.
|
||||||
// To return memory back we are resizing the VM memory balloon.
|
// To return memory back we are resizing the VM memory balloon.
|
||||||
// A longer term solution is evaluate solutions like virtio-mem
|
// A longer term solution is evaluate solutions like virtio-mem
|
||||||
func (q *qemu) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, memoryDevice, error) {
|
func (q *qemu) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSizeMB uint32, probe bool) (uint32, MemoryDevice, error) {
|
||||||
|
|
||||||
currentMemory := q.config.MemorySize + uint32(q.state.HotpluggedMemory)
|
currentMemory := q.config.MemorySize + uint32(q.state.HotpluggedMemory)
|
||||||
if err := q.qmpSetup(); err != nil {
|
if err := q.qmpSetup(); err != nil {
|
||||||
return 0, memoryDevice{}, err
|
return 0, MemoryDevice{}, err
|
||||||
}
|
}
|
||||||
var addMemDevice memoryDevice
|
var addMemDevice MemoryDevice
|
||||||
if q.config.VirtioMem && currentMemory != reqMemMB {
|
if q.config.VirtioMem && currentMemory != reqMemMB {
|
||||||
q.Logger().WithField("hotplug", "memory").Debugf("resize memory from %dMB to %dMB", currentMemory, reqMemMB)
|
q.Logger().WithField("hotplug", "memory").Debugf("resize memory from %dMB to %dMB", currentMemory, reqMemMB)
|
||||||
sizeByte := uint64(reqMemMB - q.config.MemorySize)
|
sizeByte := uint64(reqMemMB - q.config.MemorySize)
|
||||||
sizeByte = sizeByte * 1024 * 1024
|
sizeByte = sizeByte * 1024 * 1024
|
||||||
err := q.qmpMonitorCh.qmp.ExecQomSet(q.qmpMonitorCh.ctx, "virtiomem0", "requested-size", sizeByte)
|
err := q.qmpMonitorCh.qmp.ExecQomSet(q.qmpMonitorCh.ctx, "virtiomem0", "requested-size", sizeByte)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, memoryDevice{}, err
|
return 0, MemoryDevice{}, err
|
||||||
}
|
}
|
||||||
q.state.HotpluggedMemory = int(sizeByte / 1024 / 1024)
|
q.state.HotpluggedMemory = int(sizeByte / 1024 / 1024)
|
||||||
return reqMemMB, memoryDevice{}, nil
|
return reqMemMB, MemoryDevice{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
@ -2132,13 +2132,13 @@ func (q *qemu) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSiz
|
|||||||
addMemMB := reqMemMB - currentMemory
|
addMemMB := reqMemMB - currentMemory
|
||||||
memHotplugMB, err := calcHotplugMemMiBSize(addMemMB, memoryBlockSizeMB)
|
memHotplugMB, err := calcHotplugMemMiBSize(addMemMB, memoryBlockSizeMB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return currentMemory, memoryDevice{}, err
|
return currentMemory, MemoryDevice{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
addMemDevice.sizeMB = int(memHotplugMB)
|
addMemDevice.SizeMB = int(memHotplugMB)
|
||||||
addMemDevice.probe = probe
|
addMemDevice.Probe = probe
|
||||||
|
|
||||||
data, err := q.hotplugAddDevice(ctx, &addMemDevice, memoryDev)
|
data, err := q.hotplugAddDevice(ctx, &addMemDevice, MemoryDev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return currentMemory, addMemDevice, err
|
return currentMemory, addMemDevice, err
|
||||||
}
|
}
|
||||||
@ -2152,13 +2152,13 @@ func (q *qemu) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSiz
|
|||||||
addMemMB := currentMemory - reqMemMB
|
addMemMB := currentMemory - reqMemMB
|
||||||
memHotunplugMB, err := calcHotplugMemMiBSize(addMemMB, memoryBlockSizeMB)
|
memHotunplugMB, err := calcHotplugMemMiBSize(addMemMB, memoryBlockSizeMB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return currentMemory, memoryDevice{}, err
|
return currentMemory, MemoryDevice{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
addMemDevice.sizeMB = int(memHotunplugMB)
|
addMemDevice.SizeMB = int(memHotunplugMB)
|
||||||
addMemDevice.probe = probe
|
addMemDevice.Probe = probe
|
||||||
|
|
||||||
data, err := q.hotplugRemoveDevice(ctx, &addMemDevice, memoryDev)
|
data, err := q.hotplugRemoveDevice(ctx, &addMemDevice, MemoryDev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return currentMemory, addMemDevice, err
|
return currentMemory, addMemDevice, err
|
||||||
}
|
}
|
||||||
@ -2308,11 +2308,11 @@ func genericAppendPCIeRootPort(devices []govmmQemu.Device, number uint32, machin
|
|||||||
return devices
|
return devices
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) getThreadIDs(ctx context.Context) (vcpuThreadIDs, error) {
|
func (q *qemu) getThreadIDs(ctx context.Context) (VcpuThreadIDs, error) {
|
||||||
span, _ := katatrace.Trace(ctx, q.Logger(), "getThreadIDs", qemuTracingTags, map[string]string{"sandbox_id": q.id})
|
span, _ := katatrace.Trace(ctx, q.Logger(), "getThreadIDs", qemuTracingTags, map[string]string{"sandbox_id": q.id})
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
tid := vcpuThreadIDs{}
|
tid := VcpuThreadIDs{}
|
||||||
if err := q.qmpSetup(); err != nil {
|
if err := q.qmpSetup(); err != nil {
|
||||||
return tid, err
|
return tid, err
|
||||||
}
|
}
|
||||||
@ -2348,7 +2348,7 @@ func (q *qemu) resizeVCPUs(ctx context.Context, reqVCPUs uint32) (currentVCPUs u
|
|||||||
case currentVCPUs < reqVCPUs:
|
case currentVCPUs < reqVCPUs:
|
||||||
//hotplug
|
//hotplug
|
||||||
addCPUs := reqVCPUs - currentVCPUs
|
addCPUs := reqVCPUs - currentVCPUs
|
||||||
data, err := q.hotplugAddDevice(ctx, addCPUs, cpuDev)
|
data, err := q.hotplugAddDevice(ctx, addCPUs, CpuDev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return currentVCPUs, newVCPUs, err
|
return currentVCPUs, newVCPUs, err
|
||||||
}
|
}
|
||||||
@ -2360,7 +2360,7 @@ func (q *qemu) resizeVCPUs(ctx context.Context, reqVCPUs uint32) (currentVCPUs u
|
|||||||
case currentVCPUs > reqVCPUs:
|
case currentVCPUs > reqVCPUs:
|
||||||
//hotunplug
|
//hotunplug
|
||||||
removeCPUs := currentVCPUs - reqVCPUs
|
removeCPUs := currentVCPUs - reqVCPUs
|
||||||
data, err := q.hotplugRemoveDevice(ctx, removeCPUs, cpuDev)
|
data, err := q.hotplugRemoveDevice(ctx, removeCPUs, CpuDev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return currentVCPUs, newVCPUs, err
|
return currentVCPUs, newVCPUs, err
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ func TestQemuMemoryTopology(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
hostMemKb, err := getHostMemorySizeKb(procMemInfo)
|
hostMemKb, err := GetHostMemorySizeKb(procMemInfo)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
memMax := fmt.Sprintf("%dM", int(float64(hostMemKb)/1024))
|
memMax := fmt.Sprintf("%dM", int(float64(hostMemKb)/1024))
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ func TestQemuKnobs(t *testing.T) {
|
|||||||
assert.Equal(q.qemuConfig.Knobs.NoReboot, true)
|
assert.Equal(q.qemuConfig.Knobs.NoReboot, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testQemuAddDevice(t *testing.T, devInfo interface{}, devType deviceType, expected []govmmQemu.Device) {
|
func testQemuAddDevice(t *testing.T, devInfo interface{}, devType DeviceType, expected []govmmQemu.Device) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
q := &qemu{
|
q := &qemu{
|
||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
@ -237,7 +237,7 @@ func TestQemuAddDeviceFsDev(t *testing.T) {
|
|||||||
HostPath: hostPath,
|
HostPath: hostPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
testQemuAddDevice(t, volume, fsDev, expectedOut)
|
testQemuAddDevice(t, volume, FsDev, expectedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQemuAddDeviceVhostUserBlk(t *testing.T) {
|
func TestQemuAddDeviceVhostUserBlk(t *testing.T) {
|
||||||
@ -258,7 +258,7 @@ func TestQemuAddDeviceVhostUserBlk(t *testing.T) {
|
|||||||
Type: config.VhostUserBlk,
|
Type: config.VhostUserBlk,
|
||||||
}
|
}
|
||||||
|
|
||||||
testQemuAddDevice(t, vDevice, vhostuserDev, expectedOut)
|
testQemuAddDevice(t, vDevice, VhostuserDev, expectedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQemuAddDeviceSerialPortDev(t *testing.T) {
|
func TestQemuAddDeviceSerialPortDev(t *testing.T) {
|
||||||
@ -285,7 +285,7 @@ func TestQemuAddDeviceSerialPortDev(t *testing.T) {
|
|||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
|
|
||||||
testQemuAddDevice(t, socket, serialPortDev, expectedOut)
|
testQemuAddDevice(t, socket, SerialPortDev, expectedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQemuAddDeviceKataVSOCK(t *testing.T) {
|
func TestQemuAddDeviceKataVSOCK(t *testing.T) {
|
||||||
@ -318,7 +318,7 @@ func TestQemuAddDeviceKataVSOCK(t *testing.T) {
|
|||||||
VhostFd: vsockFile,
|
VhostFd: vsockFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
testQemuAddDevice(t, vsock, vSockPCIDev, expectedOut)
|
testQemuAddDevice(t, vsock, VSockPCIDev, expectedOut)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestQemuGetSandboxConsole(t *testing.T) {
|
func TestQemuGetSandboxConsole(t *testing.T) {
|
||||||
@ -401,9 +401,9 @@ func TestHotplugUnsupportedDeviceType(t *testing.T) {
|
|||||||
config: qemuConfig,
|
config: qemuConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := q.hotplugAddDevice(context.Background(), &memoryDevice{0, 128, uint64(0), false}, fsDev)
|
_, err := q.hotplugAddDevice(context.Background(), &MemoryDevice{0, 128, uint64(0), false}, FsDev)
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
_, err = q.hotplugRemoveDevice(context.Background(), &memoryDevice{0, 128, uint64(0), false}, fsDev)
|
_, err = q.hotplugRemoveDevice(context.Background(), &MemoryDevice{0, 128, uint64(0), false}, FsDev)
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -409,7 +409,7 @@ func createAssets(ctx context.Context, sandboxConfig *SandboxConfig) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sandboxConfig.HypervisorConfig.addCustomAsset(a); err != nil {
|
if err := sandboxConfig.HypervisorConfig.AddCustomAsset(a); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1101,7 +1101,7 @@ func (s *Sandbox) addSwap(ctx context.Context, swapID string, size int64) (*conf
|
|||||||
ID: swapID,
|
ID: swapID,
|
||||||
Swap: true,
|
Swap: true,
|
||||||
}
|
}
|
||||||
_, err = s.hypervisor.hotplugAddDevice(ctx, blockDevice, blockDev)
|
_, err = s.hypervisor.hotplugAddDevice(ctx, blockDevice, BlockDev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("add swapfile %s device to VM fail %s", swapFile, err.Error())
|
err = fmt.Errorf("add swapfile %s device to VM fail %s", swapFile, err.Error())
|
||||||
s.Logger().WithError(err).Error("addSwap")
|
s.Logger().WithError(err).Error("addSwap")
|
||||||
@ -1109,7 +1109,7 @@ func (s *Sandbox) addSwap(ctx context.Context, swapID string, size int64) (*conf
|
|||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, e := s.hypervisor.hotplugRemoveDevice(ctx, blockDevice, blockDev)
|
_, e := s.hypervisor.hotplugRemoveDevice(ctx, blockDevice, BlockDev)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
s.Logger().Errorf("remove swapfile %s to VM fail %s", swapFile, e.Error())
|
s.Logger().Errorf("remove swapfile %s to VM fail %s", swapFile, e.Error())
|
||||||
}
|
}
|
||||||
@ -1780,7 +1780,7 @@ func (s *Sandbox) HotplugAddDevice(ctx context.Context, device api.Device, devTy
|
|||||||
|
|
||||||
// adding a group of VFIO devices
|
// adding a group of VFIO devices
|
||||||
for _, dev := range vfioDevices {
|
for _, dev := range vfioDevices {
|
||||||
if _, err := s.hypervisor.hotplugAddDevice(ctx, dev, vfioDev); err != nil {
|
if _, err := s.hypervisor.hotplugAddDevice(ctx, dev, VfioDev); err != nil {
|
||||||
s.Logger().
|
s.Logger().
|
||||||
WithFields(logrus.Fields{
|
WithFields(logrus.Fields{
|
||||||
"sandbox": s.id,
|
"sandbox": s.id,
|
||||||
@ -1796,14 +1796,14 @@ func (s *Sandbox) HotplugAddDevice(ctx context.Context, device api.Device, devTy
|
|||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("device type mismatch, expect device type to be %s", devType)
|
return fmt.Errorf("device type mismatch, expect device type to be %s", devType)
|
||||||
}
|
}
|
||||||
_, err := s.hypervisor.hotplugAddDevice(ctx, blockDevice.BlockDrive, blockDev)
|
_, err := s.hypervisor.hotplugAddDevice(ctx, blockDevice.BlockDrive, BlockDev)
|
||||||
return err
|
return err
|
||||||
case config.VhostUserBlk:
|
case config.VhostUserBlk:
|
||||||
vhostUserBlkDevice, ok := device.(*drivers.VhostUserBlkDevice)
|
vhostUserBlkDevice, ok := device.(*drivers.VhostUserBlkDevice)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("device type mismatch, expect device type to be %s", devType)
|
return fmt.Errorf("device type mismatch, expect device type to be %s", devType)
|
||||||
}
|
}
|
||||||
_, err := s.hypervisor.hotplugAddDevice(ctx, vhostUserBlkDevice.VhostUserDeviceAttrs, vhostuserDev)
|
_, err := s.hypervisor.hotplugAddDevice(ctx, vhostUserBlkDevice.VhostUserDeviceAttrs, VhostuserDev)
|
||||||
return err
|
return err
|
||||||
case config.DeviceGeneric:
|
case config.DeviceGeneric:
|
||||||
// TODO: what?
|
// TODO: what?
|
||||||
@ -1831,7 +1831,7 @@ func (s *Sandbox) HotplugRemoveDevice(ctx context.Context, device api.Device, de
|
|||||||
|
|
||||||
// remove a group of VFIO devices
|
// remove a group of VFIO devices
|
||||||
for _, dev := range vfioDevices {
|
for _, dev := range vfioDevices {
|
||||||
if _, err := s.hypervisor.hotplugRemoveDevice(ctx, dev, vfioDev); err != nil {
|
if _, err := s.hypervisor.hotplugRemoveDevice(ctx, dev, VfioDev); err != nil {
|
||||||
s.Logger().WithError(err).
|
s.Logger().WithError(err).
|
||||||
WithFields(logrus.Fields{
|
WithFields(logrus.Fields{
|
||||||
"sandbox": s.id,
|
"sandbox": s.id,
|
||||||
@ -1852,14 +1852,14 @@ func (s *Sandbox) HotplugRemoveDevice(ctx context.Context, device api.Device, de
|
|||||||
s.Logger().WithField("path", blockDrive.File).Infof("Skip device: cannot hot remove PMEM devices")
|
s.Logger().WithField("path", blockDrive.File).Infof("Skip device: cannot hot remove PMEM devices")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
_, err := s.hypervisor.hotplugRemoveDevice(ctx, blockDrive, blockDev)
|
_, err := s.hypervisor.hotplugRemoveDevice(ctx, blockDrive, BlockDev)
|
||||||
return err
|
return err
|
||||||
case config.VhostUserBlk:
|
case config.VhostUserBlk:
|
||||||
vhostUserDeviceAttrs, ok := device.GetDeviceInfo().(*config.VhostUserDeviceAttrs)
|
vhostUserDeviceAttrs, ok := device.GetDeviceInfo().(*config.VhostUserDeviceAttrs)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("device type mismatch, expect device type to be %s", devType)
|
return fmt.Errorf("device type mismatch, expect device type to be %s", devType)
|
||||||
}
|
}
|
||||||
_, err := s.hypervisor.hotplugRemoveDevice(ctx, vhostUserDeviceAttrs, vhostuserDev)
|
_, err := s.hypervisor.hotplugRemoveDevice(ctx, vhostUserDeviceAttrs, VhostuserDev)
|
||||||
return err
|
return err
|
||||||
case config.DeviceGeneric:
|
case config.DeviceGeneric:
|
||||||
// TODO: what?
|
// TODO: what?
|
||||||
@ -1886,11 +1886,11 @@ func (s *Sandbox) UnsetSandboxBlockIndex(index int) error {
|
|||||||
func (s *Sandbox) AppendDevice(ctx context.Context, device api.Device) error {
|
func (s *Sandbox) AppendDevice(ctx context.Context, device api.Device) error {
|
||||||
switch device.DeviceType() {
|
switch device.DeviceType() {
|
||||||
case config.VhostUserSCSI, config.VhostUserNet, config.VhostUserBlk, config.VhostUserFS:
|
case config.VhostUserSCSI, config.VhostUserNet, config.VhostUserBlk, config.VhostUserFS:
|
||||||
return s.hypervisor.addDevice(ctx, device.GetDeviceInfo().(*config.VhostUserDeviceAttrs), vhostuserDev)
|
return s.hypervisor.addDevice(ctx, device.GetDeviceInfo().(*config.VhostUserDeviceAttrs), VhostuserDev)
|
||||||
case config.DeviceVFIO:
|
case config.DeviceVFIO:
|
||||||
vfioDevs := device.GetDeviceInfo().([]*config.VFIODev)
|
vfioDevs := device.GetDeviceInfo().([]*config.VFIODev)
|
||||||
for _, d := range vfioDevs {
|
for _, d := range vfioDevs {
|
||||||
return s.hypervisor.addDevice(ctx, *d, vfioDev)
|
return s.hypervisor.addDevice(ctx, *d, VfioDev)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
s.Logger().WithField("device-type", device.DeviceType()).
|
s.Logger().WithField("device-type", device.DeviceType()).
|
||||||
@ -1997,10 +1997,10 @@ func (s *Sandbox) updateResources(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.Logger().Debugf("Sandbox memory size: %d MB", newMemory)
|
s.Logger().Debugf("Sandbox memory size: %d MB", newMemory)
|
||||||
if s.state.GuestMemoryHotplugProbe && updatedMemoryDevice.addr != 0 {
|
if s.state.GuestMemoryHotplugProbe && updatedMemoryDevice.Addr != 0 {
|
||||||
// notify the guest kernel about memory hot-add event, before onlining them
|
// notify the guest kernel about memory hot-add event, before onlining them
|
||||||
s.Logger().Debugf("notify guest kernel memory hot-add event via probe interface, memory device located at 0x%x", updatedMemoryDevice.addr)
|
s.Logger().Debugf("notify guest kernel memory hot-add event via probe interface, memory device located at 0x%x", updatedMemoryDevice.Addr)
|
||||||
if err := s.agent.memHotplugByProbe(ctx, updatedMemoryDevice.addr, uint32(updatedMemoryDevice.sizeMB), s.state.GuestMemoryBlockSizeMB); err != nil {
|
if err := s.agent.memHotplugByProbe(ctx, updatedMemoryDevice.Addr, uint32(updatedMemoryDevice.SizeMB), s.state.GuestMemoryBlockSizeMB); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ func (endpoint *TapEndpoint) HotAttach(ctx context.Context, h hypervisor) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := h.hotplugAddDevice(ctx, endpoint, netDev); err != nil {
|
if _, err := h.hotplugAddDevice(ctx, endpoint, NetDev); err != nil {
|
||||||
networkLogger().WithError(err).Error("Error attach tap ep")
|
networkLogger().WithError(err).Error("Error attach tap ep")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ func (endpoint *TapEndpoint) HotDetach(ctx context.Context, h hypervisor, netNsC
|
|||||||
networkLogger().WithError(err).Warn("Error un-bridging tap ep")
|
networkLogger().WithError(err).Warn("Error un-bridging tap ep")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := h.hotplugRemoveDevice(ctx, endpoint, netDev); err != nil {
|
if _, err := h.hotplugRemoveDevice(ctx, endpoint, NetDev); err != nil {
|
||||||
networkLogger().WithError(err).Error("Error detach tap ep")
|
networkLogger().WithError(err).Error("Error detach tap ep")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ func (endpoint *TuntapEndpoint) Attach(ctx context.Context, s *Sandbox) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.addDevice(ctx, endpoint, netDev)
|
return h.addDevice(ctx, endpoint, NetDev)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detach for the tun/tap endpoint tears down the tap
|
// Detach for the tun/tap endpoint tears down the tap
|
||||||
@ -112,7 +112,7 @@ func (endpoint *TuntapEndpoint) HotAttach(ctx context.Context, h hypervisor) err
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := h.hotplugAddDevice(ctx, endpoint, netDev); err != nil {
|
if _, err := h.hotplugAddDevice(ctx, endpoint, NetDev); err != nil {
|
||||||
networkLogger().WithError(err).Error("Error attach tun/tap ep")
|
networkLogger().WithError(err).Error("Error attach tun/tap ep")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -132,7 +132,7 @@ func (endpoint *TuntapEndpoint) HotDetach(ctx context.Context, h hypervisor, net
|
|||||||
networkLogger().WithError(err).Warn("Error un-bridging tun/tap ep")
|
networkLogger().WithError(err).Warn("Error un-bridging tun/tap ep")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := h.hotplugRemoveDevice(ctx, endpoint, netDev); err != nil {
|
if _, err := h.hotplugRemoveDevice(ctx, endpoint, NetDev); err != nil {
|
||||||
networkLogger().WithError(err).Error("Error detach tun/tap ep")
|
networkLogger().WithError(err).Error("Error detach tun/tap ep")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ func (endpoint *VethEndpoint) Attach(ctx context.Context, s *Sandbox) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.addDevice(ctx, endpoint, netDev)
|
return h.addDevice(ctx, endpoint, NetDev)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detach for the veth endpoint tears down the tap and bridge
|
// Detach for the veth endpoint tears down the tap and bridge
|
||||||
@ -133,7 +133,7 @@ func (endpoint *VethEndpoint) HotAttach(ctx context.Context, h hypervisor) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := h.hotplugAddDevice(ctx, endpoint, netDev); err != nil {
|
if _, err := h.hotplugAddDevice(ctx, endpoint, NetDev); err != nil {
|
||||||
networkLogger().WithError(err).Error("Error attach virtual ep")
|
networkLogger().WithError(err).Error("Error attach virtual ep")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ func (endpoint *VethEndpoint) HotDetach(ctx context.Context, h hypervisor, netNs
|
|||||||
networkLogger().WithError(err).Warn("Error un-bridging virtual ep")
|
networkLogger().WithError(err).Warn("Error un-bridging virtual ep")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := h.hotplugRemoveDevice(ctx, endpoint, netDev); err != nil {
|
if _, err := h.hotplugRemoveDevice(ctx, endpoint, NetDev); err != nil {
|
||||||
networkLogger().WithError(err).Error("Error detach virtual ep")
|
networkLogger().WithError(err).Error("Error detach virtual ep")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func (endpoint *VhostUserEndpoint) Attach(ctx context.Context, s *Sandbox) error
|
|||||||
Type: config.VhostUserNet,
|
Type: config.VhostUserNet,
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.hypervisor.addDevice(ctx, d, vhostuserDev)
|
return s.hypervisor.addDevice(ctx, d, VhostuserDev)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detach for vhostuser endpoint
|
// Detach for vhostuser endpoint
|
||||||
|
@ -44,7 +44,7 @@ type VMConfig struct {
|
|||||||
|
|
||||||
// Valid check VMConfig validity.
|
// Valid check VMConfig validity.
|
||||||
func (c *VMConfig) Valid() error {
|
func (c *VMConfig) Valid() error {
|
||||||
return c.HypervisorConfig.valid()
|
return c.HypervisorConfig.Valid()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToGrpc convert VMConfig struct to grpc format pb.GrpcVMConfig.
|
// ToGrpc convert VMConfig struct to grpc format pb.GrpcVMConfig.
|
||||||
@ -262,7 +262,7 @@ func (v *VM) Stop(ctx context.Context) error {
|
|||||||
func (v *VM) AddCPUs(ctx context.Context, num uint32) error {
|
func (v *VM) AddCPUs(ctx context.Context, num uint32) error {
|
||||||
if num > 0 {
|
if num > 0 {
|
||||||
v.logger().Infof("hot adding %d vCPUs", num)
|
v.logger().Infof("hot adding %d vCPUs", num)
|
||||||
if _, err := v.hypervisor.hotplugAddDevice(ctx, num, cpuDev); err != nil {
|
if _, err := v.hypervisor.hotplugAddDevice(ctx, num, CpuDev); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.cpuDelta += num
|
v.cpuDelta += num
|
||||||
@ -276,8 +276,8 @@ func (v *VM) AddCPUs(ctx context.Context, num uint32) error {
|
|||||||
func (v *VM) AddMemory(ctx context.Context, numMB uint32) error {
|
func (v *VM) AddMemory(ctx context.Context, numMB uint32) error {
|
||||||
if numMB > 0 {
|
if numMB > 0 {
|
||||||
v.logger().Infof("hot adding %d MB memory", numMB)
|
v.logger().Infof("hot adding %d MB memory", numMB)
|
||||||
dev := &memoryDevice{1, int(numMB), 0, false}
|
dev := &MemoryDevice{1, int(numMB), 0, false}
|
||||||
if _, err := v.hypervisor.hotplugAddDevice(ctx, dev, memoryDev); err != nil {
|
if _, err := v.hypervisor.hotplugAddDevice(ctx, dev, MemoryDev); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -381,7 +381,7 @@ func (v *VM) ToGrpc(ctx context.Context, config VMConfig) (*pb.GrpcVM, error) {
|
|||||||
|
|
||||||
func (v *VM) GetVMStatus() *pb.GrpcVMStatus {
|
func (v *VM) GetVMStatus() *pb.GrpcVMStatus {
|
||||||
return &pb.GrpcVMStatus{
|
return &pb.GrpcVMStatus{
|
||||||
Pid: int64(getHypervisorPid(v.hypervisor)),
|
Pid: int64(GetHypervisorPid(v.hypervisor)),
|
||||||
Cpu: v.cpu,
|
Cpu: v.cpu,
|
||||||
Memory: v.memory,
|
Memory: v.memory,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user