[3/9] golang/xenlight: Convert "" to NULL
diff mbox series

Message ID 20191227163224.4113837-3-george.dunlap@citrix.com
State New
Headers show
Series
  • [1/9] golang/xenlight: Don't try to marshall zero-length arrays
Related show

Commit Message

George Dunlap Dec. 27, 2019, 4:32 p.m. UTC
C.GoString will handle NULL C strings properly, by passing back "".
But C.CString will take an empty Go string and actually generate a
'\0'-terminated empty string.  This confuses libxl, which is expecting
non-values to be NULL, not "".

Only call C.CString if the Go string is non-empty.

Signed-off-by: George Dunlap <george.dunlap@citrix.com>
---
CC: Nick Rosbrook <rosbrookn@ainfosec.com>
---
 tools/golang/xenlight/gengotypes.py  |   6 +-
 tools/golang/xenlight/helpers.gen.go | 628 ++++++++++++++++++++-------
 2 files changed, 475 insertions(+), 159 deletions(-)

Comments

Nick Rosbrook Jan. 4, 2020, 6:25 p.m. UTC | #1
> C.GoString will handle NULL C strings properly, by passing back "".
> But C.CString will take an empty Go string and actually generate a
> '\0'-terminated empty string.  This confuses libxl, which is expecting
> non-values to be NULL, not "".
>
> Only call C.CString if the Go string is non-empty.

Good catch, thanks. This should go in v5 of my series though, right?
The toC code hasn't been checked-in yet.

-NR

Patch
diff mbox series

diff --git a/tools/golang/xenlight/gengotypes.py b/tools/golang/xenlight/gengotypes.py
index 5363ca062d..e4ed4d50f5 100644
--- a/tools/golang/xenlight/gengotypes.py
+++ b/tools/golang/xenlight/gengotypes.py
@@ -487,7 +487,8 @@  def xenlight_golang_define_to_C(ty = None, typename = None, nested = False):
             if is_castable:
                 # Use the cgo helper for converting C strings.
                 if gotypename == 'string':
-                    s += 'xc.{} = C.CString(x.{})\n'.format(cname,goname)
+                    s += 'if x.{} != "" {{\n'.format(goname)
+                    s += 'xc.{} = C.CString(x.{})\n}}\n'.format(cname,goname)
                     continue
 
                 s += 'xc.{} = C.{}(x.{})\n'.format(cname,ctypename,goname)
@@ -569,7 +570,8 @@  def xenlight_golang_union_to_C(ty = None, union_name = '',
                 s += 'return xc,err \n}\n'
 
             elif gotypename == 'string':
-                s += '{}.{} = C.CString(tmp.{})\n'.format(f.name,uf.name,gofname)
+                s += 'if tmp.{} != "" {{\n'.format(gofname)
+                s += '{}.{} = C.CString(tmp.{})\n}}\n'.format(f.name,uf.name,gofname)
 
             else:
                 s += '{}.{} = C.{}(tmp.{})\n'.format(f.name,uf.name,ctypename,gofname)
diff --git a/tools/golang/xenlight/helpers.gen.go b/tools/golang/xenlight/helpers.gen.go
index 61cd73595e..2236222cc2 100644
--- a/tools/golang/xenlight/helpers.gen.go
+++ b/tools/golang/xenlight/helpers.gen.go
@@ -93,8 +93,12 @@  func (x *VncInfo) toC() (xc C.libxl_vnc_info, err error) {
 		C.libxl_vnc_info_dispose(&xc)
 		return xc, err
 	}
-	xc.listen = C.CString(x.Listen)
-	xc.passwd = C.CString(x.Passwd)
+	if x.Listen != "" {
+		xc.listen = C.CString(x.Listen)
+	}
+	if x.Passwd != "" {
+		xc.passwd = C.CString(x.Passwd)
+	}
 	xc.display = C.int(x.Display)
 	xc.findunused, err = x.Findunused.toC()
 	if err != nil {
@@ -140,13 +144,17 @@  func (x *SpiceInfo) toC() (xc C.libxl_spice_info, err error) {
 	}
 	xc.port = C.int(x.Port)
 	xc.tls_port = C.int(x.TlsPort)
-	xc.host = C.CString(x.Host)
+	if x.Host != "" {
+		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)
+	if x.Passwd != "" {
+		xc.passwd = C.CString(x.Passwd)
+	}
 	xc.agent_mouse, err = x.AgentMouse.toC()
 	if err != nil {
 		C.libxl_spice_info_dispose(&xc)
@@ -163,8 +171,12 @@  func (x *SpiceInfo) toC() (xc C.libxl_spice_info, err error) {
 		return xc, err
 	}
 	xc.usbredirection = C.int(x.Usbredirection)
-	xc.image_compression = C.CString(x.ImageCompression)
-	xc.streaming_video = C.CString(x.StreamingVideo)
+	if x.ImageCompression != "" {
+		xc.image_compression = C.CString(x.ImageCompression)
+	}
+	if x.StreamingVideo != "" {
+		xc.streaming_video = C.CString(x.StreamingVideo)
+	}
 	return xc, nil
 }
 
@@ -193,8 +205,12 @@  func (x *SdlInfo) toC() (xc C.libxl_sdl_info, err error) {
 		C.libxl_sdl_info_dispose(&xc)
 		return xc, err
 	}
-	xc.display = C.CString(x.Display)
-	xc.xauthority = C.CString(x.Xauthority)
+	if x.Display != "" {
+		xc.display = C.CString(x.Display)
+	}
+	if x.Xauthority != "" {
+		xc.xauthority = C.CString(x.Xauthority)
+	}
 	return xc, nil
 }
 
@@ -235,7 +251,9 @@  func (x *Dominfo) toC() (xc C.libxl_dominfo, err error) {
 	}
 	xc.domid = C.libxl_domid(x.Domid)
 	xc.ssidref = C.uint32_t(x.Ssidref)
-	xc.ssid_label = C.CString(x.SsidLabel)
+	if x.SsidLabel != "" {
+		xc.ssid_label = C.CString(x.SsidLabel)
+	}
 	xc.running = C.bool(x.Running)
 	xc.blocked = C.bool(x.Blocked)
 	xc.paused = C.bool(x.Paused)
@@ -271,7 +289,9 @@  func (x *Cpupoolinfo) fromC(xc *C.libxl_cpupoolinfo) error {
 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)
+	if x.PoolName != "" {
+		xc.pool_name = C.CString(x.PoolName)
+	}
 	xc.sched = C.libxl_scheduler(x.Sched)
 	xc.n_dom = C.uint32_t(x.NDom)
 	xc.cpumap, err = x.Cpumap.toC()
@@ -318,9 +338,13 @@  func (x *ChannelinfoConnectionUnionPty) fromC(xc *C.libxl_channelinfo) error {
 
 func (x *Channelinfo) toC() (xc C.libxl_channelinfo, err error) {
 	C.libxl_channelinfo_init(&xc)
-	xc.backend = C.CString(x.Backend)
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
 	xc.backend_id = C.uint32_t(x.BackendId)
-	xc.frontend = C.CString(x.Frontend)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
 	xc.frontend_id = C.uint32_t(x.FrontendId)
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.state = C.int(x.State)
@@ -335,7 +359,9 @@  func (x *Channelinfo) toC() (xc C.libxl_channelinfo, err error) {
 			return xc, errors.New("wrong type for union key connection")
 		}
 		var pty C.libxl_channelinfo_connection_union_pty
-		pty.path = C.CString(tmp.Path)
+		if tmp.Path != "" {
+			pty.path = C.CString(tmp.Path)
+		}
 		ptyBytes := C.GoBytes(unsafe.Pointer(&pty), C.sizeof_libxl_channelinfo_connection_union_pty)
 		copy(xc.u[:], ptyBytes)
 	default:
@@ -386,17 +412,35 @@  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)
+	if x.XenVersionExtra != "" {
+		xc.xen_version_extra = C.CString(x.XenVersionExtra)
+	}
+	if x.Compiler != "" {
+		xc.compiler = C.CString(x.Compiler)
+	}
+	if x.CompileBy != "" {
+		xc.compile_by = C.CString(x.CompileBy)
+	}
+	if x.CompileDomain != "" {
+		xc.compile_domain = C.CString(x.CompileDomain)
+	}
+	if x.CompileDate != "" {
+		xc.compile_date = C.CString(x.CompileDate)
+	}
+	if x.Capabilities != "" {
+		xc.capabilities = C.CString(x.Capabilities)
+	}
+	if x.Changeset != "" {
+		xc.changeset = C.CString(x.Changeset)
+	}
 	xc.virt_start = C.uint64_t(x.VirtStart)
 	xc.pagesize = C.int(x.Pagesize)
-	xc.commandline = C.CString(x.Commandline)
-	xc.build_id = C.CString(x.BuildId)
+	if x.Commandline != "" {
+		xc.commandline = C.CString(x.Commandline)
+	}
+	if x.BuildId != "" {
+		xc.build_id = C.CString(x.BuildId)
+	}
 	return xc, nil
 }
 
@@ -447,8 +491,12 @@  func (x *DomainCreateInfo) toC() (xc C.libxl_domain_create_info, err error) {
 		return xc, err
 	}
 	xc.ssidref = C.uint32_t(x.Ssidref)
-	xc.ssid_label = C.CString(x.SsidLabel)
-	xc.name = C.CString(x.Name)
+	if x.SsidLabel != "" {
+		xc.ssid_label = C.CString(x.SsidLabel)
+	}
+	if x.Name != "" {
+		xc.name = C.CString(x.Name)
+	}
 	xc.uuid, err = x.Uuid.toC()
 	if err != nil {
 		C.libxl_domain_create_info_dispose(&xc)
@@ -465,7 +513,9 @@  func (x *DomainCreateInfo) toC() (xc C.libxl_domain_create_info, err error) {
 		return xc, err
 	}
 	xc.poolid = C.uint32_t(x.Poolid)
-	xc.pool_name = C.CString(x.PoolName)
+	if x.PoolName != "" {
+		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)
@@ -495,7 +545,9 @@  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)
+	if x.ColoProxyScript != "" {
+		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)
@@ -1010,7 +1062,9 @@  func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 	xc.iommu_memkb = C.uint64_t(x.IommuMemkb)
 	xc.rtc_timeoffset = C.uint32_t(x.RtcTimeoffset)
 	xc.exec_ssidref = C.uint32_t(x.ExecSsidref)
-	xc.exec_ssid_label = C.CString(x.ExecSsidLabel)
+	if x.ExecSsidLabel != "" {
+		xc.exec_ssid_label = C.CString(x.ExecSsidLabel)
+	}
 	xc.localtime, err = x.Localtime.toC()
 	if err != nil {
 		C.libxl_domain_build_info_dispose(&xc)
@@ -1026,7 +1080,9 @@  func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 		C.libxl_domain_build_info_dispose(&xc)
 		return xc, err
 	}
-	xc.blkdev_start = C.CString(x.BlkdevStart)
+	if x.BlkdevStart != "" {
+		xc.blkdev_start = C.CString(x.BlkdevStart)
+	}
 	if numVnumaNodes := len(x.VnumaNodes); numVnumaNodes > 0 {
 		xc.vnuma_nodes = (*C.libxl_vnode_info)(C.malloc(C.ulong(numVnumaNodes) * C.sizeof_libxl_vnode_info))
 		xc.num_vnuma_nodes = C.int(numVnumaNodes)
@@ -1048,10 +1104,16 @@  func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 		C.libxl_domain_build_info_dispose(&xc)
 		return xc, err
 	}
-	xc.device_model = C.CString(x.DeviceModel)
+	if x.DeviceModel != "" {
+		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)
+	if x.DeviceModelSsidLabel != "" {
+		xc.device_model_ssid_label = C.CString(x.DeviceModelSsidLabel)
+	}
+	if x.DeviceModelUser != "" {
+		xc.device_model_user = C.CString(x.DeviceModelUser)
+	}
 	xc.extra, err = x.Extra.toC()
 	if err != nil {
 		C.libxl_domain_build_info_dispose(&xc)
@@ -1112,16 +1174,26 @@  func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 		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)
+	if x.Kernel != "" {
+		xc.kernel = C.CString(x.Kernel)
+	}
+	if x.Cmdline != "" {
+		xc.cmdline = C.CString(x.Cmdline)
+	}
+	if x.Ramdisk != "" {
+		xc.ramdisk = C.CString(x.Ramdisk)
+	}
+	if x.DeviceTree != "" {
+		xc.device_tree = C.CString(x.DeviceTree)
+	}
 	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)
+	if x.Bootloader != "" {
+		xc.bootloader = C.CString(x.Bootloader)
+	}
 	xc.bootloader_args, err = x.BootloaderArgs.toC()
 	if err != nil {
 		C.libxl_domain_build_info_dispose(&xc)
@@ -1153,7 +1225,9 @@  func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 			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)
+		if tmp.Firmware != "" {
+			hvm.firmware = C.CString(tmp.Firmware)
+		}
 		hvm.bios = C.libxl_bios_type(tmp.Bios)
 		hvm.pae, err = tmp.Pae.toC()
 		if err != nil {
@@ -1205,7 +1279,9 @@  func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 			C.libxl_domain_build_info_dispose(&xc)
 			return xc, err
 		}
-		hvm.timeoffset = C.CString(tmp.Timeoffset)
+		if tmp.Timeoffset != "" {
+			hvm.timeoffset = C.CString(tmp.Timeoffset)
+		}
 		hvm.hpet, err = tmp.Hpet.toC()
 		if err != nil {
 			C.libxl_domain_build_info_dispose(&xc)
@@ -1228,9 +1304,15 @@  func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 			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)
+		if tmp.SystemFirmware != "" {
+			hvm.system_firmware = C.CString(tmp.SystemFirmware)
+		}
+		if tmp.SmbiosFirmware != "" {
+			hvm.smbios_firmware = C.CString(tmp.SmbiosFirmware)
+		}
+		if tmp.AcpiFirmware != "" {
+			hvm.acpi_firmware = C.CString(tmp.AcpiFirmware)
+		}
 		hvm.hdtype = C.libxl_hdtype(tmp.Hdtype)
 		hvm.nographic, err = tmp.Nographic.toC()
 		if err != nil {
@@ -1247,7 +1329,9 @@  func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 			C.libxl_domain_build_info_dispose(&xc)
 			return xc, err
 		}
-		hvm.keymap = C.CString(tmp.Keymap)
+		if tmp.Keymap != "" {
+			hvm.keymap = C.CString(tmp.Keymap)
+		}
 		hvm.sdl, err = tmp.Sdl.toC()
 		if err != nil {
 			C.libxl_domain_build_info_dispose(&xc)
@@ -1264,21 +1348,29 @@  func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 			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)
+		if tmp.Serial != "" {
+			hvm.serial = C.CString(tmp.Serial)
+		}
+		if tmp.Boot != "" {
+			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)
+		if tmp.Usbdevice != "" {
+			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)
+		if tmp.Soundhw != "" {
+			hvm.soundhw = C.CString(tmp.Soundhw)
+		}
 		hvm.xen_platform_pci, err = tmp.XenPlatformPci.toC()
 		if err != nil {
 			C.libxl_domain_build_info_dispose(&xc)
@@ -1316,17 +1408,27 @@  func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 			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)
+		if tmp.Kernel != "" {
+			pv.kernel = C.CString(tmp.Kernel)
+		}
 		pv.slack_memkb = C.uint64_t(tmp.SlackMemkb)
-		pv.bootloader = C.CString(tmp.Bootloader)
+		if tmp.Bootloader != "" {
+			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)
+		if tmp.Cmdline != "" {
+			pv.cmdline = C.CString(tmp.Cmdline)
+		}
+		if tmp.Ramdisk != "" {
+			pv.ramdisk = C.CString(tmp.Ramdisk)
+		}
+		if tmp.Features != "" {
+			pv.features = C.CString(tmp.Features)
+		}
 		pv.e820_host, err = tmp.E820Host.toC()
 		if err != nil {
 			C.libxl_domain_build_info_dispose(&xc)
@@ -1346,9 +1448,15 @@  func (x *DomainBuildInfo) toC() (xc C.libxl_domain_build_info, err error) {
 			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)
+		if tmp.PvshimPath != "" {
+			pvh.pvshim_path = C.CString(tmp.PvshimPath)
+		}
+		if tmp.PvshimCmdline != "" {
+			pvh.pvshim_cmdline = C.CString(tmp.PvshimCmdline)
+		}
+		if tmp.PvshimExtra != "" {
+			pvh.pvshim_extra = C.CString(tmp.PvshimExtra)
+		}
 		pvhBytes := C.GoBytes(unsafe.Pointer(&pvh), C.sizeof_libxl_domain_build_info_type_union_pvh)
 		copy(xc.u[:], pvhBytes)
 	default:
@@ -1378,7 +1486,9 @@  func (x *DeviceVfb) fromC(xc *C.libxl_device_vfb) error {
 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)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.vnc, err = x.Vnc.toC()
 	if err != nil {
@@ -1390,7 +1500,9 @@  func (x *DeviceVfb) toC() (xc C.libxl_device_vfb, err error) {
 		C.libxl_device_vfb_dispose(&xc)
 		return xc, err
 	}
-	xc.keymap = C.CString(x.Keymap)
+	if x.Keymap != "" {
+		xc.keymap = C.CString(x.Keymap)
+	}
 	return xc, nil
 }
 
@@ -1417,10 +1529,14 @@  func (x *DeviceVkb) fromC(xc *C.libxl_device_vkb) error {
 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)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.backend_type = C.libxl_vkb_backend(x.BackendType)
-	xc.unique_id = C.CString(x.UniqueId)
+	if x.UniqueId != "" {
+		xc.unique_id = C.CString(x.UniqueId)
+	}
 	xc.feature_disable_keyboard = C.bool(x.FeatureDisableKeyboard)
 	xc.feature_disable_pointer = C.bool(x.FeatureDisablePointer)
 	xc.feature_abs_pointer = C.bool(x.FeatureAbsPointer)
@@ -1467,12 +1583,20 @@  func (x *DeviceDisk) fromC(xc *C.libxl_device_disk) error {
 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)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	if x.PdevPath != "" {
+		xc.pdev_path = C.CString(x.PdevPath)
+	}
+	if x.Vdev != "" {
+		xc.vdev = C.CString(x.Vdev)
+	}
 	xc.backend = C.libxl_disk_backend(x.Backend)
 	xc.format = C.libxl_disk_format(x.Format)
-	xc.script = C.CString(x.Script)
+	if x.Script != "" {
+		xc.script = C.CString(x.Script)
+	}
 	xc.removable = C.int(x.Removable)
 	xc.readwrite = C.int(x.Readwrite)
 	xc.is_cdrom = C.int(x.IsCdrom)
@@ -1492,11 +1616,19 @@  func (x *DeviceDisk) toC() (xc C.libxl_device_disk, err error) {
 		C.libxl_device_disk_dispose(&xc)
 		return xc, err
 	}
-	xc.colo_host = C.CString(x.ColoHost)
+	if x.ColoHost != "" {
+		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)
+	if x.ColoExport != "" {
+		xc.colo_export = C.CString(x.ColoExport)
+	}
+	if x.ActiveDisk != "" {
+		xc.active_disk = C.CString(x.ActiveDisk)
+	}
+	if x.HiddenDisk != "" {
+		xc.hidden_disk = C.CString(x.HiddenDisk)
+	}
 	return xc, nil
 }
 
@@ -1573,72 +1705,184 @@  func (x *DeviceNic) fromC(xc *C.libxl_device_nic) error {
 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)
+	if x.BackendDomname != "" {
+		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)
+	if x.Model != "" {
+		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)
+	if x.Ip != "" {
+		xc.ip = C.CString(x.Ip)
+	}
+	if x.Bridge != "" {
+		xc.bridge = C.CString(x.Bridge)
+	}
+	if x.Ifname != "" {
+		xc.ifname = C.CString(x.Ifname)
+	}
+	if x.Script != "" {
+		xc.script = C.CString(x.Script)
+	}
 	xc.nictype = C.libxl_nic_type(x.Nictype)
 	xc.rate_bytes_per_interval = C.uint64_t(x.RateBytesPerInterval)
 	xc.rate_interval_usecs = C.uint32_t(x.RateIntervalUsecs)
-	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)
+	if x.Gatewaydev != "" {
+		xc.gatewaydev = C.CString(x.Gatewaydev)
+	}
+	if x.ColoftForwarddev != "" {
+		xc.coloft_forwarddev = C.CString(x.ColoftForwarddev)
+	}
+	if x.ColoSockMirrorId != "" {
+		xc.colo_sock_mirror_id = C.CString(x.ColoSockMirrorId)
+	}
+	if x.ColoSockMirrorIp != "" {
+		xc.colo_sock_mirror_ip = C.CString(x.ColoSockMirrorIp)
+	}
+	if x.ColoSockMirrorPort != "" {
+		xc.colo_sock_mirror_port = C.CString(x.ColoSockMirrorPort)
+	}
+	if x.ColoSockComparePriInId != "" {
+		xc.colo_sock_compare_pri_in_id = C.CString(x.ColoSockComparePriInId)
+	}
+	if x.ColoSockComparePriInIp != "" {
+		xc.colo_sock_compare_pri_in_ip = C.CString(x.ColoSockComparePriInIp)
+	}
+	if x.ColoSockComparePriInPort != "" {
+		xc.colo_sock_compare_pri_in_port = C.CString(x.ColoSockComparePriInPort)
+	}
+	if x.ColoSockCompareSecInId != "" {
+		xc.colo_sock_compare_sec_in_id = C.CString(x.ColoSockCompareSecInId)
+	}
+	if x.ColoSockCompareSecInIp != "" {
+		xc.colo_sock_compare_sec_in_ip = C.CString(x.ColoSockCompareSecInIp)
+	}
+	if x.ColoSockCompareSecInPort != "" {
+		xc.colo_sock_compare_sec_in_port = C.CString(x.ColoSockCompareSecInPort)
+	}
+	if x.ColoSockCompareNotifyId != "" {
+		xc.colo_sock_compare_notify_id = C.CString(x.ColoSockCompareNotifyId)
+	}
+	if x.ColoSockCompareNotifyIp != "" {
+		xc.colo_sock_compare_notify_ip = C.CString(x.ColoSockCompareNotifyIp)
+	}
+	if x.ColoSockCompareNotifyPort != "" {
+		xc.colo_sock_compare_notify_port = C.CString(x.ColoSockCompareNotifyPort)
+	}
+	if x.ColoSockRedirector0Id != "" {
+		xc.colo_sock_redirector0_id = C.CString(x.ColoSockRedirector0Id)
+	}
+	if x.ColoSockRedirector0Ip != "" {
+		xc.colo_sock_redirector0_ip = C.CString(x.ColoSockRedirector0Ip)
+	}
+	if x.ColoSockRedirector0Port != "" {
+		xc.colo_sock_redirector0_port = C.CString(x.ColoSockRedirector0Port)
+	}
+	if x.ColoSockRedirector1Id != "" {
+		xc.colo_sock_redirector1_id = C.CString(x.ColoSockRedirector1Id)
+	}
+	if x.ColoSockRedirector1Ip != "" {
+		xc.colo_sock_redirector1_ip = C.CString(x.ColoSockRedirector1Ip)
+	}
+	if x.ColoSockRedirector1Port != "" {
+		xc.colo_sock_redirector1_port = C.CString(x.ColoSockRedirector1Port)
+	}
+	if x.ColoSockRedirector2Id != "" {
+		xc.colo_sock_redirector2_id = C.CString(x.ColoSockRedirector2Id)
+	}
+	if x.ColoSockRedirector2Ip != "" {
+		xc.colo_sock_redirector2_ip = C.CString(x.ColoSockRedirector2Ip)
+	}
+	if x.ColoSockRedirector2Port != "" {
+		xc.colo_sock_redirector2_port = C.CString(x.ColoSockRedirector2Port)
+	}
+	if x.ColoFilterMirrorQueue != "" {
+		xc.colo_filter_mirror_queue = C.CString(x.ColoFilterMirrorQueue)
+	}
+	if x.ColoFilterMirrorOutdev != "" {
+		xc.colo_filter_mirror_outdev = C.CString(x.ColoFilterMirrorOutdev)
+	}
+	if x.ColoFilterRedirector0Queue != "" {
+		xc.colo_filter_redirector0_queue = C.CString(x.ColoFilterRedirector0Queue)
+	}
+	if x.ColoFilterRedirector0Indev != "" {
+		xc.colo_filter_redirector0_indev = C.CString(x.ColoFilterRedirector0Indev)
+	}
+	if x.ColoFilterRedirector0Outdev != "" {
+		xc.colo_filter_redirector0_outdev = C.CString(x.ColoFilterRedirector0Outdev)
+	}
+	if x.ColoFilterRedirector1Queue != "" {
+		xc.colo_filter_redirector1_queue = C.CString(x.ColoFilterRedirector1Queue)
+	}
+	if x.ColoFilterRedirector1Indev != "" {
+		xc.colo_filter_redirector1_indev = C.CString(x.ColoFilterRedirector1Indev)
+	}
+	if x.ColoFilterRedirector1Outdev != "" {
+		xc.colo_filter_redirector1_outdev = C.CString(x.ColoFilterRedirector1Outdev)
+	}
+	if x.ColoComparePriIn != "" {
+		xc.colo_compare_pri_in = C.CString(x.ColoComparePriIn)
+	}
+	if x.ColoCompareSecIn != "" {
+		xc.colo_compare_sec_in = C.CString(x.ColoCompareSecIn)
+	}
+	if x.ColoCompareOut != "" {
+		xc.colo_compare_out = C.CString(x.ColoCompareOut)
+	}
+	if x.ColoCompareNotifyDev != "" {
+		xc.colo_compare_notify_dev = C.CString(x.ColoCompareNotifyDev)
+	}
+	if x.ColoSockSecRedirector0Id != "" {
+		xc.colo_sock_sec_redirector0_id = C.CString(x.ColoSockSecRedirector0Id)
+	}
+	if x.ColoSockSecRedirector0Ip != "" {
+		xc.colo_sock_sec_redirector0_ip = C.CString(x.ColoSockSecRedirector0Ip)
+	}
+	if x.ColoSockSecRedirector0Port != "" {
+		xc.colo_sock_sec_redirector0_port = C.CString(x.ColoSockSecRedirector0Port)
+	}
+	if x.ColoSockSecRedirector1Id != "" {
+		xc.colo_sock_sec_redirector1_id = C.CString(x.ColoSockSecRedirector1Id)
+	}
+	if x.ColoSockSecRedirector1Ip != "" {
+		xc.colo_sock_sec_redirector1_ip = C.CString(x.ColoSockSecRedirector1Ip)
+	}
+	if x.ColoSockSecRedirector1Port != "" {
+		xc.colo_sock_sec_redirector1_port = C.CString(x.ColoSockSecRedirector1Port)
+	}
+	if x.ColoFilterSecRedirector0Queue != "" {
+		xc.colo_filter_sec_redirector0_queue = C.CString(x.ColoFilterSecRedirector0Queue)
+	}
+	if x.ColoFilterSecRedirector0Indev != "" {
+		xc.colo_filter_sec_redirector0_indev = C.CString(x.ColoFilterSecRedirector0Indev)
+	}
+	if x.ColoFilterSecRedirector0Outdev != "" {
+		xc.colo_filter_sec_redirector0_outdev = C.CString(x.ColoFilterSecRedirector0Outdev)
+	}
+	if x.ColoFilterSecRedirector1Queue != "" {
+		xc.colo_filter_sec_redirector1_queue = C.CString(x.ColoFilterSecRedirector1Queue)
+	}
+	if x.ColoFilterSecRedirector1Indev != "" {
+		xc.colo_filter_sec_redirector1_indev = C.CString(x.ColoFilterSecRedirector1Indev)
+	}
+	if x.ColoFilterSecRedirector1Outdev != "" {
+		xc.colo_filter_sec_redirector1_outdev = C.CString(x.ColoFilterSecRedirector1Outdev)
+	}
+	if x.ColoFilterSecRewriter0Queue != "" {
+		xc.colo_filter_sec_rewriter0_queue = C.CString(x.ColoFilterSecRewriter0Queue)
+	}
+	if x.ColoCheckpointHost != "" {
+		xc.colo_checkpoint_host = C.CString(x.ColoCheckpointHost)
+	}
+	if x.ColoCheckpointPort != "" {
+		xc.colo_checkpoint_port = C.CString(x.ColoCheckpointPort)
+	}
 	return xc, nil
 }
 
@@ -1708,7 +1952,9 @@  func (x *DeviceUsbctrl) toC() (xc C.libxl_device_usbctrl, err error) {
 	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)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
 	return xc, nil
 }
 
@@ -1772,7 +2018,9 @@  func (x *DeviceDtdev) fromC(xc *C.libxl_device_dtdev) error {
 
 func (x *DeviceDtdev) toC() (xc C.libxl_device_dtdev, err error) {
 	C.libxl_device_dtdev_init(&xc)
-	xc.path = C.CString(x.Path)
+	if x.Path != "" {
+		xc.path = C.CString(x.Path)
+	}
 	return xc, nil
 }
 
@@ -1790,7 +2038,9 @@  func (x *DeviceVtpm) fromC(xc *C.libxl_device_vtpm) error {
 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)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.uuid, err = x.Uuid.toC()
 	if err != nil {
@@ -1814,10 +2064,18 @@  func (x *DeviceP9) fromC(xc *C.libxl_device_p9) error {
 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)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
+	if x.Tag != "" {
+		xc.tag = C.CString(x.Tag)
+	}
+	if x.Path != "" {
+		xc.path = C.CString(x.Path)
+	}
+	if x.SecurityModel != "" {
+		xc.security_model = C.CString(x.SecurityModel)
+	}
 	xc.devid = C.libxl_devid(x.Devid)
 	return xc, nil
 }
@@ -1833,7 +2091,9 @@  func (x *DevicePvcallsif) fromC(xc *C.libxl_device_pvcallsif) error {
 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)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
 	xc.devid = C.libxl_devid(x.Devid)
 	return xc, nil
 }
@@ -1871,9 +2131,13 @@  func (x *DeviceChannelConnectionUnionSocket) fromC(xc *C.libxl_device_channel) e
 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)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
 	xc.devid = C.libxl_devid(x.Devid)
-	xc.name = C.CString(x.Name)
+	if x.Name != "" {
+		xc.name = C.CString(x.Name)
+	}
 	xc.connection = C.libxl_channel_connection(x.Connection)
 	switch x.Connection {
 	case ChannelConnectionSocket:
@@ -1883,7 +2147,9 @@  func (x *DeviceChannel) toC() (xc C.libxl_device_channel, err error) {
 			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)
+		if tmp.Path != "" {
+			socket.path = C.CString(tmp.Path)
+		}
 		socketBytes := C.GoBytes(unsafe.Pointer(&socket), C.sizeof_libxl_device_channel_connection_union_socket)
 		copy(xc.u[:], socketBytes)
 	default:
@@ -1902,7 +2168,9 @@  func (x *ConnectorParam) fromC(xc *C.libxl_connector_param) error {
 
 func (x *ConnectorParam) toC() (xc C.libxl_connector_param, err error) {
 	C.libxl_connector_param_init(&xc)
-	xc.unique_id = C.CString(x.UniqueId)
+	if x.UniqueId != "" {
+		xc.unique_id = C.CString(x.UniqueId)
+	}
 	xc.width = C.uint32_t(x.Width)
 	xc.height = C.uint32_t(x.Height)
 	return xc, nil
@@ -1930,7 +2198,9 @@  func (x *DeviceVdispl) fromC(xc *C.libxl_device_vdispl) error {
 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)
+	if x.BackendDomname != "" {
+		xc.backend_domname = C.CString(x.BackendDomname)
+	}
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.be_alloc = C.bool(x.BeAlloc)
 	if numConnectors := len(x.Connectors); numConnectors > 0 {
@@ -2009,7 +2279,9 @@  func (x *VsndStream) fromC(xc *C.libxl_vsnd_stream) error {
 
 func (x *VsndStream) toC() (xc C.libxl_vsnd_stream, err error) {
 	C.libxl_vsnd_stream_init(&xc)
-	xc.unique_id = C.CString(x.UniqueId)
+	if x.UniqueId != "" {
+		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 {
@@ -2040,7 +2312,9 @@  func (x *VsndPcm) fromC(xc *C.libxl_vsnd_pcm) error {
 
 func (x *VsndPcm) toC() (xc C.libxl_vsnd_pcm, err error) {
 	C.libxl_vsnd_pcm_init(&xc)
-	xc.name = C.CString(x.Name)
+	if x.Name != "" {
+		xc.name = C.CString(x.Name)
+	}
 	xc.params, err = x.Params.toC()
 	if err != nil {
 		C.libxl_vsnd_pcm_dispose(&xc)
@@ -2088,10 +2362,16 @@  func (x *DeviceVsnd) fromC(xc *C.libxl_device_vsnd) error {
 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)
+	if x.BackendDomname != "" {
+		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)
+	if x.ShortName != "" {
+		xc.short_name = C.CString(x.ShortName)
+	}
+	if x.LongName != "" {
+		xc.long_name = C.CString(x.LongName)
+	}
 	xc.params, err = x.Params.toC()
 	if err != nil {
 		C.libxl_device_vsnd_dispose(&xc)
@@ -2509,9 +2789,13 @@  func (x *Diskinfo) fromC(xc *C.libxl_diskinfo) error {
 
 func (x *Diskinfo) toC() (xc C.libxl_diskinfo, err error) {
 	C.libxl_diskinfo_init(&xc)
-	xc.backend = C.CString(x.Backend)
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
 	xc.backend_id = C.uint32_t(x.BackendId)
-	xc.frontend = C.CString(x.Frontend)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
 	xc.frontend_id = C.uint32_t(x.FrontendId)
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.state = C.int(x.State)
@@ -2536,9 +2820,13 @@  func (x *Nicinfo) fromC(xc *C.libxl_nicinfo) error {
 
 func (x *Nicinfo) toC() (xc C.libxl_nicinfo, err error) {
 	C.libxl_nicinfo_init(&xc)
-	xc.backend = C.CString(x.Backend)
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
 	xc.backend_id = C.uint32_t(x.BackendId)
-	xc.frontend = C.CString(x.Frontend)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
 	xc.frontend_id = C.uint32_t(x.FrontendId)
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.state = C.int(x.State)
@@ -2566,9 +2854,13 @@  func (x *Vtpminfo) fromC(xc *C.libxl_vtpminfo) error {
 
 func (x *Vtpminfo) toC() (xc C.libxl_vtpminfo, err error) {
 	C.libxl_vtpminfo_init(&xc)
-	xc.backend = C.CString(x.Backend)
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
 	xc.backend_id = C.uint32_t(x.BackendId)
-	xc.frontend = C.CString(x.Frontend)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
 	xc.frontend_id = C.uint32_t(x.FrontendId)
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.state = C.int(x.State)
@@ -2605,9 +2897,13 @@  func (x *Usbctrlinfo) toC() (xc C.libxl_usbctrlinfo, err error) {
 	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)
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
 	xc.backend_id = C.uint32_t(x.BackendId)
-	xc.frontend = C.CString(x.Frontend)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
 	xc.frontend_id = C.uint32_t(x.FrontendId)
 	xc.state = C.int(x.State)
 	xc.evtch = C.int(x.Evtch)
@@ -2724,7 +3020,9 @@  func (x *Connectorinfo) fromC(xc *C.libxl_connectorinfo) error {
 
 func (x *Connectorinfo) toC() (xc C.libxl_connectorinfo, err error) {
 	C.libxl_connectorinfo_init(&xc)
-	xc.unique_id = C.CString(x.UniqueId)
+	if x.UniqueId != "" {
+		xc.unique_id = C.CString(x.UniqueId)
+	}
 	xc.width = C.uint32_t(x.Width)
 	xc.height = C.uint32_t(x.Height)
 	xc.req_evtch = C.int(x.ReqEvtch)
@@ -2758,9 +3056,13 @@  func (x *Vdisplinfo) fromC(xc *C.libxl_vdisplinfo) error {
 
 func (x *Vdisplinfo) toC() (xc C.libxl_vdisplinfo, err error) {
 	C.libxl_vdisplinfo_init(&xc)
-	xc.backend = C.CString(x.Backend)
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
 	xc.backend_id = C.uint32_t(x.BackendId)
-	xc.frontend = C.CString(x.Frontend)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
 	xc.frontend_id = C.uint32_t(x.FrontendId)
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.state = C.int(x.State)
@@ -2851,9 +3153,13 @@  func (x *Vsndinfo) fromC(xc *C.libxl_vsndinfo) error {
 
 func (x *Vsndinfo) toC() (xc C.libxl_vsndinfo, err error) {
 	C.libxl_vsndinfo_init(&xc)
-	xc.backend = C.CString(x.Backend)
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
 	xc.backend_id = C.uint32_t(x.BackendId)
-	xc.frontend = C.CString(x.Frontend)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
 	xc.frontend_id = C.uint32_t(x.FrontendId)
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.state = C.int(x.State)
@@ -2888,9 +3194,13 @@  func (x *Vkbinfo) fromC(xc *C.libxl_vkbinfo) error {
 
 func (x *Vkbinfo) toC() (xc C.libxl_vkbinfo, err error) {
 	C.libxl_vkbinfo_init(&xc)
-	xc.backend = C.CString(x.Backend)
+	if x.Backend != "" {
+		xc.backend = C.CString(x.Backend)
+	}
 	xc.backend_id = C.uint32_t(x.BackendId)
-	xc.frontend = C.CString(x.Frontend)
+	if x.Frontend != "" {
+		xc.frontend = C.CString(x.Frontend)
+	}
 	xc.frontend_id = C.uint32_t(x.FrontendId)
 	xc.devid = C.libxl_devid(x.Devid)
 	xc.state = C.int(x.State)
@@ -3042,7 +3352,9 @@  func (x *DomainRemusInfo) toC() (xc C.libxl_domain_remus_info, err error) {
 		C.libxl_domain_remus_info_dispose(&xc)
 		return xc, err
 	}
-	xc.netbufscript = C.CString(x.Netbufscript)
+	if x.Netbufscript != "" {
+		xc.netbufscript = C.CString(x.Netbufscript)
+	}
 	xc.diskbuf, err = x.Diskbuf.toC()
 	if err != nil {
 		C.libxl_domain_remus_info_dispose(&xc)
@@ -3163,7 +3475,9 @@  func (x *Event) toC() (xc C.libxl_event, err error) {
 			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)
+		if tmp.Vdev != "" {
+			disk_eject.vdev = C.CString(tmp.Vdev)
+		}
 		disk_eject.disk, err = tmp.Disk.toC()
 		if err != nil {
 			C.libxl_event_dispose(&xc)