func (q *qemu) init(pod *Pod) error {
	valid, err := pod.config.HypervisorConfig.valid()
	if valid == false || err != nil {
		return err
	}
	q.config = pod.config.HypervisorConfig
	q.pod = pod
	if err := pod.storage.fetchHypervisorState(pod.id, &q.state); err != nil {
		q.Logger().Debug("Creating bridges")
		q.state.Bridges = NewBridges(q.config.DefaultBridges, q.config.HypervisorMachineType)
		q.Logger().Debug("Creating UUID")
		q.state.UUID = uuid.Generate().String()
		if err := pod.storage.storeHypervisorState(pod.id, q.state); err != nil {
			return err
		}
	}
	if err := q.buildPath(); err != nil {
		return err
	}
	if err := q.buildKernelParams(q.config); err != nil {
		return err
	}
	nested, err := RunningOnVMM(procCPUInfo)
	if err != nil {
		return err
	}
	q.Logger().WithField("inside-vm", fmt.Sprintf("%t", nested)).Debug("Checking nesting environment")
	if q.config.DisableNestingChecks {
		q.nestedRun = false
	} else {
		q.nestedRun = nested
	}
	return nil
}
init intializes the Qemu structure.
package virtcontainers
import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"time"
	"github.com/containers/virtcontainers/pkg/uuid"
	govmmQemu "github.com/intel/govmm/qemu"
	"github.com/sirupsen/logrus"
)
type qmpChannel struct {
	ctx  context.Context
	path string
	wg   sync.WaitGroup
	qmp  *govmmQemu.QMP
}
type QemuState struct {
	Bridges []Bridge
	UUID    string
}
type qemu struct {
	path   string
	config HypervisorConfig
	hypervisorParams []string
	kernelParams     []string
	qmpMonitorCh qmpChannel
	qmpControlCh qmpChannel
	qemuConfig govmmQemu.Config
	nestedRun bool
	pod *Pod
	state QemuState
}
const defaultQemuPath = "/usr/bin/qemu-system-x86_64"
const defaultQemuMachineType = "pc-lite"
const defaultQemuMachineAccelerators = "kvm,kernel_irqchip,nvdimm"
const (
	QemuPCLite = defaultQemuMachineType
	QemuPC = "pc"
	QemuQ35 = "q35"
)
const qmpCapErrMsg = "Failed to negoatiate QMP capabilities"
const qmpSockPathSizeLimit = 107
var qemuPaths = map[string]string{
	QemuPCLite: "/usr/bin/qemu-lite-system-x86_64",
	QemuPC:     defaultQemuPath,
	QemuQ35:    "/usr/bin/qemu-35-system-x86_64",
}
var supportedQemuMachines = []govmmQemu.Machine{
	{
		Type:         QemuPCLite,
		Acceleration: defaultQemuMachineAccelerators,
	},
	{
		Type:         QemuPC,
		Acceleration: defaultQemuMachineAccelerators,
	},
	{
		Type:         QemuQ35,
		Acceleration: defaultQemuMachineAccelerators,
	},
}
const (
	defaultSockets uint32 = 1
	defaultThreads uint32 = 1
)
const (
	defaultMemSlots uint8 = 2
)
const (
	defaultConsole = "console.sock"
)
const (
	maxDevIDSize = 31
)
const (
	maxMemoryOffset = 1024
)
type operation int
const (
	addDevice operation = iota
	removeDevice
)
type qmpLogger struct {
	logger *logrus.Entry
}
func newQMPLogger() qmpLogger {
	return qmpLogger{
		logger: virtLog.WithField("subsystem", "qmp"),
	}
}
func (l qmpLogger) V(level int32) bool {
	if level != 0 {
		return true
	}
	return false
}
func (l qmpLogger) Infof(format string, v ...interface{}) {
	l.logger.Infof(format, v...)
}
func (l qmpLogger) Warningf(format string, v ...interface{}) {
	l.logger.Warnf(format, v...)
}
func (l qmpLogger) Errorf(format string, v ...interface{}) {
	l.logger.Errorf(format, v...)
}
var kernelDefaultParams = []Param{
	{"root", "/dev/pmem0p1"},
	{"rootflags", "dax,data=ordered,errors=remount-ro rw"},
	{"rootfstype", "ext4"},
	{"tsc", "reliable"},
	{"no_timer_check", ""},
	{"rcupdate.rcu_expedited", "1"},
	{"i8042.direct", "1"},
	{"i8042.dumbkbd", "1"},
	{"i8042.nopnp", "1"},
	{"i8042.noaux", "1"},
	{"noreplace-smp", ""},
	{"reboot", "k"},
	{"panic", "1"},
	{"console", "hvc0"},
	{"console", "hvc1"},
	{"initcall_debug", ""},
	{"iommu", "off"},
	{"cryptomgr.notests", ""},
	{"net.ifnames", "0"},
}
var kernelDefaultParamsNonDebug = []Param{
	{"quiet", ""},
	{"systemd.show_status", "false"},
}
var kernelDefaultParamsDebug = []Param{
	{"debug", ""},
	{"systemd.show_status", "true"},
	{"systemd.log_level", "debug"},
}
func (q *qemu) Logger() *logrus.Entry {
	return virtLog.WithField("subsystem", "qemu")
}
func (q *qemu) buildKernelParams(config HypervisorConfig) error {
	params := kernelDefaultParams
	if config.Debug == true {
		params = append(params, kernelDefaultParamsDebug...)
	} else {
		params = append(params, kernelDefaultParamsNonDebug...)
	}
	params = append(params, config.KernelParams...)
	q.kernelParams = SerializeParams(params, "=")
	return nil
}
func (q *qemu) capabilities() capabilities {
	var caps capabilities
	if q.qemuConfig.Machine.Type == QemuPC {
		caps.setBlockDeviceHotplugSupport()
	}
	return caps
}
func (q *qemu) appendVolume(devices []govmmQemu.Device, volume Volume) []govmmQemu.Device {
	if volume.MountTag == "" || volume.HostPath == "" {
		return devices
	}
	devID := fmt.Sprintf("extra-9p-%s", volume.MountTag)
	if len(devID) > maxDevIDSize {
		devID = string(devID[:maxDevIDSize])
	}
	devices = append(devices,
		govmmQemu.FSDevice{
			Driver:        govmmQemu.Virtio9P,
			FSDriver:      govmmQemu.Local,
			ID:            devID,
			Path:          volume.HostPath,
			MountTag:      volume.MountTag,
			SecurityModel: govmmQemu.None,
			DisableModern: q.nestedRun,
		},
	)
	return devices
}
func (q *qemu) appendBlockDevice(devices []govmmQemu.Device, drive Drive) []govmmQemu.Device {
	if drive.File == "" || drive.ID == "" || drive.Format == "" {
		return devices
	}
	if len(drive.ID) > maxDevIDSize {
		drive.ID = string(drive.ID[:maxDevIDSize])
	}
	devices = append(devices,
		govmmQemu.BlockDevice{
			Driver:        govmmQemu.VirtioBlock,
			ID:            drive.ID,
			File:          drive.File,
			AIO:           govmmQemu.Threads,
			Format:        govmmQemu.BlockDeviceFormat(drive.Format),
			Interface:     "none",
			DisableModern: q.nestedRun,
		},
	)
	return devices
}
func (q *qemu) appendVFIODevice(devices []govmmQemu.Device, vfDevice VFIODevice) []govmmQemu.Device {
	if vfDevice.BDF == "" {
		return devices
	}
	devices = append(devices,
		govmmQemu.VFIODevice{
			BDF: vfDevice.BDF,
		},
	)
	return devices
}
func (q *qemu) appendSocket(devices []govmmQemu.Device, socket Socket) []govmmQemu.Device {
	devID := socket.ID
	if len(devID) > maxDevIDSize {
		devID = string(devID[:maxDevIDSize])
	}
	devices = append(devices,
		govmmQemu.CharDevice{
			Driver:   govmmQemu.VirtioSerialPort,
			Backend:  govmmQemu.Socket,
			DeviceID: socket.DeviceID,
			ID:       devID,
			Path:     socket.HostPath,
			Name:     socket.Name,
		},
	)
	return devices
}
func networkModelToQemuType(model NetInterworkingModel) govmmQemu.NetDeviceType {
	switch model {
	case ModelBridged:
		return govmmQemu.MACVTAP  
	case ModelMacVtap:
		return govmmQemu.MACVTAP
	default:
		return govmmQemu.TAP
	}
}
var networkIndex = 0
func (q *qemu) appendNetwork(devices []govmmQemu.Device, endpoint Endpoint) []govmmQemu.Device {
	switch ep := endpoint.(type) {
	case *VirtualEndpoint:
		devices = append(devices,
			govmmQemu.NetDevice{
				Type:          networkModelToQemuType(ep.NetPair.NetInterworkingModel),
				Driver:        govmmQemu.VirtioNetPCI,
				ID:            fmt.Sprintf("network-%d", networkIndex),
				IFName:        ep.NetPair.TAPIface.Name,
				MACAddress:    ep.NetPair.TAPIface.HardAddr,
				DownScript:    "no",
				Script:        "no",
				VHost:         true,
				DisableModern: q.nestedRun,
				FDs:           ep.NetPair.VMFds,
				VhostFDs:      ep.NetPair.VhostFds,
			},
		)
		networkIndex++
	}
	return devices
}
func (q *qemu) appendFSDevices(devices []govmmQemu.Device, podConfig PodConfig) []govmmQemu.Device {
	for _, v := range podConfig.Volumes {
		devices = q.appendVolume(devices, v)
	}
	return devices
}
func (q *qemu) appendBridges(devices []govmmQemu.Device, podConfig PodConfig) ([]govmmQemu.Device, error) {
	bus := "pci.0"
	if podConfig.HypervisorConfig.HypervisorMachineType == QemuQ35 {
		bus = "pcie.0"
	}
	for idx, b := range q.state.Bridges {
		t := govmmQemu.PCIBridge
		if b.Type == pcieBridge {
			t = govmmQemu.PCIEBridge
		}
		devices = append(devices,
			govmmQemu.BridgeDevice{
				Type: t,
				Bus:  bus,
				ID:   b.ID,
				Chassis: (idx + 1),
				SHPC:    true,
			},
		)
	}
	return devices, nil
}
func (q *qemu) appendConsoles(devices []govmmQemu.Device, podConfig PodConfig) []govmmQemu.Device {
	serial := govmmQemu.SerialDevice{
		Driver:        govmmQemu.VirtioSerial,
		ID:            "serial0",
		DisableModern: q.nestedRun,
	}
	devices = append(devices, serial)
	var console govmmQemu.CharDevice
	console = govmmQemu.CharDevice{
		Driver:   govmmQemu.Console,
		Backend:  govmmQemu.Socket,
		DeviceID: "console0",
		ID:       "charconsole0",
		Path:     q.getPodConsole(podConfig.ID),
	}
	devices = append(devices, console)
	return devices
}
func (q *qemu) appendImage(devices []govmmQemu.Device, podConfig PodConfig) ([]govmmQemu.Device, error) {
	imagePath, err := q.config.ImageAssetPath()
	if err != nil {
		return nil, err
	}
	imageFile, err := os.Open(imagePath)
	if err != nil {
		return nil, err
	}
	defer imageFile.Close()
	imageStat, err := imageFile.Stat()
	if err != nil {
		return nil, err
	}
	object := govmmQemu.Object{
		Driver:   govmmQemu.NVDIMM,
		Type:     govmmQemu.MemoryBackendFile,
		DeviceID: "nv0",
		ID:       "mem0",
		MemPath:  imagePath,
		Size:     (uint64)(imageStat.Size()),
	}
	devices = append(devices, object)
	return devices, nil
}
func (q *qemu) getMachine(name string) (govmmQemu.Machine, error) {
	for _, m := range supportedQemuMachines {
		if m.Type == name {
			return m, nil
		}
	}
	return govmmQemu.Machine{}, fmt.Errorf("unrecognised machine type: %v", name)
}
func (q *qemu) buildPath() error {
	p, err := q.config.HypervisorAssetPath()
	if err != nil {
		return err
	}
	if p != "" {
		q.path = p
		return nil
	}
	machineType := q.config.HypervisorMachineType
	if machineType == "" {
		machineType = defaultQemuMachineType
	}
	p, ok := qemuPaths[machineType]
	if !ok {
		q.Logger().WithField("machine-type", machineType).Warn("Unknown machine type")
		p = defaultQemuPath
	}
	if _, err := os.Stat(p); os.IsNotExist(err) {
		return fmt.Errorf("QEMU path (%s) does not exist", p)
	}
	q.path = p
	return nil
}