Skip to content

Commit

Permalink
Avoid searching on locale sensitive properties
Browse files Browse the repository at this point in the history
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 <jason.greene@redhat.com>
n1hility committed Nov 7, 2023
1 parent 9651e31 commit 95b663b
Showing 1 changed file with 32 additions and 12 deletions.
44 changes: 32 additions & 12 deletions pkg/hypervctl/vmm.go
Original file line number Diff line number Diff line change
@@ -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 {

0 comments on commit 95b663b

Please sign in to comment.