Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
memory: update: Update state using the memory removed.
Browse files Browse the repository at this point in the history
If the memory is reduced , its cgroup in the VM was updated properly. But the
runtime assumed that the memory was also removed from the VM.

Then when it is added more memory again, more is added (but not needed).

Fixes: #801

Signed-off-by: Jose Carlos Venegas Munoz <[email protected]>
  • Loading branch information
jcvenegas committed Oct 2, 2018
1 parent 532e0bb commit 4697cf3
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 17 deletions.
35 changes: 30 additions & 5 deletions virtcontainers/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -1301,9 +1301,13 @@ func (c *Container) memHotplugValid(mem uint32) (uint32, error) {
return uint32(math.Ceil(float64(mem)/float64(memorySectionSizeMB))) * memorySectionSizeMB, nil
}

func (c *Container) updateMemoryResources(oldResources, newResources ContainerResources) error {
func (c *Container) updateMemoryResources(oldResources ContainerResources, newResources *ContainerResources) error {
oldMemMB := oldResources.MemMB
newMemMB := newResources.MemMB
c.Logger().WithFields(logrus.Fields{
"old-mem": fmt.Sprintf("%dMB", oldMemMB),
"new-mem": fmt.Sprintf("%dMB", newMemMB),
}).Debug("Request update memory")

if oldMemMB == newMemMB {
c.Logger().WithFields(logrus.Fields{
Expand All @@ -1325,16 +1329,37 @@ func (c *Container) updateMemoryResources(oldResources, newResources ContainerRe
addMemDevice := &memoryDevice{
sizeMB: int(memHotplugMB),
}
_, err = c.sandbox.hypervisor.hotplugAddDevice(addMemDevice, memoryDev)
data, err := c.sandbox.hypervisor.hotplugAddDevice(addMemDevice, memoryDev)
if err != nil {
return err
}
newResources.MemMB = newMemMB
memoryAdded, ok := data.(int)
if !ok {
return fmt.Errorf("Could not get the memory added, got %+v", data)
}
newResources.MemMB = oldMemMB + uint32(memoryAdded)
if err := c.sandbox.agent.onlineCPUMem(0, false); err != nil {
return err
}
}
// hot remove memory unsupported
if oldMemMB > newMemMB {
// Try to remove a memory device with the difference
// from new memory and old memory
removeMem := &memoryDevice{
sizeMB: int(oldMemMB - newMemMB),
}

data, err := c.sandbox.hypervisor.hotplugRemoveDevice(removeMem, memoryDev)
if err != nil {
return err
}
memoryRemoved, ok := data.(int)
if !ok {
return fmt.Errorf("Could not get the memory added, got %+v", data)
}
newResources.MemMB = oldMemMB - uint32(memoryRemoved)
newResources.MemMB = oldResources.MemMB
}
return nil
}

Expand All @@ -1358,7 +1383,7 @@ func (c *Container) updateResources(oldResources, newResources ContainerResource

// Memory is not updated if memory limit not set
if newResources.MemMB != 0 {
if err := c.updateMemoryResources(oldResources, newResources); err != nil {
if err := c.updateMemoryResources(oldResources, &newResources); err != nil {
return err
}

Expand Down
26 changes: 14 additions & 12 deletions virtcontainers/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ package virtcontainers

import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
Expand Down Expand Up @@ -913,7 +912,7 @@ func (q *qemu) hotplugDevice(devInfo interface{}, devType deviceType, op operati
return nil, q.hotplugVFIODevice(device, op)
case memoryDev:
memdev := devInfo.(*memoryDevice)
return nil, q.hotplugMemory(memdev, op)
return q.hotplugMemory(memdev, op)
case netDev:
device := devInfo.(*VirtualEndpoint)
return nil, q.hotplugNetDevice(device, op)
Expand Down Expand Up @@ -1047,38 +1046,41 @@ func (q *qemu) hotplugRemoveCPUs(amount uint32) (uint32, error) {
return amount, q.storage.storeHypervisorState(q.id, q.state)
}

func (q *qemu) hotplugMemory(memDev *memoryDevice, op operation) error {
func (q *qemu) hotplugMemory(memDev *memoryDevice, op operation) (int, error) {
if memDev.sizeMB < 0 {
return fmt.Errorf("cannot hotplug negative size (%d) memory", memDev.sizeMB)
return 0, fmt.Errorf("cannot hotplug negative size (%d) memory", memDev.sizeMB)
}

// We do not support memory hot unplug.
if op == removeDevice {
return errors.New("cannot hot unplug memory device")
// Dont fail for now, until we fix it.
// We return that we only unplugged 0
q.Logger().Warn("hot-remove VM memory not supported")
return 0, nil
}

err := q.qmpSetup()
if err != nil {
return err
return 0, err
}

maxMem, err := q.hostMemMB()
if err != nil {
return err
return 0, err
}

// calculate current memory
currentMemory := int(q.config.MemorySize) + q.state.HotpluggedMemory

// Don't exceed the maximum amount of memory
if currentMemory+memDev.sizeMB > int(maxMem) {
return 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, q.config.MemorySize)
}

memoryDevices, err := q.qmpMonitorCh.qmp.ExecQueryMemoryDevices(q.qmpMonitorCh.ctx)
if err != nil {
return fmt.Errorf("failed to query memory devices: %v", err)
return 0, fmt.Errorf("failed to query memory devices: %v", err)
}

if len(memoryDevices) != 0 {
Expand All @@ -1088,15 +1090,15 @@ func (q *qemu) hotplugMemory(memDev *memoryDevice, op operation) error {
return q.hotplugAddMemory(memDev)
}

func (q *qemu) hotplugAddMemory(memDev *memoryDevice) error {
func (q *qemu) hotplugAddMemory(memDev *memoryDevice) (int, error) {
err := q.qmpMonitorCh.qmp.ExecHotplugMemory(q.qmpMonitorCh.ctx, "memory-backend-ram", "mem"+strconv.Itoa(memDev.slot), "", memDev.sizeMB)
if err != nil {
q.Logger().WithError(err).Error("hotplug memory")
return err
return 0, err
}

q.state.HotpluggedMemory += memDev.sizeMB
return q.storage.storeHypervisorState(q.id, q.state)
return memDev.sizeMB, q.storage.storeHypervisorState(q.id, q.state)
}

func (q *qemu) pauseSandbox() error {
Expand Down

0 comments on commit 4697cf3

Please sign in to comment.