The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/7965

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Allows you to shrink memory and then increase it back to boot time size without reboot VM.
From 124aad5233ee89720edd6c137500d8c81a300508 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 1 Oct 2020 12:25:37 +0100
Subject: [PATCH 1/5] lxd/instance/drivers/qmp/monitor: Renames
 GetMemoryBalloonSizeBytes

And makes comments more accurate.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/drivers/qmp/monitor.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/instance/drivers/qmp/monitor.go 
b/lxd/instance/drivers/qmp/monitor.go
index 11c011da38..9d5eb789ff 100644
--- a/lxd/instance/drivers/qmp/monitor.go
+++ b/lxd/instance/drivers/qmp/monitor.go
@@ -323,8 +323,8 @@ func (m *Monitor) GetCPUs() ([]int, error) {
        return pids, nil
 }
 
-// GetBalloonSizeBytes returns the current size of the memory balloon in bytes.
-func (m *Monitor) GetBalloonSizeBytes() (int64, error) {
+// GetMemoryBalloonSizeBytes returns effective size of the memory in bytes 
(considering the current balloon size).
+func (m *Monitor) GetMemoryBalloonSizeBytes() (int64, error) {
        respRaw, err := m.qmp.Run([]byte("{'execute': 'query-balloon'}"))
        if err != nil {
                m.Disconnect()

From 6f9663cc9d33bd27376c28155830eca3707b3072 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 1 Oct 2020 12:26:00 +0100
Subject: [PATCH 2/5] lxd/instance/drivers/qmp/monitor: Renames
 SetMemoryBalloonSizeBytes

And makes comments more accurate.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/drivers/qmp/monitor.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/instance/drivers/qmp/monitor.go 
b/lxd/instance/drivers/qmp/monitor.go
index 9d5eb789ff..da917d78af 100644
--- a/lxd/instance/drivers/qmp/monitor.go
+++ b/lxd/instance/drivers/qmp/monitor.go
@@ -346,8 +346,8 @@ func (m *Monitor) GetMemoryBalloonSizeBytes() (int64, 
error) {
        return respDecoded.Return.Actual, nil
 }
 
-// SetBalloonSizeBytes sets the size of the memory balloon in bytes.
-func (m *Monitor) SetBalloonSizeBytes(sizeBytes int64) error {
+// SetMemoryBalloonSizeBytes sets the size of the memory in bytes (which will 
resize the balloon as needed).
+func (m *Monitor) SetMemoryBalloonSizeBytes(sizeBytes int64) error {
        respRaw, err := m.qmp.Run([]byte(fmt.Sprintf("{'execute': 'balloon', 
'arguments': {'value': %d}}", sizeBytes)))
        if err != nil {
                m.Disconnect()

From 6ced837edcae82aee518f31af32c13fd06d36d88 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 1 Oct 2020 12:26:24 +0100
Subject: [PATCH 3/5] lxd/instance/drivers/qmp/monitor: Adds GetMemorySizeBytes
 function

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/drivers/qmp/monitor.go | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/lxd/instance/drivers/qmp/monitor.go 
b/lxd/instance/drivers/qmp/monitor.go
index da917d78af..e02bc96590 100644
--- a/lxd/instance/drivers/qmp/monitor.go
+++ b/lxd/instance/drivers/qmp/monitor.go
@@ -323,6 +323,29 @@ func (m *Monitor) GetCPUs() ([]int, error) {
        return pids, nil
 }
 
+// GetMemorySizeBytes returns the current size of the base memory in bytes.
+func (m *Monitor) GetMemorySizeBytes() (int64, error) {
+       respRaw, err := m.qmp.Run([]byte("{'execute': 
'query-memory-size-summary'}"))
+       if err != nil {
+               m.Disconnect()
+               return -1, ErrMonitorDisconnect
+       }
+
+       // Process the response.
+       var respDecoded struct {
+               Return struct {
+                       BaseMemory int64 `json:"base-memory"`
+               } `json:"return"`
+       }
+
+       err = json.Unmarshal(respRaw, &respDecoded)
+       if err != nil {
+               return -1, ErrMonitorBadReturn
+       }
+
+       return respDecoded.Return.BaseMemory, nil
+}
+
 // GetMemoryBalloonSizeBytes returns effective size of the memory in bytes 
(considering the current balloon size).
 func (m *Monitor) GetMemoryBalloonSizeBytes() (int64, error) {
        respRaw, err := m.qmp.Run([]byte("{'execute': 'query-balloon'}"))

From 6c6cd366eeb1f5e0c3a6106f15975f8de6408f14 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 1 Oct 2020 12:26:49 +0100
Subject: [PATCH 4/5] lxd/instance/drivers/driver/qemu: Adds qemuDefaultMemSize
 constant

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/drivers/driver_qemu.go | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lxd/instance/drivers/driver_qemu.go 
b/lxd/instance/drivers/driver_qemu.go
index 3fed78efcb..af18d1dfe7 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -69,6 +69,9 @@ const qemuUnsafeIO = "unsafeio"
 // qemuSerialChardevName is used to communicate state via qmp between Qemu and 
LXD.
 const qemuSerialChardevName = "qemu_serial-chardev"
 
+// qemuDefaultMemSize is the default memory size for VMs if not limit 
specified.
+const qemuDefaultMemSize = "1GiB"
+
 var errQemuAgentOffline = fmt.Errorf("LXD VM agent isn't currently running")
 
 var vmConsole = map[int]bool{}
@@ -1924,7 +1927,7 @@ func (vm *qemu) addCPUMemoryConfig(sb *strings.Builder) 
error {
        // Configure memory limit.
        memSize := vm.expandedConfig["limits.memory"]
        if memSize == "" {
-               memSize = "1GiB" // Default to 1GiB if no memory limit 
specified.
+               memSize = qemuDefaultMemSize // Default if no memory limit 
specified.
        }
 
        memSizeBytes, err := units.ParseByteSizeString(memSize)

From c71a3f8ec288b9c29eb8908db316614c1d0998ef Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 1 Oct 2020 12:27:24 +0100
Subject: [PATCH 5/5] lxd/instance/drivers/driver/qemu: Updates
 updateMemoryLimit to allow memory resize back to boot time size

 - Fixes bug where unsetting limits.memory didn't try and resize memory back to 
default size.
 - Allows live memory growth back to original boot time size.
 - Makes comments more accurate base on qemu's actual balloon size commands.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/drivers/driver_qemu.go | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/lxd/instance/drivers/driver_qemu.go 
b/lxd/instance/drivers/driver_qemu.go
index af18d1dfe7..547e5fb088 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -2975,9 +2975,12 @@ func (vm *qemu) Update(args db.InstanceArgs, 
userRequested bool) error {
        return nil
 }
 
-// updateMemoryLimit live updates the VM's memory limit by shrinking the 
balloon device.
-// Only memory shrinking is supported at this time.
+// updateMemoryLimit live updates the VM's memory limit by reszing the balloon 
device.
 func (vm *qemu) updateMemoryLimit(newLimit string) error {
+       if newLimit == "" {
+               newLimit = qemuDefaultMemSize
+       }
+
        if shared.IsTrue(vm.expandedConfig["limits.memory.hugepages"]) {
                return fmt.Errorf("Cannot live update memory limit when using 
huge pages")
        }
@@ -2994,27 +2997,32 @@ func (vm *qemu) updateMemoryLimit(newLimit string) 
error {
                return err // The VM isn't running as no monitor socket 
available.
        }
 
-       curSizeBytes, err := monitor.GetBalloonSizeBytes()
+       baseSizeBytes, err := monitor.GetMemorySizeBytes()
+       if err != nil {
+               return err
+       }
+
+       curSizeBytes, err := monitor.GetMemoryBalloonSizeBytes()
        if err != nil {
                return err
        }
 
        if curSizeBytes == newSizeBytes {
                return nil
-       } else if curSizeBytes < newSizeBytes {
-               return fmt.Errorf("Cannot increase memory size when VM is 
running")
+       } else if baseSizeBytes < newSizeBytes {
+               return fmt.Errorf("Cannot increase memory size beyond boot time 
size when VM is running")
        }
 
-       // Shrink balloon device.
-       err = monitor.SetBalloonSizeBytes(newSizeBytes)
+       // Set effective memory size.
+       err = monitor.SetMemoryBalloonSizeBytes(newSizeBytes)
        if err != nil {
                return err
        }
 
-       // Shrinking the balloon can take time, so poll the actual balloon size 
to check it has shrunk within 1%
+       // Changing the memory balloon can take time, so poll the effectice 
size to check it has shrunk within 1%
        // of the target size, which we then take as success (it may still 
continue to shrink closer to target).
        for i := 0; i < 5; i++ {
-               curSizeBytes, err = monitor.GetBalloonSizeBytes()
+               curSizeBytes, err = monitor.GetMemoryBalloonSizeBytes()
                if err != nil {
                        return err
                }
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to