@@ -28,6 +28,14 @@ go_builtin_types = ['bool', 'string', 'int', 'byte',
# after a struct definition.
type_extras = []
+# cgo preamble for xenlight_helpers.go, created during type generation and
+# written later.
+cgo_helpers_preamble = []
+
+# List of strings that need to be written to a file
+# after a helper func definition.
+helper_extras = []
+
def xenlight_golang_generate_types(path = None, types = None, comment = None):
"""
Generate a .go file (xenlight_types.go by default)
@@ -159,6 +167,8 @@ def xenlight_golang_define_union(ty = None, structname = ''):
s = xenlight_golang_define_struct(f.type, typename=name)
type_extras.append(s)
+ xenlight_golang_union_cgo_preamble(f.type, name=name)
+
# Define function to implement 'union' interface
name = xenlight_golang_fmt_name(name)
s = 'func (x {}) is{}(){{}}\n'.format(name, interface_name)
@@ -174,6 +184,18 @@ def xenlight_golang_define_union(ty = None, structname = ''):
return s
+def xenlight_golang_union_cgo_preamble(ty = None, name = ''):
+ s = ''
+
+ s += 'typedef struct {} {{\n'.format(name)
+
+ for f in ty.fields:
+ s += '\t{} {};\n'.format(f.type.typename, f.name)
+
+ s += '}} {};\n'.format(name)
+
+ cgo_helpers_preamble.append(s)
+
def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
"""
Generate a .go file (xenlight_helpers.go by default)
@@ -187,6 +209,7 @@ def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
if comment is not None:
f.write(comment)
f.write('package xenlight\n')
+ f.write('import (\n"unsafe"\n"errors"\n"fmt"\n)\n')
# Cgo preamble
f.write('/*\n')
@@ -195,6 +218,10 @@ def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
f.write('#include <libxl.h>\n')
f.write('\n')
+ for s in cgo_helpers_preamble:
+ f.write(s)
+ f.write('\n')
+
f.write('*/\nimport "C"\n')
for ty in types:
@@ -204,6 +231,12 @@ def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
f.write(xenlight_golang_define_from_C(ty))
f.write('\n')
+ for extra in helper_extras:
+ f.write(extra)
+ f.write('\n')
+
+ del helper_extras[:]
+
go_fmt(path)
def xenlight_golang_define_from_C(ty = None, typename = None, nested = False):
@@ -275,7 +308,7 @@ def xenlight_golang_define_from_C(ty = None, typename = None, nested = False):
s += xenlight_golang_define_from_C(f.type, typename=f.name, nested=True)
elif isinstance(f.type, idl.KeyedUnion):
- pass
+ s += xenlight_golang_union_from_C(f.type, f.name, ty.typename)
else:
raise Exception('type {} not supported'.format(f.type))
@@ -286,6 +319,107 @@ def xenlight_golang_define_from_C(ty = None, typename = None, nested = False):
return s
+def xenlight_golang_union_from_C(ty = None, union_name = '', struct_name = ''):
+ keyname = ty.keyvar.name
+ gokeyname = xenlight_golang_fmt_name(keyname)
+ keytype = ty.keyvar.type.typename
+ gokeytype = xenlight_golang_fmt_name(keytype)
+
+ interface_name = '{}_{}_union'.format(struct_name, keyname)
+ interface_name = xenlight_golang_fmt_name(interface_name, exported=False)
+
+ cgo_keyname = keyname
+ if cgo_keyname in go_keywords:
+ cgo_keyname = '_' + cgo_keyname
+
+ cases = {}
+
+ for f in ty.fields:
+ val = '{}_{}'.format(keytype, f.name)
+ val = xenlight_golang_fmt_name(val)
+
+ # Add to list of cases to make for the switch
+ # statement below.
+ if f.type is None:
+ continue
+
+ cases[f.name] = val
+
+ # Define fromC func for 'union' struct.
+ typename = '{}_{}_union_{}'.format(struct_name,keyname,f.name)
+ gotypename = xenlight_golang_fmt_name(typename)
+
+ # Define the function here. The cases for keyed unions are a little
+ # different.
+ s = 'func (x *{}) fromC(xc *C.{}) error {{\n'.format(gotypename,struct_name)
+ s += 'if {}(xc.{}) != {} {{\n'.format(gokeytype,cgo_keyname,val)
+ err_string = '"expected union key {}"'.format(val)
+ s += 'return errors.New({})\n'.format(err_string)
+ s += '}\n\n'
+ s += 'tmp := (*C.{})(unsafe.Pointer(&xc.{}[0]))\n'.format(typename,union_name)
+
+ s += xenlight_golang_union_fields_from_C(f.type)
+ s += 'return nil\n'
+ s += '}\n'
+
+ helper_extras.append(s)
+
+ s = 'x.{} = {}(xc.{})\n'.format(gokeyname,gokeytype,cgo_keyname)
+ s += 'switch x.{}{{\n'.format(gokeyname)
+
+ # Create switch statement to determine which 'union element'
+ # to populate in the Go struct.
+ for case_name, case_val in cases.items():
+ s += 'case {}:\n'.format(case_val)
+
+ gotype = '{}_{}_union_{}'.format(struct_name,keyname,case_name)
+ gotype = xenlight_golang_fmt_name(gotype)
+ goname = '{}_{}'.format(keyname,case_name)
+ goname = xenlight_golang_fmt_name(goname,exported=False)
+
+ s += 'var {} {}\n'.format(goname, gotype)
+ s += 'if err := {}.fromC(xc);'.format(goname)
+ s += 'err != nil {\n return err \n}\n'
+
+ field_name = xenlight_golang_fmt_name('{}_union'.format(keyname))
+ s += 'x.{} = {}\n'.format(field_name, goname)
+
+ # End switch statement
+ s += 'default:\n'
+ err_string = '"invalid union key \'%v\'", x.{}'.format(gokeyname)
+ s += 'return fmt.Errorf({})'.format(err_string)
+ s += '}\n'
+
+ return s
+
+def xenlight_golang_union_fields_from_C(ty = None):
+ s = ''
+
+ for f in ty.fields:
+ gotypename = xenlight_golang_fmt_name(f.type.typename)
+ ctypename = f.type.typename
+ gofname = xenlight_golang_fmt_name(f.name)
+ cfname = f.name
+
+ is_castable = (f.type.json_parse_type == 'JSON_INTEGER' or
+ isinstance(f.type, idl.Enumeration) or
+ gotypename in go_builtin_types)
+
+ if not is_castable:
+ s += 'if err := x.{}.fromC(&tmp.{});'.format(gofname,cfname)
+ s += 'err != nil {\n return err \n}\n'
+
+ # We just did an unsafe.Pointer cast from []byte to the 'union' type
+ # struct, so we need to make sure that any string fields are actually
+ # converted properly.
+ elif gotypename == 'string':
+ s += 'x.{} = C.GoString(tmp.{})\n'.format(gofname,cfname)
+
+ else:
+ s += 'x.{} = {}(tmp.{})\n'.format(gofname,gotypename,cfname)
+
+ return s
+
def xenlight_golang_fmt_name(name, exported = True):
"""
Take a given type name and return an
@@ -5,11 +5,122 @@
//
package xenlight
+import (
+ "errors"
+ "fmt"
+ "unsafe"
+)
+
/*
#cgo LDFLAGS: -lxenlight
#include <stdlib.h>
#include <libxl.h>
+typedef struct libxl_channelinfo_connection_union_pty {
+ char * path;
+} libxl_channelinfo_connection_union_pty;
+
+typedef struct libxl_domain_build_info_type_union_hvm {
+ char * firmware;
+ libxl_bios_type bios;
+ libxl_defbool pae;
+ libxl_defbool apic;
+ libxl_defbool acpi;
+ libxl_defbool acpi_s3;
+ libxl_defbool acpi_s4;
+ libxl_defbool acpi_laptop_slate;
+ libxl_defbool nx;
+ libxl_defbool viridian;
+ libxl_bitmap viridian_enable;
+ libxl_bitmap viridian_disable;
+ char * timeoffset;
+ libxl_defbool hpet;
+ libxl_defbool vpt_align;
+ uint64_t mmio_hole_memkb;
+ libxl_timer_mode timer_mode;
+ libxl_defbool nested_hvm;
+ libxl_defbool altp2m;
+ char * system_firmware;
+ char * smbios_firmware;
+ char * acpi_firmware;
+ libxl_hdtype hdtype;
+ libxl_defbool nographic;
+ libxl_vga_interface_info vga;
+ libxl_vnc_info vnc;
+ char * keymap;
+ libxl_sdl_info sdl;
+ libxl_spice_info spice;
+ libxl_defbool gfx_passthru;
+ libxl_gfx_passthru_kind gfx_passthru_kind;
+ char * serial;
+ char * boot;
+ libxl_defbool usb;
+ int usbversion;
+ char * usbdevice;
+ libxl_defbool vkb_device;
+ char * soundhw;
+ libxl_defbool xen_platform_pci;
+ libxl_string_list usbdevice_list;
+ libxl_vendor_device vendor_device;
+ libxl_ms_vm_genid ms_vm_genid;
+ libxl_string_list serial_list;
+ libxl_rdm_reserve rdm;
+ uint64_t rdm_mem_boundary_memkb;
+ uint64_t mca_caps;
+} libxl_domain_build_info_type_union_hvm;
+
+typedef struct libxl_domain_build_info_type_union_pv {
+ char * kernel;
+ uint64_t slack_memkb;
+ char * bootloader;
+ libxl_string_list bootloader_args;
+ char * cmdline;
+ char * ramdisk;
+ char * features;
+ libxl_defbool e820_host;
+} libxl_domain_build_info_type_union_pv;
+
+typedef struct libxl_domain_build_info_type_union_pvh {
+ libxl_defbool pvshim;
+ char * pvshim_path;
+ char * pvshim_cmdline;
+ char * pvshim_extra;
+} libxl_domain_build_info_type_union_pvh;
+
+typedef struct libxl_device_usbdev_type_union_hostdev {
+ uint8_t hostbus;
+ uint8_t hostaddr;
+} libxl_device_usbdev_type_union_hostdev;
+
+typedef struct libxl_device_channel_connection_union_socket {
+ char * path;
+} libxl_device_channel_connection_union_socket;
+
+typedef struct libxl_event_type_union_domain_shutdown {
+ uint8_t shutdown_reason;
+} libxl_event_type_union_domain_shutdown;
+
+typedef struct libxl_event_type_union_disk_eject {
+ char * vdev;
+ libxl_device_disk disk;
+} libxl_event_type_union_disk_eject;
+
+typedef struct libxl_event_type_union_operation_complete {
+ int rc;
+} libxl_event_type_union_operation_complete;
+
+typedef struct libxl_psr_hw_info_type_union_cat {
+ uint32_t cos_max;
+ uint32_t cbm_len;
+ bool cdp_enabled;
+} libxl_psr_hw_info_type_union_cat;
+
+typedef struct libxl_psr_hw_info_type_union_mba {
+ uint32_t cos_max;
+ uint32_t thrtl_max;
+ bool linear;
+} libxl_psr_hw_info_type_union_mba;
+
*/
import "C"
@@ -151,6 +262,27 @@ func (x *Channelinfo) fromC(xc *C.libxl_channelinfo) error {
x.State = int(xc.state)
x.Evtch = int(xc.evtch)
x.Rref = int(xc.rref)
+ x.Connection = ChannelConnection(xc.connection)
+ switch x.Connection {
+ case ChannelConnectionPty:
+ var connectionPty ChannelinfoConnectionUnionPty
+ if err := connectionPty.fromC(xc); err != nil {
+ return err
+ }
+ x.ConnectionUnion = connectionPty
+ default:
+ return fmt.Errorf("invalid union key '%v'", x.Connection)
+ }
+ return nil
+}
+
+func (x *ChannelinfoConnectionUnionPty) fromC(xc *C.libxl_channelinfo) error {
+ if ChannelConnection(xc.connection) != ChannelConnectionPty {
+ return errors.New("expected union key ChannelConnectionPty")
+ }
+
+ tmp := (*C.libxl_channelinfo_connection_union_pty)(unsafe.Pointer(&xc.u[0]))
+ x.Path = C.GoString(tmp.path)
return nil
}
@@ -398,12 +530,180 @@ func (x *DomainBuildInfo) fromC(xc *C.libxl_domain_build_info) error {
}
x.DmRestrict = defboolDmRestrict
x.Tee = TeeType(xc.tee)
+ x.Type = DomainType(xc._type)
+ switch x.Type {
+ case DomainTypePv:
+ var typePv DomainBuildInfoTypeUnionPv
+ if err := typePv.fromC(xc); err != nil {
+ return err
+ }
+ x.TypeUnion = typePv
+ case DomainTypeHvm:
+ var typeHvm DomainBuildInfoTypeUnionHvm
+ if err := typeHvm.fromC(xc); err != nil {
+ return err
+ }
+ x.TypeUnion = typeHvm
+ case DomainTypePvh:
+ var typePvh DomainBuildInfoTypeUnionPvh
+ if err := typePvh.fromC(xc); err != nil {
+ return err
+ }
+ x.TypeUnion = typePvh
+ default:
+ return fmt.Errorf("invalid union key '%v'", x.Type)
+ }
x.ArchArm.GicVersion = GicVersion(xc.arch_arm.gic_version)
x.ArchArm.Vuart = VuartType(xc.arch_arm.vuart)
x.Altp2M = Altp2MMode(xc.altp2m)
return nil
}
+func (x *DomainBuildInfoTypeUnionHvm) fromC(xc *C.libxl_domain_build_info) error {
+ if DomainType(xc._type) != DomainTypeHvm {
+ return errors.New("expected union key DomainTypeHvm")
+ }
+
+ tmp := (*C.libxl_domain_build_info_type_union_hvm)(unsafe.Pointer(&xc.u[0]))
+ x.Firmware = C.GoString(tmp.firmware)
+ x.Bios = BiosType(tmp.bios)
+ if err := x.Pae.fromC(&tmp.pae); err != nil {
+ return err
+ }
+ if err := x.Apic.fromC(&tmp.apic); err != nil {
+ return err
+ }
+ if err := x.Acpi.fromC(&tmp.acpi); err != nil {
+ return err
+ }
+ if err := x.AcpiS3.fromC(&tmp.acpi_s3); err != nil {
+ return err
+ }
+ if err := x.AcpiS4.fromC(&tmp.acpi_s4); err != nil {
+ return err
+ }
+ if err := x.AcpiLaptopSlate.fromC(&tmp.acpi_laptop_slate); err != nil {
+ return err
+ }
+ if err := x.Nx.fromC(&tmp.nx); err != nil {
+ return err
+ }
+ if err := x.Viridian.fromC(&tmp.viridian); err != nil {
+ return err
+ }
+ if err := x.ViridianEnable.fromC(&tmp.viridian_enable); err != nil {
+ return err
+ }
+ if err := x.ViridianDisable.fromC(&tmp.viridian_disable); err != nil {
+ return err
+ }
+ x.Timeoffset = C.GoString(tmp.timeoffset)
+ if err := x.Hpet.fromC(&tmp.hpet); err != nil {
+ return err
+ }
+ if err := x.VptAlign.fromC(&tmp.vpt_align); err != nil {
+ return err
+ }
+ x.MmioHoleMemkb = uint64(tmp.mmio_hole_memkb)
+ x.TimerMode = TimerMode(tmp.timer_mode)
+ if err := x.NestedHvm.fromC(&tmp.nested_hvm); err != nil {
+ return err
+ }
+ if err := x.Altp2M.fromC(&tmp.altp2m); err != nil {
+ return err
+ }
+ x.SystemFirmware = C.GoString(tmp.system_firmware)
+ x.SmbiosFirmware = C.GoString(tmp.smbios_firmware)
+ x.AcpiFirmware = C.GoString(tmp.acpi_firmware)
+ x.Hdtype = Hdtype(tmp.hdtype)
+ if err := x.Nographic.fromC(&tmp.nographic); err != nil {
+ return err
+ }
+ if err := x.Vga.fromC(&tmp.vga); err != nil {
+ return err
+ }
+ if err := x.Vnc.fromC(&tmp.vnc); err != nil {
+ return err
+ }
+ x.Keymap = C.GoString(tmp.keymap)
+ if err := x.Sdl.fromC(&tmp.sdl); err != nil {
+ return err
+ }
+ if err := x.Spice.fromC(&tmp.spice); err != nil {
+ return err
+ }
+ if err := x.GfxPassthru.fromC(&tmp.gfx_passthru); err != nil {
+ return err
+ }
+ x.GfxPassthruKind = GfxPassthruKind(tmp.gfx_passthru_kind)
+ x.Serial = C.GoString(tmp.serial)
+ x.Boot = C.GoString(tmp.boot)
+ if err := x.Usb.fromC(&tmp.usb); err != nil {
+ return err
+ }
+ x.Usbversion = int(tmp.usbversion)
+ x.Usbdevice = C.GoString(tmp.usbdevice)
+ if err := x.VkbDevice.fromC(&tmp.vkb_device); err != nil {
+ return err
+ }
+ x.Soundhw = C.GoString(tmp.soundhw)
+ if err := x.XenPlatformPci.fromC(&tmp.xen_platform_pci); err != nil {
+ return err
+ }
+ if err := x.UsbdeviceList.fromC(&tmp.usbdevice_list); err != nil {
+ return err
+ }
+ x.VendorDevice = VendorDevice(tmp.vendor_device)
+ if err := x.MsVmGenid.fromC(&tmp.ms_vm_genid); err != nil {
+ return err
+ }
+ if err := x.SerialList.fromC(&tmp.serial_list); err != nil {
+ return err
+ }
+ if err := x.Rdm.fromC(&tmp.rdm); err != nil {
+ return err
+ }
+ x.RdmMemBoundaryMemkb = uint64(tmp.rdm_mem_boundary_memkb)
+ x.McaCaps = uint64(tmp.mca_caps)
+ return nil
+}
+
+func (x *DomainBuildInfoTypeUnionPv) fromC(xc *C.libxl_domain_build_info) error {
+ if DomainType(xc._type) != DomainTypePv {
+ return errors.New("expected union key DomainTypePv")
+ }
+
+ tmp := (*C.libxl_domain_build_info_type_union_pv)(unsafe.Pointer(&xc.u[0]))
+ x.Kernel = C.GoString(tmp.kernel)
+ x.SlackMemkb = uint64(tmp.slack_memkb)
+ x.Bootloader = C.GoString(tmp.bootloader)
+ if err := x.BootloaderArgs.fromC(&tmp.bootloader_args); err != nil {
+ return err
+ }
+ x.Cmdline = C.GoString(tmp.cmdline)
+ x.Ramdisk = C.GoString(tmp.ramdisk)
+ x.Features = C.GoString(tmp.features)
+ if err := x.E820Host.fromC(&tmp.e820_host); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (x *DomainBuildInfoTypeUnionPvh) fromC(xc *C.libxl_domain_build_info) error {
+ if DomainType(xc._type) != DomainTypePvh {
+ return errors.New("expected union key DomainTypePvh")
+ }
+
+ tmp := (*C.libxl_domain_build_info_type_union_pvh)(unsafe.Pointer(&xc.u[0]))
+ if err := x.Pvshim.fromC(&tmp.pvshim); err != nil {
+ return err
+ }
+ x.PvshimPath = C.GoString(tmp.pvshim_path)
+ x.PvshimCmdline = C.GoString(tmp.pvshim_cmdline)
+ x.PvshimExtra = C.GoString(tmp.pvshim_extra)
+ return nil
+}
+
func (x *DeviceVfb) fromC(xc *C.libxl_device_vfb) error {
x.BackendDomid = Domid(xc.backend_domid)
x.BackendDomname = C.GoString(xc.backend_domname)
@@ -582,6 +882,28 @@ func (x *DeviceUsbctrl) fromC(xc *C.libxl_device_usbctrl) error {
func (x *DeviceUsbdev) fromC(xc *C.libxl_device_usbdev) error {
x.Ctrl = Devid(xc.ctrl)
x.Port = int(xc.port)
+ x.Type = UsbdevType(xc._type)
+ switch x.Type {
+ case UsbdevTypeHostdev:
+ var typeHostdev DeviceUsbdevTypeUnionHostdev
+ if err := typeHostdev.fromC(xc); err != nil {
+ return err
+ }
+ x.TypeUnion = typeHostdev
+ default:
+ return fmt.Errorf("invalid union key '%v'", x.Type)
+ }
+ return nil
+}
+
+func (x *DeviceUsbdevTypeUnionHostdev) fromC(xc *C.libxl_device_usbdev) error {
+ if UsbdevType(xc._type) != UsbdevTypeHostdev {
+ return errors.New("expected union key UsbdevTypeHostdev")
+ }
+
+ tmp := (*C.libxl_device_usbdev_type_union_hostdev)(unsafe.Pointer(&xc.u[0]))
+ x.Hostbus = byte(tmp.hostbus)
+ x.Hostaddr = byte(tmp.hostaddr)
return nil
}
@@ -624,6 +946,27 @@ func (x *DeviceChannel) fromC(xc *C.libxl_device_channel) error {
x.BackendDomname = C.GoString(xc.backend_domname)
x.Devid = Devid(xc.devid)
x.Name = C.GoString(xc.name)
+ x.Connection = ChannelConnection(xc.connection)
+ switch x.Connection {
+ case ChannelConnectionSocket:
+ var connectionSocket DeviceChannelConnectionUnionSocket
+ if err := connectionSocket.fromC(xc); err != nil {
+ return err
+ }
+ x.ConnectionUnion = connectionSocket
+ default:
+ return fmt.Errorf("invalid union key '%v'", x.Connection)
+ }
+ return nil
+}
+
+func (x *DeviceChannelConnectionUnionSocket) fromC(xc *C.libxl_device_channel) error {
+ if ChannelConnection(xc.connection) != ChannelConnectionSocket {
+ return errors.New("expected union key ChannelConnectionSocket")
+ }
+
+ tmp := (*C.libxl_device_channel_connection_union_socket)(unsafe.Pointer(&xc.u[0]))
+ x.Path = C.GoString(tmp.path)
return nil
}
@@ -950,6 +1293,62 @@ func (x *Event) fromC(xc *C.libxl_event) error {
}
x.Domuuid = uuidDomuuid
x.ForUser = uint64(xc.for_user)
+ x.Type = EventType(xc._type)
+ switch x.Type {
+ case EventTypeOperationComplete:
+ var typeOperationComplete EventTypeUnionOperationComplete
+ if err := typeOperationComplete.fromC(xc); err != nil {
+ return err
+ }
+ x.TypeUnion = typeOperationComplete
+ case EventTypeDomainShutdown:
+ var typeDomainShutdown EventTypeUnionDomainShutdown
+ if err := typeDomainShutdown.fromC(xc); err != nil {
+ return err
+ }
+ x.TypeUnion = typeDomainShutdown
+ case EventTypeDiskEject:
+ var typeDiskEject EventTypeUnionDiskEject
+ if err := typeDiskEject.fromC(xc); err != nil {
+ return err
+ }
+ x.TypeUnion = typeDiskEject
+ default:
+ return fmt.Errorf("invalid union key '%v'", x.Type)
+ }
+ return nil
+}
+
+func (x *EventTypeUnionDomainShutdown) fromC(xc *C.libxl_event) error {
+ if EventType(xc._type) != EventTypeDomainShutdown {
+ return errors.New("expected union key EventTypeDomainShutdown")
+ }
+
+ tmp := (*C.libxl_event_type_union_domain_shutdown)(unsafe.Pointer(&xc.u[0]))
+ x.ShutdownReason = byte(tmp.shutdown_reason)
+ return nil
+}
+
+func (x *EventTypeUnionDiskEject) fromC(xc *C.libxl_event) error {
+ if EventType(xc._type) != EventTypeDiskEject {
+ return errors.New("expected union key EventTypeDiskEject")
+ }
+
+ tmp := (*C.libxl_event_type_union_disk_eject)(unsafe.Pointer(&xc.u[0]))
+ x.Vdev = C.GoString(tmp.vdev)
+ if err := x.Disk.fromC(&tmp.disk); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (x *EventTypeUnionOperationComplete) fromC(xc *C.libxl_event) error {
+ if EventType(xc._type) != EventTypeOperationComplete {
+ return errors.New("expected union key EventTypeOperationComplete")
+ }
+
+ tmp := (*C.libxl_event_type_union_operation_complete)(unsafe.Pointer(&xc.u[0]))
+ x.Rc = int(tmp.rc)
return nil
}
@@ -963,5 +1362,46 @@ func (x *PsrCatInfo) fromC(xc *C.libxl_psr_cat_info) error {
func (x *PsrHwInfo) fromC(xc *C.libxl_psr_hw_info) error {
x.Id = uint32(xc.id)
+ x.Type = PsrFeatType(xc._type)
+ switch x.Type {
+ case PsrFeatTypeMba:
+ var typeMba PsrHwInfoTypeUnionMba
+ if err := typeMba.fromC(xc); err != nil {
+ return err
+ }
+ x.TypeUnion = typeMba
+ case PsrFeatTypeCat:
+ var typeCat PsrHwInfoTypeUnionCat
+ if err := typeCat.fromC(xc); err != nil {
+ return err
+ }
+ x.TypeUnion = typeCat
+ default:
+ return fmt.Errorf("invalid union key '%v'", x.Type)
+ }
+ return nil
+}
+
+func (x *PsrHwInfoTypeUnionCat) fromC(xc *C.libxl_psr_hw_info) error {
+ if PsrFeatType(xc._type) != PsrFeatTypeCat {
+ return errors.New("expected union key PsrFeatTypeCat")
+ }
+
+ tmp := (*C.libxl_psr_hw_info_type_union_cat)(unsafe.Pointer(&xc.u[0]))
+ x.CosMax = uint32(tmp.cos_max)
+ x.CbmLen = uint32(tmp.cbm_len)
+ x.CdpEnabled = bool(tmp.cdp_enabled)
+ return nil
+}
+
+func (x *PsrHwInfoTypeUnionMba) fromC(xc *C.libxl_psr_hw_info) error {
+ if PsrFeatType(xc._type) != PsrFeatTypeMba {
+ return errors.New("expected union key PsrFeatTypeMba")
+ }
+
+ tmp := (*C.libxl_psr_hw_info_type_union_mba)(unsafe.Pointer(&xc.u[0]))
+ x.CosMax = uint32(tmp.cos_max)
+ x.ThrtlMax = uint32(tmp.thrtl_max)
+ x.Linear = bool(tmp.linear)
return nil
}