@@ -65,28 +65,48 @@ func (m *Manager) AddToVM(ctx context.Context, opts *AddOptions) (err error) {
6565 m .mu .Lock ()
6666 defer m .mu .Unlock ()
6767
68- // Check for an existing assignment with the same device key.
69- if existingGUID , ok := m .keyToGUID [key ]; ok {
70- dev := m .devices [existingGUID ]
68+ // Check if the caller-provided GUID is already tracked.
69+ if existingDev , ok := m .devices [opts .VMBusGUID ]; ok {
70+ // The GUID exists — verify the device settings match what was originally assigned.
71+ // A mismatch means the caller is trying to reuse a GUID for a different device,
72+ // which is a configuration error.
73+ if existingDev .key != key {
74+ return fmt .Errorf (
75+ "vmBusGUID %s is already assigned to device (instanceID=%s, vfIndex=%d), but caller provided different settings (instanceID=%s, vfIndex=%d)" ,
76+ opts .VMBusGUID ,
77+ existingDev .key .deviceInstanceID , existingDev .key .virtualFunctionIndex ,
78+ key .deviceInstanceID , key .virtualFunctionIndex ,
79+ )
80+ }
7181
72- // If a previous assignment left the device in an invalid state
82+ // If a previous assignment left the device in an invalid state,
7383 // reject new callers until the existing assignment is cleaned up.
74- if dev .invalid {
75- return fmt .Errorf ("vpci device with vmBusGUID %s is in an invalid state" , existingGUID )
84+ if existingDev .invalid {
85+ return fmt .Errorf ("vpci device with vmBusGUID %s is in an invalid state" , opts . VMBusGUID )
7686 }
7787
78- // Increase the refCount and return the existing device .
79- dev .refCount ++
88+ // Same GUID, same device — reuse the existing assignment .
89+ existingDev .refCount ++
8090
8191 log .G (ctx ).WithFields (logrus.Fields {
8292 "deviceInstanceID" : key .deviceInstanceID ,
8393 "virtualFunctionIndex" : key .virtualFunctionIndex ,
84- "refCount" : dev .refCount ,
94+ "refCount" : existingDev .refCount ,
8595 }).Debug ("vPCI device already assigned, reusing existing assignment" )
8696
8797 return nil
8898 }
8999
100+ // The GUID is new — check whether the same device key is already assigned
101+ // under a different GUID. This means the caller provided an inconsistent GUID.
102+ if existingGUID , ok := m .keyToGUID [key ]; ok {
103+ return fmt .Errorf (
104+ "vpci device (instanceID=%s, vfIndex=%d) is already assigned with vmBusGUID %s, but caller provided %s" ,
105+ key .deviceInstanceID , key .virtualFunctionIndex ,
106+ existingGUID , opts .VMBusGUID ,
107+ )
108+ }
109+
90110 // Device not attached to VM.
91111 // Build the VirtualPciDevice settings for HCS call.
92112
@@ -125,7 +145,7 @@ func (m *Manager) AddToVM(ctx context.Context, opts *AddOptions) (err error) {
125145 m .keyToGUID [key ] = opts .VMBusGUID
126146
127147 // Guest-side: device attach notification.
128- if err := m .addGuestVPCIDevice (ctx , opts .VMBusGUID ); err != nil {
148+ if err := m .waitGuestDeviceReady (ctx , opts .VMBusGUID ); err != nil {
129149 // Mark the device as invalid so the caller can call RemoveFromVM
130150 // to clean up the host-side assignment.
131151 dev .invalid = true
0 commit comments