@@ -11,16 +11,23 @@ import (
1111
1212// QEMU implements hypervisor.Hypervisor for QEMU VMM.
1313type QEMU struct {
14- client * Client
14+ client * Client
15+ socketPath string // for self-removal from pool on error
1516}
1617
17- // New creates a new QEMU client for an existing QMP socket.
18+ // New returns a QEMU client for the given socket path.
19+ // Uses a connection pool to ensure only one connection per socket exists.
1820func New (socketPath string ) (* QEMU , error ) {
21+ return GetOrCreate (socketPath )
22+ }
23+
24+ // newClient creates a new QEMU client (internal, used by pool).
25+ func newClient (socketPath string ) (* QEMU , error ) {
1926 client , err := NewClient (socketPath )
2027 if err != nil {
2128 return nil , fmt .Errorf ("create qemu client: %w" , err )
2229 }
23- return & QEMU {client : client }, nil
30+ return & QEMU {client : client , socketPath : socketPath }, nil
2431}
2532
2633// Verify QEMU implements the interface
@@ -40,18 +47,29 @@ func (q *QEMU) Capabilities() hypervisor.Capabilities {
4047// DeleteVM removes the VM configuration from QEMU.
4148// This sends a graceful shutdown signal to the guest.
4249func (q * QEMU ) DeleteVM (ctx context.Context ) error {
43- return q .client .SystemPowerdown ()
50+ if err := q .client .SystemPowerdown (); err != nil {
51+ Remove (q .socketPath )
52+ return err
53+ }
54+ return nil
4455}
4556
4657// Shutdown stops the QEMU process.
4758func (q * QEMU ) Shutdown (ctx context.Context ) error {
48- return q .client .Quit ()
59+ if err := q .client .Quit (); err != nil {
60+ Remove (q .socketPath )
61+ return err
62+ }
63+ // Connection is gone after quit, remove from pool
64+ Remove (q .socketPath )
65+ return nil
4966}
5067
5168// GetVMInfo returns current VM state.
5269func (q * QEMU ) GetVMInfo (ctx context.Context ) (* hypervisor.VMInfo , error ) {
5370 status , err := q .client .Status ()
5471 if err != nil {
72+ Remove (q .socketPath )
5573 return nil , fmt .Errorf ("query status: %w" , err )
5674 }
5775
@@ -85,12 +103,20 @@ func (q *QEMU) GetVMInfo(ctx context.Context) (*hypervisor.VMInfo, error) {
85103
86104// Pause suspends VM execution.
87105func (q * QEMU ) Pause (ctx context.Context ) error {
88- return q .client .Stop ()
106+ if err := q .client .Stop (); err != nil {
107+ Remove (q .socketPath )
108+ return err
109+ }
110+ return nil
89111}
90112
91113// Resume continues VM execution.
92114func (q * QEMU ) Resume (ctx context.Context ) error {
93- return q .client .Continue ()
115+ if err := q .client .Continue (); err != nil {
116+ Remove (q .socketPath )
117+ return err
118+ }
119+ return nil
94120}
95121
96122// Snapshot creates a VM snapshot.
0 commit comments