From 95b663b361b12128170ec32beff44815e7817533 Mon Sep 17 00:00:00 2001 From: "Jason T. Greene" Date: Tue, 7 Nov 2023 16:29:40 -0600 Subject: [PATCH] Avoid searching on locale sensitive properties On systems that do not have MS_409, the connection and query will fallback to the system default. Since Msvm_ComputerSystem only have locale specific types to identify the machine type (host vs vm), search through settings first to find the associated instance. Signed-off-by: Jason T. Greene --- pkg/hypervctl/vmm.go | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/pkg/hypervctl/vmm.go b/pkg/hypervctl/vmm.go index fee021e..e30f4b0 100644 --- a/pkg/hypervctl/vmm.go +++ b/pkg/hypervctl/vmm.go @@ -12,6 +12,7 @@ import ( const ( HyperVNamespace = "root\\virtualization\\v2" VirtualSystemManagementService = "Msvm_VirtualSystemManagementService" + MsvmComputerSystem = "Msvm_ComputerSystem" ) // https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/msvm-computersystem @@ -24,7 +25,8 @@ func NewVirtualMachineManager() *VirtualMachineManager { } func (vmm *VirtualMachineManager) GetAll() ([]*VirtualMachine, error) { - const wql = "Select * From Msvm_ComputerSystem Where Description = 'Microsoft Virtual Machine'" + // Fetch through settings to avoid locale sensitive properties + const wql = "Select * From Msvm_VirtualSystemSettingData Where VirtualSystemType = 'Microsoft:Hyper-V:System:Realized'" var service *wmiext.Service var err error @@ -38,22 +40,31 @@ func (vmm *VirtualMachineManager) GetAll() ([]*VirtualMachine, error) { return nil, err } defer enum.Close() - var vms []*VirtualMachine + for { - vm := &VirtualMachine{vmm: vmm} - done, err := wmiext.NextObject(enum, vm) + settings, err := enum.Next() if err != nil { return vms, err } - if done { + + // Finished iterating + if settings == nil { break } + + vm, err := vmm.findVMFromSettings(service, settings) + settings.Close() + if err != nil { + return vms, err + } + vms = append(vms, vm) } return vms, nil } + func (vmm *VirtualMachineManager) Exists(name string) (bool, error) { vms, err := vmm.GetAll() if err != nil { @@ -68,8 +79,8 @@ func (vmm *VirtualMachineManager) Exists(name string) (bool, error) { return false, nil } -func (*VirtualMachineManager) GetMachine(name string) (*VirtualMachine, error) { - const wql = "Select * From Msvm_ComputerSystem Where Description = 'Microsoft Virtual Machine' And ElementName='%s'" +func (vmm *VirtualMachineManager) GetMachine(name string) (*VirtualMachine, error) { + const wql = "Select * From Msvm_VirtualSystemSettingData Where VirtualSystemType = 'Microsoft:Hyper-V:System:Realized' And ElementName='%s'" vm := &VirtualMachine{} var service *wmiext.Service @@ -86,16 +97,25 @@ func (*VirtualMachineManager) GetMachine(name string) (*VirtualMachine, error) { } defer enum.Close() - done, err := wmiext.NextObject(enum, vm) + settings, err := service.FindFirstInstance(fmt.Sprintf(wql, name)) if err != nil { - return vm, err + return vm, fmt.Errorf("could not find virtual machine %q: %w", name, err) } + defer settings.Close() + + return vmm.findVMFromSettings(service, settings) +} - if done { - return vm, fmt.Errorf("could not find virtual machine %q", name) +func (vmm *VirtualMachineManager) findVMFromSettings(service *wmiext.Service, settings *wmiext.Instance) (*VirtualMachine, error) { + path, err := settings.Path() + if err != nil { + return nil, err } - return vm, nil + vm := &VirtualMachine{vmm: vmm} + err = service.FindFirstRelatedObject(path, MsvmComputerSystem, vm) + + return vm, err } func (*VirtualMachineManager) CreateVhdxFile(path string, maxSize uint64) error {