All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] initialize xenlight go module
@ 2020-05-13  0:58 Nick Rosbrook
  2020-05-13  0:58 ` [PATCH v2 1/3] golang/xenlight: re-track generated go code Nick Rosbrook
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Nick Rosbrook @ 2020-05-13  0:58 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Andrew Cooper,
	Ian Jackson, George Dunlap, Nick Rosbrook, Jan Beulich

These patches setup an initial Go module for the xenlight package. The
go code is tracked again, since the module is defined in xen.git as
xenbits.xenproject.org/git-http/xen.git/tools/golang/xenlight. The final patch
adds a README and LICENSE to tools/golang/xenlight so that the package
will show up properly on pkg.go.dev and be available via the module
proxy at proxy.golang.org.

Changes in v2:
 - Use xenproject.org instead of xen.org in module path.
 - Use `go build` instead of `go install` in xenlight Makefile.
 - Use LGPL instead of GPL for xenlight LICENSE.
 - Add entry for xenlight package in SUPPORT.md.
 - Change some wording in the README for clarity. 

Nick Rosbrook (3):
  golang/xenlight: re-track generated go code
  golang/xenlight: init xenlight go module
  golang/xenlight: add necessary module/package documentation

 .gitignore                           |    3 -
 .hgignore                            |    2 -
 SUPPORT.md                           |    6 +
 tools/golang/xenlight/LICENSE        |  198 ++
 tools/golang/xenlight/Makefile       |    3 +-
 tools/golang/xenlight/README.md      |   17 +
 tools/golang/xenlight/go.mod         |    1 +
 tools/golang/xenlight/helpers.gen.go | 4728 ++++++++++++++++++++++++++
 tools/golang/xenlight/types.gen.go   | 1226 +++++++
 tools/golang/xenlight/xenlight.go    |    2 +
 10 files changed, 6179 insertions(+), 7 deletions(-)
 create mode 100644 tools/golang/xenlight/LICENSE
 create mode 100644 tools/golang/xenlight/README.md
 create mode 100644 tools/golang/xenlight/go.mod
 create mode 100644 tools/golang/xenlight/helpers.gen.go
 create mode 100644 tools/golang/xenlight/types.gen.go

-- 
2.17.1



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/3] golang/xenlight: re-track generated go code
  2020-05-13  0:58 [PATCH v2 0/3] initialize xenlight go module Nick Rosbrook
@ 2020-05-13  0:58 ` Nick Rosbrook
  2020-05-13  0:58 ` [PATCH v2 2/3] golang/xenlight: init xenlight go module Nick Rosbrook
  2020-05-13  0:58 ` [PATCH v2 3/3] golang/xenlight: add necessary module/package documentation Nick Rosbrook
  2 siblings, 0 replies; 9+ messages in thread
From: Nick Rosbrook @ 2020-05-13  0:58 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Andrew Cooper,
	Ian Jackson, George Dunlap, Nick Rosbrook, Jan Beulich

Commit df669de074c395a3b2eeb975fddd3da4c148da13 un-tracked the generated
Go code, but it was decided that we actually keep the generated code
in-tree.

Undo the changes to ignore the generated code, and re-generate it.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
Reviewed-by: George Dunlap <george.dunlap@citrix.com>
---
 .gitignore                           |    3 -
 .hgignore                            |    2 -
 tools/golang/xenlight/Makefile       |    1 -
 tools/golang/xenlight/helpers.gen.go | 4728 ++++++++++++++++++++++++++
 tools/golang/xenlight/types.gen.go   | 1226 +++++++
 5 files changed, 5954 insertions(+), 6 deletions(-)
 create mode 100644 tools/golang/xenlight/helpers.gen.go
 create mode 100644 tools/golang/xenlight/types.gen.go

diff --git a/.gitignore b/.gitignore
index 9c8a31f896..bfa53723b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -406,9 +406,6 @@ tools/xenstore/xenstore-watch
 tools/xl/_paths.h
 tools/xl/xl
 
-tools/golang/src
-tools/golang/*/*.gen.go
-
 docs/txt/misc/*.txt
 docs/txt/man/*.txt
 docs/figs/*.png
diff --git a/.hgignore b/.hgignore
index 2ec52982e1..2d41670632 100644
--- a/.hgignore
+++ b/.hgignore
@@ -282,8 +282,6 @@
 ^tools/ocaml/test/xtl$
 ^tools/ocaml/test/send_debug_keys$
 ^tools/ocaml/test/list_domains$
-^tools/golang/src$
-^tools/golang/.*/.*\.gen\.go$
 ^tools/autom4te\.cache$
 ^tools/config\.h$
 ^tools/config\.log$
diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
index 144c133ced..753132306a 100644
--- a/tools/golang/xenlight/Makefile
+++ b/tools/golang/xenlight/Makefile
@@ -49,7 +49,6 @@ install: build
 clean:
 	$(RM) -r $(XEN_GOPATH)$(GOXL_PKG_DIR)
 	$(RM) $(XEN_GOPATH)/pkg/*/$(XEN_GOCODE_URL)/xenlight.a
-	$(RM) *.gen.go
 
 .PHONY: distclean
 distclean: clean
diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
new file mode 100644
index 0000000000..109e9515a2
--- /dev/null
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -0,0 +1,4728 @@
+// DO NOT EDIT.
+//
+// This file is generated by:
+// gengotypes.py ../../libxl/libxl_types.idl
+//
+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"
+
+// NewIoportRange returns an instance of IoportRange initialized with defaults.
+func NewIoportRange() (*IoportRange, error) {
+	var (
+		x  IoportRange
+		xc C.libxl_ioport_range
+	)
+
+	C.libxl_ioport_range_init(&xc)
+	defer C.libxl_ioport_range_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *IoportRange) fromC(xc *C.libxl_ioport_range) error {
+	x.First = uint32(xc.first)
+	x.Number = uint32(xc.number)
+
+	return nil
+}
+
+func (x *IoportRange) toC(xc *C.libxl_ioport_range) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_ioport_range_dispose(xc)
+		}
+	}()
+
+	xc.first = C.uint32_t(x.First)
+	xc.number = C.uint32_t(x.Number)
+
+	return nil
+}
+
+// NewIomemRange returns an instance of IomemRange initialized with defaults.
+func NewIomemRange() (*IomemRange, error) {
+	var (
+		x  IomemRange
+		xc C.libxl_iomem_range
+	)
+
+	C.libxl_iomem_range_init(&xc)
+	defer C.libxl_iomem_range_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *IomemRange) fromC(xc *C.libxl_iomem_range) error {
+	x.Start = uint64(xc.start)
+	x.Number = uint64(xc.number)
+	x.Gfn = uint64(xc.gfn)
+
+	return nil
+}
+
+func (x *IomemRange) toC(xc *C.libxl_iomem_range) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_iomem_range_dispose(xc)
+		}
+	}()
+
+	xc.start = C.uint64_t(x.Start)
+	xc.number = C.uint64_t(x.Number)
+	xc.gfn = C.uint64_t(x.Gfn)
+
+	return nil
+}
+
+// NewVgaInterfaceInfo returns an instance of VgaInterfaceInfo initialized with defaults.
+func NewVgaInterfaceInfo() (*VgaInterfaceInfo, error) {
+	var (
+		x  VgaInterfaceInfo
+		xc C.libxl_vga_interface_info
+	)
+
+	C.libxl_vga_interface_info_init(&xc)
+	defer C.libxl_vga_interface_info_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *VgaInterfaceInfo) fromC(xc *C.libxl_vga_interface_info) error {
+	x.Kind = VgaInterfaceType(xc.kind)
+
+	return nil
+}
+
+func (x *VgaInterfaceInfo) toC(xc *C.libxl_vga_interface_info) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vga_interface_info_dispose(xc)
+		}
+	}()
+
+	xc.kind = C.libxl_vga_interface_type(x.Kind)
+
+	return nil
+}
+
+// NewVncInfo returns an instance of VncInfo initialized with defaults.
+func NewVncInfo() (*VncInfo, error) {
+	var (
+		x  VncInfo
+		xc C.libxl_vnc_info
+	)
+
+	C.libxl_vnc_info_init(&xc)
+	defer C.libxl_vnc_info_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *VncInfo) fromC(xc *C.libxl_vnc_info) error {
+	if err := x.Enable.fromC(&xc.enable); err != nil {
+		return fmt.Errorf("converting field Enable: %v", err)
+	}
+	x.Listen = C.GoString(xc.listen)
+	x.Passwd = C.GoString(xc.passwd)
+	x.Display = int(xc.display)
+	if err := x.Findunused.fromC(&xc.findunused); err != nil {
+		return fmt.Errorf("converting field Findunused: %v", err)
+	}
+
+	return nil
+}
+
+func (x *VncInfo) toC(xc *C.libxl_vnc_info) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vnc_info_dispose(xc)
+		}
+	}()
+
+	if err := x.Enable.toC(&xc.enable); err != nil {
+		return fmt.Errorf("converting field Enable: %v", err)
+	}
+	if x.Listen != "" {
+		xc.listen = C.CString(x.Listen)
+	}
+	if x.Passwd != "" {
+		xc.passwd = C.CString(x.Passwd)
+	}
+	xc.display = C.int(x.Display)
+	if err := x.Findunused.toC(&xc.findunused); err != nil {
+		return fmt.Errorf("converting field Findunused: %v", err)
+	}
+
+	return nil
+}
+
+// NewSpiceInfo returns an instance of SpiceInfo initialized with defaults.
+func NewSpiceInfo() (*SpiceInfo, error) {
+	var (
+		x  SpiceInfo
+		xc C.libxl_spice_info
+	)
+
+	C.libxl_spice_info_init(&xc)
+	defer C.libxl_spice_info_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *SpiceInfo) fromC(xc *C.libxl_spice_info) error {
+	if err := x.Enable.fromC(&xc.enable); err != nil {
+		return fmt.Errorf("converting field Enable: %v", err)
+	}
+	x.Port = int(xc.port)
+	x.TlsPort = int(xc.tls_port)
+	x.Host = C.GoString(xc.host)
+	if err := x.DisableTicketing.fromC(&xc.disable_ticketing); err != nil {
+		return fmt.Errorf("converting field DisableTicketing: %v", err)
+	}
+	x.Passwd = C.GoString(xc.passwd)
+	if err := x.AgentMouse.fromC(&xc.agent_mouse); err != nil {
+		return fmt.Errorf("converting field AgentMouse: %v", err)
+	}
+	if err := x.Vdagent.fromC(&xc.vdagent); err != nil {
+		return fmt.Errorf("converting field Vdagent: %v", err)
+	}
+	if err := x.ClipboardSharing.fromC(&xc.clipboard_sharing); err != nil {
+		return fmt.Errorf("converting field ClipboardSharing: %v", err)
+	}
+	x.Usbredirection = int(xc.usbredirection)
+	x.ImageCompression = C.GoString(xc.image_compression)
+	x.StreamingVideo = C.GoString(xc.streaming_video)
+
+	return nil
+}
+
+func (x *SpiceInfo) toC(xc *C.libxl_spice_info) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_spice_info_dispose(xc)
+		}
+	}()
+
+	if err := x.Enable.toC(&xc.enable); err != nil {
+		return fmt.Errorf("converting field Enable: %v", err)
+	}
+	xc.port = C.int(x.Port)
+	xc.tls_port = C.int(x.TlsPort)
+	if x.Host != "" {
+		xc.host = C.CString(x.Host)
+	}
+	if err := x.DisableTicketing.toC(&xc.disable_ticketing); err != nil {
+		return fmt.Errorf("converting field DisableTicketing: %v", err)
+	}
+	if x.Passwd != "" {
+		xc.passwd = C.CString(x.Passwd)
+	}
+	if err := x.AgentMouse.toC(&xc.agent_mouse); err != nil {
+		return fmt.Errorf("converting field AgentMouse: %v", err)
+	}
+	if err := x.Vdagent.toC(&xc.vdagent); err != nil {
+		return fmt.Errorf("converting field Vdagent: %v", err)
+	}
+	if err := x.ClipboardSharing.toC(&xc.clipboard_sharing); err != nil {
+		return fmt.Errorf("converting field ClipboardSharing: %v", err)
+	}
+	xc.usbredirection = C.int(x.Usbredirection)
+	if x.ImageCompression != "" {
+		xc.image_compression = C.CString(x.ImageCompression)
+	}
+	if x.StreamingVideo != "" {
+		xc.streaming_video = C.CString(x.StreamingVideo)
+	}
+
+	return nil
+}
+
+// NewSdlInfo returns an instance of SdlInfo initialized with defaults.
+func NewSdlInfo() (*SdlInfo, error) {
+	var (
+		x  SdlInfo
+		xc C.libxl_sdl_info
+	)
+
+	C.libxl_sdl_info_init(&xc)
+	defer C.libxl_sdl_info_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *SdlInfo) fromC(xc *C.libxl_sdl_info) error {
+	if err := x.Enable.fromC(&xc.enable); err != nil {
+		return fmt.Errorf("converting field Enable: %v", err)
+	}
+	if err := x.Opengl.fromC(&xc.opengl); err != nil {
+		return fmt.Errorf("converting field Opengl: %v", err)
+	}
+	x.Display = C.GoString(xc.display)
+	x.Xauthority = C.GoString(xc.xauthority)
+
+	return nil
+}
+
+func (x *SdlInfo) toC(xc *C.libxl_sdl_info) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_sdl_info_dispose(xc)
+		}
+	}()
+
+	if err := x.Enable.toC(&xc.enable); err != nil {
+		return fmt.Errorf("converting field Enable: %v", err)
+	}
+	if err := x.Opengl.toC(&xc.opengl); err != nil {
+		return fmt.Errorf("converting field Opengl: %v", err)
+	}
+	if x.Display != "" {
+		xc.display = C.CString(x.Display)
+	}
+	if x.Xauthority != "" {
+		xc.xauthority = C.CString(x.Xauthority)
+	}
+
+	return nil
+}
+
+// NewDominfo returns an instance of Dominfo initialized with defaults.
+func NewDominfo() (*Dominfo, error) {
+	var (
+		x  Dominfo
+		xc C.libxl_dominfo
+	)
+
+	C.libxl_dominfo_init(&xc)
+	defer C.libxl_dominfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Dominfo) fromC(xc *C.libxl_dominfo) error {
+	if err := x.Uuid.fromC(&xc.uuid); err != nil {
+		return fmt.Errorf("converting field Uuid: %v", err)
+	}
+	x.Domid = Domid(xc.domid)
+	x.Ssidref = uint32(xc.ssidref)
+	x.SsidLabel = C.GoString(xc.ssid_label)
+	x.Running = bool(xc.running)
+	x.Blocked = bool(xc.blocked)
+	x.Paused = bool(xc.paused)
+	x.Shutdown = bool(xc.shutdown)
+	x.Dying = bool(xc.dying)
+	x.NeverStop = bool(xc.never_stop)
+	x.ShutdownReason = ShutdownReason(xc.shutdown_reason)
+	x.OutstandingMemkb = uint64(xc.outstanding_memkb)
+	x.CurrentMemkb = uint64(xc.current_memkb)
+	x.SharedMemkb = uint64(xc.shared_memkb)
+	x.PagedMemkb = uint64(xc.paged_memkb)
+	x.MaxMemkb = uint64(xc.max_memkb)
+	x.CpuTime = uint64(xc.cpu_time)
+	x.VcpuMaxId = uint32(xc.vcpu_max_id)
+	x.VcpuOnline = uint32(xc.vcpu_online)
+	x.Cpupool = uint32(xc.cpupool)
+	x.DomainType = DomainType(xc.domain_type)
+
+	return nil
+}
+
+func (x *Dominfo) toC(xc *C.libxl_dominfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_dominfo_dispose(xc)
+		}
+	}()
+
+	if err := x.Uuid.toC(&xc.uuid); err != nil {
+		return fmt.Errorf("converting field Uuid: %v", err)
+	}
+	xc.domid = C.libxl_domid(x.Domid)
+	xc.ssidref = C.uint32_t(x.Ssidref)
+	if x.SsidLabel != "" {
+		xc.ssid_label = C.CString(x.SsidLabel)
+	}
+	xc.running = C.bool(x.Running)
+	xc.blocked = C.bool(x.Blocked)
+	xc.paused = C.bool(x.Paused)
+	xc.shutdown = C.bool(x.Shutdown)
+	xc.dying = C.bool(x.Dying)
+	xc.never_stop = C.bool(x.NeverStop)
+	xc.shutdown_reason = C.libxl_shutdown_reason(x.ShutdownReason)
+	xc.outstanding_memkb = C.uint64_t(x.OutstandingMemkb)
+	xc.current_memkb = C.uint64_t(x.CurrentMemkb)
+	xc.shared_memkb = C.uint64_t(x.SharedMemkb)
+	xc.paged_memkb = C.uint64_t(x.PagedMemkb)
+	xc.max_memkb = C.uint64_t(x.MaxMemkb)
+	xc.cpu_time = C.uint64_t(x.CpuTime)
+	xc.vcpu_max_id = C.uint32_t(x.VcpuMaxId)
+	xc.vcpu_online = C.uint32_t(x.VcpuOnline)
+	xc.cpupool = C.uint32_t(x.Cpupool)
+	xc.domain_type = C.libxl_domain_type(x.DomainType)
+
+	return nil
+}
+
+// NewCpupoolinfo returns an instance of Cpupoolinfo initialized with defaults.
+func NewCpupoolinfo() (*Cpupoolinfo, error) {
+	var (
+		x  Cpupoolinfo
+		xc C.libxl_cpupoolinfo
+	)
+
+	C.libxl_cpupoolinfo_init(&xc)
+	defer C.libxl_cpupoolinfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Cpupoolinfo) fromC(xc *C.libxl_cpupoolinfo) error {
+	x.Poolid = uint32(xc.poolid)
+	x.PoolName = C.GoString(xc.pool_name)
+	x.Sched = Scheduler(xc.sched)
+	x.NDom = uint32(xc.n_dom)
+	if err := x.Cpumap.fromC(&xc.cpumap); err != nil {
+		return fmt.Errorf("converting field Cpumap: %v", err)
+	}
+
+	return nil
+}
+
+func (x *Cpupoolinfo) toC(xc *C.libxl_cpupoolinfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_cpupoolinfo_dispose(xc)
+		}
+	}()
+
+	xc.poolid = C.uint32_t(x.Poolid)
+	if x.PoolName != "" {
+		xc.pool_name = C.CString(x.PoolName)
+	}
+	xc.sched = C.libxl_scheduler(x.Sched)
+	xc.n_dom = C.uint32_t(x.NDom)
+	if err := x.Cpumap.toC(&xc.cpumap); err != nil {
+		return fmt.Errorf("converting field Cpumap: %v", err)
+	}
+
+	return nil
+}
+
+// NewChannelinfo returns an instance of Channelinfo initialized with defaults.
+func NewChannelinfo(connection ChannelConnection) (*Channelinfo, error) {
+	var (
+		x  Channelinfo
+		xc C.libxl_channelinfo
+	)
+
+	C.libxl_channelinfo_init(&xc)
+	C.libxl_channelinfo_init_connection(&xc, C.libxl_channel_connection(connection))
+	defer C.libxl_channelinfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Channelinfo) fromC(xc *C.libxl_channelinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.Rref = int(xc.rref)
+	x.Connection = ChannelConnection(xc.connection)
+	switch x.Connection {
+	case ChannelConnectionUnknown:
+		x.ConnectionUnion = nil
+	case ChannelConnectionPty:
+		var connectionPty ChannelinfoConnectionUnionPty
+		if err := connectionPty.fromC(xc); err != nil {
+			return fmt.Errorf("converting field connectionPty: %v", err)
+		}
+		x.ConnectionUnion = connectionPty
+	case ChannelConnectionSocket:
+		x.ConnectionUnion = nil
+	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 *Channelinfo) toC(xc *C.libxl_channelinfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_channelinfo_dispose(xc)
+		}
+	}()
+
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
+	xc.backend_id = C.uint32_t(x.BackendId)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
+	xc.frontend_id = C.uint32_t(x.FrontendId)
+	xc.devid = C.libxl_devid(x.Devid)
+	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 ChannelConnectionUnknown:
+		break
+	case ChannelConnectionPty:
+		tmp, ok := x.ConnectionUnion.(ChannelinfoConnectionUnionPty)
+		if !ok {
+			return errors.New("wrong type for union key connection")
+		}
+		var pty C.libxl_channelinfo_connection_union_pty
+		if tmp.Path != "" {
+			pty.path = C.CString(tmp.Path)
+		}
+		ptyBytes := C.GoBytes(unsafe.Pointer(&pty), C.sizeof_libxl_channelinfo_connection_union_pty)
+		copy(xc.u[:], ptyBytes)
+	case ChannelConnectionSocket:
+		break
+	default:
+		return fmt.Errorf("invalid union key '%v'", x.Connection)
+	}
+
+	return nil
+}
+
+// NewVminfo returns an instance of Vminfo initialized with defaults.
+func NewVminfo() (*Vminfo, error) {
+	var (
+		x  Vminfo
+		xc C.libxl_vminfo
+	)
+
+	C.libxl_vminfo_init(&xc)
+	defer C.libxl_vminfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Vminfo) fromC(xc *C.libxl_vminfo) error {
+	if err := x.Uuid.fromC(&xc.uuid); err != nil {
+		return fmt.Errorf("converting field Uuid: %v", err)
+	}
+	x.Domid = Domid(xc.domid)
+
+	return nil
+}
+
+func (x *Vminfo) toC(xc *C.libxl_vminfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vminfo_dispose(xc)
+		}
+	}()
+
+	if err := x.Uuid.toC(&xc.uuid); err != nil {
+		return fmt.Errorf("converting field Uuid: %v", err)
+	}
+	xc.domid = C.libxl_domid(x.Domid)
+
+	return nil
+}
+
+// NewVersionInfo returns an instance of VersionInfo initialized with defaults.
+func NewVersionInfo() (*VersionInfo, error) {
+	var (
+		x  VersionInfo
+		xc C.libxl_version_info
+	)
+
+	C.libxl_version_info_init(&xc)
+	defer C.libxl_version_info_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *VersionInfo) fromC(xc *C.libxl_version_info) error {
+	x.XenVersionMajor = int(xc.xen_version_major)
+	x.XenVersionMinor = int(xc.xen_version_minor)
+	x.XenVersionExtra = C.GoString(xc.xen_version_extra)
+	x.Compiler = C.GoString(xc.compiler)
+	x.CompileBy = C.GoString(xc.compile_by)
+	x.CompileDomain = C.GoString(xc.compile_domain)
+	x.CompileDate = C.GoString(xc.compile_date)
+	x.Capabilities = C.GoString(xc.capabilities)
+	x.Changeset = C.GoString(xc.changeset)
+	x.VirtStart = uint64(xc.virt_start)
+	x.Pagesize = int(xc.pagesize)
+	x.Commandline = C.GoString(xc.commandline)
+	x.BuildId = C.GoString(xc.build_id)
+
+	return nil
+}
+
+func (x *VersionInfo) toC(xc *C.libxl_version_info) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_version_info_dispose(xc)
+		}
+	}()
+
+	xc.xen_version_major = C.int(x.XenVersionMajor)
+	xc.xen_version_minor = C.int(x.XenVersionMinor)
+	if x.XenVersionExtra != "" {
+		xc.xen_version_extra = C.CString(x.XenVersionExtra)
+	}
+	if x.Compiler != "" {
+		xc.compiler = C.CString(x.Compiler)
+	}
+	if x.CompileBy != "" {
+		xc.compile_by = C.CString(x.CompileBy)
+	}
+	if x.CompileDomain != "" {
+		xc.compile_domain = C.CString(x.CompileDomain)
+	}
+	if x.CompileDate != "" {
+		xc.compile_date = C.CString(x.CompileDate)
+	}
+	if x.Capabilities != "" {
+		xc.capabilities = C.CString(x.Capabilities)
+	}
+	if x.Changeset != "" {
+		xc.changeset = C.CString(x.Changeset)
+	}
+	xc.virt_start = C.uint64_t(x.VirtStart)
+	xc.pagesize = C.int(x.Pagesize)
+	if x.Commandline != "" {
+		xc.commandline = C.CString(x.Commandline)
+	}
+	if x.BuildId != "" {
+		xc.build_id = C.CString(x.BuildId)
+	}
+
+	return nil
+}
+
+// NewDomainCreateInfo returns an instance of DomainCreateInfo initialized with defaults.
+func NewDomainCreateInfo() (*DomainCreateInfo, error) {
+	var (
+		x  DomainCreateInfo
+		xc C.libxl_domain_create_info
+	)
+
+	C.libxl_domain_create_info_init(&xc)
+	defer C.libxl_domain_create_info_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DomainCreateInfo) fromC(xc *C.libxl_domain_create_info) error {
+	x.Type = DomainType(xc._type)
+	if err := x.Hap.fromC(&xc.hap); err != nil {
+		return fmt.Errorf("converting field Hap: %v", err)
+	}
+	if err := x.Oos.fromC(&xc.oos); err != nil {
+		return fmt.Errorf("converting field Oos: %v", err)
+	}
+	x.Ssidref = uint32(xc.ssidref)
+	x.SsidLabel = C.GoString(xc.ssid_label)
+	x.Name = C.GoString(xc.name)
+	x.Domid = Domid(xc.domid)
+	if err := x.Uuid.fromC(&xc.uuid); err != nil {
+		return fmt.Errorf("converting field Uuid: %v", err)
+	}
+	if err := x.Xsdata.fromC(&xc.xsdata); err != nil {
+		return fmt.Errorf("converting field Xsdata: %v", err)
+	}
+	if err := x.Platformdata.fromC(&xc.platformdata); err != nil {
+		return fmt.Errorf("converting field Platformdata: %v", err)
+	}
+	x.Poolid = uint32(xc.poolid)
+	x.PoolName = C.GoString(xc.pool_name)
+	if err := x.RunHotplugScripts.fromC(&xc.run_hotplug_scripts); err != nil {
+		return fmt.Errorf("converting field RunHotplugScripts: %v", err)
+	}
+	if err := x.DriverDomain.fromC(&xc.driver_domain); err != nil {
+		return fmt.Errorf("converting field DriverDomain: %v", err)
+	}
+	x.Passthrough = Passthrough(xc.passthrough)
+	if err := x.XendSuspendEvtchnCompat.fromC(&xc.xend_suspend_evtchn_compat); err != nil {
+		return fmt.Errorf("converting field XendSuspendEvtchnCompat: %v", err)
+	}
+
+	return nil
+}
+
+func (x *DomainCreateInfo) toC(xc *C.libxl_domain_create_info) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_domain_create_info_dispose(xc)
+		}
+	}()
+
+	xc._type = C.libxl_domain_type(x.Type)
+	if err := x.Hap.toC(&xc.hap); err != nil {
+		return fmt.Errorf("converting field Hap: %v", err)
+	}
+	if err := x.Oos.toC(&xc.oos); err != nil {
+		return fmt.Errorf("converting field Oos: %v", err)
+	}
+	xc.ssidref = C.uint32_t(x.Ssidref)
+	if x.SsidLabel != "" {
+		xc.ssid_label = C.CString(x.SsidLabel)
+	}
+	if x.Name != "" {
+		xc.name = C.CString(x.Name)
+	}
+	xc.domid = C.libxl_domid(x.Domid)
+	if err := x.Uuid.toC(&xc.uuid); err != nil {
+		return fmt.Errorf("converting field Uuid: %v", err)
+	}
+	if err := x.Xsdata.toC(&xc.xsdata); err != nil {
+		return fmt.Errorf("converting field Xsdata: %v", err)
+	}
+	if err := x.Platformdata.toC(&xc.platformdata); err != nil {
+		return fmt.Errorf("converting field Platformdata: %v", err)
+	}
+	xc.poolid = C.uint32_t(x.Poolid)
+	if x.PoolName != "" {
+		xc.pool_name = C.CString(x.PoolName)
+	}
+	if err := x.RunHotplugScripts.toC(&xc.run_hotplug_scripts); err != nil {
+		return fmt.Errorf("converting field RunHotplugScripts: %v", err)
+	}
+	if err := x.DriverDomain.toC(&xc.driver_domain); err != nil {
+		return fmt.Errorf("converting field DriverDomain: %v", err)
+	}
+	xc.passthrough = C.libxl_passthrough(x.Passthrough)
+	if err := x.XendSuspendEvtchnCompat.toC(&xc.xend_suspend_evtchn_compat); err != nil {
+		return fmt.Errorf("converting field XendSuspendEvtchnCompat: %v", err)
+	}
+
+	return nil
+}
+
+// NewDomainRestoreParams returns an instance of DomainRestoreParams initialized with defaults.
+func NewDomainRestoreParams() (*DomainRestoreParams, error) {
+	var (
+		x  DomainRestoreParams
+		xc C.libxl_domain_restore_params
+	)
+
+	C.libxl_domain_restore_params_init(&xc)
+	defer C.libxl_domain_restore_params_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DomainRestoreParams) fromC(xc *C.libxl_domain_restore_params) error {
+	x.CheckpointedStream = int(xc.checkpointed_stream)
+	x.StreamVersion = uint32(xc.stream_version)
+	x.ColoProxyScript = C.GoString(xc.colo_proxy_script)
+	if err := x.UserspaceColoProxy.fromC(&xc.userspace_colo_proxy); err != nil {
+		return fmt.Errorf("converting field UserspaceColoProxy: %v", err)
+	}
+
+	return nil
+}
+
+func (x *DomainRestoreParams) toC(xc *C.libxl_domain_restore_params) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_domain_restore_params_dispose(xc)
+		}
+	}()
+
+	xc.checkpointed_stream = C.int(x.CheckpointedStream)
+	xc.stream_version = C.uint32_t(x.StreamVersion)
+	if x.ColoProxyScript != "" {
+		xc.colo_proxy_script = C.CString(x.ColoProxyScript)
+	}
+	if err := x.UserspaceColoProxy.toC(&xc.userspace_colo_proxy); err != nil {
+		return fmt.Errorf("converting field UserspaceColoProxy: %v", err)
+	}
+
+	return nil
+}
+
+// NewSchedParams returns an instance of SchedParams initialized with defaults.
+func NewSchedParams() (*SchedParams, error) {
+	var (
+		x  SchedParams
+		xc C.libxl_sched_params
+	)
+
+	C.libxl_sched_params_init(&xc)
+	defer C.libxl_sched_params_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *SchedParams) fromC(xc *C.libxl_sched_params) error {
+	x.Vcpuid = int(xc.vcpuid)
+	x.Weight = int(xc.weight)
+	x.Cap = int(xc.cap)
+	x.Period = int(xc.period)
+	x.Extratime = int(xc.extratime)
+	x.Budget = int(xc.budget)
+
+	return nil
+}
+
+func (x *SchedParams) toC(xc *C.libxl_sched_params) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_sched_params_dispose(xc)
+		}
+	}()
+
+	xc.vcpuid = C.int(x.Vcpuid)
+	xc.weight = C.int(x.Weight)
+	xc.cap = C.int(x.Cap)
+	xc.period = C.int(x.Period)
+	xc.extratime = C.int(x.Extratime)
+	xc.budget = C.int(x.Budget)
+
+	return nil
+}
+
+// NewVcpuSchedParams returns an instance of VcpuSchedParams initialized with defaults.
+func NewVcpuSchedParams() (*VcpuSchedParams, error) {
+	var (
+		x  VcpuSchedParams
+		xc C.libxl_vcpu_sched_params
+	)
+
+	C.libxl_vcpu_sched_params_init(&xc)
+	defer C.libxl_vcpu_sched_params_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *VcpuSchedParams) fromC(xc *C.libxl_vcpu_sched_params) error {
+	x.Sched = Scheduler(xc.sched)
+	x.Vcpus = nil
+	if n := int(xc.num_vcpus); n > 0 {
+		cVcpus := (*[1 << 28]C.libxl_sched_params)(unsafe.Pointer(xc.vcpus))[:n:n]
+		x.Vcpus = make([]SchedParams, n)
+		for i, v := range cVcpus {
+			if err := x.Vcpus[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Vcpus: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+func (x *VcpuSchedParams) toC(xc *C.libxl_vcpu_sched_params) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vcpu_sched_params_dispose(xc)
+		}
+	}()
+
+	xc.sched = C.libxl_scheduler(x.Sched)
+	if numVcpus := len(x.Vcpus); numVcpus > 0 {
+		xc.vcpus = (*C.libxl_sched_params)(C.malloc(C.ulong(numVcpus) * C.sizeof_libxl_sched_params))
+		xc.num_vcpus = C.int(numVcpus)
+		cVcpus := (*[1 << 28]C.libxl_sched_params)(unsafe.Pointer(xc.vcpus))[:numVcpus:numVcpus]
+		for i, v := range x.Vcpus {
+			if err := v.toC(&cVcpus[i]); err != nil {
+				return fmt.Errorf("converting field Vcpus: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+// NewDomainSchedParams returns an instance of DomainSchedParams initialized with defaults.
+func NewDomainSchedParams() (*DomainSchedParams, error) {
+	var (
+		x  DomainSchedParams
+		xc C.libxl_domain_sched_params
+	)
+
+	C.libxl_domain_sched_params_init(&xc)
+	defer C.libxl_domain_sched_params_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DomainSchedParams) fromC(xc *C.libxl_domain_sched_params) error {
+	x.Sched = Scheduler(xc.sched)
+	x.Weight = int(xc.weight)
+	x.Cap = int(xc.cap)
+	x.Period = int(xc.period)
+	x.Budget = int(xc.budget)
+	x.Extratime = int(xc.extratime)
+	x.Slice = int(xc.slice)
+	x.Latency = int(xc.latency)
+
+	return nil
+}
+
+func (x *DomainSchedParams) toC(xc *C.libxl_domain_sched_params) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_domain_sched_params_dispose(xc)
+		}
+	}()
+
+	xc.sched = C.libxl_scheduler(x.Sched)
+	xc.weight = C.int(x.Weight)
+	xc.cap = C.int(x.Cap)
+	xc.period = C.int(x.Period)
+	xc.budget = C.int(x.Budget)
+	xc.extratime = C.int(x.Extratime)
+	xc.slice = C.int(x.Slice)
+	xc.latency = C.int(x.Latency)
+
+	return nil
+}
+
+// NewVnodeInfo returns an instance of VnodeInfo initialized with defaults.
+func NewVnodeInfo() (*VnodeInfo, error) {
+	var (
+		x  VnodeInfo
+		xc C.libxl_vnode_info
+	)
+
+	C.libxl_vnode_info_init(&xc)
+	defer C.libxl_vnode_info_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *VnodeInfo) fromC(xc *C.libxl_vnode_info) error {
+	x.Memkb = uint64(xc.memkb)
+	x.Distances = nil
+	if n := int(xc.num_distances); n > 0 {
+		cDistances := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.distances))[:n:n]
+		x.Distances = make([]uint32, n)
+		for i, v := range cDistances {
+			x.Distances[i] = uint32(v)
+		}
+	}
+	x.Pnode = uint32(xc.pnode)
+	if err := x.Vcpus.fromC(&xc.vcpus); err != nil {
+		return fmt.Errorf("converting field Vcpus: %v", err)
+	}
+
+	return nil
+}
+
+func (x *VnodeInfo) toC(xc *C.libxl_vnode_info) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vnode_info_dispose(xc)
+		}
+	}()
+
+	xc.memkb = C.uint64_t(x.Memkb)
+	if numDistances := len(x.Distances); numDistances > 0 {
+		xc.distances = (*C.uint32_t)(C.malloc(C.size_t(numDistances * numDistances)))
+		xc.num_distances = C.int(numDistances)
+		cDistances := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.distances))[:numDistances:numDistances]
+		for i, v := range x.Distances {
+			cDistances[i] = C.uint32_t(v)
+		}
+	}
+	xc.pnode = C.uint32_t(x.Pnode)
+	if err := x.Vcpus.toC(&xc.vcpus); err != nil {
+		return fmt.Errorf("converting field Vcpus: %v", err)
+	}
+
+	return nil
+}
+
+// NewRdmReserve returns an instance of RdmReserve initialized with defaults.
+func NewRdmReserve() (*RdmReserve, error) {
+	var (
+		x  RdmReserve
+		xc C.libxl_rdm_reserve
+	)
+
+	C.libxl_rdm_reserve_init(&xc)
+	defer C.libxl_rdm_reserve_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *RdmReserve) fromC(xc *C.libxl_rdm_reserve) error {
+	x.Strategy = RdmReserveStrategy(xc.strategy)
+	x.Policy = RdmReservePolicy(xc.policy)
+
+	return nil
+}
+
+func (x *RdmReserve) toC(xc *C.libxl_rdm_reserve) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_rdm_reserve_dispose(xc)
+		}
+	}()
+
+	xc.strategy = C.libxl_rdm_reserve_strategy(x.Strategy)
+	xc.policy = C.libxl_rdm_reserve_policy(x.Policy)
+
+	return nil
+}
+
+// NewDomainBuildInfo returns an instance of DomainBuildInfo initialized with defaults.
+func NewDomainBuildInfo(dtype DomainType) (*DomainBuildInfo, error) {
+	var (
+		x  DomainBuildInfo
+		xc C.libxl_domain_build_info
+	)
+
+	C.libxl_domain_build_info_init(&xc)
+	C.libxl_domain_build_info_init_type(&xc, C.libxl_domain_type(dtype))
+	defer C.libxl_domain_build_info_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DomainBuildInfo) fromC(xc *C.libxl_domain_build_info) error {
+	x.MaxVcpus = int(xc.max_vcpus)
+	if err := x.AvailVcpus.fromC(&xc.avail_vcpus); err != nil {
+		return fmt.Errorf("converting field AvailVcpus: %v", err)
+	}
+	if err := x.Cpumap.fromC(&xc.cpumap); err != nil {
+		return fmt.Errorf("converting field Cpumap: %v", err)
+	}
+	if err := x.Nodemap.fromC(&xc.nodemap); err != nil {
+		return fmt.Errorf("converting field Nodemap: %v", err)
+	}
+	x.VcpuHardAffinity = nil
+	if n := int(xc.num_vcpu_hard_affinity); n > 0 {
+		cVcpuHardAffinity := (*[1 << 28]C.libxl_bitmap)(unsafe.Pointer(xc.vcpu_hard_affinity))[:n:n]
+		x.VcpuHardAffinity = make([]Bitmap, n)
+		for i, v := range cVcpuHardAffinity {
+			if err := x.VcpuHardAffinity[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field VcpuHardAffinity: %v", err)
+			}
+		}
+	}
+	x.VcpuSoftAffinity = nil
+	if n := int(xc.num_vcpu_soft_affinity); n > 0 {
+		cVcpuSoftAffinity := (*[1 << 28]C.libxl_bitmap)(unsafe.Pointer(xc.vcpu_soft_affinity))[:n:n]
+		x.VcpuSoftAffinity = make([]Bitmap, n)
+		for i, v := range cVcpuSoftAffinity {
+			if err := x.VcpuSoftAffinity[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field VcpuSoftAffinity: %v", err)
+			}
+		}
+	}
+	if err := x.NumaPlacement.fromC(&xc.numa_placement); err != nil {
+		return fmt.Errorf("converting field NumaPlacement: %v", err)
+	}
+	x.TscMode = TscMode(xc.tsc_mode)
+	x.MaxMemkb = uint64(xc.max_memkb)
+	x.TargetMemkb = uint64(xc.target_memkb)
+	x.VideoMemkb = uint64(xc.video_memkb)
+	x.ShadowMemkb = uint64(xc.shadow_memkb)
+	x.IommuMemkb = uint64(xc.iommu_memkb)
+	x.RtcTimeoffset = uint32(xc.rtc_timeoffset)
+	x.ExecSsidref = uint32(xc.exec_ssidref)
+	x.ExecSsidLabel = C.GoString(xc.exec_ssid_label)
+	if err := x.Localtime.fromC(&xc.localtime); err != nil {
+		return fmt.Errorf("converting field Localtime: %v", err)
+	}
+	if err := x.DisableMigrate.fromC(&xc.disable_migrate); err != nil {
+		return fmt.Errorf("converting field DisableMigrate: %v", err)
+	}
+	if err := x.Cpuid.fromC(&xc.cpuid); err != nil {
+		return fmt.Errorf("converting field Cpuid: %v", err)
+	}
+	x.BlkdevStart = C.GoString(xc.blkdev_start)
+	x.VnumaNodes = nil
+	if n := int(xc.num_vnuma_nodes); n > 0 {
+		cVnumaNodes := (*[1 << 28]C.libxl_vnode_info)(unsafe.Pointer(xc.vnuma_nodes))[:n:n]
+		x.VnumaNodes = make([]VnodeInfo, n)
+		for i, v := range cVnumaNodes {
+			if err := x.VnumaNodes[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field VnumaNodes: %v", err)
+			}
+		}
+	}
+	x.MaxGrantFrames = uint32(xc.max_grant_frames)
+	x.MaxMaptrackFrames = uint32(xc.max_maptrack_frames)
+	x.DeviceModelVersion = DeviceModelVersion(xc.device_model_version)
+	if err := x.DeviceModelStubdomain.fromC(&xc.device_model_stubdomain); err != nil {
+		return fmt.Errorf("converting field DeviceModelStubdomain: %v", err)
+	}
+	x.DeviceModel = C.GoString(xc.device_model)
+	x.DeviceModelSsidref = uint32(xc.device_model_ssidref)
+	x.DeviceModelSsidLabel = C.GoString(xc.device_model_ssid_label)
+	x.DeviceModelUser = C.GoString(xc.device_model_user)
+	if err := x.Extra.fromC(&xc.extra); err != nil {
+		return fmt.Errorf("converting field Extra: %v", err)
+	}
+	if err := x.ExtraPv.fromC(&xc.extra_pv); err != nil {
+		return fmt.Errorf("converting field ExtraPv: %v", err)
+	}
+	if err := x.ExtraHvm.fromC(&xc.extra_hvm); err != nil {
+		return fmt.Errorf("converting field ExtraHvm: %v", err)
+	}
+	if err := x.SchedParams.fromC(&xc.sched_params); err != nil {
+		return fmt.Errorf("converting field SchedParams: %v", err)
+	}
+	x.Ioports = nil
+	if n := int(xc.num_ioports); n > 0 {
+		cIoports := (*[1 << 28]C.libxl_ioport_range)(unsafe.Pointer(xc.ioports))[:n:n]
+		x.Ioports = make([]IoportRange, n)
+		for i, v := range cIoports {
+			if err := x.Ioports[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Ioports: %v", err)
+			}
+		}
+	}
+	x.Irqs = nil
+	if n := int(xc.num_irqs); n > 0 {
+		cIrqs := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.irqs))[:n:n]
+		x.Irqs = make([]uint32, n)
+		for i, v := range cIrqs {
+			x.Irqs[i] = uint32(v)
+		}
+	}
+	x.Iomem = nil
+	if n := int(xc.num_iomem); n > 0 {
+		cIomem := (*[1 << 28]C.libxl_iomem_range)(unsafe.Pointer(xc.iomem))[:n:n]
+		x.Iomem = make([]IomemRange, n)
+		for i, v := range cIomem {
+			if err := x.Iomem[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Iomem: %v", err)
+			}
+		}
+	}
+	if err := x.ClaimMode.fromC(&xc.claim_mode); err != nil {
+		return fmt.Errorf("converting field ClaimMode: %v", err)
+	}
+	x.EventChannels = uint32(xc.event_channels)
+	x.Kernel = C.GoString(xc.kernel)
+	x.Cmdline = C.GoString(xc.cmdline)
+	x.Ramdisk = C.GoString(xc.ramdisk)
+	x.DeviceTree = C.GoString(xc.device_tree)
+	if err := x.Acpi.fromC(&xc.acpi); err != nil {
+		return fmt.Errorf("converting field Acpi: %v", err)
+	}
+	x.Bootloader = C.GoString(xc.bootloader)
+	if err := x.BootloaderArgs.fromC(&xc.bootloader_args); err != nil {
+		return fmt.Errorf("converting field BootloaderArgs: %v", err)
+	}
+	x.TimerMode = TimerMode(xc.timer_mode)
+	if err := x.NestedHvm.fromC(&xc.nested_hvm); err != nil {
+		return fmt.Errorf("converting field NestedHvm: %v", err)
+	}
+	if err := x.Apic.fromC(&xc.apic); err != nil {
+		return fmt.Errorf("converting field Apic: %v", err)
+	}
+	if err := x.DmRestrict.fromC(&xc.dm_restrict); err != nil {
+		return fmt.Errorf("converting field DmRestrict: %v", err)
+	}
+	x.Tee = TeeType(xc.tee)
+	x.Type = DomainType(xc._type)
+	switch x.Type {
+	case DomainTypeHvm:
+		var typeHvm DomainBuildInfoTypeUnionHvm
+		if err := typeHvm.fromC(xc); err != nil {
+			return fmt.Errorf("converting field typeHvm: %v", err)
+		}
+		x.TypeUnion = typeHvm
+	case DomainTypePv:
+		var typePv DomainBuildInfoTypeUnionPv
+		if err := typePv.fromC(xc); err != nil {
+			return fmt.Errorf("converting field typePv: %v", err)
+		}
+		x.TypeUnion = typePv
+	case DomainTypePvh:
+		var typePvh DomainBuildInfoTypeUnionPvh
+		if err := typePvh.fromC(xc); err != nil {
+			return fmt.Errorf("converting field typePvh: %v", err)
+		}
+		x.TypeUnion = typePvh
+	case DomainTypeInvalid:
+		x.TypeUnion = nil
+	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 fmt.Errorf("converting field Pae: %v", err)
+	}
+	if err := x.Apic.fromC(&tmp.apic); err != nil {
+		return fmt.Errorf("converting field Apic: %v", err)
+	}
+	if err := x.Acpi.fromC(&tmp.acpi); err != nil {
+		return fmt.Errorf("converting field Acpi: %v", err)
+	}
+	if err := x.AcpiS3.fromC(&tmp.acpi_s3); err != nil {
+		return fmt.Errorf("converting field AcpiS3: %v", err)
+	}
+	if err := x.AcpiS4.fromC(&tmp.acpi_s4); err != nil {
+		return fmt.Errorf("converting field AcpiS4: %v", err)
+	}
+	if err := x.AcpiLaptopSlate.fromC(&tmp.acpi_laptop_slate); err != nil {
+		return fmt.Errorf("converting field AcpiLaptopSlate: %v", err)
+	}
+	if err := x.Nx.fromC(&tmp.nx); err != nil {
+		return fmt.Errorf("converting field Nx: %v", err)
+	}
+	if err := x.Viridian.fromC(&tmp.viridian); err != nil {
+		return fmt.Errorf("converting field Viridian: %v", err)
+	}
+	if err := x.ViridianEnable.fromC(&tmp.viridian_enable); err != nil {
+		return fmt.Errorf("converting field ViridianEnable: %v", err)
+	}
+	if err := x.ViridianDisable.fromC(&tmp.viridian_disable); err != nil {
+		return fmt.Errorf("converting field ViridianDisable: %v", err)
+	}
+	x.Timeoffset = C.GoString(tmp.timeoffset)
+	if err := x.Hpet.fromC(&tmp.hpet); err != nil {
+		return fmt.Errorf("converting field Hpet: %v", err)
+	}
+	if err := x.VptAlign.fromC(&tmp.vpt_align); err != nil {
+		return fmt.Errorf("converting field VptAlign: %v", 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 fmt.Errorf("converting field NestedHvm: %v", err)
+	}
+	if err := x.Altp2M.fromC(&tmp.altp2m); err != nil {
+		return fmt.Errorf("converting field Altp2M: %v", 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 fmt.Errorf("converting field Nographic: %v", err)
+	}
+	if err := x.Vga.fromC(&tmp.vga); err != nil {
+		return fmt.Errorf("converting field Vga: %v", err)
+	}
+	if err := x.Vnc.fromC(&tmp.vnc); err != nil {
+		return fmt.Errorf("converting field Vnc: %v", err)
+	}
+	x.Keymap = C.GoString(tmp.keymap)
+	if err := x.Sdl.fromC(&tmp.sdl); err != nil {
+		return fmt.Errorf("converting field Sdl: %v", err)
+	}
+	if err := x.Spice.fromC(&tmp.spice); err != nil {
+		return fmt.Errorf("converting field Spice: %v", err)
+	}
+	if err := x.GfxPassthru.fromC(&tmp.gfx_passthru); err != nil {
+		return fmt.Errorf("converting field GfxPassthru: %v", 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 fmt.Errorf("converting field Usb: %v", err)
+	}
+	x.Usbversion = int(tmp.usbversion)
+	x.Usbdevice = C.GoString(tmp.usbdevice)
+	if err := x.VkbDevice.fromC(&tmp.vkb_device); err != nil {
+		return fmt.Errorf("converting field VkbDevice: %v", err)
+	}
+	x.Soundhw = C.GoString(tmp.soundhw)
+	if err := x.XenPlatformPci.fromC(&tmp.xen_platform_pci); err != nil {
+		return fmt.Errorf("converting field XenPlatformPci: %v", err)
+	}
+	if err := x.UsbdeviceList.fromC(&tmp.usbdevice_list); err != nil {
+		return fmt.Errorf("converting field UsbdeviceList: %v", err)
+	}
+	x.VendorDevice = VendorDevice(tmp.vendor_device)
+	if err := x.MsVmGenid.fromC(&tmp.ms_vm_genid); err != nil {
+		return fmt.Errorf("converting field MsVmGenid: %v", err)
+	}
+	if err := x.SerialList.fromC(&tmp.serial_list); err != nil {
+		return fmt.Errorf("converting field SerialList: %v", err)
+	}
+	if err := x.Rdm.fromC(&tmp.rdm); err != nil {
+		return fmt.Errorf("converting field Rdm: %v", 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 fmt.Errorf("converting field BootloaderArgs: %v", 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 fmt.Errorf("converting field E820Host: %v", 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 fmt.Errorf("converting field Pvshim: %v", 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 *DomainBuildInfo) toC(xc *C.libxl_domain_build_info) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_domain_build_info_dispose(xc)
+		}
+	}()
+
+	xc.max_vcpus = C.int(x.MaxVcpus)
+	if err := x.AvailVcpus.toC(&xc.avail_vcpus); err != nil {
+		return fmt.Errorf("converting field AvailVcpus: %v", err)
+	}
+	if err := x.Cpumap.toC(&xc.cpumap); err != nil {
+		return fmt.Errorf("converting field Cpumap: %v", err)
+	}
+	if err := x.Nodemap.toC(&xc.nodemap); err != nil {
+		return fmt.Errorf("converting field Nodemap: %v", err)
+	}
+	if numVcpuHardAffinity := len(x.VcpuHardAffinity); numVcpuHardAffinity > 0 {
+		xc.vcpu_hard_affinity = (*C.libxl_bitmap)(C.malloc(C.ulong(numVcpuHardAffinity) * C.sizeof_libxl_bitmap))
+		xc.num_vcpu_hard_affinity = C.int(numVcpuHardAffinity)
+		cVcpuHardAffinity := (*[1 << 28]C.libxl_bitmap)(unsafe.Pointer(xc.vcpu_hard_affinity))[:numVcpuHardAffinity:numVcpuHardAffinity]
+		for i, v := range x.VcpuHardAffinity {
+			if err := v.toC(&cVcpuHardAffinity[i]); err != nil {
+				return fmt.Errorf("converting field VcpuHardAffinity: %v", err)
+			}
+		}
+	}
+	if numVcpuSoftAffinity := len(x.VcpuSoftAffinity); numVcpuSoftAffinity > 0 {
+		xc.vcpu_soft_affinity = (*C.libxl_bitmap)(C.malloc(C.ulong(numVcpuSoftAffinity) * C.sizeof_libxl_bitmap))
+		xc.num_vcpu_soft_affinity = C.int(numVcpuSoftAffinity)
+		cVcpuSoftAffinity := (*[1 << 28]C.libxl_bitmap)(unsafe.Pointer(xc.vcpu_soft_affinity))[:numVcpuSoftAffinity:numVcpuSoftAffinity]
+		for i, v := range x.VcpuSoftAffinity {
+			if err := v.toC(&cVcpuSoftAffinity[i]); err != nil {
+				return fmt.Errorf("converting field VcpuSoftAffinity: %v", err)
+			}
+		}
+	}
+	if err := x.NumaPlacement.toC(&xc.numa_placement); err != nil {
+		return fmt.Errorf("converting field NumaPlacement: %v", err)
+	}
+	xc.tsc_mode = C.libxl_tsc_mode(x.TscMode)
+	xc.max_memkb = C.uint64_t(x.MaxMemkb)
+	xc.target_memkb = C.uint64_t(x.TargetMemkb)
+	xc.video_memkb = C.uint64_t(x.VideoMemkb)
+	xc.shadow_memkb = C.uint64_t(x.ShadowMemkb)
+	xc.iommu_memkb = C.uint64_t(x.IommuMemkb)
+	xc.rtc_timeoffset = C.uint32_t(x.RtcTimeoffset)
+	xc.exec_ssidref = C.uint32_t(x.ExecSsidref)
+	if x.ExecSsidLabel != "" {
+		xc.exec_ssid_label = C.CString(x.ExecSsidLabel)
+	}
+	if err := x.Localtime.toC(&xc.localtime); err != nil {
+		return fmt.Errorf("converting field Localtime: %v", err)
+	}
+	if err := x.DisableMigrate.toC(&xc.disable_migrate); err != nil {
+		return fmt.Errorf("converting field DisableMigrate: %v", err)
+	}
+	if err := x.Cpuid.toC(&xc.cpuid); err != nil {
+		return fmt.Errorf("converting field Cpuid: %v", err)
+	}
+	if x.BlkdevStart != "" {
+		xc.blkdev_start = C.CString(x.BlkdevStart)
+	}
+	if numVnumaNodes := len(x.VnumaNodes); numVnumaNodes > 0 {
+		xc.vnuma_nodes = (*C.libxl_vnode_info)(C.malloc(C.ulong(numVnumaNodes) * C.sizeof_libxl_vnode_info))
+		xc.num_vnuma_nodes = C.int(numVnumaNodes)
+		cVnumaNodes := (*[1 << 28]C.libxl_vnode_info)(unsafe.Pointer(xc.vnuma_nodes))[:numVnumaNodes:numVnumaNodes]
+		for i, v := range x.VnumaNodes {
+			if err := v.toC(&cVnumaNodes[i]); err != nil {
+				return fmt.Errorf("converting field VnumaNodes: %v", err)
+			}
+		}
+	}
+	xc.max_grant_frames = C.uint32_t(x.MaxGrantFrames)
+	xc.max_maptrack_frames = C.uint32_t(x.MaxMaptrackFrames)
+	xc.device_model_version = C.libxl_device_model_version(x.DeviceModelVersion)
+	if err := x.DeviceModelStubdomain.toC(&xc.device_model_stubdomain); err != nil {
+		return fmt.Errorf("converting field DeviceModelStubdomain: %v", err)
+	}
+	if x.DeviceModel != "" {
+		xc.device_model = C.CString(x.DeviceModel)
+	}
+	xc.device_model_ssidref = C.uint32_t(x.DeviceModelSsidref)
+	if x.DeviceModelSsidLabel != "" {
+		xc.device_model_ssid_label = C.CString(x.DeviceModelSsidLabel)
+	}
+	if x.DeviceModelUser != "" {
+		xc.device_model_user = C.CString(x.DeviceModelUser)
+	}
+	if err := x.Extra.toC(&xc.extra); err != nil {
+		return fmt.Errorf("converting field Extra: %v", err)
+	}
+	if err := x.ExtraPv.toC(&xc.extra_pv); err != nil {
+		return fmt.Errorf("converting field ExtraPv: %v", err)
+	}
+	if err := x.ExtraHvm.toC(&xc.extra_hvm); err != nil {
+		return fmt.Errorf("converting field ExtraHvm: %v", err)
+	}
+	if err := x.SchedParams.toC(&xc.sched_params); err != nil {
+		return fmt.Errorf("converting field SchedParams: %v", err)
+	}
+	if numIoports := len(x.Ioports); numIoports > 0 {
+		xc.ioports = (*C.libxl_ioport_range)(C.malloc(C.ulong(numIoports) * C.sizeof_libxl_ioport_range))
+		xc.num_ioports = C.int(numIoports)
+		cIoports := (*[1 << 28]C.libxl_ioport_range)(unsafe.Pointer(xc.ioports))[:numIoports:numIoports]
+		for i, v := range x.Ioports {
+			if err := v.toC(&cIoports[i]); err != nil {
+				return fmt.Errorf("converting field Ioports: %v", err)
+			}
+		}
+	}
+	if numIrqs := len(x.Irqs); numIrqs > 0 {
+		xc.irqs = (*C.uint32_t)(C.malloc(C.size_t(numIrqs * numIrqs)))
+		xc.num_irqs = C.int(numIrqs)
+		cIrqs := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.irqs))[:numIrqs:numIrqs]
+		for i, v := range x.Irqs {
+			cIrqs[i] = C.uint32_t(v)
+		}
+	}
+	if numIomem := len(x.Iomem); numIomem > 0 {
+		xc.iomem = (*C.libxl_iomem_range)(C.malloc(C.ulong(numIomem) * C.sizeof_libxl_iomem_range))
+		xc.num_iomem = C.int(numIomem)
+		cIomem := (*[1 << 28]C.libxl_iomem_range)(unsafe.Pointer(xc.iomem))[:numIomem:numIomem]
+		for i, v := range x.Iomem {
+			if err := v.toC(&cIomem[i]); err != nil {
+				return fmt.Errorf("converting field Iomem: %v", err)
+			}
+		}
+	}
+	if err := x.ClaimMode.toC(&xc.claim_mode); err != nil {
+		return fmt.Errorf("converting field ClaimMode: %v", err)
+	}
+	xc.event_channels = C.uint32_t(x.EventChannels)
+	if x.Kernel != "" {
+		xc.kernel = C.CString(x.Kernel)
+	}
+	if x.Cmdline != "" {
+		xc.cmdline = C.CString(x.Cmdline)
+	}
+	if x.Ramdisk != "" {
+		xc.ramdisk = C.CString(x.Ramdisk)
+	}
+	if x.DeviceTree != "" {
+		xc.device_tree = C.CString(x.DeviceTree)
+	}
+	if err := x.Acpi.toC(&xc.acpi); err != nil {
+		return fmt.Errorf("converting field Acpi: %v", err)
+	}
+	if x.Bootloader != "" {
+		xc.bootloader = C.CString(x.Bootloader)
+	}
+	if err := x.BootloaderArgs.toC(&xc.bootloader_args); err != nil {
+		return fmt.Errorf("converting field BootloaderArgs: %v", err)
+	}
+	xc.timer_mode = C.libxl_timer_mode(x.TimerMode)
+	if err := x.NestedHvm.toC(&xc.nested_hvm); err != nil {
+		return fmt.Errorf("converting field NestedHvm: %v", err)
+	}
+	if err := x.Apic.toC(&xc.apic); err != nil {
+		return fmt.Errorf("converting field Apic: %v", err)
+	}
+	if err := x.DmRestrict.toC(&xc.dm_restrict); err != nil {
+		return fmt.Errorf("converting field DmRestrict: %v", 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 {
+			return errors.New("wrong type for union key type")
+		}
+		var hvm C.libxl_domain_build_info_type_union_hvm
+		if tmp.Firmware != "" {
+			hvm.firmware = C.CString(tmp.Firmware)
+		}
+		hvm.bios = C.libxl_bios_type(tmp.Bios)
+		if err := tmp.Pae.toC(&hvm.pae); err != nil {
+			return fmt.Errorf("converting field Pae: %v", err)
+		}
+		if err := tmp.Apic.toC(&hvm.apic); err != nil {
+			return fmt.Errorf("converting field Apic: %v", err)
+		}
+		if err := tmp.Acpi.toC(&hvm.acpi); err != nil {
+			return fmt.Errorf("converting field Acpi: %v", err)
+		}
+		if err := tmp.AcpiS3.toC(&hvm.acpi_s3); err != nil {
+			return fmt.Errorf("converting field AcpiS3: %v", err)
+		}
+		if err := tmp.AcpiS4.toC(&hvm.acpi_s4); err != nil {
+			return fmt.Errorf("converting field AcpiS4: %v", err)
+		}
+		if err := tmp.AcpiLaptopSlate.toC(&hvm.acpi_laptop_slate); err != nil {
+			return fmt.Errorf("converting field AcpiLaptopSlate: %v", err)
+		}
+		if err := tmp.Nx.toC(&hvm.nx); err != nil {
+			return fmt.Errorf("converting field Nx: %v", err)
+		}
+		if err := tmp.Viridian.toC(&hvm.viridian); err != nil {
+			return fmt.Errorf("converting field Viridian: %v", err)
+		}
+		if err := tmp.ViridianEnable.toC(&hvm.viridian_enable); err != nil {
+			return fmt.Errorf("converting field ViridianEnable: %v", err)
+		}
+		if err := tmp.ViridianDisable.toC(&hvm.viridian_disable); err != nil {
+			return fmt.Errorf("converting field ViridianDisable: %v", err)
+		}
+		if tmp.Timeoffset != "" {
+			hvm.timeoffset = C.CString(tmp.Timeoffset)
+		}
+		if err := tmp.Hpet.toC(&hvm.hpet); err != nil {
+			return fmt.Errorf("converting field Hpet: %v", err)
+		}
+		if err := tmp.VptAlign.toC(&hvm.vpt_align); err != nil {
+			return fmt.Errorf("converting field VptAlign: %v", err)
+		}
+		hvm.mmio_hole_memkb = C.uint64_t(tmp.MmioHoleMemkb)
+		hvm.timer_mode = C.libxl_timer_mode(tmp.TimerMode)
+		if err := tmp.NestedHvm.toC(&hvm.nested_hvm); err != nil {
+			return fmt.Errorf("converting field NestedHvm: %v", err)
+		}
+		if err := tmp.Altp2M.toC(&hvm.altp2m); err != nil {
+			return fmt.Errorf("converting field Altp2M: %v", err)
+		}
+		if tmp.SystemFirmware != "" {
+			hvm.system_firmware = C.CString(tmp.SystemFirmware)
+		}
+		if tmp.SmbiosFirmware != "" {
+			hvm.smbios_firmware = C.CString(tmp.SmbiosFirmware)
+		}
+		if tmp.AcpiFirmware != "" {
+			hvm.acpi_firmware = C.CString(tmp.AcpiFirmware)
+		}
+		hvm.hdtype = C.libxl_hdtype(tmp.Hdtype)
+		if err := tmp.Nographic.toC(&hvm.nographic); err != nil {
+			return fmt.Errorf("converting field Nographic: %v", err)
+		}
+		if err := tmp.Vga.toC(&hvm.vga); err != nil {
+			return fmt.Errorf("converting field Vga: %v", err)
+		}
+		if err := tmp.Vnc.toC(&hvm.vnc); err != nil {
+			return fmt.Errorf("converting field Vnc: %v", err)
+		}
+		if tmp.Keymap != "" {
+			hvm.keymap = C.CString(tmp.Keymap)
+		}
+		if err := tmp.Sdl.toC(&hvm.sdl); err != nil {
+			return fmt.Errorf("converting field Sdl: %v", err)
+		}
+		if err := tmp.Spice.toC(&hvm.spice); err != nil {
+			return fmt.Errorf("converting field Spice: %v", err)
+		}
+		if err := tmp.GfxPassthru.toC(&hvm.gfx_passthru); err != nil {
+			return fmt.Errorf("converting field GfxPassthru: %v", err)
+		}
+		hvm.gfx_passthru_kind = C.libxl_gfx_passthru_kind(tmp.GfxPassthruKind)
+		if tmp.Serial != "" {
+			hvm.serial = C.CString(tmp.Serial)
+		}
+		if tmp.Boot != "" {
+			hvm.boot = C.CString(tmp.Boot)
+		}
+		if err := tmp.Usb.toC(&hvm.usb); err != nil {
+			return fmt.Errorf("converting field Usb: %v", err)
+		}
+		hvm.usbversion = C.int(tmp.Usbversion)
+		if tmp.Usbdevice != "" {
+			hvm.usbdevice = C.CString(tmp.Usbdevice)
+		}
+		if err := tmp.VkbDevice.toC(&hvm.vkb_device); err != nil {
+			return fmt.Errorf("converting field VkbDevice: %v", err)
+		}
+		if tmp.Soundhw != "" {
+			hvm.soundhw = C.CString(tmp.Soundhw)
+		}
+		if err := tmp.XenPlatformPci.toC(&hvm.xen_platform_pci); err != nil {
+			return fmt.Errorf("converting field XenPlatformPci: %v", err)
+		}
+		if err := tmp.UsbdeviceList.toC(&hvm.usbdevice_list); err != nil {
+			return fmt.Errorf("converting field UsbdeviceList: %v", err)
+		}
+		hvm.vendor_device = C.libxl_vendor_device(tmp.VendorDevice)
+		if err := tmp.MsVmGenid.toC(&hvm.ms_vm_genid); err != nil {
+			return fmt.Errorf("converting field MsVmGenid: %v", err)
+		}
+		if err := tmp.SerialList.toC(&hvm.serial_list); err != nil {
+			return fmt.Errorf("converting field SerialList: %v", err)
+		}
+		if err := tmp.Rdm.toC(&hvm.rdm); err != nil {
+			return fmt.Errorf("converting field Rdm: %v", 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 {
+			return errors.New("wrong type for union key type")
+		}
+		var pv C.libxl_domain_build_info_type_union_pv
+		if tmp.Kernel != "" {
+			pv.kernel = C.CString(tmp.Kernel)
+		}
+		pv.slack_memkb = C.uint64_t(tmp.SlackMemkb)
+		if tmp.Bootloader != "" {
+			pv.bootloader = C.CString(tmp.Bootloader)
+		}
+		if err := tmp.BootloaderArgs.toC(&pv.bootloader_args); err != nil {
+			return fmt.Errorf("converting field BootloaderArgs: %v", err)
+		}
+		if tmp.Cmdline != "" {
+			pv.cmdline = C.CString(tmp.Cmdline)
+		}
+		if tmp.Ramdisk != "" {
+			pv.ramdisk = C.CString(tmp.Ramdisk)
+		}
+		if tmp.Features != "" {
+			pv.features = C.CString(tmp.Features)
+		}
+		if err := tmp.E820Host.toC(&pv.e820_host); err != nil {
+			return fmt.Errorf("converting field E820Host: %v", 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 {
+			return errors.New("wrong type for union key type")
+		}
+		var pvh C.libxl_domain_build_info_type_union_pvh
+		if err := tmp.Pvshim.toC(&pvh.pvshim); err != nil {
+			return fmt.Errorf("converting field Pvshim: %v", err)
+		}
+		if tmp.PvshimPath != "" {
+			pvh.pvshim_path = C.CString(tmp.PvshimPath)
+		}
+		if tmp.PvshimCmdline != "" {
+			pvh.pvshim_cmdline = C.CString(tmp.PvshimCmdline)
+		}
+		if tmp.PvshimExtra != "" {
+			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)
+	case DomainTypeInvalid:
+		break
+	default:
+		return 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)
+
+	return nil
+}
+
+// NewDeviceVfb returns an instance of DeviceVfb initialized with defaults.
+func NewDeviceVfb() (*DeviceVfb, error) {
+	var (
+		x  DeviceVfb
+		xc C.libxl_device_vfb
+	)
+
+	C.libxl_device_vfb_init(&xc)
+	defer C.libxl_device_vfb_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceVfb) fromC(xc *C.libxl_device_vfb) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	if err := x.Vnc.fromC(&xc.vnc); err != nil {
+		return fmt.Errorf("converting field Vnc: %v", err)
+	}
+	if err := x.Sdl.fromC(&xc.sdl); err != nil {
+		return fmt.Errorf("converting field Sdl: %v", err)
+	}
+	x.Keymap = C.GoString(xc.keymap)
+
+	return nil
+}
+
+func (x *DeviceVfb) toC(xc *C.libxl_device_vfb) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_vfb_dispose(xc)
+		}
+	}()
+
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	xc.devid = C.libxl_devid(x.Devid)
+	if err := x.Vnc.toC(&xc.vnc); err != nil {
+		return fmt.Errorf("converting field Vnc: %v", err)
+	}
+	if err := x.Sdl.toC(&xc.sdl); err != nil {
+		return fmt.Errorf("converting field Sdl: %v", err)
+	}
+	if x.Keymap != "" {
+		xc.keymap = C.CString(x.Keymap)
+	}
+
+	return nil
+}
+
+// NewDeviceVkb returns an instance of DeviceVkb initialized with defaults.
+func NewDeviceVkb() (*DeviceVkb, error) {
+	var (
+		x  DeviceVkb
+		xc C.libxl_device_vkb
+	)
+
+	C.libxl_device_vkb_init(&xc)
+	defer C.libxl_device_vkb_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceVkb) fromC(xc *C.libxl_device_vkb) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	x.BackendType = VkbBackend(xc.backend_type)
+	x.UniqueId = C.GoString(xc.unique_id)
+	x.FeatureDisableKeyboard = bool(xc.feature_disable_keyboard)
+	x.FeatureDisablePointer = bool(xc.feature_disable_pointer)
+	x.FeatureAbsPointer = bool(xc.feature_abs_pointer)
+	x.FeatureRawPointer = bool(xc.feature_raw_pointer)
+	x.FeatureMultiTouch = bool(xc.feature_multi_touch)
+	x.Width = uint32(xc.width)
+	x.Height = uint32(xc.height)
+	x.MultiTouchWidth = uint32(xc.multi_touch_width)
+	x.MultiTouchHeight = uint32(xc.multi_touch_height)
+	x.MultiTouchNumContacts = uint32(xc.multi_touch_num_contacts)
+
+	return nil
+}
+
+func (x *DeviceVkb) toC(xc *C.libxl_device_vkb) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_vkb_dispose(xc)
+		}
+	}()
+
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.backend_type = C.libxl_vkb_backend(x.BackendType)
+	if x.UniqueId != "" {
+		xc.unique_id = C.CString(x.UniqueId)
+	}
+	xc.feature_disable_keyboard = C.bool(x.FeatureDisableKeyboard)
+	xc.feature_disable_pointer = C.bool(x.FeatureDisablePointer)
+	xc.feature_abs_pointer = C.bool(x.FeatureAbsPointer)
+	xc.feature_raw_pointer = C.bool(x.FeatureRawPointer)
+	xc.feature_multi_touch = C.bool(x.FeatureMultiTouch)
+	xc.width = C.uint32_t(x.Width)
+	xc.height = C.uint32_t(x.Height)
+	xc.multi_touch_width = C.uint32_t(x.MultiTouchWidth)
+	xc.multi_touch_height = C.uint32_t(x.MultiTouchHeight)
+	xc.multi_touch_num_contacts = C.uint32_t(x.MultiTouchNumContacts)
+
+	return nil
+}
+
+// NewDeviceDisk returns an instance of DeviceDisk initialized with defaults.
+func NewDeviceDisk() (*DeviceDisk, error) {
+	var (
+		x  DeviceDisk
+		xc C.libxl_device_disk
+	)
+
+	C.libxl_device_disk_init(&xc)
+	defer C.libxl_device_disk_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceDisk) fromC(xc *C.libxl_device_disk) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.PdevPath = C.GoString(xc.pdev_path)
+	x.Vdev = C.GoString(xc.vdev)
+	x.Backend = DiskBackend(xc.backend)
+	x.Format = DiskFormat(xc.format)
+	x.Script = C.GoString(xc.script)
+	x.Removable = int(xc.removable)
+	x.Readwrite = int(xc.readwrite)
+	x.IsCdrom = int(xc.is_cdrom)
+	x.DirectIoSafe = bool(xc.direct_io_safe)
+	if err := x.DiscardEnable.fromC(&xc.discard_enable); err != nil {
+		return fmt.Errorf("converting field DiscardEnable: %v", err)
+	}
+	if err := x.ColoEnable.fromC(&xc.colo_enable); err != nil {
+		return fmt.Errorf("converting field ColoEnable: %v", err)
+	}
+	if err := x.ColoRestoreEnable.fromC(&xc.colo_restore_enable); err != nil {
+		return fmt.Errorf("converting field ColoRestoreEnable: %v", err)
+	}
+	x.ColoHost = C.GoString(xc.colo_host)
+	x.ColoPort = int(xc.colo_port)
+	x.ColoExport = C.GoString(xc.colo_export)
+	x.ActiveDisk = C.GoString(xc.active_disk)
+	x.HiddenDisk = C.GoString(xc.hidden_disk)
+
+	return nil
+}
+
+func (x *DeviceDisk) toC(xc *C.libxl_device_disk) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_disk_dispose(xc)
+		}
+	}()
+
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	if x.PdevPath != "" {
+		xc.pdev_path = C.CString(x.PdevPath)
+	}
+	if x.Vdev != "" {
+		xc.vdev = C.CString(x.Vdev)
+	}
+	xc.backend = C.libxl_disk_backend(x.Backend)
+	xc.format = C.libxl_disk_format(x.Format)
+	if x.Script != "" {
+		xc.script = C.CString(x.Script)
+	}
+	xc.removable = C.int(x.Removable)
+	xc.readwrite = C.int(x.Readwrite)
+	xc.is_cdrom = C.int(x.IsCdrom)
+	xc.direct_io_safe = C.bool(x.DirectIoSafe)
+	if err := x.DiscardEnable.toC(&xc.discard_enable); err != nil {
+		return fmt.Errorf("converting field DiscardEnable: %v", err)
+	}
+	if err := x.ColoEnable.toC(&xc.colo_enable); err != nil {
+		return fmt.Errorf("converting field ColoEnable: %v", err)
+	}
+	if err := x.ColoRestoreEnable.toC(&xc.colo_restore_enable); err != nil {
+		return fmt.Errorf("converting field ColoRestoreEnable: %v", err)
+	}
+	if x.ColoHost != "" {
+		xc.colo_host = C.CString(x.ColoHost)
+	}
+	xc.colo_port = C.int(x.ColoPort)
+	if x.ColoExport != "" {
+		xc.colo_export = C.CString(x.ColoExport)
+	}
+	if x.ActiveDisk != "" {
+		xc.active_disk = C.CString(x.ActiveDisk)
+	}
+	if x.HiddenDisk != "" {
+		xc.hidden_disk = C.CString(x.HiddenDisk)
+	}
+
+	return nil
+}
+
+// NewDeviceNic returns an instance of DeviceNic initialized with defaults.
+func NewDeviceNic() (*DeviceNic, error) {
+	var (
+		x  DeviceNic
+		xc C.libxl_device_nic
+	)
+
+	C.libxl_device_nic_init(&xc)
+	defer C.libxl_device_nic_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceNic) fromC(xc *C.libxl_device_nic) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	x.Mtu = int(xc.mtu)
+	x.Model = C.GoString(xc.model)
+	if err := x.Mac.fromC(&xc.mac); err != nil {
+		return fmt.Errorf("converting field Mac: %v", err)
+	}
+	x.Ip = C.GoString(xc.ip)
+	x.Bridge = C.GoString(xc.bridge)
+	x.Ifname = C.GoString(xc.ifname)
+	x.Script = C.GoString(xc.script)
+	x.Nictype = NicType(xc.nictype)
+	x.RateBytesPerInterval = uint64(xc.rate_bytes_per_interval)
+	x.RateIntervalUsecs = uint32(xc.rate_interval_usecs)
+	x.Gatewaydev = C.GoString(xc.gatewaydev)
+	x.ColoftForwarddev = C.GoString(xc.coloft_forwarddev)
+	x.ColoSockMirrorId = C.GoString(xc.colo_sock_mirror_id)
+	x.ColoSockMirrorIp = C.GoString(xc.colo_sock_mirror_ip)
+	x.ColoSockMirrorPort = C.GoString(xc.colo_sock_mirror_port)
+	x.ColoSockComparePriInId = C.GoString(xc.colo_sock_compare_pri_in_id)
+	x.ColoSockComparePriInIp = C.GoString(xc.colo_sock_compare_pri_in_ip)
+	x.ColoSockComparePriInPort = C.GoString(xc.colo_sock_compare_pri_in_port)
+	x.ColoSockCompareSecInId = C.GoString(xc.colo_sock_compare_sec_in_id)
+	x.ColoSockCompareSecInIp = C.GoString(xc.colo_sock_compare_sec_in_ip)
+	x.ColoSockCompareSecInPort = C.GoString(xc.colo_sock_compare_sec_in_port)
+	x.ColoSockCompareNotifyId = C.GoString(xc.colo_sock_compare_notify_id)
+	x.ColoSockCompareNotifyIp = C.GoString(xc.colo_sock_compare_notify_ip)
+	x.ColoSockCompareNotifyPort = C.GoString(xc.colo_sock_compare_notify_port)
+	x.ColoSockRedirector0Id = C.GoString(xc.colo_sock_redirector0_id)
+	x.ColoSockRedirector0Ip = C.GoString(xc.colo_sock_redirector0_ip)
+	x.ColoSockRedirector0Port = C.GoString(xc.colo_sock_redirector0_port)
+	x.ColoSockRedirector1Id = C.GoString(xc.colo_sock_redirector1_id)
+	x.ColoSockRedirector1Ip = C.GoString(xc.colo_sock_redirector1_ip)
+	x.ColoSockRedirector1Port = C.GoString(xc.colo_sock_redirector1_port)
+	x.ColoSockRedirector2Id = C.GoString(xc.colo_sock_redirector2_id)
+	x.ColoSockRedirector2Ip = C.GoString(xc.colo_sock_redirector2_ip)
+	x.ColoSockRedirector2Port = C.GoString(xc.colo_sock_redirector2_port)
+	x.ColoFilterMirrorQueue = C.GoString(xc.colo_filter_mirror_queue)
+	x.ColoFilterMirrorOutdev = C.GoString(xc.colo_filter_mirror_outdev)
+	x.ColoFilterRedirector0Queue = C.GoString(xc.colo_filter_redirector0_queue)
+	x.ColoFilterRedirector0Indev = C.GoString(xc.colo_filter_redirector0_indev)
+	x.ColoFilterRedirector0Outdev = C.GoString(xc.colo_filter_redirector0_outdev)
+	x.ColoFilterRedirector1Queue = C.GoString(xc.colo_filter_redirector1_queue)
+	x.ColoFilterRedirector1Indev = C.GoString(xc.colo_filter_redirector1_indev)
+	x.ColoFilterRedirector1Outdev = C.GoString(xc.colo_filter_redirector1_outdev)
+	x.ColoComparePriIn = C.GoString(xc.colo_compare_pri_in)
+	x.ColoCompareSecIn = C.GoString(xc.colo_compare_sec_in)
+	x.ColoCompareOut = C.GoString(xc.colo_compare_out)
+	x.ColoCompareNotifyDev = C.GoString(xc.colo_compare_notify_dev)
+	x.ColoSockSecRedirector0Id = C.GoString(xc.colo_sock_sec_redirector0_id)
+	x.ColoSockSecRedirector0Ip = C.GoString(xc.colo_sock_sec_redirector0_ip)
+	x.ColoSockSecRedirector0Port = C.GoString(xc.colo_sock_sec_redirector0_port)
+	x.ColoSockSecRedirector1Id = C.GoString(xc.colo_sock_sec_redirector1_id)
+	x.ColoSockSecRedirector1Ip = C.GoString(xc.colo_sock_sec_redirector1_ip)
+	x.ColoSockSecRedirector1Port = C.GoString(xc.colo_sock_sec_redirector1_port)
+	x.ColoFilterSecRedirector0Queue = C.GoString(xc.colo_filter_sec_redirector0_queue)
+	x.ColoFilterSecRedirector0Indev = C.GoString(xc.colo_filter_sec_redirector0_indev)
+	x.ColoFilterSecRedirector0Outdev = C.GoString(xc.colo_filter_sec_redirector0_outdev)
+	x.ColoFilterSecRedirector1Queue = C.GoString(xc.colo_filter_sec_redirector1_queue)
+	x.ColoFilterSecRedirector1Indev = C.GoString(xc.colo_filter_sec_redirector1_indev)
+	x.ColoFilterSecRedirector1Outdev = C.GoString(xc.colo_filter_sec_redirector1_outdev)
+	x.ColoFilterSecRewriter0Queue = C.GoString(xc.colo_filter_sec_rewriter0_queue)
+	x.ColoCheckpointHost = C.GoString(xc.colo_checkpoint_host)
+	x.ColoCheckpointPort = C.GoString(xc.colo_checkpoint_port)
+
+	return nil
+}
+
+func (x *DeviceNic) toC(xc *C.libxl_device_nic) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_nic_dispose(xc)
+		}
+	}()
+
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.mtu = C.int(x.Mtu)
+	if x.Model != "" {
+		xc.model = C.CString(x.Model)
+	}
+	if err := x.Mac.toC(&xc.mac); err != nil {
+		return fmt.Errorf("converting field Mac: %v", err)
+	}
+	if x.Ip != "" {
+		xc.ip = C.CString(x.Ip)
+	}
+	if x.Bridge != "" {
+		xc.bridge = C.CString(x.Bridge)
+	}
+	if x.Ifname != "" {
+		xc.ifname = C.CString(x.Ifname)
+	}
+	if x.Script != "" {
+		xc.script = C.CString(x.Script)
+	}
+	xc.nictype = C.libxl_nic_type(x.Nictype)
+	xc.rate_bytes_per_interval = C.uint64_t(x.RateBytesPerInterval)
+	xc.rate_interval_usecs = C.uint32_t(x.RateIntervalUsecs)
+	if x.Gatewaydev != "" {
+		xc.gatewaydev = C.CString(x.Gatewaydev)
+	}
+	if x.ColoftForwarddev != "" {
+		xc.coloft_forwarddev = C.CString(x.ColoftForwarddev)
+	}
+	if x.ColoSockMirrorId != "" {
+		xc.colo_sock_mirror_id = C.CString(x.ColoSockMirrorId)
+	}
+	if x.ColoSockMirrorIp != "" {
+		xc.colo_sock_mirror_ip = C.CString(x.ColoSockMirrorIp)
+	}
+	if x.ColoSockMirrorPort != "" {
+		xc.colo_sock_mirror_port = C.CString(x.ColoSockMirrorPort)
+	}
+	if x.ColoSockComparePriInId != "" {
+		xc.colo_sock_compare_pri_in_id = C.CString(x.ColoSockComparePriInId)
+	}
+	if x.ColoSockComparePriInIp != "" {
+		xc.colo_sock_compare_pri_in_ip = C.CString(x.ColoSockComparePriInIp)
+	}
+	if x.ColoSockComparePriInPort != "" {
+		xc.colo_sock_compare_pri_in_port = C.CString(x.ColoSockComparePriInPort)
+	}
+	if x.ColoSockCompareSecInId != "" {
+		xc.colo_sock_compare_sec_in_id = C.CString(x.ColoSockCompareSecInId)
+	}
+	if x.ColoSockCompareSecInIp != "" {
+		xc.colo_sock_compare_sec_in_ip = C.CString(x.ColoSockCompareSecInIp)
+	}
+	if x.ColoSockCompareSecInPort != "" {
+		xc.colo_sock_compare_sec_in_port = C.CString(x.ColoSockCompareSecInPort)
+	}
+	if x.ColoSockCompareNotifyId != "" {
+		xc.colo_sock_compare_notify_id = C.CString(x.ColoSockCompareNotifyId)
+	}
+	if x.ColoSockCompareNotifyIp != "" {
+		xc.colo_sock_compare_notify_ip = C.CString(x.ColoSockCompareNotifyIp)
+	}
+	if x.ColoSockCompareNotifyPort != "" {
+		xc.colo_sock_compare_notify_port = C.CString(x.ColoSockCompareNotifyPort)
+	}
+	if x.ColoSockRedirector0Id != "" {
+		xc.colo_sock_redirector0_id = C.CString(x.ColoSockRedirector0Id)
+	}
+	if x.ColoSockRedirector0Ip != "" {
+		xc.colo_sock_redirector0_ip = C.CString(x.ColoSockRedirector0Ip)
+	}
+	if x.ColoSockRedirector0Port != "" {
+		xc.colo_sock_redirector0_port = C.CString(x.ColoSockRedirector0Port)
+	}
+	if x.ColoSockRedirector1Id != "" {
+		xc.colo_sock_redirector1_id = C.CString(x.ColoSockRedirector1Id)
+	}
+	if x.ColoSockRedirector1Ip != "" {
+		xc.colo_sock_redirector1_ip = C.CString(x.ColoSockRedirector1Ip)
+	}
+	if x.ColoSockRedirector1Port != "" {
+		xc.colo_sock_redirector1_port = C.CString(x.ColoSockRedirector1Port)
+	}
+	if x.ColoSockRedirector2Id != "" {
+		xc.colo_sock_redirector2_id = C.CString(x.ColoSockRedirector2Id)
+	}
+	if x.ColoSockRedirector2Ip != "" {
+		xc.colo_sock_redirector2_ip = C.CString(x.ColoSockRedirector2Ip)
+	}
+	if x.ColoSockRedirector2Port != "" {
+		xc.colo_sock_redirector2_port = C.CString(x.ColoSockRedirector2Port)
+	}
+	if x.ColoFilterMirrorQueue != "" {
+		xc.colo_filter_mirror_queue = C.CString(x.ColoFilterMirrorQueue)
+	}
+	if x.ColoFilterMirrorOutdev != "" {
+		xc.colo_filter_mirror_outdev = C.CString(x.ColoFilterMirrorOutdev)
+	}
+	if x.ColoFilterRedirector0Queue != "" {
+		xc.colo_filter_redirector0_queue = C.CString(x.ColoFilterRedirector0Queue)
+	}
+	if x.ColoFilterRedirector0Indev != "" {
+		xc.colo_filter_redirector0_indev = C.CString(x.ColoFilterRedirector0Indev)
+	}
+	if x.ColoFilterRedirector0Outdev != "" {
+		xc.colo_filter_redirector0_outdev = C.CString(x.ColoFilterRedirector0Outdev)
+	}
+	if x.ColoFilterRedirector1Queue != "" {
+		xc.colo_filter_redirector1_queue = C.CString(x.ColoFilterRedirector1Queue)
+	}
+	if x.ColoFilterRedirector1Indev != "" {
+		xc.colo_filter_redirector1_indev = C.CString(x.ColoFilterRedirector1Indev)
+	}
+	if x.ColoFilterRedirector1Outdev != "" {
+		xc.colo_filter_redirector1_outdev = C.CString(x.ColoFilterRedirector1Outdev)
+	}
+	if x.ColoComparePriIn != "" {
+		xc.colo_compare_pri_in = C.CString(x.ColoComparePriIn)
+	}
+	if x.ColoCompareSecIn != "" {
+		xc.colo_compare_sec_in = C.CString(x.ColoCompareSecIn)
+	}
+	if x.ColoCompareOut != "" {
+		xc.colo_compare_out = C.CString(x.ColoCompareOut)
+	}
+	if x.ColoCompareNotifyDev != "" {
+		xc.colo_compare_notify_dev = C.CString(x.ColoCompareNotifyDev)
+	}
+	if x.ColoSockSecRedirector0Id != "" {
+		xc.colo_sock_sec_redirector0_id = C.CString(x.ColoSockSecRedirector0Id)
+	}
+	if x.ColoSockSecRedirector0Ip != "" {
+		xc.colo_sock_sec_redirector0_ip = C.CString(x.ColoSockSecRedirector0Ip)
+	}
+	if x.ColoSockSecRedirector0Port != "" {
+		xc.colo_sock_sec_redirector0_port = C.CString(x.ColoSockSecRedirector0Port)
+	}
+	if x.ColoSockSecRedirector1Id != "" {
+		xc.colo_sock_sec_redirector1_id = C.CString(x.ColoSockSecRedirector1Id)
+	}
+	if x.ColoSockSecRedirector1Ip != "" {
+		xc.colo_sock_sec_redirector1_ip = C.CString(x.ColoSockSecRedirector1Ip)
+	}
+	if x.ColoSockSecRedirector1Port != "" {
+		xc.colo_sock_sec_redirector1_port = C.CString(x.ColoSockSecRedirector1Port)
+	}
+	if x.ColoFilterSecRedirector0Queue != "" {
+		xc.colo_filter_sec_redirector0_queue = C.CString(x.ColoFilterSecRedirector0Queue)
+	}
+	if x.ColoFilterSecRedirector0Indev != "" {
+		xc.colo_filter_sec_redirector0_indev = C.CString(x.ColoFilterSecRedirector0Indev)
+	}
+	if x.ColoFilterSecRedirector0Outdev != "" {
+		xc.colo_filter_sec_redirector0_outdev = C.CString(x.ColoFilterSecRedirector0Outdev)
+	}
+	if x.ColoFilterSecRedirector1Queue != "" {
+		xc.colo_filter_sec_redirector1_queue = C.CString(x.ColoFilterSecRedirector1Queue)
+	}
+	if x.ColoFilterSecRedirector1Indev != "" {
+		xc.colo_filter_sec_redirector1_indev = C.CString(x.ColoFilterSecRedirector1Indev)
+	}
+	if x.ColoFilterSecRedirector1Outdev != "" {
+		xc.colo_filter_sec_redirector1_outdev = C.CString(x.ColoFilterSecRedirector1Outdev)
+	}
+	if x.ColoFilterSecRewriter0Queue != "" {
+		xc.colo_filter_sec_rewriter0_queue = C.CString(x.ColoFilterSecRewriter0Queue)
+	}
+	if x.ColoCheckpointHost != "" {
+		xc.colo_checkpoint_host = C.CString(x.ColoCheckpointHost)
+	}
+	if x.ColoCheckpointPort != "" {
+		xc.colo_checkpoint_port = C.CString(x.ColoCheckpointPort)
+	}
+
+	return nil
+}
+
+// NewDevicePci returns an instance of DevicePci initialized with defaults.
+func NewDevicePci() (*DevicePci, error) {
+	var (
+		x  DevicePci
+		xc C.libxl_device_pci
+	)
+
+	C.libxl_device_pci_init(&xc)
+	defer C.libxl_device_pci_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DevicePci) fromC(xc *C.libxl_device_pci) error {
+	x.Func = byte(xc._func)
+	x.Dev = byte(xc.dev)
+	x.Bus = byte(xc.bus)
+	x.Domain = int(xc.domain)
+	x.Vdevfn = uint32(xc.vdevfn)
+	x.VfuncMask = uint32(xc.vfunc_mask)
+	x.Msitranslate = bool(xc.msitranslate)
+	x.PowerMgmt = bool(xc.power_mgmt)
+	x.Permissive = bool(xc.permissive)
+	x.Seize = bool(xc.seize)
+	x.RdmPolicy = RdmReservePolicy(xc.rdm_policy)
+
+	return nil
+}
+
+func (x *DevicePci) toC(xc *C.libxl_device_pci) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_pci_dispose(xc)
+		}
+	}()
+
+	xc._func = C.uint8_t(x.Func)
+	xc.dev = C.uint8_t(x.Dev)
+	xc.bus = C.uint8_t(x.Bus)
+	xc.domain = C.int(x.Domain)
+	xc.vdevfn = C.uint32_t(x.Vdevfn)
+	xc.vfunc_mask = C.uint32_t(x.VfuncMask)
+	xc.msitranslate = C.bool(x.Msitranslate)
+	xc.power_mgmt = C.bool(x.PowerMgmt)
+	xc.permissive = C.bool(x.Permissive)
+	xc.seize = C.bool(x.Seize)
+	xc.rdm_policy = C.libxl_rdm_reserve_policy(x.RdmPolicy)
+
+	return nil
+}
+
+// NewDeviceRdm returns an instance of DeviceRdm initialized with defaults.
+func NewDeviceRdm() (*DeviceRdm, error) {
+	var (
+		x  DeviceRdm
+		xc C.libxl_device_rdm
+	)
+
+	C.libxl_device_rdm_init(&xc)
+	defer C.libxl_device_rdm_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceRdm) fromC(xc *C.libxl_device_rdm) error {
+	x.Start = uint64(xc.start)
+	x.Size = uint64(xc.size)
+	x.Policy = RdmReservePolicy(xc.policy)
+
+	return nil
+}
+
+func (x *DeviceRdm) toC(xc *C.libxl_device_rdm) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_rdm_dispose(xc)
+		}
+	}()
+
+	xc.start = C.uint64_t(x.Start)
+	xc.size = C.uint64_t(x.Size)
+	xc.policy = C.libxl_rdm_reserve_policy(x.Policy)
+
+	return nil
+}
+
+// NewDeviceUsbctrl returns an instance of DeviceUsbctrl initialized with defaults.
+func NewDeviceUsbctrl() (*DeviceUsbctrl, error) {
+	var (
+		x  DeviceUsbctrl
+		xc C.libxl_device_usbctrl
+	)
+
+	C.libxl_device_usbctrl_init(&xc)
+	defer C.libxl_device_usbctrl_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceUsbctrl) fromC(xc *C.libxl_device_usbctrl) error {
+	x.Type = UsbctrlType(xc._type)
+	x.Devid = Devid(xc.devid)
+	x.Version = int(xc.version)
+	x.Ports = int(xc.ports)
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+
+	return nil
+}
+
+func (x *DeviceUsbctrl) toC(xc *C.libxl_device_usbctrl) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_usbctrl_dispose(xc)
+		}
+	}()
+
+	xc._type = C.libxl_usbctrl_type(x.Type)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.version = C.int(x.Version)
+	xc.ports = C.int(x.Ports)
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+
+	return nil
+}
+
+// NewDeviceUsbdev returns an instance of DeviceUsbdev initialized with defaults.
+func NewDeviceUsbdev(utype UsbdevType) (*DeviceUsbdev, error) {
+	var (
+		x  DeviceUsbdev
+		xc C.libxl_device_usbdev
+	)
+
+	C.libxl_device_usbdev_init(&xc)
+	C.libxl_device_usbdev_init_type(&xc, C.libxl_usbdev_type(utype))
+	defer C.libxl_device_usbdev_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+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 fmt.Errorf("converting field typeHostdev: %v", 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 *DeviceUsbdev) toC(xc *C.libxl_device_usbdev) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_usbdev_dispose(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 {
+			return 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 fmt.Errorf("invalid union key '%v'", x.Type)
+	}
+
+	return nil
+}
+
+// NewDeviceDtdev returns an instance of DeviceDtdev initialized with defaults.
+func NewDeviceDtdev() (*DeviceDtdev, error) {
+	var (
+		x  DeviceDtdev
+		xc C.libxl_device_dtdev
+	)
+
+	C.libxl_device_dtdev_init(&xc)
+	defer C.libxl_device_dtdev_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceDtdev) fromC(xc *C.libxl_device_dtdev) error {
+	x.Path = C.GoString(xc.path)
+
+	return nil
+}
+
+func (x *DeviceDtdev) toC(xc *C.libxl_device_dtdev) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_dtdev_dispose(xc)
+		}
+	}()
+
+	if x.Path != "" {
+		xc.path = C.CString(x.Path)
+	}
+
+	return nil
+}
+
+// NewDeviceVtpm returns an instance of DeviceVtpm initialized with defaults.
+func NewDeviceVtpm() (*DeviceVtpm, error) {
+	var (
+		x  DeviceVtpm
+		xc C.libxl_device_vtpm
+	)
+
+	C.libxl_device_vtpm_init(&xc)
+	defer C.libxl_device_vtpm_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceVtpm) fromC(xc *C.libxl_device_vtpm) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	if err := x.Uuid.fromC(&xc.uuid); err != nil {
+		return fmt.Errorf("converting field Uuid: %v", err)
+	}
+
+	return nil
+}
+
+func (x *DeviceVtpm) toC(xc *C.libxl_device_vtpm) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_vtpm_dispose(xc)
+		}
+	}()
+
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	xc.devid = C.libxl_devid(x.Devid)
+	if err := x.Uuid.toC(&xc.uuid); err != nil {
+		return fmt.Errorf("converting field Uuid: %v", err)
+	}
+
+	return nil
+}
+
+// NewDeviceP9 returns an instance of DeviceP9 initialized with defaults.
+func NewDeviceP9() (*DeviceP9, error) {
+	var (
+		x  DeviceP9
+		xc C.libxl_device_p9
+	)
+
+	C.libxl_device_p9_init(&xc)
+	defer C.libxl_device_p9_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceP9) fromC(xc *C.libxl_device_p9) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Tag = C.GoString(xc.tag)
+	x.Path = C.GoString(xc.path)
+	x.SecurityModel = C.GoString(xc.security_model)
+	x.Devid = Devid(xc.devid)
+
+	return nil
+}
+
+func (x *DeviceP9) toC(xc *C.libxl_device_p9) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_p9_dispose(xc)
+		}
+	}()
+
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	if x.Tag != "" {
+		xc.tag = C.CString(x.Tag)
+	}
+	if x.Path != "" {
+		xc.path = C.CString(x.Path)
+	}
+	if x.SecurityModel != "" {
+		xc.security_model = C.CString(x.SecurityModel)
+	}
+	xc.devid = C.libxl_devid(x.Devid)
+
+	return nil
+}
+
+// NewDevicePvcallsif returns an instance of DevicePvcallsif initialized with defaults.
+func NewDevicePvcallsif() (*DevicePvcallsif, error) {
+	var (
+		x  DevicePvcallsif
+		xc C.libxl_device_pvcallsif
+	)
+
+	C.libxl_device_pvcallsif_init(&xc)
+	defer C.libxl_device_pvcallsif_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DevicePvcallsif) fromC(xc *C.libxl_device_pvcallsif) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+
+	return nil
+}
+
+func (x *DevicePvcallsif) toC(xc *C.libxl_device_pvcallsif) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_pvcallsif_dispose(xc)
+		}
+	}()
+
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	xc.devid = C.libxl_devid(x.Devid)
+
+	return nil
+}
+
+// NewDeviceChannel returns an instance of DeviceChannel initialized with defaults.
+func NewDeviceChannel(connection ChannelConnection) (*DeviceChannel, error) {
+	var (
+		x  DeviceChannel
+		xc C.libxl_device_channel
+	)
+
+	C.libxl_device_channel_init(&xc)
+	C.libxl_device_channel_init_connection(&xc, C.libxl_channel_connection(connection))
+	defer C.libxl_device_channel_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceChannel) fromC(xc *C.libxl_device_channel) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	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 ChannelConnectionUnknown:
+		x.ConnectionUnion = nil
+	case ChannelConnectionPty:
+		x.ConnectionUnion = nil
+	case ChannelConnectionSocket:
+		var connectionSocket DeviceChannelConnectionUnionSocket
+		if err := connectionSocket.fromC(xc); err != nil {
+			return fmt.Errorf("converting field connectionSocket: %v", 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 *DeviceChannel) toC(xc *C.libxl_device_channel) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_channel_dispose(xc)
+		}
+	}()
+
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	xc.devid = C.libxl_devid(x.Devid)
+	if x.Name != "" {
+		xc.name = C.CString(x.Name)
+	}
+	xc.connection = C.libxl_channel_connection(x.Connection)
+	switch x.Connection {
+	case ChannelConnectionUnknown:
+		break
+	case ChannelConnectionPty:
+		break
+	case ChannelConnectionSocket:
+		tmp, ok := x.ConnectionUnion.(DeviceChannelConnectionUnionSocket)
+		if !ok {
+			return errors.New("wrong type for union key connection")
+		}
+		var socket C.libxl_device_channel_connection_union_socket
+		if tmp.Path != "" {
+			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 fmt.Errorf("invalid union key '%v'", x.Connection)
+	}
+
+	return nil
+}
+
+// NewConnectorParam returns an instance of ConnectorParam initialized with defaults.
+func NewConnectorParam() (*ConnectorParam, error) {
+	var (
+		x  ConnectorParam
+		xc C.libxl_connector_param
+	)
+
+	C.libxl_connector_param_init(&xc)
+	defer C.libxl_connector_param_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *ConnectorParam) fromC(xc *C.libxl_connector_param) error {
+	x.UniqueId = C.GoString(xc.unique_id)
+	x.Width = uint32(xc.width)
+	x.Height = uint32(xc.height)
+
+	return nil
+}
+
+func (x *ConnectorParam) toC(xc *C.libxl_connector_param) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_connector_param_dispose(xc)
+		}
+	}()
+
+	if x.UniqueId != "" {
+		xc.unique_id = C.CString(x.UniqueId)
+	}
+	xc.width = C.uint32_t(x.Width)
+	xc.height = C.uint32_t(x.Height)
+
+	return nil
+}
+
+// NewDeviceVdispl returns an instance of DeviceVdispl initialized with defaults.
+func NewDeviceVdispl() (*DeviceVdispl, error) {
+	var (
+		x  DeviceVdispl
+		xc C.libxl_device_vdispl
+	)
+
+	C.libxl_device_vdispl_init(&xc)
+	defer C.libxl_device_vdispl_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceVdispl) fromC(xc *C.libxl_device_vdispl) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	x.BeAlloc = bool(xc.be_alloc)
+	x.Connectors = nil
+	if n := int(xc.num_connectors); n > 0 {
+		cConnectors := (*[1 << 28]C.libxl_connector_param)(unsafe.Pointer(xc.connectors))[:n:n]
+		x.Connectors = make([]ConnectorParam, n)
+		for i, v := range cConnectors {
+			if err := x.Connectors[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Connectors: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+func (x *DeviceVdispl) toC(xc *C.libxl_device_vdispl) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_vdispl_dispose(xc)
+		}
+	}()
+
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.be_alloc = C.bool(x.BeAlloc)
+	if numConnectors := len(x.Connectors); numConnectors > 0 {
+		xc.connectors = (*C.libxl_connector_param)(C.malloc(C.ulong(numConnectors) * C.sizeof_libxl_connector_param))
+		xc.num_connectors = C.int(numConnectors)
+		cConnectors := (*[1 << 28]C.libxl_connector_param)(unsafe.Pointer(xc.connectors))[:numConnectors:numConnectors]
+		for i, v := range x.Connectors {
+			if err := v.toC(&cConnectors[i]); err != nil {
+				return fmt.Errorf("converting field Connectors: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+// NewVsndParams returns an instance of VsndParams initialized with defaults.
+func NewVsndParams() (*VsndParams, error) {
+	var (
+		x  VsndParams
+		xc C.libxl_vsnd_params
+	)
+
+	C.libxl_vsnd_params_init(&xc)
+	defer C.libxl_vsnd_params_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *VsndParams) fromC(xc *C.libxl_vsnd_params) error {
+	x.SampleRates = nil
+	if n := int(xc.num_sample_rates); n > 0 {
+		cSampleRates := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.sample_rates))[:n:n]
+		x.SampleRates = make([]uint32, n)
+		for i, v := range cSampleRates {
+			x.SampleRates[i] = uint32(v)
+		}
+	}
+	x.SampleFormats = nil
+	if n := int(xc.num_sample_formats); n > 0 {
+		cSampleFormats := (*[1 << 28]C.libxl_vsnd_pcm_format)(unsafe.Pointer(xc.sample_formats))[:n:n]
+		x.SampleFormats = make([]VsndPcmFormat, n)
+		for i, v := range cSampleFormats {
+			x.SampleFormats[i] = VsndPcmFormat(v)
+		}
+	}
+	x.ChannelsMin = uint32(xc.channels_min)
+	x.ChannelsMax = uint32(xc.channels_max)
+	x.BufferSize = uint32(xc.buffer_size)
+
+	return nil
+}
+
+func (x *VsndParams) toC(xc *C.libxl_vsnd_params) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vsnd_params_dispose(xc)
+		}
+	}()
+
+	if numSampleRates := len(x.SampleRates); numSampleRates > 0 {
+		xc.sample_rates = (*C.uint32_t)(C.malloc(C.size_t(numSampleRates * numSampleRates)))
+		xc.num_sample_rates = C.int(numSampleRates)
+		cSampleRates := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.sample_rates))[:numSampleRates:numSampleRates]
+		for i, v := range x.SampleRates {
+			cSampleRates[i] = C.uint32_t(v)
+		}
+	}
+	if numSampleFormats := len(x.SampleFormats); numSampleFormats > 0 {
+		xc.sample_formats = (*C.libxl_vsnd_pcm_format)(C.malloc(C.size_t(numSampleFormats * numSampleFormats)))
+		xc.num_sample_formats = C.int(numSampleFormats)
+		cSampleFormats := (*[1 << 28]C.libxl_vsnd_pcm_format)(unsafe.Pointer(xc.sample_formats))[:numSampleFormats:numSampleFormats]
+		for i, v := range x.SampleFormats {
+			cSampleFormats[i] = C.libxl_vsnd_pcm_format(v)
+		}
+	}
+	xc.channels_min = C.uint32_t(x.ChannelsMin)
+	xc.channels_max = C.uint32_t(x.ChannelsMax)
+	xc.buffer_size = C.uint32_t(x.BufferSize)
+
+	return nil
+}
+
+// NewVsndStream returns an instance of VsndStream initialized with defaults.
+func NewVsndStream() (*VsndStream, error) {
+	var (
+		x  VsndStream
+		xc C.libxl_vsnd_stream
+	)
+
+	C.libxl_vsnd_stream_init(&xc)
+	defer C.libxl_vsnd_stream_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *VsndStream) fromC(xc *C.libxl_vsnd_stream) error {
+	x.UniqueId = C.GoString(xc.unique_id)
+	x.Type = VsndStreamType(xc._type)
+	if err := x.Params.fromC(&xc.params); err != nil {
+		return fmt.Errorf("converting field Params: %v", err)
+	}
+
+	return nil
+}
+
+func (x *VsndStream) toC(xc *C.libxl_vsnd_stream) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vsnd_stream_dispose(xc)
+		}
+	}()
+
+	if x.UniqueId != "" {
+		xc.unique_id = C.CString(x.UniqueId)
+	}
+	xc._type = C.libxl_vsnd_stream_type(x.Type)
+	if err := x.Params.toC(&xc.params); err != nil {
+		return fmt.Errorf("converting field Params: %v", err)
+	}
+
+	return nil
+}
+
+// NewVsndPcm returns an instance of VsndPcm initialized with defaults.
+func NewVsndPcm() (*VsndPcm, error) {
+	var (
+		x  VsndPcm
+		xc C.libxl_vsnd_pcm
+	)
+
+	C.libxl_vsnd_pcm_init(&xc)
+	defer C.libxl_vsnd_pcm_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *VsndPcm) fromC(xc *C.libxl_vsnd_pcm) error {
+	x.Name = C.GoString(xc.name)
+	if err := x.Params.fromC(&xc.params); err != nil {
+		return fmt.Errorf("converting field Params: %v", err)
+	}
+	x.Streams = nil
+	if n := int(xc.num_vsnd_streams); n > 0 {
+		cStreams := (*[1 << 28]C.libxl_vsnd_stream)(unsafe.Pointer(xc.streams))[:n:n]
+		x.Streams = make([]VsndStream, n)
+		for i, v := range cStreams {
+			if err := x.Streams[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Streams: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+func (x *VsndPcm) toC(xc *C.libxl_vsnd_pcm) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vsnd_pcm_dispose(xc)
+		}
+	}()
+
+	if x.Name != "" {
+		xc.name = C.CString(x.Name)
+	}
+	if err := x.Params.toC(&xc.params); err != nil {
+		return fmt.Errorf("converting field Params: %v", err)
+	}
+	if numVsndStreams := len(x.Streams); numVsndStreams > 0 {
+		xc.streams = (*C.libxl_vsnd_stream)(C.malloc(C.ulong(numVsndStreams) * C.sizeof_libxl_vsnd_stream))
+		xc.num_vsnd_streams = C.int(numVsndStreams)
+		cStreams := (*[1 << 28]C.libxl_vsnd_stream)(unsafe.Pointer(xc.streams))[:numVsndStreams:numVsndStreams]
+		for i, v := range x.Streams {
+			if err := v.toC(&cStreams[i]); err != nil {
+				return fmt.Errorf("converting field Streams: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+// NewDeviceVsnd returns an instance of DeviceVsnd initialized with defaults.
+func NewDeviceVsnd() (*DeviceVsnd, error) {
+	var (
+		x  DeviceVsnd
+		xc C.libxl_device_vsnd
+	)
+
+	C.libxl_device_vsnd_init(&xc)
+	defer C.libxl_device_vsnd_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DeviceVsnd) fromC(xc *C.libxl_device_vsnd) error {
+	x.BackendDomid = Domid(xc.backend_domid)
+	x.BackendDomname = C.GoString(xc.backend_domname)
+	x.Devid = Devid(xc.devid)
+	x.ShortName = C.GoString(xc.short_name)
+	x.LongName = C.GoString(xc.long_name)
+	if err := x.Params.fromC(&xc.params); err != nil {
+		return fmt.Errorf("converting field Params: %v", err)
+	}
+	x.Pcms = nil
+	if n := int(xc.num_vsnd_pcms); n > 0 {
+		cPcms := (*[1 << 28]C.libxl_vsnd_pcm)(unsafe.Pointer(xc.pcms))[:n:n]
+		x.Pcms = make([]VsndPcm, n)
+		for i, v := range cPcms {
+			if err := x.Pcms[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Pcms: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+func (x *DeviceVsnd) toC(xc *C.libxl_device_vsnd) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_device_vsnd_dispose(xc)
+		}
+	}()
+
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	xc.devid = C.libxl_devid(x.Devid)
+	if x.ShortName != "" {
+		xc.short_name = C.CString(x.ShortName)
+	}
+	if x.LongName != "" {
+		xc.long_name = C.CString(x.LongName)
+	}
+	if err := x.Params.toC(&xc.params); err != nil {
+		return fmt.Errorf("converting field Params: %v", err)
+	}
+	if numVsndPcms := len(x.Pcms); numVsndPcms > 0 {
+		xc.pcms = (*C.libxl_vsnd_pcm)(C.malloc(C.ulong(numVsndPcms) * C.sizeof_libxl_vsnd_pcm))
+		xc.num_vsnd_pcms = C.int(numVsndPcms)
+		cPcms := (*[1 << 28]C.libxl_vsnd_pcm)(unsafe.Pointer(xc.pcms))[:numVsndPcms:numVsndPcms]
+		for i, v := range x.Pcms {
+			if err := v.toC(&cPcms[i]); err != nil {
+				return fmt.Errorf("converting field Pcms: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+// NewDomainConfig returns an instance of DomainConfig initialized with defaults.
+func NewDomainConfig() (*DomainConfig, error) {
+	var (
+		x  DomainConfig
+		xc C.libxl_domain_config
+	)
+
+	C.libxl_domain_config_init(&xc)
+	defer C.libxl_domain_config_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DomainConfig) fromC(xc *C.libxl_domain_config) error {
+	if err := x.CInfo.fromC(&xc.c_info); err != nil {
+		return fmt.Errorf("converting field CInfo: %v", err)
+	}
+	if err := x.BInfo.fromC(&xc.b_info); err != nil {
+		return fmt.Errorf("converting field BInfo: %v", err)
+	}
+	x.Disks = nil
+	if n := int(xc.num_disks); n > 0 {
+		cDisks := (*[1 << 28]C.libxl_device_disk)(unsafe.Pointer(xc.disks))[:n:n]
+		x.Disks = make([]DeviceDisk, n)
+		for i, v := range cDisks {
+			if err := x.Disks[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Disks: %v", err)
+			}
+		}
+	}
+	x.Nics = nil
+	if n := int(xc.num_nics); n > 0 {
+		cNics := (*[1 << 28]C.libxl_device_nic)(unsafe.Pointer(xc.nics))[:n:n]
+		x.Nics = make([]DeviceNic, n)
+		for i, v := range cNics {
+			if err := x.Nics[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Nics: %v", err)
+			}
+		}
+	}
+	x.Pcidevs = nil
+	if n := int(xc.num_pcidevs); n > 0 {
+		cPcidevs := (*[1 << 28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:n:n]
+		x.Pcidevs = make([]DevicePci, n)
+		for i, v := range cPcidevs {
+			if err := x.Pcidevs[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Pcidevs: %v", err)
+			}
+		}
+	}
+	x.Rdms = nil
+	if n := int(xc.num_rdms); n > 0 {
+		cRdms := (*[1 << 28]C.libxl_device_rdm)(unsafe.Pointer(xc.rdms))[:n:n]
+		x.Rdms = make([]DeviceRdm, n)
+		for i, v := range cRdms {
+			if err := x.Rdms[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Rdms: %v", err)
+			}
+		}
+	}
+	x.Dtdevs = nil
+	if n := int(xc.num_dtdevs); n > 0 {
+		cDtdevs := (*[1 << 28]C.libxl_device_dtdev)(unsafe.Pointer(xc.dtdevs))[:n:n]
+		x.Dtdevs = make([]DeviceDtdev, n)
+		for i, v := range cDtdevs {
+			if err := x.Dtdevs[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Dtdevs: %v", err)
+			}
+		}
+	}
+	x.Vfbs = nil
+	if n := int(xc.num_vfbs); n > 0 {
+		cVfbs := (*[1 << 28]C.libxl_device_vfb)(unsafe.Pointer(xc.vfbs))[:n:n]
+		x.Vfbs = make([]DeviceVfb, n)
+		for i, v := range cVfbs {
+			if err := x.Vfbs[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Vfbs: %v", err)
+			}
+		}
+	}
+	x.Vkbs = nil
+	if n := int(xc.num_vkbs); n > 0 {
+		cVkbs := (*[1 << 28]C.libxl_device_vkb)(unsafe.Pointer(xc.vkbs))[:n:n]
+		x.Vkbs = make([]DeviceVkb, n)
+		for i, v := range cVkbs {
+			if err := x.Vkbs[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Vkbs: %v", err)
+			}
+		}
+	}
+	x.Vtpms = nil
+	if n := int(xc.num_vtpms); n > 0 {
+		cVtpms := (*[1 << 28]C.libxl_device_vtpm)(unsafe.Pointer(xc.vtpms))[:n:n]
+		x.Vtpms = make([]DeviceVtpm, n)
+		for i, v := range cVtpms {
+			if err := x.Vtpms[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Vtpms: %v", err)
+			}
+		}
+	}
+	x.P9S = nil
+	if n := int(xc.num_p9s); n > 0 {
+		cP9S := (*[1 << 28]C.libxl_device_p9)(unsafe.Pointer(xc.p9s))[:n:n]
+		x.P9S = make([]DeviceP9, n)
+		for i, v := range cP9S {
+			if err := x.P9S[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field P9S: %v", err)
+			}
+		}
+	}
+	x.Pvcallsifs = nil
+	if n := int(xc.num_pvcallsifs); n > 0 {
+		cPvcallsifs := (*[1 << 28]C.libxl_device_pvcallsif)(unsafe.Pointer(xc.pvcallsifs))[:n:n]
+		x.Pvcallsifs = make([]DevicePvcallsif, n)
+		for i, v := range cPvcallsifs {
+			if err := x.Pvcallsifs[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Pvcallsifs: %v", err)
+			}
+		}
+	}
+	x.Vdispls = nil
+	if n := int(xc.num_vdispls); n > 0 {
+		cVdispls := (*[1 << 28]C.libxl_device_vdispl)(unsafe.Pointer(xc.vdispls))[:n:n]
+		x.Vdispls = make([]DeviceVdispl, n)
+		for i, v := range cVdispls {
+			if err := x.Vdispls[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Vdispls: %v", err)
+			}
+		}
+	}
+	x.Vsnds = nil
+	if n := int(xc.num_vsnds); n > 0 {
+		cVsnds := (*[1 << 28]C.libxl_device_vsnd)(unsafe.Pointer(xc.vsnds))[:n:n]
+		x.Vsnds = make([]DeviceVsnd, n)
+		for i, v := range cVsnds {
+			if err := x.Vsnds[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Vsnds: %v", err)
+			}
+		}
+	}
+	x.Channels = nil
+	if n := int(xc.num_channels); n > 0 {
+		cChannels := (*[1 << 28]C.libxl_device_channel)(unsafe.Pointer(xc.channels))[:n:n]
+		x.Channels = make([]DeviceChannel, n)
+		for i, v := range cChannels {
+			if err := x.Channels[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Channels: %v", err)
+			}
+		}
+	}
+	x.Usbctrls = nil
+	if n := int(xc.num_usbctrls); n > 0 {
+		cUsbctrls := (*[1 << 28]C.libxl_device_usbctrl)(unsafe.Pointer(xc.usbctrls))[:n:n]
+		x.Usbctrls = make([]DeviceUsbctrl, n)
+		for i, v := range cUsbctrls {
+			if err := x.Usbctrls[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Usbctrls: %v", err)
+			}
+		}
+	}
+	x.Usbdevs = nil
+	if n := int(xc.num_usbdevs); n > 0 {
+		cUsbdevs := (*[1 << 28]C.libxl_device_usbdev)(unsafe.Pointer(xc.usbdevs))[:n:n]
+		x.Usbdevs = make([]DeviceUsbdev, n)
+		for i, v := range cUsbdevs {
+			if err := x.Usbdevs[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Usbdevs: %v", err)
+			}
+		}
+	}
+	x.OnPoweroff = ActionOnShutdown(xc.on_poweroff)
+	x.OnReboot = ActionOnShutdown(xc.on_reboot)
+	x.OnWatchdog = ActionOnShutdown(xc.on_watchdog)
+	x.OnCrash = ActionOnShutdown(xc.on_crash)
+	x.OnSoftReset = ActionOnShutdown(xc.on_soft_reset)
+
+	return nil
+}
+
+func (x *DomainConfig) toC(xc *C.libxl_domain_config) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_domain_config_dispose(xc)
+		}
+	}()
+
+	if err := x.CInfo.toC(&xc.c_info); err != nil {
+		return fmt.Errorf("converting field CInfo: %v", err)
+	}
+	if err := x.BInfo.toC(&xc.b_info); err != nil {
+		return fmt.Errorf("converting field BInfo: %v", err)
+	}
+	if numDisks := len(x.Disks); numDisks > 0 {
+		xc.disks = (*C.libxl_device_disk)(C.malloc(C.ulong(numDisks) * C.sizeof_libxl_device_disk))
+		xc.num_disks = C.int(numDisks)
+		cDisks := (*[1 << 28]C.libxl_device_disk)(unsafe.Pointer(xc.disks))[:numDisks:numDisks]
+		for i, v := range x.Disks {
+			if err := v.toC(&cDisks[i]); err != nil {
+				return fmt.Errorf("converting field Disks: %v", err)
+			}
+		}
+	}
+	if numNics := len(x.Nics); numNics > 0 {
+		xc.nics = (*C.libxl_device_nic)(C.malloc(C.ulong(numNics) * C.sizeof_libxl_device_nic))
+		xc.num_nics = C.int(numNics)
+		cNics := (*[1 << 28]C.libxl_device_nic)(unsafe.Pointer(xc.nics))[:numNics:numNics]
+		for i, v := range x.Nics {
+			if err := v.toC(&cNics[i]); err != nil {
+				return fmt.Errorf("converting field Nics: %v", err)
+			}
+		}
+	}
+	if numPcidevs := len(x.Pcidevs); numPcidevs > 0 {
+		xc.pcidevs = (*C.libxl_device_pci)(C.malloc(C.ulong(numPcidevs) * C.sizeof_libxl_device_pci))
+		xc.num_pcidevs = C.int(numPcidevs)
+		cPcidevs := (*[1 << 28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:numPcidevs:numPcidevs]
+		for i, v := range x.Pcidevs {
+			if err := v.toC(&cPcidevs[i]); err != nil {
+				return fmt.Errorf("converting field Pcidevs: %v", err)
+			}
+		}
+	}
+	if numRdms := len(x.Rdms); numRdms > 0 {
+		xc.rdms = (*C.libxl_device_rdm)(C.malloc(C.ulong(numRdms) * C.sizeof_libxl_device_rdm))
+		xc.num_rdms = C.int(numRdms)
+		cRdms := (*[1 << 28]C.libxl_device_rdm)(unsafe.Pointer(xc.rdms))[:numRdms:numRdms]
+		for i, v := range x.Rdms {
+			if err := v.toC(&cRdms[i]); err != nil {
+				return fmt.Errorf("converting field Rdms: %v", err)
+			}
+		}
+	}
+	if numDtdevs := len(x.Dtdevs); numDtdevs > 0 {
+		xc.dtdevs = (*C.libxl_device_dtdev)(C.malloc(C.ulong(numDtdevs) * C.sizeof_libxl_device_dtdev))
+		xc.num_dtdevs = C.int(numDtdevs)
+		cDtdevs := (*[1 << 28]C.libxl_device_dtdev)(unsafe.Pointer(xc.dtdevs))[:numDtdevs:numDtdevs]
+		for i, v := range x.Dtdevs {
+			if err := v.toC(&cDtdevs[i]); err != nil {
+				return fmt.Errorf("converting field Dtdevs: %v", err)
+			}
+		}
+	}
+	if numVfbs := len(x.Vfbs); numVfbs > 0 {
+		xc.vfbs = (*C.libxl_device_vfb)(C.malloc(C.ulong(numVfbs) * C.sizeof_libxl_device_vfb))
+		xc.num_vfbs = C.int(numVfbs)
+		cVfbs := (*[1 << 28]C.libxl_device_vfb)(unsafe.Pointer(xc.vfbs))[:numVfbs:numVfbs]
+		for i, v := range x.Vfbs {
+			if err := v.toC(&cVfbs[i]); err != nil {
+				return fmt.Errorf("converting field Vfbs: %v", err)
+			}
+		}
+	}
+	if numVkbs := len(x.Vkbs); numVkbs > 0 {
+		xc.vkbs = (*C.libxl_device_vkb)(C.malloc(C.ulong(numVkbs) * C.sizeof_libxl_device_vkb))
+		xc.num_vkbs = C.int(numVkbs)
+		cVkbs := (*[1 << 28]C.libxl_device_vkb)(unsafe.Pointer(xc.vkbs))[:numVkbs:numVkbs]
+		for i, v := range x.Vkbs {
+			if err := v.toC(&cVkbs[i]); err != nil {
+				return fmt.Errorf("converting field Vkbs: %v", err)
+			}
+		}
+	}
+	if numVtpms := len(x.Vtpms); numVtpms > 0 {
+		xc.vtpms = (*C.libxl_device_vtpm)(C.malloc(C.ulong(numVtpms) * C.sizeof_libxl_device_vtpm))
+		xc.num_vtpms = C.int(numVtpms)
+		cVtpms := (*[1 << 28]C.libxl_device_vtpm)(unsafe.Pointer(xc.vtpms))[:numVtpms:numVtpms]
+		for i, v := range x.Vtpms {
+			if err := v.toC(&cVtpms[i]); err != nil {
+				return fmt.Errorf("converting field Vtpms: %v", err)
+			}
+		}
+	}
+	if numP9S := len(x.P9S); numP9S > 0 {
+		xc.p9s = (*C.libxl_device_p9)(C.malloc(C.ulong(numP9S) * C.sizeof_libxl_device_p9))
+		xc.num_p9s = C.int(numP9S)
+		cP9S := (*[1 << 28]C.libxl_device_p9)(unsafe.Pointer(xc.p9s))[:numP9S:numP9S]
+		for i, v := range x.P9S {
+			if err := v.toC(&cP9S[i]); err != nil {
+				return fmt.Errorf("converting field P9S: %v", err)
+			}
+		}
+	}
+	if numPvcallsifs := len(x.Pvcallsifs); numPvcallsifs > 0 {
+		xc.pvcallsifs = (*C.libxl_device_pvcallsif)(C.malloc(C.ulong(numPvcallsifs) * C.sizeof_libxl_device_pvcallsif))
+		xc.num_pvcallsifs = C.int(numPvcallsifs)
+		cPvcallsifs := (*[1 << 28]C.libxl_device_pvcallsif)(unsafe.Pointer(xc.pvcallsifs))[:numPvcallsifs:numPvcallsifs]
+		for i, v := range x.Pvcallsifs {
+			if err := v.toC(&cPvcallsifs[i]); err != nil {
+				return fmt.Errorf("converting field Pvcallsifs: %v", err)
+			}
+		}
+	}
+	if numVdispls := len(x.Vdispls); numVdispls > 0 {
+		xc.vdispls = (*C.libxl_device_vdispl)(C.malloc(C.ulong(numVdispls) * C.sizeof_libxl_device_vdispl))
+		xc.num_vdispls = C.int(numVdispls)
+		cVdispls := (*[1 << 28]C.libxl_device_vdispl)(unsafe.Pointer(xc.vdispls))[:numVdispls:numVdispls]
+		for i, v := range x.Vdispls {
+			if err := v.toC(&cVdispls[i]); err != nil {
+				return fmt.Errorf("converting field Vdispls: %v", err)
+			}
+		}
+	}
+	if numVsnds := len(x.Vsnds); numVsnds > 0 {
+		xc.vsnds = (*C.libxl_device_vsnd)(C.malloc(C.ulong(numVsnds) * C.sizeof_libxl_device_vsnd))
+		xc.num_vsnds = C.int(numVsnds)
+		cVsnds := (*[1 << 28]C.libxl_device_vsnd)(unsafe.Pointer(xc.vsnds))[:numVsnds:numVsnds]
+		for i, v := range x.Vsnds {
+			if err := v.toC(&cVsnds[i]); err != nil {
+				return fmt.Errorf("converting field Vsnds: %v", err)
+			}
+		}
+	}
+	if numChannels := len(x.Channels); numChannels > 0 {
+		xc.channels = (*C.libxl_device_channel)(C.malloc(C.ulong(numChannels) * C.sizeof_libxl_device_channel))
+		xc.num_channels = C.int(numChannels)
+		cChannels := (*[1 << 28]C.libxl_device_channel)(unsafe.Pointer(xc.channels))[:numChannels:numChannels]
+		for i, v := range x.Channels {
+			if err := v.toC(&cChannels[i]); err != nil {
+				return fmt.Errorf("converting field Channels: %v", err)
+			}
+		}
+	}
+	if numUsbctrls := len(x.Usbctrls); numUsbctrls > 0 {
+		xc.usbctrls = (*C.libxl_device_usbctrl)(C.malloc(C.ulong(numUsbctrls) * C.sizeof_libxl_device_usbctrl))
+		xc.num_usbctrls = C.int(numUsbctrls)
+		cUsbctrls := (*[1 << 28]C.libxl_device_usbctrl)(unsafe.Pointer(xc.usbctrls))[:numUsbctrls:numUsbctrls]
+		for i, v := range x.Usbctrls {
+			if err := v.toC(&cUsbctrls[i]); err != nil {
+				return fmt.Errorf("converting field Usbctrls: %v", err)
+			}
+		}
+	}
+	if numUsbdevs := len(x.Usbdevs); numUsbdevs > 0 {
+		xc.usbdevs = (*C.libxl_device_usbdev)(C.malloc(C.ulong(numUsbdevs) * C.sizeof_libxl_device_usbdev))
+		xc.num_usbdevs = C.int(numUsbdevs)
+		cUsbdevs := (*[1 << 28]C.libxl_device_usbdev)(unsafe.Pointer(xc.usbdevs))[:numUsbdevs:numUsbdevs]
+		for i, v := range x.Usbdevs {
+			if err := v.toC(&cUsbdevs[i]); err != nil {
+				return fmt.Errorf("converting field Usbdevs: %v", err)
+			}
+		}
+	}
+	xc.on_poweroff = C.libxl_action_on_shutdown(x.OnPoweroff)
+	xc.on_reboot = C.libxl_action_on_shutdown(x.OnReboot)
+	xc.on_watchdog = C.libxl_action_on_shutdown(x.OnWatchdog)
+	xc.on_crash = C.libxl_action_on_shutdown(x.OnCrash)
+	xc.on_soft_reset = C.libxl_action_on_shutdown(x.OnSoftReset)
+
+	return nil
+}
+
+// NewDiskinfo returns an instance of Diskinfo initialized with defaults.
+func NewDiskinfo() (*Diskinfo, error) {
+	var (
+		x  Diskinfo
+		xc C.libxl_diskinfo
+	)
+
+	C.libxl_diskinfo_init(&xc)
+	defer C.libxl_diskinfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Diskinfo) fromC(xc *C.libxl_diskinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.Rref = int(xc.rref)
+
+	return nil
+}
+
+func (x *Diskinfo) toC(xc *C.libxl_diskinfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_diskinfo_dispose(xc)
+		}
+	}()
+
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
+	xc.backend_id = C.uint32_t(x.BackendId)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
+	xc.frontend_id = C.uint32_t(x.FrontendId)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.state = C.int(x.State)
+	xc.evtch = C.int(x.Evtch)
+	xc.rref = C.int(x.Rref)
+
+	return nil
+}
+
+// NewNicinfo returns an instance of Nicinfo initialized with defaults.
+func NewNicinfo() (*Nicinfo, error) {
+	var (
+		x  Nicinfo
+		xc C.libxl_nicinfo
+	)
+
+	C.libxl_nicinfo_init(&xc)
+	defer C.libxl_nicinfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Nicinfo) fromC(xc *C.libxl_nicinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.RrefTx = int(xc.rref_tx)
+	x.RrefRx = int(xc.rref_rx)
+
+	return nil
+}
+
+func (x *Nicinfo) toC(xc *C.libxl_nicinfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_nicinfo_dispose(xc)
+		}
+	}()
+
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
+	xc.backend_id = C.uint32_t(x.BackendId)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
+	xc.frontend_id = C.uint32_t(x.FrontendId)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.state = C.int(x.State)
+	xc.evtch = C.int(x.Evtch)
+	xc.rref_tx = C.int(x.RrefTx)
+	xc.rref_rx = C.int(x.RrefRx)
+
+	return nil
+}
+
+// NewVtpminfo returns an instance of Vtpminfo initialized with defaults.
+func NewVtpminfo() (*Vtpminfo, error) {
+	var (
+		x  Vtpminfo
+		xc C.libxl_vtpminfo
+	)
+
+	C.libxl_vtpminfo_init(&xc)
+	defer C.libxl_vtpminfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Vtpminfo) fromC(xc *C.libxl_vtpminfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.Rref = int(xc.rref)
+	if err := x.Uuid.fromC(&xc.uuid); err != nil {
+		return fmt.Errorf("converting field Uuid: %v", err)
+	}
+
+	return nil
+}
+
+func (x *Vtpminfo) toC(xc *C.libxl_vtpminfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vtpminfo_dispose(xc)
+		}
+	}()
+
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
+	xc.backend_id = C.uint32_t(x.BackendId)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
+	xc.frontend_id = C.uint32_t(x.FrontendId)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.state = C.int(x.State)
+	xc.evtch = C.int(x.Evtch)
+	xc.rref = C.int(x.Rref)
+	if err := x.Uuid.toC(&xc.uuid); err != nil {
+		return fmt.Errorf("converting field Uuid: %v", err)
+	}
+
+	return nil
+}
+
+// NewUsbctrlinfo returns an instance of Usbctrlinfo initialized with defaults.
+func NewUsbctrlinfo() (*Usbctrlinfo, error) {
+	var (
+		x  Usbctrlinfo
+		xc C.libxl_usbctrlinfo
+	)
+
+	C.libxl_usbctrlinfo_init(&xc)
+	defer C.libxl_usbctrlinfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Usbctrlinfo) fromC(xc *C.libxl_usbctrlinfo) error {
+	x.Type = UsbctrlType(xc._type)
+	x.Devid = Devid(xc.devid)
+	x.Version = int(xc.version)
+	x.Ports = int(xc.ports)
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.RefUrb = int(xc.ref_urb)
+	x.RefConn = int(xc.ref_conn)
+
+	return nil
+}
+
+func (x *Usbctrlinfo) toC(xc *C.libxl_usbctrlinfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_usbctrlinfo_dispose(xc)
+		}
+	}()
+
+	xc._type = C.libxl_usbctrl_type(x.Type)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.version = C.int(x.Version)
+	xc.ports = C.int(x.Ports)
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
+	xc.backend_id = C.uint32_t(x.BackendId)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
+	xc.frontend_id = C.uint32_t(x.FrontendId)
+	xc.state = C.int(x.State)
+	xc.evtch = C.int(x.Evtch)
+	xc.ref_urb = C.int(x.RefUrb)
+	xc.ref_conn = C.int(x.RefConn)
+
+	return nil
+}
+
+// NewVcpuinfo returns an instance of Vcpuinfo initialized with defaults.
+func NewVcpuinfo() (*Vcpuinfo, error) {
+	var (
+		x  Vcpuinfo
+		xc C.libxl_vcpuinfo
+	)
+
+	C.libxl_vcpuinfo_init(&xc)
+	defer C.libxl_vcpuinfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Vcpuinfo) fromC(xc *C.libxl_vcpuinfo) error {
+	x.Vcpuid = uint32(xc.vcpuid)
+	x.Cpu = uint32(xc.cpu)
+	x.Online = bool(xc.online)
+	x.Blocked = bool(xc.blocked)
+	x.Running = bool(xc.running)
+	x.VcpuTime = uint64(xc.vcpu_time)
+	if err := x.Cpumap.fromC(&xc.cpumap); err != nil {
+		return fmt.Errorf("converting field Cpumap: %v", err)
+	}
+	if err := x.CpumapSoft.fromC(&xc.cpumap_soft); err != nil {
+		return fmt.Errorf("converting field CpumapSoft: %v", err)
+	}
+
+	return nil
+}
+
+func (x *Vcpuinfo) toC(xc *C.libxl_vcpuinfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vcpuinfo_dispose(xc)
+		}
+	}()
+
+	xc.vcpuid = C.uint32_t(x.Vcpuid)
+	xc.cpu = C.uint32_t(x.Cpu)
+	xc.online = C.bool(x.Online)
+	xc.blocked = C.bool(x.Blocked)
+	xc.running = C.bool(x.Running)
+	xc.vcpu_time = C.uint64_t(x.VcpuTime)
+	if err := x.Cpumap.toC(&xc.cpumap); err != nil {
+		return fmt.Errorf("converting field Cpumap: %v", err)
+	}
+	if err := x.CpumapSoft.toC(&xc.cpumap_soft); err != nil {
+		return fmt.Errorf("converting field CpumapSoft: %v", err)
+	}
+
+	return nil
+}
+
+// NewPhysinfo returns an instance of Physinfo initialized with defaults.
+func NewPhysinfo() (*Physinfo, error) {
+	var (
+		x  Physinfo
+		xc C.libxl_physinfo
+	)
+
+	C.libxl_physinfo_init(&xc)
+	defer C.libxl_physinfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Physinfo) fromC(xc *C.libxl_physinfo) error {
+	x.ThreadsPerCore = uint32(xc.threads_per_core)
+	x.CoresPerSocket = uint32(xc.cores_per_socket)
+	x.MaxCpuId = uint32(xc.max_cpu_id)
+	x.NrCpus = uint32(xc.nr_cpus)
+	x.CpuKhz = uint32(xc.cpu_khz)
+	x.TotalPages = uint64(xc.total_pages)
+	x.FreePages = uint64(xc.free_pages)
+	x.ScrubPages = uint64(xc.scrub_pages)
+	x.OutstandingPages = uint64(xc.outstanding_pages)
+	x.SharingFreedPages = uint64(xc.sharing_freed_pages)
+	x.SharingUsedFrames = uint64(xc.sharing_used_frames)
+	x.MaxPossibleMfn = uint64(xc.max_possible_mfn)
+	x.NrNodes = uint32(xc.nr_nodes)
+	if err := x.HwCap.fromC(&xc.hw_cap); err != nil {
+		return fmt.Errorf("converting field HwCap: %v", err)
+	}
+	x.CapHvm = bool(xc.cap_hvm)
+	x.CapPv = bool(xc.cap_pv)
+	x.CapHvmDirectio = bool(xc.cap_hvm_directio)
+	x.CapHap = bool(xc.cap_hap)
+	x.CapShadow = bool(xc.cap_shadow)
+	x.CapIommuHapPtShare = bool(xc.cap_iommu_hap_pt_share)
+
+	return nil
+}
+
+func (x *Physinfo) toC(xc *C.libxl_physinfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_physinfo_dispose(xc)
+		}
+	}()
+
+	xc.threads_per_core = C.uint32_t(x.ThreadsPerCore)
+	xc.cores_per_socket = C.uint32_t(x.CoresPerSocket)
+	xc.max_cpu_id = C.uint32_t(x.MaxCpuId)
+	xc.nr_cpus = C.uint32_t(x.NrCpus)
+	xc.cpu_khz = C.uint32_t(x.CpuKhz)
+	xc.total_pages = C.uint64_t(x.TotalPages)
+	xc.free_pages = C.uint64_t(x.FreePages)
+	xc.scrub_pages = C.uint64_t(x.ScrubPages)
+	xc.outstanding_pages = C.uint64_t(x.OutstandingPages)
+	xc.sharing_freed_pages = C.uint64_t(x.SharingFreedPages)
+	xc.sharing_used_frames = C.uint64_t(x.SharingUsedFrames)
+	xc.max_possible_mfn = C.uint64_t(x.MaxPossibleMfn)
+	xc.nr_nodes = C.uint32_t(x.NrNodes)
+	if err := x.HwCap.toC(&xc.hw_cap); err != nil {
+		return fmt.Errorf("converting field HwCap: %v", err)
+	}
+	xc.cap_hvm = C.bool(x.CapHvm)
+	xc.cap_pv = C.bool(x.CapPv)
+	xc.cap_hvm_directio = C.bool(x.CapHvmDirectio)
+	xc.cap_hap = C.bool(x.CapHap)
+	xc.cap_shadow = C.bool(x.CapShadow)
+	xc.cap_iommu_hap_pt_share = C.bool(x.CapIommuHapPtShare)
+
+	return nil
+}
+
+// NewConnectorinfo returns an instance of Connectorinfo initialized with defaults.
+func NewConnectorinfo() (*Connectorinfo, error) {
+	var (
+		x  Connectorinfo
+		xc C.libxl_connectorinfo
+	)
+
+	C.libxl_connectorinfo_init(&xc)
+	defer C.libxl_connectorinfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Connectorinfo) fromC(xc *C.libxl_connectorinfo) error {
+	x.UniqueId = C.GoString(xc.unique_id)
+	x.Width = uint32(xc.width)
+	x.Height = uint32(xc.height)
+	x.ReqEvtch = int(xc.req_evtch)
+	x.ReqRref = int(xc.req_rref)
+	x.EvtEvtch = int(xc.evt_evtch)
+	x.EvtRref = int(xc.evt_rref)
+
+	return nil
+}
+
+func (x *Connectorinfo) toC(xc *C.libxl_connectorinfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_connectorinfo_dispose(xc)
+		}
+	}()
+
+	if x.UniqueId != "" {
+		xc.unique_id = C.CString(x.UniqueId)
+	}
+	xc.width = C.uint32_t(x.Width)
+	xc.height = C.uint32_t(x.Height)
+	xc.req_evtch = C.int(x.ReqEvtch)
+	xc.req_rref = C.int(x.ReqRref)
+	xc.evt_evtch = C.int(x.EvtEvtch)
+	xc.evt_rref = C.int(x.EvtRref)
+
+	return nil
+}
+
+// NewVdisplinfo returns an instance of Vdisplinfo initialized with defaults.
+func NewVdisplinfo() (*Vdisplinfo, error) {
+	var (
+		x  Vdisplinfo
+		xc C.libxl_vdisplinfo
+	)
+
+	C.libxl_vdisplinfo_init(&xc)
+	defer C.libxl_vdisplinfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Vdisplinfo) fromC(xc *C.libxl_vdisplinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.BeAlloc = bool(xc.be_alloc)
+	x.Connectors = nil
+	if n := int(xc.num_connectors); n > 0 {
+		cConnectors := (*[1 << 28]C.libxl_connectorinfo)(unsafe.Pointer(xc.connectors))[:n:n]
+		x.Connectors = make([]Connectorinfo, n)
+		for i, v := range cConnectors {
+			if err := x.Connectors[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Connectors: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+func (x *Vdisplinfo) toC(xc *C.libxl_vdisplinfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vdisplinfo_dispose(xc)
+		}
+	}()
+
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
+	xc.backend_id = C.uint32_t(x.BackendId)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
+	xc.frontend_id = C.uint32_t(x.FrontendId)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.state = C.int(x.State)
+	xc.be_alloc = C.bool(x.BeAlloc)
+	if numConnectors := len(x.Connectors); numConnectors > 0 {
+		xc.connectors = (*C.libxl_connectorinfo)(C.malloc(C.ulong(numConnectors) * C.sizeof_libxl_connectorinfo))
+		xc.num_connectors = C.int(numConnectors)
+		cConnectors := (*[1 << 28]C.libxl_connectorinfo)(unsafe.Pointer(xc.connectors))[:numConnectors:numConnectors]
+		for i, v := range x.Connectors {
+			if err := v.toC(&cConnectors[i]); err != nil {
+				return fmt.Errorf("converting field Connectors: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+// NewStreaminfo returns an instance of Streaminfo initialized with defaults.
+func NewStreaminfo() (*Streaminfo, error) {
+	var (
+		x  Streaminfo
+		xc C.libxl_streaminfo
+	)
+
+	C.libxl_streaminfo_init(&xc)
+	defer C.libxl_streaminfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Streaminfo) fromC(xc *C.libxl_streaminfo) error {
+	x.ReqEvtch = int(xc.req_evtch)
+	x.ReqRref = int(xc.req_rref)
+
+	return nil
+}
+
+func (x *Streaminfo) toC(xc *C.libxl_streaminfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_streaminfo_dispose(xc)
+		}
+	}()
+
+	xc.req_evtch = C.int(x.ReqEvtch)
+	xc.req_rref = C.int(x.ReqRref)
+
+	return nil
+}
+
+// NewPcminfo returns an instance of Pcminfo initialized with defaults.
+func NewPcminfo() (*Pcminfo, error) {
+	var (
+		x  Pcminfo
+		xc C.libxl_pcminfo
+	)
+
+	C.libxl_pcminfo_init(&xc)
+	defer C.libxl_pcminfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Pcminfo) fromC(xc *C.libxl_pcminfo) error {
+	x.Streams = nil
+	if n := int(xc.num_vsnd_streams); n > 0 {
+		cStreams := (*[1 << 28]C.libxl_streaminfo)(unsafe.Pointer(xc.streams))[:n:n]
+		x.Streams = make([]Streaminfo, n)
+		for i, v := range cStreams {
+			if err := x.Streams[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Streams: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+func (x *Pcminfo) toC(xc *C.libxl_pcminfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_pcminfo_dispose(xc)
+		}
+	}()
+
+	if numVsndStreams := len(x.Streams); numVsndStreams > 0 {
+		xc.streams = (*C.libxl_streaminfo)(C.malloc(C.ulong(numVsndStreams) * C.sizeof_libxl_streaminfo))
+		xc.num_vsnd_streams = C.int(numVsndStreams)
+		cStreams := (*[1 << 28]C.libxl_streaminfo)(unsafe.Pointer(xc.streams))[:numVsndStreams:numVsndStreams]
+		for i, v := range x.Streams {
+			if err := v.toC(&cStreams[i]); err != nil {
+				return fmt.Errorf("converting field Streams: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+// NewVsndinfo returns an instance of Vsndinfo initialized with defaults.
+func NewVsndinfo() (*Vsndinfo, error) {
+	var (
+		x  Vsndinfo
+		xc C.libxl_vsndinfo
+	)
+
+	C.libxl_vsndinfo_init(&xc)
+	defer C.libxl_vsndinfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Vsndinfo) fromC(xc *C.libxl_vsndinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.Pcms = nil
+	if n := int(xc.num_vsnd_pcms); n > 0 {
+		cPcms := (*[1 << 28]C.libxl_pcminfo)(unsafe.Pointer(xc.pcms))[:n:n]
+		x.Pcms = make([]Pcminfo, n)
+		for i, v := range cPcms {
+			if err := x.Pcms[i].fromC(&v); err != nil {
+				return fmt.Errorf("converting field Pcms: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+func (x *Vsndinfo) toC(xc *C.libxl_vsndinfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vsndinfo_dispose(xc)
+		}
+	}()
+
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
+	xc.backend_id = C.uint32_t(x.BackendId)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
+	xc.frontend_id = C.uint32_t(x.FrontendId)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.state = C.int(x.State)
+	if numVsndPcms := len(x.Pcms); numVsndPcms > 0 {
+		xc.pcms = (*C.libxl_pcminfo)(C.malloc(C.ulong(numVsndPcms) * C.sizeof_libxl_pcminfo))
+		xc.num_vsnd_pcms = C.int(numVsndPcms)
+		cPcms := (*[1 << 28]C.libxl_pcminfo)(unsafe.Pointer(xc.pcms))[:numVsndPcms:numVsndPcms]
+		for i, v := range x.Pcms {
+			if err := v.toC(&cPcms[i]); err != nil {
+				return fmt.Errorf("converting field Pcms: %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+
+// NewVkbinfo returns an instance of Vkbinfo initialized with defaults.
+func NewVkbinfo() (*Vkbinfo, error) {
+	var (
+		x  Vkbinfo
+		xc C.libxl_vkbinfo
+	)
+
+	C.libxl_vkbinfo_init(&xc)
+	defer C.libxl_vkbinfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Vkbinfo) fromC(xc *C.libxl_vkbinfo) error {
+	x.Backend = C.GoString(xc.backend)
+	x.BackendId = uint32(xc.backend_id)
+	x.Frontend = C.GoString(xc.frontend)
+	x.FrontendId = uint32(xc.frontend_id)
+	x.Devid = Devid(xc.devid)
+	x.State = int(xc.state)
+	x.Evtch = int(xc.evtch)
+	x.Rref = int(xc.rref)
+
+	return nil
+}
+
+func (x *Vkbinfo) toC(xc *C.libxl_vkbinfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_vkbinfo_dispose(xc)
+		}
+	}()
+
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
+	xc.backend_id = C.uint32_t(x.BackendId)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
+	xc.frontend_id = C.uint32_t(x.FrontendId)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.state = C.int(x.State)
+	xc.evtch = C.int(x.Evtch)
+	xc.rref = C.int(x.Rref)
+
+	return nil
+}
+
+// NewNumainfo returns an instance of Numainfo initialized with defaults.
+func NewNumainfo() (*Numainfo, error) {
+	var (
+		x  Numainfo
+		xc C.libxl_numainfo
+	)
+
+	C.libxl_numainfo_init(&xc)
+	defer C.libxl_numainfo_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Numainfo) fromC(xc *C.libxl_numainfo) error {
+	x.Size = uint64(xc.size)
+	x.Free = uint64(xc.free)
+	x.Dists = nil
+	if n := int(xc.num_dists); n > 0 {
+		cDists := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.dists))[:n:n]
+		x.Dists = make([]uint32, n)
+		for i, v := range cDists {
+			x.Dists[i] = uint32(v)
+		}
+	}
+
+	return nil
+}
+
+func (x *Numainfo) toC(xc *C.libxl_numainfo) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_numainfo_dispose(xc)
+		}
+	}()
+
+	xc.size = C.uint64_t(x.Size)
+	xc.free = C.uint64_t(x.Free)
+	if numDists := len(x.Dists); numDists > 0 {
+		xc.dists = (*C.uint32_t)(C.malloc(C.size_t(numDists * numDists)))
+		xc.num_dists = C.int(numDists)
+		cDists := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.dists))[:numDists:numDists]
+		for i, v := range x.Dists {
+			cDists[i] = C.uint32_t(v)
+		}
+	}
+
+	return nil
+}
+
+// NewCputopology returns an instance of Cputopology initialized with defaults.
+func NewCputopology() (*Cputopology, error) {
+	var (
+		x  Cputopology
+		xc C.libxl_cputopology
+	)
+
+	C.libxl_cputopology_init(&xc)
+	defer C.libxl_cputopology_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Cputopology) fromC(xc *C.libxl_cputopology) error {
+	x.Core = uint32(xc.core)
+	x.Socket = uint32(xc.socket)
+	x.Node = uint32(xc.node)
+
+	return nil
+}
+
+func (x *Cputopology) toC(xc *C.libxl_cputopology) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_cputopology_dispose(xc)
+		}
+	}()
+
+	xc.core = C.uint32_t(x.Core)
+	xc.socket = C.uint32_t(x.Socket)
+	xc.node = C.uint32_t(x.Node)
+
+	return nil
+}
+
+// NewPcitopology returns an instance of Pcitopology initialized with defaults.
+func NewPcitopology() (*Pcitopology, error) {
+	var (
+		x  Pcitopology
+		xc C.libxl_pcitopology
+	)
+
+	C.libxl_pcitopology_init(&xc)
+	defer C.libxl_pcitopology_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Pcitopology) fromC(xc *C.libxl_pcitopology) error {
+	x.Seg = uint16(xc.seg)
+	x.Bus = byte(xc.bus)
+	x.Devfn = byte(xc.devfn)
+	x.Node = uint32(xc.node)
+
+	return nil
+}
+
+func (x *Pcitopology) toC(xc *C.libxl_pcitopology) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_pcitopology_dispose(xc)
+		}
+	}()
+
+	xc.seg = C.uint16_t(x.Seg)
+	xc.bus = C.uint8_t(x.Bus)
+	xc.devfn = C.uint8_t(x.Devfn)
+	xc.node = C.uint32_t(x.Node)
+
+	return nil
+}
+
+// NewSchedCreditParams returns an instance of SchedCreditParams initialized with defaults.
+func NewSchedCreditParams() (*SchedCreditParams, error) {
+	var (
+		x  SchedCreditParams
+		xc C.libxl_sched_credit_params
+	)
+
+	C.libxl_sched_credit_params_init(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *SchedCreditParams) fromC(xc *C.libxl_sched_credit_params) error {
+	x.TsliceMs = int(xc.tslice_ms)
+	x.RatelimitUs = int(xc.ratelimit_us)
+	x.VcpuMigrDelayUs = int(xc.vcpu_migr_delay_us)
+
+	return nil
+}
+
+func (x *SchedCreditParams) toC(xc *C.libxl_sched_credit_params) (err error) {
+	xc.tslice_ms = C.int(x.TsliceMs)
+	xc.ratelimit_us = C.int(x.RatelimitUs)
+	xc.vcpu_migr_delay_us = C.int(x.VcpuMigrDelayUs)
+
+	return nil
+}
+
+// NewSchedCredit2Params returns an instance of SchedCredit2Params initialized with defaults.
+func NewSchedCredit2Params() (*SchedCredit2Params, error) {
+	var (
+		x  SchedCredit2Params
+		xc C.libxl_sched_credit2_params
+	)
+
+	C.libxl_sched_credit2_params_init(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *SchedCredit2Params) fromC(xc *C.libxl_sched_credit2_params) error {
+	x.RatelimitUs = int(xc.ratelimit_us)
+
+	return nil
+}
+
+func (x *SchedCredit2Params) toC(xc *C.libxl_sched_credit2_params) (err error) {
+	xc.ratelimit_us = C.int(x.RatelimitUs)
+
+	return nil
+}
+
+// NewDomainRemusInfo returns an instance of DomainRemusInfo initialized with defaults.
+func NewDomainRemusInfo() (*DomainRemusInfo, error) {
+	var (
+		x  DomainRemusInfo
+		xc C.libxl_domain_remus_info
+	)
+
+	C.libxl_domain_remus_info_init(&xc)
+	defer C.libxl_domain_remus_info_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *DomainRemusInfo) fromC(xc *C.libxl_domain_remus_info) error {
+	x.Interval = int(xc.interval)
+	if err := x.AllowUnsafe.fromC(&xc.allow_unsafe); err != nil {
+		return fmt.Errorf("converting field AllowUnsafe: %v", err)
+	}
+	if err := x.Blackhole.fromC(&xc.blackhole); err != nil {
+		return fmt.Errorf("converting field Blackhole: %v", err)
+	}
+	if err := x.Compression.fromC(&xc.compression); err != nil {
+		return fmt.Errorf("converting field Compression: %v", err)
+	}
+	if err := x.Netbuf.fromC(&xc.netbuf); err != nil {
+		return fmt.Errorf("converting field Netbuf: %v", err)
+	}
+	x.Netbufscript = C.GoString(xc.netbufscript)
+	if err := x.Diskbuf.fromC(&xc.diskbuf); err != nil {
+		return fmt.Errorf("converting field Diskbuf: %v", err)
+	}
+	if err := x.Colo.fromC(&xc.colo); err != nil {
+		return fmt.Errorf("converting field Colo: %v", err)
+	}
+	if err := x.UserspaceColoProxy.fromC(&xc.userspace_colo_proxy); err != nil {
+		return fmt.Errorf("converting field UserspaceColoProxy: %v", err)
+	}
+
+	return nil
+}
+
+func (x *DomainRemusInfo) toC(xc *C.libxl_domain_remus_info) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_domain_remus_info_dispose(xc)
+		}
+	}()
+
+	xc.interval = C.int(x.Interval)
+	if err := x.AllowUnsafe.toC(&xc.allow_unsafe); err != nil {
+		return fmt.Errorf("converting field AllowUnsafe: %v", err)
+	}
+	if err := x.Blackhole.toC(&xc.blackhole); err != nil {
+		return fmt.Errorf("converting field Blackhole: %v", err)
+	}
+	if err := x.Compression.toC(&xc.compression); err != nil {
+		return fmt.Errorf("converting field Compression: %v", err)
+	}
+	if err := x.Netbuf.toC(&xc.netbuf); err != nil {
+		return fmt.Errorf("converting field Netbuf: %v", err)
+	}
+	if x.Netbufscript != "" {
+		xc.netbufscript = C.CString(x.Netbufscript)
+	}
+	if err := x.Diskbuf.toC(&xc.diskbuf); err != nil {
+		return fmt.Errorf("converting field Diskbuf: %v", err)
+	}
+	if err := x.Colo.toC(&xc.colo); err != nil {
+		return fmt.Errorf("converting field Colo: %v", err)
+	}
+	if err := x.UserspaceColoProxy.toC(&xc.userspace_colo_proxy); err != nil {
+		return fmt.Errorf("converting field UserspaceColoProxy: %v", err)
+	}
+
+	return nil
+}
+
+// NewEvent returns an instance of Event initialized with defaults.
+func NewEvent(etype EventType) (*Event, error) {
+	var (
+		x  Event
+		xc C.libxl_event
+	)
+
+	C.libxl_event_init(&xc)
+	C.libxl_event_init_type(&xc, C.libxl_event_type(etype))
+	defer C.libxl_event_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *Event) fromC(xc *C.libxl_event) error {
+	if err := x.Link.fromC(&xc.link); err != nil {
+		return fmt.Errorf("converting field Link: %v", err)
+	}
+	x.Domid = Domid(xc.domid)
+	if err := x.Domuuid.fromC(&xc.domuuid); err != nil {
+		return fmt.Errorf("converting field Domuuid: %v", err)
+	}
+	x.ForUser = uint64(xc.for_user)
+	x.Type = EventType(xc._type)
+	switch x.Type {
+	case EventTypeDomainShutdown:
+		var typeDomainShutdown EventTypeUnionDomainShutdown
+		if err := typeDomainShutdown.fromC(xc); err != nil {
+			return fmt.Errorf("converting field typeDomainShutdown: %v", err)
+		}
+		x.TypeUnion = typeDomainShutdown
+	case EventTypeDomainDeath:
+		x.TypeUnion = nil
+	case EventTypeDiskEject:
+		var typeDiskEject EventTypeUnionDiskEject
+		if err := typeDiskEject.fromC(xc); err != nil {
+			return fmt.Errorf("converting field typeDiskEject: %v", err)
+		}
+		x.TypeUnion = typeDiskEject
+	case EventTypeOperationComplete:
+		var typeOperationComplete EventTypeUnionOperationComplete
+		if err := typeOperationComplete.fromC(xc); err != nil {
+			return fmt.Errorf("converting field typeOperationComplete: %v", err)
+		}
+		x.TypeUnion = typeOperationComplete
+	case EventTypeDomainCreateConsoleAvailable:
+		x.TypeUnion = nil
+	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 fmt.Errorf("converting field Disk: %v", 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 *Event) toC(xc *C.libxl_event) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_event_dispose(xc)
+		}
+	}()
+
+	if err := x.Link.toC(&xc.link); err != nil {
+		return fmt.Errorf("converting field Link: %v", err)
+	}
+	xc.domid = C.libxl_domid(x.Domid)
+	if err := x.Domuuid.toC(&xc.domuuid); err != nil {
+		return fmt.Errorf("converting field Domuuid: %v", 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 {
+			return 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 EventTypeDomainDeath:
+		break
+	case EventTypeDiskEject:
+		tmp, ok := x.TypeUnion.(EventTypeUnionDiskEject)
+		if !ok {
+			return errors.New("wrong type for union key type")
+		}
+		var disk_eject C.libxl_event_type_union_disk_eject
+		if tmp.Vdev != "" {
+			disk_eject.vdev = C.CString(tmp.Vdev)
+		}
+		if err := tmp.Disk.toC(&disk_eject.disk); err != nil {
+			return fmt.Errorf("converting field Disk: %v", 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 {
+			return 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)
+	case EventTypeDomainCreateConsoleAvailable:
+		break
+	default:
+		return fmt.Errorf("invalid union key '%v'", x.Type)
+	}
+
+	return nil
+}
+
+// NewPsrCatInfo returns an instance of PsrCatInfo initialized with defaults.
+func NewPsrCatInfo() (*PsrCatInfo, error) {
+	var (
+		x  PsrCatInfo
+		xc C.libxl_psr_cat_info
+	)
+
+	C.libxl_psr_cat_info_init(&xc)
+	defer C.libxl_psr_cat_info_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+func (x *PsrCatInfo) fromC(xc *C.libxl_psr_cat_info) error {
+	x.Id = uint32(xc.id)
+	x.CosMax = uint32(xc.cos_max)
+	x.CbmLen = uint32(xc.cbm_len)
+	x.CdpEnabled = bool(xc.cdp_enabled)
+
+	return nil
+}
+
+func (x *PsrCatInfo) toC(xc *C.libxl_psr_cat_info) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_psr_cat_info_dispose(xc)
+		}
+	}()
+
+	xc.id = C.uint32_t(x.Id)
+	xc.cos_max = C.uint32_t(x.CosMax)
+	xc.cbm_len = C.uint32_t(x.CbmLen)
+	xc.cdp_enabled = C.bool(x.CdpEnabled)
+
+	return nil
+}
+
+// NewPsrHwInfo returns an instance of PsrHwInfo initialized with defaults.
+func NewPsrHwInfo(ptype PsrFeatType) (*PsrHwInfo, error) {
+	var (
+		x  PsrHwInfo
+		xc C.libxl_psr_hw_info
+	)
+
+	C.libxl_psr_hw_info_init(&xc)
+	C.libxl_psr_hw_info_init_type(&xc, C.libxl_psr_feat_type(ptype))
+	defer C.libxl_psr_hw_info_dispose(&xc)
+
+	if err := x.fromC(&xc); err != nil {
+		return nil, err
+	}
+
+	return &x, nil
+}
+
+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 PsrFeatTypeCat:
+		var typeCat PsrHwInfoTypeUnionCat
+		if err := typeCat.fromC(xc); err != nil {
+			return fmt.Errorf("converting field typeCat: %v", err)
+		}
+		x.TypeUnion = typeCat
+	case PsrFeatTypeMba:
+		var typeMba PsrHwInfoTypeUnionMba
+		if err := typeMba.fromC(xc); err != nil {
+			return fmt.Errorf("converting field typeMba: %v", err)
+		}
+		x.TypeUnion = typeMba
+	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
+}
+
+func (x *PsrHwInfo) toC(xc *C.libxl_psr_hw_info) (err error) {
+	defer func() {
+		if err != nil {
+			C.libxl_psr_hw_info_dispose(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 {
+			return 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 {
+			return 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 fmt.Errorf("invalid union key '%v'", x.Type)
+	}
+
+	return nil
+}
diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/types.gen.go
new file mode 100644
index 0000000000..df68fd0e88
--- /dev/null
+++ b/tools/golang/xenlight/types.gen.go
@@ -0,0 +1,1226 @@
+// DO NOT EDIT.
+//
+// This file is generated by:
+// gengotypes.py ../../libxl/libxl_types.idl
+//
+package xenlight
+
+type Error int
+
+const (
+	ErrorNonspecific                  Error = -1
+	ErrorVersion                      Error = -2
+	ErrorFail                         Error = -3
+	ErrorNi                           Error = -4
+	ErrorNomem                        Error = -5
+	ErrorInval                        Error = -6
+	ErrorBadfail                      Error = -7
+	ErrorGuestTimedout                Error = -8
+	ErrorTimedout                     Error = -9
+	ErrorNoparavirt                   Error = -10
+	ErrorNotReady                     Error = -11
+	ErrorOseventRegFail               Error = -12
+	ErrorBufferfull                   Error = -13
+	ErrorUnknownChild                 Error = -14
+	ErrorLockFail                     Error = -15
+	ErrorJsonConfigEmpty              Error = -16
+	ErrorDeviceExists                 Error = -17
+	ErrorCheckpointDevopsDoesNotMatch Error = -18
+	ErrorCheckpointDeviceNotSupported Error = -19
+	ErrorVnumaConfigInvalid           Error = -20
+	ErrorDomainNotfound               Error = -21
+	ErrorAborted                      Error = -22
+	ErrorNotfound                     Error = -23
+	ErrorDomainDestroyed              Error = -24
+	ErrorFeatureRemoved               Error = -25
+	ErrorProtocolErrorQmp             Error = -26
+	ErrorUnknownQmpError              Error = -27
+	ErrorQmpGenericError              Error = -28
+	ErrorQmpCommandNotFound           Error = -29
+	ErrorQmpDeviceNotActive           Error = -30
+	ErrorQmpDeviceNotFound            Error = -31
+	ErrorQemuApi                      Error = -32
+)
+
+type DomainType int
+
+const (
+	DomainTypeInvalid DomainType = -1
+	DomainTypeHvm     DomainType = 1
+	DomainTypePv      DomainType = 2
+	DomainTypePvh     DomainType = 3
+)
+
+type RdmReserveStrategy int
+
+const (
+	RdmReserveStrategyIgnore RdmReserveStrategy = 0
+	RdmReserveStrategyHost   RdmReserveStrategy = 1
+)
+
+type RdmReservePolicy int
+
+const (
+	RdmReservePolicyInvalid RdmReservePolicy = -1
+	RdmReservePolicyStrict  RdmReservePolicy = 0
+	RdmReservePolicyRelaxed RdmReservePolicy = 1
+)
+
+type ChannelConnection int
+
+const (
+	ChannelConnectionUnknown ChannelConnection = 0
+	ChannelConnectionPty     ChannelConnection = 1
+	ChannelConnectionSocket  ChannelConnection = 2
+)
+
+type DeviceModelVersion int
+
+const (
+	DeviceModelVersionUnknown            DeviceModelVersion = 0
+	DeviceModelVersionQemuXenTraditional DeviceModelVersion = 1
+	DeviceModelVersionQemuXen            DeviceModelVersion = 2
+)
+
+type ConsoleType int
+
+const (
+	ConsoleTypeUnknown ConsoleType = 0
+	ConsoleTypeSerial  ConsoleType = 1
+	ConsoleTypePv      ConsoleType = 2
+	ConsoleTypeVuart   ConsoleType = 3
+)
+
+type DiskFormat int
+
+const (
+	DiskFormatUnknown DiskFormat = 0
+	DiskFormatQcow    DiskFormat = 1
+	DiskFormatQcow2   DiskFormat = 2
+	DiskFormatVhd     DiskFormat = 3
+	DiskFormatRaw     DiskFormat = 4
+	DiskFormatEmpty   DiskFormat = 5
+	DiskFormatQed     DiskFormat = 6
+)
+
+type DiskBackend int
+
+const (
+	DiskBackendUnknown DiskBackend = 0
+	DiskBackendPhy     DiskBackend = 1
+	DiskBackendTap     DiskBackend = 2
+	DiskBackendQdisk   DiskBackend = 3
+)
+
+type NicType int
+
+const (
+	NicTypeUnknown  NicType = 0
+	NicTypeVifIoemu NicType = 1
+	NicTypeVif      NicType = 2
+)
+
+type ActionOnShutdown int
+
+const (
+	ActionOnShutdownDestroy         ActionOnShutdown = 1
+	ActionOnShutdownRestart         ActionOnShutdown = 2
+	ActionOnShutdownRestartRename   ActionOnShutdown = 3
+	ActionOnShutdownPreserve        ActionOnShutdown = 4
+	ActionOnShutdownCoredumpDestroy ActionOnShutdown = 5
+	ActionOnShutdownCoredumpRestart ActionOnShutdown = 6
+	ActionOnShutdownSoftReset       ActionOnShutdown = 7
+)
+
+type Trigger int
+
+const (
+	TriggerUnknown  Trigger = 0
+	TriggerPower    Trigger = 1
+	TriggerSleep    Trigger = 2
+	TriggerNmi      Trigger = 3
+	TriggerInit     Trigger = 4
+	TriggerReset    Trigger = 5
+	TriggerS3Resume Trigger = 6
+)
+
+type TscMode int
+
+const (
+	TscModeDefault        TscMode = 0
+	TscModeAlwaysEmulate  TscMode = 1
+	TscModeNative         TscMode = 2
+	TscModeNativeParavirt TscMode = 3
+)
+
+type GfxPassthruKind int
+
+const (
+	GfxPassthruKindDefault GfxPassthruKind = 0
+	GfxPassthruKindIgd     GfxPassthruKind = 1
+)
+
+type TimerMode int
+
+const (
+	TimerModeUnknown               TimerMode = -1
+	TimerModeDelayForMissedTicks   TimerMode = 0
+	TimerModeNoDelayForMissedTicks TimerMode = 1
+	TimerModeNoMissedTicksPending  TimerMode = 2
+	TimerModeOneMissedTickPending  TimerMode = 3
+)
+
+type BiosType int
+
+const (
+	BiosTypeUnknown BiosType = 0
+	BiosTypeRombios BiosType = 1
+	BiosTypeSeabios BiosType = 2
+	BiosTypeOvmf    BiosType = 3
+)
+
+type Scheduler int
+
+const (
+	SchedulerUnknown  Scheduler = 0
+	SchedulerSedf     Scheduler = 4
+	SchedulerCredit   Scheduler = 5
+	SchedulerCredit2  Scheduler = 6
+	SchedulerArinc653 Scheduler = 7
+	SchedulerRtds     Scheduler = 8
+	SchedulerNull     Scheduler = 9
+)
+
+type ShutdownReason int
+
+const (
+	ShutdownReasonUnknown   ShutdownReason = -1
+	ShutdownReasonPoweroff  ShutdownReason = 0
+	ShutdownReasonReboot    ShutdownReason = 1
+	ShutdownReasonSuspend   ShutdownReason = 2
+	ShutdownReasonCrash     ShutdownReason = 3
+	ShutdownReasonWatchdog  ShutdownReason = 4
+	ShutdownReasonSoftReset ShutdownReason = 5
+)
+
+type VgaInterfaceType int
+
+const (
+	VgaInterfaceTypeUnknown VgaInterfaceType = 0
+	VgaInterfaceTypeCirrus  VgaInterfaceType = 1
+	VgaInterfaceTypeStd     VgaInterfaceType = 2
+	VgaInterfaceTypeNone    VgaInterfaceType = 3
+	VgaInterfaceTypeQxl     VgaInterfaceType = 4
+)
+
+type VendorDevice int
+
+const (
+	VendorDeviceNone      VendorDevice = 0
+	VendorDeviceXenserver VendorDevice = 1
+)
+
+type ViridianEnlightenment int
+
+const (
+	ViridianEnlightenmentBase                ViridianEnlightenment = 0
+	ViridianEnlightenmentFreq                ViridianEnlightenment = 1
+	ViridianEnlightenmentTimeRefCount        ViridianEnlightenment = 2
+	ViridianEnlightenmentReferenceTsc        ViridianEnlightenment = 3
+	ViridianEnlightenmentHcallRemoteTlbFlush ViridianEnlightenment = 4
+	ViridianEnlightenmentApicAssist          ViridianEnlightenment = 5
+	ViridianEnlightenmentCrashCtl            ViridianEnlightenment = 6
+	ViridianEnlightenmentSynic               ViridianEnlightenment = 7
+	ViridianEnlightenmentStimer              ViridianEnlightenment = 8
+	ViridianEnlightenmentHcallIpi            ViridianEnlightenment = 9
+)
+
+type Hdtype int
+
+const (
+	HdtypeIde  Hdtype = 1
+	HdtypeAhci Hdtype = 2
+)
+
+type CheckpointedStream int
+
+const (
+	CheckpointedStreamNone  CheckpointedStream = 0
+	CheckpointedStreamRemus CheckpointedStream = 1
+	CheckpointedStreamColo  CheckpointedStream = 2
+)
+
+type VuartType int
+
+const (
+	VuartTypeUnknown  VuartType = 0
+	VuartTypeSbsaUart VuartType = 1
+)
+
+type VkbBackend int
+
+const (
+	VkbBackendUnknown VkbBackend = 0
+	VkbBackendQemu    VkbBackend = 1
+	VkbBackendLinux   VkbBackend = 2
+)
+
+type Passthrough int
+
+const (
+	PassthroughDefault  Passthrough = 0
+	PassthroughDisabled Passthrough = 1
+	PassthroughEnabled  Passthrough = 2
+	PassthroughSyncPt   Passthrough = 3
+	PassthroughSharePt  Passthrough = 4
+)
+
+type IoportRange struct {
+	First  uint32
+	Number uint32
+}
+
+type IomemRange struct {
+	Start  uint64
+	Number uint64
+	Gfn    uint64
+}
+
+type VgaInterfaceInfo struct {
+	Kind VgaInterfaceType
+}
+
+type VncInfo struct {
+	Enable     Defbool
+	Listen     string
+	Passwd     string
+	Display    int
+	Findunused Defbool
+}
+
+type SpiceInfo struct {
+	Enable           Defbool
+	Port             int
+	TlsPort          int
+	Host             string
+	DisableTicketing Defbool
+	Passwd           string
+	AgentMouse       Defbool
+	Vdagent          Defbool
+	ClipboardSharing Defbool
+	Usbredirection   int
+	ImageCompression string
+	StreamingVideo   string
+}
+
+type SdlInfo struct {
+	Enable     Defbool
+	Opengl     Defbool
+	Display    string
+	Xauthority string
+}
+
+type Dominfo struct {
+	Uuid             Uuid
+	Domid            Domid
+	Ssidref          uint32
+	SsidLabel        string
+	Running          bool
+	Blocked          bool
+	Paused           bool
+	Shutdown         bool
+	Dying            bool
+	NeverStop        bool
+	ShutdownReason   ShutdownReason
+	OutstandingMemkb uint64
+	CurrentMemkb     uint64
+	SharedMemkb      uint64
+	PagedMemkb       uint64
+	MaxMemkb         uint64
+	CpuTime          uint64
+	VcpuMaxId        uint32
+	VcpuOnline       uint32
+	Cpupool          uint32
+	DomainType       DomainType
+}
+
+type Cpupoolinfo struct {
+	Poolid   uint32
+	PoolName string
+	Sched    Scheduler
+	NDom     uint32
+	Cpumap   Bitmap
+}
+
+type Channelinfo struct {
+	Backend         string
+	BackendId       uint32
+	Frontend        string
+	FrontendId      uint32
+	Devid           Devid
+	State           int
+	Evtch           int
+	Rref            int
+	Connection      ChannelConnection
+	ConnectionUnion channelinfoConnectionUnion
+}
+
+type channelinfoConnectionUnion interface {
+	ischannelinfoConnectionUnion()
+}
+
+type ChannelinfoConnectionUnionPty struct {
+	Path string
+}
+
+func (x ChannelinfoConnectionUnionPty) ischannelinfoConnectionUnion() {}
+
+type Vminfo struct {
+	Uuid  Uuid
+	Domid Domid
+}
+
+type VersionInfo struct {
+	XenVersionMajor int
+	XenVersionMinor int
+	XenVersionExtra string
+	Compiler        string
+	CompileBy       string
+	CompileDomain   string
+	CompileDate     string
+	Capabilities    string
+	Changeset       string
+	VirtStart       uint64
+	Pagesize        int
+	Commandline     string
+	BuildId         string
+}
+
+type DomainCreateInfo struct {
+	Type                    DomainType
+	Hap                     Defbool
+	Oos                     Defbool
+	Ssidref                 uint32
+	SsidLabel               string
+	Name                    string
+	Domid                   Domid
+	Uuid                    Uuid
+	Xsdata                  KeyValueList
+	Platformdata            KeyValueList
+	Poolid                  uint32
+	PoolName                string
+	RunHotplugScripts       Defbool
+	DriverDomain            Defbool
+	Passthrough             Passthrough
+	XendSuspendEvtchnCompat Defbool
+}
+
+type DomainRestoreParams struct {
+	CheckpointedStream int
+	StreamVersion      uint32
+	ColoProxyScript    string
+	UserspaceColoProxy Defbool
+}
+
+type SchedParams struct {
+	Vcpuid    int
+	Weight    int
+	Cap       int
+	Period    int
+	Extratime int
+	Budget    int
+}
+
+type VcpuSchedParams struct {
+	Sched Scheduler
+	Vcpus []SchedParams
+}
+
+type DomainSchedParams struct {
+	Sched     Scheduler
+	Weight    int
+	Cap       int
+	Period    int
+	Budget    int
+	Extratime int
+	Slice     int
+	Latency   int
+}
+
+type VnodeInfo struct {
+	Memkb     uint64
+	Distances []uint32
+	Pnode     uint32
+	Vcpus     Bitmap
+}
+
+type GicVersion int
+
+const (
+	GicVersionDefault GicVersion = 0
+	GicVersionV2      GicVersion = 32
+	GicVersionV3      GicVersion = 48
+)
+
+type TeeType int
+
+const (
+	TeeTypeNone  TeeType = 0
+	TeeTypeOptee TeeType = 1
+)
+
+type RdmReserve struct {
+	Strategy RdmReserveStrategy
+	Policy   RdmReservePolicy
+}
+
+type Altp2MMode int
+
+const (
+	Altp2MModeDisabled Altp2MMode = 0
+	Altp2MModeMixed    Altp2MMode = 1
+	Altp2MModeExternal Altp2MMode = 2
+	Altp2MModeLimited  Altp2MMode = 3
+)
+
+type DomainBuildInfo struct {
+	MaxVcpus              int
+	AvailVcpus            Bitmap
+	Cpumap                Bitmap
+	Nodemap               Bitmap
+	VcpuHardAffinity      []Bitmap
+	VcpuSoftAffinity      []Bitmap
+	NumaPlacement         Defbool
+	TscMode               TscMode
+	MaxMemkb              uint64
+	TargetMemkb           uint64
+	VideoMemkb            uint64
+	ShadowMemkb           uint64
+	IommuMemkb            uint64
+	RtcTimeoffset         uint32
+	ExecSsidref           uint32
+	ExecSsidLabel         string
+	Localtime             Defbool
+	DisableMigrate        Defbool
+	Cpuid                 CpuidPolicyList
+	BlkdevStart           string
+	VnumaNodes            []VnodeInfo
+	MaxGrantFrames        uint32
+	MaxMaptrackFrames     uint32
+	DeviceModelVersion    DeviceModelVersion
+	DeviceModelStubdomain Defbool
+	DeviceModel           string
+	DeviceModelSsidref    uint32
+	DeviceModelSsidLabel  string
+	DeviceModelUser       string
+	Extra                 StringList
+	ExtraPv               StringList
+	ExtraHvm              StringList
+	SchedParams           DomainSchedParams
+	Ioports               []IoportRange
+	Irqs                  []uint32
+	Iomem                 []IomemRange
+	ClaimMode             Defbool
+	EventChannels         uint32
+	Kernel                string
+	Cmdline               string
+	Ramdisk               string
+	DeviceTree            string
+	Acpi                  Defbool
+	Bootloader            string
+	BootloaderArgs        StringList
+	TimerMode             TimerMode
+	NestedHvm             Defbool
+	Apic                  Defbool
+	DmRestrict            Defbool
+	Tee                   TeeType
+	Type                  DomainType
+	TypeUnion             domainBuildInfoTypeUnion
+	ArchArm               struct {
+		GicVersion GicVersion
+		Vuart      VuartType
+	}
+	Altp2M Altp2MMode
+}
+
+type domainBuildInfoTypeUnion interface {
+	isdomainBuildInfoTypeUnion()
+}
+
+type DomainBuildInfoTypeUnionHvm struct {
+	Firmware            string
+	Bios                BiosType
+	Pae                 Defbool
+	Apic                Defbool
+	Acpi                Defbool
+	AcpiS3              Defbool
+	AcpiS4              Defbool
+	AcpiLaptopSlate     Defbool
+	Nx                  Defbool
+	Viridian            Defbool
+	ViridianEnable      Bitmap
+	ViridianDisable     Bitmap
+	Timeoffset          string
+	Hpet                Defbool
+	VptAlign            Defbool
+	MmioHoleMemkb       uint64
+	TimerMode           TimerMode
+	NestedHvm           Defbool
+	Altp2M              Defbool
+	SystemFirmware      string
+	SmbiosFirmware      string
+	AcpiFirmware        string
+	Hdtype              Hdtype
+	Nographic           Defbool
+	Vga                 VgaInterfaceInfo
+	Vnc                 VncInfo
+	Keymap              string
+	Sdl                 SdlInfo
+	Spice               SpiceInfo
+	GfxPassthru         Defbool
+	GfxPassthruKind     GfxPassthruKind
+	Serial              string
+	Boot                string
+	Usb                 Defbool
+	Usbversion          int
+	Usbdevice           string
+	VkbDevice           Defbool
+	Soundhw             string
+	XenPlatformPci      Defbool
+	UsbdeviceList       StringList
+	VendorDevice        VendorDevice
+	MsVmGenid           MsVmGenid
+	SerialList          StringList
+	Rdm                 RdmReserve
+	RdmMemBoundaryMemkb uint64
+	McaCaps             uint64
+}
+
+func (x DomainBuildInfoTypeUnionHvm) isdomainBuildInfoTypeUnion() {}
+
+type DomainBuildInfoTypeUnionPv struct {
+	Kernel         string
+	SlackMemkb     uint64
+	Bootloader     string
+	BootloaderArgs StringList
+	Cmdline        string
+	Ramdisk        string
+	Features       string
+	E820Host       Defbool
+}
+
+func (x DomainBuildInfoTypeUnionPv) isdomainBuildInfoTypeUnion() {}
+
+type DomainBuildInfoTypeUnionPvh struct {
+	Pvshim        Defbool
+	PvshimPath    string
+	PvshimCmdline string
+	PvshimExtra   string
+}
+
+func (x DomainBuildInfoTypeUnionPvh) isdomainBuildInfoTypeUnion() {}
+
+type DeviceVfb struct {
+	BackendDomid   Domid
+	BackendDomname string
+	Devid          Devid
+	Vnc            VncInfo
+	Sdl            SdlInfo
+	Keymap         string
+}
+
+type DeviceVkb struct {
+	BackendDomid           Domid
+	BackendDomname         string
+	Devid                  Devid
+	BackendType            VkbBackend
+	UniqueId               string
+	FeatureDisableKeyboard bool
+	FeatureDisablePointer  bool
+	FeatureAbsPointer      bool
+	FeatureRawPointer      bool
+	FeatureMultiTouch      bool
+	Width                  uint32
+	Height                 uint32
+	MultiTouchWidth        uint32
+	MultiTouchHeight       uint32
+	MultiTouchNumContacts  uint32
+}
+
+type DeviceDisk struct {
+	BackendDomid      Domid
+	BackendDomname    string
+	PdevPath          string
+	Vdev              string
+	Backend           DiskBackend
+	Format            DiskFormat
+	Script            string
+	Removable         int
+	Readwrite         int
+	IsCdrom           int
+	DirectIoSafe      bool
+	DiscardEnable     Defbool
+	ColoEnable        Defbool
+	ColoRestoreEnable Defbool
+	ColoHost          string
+	ColoPort          int
+	ColoExport        string
+	ActiveDisk        string
+	HiddenDisk        string
+}
+
+type DeviceNic struct {
+	BackendDomid                   Domid
+	BackendDomname                 string
+	Devid                          Devid
+	Mtu                            int
+	Model                          string
+	Mac                            Mac
+	Ip                             string
+	Bridge                         string
+	Ifname                         string
+	Script                         string
+	Nictype                        NicType
+	RateBytesPerInterval           uint64
+	RateIntervalUsecs              uint32
+	Gatewaydev                     string
+	ColoftForwarddev               string
+	ColoSockMirrorId               string
+	ColoSockMirrorIp               string
+	ColoSockMirrorPort             string
+	ColoSockComparePriInId         string
+	ColoSockComparePriInIp         string
+	ColoSockComparePriInPort       string
+	ColoSockCompareSecInId         string
+	ColoSockCompareSecInIp         string
+	ColoSockCompareSecInPort       string
+	ColoSockCompareNotifyId        string
+	ColoSockCompareNotifyIp        string
+	ColoSockCompareNotifyPort      string
+	ColoSockRedirector0Id          string
+	ColoSockRedirector0Ip          string
+	ColoSockRedirector0Port        string
+	ColoSockRedirector1Id          string
+	ColoSockRedirector1Ip          string
+	ColoSockRedirector1Port        string
+	ColoSockRedirector2Id          string
+	ColoSockRedirector2Ip          string
+	ColoSockRedirector2Port        string
+	ColoFilterMirrorQueue          string
+	ColoFilterMirrorOutdev         string
+	ColoFilterRedirector0Queue     string
+	ColoFilterRedirector0Indev     string
+	ColoFilterRedirector0Outdev    string
+	ColoFilterRedirector1Queue     string
+	ColoFilterRedirector1Indev     string
+	ColoFilterRedirector1Outdev    string
+	ColoComparePriIn               string
+	ColoCompareSecIn               string
+	ColoCompareOut                 string
+	ColoCompareNotifyDev           string
+	ColoSockSecRedirector0Id       string
+	ColoSockSecRedirector0Ip       string
+	ColoSockSecRedirector0Port     string
+	ColoSockSecRedirector1Id       string
+	ColoSockSecRedirector1Ip       string
+	ColoSockSecRedirector1Port     string
+	ColoFilterSecRedirector0Queue  string
+	ColoFilterSecRedirector0Indev  string
+	ColoFilterSecRedirector0Outdev string
+	ColoFilterSecRedirector1Queue  string
+	ColoFilterSecRedirector1Indev  string
+	ColoFilterSecRedirector1Outdev string
+	ColoFilterSecRewriter0Queue    string
+	ColoCheckpointHost             string
+	ColoCheckpointPort             string
+}
+
+type DevicePci struct {
+	Func         byte
+	Dev          byte
+	Bus          byte
+	Domain       int
+	Vdevfn       uint32
+	VfuncMask    uint32
+	Msitranslate bool
+	PowerMgmt    bool
+	Permissive   bool
+	Seize        bool
+	RdmPolicy    RdmReservePolicy
+}
+
+type DeviceRdm struct {
+	Start  uint64
+	Size   uint64
+	Policy RdmReservePolicy
+}
+
+type UsbctrlType int
+
+const (
+	UsbctrlTypeAuto        UsbctrlType = 0
+	UsbctrlTypePv          UsbctrlType = 1
+	UsbctrlTypeDevicemodel UsbctrlType = 2
+	UsbctrlTypeQusb        UsbctrlType = 3
+)
+
+type UsbdevType int
+
+const (
+	UsbdevTypeHostdev UsbdevType = 1
+)
+
+type DeviceUsbctrl struct {
+	Type           UsbctrlType
+	Devid          Devid
+	Version        int
+	Ports          int
+	BackendDomid   Domid
+	BackendDomname string
+}
+
+type DeviceUsbdev struct {
+	Ctrl      Devid
+	Port      int
+	Type      UsbdevType
+	TypeUnion deviceUsbdevTypeUnion
+}
+
+type deviceUsbdevTypeUnion interface {
+	isdeviceUsbdevTypeUnion()
+}
+
+type DeviceUsbdevTypeUnionHostdev struct {
+	Hostbus  byte
+	Hostaddr byte
+}
+
+func (x DeviceUsbdevTypeUnionHostdev) isdeviceUsbdevTypeUnion() {}
+
+type DeviceDtdev struct {
+	Path string
+}
+
+type DeviceVtpm struct {
+	BackendDomid   Domid
+	BackendDomname string
+	Devid          Devid
+	Uuid           Uuid
+}
+
+type DeviceP9 struct {
+	BackendDomid   Domid
+	BackendDomname string
+	Tag            string
+	Path           string
+	SecurityModel  string
+	Devid          Devid
+}
+
+type DevicePvcallsif struct {
+	BackendDomid   Domid
+	BackendDomname string
+	Devid          Devid
+}
+
+type DeviceChannel struct {
+	BackendDomid    Domid
+	BackendDomname  string
+	Devid           Devid
+	Name            string
+	Connection      ChannelConnection
+	ConnectionUnion deviceChannelConnectionUnion
+}
+
+type deviceChannelConnectionUnion interface {
+	isdeviceChannelConnectionUnion()
+}
+
+type DeviceChannelConnectionUnionSocket struct {
+	Path string
+}
+
+func (x DeviceChannelConnectionUnionSocket) isdeviceChannelConnectionUnion() {}
+
+type ConnectorParam struct {
+	UniqueId string
+	Width    uint32
+	Height   uint32
+}
+
+type DeviceVdispl struct {
+	BackendDomid   Domid
+	BackendDomname string
+	Devid          Devid
+	BeAlloc        bool
+	Connectors     []ConnectorParam
+}
+
+type VsndPcmFormat int
+
+const (
+	VsndPcmFormatS8               VsndPcmFormat = 1
+	VsndPcmFormatU8               VsndPcmFormat = 2
+	VsndPcmFormatS16Le            VsndPcmFormat = 3
+	VsndPcmFormatS16Be            VsndPcmFormat = 4
+	VsndPcmFormatU16Le            VsndPcmFormat = 5
+	VsndPcmFormatU16Be            VsndPcmFormat = 6
+	VsndPcmFormatS24Le            VsndPcmFormat = 7
+	VsndPcmFormatS24Be            VsndPcmFormat = 8
+	VsndPcmFormatU24Le            VsndPcmFormat = 9
+	VsndPcmFormatU24Be            VsndPcmFormat = 10
+	VsndPcmFormatS32Le            VsndPcmFormat = 11
+	VsndPcmFormatS32Be            VsndPcmFormat = 12
+	VsndPcmFormatU32Le            VsndPcmFormat = 13
+	VsndPcmFormatU32Be            VsndPcmFormat = 14
+	VsndPcmFormatF32Le            VsndPcmFormat = 15
+	VsndPcmFormatF32Be            VsndPcmFormat = 16
+	VsndPcmFormatF64Le            VsndPcmFormat = 17
+	VsndPcmFormatF64Be            VsndPcmFormat = 18
+	VsndPcmFormatIec958SubframeLe VsndPcmFormat = 19
+	VsndPcmFormatIec958SubframeBe VsndPcmFormat = 20
+	VsndPcmFormatMuLaw            VsndPcmFormat = 21
+	VsndPcmFormatALaw             VsndPcmFormat = 22
+	VsndPcmFormatImaAdpcm         VsndPcmFormat = 23
+	VsndPcmFormatMpeg             VsndPcmFormat = 24
+	VsndPcmFormatGsm              VsndPcmFormat = 25
+)
+
+type VsndParams struct {
+	SampleRates   []uint32
+	SampleFormats []VsndPcmFormat
+	ChannelsMin   uint32
+	ChannelsMax   uint32
+	BufferSize    uint32
+}
+
+type VsndStreamType int
+
+const (
+	VsndStreamTypeP VsndStreamType = 1
+	VsndStreamTypeC VsndStreamType = 2
+)
+
+type VsndStream struct {
+	UniqueId string
+	Type     VsndStreamType
+	Params   VsndParams
+}
+
+type VsndPcm struct {
+	Name    string
+	Params  VsndParams
+	Streams []VsndStream
+}
+
+type DeviceVsnd struct {
+	BackendDomid   Domid
+	BackendDomname string
+	Devid          Devid
+	ShortName      string
+	LongName       string
+	Params         VsndParams
+	Pcms           []VsndPcm
+}
+
+type DomainConfig struct {
+	CInfo       DomainCreateInfo
+	BInfo       DomainBuildInfo
+	Disks       []DeviceDisk
+	Nics        []DeviceNic
+	Pcidevs     []DevicePci
+	Rdms        []DeviceRdm
+	Dtdevs      []DeviceDtdev
+	Vfbs        []DeviceVfb
+	Vkbs        []DeviceVkb
+	Vtpms       []DeviceVtpm
+	P9S         []DeviceP9
+	Pvcallsifs  []DevicePvcallsif
+	Vdispls     []DeviceVdispl
+	Vsnds       []DeviceVsnd
+	Channels    []DeviceChannel
+	Usbctrls    []DeviceUsbctrl
+	Usbdevs     []DeviceUsbdev
+	OnPoweroff  ActionOnShutdown
+	OnReboot    ActionOnShutdown
+	OnWatchdog  ActionOnShutdown
+	OnCrash     ActionOnShutdown
+	OnSoftReset ActionOnShutdown
+}
+
+type Diskinfo struct {
+	Backend    string
+	BackendId  uint32
+	Frontend   string
+	FrontendId uint32
+	Devid      Devid
+	State      int
+	Evtch      int
+	Rref       int
+}
+
+type Nicinfo struct {
+	Backend    string
+	BackendId  uint32
+	Frontend   string
+	FrontendId uint32
+	Devid      Devid
+	State      int
+	Evtch      int
+	RrefTx     int
+	RrefRx     int
+}
+
+type Vtpminfo struct {
+	Backend    string
+	BackendId  uint32
+	Frontend   string
+	FrontendId uint32
+	Devid      Devid
+	State      int
+	Evtch      int
+	Rref       int
+	Uuid       Uuid
+}
+
+type Usbctrlinfo struct {
+	Type       UsbctrlType
+	Devid      Devid
+	Version    int
+	Ports      int
+	Backend    string
+	BackendId  uint32
+	Frontend   string
+	FrontendId uint32
+	State      int
+	Evtch      int
+	RefUrb     int
+	RefConn    int
+}
+
+type Vcpuinfo struct {
+	Vcpuid     uint32
+	Cpu        uint32
+	Online     bool
+	Blocked    bool
+	Running    bool
+	VcpuTime   uint64
+	Cpumap     Bitmap
+	CpumapSoft Bitmap
+}
+
+type Physinfo struct {
+	ThreadsPerCore     uint32
+	CoresPerSocket     uint32
+	MaxCpuId           uint32
+	NrCpus             uint32
+	CpuKhz             uint32
+	TotalPages         uint64
+	FreePages          uint64
+	ScrubPages         uint64
+	OutstandingPages   uint64
+	SharingFreedPages  uint64
+	SharingUsedFrames  uint64
+	MaxPossibleMfn     uint64
+	NrNodes            uint32
+	HwCap              Hwcap
+	CapHvm             bool
+	CapPv              bool
+	CapHvmDirectio     bool
+	CapHap             bool
+	CapShadow          bool
+	CapIommuHapPtShare bool
+}
+
+type Connectorinfo struct {
+	UniqueId string
+	Width    uint32
+	Height   uint32
+	ReqEvtch int
+	ReqRref  int
+	EvtEvtch int
+	EvtRref  int
+}
+
+type Vdisplinfo struct {
+	Backend    string
+	BackendId  uint32
+	Frontend   string
+	FrontendId uint32
+	Devid      Devid
+	State      int
+	BeAlloc    bool
+	Connectors []Connectorinfo
+}
+
+type Streaminfo struct {
+	ReqEvtch int
+	ReqRref  int
+}
+
+type Pcminfo struct {
+	Streams []Streaminfo
+}
+
+type Vsndinfo struct {
+	Backend    string
+	BackendId  uint32
+	Frontend   string
+	FrontendId uint32
+	Devid      Devid
+	State      int
+	Pcms       []Pcminfo
+}
+
+type Vkbinfo struct {
+	Backend    string
+	BackendId  uint32
+	Frontend   string
+	FrontendId uint32
+	Devid      Devid
+	State      int
+	Evtch      int
+	Rref       int
+}
+
+type Numainfo struct {
+	Size  uint64
+	Free  uint64
+	Dists []uint32
+}
+
+type Cputopology struct {
+	Core   uint32
+	Socket uint32
+	Node   uint32
+}
+
+type Pcitopology struct {
+	Seg   uint16
+	Bus   byte
+	Devfn byte
+	Node  uint32
+}
+
+type SchedCreditParams struct {
+	TsliceMs        int
+	RatelimitUs     int
+	VcpuMigrDelayUs int
+}
+
+type SchedCredit2Params struct {
+	RatelimitUs int
+}
+
+type DomainRemusInfo struct {
+	Interval           int
+	AllowUnsafe        Defbool
+	Blackhole          Defbool
+	Compression        Defbool
+	Netbuf             Defbool
+	Netbufscript       string
+	Diskbuf            Defbool
+	Colo               Defbool
+	UserspaceColoProxy Defbool
+}
+
+type EventType int
+
+const (
+	EventTypeDomainShutdown               EventType = 1
+	EventTypeDomainDeath                  EventType = 2
+	EventTypeDiskEject                    EventType = 3
+	EventTypeOperationComplete            EventType = 4
+	EventTypeDomainCreateConsoleAvailable EventType = 5
+)
+
+type Event struct {
+	Link      EvLink
+	Domid     Domid
+	Domuuid   Uuid
+	ForUser   uint64
+	Type      EventType
+	TypeUnion eventTypeUnion
+}
+
+type eventTypeUnion interface {
+	iseventTypeUnion()
+}
+
+type EventTypeUnionDomainShutdown struct {
+	ShutdownReason byte
+}
+
+func (x EventTypeUnionDomainShutdown) iseventTypeUnion() {}
+
+type EventTypeUnionDiskEject struct {
+	Vdev string
+	Disk DeviceDisk
+}
+
+func (x EventTypeUnionDiskEject) iseventTypeUnion() {}
+
+type EventTypeUnionOperationComplete struct {
+	Rc int
+}
+
+func (x EventTypeUnionOperationComplete) iseventTypeUnion() {}
+
+type PsrCmtType int
+
+const (
+	PsrCmtTypeCacheOccupancy PsrCmtType = 1
+	PsrCmtTypeTotalMemCount  PsrCmtType = 2
+	PsrCmtTypeLocalMemCount  PsrCmtType = 3
+)
+
+type PsrCbmType int
+
+const (
+	PsrCbmTypeUnknown   PsrCbmType = 0
+	PsrCbmTypeL3Cbm     PsrCbmType = 1
+	PsrCbmTypeL3CbmCode PsrCbmType = 2
+	PsrCbmTypeL3CbmData PsrCbmType = 3
+	PsrCbmTypeL2Cbm     PsrCbmType = 4
+	PsrCbmTypeMbaThrtl  PsrCbmType = 5
+)
+
+type PsrCatInfo struct {
+	Id         uint32
+	CosMax     uint32
+	CbmLen     uint32
+	CdpEnabled bool
+}
+
+type PsrFeatType int
+
+const (
+	PsrFeatTypeCat PsrFeatType = 1
+	PsrFeatTypeMba PsrFeatType = 2
+)
+
+type PsrHwInfo struct {
+	Id        uint32
+	Type      PsrFeatType
+	TypeUnion psrHwInfoTypeUnion
+}
+
+type psrHwInfoTypeUnion interface {
+	ispsrHwInfoTypeUnion()
+}
+
+type PsrHwInfoTypeUnionCat struct {
+	CosMax     uint32
+	CbmLen     uint32
+	CdpEnabled bool
+}
+
+func (x PsrHwInfoTypeUnionCat) ispsrHwInfoTypeUnion() {}
+
+type PsrHwInfoTypeUnionMba struct {
+	CosMax   uint32
+	ThrtlMax uint32
+	Linear   bool
+}
+
+func (x PsrHwInfoTypeUnionMba) ispsrHwInfoTypeUnion() {}
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/3] golang/xenlight: init xenlight go module
  2020-05-13  0:58 [PATCH v2 0/3] initialize xenlight go module Nick Rosbrook
  2020-05-13  0:58 ` [PATCH v2 1/3] golang/xenlight: re-track generated go code Nick Rosbrook
@ 2020-05-13  0:58 ` Nick Rosbrook
  2020-05-13 10:38   ` George Dunlap
  2020-05-13  0:58 ` [PATCH v2 3/3] golang/xenlight: add necessary module/package documentation Nick Rosbrook
  2 siblings, 1 reply; 9+ messages in thread
From: Nick Rosbrook @ 2020-05-13  0:58 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, George Dunlap, Wei Liu

Initialize the xenlight Go module using the xenbits git-http URL,
xenbits.xenproject.org/git-http/xen.git/tools/golang/xenlight.

Also simplify the build Make target by using `go build` instead of `go
install`, and do not set GOPATH here because it is now unnecessary.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Changes in v2:
 - Use xenproject.org instead of xen.org in module path.
 - Undo change to XEN_GOCODE_URL; just use `go build`.
---
 tools/golang/xenlight/Makefile | 2 +-
 tools/golang/xenlight/go.mod   | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)
 create mode 100644 tools/golang/xenlight/go.mod

diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
index 753132306a..37ed1358c4 100644
--- a/tools/golang/xenlight/Makefile
+++ b/tools/golang/xenlight/Makefile
@@ -33,7 +33,7 @@ $(XEN_GOPATH)/src/$(XEN_GOCODE_URL)/xenlight/: xenlight.go types.gen.go helpers.
 # so that it can find the actual library.
 .PHONY: build
 build: package
-	CGO_CFLAGS="$(CFLAGS_libxenlight) $(CFLAGS_libxentoollog)" CGO_LDFLAGS="$(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) -L$(XEN_XENLIGHT) -L$(XEN_LIBXENTOOLLOG)" GOPATH=$(XEN_GOPATH) $(GO) install -x $(XEN_GOCODE_URL)/xenlight
+	CGO_CFLAGS="$(CFLAGS_libxenlight) $(CFLAGS_libxentoollog)" CGO_LDFLAGS="$(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) -L$(XEN_XENLIGHT) -L$(XEN_LIBXENTOOLLOG)" $(GO) build -x
 
 .PHONY: install
 install: build
diff --git a/tools/golang/xenlight/go.mod b/tools/golang/xenlight/go.mod
new file mode 100644
index 0000000000..926474d929
--- /dev/null
+++ b/tools/golang/xenlight/go.mod
@@ -0,0 +1 @@
+module xenbits.xenproject.org/git-http/xen.git/tools/golang/xenlight
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/3] golang/xenlight: add necessary module/package documentation
  2020-05-13  0:58 [PATCH v2 0/3] initialize xenlight go module Nick Rosbrook
  2020-05-13  0:58 ` [PATCH v2 1/3] golang/xenlight: re-track generated go code Nick Rosbrook
  2020-05-13  0:58 ` [PATCH v2 2/3] golang/xenlight: init xenlight go module Nick Rosbrook
@ 2020-05-13  0:58 ` Nick Rosbrook
  2020-05-13 11:29   ` George Dunlap
  2020-05-13 13:05   ` George Dunlap
  2 siblings, 2 replies; 9+ messages in thread
From: Nick Rosbrook @ 2020-05-13  0:58 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Andrew Cooper,
	Ian Jackson, George Dunlap, Nick Rosbrook, Jan Beulich

Add a README and package comment giving a brief overview of the package.
These also help pkg.go.dev generate better documentation.

Also, add a copy of the LGPL (the same license used by libxl) to
tools/golang/xenlight. This is required for the package to be shown
on pkg.go.dev and added to the default module proxy, proxy.golang.org.

Finally, add an entry for the xenlight package to SUPPORT.md.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Changes in v2:
 - Use LGPL instead of GPL for license.
 - Change some wording in README for clarity.
 - Add entry to SUPPORT.md for xenlight package.
---
 SUPPORT.md                        |   6 +
 tools/golang/xenlight/LICENSE     | 198 ++++++++++++++++++++++++++++++
 tools/golang/xenlight/README.md   |  17 +++
 tools/golang/xenlight/xenlight.go |   2 +
 4 files changed, 223 insertions(+)
 create mode 100644 tools/golang/xenlight/LICENSE
 create mode 100644 tools/golang/xenlight/README.md

diff --git a/SUPPORT.md b/SUPPORT.md
index 7270c9b021..e3a366fd56 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -147,6 +147,12 @@ Output of information in machine-parseable JSON format
 
     Status: Supported
 
+### xenlight Go package
+
+Go (golang) bindings for libxl
+
+    Status: Experimental
+
 ## Toolstack/3rd party
 
 ### libvirt driver for xl
diff --git a/tools/golang/xenlight/LICENSE b/tools/golang/xenlight/LICENSE
new file mode 100644
index 0000000000..d4d1f17688
--- /dev/null
+++ b/tools/golang/xenlight/LICENSE
@@ -0,0 +1,198 @@
+This repository is distributed under the terms of the GNU Lesser General
+Public License version 2.1 (included below).
+
+As a special exception to the GNU Lesser General Public License, you
+may link, statically or dynamically, a "work that uses the Library"
+with a publicly distributed version of the Library to produce an
+executable file containing portions of the Library, and distribute
+that executable file under terms of your choice, without any of the
+additional requirements listed in clause 6 of the GNU Lesser General
+Public License.  By "a publicly distributed version of the Library",
+we mean either the unmodified Library as distributed, or a
+modified version of the Library that is distributed under the
+conditions defined in clause 3 of the GNU Library General Public
+License.  This exception does not however invalidate any other reasons
+why the executable file might be covered by the GNU Lesser General
+Public License.
+
+------------
+
+GNU LESSER GENERAL PUBLIC LICENSE
+Version 2.1, February 1999
+
+
+Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+Preamble
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.
+
+This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.
+
+When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.
+
+To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.
+
+For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.
+
+We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.
+
+To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.
+
+Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.
+
+Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.
+
+When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.
+
+We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.
+
+For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.
+
+In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.
+
+Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.
+
+The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.
+
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".
+
+A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.
+
+The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)
+
+"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.
+
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.
+
+1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.
+
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
+
+
+a) The modified work must itself be a software library.
+b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.
+c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.
+d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.
+(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+
+3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.
+
+Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.
+
+This option is useful when you wish to copy part of the code of the Library into a program that is not a library.
+
+4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.
+
+If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.
+
+5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.
+
+However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.
+
+When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.
+
+If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)
+
+Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.
+
+6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.
+
+You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:
+
+
+a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
+b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
+c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
+d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
+e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.
+For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.
+
+It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.
+
+7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:
+
+
+a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
+b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
+8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
+
+9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.
+
+10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.
+
+11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.
+
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+
+12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+
+13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.
+
+14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+
+END OF TERMS AND CONDITIONS
+How to Apply These Terms to Your New Libraries
+If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License).
+
+To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
+
+
+one line to give the library's name and an idea of what it does.
+Copyright (C) year  name of author
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names:
+
+
+Yoyodyne, Inc., hereby disclaims all copyright interest in
+the library `Frob' (a library for tweaking knobs) written
+by James Random Hacker.
+
+signature of Ty Coon, 1 April 1990
+Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/tools/golang/xenlight/README.md b/tools/golang/xenlight/README.md
new file mode 100644
index 0000000000..046f86ab3e
--- /dev/null
+++ b/tools/golang/xenlight/README.md
@@ -0,0 +1,17 @@
+# xenlight
+
+## About
+
+The xenlight package provides Go bindings to Xen's libxl C library via cgo. The package is currently in an unstable "experimental" state. This means the package is ready for initial use and evaluation, but is not yet fully functional. Namely, only a subset of libxl's API is implemented, and breaking changes may occur in future package versions.
+
+Much of the package is generated using the libxl IDL. Changes to the generated code can be made by modifying `tools/golang/xenlight/gengotypes.py` in the xen.git tree.
+
+## Getting Started
+
+```go
+import (
+        "xenbits.xenproject.org/git-http/xen.git/tools/golang/xenlight"
+)
+```
+
+The module is not yet tagged independently of xen.git; if you don’t specify the version, you’ll get the most recent development version, which is probably not what you want.  A better option would be to specify a Xen release tag; for instance: `go get xenbits.xenproject.org/git-http/xen.git/tools/golang/xenlight@RELEASE-4.14.0`.
diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 6b4f492550..3eaa5a3d63 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -14,6 +14,8 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; If not, see <http://www.gnu.org/licenses/>.
  */
+
+// Package xenlight provides bindings to Xen's libxl C library.
 package xenlight
 
 /*
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/3] golang/xenlight: init xenlight go module
  2020-05-13  0:58 ` [PATCH v2 2/3] golang/xenlight: init xenlight go module Nick Rosbrook
@ 2020-05-13 10:38   ` George Dunlap
  0 siblings, 0 replies; 9+ messages in thread
From: George Dunlap @ 2020-05-13 10:38 UTC (permalink / raw)
  To: Nick Rosbrook; +Cc: Nick Rosbrook, xen-devel, Wei Liu, Ian Jackson



> On May 13, 2020, at 1:58 AM, Nick Rosbrook <rosbrookn@gmail.com> wrote:
> 
> Initialize the xenlight Go module using the xenbits git-http URL,
> xenbits.xenproject.org/git-http/xen.git/tools/golang/xenlight.
> 
> Also simplify the build Make target by using `go build` instead of `go
> install`, and do not set GOPATH here because it is now unnecessary.

Glad you caught the GOPATH thing. :-)

> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>

Revewied-by: George Dunlap <george.dunlap@citrix.com>



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/3] golang/xenlight: add necessary module/package documentation
  2020-05-13  0:58 ` [PATCH v2 3/3] golang/xenlight: add necessary module/package documentation Nick Rosbrook
@ 2020-05-13 11:29   ` George Dunlap
  2020-05-13 13:03     ` Nick Rosbrook
  2020-05-13 13:05   ` George Dunlap
  1 sibling, 1 reply; 9+ messages in thread
From: George Dunlap @ 2020-05-13 11:29 UTC (permalink / raw)
  To: Nick Rosbrook
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Andrew Cooper,
	Nick Rosbrook, Jan Beulich, Ian Jackson, xen-devel



> On May 13, 2020, at 1:58 AM, Nick Rosbrook <rosbrookn@gmail.com> wrote:
> 
> Add a README and package comment giving a brief overview of the package.
> These also help pkg.go.dev generate better documentation.

One thing I forgot to mention about the README is the long lines — do you mind if I wrap those before checking it in?

> Also, add a copy of the LGPL (the same license used by libxl) to
> tools/golang/xenlight. This is required for the package to be shown
> on pkg.go.dev and added to the default module proxy, proxy.golang.org.
> 
> Finally, add an entry for the xenlight package to SUPPORT.md.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>

Reviewed-by: George Dunlap <george.dunlap@citrix.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/3] golang/xenlight: add necessary module/package documentation
  2020-05-13 11:29   ` George Dunlap
@ 2020-05-13 13:03     ` Nick Rosbrook
  0 siblings, 0 replies; 9+ messages in thread
From: Nick Rosbrook @ 2020-05-13 13:03 UTC (permalink / raw)
  To: George Dunlap
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Andrew Cooper,
	Nick Rosbrook, Jan Beulich, Ian Jackson, xen-devel

> One thing I forgot to mention about the README is the long lines — do you mind if I wrap those before checking it in?

I don't mind at all.

> > Also, add a copy of the LGPL (the same license used by libxl) to
> > tools/golang/xenlight. This is required for the package to be shown
> > on pkg.go.dev and added to the default module proxy, proxy.golang.org.
> >
> > Finally, add an entry for the xenlight package to SUPPORT.md.
> >
> > Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
>
> Reviewed-by: George Dunlap <george.dunlap@citrix.com>

Thanks!

-NR


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/3] golang/xenlight: add necessary module/package documentation
  2020-05-13  0:58 ` [PATCH v2 3/3] golang/xenlight: add necessary module/package documentation Nick Rosbrook
  2020-05-13 11:29   ` George Dunlap
@ 2020-05-13 13:05   ` George Dunlap
  2020-05-13 13:25     ` Nick Rosbrook
  1 sibling, 1 reply; 9+ messages in thread
From: George Dunlap @ 2020-05-13 13:05 UTC (permalink / raw)
  To: Nick Rosbrook
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Andrew Cooper,
	Nick Rosbrook, Jan Beulich, Ian Jackson, xen-devel


> On May 13, 2020, at 1:58 AM, Nick Rosbrook <rosbrookn@gmail.com> wrote:
> 
> Add a README and package comment giving a brief overview of the package.
> These also help pkg.go.dev generate better documentation.
> 
> Also, add a copy of the LGPL (the same license used by libxl) to
> tools/golang/xenlight. This is required for the package to be shown
> on pkg.go.dev and added to the default module proxy, proxy.golang.org.

OK, so didn’t notice this at first.  It looks like you read the comments at the top of libxl.c, noticed the comment about “...the special exception on linking described in file LICENSE”, looked around for such a file, and found it in tools/ocaml, and copied that one?

I had a chat with Ian Jackson on IRC (copied below for the record), and think that comment is simply in error.  We agreed that we should just copy https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt into the directory verbatim.

 -George

12:49:40           gwd | Hmm... libxl is supposedly under the LGPL, but I can't   
                       | seem to find a copy of it in our source tree             
12:50:01           gwd | Oh, there's one in tools/libxc                           
12:54:44           gwd | Diziet: The comment at the top of libxl.c refers to      
                       | "...the special exception on linking described in file   
                       | LICENSE."  But there's no such file in tools/libxl       
12:55:22           gwd | The most plausible candidate for what it's talking about 
                       | is tools/ocaml/LICENSE                                   
12:59:43        Diziet | Weird                                                    
13:00:16        Diziet | That text is present in                                  
                       | c5c301ac774d8cb36ccbc775bb7f1d7005d78a71 "libxenlight:   
                       | initial libxenlight implementation under tools/libxl"    
13:00:39        Diziet | There is no file LICENSE other than                      
                       | xen/tools/figlet/LICENSE                                 
13:00:57        Diziet | Which is a copy of the Artistic License and not          
                       | relevant.                                                
13:01:18        Diziet | However,                                                 
13:01:43        Diziet | | Licensing Exceptions (the relaxed BSD-style license)   
13:01:47        Diziet | ^ in the top-level COPYING                               
13:02:30        Diziet | I don't think this is an "exception on linking" and it   
                       | doesn't state that it applies to libxl.                  
13:03:29        Diziet | The phrase "exception on linking" appears only in libxl  
                       | in thta commit                                           
13:04:05        Diziet | https://github.com/xapi-project/xen-api/blob/master/ocam 
                       | l/idl/datamodel.ml                                       
13:04:31        Diziet | https://github.com/xapi-project/xen-api/blob/master/LICE 
                       | NSE                                                      
13:04:40        Diziet | I think that is probably what was intended to be         
                       | referred to.                                             
13:05:24        Diziet | And indeed that text appears in tools/ocaml              
13:06:59        Diziet | This is an additional permission (borrowing GPLv3        
                       | terminology) which a downstream can drop.                
13:07:39        Diziet | Furthermore I don't think anyone's S-o-b for a libxl     
                       | commit can be taken to have meant to include that        
                       | exception.  So I conclude that no exception in fact      
                       | applies and the text referring to it should be deleted.  
13:07:53        Diziet | gwd: ^                                                   
13:13:29           --> | zhengc (~zhengc@180.110.50.11) has joined #xendevel     
13:17:55           <-- | zhengc (~zhengc@180.110.50.11) has quit (Ping timeout:   
                       | 258 seconds)                                             
13:28:11           gwd | Diziet: OK -- this came up actually in the context of    
                       | "[PATCH v2 3/3] golang/xenlight: add necessary           
                       | module/package documentation"                            
13:28:48           gwd | golang has this automatic package proxy / cataloging     
                       | system                                                   
13:29:24           gwd | To have it work the way he wants it, the golang/xenlight 
                       | directory needs something that their system can          
                       | recognize as a suitable license                          
13:30:20           gwd | v1 had the GPL, which was just wrong; it looks like he's 
                       | then followed the same path I did, looking at libxl.c,   
                       | trying to find this "exception" thing, and copying the   
                       | file f/ tools/ocaml                                      
13:30:58           gwd | I guess I should tell him to just copy                   
                       | https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt   
13:31:37        Diziet | y


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/3] golang/xenlight: add necessary module/package documentation
  2020-05-13 13:05   ` George Dunlap
@ 2020-05-13 13:25     ` Nick Rosbrook
  0 siblings, 0 replies; 9+ messages in thread
From: Nick Rosbrook @ 2020-05-13 13:25 UTC (permalink / raw)
  To: George Dunlap
  Cc: Stefano Stabellini, Julien Grall, Wei Liu, Andrew Cooper,
	Nick Rosbrook, Jan Beulich, Ian Jackson, xen-devel

> OK, so didn’t notice this at first.  It looks like you read the comments at the top of libxl.c, noticed the comment about “...the special exception on linking described in file LICENSE”, looked around for such a file, and found it in tools/ocaml, and copied that one?
>
> I had a chat with Ian Jackson on IRC (copied below for the record), and think that comment is simply in error.  We agreed that we should just copy https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt into the directory verbatim.

Yeah that's what I did. I'll send a corrected patch shortly.

Thanks,
-NR


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-05-13 13:26 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-13  0:58 [PATCH v2 0/3] initialize xenlight go module Nick Rosbrook
2020-05-13  0:58 ` [PATCH v2 1/3] golang/xenlight: re-track generated go code Nick Rosbrook
2020-05-13  0:58 ` [PATCH v2 2/3] golang/xenlight: init xenlight go module Nick Rosbrook
2020-05-13 10:38   ` George Dunlap
2020-05-13  0:58 ` [PATCH v2 3/3] golang/xenlight: add necessary module/package documentation Nick Rosbrook
2020-05-13 11:29   ` George Dunlap
2020-05-13 13:03     ` Nick Rosbrook
2020-05-13 13:05   ` George Dunlap
2020-05-13 13:25     ` Nick Rosbrook

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.