[libvirt] [PATCH v2 08/12] qemu: Add length for bps/iops throttling parameters to driver
John Ferlan
jferlan at redhat.com
Tue Oct 25 21:31:17 UTC 2016
On 10/25/2016 01:30 PM, Erik Skultety wrote:
> On Thu, Oct 06, 2016 at 06:38:56PM -0400, John Ferlan wrote:
>> Add support for a duration/length for the bps/iops and friends.
>>
>> Modify the API in order to add the "blkdeviotune." specific definitions
>> for the iotune throttling duration/length options
>>
>> total_bytes_sec_max_length
>> write_bytes_sec_max_length
>> read_bytes_sec_max_length
>> total_iops_sec_max_length
>> write_iops_sec_max_length
>> read_iops_sec_max_length
>>
>> Signed-off-by: John Ferlan <jferlan at redhat.com>
>> ---
>> include/libvirt/libvirt-domain.h | 54 +++++++++++++++++++++
>> src/conf/domain_conf.h | 6 +++
>> src/qemu/qemu_driver.c | 100 +++++++++++++++++++++++++++++++++++++--
>> src/qemu/qemu_monitor.c | 7 ++-
>> src/qemu/qemu_monitor.h | 3 +-
>> src/qemu/qemu_monitor_json.c | 25 +++++++++-
>> src/qemu/qemu_monitor_json.h | 3 +-
>> tests/qemumonitorjsontest.c | 17 ++++++-
>> 8 files changed, 202 insertions(+), 13 deletions(-)
>>
>
> [...]
>
>> @@ -17296,7 +17297,9 @@ qemuDomainSetBlockIoTuneSetDefaults(virDomainBlockIoTuneInfoPtr newinfo,
>
> just a nitpick, are both the 'Set's necessary in the name, unless one of them
> is a verb and the other a noun, I think the first one could be dropped.
>
D'oh... The name was so long I missed the double set!
>> bool set_iops,
>> bool set_bytes_max,
>> bool set_iops_max,
>> - bool set_size_iops)
>> + bool set_size_iops,
>> + bool set_bytes_max_length,
>> + bool set_iops_max_length)
>> {
>> if (!set_bytes) {
>> newinfo->total_bytes_sec = oldinfo->total_bytes_sec;
>> @@ -17320,6 +17323,36 @@ qemuDomainSetBlockIoTuneSetDefaults(virDomainBlockIoTuneInfoPtr newinfo,
>> }
>> if (!set_size_iops)
>> newinfo->size_iops_sec = oldinfo->size_iops_sec;
>> +
>> + /* The length field is handled a bit differently. If not defined/set,
>> + * QEMU will default these to 0 or 1 depending on whether something in
>> + * the same family is set or not.
>> + *
>> + * Similar to other values, if nothing in the family is defined/set,
>> + * then take whatever is in the oldinfo.
>> + *
>> + * To clear an existing limit, a 0 is provided; however, passing that
>> + * 0 onto QEMU if there's a family value defined/set (or defaulted)
>> + * will cause an error. So, to mimic that, if our oldinfo was set and
>> + * our newinfo is clearing, then set max_length based on whether we
>> + * have a value in the family set/defined. */
>
> Hmm. You can disregard my comment in 4/12 about replacing the whole function
> with a macro, instead I suggest keeping the function and making the macro below
> also work for all the settings above, otherwise it just doesn't look right, one
> part of the function being expanded while the other covered by a macro because
> the behaviour is slightly different (I have to admit though, it was kinda
> painful to comprehend what's going on on the qemu side)
>
Yes, quite painful - especially when I realized it after the initial
series... The difference is I went with a function.
I create a macro for the setting of the defaults
>> +#define SET_MAX_LENGTH(BOOL, FIELD) \
>> + if (!BOOL) \
>> + newinfo->FIELD##_max_length = oldinfo->FIELD##_max_length; \
>> + else if (BOOL && oldinfo->FIELD##_max_length && \
>> + !newinfo->FIELD##_max_length) \
>> + newinfo->FIELD##_max_length = (newinfo->FIELD || \
>> + newinfo->FIELD##_max) ? 1 : 0;
>> +
>> + SET_MAX_LENGTH(set_bytes_max_length, total_bytes_sec);
>> + SET_MAX_LENGTH(set_bytes_max_length, read_bytes_sec);
>> + SET_MAX_LENGTH(set_bytes_max_length, write_bytes_sec);
>> + SET_MAX_LENGTH(set_iops_max_length, total_iops_sec);
>> + SET_MAX_LENGTH(set_iops_max_length, read_iops_sec);
>> + SET_MAX_LENGTH(set_iops_max_length, write_iops_sec);
>> +
>> +#undef SET_MAX_LENGTH
>> +
>> }
>>
>>
>> @@ -17346,7 +17379,10 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
>> bool set_bytes_max = false;
>> bool set_iops_max = false;
>> bool set_size_iops = false;
>> + bool set_bytes_max_length = false;
>> + bool set_iops_max_length = false;
>> bool supportMaxOptions = true;
>> + bool supportMaxLengthOptions = true;
>> virQEMUDriverConfigPtr cfg = NULL;
>> virObjectEventPtr event = NULL;
>> virTypedParameterPtr eventParams = NULL;
>> @@ -17382,6 +17418,18 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
>> VIR_TYPED_PARAM_ULLONG,
>> VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC,
>> VIR_TYPED_PARAM_ULLONG,
>> + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX_LENGTH,
>> + VIR_TYPED_PARAM_ULLONG,
>> + VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX_LENGTH,
>> + VIR_TYPED_PARAM_ULLONG,
>> + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX_LENGTH,
>> + VIR_TYPED_PARAM_ULLONG,
>> + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX_LENGTH,
>> + VIR_TYPED_PARAM_ULLONG,
>> + VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX_LENGTH,
>> + VIR_TYPED_PARAM_ULLONG,
>> + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX_LENGTH,
>> + VIR_TYPED_PARAM_ULLONG,
>> NULL) < 0)
>> return -1;
>>
>> @@ -17449,6 +17497,19 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
>> SET_IOTUNE_FIELD(write_iops_sec_max, set_iops_max,
>> WRITE_IOPS_SEC_MAX);
>> SET_IOTUNE_FIELD(size_iops_sec, set_size_iops, SIZE_IOPS_SEC);
>> +
>> + SET_IOTUNE_FIELD(total_bytes_sec_max_length, set_bytes_max_length,
>> + TOTAL_BYTES_SEC_MAX_LENGTH);
>> + SET_IOTUNE_FIELD(read_bytes_sec_max_length, set_bytes_max_length,
>> + READ_BYTES_SEC_MAX_LENGTH);
>> + SET_IOTUNE_FIELD(write_bytes_sec_max_length, set_bytes_max_length,
>> + WRITE_BYTES_SEC_MAX_LENGTH);
>> + SET_IOTUNE_FIELD(total_iops_sec_max_length, set_iops_max_length,
>> + TOTAL_IOPS_SEC_MAX_LENGTH);
>> + SET_IOTUNE_FIELD(read_iops_sec_max_length, set_iops_max_length,
>> + READ_IOPS_SEC_MAX_LENGTH);
>> + SET_IOTUNE_FIELD(write_iops_sec_max_length, set_iops_max_length,
>> + WRITE_IOPS_SEC_MAX_LENGTH);
>> }
>>
>> #undef SET_IOTUNE_FIELD
>> @@ -17488,6 +17549,9 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
>> if (def) {
>> supportMaxOptions = virQEMUCapsGet(priv->qemuCaps,
>> QEMU_CAPS_DRIVE_IOTUNE_MAX);
>> + supportMaxLengthOptions =
>> + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX_LENGTH);
>> +
>
> Basically I have nothing against this^^, just a note that should the
> capabilities covering iotune be extended in the future I can image this to be
> handled as OR'd flags rather than individual variables, but it's okay now.
Ironically - there is another field, but it was added before the -length
values were supported. That's the *next* series I'll be posting...
The tricky part of the OR'd flags will be how the command line logic is
put together. It's a rather unique hack that ultimately is in
qemuMonitorJSONSetBlockIoThrottle regarding how the command line is put
together with a bit of "knowledge" regarding "when" the boolean was added.
Coming to the theater of the absurd soon is "max" (added in qemu 1.7),
"group" (added in qemu 2.4), and "max_length" (added in qemu 2.6).
Tks -
John
>
> ACK with the macro adjustment above.
>
> Erik
>
More information about the libvir-list
mailing list