All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nick Rosbrook <rosbrookn@gmail.com>
To: xen-devel@lists.xenproject.org
Cc: Nick Rosbrook <rosbrookn@ainfosec.com>,
	Ian Jackson <ian.jackson@eu.citrix.com>,
	kerriganb@ainfosec.com, George Dunlap <george.dunlap@citrix.com>,
	Wei Liu <wl@xen.org>
Subject: [Xen-devel] [PATCH v2 16/22] golang/xenlight: implement keyed union C to Go marshaling
Date: Fri, 15 Nov 2019 14:44:23 -0500	[thread overview]
Message-ID: <938dbf7c3a083ec050c16729805f4ce5f3f2891f.1573840474.git.rosbrookn@ainfosec.com> (raw)
In-Reply-To: <cover.1573840473.git.rosbrookn@ainfosec.com>

From: Nick Rosbrook <rosbrookn@ainfosec.com>

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@ainfosec.com>
---
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@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2019-11-15 19:46 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-15 19:44 [Xen-devel] [PATCH v2 00/22] generated Go libxl bindings using IDL Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 01/22] golang/xenlight: generate enum types from IDL Nick Rosbrook
2019-12-03 18:11   ` George Dunlap
2019-12-04 15:58   ` George Dunlap
2019-12-05 15:02   ` George Dunlap
2019-12-05 17:00     ` Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 02/22] golang/xenlight: define Defbool builtin type Nick Rosbrook
2019-12-04 15:50   ` George Dunlap
2019-12-05 15:23     ` Nick Rosbrook
2019-12-05 15:27       ` George Dunlap
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 03/22] golang/xenlight: define Devid type as int Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 04/22] golang/xenlight: define KeyValueList as empty struct Nick Rosbrook
2019-12-04 16:08   ` George Dunlap
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 05/22] golang/xenlight: re-name Bitmap marshaling functions Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 06/22] golang/xenlight: define StringList builtin type Nick Rosbrook
2019-12-04 16:15   ` George Dunlap
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 07/22] golang/xenlight: define Mac " Nick Rosbrook
2019-12-04 16:18   ` George Dunlap
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 08/22] golang/xenlight: define MsVmGenid " Nick Rosbrook
2019-12-04 17:00   ` George Dunlap
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 09/22] golang/xenlight: define EvLink builtin as empty struct Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 10/22] golang/xenlight: define CpuidPolicyList builtin type Nick Rosbrook
2019-12-04 16:48   ` George Dunlap
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 11/22] golang/xenlight: re-factor Uuid type implementation Nick Rosbrook
2019-12-04 17:02   ` George Dunlap
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 12/22] golang/xenlight: re-factor Hwcap " Nick Rosbrook
2019-12-04 17:07   ` George Dunlap
2019-12-05 15:35     ` Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 13/22] golang/xenlight: generate structs from the IDL Nick Rosbrook
2019-12-04 17:25   ` George Dunlap
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 14/22] golang/xenlight: remove no-longer used type MemKB Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 15/22] golang/xenlight: begin C to Go type marshaling Nick Rosbrook
2019-12-04 18:07   ` George Dunlap
2019-12-05 16:38     ` Nick Rosbrook
2019-12-05 18:00       ` George Dunlap
2019-12-05 18:32         ` Nick Rosbrook
2019-11-15 19:44 ` Nick Rosbrook [this message]
2019-12-04 18:40   ` [Xen-devel] [PATCH v2 16/22] golang/xenlight: implement keyed union C to Go marshaling George Dunlap
2019-12-05 12:22     ` George Dunlap
2019-12-05 16:53       ` Nick Rosbrook
2019-12-05 17:33         ` George Dunlap
2019-12-05 18:39           ` Nick Rosbrook
2019-12-06 10:46             ` George Dunlap
2019-12-06 15:39               ` Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 17/22] golang/xenlight: implement array " Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 18/22] golang/xenlight: begin Go to C type marshaling Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 19/22] golang/xenlight: implement keyed union Go to C marshaling Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 20/22] golang/xenlight: implement array " Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 21/22] golang/xenlight: revise use of Context type Nick Rosbrook
2019-11-15 19:44 ` [Xen-devel] [PATCH v2 22/22] golang/xenlight: add error return type to Context.Cpupoolinfo Nick Rosbrook

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=938dbf7c3a083ec050c16729805f4ce5f3f2891f.1573840474.git.rosbrookn@ainfosec.com \
    --to=rosbrookn@gmail.com \
    --cc=george.dunlap@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=kerriganb@ainfosec.com \
    --cc=rosbrookn@ainfosec.com \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.