1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
|
Author: Mathias Gibbens <gibmat@debian.org>
Description: Fix creation of VMs with newer versions of QEMU (ported from Incus)
From: https://github.com/lxc/incus/pull/1196, https://github.com/lxc/incus/pull/1531, and https://github.com/lxc/incus/pull/1871
diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index 8f19feb95..3b557ff9f 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -1468,7 +1468,15 @@ func (d *qemu) start(stateful bool, op *operationlock.InstanceOperation) error {
// Attempt to drop privileges (doesn't work when restoring state).
if !stateful && d.state.OS.UnprivUser != "" {
- qemuCmd = append(qemuCmd, "-runas", d.state.OS.UnprivUser)
+ qemuVer, _ := d.version()
+ qemuVer91, _ := version.NewDottedVersion("9.1.0")
+
+ // Since QEMU 9.1 the parameter `runas` has been marked as deprecated.
+ if qemuVer != nil && qemuVer.Compare(qemuVer91) >= 0 {
+ qemuCmd = append(qemuCmd, "-run-with", fmt.Sprintf("user=%s", d.state.OS.UnprivUser))
+ } else {
+ qemuCmd = append(qemuCmd, "-runas", d.state.OS.UnprivUser)
+ }
nvRAMPath := d.nvramPath()
if d.architectureSupportsUEFI(d.architecture) && shared.PathExists(nvRAMPath) {
@@ -2110,7 +2118,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 shared.StringInSlice(qemuBus, []string{"pcie", "pci"}) {
@@ -3021,7 +3029,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 shared.StringInSlice(bus.name, []string{"pcie", "pci"}) {
// Allocate a PCI(e) port and write it to the config file so QMP can "hotplug" the
// NIC into it later.
@@ -3032,7 +3040,7 @@ func (d *qemu) generateQemuConfigFile(cpuInfo *cpuTopology, mountInfo *storagePo
qemuDev["addr"] = devAddr
if multi {
- qemuDev["multifunction"] = "on"
+ qemuDev["multifunction"] = true
}
}
@@ -3591,17 +3599,17 @@ func (d *qemu) addDriveConfig(bootIndexes map[string]int, driveConf deviceConfig
blockDev["locking"] = "off"
}
- device := map[string]string{
+ device := map[string]any{
"id": fmt.Sprintf("%s%s", qemuDeviceIDPrefix, escapedDeviceName),
"drive": blockDev["node-name"].(string),
"bus": "qemu_scsi.0",
- "channel": "0",
- "lun": "1",
+ "channel": 0,
+ "lun": 1,
"serial": fmt.Sprintf("%s%s", qemuBlockDevIDPrefix, escapedDeviceName),
}
if bootIndexes != nil {
- device["bootindex"] = strconv.Itoa(bootIndexes[driveConf.DevName])
+ device["bootindex"] = bootIndexes[driveConf.DevName]
}
if media == "disk" {
@@ -3632,6 +3640,8 @@ func (d *qemu) addDriveConfig(bootIndexes map[string]int, driveConf deviceConfig
permissions = unix.O_RDONLY
}
+ permissions |= unix.O_DIRECT
+
f, err := os.OpenFile(driveConf.DevPath, permissions, 0)
if err != nil {
return fmt.Errorf("Failed opening file descriptor for disk device %q: %w", driveConf.DevName, err)
@@ -3665,7 +3675,7 @@ func (d *qemu) addDriveConfig(bootIndexes map[string]int, driveConf deviceConfig
// 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()
@@ -3701,7 +3711,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
}
}
@@ -3719,9 +3729,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 shared.StringInSlice(busName, []string{"pcie", "pci"}) {
- qemuDev["vectors"] = strconv.Itoa(vectors)
+ qemuDev["vectors"] = vectors
}
}
@@ -4087,7 +4097,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",
@@ -4104,18 +4114,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)
}
@@ -8137,19 +8147,19 @@ func (d *qemu) setCPUs(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)
}
@@ -8178,12 +8188,12 @@ func (d *qemu) setCPUs(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/lxd/instance/drivers/qmp/commands.go b/lxd/instance/drivers/qmp/commands.go
index 495970514..4de393ecd 100644
--- a/lxd/instance/drivers/qmp/commands.go
+++ b/lxd/instance/drivers/qmp/commands.go
@@ -466,7 +466,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()
@@ -520,7 +520,7 @@ func (m *Monitor) RemoveBlockDevice(blockDevName 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 {
@@ -552,7 +552,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()
|