With the blkdeviotune event this patch also fixes a bug that the updated
live values weren't saved to the live XML so they won't survive
restarting the libvirtd.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
include/libvirt/libvirt.h.in | 56 ++++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_driver.c | 54 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 110 insertions(+)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 898f8b5..32930e2 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -5262,6 +5262,61 @@ typedef void
(*virConnectDomainEventDeviceRemovedCallback)(virConnectPtr conn,
*/
#define VIR_DOMAIN_EVENT_CPUTUNE_EMULATOR_QUOTA "cputune.emulator_quota"
+/**
+ * VIR_DOMAIN_EVENT_BLKDEVIOTUNE_DISK:
+ *
+ * Macro represents the name of guest disk for which the values are updated,
+ * as VIR_TYPED_PARAM_STRING.
+ */
+#define VIR_DOMAIN_EVENT_BLKDEVIOTUNE_DISK "blkdeviotune.disk"
+
+/**
+ * VIR_DOMAIN_EVENT_BLKDEVIOTUNE_TOTAL_BYTES_SEC:
+ *
+ * Marco represents the total throughput limit in bytes per second,
+ * as VIR_TYPED_PARAM_ULLONG.
+ */
+#define VIR_DOMAIN_EVENT_BLKDEVIOTUNE_TOTAL_BYTES_SEC
"blkdeviotune.total_bytes_sec"
+
+/**
+ * VIR_DOMAIN_EVENT_BLKDEVIOTUNE_READ_BYTES_SEC:
+ *
+ * Marco represents the read throughput limit in bytes per second,
+ * as VIR_TYPED_PARAM_ULLONG.
+ */
+#define VIR_DOMAIN_EVENT_BLKDEVIOTUNE_READ_BYTES_SEC
"blkdeviotune.read_bytes_sec"
+
+/**
+ * VIR_DOMAIN_EVENT_BLKDEVIOTUNE_WRITE_BYTES_SEC:
+ *
+ * Macro represents the write throughput limit in bytes per second,
+ * as VIR_TYPED_PARAM_ULLONG.
+ */
+#define VIR_DOMAIN_EVENT_BLKDEVIOTUNE_WRITE_BYTES_SEC
"blkdeviotune.write_bytes_sec"
+
+/**
+ * VIR_DOMAIN_EVENT_BLKDEVIOTUNE_TOTAL_IOPS_SEC:
+ *
+ * Macro represents the total I/O operations per second,
+ * as VIR_TYPED_PARAM_ULLONG.
+ */
+#define VIR_DOMAIN_EVENT_BLKDEVIOTUNE_TOTAL_IOPS_SEC
"blkdeviotune.total_iops_sec"
+
+/**
+ * VIR_DOMAIN_EVENT_BLKDEVIOTUNE_READ_IOPS_SEC:
+ *
+ * Macro represents the read I/O operations per second,
+ * as VIR_TYPED_PARAM_ULLONG.
+ */
+#define VIR_DOMAIN_EVENT_BLKDEVIOTUNE_READ_IOPS_SEC
"blkdeviotune.read_iops_sec"
+
+/**
+ * VIR_DOMAIN_EVENT_BLKDEVIOTUNE_WRITE_IOPS_SEC:
+ *
+ * Macro represents the write I/O operations per second,
+ * as VIR_TYPED_PARAM_ULLONG.
+ */
+#define VIR_DOMAIN_EVENT_BLKDEVIOTUNE_WRITE_IOPS_SEC
"blkdeviotune.write_iops_sec"
/**
* virConnectDomainEventTunableCallback:
@@ -5277,6 +5332,7 @@ typedef void
(*virConnectDomainEventDeviceRemovedCallback)(virConnectPtr conn,
*
* Currently supported name spaces:
* "cputune.*"
+ * "blkdeviotune.*"
*
* The callback signature to use when registering for an event of type
* VIR_DOMAIN_EVENT_ID_TUNABLE with virConnectDomainEventRegisterAny()
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d1a0657..173333a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16274,6 +16274,10 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
bool set_iops = false;
virQEMUDriverConfigPtr cfg = NULL;
virCapsPtr caps = NULL;
+ virObjectEventPtr event = NULL;
+ virTypedParameterPtr eventParams = NULL;
+ int eventNparams = 0;
+ int eventMaxparams = 0;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -16315,6 +16319,10 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
&persistentDef) < 0)
goto endjob;
+ if (virTypedParamsAddString(&eventParams, &eventNparams,
&eventMaxparams,
+ VIR_DOMAIN_EVENT_BLKDEVIOTUNE_DISK, disk) < 0)
+ goto endjob;
+
for (i = 0; i < nparams; i++) {
virTypedParameterPtr param = ¶ms[i];
@@ -16328,26 +16336,56 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
if (STREQ(param->field, VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC)) {
info.total_bytes_sec = param->value.ul;
set_bytes = true;
+ if (virTypedParamsAddULLong(&eventParams, &eventNparams,
+ &eventMaxparams,
+ VIR_DOMAIN_EVENT_BLKDEVIOTUNE_TOTAL_BYTES_SEC,
+ param->value.ul) < 0)
+ goto endjob;
} else if (STREQ(param->field,
VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC)) {
info.read_bytes_sec = param->value.ul;
set_bytes = true;
+ if (virTypedParamsAddULLong(&eventParams, &eventNparams,
+ &eventMaxparams,
+ VIR_DOMAIN_EVENT_BLKDEVIOTUNE_READ_BYTES_SEC,
+ param->value.ul) < 0)
+ goto endjob;
} else if (STREQ(param->field,
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC)) {
info.write_bytes_sec = param->value.ul;
set_bytes = true;
+ if (virTypedParamsAddULLong(&eventParams, &eventNparams,
+ &eventMaxparams,
+ VIR_DOMAIN_EVENT_BLKDEVIOTUNE_WRITE_BYTES_SEC,
+ param->value.ul) < 0)
+ goto endjob;
} else if (STREQ(param->field,
VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC)) {
info.total_iops_sec = param->value.ul;
set_iops = true;
+ if (virTypedParamsAddULLong(&eventParams, &eventNparams,
+ &eventMaxparams,
+ VIR_DOMAIN_EVENT_BLKDEVIOTUNE_TOTAL_IOPS_SEC,
+ param->value.ul) < 0)
+ goto endjob;
} else if (STREQ(param->field,
VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC)) {
info.read_iops_sec = param->value.ul;
set_iops = true;
+ if (virTypedParamsAddULLong(&eventParams, &eventNparams,
+ &eventMaxparams,
+ VIR_DOMAIN_EVENT_BLKDEVIOTUNE_READ_IOPS_SEC,
+ param->value.ul) < 0)
+ goto endjob;
} else if (STREQ(param->field,
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC)) {
info.write_iops_sec = param->value.ul;
set_iops = true;
+ if (virTypedParamsAddULLong(&eventParams, &eventNparams,
+ &eventMaxparams,
+ VIR_DOMAIN_EVENT_BLKDEVIOTUNE_WRITE_IOPS_SEC,
+ param->value.ul) < 0)
+ goto endjob;
}
}
@@ -16405,6 +16443,20 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
if (ret < 0)
goto endjob;
vm->def->disks[idx]->blkdeviotune = info;
+
+ ret = virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm);
+ if (ret < 0) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("Saving live XML config failed"));
+ goto endjob;
+ }
+
+ if (eventNparams) {
+ event = virDomainEventTunableNewFromDom(dom, eventParams, eventNparams);
+ eventNparams = 0;
+ if (event)
+ qemuDomainEventQueue(driver, event);
+ }
}
if (flags & VIR_DOMAIN_AFFECT_CONFIG) {
@@ -16437,6 +16489,8 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
VIR_FREE(device);
if (vm)
virObjectUnlock(vm);
+ if (eventNparams)
+ virTypedParamsFree(eventParams, eventNparams);
virObjectUnref(caps);
virObjectUnref(cfg);
return ret;
--
1.8.5.5