func (vhostuserDev VhostUserDevice) Valid() bool {
	if vhostuserDev.SocketPath == "" || vhostuserDev.CharDevID == "" {
		return false
	}
	switch vhostuserDev.VhostUserType {
	case VhostUserNet:
		if vhostuserDev.TypeDevID == "" || vhostuserDev.Address == "" {
			return false
		}
	case VhostUserSCSI:
		if vhostuserDev.TypeDevID == "" {
			return false
		}
	case VhostUserBlk:
	default:
		return false
	}
	return true
}
Valid returns true if there is a valid structure defined for VhostUserDevice
package qemu
import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"syscall"
	"context"
)
type Machine struct {
	Type string
	Acceleration string
}
type Device interface {
	Valid() bool
	QemuParams(config *Config) []string
}
type DeviceDriver string
const (
	NVDIMM DeviceDriver = "nvdimm"
	Virtio9P = "virtio-9p-pci"
	VirtioNet = "virtio-net"
	VirtioNetPCI = "virtio-net-pci"
	VirtioSerial = "virtio-serial-pci"
	VirtioBlock = "virtio-blk"
	Console = "virtconsole"
	VirtioSerialPort = "virtserialport"
)
type ObjectType string
const (
	MemoryBackendFile ObjectType = "memory-backend-file"
)
type Object struct {
	Driver DeviceDriver
	Type ObjectType
	ID string
	DeviceID string
	MemPath string
	Size uint64
}
func (object Object) Valid() bool {
	switch object.Type {
	case MemoryBackendFile:
		if object.ID == "" || object.MemPath == "" || object.Size == 0 {
			return false
		}
	default:
		return false
	}
	return true
}
func (object Object) QemuParams(config *Config) []string {
	var objectParams []string
	var deviceParams []string
	var qemuParams []string
	deviceParams = append(deviceParams, string(object.Driver))
	deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", object.DeviceID))
	switch object.Type {
	case MemoryBackendFile:
		objectParams = append(objectParams, string(object.Type))
		objectParams = append(objectParams, fmt.Sprintf(",id=%s", object.ID))
		objectParams = append(objectParams, fmt.Sprintf(",mem-path=%s", object.MemPath))
		objectParams = append(objectParams, fmt.Sprintf(",size=%d", object.Size))
		deviceParams = append(deviceParams, fmt.Sprintf(",memdev=%s", object.ID))
	}
	qemuParams = append(qemuParams, "-device")
	qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
	qemuParams = append(qemuParams, "-object")
	qemuParams = append(qemuParams, strings.Join(objectParams, ""))
	return qemuParams
}
type FSDriver string
type SecurityModelType string
const (
	Local FSDriver = "local"
	Handle = "handle"
	Proxy = "proxy"
)
const (
	None SecurityModelType = "none"
	PassThrough = "passthrough"
	MappedXattr = "mapped-xattr"
	MappedFile = "mapped-file"
)
type FSDevice struct {
	Driver DeviceDriver
	FSDriver FSDriver
	ID string
	Path string
	MountTag string
	SecurityModel SecurityModelType
	DisableModern bool
}
func (fsdev FSDevice) Valid() bool {
	if fsdev.ID == "" || fsdev.Path == "" || fsdev.MountTag == "" {
		return false
	}
	return true
}
func (fsdev FSDevice) QemuParams(config *Config) []string {
	var fsParams []string
	var deviceParams []string
	var qemuParams []string
	deviceParams = append(deviceParams, fmt.Sprintf("%s", fsdev.Driver))
	if fsdev.DisableModern {
		deviceParams = append(deviceParams, ",disable-modern=true")
	}
	deviceParams = append(deviceParams, fmt.Sprintf(",fsdev=%s", fsdev.ID))
	deviceParams = append(deviceParams, fmt.Sprintf(",mount_tag=%s", fsdev.MountTag))
	fsParams = append(fsParams, string(fsdev.FSDriver))
	fsParams = append(fsParams, fmt.Sprintf(",id=%s", fsdev.ID))
	fsParams = append(fsParams, fmt.Sprintf(",path=%s", fsdev.Path))
	fsParams = append(fsParams, fmt.Sprintf(",security_model=%s", fsdev.SecurityModel))
	qemuParams = append(qemuParams, "-device")
	qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
	qemuParams = append(qemuParams, "-fsdev")
	qemuParams = append(qemuParams, strings.Join(fsParams, ""))
	return qemuParams
}
type CharDeviceBackend string
const (
	Pipe CharDeviceBackend = "pipe"
	Socket = "socket"
	CharConsole = "console"
	Serial = "serial"
	TTY = "tty"
	PTY = "pty"
)
type CharDevice struct {
	Backend CharDeviceBackend
	Driver DeviceDriver
	Bus string
	DeviceID string
	ID   string
	Path string
	Name string
	DisableModern bool
}
func (cdev CharDevice) Valid() bool {
	if cdev.ID == "" || cdev.Path == "" {
		return false
	}
	return true
}
func (cdev CharDevice) QemuParams(config *Config) []string {
	var cdevParams []string
	var deviceParams []string
	var qemuParams []string
	deviceParams = append(deviceParams, fmt.Sprintf("%s", cdev.Driver))
	if cdev.DisableModern {
		deviceParams = append(deviceParams, ",disable-modern=true")
	}
	if cdev.Bus != "" {
		deviceParams = append(deviceParams, fmt.Sprintf(",bus=%s", cdev.Bus))
	}
	deviceParams = append(deviceParams, fmt.Sprintf(",chardev=%s", cdev.ID))
	deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", cdev.DeviceID))
	if cdev.Name != "" {
		deviceParams = append(deviceParams, fmt.Sprintf(",name=%s", cdev.Name))
	}
	cdevParams = append(cdevParams, string(cdev.Backend))
	cdevParams = append(cdevParams, fmt.Sprintf(",id=%s", cdev.ID))
	if cdev.Backend == Socket {
		cdevParams = append(cdevParams, fmt.Sprintf(",path=%s,server,nowait", cdev.Path))
	} else {
		cdevParams = append(cdevParams, fmt.Sprintf(",path=%s", cdev.Path))
	}
	qemuParams = append(qemuParams, "-device")
	qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
	qemuParams = append(qemuParams, "-chardev")
	qemuParams = append(qemuParams, strings.Join(cdevParams, ""))
	return qemuParams
}
type NetDeviceType string
const (
	TAP NetDeviceType = "tap"
	MACVTAP = "macvtap"
	IPVTAP = "ipvtap"
	VETHTAP = "vethtap"
	VFIO = "VFIO"
	VHOSTUSER = "vhostuser"
)
func (n NetDeviceType) QemuNetdevParam() string {
	switch n {
	case TAP:
		return "tap"
	case MACVTAP:
		return "tap"
	case IPVTAP:
		return "tap"
	case VETHTAP:
		return "tap"  
	case VFIO:
		return ""  
	case VHOSTUSER:
		return "vhost-user"  
	default:
		return ""
	}
}
func (n NetDeviceType) QemuDeviceParam() string {
	switch n {
	case TAP:
		return "virtio-net-pci"
	case MACVTAP:
		return "virtio-net-pci"
	case IPVTAP:
		return "virtio-net-pci"
	case VETHTAP:
		return "virtio-net-pci"  
	case VFIO:
		return "vfio-pci"  
	case VHOSTUSER:
		return ""  
	default:
		return ""
	}
}
type NetDevice struct {
	Type NetDeviceType
	Driver DeviceDriver
	ID string
	IFName string
	Bus string
	Addr string
	DownScript string
	Script string
	FDs      []*os.File
	VhostFDs []*os.File
	VHost bool
	MACAddress string
	DisableModern bool
}
func (netdev NetDevice) Valid() bool {
	if netdev.ID == "" || netdev.IFName == "" {
		return false
	}
	switch netdev.Type {
	case TAP:
		return true
	case MACVTAP:
		return true
	default:
		return false
	}
}
func (netdev NetDevice) QemuDeviceParams(config *Config) []string {
	var deviceParams []string
	if netdev.Type.QemuDeviceParam() == "" {
		return nil
	}
	deviceParams = append(deviceParams, "driver=")
	deviceParams = append(deviceParams, netdev.Type.QemuDeviceParam())
	deviceParams = append(deviceParams, fmt.Sprintf(",netdev=%s", netdev.ID))
	deviceParams = append(deviceParams, fmt.Sprintf(",mac=%s", netdev.MACAddress))
	if netdev.Bus != "" {
		deviceParams = append(deviceParams, fmt.Sprintf(",bus=%s", netdev.Bus))
	}
	if netdev.Addr != "" {
		addr, err := strconv.Atoi(netdev.Addr)
		if err == nil && addr >= 0 {
			deviceParams = append(deviceParams, fmt.Sprintf(",addr=%x", addr))
		}
	}
	if netdev.DisableModern {
		deviceParams = append(deviceParams, ",disable-modern=true")
	}
	if len(netdev.FDs) > 0 {
		vectors := len(netdev.FDs)*2 + 2
		deviceParams = append(deviceParams, ",mq=on")
		deviceParams = append(deviceParams, fmt.Sprintf(",vectors=%d", vectors))
	}
	return deviceParams
}
func (netdev NetDevice) QemuNetdevParams(config *Config) []string {
	var netdevParams []string
	if netdev.Type.QemuNetdevParam() == "" {
		return nil
	}
	netdevParams = append(netdevParams, netdev.Type.QemuNetdevParam())
	netdevParams = append(netdevParams, fmt.Sprintf(",id=%s", netdev.ID))
	if netdev.VHost == true {
		netdevParams = append(netdevParams, ",vhost=on")
		if len(netdev.VhostFDs) > 0 {
			var fdParams []string
			qemuFDs := config.appendFDs(netdev.VhostFDs)
			for _, fd := range qemuFDs {
				fdParams = append(fdParams, fmt.Sprintf("%d", fd))
			}
			netdevParams = append(netdevParams, fmt.Sprintf(",vhostfds=%s", strings.Join(fdParams, ":")))
		}
	}
	if len(netdev.FDs) > 0 {
		var fdParams []string
		qemuFDs := config.appendFDs(netdev.FDs)
		for _, fd := range qemuFDs {
			fdParams = append(fdParams, fmt.Sprintf("%d", fd))
		}
		netdevParams = append(netdevParams, fmt.Sprintf(",fds=%s", strings.Join(fdParams, ":")))
	} else {
		netdevParams = append(netdevParams, fmt.Sprintf(",ifname=%s", netdev.IFName))
		if netdev.DownScript != "" {
			netdevParams = append(netdevParams, fmt.Sprintf(",downscript=%s", netdev.DownScript))
		}
		if netdev.Script != "" {
			netdevParams = append(netdevParams, fmt.Sprintf(",script=%s", netdev.Script))
		}
	}
	return netdevParams
}
func (netdev NetDevice) QemuParams(config *Config) []string {
	var netdevParams []string
	var deviceParams []string
	var qemuParams []string
	if (netdev.Type == MACVTAP) && (len(netdev.FDs) == 0) {
		return nil  
	}
	if netdev.Type.QemuNetdevParam() != "" {
		netdevParams = netdev.QemuNetdevParams(config)
		if netdevParams != nil {
			qemuParams = append(qemuParams, "-netdev")
			qemuParams = append(qemuParams, strings.Join(netdevParams, ""))
		}
	}
	if netdev.Type.QemuDeviceParam() != "" {
		deviceParams = netdev.QemuDeviceParams(config)
		if deviceParams != nil {
			qemuParams = append(qemuParams, "-device")
			qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
		}
	}
	return qemuParams
}
type SerialDevice struct {
	Driver DeviceDriver
	ID string
	DisableModern bool
}
func (dev SerialDevice) Valid() bool {
	if dev.Driver == "" || dev.ID == "" {
		return false
	}
	return true
}
func (dev SerialDevice) QemuParams(config *Config) []string {
	var deviceParams []string
	var qemuParams []string
	deviceParams = append(deviceParams, fmt.Sprintf("%s", dev.Driver))
	if dev.DisableModern {
		deviceParams = append(deviceParams, ",disable-modern=true")
	}
	deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", dev.ID))
	qemuParams = append(qemuParams, "-device")
	qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
	return qemuParams
}
type BlockDeviceInterface string
type BlockDeviceAIO string
type BlockDeviceFormat string
const (
	NoInterface BlockDeviceInterface = "none"
	SCSI = "scsi"
)
const (
	Threads BlockDeviceAIO = "threads"
	Native = "native"
)
const (
	QCOW2 BlockDeviceFormat = "qcow2"
)
type BlockDevice struct {
	Driver    DeviceDriver
	ID        string
	File      string
	Interface BlockDeviceInterface
	AIO       BlockDeviceAIO
	Format    BlockDeviceFormat
	SCSI      bool
	WCE       bool
	DisableModern bool
}
func (blkdev BlockDevice) Valid() bool {
	if blkdev.Driver == "" || blkdev.ID == "" || blkdev.File == "" {
		return false
	}
	return true
}
func (blkdev BlockDevice) QemuParams(config *Config) []string {
	var blkParams []string
	var deviceParams []string
	var qemuParams []string
	deviceParams = append(deviceParams, fmt.Sprintf("%s", blkdev.Driver))
	if blkdev.DisableModern {
		deviceParams = append(deviceParams, ",disable-modern=true")
	}
	deviceParams = append(deviceParams, fmt.Sprintf(",drive=%s", blkdev.ID))
	if blkdev.SCSI == false {
		deviceParams = append(deviceParams, ",scsi=off")
	}
	if blkdev.WCE == false {
		deviceParams = append(deviceParams, ",config-wce=off")
	}
	blkParams = append(blkParams, fmt.Sprintf("id=%s", blkdev.ID))
	blkParams = append(blkParams, fmt.Sprintf(",file=%s", blkdev.File))
	blkParams = append(blkParams, fmt.Sprintf(",aio=%s", blkdev.AIO))
	blkParams = append(blkParams, fmt.Sprintf(",format=%s", blkdev.Format))
	blkParams = append(blkParams, fmt.Sprintf(",if=%s", blkdev.Interface))
	qemuParams = append(qemuParams, "-device")
	qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
	qemuParams = append(qemuParams, "-drive")
	qemuParams = append(qemuParams, strings.Join(blkParams, ""))
	return qemuParams
}
type VhostUserDeviceType string
const (
	VhostUserSCSI = "vhost-user-scsi-pci"
	VhostUserNet = "virtio-net-pci"
	VhostUserBlk = "vhost-user-blk-pci"
)
type VhostUserDevice struct {
	SocketPath    string  
	CharDevID     string
	TypeDevID     string  
	Address       string  
	VhostUserType VhostUserDeviceType
}