All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL
@ 2019-10-07 15:12 Nick Rosbrook
  2019-10-07 15:12 ` [Xen-devel] [PATCH 01/24] golang/xenlight: fix calls to libxl_domain_unpause/pause Nick Rosbrook
                   ` (23 more replies)
  0 siblings, 24 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

After Xen summit, we started the discussion in this[1] RFC thread
to figure out how to generate Go bindings for libxl. This series
implements that Go code generation using the existing IDL, and updates
the existing hand-written code in xenlight.go to use the generated
code.

The goal of this series is to provide a good foundation for continued
development of the Go package.

These patches can also be found on my GitHub branch[2].

[1] https://lists.xenproject.org/archives/html/xen-devel/2019-07/msg02259.html
[2] https://github.com/enr0n/xen/tree/golang-patches-v1

Nick Rosbrook (24):
  golang/xenlight: fix calls to libxl_domain_unpause/pause
  golang/xenlight: generate enum types from IDL
  golang/xenlight: define Defbool builtin type
  golang/xenlight: define Devid type as int
  golang/xenlight: define KeyValueList builtin type
  golang/xenlight: re-name Bitmap marshaling functions
  golang/xenlight: define StringList builtin type
  golang/xenlight: define Mac builtin type
  golang/xenlight: define MsVmGenid builtin type
  golang/xenlight: define EvLink builtin as empty struct
  golang/xenlight: define CpuidPolicyList builtin type
  golang/xenlight: re-factor Uuid type implementation
  golang/xenlight: re-factor Hwcap type implementation
  golang/xenlight: generate structs from the IDL
  golang/xenlight: remove no-longer used type MemKB
  golang/xenlight: begin C to Go type marshaling
  golang/xenlight: implement keyed union C to Go marshaling
  golang/xenlight: implement array C to Go marshaling
  golang/xenlight: begin Go to C type marshaling
  golang/xenlight: implement keyed union Go to C marshaling
  golang/xenlight: implement array Go to C marshaling
  golang/xenlight: revise use of Context type
  golang/xenlight: add error return type to Context.Cpupoolinfo
  golang/xenlight: add make target for generated files

 tools/golang/xenlight/Makefile            |   22 +-
 tools/golang/xenlight/gengotypes.py       |  698 +++++
 tools/golang/xenlight/xenlight.go         |  928 +++---
 tools/golang/xenlight/xenlight_helpers.go | 3404 +++++++++++++++++++++
 tools/golang/xenlight/xenlight_types.go   | 1212 ++++++++
 5 files changed, 5727 insertions(+), 537 deletions(-)
 create mode 100644 tools/golang/xenlight/gengotypes.py
 create mode 100644 tools/golang/xenlight/xenlight_helpers.go
 create mode 100644 tools/golang/xenlight/xenlight_types.go

Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 01/24] golang/xenlight: fix calls to libxl_domain_unpause/pause
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-10-07 16:39   ` George Dunlap
  2019-10-07 15:12 ` [Xen-devel] [PATCH 02/24] golang/xenlight: generate enum types from IDL Nick Rosbrook
                   ` (22 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

These functions require a third argument of type const *libxl_asyncop_how.

Pass nil to fix compilation errors. This will have the effect of
performing these operations synchronously.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index f5d171c2d5..59b8186a64 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -1011,7 +1011,7 @@ func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
 		return
 	}
 
-	ret := C.libxl_domain_unpause(Ctx.ctx, C.uint32_t(Id))
+	ret := C.libxl_domain_unpause(Ctx.ctx, C.uint32_t(Id), nil)
 
 	if ret != 0 {
 		err = Error(-ret)
@@ -1026,7 +1026,7 @@ func (Ctx *Context) DomainPause(id Domid) (err error) {
 		return
 	}
 
-	ret := C.libxl_domain_pause(Ctx.ctx, C.uint32_t(id))
+	ret := C.libxl_domain_pause(Ctx.ctx, C.uint32_t(id), nil)
 
 	if ret != 0 {
 		err = Error(-ret)
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 02/24] golang/xenlight: generate enum types from IDL
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
  2019-10-07 15:12 ` [Xen-devel] [PATCH 01/24] golang/xenlight: fix calls to libxl_domain_unpause/pause Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-10-24 14:35   ` George Dunlap
  2019-10-07 15:12 ` [Xen-devel] [PATCH 03/24] golang/xenlight: define Defbool builtin type Nick Rosbrook
                   ` (21 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Introduce gengotypes.py to generate Go code the from IDL. As a first step,
implement 'enum' type generation.

As a result of the newly-generated code, remove the existing, and now
conflicting definitions in xenlight.go. In the case of the Error type,
rename the slice 'errors' to 'libxlErrors' so that it does not conflict
with the standard library package 'errors.' And, negate the values used
in 'libxlErrors' since the generated error values are negative.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/gengotypes.py     | 109 +++++++
 tools/golang/xenlight/xenlight.go       | 140 ++-------
 tools/golang/xenlight/xenlight_types.go | 378 ++++++++++++++++++++++++
 3 files changed, 515 insertions(+), 112 deletions(-)
 create mode 100644 tools/golang/xenlight/gengotypes.py
 create mode 100644 tools/golang/xenlight/xenlight_types.go

diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
new file mode 100644
index 0000000000..59307492cb
--- /dev/null
+++ b/tools/golang/xenlight/gengotypes.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+
+import os
+import sys
+
+sys.path.append('{}/tools/libxl'.format(os.environ['XEN_ROOT']))
+import idl
+
+# Go versions of some builtin types.
+# Append the libxl-defined builtins after IDL parsing.
+builtin_type_names = {
+    idl.bool.typename: 'bool',
+    idl.string.typename: 'string',
+    idl.integer.typename: 'int',
+    idl.uint8.typename: 'byte',
+    idl.uint16.typename: 'uint16',
+    idl.uint32.typename: 'uint32',
+    idl.uint64.typename: 'uint64',
+}
+
+def xenlight_golang_generate_types(path = None, types = None, comment = None):
+    """
+    Generate a .go file (xenlight_types.go by default)
+    that contains a Go type for each type in types.
+    """
+    if path is None:
+        path = 'xenlight_types.go'
+
+    with open(path, 'w') as f:
+        if comment is not None:
+            f.write(comment)
+        f.write('package xenlight\n')
+
+        for ty in types:
+            f.write(xenlight_golang_type_define(ty))
+            f.write('\n')
+
+    go_fmt(path)
+
+def xenlight_golang_type_define(ty = None):
+    s = ''
+
+    if isinstance(ty, idl.Enumeration):
+        s += xenlight_golang_define_enum(ty)
+
+    return s
+
+def xenlight_golang_define_enum(ty = None):
+    s = ''
+    typename = ''
+
+    if ty.typename is not None:
+        typename = xenlight_golang_fmt_name(ty.typename)
+        s += 'type {} int\n'.format(typename)
+
+    # Start const block
+    s += 'const(\n'
+
+    for v in ty.values:
+        name = xenlight_golang_fmt_name(v.name)
+        s += '{} {} = {}\n'.format(name, typename, v.value)
+
+    # End const block
+    s += ')\n'
+
+    return s
+
+def xenlight_golang_fmt_name(name, exported = True):
+    """
+    Take a given type name and return an
+    appropriate Go type name.
+    """
+    if name in builtin_type_names.keys():
+        return builtin_type_names[name]
+
+    # Name is not a builtin, format it for Go.
+    words = name.split('_')
+
+    # Remove 'libxl' prefix
+    if words[0].lower() == 'libxl':
+        words.remove(words[0])
+
+    if exported:
+        return ''.join(x.title() for x in words)
+
+    return words[0] + ''.join(x.title() for x in words[1:])
+
+def go_fmt(path):
+    """ Call go fmt on the given path. """
+    os.system('go fmt {}'.format(path))
+
+if __name__ == '__main__':
+    idlname = sys.argv[1]
+
+    (builtins, types) = idl.parse(idlname)
+
+    for b in builtins:
+        name = b.typename
+        builtin_type_names[name] = xenlight_golang_fmt_name(name)
+
+    header_comment="""// DO NOT EDIT.
+    //
+    // This file is generated by:
+    // {}
+    //
+    """.format(' '.join(sys.argv))
+
+    xenlight_golang_generate_types(types=types,
+                                   comment=header_comment)
diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 59b8186a64..e617f22fcf 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -37,77 +37,42 @@ import (
 	"unsafe"
 )
 
-/*
- * Errors
- */
-
-type Error int
-
-const (
-	ErrorNonspecific                  = Error(-C.ERROR_NONSPECIFIC)
-	ErrorVersion                      = Error(-C.ERROR_VERSION)
-	ErrorFail                         = Error(-C.ERROR_FAIL)
-	ErrorNi                           = Error(-C.ERROR_NI)
-	ErrorNomem                        = Error(-C.ERROR_NOMEM)
-	ErrorInval                        = Error(-C.ERROR_INVAL)
-	ErrorBadfail                      = Error(-C.ERROR_BADFAIL)
-	ErrorGuestTimedout                = Error(-C.ERROR_GUEST_TIMEDOUT)
-	ErrorTimedout                     = Error(-C.ERROR_TIMEDOUT)
-	ErrorNoparavirt                   = Error(-C.ERROR_NOPARAVIRT)
-	ErrorNotReady                     = Error(-C.ERROR_NOT_READY)
-	ErrorOseventRegFail               = Error(-C.ERROR_OSEVENT_REG_FAIL)
-	ErrorBufferfull                   = Error(-C.ERROR_BUFFERFULL)
-	ErrorUnknownChild                 = Error(-C.ERROR_UNKNOWN_CHILD)
-	ErrorLockFail                     = Error(-C.ERROR_LOCK_FAIL)
-	ErrorJsonConfigEmpty              = Error(-C.ERROR_JSON_CONFIG_EMPTY)
-	ErrorDeviceExists                 = Error(-C.ERROR_DEVICE_EXISTS)
-	ErrorCheckpointDevopsDoesNotMatch = Error(-C.ERROR_CHECKPOINT_DEVOPS_DOES_NOT_MATCH)
-	ErrorCheckpointDeviceNotSupported = Error(-C.ERROR_CHECKPOINT_DEVICE_NOT_SUPPORTED)
-	ErrorVnumaConfigInvalid           = Error(-C.ERROR_VNUMA_CONFIG_INVALID)
-	ErrorDomainNotfound               = Error(-C.ERROR_DOMAIN_NOTFOUND)
-	ErrorAborted                      = Error(-C.ERROR_ABORTED)
-	ErrorNotfound                     = Error(-C.ERROR_NOTFOUND)
-	ErrorDomainDestroyed              = Error(-C.ERROR_DOMAIN_DESTROYED)
-	ErrorFeatureRemoved               = Error(-C.ERROR_FEATURE_REMOVED)
-)
-
-var errors = [...]string{
-	ErrorNonspecific:                  "Non-specific error",
-	ErrorVersion:                      "Wrong version",
-	ErrorFail:                         "Failed",
-	ErrorNi:                           "Not Implemented",
-	ErrorNomem:                        "No memory",
-	ErrorInval:                        "Invalid argument",
-	ErrorBadfail:                      "Bad Fail",
-	ErrorGuestTimedout:                "Guest timed out",
-	ErrorTimedout:                     "Timed out",
-	ErrorNoparavirt:                   "No Paravirtualization",
-	ErrorNotReady:                     "Not ready",
-	ErrorOseventRegFail:               "OS event registration failed",
-	ErrorBufferfull:                   "Buffer full",
-	ErrorUnknownChild:                 "Unknown child",
-	ErrorLockFail:                     "Lock failed",
-	ErrorJsonConfigEmpty:              "JSON config empty",
-	ErrorDeviceExists:                 "Device exists",
-	ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does not match",
-	ErrorCheckpointDeviceNotSupported: "Checkpoint device not supported",
-	ErrorVnumaConfigInvalid:           "VNUMA config invalid",
-	ErrorDomainNotfound:               "Domain not found",
-	ErrorAborted:                      "Aborted",
-	ErrorNotfound:                     "Not found",
-	ErrorDomainDestroyed:              "Domain destroyed",
-	ErrorFeatureRemoved:               "Feature removed",
+var libxlErrors = [...]string{
+	-ErrorNonspecific:                  "Non-specific error",
+	-ErrorVersion:                      "Wrong version",
+	-ErrorFail:                         "Failed",
+	-ErrorNi:                           "Not Implemented",
+	-ErrorNomem:                        "No memory",
+	-ErrorInval:                        "Invalid argument",
+	-ErrorBadfail:                      "Bad Fail",
+	-ErrorGuestTimedout:                "Guest timed out",
+	-ErrorTimedout:                     "Timed out",
+	-ErrorNoparavirt:                   "No Paravirtualization",
+	-ErrorNotReady:                     "Not ready",
+	-ErrorOseventRegFail:               "OS event registration failed",
+	-ErrorBufferfull:                   "Buffer full",
+	-ErrorUnknownChild:                 "Unknown child",
+	-ErrorLockFail:                     "Lock failed",
+	-ErrorJsonConfigEmpty:              "JSON config empty",
+	-ErrorDeviceExists:                 "Device exists",
+	-ErrorCheckpointDevopsDoesNotMatch: "Checkpoint devops does not match",
+	-ErrorCheckpointDeviceNotSupported: "Checkpoint device not supported",
+	-ErrorVnumaConfigInvalid:           "VNUMA config invalid",
+	-ErrorDomainNotfound:               "Domain not found",
+	-ErrorAborted:                      "Aborted",
+	-ErrorNotfound:                     "Not found",
+	-ErrorDomainDestroyed:              "Domain destroyed",
+	-ErrorFeatureRemoved:               "Feature removed",
 }
 
 func (e Error) Error() string {
-	if 0 < int(e) && int(e) < len(errors) {
-		s := errors[e]
+	if 0 < int(e) && int(e) < len(libxlErrors) {
+		s := libxlErrors[e]
 		if s != "" {
 			return s
 		}
 	}
 	return fmt.Sprintf("libxl error: %d", -e)
-
 }
 
 /*
@@ -236,18 +201,6 @@ func (cinfo *C.libxl_version_info) toGo() (info *VersionInfo) {
 	return
 }
 
-type ShutdownReason int32
-
-const (
-	ShutdownReasonUnknown   = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_UNKNOWN)
-	ShutdownReasonPoweroff  = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_POWEROFF)
-	ShutdownReasonReboot    = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_REBOOT)
-	ShutdownReasonSuspend   = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SUSPEND)
-	ShutdownReasonCrash     = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_CRASH)
-	ShutdownReasonWatchdog  = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_WATCHDOG)
-	ShutdownReasonSoftReset = ShutdownReason(C.LIBXL_SHUTDOWN_REASON_SOFT_RESET)
-)
-
 func (sr ShutdownReason) String() (str string) {
 	cstr := C.libxl_shutdown_reason_to_string(C.libxl_shutdown_reason(sr))
 	str = C.GoString(cstr)
@@ -255,14 +208,6 @@ func (sr ShutdownReason) String() (str string) {
 	return
 }
 
-type DomainType int32
-
-const (
-	DomainTypeInvalid = DomainType(C.LIBXL_DOMAIN_TYPE_INVALID)
-	DomainTypeHvm     = DomainType(C.LIBXL_DOMAIN_TYPE_HVM)
-	DomainTypePv      = DomainType(C.LIBXL_DOMAIN_TYPE_PV)
-)
-
 func (dt DomainType) String() (str string) {
 	cstr := C.libxl_domain_type_to_string(C.libxl_domain_type(dt))
 	str = C.GoString(cstr)
@@ -323,27 +268,6 @@ func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
 	return
 }
 
-// # Consistent with values defined in domctl.h
-// # Except unknown which we have made up
-// libxl_scheduler = Enumeration("scheduler", [
-//     (0, "unknown"),
-//     (4, "sedf"),
-//     (5, "credit"),
-//     (6, "credit2"),
-//     (7, "arinc653"),
-//     (8, "rtds"),
-//     ])
-type Scheduler int
-
-var (
-	SchedulerUnknown  Scheduler = C.LIBXL_SCHEDULER_UNKNOWN
-	SchedulerSedf     Scheduler = C.LIBXL_SCHEDULER_SEDF
-	SchedulerCredit   Scheduler = C.LIBXL_SCHEDULER_CREDIT
-	SchedulerCredit2  Scheduler = C.LIBXL_SCHEDULER_CREDIT2
-	SchedulerArinc653 Scheduler = C.LIBXL_SCHEDULER_ARINC653
-	SchedulerRTDS     Scheduler = C.LIBXL_SCHEDULER_RTDS
-)
-
 // const char *libxl_scheduler_to_string(libxl_scheduler p);
 func (s Scheduler) String() string {
 	cs := C.libxl_scheduler_to_string(C.libxl_scheduler(s))
@@ -1141,14 +1065,6 @@ func (Ctx *Context) ListVcpu(id Domid) (glist []Vcpuinfo) {
 	return
 }
 
-type ConsoleType int
-
-const (
-	ConsoleTypeUnknown = ConsoleType(C.LIBXL_CONSOLE_TYPE_UNKNOWN)
-	ConsoleTypeSerial  = ConsoleType(C.LIBXL_CONSOLE_TYPE_SERIAL)
-	ConsoleTypePV      = ConsoleType(C.LIBXL_CONSOLE_TYPE_PV)
-)
-
 func (ct ConsoleType) String() (str string) {
 	cstr := C.libxl_console_type_to_string(C.libxl_console_type(ct))
 	str = C.GoString(cstr)
diff --git a/tools/golang/xenlight/xenlight_types.go b/tools/golang/xenlight/xenlight_types.go
new file mode 100644
index 0000000000..05f62182b7
--- /dev/null
+++ b/tools/golang/xenlight/xenlight_types.go
@@ -0,0 +1,378 @@
+// 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 GicVersion int
+
+const (
+	GicVersionDefault GicVersion = 0
+	GicVersionV2      GicVersion = 32
+	GicVersionV3      GicVersion = 48
+)
+
+type TeeType int
+
+const (
+	TeeTypeNone  TeeType = 0
+	TeeTypeOptee TeeType = 1
+)
+
+type Altp2MMode int
+
+const (
+	Altp2MModeDisabled Altp2MMode = 0
+	Altp2MModeMixed    Altp2MMode = 1
+	Altp2MModeExternal Altp2MMode = 2
+	Altp2MModeLimited  Altp2MMode = 3
+)
+
+type UsbctrlType int
+
+const (
+	UsbctrlTypeAuto        UsbctrlType = 0
+	UsbctrlTypePv          UsbctrlType = 1
+	UsbctrlTypeDevicemodel UsbctrlType = 2
+	UsbctrlTypeQusb        UsbctrlType = 3
+)
+
+type UsbdevType int
+
+const (
+	UsbdevTypeHostdev UsbdevType = 1
+)
+
+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 VsndStreamType int
+
+const (
+	VsndStreamTypeP VsndStreamType = 1
+	VsndStreamTypeC VsndStreamType = 2
+)
+
+type EventType int
+
+const (
+	EventTypeDomainShutdown               EventType = 1
+	EventTypeDomainDeath                  EventType = 2
+	EventTypeDiskEject                    EventType = 3
+	EventTypeOperationComplete            EventType = 4
+	EventTypeDomainCreateConsoleAvailable EventType = 5
+)
+
+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 PsrFeatType int
+
+const (
+	PsrFeatTypeCat PsrFeatType = 1
+	PsrFeatTypeMba PsrFeatType = 2
+)
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 03/24] golang/xenlight: define Defbool builtin type
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
  2019-10-07 15:12 ` [Xen-devel] [PATCH 01/24] golang/xenlight: fix calls to libxl_domain_unpause/pause Nick Rosbrook
  2019-10-07 15:12 ` [Xen-devel] [PATCH 02/24] golang/xenlight: generate enum types from IDL Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-10-24 15:17   ` George Dunlap
  2019-10-07 15:12 ` [Xen-devel] [PATCH 04/24] golang/xenlight: define Devid type as int Nick Rosbrook
                   ` (20 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Define Defbool as struct analagous to the C type, and define the type
'defboolVal' that represent true, false, and default defbool values.

Implement Set, Unset, SetIfDefault, IsDefault, Val, and String functions
on Defbool so that the type can be used in Go analagously to how its
used in C.

Finally, implement fromC and toC functions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 93 +++++++++++++++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index e617f22fcf..7bf16dc03b 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -85,6 +85,99 @@ type MemKB uint64
 
 type Uuid C.libxl_uuid
 
+// defboolVal represents a defbool value.
+type defboolVal int
+
+const (
+	defboolDefault defboolVal = 0
+	defboolFalse   defboolVal = -1
+	defboolTrue    defboolVal = 1
+)
+
+// Defbool represents a libxl_defbool.
+type Defbool struct {
+	val defboolVal
+}
+
+func (d Defbool) String() string {
+	switch d.val {
+	case defboolDefault:
+		return "<default>"
+	case defboolFalse:
+		return "False"
+	case defboolTrue:
+		return "True"
+	}
+
+	return ""
+}
+
+// Set sets the value of the Defbool.
+func (d *Defbool) Set(b bool) {
+	if b {
+		d.val = defboolTrue
+		return
+	}
+	d.val = defboolFalse
+}
+
+// Unset resets the Defbool to default value.
+func (d *Defbool) Unset() {
+	d.val = defboolDefault
+}
+
+// SetIfDefault sets the value of Defbool only if
+// its current value is default.
+func (d *Defbool) SetIfDefault(b bool) {
+	if d.IsDefault() {
+		d.Set(b)
+	}
+}
+
+// IsDefault returns true if the value of Defbool
+// is default, returns false otherwise.
+func (d *Defbool) IsDefault() bool {
+	return d.val == defboolDefault
+}
+
+// Val returns the boolean value associated with the
+// Defbool value. An error is returned if the value
+// is default.
+func (d *Defbool) Val() (bool, error) {
+	if d.IsDefault() {
+		return false, fmt.Errorf("%v: cannot take value of default defbool", ErrorInval)
+	}
+
+	return (d.val > 0), nil
+}
+
+func (d *Defbool) fromC(c *C.libxl_defbool) error {
+	if C.libxl_defbool_is_default(*c) {
+		d.val = defboolDefault
+		return nil
+	}
+
+	if C.libxl_defbool_val(*c) {
+		d.val = defboolTrue
+		return nil
+	}
+
+	d.val = defboolFalse
+
+	return nil
+}
+
+func (d *Defbool) toC() (C.libxl_defbool, error) {
+	var c C.libxl_defbool
+
+	if !d.IsDefault() {
+		val, _ := d.Val()
+		C.libxl_defbool_set(&c, C.bool(val))
+	}
+
+	return c, nil
+}
+
 type Context struct {
 	ctx    *C.libxl_ctx
 	logger *C.xentoollog_logger_stdiostream
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 04/24] golang/xenlight: define Devid type as int
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (2 preceding siblings ...)
  2019-10-07 15:12 ` [Xen-devel] [PATCH 03/24] golang/xenlight: define Defbool builtin type Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-10-24 15:20   ` George Dunlap
  2019-10-07 15:12 ` [Xen-devel] [PATCH 05/24] golang/xenlight: define KeyValueList builtin type Nick Rosbrook
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 7bf16dc03b..4d4fad2a9d 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -81,6 +81,9 @@ func (e Error) Error() string {
 
 type Domid uint32
 
+// Devid is a device ID.
+type Devid int
+
 type MemKB uint64
 
 type Uuid C.libxl_uuid
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 05/24] golang/xenlight: define KeyValueList builtin type
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (3 preceding siblings ...)
  2019-10-07 15:12 ` [Xen-devel] [PATCH 04/24] golang/xenlight: define Devid type as int Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-10-24 16:34   ` George Dunlap
  2019-10-07 15:12 ` [Xen-devel] [PATCH 06/24] golang/xenlight: re-name Bitmap marshaling functions Nick Rosbrook
                   ` (18 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Define KeyValueList builtin type, analagous to libxl_key_value_list as
map[string]string, and implement its fromC and toC functions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 33 ++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 4d4fad2a9d..8196a42855 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -202,11 +202,42 @@ func (chwcap C.libxl_hwcap) toGo() (ghwcap Hwcap) {
 	return
 }
 
+// KeyValueList represents a libxl_key_value_list.
+type KeyValueList map[string]string
+
+func (kvl KeyValueList) fromC(ckvl *C.libxl_key_value_list) error {
+	size := int(C.libxl_key_value_list_length(ckvl))
+	list := (*[1 << 30]*C.char)(unsafe.Pointer(ckvl))[:size:size]
+
+	for i := 0; i < size*2; i += 2 {
+		kvl[C.GoString(list[i])] = C.GoString(list[i+1])
+	}
+
+	return nil
+}
+
+func (kvl KeyValueList) toC() (C.libxl_key_value_list, error) {
+	// Add extra slot for sentinel
+	var char *C.char
+	csize := 2*len(kvl) + 1
+	ckvl := (C.libxl_key_value_list)(C.malloc(C.ulong(csize) * C.ulong(unsafe.Sizeof(char))))
+	clist := (*[1 << 31]*C.char)(unsafe.Pointer(ckvl))[:csize:csize]
+
+	i := 0
+	for k, v := range kvl {
+		clist[i] = C.CString(k)
+		clist[i+1] = C.CString(v)
+		i += 2
+	}
+	clist[len(clist)-1] = nil
+
+	return ckvl, nil
+}
+
 // typedef struct {
 //     uint32_t size;          /* number of bytes in map */
 //     uint8_t *map;
 // } libxl_bitmap;
-
 // Implement the Go bitmap type such that the underlying data can
 // easily be copied in and out.  NB that we still have to do copies
 // both directions, because cgo runtime restrictions forbid passing to
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 06/24] golang/xenlight: re-name Bitmap marshaling functions
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (4 preceding siblings ...)
  2019-10-07 15:12 ` [Xen-devel] [PATCH 05/24] golang/xenlight: define KeyValueList builtin type Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-11-13 15:21   ` George Dunlap
  2019-10-07 15:12 ` [Xen-devel] [PATCH 07/24] golang/xenlight: define StringList builtin type Nick Rosbrook
                   ` (17 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Re-name and modify signature of toGo function to fromC. The reason for
using 'fromC' rather than 'toGo' is that it is not a good idea to define
methods on the C types. Also, add error return type to Bitmap's toC function.

Finally, as code-cleanup, re-organize the Bitmap type's comments as per
Go conventions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 93 ++++++++++++++++---------------
 1 file changed, 48 insertions(+), 45 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 8196a42855..09fcdca5d1 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -234,19 +234,48 @@ func (kvl KeyValueList) toC() (C.libxl_key_value_list, error) {
 	return ckvl, nil
 }
 
-// typedef struct {
-//     uint32_t size;          /* number of bytes in map */
-//     uint8_t *map;
-// } libxl_bitmap;
+// Bitmap represents a libxl_bitmap.
+//
 // Implement the Go bitmap type such that the underlying data can
 // easily be copied in and out.  NB that we still have to do copies
 // both directions, because cgo runtime restrictions forbid passing to
 // a C function a pointer to a Go-allocated structure which contains a
 // pointer.
 type Bitmap struct {
+	// typedef struct {
+	//     uint32_t size;          /* number of bytes in map */
+	//     uint8_t *map;
+	// } libxl_bitmap;
 	bitmap []C.uint8_t
 }
 
+func (bm *Bitmap) fromC(cbm *C.libxl_bitmap) error {
+	// Alloc a Go slice for the bytes
+	size := int(cbm.size)
+	bm.bitmap = make([]C.uint8_t, size)
+
+	// Make a slice pointing to the C array
+	mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
+
+	// And copy the C array into the Go array
+	copy(bm.bitmap, mapslice)
+
+	return nil
+}
+
+func (bm *Bitmap) toC() (C.libxl_bitmap, error) {
+	var cbm C.libxl_bitmap
+
+	size := len(bm.bitmap)
+	cbm.size = C.uint32_t(size)
+	cbm._map = (*C.uint8_t)(C.malloc(C.ulong(cbm.size) * C.sizeof_uint8_t))
+	cslice := (*[1 << 31]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
+
+	copy(cslice, bm.bitmap)
+
+	return cbm, nil
+}
+
 /*
  * Types: IDL
  *
@@ -447,7 +476,7 @@ func (cci C.libxl_cpupoolinfo) toGo() (gci CpupoolInfo) {
 	gci.PoolName = C.GoString(cci.pool_name)
 	gci.Scheduler = Scheduler(cci.sched)
 	gci.DomainCount = int(cci.n_dom)
-	gci.Cpumap = cci.cpumap.toGo()
+	gci.Cpumap.fromC(&cci.cpumap)
 
 	return
 }
@@ -521,7 +550,10 @@ func (Ctx *Context) CpupoolCreate(Name string, Scheduler Scheduler, Cpumap Bitma
 	var uuid C.libxl_uuid
 	C.libxl_uuid_generate(&uuid)
 
-	cbm := Cpumap.toC()
+	cbm, err := Cpumap.toC()
+	if err != nil {
+		return
+	}
 	defer C.libxl_bitmap_dispose(&cbm)
 
 	ret := C.libxl_cpupool_create(Ctx.ctx, name, C.libxl_scheduler(Scheduler),
@@ -576,7 +608,10 @@ func (Ctx *Context) CpupoolCpuaddCpumap(Poolid uint32, Cpumap Bitmap) (err error
 		return
 	}
 
-	cbm := Cpumap.toC()
+	cbm, err := Cpumap.toC()
+	if err != nil {
+		return
+	}
 	defer C.libxl_bitmap_dispose(&cbm)
 
 	ret := C.libxl_cpupool_cpuadd_cpumap(Ctx.ctx, C.uint32_t(Poolid), &cbm)
@@ -612,7 +647,10 @@ func (Ctx *Context) CpupoolCpuremoveCpumap(Poolid uint32, Cpumap Bitmap) (err er
 		return
 	}
 
-	cbm := Cpumap.toC()
+	cbm, err := Cpumap.toC()
+	if err != nil {
+		return
+	}
 	defer C.libxl_bitmap_dispose(&cbm)
 
 	ret := C.libxl_cpupool_cpuremove_cpumap(Ctx.ctx, C.uint32_t(Poolid), &cbm)
@@ -735,41 +773,6 @@ func (Ctx *Context) CpupoolMakeFree(Cpumap Bitmap) (err error) {
  * Bitmap operations
  */
 
-// Return a Go bitmap which is a copy of the referred C bitmap.
-func (cbm C.libxl_bitmap) toGo() (gbm Bitmap) {
-	// Alloc a Go slice for the bytes
-	size := int(cbm.size)
-	gbm.bitmap = make([]C.uint8_t, size)
-
-	// Make a slice pointing to the C array
-	mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
-
-	// And copy the C array into the Go array
-	copy(gbm.bitmap, mapslice)
-
-	return
-}
-
-// Must be C.libxl_bitmap_dispose'd of afterwards
-func (gbm Bitmap) toC() (cbm C.libxl_bitmap) {
-	C.libxl_bitmap_init(&cbm)
-
-	size := len(gbm.bitmap)
-	cbm._map = (*C.uint8_t)(C.malloc(C.size_t(size)))
-	cbm.size = C.uint32_t(size)
-	if cbm._map == nil {
-		panic("C.calloc failed!")
-	}
-
-	// Make a slice pointing to the C array
-	mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
-
-	// And copy the Go array into the C array
-	copy(mapslice, gbm.bitmap)
-
-	return
-}
-
 func (bm *Bitmap) Test(bit int) bool {
 	ubit := uint(bit)
 	if bit > bm.Max() || bm.bitmap == nil {
@@ -1158,8 +1161,8 @@ func (cvci C.libxl_vcpuinfo) toGo() (gvci Vcpuinfo) {
 	gvci.Blocked = bool(cvci.blocked)
 	gvci.Running = bool(cvci.running)
 	gvci.VCpuTime = time.Duration(cvci.vcpu_time)
-	gvci.Cpumap = cvci.cpumap.toGo()
-	gvci.CpumapSoft = cvci.cpumap_soft.toGo()
+	gvci.Cpumap.fromC(&cvci.cpumap)
+	gvci.CpumapSoft.fromC(&cvci.cpumap_soft)
 
 	return
 }
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 07/24] golang/xenlight: define StringList builtin type
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (5 preceding siblings ...)
  2019-10-07 15:12 ` [Xen-devel] [PATCH 06/24] golang/xenlight: re-name Bitmap marshaling functions Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-11-13 15:37   ` George Dunlap
  2019-10-07 15:12 ` [Xen-devel] [PATCH 08/24] golang/xenlight: define Mac " Nick Rosbrook
                   ` (16 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Define StringList as []string an implement fromC and toC functions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 09fcdca5d1..a3a1836d31 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -234,6 +234,35 @@ func (kvl KeyValueList) toC() (C.libxl_key_value_list, error) {
 	return ckvl, nil
 }
 
+// StringList represents a libxl_string_list.
+type StringList []string
+
+func (sl StringList) fromC(csl *C.libxl_string_list) error {
+	size := int(C.libxl_string_list_length(csl))
+	list := (*[1 << 30]*C.char)(unsafe.Pointer(csl))[:size:size]
+
+	sl = make([]string, size)
+
+	for i, v := range list {
+		sl[i] = C.GoString(v)
+	}
+
+	return nil
+}
+
+func (sl StringList) toC() (C.libxl_string_list, error) {
+	var char *C.char
+	size := len(sl)
+	csl := (C.libxl_string_list)(C.malloc(C.ulong(size) * C.ulong(unsafe.Sizeof(char))))
+	clist := (*[1 << 30]*C.char)(unsafe.Pointer(csl))[:size:size]
+
+	for i, v := range sl {
+		clist[i] = C.CString(v)
+	}
+
+	return csl, nil
+}
+
 // Bitmap represents a libxl_bitmap.
 //
 // Implement the Go bitmap type such that the underlying data can
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 08/24] golang/xenlight: define Mac builtin type
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (6 preceding siblings ...)
  2019-10-07 15:12 ` [Xen-devel] [PATCH 07/24] golang/xenlight: define StringList builtin type Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-11-13 15:51   ` George Dunlap
  2019-10-07 15:12 ` [Xen-devel] [PATCH 09/24] golang/xenlight: define MsVmGenid " Nick Rosbrook
                   ` (15 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Define Mac as [6]byte and implement fromC, toC, and String functions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 35 +++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index a3a1836d31..3b7824b284 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -181,6 +181,41 @@ func (d *Defbool) toC() (C.libxl_defbool, error) {
 	return c, nil
 }
 
+// Mac represents a libxl_mac, or simply a MAC address.
+type Mac [6]byte
+
+// String formats a Mac address to string representation.
+func (mac Mac) String() string {
+	s := "%x:%x:%x:%x:%x:%x"
+	opts := make([]interface{}, 6)
+
+	for i, v := range mac {
+		opts[i] = v
+	}
+
+	return fmt.Sprintf(s, opts...)
+}
+
+func (mac *Mac) fromC(cmac *C.libxl_mac) error {
+	b := (*[6]C.uint8_t)(unsafe.Pointer(cmac))
+
+	for i, v := range b {
+		mac[i] = byte(v)
+	}
+
+	return nil
+}
+
+func (mac *Mac) toC() (C.libxl_mac, error) {
+	var cmac C.libxl_mac
+
+	for i, v := range mac {
+		cmac[i] = C.uint8_t(v)
+	}
+
+	return cmac, nil
+}
+
 type Context struct {
 	ctx    *C.libxl_ctx
 	logger *C.xentoollog_logger_stdiostream
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 09/24] golang/xenlight: define MsVmGenid builtin type
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (7 preceding siblings ...)
  2019-10-07 15:12 ` [Xen-devel] [PATCH 08/24] golang/xenlight: define Mac " Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-11-13 16:20   ` George Dunlap
  2019-10-07 15:12 ` [Xen-devel] [PATCH 10/24] golang/xenlight: define EvLink builtin as empty struct Nick Rosbrook
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Define MsVmGenid as [int(C.LIBXL_MS_VM_GENID_LEN)]byte and implement fromC and toC functions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 3b7824b284..6aca5b89c0 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -216,6 +216,29 @@ func (mac *Mac) toC() (C.libxl_mac, error) {
 	return cmac, nil
 }
 
+// MsVmGenid represents a libxl_ms_vm_genid.
+type MsVmGenid [int(C.LIBXL_MS_VM_GENID_LEN)]byte
+
+func (mvg *MsVmGenid) fromC(cmvg *C.libxl_ms_vm_genid) error {
+	b := (*[int(C.LIBXL_MS_VM_GENID_LEN)]C.uint8_t)(unsafe.Pointer(&cmvg.bytes[0]))
+
+	for i, v := range b {
+		mvg[i] = byte(v)
+	}
+
+	return nil
+}
+
+func (mvg *MsVmGenid) toC() (C.libxl_ms_vm_genid, error) {
+	var cmvg C.libxl_ms_vm_genid
+
+	for i, v := range mvg {
+		cmvg.bytes[i] = C.uint8_t(v)
+	}
+
+	return cmvg, nil
+}
+
 type Context struct {
 	ctx    *C.libxl_ctx
 	logger *C.xentoollog_logger_stdiostream
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 10/24] golang/xenlight: define EvLink builtin as empty struct
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (8 preceding siblings ...)
  2019-10-07 15:12 ` [Xen-devel] [PATCH 09/24] golang/xenlight: define MsVmGenid " Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-11-13 16:23   ` George Dunlap
  2019-10-07 15:12 ` [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type Nick Rosbrook
                   ` (13 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Define EvLink as empty struct as there is currently no reason the internal of
this type should be used in Go.

Implement fromC and toC functions as no-ops.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 6aca5b89c0..d41de253f3 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -239,6 +239,16 @@ func (mvg *MsVmGenid) toC() (C.libxl_ms_vm_genid, error) {
 	return cmvg, nil
 }
 
+// EvLink represents a libxl_ev_link.
+//
+// Represented as an empty struct for now, as there is no
+// apparent need for the internals of this type to be exposed
+// through the Go package.
+type EvLink struct{}
+
+func (el *EvLink) fromC(cel *C.libxl_ev_link) error      { return nil }
+func (el *EvLink) toC() (cel C.libxl_ev_link, err error) { return }
+
 type Context struct {
 	ctx    *C.libxl_ctx
 	logger *C.xentoollog_logger_stdiostream
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (9 preceding siblings ...)
  2019-10-07 15:12 ` [Xen-devel] [PATCH 10/24] golang/xenlight: define EvLink builtin as empty struct Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-11-13 17:34   ` George Dunlap
  2019-10-07 15:12 ` [Xen-devel] [PATCH 12/24] golang/xenlight: re-factor Uuid type implementation Nick Rosbrook
                   ` (12 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Define CpuidPolicyList as a wrapper struct with field val of type
*C.libxl_cpuid_policy_list and implement fromC and toC functions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index d41de253f3..9c384485e1 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -249,6 +249,26 @@ type EvLink struct{}
 func (el *EvLink) fromC(cel *C.libxl_ev_link) error      { return nil }
 func (el *EvLink) toC() (cel C.libxl_ev_link, err error) { return }
 
+// CpuidPolicyList represents a libxl_cpuid_policy_list.
+type CpuidPolicyList struct {
+	val *C.libxl_cpuid_policy_list
+}
+
+func (cpl *CpuidPolicyList) fromC(ccpl *C.libxl_cpuid_policy_list) error {
+	cpl.val = ccpl
+	return nil
+}
+
+func (cpl *CpuidPolicyList) toC() (C.libxl_cpuid_policy_list, error) {
+	if cpl.val == nil {
+		var c C.libxl_cpuid_policy_list
+		return c, nil
+	}
+	ccpl := (*C.libxl_cpuid_policy_list)(unsafe.Pointer(cpl.val))
+
+	return *ccpl, nil
+}
+
 type Context struct {
 	ctx    *C.libxl_ctx
 	logger *C.xentoollog_logger_stdiostream
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 12/24] golang/xenlight: re-factor Uuid type implementation
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (10 preceding siblings ...)
  2019-10-07 15:12 ` [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type Nick Rosbrook
@ 2019-10-07 15:12 ` Nick Rosbrook
  2019-11-13 17:47   ` George Dunlap
  2019-10-07 15:13 ` [Xen-devel] [PATCH 13/24] golang/xenlight: re-factor Hwcap " Nick Rosbrook
                   ` (11 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:12 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Re-define Uuid as [16]byte and implement fromC, toC, and String functions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 37 +++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 9c384485e1..3e3753f92e 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -86,7 +86,40 @@ type Devid int
 
 type MemKB uint64
 
-type Uuid C.libxl_uuid
+// Uuid is a domain UUID.
+type Uuid [16]byte
+
+// String formats a Uuid in the form "xxxx-xx-xx-xx-xxxxxx".
+func (u Uuid) String() string {
+	s := "%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x"
+	opts := make([]interface{}, 16)
+
+	for i, v := range u {
+		opts[i] = v
+	}
+
+	return fmt.Sprintf(s, opts...)
+}
+
+func (u *Uuid) fromC(c *C.libxl_uuid) error {
+	b := (*[16]C.uint8_t)(unsafe.Pointer(&c.uuid[0]))
+
+	for i, v := range b {
+		u[i] = byte(v)
+	}
+
+	return nil
+}
+
+func (u *Uuid) toC() (C.libxl_uuid, error) {
+	var c C.libxl_uuid
+
+	for i, v := range u {
+		c.uuid[i] = C.uint8_t(v)
+	}
+
+	return c, nil
+}
 
 // defboolVal represents a defbool value.
 type defboolVal int
@@ -516,7 +549,7 @@ type Dominfo struct {
 func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
 
 	di = &Dominfo{}
-	di.Uuid = Uuid(cdi.uuid)
+	di.Uuid.fromC(&cdi.uuid)
 	di.Domid = Domid(cdi.domid)
 	di.Ssidref = uint32(cdi.ssidref)
 	di.SsidLabel = C.GoString(cdi.ssid_label)
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 13/24] golang/xenlight: re-factor Hwcap type implementation
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (11 preceding siblings ...)
  2019-10-07 15:12 ` [Xen-devel] [PATCH 12/24] golang/xenlight: re-factor Uuid type implementation Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-11-13 17:58   ` George Dunlap
  2019-10-07 15:13 ` [Xen-devel] [PATCH 14/24] golang/xenlight: generate structs from the IDL Nick Rosbrook
                   ` (10 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Re-define Hwcap as [8]uint32, and implement toC function. Also, re-name and
modify signature of toGo function to fromC.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 3e3753f92e..8d520bbd98 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -307,20 +307,29 @@ type Context struct {
 	logger *C.xentoollog_logger_stdiostream
 }
 
-type Hwcap []C.uint32_t
-
-func (chwcap C.libxl_hwcap) toGo() (ghwcap Hwcap) {
-	// Alloc a Go slice for the bytes
-	size := 8
-	ghwcap = make([]C.uint32_t, size)
+// Hwcap represents a libxl_hwcap.
+type Hwcap [8]uint32
 
+func (hwcap *Hwcap) fromC(chwcap *C.libxl_hwcap) error {
 	// Make a slice pointing to the C array
-	mapslice := (*[1 << 30]C.uint32_t)(unsafe.Pointer(&chwcap[0]))[:size:size]
+	mapslice := (*[8]C.uint32_t)(unsafe.Pointer(chwcap))
 
 	// And copy the C array into the Go array
-	copy(ghwcap, mapslice)
+	for i, v := range mapslice {
+		hwcap[i] = uint32(v)
+	}
 
-	return
+	return nil
+}
+
+func (hwcap *Hwcap) toC() (C.libxl_hwcap, error) {
+	var chwcap C.libxl_hwcap
+
+	for i, v := range hwcap {
+		chwcap[i] = C.uint32_t(v)
+	}
+
+	return chwcap, nil
 }
 
 // KeyValueList represents a libxl_key_value_list.
@@ -465,7 +474,7 @@ func (cphys *C.libxl_physinfo) toGo() (physinfo *Physinfo) {
 	physinfo.SharingFreedPages = uint64(cphys.sharing_freed_pages)
 	physinfo.SharingUsedFrames = uint64(cphys.sharing_used_frames)
 	physinfo.NrNodes = uint32(cphys.nr_nodes)
-	physinfo.HwCap = cphys.hw_cap.toGo()
+	physinfo.HwCap.fromC(&cphys.hw_cap)
 	physinfo.CapHvm = bool(cphys.cap_hvm)
 	physinfo.CapHvmDirectio = bool(cphys.cap_hvm_directio)
 
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 14/24] golang/xenlight: generate structs from the IDL
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (12 preceding siblings ...)
  2019-10-07 15:13 ` [Xen-devel] [PATCH 13/24] golang/xenlight: re-factor Hwcap " Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-11-14 14:18   ` George Dunlap
  2019-10-07 15:13 ` [Xen-devel] [PATCH 15/24] golang/xenlight: remove no-longer used type MemKB Nick Rosbrook
                   ` (9 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Add struct and keyed union generation to gengotypes.py. For keyed unions,
use a method similar to gRPC's oneof to interpret C unions as Go types.
Meaning, for a given struct with a union field, generate a struct for
each sub-struct defined in the union. Then, define an interface of one
method which is implemented by each of the defined sub-structs. For
example:

  type domainBuildInfoTypeUnion interface {
          isdomainBuildInfoTypeUnion()
  }

  type DomainBuildInfoTypeUnionHvm struct {
      // HVM-specific fields...
  }

  func (x DomainBuildInfoTypeUnionHvm) isdomainBuildInfoTypeUnion() {}

  type DomainBuildInfoTypeUnionPv struct {
      // PV-specific fields...
  }

  func (x DomainBuildInfoTypeUnionPv) isdomainBuildInfoTypeUnion() {}

  type DomainBuildInfoTypeUnionPvh struct {
      // PVH-specific fields...
  }

  func (x DomainBuildInfoTypeUnionPvh) isdomainBuildInfoTypeUnion() {}

Then, remove existing struct definitions in xenlight.go that conflict
with the generated types, and modify existing marshaling functions to
align with the new type definitions. Notably, drop "time" package since
fields of type time.Duration are now of type uint64.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/gengotypes.py     | 103 +++
 tools/golang/xenlight/xenlight.go       | 123 +---
 tools/golang/xenlight/xenlight_types.go | 834 ++++++++++++++++++++++++
 3 files changed, 952 insertions(+), 108 deletions(-)

diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
index 59307492cb..c8513b79e0 100644
--- a/tools/golang/xenlight/gengotypes.py
+++ b/tools/golang/xenlight/gengotypes.py
@@ -18,6 +18,10 @@ builtin_type_names = {
     idl.uint64.typename: 'uint64',
 }
 
+# List of strings that need to be written to a file
+# after a struct definition.
+type_extras = []
+
 def xenlight_golang_generate_types(path = None, types = None, comment = None):
     """
     Generate a .go file (xenlight_types.go by default)
@@ -35,6 +39,13 @@ def xenlight_golang_generate_types(path = None, types = None, comment = None):
             f.write(xenlight_golang_type_define(ty))
             f.write('\n')
 
+            # Append extra types
+            for extra in type_extras:
+                f.write(extra)
+                f.write('\n')
+
+            del type_extras[:]
+
     go_fmt(path)
 
 def xenlight_golang_type_define(ty = None):
@@ -43,6 +54,9 @@ def xenlight_golang_type_define(ty = None):
     if isinstance(ty, idl.Enumeration):
         s += xenlight_golang_define_enum(ty)
 
+    elif isinstance(ty, idl.Aggregate):
+        s += xenlight_golang_define_struct(ty)
+
     return s
 
 def xenlight_golang_define_enum(ty = None):
@@ -65,6 +79,95 @@ def xenlight_golang_define_enum(ty = None):
 
     return s
 
+def xenlight_golang_define_struct(ty = None, typename = None, nested = False):
+    s = ''
+    name = ''
+
+    if typename is not None:
+        name = xenlight_golang_fmt_name(typename)
+    else:
+        name = xenlight_golang_fmt_name(ty.typename)
+
+    # Begin struct definition
+    if nested:
+        s += '{} struct {{\n'.format(name)
+    else:
+        s += 'type {} struct {{\n'.format(name)
+
+    # Write struct fields
+    for f in ty.fields:
+        if f.type.typename is not None:
+            if isinstance(f.type, idl.Array):
+                typename = f.type.elem_type.typename
+                typename = xenlight_golang_fmt_name(typename)
+                name     = xenlight_golang_fmt_name(f.name)
+
+                s += '{} []{}\n'.format(name, typename)
+            else:
+                typename = f.type.typename
+                typename = xenlight_golang_fmt_name(typename)
+                name     = xenlight_golang_fmt_name(f.name)
+
+                s += '{} {}\n'.format(name, typename)
+
+        elif isinstance(f.type, idl.Struct):
+            s += xenlight_golang_define_struct(f.type, typename=f.name, nested=True)
+
+        elif isinstance(f.type, idl.KeyedUnion):
+            s += xenlight_golang_define_union(f.type, ty.typename)
+
+        else:
+            raise Exception('type {} not supported'.format(f.type))
+
+    # End struct definition
+    s += '}\n'
+
+    return s
+
+def xenlight_golang_define_union(ty = None, structname = ''):
+    """
+    Generate the Go translation of a KeyedUnion.
+
+    Define an unexported interface to be used as
+    the type of the union. Then, define a struct
+    for each field of the union which implements
+    that interface.
+    """
+    s = ''
+
+    interface_name = '{}_{}_union'.format(structname, ty.keyvar.name)
+    interface_name = xenlight_golang_fmt_name(interface_name, exported=False)
+
+    s += 'type {} interface {{\n'.format(interface_name)
+    s += 'is{}()\n'.format(interface_name)
+    s += '}\n'
+
+    type_extras.append(s)
+
+    for f in ty.fields:
+        if f.type is None:
+            continue
+
+        # Define struct
+        name = '{}_{}_union_{}'.format(structname, ty.keyvar.name, f.name)
+        s = xenlight_golang_define_struct(f.type, typename=name)
+        type_extras.append(s)
+
+        # Define function to implement 'union' interface
+        name = xenlight_golang_fmt_name(name)
+        s = 'func (x {}) is{}(){{}}\n'.format(name, interface_name)
+        type_extras.append(s)
+
+    # Return the field entries, but the associated types are generated later.
+    fname = xenlight_golang_fmt_name(ty.keyvar.name)
+    ftype = xenlight_golang_fmt_name(ty.keyvar.type.typename)
+    s = '{} {}\n'.format(fname, ftype)
+
+    fname = xenlight_golang_fmt_name('{}_union'.format(ty.keyvar.name))
+    s += '{} {}\n'.format(fname, interface_name)
+
+    return s
+
 def xenlight_golang_fmt_name(name, exported = True):
     """
     Take a given type name and return an
diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 8d520bbd98..0adb12d1bf 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -33,7 +33,6 @@ import "C"
 
 import (
 	"fmt"
-	"time"
 	"unsafe"
 )
 
@@ -435,30 +434,6 @@ func (bm *Bitmap) toC() (C.libxl_bitmap, error) {
 	return cbm, nil
 }
 
-/*
- * Types: IDL
- *
- * FIXME: Generate these automatically from the IDL
- */
-
-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
-	NrNodes           uint32
-	HwCap             Hwcap
-	CapHvm            bool
-	CapHvmDirectio    bool
-}
-
 func (cphys *C.libxl_physinfo) toGo() (physinfo *Physinfo) {
 
 	physinfo = &Physinfo{}
@@ -481,22 +456,6 @@ func (cphys *C.libxl_physinfo) toGo() (physinfo *Physinfo) {
 	return
 }
 
-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
-}
-
 func (cinfo *C.libxl_version_info) toGo() (info *VersionInfo) {
 	info = &VersionInfo{}
 	info.XenVersionMajor = int(cinfo.xen_version_major)
@@ -530,31 +489,6 @@ func (dt DomainType) String() (str string) {
 	return
 }
 
-type Dominfo struct {
-	Uuid      Uuid
-	Domid     Domid
-	Ssidref   uint32
-	SsidLabel string
-	Running   bool
-	Blocked   bool
-	Paused    bool
-	Shutdown  bool
-	Dying     bool
-	NeverStop bool
-
-	ShutdownReason   int32
-	OutstandingMemkb MemKB
-	CurrentMemkb     MemKB
-	SharedMemkb      MemKB
-	PagedMemkb       MemKB
-	MaxMemkb         MemKB
-	CpuTime          time.Duration
-	VcpuMaxId        uint32
-	VcpuOnline       uint32
-	Cpupool          uint32
-	DomainType       int32
-}
-
 func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
 
 	di = &Dominfo{}
@@ -568,17 +502,17 @@ func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
 	di.Shutdown = bool(cdi.shutdown)
 	di.Dying = bool(cdi.dying)
 	di.NeverStop = bool(cdi.never_stop)
-	di.ShutdownReason = int32(cdi.shutdown_reason)
-	di.OutstandingMemkb = MemKB(cdi.outstanding_memkb)
-	di.CurrentMemkb = MemKB(cdi.current_memkb)
-	di.SharedMemkb = MemKB(cdi.shared_memkb)
-	di.PagedMemkb = MemKB(cdi.paged_memkb)
-	di.MaxMemkb = MemKB(cdi.max_memkb)
-	di.CpuTime = time.Duration(cdi.cpu_time)
+	di.ShutdownReason = ShutdownReason(cdi.shutdown_reason)
+	di.OutstandingMemkb = uint64(cdi.outstanding_memkb)
+	di.CurrentMemkb = uint64(cdi.current_memkb)
+	di.SharedMemkb = uint64(cdi.shared_memkb)
+	di.PagedMemkb = uint64(cdi.paged_memkb)
+	di.MaxMemkb = uint64(cdi.max_memkb)
+	di.CpuTime = uint64(cdi.cpu_time)
 	di.VcpuMaxId = uint32(cdi.vcpu_max_id)
 	di.VcpuOnline = uint32(cdi.vcpu_online)
 	di.Cpupool = uint32(cdi.cpupool)
-	di.DomainType = int32(cdi.domain_type)
+	di.DomainType = DomainType(cdi.domain_type)
 
 	return
 }
@@ -614,27 +548,11 @@ func SchedulerFromString(name string) (s Scheduler, err error) {
 	return
 }
 
-// libxl_cpupoolinfo = Struct("cpupoolinfo", [
-//     ("poolid",      uint32),
-//     ("pool_name",   string),
-//     ("sched",       libxl_scheduler),
-//     ("n_dom",       uint32),
-//     ("cpumap",      libxl_bitmap)
-//     ], dir=DIR_OUT)
-
-type CpupoolInfo struct {
-	Poolid      uint32
-	PoolName    string
-	Scheduler   Scheduler
-	DomainCount int
-	Cpumap      Bitmap
-}
-
-func (cci C.libxl_cpupoolinfo) toGo() (gci CpupoolInfo) {
+func (cci C.libxl_cpupoolinfo) toGo() (gci Cpupoolinfo) {
 	gci.Poolid = uint32(cci.poolid)
 	gci.PoolName = C.GoString(cci.pool_name)
-	gci.Scheduler = Scheduler(cci.sched)
-	gci.DomainCount = int(cci.n_dom)
+	gci.Sched = Scheduler(cci.sched)
+	gci.NDom = uint32(cci.n_dom)
 	gci.Cpumap.fromC(&cci.cpumap)
 
 	return
@@ -642,7 +560,7 @@ func (cci C.libxl_cpupoolinfo) toGo() (gci CpupoolInfo) {
 
 // libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
 // void libxl_cpupoolinfo_list_free(libxl_cpupoolinfo *list, int nb_pool);
-func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
+func (Ctx *Context) ListCpupool() (list []Cpupoolinfo) {
 	err := Ctx.CheckOpen()
 	if err != nil {
 		return
@@ -669,7 +587,7 @@ func (Ctx *Context) ListCpupool() (list []CpupoolInfo) {
 }
 
 // int libxl_cpupool_info(libxl_ctx *ctx, libxl_cpupoolinfo *info, uint32_t poolid);
-func (Ctx *Context) CpupoolInfo(Poolid uint32) (pool CpupoolInfo) {
+func (Ctx *Context) CpupoolInfo(Poolid uint32) (pool Cpupoolinfo) {
 	err := Ctx.CheckOpen()
 	if err != nil {
 		return
@@ -899,7 +817,7 @@ func (Ctx *Context) CpupoolMovedomain(Poolid uint32, Id Domid) (err error) {
 //
 // Utility functions
 //
-func (Ctx *Context) CpupoolFindByName(name string) (info CpupoolInfo, found bool) {
+func (Ctx *Context) CpupoolFindByName(name string) (info Cpupoolinfo, found bool) {
 	plist := Ctx.ListCpupool()
 
 	for i := range plist {
@@ -1302,24 +1220,13 @@ func (Ctx *Context) ListDomain() (glist []Dominfo) {
 	return
 }
 
-type Vcpuinfo struct {
-	Vcpuid     uint32
-	Cpu        uint32
-	Online     bool
-	Blocked    bool
-	Running    bool
-	VCpuTime   time.Duration
-	Cpumap     Bitmap
-	CpumapSoft Bitmap
-}
-
 func (cvci C.libxl_vcpuinfo) toGo() (gvci Vcpuinfo) {
 	gvci.Vcpuid = uint32(cvci.vcpuid)
 	gvci.Cpu = uint32(cvci.cpu)
 	gvci.Online = bool(cvci.online)
 	gvci.Blocked = bool(cvci.blocked)
 	gvci.Running = bool(cvci.running)
-	gvci.VCpuTime = time.Duration(cvci.vcpu_time)
+	gvci.VcpuTime = uint64(cvci.vcpu_time)
 	gvci.Cpumap.fromC(&cvci.cpumap)
 	gvci.CpumapSoft.fromC(&cvci.cpumap_soft)
 
diff --git a/tools/golang/xenlight/xenlight_types.go b/tools/golang/xenlight/xenlight_types.go
index 05f62182b7..8dd435c0dd 100644
--- a/tools/golang/xenlight/xenlight_types.go
+++ b/tools/golang/xenlight/xenlight_types.go
@@ -265,6 +265,182 @@ const (
 	VkbBackendLinux   VkbBackend = 2
 )
 
+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
+	Uuid              Uuid
+	Xsdata            KeyValueList
+	Platformdata      KeyValueList
+	Poolid            uint32
+	PoolName          string
+	RunHotplugScripts Defbool
+	DriverDomain      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 (
@@ -280,6 +456,11 @@ const (
 	TeeTypeOptee TeeType = 1
 )
 
+type RdmReserve struct {
+	Strategy RdmReserveStrategy
+	Policy   RdmReservePolicy
+}
+
 type Altp2MMode int
 
 const (
@@ -289,6 +470,277 @@ const (
 	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
+	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 (
@@ -304,6 +756,92 @@ 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 (
@@ -334,6 +872,14 @@ const (
 	VsndPcmFormatGsm              VsndPcmFormat = 25
 )
 
+type VsndParams struct {
+	SampleRates   []uint32
+	SampleFormats []VsndPcmFormat
+	ChannelsMin   uint32
+	ChannelsMax   uint32
+	BufferSize    uint32
+}
+
 type VsndStreamType int
 
 const (
@@ -341,6 +887,229 @@ const (
 	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 (
@@ -351,6 +1120,38 @@ const (
 	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 (
@@ -370,9 +1171,42 @@ const (
 	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.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 15/24] golang/xenlight: remove no-longer used type MemKB
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (13 preceding siblings ...)
  2019-10-07 15:13 ` [Xen-devel] [PATCH 14/24] golang/xenlight: generate structs from the IDL Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-11-14 14:18   ` George Dunlap
  2019-10-07 15:13 ` [Xen-devel] [PATCH 16/24] golang/xenlight: begin C to Go type marshaling Nick Rosbrook
                   ` (8 subsequent siblings)
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 2 --
 1 file changed, 2 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index 0adb12d1bf..f91c0d2be2 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -83,8 +83,6 @@ type Domid uint32
 // Devid is a device ID.
 type Devid int
 
-type MemKB uint64
-
 // Uuid is a domain UUID.
 type Uuid [16]byte
 
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 16/24] golang/xenlight: begin C to Go type marshaling
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (14 preceding siblings ...)
  2019-10-07 15:13 ` [Xen-devel] [PATCH 15/24] golang/xenlight: remove no-longer used type MemKB Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-10-07 15:13 ` [Xen-devel] [PATCH 17/24] golang/xenlight: implement keyed union C to Go marshaling Nick Rosbrook
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Implement basic type conversion in fromC functions such as strings and
integer types. Also, remove existing toGo functions from xenlight.go in
favor of the new generated functions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/gengotypes.py       | 120 +++
 tools/golang/xenlight/xenlight.go         | 111 +--
 tools/golang/xenlight/xenlight_helpers.go | 967 ++++++++++++++++++++++
 3 files changed, 1098 insertions(+), 100 deletions(-)
 create mode 100644 tools/golang/xenlight/xenlight_helpers.go

diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
index c8513b79e0..75dcd01724 100644
--- a/tools/golang/xenlight/gengotypes.py
+++ b/tools/golang/xenlight/gengotypes.py
@@ -18,6 +18,12 @@ builtin_type_names = {
     idl.uint64.typename: 'uint64',
 }
 
+# Some go keywords that conflict with field names in libxl structs.
+go_keywords = ['type', 'func']
+
+go_builtin_types = ['bool', 'string', 'int', 'byte',
+                    'uint16', 'uint32', 'uint64']
+
 # List of strings that need to be written to a file
 # after a struct definition.
 type_extras = []
@@ -168,6 +174,118 @@ def xenlight_golang_define_union(ty = None, structname = ''):
 
     return s
 
+def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
+    """
+    Generate a .go file (xenlight_helpers.go by default)
+    that contains helper functions for marshaling between
+    C and Go types.
+    """
+    if path is None:
+        path = 'xenlight_helpers.go'
+
+    with open(path, 'w') as f:
+        if comment is not None:
+            f.write(comment)
+        f.write('package xenlight\n')
+
+        # Cgo preamble
+        f.write('/*\n')
+        f.write('#cgo LDFLAGS: -lxenlight\n')
+        f.write('#include <stdlib.h>\n')
+        f.write('#include <libxl.h>\n')
+        f.write('\n')
+
+        f.write('*/\nimport "C"\n')
+
+        for ty in types:
+            if not isinstance(ty, idl.Struct):
+                continue
+
+            f.write(xenlight_golang_define_from_C(ty))
+            f.write('\n')
+
+    go_fmt(path)
+
+def xenlight_golang_define_from_C(ty = None, typename = None, nested = False):
+    s = ''
+
+    gotypename = ctypename = ''
+
+    if typename is not None:
+        gotypename = xenlight_golang_fmt_name(typename)
+        ctypename  = typename
+    else:
+        gotypename = xenlight_golang_fmt_name(ty.typename)
+        ctypename  = ty.typename
+
+    if not nested:
+        s += 'func (x *{}) fromC(xc *C.{}) error {{\n'.format(gotypename,ctypename)
+
+    for f in ty.fields:
+        if f.type.typename is not None:
+            if isinstance(f.type, idl.Array):
+                # TODO
+                continue
+
+            gotypename = xenlight_golang_fmt_name(f.type.typename)
+            gofname    = xenlight_golang_fmt_name(f.name)
+            cfname     = f.name
+
+            # In cgo, C names that conflict with Go keywords can be
+            # accessed by prepending an underscore to the name.
+            if cfname in go_keywords:
+                cfname = '_' + cfname
+
+            # If this is nested, we need the outer name too.
+            if nested and typename is not None:
+                goname = xenlight_golang_fmt_name(typename)
+                goname = '{}.{}'.format(goname, gofname)
+                cname  = '{}.{}'.format(typename, cfname)
+
+            else:
+                goname = gofname
+                cname  = cfname
+
+            # Types that satisfy this condition can be easily casted or
+            # converted to a Go builtin type.
+            is_castable = (f.type.json_parse_type == 'JSON_INTEGER' or
+                           isinstance(f.type, idl.Enumeration) or
+                           gotypename in go_builtin_types)
+
+            if is_castable:
+                # Use the cgo helper for converting C strings.
+                if gotypename == 'string':
+                    s += 'x.{} = C.GoString(xc.{})\n'.format(goname, cname)
+                    continue
+
+                s += 'x.{} = {}(xc.{})\n'.format(goname, gotypename, cname)
+
+            else:
+                # If the type is not castable, we need to call its fromC
+                # function.
+                varname = '{}_{}'.format(f.type.typename,f.name)
+                varname = xenlight_golang_fmt_name(varname, exported=False)
+
+                s += 'var {} {}\n'.format(varname, gotypename)
+                s += 'if err := {}.fromC(&xc.{});'.format(varname, cname)
+                s += 'err != nil {\n return err\n}\n'
+                s += 'x.{} = {}\n'.format(goname, varname)
+
+        elif isinstance(f.type, idl.Struct):
+            s += xenlight_golang_define_from_C(f.type, typename=f.name, nested=True)
+
+        elif isinstance(f.type, idl.KeyedUnion):
+            pass
+
+        else:
+            raise Exception('type {} not supported'.format(f.type))
+
+    if not nested:
+        s += 'return nil'
+        s += '}\n'
+
+    return s
+
 def xenlight_golang_fmt_name(name, exported = True):
     """
     Take a given type name and return an
@@ -210,3 +328,5 @@ if __name__ == '__main__':
 
     xenlight_golang_generate_types(types=types,
                                    comment=header_comment)
+    xenlight_golang_generate_helpers(types=types,
+                                     comment=header_comment)
diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index f91c0d2be2..a8f933c75f 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -432,47 +432,6 @@ func (bm *Bitmap) toC() (C.libxl_bitmap, error) {
 	return cbm, nil
 }
 
-func (cphys *C.libxl_physinfo) toGo() (physinfo *Physinfo) {
-
-	physinfo = &Physinfo{}
-	physinfo.ThreadsPerCore = uint32(cphys.threads_per_core)
-	physinfo.CoresPerSocket = uint32(cphys.cores_per_socket)
-	physinfo.MaxCpuId = uint32(cphys.max_cpu_id)
-	physinfo.NrCpus = uint32(cphys.nr_cpus)
-	physinfo.CpuKhz = uint32(cphys.cpu_khz)
-	physinfo.TotalPages = uint64(cphys.total_pages)
-	physinfo.FreePages = uint64(cphys.free_pages)
-	physinfo.ScrubPages = uint64(cphys.scrub_pages)
-	physinfo.ScrubPages = uint64(cphys.scrub_pages)
-	physinfo.SharingFreedPages = uint64(cphys.sharing_freed_pages)
-	physinfo.SharingUsedFrames = uint64(cphys.sharing_used_frames)
-	physinfo.NrNodes = uint32(cphys.nr_nodes)
-	physinfo.HwCap.fromC(&cphys.hw_cap)
-	physinfo.CapHvm = bool(cphys.cap_hvm)
-	physinfo.CapHvmDirectio = bool(cphys.cap_hvm_directio)
-
-	return
-}
-
-func (cinfo *C.libxl_version_info) toGo() (info *VersionInfo) {
-	info = &VersionInfo{}
-	info.XenVersionMajor = int(cinfo.xen_version_major)
-	info.XenVersionMinor = int(cinfo.xen_version_minor)
-	info.XenVersionExtra = C.GoString(cinfo.xen_version_extra)
-	info.Compiler = C.GoString(cinfo.compiler)
-	info.CompileBy = C.GoString(cinfo.compile_by)
-	info.CompileDomain = C.GoString(cinfo.compile_domain)
-	info.CompileDate = C.GoString(cinfo.compile_date)
-	info.Capabilities = C.GoString(cinfo.capabilities)
-	info.Changeset = C.GoString(cinfo.changeset)
-	info.VirtStart = uint64(cinfo.virt_start)
-	info.Pagesize = int(cinfo.pagesize)
-	info.Commandline = C.GoString(cinfo.commandline)
-	info.BuildId = C.GoString(cinfo.build_id)
-
-	return
-}
-
 func (sr ShutdownReason) String() (str string) {
 	cstr := C.libxl_shutdown_reason_to_string(C.libxl_shutdown_reason(sr))
 	str = C.GoString(cstr)
@@ -487,34 +446,6 @@ func (dt DomainType) String() (str string) {
 	return
 }
 
-func (cdi *C.libxl_dominfo) toGo() (di *Dominfo) {
-
-	di = &Dominfo{}
-	di.Uuid.fromC(&cdi.uuid)
-	di.Domid = Domid(cdi.domid)
-	di.Ssidref = uint32(cdi.ssidref)
-	di.SsidLabel = C.GoString(cdi.ssid_label)
-	di.Running = bool(cdi.running)
-	di.Blocked = bool(cdi.blocked)
-	di.Paused = bool(cdi.paused)
-	di.Shutdown = bool(cdi.shutdown)
-	di.Dying = bool(cdi.dying)
-	di.NeverStop = bool(cdi.never_stop)
-	di.ShutdownReason = ShutdownReason(cdi.shutdown_reason)
-	di.OutstandingMemkb = uint64(cdi.outstanding_memkb)
-	di.CurrentMemkb = uint64(cdi.current_memkb)
-	di.SharedMemkb = uint64(cdi.shared_memkb)
-	di.PagedMemkb = uint64(cdi.paged_memkb)
-	di.MaxMemkb = uint64(cdi.max_memkb)
-	di.CpuTime = uint64(cdi.cpu_time)
-	di.VcpuMaxId = uint32(cdi.vcpu_max_id)
-	di.VcpuOnline = uint32(cdi.vcpu_online)
-	di.Cpupool = uint32(cdi.cpupool)
-	di.DomainType = DomainType(cdi.domain_type)
-
-	return
-}
-
 // const char *libxl_scheduler_to_string(libxl_scheduler p);
 func (s Scheduler) String() string {
 	cs := C.libxl_scheduler_to_string(C.libxl_scheduler(s))
@@ -546,16 +477,6 @@ func SchedulerFromString(name string) (s Scheduler, err error) {
 	return
 }
 
-func (cci C.libxl_cpupoolinfo) toGo() (gci Cpupoolinfo) {
-	gci.Poolid = uint32(cci.poolid)
-	gci.PoolName = C.GoString(cci.pool_name)
-	gci.Sched = Scheduler(cci.sched)
-	gci.NDom = uint32(cci.n_dom)
-	gci.Cpumap.fromC(&cci.cpumap)
-
-	return
-}
-
 // libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
 // void libxl_cpupoolinfo_list_free(libxl_cpupoolinfo *list, int nb_pool);
 func (Ctx *Context) ListCpupool() (list []Cpupoolinfo) {
@@ -577,7 +498,8 @@ func (Ctx *Context) ListCpupool() (list []Cpupoolinfo) {
 	// Magic
 	cpupoolListSlice := (*[1 << 30]C.libxl_cpupoolinfo)(unsafe.Pointer(c_cpupool_list))[:nbPool:nbPool]
 	for i := range cpupoolListSlice {
-		info := cpupoolListSlice[i].toGo()
+		var info Cpupoolinfo
+		_ = info.fromC(&cpupoolListSlice[i])
 		list = append(list, info)
 	}
 
@@ -600,7 +522,7 @@ func (Ctx *Context) CpupoolInfo(Poolid uint32) (pool Cpupoolinfo) {
 	}
 	defer C.libxl_cpupoolinfo_dispose(&c_cpupool)
 
-	pool = c_cpupool.toGo()
+	_ = pool.fromC(&c_cpupool)
 
 	return
 }
@@ -1091,7 +1013,7 @@ func (Ctx *Context) GetPhysinfo() (physinfo *Physinfo, err error) {
 		err = Error(ret)
 		return
 	}
-	physinfo = cphys.toGo()
+	err = physinfo.fromC(&cphys)
 
 	return
 }
@@ -1107,7 +1029,7 @@ func (Ctx *Context) GetVersionInfo() (info *VersionInfo, err error) {
 
 	cinfo = C.libxl_get_version_info(Ctx.ctx)
 
-	info = cinfo.toGo()
+	err = info.fromC(cinfo)
 
 	return
 }
@@ -1129,7 +1051,7 @@ func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
 		return
 	}
 
-	di = cdi.toGo()
+	err = di.fromC(&cdi)
 
 	return
 }
@@ -1211,26 +1133,14 @@ func (Ctx *Context) ListDomain() (glist []Dominfo) {
 
 	gslice := (*[1 << 30]C.libxl_dominfo)(unsafe.Pointer(clist))[:nbDomain:nbDomain]
 	for i := range gslice {
-		info := gslice[i].toGo()
-		glist = append(glist, *info)
+		var info Dominfo
+		_ = info.fromC(&gslice[i])
+		glist = append(glist, info)
 	}
 
 	return
 }
 
-func (cvci C.libxl_vcpuinfo) toGo() (gvci Vcpuinfo) {
-	gvci.Vcpuid = uint32(cvci.vcpuid)
-	gvci.Cpu = uint32(cvci.cpu)
-	gvci.Online = bool(cvci.online)
-	gvci.Blocked = bool(cvci.blocked)
-	gvci.Running = bool(cvci.running)
-	gvci.VcpuTime = uint64(cvci.vcpu_time)
-	gvci.Cpumap.fromC(&cvci.cpumap)
-	gvci.CpumapSoft.fromC(&cvci.cpumap_soft)
-
-	return
-}
-
 //libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid,
 //				int *nb_vcpu, int *nr_cpus_out);
 //void libxl_vcpuinfo_list_free(libxl_vcpuinfo *, int nr_vcpus);
@@ -1252,7 +1162,8 @@ func (Ctx *Context) ListVcpu(id Domid) (glist []Vcpuinfo) {
 
 	gslice := (*[1 << 30]C.libxl_vcpuinfo)(unsafe.Pointer(clist))[:nbVcpu:nbVcpu]
 	for i := range gslice {
-		info := gslice[i].toGo()
+		var info Vcpuinfo
+		_ = info.fromC(&gslice[i])
 		glist = append(glist, info)
 	}
 
diff --git a/tools/golang/xenlight/xenlight_helpers.go b/tools/golang/xenlight/xenlight_helpers.go
new file mode 100644
index 0000000000..4ece90dc6b
--- /dev/null
+++ b/tools/golang/xenlight/xenlight_helpers.go
@@ -0,0 +1,967 @@
+// DO NOT EDIT.
+//
+// This file is generated by:
+// gengotypes.py ../../libxl/libxl_types.idl
+//
+package xenlight
+
+/*
+#cgo LDFLAGS: -lxenlight
+#include <stdlib.h>
+#include <libxl.h>
+
+*/
+import "C"
+
+func (x *IoportRange) fromC(xc *C.libxl_ioport_range) error {
+	x.First = uint32(xc.first)
+	x.Number = uint32(xc.number)
+	return 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 *VgaInterfaceInfo) fromC(xc *C.libxl_vga_interface_info) error {
+	x.Kind = VgaInterfaceType(xc.kind)
+	return nil
+}
+
+func (x *VncInfo) fromC(xc *C.libxl_vnc_info) error {
+	var defboolEnable Defbool
+	if err := defboolEnable.fromC(&xc.enable); err != nil {
+		return err
+	}
+	x.Enable = defboolEnable
+	x.Listen = C.GoString(xc.listen)
+	x.Passwd = C.GoString(xc.passwd)
+	x.Display = int(xc.display)
+	var defboolFindunused Defbool
+	if err := defboolFindunused.fromC(&xc.findunused); err != nil {
+		return err
+	}
+	x.Findunused = defboolFindunused
+	return nil
+}
+
+func (x *SpiceInfo) fromC(xc *C.libxl_spice_info) error {
+	var defboolEnable Defbool
+	if err := defboolEnable.fromC(&xc.enable); err != nil {
+		return err
+	}
+	x.Enable = defboolEnable
+	x.Port = int(xc.port)
+	x.TlsPort = int(xc.tls_port)
+	x.Host = C.GoString(xc.host)
+	var defboolDisableTicketing Defbool
+	if err := defboolDisableTicketing.fromC(&xc.disable_ticketing); err != nil {
+		return err
+	}
+	x.DisableTicketing = defboolDisableTicketing
+	x.Passwd = C.GoString(xc.passwd)
+	var defboolAgentMouse Defbool
+	if err := defboolAgentMouse.fromC(&xc.agent_mouse); err != nil {
+		return err
+	}
+	x.AgentMouse = defboolAgentMouse
+	var defboolVdagent Defbool
+	if err := defboolVdagent.fromC(&xc.vdagent); err != nil {
+		return err
+	}
+	x.Vdagent = defboolVdagent
+	var defboolClipboardSharing Defbool
+	if err := defboolClipboardSharing.fromC(&xc.clipboard_sharing); err != nil {
+		return err
+	}
+	x.ClipboardSharing = defboolClipboardSharing
+	x.Usbredirection = int(xc.usbredirection)
+	x.ImageCompression = C.GoString(xc.image_compression)
+	x.StreamingVideo = C.GoString(xc.streaming_video)
+	return nil
+}
+
+func (x *SdlInfo) fromC(xc *C.libxl_sdl_info) error {
+	var defboolEnable Defbool
+	if err := defboolEnable.fromC(&xc.enable); err != nil {
+		return err
+	}
+	x.Enable = defboolEnable
+	var defboolOpengl Defbool
+	if err := defboolOpengl.fromC(&xc.opengl); err != nil {
+		return err
+	}
+	x.Opengl = defboolOpengl
+	x.Display = C.GoString(xc.display)
+	x.Xauthority = C.GoString(xc.xauthority)
+	return nil
+}
+
+func (x *Dominfo) fromC(xc *C.libxl_dominfo) error {
+	var uuidUuid Uuid
+	if err := uuidUuid.fromC(&xc.uuid); err != nil {
+		return err
+	}
+	x.Uuid = uuidUuid
+	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 *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)
+	var bitmapCpumap Bitmap
+	if err := bitmapCpumap.fromC(&xc.cpumap); err != nil {
+		return err
+	}
+	x.Cpumap = bitmapCpumap
+	return 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)
+	return nil
+}
+
+func (x *Vminfo) fromC(xc *C.libxl_vminfo) error {
+	var uuidUuid Uuid
+	if err := uuidUuid.fromC(&xc.uuid); err != nil {
+		return err
+	}
+	x.Uuid = uuidUuid
+	x.Domid = Domid(xc.domid)
+	return 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 *DomainCreateInfo) fromC(xc *C.libxl_domain_create_info) error {
+	x.Type = DomainType(xc._type)
+	var defboolHap Defbool
+	if err := defboolHap.fromC(&xc.hap); err != nil {
+		return err
+	}
+	x.Hap = defboolHap
+	var defboolOos Defbool
+	if err := defboolOos.fromC(&xc.oos); err != nil {
+		return err
+	}
+	x.Oos = defboolOos
+	x.Ssidref = uint32(xc.ssidref)
+	x.SsidLabel = C.GoString(xc.ssid_label)
+	x.Name = C.GoString(xc.name)
+	var uuidUuid Uuid
+	if err := uuidUuid.fromC(&xc.uuid); err != nil {
+		return err
+	}
+	x.Uuid = uuidUuid
+	var keyValueListXsdata KeyValueList
+	if err := keyValueListXsdata.fromC(&xc.xsdata); err != nil {
+		return err
+	}
+	x.Xsdata = keyValueListXsdata
+	var keyValueListPlatformdata KeyValueList
+	if err := keyValueListPlatformdata.fromC(&xc.platformdata); err != nil {
+		return err
+	}
+	x.Platformdata = keyValueListPlatformdata
+	x.Poolid = uint32(xc.poolid)
+	x.PoolName = C.GoString(xc.pool_name)
+	var defboolRunHotplugScripts Defbool
+	if err := defboolRunHotplugScripts.fromC(&xc.run_hotplug_scripts); err != nil {
+		return err
+	}
+	x.RunHotplugScripts = defboolRunHotplugScripts
+	var defboolDriverDomain Defbool
+	if err := defboolDriverDomain.fromC(&xc.driver_domain); err != nil {
+		return err
+	}
+	x.DriverDomain = defboolDriverDomain
+	return 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)
+	var defboolUserspaceColoProxy Defbool
+	if err := defboolUserspaceColoProxy.fromC(&xc.userspace_colo_proxy); err != nil {
+		return err
+	}
+	x.UserspaceColoProxy = defboolUserspaceColoProxy
+	return 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 *VcpuSchedParams) fromC(xc *C.libxl_vcpu_sched_params) error {
+	x.Sched = Scheduler(xc.sched)
+	return 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 *VnodeInfo) fromC(xc *C.libxl_vnode_info) error {
+	x.Memkb = uint64(xc.memkb)
+	x.Pnode = uint32(xc.pnode)
+	var bitmapVcpus Bitmap
+	if err := bitmapVcpus.fromC(&xc.vcpus); err != nil {
+		return err
+	}
+	x.Vcpus = bitmapVcpus
+	return 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 *DomainBuildInfo) fromC(xc *C.libxl_domain_build_info) error {
+	x.MaxVcpus = int(xc.max_vcpus)
+	var bitmapAvailVcpus Bitmap
+	if err := bitmapAvailVcpus.fromC(&xc.avail_vcpus); err != nil {
+		return err
+	}
+	x.AvailVcpus = bitmapAvailVcpus
+	var bitmapCpumap Bitmap
+	if err := bitmapCpumap.fromC(&xc.cpumap); err != nil {
+		return err
+	}
+	x.Cpumap = bitmapCpumap
+	var bitmapNodemap Bitmap
+	if err := bitmapNodemap.fromC(&xc.nodemap); err != nil {
+		return err
+	}
+	x.Nodemap = bitmapNodemap
+	var defboolNumaPlacement Defbool
+	if err := defboolNumaPlacement.fromC(&xc.numa_placement); err != nil {
+		return err
+	}
+	x.NumaPlacement = defboolNumaPlacement
+	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.RtcTimeoffset = uint32(xc.rtc_timeoffset)
+	x.ExecSsidref = uint32(xc.exec_ssidref)
+	x.ExecSsidLabel = C.GoString(xc.exec_ssid_label)
+	var defboolLocaltime Defbool
+	if err := defboolLocaltime.fromC(&xc.localtime); err != nil {
+		return err
+	}
+	x.Localtime = defboolLocaltime
+	var defboolDisableMigrate Defbool
+	if err := defboolDisableMigrate.fromC(&xc.disable_migrate); err != nil {
+		return err
+	}
+	x.DisableMigrate = defboolDisableMigrate
+	var cpuidPolicyListCpuid CpuidPolicyList
+	if err := cpuidPolicyListCpuid.fromC(&xc.cpuid); err != nil {
+		return err
+	}
+	x.Cpuid = cpuidPolicyListCpuid
+	x.BlkdevStart = C.GoString(xc.blkdev_start)
+	x.MaxGrantFrames = uint32(xc.max_grant_frames)
+	x.MaxMaptrackFrames = uint32(xc.max_maptrack_frames)
+	x.DeviceModelVersion = DeviceModelVersion(xc.device_model_version)
+	var defboolDeviceModelStubdomain Defbool
+	if err := defboolDeviceModelStubdomain.fromC(&xc.device_model_stubdomain); err != nil {
+		return err
+	}
+	x.DeviceModelStubdomain = defboolDeviceModelStubdomain
+	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)
+	var stringListExtra StringList
+	if err := stringListExtra.fromC(&xc.extra); err != nil {
+		return err
+	}
+	x.Extra = stringListExtra
+	var stringListExtraPv StringList
+	if err := stringListExtraPv.fromC(&xc.extra_pv); err != nil {
+		return err
+	}
+	x.ExtraPv = stringListExtraPv
+	var stringListExtraHvm StringList
+	if err := stringListExtraHvm.fromC(&xc.extra_hvm); err != nil {
+		return err
+	}
+	x.ExtraHvm = stringListExtraHvm
+	var domainSchedParamsSchedParams DomainSchedParams
+	if err := domainSchedParamsSchedParams.fromC(&xc.sched_params); err != nil {
+		return err
+	}
+	x.SchedParams = domainSchedParamsSchedParams
+	var defboolClaimMode Defbool
+	if err := defboolClaimMode.fromC(&xc.claim_mode); err != nil {
+		return err
+	}
+	x.ClaimMode = defboolClaimMode
+	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)
+	var defboolAcpi Defbool
+	if err := defboolAcpi.fromC(&xc.acpi); err != nil {
+		return err
+	}
+	x.Acpi = defboolAcpi
+	x.Bootloader = C.GoString(xc.bootloader)
+	var stringListBootloaderArgs StringList
+	if err := stringListBootloaderArgs.fromC(&xc.bootloader_args); err != nil {
+		return err
+	}
+	x.BootloaderArgs = stringListBootloaderArgs
+	x.TimerMode = TimerMode(xc.timer_mode)
+	var defboolNestedHvm Defbool
+	if err := defboolNestedHvm.fromC(&xc.nested_hvm); err != nil {
+		return err
+	}
+	x.NestedHvm = defboolNestedHvm
+	var defboolApic Defbool
+	if err := defboolApic.fromC(&xc.apic); err != nil {
+		return err
+	}
+	x.Apic = defboolApic
+	var defboolDmRestrict Defbool
+	if err := defboolDmRestrict.fromC(&xc.dm_restrict); err != nil {
+		return err
+	}
+	x.DmRestrict = defboolDmRestrict
+	x.Tee = TeeType(xc.tee)
+	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 *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)
+	var vncInfoVnc VncInfo
+	if err := vncInfoVnc.fromC(&xc.vnc); err != nil {
+		return err
+	}
+	x.Vnc = vncInfoVnc
+	var sdlInfoSdl SdlInfo
+	if err := sdlInfoSdl.fromC(&xc.sdl); err != nil {
+		return err
+	}
+	x.Sdl = sdlInfoSdl
+	x.Keymap = C.GoString(xc.keymap)
+	return 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 *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)
+	var defboolDiscardEnable Defbool
+	if err := defboolDiscardEnable.fromC(&xc.discard_enable); err != nil {
+		return err
+	}
+	x.DiscardEnable = defboolDiscardEnable
+	var defboolColoEnable Defbool
+	if err := defboolColoEnable.fromC(&xc.colo_enable); err != nil {
+		return err
+	}
+	x.ColoEnable = defboolColoEnable
+	var defboolColoRestoreEnable Defbool
+	if err := defboolColoRestoreEnable.fromC(&xc.colo_restore_enable); err != nil {
+		return err
+	}
+	x.ColoRestoreEnable = defboolColoRestoreEnable
+	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 *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)
+	var macMac Mac
+	if err := macMac.fromC(&xc.mac); err != nil {
+		return err
+	}
+	x.Mac = macMac
+	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 *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 *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 *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 *DeviceUsbdev) fromC(xc *C.libxl_device_usbdev) error {
+	x.Ctrl = Devid(xc.ctrl)
+	x.Port = int(xc.port)
+	return nil
+}
+
+func (x *DeviceDtdev) fromC(xc *C.libxl_device_dtdev) error {
+	x.Path = C.GoString(xc.path)
+	return 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)
+	var uuidUuid Uuid
+	if err := uuidUuid.fromC(&xc.uuid); err != nil {
+		return err
+	}
+	x.Uuid = uuidUuid
+	return 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 *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 *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)
+	return 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 *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)
+	return nil
+}
+
+func (x *VsndParams) fromC(xc *C.libxl_vsnd_params) error {
+	x.ChannelsMin = uint32(xc.channels_min)
+	x.ChannelsMax = uint32(xc.channels_max)
+	x.BufferSize = uint32(xc.buffer_size)
+	return nil
+}
+
+func (x *VsndStream) fromC(xc *C.libxl_vsnd_stream) error {
+	x.UniqueId = C.GoString(xc.unique_id)
+	x.Type = VsndStreamType(xc._type)
+	var vsndParamsParams VsndParams
+	if err := vsndParamsParams.fromC(&xc.params); err != nil {
+		return err
+	}
+	x.Params = vsndParamsParams
+	return nil
+}
+
+func (x *VsndPcm) fromC(xc *C.libxl_vsnd_pcm) error {
+	x.Name = C.GoString(xc.name)
+	var vsndParamsParams VsndParams
+	if err := vsndParamsParams.fromC(&xc.params); err != nil {
+		return err
+	}
+	x.Params = vsndParamsParams
+	return 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)
+	var vsndParamsParams VsndParams
+	if err := vsndParamsParams.fromC(&xc.params); err != nil {
+		return err
+	}
+	x.Params = vsndParamsParams
+	return nil
+}
+
+func (x *DomainConfig) fromC(xc *C.libxl_domain_config) error {
+	var domainCreateInfoCInfo DomainCreateInfo
+	if err := domainCreateInfoCInfo.fromC(&xc.c_info); err != nil {
+		return err
+	}
+	x.CInfo = domainCreateInfoCInfo
+	var domainBuildInfoBInfo DomainBuildInfo
+	if err := domainBuildInfoBInfo.fromC(&xc.b_info); err != nil {
+		return err
+	}
+	x.BInfo = domainBuildInfoBInfo
+	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 *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 *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 *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)
+	var uuidUuid Uuid
+	if err := uuidUuid.fromC(&xc.uuid); err != nil {
+		return err
+	}
+	x.Uuid = uuidUuid
+	return 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 *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)
+	var bitmapCpumap Bitmap
+	if err := bitmapCpumap.fromC(&xc.cpumap); err != nil {
+		return err
+	}
+	x.Cpumap = bitmapCpumap
+	var bitmapCpumapSoft Bitmap
+	if err := bitmapCpumapSoft.fromC(&xc.cpumap_soft); err != nil {
+		return err
+	}
+	x.CpumapSoft = bitmapCpumapSoft
+	return 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)
+	var hwcapHwCap Hwcap
+	if err := hwcapHwCap.fromC(&xc.hw_cap); err != nil {
+		return err
+	}
+	x.HwCap = hwcapHwCap
+	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 *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 *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)
+	return 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 *Pcminfo) fromC(xc *C.libxl_pcminfo) error {
+	return 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)
+	return 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 *Numainfo) fromC(xc *C.libxl_numainfo) error {
+	x.Size = uint64(xc.size)
+	x.Free = uint64(xc.free)
+	return 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 *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 *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 *SchedCredit2Params) fromC(xc *C.libxl_sched_credit2_params) error {
+	x.RatelimitUs = int(xc.ratelimit_us)
+	return nil
+}
+
+func (x *DomainRemusInfo) fromC(xc *C.libxl_domain_remus_info) error {
+	x.Interval = int(xc.interval)
+	var defboolAllowUnsafe Defbool
+	if err := defboolAllowUnsafe.fromC(&xc.allow_unsafe); err != nil {
+		return err
+	}
+	x.AllowUnsafe = defboolAllowUnsafe
+	var defboolBlackhole Defbool
+	if err := defboolBlackhole.fromC(&xc.blackhole); err != nil {
+		return err
+	}
+	x.Blackhole = defboolBlackhole
+	var defboolCompression Defbool
+	if err := defboolCompression.fromC(&xc.compression); err != nil {
+		return err
+	}
+	x.Compression = defboolCompression
+	var defboolNetbuf Defbool
+	if err := defboolNetbuf.fromC(&xc.netbuf); err != nil {
+		return err
+	}
+	x.Netbuf = defboolNetbuf
+	x.Netbufscript = C.GoString(xc.netbufscript)
+	var defboolDiskbuf Defbool
+	if err := defboolDiskbuf.fromC(&xc.diskbuf); err != nil {
+		return err
+	}
+	x.Diskbuf = defboolDiskbuf
+	var defboolColo Defbool
+	if err := defboolColo.fromC(&xc.colo); err != nil {
+		return err
+	}
+	x.Colo = defboolColo
+	var defboolUserspaceColoProxy Defbool
+	if err := defboolUserspaceColoProxy.fromC(&xc.userspace_colo_proxy); err != nil {
+		return err
+	}
+	x.UserspaceColoProxy = defboolUserspaceColoProxy
+	return nil
+}
+
+func (x *Event) fromC(xc *C.libxl_event) error {
+	var evLinkLink EvLink
+	if err := evLinkLink.fromC(&xc.link); err != nil {
+		return err
+	}
+	x.Link = evLinkLink
+	x.Domid = Domid(xc.domid)
+	var uuidDomuuid Uuid
+	if err := uuidDomuuid.fromC(&xc.domuuid); err != nil {
+		return err
+	}
+	x.Domuuid = uuidDomuuid
+	x.ForUser = uint64(xc.for_user)
+	return 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 *PsrHwInfo) fromC(xc *C.libxl_psr_hw_info) error {
+	x.Id = uint32(xc.id)
+	return nil
+}
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 17/24] golang/xenlight: implement keyed union C to Go marshaling
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (15 preceding siblings ...)
  2019-10-07 15:13 ` [Xen-devel] [PATCH 16/24] golang/xenlight: begin C to Go type marshaling Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-10-07 15:13 ` [Xen-devel] [PATCH 18/24] golang/xenlight: implement array " Nick Rosbrook
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Switch over union key to determine how to populate 'union' in Go struct.

Since the unions of C types cannot be directly accessed, add C structs in
cgo preamble to assist in marshaling keyed unions. This allows the C
type defined in the preamble to be populated first, and then accessed
directly to populate the Go struct.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/gengotypes.py       | 136 ++++++-
 tools/golang/xenlight/xenlight_helpers.go | 440 ++++++++++++++++++++++
 2 files changed, 575 insertions(+), 1 deletion(-)

diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
index 75dcd01724..ececaafd72 100644
--- a/tools/golang/xenlight/gengotypes.py
+++ b/tools/golang/xenlight/gengotypes.py
@@ -28,6 +28,14 @@ go_builtin_types = ['bool', 'string', 'int', 'byte',
 # after a struct definition.
 type_extras = []
 
+# cgo preamble for xenlight_helpers.go, created during type generation and
+# written later.
+cgo_helpers_preamble = []
+
+# List of strings that need to be written to a file
+# after a helper func definition.
+helper_extras = []
+
 def xenlight_golang_generate_types(path = None, types = None, comment = None):
     """
     Generate a .go file (xenlight_types.go by default)
@@ -159,6 +167,8 @@ def xenlight_golang_define_union(ty = None, structname = ''):
         s = xenlight_golang_define_struct(f.type, typename=name)
         type_extras.append(s)
 
+        xenlight_golang_union_cgo_preamble(f.type, name=name)
+
         # Define function to implement 'union' interface
         name = xenlight_golang_fmt_name(name)
         s = 'func (x {}) is{}(){{}}\n'.format(name, interface_name)
@@ -174,6 +184,18 @@ def xenlight_golang_define_union(ty = None, structname = ''):
 
     return s
 
+def xenlight_golang_union_cgo_preamble(ty = None, name = ''):
+    s = ''
+
+    s += 'typedef struct {} {{\n'.format(name)
+
+    for f in ty.fields:
+        s += '\t{} {};\n'.format(f.type.typename, f.name)
+
+    s += '}} {};\n'.format(name)
+
+    cgo_helpers_preamble.append(s)
+
 def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
     """
     Generate a .go file (xenlight_helpers.go by default)
@@ -187,6 +209,7 @@ def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
         if comment is not None:
             f.write(comment)
         f.write('package xenlight\n')
+        f.write('import (\n"unsafe"\n"errors"\n"fmt"\n)\n')
 
         # Cgo preamble
         f.write('/*\n')
@@ -195,6 +218,10 @@ def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
         f.write('#include <libxl.h>\n')
         f.write('\n')
 
+        for s in cgo_helpers_preamble:
+            f.write(s)
+            f.write('\n')
+
         f.write('*/\nimport "C"\n')
 
         for ty in types:
@@ -204,6 +231,12 @@ def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
             f.write(xenlight_golang_define_from_C(ty))
             f.write('\n')
 
+            for extra in helper_extras:
+                f.write(extra)
+                f.write('\n')
+
+            del helper_extras[:]
+
     go_fmt(path)
 
 def xenlight_golang_define_from_C(ty = None, typename = None, nested = False):
@@ -275,7 +308,7 @@ def xenlight_golang_define_from_C(ty = None, typename = None, nested = False):
             s += xenlight_golang_define_from_C(f.type, typename=f.name, nested=True)
 
         elif isinstance(f.type, idl.KeyedUnion):
-            pass
+            s += xenlight_golang_union_from_C(f.type, f.name, ty.typename)
 
         else:
             raise Exception('type {} not supported'.format(f.type))
@@ -286,6 +319,107 @@ def xenlight_golang_define_from_C(ty = None, typename = None, nested = False):
 
     return s
 
+def xenlight_golang_union_from_C(ty = None, union_name = '', struct_name = ''):
+    keyname   = ty.keyvar.name
+    gokeyname = xenlight_golang_fmt_name(keyname)
+    keytype   = ty.keyvar.type.typename
+    gokeytype = xenlight_golang_fmt_name(keytype)
+
+    interface_name = '{}_{}_union'.format(struct_name, keyname)
+    interface_name = xenlight_golang_fmt_name(interface_name, exported=False)
+
+    cgo_keyname = keyname
+    if cgo_keyname in go_keywords:
+        cgo_keyname = '_' + cgo_keyname
+
+    cases = {}
+
+    for f in ty.fields:
+        val = '{}_{}'.format(keytype, f.name)
+        val = xenlight_golang_fmt_name(val)
+
+        # Add to list of cases to make for the switch
+        # statement below.
+        if f.type is None:
+            continue
+
+        cases[f.name] = val
+
+        # Define fromC func for 'union' struct.
+        typename   = '{}_{}_union_{}'.format(struct_name,keyname,f.name)
+        gotypename = xenlight_golang_fmt_name(typename)
+
+        # Define the function here. The cases for keyed unions are a little
+        # different.
+        s = 'func (x *{}) fromC(xc *C.{}) error {{\n'.format(gotypename,struct_name)
+        s += 'if {}(xc.{}) != {} {{\n'.format(gokeytype,cgo_keyname,val)
+        err_string = '"expected union key {}"'.format(val)
+        s += 'return errors.New({})\n'.format(err_string)
+        s += '}\n\n'
+        s += 'tmp := (*C.{})(unsafe.Pointer(&xc.{}[0]))\n'.format(typename,union_name)
+
+        s += xenlight_golang_union_fields_from_C(f.type)
+        s += 'return nil\n'
+        s += '}\n'
+
+        helper_extras.append(s)
+
+    s = 'x.{} = {}(xc.{})\n'.format(gokeyname,gokeytype,cgo_keyname)
+    s += 'switch x.{}{{\n'.format(gokeyname)
+
+    # Create switch statement to determine which 'union element'
+    # to populate in the Go struct.
+    for case_name, case_val in cases.items():
+        s += 'case {}:\n'.format(case_val)
+
+        gotype = '{}_{}_union_{}'.format(struct_name,keyname,case_name)
+        gotype = xenlight_golang_fmt_name(gotype)
+        goname = '{}_{}'.format(keyname,case_name)
+        goname = xenlight_golang_fmt_name(goname,exported=False)
+
+        s += 'var {} {}\n'.format(goname, gotype)
+        s += 'if err := {}.fromC(xc);'.format(goname)
+        s += 'err != nil {\n return err \n}\n'
+
+        field_name = xenlight_golang_fmt_name('{}_union'.format(keyname))
+        s += 'x.{} = {}\n'.format(field_name, goname)
+
+    # End switch statement
+    s += 'default:\n'
+    err_string = '"invalid union key \'%v\'", x.{}'.format(gokeyname)
+    s += 'return fmt.Errorf({})'.format(err_string)
+    s += '}\n'
+
+    return s
+
+def xenlight_golang_union_fields_from_C(ty = None):
+    s = ''
+
+    for f in ty.fields:
+        gotypename = xenlight_golang_fmt_name(f.type.typename)
+        ctypename  = f.type.typename
+        gofname    = xenlight_golang_fmt_name(f.name)
+        cfname     = f.name
+
+        is_castable = (f.type.json_parse_type == 'JSON_INTEGER' or
+                       isinstance(f.type, idl.Enumeration) or
+                       gotypename in go_builtin_types)
+
+        if not is_castable:
+            s += 'if err := x.{}.fromC(&tmp.{});'.format(gofname,cfname)
+            s += 'err != nil {\n return err \n}\n'
+
+        # We just did an unsafe.Pointer cast from []byte to the 'union' type
+        # struct, so we need to make sure that any string fields are actually
+        # converted properly.
+        elif gotypename == 'string':
+            s += 'x.{} = C.GoString(tmp.{})\n'.format(gofname,cfname)
+
+        else:
+            s += 'x.{} = {}(tmp.{})\n'.format(gofname,gotypename,cfname)
+
+    return s
+
 def xenlight_golang_fmt_name(name, exported = True):
     """
     Take a given type name and return an
diff --git a/tools/golang/xenlight/xenlight_helpers.go b/tools/golang/xenlight/xenlight_helpers.go
index 4ece90dc6b..b8abef8068 100644
--- a/tools/golang/xenlight/xenlight_helpers.go
+++ b/tools/golang/xenlight/xenlight_helpers.go
@@ -5,11 +5,122 @@
 //
 package xenlight
 
+import (
+	"errors"
+	"fmt"
+	"unsafe"
+)
+
 /*
 #cgo LDFLAGS: -lxenlight
 #include <stdlib.h>
 #include <libxl.h>
 
+typedef struct libxl_channelinfo_connection_union_pty {
+	char * path;
+} libxl_channelinfo_connection_union_pty;
+
+typedef struct libxl_domain_build_info_type_union_hvm {
+	char * firmware;
+	libxl_bios_type bios;
+	libxl_defbool pae;
+	libxl_defbool apic;
+	libxl_defbool acpi;
+	libxl_defbool acpi_s3;
+	libxl_defbool acpi_s4;
+	libxl_defbool acpi_laptop_slate;
+	libxl_defbool nx;
+	libxl_defbool viridian;
+	libxl_bitmap viridian_enable;
+	libxl_bitmap viridian_disable;
+	char * timeoffset;
+	libxl_defbool hpet;
+	libxl_defbool vpt_align;
+	uint64_t mmio_hole_memkb;
+	libxl_timer_mode timer_mode;
+	libxl_defbool nested_hvm;
+	libxl_defbool altp2m;
+	char * system_firmware;
+	char * smbios_firmware;
+	char * acpi_firmware;
+	libxl_hdtype hdtype;
+	libxl_defbool nographic;
+	libxl_vga_interface_info vga;
+	libxl_vnc_info vnc;
+	char * keymap;
+	libxl_sdl_info sdl;
+	libxl_spice_info spice;
+	libxl_defbool gfx_passthru;
+	libxl_gfx_passthru_kind gfx_passthru_kind;
+	char * serial;
+	char * boot;
+	libxl_defbool usb;
+	int usbversion;
+	char * usbdevice;
+	libxl_defbool vkb_device;
+	char * soundhw;
+	libxl_defbool xen_platform_pci;
+	libxl_string_list usbdevice_list;
+	libxl_vendor_device vendor_device;
+	libxl_ms_vm_genid ms_vm_genid;
+	libxl_string_list serial_list;
+	libxl_rdm_reserve rdm;
+	uint64_t rdm_mem_boundary_memkb;
+	uint64_t mca_caps;
+} libxl_domain_build_info_type_union_hvm;
+
+typedef struct libxl_domain_build_info_type_union_pv {
+	char * kernel;
+	uint64_t slack_memkb;
+	char * bootloader;
+	libxl_string_list bootloader_args;
+	char * cmdline;
+	char * ramdisk;
+	char * features;
+	libxl_defbool e820_host;
+} libxl_domain_build_info_type_union_pv;
+
+typedef struct libxl_domain_build_info_type_union_pvh {
+	libxl_defbool pvshim;
+	char * pvshim_path;
+	char * pvshim_cmdline;
+	char * pvshim_extra;
+} libxl_domain_build_info_type_union_pvh;
+
+typedef struct libxl_device_usbdev_type_union_hostdev {
+	uint8_t hostbus;
+	uint8_t hostaddr;
+} libxl_device_usbdev_type_union_hostdev;
+
+typedef struct libxl_device_channel_connection_union_socket {
+	char * path;
+} libxl_device_channel_connection_union_socket;
+
+typedef struct libxl_event_type_union_domain_shutdown {
+	uint8_t shutdown_reason;
+} libxl_event_type_union_domain_shutdown;
+
+typedef struct libxl_event_type_union_disk_eject {
+	char * vdev;
+	libxl_device_disk disk;
+} libxl_event_type_union_disk_eject;
+
+typedef struct libxl_event_type_union_operation_complete {
+	int rc;
+} libxl_event_type_union_operation_complete;
+
+typedef struct libxl_psr_hw_info_type_union_cat {
+	uint32_t cos_max;
+	uint32_t cbm_len;
+	bool cdp_enabled;
+} libxl_psr_hw_info_type_union_cat;
+
+typedef struct libxl_psr_hw_info_type_union_mba {
+	uint32_t cos_max;
+	uint32_t thrtl_max;
+	bool linear;
+} libxl_psr_hw_info_type_union_mba;
+
 */
 import "C"
 
@@ -151,6 +262,27 @@ func (x *Channelinfo) fromC(xc *C.libxl_channelinfo) error {
 	x.State = int(xc.state)
 	x.Evtch = int(xc.evtch)
 	x.Rref = int(xc.rref)
+	x.Connection = ChannelConnection(xc.connection)
+	switch x.Connection {
+	case ChannelConnectionPty:
+		var connectionPty ChannelinfoConnectionUnionPty
+		if err := connectionPty.fromC(xc); err != nil {
+			return err
+		}
+		x.ConnectionUnion = connectionPty
+	default:
+		return fmt.Errorf("invalid union key '%v'", x.Connection)
+	}
+	return nil
+}
+
+func (x *ChannelinfoConnectionUnionPty) fromC(xc *C.libxl_channelinfo) error {
+	if ChannelConnection(xc.connection) != ChannelConnectionPty {
+		return errors.New("expected union key ChannelConnectionPty")
+	}
+
+	tmp := (*C.libxl_channelinfo_connection_union_pty)(unsafe.Pointer(&xc.u[0]))
+	x.Path = C.GoString(tmp.path)
 	return nil
 }
 
@@ -398,12 +530,180 @@ func (x *DomainBuildInfo) fromC(xc *C.libxl_domain_build_info) error {
 	}
 	x.DmRestrict = defboolDmRestrict
 	x.Tee = TeeType(xc.tee)
+	x.Type = DomainType(xc._type)
+	switch x.Type {
+	case DomainTypePv:
+		var typePv DomainBuildInfoTypeUnionPv
+		if err := typePv.fromC(xc); err != nil {
+			return err
+		}
+		x.TypeUnion = typePv
+	case DomainTypeHvm:
+		var typeHvm DomainBuildInfoTypeUnionHvm
+		if err := typeHvm.fromC(xc); err != nil {
+			return err
+		}
+		x.TypeUnion = typeHvm
+	case DomainTypePvh:
+		var typePvh DomainBuildInfoTypeUnionPvh
+		if err := typePvh.fromC(xc); err != nil {
+			return err
+		}
+		x.TypeUnion = typePvh
+	default:
+		return fmt.Errorf("invalid union key '%v'", x.Type)
+	}
 	x.ArchArm.GicVersion = GicVersion(xc.arch_arm.gic_version)
 	x.ArchArm.Vuart = VuartType(xc.arch_arm.vuart)
 	x.Altp2M = Altp2MMode(xc.altp2m)
 	return nil
 }
 
+func (x *DomainBuildInfoTypeUnionHvm) fromC(xc *C.libxl_domain_build_info) error {
+	if DomainType(xc._type) != DomainTypeHvm {
+		return errors.New("expected union key DomainTypeHvm")
+	}
+
+	tmp := (*C.libxl_domain_build_info_type_union_hvm)(unsafe.Pointer(&xc.u[0]))
+	x.Firmware = C.GoString(tmp.firmware)
+	x.Bios = BiosType(tmp.bios)
+	if err := x.Pae.fromC(&tmp.pae); err != nil {
+		return err
+	}
+	if err := x.Apic.fromC(&tmp.apic); err != nil {
+		return err
+	}
+	if err := x.Acpi.fromC(&tmp.acpi); err != nil {
+		return err
+	}
+	if err := x.AcpiS3.fromC(&tmp.acpi_s3); err != nil {
+		return err
+	}
+	if err := x.AcpiS4.fromC(&tmp.acpi_s4); err != nil {
+		return err
+	}
+	if err := x.AcpiLaptopSlate.fromC(&tmp.acpi_laptop_slate); err != nil {
+		return err
+	}
+	if err := x.Nx.fromC(&tmp.nx); err != nil {
+		return err
+	}
+	if err := x.Viridian.fromC(&tmp.viridian); err != nil {
+		return err
+	}
+	if err := x.ViridianEnable.fromC(&tmp.viridian_enable); err != nil {
+		return err
+	}
+	if err := x.ViridianDisable.fromC(&tmp.viridian_disable); err != nil {
+		return err
+	}
+	x.Timeoffset = C.GoString(tmp.timeoffset)
+	if err := x.Hpet.fromC(&tmp.hpet); err != nil {
+		return err
+	}
+	if err := x.VptAlign.fromC(&tmp.vpt_align); err != nil {
+		return err
+	}
+	x.MmioHoleMemkb = uint64(tmp.mmio_hole_memkb)
+	x.TimerMode = TimerMode(tmp.timer_mode)
+	if err := x.NestedHvm.fromC(&tmp.nested_hvm); err != nil {
+		return err
+	}
+	if err := x.Altp2M.fromC(&tmp.altp2m); err != nil {
+		return err
+	}
+	x.SystemFirmware = C.GoString(tmp.system_firmware)
+	x.SmbiosFirmware = C.GoString(tmp.smbios_firmware)
+	x.AcpiFirmware = C.GoString(tmp.acpi_firmware)
+	x.Hdtype = Hdtype(tmp.hdtype)
+	if err := x.Nographic.fromC(&tmp.nographic); err != nil {
+		return err
+	}
+	if err := x.Vga.fromC(&tmp.vga); err != nil {
+		return err
+	}
+	if err := x.Vnc.fromC(&tmp.vnc); err != nil {
+		return err
+	}
+	x.Keymap = C.GoString(tmp.keymap)
+	if err := x.Sdl.fromC(&tmp.sdl); err != nil {
+		return err
+	}
+	if err := x.Spice.fromC(&tmp.spice); err != nil {
+		return err
+	}
+	if err := x.GfxPassthru.fromC(&tmp.gfx_passthru); err != nil {
+		return err
+	}
+	x.GfxPassthruKind = GfxPassthruKind(tmp.gfx_passthru_kind)
+	x.Serial = C.GoString(tmp.serial)
+	x.Boot = C.GoString(tmp.boot)
+	if err := x.Usb.fromC(&tmp.usb); err != nil {
+		return err
+	}
+	x.Usbversion = int(tmp.usbversion)
+	x.Usbdevice = C.GoString(tmp.usbdevice)
+	if err := x.VkbDevice.fromC(&tmp.vkb_device); err != nil {
+		return err
+	}
+	x.Soundhw = C.GoString(tmp.soundhw)
+	if err := x.XenPlatformPci.fromC(&tmp.xen_platform_pci); err != nil {
+		return err
+	}
+	if err := x.UsbdeviceList.fromC(&tmp.usbdevice_list); err != nil {
+		return err
+	}
+	x.VendorDevice = VendorDevice(tmp.vendor_device)
+	if err := x.MsVmGenid.fromC(&tmp.ms_vm_genid); err != nil {
+		return err
+	}
+	if err := x.SerialList.fromC(&tmp.serial_list); err != nil {
+		return err
+	}
+	if err := x.Rdm.fromC(&tmp.rdm); err != nil {
+		return err
+	}
+	x.RdmMemBoundaryMemkb = uint64(tmp.rdm_mem_boundary_memkb)
+	x.McaCaps = uint64(tmp.mca_caps)
+	return nil
+}
+
+func (x *DomainBuildInfoTypeUnionPv) fromC(xc *C.libxl_domain_build_info) error {
+	if DomainType(xc._type) != DomainTypePv {
+		return errors.New("expected union key DomainTypePv")
+	}
+
+	tmp := (*C.libxl_domain_build_info_type_union_pv)(unsafe.Pointer(&xc.u[0]))
+	x.Kernel = C.GoString(tmp.kernel)
+	x.SlackMemkb = uint64(tmp.slack_memkb)
+	x.Bootloader = C.GoString(tmp.bootloader)
+	if err := x.BootloaderArgs.fromC(&tmp.bootloader_args); err != nil {
+		return err
+	}
+	x.Cmdline = C.GoString(tmp.cmdline)
+	x.Ramdisk = C.GoString(tmp.ramdisk)
+	x.Features = C.GoString(tmp.features)
+	if err := x.E820Host.fromC(&tmp.e820_host); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (x *DomainBuildInfoTypeUnionPvh) fromC(xc *C.libxl_domain_build_info) error {
+	if DomainType(xc._type) != DomainTypePvh {
+		return errors.New("expected union key DomainTypePvh")
+	}
+
+	tmp := (*C.libxl_domain_build_info_type_union_pvh)(unsafe.Pointer(&xc.u[0]))
+	if err := x.Pvshim.fromC(&tmp.pvshim); err != nil {
+		return err
+	}
+	x.PvshimPath = C.GoString(tmp.pvshim_path)
+	x.PvshimCmdline = C.GoString(tmp.pvshim_cmdline)
+	x.PvshimExtra = C.GoString(tmp.pvshim_extra)
+	return nil
+}
+
 func (x *DeviceVfb) fromC(xc *C.libxl_device_vfb) error {
 	x.BackendDomid = Domid(xc.backend_domid)
 	x.BackendDomname = C.GoString(xc.backend_domname)
@@ -582,6 +882,28 @@ func (x *DeviceUsbctrl) fromC(xc *C.libxl_device_usbctrl) error {
 func (x *DeviceUsbdev) fromC(xc *C.libxl_device_usbdev) error {
 	x.Ctrl = Devid(xc.ctrl)
 	x.Port = int(xc.port)
+	x.Type = UsbdevType(xc._type)
+	switch x.Type {
+	case UsbdevTypeHostdev:
+		var typeHostdev DeviceUsbdevTypeUnionHostdev
+		if err := typeHostdev.fromC(xc); err != nil {
+			return err
+		}
+		x.TypeUnion = typeHostdev
+	default:
+		return fmt.Errorf("invalid union key '%v'", x.Type)
+	}
+	return nil
+}
+
+func (x *DeviceUsbdevTypeUnionHostdev) fromC(xc *C.libxl_device_usbdev) error {
+	if UsbdevType(xc._type) != UsbdevTypeHostdev {
+		return errors.New("expected union key UsbdevTypeHostdev")
+	}
+
+	tmp := (*C.libxl_device_usbdev_type_union_hostdev)(unsafe.Pointer(&xc.u[0]))
+	x.Hostbus = byte(tmp.hostbus)
+	x.Hostaddr = byte(tmp.hostaddr)
 	return nil
 }
 
@@ -624,6 +946,27 @@ func (x *DeviceChannel) fromC(xc *C.libxl_device_channel) error {
 	x.BackendDomname = C.GoString(xc.backend_domname)
 	x.Devid = Devid(xc.devid)
 	x.Name = C.GoString(xc.name)
+	x.Connection = ChannelConnection(xc.connection)
+	switch x.Connection {
+	case ChannelConnectionSocket:
+		var connectionSocket DeviceChannelConnectionUnionSocket
+		if err := connectionSocket.fromC(xc); err != nil {
+			return err
+		}
+		x.ConnectionUnion = connectionSocket
+	default:
+		return fmt.Errorf("invalid union key '%v'", x.Connection)
+	}
+	return nil
+}
+
+func (x *DeviceChannelConnectionUnionSocket) fromC(xc *C.libxl_device_channel) error {
+	if ChannelConnection(xc.connection) != ChannelConnectionSocket {
+		return errors.New("expected union key ChannelConnectionSocket")
+	}
+
+	tmp := (*C.libxl_device_channel_connection_union_socket)(unsafe.Pointer(&xc.u[0]))
+	x.Path = C.GoString(tmp.path)
 	return nil
 }
 
@@ -950,6 +1293,62 @@ func (x *Event) fromC(xc *C.libxl_event) error {
 	}
 	x.Domuuid = uuidDomuuid
 	x.ForUser = uint64(xc.for_user)
+	x.Type = EventType(xc._type)
+	switch x.Type {
+	case EventTypeOperationComplete:
+		var typeOperationComplete EventTypeUnionOperationComplete
+		if err := typeOperationComplete.fromC(xc); err != nil {
+			return err
+		}
+		x.TypeUnion = typeOperationComplete
+	case EventTypeDomainShutdown:
+		var typeDomainShutdown EventTypeUnionDomainShutdown
+		if err := typeDomainShutdown.fromC(xc); err != nil {
+			return err
+		}
+		x.TypeUnion = typeDomainShutdown
+	case EventTypeDiskEject:
+		var typeDiskEject EventTypeUnionDiskEject
+		if err := typeDiskEject.fromC(xc); err != nil {
+			return err
+		}
+		x.TypeUnion = typeDiskEject
+	default:
+		return fmt.Errorf("invalid union key '%v'", x.Type)
+	}
+	return nil
+}
+
+func (x *EventTypeUnionDomainShutdown) fromC(xc *C.libxl_event) error {
+	if EventType(xc._type) != EventTypeDomainShutdown {
+		return errors.New("expected union key EventTypeDomainShutdown")
+	}
+
+	tmp := (*C.libxl_event_type_union_domain_shutdown)(unsafe.Pointer(&xc.u[0]))
+	x.ShutdownReason = byte(tmp.shutdown_reason)
+	return nil
+}
+
+func (x *EventTypeUnionDiskEject) fromC(xc *C.libxl_event) error {
+	if EventType(xc._type) != EventTypeDiskEject {
+		return errors.New("expected union key EventTypeDiskEject")
+	}
+
+	tmp := (*C.libxl_event_type_union_disk_eject)(unsafe.Pointer(&xc.u[0]))
+	x.Vdev = C.GoString(tmp.vdev)
+	if err := x.Disk.fromC(&tmp.disk); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (x *EventTypeUnionOperationComplete) fromC(xc *C.libxl_event) error {
+	if EventType(xc._type) != EventTypeOperationComplete {
+		return errors.New("expected union key EventTypeOperationComplete")
+	}
+
+	tmp := (*C.libxl_event_type_union_operation_complete)(unsafe.Pointer(&xc.u[0]))
+	x.Rc = int(tmp.rc)
 	return nil
 }
 
@@ -963,5 +1362,46 @@ func (x *PsrCatInfo) fromC(xc *C.libxl_psr_cat_info) error {
 
 func (x *PsrHwInfo) fromC(xc *C.libxl_psr_hw_info) error {
 	x.Id = uint32(xc.id)
+	x.Type = PsrFeatType(xc._type)
+	switch x.Type {
+	case PsrFeatTypeMba:
+		var typeMba PsrHwInfoTypeUnionMba
+		if err := typeMba.fromC(xc); err != nil {
+			return err
+		}
+		x.TypeUnion = typeMba
+	case PsrFeatTypeCat:
+		var typeCat PsrHwInfoTypeUnionCat
+		if err := typeCat.fromC(xc); err != nil {
+			return err
+		}
+		x.TypeUnion = typeCat
+	default:
+		return fmt.Errorf("invalid union key '%v'", x.Type)
+	}
+	return nil
+}
+
+func (x *PsrHwInfoTypeUnionCat) fromC(xc *C.libxl_psr_hw_info) error {
+	if PsrFeatType(xc._type) != PsrFeatTypeCat {
+		return errors.New("expected union key PsrFeatTypeCat")
+	}
+
+	tmp := (*C.libxl_psr_hw_info_type_union_cat)(unsafe.Pointer(&xc.u[0]))
+	x.CosMax = uint32(tmp.cos_max)
+	x.CbmLen = uint32(tmp.cbm_len)
+	x.CdpEnabled = bool(tmp.cdp_enabled)
+	return nil
+}
+
+func (x *PsrHwInfoTypeUnionMba) fromC(xc *C.libxl_psr_hw_info) error {
+	if PsrFeatType(xc._type) != PsrFeatTypeMba {
+		return errors.New("expected union key PsrFeatTypeMba")
+	}
+
+	tmp := (*C.libxl_psr_hw_info_type_union_mba)(unsafe.Pointer(&xc.u[0]))
+	x.CosMax = uint32(tmp.cos_max)
+	x.ThrtlMax = uint32(tmp.thrtl_max)
+	x.Linear = bool(tmp.linear)
 	return nil
 }
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 18/24] golang/xenlight: implement array C to Go marshaling
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (16 preceding siblings ...)
  2019-10-07 15:13 ` [Xen-devel] [PATCH 17/24] golang/xenlight: implement keyed union C to Go marshaling Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-10-07 15:13 ` [Xen-devel] [PATCH 19/24] golang/xenlight: begin Go to C type marshaling Nick Rosbrook
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/gengotypes.py       |  39 ++-
 tools/golang/xenlight/xenlight_helpers.go | 300 ++++++++++++++++++++++
 2 files changed, 338 insertions(+), 1 deletion(-)

diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
index ececaafd72..2b620f0ae9 100644
--- a/tools/golang/xenlight/gengotypes.py
+++ b/tools/golang/xenlight/gengotypes.py
@@ -257,7 +257,7 @@ def xenlight_golang_define_from_C(ty = None, typename = None, nested = False):
     for f in ty.fields:
         if f.type.typename is not None:
             if isinstance(f.type, idl.Array):
-                # TODO
+                s += xenlight_golang_array_from_C(f)
                 continue
 
             gotypename = xenlight_golang_fmt_name(f.type.typename)
@@ -420,6 +420,43 @@ def xenlight_golang_union_fields_from_C(ty = None):
 
     return s
 
+def xenlight_golang_array_from_C(ty = None):
+    """
+    Convert C array to Go slice using the method
+    described here:
+
+    https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices
+    """
+    s = ''
+
+    gotypename = xenlight_golang_fmt_name(ty.type.elem_type.typename)
+    goname     = xenlight_golang_fmt_name(ty.name)
+    ctypename  = ty.type.elem_type.typename
+    cname      = ty.name
+    cslice     = 'c{}'.format(goname)
+    clenvar    = ty.type.lenvar.name
+    golenvar   = xenlight_golang_fmt_name(clenvar,exported=False)
+
+    s += '{} := int(xc.{})\n'.format(golenvar, clenvar)
+    s += '{} := '.format(cslice)
+    s +='(*[1<<28]C.{})(unsafe.Pointer(xc.{}))[:{}:{}]\n'.format(ctypename, cname,
+                                                                golenvar, golenvar)
+    s += 'x.{} = make([]{}, {})\n'.format(goname, gotypename, golenvar)
+    s += 'for i, v := range {} {{\n'.format(cslice)
+
+    is_enum = isinstance(ty.type.elem_type,idl.Enumeration)
+    if gotypename in go_builtin_types or is_enum:
+        s += 'x.{}[i] = {}(v)\n'.format(goname, gotypename)
+    else:
+        s += 'var e {}\n'.format(gotypename)
+        s += 'if err := e.fromC(&v); err != nil {\n'
+        s += 'return err }\n'
+        s += 'x.{}[i] = e\n'.format(goname)
+
+    s += '}\n'
+
+    return s
+
 def xenlight_golang_fmt_name(name, exported = True):
     """
     Take a given type name and return an
diff --git a/tools/golang/xenlight/xenlight_helpers.go b/tools/golang/xenlight/xenlight_helpers.go
index b8abef8068..2cdc1bbdc9 100644
--- a/tools/golang/xenlight/xenlight_helpers.go
+++ b/tools/golang/xenlight/xenlight_helpers.go
@@ -382,6 +382,16 @@ func (x *SchedParams) fromC(xc *C.libxl_sched_params) error {
 
 func (x *VcpuSchedParams) fromC(xc *C.libxl_vcpu_sched_params) error {
 	x.Sched = Scheduler(xc.sched)
+	numVcpus := int(xc.num_vcpus)
+	cVcpus := (*[1 << 28]C.libxl_sched_params)(unsafe.Pointer(xc.vcpus))[:numVcpus:numVcpus]
+	x.Vcpus = make([]SchedParams, numVcpus)
+	for i, v := range cVcpus {
+		var e SchedParams
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Vcpus[i] = e
+	}
 	return nil
 }
 
@@ -399,6 +409,12 @@ func (x *DomainSchedParams) fromC(xc *C.libxl_domain_sched_params) error {
 
 func (x *VnodeInfo) fromC(xc *C.libxl_vnode_info) error {
 	x.Memkb = uint64(xc.memkb)
+	numDistances := int(xc.num_distances)
+	cDistances := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.distances))[:numDistances:numDistances]
+	x.Distances = make([]uint32, numDistances)
+	for i, v := range cDistances {
+		x.Distances[i] = uint32(v)
+	}
 	x.Pnode = uint32(xc.pnode)
 	var bitmapVcpus Bitmap
 	if err := bitmapVcpus.fromC(&xc.vcpus); err != nil {
@@ -431,6 +447,26 @@ func (x *DomainBuildInfo) fromC(xc *C.libxl_domain_build_info) error {
 		return err
 	}
 	x.Nodemap = bitmapNodemap
+	numVcpuHardAffinity := int(xc.num_vcpu_hard_affinity)
+	cVcpuHardAffinity := (*[1 << 28]C.libxl_bitmap)(unsafe.Pointer(xc.vcpu_hard_affinity))[:numVcpuHardAffinity:numVcpuHardAffinity]
+	x.VcpuHardAffinity = make([]Bitmap, numVcpuHardAffinity)
+	for i, v := range cVcpuHardAffinity {
+		var e Bitmap
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.VcpuHardAffinity[i] = e
+	}
+	numVcpuSoftAffinity := int(xc.num_vcpu_soft_affinity)
+	cVcpuSoftAffinity := (*[1 << 28]C.libxl_bitmap)(unsafe.Pointer(xc.vcpu_soft_affinity))[:numVcpuSoftAffinity:numVcpuSoftAffinity]
+	x.VcpuSoftAffinity = make([]Bitmap, numVcpuSoftAffinity)
+	for i, v := range cVcpuSoftAffinity {
+		var e Bitmap
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.VcpuSoftAffinity[i] = e
+	}
 	var defboolNumaPlacement Defbool
 	if err := defboolNumaPlacement.fromC(&xc.numa_placement); err != nil {
 		return err
@@ -460,6 +496,16 @@ func (x *DomainBuildInfo) fromC(xc *C.libxl_domain_build_info) error {
 	}
 	x.Cpuid = cpuidPolicyListCpuid
 	x.BlkdevStart = C.GoString(xc.blkdev_start)
+	numVnumaNodes := int(xc.num_vnuma_nodes)
+	cVnumaNodes := (*[1 << 28]C.libxl_vnode_info)(unsafe.Pointer(xc.vnuma_nodes))[:numVnumaNodes:numVnumaNodes]
+	x.VnumaNodes = make([]VnodeInfo, numVnumaNodes)
+	for i, v := range cVnumaNodes {
+		var e VnodeInfo
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.VnumaNodes[i] = e
+	}
 	x.MaxGrantFrames = uint32(xc.max_grant_frames)
 	x.MaxMaptrackFrames = uint32(xc.max_maptrack_frames)
 	x.DeviceModelVersion = DeviceModelVersion(xc.device_model_version)
@@ -492,6 +538,32 @@ func (x *DomainBuildInfo) fromC(xc *C.libxl_domain_build_info) error {
 		return err
 	}
 	x.SchedParams = domainSchedParamsSchedParams
+	numIoports := int(xc.num_ioports)
+	cIoports := (*[1 << 28]C.libxl_ioport_range)(unsafe.Pointer(xc.ioports))[:numIoports:numIoports]
+	x.Ioports = make([]IoportRange, numIoports)
+	for i, v := range cIoports {
+		var e IoportRange
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Ioports[i] = e
+	}
+	numIrqs := int(xc.num_irqs)
+	cIrqs := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.irqs))[:numIrqs:numIrqs]
+	x.Irqs = make([]uint32, numIrqs)
+	for i, v := range cIrqs {
+		x.Irqs[i] = uint32(v)
+	}
+	numIomem := int(xc.num_iomem)
+	cIomem := (*[1 << 28]C.libxl_iomem_range)(unsafe.Pointer(xc.iomem))[:numIomem:numIomem]
+	x.Iomem = make([]IomemRange, numIomem)
+	for i, v := range cIomem {
+		var e IomemRange
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Iomem[i] = e
+	}
 	var defboolClaimMode Defbool
 	if err := defboolClaimMode.fromC(&xc.claim_mode); err != nil {
 		return err
@@ -982,10 +1054,32 @@ func (x *DeviceVdispl) fromC(xc *C.libxl_device_vdispl) error {
 	x.BackendDomname = C.GoString(xc.backend_domname)
 	x.Devid = Devid(xc.devid)
 	x.BeAlloc = bool(xc.be_alloc)
+	numConnectors := int(xc.num_connectors)
+	cConnectors := (*[1 << 28]C.libxl_connector_param)(unsafe.Pointer(xc.connectors))[:numConnectors:numConnectors]
+	x.Connectors = make([]ConnectorParam, numConnectors)
+	for i, v := range cConnectors {
+		var e ConnectorParam
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Connectors[i] = e
+	}
 	return nil
 }
 
 func (x *VsndParams) fromC(xc *C.libxl_vsnd_params) error {
+	numSampleRates := int(xc.num_sample_rates)
+	cSampleRates := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.sample_rates))[:numSampleRates:numSampleRates]
+	x.SampleRates = make([]uint32, numSampleRates)
+	for i, v := range cSampleRates {
+		x.SampleRates[i] = uint32(v)
+	}
+	numSampleFormats := int(xc.num_sample_formats)
+	cSampleFormats := (*[1 << 28]C.libxl_vsnd_pcm_format)(unsafe.Pointer(xc.sample_formats))[:numSampleFormats:numSampleFormats]
+	x.SampleFormats = make([]VsndPcmFormat, numSampleFormats)
+	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)
@@ -1010,6 +1104,16 @@ func (x *VsndPcm) fromC(xc *C.libxl_vsnd_pcm) error {
 		return err
 	}
 	x.Params = vsndParamsParams
+	numVsndStreams := int(xc.num_vsnd_streams)
+	cStreams := (*[1 << 28]C.libxl_vsnd_stream)(unsafe.Pointer(xc.streams))[:numVsndStreams:numVsndStreams]
+	x.Streams = make([]VsndStream, numVsndStreams)
+	for i, v := range cStreams {
+		var e VsndStream
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Streams[i] = e
+	}
 	return nil
 }
 
@@ -1024,6 +1128,16 @@ func (x *DeviceVsnd) fromC(xc *C.libxl_device_vsnd) error {
 		return err
 	}
 	x.Params = vsndParamsParams
+	numVsndPcms := int(xc.num_vsnd_pcms)
+	cPcms := (*[1 << 28]C.libxl_vsnd_pcm)(unsafe.Pointer(xc.pcms))[:numVsndPcms:numVsndPcms]
+	x.Pcms = make([]VsndPcm, numVsndPcms)
+	for i, v := range cPcms {
+		var e VsndPcm
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Pcms[i] = e
+	}
 	return nil
 }
 
@@ -1038,6 +1152,156 @@ func (x *DomainConfig) fromC(xc *C.libxl_domain_config) error {
 		return err
 	}
 	x.BInfo = domainBuildInfoBInfo
+	numDisks := int(xc.num_disks)
+	cDisks := (*[1 << 28]C.libxl_device_disk)(unsafe.Pointer(xc.disks))[:numDisks:numDisks]
+	x.Disks = make([]DeviceDisk, numDisks)
+	for i, v := range cDisks {
+		var e DeviceDisk
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Disks[i] = e
+	}
+	numNics := int(xc.num_nics)
+	cNics := (*[1 << 28]C.libxl_device_nic)(unsafe.Pointer(xc.nics))[:numNics:numNics]
+	x.Nics = make([]DeviceNic, numNics)
+	for i, v := range cNics {
+		var e DeviceNic
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Nics[i] = e
+	}
+	numPcidevs := int(xc.num_pcidevs)
+	cPcidevs := (*[1 << 28]C.libxl_device_pci)(unsafe.Pointer(xc.pcidevs))[:numPcidevs:numPcidevs]
+	x.Pcidevs = make([]DevicePci, numPcidevs)
+	for i, v := range cPcidevs {
+		var e DevicePci
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Pcidevs[i] = e
+	}
+	numRdms := int(xc.num_rdms)
+	cRdms := (*[1 << 28]C.libxl_device_rdm)(unsafe.Pointer(xc.rdms))[:numRdms:numRdms]
+	x.Rdms = make([]DeviceRdm, numRdms)
+	for i, v := range cRdms {
+		var e DeviceRdm
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Rdms[i] = e
+	}
+	numDtdevs := int(xc.num_dtdevs)
+	cDtdevs := (*[1 << 28]C.libxl_device_dtdev)(unsafe.Pointer(xc.dtdevs))[:numDtdevs:numDtdevs]
+	x.Dtdevs = make([]DeviceDtdev, numDtdevs)
+	for i, v := range cDtdevs {
+		var e DeviceDtdev
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Dtdevs[i] = e
+	}
+	numVfbs := int(xc.num_vfbs)
+	cVfbs := (*[1 << 28]C.libxl_device_vfb)(unsafe.Pointer(xc.vfbs))[:numVfbs:numVfbs]
+	x.Vfbs = make([]DeviceVfb, numVfbs)
+	for i, v := range cVfbs {
+		var e DeviceVfb
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Vfbs[i] = e
+	}
+	numVkbs := int(xc.num_vkbs)
+	cVkbs := (*[1 << 28]C.libxl_device_vkb)(unsafe.Pointer(xc.vkbs))[:numVkbs:numVkbs]
+	x.Vkbs = make([]DeviceVkb, numVkbs)
+	for i, v := range cVkbs {
+		var e DeviceVkb
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Vkbs[i] = e
+	}
+	numVtpms := int(xc.num_vtpms)
+	cVtpms := (*[1 << 28]C.libxl_device_vtpm)(unsafe.Pointer(xc.vtpms))[:numVtpms:numVtpms]
+	x.Vtpms = make([]DeviceVtpm, numVtpms)
+	for i, v := range cVtpms {
+		var e DeviceVtpm
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Vtpms[i] = e
+	}
+	numP9S := int(xc.num_p9s)
+	cP9S := (*[1 << 28]C.libxl_device_p9)(unsafe.Pointer(xc.p9s))[:numP9S:numP9S]
+	x.P9S = make([]DeviceP9, numP9S)
+	for i, v := range cP9S {
+		var e DeviceP9
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.P9S[i] = e
+	}
+	numPvcallsifs := int(xc.num_pvcallsifs)
+	cPvcallsifs := (*[1 << 28]C.libxl_device_pvcallsif)(unsafe.Pointer(xc.pvcallsifs))[:numPvcallsifs:numPvcallsifs]
+	x.Pvcallsifs = make([]DevicePvcallsif, numPvcallsifs)
+	for i, v := range cPvcallsifs {
+		var e DevicePvcallsif
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Pvcallsifs[i] = e
+	}
+	numVdispls := int(xc.num_vdispls)
+	cVdispls := (*[1 << 28]C.libxl_device_vdispl)(unsafe.Pointer(xc.vdispls))[:numVdispls:numVdispls]
+	x.Vdispls = make([]DeviceVdispl, numVdispls)
+	for i, v := range cVdispls {
+		var e DeviceVdispl
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Vdispls[i] = e
+	}
+	numVsnds := int(xc.num_vsnds)
+	cVsnds := (*[1 << 28]C.libxl_device_vsnd)(unsafe.Pointer(xc.vsnds))[:numVsnds:numVsnds]
+	x.Vsnds = make([]DeviceVsnd, numVsnds)
+	for i, v := range cVsnds {
+		var e DeviceVsnd
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Vsnds[i] = e
+	}
+	numChannels := int(xc.num_channels)
+	cChannels := (*[1 << 28]C.libxl_device_channel)(unsafe.Pointer(xc.channels))[:numChannels:numChannels]
+	x.Channels = make([]DeviceChannel, numChannels)
+	for i, v := range cChannels {
+		var e DeviceChannel
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Channels[i] = e
+	}
+	numUsbctrls := int(xc.num_usbctrls)
+	cUsbctrls := (*[1 << 28]C.libxl_device_usbctrl)(unsafe.Pointer(xc.usbctrls))[:numUsbctrls:numUsbctrls]
+	x.Usbctrls = make([]DeviceUsbctrl, numUsbctrls)
+	for i, v := range cUsbctrls {
+		var e DeviceUsbctrl
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Usbctrls[i] = e
+	}
+	numUsbdevs := int(xc.num_usbdevs)
+	cUsbdevs := (*[1 << 28]C.libxl_device_usbdev)(unsafe.Pointer(xc.usbdevs))[:numUsbdevs:numUsbdevs]
+	x.Usbdevs = make([]DeviceUsbdev, numUsbdevs)
+	for i, v := range cUsbdevs {
+		var e DeviceUsbdev
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Usbdevs[i] = e
+	}
 	x.OnPoweroff = ActionOnShutdown(xc.on_poweroff)
 	x.OnReboot = ActionOnShutdown(xc.on_reboot)
 	x.OnWatchdog = ActionOnShutdown(xc.on_watchdog)
@@ -1171,6 +1435,16 @@ func (x *Vdisplinfo) fromC(xc *C.libxl_vdisplinfo) error {
 	x.Devid = Devid(xc.devid)
 	x.State = int(xc.state)
 	x.BeAlloc = bool(xc.be_alloc)
+	numConnectors := int(xc.num_connectors)
+	cConnectors := (*[1 << 28]C.libxl_connectorinfo)(unsafe.Pointer(xc.connectors))[:numConnectors:numConnectors]
+	x.Connectors = make([]Connectorinfo, numConnectors)
+	for i, v := range cConnectors {
+		var e Connectorinfo
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Connectors[i] = e
+	}
 	return nil
 }
 
@@ -1181,6 +1455,16 @@ func (x *Streaminfo) fromC(xc *C.libxl_streaminfo) error {
 }
 
 func (x *Pcminfo) fromC(xc *C.libxl_pcminfo) error {
+	numVsndStreams := int(xc.num_vsnd_streams)
+	cStreams := (*[1 << 28]C.libxl_streaminfo)(unsafe.Pointer(xc.streams))[:numVsndStreams:numVsndStreams]
+	x.Streams = make([]Streaminfo, numVsndStreams)
+	for i, v := range cStreams {
+		var e Streaminfo
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Streams[i] = e
+	}
 	return nil
 }
 
@@ -1191,6 +1475,16 @@ func (x *Vsndinfo) fromC(xc *C.libxl_vsndinfo) error {
 	x.FrontendId = uint32(xc.frontend_id)
 	x.Devid = Devid(xc.devid)
 	x.State = int(xc.state)
+	numVsndPcms := int(xc.num_vsnd_pcms)
+	cPcms := (*[1 << 28]C.libxl_pcminfo)(unsafe.Pointer(xc.pcms))[:numVsndPcms:numVsndPcms]
+	x.Pcms = make([]Pcminfo, numVsndPcms)
+	for i, v := range cPcms {
+		var e Pcminfo
+		if err := e.fromC(&v); err != nil {
+			return err
+		}
+		x.Pcms[i] = e
+	}
 	return nil
 }
 
@@ -1209,6 +1503,12 @@ func (x *Vkbinfo) fromC(xc *C.libxl_vkbinfo) error {
 func (x *Numainfo) fromC(xc *C.libxl_numainfo) error {
 	x.Size = uint64(xc.size)
 	x.Free = uint64(xc.free)
+	numDists := int(xc.num_dists)
+	cDists := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.dists))[:numDists:numDists]
+	x.Dists = make([]uint32, numDists)
+	for i, v := range cDists {
+		x.Dists[i] = uint32(v)
+	}
 	return nil
 }
 
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 19/24] golang/xenlight: begin Go to C type marshaling
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (17 preceding siblings ...)
  2019-10-07 15:13 ` [Xen-devel] [PATCH 18/24] golang/xenlight: implement array " Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-10-07 15:13 ` [Xen-devel] [PATCH 20/24] golang/xenlight: implement keyed union Go to C marshaling Nick Rosbrook
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Implement conversion of basic type conversions such as strings
and integer types in toC functions.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/gengotypes.py       |   80 ++
 tools/golang/xenlight/xenlight_helpers.go | 1013 +++++++++++++++++++++
 2 files changed, 1093 insertions(+)

diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
index 2b620f0ae9..eccc334b41 100644
--- a/tools/golang/xenlight/gengotypes.py
+++ b/tools/golang/xenlight/gengotypes.py
@@ -237,6 +237,9 @@ def xenlight_golang_generate_helpers(path = None, types = None, comment = None):
 
             del helper_extras[:]
 
+            f.write(xenlight_golang_define_to_C(ty))
+            f.write('\n')
+
     go_fmt(path)
 
 def xenlight_golang_define_from_C(ty = None, typename = None, nested = False):
@@ -457,6 +460,83 @@ def xenlight_golang_array_from_C(ty = None):
 
     return s
 
+def xenlight_golang_define_to_C(ty = None, typename = None, nested = False):
+    s = ''
+
+    gotypename = ctypename = ''
+
+    if typename is not None:
+        gotypename = xenlight_golang_fmt_name(typename)
+        ctypename  = typename
+    else:
+        gotypename = xenlight_golang_fmt_name(ty.typename)
+        ctypename  = ty.typename
+
+    if not nested:
+        s += 'func (x *{}) toC() (xc C.{},err error) {{\n'.format(gotypename,ctypename)
+        s += 'C.{}(&xc)\n'.format(ty.init_fn)
+
+    for f in ty.fields:
+        if f.type.typename is not None:
+            if isinstance(f.type, idl.Array):
+                # TODO
+                continue
+
+            gotypename = xenlight_golang_fmt_name(f.type.typename)
+            ctypename  = f.type.typename
+            gofname    = xenlight_golang_fmt_name(f.name)
+            cfname     = f.name
+
+            # In cgo, C names that conflict with Go keywords can be
+            # accessed by prepending an underscore to the name.
+            if cfname in go_keywords:
+                cfname = '_' + cfname
+
+            # If this is nested, we need the outer name too.
+            if nested and typename is not None:
+                goname = xenlight_golang_fmt_name(typename)
+                goname = '{}.{}'.format(goname, gofname)
+                cname  = '{}.{}'.format(typename, cfname)
+
+            else:
+                goname = gofname
+                cname  = cfname
+
+            is_castable = (f.type.json_parse_type == 'JSON_INTEGER' or
+                           isinstance(f.type, idl.Enumeration) or
+                           gotypename in go_builtin_types)
+
+            if is_castable:
+                # Use the cgo helper for converting C strings.
+                if gotypename == 'string':
+                    s += 'xc.{} = C.CString(x.{})\n'.format(cname,goname)
+                    continue
+
+                s += 'xc.{} = C.{}(x.{})\n'.format(cname,ctypename,goname)
+
+            else:
+                s += 'xc.{}, err = x.{}.toC()\n'.format(cname,goname)
+                s += 'if err != nil {\n'
+                s += 'C.{}(&xc)\n'.format(ty.dispose_fn)
+                s += 'return xc, err\n'
+                s += '}\n'
+
+        elif isinstance(f.type, idl.Struct):
+            s += xenlight_golang_define_to_C(f.type, typename=f.name, nested=True)
+
+        elif isinstance(f.type, idl.KeyedUnion):
+            # TODO
+            pass
+
+        else:
+            raise Exception('type {} not supported'.format(f.type))
+
+    if not nested:
+        s += 'return xc, nil'
+        s += '}\n'
+
+    return s
+
 def xenlight_golang_fmt_name(name, exported = True):
     """
     Take a given type name and return an
diff --git a/tools/golang/xenlight/xenlight_helpers.go b/tools/golang/xenlight/xenlight_helpers.go
index 2cdc1bbdc9..92e6afcd10 100644
--- a/tools/golang/xenlight/xenlight_helpers.go
+++ b/tools/golang/xenlight/xenlight_helpers.go
@@ -130,6 +130,13 @@ func (x *IoportRange) fromC(xc *C.libxl_ioport_range) error {
 	return nil
 }
 
+func (x *IoportRange) toC() (xc C.libxl_ioport_range, err error) {
+	C.libxl_ioport_range_init(&xc)
+	xc.first = C.uint32_t(x.First)
+	xc.number = C.uint32_t(x.Number)
+	return xc, nil
+}
+
 func (x *IomemRange) fromC(xc *C.libxl_iomem_range) error {
 	x.Start = uint64(xc.start)
 	x.Number = uint64(xc.number)
@@ -137,11 +144,25 @@ func (x *IomemRange) fromC(xc *C.libxl_iomem_range) error {
 	return nil
 }
 
+func (x *IomemRange) toC() (xc C.libxl_iomem_range, err error) {
+	C.libxl_iomem_range_init(&xc)
+	xc.start = C.uint64_t(x.Start)
+	xc.number = C.uint64_t(x.Number)
+	xc.gfn = C.uint64_t(x.Gfn)
+	return xc, 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) {
+	C.libxl_vga_interface_info_init(&xc)
+	xc.kind = C.libxl_vga_interface_type(x.Kind)
+	return xc, nil
+}
+
 func (x *VncInfo) fromC(xc *C.libxl_vnc_info) error {
 	var defboolEnable Defbool
 	if err := defboolEnable.fromC(&xc.enable); err != nil {
@@ -159,6 +180,24 @@ func (x *VncInfo) fromC(xc *C.libxl_vnc_info) error {
 	return nil
 }
 
+func (x *VncInfo) toC() (xc C.libxl_vnc_info, err error) {
+	C.libxl_vnc_info_init(&xc)
+	xc.enable, err = x.Enable.toC()
+	if err != nil {
+		C.libxl_vnc_info_dispose(&xc)
+		return xc, err
+	}
+	xc.listen = C.CString(x.Listen)
+	xc.passwd = C.CString(x.Passwd)
+	xc.display = C.int(x.Display)
+	xc.findunused, err = x.Findunused.toC()
+	if err != nil {
+		C.libxl_vnc_info_dispose(&xc)
+		return xc, err
+	}
+	return xc, nil
+}
+
 func (x *SpiceInfo) fromC(xc *C.libxl_spice_info) error {
 	var defboolEnable Defbool
 	if err := defboolEnable.fromC(&xc.enable); err != nil {
@@ -195,6 +234,43 @@ func (x *SpiceInfo) fromC(xc *C.libxl_spice_info) error {
 	return nil
 }
 
+func (x *SpiceInfo) toC() (xc C.libxl_spice_info, err error) {
+	C.libxl_spice_info_init(&xc)
+	xc.enable, err = x.Enable.toC()
+	if err != nil {
+		C.libxl_spice_info_dispose(&xc)
+		return xc, err
+	}
+	xc.port = C.int(x.Port)
+	xc.tls_port = C.int(x.TlsPort)
+	xc.host = C.CString(x.Host)
+	xc.disable_ticketing, err = x.DisableTicketing.toC()
+	if err != nil {
+		C.libxl_spice_info_dispose(&xc)
+		return xc, err
+	}
+	xc.passwd = C.CString(x.Passwd)
+	xc.agent_mouse, err = x.AgentMouse.toC()
+	if err != nil {
+		C.libxl_spice_info_dispose(&xc)
+		return xc, err
+	}
+	xc.vdagent, err = x.Vdagent.toC()
+	if err != nil {
+		C.libxl_spice_info_dispose(&xc)
+		return xc, err
+	}
+	xc.clipboard_sharing, err = x.ClipboardSharing.toC()
+	if err != nil {
+		C.libxl_spice_info_dispose(&xc)
+		return xc, err
+	}
+	xc.usbredirection = C.int(x.Usbredirection)
+	xc.image_compression = C.CString(x.ImageCompression)
+	xc.streaming_video = C.CString(x.StreamingVideo)
+	return xc, nil
+}
+
 func (x *SdlInfo) fromC(xc *C.libxl_sdl_info) error {
 	var defboolEnable Defbool
 	if err := defboolEnable.fromC(&xc.enable); err != nil {
@@ -211,6 +287,23 @@ func (x *SdlInfo) fromC(xc *C.libxl_sdl_info) error {
 	return nil
 }
 
+func (x *SdlInfo) toC() (xc C.libxl_sdl_info, err error) {
+	C.libxl_sdl_info_init(&xc)
+	xc.enable, err = x.Enable.toC()
+	if err != nil {
+		C.libxl_sdl_info_dispose(&xc)
+		return xc, err
+	}
+	xc.opengl, err = x.Opengl.toC()
+	if err != nil {
+		C.libxl_sdl_info_dispose(&xc)
+		return xc, err
+	}
+	xc.display = C.CString(x.Display)
+	xc.xauthority = C.CString(x.Xauthority)
+	return xc, nil
+}
+
 func (x *Dominfo) fromC(xc *C.libxl_dominfo) error {
 	var uuidUuid Uuid
 	if err := uuidUuid.fromC(&xc.uuid); err != nil {
@@ -240,6 +333,36 @@ func (x *Dominfo) fromC(xc *C.libxl_dominfo) error {
 	return nil
 }
 
+func (x *Dominfo) toC() (xc C.libxl_dominfo, err error) {
+	C.libxl_dominfo_init(&xc)
+	xc.uuid, err = x.Uuid.toC()
+	if err != nil {
+		C.libxl_dominfo_dispose(&xc)
+		return xc, err
+	}
+	xc.domid = C.libxl_domid(x.Domid)
+	xc.ssidref = C.uint32_t(x.Ssidref)
+	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 xc, nil
+}
+
 func (x *Cpupoolinfo) fromC(xc *C.libxl_cpupoolinfo) error {
 	x.Poolid = uint32(xc.poolid)
 	x.PoolName = C.GoString(xc.pool_name)
@@ -253,6 +376,20 @@ func (x *Cpupoolinfo) fromC(xc *C.libxl_cpupoolinfo) error {
 	return nil
 }
 
+func (x *Cpupoolinfo) toC() (xc C.libxl_cpupoolinfo, err error) {
+	C.libxl_cpupoolinfo_init(&xc)
+	xc.poolid = C.uint32_t(x.Poolid)
+	xc.pool_name = C.CString(x.PoolName)
+	xc.sched = C.libxl_scheduler(x.Sched)
+	xc.n_dom = C.uint32_t(x.NDom)
+	xc.cpumap, err = x.Cpumap.toC()
+	if err != nil {
+		C.libxl_cpupoolinfo_dispose(&xc)
+		return xc, err
+	}
+	return xc, nil
+}
+
 func (x *Channelinfo) fromC(xc *C.libxl_channelinfo) error {
 	x.Backend = C.GoString(xc.backend)
 	x.BackendId = uint32(xc.backend_id)
@@ -286,6 +423,19 @@ func (x *ChannelinfoConnectionUnionPty) fromC(xc *C.libxl_channelinfo) error {
 	return nil
 }
 
+func (x *Channelinfo) toC() (xc C.libxl_channelinfo, err error) {
+	C.libxl_channelinfo_init(&xc)
+	xc.backend = C.CString(x.Backend)
+	xc.backend_id = C.uint32_t(x.BackendId)
+	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 xc, nil
+}
+
 func (x *Vminfo) fromC(xc *C.libxl_vminfo) error {
 	var uuidUuid Uuid
 	if err := uuidUuid.fromC(&xc.uuid); err != nil {
@@ -296,6 +446,17 @@ func (x *Vminfo) fromC(xc *C.libxl_vminfo) error {
 	return nil
 }
 
+func (x *Vminfo) toC() (xc C.libxl_vminfo, err error) {
+	C.libxl_vminfo_init(&xc)
+	xc.uuid, err = x.Uuid.toC()
+	if err != nil {
+		C.libxl_vminfo_dispose(&xc)
+		return xc, err
+	}
+	xc.domid = C.libxl_domid(x.Domid)
+	return xc, 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)
@@ -313,6 +474,24 @@ func (x *VersionInfo) fromC(xc *C.libxl_version_info) error {
 	return nil
 }
 
+func (x *VersionInfo) toC() (xc C.libxl_version_info, err error) {
+	C.libxl_version_info_init(&xc)
+	xc.xen_version_major = C.int(x.XenVersionMajor)
+	xc.xen_version_minor = C.int(x.XenVersionMinor)
+	xc.xen_version_extra = C.CString(x.XenVersionExtra)
+	xc.compiler = C.CString(x.Compiler)
+	xc.compile_by = C.CString(x.CompileBy)
+	xc.compile_domain = C.CString(x.CompileDomain)
+	xc.compile_date = C.CString(x.CompileDate)
+	xc.capabilities = C.CString(x.Capabilities)
+	xc.changeset = C.CString(x.Changeset)
+	xc.virt_start = C.uint64_t(x.VirtStart)
+	xc.pagesize = C.int(x.Pagesize)
+	xc.commandline = C.CString(x.Commandline)
+	xc.build_id = C.CString(x.BuildId)
+	return xc, nil
+}
+
 func (x *DomainCreateInfo) fromC(xc *C.libxl_domain_create_info) error {
 	x.Type = DomainType(xc._type)
 	var defboolHap Defbool
@@ -358,6 +537,52 @@ func (x *DomainCreateInfo) fromC(xc *C.libxl_domain_create_info) error {
 	return nil
 }
 
+func (x *DomainCreateInfo) toC() (xc C.libxl_domain_create_info, err error) {
+	C.libxl_domain_create_info_init(&xc)
+	xc._type = C.libxl_domain_type(x.Type)
+	xc.hap, err = x.Hap.toC()
+	if err != nil {
+		C.libxl_domain_create_info_dispose(&xc)
+		return xc, err
+	}
+	xc.oos, err = x.Oos.toC()
+	if err != nil {
+		C.libxl_domain_create_info_dispose(&xc)
+		return xc, err
+	}
+	xc.ssidref = C.uint32_t(x.Ssidref)
+	xc.ssid_label = C.CString(x.SsidLabel)
+	xc.name = C.CString(x.Name)
+	xc.uuid, err = x.Uuid.toC()
+	if err != nil {
+		C.libxl_domain_create_info_dispose(&xc)
+		return xc, err
+	}
+	xc.xsdata, err = x.Xsdata.toC()
+	if err != nil {
+		C.libxl_domain_create_info_dispose(&xc)
+		return xc, err
+	}
+	xc.platformdata, err = x.Platformdata.toC()
+	if err != nil {
+		C.libxl_domain_create_info_dispose(&xc)
+		return xc, err
+	}
+	xc.poolid = C.uint32_t(x.Poolid)
+	xc.pool_name = C.CString(x.PoolName)
+	xc.run_hotplug_scripts, err = x.RunHotplugScripts.toC()
+	if err != nil {
+		C.libxl_domain_create_info_dispose(&xc)
+		return xc, err
+	}
+	xc.driver_domain, err = x.DriverDomain.toC()
+	if err != nil {
+		C.libxl_domain_create_info_dispose(&xc)
+		return xc, err
+	}
+	return xc, nil
+}
+
 func (x *DomainRestoreParams) fromC(xc *C.libxl_domain_restore_params) error {
 	x.CheckpointedStream = int(xc.checkpointed_stream)
 	x.StreamVersion = uint32(xc.stream_version)
@@ -370,6 +595,19 @@ func (x *DomainRestoreParams) fromC(xc *C.libxl_domain_restore_params) error {
 	return nil
 }
 
+func (x *DomainRestoreParams) toC() (xc C.libxl_domain_restore_params, err error) {
+	C.libxl_domain_restore_params_init(&xc)
+	xc.checkpointed_stream = C.int(x.CheckpointedStream)
+	xc.stream_version = C.uint32_t(x.StreamVersion)
+	xc.colo_proxy_script = C.CString(x.ColoProxyScript)
+	xc.userspace_colo_proxy, err = x.UserspaceColoProxy.toC()
+	if err != nil {
+		C.libxl_domain_restore_params_dispose(&xc)
+		return xc, err
+	}
+	return xc, nil
+}
+
 func (x *SchedParams) fromC(xc *C.libxl_sched_params) error {
 	x.Vcpuid = int(xc.vcpuid)
 	x.Weight = int(xc.weight)
@@ -380,6 +618,17 @@ func (x *SchedParams) fromC(xc *C.libxl_sched_params) error {
 	return nil
 }
 
+func (x *SchedParams) toC() (xc C.libxl_sched_params, err error) {
+	C.libxl_sched_params_init(&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 xc, nil
+}
+
 func (x *VcpuSchedParams) fromC(xc *C.libxl_vcpu_sched_params) error {
 	x.Sched = Scheduler(xc.sched)
 	numVcpus := int(xc.num_vcpus)
@@ -395,6 +644,12 @@ func (x *VcpuSchedParams) fromC(xc *C.libxl_vcpu_sched_params) error {
 	return nil
 }
 
+func (x *VcpuSchedParams) toC() (xc C.libxl_vcpu_sched_params, err error) {
+	C.libxl_vcpu_sched_params_init(&xc)
+	xc.sched = C.libxl_scheduler(x.Sched)
+	return xc, nil
+}
+
 func (x *DomainSchedParams) fromC(xc *C.libxl_domain_sched_params) error {
 	x.Sched = Scheduler(xc.sched)
 	x.Weight = int(xc.weight)
@@ -407,6 +662,19 @@ func (x *DomainSchedParams) fromC(xc *C.libxl_domain_sched_params) error {
 	return nil
 }
 
+func (x *DomainSchedParams) toC() (xc C.libxl_domain_sched_params, err error) {
+	C.libxl_domain_sched_params_init(&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 xc, nil
+}
+
 func (x *VnodeInfo) fromC(xc *C.libxl_vnode_info) error {
 	x.Memkb = uint64(xc.memkb)
 	numDistances := int(xc.num_distances)
@@ -424,12 +692,31 @@ func (x *VnodeInfo) fromC(xc *C.libxl_vnode_info) error {
 	return nil
 }
 
+func (x *VnodeInfo) toC() (xc C.libxl_vnode_info, err error) {
+	C.libxl_vnode_info_init(&xc)
+	xc.memkb = C.uint64_t(x.Memkb)
+	xc.pnode = C.uint32_t(x.Pnode)
+	xc.vcpus, err = x.Vcpus.toC()
+	if err != nil {
+		C.libxl_vnode_info_dispose(&xc)
+		return xc, err
+	}
+	return xc, 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) {
+	C.libxl_rdm_reserve_init(&xc)
+	xc.strategy = C.libxl_rdm_reserve_strategy(x.Strategy)
+	xc.policy = C.libxl_rdm_reserve_policy(x.Policy)
+	return xc, nil
+}
+
 func (x *DomainBuildInfo) fromC(xc *C.libxl_domain_build_info) error {
 	x.MaxVcpus = int(xc.max_vcpus)
 	var bitmapAvailVcpus Bitmap
@@ -776,6 +1063,129 @@ func (x *DomainBuildInfoTypeUnionPvh) fromC(xc *C.libxl_domain_build_info) error
 	return nil
 }
 
+func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
+	C.libxl_domain_build_info_init(&xc)
+	xc.max_vcpus = C.int(x.MaxVcpus)
+	xc.avail_vcpus, err = x.AvailVcpus.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.cpumap, err = x.Cpumap.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.nodemap, err = x.Nodemap.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.numa_placement, err = x.NumaPlacement.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, 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.rtc_timeoffset = C.uint32_t(x.RtcTimeoffset)
+	xc.exec_ssidref = C.uint32_t(x.ExecSsidref)
+	xc.exec_ssid_label = C.CString(x.ExecSsidLabel)
+	xc.localtime, err = x.Localtime.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.disable_migrate, err = x.DisableMigrate.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.cpuid, err = x.Cpuid.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.blkdev_start = C.CString(x.BlkdevStart)
+	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)
+	xc.device_model_stubdomain, err = x.DeviceModelStubdomain.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.device_model = C.CString(x.DeviceModel)
+	xc.device_model_ssidref = C.uint32_t(x.DeviceModelSsidref)
+	xc.device_model_ssid_label = C.CString(x.DeviceModelSsidLabel)
+	xc.device_model_user = C.CString(x.DeviceModelUser)
+	xc.extra, err = x.Extra.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.extra_pv, err = x.ExtraPv.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.extra_hvm, err = x.ExtraHvm.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.sched_params, err = x.SchedParams.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.claim_mode, err = x.ClaimMode.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.event_channels = C.uint32_t(x.EventChannels)
+	xc.kernel = C.CString(x.Kernel)
+	xc.cmdline = C.CString(x.Cmdline)
+	xc.ramdisk = C.CString(x.Ramdisk)
+	xc.device_tree = C.CString(x.DeviceTree)
+	xc.acpi, err = x.Acpi.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.bootloader = C.CString(x.Bootloader)
+	xc.bootloader_args, err = x.BootloaderArgs.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.timer_mode = C.libxl_timer_mode(x.TimerMode)
+	xc.nested_hvm, err = x.NestedHvm.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.apic, err = x.Apic.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.dm_restrict, err = x.DmRestrict.toC()
+	if err != nil {
+		C.libxl_domain_build_info_dispose(&xc)
+		return xc, err
+	}
+	xc.tee = C.libxl_tee_type(x.Tee)
+	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 xc, nil
+}
+
 func (x *DeviceVfb) fromC(xc *C.libxl_device_vfb) error {
 	x.BackendDomid = Domid(xc.backend_domid)
 	x.BackendDomname = C.GoString(xc.backend_domname)
@@ -794,6 +1204,25 @@ func (x *DeviceVfb) fromC(xc *C.libxl_device_vfb) error {
 	return nil
 }
 
+func (x *DeviceVfb) toC() (xc C.libxl_device_vfb, err error) {
+	C.libxl_device_vfb_init(&xc)
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	xc.backend_domname = C.CString(x.BackendDomname)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.vnc, err = x.Vnc.toC()
+	if err != nil {
+		C.libxl_device_vfb_dispose(&xc)
+		return xc, err
+	}
+	xc.sdl, err = x.Sdl.toC()
+	if err != nil {
+		C.libxl_device_vfb_dispose(&xc)
+		return xc, err
+	}
+	xc.keymap = C.CString(x.Keymap)
+	return xc, nil
+}
+
 func (x *DeviceVkb) fromC(xc *C.libxl_device_vkb) error {
 	x.BackendDomid = Domid(xc.backend_domid)
 	x.BackendDomname = C.GoString(xc.backend_domname)
@@ -813,6 +1242,26 @@ func (x *DeviceVkb) fromC(xc *C.libxl_device_vkb) error {
 	return nil
 }
 
+func (x *DeviceVkb) toC() (xc C.libxl_device_vkb, err error) {
+	C.libxl_device_vkb_init(&xc)
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	xc.backend_domname = C.CString(x.BackendDomname)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.backend_type = C.libxl_vkb_backend(x.BackendType)
+	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 xc, nil
+}
+
 func (x *DeviceDisk) fromC(xc *C.libxl_device_disk) error {
 	x.BackendDomid = Domid(xc.backend_domid)
 	x.BackendDomname = C.GoString(xc.backend_domname)
@@ -848,6 +1297,42 @@ func (x *DeviceDisk) fromC(xc *C.libxl_device_disk) error {
 	return nil
 }
 
+func (x *DeviceDisk) toC() (xc C.libxl_device_disk, err error) {
+	C.libxl_device_disk_init(&xc)
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	xc.backend_domname = C.CString(x.BackendDomname)
+	xc.pdev_path = C.CString(x.PdevPath)
+	xc.vdev = C.CString(x.Vdev)
+	xc.backend = C.libxl_disk_backend(x.Backend)
+	xc.format = C.libxl_disk_format(x.Format)
+	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)
+	xc.discard_enable, err = x.DiscardEnable.toC()
+	if err != nil {
+		C.libxl_device_disk_dispose(&xc)
+		return xc, err
+	}
+	xc.colo_enable, err = x.ColoEnable.toC()
+	if err != nil {
+		C.libxl_device_disk_dispose(&xc)
+		return xc, err
+	}
+	xc.colo_restore_enable, err = x.ColoRestoreEnable.toC()
+	if err != nil {
+		C.libxl_device_disk_dispose(&xc)
+		return xc, err
+	}
+	xc.colo_host = C.CString(x.ColoHost)
+	xc.colo_port = C.int(x.ColoPort)
+	xc.colo_export = C.CString(x.ColoExport)
+	xc.active_disk = C.CString(x.ActiveDisk)
+	xc.hidden_disk = C.CString(x.HiddenDisk)
+	return xc, nil
+}
+
 func (x *DeviceNic) fromC(xc *C.libxl_device_nic) error {
 	x.BackendDomid = Domid(xc.backend_domid)
 	x.BackendDomname = C.GoString(xc.backend_domname)
@@ -919,6 +1404,78 @@ func (x *DeviceNic) fromC(xc *C.libxl_device_nic) error {
 	return nil
 }
 
+func (x *DeviceNic) toC() (xc C.libxl_device_nic, err error) {
+	C.libxl_device_nic_init(&xc)
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	xc.backend_domname = C.CString(x.BackendDomname)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.mtu = C.int(x.Mtu)
+	xc.model = C.CString(x.Model)
+	xc.mac, err = x.Mac.toC()
+	if err != nil {
+		C.libxl_device_nic_dispose(&xc)
+		return xc, err
+	}
+	xc.ip = C.CString(x.Ip)
+	xc.bridge = C.CString(x.Bridge)
+	xc.ifname = C.CString(x.Ifname)
+	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)
+	xc.gatewaydev = C.CString(x.Gatewaydev)
+	xc.coloft_forwarddev = C.CString(x.ColoftForwarddev)
+	xc.colo_sock_mirror_id = C.CString(x.ColoSockMirrorId)
+	xc.colo_sock_mirror_ip = C.CString(x.ColoSockMirrorIp)
+	xc.colo_sock_mirror_port = C.CString(x.ColoSockMirrorPort)
+	xc.colo_sock_compare_pri_in_id = C.CString(x.ColoSockComparePriInId)
+	xc.colo_sock_compare_pri_in_ip = C.CString(x.ColoSockComparePriInIp)
+	xc.colo_sock_compare_pri_in_port = C.CString(x.ColoSockComparePriInPort)
+	xc.colo_sock_compare_sec_in_id = C.CString(x.ColoSockCompareSecInId)
+	xc.colo_sock_compare_sec_in_ip = C.CString(x.ColoSockCompareSecInIp)
+	xc.colo_sock_compare_sec_in_port = C.CString(x.ColoSockCompareSecInPort)
+	xc.colo_sock_compare_notify_id = C.CString(x.ColoSockCompareNotifyId)
+	xc.colo_sock_compare_notify_ip = C.CString(x.ColoSockCompareNotifyIp)
+	xc.colo_sock_compare_notify_port = C.CString(x.ColoSockCompareNotifyPort)
+	xc.colo_sock_redirector0_id = C.CString(x.ColoSockRedirector0Id)
+	xc.colo_sock_redirector0_ip = C.CString(x.ColoSockRedirector0Ip)
+	xc.colo_sock_redirector0_port = C.CString(x.ColoSockRedirector0Port)
+	xc.colo_sock_redirector1_id = C.CString(x.ColoSockRedirector1Id)
+	xc.colo_sock_redirector1_ip = C.CString(x.ColoSockRedirector1Ip)
+	xc.colo_sock_redirector1_port = C.CString(x.ColoSockRedirector1Port)
+	xc.colo_sock_redirector2_id = C.CString(x.ColoSockRedirector2Id)
+	xc.colo_sock_redirector2_ip = C.CString(x.ColoSockRedirector2Ip)
+	xc.colo_sock_redirector2_port = C.CString(x.ColoSockRedirector2Port)
+	xc.colo_filter_mirror_queue = C.CString(x.ColoFilterMirrorQueue)
+	xc.colo_filter_mirror_outdev = C.CString(x.ColoFilterMirrorOutdev)
+	xc.colo_filter_redirector0_queue = C.CString(x.ColoFilterRedirector0Queue)
+	xc.colo_filter_redirector0_indev = C.CString(x.ColoFilterRedirector0Indev)
+	xc.colo_filter_redirector0_outdev = C.CString(x.ColoFilterRedirector0Outdev)
+	xc.colo_filter_redirector1_queue = C.CString(x.ColoFilterRedirector1Queue)
+	xc.colo_filter_redirector1_indev = C.CString(x.ColoFilterRedirector1Indev)
+	xc.colo_filter_redirector1_outdev = C.CString(x.ColoFilterRedirector1Outdev)
+	xc.colo_compare_pri_in = C.CString(x.ColoComparePriIn)
+	xc.colo_compare_sec_in = C.CString(x.ColoCompareSecIn)
+	xc.colo_compare_out = C.CString(x.ColoCompareOut)
+	xc.colo_compare_notify_dev = C.CString(x.ColoCompareNotifyDev)
+	xc.colo_sock_sec_redirector0_id = C.CString(x.ColoSockSecRedirector0Id)
+	xc.colo_sock_sec_redirector0_ip = C.CString(x.ColoSockSecRedirector0Ip)
+	xc.colo_sock_sec_redirector0_port = C.CString(x.ColoSockSecRedirector0Port)
+	xc.colo_sock_sec_redirector1_id = C.CString(x.ColoSockSecRedirector1Id)
+	xc.colo_sock_sec_redirector1_ip = C.CString(x.ColoSockSecRedirector1Ip)
+	xc.colo_sock_sec_redirector1_port = C.CString(x.ColoSockSecRedirector1Port)
+	xc.colo_filter_sec_redirector0_queue = C.CString(x.ColoFilterSecRedirector0Queue)
+	xc.colo_filter_sec_redirector0_indev = C.CString(x.ColoFilterSecRedirector0Indev)
+	xc.colo_filter_sec_redirector0_outdev = C.CString(x.ColoFilterSecRedirector0Outdev)
+	xc.colo_filter_sec_redirector1_queue = C.CString(x.ColoFilterSecRedirector1Queue)
+	xc.colo_filter_sec_redirector1_indev = C.CString(x.ColoFilterSecRedirector1Indev)
+	xc.colo_filter_sec_redirector1_outdev = C.CString(x.ColoFilterSecRedirector1Outdev)
+	xc.colo_filter_sec_rewriter0_queue = C.CString(x.ColoFilterSecRewriter0Queue)
+	xc.colo_checkpoint_host = C.CString(x.ColoCheckpointHost)
+	xc.colo_checkpoint_port = C.CString(x.ColoCheckpointPort)
+	return xc, nil
+}
+
 func (x *DevicePci) fromC(xc *C.libxl_device_pci) error {
 	x.Func = byte(xc._func)
 	x.Dev = byte(xc.dev)
@@ -934,6 +1491,22 @@ func (x *DevicePci) fromC(xc *C.libxl_device_pci) error {
 	return nil
 }
 
+func (x *DevicePci) toC() (xc C.libxl_device_pci, err error) {
+	C.libxl_device_pci_init(&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 xc, nil
+}
+
 func (x *DeviceRdm) fromC(xc *C.libxl_device_rdm) error {
 	x.Start = uint64(xc.start)
 	x.Size = uint64(xc.size)
@@ -941,6 +1514,14 @@ func (x *DeviceRdm) fromC(xc *C.libxl_device_rdm) error {
 	return nil
 }
 
+func (x *DeviceRdm) toC() (xc C.libxl_device_rdm, err error) {
+	C.libxl_device_rdm_init(&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 xc, nil
+}
+
 func (x *DeviceUsbctrl) fromC(xc *C.libxl_device_usbctrl) error {
 	x.Type = UsbctrlType(xc._type)
 	x.Devid = Devid(xc.devid)
@@ -951,6 +1532,17 @@ func (x *DeviceUsbctrl) fromC(xc *C.libxl_device_usbctrl) error {
 	return nil
 }
 
+func (x *DeviceUsbctrl) toC() (xc C.libxl_device_usbctrl, err error) {
+	C.libxl_device_usbctrl_init(&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)
+	xc.backend_domname = C.CString(x.BackendDomname)
+	return xc, nil
+}
+
 func (x *DeviceUsbdev) fromC(xc *C.libxl_device_usbdev) error {
 	x.Ctrl = Devid(xc.ctrl)
 	x.Port = int(xc.port)
@@ -979,11 +1571,24 @@ func (x *DeviceUsbdevTypeUnionHostdev) fromC(xc *C.libxl_device_usbdev) error {
 	return nil
 }
 
+func (x *DeviceUsbdev) toC() (xc C.libxl_device_usbdev, err error) {
+	C.libxl_device_usbdev_init(&xc)
+	xc.ctrl = C.libxl_devid(x.Ctrl)
+	xc.port = C.int(x.Port)
+	return xc, 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) {
+	C.libxl_device_dtdev_init(&xc)
+	xc.path = C.CString(x.Path)
+	return xc, nil
+}
+
 func (x *DeviceVtpm) fromC(xc *C.libxl_device_vtpm) error {
 	x.BackendDomid = Domid(xc.backend_domid)
 	x.BackendDomname = C.GoString(xc.backend_domname)
@@ -996,6 +1601,19 @@ func (x *DeviceVtpm) fromC(xc *C.libxl_device_vtpm) error {
 	return nil
 }
 
+func (x *DeviceVtpm) toC() (xc C.libxl_device_vtpm, err error) {
+	C.libxl_device_vtpm_init(&xc)
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	xc.backend_domname = C.CString(x.BackendDomname)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.uuid, err = x.Uuid.toC()
+	if err != nil {
+		C.libxl_device_vtpm_dispose(&xc)
+		return xc, err
+	}
+	return xc, nil
+}
+
 func (x *DeviceP9) fromC(xc *C.libxl_device_p9) error {
 	x.BackendDomid = Domid(xc.backend_domid)
 	x.BackendDomname = C.GoString(xc.backend_domname)
@@ -1006,6 +1624,17 @@ func (x *DeviceP9) fromC(xc *C.libxl_device_p9) error {
 	return nil
 }
 
+func (x *DeviceP9) toC() (xc C.libxl_device_p9, err error) {
+	C.libxl_device_p9_init(&xc)
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	xc.backend_domname = C.CString(x.BackendDomname)
+	xc.tag = C.CString(x.Tag)
+	xc.path = C.CString(x.Path)
+	xc.security_model = C.CString(x.SecurityModel)
+	xc.devid = C.libxl_devid(x.Devid)
+	return xc, nil
+}
+
 func (x *DevicePvcallsif) fromC(xc *C.libxl_device_pvcallsif) error {
 	x.BackendDomid = Domid(xc.backend_domid)
 	x.BackendDomname = C.GoString(xc.backend_domname)
@@ -1013,6 +1642,14 @@ func (x *DevicePvcallsif) fromC(xc *C.libxl_device_pvcallsif) error {
 	return nil
 }
 
+func (x *DevicePvcallsif) toC() (xc C.libxl_device_pvcallsif, err error) {
+	C.libxl_device_pvcallsif_init(&xc)
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	xc.backend_domname = C.CString(x.BackendDomname)
+	xc.devid = C.libxl_devid(x.Devid)
+	return xc, nil
+}
+
 func (x *DeviceChannel) fromC(xc *C.libxl_device_channel) error {
 	x.BackendDomid = Domid(xc.backend_domid)
 	x.BackendDomname = C.GoString(xc.backend_domname)
@@ -1042,6 +1679,15 @@ func (x *DeviceChannelConnectionUnionSocket) fromC(xc *C.libxl_device_channel) e
 	return nil
 }
 
+func (x *DeviceChannel) toC() (xc C.libxl_device_channel, err error) {
+	C.libxl_device_channel_init(&xc)
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	xc.backend_domname = C.CString(x.BackendDomname)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.name = C.CString(x.Name)
+	return xc, nil
+}
+
 func (x *ConnectorParam) fromC(xc *C.libxl_connector_param) error {
 	x.UniqueId = C.GoString(xc.unique_id)
 	x.Width = uint32(xc.width)
@@ -1049,6 +1695,14 @@ func (x *ConnectorParam) fromC(xc *C.libxl_connector_param) error {
 	return nil
 }
 
+func (x *ConnectorParam) toC() (xc C.libxl_connector_param, err error) {
+	C.libxl_connector_param_init(&xc)
+	xc.unique_id = C.CString(x.UniqueId)
+	xc.width = C.uint32_t(x.Width)
+	xc.height = C.uint32_t(x.Height)
+	return xc, nil
+}
+
 func (x *DeviceVdispl) fromC(xc *C.libxl_device_vdispl) error {
 	x.BackendDomid = Domid(xc.backend_domid)
 	x.BackendDomname = C.GoString(xc.backend_domname)
@@ -1067,6 +1721,15 @@ func (x *DeviceVdispl) fromC(xc *C.libxl_device_vdispl) error {
 	return nil
 }
 
+func (x *DeviceVdispl) toC() (xc C.libxl_device_vdispl, err error) {
+	C.libxl_device_vdispl_init(&xc)
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	xc.backend_domname = C.CString(x.BackendDomname)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.be_alloc = C.bool(x.BeAlloc)
+	return xc, nil
+}
+
 func (x *VsndParams) fromC(xc *C.libxl_vsnd_params) error {
 	numSampleRates := int(xc.num_sample_rates)
 	cSampleRates := (*[1 << 28]C.uint32_t)(unsafe.Pointer(xc.sample_rates))[:numSampleRates:numSampleRates]
@@ -1086,6 +1749,14 @@ func (x *VsndParams) fromC(xc *C.libxl_vsnd_params) error {
 	return nil
 }
 
+func (x *VsndParams) toC() (xc C.libxl_vsnd_params, err error) {
+	C.libxl_vsnd_params_init(&xc)
+	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 xc, nil
+}
+
 func (x *VsndStream) fromC(xc *C.libxl_vsnd_stream) error {
 	x.UniqueId = C.GoString(xc.unique_id)
 	x.Type = VsndStreamType(xc._type)
@@ -1097,6 +1768,18 @@ func (x *VsndStream) fromC(xc *C.libxl_vsnd_stream) error {
 	return nil
 }
 
+func (x *VsndStream) toC() (xc C.libxl_vsnd_stream, err error) {
+	C.libxl_vsnd_stream_init(&xc)
+	xc.unique_id = C.CString(x.UniqueId)
+	xc._type = C.libxl_vsnd_stream_type(x.Type)
+	xc.params, err = x.Params.toC()
+	if err != nil {
+		C.libxl_vsnd_stream_dispose(&xc)
+		return xc, err
+	}
+	return xc, nil
+}
+
 func (x *VsndPcm) fromC(xc *C.libxl_vsnd_pcm) error {
 	x.Name = C.GoString(xc.name)
 	var vsndParamsParams VsndParams
@@ -1117,6 +1800,17 @@ func (x *VsndPcm) fromC(xc *C.libxl_vsnd_pcm) error {
 	return nil
 }
 
+func (x *VsndPcm) toC() (xc C.libxl_vsnd_pcm, err error) {
+	C.libxl_vsnd_pcm_init(&xc)
+	xc.name = C.CString(x.Name)
+	xc.params, err = x.Params.toC()
+	if err != nil {
+		C.libxl_vsnd_pcm_dispose(&xc)
+		return xc, err
+	}
+	return xc, nil
+}
+
 func (x *DeviceVsnd) fromC(xc *C.libxl_device_vsnd) error {
 	x.BackendDomid = Domid(xc.backend_domid)
 	x.BackendDomname = C.GoString(xc.backend_domname)
@@ -1141,6 +1835,21 @@ func (x *DeviceVsnd) fromC(xc *C.libxl_device_vsnd) error {
 	return nil
 }
 
+func (x *DeviceVsnd) toC() (xc C.libxl_device_vsnd, err error) {
+	C.libxl_device_vsnd_init(&xc)
+	xc.backend_domid = C.libxl_domid(x.BackendDomid)
+	xc.backend_domname = C.CString(x.BackendDomname)
+	xc.devid = C.libxl_devid(x.Devid)
+	xc.short_name = C.CString(x.ShortName)
+	xc.long_name = C.CString(x.LongName)
+	xc.params, err = x.Params.toC()
+	if err != nil {
+		C.libxl_device_vsnd_dispose(&xc)
+		return xc, err
+	}
+	return xc, nil
+}
+
 func (x *DomainConfig) fromC(xc *C.libxl_domain_config) error {
 	var domainCreateInfoCInfo DomainCreateInfo
 	if err := domainCreateInfoCInfo.fromC(&xc.c_info); err != nil {
@@ -1310,6 +2019,26 @@ func (x *DomainConfig) fromC(xc *C.libxl_domain_config) error {
 	return nil
 }
 
+func (x *DomainConfig) toC() (xc C.libxl_domain_config, err error) {
+	C.libxl_domain_config_init(&xc)
+	xc.c_info, err = x.CInfo.toC()
+	if err != nil {
+		C.libxl_domain_config_dispose(&xc)
+		return xc, err
+	}
+	xc.b_info, err = x.BInfo.toC()
+	if err != nil {
+		C.libxl_domain_config_dispose(&xc)
+		return xc, 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 xc, nil
+}
+
 func (x *Diskinfo) fromC(xc *C.libxl_diskinfo) error {
 	x.Backend = C.GoString(xc.backend)
 	x.BackendId = uint32(xc.backend_id)
@@ -1322,6 +2051,19 @@ func (x *Diskinfo) fromC(xc *C.libxl_diskinfo) error {
 	return nil
 }
 
+func (x *Diskinfo) toC() (xc C.libxl_diskinfo, err error) {
+	C.libxl_diskinfo_init(&xc)
+	xc.backend = C.CString(x.Backend)
+	xc.backend_id = C.uint32_t(x.BackendId)
+	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 xc, nil
+}
+
 func (x *Nicinfo) fromC(xc *C.libxl_nicinfo) error {
 	x.Backend = C.GoString(xc.backend)
 	x.BackendId = uint32(xc.backend_id)
@@ -1335,6 +2077,20 @@ func (x *Nicinfo) fromC(xc *C.libxl_nicinfo) error {
 	return nil
 }
 
+func (x *Nicinfo) toC() (xc C.libxl_nicinfo, err error) {
+	C.libxl_nicinfo_init(&xc)
+	xc.backend = C.CString(x.Backend)
+	xc.backend_id = C.uint32_t(x.BackendId)
+	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 xc, nil
+}
+
 func (x *Vtpminfo) fromC(xc *C.libxl_vtpminfo) error {
 	x.Backend = C.GoString(xc.backend)
 	x.BackendId = uint32(xc.backend_id)
@@ -1352,6 +2108,24 @@ func (x *Vtpminfo) fromC(xc *C.libxl_vtpminfo) error {
 	return nil
 }
 
+func (x *Vtpminfo) toC() (xc C.libxl_vtpminfo, err error) {
+	C.libxl_vtpminfo_init(&xc)
+	xc.backend = C.CString(x.Backend)
+	xc.backend_id = C.uint32_t(x.BackendId)
+	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.uuid, err = x.Uuid.toC()
+	if err != nil {
+		C.libxl_vtpminfo_dispose(&xc)
+		return xc, err
+	}
+	return xc, nil
+}
+
 func (x *Usbctrlinfo) fromC(xc *C.libxl_usbctrlinfo) error {
 	x.Type = UsbctrlType(xc._type)
 	x.Devid = Devid(xc.devid)
@@ -1368,6 +2142,23 @@ func (x *Usbctrlinfo) fromC(xc *C.libxl_usbctrlinfo) error {
 	return nil
 }
 
+func (x *Usbctrlinfo) toC() (xc C.libxl_usbctrlinfo, err error) {
+	C.libxl_usbctrlinfo_init(&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 = C.CString(x.Backend)
+	xc.backend_id = C.uint32_t(x.BackendId)
+	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 xc, nil
+}
+
 func (x *Vcpuinfo) fromC(xc *C.libxl_vcpuinfo) error {
 	x.Vcpuid = uint32(xc.vcpuid)
 	x.Cpu = uint32(xc.cpu)
@@ -1388,6 +2179,27 @@ func (x *Vcpuinfo) fromC(xc *C.libxl_vcpuinfo) error {
 	return nil
 }
 
+func (x *Vcpuinfo) toC() (xc C.libxl_vcpuinfo, err error) {
+	C.libxl_vcpuinfo_init(&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)
+	xc.cpumap, err = x.Cpumap.toC()
+	if err != nil {
+		C.libxl_vcpuinfo_dispose(&xc)
+		return xc, err
+	}
+	xc.cpumap_soft, err = x.CpumapSoft.toC()
+	if err != nil {
+		C.libxl_vcpuinfo_dispose(&xc)
+		return xc, err
+	}
+	return xc, nil
+}
+
 func (x *Physinfo) fromC(xc *C.libxl_physinfo) error {
 	x.ThreadsPerCore = uint32(xc.threads_per_core)
 	x.CoresPerSocket = uint32(xc.cores_per_socket)
@@ -1416,6 +2228,35 @@ func (x *Physinfo) fromC(xc *C.libxl_physinfo) error {
 	return nil
 }
 
+func (x *Physinfo) toC() (xc C.libxl_physinfo, err error) {
+	C.libxl_physinfo_init(&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)
+	xc.hw_cap, err = x.HwCap.toC()
+	if err != nil {
+		C.libxl_physinfo_dispose(&xc)
+		return xc, 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 xc, nil
+}
+
 func (x *Connectorinfo) fromC(xc *C.libxl_connectorinfo) error {
 	x.UniqueId = C.GoString(xc.unique_id)
 	x.Width = uint32(xc.width)
@@ -1427,6 +2268,18 @@ func (x *Connectorinfo) fromC(xc *C.libxl_connectorinfo) error {
 	return nil
 }
 
+func (x *Connectorinfo) toC() (xc C.libxl_connectorinfo, err error) {
+	C.libxl_connectorinfo_init(&xc)
+	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 xc, nil
+}
+
 func (x *Vdisplinfo) fromC(xc *C.libxl_vdisplinfo) error {
 	x.Backend = C.GoString(xc.backend)
 	x.BackendId = uint32(xc.backend_id)
@@ -1448,12 +2301,31 @@ func (x *Vdisplinfo) fromC(xc *C.libxl_vdisplinfo) error {
 	return nil
 }
 
+func (x *Vdisplinfo) toC() (xc C.libxl_vdisplinfo, err error) {
+	C.libxl_vdisplinfo_init(&xc)
+	xc.backend = C.CString(x.Backend)
+	xc.backend_id = C.uint32_t(x.BackendId)
+	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)
+	return xc, 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) {
+	C.libxl_streaminfo_init(&xc)
+	xc.req_evtch = C.int(x.ReqEvtch)
+	xc.req_rref = C.int(x.ReqRref)
+	return xc, nil
+}
+
 func (x *Pcminfo) fromC(xc *C.libxl_pcminfo) error {
 	numVsndStreams := int(xc.num_vsnd_streams)
 	cStreams := (*[1 << 28]C.libxl_streaminfo)(unsafe.Pointer(xc.streams))[:numVsndStreams:numVsndStreams]
@@ -1468,6 +2340,11 @@ func (x *Pcminfo) fromC(xc *C.libxl_pcminfo) error {
 	return nil
 }
 
+func (x *Pcminfo) toC() (xc C.libxl_pcminfo, err error) {
+	C.libxl_pcminfo_init(&xc)
+	return xc, nil
+}
+
 func (x *Vsndinfo) fromC(xc *C.libxl_vsndinfo) error {
 	x.Backend = C.GoString(xc.backend)
 	x.BackendId = uint32(xc.backend_id)
@@ -1488,6 +2365,17 @@ func (x *Vsndinfo) fromC(xc *C.libxl_vsndinfo) error {
 	return nil
 }
 
+func (x *Vsndinfo) toC() (xc C.libxl_vsndinfo, err error) {
+	C.libxl_vsndinfo_init(&xc)
+	xc.backend = C.CString(x.Backend)
+	xc.backend_id = C.uint32_t(x.BackendId)
+	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)
+	return xc, nil
+}
+
 func (x *Vkbinfo) fromC(xc *C.libxl_vkbinfo) error {
 	x.Backend = C.GoString(xc.backend)
 	x.BackendId = uint32(xc.backend_id)
@@ -1500,6 +2388,19 @@ func (x *Vkbinfo) fromC(xc *C.libxl_vkbinfo) error {
 	return nil
 }
 
+func (x *Vkbinfo) toC() (xc C.libxl_vkbinfo, err error) {
+	C.libxl_vkbinfo_init(&xc)
+	xc.backend = C.CString(x.Backend)
+	xc.backend_id = C.uint32_t(x.BackendId)
+	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 xc, nil
+}
+
 func (x *Numainfo) fromC(xc *C.libxl_numainfo) error {
 	x.Size = uint64(xc.size)
 	x.Free = uint64(xc.free)
@@ -1512,6 +2413,13 @@ func (x *Numainfo) fromC(xc *C.libxl_numainfo) error {
 	return nil
 }
 
+func (x *Numainfo) toC() (xc C.libxl_numainfo, err error) {
+	C.libxl_numainfo_init(&xc)
+	xc.size = C.uint64_t(x.Size)
+	xc.free = C.uint64_t(x.Free)
+	return xc, nil
+}
+
 func (x *Cputopology) fromC(xc *C.libxl_cputopology) error {
 	x.Core = uint32(xc.core)
 	x.Socket = uint32(xc.socket)
@@ -1519,6 +2427,14 @@ func (x *Cputopology) fromC(xc *C.libxl_cputopology) error {
 	return nil
 }
 
+func (x *Cputopology) toC() (xc C.libxl_cputopology, err error) {
+	C.libxl_cputopology_init(&xc)
+	xc.core = C.uint32_t(x.Core)
+	xc.socket = C.uint32_t(x.Socket)
+	xc.node = C.uint32_t(x.Node)
+	return xc, nil
+}
+
 func (x *Pcitopology) fromC(xc *C.libxl_pcitopology) error {
 	x.Seg = uint16(xc.seg)
 	x.Bus = byte(xc.bus)
@@ -1527,6 +2443,15 @@ func (x *Pcitopology) fromC(xc *C.libxl_pcitopology) error {
 	return nil
 }
 
+func (x *Pcitopology) toC() (xc C.libxl_pcitopology, err error) {
+	C.libxl_pcitopology_init(&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 xc, nil
+}
+
 func (x *SchedCreditParams) fromC(xc *C.libxl_sched_credit_params) error {
 	x.TsliceMs = int(xc.tslice_ms)
 	x.RatelimitUs = int(xc.ratelimit_us)
@@ -1534,11 +2459,25 @@ func (x *SchedCreditParams) fromC(xc *C.libxl_sched_credit_params) error {
 	return nil
 }
 
+func (x *SchedCreditParams) toC() (xc C.libxl_sched_credit_params, err error) {
+	C.libxl_sched_credit_params_init(&xc)
+	xc.tslice_ms = C.int(x.TsliceMs)
+	xc.ratelimit_us = C.int(x.RatelimitUs)
+	xc.vcpu_migr_delay_us = C.int(x.VcpuMigrDelayUs)
+	return xc, 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) {
+	C.libxl_sched_credit2_params_init(&xc)
+	xc.ratelimit_us = C.int(x.RatelimitUs)
+	return xc, nil
+}
+
 func (x *DomainRemusInfo) fromC(xc *C.libxl_domain_remus_info) error {
 	x.Interval = int(xc.interval)
 	var defboolAllowUnsafe Defbool
@@ -1580,6 +2519,48 @@ func (x *DomainRemusInfo) fromC(xc *C.libxl_domain_remus_info) error {
 	return nil
 }
 
+func (x *DomainRemusInfo) toC() (xc C.libxl_domain_remus_info, err error) {
+	C.libxl_domain_remus_info_init(&xc)
+	xc.interval = C.int(x.Interval)
+	xc.allow_unsafe, err = x.AllowUnsafe.toC()
+	if err != nil {
+		C.libxl_domain_remus_info_dispose(&xc)
+		return xc, err
+	}
+	xc.blackhole, err = x.Blackhole.toC()
+	if err != nil {
+		C.libxl_domain_remus_info_dispose(&xc)
+		return xc, err
+	}
+	xc.compression, err = x.Compression.toC()
+	if err != nil {
+		C.libxl_domain_remus_info_dispose(&xc)
+		return xc, err
+	}
+	xc.netbuf, err = x.Netbuf.toC()
+	if err != nil {
+		C.libxl_domain_remus_info_dispose(&xc)
+		return xc, err
+	}
+	xc.netbufscript = C.CString(x.Netbufscript)
+	xc.diskbuf, err = x.Diskbuf.toC()
+	if err != nil {
+		C.libxl_domain_remus_info_dispose(&xc)
+		return xc, err
+	}
+	xc.colo, err = x.Colo.toC()
+	if err != nil {
+		C.libxl_domain_remus_info_dispose(&xc)
+		return xc, err
+	}
+	xc.userspace_colo_proxy, err = x.UserspaceColoProxy.toC()
+	if err != nil {
+		C.libxl_domain_remus_info_dispose(&xc)
+		return xc, err
+	}
+	return xc, nil
+}
+
 func (x *Event) fromC(xc *C.libxl_event) error {
 	var evLinkLink EvLink
 	if err := evLinkLink.fromC(&xc.link); err != nil {
@@ -1652,6 +2633,23 @@ func (x *EventTypeUnionOperationComplete) fromC(xc *C.libxl_event) error {
 	return nil
 }
 
+func (x *Event) toC() (xc C.libxl_event, err error) {
+	C.libxl_event_init(&xc)
+	xc.link, err = x.Link.toC()
+	if err != nil {
+		C.libxl_event_dispose(&xc)
+		return xc, err
+	}
+	xc.domid = C.libxl_domid(x.Domid)
+	xc.domuuid, err = x.Domuuid.toC()
+	if err != nil {
+		C.libxl_event_dispose(&xc)
+		return xc, err
+	}
+	xc.for_user = C.uint64_t(x.ForUser)
+	return xc, nil
+}
+
 func (x *PsrCatInfo) fromC(xc *C.libxl_psr_cat_info) error {
 	x.Id = uint32(xc.id)
 	x.CosMax = uint32(xc.cos_max)
@@ -1660,6 +2658,15 @@ func (x *PsrCatInfo) fromC(xc *C.libxl_psr_cat_info) error {
 	return nil
 }
 
+func (x *PsrCatInfo) toC() (xc C.libxl_psr_cat_info, err error) {
+	C.libxl_psr_cat_info_init(&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 xc, nil
+}
+
 func (x *PsrHwInfo) fromC(xc *C.libxl_psr_hw_info) error {
 	x.Id = uint32(xc.id)
 	x.Type = PsrFeatType(xc._type)
@@ -1705,3 +2712,9 @@ func (x *PsrHwInfoTypeUnionMba) fromC(xc *C.libxl_psr_hw_info) error {
 	x.Linear = bool(tmp.linear)
 	return nil
 }
+
+func (x *PsrHwInfo) toC() (xc C.libxl_psr_hw_info, err error) {
+	C.libxl_psr_hw_info_init(&xc)
+	xc.id = C.uint32_t(x.Id)
+	return xc, nil
+}
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 20/24] golang/xenlight: implement keyed union Go to C marshaling
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (18 preceding siblings ...)
  2019-10-07 15:13 ` [Xen-devel] [PATCH 19/24] golang/xenlight: begin Go to C type marshaling Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-10-07 15:13 ` [Xen-devel] [PATCH 21/24] golang/xenlight: implement array " Nick Rosbrook
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Since the C union cannot be directly populated, populate the fields of the
corresponding C struct defined in the cgo preamble, and then copy that
struct as bytes into the byte slice that Go uses as the union.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/gengotypes.py       |  77 ++++-
 tools/golang/xenlight/xenlight_helpers.go | 325 ++++++++++++++++++++++
 2 files changed, 400 insertions(+), 2 deletions(-)

diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
index eccc334b41..35d9dfea40 100644
--- a/tools/golang/xenlight/gengotypes.py
+++ b/tools/golang/xenlight/gengotypes.py
@@ -525,8 +525,7 @@ def xenlight_golang_define_to_C(ty = None, typename = None, nested = False):
             s += xenlight_golang_define_to_C(f.type, typename=f.name, nested=True)
 
         elif isinstance(f.type, idl.KeyedUnion):
-            # TODO
-            pass
+            s += xenlight_golang_union_to_C(f.type, f.name, ty.typename, ty.dispose_fn)
 
         else:
             raise Exception('type {} not supported'.format(f.type))
@@ -537,6 +536,80 @@ def xenlight_golang_define_to_C(ty = None, typename = None, nested = False):
 
     return s
 
+def xenlight_golang_union_to_C(ty = None, union_name = '',
+                               struct_name = '', dispose_fn = ''):
+    keyname   = ty.keyvar.name
+    gokeyname = xenlight_golang_fmt_name(keyname)
+    keytype   = ty.keyvar.type.typename
+    gokeytype = xenlight_golang_fmt_name(keytype)
+
+    interface_name = '{}_{}_union'.format(struct_name, keyname)
+    interface_name = xenlight_golang_fmt_name(interface_name, exported=False)
+
+    cgo_keyname = keyname
+    if cgo_keyname in go_keywords:
+        cgo_keyname = '_' + cgo_keyname
+
+
+    s = 'xc.{} = C.{}(x.{})\n'.format(cgo_keyname,keytype,gokeyname)
+    s += 'switch x.{}{{\n'.format(gokeyname)
+
+    # Create switch statement to determine how to populate the C union.
+    for f in ty.fields:
+        key_val = '{}_{}'.format(keytype, f.name)
+        key_val = xenlight_golang_fmt_name(key_val)
+        if f.type is None:
+            continue
+
+        s += 'case {}:\n'.format(key_val)
+        cgotype = '{}_{}_union_{}'.format(struct_name,keyname,f.name)
+        gotype  = xenlight_golang_fmt_name(cgotype)
+        goname  = '{}_{}'.format(keyname,f.name)
+        goname  = xenlight_golang_fmt_name(goname,exported=False)
+
+        field_name = xenlight_golang_fmt_name('{}_union'.format(keyname))
+        s += 'tmp, ok := x.{}.({})\n'.format(field_name,gotype)
+        s += 'if !ok {\n'
+        s += 'C.{}(&xc)\n'.format(dispose_fn)
+        s += 'return xc,errors.New("wrong type for union key {}")\n'.format(keyname)
+        s += '}\n'
+
+        s += 'var {} C.{}\n'.format(f.name,cgotype)
+        for uf in f.type.fields:
+            gotypename = xenlight_golang_fmt_name(uf.type.typename)
+            ctypename  = uf.type.typename
+            gofname    = xenlight_golang_fmt_name(uf.name)
+
+            is_castable = (uf.type.json_parse_type == 'JSON_INTEGER' or
+                           isinstance(uf.type, idl.Enumeration) or
+                           gotypename in go_builtin_types)
+
+            if not is_castable:
+                s += '{}.{}, err = tmp.{}.toC()\n'.format(f.name,uf.name,gofname)
+                s += 'if err != nil {\n'
+                s += 'C.{}(&xc)\n'.format(dispose_fn)
+                s += 'return xc,err \n}\n'
+
+            elif gotypename == 'string':
+                s += '{}.{} = C.CString(tmp.{})\n'.format(f.name,uf.name,gofname)
+
+            else:
+                s += '{}.{} = C.{}(tmp.{})\n'.format(f.name,uf.name,ctypename,gofname)
+
+        # The union is still represented as Go []byte.
+        s += '{}Bytes := C.GoBytes(unsafe.Pointer(&{}),C.sizeof_{})\n'.format(f.name,
+                                                                              f.name,
+                                                                              cgotype)
+        s += 'copy(xc.{}[:],{}Bytes)\n'.format(union_name,f.name)
+
+    # End switch statement
+    s += 'default:\n'
+    err_string = '"invalid union key \'%v\'", x.{}'.format(gokeyname)
+    s += 'return xc, fmt.Errorf({})'.format(err_string)
+    s += '}\n'
+
+    return s
+
 def xenlight_golang_fmt_name(name, exported = True):
     """
     Take a given type name and return an
diff --git a/tools/golang/xenlight/xenlight_helpers.go b/tools/golang/xenlight/xenlight_helpers.go
index 92e6afcd10..2cb5adaec5 100644
--- a/tools/golang/xenlight/xenlight_helpers.go
+++ b/tools/golang/xenlight/xenlight_helpers.go
@@ -433,6 +433,21 @@ func (x *Channelinfo) toC() (xc C.libxl_channelinfo, err error) {
 	xc.state = C.int(x.State)
 	xc.evtch = C.int(x.Evtch)
 	xc.rref = C.int(x.Rref)
+	xc.connection = C.libxl_channel_connection(x.Connection)
+	switch x.Connection {
+	case ChannelConnectionPty:
+		tmp, ok := x.ConnectionUnion.(ChannelinfoConnectionUnionPty)
+		if !ok {
+			C.libxl_channelinfo_dispose(&xc)
+			return xc, errors.New("wrong type for union key connection")
+		}
+		var pty C.libxl_channelinfo_connection_union_pty
+		pty.path = C.CString(tmp.Path)
+		ptyBytes := C.GoBytes(unsafe.Pointer(&pty), C.sizeof_libxl_channelinfo_connection_union_pty)
+		copy(xc.u[:], ptyBytes)
+	default:
+		return xc, fmt.Errorf("invalid union key '%v'", x.Connection)
+	}
 	return xc, nil
 }
 
@@ -1180,6 +1195,216 @@ func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 		return xc, err
 	}
 	xc.tee = C.libxl_tee_type(x.Tee)
+	xc._type = C.libxl_domain_type(x.Type)
+	switch x.Type {
+	case DomainTypeHvm:
+		tmp, ok := x.TypeUnion.(DomainBuildInfoTypeUnionHvm)
+		if !ok {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, errors.New("wrong type for union key type")
+		}
+		var hvm C.libxl_domain_build_info_type_union_hvm
+		hvm.firmware = C.CString(tmp.Firmware)
+		hvm.bios = C.libxl_bios_type(tmp.Bios)
+		hvm.pae, err = tmp.Pae.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.apic, err = tmp.Apic.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.acpi, err = tmp.Acpi.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.acpi_s3, err = tmp.AcpiS3.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.acpi_s4, err = tmp.AcpiS4.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.acpi_laptop_slate, err = tmp.AcpiLaptopSlate.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.nx, err = tmp.Nx.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.viridian, err = tmp.Viridian.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.viridian_enable, err = tmp.ViridianEnable.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.viridian_disable, err = tmp.ViridianDisable.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.timeoffset = C.CString(tmp.Timeoffset)
+		hvm.hpet, err = tmp.Hpet.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.vpt_align, err = tmp.VptAlign.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.mmio_hole_memkb = C.uint64_t(tmp.MmioHoleMemkb)
+		hvm.timer_mode = C.libxl_timer_mode(tmp.TimerMode)
+		hvm.nested_hvm, err = tmp.NestedHvm.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.altp2m, err = tmp.Altp2M.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.system_firmware = C.CString(tmp.SystemFirmware)
+		hvm.smbios_firmware = C.CString(tmp.SmbiosFirmware)
+		hvm.acpi_firmware = C.CString(tmp.AcpiFirmware)
+		hvm.hdtype = C.libxl_hdtype(tmp.Hdtype)
+		hvm.nographic, err = tmp.Nographic.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.vga, err = tmp.Vga.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.vnc, err = tmp.Vnc.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.keymap = C.CString(tmp.Keymap)
+		hvm.sdl, err = tmp.Sdl.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.spice, err = tmp.Spice.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.gfx_passthru, err = tmp.GfxPassthru.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.gfx_passthru_kind = C.libxl_gfx_passthru_kind(tmp.GfxPassthruKind)
+		hvm.serial = C.CString(tmp.Serial)
+		hvm.boot = C.CString(tmp.Boot)
+		hvm.usb, err = tmp.Usb.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.usbversion = C.int(tmp.Usbversion)
+		hvm.usbdevice = C.CString(tmp.Usbdevice)
+		hvm.vkb_device, err = tmp.VkbDevice.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.soundhw = C.CString(tmp.Soundhw)
+		hvm.xen_platform_pci, err = tmp.XenPlatformPci.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.usbdevice_list, err = tmp.UsbdeviceList.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.vendor_device = C.libxl_vendor_device(tmp.VendorDevice)
+		hvm.ms_vm_genid, err = tmp.MsVmGenid.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.serial_list, err = tmp.SerialList.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.rdm, err = tmp.Rdm.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		hvm.rdm_mem_boundary_memkb = C.uint64_t(tmp.RdmMemBoundaryMemkb)
+		hvm.mca_caps = C.uint64_t(tmp.McaCaps)
+		hvmBytes := C.GoBytes(unsafe.Pointer(&hvm), C.sizeof_libxl_domain_build_info_type_union_hvm)
+		copy(xc.u[:], hvmBytes)
+	case DomainTypePv:
+		tmp, ok := x.TypeUnion.(DomainBuildInfoTypeUnionPv)
+		if !ok {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, errors.New("wrong type for union key type")
+		}
+		var pv C.libxl_domain_build_info_type_union_pv
+		pv.kernel = C.CString(tmp.Kernel)
+		pv.slack_memkb = C.uint64_t(tmp.SlackMemkb)
+		pv.bootloader = C.CString(tmp.Bootloader)
+		pv.bootloader_args, err = tmp.BootloaderArgs.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		pv.cmdline = C.CString(tmp.Cmdline)
+		pv.ramdisk = C.CString(tmp.Ramdisk)
+		pv.features = C.CString(tmp.Features)
+		pv.e820_host, err = tmp.E820Host.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		pvBytes := C.GoBytes(unsafe.Pointer(&pv), C.sizeof_libxl_domain_build_info_type_union_pv)
+		copy(xc.u[:], pvBytes)
+	case DomainTypePvh:
+		tmp, ok := x.TypeUnion.(DomainBuildInfoTypeUnionPvh)
+		if !ok {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, errors.New("wrong type for union key type")
+		}
+		var pvh C.libxl_domain_build_info_type_union_pvh
+		pvh.pvshim, err = tmp.Pvshim.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		pvh.pvshim_path = C.CString(tmp.PvshimPath)
+		pvh.pvshim_cmdline = C.CString(tmp.PvshimCmdline)
+		pvh.pvshim_extra = C.CString(tmp.PvshimExtra)
+		pvhBytes := C.GoBytes(unsafe.Pointer(&pvh), C.sizeof_libxl_domain_build_info_type_union_pvh)
+		copy(xc.u[:], pvhBytes)
+	default:
+		return xc, fmt.Errorf("invalid union key '%v'", x.Type)
+	}
 	xc.arch_arm.gic_version = C.libxl_gic_version(x.ArchArm.GicVersion)
 	xc.arch_arm.vuart = C.libxl_vuart_type(x.ArchArm.Vuart)
 	xc.altp2m = C.libxl_altp2m_mode(x.Altp2M)
@@ -1575,6 +1800,22 @@ func (x *DeviceUsbdev) toC() (xc C.libxl_device_usbdev, err error) {
 	C.libxl_device_usbdev_init(&xc)
 	xc.ctrl = C.libxl_devid(x.Ctrl)
 	xc.port = C.int(x.Port)
+	xc._type = C.libxl_usbdev_type(x.Type)
+	switch x.Type {
+	case UsbdevTypeHostdev:
+		tmp, ok := x.TypeUnion.(DeviceUsbdevTypeUnionHostdev)
+		if !ok {
+			C.libxl_device_usbdev_dispose(&xc)
+			return xc, errors.New("wrong type for union key type")
+		}
+		var hostdev C.libxl_device_usbdev_type_union_hostdev
+		hostdev.hostbus = C.uint8_t(tmp.Hostbus)
+		hostdev.hostaddr = C.uint8_t(tmp.Hostaddr)
+		hostdevBytes := C.GoBytes(unsafe.Pointer(&hostdev), C.sizeof_libxl_device_usbdev_type_union_hostdev)
+		copy(xc.u[:], hostdevBytes)
+	default:
+		return xc, fmt.Errorf("invalid union key '%v'", x.Type)
+	}
 	return xc, nil
 }
 
@@ -1685,6 +1926,21 @@ func (x *DeviceChannel) toC() (xc C.libxl_device_channel, err error) {
 	xc.backend_domname = C.CString(x.BackendDomname)
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.name = C.CString(x.Name)
+	xc.connection = C.libxl_channel_connection(x.Connection)
+	switch x.Connection {
+	case ChannelConnectionSocket:
+		tmp, ok := x.ConnectionUnion.(DeviceChannelConnectionUnionSocket)
+		if !ok {
+			C.libxl_device_channel_dispose(&xc)
+			return xc, errors.New("wrong type for union key connection")
+		}
+		var socket C.libxl_device_channel_connection_union_socket
+		socket.path = C.CString(tmp.Path)
+		socketBytes := C.GoBytes(unsafe.Pointer(&socket), C.sizeof_libxl_device_channel_connection_union_socket)
+		copy(xc.u[:], socketBytes)
+	default:
+		return xc, fmt.Errorf("invalid union key '%v'", x.Connection)
+	}
 	return xc, nil
 }
 
@@ -2647,6 +2903,46 @@ func (x *Event) toC() (xc C.libxl_event, err error) {
 		return xc, err
 	}
 	xc.for_user = C.uint64_t(x.ForUser)
+	xc._type = C.libxl_event_type(x.Type)
+	switch x.Type {
+	case EventTypeDomainShutdown:
+		tmp, ok := x.TypeUnion.(EventTypeUnionDomainShutdown)
+		if !ok {
+			C.libxl_event_dispose(&xc)
+			return xc, errors.New("wrong type for union key type")
+		}
+		var domain_shutdown C.libxl_event_type_union_domain_shutdown
+		domain_shutdown.shutdown_reason = C.uint8_t(tmp.ShutdownReason)
+		domain_shutdownBytes := C.GoBytes(unsafe.Pointer(&domain_shutdown), C.sizeof_libxl_event_type_union_domain_shutdown)
+		copy(xc.u[:], domain_shutdownBytes)
+	case EventTypeDiskEject:
+		tmp, ok := x.TypeUnion.(EventTypeUnionDiskEject)
+		if !ok {
+			C.libxl_event_dispose(&xc)
+			return xc, errors.New("wrong type for union key type")
+		}
+		var disk_eject C.libxl_event_type_union_disk_eject
+		disk_eject.vdev = C.CString(tmp.Vdev)
+		disk_eject.disk, err = tmp.Disk.toC()
+		if err != nil {
+			C.libxl_event_dispose(&xc)
+			return xc, err
+		}
+		disk_ejectBytes := C.GoBytes(unsafe.Pointer(&disk_eject), C.sizeof_libxl_event_type_union_disk_eject)
+		copy(xc.u[:], disk_ejectBytes)
+	case EventTypeOperationComplete:
+		tmp, ok := x.TypeUnion.(EventTypeUnionOperationComplete)
+		if !ok {
+			C.libxl_event_dispose(&xc)
+			return xc, errors.New("wrong type for union key type")
+		}
+		var operation_complete C.libxl_event_type_union_operation_complete
+		operation_complete.rc = C.int(tmp.Rc)
+		operation_completeBytes := C.GoBytes(unsafe.Pointer(&operation_complete), C.sizeof_libxl_event_type_union_operation_complete)
+		copy(xc.u[:], operation_completeBytes)
+	default:
+		return xc, fmt.Errorf("invalid union key '%v'", x.Type)
+	}
 	return xc, nil
 }
 
@@ -2716,5 +3012,34 @@ func (x *PsrHwInfoTypeUnionMba) fromC(xc *C.libxl_psr_hw_info) error {
 func (x *PsrHwInfo) toC() (xc C.libxl_psr_hw_info, err error) {
 	C.libxl_psr_hw_info_init(&xc)
 	xc.id = C.uint32_t(x.Id)
+	xc._type = C.libxl_psr_feat_type(x.Type)
+	switch x.Type {
+	case PsrFeatTypeCat:
+		tmp, ok := x.TypeUnion.(PsrHwInfoTypeUnionCat)
+		if !ok {
+			C.libxl_psr_hw_info_dispose(&xc)
+			return xc, errors.New("wrong type for union key type")
+		}
+		var cat C.libxl_psr_hw_info_type_union_cat
+		cat.cos_max = C.uint32_t(tmp.CosMax)
+		cat.cbm_len = C.uint32_t(tmp.CbmLen)
+		cat.cdp_enabled = C.bool(tmp.CdpEnabled)
+		catBytes := C.GoBytes(unsafe.Pointer(&cat), C.sizeof_libxl_psr_hw_info_type_union_cat)
+		copy(xc.u[:], catBytes)
+	case PsrFeatTypeMba:
+		tmp, ok := x.TypeUnion.(PsrHwInfoTypeUnionMba)
+		if !ok {
+			C.libxl_psr_hw_info_dispose(&xc)
+			return xc, errors.New("wrong type for union key type")
+		}
+		var mba C.libxl_psr_hw_info_type_union_mba
+		mba.cos_max = C.uint32_t(tmp.CosMax)
+		mba.thrtl_max = C.uint32_t(tmp.ThrtlMax)
+		mba.linear = C.bool(tmp.Linear)
+		mbaBytes := C.GoBytes(unsafe.Pointer(&mba), C.sizeof_libxl_psr_hw_info_type_union_mba)
+		copy(xc.u[:], mbaBytes)
+	default:
+		return xc, fmt.Errorf("invalid union key '%v'", x.Type)
+	}
 	return xc, nil
 }
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 21/24] golang/xenlight: implement array Go to C marshaling
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (19 preceding siblings ...)
  2019-10-07 15:13 ` [Xen-devel] [PATCH 20/24] golang/xenlight: implement keyed union Go to C marshaling Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-10-07 15:13 ` [Xen-devel] [PATCH 22/24] golang/xenlight: revise use of Context type Nick Rosbrook
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/gengotypes.py       |  44 ++-
 tools/golang/xenlight/xenlight_helpers.go | 359 ++++++++++++++++++++++
 2 files changed, 402 insertions(+), 1 deletion(-)

diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
index 35d9dfea40..d8a6120e5c 100644
--- a/tools/golang/xenlight/gengotypes.py
+++ b/tools/golang/xenlight/gengotypes.py
@@ -479,7 +479,7 @@ def xenlight_golang_define_to_C(ty = None, typename = None, nested = False):
     for f in ty.fields:
         if f.type.typename is not None:
             if isinstance(f.type, idl.Array):
-                # TODO
+                s += xenlight_golang_array_to_C(f, ty.dispose_fn)
                 continue
 
             gotypename = xenlight_golang_fmt_name(f.type.typename)
@@ -610,6 +610,48 @@ def xenlight_golang_union_to_C(ty = None, union_name = '',
 
     return s
 
+def xenlight_golang_array_to_C(ty = None, dispose_fn = ''):
+    s = ''
+
+    gotypename = xenlight_golang_fmt_name(ty.type.elem_type.typename)
+    goname     = xenlight_golang_fmt_name(ty.name)
+    ctypename  = ty.type.elem_type.typename
+    cname      = ty.name
+    clenvar    = ty.type.lenvar.name
+    golenvar   = xenlight_golang_fmt_name(clenvar,exported=False)
+
+    is_enum = isinstance(ty.type.elem_type,idl.Enumeration)
+    if gotypename in go_builtin_types or is_enum:
+        s += '{} := len(x.{})\n'.format(golenvar,goname)
+        s += 'xc.{} = (*C.{})(C.malloc(C.size_t({}*{})))\n'.format(cname,ctypename,
+                                                                   golenvar,golenvar)
+        s += 'xc.{} = C.int({})\n'.format(clenvar,golenvar)
+        s += 'c{} := (*[1<<28]C.{})(unsafe.Pointer(xc.{}))[:{}:{}]\n'.format(goname,
+                                                                      ctypename,cname,
+                                                                      golenvar,golenvar)
+        s += 'for i,v := range x.{} {{\n'.format(goname)
+        s += 'c{}[i] = C.{}(v)\n'.format(goname,ctypename)
+        s += '}\n'
+
+        return s
+
+    s += '{} := len(x.{})\n'.format(golenvar,goname)
+    s += 'xc.{} = (*C.{})(C.malloc(C.ulong({})*C.sizeof_{}))\n'.format(cname,ctypename,
+                                                                   golenvar,ctypename)
+    s += 'xc.{} = C.int({})\n'.format(clenvar,golenvar)
+    s += 'c{} := (*[1<<28]C.{})(unsafe.Pointer(xc.{}))[:{}:{}]\n'.format(goname,
+                                                                         ctypename,cname,
+                                                                         golenvar,golenvar)
+    s += 'for i,v := range x.{} {{\n'.format(goname)
+    s += 'tmp, err := v.toC()\n'
+    s += 'if err != nil {\n'
+    s += 'C.{}(&xc)\n'.format(dispose_fn)
+    s += 'return xc,err\n}\n'
+    s += 'c{}[i] = tmp\n'.format(goname)
+    s += '}\n'
+
+    return s
+
 def xenlight_golang_fmt_name(name, exported = True):
     """
     Take a given type name and return an
diff --git a/tools/golang/xenlight/xenlight_helpers.go b/tools/golang/xenlight/xenlight_helpers.go
index 2cb5adaec5..7940c209a2 100644
--- a/tools/golang/xenlight/xenlight_helpers.go
+++ b/tools/golang/xenlight/xenlight_helpers.go
@@ -662,6 +662,18 @@ func (x *VcpuSchedParams) fromC(xc *C.libxl_vcpu_sched_params) error {
 func (x *VcpuSchedParams) toC() (xc C.libxl_vcpu_sched_params, err error) {
 	C.libxl_vcpu_sched_params_init(&xc)
 	xc.sched = C.libxl_scheduler(x.Sched)
+	numVcpus := len(x.Vcpus)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_vcpu_sched_params_dispose(&xc)
+			return xc, err
+		}
+		cVcpus[i] = tmp
+	}
 	return xc, nil
 }
 
@@ -710,6 +722,13 @@ func (x *VnodeInfo) fromC(xc *C.libxl_vnode_info) error {
 func (x *VnodeInfo) toC() (xc C.libxl_vnode_info, err error) {
 	C.libxl_vnode_info_init(&xc)
 	xc.memkb = C.uint64_t(x.Memkb)
+	numDistances := len(x.Distances)
+	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)
 	xc.vcpus, err = x.Vcpus.toC()
 	if err != nil {
@@ -1096,6 +1115,30 @@ func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 		C.libxl_domain_build_info_dispose(&xc)
 		return xc, err
 	}
+	numVcpuHardAffinity := len(x.VcpuHardAffinity)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		cVcpuHardAffinity[i] = tmp
+	}
+	numVcpuSoftAffinity := len(x.VcpuSoftAffinity)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		cVcpuSoftAffinity[i] = tmp
+	}
 	xc.numa_placement, err = x.NumaPlacement.toC()
 	if err != nil {
 		C.libxl_domain_build_info_dispose(&xc)
@@ -1125,6 +1168,18 @@ func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 		return xc, err
 	}
 	xc.blkdev_start = C.CString(x.BlkdevStart)
+	numVnumaNodes := len(x.VnumaNodes)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		cVnumaNodes[i] = tmp
+	}
 	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)
@@ -1157,6 +1212,37 @@ func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 		C.libxl_domain_build_info_dispose(&xc)
 		return xc, err
 	}
+	numIoports := len(x.Ioports)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		cIoports[i] = tmp
+	}
+	numIrqs := len(x.Irqs)
+	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)
+	}
+	numIomem := len(x.Iomem)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_build_info_dispose(&xc)
+			return xc, err
+		}
+		cIomem[i] = tmp
+	}
 	xc.claim_mode, err = x.ClaimMode.toC()
 	if err != nil {
 		C.libxl_domain_build_info_dispose(&xc)
@@ -1983,6 +2069,18 @@ func (x *DeviceVdispl) toC() (xc C.libxl_device_vdispl, err error) {
 	xc.backend_domname = C.CString(x.BackendDomname)
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.be_alloc = C.bool(x.BeAlloc)
+	numConnectors := len(x.Connectors)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_device_vdispl_dispose(&xc)
+			return xc, err
+		}
+		cConnectors[i] = tmp
+	}
 	return xc, nil
 }
 
@@ -2007,6 +2105,20 @@ func (x *VsndParams) fromC(xc *C.libxl_vsnd_params) error {
 
 func (x *VsndParams) toC() (xc C.libxl_vsnd_params, err error) {
 	C.libxl_vsnd_params_init(&xc)
+	numSampleRates := len(x.SampleRates)
+	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)
+	}
+	numSampleFormats := len(x.SampleFormats)
+	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)
@@ -2064,6 +2176,18 @@ func (x *VsndPcm) toC() (xc C.libxl_vsnd_pcm, err error) {
 		C.libxl_vsnd_pcm_dispose(&xc)
 		return xc, err
 	}
+	numVsndStreams := len(x.Streams)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_vsnd_pcm_dispose(&xc)
+			return xc, err
+		}
+		cStreams[i] = tmp
+	}
 	return xc, nil
 }
 
@@ -2103,6 +2227,18 @@ func (x *DeviceVsnd) toC() (xc C.libxl_device_vsnd, err error) {
 		C.libxl_device_vsnd_dispose(&xc)
 		return xc, err
 	}
+	numVsndPcms := len(x.Pcms)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_device_vsnd_dispose(&xc)
+			return xc, err
+		}
+		cPcms[i] = tmp
+	}
 	return xc, nil
 }
 
@@ -2287,6 +2423,186 @@ func (x *DomainConfig) toC() (xc C.libxl_domain_config, err error) {
 		C.libxl_domain_config_dispose(&xc)
 		return xc, err
 	}
+	numDisks := len(x.Disks)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cDisks[i] = tmp
+	}
+	numNics := len(x.Nics)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cNics[i] = tmp
+	}
+	numPcidevs := len(x.Pcidevs)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cPcidevs[i] = tmp
+	}
+	numRdms := len(x.Rdms)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cRdms[i] = tmp
+	}
+	numDtdevs := len(x.Dtdevs)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cDtdevs[i] = tmp
+	}
+	numVfbs := len(x.Vfbs)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cVfbs[i] = tmp
+	}
+	numVkbs := len(x.Vkbs)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cVkbs[i] = tmp
+	}
+	numVtpms := len(x.Vtpms)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cVtpms[i] = tmp
+	}
+	numP9S := len(x.P9S)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cP9S[i] = tmp
+	}
+	numPvcallsifs := len(x.Pvcallsifs)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cPvcallsifs[i] = tmp
+	}
+	numVdispls := len(x.Vdispls)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cVdispls[i] = tmp
+	}
+	numVsnds := len(x.Vsnds)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cVsnds[i] = tmp
+	}
+	numChannels := len(x.Channels)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cChannels[i] = tmp
+	}
+	numUsbctrls := len(x.Usbctrls)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cUsbctrls[i] = tmp
+	}
+	numUsbdevs := len(x.Usbdevs)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_domain_config_dispose(&xc)
+			return xc, err
+		}
+		cUsbdevs[i] = tmp
+	}
 	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)
@@ -2566,6 +2882,18 @@ func (x *Vdisplinfo) toC() (xc C.libxl_vdisplinfo, err error) {
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.state = C.int(x.State)
 	xc.be_alloc = C.bool(x.BeAlloc)
+	numConnectors := len(x.Connectors)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_vdisplinfo_dispose(&xc)
+			return xc, err
+		}
+		cConnectors[i] = tmp
+	}
 	return xc, nil
 }
 
@@ -2598,6 +2926,18 @@ func (x *Pcminfo) fromC(xc *C.libxl_pcminfo) error {
 
 func (x *Pcminfo) toC() (xc C.libxl_pcminfo, err error) {
 	C.libxl_pcminfo_init(&xc)
+	numVsndStreams := len(x.Streams)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_pcminfo_dispose(&xc)
+			return xc, err
+		}
+		cStreams[i] = tmp
+	}
 	return xc, nil
 }
 
@@ -2629,6 +2969,18 @@ func (x *Vsndinfo) toC() (xc C.libxl_vsndinfo, err error) {
 	xc.frontend_id = C.uint32_t(x.FrontendId)
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.state = C.int(x.State)
+	numVsndPcms := len(x.Pcms)
+	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 {
+		tmp, err := v.toC()
+		if err != nil {
+			C.libxl_vsndinfo_dispose(&xc)
+			return xc, err
+		}
+		cPcms[i] = tmp
+	}
 	return xc, nil
 }
 
@@ -2673,6 +3025,13 @@ func (x *Numainfo) toC() (xc C.libxl_numainfo, err error) {
 	C.libxl_numainfo_init(&xc)
 	xc.size = C.uint64_t(x.Size)
 	xc.free = C.uint64_t(x.Free)
+	numDists := len(x.Dists)
+	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 xc, nil
 }
 
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 22/24] golang/xenlight: revise use of Context type
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (20 preceding siblings ...)
  2019-10-07 15:13 ` [Xen-devel] [PATCH 21/24] golang/xenlight: implement array " Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-10-07 15:13 ` [Xen-devel] [PATCH 23/24] golang/xenlight: add error return type to Context.Cpupoolinfo Nick Rosbrook
  2019-10-07 15:13 ` [Xen-devel] [PATCH 24/24] golang/xenlight: add make target for generated files Nick Rosbrook
  23 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Remove the exported global context variable, 'Ctx.' Generally, it is
better to not export global variables for use through a Go package.
However, there are some exceptions that can be found in the standard
library.

Add a NewContext function instead, and remove the Open, IsOpen, and
CheckOpen functions as a result.

Also, comment-out an ineffectual assignment to 'err' inside the function
Context.CpupoolInfo so that compilation does not fail.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 219 +++++-------------------------
 1 file changed, 34 insertions(+), 185 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index a8f933c75f..e540b5413d 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -74,6 +74,39 @@ func (e Error) Error() string {
 	return fmt.Sprintf("libxl error: %d", -e)
 }
 
+// Context represents a libxl_ctx.
+type Context struct {
+	ctx    *C.libxl_ctx
+	logger *C.xentoollog_logger_stdiostream
+}
+
+// NewContext returns a new Context.
+func NewContext() (*Context, error) {
+	var ctx Context
+
+	ctx.logger = C.xtl_createlogger_stdiostream(C.stderr, C.XTL_ERROR, 0)
+
+	ret := C.libxl_ctx_alloc(&ctx.ctx, C.LIBXL_VERSION, 0, (*C.xentoollog_logger)(unsafe.Pointer(ctx.logger)))
+	if ret != 0 {
+		return nil, Error(ret)
+	}
+
+	return &ctx, nil
+}
+
+// Close closes the Context.
+func (ctx *Context) Close() error {
+	ret := C.libxl_ctx_free(ctx.ctx)
+	ctx.ctx = nil
+	C.xtl_logger_destroy((*C.xentoollog_logger)(unsafe.Pointer(ctx.logger)))
+
+	if ret != 0 {
+		return Error(ret)
+	}
+
+	return nil
+}
+
 /*
  * Types: Builtins
  */
@@ -299,11 +332,6 @@ func (cpl *CpuidPolicyList) toC() (C.libxl_cpuid_policy_list, error) {
 	return *ccpl, nil
 }
 
-type Context struct {
-	ctx    *C.libxl_ctx
-	logger *C.xentoollog_logger_stdiostream
-}
-
 // Hwcap represents a libxl_hwcap.
 type Hwcap [8]uint32
 
@@ -480,11 +508,6 @@ func SchedulerFromString(name string) (s Scheduler, err error) {
 // libxl_cpupoolinfo * libxl_list_cpupool(libxl_ctx*, int *nb_pool_out);
 // void libxl_cpupoolinfo_list_free(libxl_cpupoolinfo *list, int nb_pool);
 func (Ctx *Context) ListCpupool() (list []Cpupoolinfo) {
-	err := Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	var nbPool C.int
 
 	c_cpupool_list := C.libxl_list_cpupool(Ctx.ctx, &nbPool)
@@ -508,16 +531,11 @@ func (Ctx *Context) ListCpupool() (list []Cpupoolinfo) {
 
 // int libxl_cpupool_info(libxl_ctx *ctx, libxl_cpupoolinfo *info, uint32_t poolid);
 func (Ctx *Context) CpupoolInfo(Poolid uint32) (pool Cpupoolinfo) {
-	err := Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	var c_cpupool C.libxl_cpupoolinfo
 
 	ret := C.libxl_cpupool_info(Ctx.ctx, &c_cpupool, C.uint32_t(Poolid))
 	if ret != 0 {
-		err = Error(-ret)
+		//err = Error(-ret)
 		return
 	}
 	defer C.libxl_cpupoolinfo_dispose(&c_cpupool)
@@ -534,11 +552,6 @@ func (Ctx *Context) CpupoolInfo(Poolid uint32) (pool Cpupoolinfo) {
 // FIXME: uuid
 // FIXME: Setting poolid
 func (Ctx *Context) CpupoolCreate(Name string, Scheduler Scheduler, Cpumap Bitmap) (err error, Poolid uint32) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	poolid := C.uint32_t(C.LIBXL_CPUPOOL_POOLID_ANY)
 	name := C.CString(Name)
 	defer C.free(unsafe.Pointer(name))
@@ -567,11 +580,6 @@ func (Ctx *Context) CpupoolCreate(Name string, Scheduler Scheduler, Cpumap Bitma
 
 // int libxl_cpupool_destroy(libxl_ctx *ctx, uint32_t poolid);
 func (Ctx *Context) CpupoolDestroy(Poolid uint32) (err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ret := C.libxl_cpupool_destroy(Ctx.ctx, C.uint32_t(Poolid))
 	if ret != 0 {
 		err = Error(-ret)
@@ -583,11 +591,6 @@ func (Ctx *Context) CpupoolDestroy(Poolid uint32) (err error) {
 
 // int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu);
 func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) (err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ret := C.libxl_cpupool_cpuadd(Ctx.ctx, C.uint32_t(Poolid), C.int(Cpu))
 	if ret != 0 {
 		err = Error(-ret)
@@ -600,11 +603,6 @@ func (Ctx *Context) CpupoolCpuadd(Poolid uint32, Cpu int) (err error) {
 // int libxl_cpupool_cpuadd_cpumap(libxl_ctx *ctx, uint32_t poolid,
 //                                 const libxl_bitmap *cpumap);
 func (Ctx *Context) CpupoolCpuaddCpumap(Poolid uint32, Cpumap Bitmap) (err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	cbm, err := Cpumap.toC()
 	if err != nil {
 		return
@@ -622,11 +620,6 @@ func (Ctx *Context) CpupoolCpuaddCpumap(Poolid uint32, Cpumap Bitmap) (err error
 
 // int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu);
 func (Ctx *Context) CpupoolCpuremove(Poolid uint32, Cpu int) (err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ret := C.libxl_cpupool_cpuremove(Ctx.ctx, C.uint32_t(Poolid), C.int(Cpu))
 	if ret != 0 {
 		err = Error(-ret)
@@ -639,11 +632,6 @@ func (Ctx *Context) CpupoolCpuremove(Poolid uint32, Cpu int) (err error) {
 // int libxl_cpupool_cpuremove_cpumap(libxl_ctx *ctx, uint32_t poolid,
 //                                    const libxl_bitmap *cpumap);
 func (Ctx *Context) CpupoolCpuremoveCpumap(Poolid uint32, Cpumap Bitmap) (err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	cbm, err := Cpumap.toC()
 	if err != nil {
 		return
@@ -661,11 +649,6 @@ func (Ctx *Context) CpupoolCpuremoveCpumap(Poolid uint32, Cpumap Bitmap) (err er
 
 // int libxl_cpupool_rename(libxl_ctx *ctx, const char *name, uint32_t poolid);
 func (Ctx *Context) CpupoolRename(Name string, Poolid uint32) (err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	name := C.CString(Name)
 	defer C.free(unsafe.Pointer(name))
 
@@ -680,11 +663,6 @@ func (Ctx *Context) CpupoolRename(Name string, Poolid uint32) (err error) {
 
 // int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus);
 func (Ctx *Context) CpupoolCpuaddNode(Poolid uint32, Node int) (Cpus int, err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ccpus := C.int(0)
 
 	ret := C.libxl_cpupool_cpuadd_node(Ctx.ctx, C.uint32_t(Poolid), C.int(Node), &ccpus)
@@ -700,11 +678,6 @@ func (Ctx *Context) CpupoolCpuaddNode(Poolid uint32, Node int) (Cpus int, err er
 
 // int libxl_cpupool_cpuremove_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus);
 func (Ctx *Context) CpupoolCpuremoveNode(Poolid uint32, Node int) (Cpus int, err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ccpus := C.int(0)
 
 	ret := C.libxl_cpupool_cpuremove_node(Ctx.ctx, C.uint32_t(Poolid), C.int(Node), &ccpus)
@@ -720,11 +693,6 @@ func (Ctx *Context) CpupoolCpuremoveNode(Poolid uint32, Node int) (Cpus int, err
 
 // int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid);
 func (Ctx *Context) CpupoolMovedomain(Poolid uint32, Id Domid) (err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ret := C.libxl_cpupool_movedomain(Ctx.ctx, C.uint32_t(Poolid), C.uint32_t(Id))
 	if ret != 0 {
 		err = Error(-ret)
@@ -884,60 +852,8 @@ func (bm Bitmap) String() (s string) {
 	return
 }
 
-/*
- * Context
- */
-var Ctx Context
-
-func (Ctx *Context) IsOpen() bool {
-	return Ctx.ctx != nil
-}
-
-func (Ctx *Context) Open() (err error) {
-	if Ctx.ctx != nil {
-		return
-	}
-
-	Ctx.logger = C.xtl_createlogger_stdiostream(C.stderr, C.XTL_ERROR, 0)
-	if Ctx.logger == nil {
-		err = fmt.Errorf("Cannot open stdiostream")
-		return
-	}
-
-	ret := C.libxl_ctx_alloc(&Ctx.ctx, C.LIBXL_VERSION,
-		0, (*C.xentoollog_logger)(unsafe.Pointer(Ctx.logger)))
-
-	if ret != 0 {
-		err = Error(-ret)
-	}
-	return
-}
-
-func (Ctx *Context) Close() (err error) {
-	ret := C.libxl_ctx_free(Ctx.ctx)
-	Ctx.ctx = nil
-
-	if ret != 0 {
-		err = Error(-ret)
-	}
-	C.xtl_logger_destroy((*C.xentoollog_logger)(unsafe.Pointer(Ctx.logger)))
-	return
-}
-
-func (Ctx *Context) CheckOpen() (err error) {
-	if Ctx.ctx == nil {
-		err = fmt.Errorf("Context not opened")
-	}
-	return
-}
-
 //int libxl_get_max_cpus(libxl_ctx *ctx);
 func (Ctx *Context) GetMaxCpus() (maxCpus int, err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ret := C.libxl_get_max_cpus(Ctx.ctx)
 	if ret < 0 {
 		err = Error(-ret)
@@ -949,11 +865,6 @@ func (Ctx *Context) GetMaxCpus() (maxCpus int, err error) {
 
 //int libxl_get_online_cpus(libxl_ctx *ctx);
 func (Ctx *Context) GetOnlineCpus() (onCpus int, err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ret := C.libxl_get_online_cpus(Ctx.ctx)
 	if ret < 0 {
 		err = Error(-ret)
@@ -965,10 +876,6 @@ func (Ctx *Context) GetOnlineCpus() (onCpus int, err error) {
 
 //int libxl_get_max_nodes(libxl_ctx *ctx);
 func (Ctx *Context) GetMaxNodes() (maxNodes int, err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
 	ret := C.libxl_get_max_nodes(Ctx.ctx)
 	if ret < 0 {
 		err = Error(-ret)
@@ -980,10 +887,6 @@ func (Ctx *Context) GetMaxNodes() (maxNodes int, err error) {
 
 //int libxl_get_free_memory(libxl_ctx *ctx, uint64_t *memkb);
 func (Ctx *Context) GetFreeMemory() (memkb uint64, err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
 	var cmem C.uint64_t
 	ret := C.libxl_get_free_memory(Ctx.ctx, &cmem)
 
@@ -999,10 +902,6 @@ func (Ctx *Context) GetFreeMemory() (memkb uint64, err error) {
 
 //int libxl_get_physinfo(libxl_ctx *ctx, libxl_physinfo *physinfo)
 func (Ctx *Context) GetPhysinfo() (physinfo *Physinfo, err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
 	var cphys C.libxl_physinfo
 	C.libxl_physinfo_init(&cphys)
 	defer C.libxl_physinfo_dispose(&cphys)
@@ -1020,11 +919,6 @@ func (Ctx *Context) GetPhysinfo() (physinfo *Physinfo, err error) {
 
 //const libxl_version_info* libxl_get_version_info(libxl_ctx *ctx);
 func (Ctx *Context) GetVersionInfo() (info *VersionInfo, err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	var cinfo *C.libxl_version_info
 
 	cinfo = C.libxl_get_version_info(Ctx.ctx)
@@ -1035,11 +929,6 @@ func (Ctx *Context) GetVersionInfo() (info *VersionInfo, err error) {
 }
 
 func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	var cdi C.libxl_dominfo
 	C.libxl_dominfo_init(&cdi)
 	defer C.libxl_dominfo_dispose(&cdi)
@@ -1057,11 +946,6 @@ func (Ctx *Context) DomainInfo(Id Domid) (di *Dominfo, err error) {
 }
 
 func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ret := C.libxl_domain_unpause(Ctx.ctx, C.uint32_t(Id), nil)
 
 	if ret != 0 {
@@ -1072,11 +956,6 @@ func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
 
 //int libxl_domain_pause(libxl_ctx *ctx, uint32_t domain);
 func (Ctx *Context) DomainPause(id Domid) (err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ret := C.libxl_domain_pause(Ctx.ctx, C.uint32_t(id), nil)
 
 	if ret != 0 {
@@ -1087,11 +966,6 @@ func (Ctx *Context) DomainPause(id Domid) (err error) {
 
 //int libxl_domain_shutdown(libxl_ctx *ctx, uint32_t domid);
 func (Ctx *Context) DomainShutdown(id Domid) (err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ret := C.libxl_domain_shutdown(Ctx.ctx, C.uint32_t(id))
 
 	if ret != 0 {
@@ -1102,11 +976,6 @@ func (Ctx *Context) DomainShutdown(id Domid) (err error) {
 
 //int libxl_domain_reboot(libxl_ctx *ctx, uint32_t domid);
 func (Ctx *Context) DomainReboot(id Domid) (err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	ret := C.libxl_domain_reboot(Ctx.ctx, C.uint32_t(id))
 
 	if ret != 0 {
@@ -1118,11 +987,6 @@ func (Ctx *Context) DomainReboot(id Domid) (err error) {
 //libxl_dominfo * libxl_list_domain(libxl_ctx*, int *nb_domain_out);
 //void libxl_dominfo_list_free(libxl_dominfo *list, int nb_domain);
 func (Ctx *Context) ListDomain() (glist []Dominfo) {
-	err := Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	var nbDomain C.int
 	clist := C.libxl_list_domain(Ctx.ctx, &nbDomain)
 	defer C.libxl_dominfo_list_free(clist, nbDomain)
@@ -1145,11 +1009,6 @@ func (Ctx *Context) ListDomain() (glist []Dominfo) {
 //				int *nb_vcpu, int *nr_cpus_out);
 //void libxl_vcpuinfo_list_free(libxl_vcpuinfo *, int nr_vcpus);
 func (Ctx *Context) ListVcpu(id Domid) (glist []Vcpuinfo) {
-	err := Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	var nbVcpu C.int
 	var nrCpu C.int
 
@@ -1180,11 +1039,6 @@ func (ct ConsoleType) String() (str string) {
 //int libxl_console_get_tty(libxl_ctx *ctx, uint32_t domid, int cons_num,
 //libxl_console_type type, char **path);
 func (Ctx *Context) ConsoleGetTty(id Domid, consNum int, conType ConsoleType) (path string, err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	var cpath *C.char
 	ret := C.libxl_console_get_tty(Ctx.ctx, C.uint32_t(id), C.int(consNum), C.libxl_console_type(conType), &cpath)
 	if ret != 0 {
@@ -1200,11 +1054,6 @@ func (Ctx *Context) ConsoleGetTty(id Domid, consNum int, conType ConsoleType) (p
 //int libxl_primary_console_get_tty(libxl_ctx *ctx, uint32_t domid_vm,
 //					char **path);
 func (Ctx *Context) PrimaryConsoleGetTty(domid uint32) (path string, err error) {
-	err = Ctx.CheckOpen()
-	if err != nil {
-		return
-	}
-
 	var cpath *C.char
 	ret := C.libxl_primary_console_get_tty(Ctx.ctx, C.uint32_t(domid), &cpath)
 	if ret != 0 {
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 23/24] golang/xenlight: add error return type to Context.Cpupoolinfo
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (21 preceding siblings ...)
  2019-10-07 15:13 ` [Xen-devel] [PATCH 22/24] golang/xenlight: revise use of Context type Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-10-07 15:13 ` [Xen-devel] [PATCH 24/24] golang/xenlight: add make target for generated files Nick Rosbrook
  23 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

A previous commit that removed Context.CheckOpen revealed
an ineffectual assignent to err in Context.Cpupoolinfo, as
there is no error return type.

Since it appears that the intent is to return an error here,
add an error return value to the function signature.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/xenlight.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
index e540b5413d..0a4f476451 100644
--- a/tools/golang/xenlight/xenlight.go
+++ b/tools/golang/xenlight/xenlight.go
@@ -530,17 +530,17 @@ func (Ctx *Context) ListCpupool() (list []Cpupoolinfo) {
 }
 
 // int libxl_cpupool_info(libxl_ctx *ctx, libxl_cpupoolinfo *info, uint32_t poolid);
-func (Ctx *Context) CpupoolInfo(Poolid uint32) (pool Cpupoolinfo) {
+func (Ctx *Context) CpupoolInfo(Poolid uint32) (pool Cpupoolinfo, err error) {
 	var c_cpupool C.libxl_cpupoolinfo
 
 	ret := C.libxl_cpupool_info(Ctx.ctx, &c_cpupool, C.uint32_t(Poolid))
 	if ret != 0 {
-		//err = Error(-ret)
+		err = Error(-ret)
 		return
 	}
 	defer C.libxl_cpupoolinfo_dispose(&c_cpupool)
 
-	_ = pool.fromC(&c_cpupool)
+	err = pool.fromC(&c_cpupool)
 
 	return
 }
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* [Xen-devel] [PATCH 24/24] golang/xenlight: add make target for generated files
  2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
                   ` (22 preceding siblings ...)
  2019-10-07 15:13 ` [Xen-devel] [PATCH 23/24] golang/xenlight: add error return type to Context.Cpupoolinfo Nick Rosbrook
@ 2019-10-07 15:13 ` Nick Rosbrook
  2019-10-24 14:26   ` George Dunlap
  23 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-07 15:13 UTC (permalink / raw)
  To: xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, George Dunlap, Wei Liu

From: Nick Rosbrook <rosbrookn@ainfosec.com>

Remove the PKGSOURCES variable since adding xenlight_types.go
and xenlight_helpers.go to this list breaks the rest of the
Makefile.

Add xenlight_%.go target for generated files, and use full
file names within install, uninstall and $(XEN_GOPATH)$(GOXL_PKG_DIR)
rule.

Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
---
Cc: George Dunlap <george.dunlap@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wl@xen.org>

 tools/golang/xenlight/Makefile | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
index 0987305224..821a5d48fa 100644
--- a/tools/golang/xenlight/Makefile
+++ b/tools/golang/xenlight/Makefile
@@ -7,20 +7,22 @@ GOCODE_DIR ?= $(prefix)/share/gocode/
 GOXL_PKG_DIR = /src/$(XEN_GOCODE_URL)/xenlight/
 GOXL_INSTALL_DIR = $(GOCODE_DIR)$(GOXL_PKG_DIR)
 
-# PKGSOURCES: Files which comprise the distributed source package
-PKGSOURCES = xenlight.go
-
 GO ?= go
 
 .PHONY: all
 all: build
 
 .PHONY: package
-package: $(XEN_GOPATH)$(GOXL_PKG_DIR)$(PKGSOURCES)
+package: $(XEN_GOPATH)$(GOXL_PKG_DIR)
 
-$(XEN_GOPATH)/src/$(XEN_GOCODE_URL)/xenlight/$(PKGSOURCES): $(PKGSOURCES)
+$(XEN_GOPATH)/src/$(XEN_GOCODE_URL)/xenlight/: xenlight_%.go
 	$(INSTALL_DIR) $(XEN_GOPATH)$(GOXL_PKG_DIR)
-	$(INSTALL_DATA) $(PKGSOURCES) $(XEN_GOPATH)$(GOXL_PKG_DIR)
+	$(INSTALL_DATA) xenlight.go $(XEN_GOPATH)$(GOXL_PKG_DIR)
+	$(INSTALL_DATA) xenlight_types.go $(XEN_GOPATH)$(GOXL_PKG_DIR)
+	$(INSTALL_DATA) xenlight_helpers.go $(XEN_GOPATH)$(GOXL_PKG_DIR)
+
+xenlight_%.go: gengotypes.py $(XEN_ROOT)/tools/libxl/libxl_types.idl $(XEN_ROOT)/tools/libxl/idl.py
+	XEN_ROOT=$(XEN_ROOT) $(PYTHON) gengotypes.py ../../libxl/libxl_types.idl
 
 # Go will do its own dependency checking, and not actuall go through
 # with the build if none of the input files have changed.
@@ -36,10 +38,14 @@ build: package
 .PHONY: install
 install: build
 	$(INSTALL_DIR) $(DESTDIR)$(GOXL_INSTALL_DIR)
-	$(INSTALL_DATA) $(XEN_GOPATH)$(GOXL_PKG_DIR)$(PKGSOURCES) $(DESTDIR)$(GOXL_INSTALL_DIR)
+	$(install_data) $(xen_gopath)$(goxl_pkg_dir)xenlight.go $(destdir)$(goxl_install_dir)
+	$(install_data) $(xen_gopath)$(goxl_pkg_dir)xenlight_types.go $(destdir)$(goxl_install_dir)
+	$(install_data) $(xen_gopath)$(goxl_pkg_dir)xenlight_helpers.go $(destdir)$(goxl_install_dir)
 
 .PHONY: uninstall
-	rm -f $(addprefix $(DESTDIR)$(GOXL_INSTALL_DIR)/, $(PKGSOURCES))
+	rm -f $(addprefix $(DESTDIR)$(GOXL_INSTALL_DIR)/, xenlight.go)
+	rm -f $(addprefix $(DESTDIR)$(GOXL_INSTALL_DIR)/, xenlight_types.go)
+	rm -f $(addprefix $(DESTDIR)$(GOXL_INSTALL_DIR)/, xenlight_helpers.go)
 
 .PHONY: clean
 clean:
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 01/24] golang/xenlight: fix calls to libxl_domain_unpause/pause
  2019-10-07 15:12 ` [Xen-devel] [PATCH 01/24] golang/xenlight: fix calls to libxl_domain_unpause/pause Nick Rosbrook
@ 2019-10-07 16:39   ` George Dunlap
  2019-10-08  4:17     ` Jürgen Groß
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-10-07 16:39 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel
  Cc: Nick Rosbrook, Ian Jackson, kerriganb, Juergen Gross, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> These functions require a third argument of type const *libxl_asyncop_how.
> 
> Pass nil to fix compilation errors. This will have the effect of
> performing these operations synchronously.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>

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

Juergen, this is actually a bug fix (these lines didn't get updated when
the API changed), so I'm going to check this in later this week if you
don't object.

> ---
> Cc: George Dunlap <george.dunlap@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wl@xen.org>
> 
>  tools/golang/xenlight/xenlight.go | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
> index f5d171c2d5..59b8186a64 100644
> --- a/tools/golang/xenlight/xenlight.go
> +++ b/tools/golang/xenlight/xenlight.go
> @@ -1011,7 +1011,7 @@ func (Ctx *Context) DomainUnpause(Id Domid) (err error) {
>  		return
>  	}
>  
> -	ret := C.libxl_domain_unpause(Ctx.ctx, C.uint32_t(Id))
> +	ret := C.libxl_domain_unpause(Ctx.ctx, C.uint32_t(Id), nil)
>  
>  	if ret != 0 {
>  		err = Error(-ret)
> @@ -1026,7 +1026,7 @@ func (Ctx *Context) DomainPause(id Domid) (err error) {
>  		return
>  	}
>  
> -	ret := C.libxl_domain_pause(Ctx.ctx, C.uint32_t(id))
> +	ret := C.libxl_domain_pause(Ctx.ctx, C.uint32_t(id), nil)
>  
>  	if ret != 0 {
>  		err = Error(-ret)
> 


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 01/24] golang/xenlight: fix calls to libxl_domain_unpause/pause
  2019-10-07 16:39   ` George Dunlap
@ 2019-10-08  4:17     ` Jürgen Groß
  0 siblings, 0 replies; 61+ messages in thread
From: Jürgen Groß @ 2019-10-08  4:17 UTC (permalink / raw)
  To: George Dunlap, Nick Rosbrook, xen-devel
  Cc: Nick Rosbrook, IanJackson, kerriganb, Wei Liu

On 07.10.19 18:39, George Dunlap wrote:
> On 10/7/19 4:12 PM, Nick Rosbrook wrote:
>> From: Nick Rosbrook <rosbrookn@ainfosec.com>
>>
>> These functions require a third argument of type const *libxl_asyncop_how.
>>
>> Pass nil to fix compilation errors. This will have the effect of
>> performing these operations synchronously.
>>
>> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Reviewed-by: George Dunlap <george.dunlap@citrix.com>
> 
> Juergen, this is actually a bug fix (these lines didn't get updated when
> the API changed), so I'm going to check this in later this week if you
> don't object.

Release-acked-by: Juergen Gross <jgross@suse.com>


Juergen

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 24/24] golang/xenlight: add make target for generated files
  2019-10-07 15:13 ` [Xen-devel] [PATCH 24/24] golang/xenlight: add make target for generated files Nick Rosbrook
@ 2019-10-24 14:26   ` George Dunlap
  2019-10-24 18:49     ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-10-24 14:26 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:13 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Remove the PKGSOURCES variable since adding xenlight_types.go
> and xenlight_helpers.go to this list breaks the rest of the
> Makefile.
> 
> Add xenlight_%.go target for generated files, and use full
> file names within install, uninstall and $(XEN_GOPATH)$(GOXL_PKG_DIR)
> rule.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>

Hey Nick!  Thanks for breaking down the series this way -- this is much
easier to review.

One standard practice when making a series is to try to avoid any
regressions, including build regressions, in the middle of the series.
This is particularly helpful to aid in bisections, but in this case it
makes it easier to observe the action of the `gengotypes.py` script (and
how it's meant to be called).

So I would basically make this part of patch 2, except remove references
to xenlight_helpers.go until the patch where that file is generated.

One other comment...

> ---
> Cc: George Dunlap <george.dunlap@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wl@xen.org>
> 
>  tools/golang/xenlight/Makefile | 22 ++++++++++++++--------
>  1 file changed, 14 insertions(+), 8 deletions(-)
> 
> diff --git a/tools/golang/xenlight/Makefile b/tools/golang/xenlight/Makefile
> index 0987305224..821a5d48fa 100644
> --- a/tools/golang/xenlight/Makefile
> +++ b/tools/golang/xenlight/Makefile
> @@ -7,20 +7,22 @@ GOCODE_DIR ?= $(prefix)/share/gocode/
>  GOXL_PKG_DIR = /src/$(XEN_GOCODE_URL)/xenlight/
>  GOXL_INSTALL_DIR = $(GOCODE_DIR)$(GOXL_PKG_DIR)
>  
> -# PKGSOURCES: Files which comprise the distributed source package
> -PKGSOURCES = xenlight.go
> -
>  GO ?= go
>  
>  .PHONY: all
>  all: build
>  
>  .PHONY: package
> -package: $(XEN_GOPATH)$(GOXL_PKG_DIR)$(PKGSOURCES)
> +package: $(XEN_GOPATH)$(GOXL_PKG_DIR)
>  
> -$(XEN_GOPATH)/src/$(XEN_GOCODE_URL)/xenlight/$(PKGSOURCES): $(PKGSOURCES)
> +$(XEN_GOPATH)/src/$(XEN_GOCODE_URL)/xenlight/: xenlight_%.go
>  	$(INSTALL_DIR) $(XEN_GOPATH)$(GOXL_PKG_DIR)
> -	$(INSTALL_DATA) $(PKGSOURCES) $(XEN_GOPATH)$(GOXL_PKG_DIR)
> +	$(INSTALL_DATA) xenlight.go $(XEN_GOPATH)$(GOXL_PKG_DIR)
> +	$(INSTALL_DATA) xenlight_types.go $(XEN_GOPATH)$(GOXL_PKG_DIR)
> +	$(INSTALL_DATA) xenlight_helpers.go $(XEN_GOPATH)$(GOXL_PKG_DIR)

It might be nice to have a naming convention for the generated files
that clues people in to the fact that they're generated (other than the
comment at the top of course).  In libxl, this is done by giving them a
leading underscore (e.g., _libxl_type.h); but the go compiler will
helpfully ignore such files. :-)

The go compiler will also do special things sometimes with things after
a `_`; e.g., "${foo}_test.go" will only be compiled for `go test`,
"${foo}_linux.go" will only be compiled on Linux, and so on.  I'm pretty
sure these names will be safe, but it might be slightly more
future-proof to avoid using an underscore in the names.

What about something like "gentypes.go" or "idltypes.go"?

Just a suggestion.

> +
> +xenlight_%.go: gengotypes.py $(XEN_ROOT)/tools/libxl/libxl_types.idl $(XEN_ROOT)/tools/libxl/idl.py
> +	XEN_ROOT=$(XEN_ROOT) $(PYTHON) gengotypes.py ../../libxl/libxl_types.idl
>  
>  # Go will do its own dependency checking, and not actuall go through
>  # with the build if none of the input files have changed.
> @@ -36,10 +38,14 @@ build: package
>  .PHONY: install
>  install: build
>  	$(INSTALL_DIR) $(DESTDIR)$(GOXL_INSTALL_DIR)
> -	$(INSTALL_DATA) $(XEN_GOPATH)$(GOXL_PKG_DIR)$(PKGSOURCES) $(DESTDIR)$(GOXL_INSTALL_DIR)
> +	$(install_data) $(xen_gopath)$(goxl_pkg_dir)xenlight.go $(destdir)$(goxl_install_dir)
> +	$(install_data) $(xen_gopath)$(goxl_pkg_dir)xenlight_types.go $(destdir)$(goxl_install_dir)
> +	$(install_data) $(xen_gopath)$(goxl_pkg_dir)xenlight_helpers.go $(destdir)$(goxl_install_dir)
>  
>  .PHONY: uninstall
> -	rm -f $(addprefix $(DESTDIR)$(GOXL_INSTALL_DIR)/, $(PKGSOURCES))
> +	rm -f $(addprefix $(DESTDIR)$(GOXL_INSTALL_DIR)/, xenlight.go)
> +	rm -f $(addprefix $(DESTDIR)$(GOXL_INSTALL_DIR)/, xenlight_types.go)
> +	rm -f $(addprefix $(DESTDIR)$(GOXL_INSTALL_DIR)/, xenlight_helpers.go)

Kind of random, but would it make sense to `rm -rf` the whole directory
here instead?

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 02/24] golang/xenlight: generate enum types from IDL
  2019-10-07 15:12 ` [Xen-devel] [PATCH 02/24] golang/xenlight: generate enum types from IDL Nick Rosbrook
@ 2019-10-24 14:35   ` George Dunlap
  0 siblings, 0 replies; 61+ messages in thread
From: George Dunlap @ 2019-10-24 14:35 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Introduce gengotypes.py to generate Go code the from IDL. As a first step,
> implement 'enum' type generation.
> 
> As a result of the newly-generated code, remove the existing, and now
> conflicting definitions in xenlight.go. In the case of the Error type,
> rename the slice 'errors' to 'libxlErrors' so that it does not conflict
> with the standard library package 'errors.' And, negate the values used
> in 'libxlErrors' since the generated error values are negative.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>

This looks good, thanks.  Just needs to be ported after and/or merged
with the Makefile changes from 24/24.

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 03/24] golang/xenlight: define Defbool builtin type
  2019-10-07 15:12 ` [Xen-devel] [PATCH 03/24] golang/xenlight: define Defbool builtin type Nick Rosbrook
@ 2019-10-24 15:17   ` George Dunlap
  0 siblings, 0 replies; 61+ messages in thread
From: George Dunlap @ 2019-10-24 15:17 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Define Defbool as struct analagous to the C type, and define the type
> 'defboolVal' that represent true, false, and default defbool values.
> 
> Implement Set, Unset, SetIfDefault, IsDefault, Val, and String functions
> on Defbool so that the type can be used in Go analagously to how its
> used in C.
> 
> Finally, implement fromC and toC functions.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>

Looks good:

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

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 04/24] golang/xenlight: define Devid type as int
  2019-10-07 15:12 ` [Xen-devel] [PATCH 04/24] golang/xenlight: define Devid type as int Nick Rosbrook
@ 2019-10-24 15:20   ` George Dunlap
  0 siblings, 0 replies; 61+ messages in thread
From: George Dunlap @ 2019-10-24 15:20 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>

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

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 05/24] golang/xenlight: define KeyValueList builtin type
  2019-10-07 15:12 ` [Xen-devel] [PATCH 05/24] golang/xenlight: define KeyValueList builtin type Nick Rosbrook
@ 2019-10-24 16:34   ` George Dunlap
  2019-10-24 19:54     ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-10-24 16:34 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Define KeyValueList builtin type, analagous to libxl_key_value_list as
> map[string]string, and implement its fromC and toC functions.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
> ---
> Cc: George Dunlap <george.dunlap@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wl@xen.org>
> 
>  tools/golang/xenlight/xenlight.go | 33 ++++++++++++++++++++++++++++++-
>  1 file changed, 32 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
> index 4d4fad2a9d..8196a42855 100644
> --- a/tools/golang/xenlight/xenlight.go
> +++ b/tools/golang/xenlight/xenlight.go
> @@ -202,11 +202,42 @@ func (chwcap C.libxl_hwcap) toGo() (ghwcap Hwcap) {
>  	return
>  }
>  
> +// KeyValueList represents a libxl_key_value_list.
> +type KeyValueList map[string]string
> +
> +func (kvl KeyValueList) fromC(ckvl *C.libxl_key_value_list) error {
> +	size := int(C.libxl_key_value_list_length(ckvl))
> +	list := (*[1 << 30]*C.char)(unsafe.Pointer(ckvl))[:size:size]
> +
> +	for i := 0; i < size*2; i += 2 {
> +		kvl[C.GoString(list[i])] = C.GoString(list[i+1])
> +	}

It looks like when you use this, you use patterns like this:

	var keyValueListXsdata KeyValueList
	if err := keyValueListXsdata.fromC(&xc.xsdata); err != nil {

But this never calls make(); so won't this crash with a null pointer
deref?  Or am I missing something?

Would it be better to take a pointer method here, and set `*kvl =
make(map[string]string)` before copying the strings over?

That would also very naturally take care of the case where you called
the .fromC() method twice with two different key value lists.  As it is,
if the caller had to initialize it, you'd get a "clobbered union" of the
two lists (where in the case of duplicate keys, the second value
clobbers the first); this way, you only get the most recent list, which
is probably closer to what you wanted.

Also, when going the other direction, how are callers of, say,
libxl_domain_create_new() supposed to initialize this and fill in values?

Looking through the code -- it seems that this type is somewhat
vestigal.  It's only used for two fields of a single struct, and those
fields aren't actually used by xl or libvirt at the moment; and after
some discussion it was determined that anything they might be used to
achieve should probably be done a different way.

So we *could* actually just `type KeyValueList struct { }`, and punt on
all these initialization questions until such time as it turns out that
they're needed.

On the other hand, I think we may need to actually think about
initializing structures.  You've carefully coded DefBool such that the
"zero" value is undefined; but for DevId, for instance, the "initial"
value is supposed to be -1; but the way it's coded, an uninitialized Go
structure will end up as 0, which may be a valid devid.

At the moment, all implemented methods take scalar arguments; but when
they take structs, having  non-default values means "try to get this
specific devid", as opposed to "just choose a free one for me".

Anyway, perhaps we can think about structure initialization, and
implement it after we do the basic structure /  marshalling implementaiton.

In the mean time, we could either keep the KeyValueList you've
implemented here (perhaps adding a make() to the fromC method, and
having toC return NULL if kvl is NULL), or just replace it with a
placeholder until it's needed.

What do you think?

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 24/24] golang/xenlight: add make target for generated files
  2019-10-24 14:26   ` George Dunlap
@ 2019-10-24 18:49     ` Nick Rosbrook
  2019-11-14 17:19       ` George Dunlap
  0 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-24 18:49 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, xen-devel, kerriganb, Ian Jackson, Wei Liu

> One standard practice when making a series is to try to avoid any
> regressions, including build regressions, in the middle of the series.
> This is particularly helpful to aid in bisections, but in this case it
> makes it easier to observe the action of the `gengotypes.py` script (and
> how it's meant to be called).
>
> So I would basically make this part of patch 2, except remove references
> to xenlight_helpers.go until the patch where that file is generated.

Ah yeah that makes sense, I'll correct this in v2.

> It might be nice to have a naming convention for the generated files
> that clues people in to the fact that they're generated (other than the
> comment at the top of course).  In libxl, this is done by giving them a
> leading underscore (e.g., _libxl_type.h); but the go compiler will
> helpfully ignore such files. :-)
>
> The go compiler will also do special things sometimes with things after
> a `_`; e.g., "${foo}_test.go" will only be compiled for `go test`,
> "${foo}_linux.go" will only be compiled on Linux, and so on.  I'm pretty
> sure these names will be safe, but it might be slightly more
> future-proof to avoid using an underscore in the names.

+1 for a naming convention that says "this file is generated." But,
the only special
cases that I'm aware of for go file name suffixes are "test", and
valid GOOS and GOARCH
values. It's conventional to use underscores for compounded file
names, and unnecessary
to avoid them.

To reference gRPC again, their protobuf compiler writes file names
like 'package.pb.go', where
pb is short for protobuf. So, I think something like
'<name>_generated.go', or '<name>.idl.go'
could work.

> Kind of random, but would it make sense to `rm -rf` the whole directory
> here instead?

Yeah probably :)

-NR

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 05/24] golang/xenlight: define KeyValueList builtin type
  2019-10-24 16:34   ` George Dunlap
@ 2019-10-24 19:54     ` Nick Rosbrook
  2019-10-25 11:26       ` George Dunlap
  0 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-24 19:54 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, xen-devel, kerriganb, Ian Jackson, Wei Liu

> So we *could* actually just `type KeyValueList struct { }`, and punt on
> all these initialization questions until such time as it turns out that
> they're needed.

If there is no clear need for this type to be implemented in the Go
package, then I would be in favor of not doing so. IMO, a smaller,
more focused package is ideal.

> On the other hand, I think we may need to actually think about
> initializing structures.  You've carefully coded DefBool such that the
> "zero" value is undefined; but for DevId, for instance, the "initial"
> value is supposed to be -1; but the way it's coded, an uninitialized Go
> structure will end up as 0, which may be a valid devid.
>
> [...]
>
> Anyway, perhaps we can think about structure initialization, and
> implement it after we do the basic structure /  marshalling implementaiton.

That's probably best. However, at a quick glance it seems like it
would be pretty straight-forward to generate NewStructType functions
analogous to libxl_struct_type_init, if that's the desired behavior.

> In the mean time, we could either keep the KeyValueList you've
> implemented here (perhaps adding a make() to the fromC method, and
> having toC return NULL if kvl is NULL), or just replace it with a
> placeholder until it's needed.
>
> What do you think?

Based on what you said above, I think I would like to drop the
implementation for now. But, if we keep the current implementation, I
will make those corrections.

-NR

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 05/24] golang/xenlight: define KeyValueList builtin type
  2019-10-24 19:54     ` Nick Rosbrook
@ 2019-10-25 11:26       ` George Dunlap
  2019-10-25 12:30         ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-10-25 11:26 UTC (permalink / raw)
  To: Nick Rosbrook; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Wei Liu, Ian Jackson



> On Oct 24, 2019, at 8:54 PM, Nick Rosbrook <rosbrookn@gmail.com> wrote:
> 
>> So we *could* actually just `type KeyValueList struct { }`, and punt on
>> all these initialization questions until such time as it turns out that
>> they're needed.
> 
> If there is no clear need for this type to be implemented in the Go
> package, then I would be in favor of not doing so. IMO, a smaller,
> more focused package is ideal.

Ok, in that case let’s just leave the struct empty.

> 
>> On the other hand, I think we may need to actually think about
>> initializing structures.  You've carefully coded DefBool such that the
>> "zero" value is undefined; but for DevId, for instance, the "initial"
>> value is supposed to be -1; but the way it's coded, an uninitialized Go
>> structure will end up as 0, which may be a valid devid.
>> 
>> [...]
>> 
>> Anyway, perhaps we can think about structure initialization, and
>> implement it after we do the basic structure /  marshalling implementaiton.
> 
> That's probably best. However, at a quick glance it seems like it
> would be pretty straight-forward to generate NewStructType functions
> analogous to libxl_struct_type_init, if that's the desired behavior.

I think we basically have three options:

1. Try to arrange it so that the “zero” values correspond to “default” values in libxl; i.e., have DevID 0 -> libxl_devid -1, DevID 1 -> libxl_devid 0, &c

2. Add NewStructType functions

3. Add .Init() methods to structs

#1 I think is probably too risky; so 2 or 3 (or maybe both) will probably be needed.  The NewStructType() seems to be more standard.  But I’m open so suggestions. :-)

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 05/24] golang/xenlight: define KeyValueList builtin type
  2019-10-25 11:26       ` George Dunlap
@ 2019-10-25 12:30         ` Nick Rosbrook
  0 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-10-25 12:30 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Wei Liu, Ian Jackson

> Ok, in that case let’s just leave the struct empty.

Ok, sounds like a plan.

> I think we basically have three options:
>
> 1. Try to arrange it so that the “zero” values correspond to “default” values in libxl; i.e., have DevID 0 -> libxl_devid -1, DevID 1 -> libxl_devid 0, &c
>
> 2. Add NewStructType functions
>
> 3. Add .Init() methods to structs
>
> #1 I think is probably too risky; so 2 or 3 (or maybe both) will probably be needed.  The NewStructType() seems to be more standard.  But I’m open so suggestions. :-)

Option 2 is certainly the standard, and best to avoid confusing
.Init() functions with the special function init(). I'll work on the
implementation as soon as we get this series done :)

-NR

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 06/24] golang/xenlight: re-name Bitmap marshaling functions
  2019-10-07 15:12 ` [Xen-devel] [PATCH 06/24] golang/xenlight: re-name Bitmap marshaling functions Nick Rosbrook
@ 2019-11-13 15:21   ` George Dunlap
  2019-11-13 20:53     ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-11-13 15:21 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Re-name and modify signature of toGo function to fromC. The reason for
> using 'fromC' rather than 'toGo' is that it is not a good idea to define
> methods on the C types. Also, add error return type to Bitmap's toC function.
> 
> Finally, as code-cleanup, re-organize the Bitmap type's comments as per
> Go conventions.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>

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

With one minor comment...


> +func (bm *Bitmap) fromC(cbm *C.libxl_bitmap) error {
> +	// Alloc a Go slice for the bytes
> +	size := int(cbm.size)
> +	bm.bitmap = make([]C.uint8_t, size)
> +
> +	// Make a slice pointing to the C array
> +	mapslice := (*[1 << 30]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]
> +
> +	// And copy the C array into the Go array
> +	copy(bm.bitmap, mapslice)
> +
> +	return nil
> +}
> +
> +func (bm *Bitmap) toC() (C.libxl_bitmap, error) {
> +	var cbm C.libxl_bitmap
> +
> +	size := len(bm.bitmap)
> +	cbm.size = C.uint32_t(size)
> +	cbm._map = (*C.uint8_t)(C.malloc(C.ulong(cbm.size) * C.sizeof_uint8_t))
> +	cslice := (*[1 << 31]C.uint8_t)(unsafe.Pointer(cbm._map))[:size:size]

Any particular reason to use `cslice` here rather than `mapslice` (or
vice versa)?

Not a big deal, but since they're of the came element in the C struct,
it seems like it would be better to give them the same name.  (Don't
have a strong opinion on which one).

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 07/24] golang/xenlight: define StringList builtin type
  2019-10-07 15:12 ` [Xen-devel] [PATCH 07/24] golang/xenlight: define StringList builtin type Nick Rosbrook
@ 2019-11-13 15:37   ` George Dunlap
  2019-11-13 21:14     ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-11-13 15:37 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Define StringList as []string an implement fromC and toC functions.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
> ---
> Cc: George Dunlap <george.dunlap@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wl@xen.org>
> 
>  tools/golang/xenlight/xenlight.go | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
> index 09fcdca5d1..a3a1836d31 100644
> --- a/tools/golang/xenlight/xenlight.go
> +++ b/tools/golang/xenlight/xenlight.go
> @@ -234,6 +234,35 @@ func (kvl KeyValueList) toC() (C.libxl_key_value_list, error) {
>  	return ckvl, nil
>  }
>  
> +// StringList represents a libxl_string_list.
> +type StringList []string
> +
> +func (sl StringList) fromC(csl *C.libxl_string_list) error {
> +	size := int(C.libxl_string_list_length(csl))
> +	list := (*[1 << 30]*C.char)(unsafe.Pointer(csl))[:size:size]
> +
> +	sl = make([]string, size)

Doesn't this method want a pointer receiver?

Everything else looks good.

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 08/24] golang/xenlight: define Mac builtin type
  2019-10-07 15:12 ` [Xen-devel] [PATCH 08/24] golang/xenlight: define Mac " Nick Rosbrook
@ 2019-11-13 15:51   ` George Dunlap
  2019-11-13 21:50     ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-11-13 15:51 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Define Mac as [6]byte and implement fromC, toC, and String functions.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
> ---
> Cc: George Dunlap <george.dunlap@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wl@xen.org>
> 
>  tools/golang/xenlight/xenlight.go | 35 +++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
> 
> diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
> index a3a1836d31..3b7824b284 100644
> --- a/tools/golang/xenlight/xenlight.go
> +++ b/tools/golang/xenlight/xenlight.go
> @@ -181,6 +181,41 @@ func (d *Defbool) toC() (C.libxl_defbool, error) {
>  	return c, nil
>  }
>  
> +// Mac represents a libxl_mac, or simply a MAC address.
> +type Mac [6]byte
> +
> +// String formats a Mac address to string representation.
> +func (mac Mac) String() string {
> +	s := "%x:%x:%x:%x:%x:%x"
> +	opts := make([]interface{}, 6)
> +
> +	for i, v := range mac {
> +		opts[i] = v
> +	}

What's the point of this?

I realize it's slightly annoying to have to type `mac[0], mac[1], ...`,
but I'd rather do that once than make the runtime copy everything over
into a slice of interfaces every String() call.

Also, I guess the format should be "%02x".

> +
> +	return fmt.Sprintf(s, opts...)
> +}
> +
> +func (mac *Mac) fromC(cmac *C.libxl_mac) error {
> +	b := (*[6]C.uint8_t)(unsafe.Pointer(cmac))
> +
> +	for i, v := range b {
> +		mac[i] = byte(v)
> +	}
> +
> +	return nil
> +}
> +
> +func (mac *Mac) toC() (C.libxl_mac, error) {

Conversely, shouldn't this be a value receiver, since we're don't want
this function to change the contents of mac?

Thanks,
 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 09/24] golang/xenlight: define MsVmGenid builtin type
  2019-10-07 15:12 ` [Xen-devel] [PATCH 09/24] golang/xenlight: define MsVmGenid " Nick Rosbrook
@ 2019-11-13 16:20   ` George Dunlap
  0 siblings, 0 replies; 61+ messages in thread
From: George Dunlap @ 2019-11-13 16:20 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Define MsVmGenid as [int(C.LIBXL_MS_VM_GENID_LEN)]byte and implement fromC and toC functions.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
> ---
> Cc: George Dunlap <george.dunlap@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wl@xen.org>
> 
>  tools/golang/xenlight/xenlight.go | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
> 
> diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
> index 3b7824b284..6aca5b89c0 100644
> --- a/tools/golang/xenlight/xenlight.go
> +++ b/tools/golang/xenlight/xenlight.go
> @@ -216,6 +216,29 @@ func (mac *Mac) toC() (C.libxl_mac, error) {
>  	return cmac, nil
>  }
>  
> +// MsVmGenid represents a libxl_ms_vm_genid.
> +type MsVmGenid [int(C.LIBXL_MS_VM_GENID_LEN)]byte
> +
> +func (mvg *MsVmGenid) fromC(cmvg *C.libxl_ms_vm_genid) error {
> +	b := (*[int(C.LIBXL_MS_VM_GENID_LEN)]C.uint8_t)(unsafe.Pointer(&cmvg.bytes[0]))
> +
> +	for i, v := range b {
> +		mvg[i] = byte(v)
> +	}

It's slightly annoying to have to do this loop, but I guess given that
we have to technically cast each element of the array.  Hopefully the
compiler will eventually be able to figure out what's going on here and
just do a memcpy.

> +
> +	return nil
> +}
> +
> +func (mvg *MsVmGenid) toC() (C.libxl_ms_vm_genid, error) {

Hmm, I guess we want a pointer receiver here to make sure we don't end
up doing a 16-byte copy.

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

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 10/24] golang/xenlight: define EvLink builtin as empty struct
  2019-10-07 15:12 ` [Xen-devel] [PATCH 10/24] golang/xenlight: define EvLink builtin as empty struct Nick Rosbrook
@ 2019-11-13 16:23   ` George Dunlap
  0 siblings, 0 replies; 61+ messages in thread
From: George Dunlap @ 2019-11-13 16:23 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Define EvLink as empty struct as there is currently no reason the internal of
> this type should be used in Go.
> 
> Implement fromC and toC functions as no-ops.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>

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

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type
  2019-10-07 15:12 ` [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type Nick Rosbrook
@ 2019-11-13 17:34   ` George Dunlap
  2019-11-14 14:58     ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-11-13 17:34 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Define CpuidPolicyList as a wrapper struct with field val of type
> *C.libxl_cpuid_policy_list and implement fromC and toC functions.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
> ---
> Cc: George Dunlap <george.dunlap@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wl@xen.org>
> 
>  tools/golang/xenlight/xenlight.go | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
> index d41de253f3..9c384485e1 100644
> --- a/tools/golang/xenlight/xenlight.go
> +++ b/tools/golang/xenlight/xenlight.go
> @@ -249,6 +249,26 @@ type EvLink struct{}
>  func (el *EvLink) fromC(cel *C.libxl_ev_link) error      { return nil }
>  func (el *EvLink) toC() (cel C.libxl_ev_link, err error) { return }
>  
> +// CpuidPolicyList represents a libxl_cpuid_policy_list.
> +type CpuidPolicyList struct {
> +	val *C.libxl_cpuid_policy_list
> +}

Hmm, this introduces a pretty significant risk of memory leaks; but I
don't really see any way around it.  I guess we really want to do some
SetFinalizer() magic on this to call libxl_cpuid_dispose()?

We might also want to add something like a .Dispose() method to have
predictable memory effects.  But then do we want to have a .Dispose()
method on all types that might contain a CpuidPolicyList?  Technically
we're supposed to, so we might have to. (And now I'm having deja vu,
like we've had this discussion before, but I can't seem to find it.)

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 12/24] golang/xenlight: re-factor Uuid type implementation
  2019-10-07 15:12 ` [Xen-devel] [PATCH 12/24] golang/xenlight: re-factor Uuid type implementation Nick Rosbrook
@ 2019-11-13 17:47   ` George Dunlap
  0 siblings, 0 replies; 61+ messages in thread
From: George Dunlap @ 2019-11-13 17:47 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:12 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Re-define Uuid as [16]byte and implement fromC, toC, and String functions.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
> ---
> Cc: George Dunlap <george.dunlap@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wl@xen.org>
> 
>  tools/golang/xenlight/xenlight.go | 37 +++++++++++++++++++++++++++++--
>  1 file changed, 35 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
> index 9c384485e1..3e3753f92e 100644
> --- a/tools/golang/xenlight/xenlight.go
> +++ b/tools/golang/xenlight/xenlight.go
> @@ -86,7 +86,40 @@ type Devid int
>  
>  type MemKB uint64
>  
> -type Uuid C.libxl_uuid
> +// Uuid is a domain UUID.
> +type Uuid [16]byte
> +
> +// String formats a Uuid in the form "xxxx-xx-xx-xx-xxxxxx".
> +func (u Uuid) String() string {
> +	s := "%x%x%x%x-%x%x-%x%x-%x%x-%x%x%x%x%x%x"
> +	opts := make([]interface{}, 16)
> +
> +	for i, v := range u {
> +		opts[i] = v
> +	}
> +
> +	return fmt.Sprintf(s, opts...)

*Sigh*  Is there really no better way to do this?  (Not complaining at
you, more at the language really...)

Everything else looks good.

 -George



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 13/24] golang/xenlight: re-factor Hwcap type implementation
  2019-10-07 15:13 ` [Xen-devel] [PATCH 13/24] golang/xenlight: re-factor Hwcap " Nick Rosbrook
@ 2019-11-13 17:58   ` George Dunlap
  0 siblings, 0 replies; 61+ messages in thread
From: George Dunlap @ 2019-11-13 17:58 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:13 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Re-define Hwcap as [8]uint32, and implement toC function. Also, re-name and
> modify signature of toGo function to fromC.
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>

Looks good.  Just one comment...

> ---
> Cc: George Dunlap <george.dunlap@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wl@xen.org>
> 
>  tools/golang/xenlight/xenlight.go | 29 +++++++++++++++++++----------
>  1 file changed, 19 insertions(+), 10 deletions(-)
> 
> diff --git a/tools/golang/xenlight/xenlight.go b/tools/golang/xenlight/xenlight.go
> index 3e3753f92e..8d520bbd98 100644
> --- a/tools/golang/xenlight/xenlight.go
> +++ b/tools/golang/xenlight/xenlight.go
> @@ -307,20 +307,29 @@ type Context struct {
>  	logger *C.xentoollog_logger_stdiostream
>  }
>  
> -type Hwcap []C.uint32_t
> -
> -func (chwcap C.libxl_hwcap) toGo() (ghwcap Hwcap) {
> -	// Alloc a Go slice for the bytes
> -	size := 8
> -	ghwcap = make([]C.uint32_t, size)
> +// Hwcap represents a libxl_hwcap.
> +type Hwcap [8]uint32
>  
> +func (hwcap *Hwcap) fromC(chwcap *C.libxl_hwcap) error {
>  	// Make a slice pointing to the C array
> -	mapslice := (*[1 << 30]C.uint32_t)(unsafe.Pointer(&chwcap[0]))[:size:size]
> +	mapslice := (*[8]C.uint32_t)(unsafe.Pointer(chwcap))

To be pedantic, this isn't a slice anymore. :-)  Do you want to change
this to 'b' (or maybe 'u' or something like that) and fix the comment?

With that changed:

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

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 06/24] golang/xenlight: re-name Bitmap marshaling functions
  2019-11-13 15:21   ` George Dunlap
@ 2019-11-13 20:53     ` Nick Rosbrook
  2019-11-14 11:44       ` George Dunlap
  0 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-11-13 20:53 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

> Any particular reason to use `cslice` here rather than `mapslice` (or
> vice versa)?
>
> Not a big deal, but since they're of the came element in the C struct,
> it seems like it would be better to give them the same name.  (Don't
> have a strong opinion on which one).

IIRC, I found the name `mapslice` a little confusing, since it wasn't
of type []map[T1]T2. But, as to the inconsistent naming between the
two functions, I agree. I'll name them both `cslice`.

-NR

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 07/24] golang/xenlight: define StringList builtin type
  2019-11-13 15:37   ` George Dunlap
@ 2019-11-13 21:14     ` Nick Rosbrook
  0 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-11-13 21:14 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

> Doesn't this method want a pointer receiver?

Yes, since I'm allocating a new slice. If I wasn't allocating a new
slice, this would be okay since the slice contains a pointer to the
underlying array.

-NR

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 08/24] golang/xenlight: define Mac builtin type
  2019-11-13 15:51   ` George Dunlap
@ 2019-11-13 21:50     ` Nick Rosbrook
  2019-11-14 12:27       ` George Dunlap
  0 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-11-13 21:50 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

> What's the point of this?
>
> I realize it's slightly annoying to have to type `mac[0], mac[1], ...`,
> but I'd rather do that once than make the runtime copy everything over
> into a slice of interfaces every String() call.

As I think you realized by looking at subsequent patches, this is to
get around the fact that "an array of an interface type != an array of
type that implements that interface." Since this is a small array, I'm
fine with explicitly passing each element of the array to fmt.Sprintf.

> Also, I guess the format should be "%02x".

Yeah, thanks.

> Conversely, shouldn't this be a value receiver, since we're don't want
> this function to change the contents of mac?

Conventionally receivers are kept consistent between methods of a
type, unless it's implementing some interface like Stringer. And, it's
consistent with the other toC functions which are defined with
pointers in the generated functions since there are some large
structs.

But, yes this could just be a value receiver. I don't have a strong
opinion to keep it as is, so I'll change it.

-NR

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 06/24] golang/xenlight: re-name Bitmap marshaling functions
  2019-11-13 20:53     ` Nick Rosbrook
@ 2019-11-14 11:44       ` George Dunlap
  0 siblings, 0 replies; 61+ messages in thread
From: George Dunlap @ 2019-11-14 11:44 UTC (permalink / raw)
  To: Nick Rosbrook; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

On 11/13/19 8:53 PM, Nick Rosbrook wrote:
>> Any particular reason to use `cslice` here rather than `mapslice` (or
>> vice versa)?
>>
>> Not a big deal, but since they're of the came element in the C struct,
>> it seems like it would be better to give them the same name.  (Don't
>> have a strong opinion on which one).
> 
> IIRC, I found the name `mapslice` a little confusing, since it wasn't
> of type []map[T1]T2. But, as to the inconsistent naming between the
> two functions, I agree. I'll name them both `cslice`.

I think I named it that way because it's a slice fake-up of the struct
element `map`.  But it certainly has the risk of confusing people, and
I'm a big believer in absolutely minimizing useless cognitive load. :-)

Another approach might be to just choose a short "metavariable" for this
sort of thing; i.e., if you use `i` and `j`, everyone knows they're
going to be indexes for nested loops.  `cslice` is OK but is probably
longer than necessary.

Anyway, I'll let you paint this bike shed whatever color you want; just
make sure all sheds for the same struct are the same color. ;-)

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 08/24] golang/xenlight: define Mac builtin type
  2019-11-13 21:50     ` Nick Rosbrook
@ 2019-11-14 12:27       ` George Dunlap
  2019-11-14 15:34         ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-11-14 12:27 UTC (permalink / raw)
  To: Nick Rosbrook; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

On 11/13/19 9:50 PM, Nick Rosbrook wrote:
>> What's the point of this?
>>
>> I realize it's slightly annoying to have to type `mac[0], mac[1], ...`,
>> but I'd rather do that once than make the runtime copy everything over
>> into a slice of interfaces every String() call.
> 
> As I think you realized by looking at subsequent patches, this is to
> get around the fact that "an array of an interface type != an array of
> type that implements that interface." Since this is a small array, I'm
> fine with explicitly passing each element of the array to fmt.Sprintf.

Using `mac[0], mac[1], ...` for this one is kind of just on the border
of reasonable, but when I got to a later patch, I felt like `uuid[0],
uuid[1], ... uuid[15]` was a bit much.  And on further reflection, the
fact is that all of these will be changed to interface{} under the hood
by the function call and then reflect'ed to determine their type anyway;
i.e., I'm pretty sure:

    fmt.Sprintf(s, mac[0], mac[1], /* &c */)

from a compiler perspective is basically identical to:

    fmt.Sprintf(s, []interface{}{mac[0], mac[1], /* &c */}...)

So the code you have is probably going to be about equally efficient anyway.

So I guess, unless you feel strongly that using `mac[0], mac[1], ...` is
a better way to go, maybe just leave it the way it is for now.

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 14/24] golang/xenlight: generate structs from the IDL
  2019-10-07 15:13 ` [Xen-devel] [PATCH 14/24] golang/xenlight: generate structs from the IDL Nick Rosbrook
@ 2019-11-14 14:18   ` George Dunlap
  2019-11-14 16:15     ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-11-14 14:18 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:13 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Add struct and keyed union generation to gengotypes.py. For keyed unions,
> use a method similar to gRPC's oneof to interpret C unions as Go types.
> Meaning, for a given struct with a union field, generate a struct for
> each sub-struct defined in the union. Then, define an interface of one
> method which is implemented by each of the defined sub-structs. For
> example:
> 
>   type domainBuildInfoTypeUnion interface {
>           isdomainBuildInfoTypeUnion()
>   }
> 
>   type DomainBuildInfoTypeUnionHvm struct {
>       // HVM-specific fields...
>   }
> 
>   func (x DomainBuildInfoTypeUnionHvm) isdomainBuildInfoTypeUnion() {}
> 
>   type DomainBuildInfoTypeUnionPv struct {
>       // PV-specific fields...
>   }
> 
>   func (x DomainBuildInfoTypeUnionPv) isdomainBuildInfoTypeUnion() {}
> 
>   type DomainBuildInfoTypeUnionPvh struct {
>       // PVH-specific fields...
>   }
> 
>   func (x DomainBuildInfoTypeUnionPvh) isdomainBuildInfoTypeUnion() {}
> 
> Then, remove existing struct definitions in xenlight.go that conflict
> with the generated types, and modify existing marshaling functions to
> align with the new type definitions. Notably, drop "time" package since
> fields of type time.Duration are now of type uint64.

BTW I was discussing with Ian Jackson, and I think at some point it
would be worth considering adding in an annotation or something to the
IDL such that the generator can use time.Duration for these things.
That opens up another can of works, like  the fact that Duration is
int64 rather than uint64.

But at any rate, that's something to look into *after* this series is
checked in.

The generated code here looks really good -- thanks for the work!  One
comment on the generator...

> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>
> ---
> Cc: George Dunlap <george.dunlap@citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wl@xen.org>
> 
>  tools/golang/xenlight/gengotypes.py     | 103 +++
>  tools/golang/xenlight/xenlight.go       | 123 +---
>  tools/golang/xenlight/xenlight_types.go | 834 ++++++++++++++++++++++++
>  3 files changed, 952 insertions(+), 108 deletions(-)
> 
> diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
> index 59307492cb..c8513b79e0 100644
> --- a/tools/golang/xenlight/gengotypes.py
> +++ b/tools/golang/xenlight/gengotypes.py
> @@ -18,6 +18,10 @@ builtin_type_names = {
>      idl.uint64.typename: 'uint64',
>  }
>  
> +# List of strings that need to be written to a file
> +# after a struct definition.
> +type_extras = []
> +
>  def xenlight_golang_generate_types(path = None, types = None, comment = None):
>      """
>      Generate a .go file (xenlight_types.go by default)
> @@ -35,6 +39,13 @@ def xenlight_golang_generate_types(path = None, types = None, comment = None):
>              f.write(xenlight_golang_type_define(ty))
>              f.write('\n')
>  
> +            # Append extra types
> +            for extra in type_extras:
> +                f.write(extra)
> +                f.write('\n')
> +
> +            del type_extras[:]

So it looks like you've added a global variable, and have the various
functions adding to this global variable in the back-door, and then at
the toplevel "flush" the output and clear it?

This doesn't seem like great software engineering. :-)  Would it be
terribly difficult to refactor things to avoid this?  Perhaps by
returning tuples that are merged together or something?

 -George


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 15/24] golang/xenlight: remove no-longer used type MemKB
  2019-10-07 15:13 ` [Xen-devel] [PATCH 15/24] golang/xenlight: remove no-longer used type MemKB Nick Rosbrook
@ 2019-11-14 14:18   ` George Dunlap
  0 siblings, 0 replies; 61+ messages in thread
From: George Dunlap @ 2019-11-14 14:18 UTC (permalink / raw)
  To: Nick Rosbrook, xen-devel; +Cc: Nick Rosbrook, Ian Jackson, kerriganb, Wei Liu

On 10/7/19 4:13 PM, Nick Rosbrook wrote:
> From: Nick Rosbrook <rosbrookn@ainfosec.com>
> 
> Signed-off-by: Nick Rosbrook <rosbrookn@ainfosec.com>

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

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type
  2019-11-13 17:34   ` George Dunlap
@ 2019-11-14 14:58     ` Nick Rosbrook
  2019-11-14 17:44       ` George Dunlap
  0 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-11-14 14:58 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

> Hmm, this introduces a pretty significant risk of memory leaks; but I
> don't really see any way around it.  I guess we really want to do some
> SetFinalizer() magic on this to call libxl_cpuid_dispose()?
>
> We might also want to add something like a .Dispose() method to have
> predictable memory effects.  But then do we want to have a .Dispose()
> method on all types that might contain a CpuidPolicyList?  Technically
> we're supposed to, so we might have to. (And now I'm having deja vu,
> like we've had this discussion before, but I can't seem to find it.)

As I've expressed before, I don't think its a good idea to look to the
runtime to fix this sort of problem, so I'd be more inclined to look
into a Dispose like option. But then it does seem weird from an API
perspective to only define Dispose on some types since it introduces a
closer, but incomplete, semantic relationship between libxl and the Go
package.

WRT the definition of CpuidPolicyList, is the best we can do? Or is
there a way we can hide the use of the C type better so that someone
using this package doesn't need to worry about calling Dispose or
otherwise? I think [1] is where we originally discussed this.

-NR

[1] https://lists.xenproject.org/archives/html/xen-devel/2019-09/msg01112.html

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 08/24] golang/xenlight: define Mac builtin type
  2019-11-14 12:27       ` George Dunlap
@ 2019-11-14 15:34         ` Nick Rosbrook
  0 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-11-14 15:34 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

> So the code you have is probably going to be about equally efficient anyway.

A quick benchmark [1] shows:

goos: linux
goarch: amd64
BenchmarkString1-8        5000000           251 ns/op
BenchmarkString2-8        5000000           247 ns/op

So yes, they're about the same :)

I'll leave it as is.

-NR

[1] https://play.golang.org/p/2cOzBpoTfgE

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 14/24] golang/xenlight: generate structs from the IDL
  2019-11-14 14:18   ` George Dunlap
@ 2019-11-14 16:15     ` Nick Rosbrook
  0 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-11-14 16:15 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

> BTW I was discussing with Ian Jackson, and I think at some point it
> would be worth considering adding in an annotation or something to the
> IDL such that the generator can use time.Duration for these things.
> That opens up another can of works, like  the fact that Duration is
> int64 rather than uint64.
>
> But at any rate, that's something to look into *after* this series is
> checked in.

Add it to the list! :)

> This doesn't seem like great software engineering. :-)  Would it be
> terribly difficult to refactor things to avoid this?  Perhaps by
> returning tuples that are merged together or something?

No, I don't think this would be difficult to re-factor. I think either
just returning a list of strings, or some n-tuple as you suggest would
be fine.

-NR

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 24/24] golang/xenlight: add make target for generated files
  2019-10-24 18:49     ` Nick Rosbrook
@ 2019-11-14 17:19       ` George Dunlap
  0 siblings, 0 replies; 61+ messages in thread
From: George Dunlap @ 2019-11-14 17:19 UTC (permalink / raw)
  To: Nick Rosbrook; +Cc: Nick Rosbrook, xen-devel, kerriganb, Ian Jackson, Wei Liu

On 10/24/19 7:49 PM, Nick Rosbrook wrote:
>> One standard practice when making a series is to try to avoid any
>> regressions, including build regressions, in the middle of the series.
>> This is particularly helpful to aid in bisections, but in this case it
>> makes it easier to observe the action of the `gengotypes.py` script (and
>> how it's meant to be called).
>>
>> So I would basically make this part of patch 2, except remove references
>> to xenlight_helpers.go until the patch where that file is generated.
> 
> Ah yeah that makes sense, I'll correct this in v2.
> 
>> It might be nice to have a naming convention for the generated files
>> that clues people in to the fact that they're generated (other than the
>> comment at the top of course).  In libxl, this is done by giving them a
>> leading underscore (e.g., _libxl_type.h); but the go compiler will
>> helpfully ignore such files. :-)
>>
>> The go compiler will also do special things sometimes with things after
>> a `_`; e.g., "${foo}_test.go" will only be compiled for `go test`,
>> "${foo}_linux.go" will only be compiled on Linux, and so on.  I'm pretty
>> sure these names will be safe, but it might be slightly more
>> future-proof to avoid using an underscore in the names.
> 
> +1 for a naming convention that says "this file is generated." But,
> the only special
> cases that I'm aware of for go file name suffixes are "test", and
> valid GOOS and GOARCH
> values. It's conventional to use underscores for compounded file
> names, and unnecessary
> to avoid them.
> 
> To reference gRPC again, their protobuf compiler writes file names
> like 'package.pb.go', where
> pb is short for protobuf. So, I think something like
> '<name>_generated.go', or '<name>.idl.go'
> could work.

Both of those are OK.  I might go with "gen_*.go" to be a bit shorter,
or ".idlgen.go" to make it clear that this is /generated from/ and idl,
and not an idl itself.  But I don't have strong opinions; any of those
four options would be fine with me.

 -George




_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type
  2019-11-14 14:58     ` Nick Rosbrook
@ 2019-11-14 17:44       ` George Dunlap
  2019-11-15 15:26         ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-11-14 17:44 UTC (permalink / raw)
  To: Nick Rosbrook; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

On 11/14/19 2:58 PM, Nick Rosbrook wrote:
>> Hmm, this introduces a pretty significant risk of memory leaks; but I
>> don't really see any way around it.  I guess we really want to do some
>> SetFinalizer() magic on this to call libxl_cpuid_dispose()?
>>
>> We might also want to add something like a .Dispose() method to have
>> predictable memory effects.  But then do we want to have a .Dispose()
>> method on all types that might contain a CpuidPolicyList?  Technically
>> we're supposed to, so we might have to. (And now I'm having deja vu,
>> like we've had this discussion before, but I can't seem to find it.)
> 
> As I've expressed before, I don't think its a good idea to look to the
> runtime to fix this sort of problem, so I'd be more inclined to look
> into a Dispose like option. But then it does seem weird from an API
> perspective to only define Dispose on some types since it introduces a
> closer, but incomplete, semantic relationship between libxl and the Go
> package.
> 
> WRT the definition of CpuidPolicyList, is the best we can do? Or is
> there a way we can hide the use of the C type better so that someone
> using this package doesn't need to worry about calling Dispose or
> otherwise? I think [1] is where we originally discussed this.

If we do have to keep the C pointer around for some reason, I think
using SetFinalizer is a necessary backstop to keep the library from
leaking.  It's all well and good to say, "Make sure you call Dispose()",
but I think for a GC'd language that's just going to be too easy to
forget; and it will be a huge pain for long-running processes.

It is pretty annoying; and this is really the *only* type that has this
"opaque structure behind a pointer" property.

If we didn't have this type as a type, we'd have to avoid somehow
exposing the user to the functions which take and use it.  The main
place it's used ATM is in DomainBuildInfo.  We could explore whether it
would be practical to "implement" CpuidPolicyList as a string, and then
have toC() call libxl_cpuid_parse_config().  Obviously that means
fromC() would fail; but I'm not sure DomainBuildInfo is really a
structure passed "out" of libxl anyway.

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type
  2019-11-14 17:44       ` George Dunlap
@ 2019-11-15 15:26         ` Nick Rosbrook
  2019-11-15 15:42           ` George Dunlap
  0 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-11-15 15:26 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

> If we do have to keep the C pointer around for some reason, I think
> using SetFinalizer is a necessary backstop to keep the library from
> leaking.  It's all well and good to say, "Make sure you call Dispose()",
> but I think for a GC'd language that's just going to be too easy to
> forget; and it will be a huge pain for long-running processes.

I understand your motivation for wanting to make this fool-proof, but
there are plenty of common examples in Go where it's well-understood
that if I call `NewFoo` then I need to `foo.Close()` (defer'd or
otherwise). I don't think that alone is a good enough argument for
turning to SetFinalizer. But, I'm certainly not advocating for the
Dispose option either - as I said I think that would be unfortunate
from an API perspective.

> If we didn't have this type as a type, we'd have to avoid somehow
> exposing the user to the functions which take and use it.  The main
> place it's used ATM is in DomainBuildInfo.  We could explore whether it
> would be practical to "implement" CpuidPolicyList as a string, and then
> have toC() call libxl_cpuid_parse_config().  Obviously that means
> fromC() would fail; but I'm not sure DomainBuildInfo is really a
> structure passed "out" of libxl anyway.

It's sounding more and more like we need a way to give types an
"exported/unexported" attribute in the IDL.

Why exactly would fromC be doomed to fail? Just because there is no
`libxl_cpuid_to_string` or otherwise? In any case, I think defining it
as a string may be a good intermediate option for now (even if it
means fromC has to be a no-op). That way we can ensure calls to
`libxl_cpuid_dipose` as usual.

-NR

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type
  2019-11-15 15:26         ` Nick Rosbrook
@ 2019-11-15 15:42           ` George Dunlap
  2019-11-15 15:51             ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-11-15 15:42 UTC (permalink / raw)
  To: Nick Rosbrook; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

On 11/15/19 3:26 PM, Nick Rosbrook wrote:
>> If we do have to keep the C pointer around for some reason, I think
>> using SetFinalizer is a necessary backstop to keep the library from
>> leaking.  It's all well and good to say, "Make sure you call Dispose()",
>> but I think for a GC'd language that's just going to be too easy to
>> forget; and it will be a huge pain for long-running processes.
> 
> I understand your motivation for wanting to make this fool-proof, but
> there are plenty of common examples in Go where it's well-understood
> that if I call `NewFoo` then I need to `foo.Close()` (defer'd or
> otherwise). I don't think that alone is a good enough argument for
> turning to SetFinalizer. But, I'm certainly not advocating for the
> Dispose option either - as I said I think that would be unfortunate
> from an API perspective.
> 
>> If we didn't have this type as a type, we'd have to avoid somehow
>> exposing the user to the functions which take and use it.  The main
>> place it's used ATM is in DomainBuildInfo.  We could explore whether it
>> would be practical to "implement" CpuidPolicyList as a string, and then
>> have toC() call libxl_cpuid_parse_config().  Obviously that means
>> fromC() would fail; but I'm not sure DomainBuildInfo is really a
>> structure passed "out" of libxl anyway.
> 
> It's sounding more and more like we need a way to give types an
> "exported/unexported" attribute in the IDL.
> 
> Why exactly would fromC be doomed to fail? Just because there is no
> `libxl_cpuid_to_string` or otherwise?

Sorry, I was typing this in a bit of a rush at the end of the day
yesterday. :-)

Yes, that's what I meant: There's basically no way to read a policy from
libxl and then pass it back to libxl (since there's no way to convert
libxl_cpuid_policy_list => CpuidPolicyList => libxl_cpuid_policy_list
again).

But at the moment, a string is the "preferred form of modification" as
it were; so if such a read-modify-write feature were implemented, libxl
would need to add libxl_cpuid_to_string anyway.  (Or give some other
modifiable form.)

> In any case, I think defining it
> as a string may be a good intermediate option for now (even if it
> means fromC has to be a no-op). That way we can ensure calls to
> `libxl_cpuid_dipose` as usual.

Yes, let's do that.

 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type
  2019-11-15 15:42           ` George Dunlap
@ 2019-11-15 15:51             ` Nick Rosbrook
  2019-11-15 15:58               ` George Dunlap
  0 siblings, 1 reply; 61+ messages in thread
From: Nick Rosbrook @ 2019-11-15 15:51 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

> Yes, let's do that.

Okay, will do.

As a point of clarification, should I be waiting until you've reviewed
all patches in v1 before I send v2 of this series? Or do you prefer
that I send a v2 that addresses your review so far?

Thanks,
-NR

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type
  2019-11-15 15:51             ` Nick Rosbrook
@ 2019-11-15 15:58               ` George Dunlap
  2019-11-15 16:06                 ` Nick Rosbrook
  0 siblings, 1 reply; 61+ messages in thread
From: George Dunlap @ 2019-11-15 15:58 UTC (permalink / raw)
  To: Nick Rosbrook; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

On 11/15/19 3:51 PM, Nick Rosbrook wrote:
>> Yes, let's do that.
> 
> Okay, will do.
> 
> As a point of clarification, should I be waiting until you've reviewed
> all patches in v1 before I send v2 of this series? Or do you prefer
> that I send a v2 that addresses your review so far?

On the whole I think sending v2 earlier is better, since I'll have the
discussions more recently in my head, and so will (hopefully) be able to
get an Ack or R-b more quickly.

When the development window is open, stuff can be checked in as it's
reviewed, making the whole thing easier.

To be clear, this is for times when the review of the whole series is
taking longer than a few days.  If I review 3 patches of a 6-patch
series one day, probably better to give me a chance to finish the next
day before sending vN+1. :-)  But if I stall for a few days, go ahead
and resend.

Thanks,
 -George

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

* Re: [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type
  2019-11-15 15:58               ` George Dunlap
@ 2019-11-15 16:06                 ` Nick Rosbrook
  0 siblings, 0 replies; 61+ messages in thread
From: Nick Rosbrook @ 2019-11-15 16:06 UTC (permalink / raw)
  To: George Dunlap; +Cc: Nick Rosbrook, Xen-devel, kerriganb, Ian Jackson, Wei Liu

> On the whole I think sending v2 earlier is better, since I'll have the
> discussions more recently in my head, and so will (hopefully) be able to
> get an Ack or R-b more quickly.
>
> When the development window is open, stuff can be checked in as it's
> reviewed, making the whole thing easier.
>
> To be clear, this is for times when the review of the whole series is
> taking longer than a few days.  If I review 3 patches of a 6-patch
> series one day, probably better to give me a chance to finish the next
> day before sending vN+1. :-)  But if I stall for a few days, go ahead
> and resend.

Okay thanks for the clarification. I'll plan on sending v2 once I make
these changes to CpuidPolicyList.

-NR

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

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

end of thread, other threads:[~2019-11-15 16:07 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-07 15:12 [Xen-devel] [PATCH 00/24] generated Go libxl bindings using IDL Nick Rosbrook
2019-10-07 15:12 ` [Xen-devel] [PATCH 01/24] golang/xenlight: fix calls to libxl_domain_unpause/pause Nick Rosbrook
2019-10-07 16:39   ` George Dunlap
2019-10-08  4:17     ` Jürgen Groß
2019-10-07 15:12 ` [Xen-devel] [PATCH 02/24] golang/xenlight: generate enum types from IDL Nick Rosbrook
2019-10-24 14:35   ` George Dunlap
2019-10-07 15:12 ` [Xen-devel] [PATCH 03/24] golang/xenlight: define Defbool builtin type Nick Rosbrook
2019-10-24 15:17   ` George Dunlap
2019-10-07 15:12 ` [Xen-devel] [PATCH 04/24] golang/xenlight: define Devid type as int Nick Rosbrook
2019-10-24 15:20   ` George Dunlap
2019-10-07 15:12 ` [Xen-devel] [PATCH 05/24] golang/xenlight: define KeyValueList builtin type Nick Rosbrook
2019-10-24 16:34   ` George Dunlap
2019-10-24 19:54     ` Nick Rosbrook
2019-10-25 11:26       ` George Dunlap
2019-10-25 12:30         ` Nick Rosbrook
2019-10-07 15:12 ` [Xen-devel] [PATCH 06/24] golang/xenlight: re-name Bitmap marshaling functions Nick Rosbrook
2019-11-13 15:21   ` George Dunlap
2019-11-13 20:53     ` Nick Rosbrook
2019-11-14 11:44       ` George Dunlap
2019-10-07 15:12 ` [Xen-devel] [PATCH 07/24] golang/xenlight: define StringList builtin type Nick Rosbrook
2019-11-13 15:37   ` George Dunlap
2019-11-13 21:14     ` Nick Rosbrook
2019-10-07 15:12 ` [Xen-devel] [PATCH 08/24] golang/xenlight: define Mac " Nick Rosbrook
2019-11-13 15:51   ` George Dunlap
2019-11-13 21:50     ` Nick Rosbrook
2019-11-14 12:27       ` George Dunlap
2019-11-14 15:34         ` Nick Rosbrook
2019-10-07 15:12 ` [Xen-devel] [PATCH 09/24] golang/xenlight: define MsVmGenid " Nick Rosbrook
2019-11-13 16:20   ` George Dunlap
2019-10-07 15:12 ` [Xen-devel] [PATCH 10/24] golang/xenlight: define EvLink builtin as empty struct Nick Rosbrook
2019-11-13 16:23   ` George Dunlap
2019-10-07 15:12 ` [Xen-devel] [PATCH 11/24] golang/xenlight: define CpuidPolicyList builtin type Nick Rosbrook
2019-11-13 17:34   ` George Dunlap
2019-11-14 14:58     ` Nick Rosbrook
2019-11-14 17:44       ` George Dunlap
2019-11-15 15:26         ` Nick Rosbrook
2019-11-15 15:42           ` George Dunlap
2019-11-15 15:51             ` Nick Rosbrook
2019-11-15 15:58               ` George Dunlap
2019-11-15 16:06                 ` Nick Rosbrook
2019-10-07 15:12 ` [Xen-devel] [PATCH 12/24] golang/xenlight: re-factor Uuid type implementation Nick Rosbrook
2019-11-13 17:47   ` George Dunlap
2019-10-07 15:13 ` [Xen-devel] [PATCH 13/24] golang/xenlight: re-factor Hwcap " Nick Rosbrook
2019-11-13 17:58   ` George Dunlap
2019-10-07 15:13 ` [Xen-devel] [PATCH 14/24] golang/xenlight: generate structs from the IDL Nick Rosbrook
2019-11-14 14:18   ` George Dunlap
2019-11-14 16:15     ` Nick Rosbrook
2019-10-07 15:13 ` [Xen-devel] [PATCH 15/24] golang/xenlight: remove no-longer used type MemKB Nick Rosbrook
2019-11-14 14:18   ` George Dunlap
2019-10-07 15:13 ` [Xen-devel] [PATCH 16/24] golang/xenlight: begin C to Go type marshaling Nick Rosbrook
2019-10-07 15:13 ` [Xen-devel] [PATCH 17/24] golang/xenlight: implement keyed union C to Go marshaling Nick Rosbrook
2019-10-07 15:13 ` [Xen-devel] [PATCH 18/24] golang/xenlight: implement array " Nick Rosbrook
2019-10-07 15:13 ` [Xen-devel] [PATCH 19/24] golang/xenlight: begin Go to C type marshaling Nick Rosbrook
2019-10-07 15:13 ` [Xen-devel] [PATCH 20/24] golang/xenlight: implement keyed union Go to C marshaling Nick Rosbrook
2019-10-07 15:13 ` [Xen-devel] [PATCH 21/24] golang/xenlight: implement array " Nick Rosbrook
2019-10-07 15:13 ` [Xen-devel] [PATCH 22/24] golang/xenlight: revise use of Context type Nick Rosbrook
2019-10-07 15:13 ` [Xen-devel] [PATCH 23/24] golang/xenlight: add error return type to Context.Cpupoolinfo Nick Rosbrook
2019-10-07 15:13 ` [Xen-devel] [PATCH 24/24] golang/xenlight: add make target for generated files Nick Rosbrook
2019-10-24 14:26   ` George Dunlap
2019-10-24 18:49     ` Nick Rosbrook
2019-11-14 17:19       ` George Dunlap

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.