@@ -177,7 +177,7 @@ func (h HyperVStubber) Remove(mc *vmconfigs.MachineConfig) ([]string, func() err
177177 //
178178 // This is to prevent a non-admin user from deleting the last machine
179179 // which would require removal of vsock entries from the Windows Registry.
180- if err := h .canRemove (); err != nil {
180+ if err := h .canRemove (mc ); err != nil {
181181 return nil , nil , err
182182 }
183183
@@ -200,8 +200,12 @@ func (h HyperVStubber) Remove(mc *vmconfigs.MachineConfig) ([]string, func() err
200200 }
201201
202202 // remove vsock registry entries
203- if err := h .removeHvSockFromRegistry (); err != nil {
204- logrus .Errorf ("unable to remove hvsock registry entries: %q" , err )
203+ if isLegacyMachine (mc ) {
204+ removeLegacyHvSockEntries (mc )
205+ } else {
206+ if err := h .removeHvSockFromRegistry (); err != nil {
207+ logrus .Errorf ("unable to remove hvsock registry entries: %q" , err )
208+ }
205209 }
206210
207211 return nil
@@ -232,11 +236,21 @@ func (h HyperVStubber) canCreate() error {
232236 return ErrHypervUserNotInAdminGroup
233237}
234238
235- func (h HyperVStubber ) canRemove () error {
239+ func isLegacyMachine (mc * vmconfigs.MachineConfig ) bool {
240+ return mc .HyperVHypervisor != nil && mc .HyperVHypervisor .ReadyVsock .MachineName != ""
241+ }
242+
243+ func (h HyperVStubber ) canRemove (mc * vmconfigs.MachineConfig ) error {
236244 // if admin, can always remove
237245 if windows .HasAdminRights () {
238246 return nil
239247 }
248+
249+ // if machine is legacy (machineName field), require admin rights to remove
250+ if isLegacyMachine (mc ) {
251+ return ErrHypervRegistryRemoveRequiresElevation
252+ }
253+
240254 // not admin, check if there are multiple machines
241255 // if so, user could remove the machine just by being member of the hyperv admin group
242256 // (only the last machine removal requires Registry changes)
@@ -270,6 +284,45 @@ func (h HyperVStubber) countMachinesWithToolname() (int, error) {
270284 return count , nil
271285}
272286
287+ // removeLegacyHvSockEntries removes any legacy HVSOCK registry entries associated with the machine.
288+ // This is used to clean up entries from older versions of Podman that did not manage the Toolname field.
289+ func removeLegacyHvSockEntries (mc * vmconfigs.MachineConfig ) {
290+ if mc .HyperVHypervisor .NetworkVSock .MachineName != "" {
291+ // Remove the HVSOCK for networking
292+ if err := mc .HyperVHypervisor .NetworkVSock .Remove (); err != nil {
293+ logrus .Errorf ("unable to remove registry entry for %s: %q" , mc .HyperVHypervisor .NetworkVSock .KeyName , err )
294+ }
295+ }
296+
297+ if mc .HyperVHypervisor .ReadyVsock .MachineName != "" {
298+ // Remove the HVSOCK for events
299+ if err := mc .HyperVHypervisor .ReadyVsock .Remove (); err != nil {
300+ logrus .Errorf ("unable to remove registry entry for %s: %q" , mc .HyperVHypervisor .ReadyVsock .KeyName , err )
301+ }
302+ }
303+
304+ for _ , mount := range mc .Mounts {
305+ if mount .VSockNumber == nil {
306+ // nothing to do if the vsock number was never defined
307+ continue
308+ }
309+
310+ vsockReg , err := vsock .LoadHVSockRegistryEntry (* mount .VSockNumber )
311+ if err != nil {
312+ logrus .Debugf ("Vsock %d for mountpoint %s does not have a valid registry entry, skipping removal" , * mount .VSockNumber , mount .Target )
313+ continue
314+ }
315+
316+ if vsockReg .MachineName == "" {
317+ continue
318+ }
319+
320+ if err := vsockReg .Remove (); err != nil {
321+ logrus .Debugf ("unable to remove vsock %d for mountpoint %s: %v" , * mount .VSockNumber , mount .Target , err )
322+ }
323+ }
324+ }
325+
273326func (h HyperVStubber ) removeHvSockFromRegistry () error {
274327 // Remove hvsock registry entries only if this is the last machine
275328 machines , err := h .countMachinesWithToolname ()
0 commit comments