Currenly API is not very convinient when switching from read/write to total tunes back and forth. read/write and total tunes can not be set simulaneously so one need to choose one. Now if for example total_bytes_sec and total_bytes_sec_max are set and we set read_bytes_sec only then API fails. The issue is new max settings are copied from the old ones in this case and as a result after defaults are applied we got settings for read_bytes_sec and total_bytes_sec_max which is incorrect. In order to handle such situation nicely let's reset max settings if appropriate avg settings is reseted explicitly or implicitly. Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@xxxxxxxxxxxxx> --- src/qemu/qemu_driver.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 117c7b7..9093baf 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15901,6 +15901,22 @@ qemuDomainSetBlockIoTuneDefaults(virDomainBlockIoTuneInfoPtr newinfo, SET_IOTUNE_DEFAULTS(IOPS_MAX, iops_sec_max); #undef SET_IOTUNE_DEFAULTS +#define RESET_IOTUNE_MAX(BOOL, FIELD) \ + do { \ + if (set_fields & QEMU_BLOCK_IOTUNE_SET_##BOOL) { \ + if (!newinfo->total_##FIELD) \ + newinfo->total_##FIELD##_max = 0; \ + if (!newinfo->read_##FIELD) \ + newinfo->read_##FIELD##_max = 0; \ + if (!newinfo->write_##FIELD) \ + newinfo->write_##FIELD##_max = 0; \ + } \ + } while (0) + + RESET_IOTUNE_MAX(BYTES, bytes_sec); + RESET_IOTUNE_MAX(IOPS, iops_sec); +#undef RESET_IOTUNE_MAX + if (!(set_fields & QEMU_BLOCK_IOTUNE_SET_SIZE_IOPS)) newinfo->size_iops_sec = oldinfo->size_iops_sec; if (!(set_fields & QEMU_BLOCK_IOTUNE_SET_GROUP_NAME)) @@ -16210,17 +16226,10 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, do { \ if (info.val##_max) { \ if (!info.val) { \ - if (QEMU_BLOCK_IOTUNE_SET_##_bool) { \ - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \ - _("cannot reset '%s' when " \ - "'%s' is set"), \ - #val, #val "_max"); \ - } else { \ - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \ - _("value '%s' cannot be set if " \ - "'%s' is not set"), \ - #val "_max", #val); \ - } \ + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, \ + _("value '%s' cannot be set if " \ + "'%s' is not set"), \ + #val "_max", #val); \ goto endjob; \ } \ if (info.val##_max < info.val) { \ -- 1.8.3.1