55 "os"
66 "os/signal"
77 "strconv"
8+ "sync"
89 "syscall"
910
1011 "github.com/NexusGPU/gpu-go/internal/agent"
2627 acceleratorLib string
2728 isolationMode string
2829 paths = platform .DefaultPaths ()
30+
31+ // Hypervisor singleton
32+ hypervisorOnce sync.Once
33+ hypervisorManager * hypervisor.Manager
34+ hypervisorErr error
2935)
3036
3137// NewAgentCmd creates the agent command
@@ -65,6 +71,45 @@ func getIsolationMode() tfv1.IsolationModeType {
6571 }
6672}
6773
74+ // getHypervisorManager returns the singleton hypervisor manager, initializing it if needed
75+ func getHypervisorManager () (* hypervisor.Manager , error ) {
76+ hypervisorOnce .Do (func () {
77+ if os .Getenv ("GPU_GO_MOCK_GPUS" ) != "" {
78+ hypervisorErr = fmt .Errorf ("mock mode enabled, hypervisor not available" )
79+ return
80+ }
81+
82+ libPath := acceleratorLib
83+ if libPath == "" {
84+ libPath = agent .FindAcceleratorLibrary ()
85+ }
86+ if libPath == "" {
87+ hypervisorErr = fmt .Errorf ("accelerator library not found" )
88+ return
89+ }
90+
91+ hypervisorManager , hypervisorErr = hypervisor .NewManager (hypervisor.Config {
92+ LibPath : libPath ,
93+ Vendor : agent .DetectVendorFromLibPath (libPath ),
94+ IsolationMode : getIsolationMode (),
95+ Logger : log .Logger ,
96+ StateDir : stateDir ,
97+ })
98+ if hypervisorErr != nil {
99+ return
100+ }
101+ hypervisorErr = hypervisorManager .Start ()
102+ })
103+ return hypervisorManager , hypervisorErr
104+ }
105+
106+ // stopHypervisorManager stops the singleton hypervisor manager if running
107+ func stopHypervisorManager () {
108+ if hypervisorManager != nil {
109+ hypervisorManager .Stop ()
110+ }
111+ }
112+
68113func newRegisterCmd () * cobra.Command {
69114 var token string
70115
@@ -151,8 +196,8 @@ func newStartCmd() *cobra.Command {
151196 api .WithAgentSecret (cfg .AgentSecret ),
152197 )
153198
154- // Create hypervisor manager
155- hvMgr , err := createHypervisorManager ()
199+ // Get singleton hypervisor manager
200+ hvMgr , err := getHypervisorManager ()
156201 if err != nil {
157202 // Log warning but continue - agent can work without hypervisor for some operations
158203 log .Warn ().Err (err ).Msg ("Failed to initialize hypervisor manager, worker management will be limited" )
@@ -196,6 +241,7 @@ func newStartCmd() *cobra.Command {
196241 }
197242
198243 agentInstance .Stop ()
244+ stopHypervisorManager ()
199245 return nil
200246 },
201247 }
@@ -329,38 +375,13 @@ func discoverGPUs() []api.GPUInfo {
329375 return agent .CreateMockGPUs (count )
330376 }
331377
332- // Try to discover GPUs using hypervisor
333- libPath := acceleratorLib
334- if libPath == "" {
335- libPath = agent .FindAcceleratorLibrary ()
336- }
337-
338- if libPath == "" {
339- log .Warn ().Msg ("No accelerator library found, set TENSOR_FUSION_LIB_PATH or use --accelerator-lib" )
340- return nil
341- }
342-
343- // Create temporary hypervisor manager for GPU discovery
344- hvMgr , err := hypervisor .NewManager (hypervisor.Config {
345- LibPath : libPath ,
346- Vendor : agent .DetectVendorFromLibPath (libPath ),
347- IsolationMode : getIsolationMode (),
348- Logger : log .Logger ,
349- StateDir : stateDir ,
350- })
378+ // Use singleton hypervisor manager
379+ hvMgr , err := getHypervisorManager ()
351380 if err != nil {
352- log .Error ().Err (err ).Msg ("Failed to create hypervisor manager" )
381+ log .Warn ().Err (err ).Msg ("Failed to get hypervisor manager" )
353382 return nil
354383 }
355384
356- // Start manager to discover devices
357- if err := hvMgr .Start (); err != nil {
358- log .Error ().Err (err ).Msg ("Failed to start hypervisor manager" )
359- return nil
360- }
361- defer hvMgr .Stop ()
362-
363- // Get devices from hypervisor
364385 devices , err := hvMgr .ListDevices ()
365386 if err != nil {
366387 log .Error ().Err (err ).Msg ("Failed to list devices" )
@@ -370,40 +391,6 @@ func discoverGPUs() []api.GPUInfo {
370391 return agent .ConvertDevicesToGPUInfo (devices )
371392}
372393
373- // createHypervisorManager creates a hypervisor manager for the agent
374- func createHypervisorManager () (* hypervisor.Manager , error ) {
375- // Check for mock mode
376- if os .Getenv ("GPU_GO_MOCK_GPUS" ) != "" {
377- return nil , fmt .Errorf ("mock mode enabled, hypervisor not available" )
378- }
379-
380- libPath := acceleratorLib
381- if libPath == "" {
382- libPath = agent .FindAcceleratorLibrary ()
383- }
384-
385- if libPath == "" {
386- return nil , fmt .Errorf ("accelerator library not found" )
387- }
388-
389- hvMgr , err := hypervisor .NewManager (hypervisor.Config {
390- LibPath : libPath ,
391- Vendor : agent .DetectVendorFromLibPath (libPath ),
392- IsolationMode : getIsolationMode (),
393- Logger : log .Logger ,
394- StateDir : stateDir ,
395- })
396- if err != nil {
397- return nil , err
398- }
399-
400- if err := hvMgr .Start (); err != nil {
401- return nil , err
402- }
403-
404- return hvMgr , nil
405- }
406-
407394func boolToYesNo (b bool ) string {
408395 if b {
409396 return "yes"
0 commit comments