From 901bd69e05f88c0633c27b772c791bc5a81e764a Mon Sep 17 00:00:00 2001 From: lstocchi Date: Mon, 27 Oct 2025 23:56:39 +0100 Subject: [PATCH] remove legacy registry entry if users have legacy VMs (podman machines having hvsock registry entries with the machineName field) when using podman with this patch, their Registry entries will never be deleted by the functions added in previous commits. This commit adds a helper func to clean the Registry when these legacy machines get removed Signed-off-by: lstocchi --- pkg/machine/hyperv/stubber.go | 61 +++++++++++++++++++++++++++++-- pkg/machine/hyperv/vsock/vsock.go | 14 +++++-- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/pkg/machine/hyperv/stubber.go b/pkg/machine/hyperv/stubber.go index 5d17e19d2f..245860127d 100644 --- a/pkg/machine/hyperv/stubber.go +++ b/pkg/machine/hyperv/stubber.go @@ -177,7 +177,7 @@ func (h HyperVStubber) Remove(mc *vmconfigs.MachineConfig) ([]string, func() err // // This is to prevent a non-admin user from deleting the last machine // which would require removal of vsock entries from the Windows Registry. - if err := h.canRemove(); err != nil { + if err := h.canRemove(mc); err != nil { return nil, nil, err } @@ -200,8 +200,12 @@ func (h HyperVStubber) Remove(mc *vmconfigs.MachineConfig) ([]string, func() err } // remove vsock registry entries - if err := h.removeHvSockFromRegistry(); err != nil { - logrus.Errorf("unable to remove hvsock registry entries: %q", err) + if isLegacyMachine(mc) { + removeLegacyHvSockEntries(mc) + } else { + if err := h.removeHvSockFromRegistry(); err != nil { + logrus.Errorf("unable to remove hvsock registry entries: %q", err) + } } return nil @@ -232,11 +236,21 @@ func (h HyperVStubber) canCreate() error { return ErrHypervUserNotInAdminGroup } -func (h HyperVStubber) canRemove() error { +func isLegacyMachine(mc *vmconfigs.MachineConfig) bool { + return mc.HyperVHypervisor != nil && mc.HyperVHypervisor.ReadyVsock.MachineName != "" +} + +func (h HyperVStubber) canRemove(mc *vmconfigs.MachineConfig) error { // if admin, can always remove if windows.HasAdminRights() { return nil } + + // if machine is legacy (machineName field), require admin rights to remove + if isLegacyMachine(mc) { + return ErrHypervRegistryRemoveRequiresElevation + } + // not admin, check if there are multiple machines // if so, user could remove the machine just by being member of the hyperv admin group // (only the last machine removal requires Registry changes) @@ -270,6 +284,45 @@ func (h HyperVStubber) countMachinesWithToolname() (int, error) { return count, nil } +// removeLegacyHvSockEntries removes any legacy HVSOCK registry entries associated with the machine. +// This is used to clean up entries from older versions of Podman that did not manage the Toolname field. +func removeLegacyHvSockEntries(mc *vmconfigs.MachineConfig) { + if mc.HyperVHypervisor.NetworkVSock.MachineName != "" { + // Remove the HVSOCK for networking + if err := mc.HyperVHypervisor.NetworkVSock.Remove(); err != nil { + logrus.Errorf("unable to remove registry entry for %s: %q", mc.HyperVHypervisor.NetworkVSock.KeyName, err) + } + } + + if mc.HyperVHypervisor.ReadyVsock.MachineName != "" { + // Remove the HVSOCK for events + if err := mc.HyperVHypervisor.ReadyVsock.Remove(); err != nil { + logrus.Errorf("unable to remove registry entry for %s: %q", mc.HyperVHypervisor.ReadyVsock.KeyName, err) + } + } + + for _, mount := range mc.Mounts { + if mount.VSockNumber == nil { + // nothing to do if the vsock number was never defined + continue + } + + vsockReg, err := vsock.LoadHVSockRegistryEntry(*mount.VSockNumber) + if err != nil { + logrus.Debugf("Vsock %d for mountpoint %s does not have a valid registry entry, skipping removal", *mount.VSockNumber, mount.Target) + continue + } + + if vsockReg.MachineName == "" { + continue + } + + if err := vsockReg.Remove(); err != nil { + logrus.Debugf("unable to remove vsock %d for mountpoint %s: %v", *mount.VSockNumber, mount.Target, err) + } + } +} + func (h HyperVStubber) removeHvSockFromRegistry() error { // Remove hvsock registry entries only if this is the last machine machines, err := h.countMachinesWithToolname() diff --git a/pkg/machine/hyperv/vsock/vsock.go b/pkg/machine/hyperv/vsock/vsock.go index 0be6ca2df5..9c79f60ff7 100644 --- a/pkg/machine/hyperv/vsock/vsock.go +++ b/pkg/machine/hyperv/vsock/vsock.go @@ -244,11 +244,17 @@ func LoadHVSockRegistryEntry(port uint64) (*HVSockRegistryEntry, error) { return nil, err } + m, _, err := k.GetStringValue(HvsockMachineName) + if err != nil { + return nil, err + } + return &HVSockRegistryEntry{ - KeyName: keyName, - Purpose: purpose, - Port: port, - Key: k, + KeyName: keyName, + Purpose: purpose, + Port: port, + Key: k, + MachineName: m, }, nil }