[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] golang/xenlight: implement keyed union C to Go marshaling
commit 21cb0bdcf4c12b8edd34f3d086edd76f2e974c32 Author: Nick Rosbrook <rosbrookn@xxxxxxxxxxxx> AuthorDate: Mon Dec 16 18:08:10 2019 +0000 Commit: George Dunlap <george.dunlap@xxxxxxxxxx> CommitDate: Mon Dec 16 18:08:10 2019 +0000 golang/xenlight: implement keyed union C to Go marshaling Switch over union key to determine how to populate 'union' in Go struct. Since the unions of C types cannot be directly accessed in cgo, use a typeof trick to typedef a struct in the cgo preamble that is analagous to each inner struct of a keyed union. For example, to define a struct for the hvm inner struct of libxl_domain_build_info, do: typedef typeof(((struct libxl_domain_build_info *)NULL)->u.hvm) libxl_domain_build_info_type_union_hvm; Signed-off-by: Nick Rosbrook <rosbrookn@xxxxxxxxxxxx> Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxx> --- tools/golang/xenlight/Makefile | 2 +- tools/golang/xenlight/gengotypes.py | 129 +++++++++++-- tools/golang/xenlight/helpers.gen.go | 346 +++++++++++++++++++++++++++++++++++ 3 files changed, 465 insertions(+), 12 deletions(-) diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile index 56192fee0e..753132306a 100644 --- a/tools/golang/xenlight/Makefile +++ b/tools/golang/xenlight/Makefile @@ -15,7 +15,7 @@ all: build .PHONY: package package: $(XEN_GOPATH)$(GOXL_PKG_DIR) -$(XEN_GOPATH)/src/$(XEN_GOCODE_URL)/xenlight/: xenlight.go types.gen.go +$(XEN_GOPATH)/src/$(XEN_GOCODE_URL)/xenlight/: xenlight.go types.gen.go helpers.gen.go $(INSTALL_DIR) $(XEN_GOPATH)$(GOXL_PKG_DIR) $(INSTALL_DATA) xenlight.go $(XEN_GOPATH)$(GOXL_PKG_DIR) $(INSTALL_DATA) types.gen.go $(XEN_GOPATH)$(GOXL_PKG_DIR) diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py index 1fe56179e2..b68c1aa66b 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) @@ -124,7 +128,7 @@ def xenlight_golang_define_struct(ty = None, typename = None, nested = False): extras.extend(r[1]) elif isinstance(f.type, idl.KeyedUnion): - r = xenlight_golang_define_union(f.type, ty.typename) + r = xenlight_golang_define_union(f.type, ty.typename, f.name) s += r[0] extras.extend(r[1]) @@ -137,7 +141,7 @@ def xenlight_golang_define_struct(ty = None, typename = None, nested = False): return (s,extras) -def xenlight_golang_define_union(ty = None, structname = ''): +def xenlight_golang_define_union(ty = None, struct_name = '', union_name = ''): """ Generate the Go translation of a KeyedUnion. @@ -149,7 +153,7 @@ def xenlight_golang_define_union(ty = None, structname = ''): s = '' extras = [] - interface_name = '{}_{}_union'.format(structname, ty.keyvar.name) + interface_name = '{}_{}_union'.format(struct_name, ty.keyvar.name) interface_name = xenlight_golang_fmt_name(interface_name, exported=False) s += 'type {} interface {{\n'.format(interface_name) @@ -163,11 +167,18 @@ def xenlight_golang_define_union(ty = None, structname = ''): continue # Define struct - name = '{}_{}_union_{}'.format(structname, ty.keyvar.name, f.name) + name = '{}_{}_union_{}'.format(struct_name, ty.keyvar.name, f.name) r = xenlight_golang_define_struct(f.type, typename=name) extras.append(r[0]) extras.extend(r[1]) + # This typeof trick ensures that the fields used in the cgo struct + # used for marshaling are the same as the fields of the union in the + # actual C type, and avoids re-defining all of those fields. + s = 'typedef typeof(((struct {} *)NULL)->{}.{}){};' + s = s.format(struct_name, union_name, f.name, name) + cgo_helpers_preamble.append(s) + # Define function to implement 'union' interface name = xenlight_golang_fmt_name(name) s = 'func (x {}) is{}(){{}}\n'.format(name, interface_name) @@ -195,6 +206,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,15 +215,25 @@ 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): @@ -225,6 +247,7 @@ def xenlight_golang_define_from_C(ty = None): cname = ty.typename body = '' + extras = [] for f in ty.fields: if f.type.typename is not None: @@ -240,14 +263,17 @@ def xenlight_golang_define_from_C(ty = None): body += xenlight_golang_convert_from_C(nf,outer_name=f.name) elif isinstance(f.type, idl.KeyedUnion): - pass + r = xenlight_golang_union_from_C(f.type, f.name, ty.typename) + + body += r[0] + extras.extend(r[1]) else: raise Exception('type {} not supported'.format(f.type)) - return func.format(goname, cname, body) + return (func.format(goname, cname, body), extras) -def xenlight_golang_convert_from_C(ty = None, outer_name = None): +def xenlight_golang_convert_from_C(ty = None, outer_name = None, cvarname = None): """ Returns a line of Go code that converts the C type represented by ty to its corresponding Go type. @@ -257,6 +283,10 @@ def xenlight_golang_convert_from_C(ty = None, outer_name = None): """ s = '' + # Use 'xc' as the name for the C variable unless otherwise specified + if cvarname is None: + cvarname = 'xc' + gotypename = xenlight_golang_fmt_name(ty.type.typename) goname = xenlight_golang_fmt_name(ty.name) cname = ty.name @@ -280,18 +310,95 @@ def xenlight_golang_convert_from_C(ty = None, outer_name = None): if not is_castable: # If the type is not castable, we need to call its fromC # function. - s += 'if err := x.{}.fromC(&xc.{});'.format(goname,cname) + s += 'if err := x.{}.fromC(&{}.{});'.format(goname,cvarname,cname) s += 'err != nil {\n return err \n}\n' elif gotypename == 'string': # Use the cgo helper for converting C strings. - s += 'x.{} = C.GoString(xc.{})\n'.format(goname, cname) + s += 'x.{} = C.GoString({}.{})\n'.format(goname,cvarname,cname) else: - s += 'x.{} = {}(xc.{})\n'.format(goname, gotypename, cname) + s += 'x.{} = {}({}.{})\n'.format(goname,gotypename,cvarname,cname) return s +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) + + for nf in f.type.fields: + s += xenlight_golang_convert_from_C(nf,cvarname='tmp') + + 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_fmt_name(name, exported = True): """ Take a given type name and return an diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go index 576aebcf6d..e6eee234c0 100644 --- a/tools/golang/xenlight/helpers.gen.go +++ b/tools/golang/xenlight/helpers.gen.go @@ -5,11 +5,28 @@ // package xenlight +import ( + "errors" + "fmt" + "unsafe" +) + /* #cgo LDFLAGS: -lxenlight #include <stdlib.h> #include <libxl.h> +typedef typeof(((struct libxl_channelinfo *)NULL)->u.pty)libxl_channelinfo_connection_union_pty; +typedef typeof(((struct libxl_domain_build_info *)NULL)->u.hvm)libxl_domain_build_info_type_union_hvm; +typedef typeof(((struct libxl_domain_build_info *)NULL)->u.pv)libxl_domain_build_info_type_union_pv; +typedef typeof(((struct libxl_domain_build_info *)NULL)->u.pvh)libxl_domain_build_info_type_union_pvh; +typedef typeof(((struct libxl_device_usbdev *)NULL)->u.hostdev)libxl_device_usbdev_type_union_hostdev; +typedef typeof(((struct libxl_device_channel *)NULL)->u.socket)libxl_device_channel_connection_union_socket; +typedef typeof(((struct libxl_event *)NULL)->u.domain_shutdown)libxl_event_type_union_domain_shutdown; +typedef typeof(((struct libxl_event *)NULL)->u.disk_eject)libxl_event_type_union_disk_eject; +typedef typeof(((struct libxl_event *)NULL)->u.operation_complete)libxl_event_type_union_operation_complete; +typedef typeof(((struct libxl_psr_hw_info *)NULL)->u.cat)libxl_psr_hw_info_type_union_cat; +typedef typeof(((struct libxl_psr_hw_info *)NULL)->u.mba)libxl_psr_hw_info_type_union_mba; */ import "C" @@ -137,7 +154,28 @@ 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 } @@ -340,6 +378,29 @@ func (x *DomainBuildInfo) fromC(xc *C.libxl_domain_build_info) error { return err } 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) @@ -347,6 +408,151 @@ func (x *DomainBuildInfo) fromC(xc *C.libxl_domain_build_info) error { 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) @@ -520,10 +726,32 @@ 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 +} + func (x *DeviceDtdev) fromC(xc *C.libxl_device_dtdev) error { x.Path = C.GoString(xc.path) @@ -565,7 +793,28 @@ 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 } @@ -881,7 +1130,63 @@ func (x *Event) fromC(xc *C.libxl_event) error { return err } 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 } @@ -896,6 +1201,47 @@ 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 } -- generated by git-patchbot for /home/xen/git/xen.git#staging _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |