Unverified Commit 7298e13c authored by Adam C. Stephens's avatar Adam C. Stephens Committed by GitHub
Browse files

incus: fix virtual-machines with qemu 9.2 (#369996)

parents 523c8d36 7dbb4ff1
Loading
Loading
Loading
Loading
+271 −0
Original line number Diff line number Diff line
diff --git a/internal/server/instance/drivers/driver_qemu.go b/internal/server/instance/drivers/driver_qemu.go
index 1c773213468..fb43917ca96 100644
--- a/internal/server/instance/drivers/driver_qemu.go
+++ b/internal/server/instance/drivers/driver_qemu.go
@@ -2393,7 +2393,7 @@ func (d *qemu) deviceAttachPath(deviceName string, configCopy map[string]string,
 
 	d.logger.Debug("Using PCI bus device to hotplug virtiofs into", logger.Ctx{"device": deviceName, "port": pciDeviceName})
 
-	qemuDev := map[string]string{
+	qemuDev := map[string]any{
 		"driver":  "vhost-user-fs-pci",
 		"bus":     pciDeviceName,
 		"addr":    "00.0",
@@ -2535,7 +2535,7 @@ func (d *qemu) deviceAttachNIC(deviceName string, configCopy map[string]string,
 		return err
 	}
 
-	qemuDev := make(map[string]string)
+	qemuDev := make(map[string]any)
 
 	// PCIe and PCI require a port device name to hotplug the NIC into.
 	if slices.Contains([]string{"pcie", "pci"}, qemuBus) {
@@ -2633,7 +2633,7 @@ func (d *qemu) deviceAttachPCI(deviceName string, configCopy map[string]string,
 		return err
 	}
 
-	qemuDev := make(map[string]string)
+	qemuDev := make(map[string]any)
 	escapedDeviceName := linux.PathNameEncode(devName)
 
 	d.logger.Debug("Using PCI bus device to hotplug NIC into", logger.Ctx{"device": deviceName, "port": pciDeviceName})
@@ -3589,7 +3589,7 @@ func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePo
 					break
 				}
 
-				qemuDev := make(map[string]string)
+				qemuDev := make(map[string]any)
 				if slices.Contains([]string{"nvme", "virtio-blk"}, busName) {
 					// Allocate a PCI(e) port and write it to the config file so QMP can "hotplug" the
 					// drive into it later.
@@ -3600,7 +3600,7 @@ func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePo
 					qemuDev["addr"] = devAddr
 
 					if multi {
-						qemuDev["multifunction"] = "on"
+						qemuDev["multifunction"] = true
 					}
 				}
 
@@ -3624,7 +3624,7 @@ func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePo
 
 		// Add network device.
 		if len(runConf.NetworkInterface) > 0 {
-			qemuDev := make(map[string]string)
+			qemuDev := make(map[string]any)
 			if slices.Contains([]string{"pcie", "pci"}, bus.name) {
 				// Allocate a PCI(e) port and write it to the config file so QMP can "hotplug" the
 				// NIC into it later.
@@ -3635,7 +3635,7 @@ func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePo
 				qemuDev["addr"] = devAddr
 
 				if multi {
-					qemuDev["multifunction"] = "on"
+					qemuDev["multifunction"] = true
 				}
 			}
 
@@ -3860,7 +3860,7 @@ func (d *qemu) addFileDescriptor(fdFiles *[]*os.File, file *os.File) int {
 }
 
 // addRootDriveConfig adds the qemu config required for adding the root drive.
-func (d *qemu) addRootDriveConfig(qemuDev map[string]string, mountInfo *storagePools.MountInfo, bootIndexes map[string]int, rootDriveConf deviceConfig.MountEntryItem) (monitorHook, error) {
+func (d *qemu) addRootDriveConfig(qemuDev map[string]any, mountInfo *storagePools.MountInfo, bootIndexes map[string]int, rootDriveConf deviceConfig.MountEntryItem) (monitorHook, error) {
 	if rootDriveConf.TargetPath != "/" {
 		return nil, fmt.Errorf("Non-root drive config supplied")
 	}
@@ -3992,7 +3992,7 @@ func (d *qemu) addDriveDirConfig(cfg *[]cfgSection, bus *qemuBus, fdFiles *[]*os
 }
 
 // addDriveConfig adds the qemu config required for adding a supplementary drive.
-func (d *qemu) addDriveConfig(qemuDev map[string]string, bootIndexes map[string]int, driveConf deviceConfig.MountEntryItem) (monitorHook, error) {
+func (d *qemu) addDriveConfig(qemuDev map[string]any, bootIndexes map[string]int, driveConf deviceConfig.MountEntryItem) (monitorHook, error) {
 	aioMode := "native" // Use native kernel async IO and O_DIRECT by default.
 	cacheMode := "none" // Bypass host cache, use O_DIRECT semantics by default.
 	media := "disk"
@@ -4248,7 +4248,7 @@ func (d *qemu) addDriveConfig(qemuDev map[string]string, bootIndexes map[string]
 	}
 
 	if qemuDev == nil {
-		qemuDev = map[string]string{}
+		qemuDev = map[string]any{}
 	}
 
 	qemuDev["id"] = fmt.Sprintf("%s%s", qemuDeviceIDPrefix, escapedDeviceName)
@@ -4256,8 +4256,8 @@ func (d *qemu) addDriveConfig(qemuDev map[string]string, bootIndexes map[string]
 	qemuDev["serial"] = fmt.Sprintf("%s%s", qemuBlockDevIDPrefix, escapedDeviceName)
 
 	if bus == "virtio-scsi" {
-		qemuDev["channel"] = "0"
-		qemuDev["lun"] = "1"
+		qemuDev["channel"] = 0
+		qemuDev["lun"] = 1
 		qemuDev["bus"] = "qemu_scsi.0"
 
 		if media == "disk" {
@@ -4282,7 +4282,7 @@ func (d *qemu) addDriveConfig(qemuDev map[string]string, bootIndexes map[string]
 	}
 
 	if bootIndexes != nil {
-		qemuDev["bootindex"] = strconv.Itoa(bootIndexes[driveConf.DevName])
+		qemuDev["bootindex"] = bootIndexes[driveConf.DevName]
 	}
 
 	monHook := func(m *qmp.Monitor) error {
@@ -4336,7 +4336,7 @@ func (d *qemu) addDriveConfig(qemuDev map[string]string, bootIndexes map[string]
 		}
 
 		if driveConf.Limits != nil {
-			err = m.SetBlockThrottle(qemuDev["id"], int(driveConf.Limits.ReadBytes), int(driveConf.Limits.WriteBytes), int(driveConf.Limits.ReadIOps), int(driveConf.Limits.WriteIOps))
+			err = m.SetBlockThrottle(qemuDev["id"].(string), int(driveConf.Limits.ReadBytes), int(driveConf.Limits.WriteBytes), int(driveConf.Limits.ReadIOps), int(driveConf.Limits.WriteIOps))
 			if err != nil {
 				return fmt.Errorf("Failed applying limits for disk device %q: %w", driveConf.DevName, err)
 			}
@@ -4351,7 +4351,7 @@ func (d *qemu) addDriveConfig(qemuDev map[string]string, bootIndexes map[string]
 
 // addNetDevConfig adds the qemu config required for adding a network device.
 // The qemuDev map is expected to be preconfigured with the settings for an existing port to use for the device.
-func (d *qemu) addNetDevConfig(busName string, qemuDev map[string]string, bootIndexes map[string]int, nicConfig []deviceConfig.RunConfigItem) (monitorHook, error) {
+func (d *qemu) addNetDevConfig(busName string, qemuDev map[string]any, bootIndexes map[string]int, nicConfig []deviceConfig.RunConfigItem) (monitorHook, error) {
 	reverter := revert.New()
 	defer reverter.Fail()
 
@@ -4382,7 +4382,7 @@ func (d *qemu) addNetDevConfig(busName string, qemuDev map[string]string, bootIn
 	if len(bootIndexes) > 0 {
 		bootIndex, found := bootIndexes[devName]
 		if found {
-			qemuDev["bootindex"] = strconv.Itoa(bootIndex)
+			qemuDev["bootindex"] = bootIndex
 		}
 	}
 
@@ -4400,9 +4400,9 @@ func (d *qemu) addNetDevConfig(busName string, qemuDev map[string]string, bootIn
 		// Number of vectors is number of vCPUs * 2 (RX/TX) + 2 (config/control MSI-X).
 		vectors := 2*queueCount + 2
 		if vectors > 0 {
-			qemuDev["mq"] = "on"
+			qemuDev["mq"] = true
 			if slices.Contains([]string{"pcie", "pci"}, busName) {
-				qemuDev["vectors"] = strconv.Itoa(vectors)
+				qemuDev["vectors"] = vectors
 			}
 		}
 
@@ -4591,9 +4591,9 @@ func (d *qemu) addNetDevConfig(busName string, qemuDev map[string]string, bootIn
 			}
 
 			qemuDev["netdev"] = qemuNetDev["id"].(string)
-			qemuDev["page-per-vq"] = "on"
-			qemuDev["iommu_platform"] = "on"
-			qemuDev["disable-legacy"] = "on"
+			qemuDev["page-per-vq"] = true
+			qemuDev["iommu_platform"] = true
+			qemuDev["disable-legacy"] = true
 
 			err = m.AddNIC(qemuNetDev, qemuDev)
 			if err != nil {
@@ -4819,7 +4819,7 @@ func (d *qemu) addGPUDevConfig(cfg *[]cfgSection, bus *qemuBus, gpuConfig []devi
 }
 
 func (d *qemu) addUSBDeviceConfig(usbDev deviceConfig.USBDeviceItem) (monitorHook, error) {
-	device := map[string]string{
+	qemuDev := map[string]any{
 		"id":     fmt.Sprintf("%s%s", qemuDeviceIDPrefix, usbDev.DeviceName),
 		"driver": "usb-host",
 		"bus":    "qemu_usb.0",
@@ -4836,18 +4836,18 @@ func (d *qemu) addUSBDeviceConfig(usbDev deviceConfig.USBDeviceItem) (monitorHoo
 
 		defer func() { _ = f.Close() }()
 
-		info, err := m.SendFileWithFDSet(device["id"], f, false)
+		info, err := m.SendFileWithFDSet(qemuDev["id"].(string), f, false)
 		if err != nil {
 			return fmt.Errorf("Failed to send file descriptor: %w", err)
 		}
 
 		revert.Add(func() {
-			_ = m.RemoveFDFromFDSet(device["id"])
+			_ = m.RemoveFDFromFDSet(qemuDev["id"].(string))
 		})
 
-		device["hostdevice"] = fmt.Sprintf("/dev/fdset/%d", info.ID)
+		qemuDev["hostdevice"] = fmt.Sprintf("/dev/fdset/%d", info.ID)
 
-		err = m.AddDevice(device)
+		err = m.AddDevice(qemuDev)
 		if err != nil {
 			return fmt.Errorf("Failed to add device: %w", err)
 		}
@@ -9188,19 +9188,19 @@ func (d *qemu) setCPUs(monitor *qmp.Monitor, count int) error {
 
 			devID := fmt.Sprintf("cpu%d%d%d", cpu.Props.SocketID, cpu.Props.CoreID, cpu.Props.ThreadID)
 
-			dev := map[string]string{
+			qemuDev := map[string]any{
 				"id":      devID,
 				"driver":  cpu.Type,
-				"core-id": fmt.Sprintf("%d", cpu.Props.CoreID),
+				"core-id": cpu.Props.CoreID,
 			}
 
 			// No such thing as sockets and threads on s390x.
 			if d.architecture != osarch.ARCH_64BIT_S390_BIG_ENDIAN {
-				dev["socket-id"] = fmt.Sprintf("%d", cpu.Props.SocketID)
-				dev["thread-id"] = fmt.Sprintf("%d", cpu.Props.ThreadID)
+				qemuDev["socket-id"] = cpu.Props.SocketID
+				qemuDev["thread-id"] = cpu.Props.ThreadID
 			}
 
-			err := monitor.AddDevice(dev)
+			err := monitor.AddDevice(qemuDev)
 			if err != nil {
 				return fmt.Errorf("Failed to add device: %w", err)
 			}
@@ -9229,12 +9229,12 @@ func (d *qemu) setCPUs(monitor *qmp.Monitor, count int) error {
 			}
 
 			revert.Add(func() {
-				err := monitor.AddDevice(map[string]string{
+				err := monitor.AddDevice(map[string]any{
 					"id":        devID,
 					"driver":    cpu.Type,
-					"socket-id": fmt.Sprintf("%d", cpu.Props.SocketID),
-					"core-id":   fmt.Sprintf("%d", cpu.Props.CoreID),
-					"thread-id": fmt.Sprintf("%d", cpu.Props.ThreadID),
+					"socket-id": cpu.Props.SocketID,
+					"core-id":   cpu.Props.CoreID,
+					"thread-id": cpu.Props.ThreadID,
 				})
 				d.logger.Warn("Failed to add CPU device", logger.Ctx{"err": err})
 			})
diff --git a/internal/server/instance/drivers/qmp/commands.go b/internal/server/instance/drivers/qmp/commands.go
index 3e9752780c5..d81da8ff4f4 100644
--- a/internal/server/instance/drivers/qmp/commands.go
+++ b/internal/server/instance/drivers/qmp/commands.go
@@ -538,7 +538,7 @@ func (m *Monitor) SetMemoryBalloonSizeBytes(sizeBytes int64) error {
 }
 
 // AddBlockDevice adds a block device.
-func (m *Monitor) AddBlockDevice(blockDev map[string]any, device map[string]string) error {
+func (m *Monitor) AddBlockDevice(blockDev map[string]any, device map[string]any) error {
 	revert := revert.New()
 	defer revert.Fail()
 
@@ -624,7 +624,7 @@ func (m *Monitor) RemoveCharDevice(deviceID string) error {
 }
 
 // AddDevice adds a new device.
-func (m *Monitor) AddDevice(device map[string]string) error {
+func (m *Monitor) AddDevice(device map[string]any) error {
 	if device != nil {
 		err := m.Run("device_add", device, nil)
 		if err != nil {
@@ -656,7 +656,7 @@ func (m *Monitor) RemoveDevice(deviceID string) error {
 }
 
 // AddNIC adds a NIC device.
-func (m *Monitor) AddNIC(netDev map[string]any, device map[string]string) error {
+func (m *Monitor) AddNIC(netDev map[string]any, device map[string]any) error {
 	revert := revert.New()
 	defer revert.Fail()
 
+4 −1
Original line number Diff line number Diff line
@@ -2,5 +2,8 @@ import ./generic.nix {
  hash = "sha256-Ir+cT+2xA+L4kBXhwA0XXE/D8zjMPGYiwW0VrEdobZ4=";
  version = "6.8.0";
  vendorHash = "sha256-CDLq41AB2Y9nYlTuXZaAOgwXIin9CbqSXCFoigsc14A=";
  patches = [ ];
  patches = [
    # qemu 9.2 support
    ./1531.diff
  ];
}