[libvirt] [PATCH v2 0/9] qemu: Introduce support for new the block_set_io_throttle parameters add in the version 1.7 of qemu.

This series of patches add support for bps_max, bps_rd_max, bps_wr_max, bps_max, bps_rd_max, bps_wr_max, and iops_size in the functions qemuDomainSetBlockIoTune and qemuDomainGetBlockIoTune. The last patch add support for terse parameters to the virsh blkdeviotune command. v2: spellfix Matthias Gatto (9): qemu: Add defines for the news throttle options qemu: Add news throttle options to the structure _virDomainBlockIoTuneInfo. qemu: Add the capabilitie to detect if the qemu binary have the capability to use bps_max and friends qemu: Add bps_max and friends qemu driver qemu: Add bps_max and friend to domain_conf qemu: Add bps_max and friends QMP suport qemu: Add bps_max and friends "text" support qemu: add bps_max and friends to qemu command generation virsh: Add bps_max and friends to virsh include/libvirt/libvirt.h.in | 54 +++++++++++++++ src/conf/domain_conf.c | 89 +++++++++++++++++++++++- src/conf/domain_conf.h | 8 +++ src/qemu/qemu_capabilities.c | 6 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 49 ++++++++++++++ src/qemu/qemu_driver.c | 158 +++++++++++++++++++++++++++++++++++++++++-- src/qemu/qemu_monitor_json.c | 58 +++++++++++++--- src/qemu/qemu_monitor_text.c | 75 ++++++++++++++++++-- tests/qemumonitorjsontest.c | 2 +- tools/virsh-domain.c | 119 ++++++++++++++++++++++++++++++++ 11 files changed, 595 insertions(+), 24 deletions(-) -- 1.8.3.1

Add defines for the news options total_bytes_sec_max, write_bytes_sec_max, read_bytes_sec_max total_iops_sec_max, write_iops_sec_max, read_iops_sec_max, size_iops_sec. Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- include/libvirt/libvirt.h.in | 54 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index ad6785f..4094103 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2668,6 +2668,60 @@ int virDomainBlockCommit(virDomainPtr dom, const char *disk, const char *base, */ #define VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC "write_iops_sec" +/** + * VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX: + * + * Macro for the BlockIoTune tunable weight: it represents the maximum total + * bytes per second permitted through a block device, as a ullong. + */ +#define VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX "total_bytes_sec_max" + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX: + * + * Macro for the BlockIoTune tunable weight: it represents the maximum read + * bytes per second permitted through a block device, as a ullong. + */ +#define VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX "read_bytes_sec_max" + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX: + * + * Macro for the BlockIoTune tunable weight: it represents the maximum write + * bytes per second permitted through a block device, as a ullong. + */ +#define VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX "write_bytes_sec_max" + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX: + * + * Macro for the BlockIoTune tunable weight: it represents the maximum + * I/O operations per second permitted through a block device, as a ullong. + */ +#define VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX "total_iops_sec_max" + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX: + * + * Macro for the BlockIoTune tunable weight: it represents the maximum read + * I/O operations per second permitted through a block device, as a ullong. + */ +#define VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX "read_iops_sec_max" + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX: + * Macro for the BlockIoTune tunable weight: it represents the maximum write + * I/O operations per second permitted through a block device, as a ullong. + */ +#define VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX "write_iops_sec_max" + +/** + * VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC: + * Macro for the BlockIoTune tunable weight: it represents the size + * I/O operations per second permitted through a block device, as a ullong. + */ +#define VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC "size_iops_sec" + int virDomainSetBlockIoTune(virDomainPtr dom, const char *disk, -- 1.8.3.1

Modify the structure _virDomainBlockIoTuneInfo to support total_bytes_sec_max, write_bytes_sec_max, read_bytes_sec_max, total_iops_sec_max, write_iops_sec_max, read_iops_sec_max, size_iops_sec options. Add the boolean support_max_options in the structure _virDomainBlockIoTuneInfo to know if the qemu binary suport the bps_max options and they friends. Change the initialization of the variable expectedInfo in qemumonitorjsontest.c to avoid compiling problem. Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/conf/domain_conf.h | 8 ++++++++ tests/qemumonitorjsontest.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index ff7d640..5423523 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -606,6 +606,14 @@ struct _virDomainBlockIoTuneInfo { unsigned long long total_iops_sec; unsigned long long read_iops_sec; unsigned long long write_iops_sec; + unsigned long long total_bytes_sec_max; + unsigned long long read_bytes_sec_max; + unsigned long long write_bytes_sec_max; + unsigned long long total_iops_sec_max; + unsigned long long read_iops_sec_max; + unsigned long long write_iops_sec_max; + unsigned long long size_iops_sec; + bool suport_max_options; }; typedef virDomainBlockIoTuneInfo *virDomainBlockIoTuneInfoPtr; diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index baee80a..5a2a337 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1835,7 +1835,7 @@ testQemuMonitorJSONqemuMonitorJSONSetBlockIoThrottle(const void *data) if (!test) return -1; - expectedInfo = (virDomainBlockIoTuneInfo) {1, 2, 3, 4, 5, 6}; + expectedInfo = (virDomainBlockIoTuneInfo) {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, false}; if (qemuMonitorTestAddItem(test, "query-block", queryBlockReply) < 0 || qemuMonitorTestAddItemParams(test, "block_set_io_throttle", -- 1.8.3.1

On 15.09.2014 19:27, Matthias Gatto wrote:
Modify the structure _virDomainBlockIoTuneInfo to support total_bytes_sec_max, write_bytes_sec_max, read_bytes_sec_max, total_iops_sec_max, write_iops_sec_max, read_iops_sec_max, size_iops_sec options.
Add the boolean support_max_options in the structure _virDomainBlockIoTuneInfo to know if the qemu binary suport the bps_max options and they friends.
Change the initialization of the variable expectedInfo in qemumonitorjsontest.c to avoid compiling problem.
Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/conf/domain_conf.h | 8 ++++++++ tests/qemumonitorjsontest.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index ff7d640..5423523 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -606,6 +606,14 @@ struct _virDomainBlockIoTuneInfo { unsigned long long total_iops_sec; unsigned long long read_iops_sec; unsigned long long write_iops_sec; + unsigned long long total_bytes_sec_max; + unsigned long long read_bytes_sec_max; + unsigned long long write_bytes_sec_max; + unsigned long long total_iops_sec_max; + unsigned long long read_iops_sec_max; + unsigned long long write_iops_sec_max; + unsigned long long size_iops_sec; + bool suport_max_options;
Spelling is not right: s/suport/support/ Why is the field needed anyway? You're setting it depending on virQEMUCapsGet() anyway ...
}; typedef virDomainBlockIoTuneInfo *virDomainBlockIoTuneInfoPtr;
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index baee80a..5a2a337 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1835,7 +1835,7 @@ testQemuMonitorJSONqemuMonitorJSONSetBlockIoThrottle(const void *data) if (!test) return -1;
- expectedInfo = (virDomainBlockIoTuneInfo) {1, 2, 3, 4, 5, 6}; + expectedInfo = (virDomainBlockIoTuneInfo) {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, false};
if (qemuMonitorTestAddItem(test, "query-block", queryBlockReply) < 0 || qemuMonitorTestAddItemParams(test, "block_set_io_throttle",
Michal

When I've add this field I was thinking it would simplify the check of the capability of read_iops_sec_max and co. But you're right I can add some arguments in the functions which use read_iops_sec_max and co. I will remove this for the "v3" of this patch. On Fri, Sep 19, 2014 at 1:11 PM, Michal Privoznik <mprivozn@redhat.com> wrote:
On 15.09.2014 19:27, Matthias Gatto wrote:
Modify the structure _virDomainBlockIoTuneInfo to support total_bytes_sec_max, write_bytes_sec_max, read_bytes_sec_max, total_iops_sec_max, write_iops_sec_max, read_iops_sec_max, size_iops_sec options.
Add the boolean support_max_options in the structure _virDomainBlockIoTuneInfo to know if the qemu binary suport the bps_max options and they friends.
Change the initialization of the variable expectedInfo in qemumonitorjsontest.c to avoid compiling problem.
Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/conf/domain_conf.h | 8 ++++++++ tests/qemumonitorjsontest.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index ff7d640..5423523 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -606,6 +606,14 @@ struct _virDomainBlockIoTuneInfo { unsigned long long total_iops_sec; unsigned long long read_iops_sec; unsigned long long write_iops_sec; + unsigned long long total_bytes_sec_max; + unsigned long long read_bytes_sec_max; + unsigned long long write_bytes_sec_max; + unsigned long long total_iops_sec_max; + unsigned long long read_iops_sec_max; + unsigned long long write_iops_sec_max; + unsigned long long size_iops_sec; + bool suport_max_options;
Spelling is not right: s/suport/support/
Why is the field needed anyway? You're setting it depending on virQEMUCapsGet() anyway ...
}; typedef virDomainBlockIoTuneInfo *virDomainBlockIoTuneInfoPtr;
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index baee80a..5a2a337 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1835,7 +1835,7 @@ testQemuMonitorJSONqemuMonitorJSONSetBlockIoThrottle(const void *data) if (!test) return -1;
- expectedInfo = (virDomainBlockIoTuneInfo) {1, 2, 3, 4, 5, 6}; + expectedInfo = (virDomainBlockIoTuneInfo) {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, false};
if (qemuMonitorTestAddItem(test, "query-block", queryBlockReply) < 0 || qemuMonitorTestAddItemParams(test, "block_set_io_throttle",
Michal

Add a value in the enum virQEMUCapsFlags for the qemu capability. Set it with virQEMUCapsSet if the binary suport bps_max and they friends. Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/qemu/qemu_capabilities.c | 6 ++++++ src/qemu/qemu_capabilities.h | 1 + 2 files changed, 7 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 360cc67..a97ca03 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -265,6 +265,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "numa", "memory-backend-file", "usb-audio", + "drive-iotune-max", ); @@ -1063,6 +1064,8 @@ virQEMUCapsComputeCmdFlags(const char *help, virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ); if (strstr(help, "bps=")) virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE); + if (strstr(help, "bps_max=")) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX); } if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) { const char *nl = strstr(p, "\n"); @@ -3141,6 +3144,9 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, if (qemuCaps->version >= 1006000) virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY); + if (qemuCaps->version >= 1007000) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX); + if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0) goto cleanup; if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0) diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 2911759..394a836 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -213,6 +213,7 @@ typedef enum { QEMU_CAPS_NUMA = 171, /* newer -numa handling with disjoint cpu ranges */ QEMU_CAPS_OBJECT_MEMORY_FILE = 172, /* -object memory-backend-file */ QEMU_CAPS_OBJECT_USB_AUDIO = 173, /* usb-audio device support */ + QEMU_CAPS_DRIVE_IOTUNE_MAX = 174, /* -drive bps_max= and friends */ QEMU_CAPS_LAST, /* this must always be the last item */ } virQEMUCapsFlags; -- 1.8.3.1

On 15.09.2014 19:27, Matthias Gatto wrote:
Add a value in the enum virQEMUCapsFlags for the qemu capability. Set it with virQEMUCapsSet if the binary suport bps_max and they friends.
Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/qemu/qemu_capabilities.c | 6 ++++++ src/qemu/qemu_capabilities.h | 1 + 2 files changed, 7 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 360cc67..a97ca03 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -265,6 +265,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "numa", "memory-backend-file", "usb-audio", + "drive-iotune-max", );
@@ -1063,6 +1064,8 @@ virQEMUCapsComputeCmdFlags(const char *help, virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ); if (strstr(help, "bps=")) virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE); + if (strstr(help, "bps_max=")) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX); } if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) { const char *nl = strstr(p, "\n"); @@ -3141,6 +3144,9 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, if (qemuCaps->version >= 1006000) virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
+ if (qemuCaps->version >= 1007000) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX); +
What's wrong with just the above chunk? I mean, version based checks are not good. I'd just drop this one.
if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0) goto cleanup; if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0) diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 2911759..394a836 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -213,6 +213,7 @@ typedef enum { QEMU_CAPS_NUMA = 171, /* newer -numa handling with disjoint cpu ranges */ QEMU_CAPS_OBJECT_MEMORY_FILE = 172, /* -object memory-backend-file */ QEMU_CAPS_OBJECT_USB_AUDIO = 173, /* usb-audio device support */ + QEMU_CAPS_DRIVE_IOTUNE_MAX = 174, /* -drive bps_max= and friends */
QEMU_CAPS_LAST, /* this must always be the last item */ } virQEMUCapsFlags;
Michal

For virQEMUCapsInitQMPMonitor I didn't find other way to check the capability than to check the version, and virQEMUCapsComputeCmdFlags is not call when qemu use QMP(or I've miss how to call it). I don't understand how i should change this patch, can you explain it to me please ? On Fri, Sep 19, 2014 at 1:11 PM, Michal Privoznik <mprivozn@redhat.com> wrote:
On 15.09.2014 19:27, Matthias Gatto wrote:
Add a value in the enum virQEMUCapsFlags for the qemu capability. Set it with virQEMUCapsSet if the binary suport bps_max and they friends.
Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/qemu/qemu_capabilities.c | 6 ++++++ src/qemu/qemu_capabilities.h | 1 + 2 files changed, 7 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 360cc67..a97ca03 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -265,6 +265,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "numa", "memory-backend-file", "usb-audio", + "drive-iotune-max", );
@@ -1063,6 +1064,8 @@ virQEMUCapsComputeCmdFlags(const char *help, virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ); if (strstr(help, "bps=")) virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE); + if (strstr(help, "bps_max=")) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX); } if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) { const char *nl = strstr(p, "\n"); @@ -3141,6 +3144,9 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps, if (qemuCaps->version >= 1006000) virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
+ if (qemuCaps->version >= 1007000) + virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX); +
What's wrong with just the above chunk? I mean, version based checks are not good. I'd just drop this one.
if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0) goto cleanup; if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0) diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 2911759..394a836 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -213,6 +213,7 @@ typedef enum { QEMU_CAPS_NUMA = 171, /* newer -numa handling with disjoint cpu ranges */ QEMU_CAPS_OBJECT_MEMORY_FILE = 172, /* -object memory-backend-file */ QEMU_CAPS_OBJECT_USB_AUDIO = 173, /* usb-audio device support */ + QEMU_CAPS_DRIVE_IOTUNE_MAX = 174, /* -drive bps_max= and friends */
QEMU_CAPS_LAST, /* this must always be the last item */ } virQEMUCapsFlags;
Michal

On 22.09.2014 11:39, Matthias Gatto wrote:
For virQEMUCapsInitQMPMonitor I didn't find other way to check the capability than to check the version, and virQEMUCapsComputeCmdFlags is not call when qemu use QMP(or I've miss how to call it). I don't understand how i should change this patch, can you explain it to me please ?
[please don't top-post on technical lists] Well, grepping qemu.git I've found this: blockdev.c:658: qemu_opt_rename(all_opts, "bps_max", "throttling.bps-total-max"); And then, grepping libvirtd.log shows that qemu does report the throttling.bps-total-max. So I guess the diff that you are looking for is: diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 62a1124..af4e067 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2443,6 +2443,7 @@ static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = { { "spice", "disable-agent-file-xfer", QEMU_CAPS_SPICE_FILE_XFER_DISABLE }, { "msg", "timestamp", QEMU_CAPS_MSG_TIMESTAMP }, { "numa", NULL, QEMU_CAPS_NUMA }, + { "drive", "throttling.bps-total-max", QEMU_CAPS_DRIVE_IOTUNE_MAX}, }; static int This means, that 'drive' supports 'throttling.bps-total-max' on the command line. Which brings up interesting question - should we use that instead of "bps_max"? Michal

On Mon, Sep 22, 2014 at 1:38 PM, Michal Privoznik <mprivozn@redhat.com> wrote:
On 22.09.2014 11:39, Matthias Gatto wrote:
For virQEMUCapsInitQMPMonitor I didn't find other way to check the capability than to check the version, and virQEMUCapsComputeCmdFlags is not call when qemu use QMP(or I've miss how to call it). I don't understand how i should change this patch, can you explain it to me please ?
[please don't top-post on technical lists]
Well, grepping qemu.git I've found this:
blockdev.c:658: qemu_opt_rename(all_opts, "bps_max", "throttling.bps-total-max");
And then, grepping libvirtd.log shows that qemu does report the throttling.bps-total-max. So I guess the diff that you are looking for is:
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 62a1124..af4e067 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2443,6 +2443,7 @@ static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = { { "spice", "disable-agent-file-xfer", QEMU_CAPS_SPICE_FILE_XFER_DISABLE }, { "msg", "timestamp", QEMU_CAPS_MSG_TIMESTAMP }, { "numa", NULL, QEMU_CAPS_NUMA }, + { "drive", "throttling.bps-total-max", QEMU_CAPS_DRIVE_IOTUNE_MAX}, };
static int
This means, that 'drive' supports 'throttling.bps-total-max' on the command line. Which brings up interesting question - should we use that instead of "bps_max"?
Michal
Ok, i'll try to do it with throttling.bps-total-max Thank you for the explain, and your review

Add support for bps_max and friends in the driver part. In the part checking if a qemu is running, check if the running binary support bps_max, if not print an error message, if yes add it to "info" variable Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/qemu/qemu_driver.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 152 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2c3f179..7d024b3 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -104,6 +104,7 @@ VIR_LOG_INIT("qemu.qemu_driver"); #define QEMU_NB_MEM_PARAM 3 #define QEMU_NB_BLOCK_IO_TUNE_PARAM 6 +#define QEMU_NB_BLOCK_IO_TUNE_PARAM_MAX 13 #define QEMU_NB_NUMA_PARAM 2 @@ -15818,8 +15819,12 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, int idx = -1; bool set_bytes = false; bool set_iops = false; + bool set_bytes_max = false; + bool set_iops_max = false; + bool set_size_iops = false; virQEMUDriverConfigPtr cfg = NULL; virCapsPtr caps = NULL; + info.suport_max_options = true; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -15836,6 +15841,20 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, VIR_TYPED_PARAM_ULLONG, VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC, VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC, + VIR_TYPED_PARAM_ULLONG, NULL) < 0) return -1; @@ -15902,6 +15921,34 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC)) { info.write_iops_sec = param->value.ul; set_iops = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX)) { + info.total_bytes_sec_max = param->value.ul; + set_bytes_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX)) { + info.read_bytes_sec_max = param->value.ul; + set_bytes_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX)) { + info.write_bytes_sec_max = param->value.ul; + set_bytes_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX)) { + info.total_iops_sec_max = param->value.ul; + set_iops_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX)) { + info.read_iops_sec_max = param->value.ul; + set_iops_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX)) { + info.write_iops_sec_max = param->value.ul; + set_iops_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC)) { + info.size_iops_sec = param->value.ul; + set_size_iops = true; } } @@ -15919,11 +15966,33 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, goto endjob; } + if ((info.total_bytes_sec_max && info.read_bytes_sec_max) || + (info.total_bytes_sec_max && info.write_bytes_sec_max)) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("total and read/write of bytes_sec_max cannot be set at the same time")); + goto endjob; + } + + if ((info.total_iops_sec_max && info.read_iops_sec_max) || + (info.total_iops_sec_max && info.write_iops_sec_max)) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("total and read/write of iops_sec_max cannot be set at the same time")); + goto endjob; + } + if (flags & VIR_DOMAIN_AFFECT_LIVE) { if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("block I/O throttling not supported with this " - "QEMU binary")); + _("block I/O throttling not supported with this " + "QEMU binary")); + goto endjob; + } + + info.suport_max_options = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX); + if ((!info.suport_max_options) && (set_iops_max || set_bytes_max)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("a block I/O throttling parameter is not supported with this " + "QEMU binary")); goto endjob; } @@ -15936,11 +16005,23 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, info.read_bytes_sec = oldinfo->read_bytes_sec; info.write_bytes_sec = oldinfo->write_bytes_sec; } + if (!set_bytes_max) { + info.total_bytes_sec_max = oldinfo->total_bytes_sec_max; + info.read_bytes_sec_max = oldinfo->read_bytes_sec_max; + info.write_bytes_sec_max = oldinfo->write_bytes_sec_max; + } if (!set_iops) { info.total_iops_sec = oldinfo->total_iops_sec; info.read_iops_sec = oldinfo->read_iops_sec; info.write_iops_sec = oldinfo->write_iops_sec; } + if (!set_iops_max) { + info.total_iops_sec_max = oldinfo->total_iops_sec_max; + info.read_iops_sec_max = oldinfo->read_iops_sec_max; + info.write_iops_sec_max = oldinfo->write_iops_sec_max; + } + if (!set_size_iops) + info.size_iops_sec = oldinfo->size_iops_sec; qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorSetBlockIoThrottle(priv->mon, device, &info); qemuDomainObjExitMonitor(driver, vm); @@ -15957,11 +16038,23 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, info.read_bytes_sec = oldinfo->read_bytes_sec; info.write_bytes_sec = oldinfo->write_bytes_sec; } + if (!set_bytes_max) { + info.total_bytes_sec_max = oldinfo->total_bytes_sec_max; + info.read_bytes_sec_max = oldinfo->read_bytes_sec_max; + info.write_bytes_sec_max = oldinfo->write_bytes_sec_max; + } if (!set_iops) { info.total_iops_sec = oldinfo->total_iops_sec; info.read_iops_sec = oldinfo->read_iops_sec; info.write_iops_sec = oldinfo->write_iops_sec; } + if (!set_iops_max) { + info.total_iops_sec_max = oldinfo->total_iops_sec_max; + info.read_iops_sec_max = oldinfo->read_iops_sec_max; + info.write_iops_sec_max = oldinfo->write_iops_sec_max; + } + if (!set_size_iops) + info.size_iops_sec = oldinfo->size_iops_sec; persistentDef->disks[idx]->blkdeviotune = info; ret = virDomainSaveConfig(cfg->configDir, persistentDef); if (ret < 0) { @@ -15972,6 +16065,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, } endjob: + if (!qemuDomainObjEndJob(driver, vm)) vm = NULL; @@ -16001,6 +16095,7 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, size_t i; virCapsPtr caps = NULL; virQEMUDriverConfigPtr cfg = NULL; + reply.suport_max_options = true; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -16027,7 +16122,7 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, if ((*nparams) == 0) { /* Current number of parameters supported by QEMU Block I/O Throttling */ - *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM; + *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM_MAX; ret = 0; goto cleanup; } @@ -16046,6 +16141,9 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, if (flags & VIR_DOMAIN_AFFECT_LIVE) { priv = vm->privateData; + reply.suport_max_options = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX); + if (!reply.suport_max_options) + *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM; qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorGetBlockIoThrottle(priv->mon, device, &reply); qemuDomainObjExitMonitor(driver, vm); @@ -16060,7 +16158,7 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, reply = persistentDef->disks[idx]->blkdeviotune; } - for (i = 0; i < QEMU_NB_BLOCK_IO_TUNE_PARAM && i < *nparams; i++) { + for (i = 0; i < QEMU_NB_BLOCK_IO_TUNE_PARAM_MAX && i < *nparams; i++) { virTypedParameterPtr param = ¶ms[i]; switch (i) { @@ -16106,13 +16204,61 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, reply.write_iops_sec) < 0) goto endjob; break; + case 6: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.total_bytes_sec_max) < 0) + goto endjob; + break; + case 7: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.read_bytes_sec_max) < 0) + goto endjob; + break; + case 8: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.write_bytes_sec_max) < 0) + goto endjob; + break; + case 9: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.total_iops_sec_max) < 0) + goto endjob; + break; + case 10: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.read_iops_sec_max) < 0) + goto endjob; + break; + case 11: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.write_iops_sec_max) < 0) + goto endjob; + break; + case 12: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC, + VIR_TYPED_PARAM_ULLONG, + reply.size_iops_sec) < 0) + goto endjob; default: break; } } - if (*nparams > QEMU_NB_BLOCK_IO_TUNE_PARAM) - *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM; + if (*nparams > QEMU_NB_BLOCK_IO_TUNE_PARAM_MAX) + *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM_MAX; ret = 0; endjob: -- 1.8.3.1

On 15.09.2014 19:27, Matthias Gatto wrote:
Add support for bps_max and friends in the driver part. In the part checking if a qemu is running, check if the running binary support bps_max, if not print an error message, if yes add it to "info" variable
Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/qemu/qemu_driver.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 152 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2c3f179..7d024b3 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -104,6 +104,7 @@ VIR_LOG_INIT("qemu.qemu_driver"); #define QEMU_NB_MEM_PARAM 3
#define QEMU_NB_BLOCK_IO_TUNE_PARAM 6 +#define QEMU_NB_BLOCK_IO_TUNE_PARAM_MAX 13
Why? I think we can just proceed with current _PARAM changed so it reflects the number of arguments that can be returned. Aha! going through the later patches I think I understand why you want this - in case qemu supports QEMU_CAPS_DRIVE_IOTUNE_MAX then we should report 13, if it doesn't then 6. Well, the code doesn't say that [2].
#define QEMU_NB_NUMA_PARAM 2
@@ -15818,8 +15819,12 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, int idx = -1; bool set_bytes = false; bool set_iops = false; + bool set_bytes_max = false; + bool set_iops_max = false; + bool set_size_iops = false; virQEMUDriverConfigPtr cfg = NULL; virCapsPtr caps = NULL; + info.suport_max_options = true;
This is useless ... [1]
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); @@ -15836,6 +15841,20 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, VIR_TYPED_PARAM_ULLONG, VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC, VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC, + VIR_TYPED_PARAM_ULLONG, NULL) < 0) return -1;
@@ -15902,6 +15921,34 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC)) { info.write_iops_sec = param->value.ul; set_iops = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX)) { + info.total_bytes_sec_max = param->value.ul; + set_bytes_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX)) { + info.read_bytes_sec_max = param->value.ul; + set_bytes_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX)) { + info.write_bytes_sec_max = param->value.ul; + set_bytes_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX)) { + info.total_iops_sec_max = param->value.ul; + set_iops_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX)) { + info.read_iops_sec_max = param->value.ul; + set_iops_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX)) { + info.write_iops_sec_max = param->value.ul; + set_iops_max = true; + } else if (STREQ(param->field, + VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC)) { + info.size_iops_sec = param->value.ul; + set_size_iops = true; } }
@@ -15919,11 +15966,33 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, goto endjob; }
+ if ((info.total_bytes_sec_max && info.read_bytes_sec_max) || + (info.total_bytes_sec_max && info.write_bytes_sec_max)) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("total and read/write of bytes_sec_max cannot be set at the same time")); + goto endjob; + } + + if ((info.total_iops_sec_max && info.read_iops_sec_max) || + (info.total_iops_sec_max && info.write_iops_sec_max)) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("total and read/write of iops_sec_max cannot be set at the same time")); + goto endjob; + } + if (flags & VIR_DOMAIN_AFFECT_LIVE) { if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("block I/O throttling not supported with this " - "QEMU binary")); + _("block I/O throttling not supported with this " + "QEMU binary")); + goto endjob; + } + + info.suport_max_options = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX);
1: esp. if this occurs
+ if ((!info.suport_max_options) && (set_iops_max || set_bytes_max)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("a block I/O throttling parameter is not supported with this " + "QEMU binary")); goto endjob; }
@@ -15936,11 +16005,23 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, info.read_bytes_sec = oldinfo->read_bytes_sec; info.write_bytes_sec = oldinfo->write_bytes_sec; } + if (!set_bytes_max) { + info.total_bytes_sec_max = oldinfo->total_bytes_sec_max; + info.read_bytes_sec_max = oldinfo->read_bytes_sec_max; + info.write_bytes_sec_max = oldinfo->write_bytes_sec_max; + } if (!set_iops) { info.total_iops_sec = oldinfo->total_iops_sec; info.read_iops_sec = oldinfo->read_iops_sec; info.write_iops_sec = oldinfo->write_iops_sec; } + if (!set_iops_max) { + info.total_iops_sec_max = oldinfo->total_iops_sec_max; + info.read_iops_sec_max = oldinfo->read_iops_sec_max; + info.write_iops_sec_max = oldinfo->write_iops_sec_max; + } + if (!set_size_iops) + info.size_iops_sec = oldinfo->size_iops_sec; qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorSetBlockIoThrottle(priv->mon, device, &info); qemuDomainObjExitMonitor(driver, vm); @@ -15957,11 +16038,23 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, info.read_bytes_sec = oldinfo->read_bytes_sec; info.write_bytes_sec = oldinfo->write_bytes_sec; } + if (!set_bytes_max) { + info.total_bytes_sec_max = oldinfo->total_bytes_sec_max; + info.read_bytes_sec_max = oldinfo->read_bytes_sec_max; + info.write_bytes_sec_max = oldinfo->write_bytes_sec_max; + } if (!set_iops) { info.total_iops_sec = oldinfo->total_iops_sec; info.read_iops_sec = oldinfo->read_iops_sec; info.write_iops_sec = oldinfo->write_iops_sec; } + if (!set_iops_max) { + info.total_iops_sec_max = oldinfo->total_iops_sec_max; + info.read_iops_sec_max = oldinfo->read_iops_sec_max; + info.write_iops_sec_max = oldinfo->write_iops_sec_max; + } + if (!set_size_iops) + info.size_iops_sec = oldinfo->size_iops_sec; persistentDef->disks[idx]->blkdeviotune = info; ret = virDomainSaveConfig(cfg->configDir, persistentDef); if (ret < 0) { @@ -15972,6 +16065,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom, }
endjob: + if (!qemuDomainObjEndJob(driver, vm)) vm = NULL;
@@ -16001,6 +16095,7 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, size_t i; virCapsPtr caps = NULL; virQEMUDriverConfigPtr cfg = NULL; + reply.suport_max_options = true;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG | @@ -16027,7 +16122,7 @@ qemuDomainGetBlockIoTune(virDomainPtr dom,
if ((*nparams) == 0) { /* Current number of parameters supported by QEMU Block I/O Throttling */ - *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM; + *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM_MAX;
2: ^^^
ret = 0; goto cleanup; } @@ -16046,6 +16141,9 @@ qemuDomainGetBlockIoTune(virDomainPtr dom,
if (flags & VIR_DOMAIN_AFFECT_LIVE) { priv = vm->privateData; + reply.suport_max_options = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX); + if (!reply.suport_max_options) + *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM; qemuDomainObjEnterMonitor(driver, vm); ret = qemuMonitorGetBlockIoThrottle(priv->mon, device, &reply);
Instead of passing support_max_options like you're, I'd change the qemuMonitorGetBlockIoThrottle() to accept one more boole attribute to fetch minimal or extended set of values from qemu.
qemuDomainObjExitMonitor(driver, vm); @@ -16060,7 +16158,7 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, reply = persistentDef->disks[idx]->blkdeviotune; }
- for (i = 0; i < QEMU_NB_BLOCK_IO_TUNE_PARAM && i < *nparams; i++) { + for (i = 0; i < QEMU_NB_BLOCK_IO_TUNE_PARAM_MAX && i < *nparams; i++) { virTypedParameterPtr param = ¶ms[i];
switch (i) { @@ -16106,13 +16204,61 @@ qemuDomainGetBlockIoTune(virDomainPtr dom, reply.write_iops_sec) < 0) goto endjob; break; + case 6: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.total_bytes_sec_max) < 0) + goto endjob; + break; + case 7: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.read_bytes_sec_max) < 0) + goto endjob; + break; + case 8: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.write_bytes_sec_max) < 0) + goto endjob; + break; + case 9: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.total_iops_sec_max) < 0) + goto endjob; + break; + case 10: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.read_iops_sec_max) < 0) + goto endjob; + break; + case 11: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX, + VIR_TYPED_PARAM_ULLONG, + reply.write_iops_sec_max) < 0) + goto endjob; + break; + case 12: + if (virTypedParameterAssign(param, + VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC, + VIR_TYPED_PARAM_ULLONG, + reply.size_iops_sec) < 0) + goto endjob; default: break; } }
- if (*nparams > QEMU_NB_BLOCK_IO_TUNE_PARAM) - *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM; + if (*nparams > QEMU_NB_BLOCK_IO_TUNE_PARAM_MAX) + *nparams = QEMU_NB_BLOCK_IO_TUNE_PARAM_MAX; ret = 0;
endjob:
Michal

Allow qemu driver to save the configuration use by bps_max and they friends. Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/conf/domain_conf.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c7016f3..57b9e7f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5680,6 +5680,49 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, def->blkdeviotune.write_iops_sec = 0; } + if (virXPathULongLong("string(./iotune/total_bytes_sec_max)", + ctxt, + &def->blkdeviotune.total_bytes_sec_max) < 0) { + def->blkdeviotune.total_bytes_sec_max = 0; + } + + if (virXPathULongLong("string(./iotune/read_bytes_sec_max)", + ctxt, + &def->blkdeviotune.read_bytes_sec_max) < 0) { + def->blkdeviotune.read_bytes_sec_max = 0; + } + + if (virXPathULongLong("string(./iotune/write_bytes_sec_max)", + ctxt, + &def->blkdeviotune.write_bytes_sec_max) < 0) { + def->blkdeviotune.write_bytes_sec_max = 0; + } + + if (virXPathULongLong("string(./iotune/total_iops_sec_max)", + ctxt, + &def->blkdeviotune.total_iops_sec_max) < 0) { + def->blkdeviotune.total_iops_sec_max = 0; + } + + if (virXPathULongLong("string(./iotune/read_iops_sec_max)", + ctxt, + &def->blkdeviotune.read_iops_sec_max) < 0) { + def->blkdeviotune.read_iops_sec_max = 0; + } + + if (virXPathULongLong("string(./iotune/write_iops_sec_max)", + ctxt, + &def->blkdeviotune.write_iops_sec_max) < 0) { + def->blkdeviotune.write_iops_sec_max = 0; + } + + if (virXPathULongLong("string(./iotune/size_iops_sec)", + ctxt, + &def->blkdeviotune.size_iops_sec) < 0) { + def->blkdeviotune.size_iops_sec = 0; + } + + if ((def->blkdeviotune.total_bytes_sec && def->blkdeviotune.read_bytes_sec) || (def->blkdeviotune.total_bytes_sec && @@ -15578,7 +15621,14 @@ virDomainDiskDefFormat(virBufferPtr buf, def->blkdeviotune.write_bytes_sec || def->blkdeviotune.total_iops_sec || def->blkdeviotune.read_iops_sec || - def->blkdeviotune.write_iops_sec) { + def->blkdeviotune.write_iops_sec || + def->blkdeviotune.total_bytes_sec_max || + def->blkdeviotune.read_bytes_sec_max || + def->blkdeviotune.write_bytes_sec_max || + def->blkdeviotune.total_iops_sec_max || + def->blkdeviotune.read_iops_sec_max || + def->blkdeviotune.write_iops_sec_max || + def->blkdeviotune.size_iops_sec) { virBufferAddLit(buf, "<iotune>\n"); virBufferAdjustIndent(buf, 2); if (def->blkdeviotune.total_bytes_sec) { @@ -15611,6 +15661,43 @@ virDomainDiskDefFormat(virBufferPtr buf, virBufferAsprintf(buf, "<write_iops_sec>%llu</write_iops_sec>\n", def->blkdeviotune.write_iops_sec); } + + if (def->blkdeviotune.total_bytes_sec_max) { + virBufferAsprintf(buf, "<total_bytes_sec_max>%llu</total_bytes_sec_max>\n", + def->blkdeviotune.total_bytes_sec_max); + } + + if (def->blkdeviotune.read_bytes_sec_max) { + virBufferAsprintf(buf, "<read_bytes_sec_max>%llu</read_bytes_sec_max>\n", + def->blkdeviotune.read_bytes_sec_max); + + } + + if (def->blkdeviotune.write_bytes_sec_max) { + virBufferAsprintf(buf, "<write_bytes_sec_max>%llu</write_bytes_sec_max>\n", + def->blkdeviotune.write_bytes_sec_max); + } + + if (def->blkdeviotune.total_iops_sec_max) { + virBufferAsprintf(buf, "<total_iops_sec_max>%llu</total_iops_sec_max>\n", + def->blkdeviotune.total_iops_sec_max); + } + + if (def->blkdeviotune.read_iops_sec_max) { + virBufferAsprintf(buf, "<read_iops_sec_max>%llu</read_iops_sec_max>\n", + def->blkdeviotune.read_iops_sec_max); + } + + if (def->blkdeviotune.write_iops_sec_max) { + virBufferAsprintf(buf, "<write_iops_sec_max>%llu</write_iops_sec_max>\n", + def->blkdeviotune.write_iops_sec_max); + } + + if (def->blkdeviotune.size_iops_sec) { + virBufferAsprintf(buf, "<size_iops_sec>%llu</size_iops_sec>\n", + def->blkdeviotune.size_iops_sec); + } + virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</iotune>\n"); } -- 1.8.3.1

On 15.09.2014 19:27, Matthias Gatto wrote:
Allow qemu driver to save the configuration use by bps_max and they friends.
Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/conf/domain_conf.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-)
I'd expect this patch to be merged with 1/9. Michal

Detect if the the qemu binary currently in use suport the bps_max option, If yes add it to the command, if not, just ignore the options. Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/qemu/qemu_monitor_json.c | 58 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index a62c02f..de33499 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -3924,6 +3924,12 @@ int qemuMonitorJSONOpenGraphics(qemuMonitorPtr mon, } +#define GET_THROTTLE_STATS_OPTIONAL(FIELD, STORE) \ + if (virJSONValueObjectGetNumberUlong(inserted, \ + FIELD, \ + &reply->STORE) < 0) { \ + reply->STORE = 0; \ + } #define GET_THROTTLE_STATS(FIELD, STORE) \ if (virJSONValueObjectGetNumberUlong(inserted, \ FIELD, \ @@ -3989,7 +3995,16 @@ qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result, GET_THROTTLE_STATS("iops", total_iops_sec); GET_THROTTLE_STATS("iops_rd", read_iops_sec); GET_THROTTLE_STATS("iops_wr", write_iops_sec); - + if (reply->suport_max_options) + { + GET_THROTTLE_STATS_OPTIONAL("bps_max", total_bytes_sec_max); + GET_THROTTLE_STATS_OPTIONAL("bps_rd_max", read_bytes_sec_max); + GET_THROTTLE_STATS_OPTIONAL("bps_wr_max", write_bytes_sec_max); + GET_THROTTLE_STATS_OPTIONAL("iops_max", total_iops_sec_max); + GET_THROTTLE_STATS_OPTIONAL("iops_rd_max", read_iops_sec_max); + GET_THROTTLE_STATS_OPTIONAL("iops_wr_max", write_iops_sec_max); + GET_THROTTLE_STATS_OPTIONAL("iops_size", size_iops_sec); + } break; } @@ -4005,6 +4020,7 @@ qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result, return ret; } #undef GET_THROTTLE_STATS +#undef GET_THROTTLE_STATS_OPTIONAL int qemuMonitorJSONSetBlockIoThrottle(qemuMonitorPtr mon, const char *device, @@ -4014,15 +4030,37 @@ int qemuMonitorJSONSetBlockIoThrottle(qemuMonitorPtr mon, virJSONValuePtr cmd = NULL; virJSONValuePtr result = NULL; - cmd = qemuMonitorJSONMakeCommand("block_set_io_throttle", - "s:device", device, - "U:bps", info->total_bytes_sec, - "U:bps_rd", info->read_bytes_sec, - "U:bps_wr", info->write_bytes_sec, - "U:iops", info->total_iops_sec, - "U:iops_rd", info->read_iops_sec, - "U:iops_wr", info->write_iops_sec, - NULL); + if (info->suport_max_options) + { + cmd = qemuMonitorJSONMakeCommand("block_set_io_throttle", + "s:device", device, + "U:bps", info->total_bytes_sec, + "U:bps_rd", info->read_bytes_sec, + "U:bps_wr", info->write_bytes_sec, + "U:iops", info->total_iops_sec, + "U:iops_rd", info->read_iops_sec, + "U:iops_wr", info->write_iops_sec, + "U:bps_max", info->total_bytes_sec_max, + "U:bps_rd_max", info->read_bytes_sec_max, + "U:bps_wr_max", info->write_bytes_sec_max, + "U:iops_max", info->total_iops_sec_max, + "U:iops_rd_max", info->read_iops_sec_max, + "U:iops_wr_max", info->write_iops_sec_max, + "U:iops_size", info->size_iops_sec, + NULL); + } + else + { + cmd = qemuMonitorJSONMakeCommand("block_set_io_throttle", + "s:device", device, + "U:bps", info->total_bytes_sec, + "U:bps_rd", info->read_bytes_sec, + "U:bps_wr", info->write_bytes_sec, + "U:iops", info->total_iops_sec, + "U:iops_rd", info->read_iops_sec, + "U:iops_wr", info->write_iops_sec, + NULL); + } if (!cmd) return -1; -- 1.8.3.1

Detect if the the qemu binary currently in use suport the bps_max option and thy firends, If yes add it to the command, if not, just ignore the options. Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/qemu/qemu_monitor_text.c | 75 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index fc54a11..e741d27 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -2994,11 +2994,26 @@ int qemuMonitorTextSetBlockIoThrottle(qemuMonitorPtr mon, /* For the not specified fields, 0 by default */ cmd_name = "block_set_io_throttle"; - if (virAsprintf(&cmd, "%s %s %llu %llu %llu %llu %llu %llu", cmd_name, - device, info->total_bytes_sec, info->read_bytes_sec, - info->write_bytes_sec, info->total_iops_sec, - info->read_iops_sec, info->write_iops_sec) < 0) - goto cleanup; + if (info->suport_max_options) + { + if (virAsprintf(&cmd, "%s %s %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", cmd_name, + device, info->total_bytes_sec, info->read_bytes_sec, + info->write_bytes_sec, info->total_iops_sec, + info->read_iops_sec, info->write_iops_sec, + info->total_bytes_sec_max, info->read_bytes_sec_max, + info->write_bytes_sec_max, info->total_iops_sec_max, + info->read_iops_sec_max, info->write_iops_sec_max, + info->size_iops_sec) < 0) + goto cleanup; + } + else + { + if (virAsprintf(&cmd, "%s %s %llu %llu %llu %llu %llu %llu", cmd_name, + device, info->total_bytes_sec, info->read_bytes_sec, + info->write_bytes_sec, info->total_iops_sec, + info->read_iops_sec, info->write_iops_sec) < 0) + goto cleanup; + } if (qemuMonitorHMPCommand(mon, cmd, &result) < 0) goto cleanup; @@ -3025,6 +3040,7 @@ qemuMonitorTextParseBlockIoThrottle(const char *result, int ret = -1; const char *p, *eol; int devnamelen = strlen(device); + bool checkBlockInfo; p = result; @@ -3039,31 +3055,78 @@ qemuMonitorTextParseBlockIoThrottle(const char *result, p += devnamelen + 2; /* Skip to first label. */ while (*p) { + checkBlockInfo = false; if (STRPREFIX(p, "bps=")) { p += strlen("bps="); + checkBlockInfo = true; if (virStrToLong_ull(p, &dummy, 10, &reply->total_bytes_sec) == -1) VIR_DEBUG("error reading total_bytes_sec: %s", p); } else if (STRPREFIX(p, "bps_rd=")) { + checkBlockInfo = true; p += strlen("bps_rd="); if (virStrToLong_ull(p, &dummy, 10, &reply->read_bytes_sec) == -1) VIR_DEBUG("error reading read_bytes_sec: %s", p); } else if (STRPREFIX(p, "bps_wr=")) { + checkBlockInfo = true; p += strlen("bps_wr="); if (virStrToLong_ull(p, &dummy, 10, &reply->write_bytes_sec) == -1) VIR_DEBUG("error reading write_bytes_sec: %s", p); } else if (STRPREFIX(p, "iops=")) { + checkBlockInfo = true; p += strlen("iops="); if (virStrToLong_ull(p, &dummy, 10, &reply->total_iops_sec) == -1) VIR_DEBUG("error reading total_iops_sec: %s", p); } else if (STRPREFIX(p, "iops_rd=")) { + checkBlockInfo = true; p += strlen("iops_rd="); if (virStrToLong_ull(p, &dummy, 10, &reply->read_iops_sec) == -1) VIR_DEBUG("error reading read_iops_sec: %s", p); } else if (STRPREFIX(p, "iops_wr=")) { + checkBlockInfo = true; p += strlen("iops_wr="); if (virStrToLong_ull(p, &dummy, 10, &reply->write_iops_sec) == -1) VIR_DEBUG("error reading write_iops_sec: %s", p); - } else { + } + if (reply->suport_max_options) + { + if (STRPREFIX(p, "bps_max=")) { + checkBlockInfo = true; + p += strlen("bps_max="); + if (virStrToLong_ull(p, &dummy, 10, &reply->total_bytes_sec_max) == -1) + VIR_DEBUG("error reading total_bytes_sec_max: %s", p); + } else if (STRPREFIX(p, "bps_wr_max=")) { + checkBlockInfo = true; + p += strlen("bps_wr_max="); + if (virStrToLong_ull(p, &dummy, 10, &reply->write_bytes_sec_max) == -1) + VIR_DEBUG("error reading write_bytes_sec_max: %s", p); + } else if (STRPREFIX(p, "bps_rd_max=")) { + checkBlockInfo = true; + p += strlen("bps_rd_max="); + if (virStrToLong_ull(p, &dummy, 10, &reply->read_bytes_sec_max) == -1) + VIR_DEBUG("error reading read_bytes_sec_max: %s", p); + } else if (STRPREFIX(p, "iops_max=")) { + checkBlockInfo = true; + p += strlen("iops_max="); + if (virStrToLong_ull(p, &dummy, 10, &reply->total_iops_sec_max) == -1) + VIR_DEBUG("error reading total_iops_sec_max: %s", p); + } else if (STRPREFIX(p, "iops_rd_max=")) { + checkBlockInfo = true; + p += strlen("iops_rd_max="); + if (virStrToLong_ull(p, &dummy, 10, &reply->read_iops_sec_max) == -1) + VIR_DEBUG("error reading read_iops_sec_max: %s", p); + } else if (STRPREFIX(p, "iops_wr_max=")) { + checkBlockInfo = true; + p += strlen("iops_wr_max="); + if (virStrToLong_ull(p, &dummy, 10, &reply->write_iops_sec_max) == -1) + VIR_DEBUG("error reading write_iops_sec_max: %s", p); + } else if (STRPREFIX(p, "size_iops=")) { + checkBlockInfo = true; + p += strlen("size_iops="); + if (virStrToLong_ull(p, &dummy, 10, &reply->size_iops_sec) == -1) + VIR_DEBUG("error reading size_iops_sec: %s", p); + } + } + if (!checkBlockInfo) { VIR_DEBUG(" unknown block info %s", p); } -- 1.8.3.1

Check the arability of the options with the current qemu binary, add them in the varable opt if yes, print a message if not. Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- src/qemu/qemu_command.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8a69976..9e84e98 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3598,6 +3598,55 @@ qemuBuildDriveStr(virConnectPtr conn, disk->blkdeviotune.write_iops_sec); } + /* block I/O throttling 1.7 */ + if ((disk->blkdeviotune.total_bytes_sec_max || + disk->blkdeviotune.read_bytes_sec_max || + disk->blkdeviotune.write_bytes_sec_max || + disk->blkdeviotune.total_iops_sec_max || + disk->blkdeviotune.read_iops_sec_max || + disk->blkdeviotune.write_iops_sec_max) && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE_MAX)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("there is some block I/O throttling paramater that are not supported with this " + "QEMU binary(need QEMU 1.7 or superior)")); + goto error; + } + + if (disk->blkdeviotune.total_bytes_sec_max) { + virBufferAsprintf(&opt, ",bps_max=%llu", + disk->blkdeviotune.total_bytes_sec_max); + } + + if (disk->blkdeviotune.read_bytes_sec_max) { + virBufferAsprintf(&opt, ",bps_rd_max=%llu", + disk->blkdeviotune.read_bytes_sec_max); + } + + if (disk->blkdeviotune.write_bytes_sec_max) { + virBufferAsprintf(&opt, ",bps_wr_max=%llu", + disk->blkdeviotune.write_bytes_sec_max); + } + + if (disk->blkdeviotune.total_iops_sec_max) { + virBufferAsprintf(&opt, ",iops_max=%llu", + disk->blkdeviotune.total_iops_sec_max); + } + + if (disk->blkdeviotune.read_iops_sec_max) { + virBufferAsprintf(&opt, ",iops_rd_max=%llu", + disk->blkdeviotune.read_iops_sec_max); + } + + if (disk->blkdeviotune.write_iops_sec_max) { + virBufferAsprintf(&opt, ",iops_wr_max=%llu", + disk->blkdeviotune.write_iops_sec_max); + } + + if (disk->blkdeviotune.write_iops_sec_max) { + virBufferAsprintf(&opt, ",iops_size=%llu", + disk->blkdeviotune.size_iops_sec); + } + if (virBufferCheckError(&opt) < 0) goto error; -- 1.8.3.1

Add the new throttle options to virsh, and send them to libvirt. Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- tools/virsh-domain.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index f7193cb..cf7884f 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -1082,6 +1082,62 @@ static const vshCmdOptDef opts_blkdeviotune[] = { .type = VSH_OT_INT, .help = N_("write I/O operations limit per second") }, + {.name = "total_bytes_sec_max", + .type = VSH_OT_ALIAS, + .help = "total-bytes-sec-max" + }, + {.name = "total-bytes-sec-max", + .type = VSH_OT_INT, + .help = N_("total max in bytes") + }, + {.name = "read_bytes_sec_max", + .type = VSH_OT_ALIAS, + .help = "read-bytes-sec-max" + }, + {.name = "read-bytes-sec-max", + .type = VSH_OT_INT, + .help = N_("read max in bytes") + }, + {.name = "write_bytes_sec_max", + .type = VSH_OT_ALIAS, + .help = "write-bytes-sec-max" + }, + {.name = "write-bytes-sec-max", + .type = VSH_OT_INT, + .help = N_("write max in bytes") + }, + {.name = "total_iops_sec_max", + .type = VSH_OT_ALIAS, + .help = "total-iops-sec-max" + }, + {.name = "total-iops-sec-max", + .type = VSH_OT_INT, + .help = N_("total I/O operations max") + }, + {.name = "read_iops_sec_max", + .type = VSH_OT_ALIAS, + .help = "read-iops-sec-max" + }, + {.name = "read-iops-sec-max", + .type = VSH_OT_INT, + .help = N_("read I/O operations max") + }, + {.name = "write_iops_sec_max", + .type = VSH_OT_ALIAS, + .help = "write-iops-sec-max" + }, + {.name = "write-iops-sec-max", + .type = VSH_OT_INT, + .help = N_("write I/O operations max") + }, + {.name = "size_iops_sec", + .type = VSH_OT_ALIAS, + .help = "size-iops-sec" + }, + {.name = "size-iops-sec", + .type = VSH_OT_INT, + .help = N_("I/O size in bytes") + }, {.name = "config", .type = VSH_OT_BOOL, .help = N_("affect next boot") @@ -1155,6 +1211,33 @@ cmdBlkdeviotune(vshControl *ctl, const vshCmd *cmd) goto save_error; } + if ((rv = vshCommandOptULongLong(cmd, "total-bytes-sec-max", &value)) < 0) { + goto interror; + } else if (rv > 0) { + if (virTypedParamsAddULLong(¶ms, &nparams, &maxparams, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX, + value) < 0) + goto save_error; + } + + if ((rv = vshCommandOptULongLong(cmd, "read-bytes-sec-max", &value)) < 0) { + goto interror; + } else if (rv > 0) { + if (virTypedParamsAddULLong(¶ms, &nparams, &maxparams, + VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX, + value) < 0) + goto save_error; + } + + if ((rv = vshCommandOptULongLong(cmd, "write-bytes-sec-max", &value)) < 0) { + goto interror; + } else if (rv > 0) { + if (virTypedParamsAddULLong(¶ms, &nparams, &maxparams, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX, + value) < 0) + goto save_error; + } + if ((rv = vshCommandOptULongLong(cmd, "total-iops-sec", &value)) < 0) { goto interror; } else if (rv > 0) { @@ -1182,6 +1265,42 @@ cmdBlkdeviotune(vshControl *ctl, const vshCmd *cmd) goto save_error; } + if ((rv = vshCommandOptULongLong(cmd, "write-iops-sec-max", &value)) < 0) { + goto interror; + } else if (rv > 0) { + if (virTypedParamsAddULLong(¶ms, &nparams, &maxparams, + VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX, + value) < 0) + goto save_error; + } + + if ((rv = vshCommandOptULongLong(cmd, "read-iops-sec-max", &value)) < 0) { + goto interror; + } else if (rv > 0) { + if (virTypedParamsAddULLong(¶ms, &nparams, &maxparams, + VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX, + value) < 0) + goto save_error; + } + + if ((rv = vshCommandOptULongLong(cmd, "total-iops-sec-max", &value)) < 0) { + goto interror; + } else if (rv > 0) { + if (virTypedParamsAddULLong(¶ms, &nparams, &maxparams, + VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX, + value) < 0) + goto save_error; + } + + if ((rv = vshCommandOptULongLong(cmd, "size-iops-sec", &value)) < 0) { + goto interror; + } else if (rv > 0) { + if (virTypedParamsAddULLong(¶ms, &nparams, &maxparams, + VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC, + value) < 0) + goto save_error; + } + if (nparams == 0) { if (virDomainGetBlockIoTune(dom, NULL, NULL, &nparams, flags) != 0) { vshError(ctl, "%s", -- 1.8.3.1

On 15.09.2014 19:27, Matthias Gatto wrote:
Add the new throttle options to virsh, and send them to libvirt.
Signed-off-by: Matthias Gatto <matthias.gatto@outscale.com> --- tools/virsh-domain.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+)
virsh.pod needs to be updated too Michal
participants (2)
-
Matthias Gatto
-
Michal Privoznik