[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 16/22] golang/xenlight: implement keyed union C to Go marshaling
From: Nick Rosbrook <rosbrookn@xxxxxxxxxxxx> Switch over union key to determine how to populate 'union' in Go struct. Since the unions of C types cannot be directly accessed, add C structs in cgo preamble to assist in marshaling keyed unions. This allows the C type defined in the preamble to be populated first, and then accessed directly to populate the Go struct. Signed-off-by: Nick Rosbrook <rosbrookn@xxxxxxxxxxxx> --- Changes in v2: - Do not use global variable for extra helper function definitions. Instead, return a tuple which contains a list of extra helper functions associated with the original. tools/golang/xenlight/gengotypes.py | 153 +++++++++- tools/golang/xenlight/helpers.gen.go | 440 +++++++++++++++++++++++++++ 2 files changed, 590 insertions(+), 3 deletions(-) diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py index 0c8a1327a1..57cecd5989 100644 --- a/tools/golang/xenlight/gengotypes.py +++ b/tools/golang/xenlight/gengotypes.py @@ -24,6 +24,10 @@ go_keywords = ['type', 'func'] go_builtin_types = ['bool', 'string', 'int', 'byte', 'uint16', 'uint32', 'uint64'] +# cgo preamble for xenlight_helpers.go, created during type generation and +# written later. +cgo_helpers_preamble = [] + def xenlight_golang_generate_types(path = None, types = None, comment = None): """ Generate a .go file (types.gen.go by default) @@ -168,6 +172,8 @@ def xenlight_golang_define_union(ty = None, structname = ''): extras.append(r[0]) extras.extend(r[1]) + 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) @@ -182,6 +188,18 @@ def xenlight_golang_define_union(ty = None, structname = ''): return (s,extras) +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 (helpers.gen.go by default) @@ -195,6 +213,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') @@ -203,19 +222,38 @@ 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: if not isinstance(ty, idl.Struct): continue - f.write(xenlight_golang_define_from_C(ty)) + (fdef, extras) = xenlight_golang_define_from_C(ty) + + f.write(fdef) f.write('\n') + for extra in extras: + f.write(extra) + f.write('\n') + go_fmt(path) def xenlight_golang_define_from_C(ty = None, typename = None, nested = False): + """ + Define the fromC helper function for ty. + + Return a tuple that contains a string with the + function definition, and a (potentially empty) list + of extra definitions that are associated with + this helper function. + """ s = '' + extras = [] gotypename = ctypename = '' @@ -280,10 +318,16 @@ def xenlight_golang_define_from_C(ty = None, typename = None, nested = False): s += 'x.{} = {}\n'.format(goname, varname) elif isinstance(f.type, idl.Struct): - s += xenlight_golang_define_from_C(f.type, typename=f.name, nested=True) + r = xenlight_golang_define_from_C(f.type, typename=f.name, nested=True) + + s += r[0] + extras.extend(r[1]) elif isinstance(f.type, idl.KeyedUnion): - pass + r = xenlight_golang_union_from_C(f.type, f.name, ty.typename) + + s += r[0] + extras.extend(r[1]) else: raise Exception('type {} not supported'.format(f.type)) @@ -292,6 +336,109 @@ def xenlight_golang_define_from_C(ty = None, typename = None, nested = False): s += 'return nil' s += '}\n' + return (s,extras) + +def xenlight_golang_union_from_C(ty = None, union_name = '', struct_name = ''): + extras = [] + + 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' + + 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,extras) + +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): diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go index 0de42eaa6b..d2dd9f2507 100644 --- a/tools/golang/xenlight/helpers.gen.go +++ b/tools/golang/xenlight/helpers.gen.go @@ -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 } @@ -400,12 +532,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) @@ -584,6 +884,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 } @@ -626,6 +948,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 } @@ -952,6 +1295,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 } @@ -965,5 +1364,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 } -- 2.19.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |