mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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@ainfosec.com> Reviewed-by: George Dunlap <george.dunlap@citrix.com>
This commit is contained in:
1 parent
cc8e54a1a2
commit
21cb0bdcf4
3 files changed
+465
-12
No files matched your search
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,10 +154,31 @@ 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
|
||||
}
|
||||
|
||||
func (x *Vminfo) fromC(xc *C.libxl_vminfo) error {
|
||||
if err := x.Uuid.fromC(&xc.uuid); err != nil {
|
||||
return err
|
||||
@@ -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,10 +793,31 @@ 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
|
||||
}
|
||||
|
||||
func (x *ConnectorParam) fromC(xc *C.libxl_connector_param) error {
|
||||
x.UniqueId = C.GoString(xc.unique_id)
|
||||
x.Width = uint32(xc.width)
|
||||
@@ -881,10 +1130,66 @@ 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
|
||||
}
|
||||
|
||||
func (x *PsrCatInfo) fromC(xc *C.libxl_psr_cat_info) error {
|
||||
x.Id = uint32(xc.id)
|
||||
x.CosMax = uint32(xc.cos_max)
|
||||
@@ -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
|
||||
}
|
||||