|
|
7a3408 |
From 3216788d3cd902dd31705cac5e91589b9b467543 Mon Sep 17 00:00:00 2001
|
|
|
7a3408 |
Message-Id: <3216788d3cd902dd31705cac5e91589b9b467543@dist-git>
|
|
|
7a3408 |
From: Martin Kletzander <mkletzan@redhat.com>
|
|
|
7a3408 |
Date: Thu, 6 Aug 2015 13:10:54 +0200
|
|
|
7a3408 |
Subject: [PATCH] qemu: Reject updating unsupported disk information
|
|
|
7a3408 |
|
|
|
7a3408 |
If one calls update-device with information that is not updatable,
|
|
|
7a3408 |
libvirt reports success even though no data were updated. The example
|
|
|
7a3408 |
used in the bug linked below uses updating device with <boot order='2'/>
|
|
|
7a3408 |
which, in my opinion, is a valid thing to request from user's
|
|
|
7a3408 |
perspective. Mainly since we properly error out if user wants to update
|
|
|
7a3408 |
such data on a network device for example.
|
|
|
7a3408 |
|
|
|
7a3408 |
And since there are many things that might happen (update-device on disk
|
|
|
7a3408 |
basically knows just how to change removable media), check for what's
|
|
|
7a3408 |
changing and moreover, since the function might be usable in other
|
|
|
7a3408 |
drivers (updating only disk path is a valid possibility) let's abstract
|
|
|
7a3408 |
it for any two disks.
|
|
|
7a3408 |
|
|
|
7a3408 |
We can't possibly check for everything since for many fields our code
|
|
|
7a3408 |
does not properly differentiate between default and unspecified values.
|
|
|
7a3408 |
Even though this could be changed, I don't feel like it's worth the
|
|
|
7a3408 |
complexity so it's not the aim of this patch.
|
|
|
7a3408 |
|
|
|
7a3408 |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1007228
|
|
|
7a3408 |
(cherry picked from commit 717c99f3602354136ca97edca6afc8dce69aae85)
|
|
|
7a3408 |
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
|
|
7a3408 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
---
|
|
|
7a3408 |
src/conf/domain_conf.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
7a3408 |
src/conf/domain_conf.h | 2 +
|
|
|
7a3408 |
src/libvirt_private.syms | 1 +
|
|
|
7a3408 |
src/qemu/qemu_driver.c | 3 ++
|
|
|
7a3408 |
4 files changed, 134 insertions(+)
|
|
|
7a3408 |
|
|
|
7a3408 |
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|
|
7a3408 |
index 72d87dd..4fe38ae 100644
|
|
|
7a3408 |
--- a/src/conf/domain_conf.c
|
|
|
7a3408 |
+++ b/src/conf/domain_conf.c
|
|
|
7a3408 |
@@ -5690,6 +5690,134 @@ virDomainDiskFindByBusAndDst(virDomainDefPtr def,
|
|
|
7a3408 |
return NULL;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+/*
|
|
|
7a3408 |
+ * Makes sure the @disk differs from @orig_disk only by the source
|
|
|
7a3408 |
+ * path and nothing else. Fields that are being checked and the
|
|
|
7a3408 |
+ * information whether they are nullable (may not be specified) or is
|
|
|
7a3408 |
+ * taken from the virDomainDiskDefFormat() code.
|
|
|
7a3408 |
+ */
|
|
|
7a3408 |
+bool
|
|
|
7a3408 |
+virDomainDiskDiffersSourceOnly(virDomainDiskDefPtr disk,
|
|
|
7a3408 |
+ virDomainDiskDefPtr orig_disk)
|
|
|
7a3408 |
+{
|
|
|
7a3408 |
+#define CHECK_EQ(field, field_name, nullable) \
|
|
|
7a3408 |
+ do { \
|
|
|
7a3408 |
+ if (nullable && !disk->field) \
|
|
|
7a3408 |
+ break; \
|
|
|
7a3408 |
+ if (disk->field != orig_disk->field) { \
|
|
|
7a3408 |
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, \
|
|
|
7a3408 |
+ _("cannot modify field '%s' of the disk"), \
|
|
|
7a3408 |
+ field_name); \
|
|
|
7a3408 |
+ return false; \
|
|
|
7a3408 |
+ } \
|
|
|
7a3408 |
+ } while (0)
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ CHECK_EQ(device, "device", false);
|
|
|
7a3408 |
+ CHECK_EQ(cachemode, "cache", true);
|
|
|
7a3408 |
+ CHECK_EQ(error_policy, "error_policy", true);
|
|
|
7a3408 |
+ CHECK_EQ(rerror_policy, "rerror_policy", true);
|
|
|
7a3408 |
+ CHECK_EQ(iomode, "io", true);
|
|
|
7a3408 |
+ CHECK_EQ(ioeventfd, "ioeventfd", true);
|
|
|
7a3408 |
+ CHECK_EQ(event_idx, "event_idx", true);
|
|
|
7a3408 |
+ CHECK_EQ(copy_on_read, "copy_on_read", true);
|
|
|
7a3408 |
+ CHECK_EQ(discard, "discard", true);
|
|
|
7a3408 |
+ CHECK_EQ(iothread, "iothread", true);
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (disk->geometry.cylinders &&
|
|
|
7a3408 |
+ disk->geometry.heads &&
|
|
|
7a3408 |
+ disk->geometry.sectors) {
|
|
|
7a3408 |
+ CHECK_EQ(geometry.cylinders, "geometry cylinders", false);
|
|
|
7a3408 |
+ CHECK_EQ(geometry.heads, "geometry heads", false);
|
|
|
7a3408 |
+ CHECK_EQ(geometry.sectors, "geometry sectors", false);
|
|
|
7a3408 |
+ CHECK_EQ(geometry.trans, "BIOS-translation-modus", true);
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ CHECK_EQ(blockio.logical_block_size,
|
|
|
7a3408 |
+ "blockio logical_block_size", false);
|
|
|
7a3408 |
+ CHECK_EQ(blockio.physical_block_size,
|
|
|
7a3408 |
+ "blockio physical_block_size", false);
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (disk->bus == VIR_DOMAIN_DISK_BUS_USB)
|
|
|
7a3408 |
+ CHECK_EQ(removable, "removable", true);
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.total_bytes_sec,
|
|
|
7a3408 |
+ "blkdeviotune total_bytes_sec",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.read_bytes_sec,
|
|
|
7a3408 |
+ "blkdeviotune read_bytes_sec",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.write_bytes_sec,
|
|
|
7a3408 |
+ "blkdeviotune write_bytes_sec",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.total_iops_sec,
|
|
|
7a3408 |
+ "blkdeviotune total_iops_sec",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.read_iops_sec,
|
|
|
7a3408 |
+ "blkdeviotune read_iops_sec",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.write_iops_sec,
|
|
|
7a3408 |
+ "blkdeviotune write_iops_sec",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.total_bytes_sec_max,
|
|
|
7a3408 |
+ "blkdeviotune total_bytes_sec_max",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.read_bytes_sec_max,
|
|
|
7a3408 |
+ "blkdeviotune read_bytes_sec_max",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.write_bytes_sec_max,
|
|
|
7a3408 |
+ "blkdeviotune write_bytes_sec_max",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.total_iops_sec_max,
|
|
|
7a3408 |
+ "blkdeviotune total_iops_sec_max",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.read_iops_sec_max,
|
|
|
7a3408 |
+ "blkdeviotune read_iops_sec_max",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.write_iops_sec_max,
|
|
|
7a3408 |
+ "blkdeviotune write_iops_sec_max",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+ CHECK_EQ(blkdeviotune.size_iops_sec,
|
|
|
7a3408 |
+ "blkdeviotune size_iops_sec",
|
|
|
7a3408 |
+ true);
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ CHECK_EQ(transient, "transient", true);
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (disk->serial && STRNEQ(disk->serial, orig_disk->serial)) {
|
|
|
7a3408 |
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
|
|
7a3408 |
+ _("cannot modify field '%s' of the disk"),
|
|
|
7a3408 |
+ "serial");
|
|
|
7a3408 |
+ return false;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (disk->wwn && STRNEQ(disk->wwn, orig_disk->wwn)) {
|
|
|
7a3408 |
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
|
|
7a3408 |
+ _("cannot modify field '%s' of the disk"),
|
|
|
7a3408 |
+ "wwn");
|
|
|
7a3408 |
+ return false;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (disk->vendor && STRNEQ(disk->vendor, orig_disk->vendor)) {
|
|
|
7a3408 |
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
|
|
7a3408 |
+ _("cannot modify field '%s' of the disk"),
|
|
|
7a3408 |
+ "vendor");
|
|
|
7a3408 |
+ return false;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ if (disk->product && STRNEQ(disk->product, orig_disk->product)) {
|
|
|
7a3408 |
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
|
|
7a3408 |
+ _("cannot modify field '%s' of the disk"),
|
|
|
7a3408 |
+ "product");
|
|
|
7a3408 |
+ return false;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ CHECK_EQ(info.bootIndex, "boot order", true);
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+#undef CHECK_EQ
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ return true;
|
|
|
7a3408 |
+}
|
|
|
7a3408 |
+
|
|
|
7a3408 |
int
|
|
|
7a3408 |
virDomainDiskDefAssignAddress(virDomainXMLOptionPtr xmlopt,
|
|
|
7a3408 |
virDomainDiskDefPtr def)
|
|
|
7a3408 |
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
|
|
|
7a3408 |
index 604d0b8..1be8e63 100644
|
|
|
7a3408 |
--- a/src/conf/domain_conf.h
|
|
|
7a3408 |
+++ b/src/conf/domain_conf.h
|
|
|
7a3408 |
@@ -2474,6 +2474,8 @@ int virDomainDeviceFindControllerModel(virDomainDefPtr def,
|
|
|
7a3408 |
virDomainDiskDefPtr virDomainDiskFindByBusAndDst(virDomainDefPtr def,
|
|
|
7a3408 |
int bus,
|
|
|
7a3408 |
char *dst);
|
|
|
7a3408 |
+bool virDomainDiskDiffersSourceOnly(virDomainDiskDefPtr disk,
|
|
|
7a3408 |
+ virDomainDiskDefPtr orig_disk);
|
|
|
7a3408 |
void virDomainControllerDefFree(virDomainControllerDefPtr def);
|
|
|
7a3408 |
void virDomainFSDefFree(virDomainFSDefPtr def);
|
|
|
7a3408 |
void virDomainActualNetDefFree(virDomainActualNetDefPtr def);
|
|
|
7a3408 |
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
|
7a3408 |
index 46e535e..0517c24 100644
|
|
|
7a3408 |
--- a/src/libvirt_private.syms
|
|
|
7a3408 |
+++ b/src/libvirt_private.syms
|
|
|
7a3408 |
@@ -249,6 +249,7 @@ virDomainDiskDefFree;
|
|
|
7a3408 |
virDomainDiskDefNew;
|
|
|
7a3408 |
virDomainDiskDefSourceParse;
|
|
|
7a3408 |
virDomainDiskDeviceTypeToString;
|
|
|
7a3408 |
+virDomainDiskDiffersSourceOnly;
|
|
|
7a3408 |
virDomainDiskDiscardTypeToString;
|
|
|
7a3408 |
virDomainDiskErrorPolicyTypeFromString;
|
|
|
7a3408 |
virDomainDiskErrorPolicyTypeToString;
|
|
|
7a3408 |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
7a3408 |
index bb0dc7e..8d569fe 100644
|
|
|
7a3408 |
--- a/src/qemu/qemu_driver.c
|
|
|
7a3408 |
+++ b/src/qemu/qemu_driver.c
|
|
|
7a3408 |
@@ -7940,6 +7940,9 @@ qemuDomainChangeDiskMediaLive(virConnectPtr conn,
|
|
|
7a3408 |
goto end;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
+ if (!virDomainDiskDiffersSourceOnly(disk, orig_disk))
|
|
|
7a3408 |
+ goto end;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
/* Add the new disk src into shared disk hash table */
|
|
|
7a3408 |
if (qemuAddSharedDevice(driver, dev, vm->def->name) < 0)
|
|
|
7a3408 |
goto end;
|
|
|
7a3408 |
--
|
|
|
7a3408 |
2.5.0
|
|
|
7a3408 |
|