@@ -5,15 +5,15 @@ package cloudhypervisor
55import (
66 "context"
77 "fmt"
8+ "time"
89
910 "github.com/onkernel/hypeman/lib/hypervisor"
1011 "github.com/onkernel/hypeman/lib/vmm"
1112)
1213
1314// CloudHypervisor implements hypervisor.Hypervisor for Cloud Hypervisor VMM.
1415type CloudHypervisor struct {
15- client * vmm.VMM
16- socketPath string
16+ client * vmm.VMM
1717}
1818
1919// New creates a new Cloud Hypervisor client for an existing VMM socket.
@@ -23,8 +23,7 @@ func New(socketPath string) (*CloudHypervisor, error) {
2323 return nil , fmt .Errorf ("create vmm client: %w" , err )
2424 }
2525 return & CloudHypervisor {
26- client : client ,
27- socketPath : socketPath ,
26+ client : client ,
2827 }, nil
2928}
3029
@@ -114,7 +113,10 @@ func (c *CloudHypervisor) GetVMInfo(ctx context.Context) (*hypervisor.VMInfo, er
114113 return nil , fmt .Errorf ("unknown vm state: %s" , resp .JSON200 .State )
115114 }
116115
117- return & hypervisor.VMInfo {State : state }, nil
116+ return & hypervisor.VMInfo {
117+ State : state ,
118+ MemoryActualSize : resp .JSON200 .MemoryActualSize ,
119+ }, nil
118120}
119121
120122// Pause suspends VM execution.
@@ -185,6 +187,59 @@ func (c *CloudHypervisor) ResizeMemory(ctx context.Context, bytes int64) error {
185187 return nil
186188}
187189
190+ // ResizeMemoryAndWait changes the VM's memory allocation and waits for it to stabilize.
191+ // It polls until the actual memory size stabilizes (stops changing) or timeout is reached.
192+ func (c * CloudHypervisor ) ResizeMemoryAndWait (ctx context.Context , bytes int64 , timeout time.Duration ) error {
193+ // First, request the resize
194+ if err := c .ResizeMemory (ctx , bytes ); err != nil {
195+ return err
196+ }
197+
198+ // Poll until memory stabilizes
199+ const pollInterval = 20 * time .Millisecond
200+ deadline := time .Now ().Add (timeout )
201+
202+ var lastSize int64 = - 1
203+ stableCount := 0
204+ const requiredStableChecks = 3 // Require 3 consecutive stable readings
205+
206+ for time .Now ().Before (deadline ) {
207+ select {
208+ case <- ctx .Done ():
209+ return ctx .Err ()
210+ default :
211+ }
212+
213+ info , err := c .GetVMInfo (ctx )
214+ if err != nil {
215+ return fmt .Errorf ("poll memory size: %w" , err )
216+ }
217+
218+ if info .MemoryActualSize == nil {
219+ // No memory info available, just return after resize
220+ return nil
221+ }
222+
223+ currentSize := * info .MemoryActualSize
224+
225+ if currentSize == lastSize {
226+ stableCount ++
227+ if stableCount >= requiredStableChecks {
228+ // Memory has stabilized
229+ return nil
230+ }
231+ } else {
232+ stableCount = 0
233+ lastSize = currentSize
234+ }
235+
236+ time .Sleep (pollInterval )
237+ }
238+
239+ // Timeout reached, but resize was requested successfully
240+ return nil
241+ }
242+
188243func ptr [T any ](v T ) * T {
189244 return & v
190245}
0 commit comments