From patchwork Mon Oct 7 15:13:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nick Rosbrook X-Patchwork-Id: 11177807 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9E25213BD for ; Mon, 7 Oct 2019 15:16:17 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6E0A32053B for ; Mon, 7 Oct 2019 15:16:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hsaB+s9o" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6E0A32053B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iHUiq-0007de-EI; Mon, 07 Oct 2019 15:14:52 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iHUip-0007d0-Pr for xen-devel@lists.xenproject.org; Mon, 07 Oct 2019 15:14:51 +0000 X-Inumbo-ID: 0b1204cc-e915-11e9-8c93-bc764e2007e4 Received: from mail-qt1-x82c.google.com (unknown [2607:f8b0:4864:20::82c]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 0b1204cc-e915-11e9-8c93-bc764e2007e4; Mon, 07 Oct 2019 15:13:40 +0000 (UTC) Received: by mail-qt1-x82c.google.com with SMTP id u22so19592333qtq.13 for ; Mon, 07 Oct 2019 08:13:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LUYRgjlAufinBicA8NtCPTHU6A7dJzgpXyfy8a3qo9M=; b=hsaB+s9oggH0saICrOWav874+d7YCdVHkvyGZhy9PCMZOUkK0HLakJhGW2haOxuvpX Pw6pFbZ/2gABPyyDRC1esPSyn5lk2AklVbY1xdovqUzNZBHiGmv4r122KXJh8D+Ps0qG Ib6nydaOPFHfBnIuTHgy+8iYH91Meg1BYoK+uAO5Sagofu69YYKIvthX7q0LNfGUyDqs zYewa9XHx3+QFd3eIcLotafBLDEVeanUKB2AUX1uNZUOknr0GDgkfixvME29HqlaQ8Ju RRbdDndLrYV0g5YD7n1fAraFDpPN6TuQTkTTOzNnxcZH227OO+Ls8y5ebYnYRoNLlKKH Uxgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LUYRgjlAufinBicA8NtCPTHU6A7dJzgpXyfy8a3qo9M=; b=kgOgBCpae09z2xwYlu7oYRAV7ZcMHHVMb6om/LVIBhyOekrlsHibKNeHAXXnxleuDd mnOJDrcdiAvACgCId1RRfha13flRNXnY8z8i49JSXX1/Ty6S3Nln49l82dVmuP/m9tJW mFJ5/BwaPWjXAlI7Qda9Q8UL1dp0fEMpLvtBn+9Oc8MmS7Z3yyncfq8F+D28Ax+v4xPD /Csf7zPawhGCX7Vq2idM6rE6ECguLmusnugZXKCgEhhAiTDLcQoVoCDowVHJ9ftwJ2ox 4TtvCg0vvvyHzfIBLivRdTyozKlz1E0WaVbQILncR2vYYv8VJLRLyJMm7A8N3ZdCqQS5 ORPQ== X-Gm-Message-State: APjAAAXLjY8uhe56S/ksFOWKx+jBrg1oPwddQyFLmio/vIcj/dCBEfSp oPGoUjPePBZaDAnhztZhLfe7TcGk X-Google-Smtp-Source: APXvYqxs7dTgrzPWibkVI7+mLjepb1Mbcys3EohzibKSCnroqA49Rwb7XytQ17bewv70ZgDiGP+0Nw== X-Received: by 2002:ac8:7604:: with SMTP id t4mr30475588qtq.34.1570461219283; Mon, 07 Oct 2019 08:13:39 -0700 (PDT) Received: from five.crux.rad.ainfosec.com (209-217-208-226.northland.net. [209.217.208.226]) by smtp.googlemail.com with ESMTPSA id c185sm8354313qkg.74.2019.10.07.08.13.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Oct 2019 08:13:38 -0700 (PDT) From: Nick Rosbrook To: xen-devel@lists.xenproject.org Date: Mon, 7 Oct 2019 11:13:07 -0400 Message-Id: <938d9d152a9e31ca5b40e10282bd9c3c34c4348b.1570456846.git.rosbrookn@ainfosec.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: References: MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 20/24] golang/xenlight: implement keyed union Go to C marshaling X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Nick Rosbrook , Ian Jackson , kerriganb@ainfosec.com, George Dunlap , Wei Liu Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" From: Nick Rosbrook Since the C union cannot be directly populated, populate the fields of the corresponding C struct defined in the cgo preamble, and then copy that struct as bytes into the byte slice that Go uses as the union. Signed-off-by: Nick Rosbrook --- Cc: George Dunlap Cc: Ian Jackson Cc: Wei Liu tools/golang/xenlight/gengotypes.py | 77 ++++- tools/golang/xenlight/xenlight_helpers.go | 325 ++++++++++++++++++++++ 2 files changed, 400 insertions(+), 2 deletions(-) diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py index eccc334b41..35d9dfea40 100644 --- a/tools/golang/xenlight/gengotypes.py +++ b/tools/golang/xenlight/gengotypes.py @@ -525,8 +525,7 @@ def xenlight_golang_define_to_C(ty = None, typename = None, nested = False): s += xenlight_golang_define_to_C(f.type, typename=f.name, nested=True) elif isinstance(f.type, idl.KeyedUnion): - # TODO - pass + s += xenlight_golang_union_to_C(f.type, f.name, ty.typename, ty.dispose_fn) else: raise Exception('type {} not supported'.format(f.type)) @@ -537,6 +536,80 @@ def xenlight_golang_define_to_C(ty = None, typename = None, nested = False): return s +def xenlight_golang_union_to_C(ty = None, union_name = '', + struct_name = '', dispose_fn = ''): + 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 + + + s = 'xc.{} = C.{}(x.{})\n'.format(cgo_keyname,keytype,gokeyname) + s += 'switch x.{}{{\n'.format(gokeyname) + + # Create switch statement to determine how to populate the C union. + for f in ty.fields: + key_val = '{}_{}'.format(keytype, f.name) + key_val = xenlight_golang_fmt_name(key_val) + if f.type is None: + continue + + s += 'case {}:\n'.format(key_val) + cgotype = '{}_{}_union_{}'.format(struct_name,keyname,f.name) + gotype = xenlight_golang_fmt_name(cgotype) + goname = '{}_{}'.format(keyname,f.name) + goname = xenlight_golang_fmt_name(goname,exported=False) + + field_name = xenlight_golang_fmt_name('{}_union'.format(keyname)) + s += 'tmp, ok := x.{}.({})\n'.format(field_name,gotype) + s += 'if !ok {\n' + s += 'C.{}(&xc)\n'.format(dispose_fn) + s += 'return xc,errors.New("wrong type for union key {}")\n'.format(keyname) + s += '}\n' + + s += 'var {} C.{}\n'.format(f.name,cgotype) + for uf in f.type.fields: + gotypename = xenlight_golang_fmt_name(uf.type.typename) + ctypename = uf.type.typename + gofname = xenlight_golang_fmt_name(uf.name) + + is_castable = (uf.type.json_parse_type == 'JSON_INTEGER' or + isinstance(uf.type, idl.Enumeration) or + gotypename in go_builtin_types) + + if not is_castable: + s += '{}.{}, err = tmp.{}.toC()\n'.format(f.name,uf.name,gofname) + s += 'if err != nil {\n' + s += 'C.{}(&xc)\n'.format(dispose_fn) + s += 'return xc,err \n}\n' + + elif gotypename == 'string': + s += '{}.{} = C.CString(tmp.{})\n'.format(f.name,uf.name,gofname) + + else: + s += '{}.{} = C.{}(tmp.{})\n'.format(f.name,uf.name,ctypename,gofname) + + # The union is still represented as Go []byte. + s += '{}Bytes := C.GoBytes(unsafe.Pointer(&{}),C.sizeof_{})\n'.format(f.name, + f.name, + cgotype) + s += 'copy(xc.{}[:],{}Bytes)\n'.format(union_name,f.name) + + # End switch statement + s += 'default:\n' + err_string = '"invalid union key \'%v\'", x.{}'.format(gokeyname) + s += 'return xc, fmt.Errorf({})'.format(err_string) + s += '}\n' + + return s + def xenlight_golang_fmt_name(name, exported = True): """ Take a given type name and return an diff --git a/tools/golang/xenlight/xenlight_helpers.go b/tools/golang/xenlight/xenlight_helpers.go index 92e6afcd10..2cb5adaec5 100644 --- a/tools/golang/xenlight/xenlight_helpers.go +++ b/tools/golang/xenlight/xenlight_helpers.go @@ -433,6 +433,21 @@ func (x *Channelinfo) toC() (xc C.libxl_channelinfo, err error) { xc.state = C.int(x.State) xc.evtch = C.int(x.Evtch) xc.rref = C.int(x.Rref) + xc.connection = C.libxl_channel_connection(x.Connection) + switch x.Connection { + case ChannelConnectionPty: + tmp, ok := x.ConnectionUnion.(ChannelinfoConnectionUnionPty) + if !ok { + C.libxl_channelinfo_dispose(&xc) + return xc, errors.New("wrong type for union key connection") + } + var pty C.libxl_channelinfo_connection_union_pty + pty.path = C.CString(tmp.Path) + ptyBytes := C.GoBytes(unsafe.Pointer(&pty), C.sizeof_libxl_channelinfo_connection_union_pty) + copy(xc.u[:], ptyBytes) + default: + return xc, fmt.Errorf("invalid union key '%v'", x.Connection) + } return xc, nil } @@ -1180,6 +1195,216 @@ func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) { return xc, err } xc.tee = C.libxl_tee_type(x.Tee) + xc._type = C.libxl_domain_type(x.Type) + switch x.Type { + case DomainTypeHvm: + tmp, ok := x.TypeUnion.(DomainBuildInfoTypeUnionHvm) + if !ok { + C.libxl_domain_build_info_dispose(&xc) + return xc, errors.New("wrong type for union key type") + } + var hvm C.libxl_domain_build_info_type_union_hvm + hvm.firmware = C.CString(tmp.Firmware) + hvm.bios = C.libxl_bios_type(tmp.Bios) + hvm.pae, err = tmp.Pae.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.apic, err = tmp.Apic.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.acpi, err = tmp.Acpi.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.acpi_s3, err = tmp.AcpiS3.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.acpi_s4, err = tmp.AcpiS4.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.acpi_laptop_slate, err = tmp.AcpiLaptopSlate.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.nx, err = tmp.Nx.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.viridian, err = tmp.Viridian.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.viridian_enable, err = tmp.ViridianEnable.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.viridian_disable, err = tmp.ViridianDisable.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.timeoffset = C.CString(tmp.Timeoffset) + hvm.hpet, err = tmp.Hpet.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.vpt_align, err = tmp.VptAlign.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.mmio_hole_memkb = C.uint64_t(tmp.MmioHoleMemkb) + hvm.timer_mode = C.libxl_timer_mode(tmp.TimerMode) + hvm.nested_hvm, err = tmp.NestedHvm.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.altp2m, err = tmp.Altp2M.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.system_firmware = C.CString(tmp.SystemFirmware) + hvm.smbios_firmware = C.CString(tmp.SmbiosFirmware) + hvm.acpi_firmware = C.CString(tmp.AcpiFirmware) + hvm.hdtype = C.libxl_hdtype(tmp.Hdtype) + hvm.nographic, err = tmp.Nographic.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.vga, err = tmp.Vga.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.vnc, err = tmp.Vnc.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.keymap = C.CString(tmp.Keymap) + hvm.sdl, err = tmp.Sdl.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.spice, err = tmp.Spice.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.gfx_passthru, err = tmp.GfxPassthru.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.gfx_passthru_kind = C.libxl_gfx_passthru_kind(tmp.GfxPassthruKind) + hvm.serial = C.CString(tmp.Serial) + hvm.boot = C.CString(tmp.Boot) + hvm.usb, err = tmp.Usb.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.usbversion = C.int(tmp.Usbversion) + hvm.usbdevice = C.CString(tmp.Usbdevice) + hvm.vkb_device, err = tmp.VkbDevice.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.soundhw = C.CString(tmp.Soundhw) + hvm.xen_platform_pci, err = tmp.XenPlatformPci.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.usbdevice_list, err = tmp.UsbdeviceList.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.vendor_device = C.libxl_vendor_device(tmp.VendorDevice) + hvm.ms_vm_genid, err = tmp.MsVmGenid.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.serial_list, err = tmp.SerialList.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.rdm, err = tmp.Rdm.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + hvm.rdm_mem_boundary_memkb = C.uint64_t(tmp.RdmMemBoundaryMemkb) + hvm.mca_caps = C.uint64_t(tmp.McaCaps) + hvmBytes := C.GoBytes(unsafe.Pointer(&hvm), C.sizeof_libxl_domain_build_info_type_union_hvm) + copy(xc.u[:], hvmBytes) + case DomainTypePv: + tmp, ok := x.TypeUnion.(DomainBuildInfoTypeUnionPv) + if !ok { + C.libxl_domain_build_info_dispose(&xc) + return xc, errors.New("wrong type for union key type") + } + var pv C.libxl_domain_build_info_type_union_pv + pv.kernel = C.CString(tmp.Kernel) + pv.slack_memkb = C.uint64_t(tmp.SlackMemkb) + pv.bootloader = C.CString(tmp.Bootloader) + pv.bootloader_args, err = tmp.BootloaderArgs.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + pv.cmdline = C.CString(tmp.Cmdline) + pv.ramdisk = C.CString(tmp.Ramdisk) + pv.features = C.CString(tmp.Features) + pv.e820_host, err = tmp.E820Host.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + pvBytes := C.GoBytes(unsafe.Pointer(&pv), C.sizeof_libxl_domain_build_info_type_union_pv) + copy(xc.u[:], pvBytes) + case DomainTypePvh: + tmp, ok := x.TypeUnion.(DomainBuildInfoTypeUnionPvh) + if !ok { + C.libxl_domain_build_info_dispose(&xc) + return xc, errors.New("wrong type for union key type") + } + var pvh C.libxl_domain_build_info_type_union_pvh + pvh.pvshim, err = tmp.Pvshim.toC() + if err != nil { + C.libxl_domain_build_info_dispose(&xc) + return xc, err + } + pvh.pvshim_path = C.CString(tmp.PvshimPath) + pvh.pvshim_cmdline = C.CString(tmp.PvshimCmdline) + pvh.pvshim_extra = C.CString(tmp.PvshimExtra) + pvhBytes := C.GoBytes(unsafe.Pointer(&pvh), C.sizeof_libxl_domain_build_info_type_union_pvh) + copy(xc.u[:], pvhBytes) + default: + return xc, fmt.Errorf("invalid union key '%v'", x.Type) + } xc.arch_arm.gic_version = C.libxl_gic_version(x.ArchArm.GicVersion) xc.arch_arm.vuart = C.libxl_vuart_type(x.ArchArm.Vuart) xc.altp2m = C.libxl_altp2m_mode(x.Altp2M) @@ -1575,6 +1800,22 @@ func (x *DeviceUsbdev) toC() (xc C.libxl_device_usbdev, err error) { C.libxl_device_usbdev_init(&xc) xc.ctrl = C.libxl_devid(x.Ctrl) xc.port = C.int(x.Port) + xc._type = C.libxl_usbdev_type(x.Type) + switch x.Type { + case UsbdevTypeHostdev: + tmp, ok := x.TypeUnion.(DeviceUsbdevTypeUnionHostdev) + if !ok { + C.libxl_device_usbdev_dispose(&xc) + return xc, errors.New("wrong type for union key type") + } + var hostdev C.libxl_device_usbdev_type_union_hostdev + hostdev.hostbus = C.uint8_t(tmp.Hostbus) + hostdev.hostaddr = C.uint8_t(tmp.Hostaddr) + hostdevBytes := C.GoBytes(unsafe.Pointer(&hostdev), C.sizeof_libxl_device_usbdev_type_union_hostdev) + copy(xc.u[:], hostdevBytes) + default: + return xc, fmt.Errorf("invalid union key '%v'", x.Type) + } return xc, nil } @@ -1685,6 +1926,21 @@ func (x *DeviceChannel) toC() (xc C.libxl_device_channel, err error) { xc.backend_domname = C.CString(x.BackendDomname) xc.devid = C.libxl_devid(x.Devid) xc.name = C.CString(x.Name) + xc.connection = C.libxl_channel_connection(x.Connection) + switch x.Connection { + case ChannelConnectionSocket: + tmp, ok := x.ConnectionUnion.(DeviceChannelConnectionUnionSocket) + if !ok { + C.libxl_device_channel_dispose(&xc) + return xc, errors.New("wrong type for union key connection") + } + var socket C.libxl_device_channel_connection_union_socket + socket.path = C.CString(tmp.Path) + socketBytes := C.GoBytes(unsafe.Pointer(&socket), C.sizeof_libxl_device_channel_connection_union_socket) + copy(xc.u[:], socketBytes) + default: + return xc, fmt.Errorf("invalid union key '%v'", x.Connection) + } return xc, nil } @@ -2647,6 +2903,46 @@ func (x *Event) toC() (xc C.libxl_event, err error) { return xc, err } xc.for_user = C.uint64_t(x.ForUser) + xc._type = C.libxl_event_type(x.Type) + switch x.Type { + case EventTypeDomainShutdown: + tmp, ok := x.TypeUnion.(EventTypeUnionDomainShutdown) + if !ok { + C.libxl_event_dispose(&xc) + return xc, errors.New("wrong type for union key type") + } + var domain_shutdown C.libxl_event_type_union_domain_shutdown + domain_shutdown.shutdown_reason = C.uint8_t(tmp.ShutdownReason) + domain_shutdownBytes := C.GoBytes(unsafe.Pointer(&domain_shutdown), C.sizeof_libxl_event_type_union_domain_shutdown) + copy(xc.u[:], domain_shutdownBytes) + case EventTypeDiskEject: + tmp, ok := x.TypeUnion.(EventTypeUnionDiskEject) + if !ok { + C.libxl_event_dispose(&xc) + return xc, errors.New("wrong type for union key type") + } + var disk_eject C.libxl_event_type_union_disk_eject + disk_eject.vdev = C.CString(tmp.Vdev) + disk_eject.disk, err = tmp.Disk.toC() + if err != nil { + C.libxl_event_dispose(&xc) + return xc, err + } + disk_ejectBytes := C.GoBytes(unsafe.Pointer(&disk_eject), C.sizeof_libxl_event_type_union_disk_eject) + copy(xc.u[:], disk_ejectBytes) + case EventTypeOperationComplete: + tmp, ok := x.TypeUnion.(EventTypeUnionOperationComplete) + if !ok { + C.libxl_event_dispose(&xc) + return xc, errors.New("wrong type for union key type") + } + var operation_complete C.libxl_event_type_union_operation_complete + operation_complete.rc = C.int(tmp.Rc) + operation_completeBytes := C.GoBytes(unsafe.Pointer(&operation_complete), C.sizeof_libxl_event_type_union_operation_complete) + copy(xc.u[:], operation_completeBytes) + default: + return xc, fmt.Errorf("invalid union key '%v'", x.Type) + } return xc, nil } @@ -2716,5 +3012,34 @@ func (x *PsrHwInfoTypeUnionMba) fromC(xc *C.libxl_psr_hw_info) error { func (x *PsrHwInfo) toC() (xc C.libxl_psr_hw_info, err error) { C.libxl_psr_hw_info_init(&xc) xc.id = C.uint32_t(x.Id) + xc._type = C.libxl_psr_feat_type(x.Type) + switch x.Type { + case PsrFeatTypeCat: + tmp, ok := x.TypeUnion.(PsrHwInfoTypeUnionCat) + if !ok { + C.libxl_psr_hw_info_dispose(&xc) + return xc, errors.New("wrong type for union key type") + } + var cat C.libxl_psr_hw_info_type_union_cat + cat.cos_max = C.uint32_t(tmp.CosMax) + cat.cbm_len = C.uint32_t(tmp.CbmLen) + cat.cdp_enabled = C.bool(tmp.CdpEnabled) + catBytes := C.GoBytes(unsafe.Pointer(&cat), C.sizeof_libxl_psr_hw_info_type_union_cat) + copy(xc.u[:], catBytes) + case PsrFeatTypeMba: + tmp, ok := x.TypeUnion.(PsrHwInfoTypeUnionMba) + if !ok { + C.libxl_psr_hw_info_dispose(&xc) + return xc, errors.New("wrong type for union key type") + } + var mba C.libxl_psr_hw_info_type_union_mba + mba.cos_max = C.uint32_t(tmp.CosMax) + mba.thrtl_max = C.uint32_t(tmp.ThrtlMax) + mba.linear = C.bool(tmp.Linear) + mbaBytes := C.GoBytes(unsafe.Pointer(&mba), C.sizeof_libxl_psr_hw_info_type_union_mba) + copy(xc.u[:], mbaBytes) + default: + return xc, fmt.Errorf("invalid union key '%v'", x.Type) + } return xc, nil }