Support to update the disk's bootindex using 'virsh update-device'.
Using flag --config or --persistent to change the boot index and the
change will be affected after reboot. With --persistent, we can get
the result of change immediently, but it still takes effect after reboot.
Currently, support update bootindex of disk type as cdrom or disk.
Signed-off-by: Jiang Jiacheng <jiangjiacheng(a)huawei.com>
---
src/qemu/qemu_domain.c | 37 ++++++++++++++++++++++++++++++++++++-
src/qemu/qemu_domain.h | 5 +++++
src/qemu/qemu_driver.c | 28 ++++++++++++++++++++++++++++
3 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 6ec3be14c0..dfc4d15387 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8235,7 +8235,8 @@ qemuDomainDiskChangeSupported(virDomainDiskDef *disk,
/* device alias is checked already in virDomainDefCompatibleDevice */
- CHECK_EQ(info.bootIndex, "boot order", true);
+ if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
+ CHECK_EQ(info.bootIndex, "boot order", true);
CHECK_EQ(rawio, "rawio", true);
CHECK_EQ(sgio, "sgio", true);
CHECK_EQ(discard, "discard", true);
@@ -12309,3 +12310,37 @@ qemuCheckBootIndex(virDomainDeviceInfo *devInfo,
return 0;
}
+
+/**
+ * qemuChangeDiskBootIndex:
+ * @vm: domain object
+ * @orig_disk: the origin disk
+ * @disk: the new disk to be updated to
+ *
+ * check device's type and if its type support update bootIndex, update it.
+ *
+ */
+int
+qemuChangeDiskBootIndex(virDomainObj *vm,
+ virDomainDiskDef *orig_disk,
+ virDomainDiskDef *disk)
+{
+ switch (disk->device) {
+ case VIR_DOMAIN_DISK_DEVICE_CDROM:
+ case VIR_DOMAIN_DISK_DEVICE_DISK:
+ case VIR_DOMAIN_DISK_DEVICE_LUN:
+ if (qemuDomainChangeBootIndex(vm, &orig_disk->info,
+ disk->info.bootIndex) < 0)
+ return -1;
+
+ orig_disk->info.bootIndex = disk->info.bootIndex;
+ break;
+ case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
+ case VIR_DOMAIN_DISK_DEVICE_LAST:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("The boot index of disk bus '%s' cannot be
changed."),
+ virDomainDiskBusTypeToString(disk->bus));
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 5869771a0d..da661d11da 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1144,3 +1144,8 @@ qemuDomainSchedCoreStop(qemuDomainObjPrivate *priv);
int
qemuCheckBootIndex(virDomainDeviceInfo *devInfo,
const int new_bootindex);
+
+int
+qemuChangeDiskBootIndex(virDomainObj *vm,
+ virDomainDiskDef *orig_disk,
+ virDomainDiskDef *disk);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d509582719..d5fa9c022c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6795,6 +6795,7 @@ qemuDomainChangeDiskLive(virDomainObj *vm,
virDomainDiskDef *orig_disk = NULL;
virDomainStartupPolicy origStartupPolicy;
virDomainDeviceDef oldDev = { .type = dev->type };
+ int needChangeIndex = 0;
if (!(orig_disk = virDomainDiskByTarget(vm->def, disk->dst))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -6812,6 +6813,10 @@ qemuDomainChangeDiskLive(virDomainObj *vm,
if (!qemuDomainDiskChangeSupported(disk, orig_disk))
return -1;
+ if ((needChangeIndex = qemuCheckBootIndex(&orig_disk->info,
+ disk->info.bootIndex)) < 0)
+ return -1;
+
if (!virStorageSourceIsSameLocation(disk->src, orig_disk->src)) {
/* Disk source can be changed only for removable devices */
if (disk->device != VIR_DOMAIN_DISK_DEVICE_CDROM &&
@@ -6835,6 +6840,11 @@ qemuDomainChangeDiskLive(virDomainObj *vm,
dev->data.disk->src = NULL;
}
+ if (needChangeIndex) {
+ if (qemuChangeDiskBootIndex(vm, orig_disk, disk) < 0)
+ return -1;
+ }
+
/* in case when we aren't updating disk source we update startup policy here */
orig_disk->startupPolicy = dev->data.disk->startupPolicy;
orig_disk->snapshot = dev->data.disk->snapshot;
@@ -7531,6 +7541,24 @@ qemuDomainUpdateDeviceConfig(virDomainDef *vmdef,
false) < 0)
return -1;
+ switch (vmdef->disks[pos]->device) {
+ case VIR_DOMAIN_DISK_DEVICE_CDROM:
+ case VIR_DOMAIN_DISK_DEVICE_DISK:
+ case VIR_DOMAIN_DISK_DEVICE_LUN:
+ if (qemuCheckBootIndex(&vmdef->disks[pos]->info,
+ newDisk->info.bootIndex) < 0)
+ return -1;
+ break;
+ case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
+ case VIR_DOMAIN_DISK_DEVICE_LAST:
+ if ((newDisk->info.bootIndex) &&
+ (vmdef->disks[pos]->info.bootIndex != newDisk->info.bootIndex))
{
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("this disk doesn't support update"));
+ return -1;
+ }
+ }
+
virDomainDiskDefFree(vmdef->disks[pos]);
vmdef->disks[pos] = newDisk;
dev->data.disk = NULL;
--
2.33.0