Re: [libvirt] [PATCH 3/8] Implement virDomain{Set, Get}BlockIoTune for the qemu driver

2011-11-28 Thread Adam Litke
On Wed, Nov 23, 2011 at 10:41:32AM -0700, Eric Blake wrote:

 Hmm - passing nparams==1 to set just read_bytes_sec has the side effect
 of wiping out any existing total_iops_sec, even though those two
 parameters seem somewhat orthogonal, all because we zero-initialized the
 struct that we pass on to the monitor command.  Is that intended?  I can
 live with it (but it probably ought to be documented), but we may want
 to consider being more flexible, by using '0' to clear a previous limit,
 but initializing to '-1' to imply the limit does not change.  Then the
 qemu_monitor_json code should only emit the arguments that are actually
 being changed, rather than blindly always outputting 6 parameters even
 when the user only passed in one parameter.  But I'm okay delaying that
 to a separate patch based on whether others think it would be a good
 improvement.

+1.  I believe I had pointed this out previously as well (albeit not as
concisely as this).


-- 
Adam Litke a...@us.ibm.com
IBM Linux Technology Center

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 3/8] Implement virDomain{Set, Get}BlockIoTune for the qemu driver

2011-11-28 Thread Lei Li

On 11/28/2011 11:24 PM, Adam Litke wrote:

On Wed, Nov 23, 2011 at 10:41:32AM -0700, Eric Blake wrote:


Hmm - passing nparams==1 to set just read_bytes_sec has the side effect
of wiping out any existing total_iops_sec, even though those two
parameters seem somewhat orthogonal, all because we zero-initialized the
struct that we pass on to the monitor command.  Is that intended?  I can
live with it (but it probably ought to be documented), but we may want
to consider being more flexible, by using '0' to clear a previous limit,
but initializing to '-1' to imply the limit does not change.  Then the
qemu_monitor_json code should only emit the arguments that are actually
being changed, rather than blindly always outputting 6 parameters even
when the user only passed in one parameter.  But I'm okay delaying that
to a separate patch based on whether others think it would be a good
improvement.

+1.  I believe I had pointed this out previously as well (albeit not as
concisely as this).


Well, here is the description of block I/O throttling command 
'block_io_set_throttle'
in qmp-commands.hx.

EQMP

{
.name   = block_set_io_throttle,
.args_type  = 
device:B,bps:i?,bps_rd:i?,bps_wr:i?,iops:i?,iops_rd:i?,iops_wr:i?,
.params = device [bps] [bps_rd] [bps_wr] [iops] [iops_rd] 
[iops_wr],
.help   = change I/O throttle limits for a block drive,
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_block_set_io_throttle,
},

SQMP
block_set_io_throttle


Change I/O throttle limits for a block drive.

Arguments:

- device: device name (json-string)
- bps:  total throughput limit in bytes per second(json-int, optional)
- bps_rd:  read throughput limit in bytes per second(json-int, optional)
- bps_wr:  read throughput limit in bytes per second(json-int, optional)
- iops:  total I/O operations per second(json-int, optional)
- iops_rd:  read I/O operations per second(json-int, optional)
- iops_wr:  write I/O operations per second(json-int, optional)

Example:

-  { execute: block_set_io_throttle, arguments: { device: virtio0,
   bps: 100,
   bps_rd: 0,
   bps_wr: 0,
   iops: 0,
   iops_rd: 0,
   iops_wr: 0 } }
- { return: {} }


This qmp command need all these 6 parameters at one time in qemu, so
zero-initialized the struct to meet If there is no setting value for
some of the fields.





--
Lei

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 3/8] Implement virDomain{Set, Get}BlockIoTune for the qemu driver

2011-11-23 Thread Eric Blake
On 11/15/2011 02:02 AM, Lei Li wrote:
 Implement the block I/O throttle setting and getting support to qemu
 driver.
 
 Signed-off-by: Lei Li li...@linux.vnet.ibm.com
 Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
 ---
  src/qemu/qemu_driver.c   |  342 
 ++
  src/qemu/qemu_monitor.c  |   37 +
  src/qemu/qemu_monitor.h  |   22 +++
  src/qemu/qemu_monitor_json.c |  186 +++
  src/qemu/qemu_monitor_json.h |   10 ++
  src/qemu/qemu_monitor_text.c |  165 
  src/qemu/qemu_monitor_text.h |   10 ++
  7 files changed, 772 insertions(+), 0 deletions(-)

Now that I've finished reviewing 4/8 and 6/8, I'm back to this one.  In
addition to the syntax check fixes I previously mentioned...

 +static int
 +qemuDomainSetBlockIoTune(virDomainPtr dom,
 + const char *disk,
 + virTypedParameterPtr params,
 + int nparams,
 + unsigned int flags)
 +{

 +
 +device = qemuDiskPathToAlias(vm, disk);

Huh, I just noticed that qemuDiskPathToAlias returns a malloc'd string
as const char*, which is not const-correct.  I'll fix that separately.

 +if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY)  0)
 +goto cleanup;
 +
 +isActive = virDomainObjIsActive(vm);
 +
 +if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
 +if (isActive)
 +flags = VIR_DOMAIN_AFFECT_LIVE;
 +else
 +flags = VIR_DOMAIN_AFFECT_CONFIG;
 +}
 +
 +if (!isActive  (flags  VIR_DOMAIN_AFFECT_LIVE)) {
 +qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
 +_(domain is not running));
 +goto endjob;
 +}
 +
 +if (flags  VIR_DOMAIN_AFFECT_CONFIG) {
 +if (!vm-persistent) {
 +qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
 +_(cannot change persistent config of a 
 transient domain));
 +goto endjob;
 +}
 +if (!(persistentDef = virDomainObjGetPersistentDef(driver-caps, 
 vm)))
 +goto endjob;
 +}

Hmm, we repeat this chunk of code in several functions; maybe it's time
to factor it into a helper method.  But that's a patch for another day.

 +
 +for (i = 0; i  nparams; i++) {
 +virTypedParameterPtr param = params[i];
 +
 +if (STREQ(param-field, VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC)) {
 +
 +info.total_bytes_sec = params[i].value.ul;
 +} else if (STREQ(param-field, 
 VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC)) {
 +info.read_bytes_sec = params[i].value.ul;
 +} else if (STREQ(param-field, 
 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC)) {
 +info.write_bytes_sec = params[i].value.ul;
 +} else if (STREQ(param-field, 
 VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC)) {
 +info.total_iops_sec = params[i].value.ul;
 +} else if (STREQ(param-field, 
 VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC)) {
 +info.read_iops_sec = params[i].value.ul;
 +} else if (STREQ(param-field, 
 VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC)) {
 +info.write_iops_sec = params[i].value.ul;

This is not type-safe.  You have to also validate that the user passed a
ullong value before you blindly dereference the value.ul union memory.

Hmm - passing nparams==1 to set just read_bytes_sec has the side effect
of wiping out any existing total_iops_sec, even though those two
parameters seem somewhat orthogonal, all because we zero-initialized the
struct that we pass on to the monitor command.  Is that intended?  I can
live with it (but it probably ought to be documented), but we may want
to consider being more flexible, by using '0' to clear a previous limit,
but initializing to '-1' to imply the limit does not change.  Then the
qemu_monitor_json code should only emit the arguments that are actually
being changed, rather than blindly always outputting 6 parameters even
when the user only passed in one parameter.  But I'm okay delaying that
to a separate patch based on whether others think it would be a good
improvement.

 +} else {
 +qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
 +_(Unrecognized parameter));

Why not tell the user which parameter name was not recognized?  Also,
this is not an OPERATION_INVALID, but an INVALID_ARG (it is bad input,
not input that might be valid if the domain were in a different state).

 +goto endjob;
 +}
 +}
 +
 +if ((info.total_bytes_sec  info.read_bytes_sec) ||
 +(info.total_bytes_sec  info.write_bytes_sec)) {
 +qemuReportError(VIR_ERR_INVALID_ARG, %s,
 +_(total and read/write of bytes_sec cannot be set 
 at the same time));
 +goto endjob;
 +}
 +
 +if ((info.total_iops_sec  info.read_iops_sec) ||
 +(info.total_iops_sec  info.write_iops_sec)) {
 +

Re: [libvirt] [PATCH 3/8] Implement virDomain{Set, Get}BlockIoTune for the qemu driver

2011-11-22 Thread Eric Blake
On 11/15/2011 02:02 AM, Lei Li wrote:
 Implement the block I/O throttle setting and getting support to qemu
 driver.
 
 Signed-off-by: Lei Li li...@linux.vnet.ibm.com
 Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
 ---
  src/qemu/qemu_driver.c   |  342 
 ++
  src/qemu/qemu_monitor.c  |   37 +
  src/qemu/qemu_monitor.h  |   22 +++
  src/qemu/qemu_monitor_json.c |  186 +++
  src/qemu/qemu_monitor_json.h |   10 ++
  src/qemu/qemu_monitor_text.c |  165 
  src/qemu/qemu_monitor_text.h |   10 ++
  7 files changed, 772 insertions(+), 0 deletions(-)

'make syntax-check' didn't like this one:

libvirt_unmarked_diagnostics
src/qemu/qemu_monitor_json.c-3332-),
total_bytes_sec);
src/qemu/qemu_monitor_json.c-3338-),
read_bytes_sec);
src/qemu/qemu_monitor_json.c-3344-),
write_bytes_sec);
src/qemu/qemu_monitor_json.c-3350-),
total_iops_sec);
src/qemu/qemu_monitor_json.c-3356-),
read_iops_sec);
src/qemu/qemu_monitor_json.c-3362-),
write_iops_sec);
maint.mk: found unmarked diagnostic(s)

I ended up shuffling those lines around.  Also,

prohibit_empty_lines_at_EOF
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_text.c
maint.mk: empty line(s) or no newline at EOF

I stripped the spurious whitespace.

 
 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index 5f4a18d..0a4eaa9 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -94,6 +94,8 @@
  
  #define QEMU_NB_MEM_PARAM  3
  
 +#define QEMU_NB_BLKIOTHROTTLE_PARAM  6

Naming should match the public API.

After fixing the syntax errors, I then got:
qemu/qemu_driver.c: In function 'qemuDomainSetBlockIoTune':
qemu/qemu_driver.c:10881:34: error: 'virDomainDiskDef' has no member
named 'blkdeviotune'

Ouch - your patches are submitted out of order.  Looks like I'll have to
defer further review of this one until domain_conf.h is updated.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH 3/8] Implement virDomain{Set, Get}BlockIoTune for the qemu driver

2011-11-15 Thread Lei Li
Implement the block I/O throttle setting and getting support to qemu
driver.

Signed-off-by: Lei Li li...@linux.vnet.ibm.com
Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
---
 src/qemu/qemu_driver.c   |  342 ++
 src/qemu/qemu_monitor.c  |   37 +
 src/qemu/qemu_monitor.h  |   22 +++
 src/qemu/qemu_monitor_json.c |  186 +++
 src/qemu/qemu_monitor_json.h |   10 ++
 src/qemu/qemu_monitor_text.c |  165 
 src/qemu/qemu_monitor_text.h |   10 ++
 7 files changed, 772 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5f4a18d..0a4eaa9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -94,6 +94,8 @@
 
 #define QEMU_NB_MEM_PARAM  3
 
+#define QEMU_NB_BLKIOTHROTTLE_PARAM  6
+
 #if HAVE_LINUX_KVM_H
 # include linux/kvm.h
 #endif
@@ -10775,6 +10777,344 @@ cleanup:
 return ret;
 }
 
+static int
+qemuDomainSetBlockIoTune(virDomainPtr dom,
+ const char *disk,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags)
+{
+struct qemud_driver *driver = dom-conn-privateData;
+virDomainObjPtr vm = NULL;
+qemuDomainObjPrivatePtr priv;
+virDomainDefPtr persistentDef = NULL;
+virDomainBlockIoTuneInfo info;
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+const char *device = NULL;
+int ret = -1;
+int i;
+bool isActive;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+memset(info, 0, sizeof(info));
+
+qemuDriverLock(driver);
+virUUIDFormat(dom-uuid, uuidstr);
+vm = virDomainFindByUUID(driver-domains, dom-uuid);
+if (!vm) {
+qemuReportError(VIR_ERR_NO_DOMAIN,
+_(no domain with matching uuid '%s'), uuidstr);
+goto cleanup;
+}
+
+device = qemuDiskPathToAlias(vm, disk);
+if (!device) {
+goto cleanup;
+}
+
+if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY)  0)
+goto cleanup;
+
+isActive = virDomainObjIsActive(vm);
+
+if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
+if (isActive)
+flags = VIR_DOMAIN_AFFECT_LIVE;
+else
+flags = VIR_DOMAIN_AFFECT_CONFIG;
+}
+
+if (!isActive  (flags  VIR_DOMAIN_AFFECT_LIVE)) {
+qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
+_(domain is not running));
+goto endjob;
+}
+
+if (flags  VIR_DOMAIN_AFFECT_CONFIG) {
+if (!vm-persistent) {
+qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
+_(cannot change persistent config of a transient 
domain));
+goto endjob;
+}
+if (!(persistentDef = virDomainObjGetPersistentDef(driver-caps, vm)))
+goto endjob;
+}
+
+for (i = 0; i  nparams; i++) {
+virTypedParameterPtr param = params[i];
+
+if (STREQ(param-field, VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC)) {
+
+info.total_bytes_sec = params[i].value.ul;
+} else if (STREQ(param-field, 
VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC)) {
+info.read_bytes_sec = params[i].value.ul;
+} else if (STREQ(param-field, 
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC)) {
+info.write_bytes_sec = params[i].value.ul;
+} else if (STREQ(param-field, 
VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC)) {
+info.total_iops_sec = params[i].value.ul;
+} else if (STREQ(param-field, VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC)) 
{
+info.read_iops_sec = params[i].value.ul;
+} else if (STREQ(param-field, 
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC)) {
+info.write_iops_sec = params[i].value.ul;
+} else {
+qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
+_(Unrecognized parameter));
+goto endjob;
+}
+}
+
+if ((info.total_bytes_sec  info.read_bytes_sec) ||
+(info.total_bytes_sec  info.write_bytes_sec)) {
+qemuReportError(VIR_ERR_INVALID_ARG, %s,
+_(total and read/write of bytes_sec cannot be set at 
the same time));
+goto endjob;
+}
+
+if ((info.total_iops_sec  info.read_iops_sec) ||
+(info.total_iops_sec  info.write_iops_sec)) {
+qemuReportError(VIR_ERR_INVALID_ARG, %s,
+_(total and read/write of iops_sec cannot be set at 
the same time));
+goto endjob;
+}
+
+if (flags  VIR_DOMAIN_AFFECT_LIVE) {
+priv = vm-privateData;
+qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ret = qemuMonitorSetBlockIoThrottle(priv-mon, device, info, 1);
+qemuDomainObjExitMonitorWithDriver(driver, vm);
+}
+
+if (flags  VIR_DOMAIN_AFFECT_CONFIG) {
+sa_assert(persistentDef);
+int idx = 

[libvirt] [PATCH 3/8] Implement virDomain{Set, Get}BlockIoTune for the qemu driver

2011-11-14 Thread Lei Li
This patch implement the block I/O throttle setting and getting support to qemu
driver.

Signed-off-by: Lei Li li...@linux.vnet.ibm.com
Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
---
 src/qemu/qemu_driver.c   |  340 ++
 src/qemu/qemu_monitor.c  |   37 +
 src/qemu/qemu_monitor.h  |   22 +++
 src/qemu/qemu_monitor_json.c |  185 +++
 src/qemu/qemu_monitor_json.h |   10 ++
 src/qemu/qemu_monitor_text.c |  164 
 src/qemu/qemu_monitor_text.h |   10 ++
 7 files changed, 768 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5f4a18d..740d2a2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10775,6 +10775,344 @@ cleanup:
 return ret;
 }
 
+static int
+qemuDomainSetBlockIoTune(virDomainPtr dom,
+ const char *disk,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags)
+{
+struct qemud_driver *driver = dom-conn-privateData;
+virDomainObjPtr vm = NULL;
+qemuDomainObjPrivatePtr priv;
+virDomainDefPtr persistentDef = NULL;
+virDomainBlockIoTuneInfo info;
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+const char *device = NULL;
+int ret = -1;
+int i;
+bool isActive;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+memset(info, 0, sizeof(info));
+
+qemuDriverLock(driver);
+virUUIDFormat(dom-uuid, uuidstr);
+vm = virDomainFindByUUID(driver-domains, dom-uuid);
+if (!vm) {
+qemuReportError(VIR_ERR_NO_DOMAIN,
+_(no domain with matching uuid '%s'), uuidstr);
+goto cleanup;
+}
+
+device = qemuDiskPathToAlias(vm, disk);
+if (!device) {
+goto cleanup;
+}
+
+if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY)  0)
+goto cleanup;
+
+isActive = virDomainObjIsActive(vm);
+
+if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
+if (isActive)
+flags = VIR_DOMAIN_AFFECT_LIVE;
+else
+flags = VIR_DOMAIN_AFFECT_CONFIG;
+}
+
+if (!isActive  (flags  VIR_DOMAIN_AFFECT_LIVE)) {
+qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
+_(domain is not running));
+goto endjob;
+}
+
+if (flags  VIR_DOMAIN_AFFECT_CONFIG) {
+if (!vm-persistent) {
+qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
+_(cannot change persistent config of a transient 
domain));
+goto endjob;
+}
+if (!(persistentDef = virDomainObjGetPersistentDef(driver-caps, vm)))
+goto endjob;
+}
+
+for (i = 0; i  nparams; i++) {
+virTypedParameterPtr param = params[i];
+
+if (STREQ(param-field, VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC)) {
+
+info.total_bytes_sec = params[i].value.ul;
+} else if (STREQ(param-field, 
VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC)) {
+info.read_bytes_sec = params[i].value.ul;
+} else if (STREQ(param-field, 
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC)) {
+info.write_bytes_sec = params[i].value.ul;
+} else if (STREQ(param-field, 
VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC)) {
+info.total_iops_sec = params[i].value.ul;
+} else if (STREQ(param-field, VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC)) 
{
+info.read_iops_sec = params[i].value.ul;
+} else if (STREQ(param-field, 
VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC)) {
+info.write_iops_sec = params[i].value.ul;
+} else {
+qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
+_(Unrecognized parameter));
+goto endjob;
+}
+}
+
+if ((info.total_bytes_sec  info.read_bytes_sec) ||
+(info.total_bytes_sec  info.write_bytes_sec)) {
+qemuReportError(VIR_ERR_INVALID_ARG, %s,
+_(total and read/write of bytes_sec cannot be set at 
the same time));
+goto endjob;
+}
+
+if ((info.total_iops_sec  info.read_iops_sec) ||
+(info.total_iops_sec  info.write_iops_sec)) {
+qemuReportError(VIR_ERR_INVALID_ARG, %s,
+_(total and read/write of iops_sec cannot be set at 
the same time));
+goto endjob;
+}
+
+if (flags  VIR_DOMAIN_AFFECT_LIVE) {
+priv = vm-privateData;
+qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ret = qemuMonitorSetBlockIoThrottle(priv-mon, device, info, 1);
+qemuDomainObjExitMonitorWithDriver(driver, vm);
+}
+
+if (flags  VIR_DOMAIN_AFFECT_CONFIG) {
+sa_assert(persistentDef);
+int idx = virDomainDiskIndexByName(vm-def, disk, true);
+if (i  0)
+goto endjob;
+persistentDef-disks[idx]-blkdeviotune.total_bytes_sec = 

Re: [libvirt] [PATCH 3/8] Implement virDomain{Set, Get}BlockIoTune for the qemu driver

2011-11-10 Thread Adam Litke
On Thu, Nov 10, 2011 at 04:32:53AM +0800, Lei HH Li wrote:
 This patch implement the blk io throttle setting and getting support to qemu
 driver.
 
 
 Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
 Signed-off-by: Lei Li li...@linux.vnet.ibm.com
 ---
  src/qemu/qemu_driver.c   |  216 
 ++
  src/qemu/qemu_monitor.c  |   36 +++
  src/qemu/qemu_monitor.h  |   10 ++
  src/qemu/qemu_monitor_json.c |  191 +
  src/qemu/qemu_monitor_json.h |   10 ++
  src/qemu/qemu_monitor_text.c |  152 +
  src/qemu/qemu_monitor_text.h |   10 ++
  7 files changed, 625 insertions(+), 0 deletions(-)
 
 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index db2ac0d..7ca6719 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -10759,6 +10759,220 @@ cleanup:
  return ret;
  }
 
 +static int
 +qemuDomainSetBlockIoTune(virDomainPtr dom,
 + const char *disk,
 + virDomainBlockIoTuneInfoPtr info,
 + unsigned int flags)
 +{
 +struct qemud_driver *driver = dom-conn-privateData;
 +virDomainObjPtr vm = NULL;
 +qemuDomainObjPrivatePtr priv;
 +virDomainDefPtr persistentDef = NULL;
 +char uuidstr[VIR_UUID_STRING_BUFLEN];
 +const char *device = NULL;
 +int ret = -1;
 +bool isActive;
 +
 +virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
 +  VIR_DOMAIN_AFFECT_CONFIG, -1);
 +
 +qemuDriverLock(driver);
 +virUUIDFormat(dom-uuid, uuidstr);
 +vm = virDomainFindByUUID(driver-domains, dom-uuid);
 +if (!vm) {
 +qemuReportError(VIR_ERR_NO_DOMAIN,
 +_(no domain with matching uuid '%s'), uuidstr);
 +goto cleanup;
 +}
 +
 +device = qemuDiskPathToAlias(vm, disk);
 +if (!device) {
 +goto cleanup;
 +}
 +
 +if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY)  0)
 +goto cleanup;
 +
 +isActive = virDomainObjIsActive(vm);
 +
 +if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
 +if (isActive)
 +flags = VIR_DOMAIN_AFFECT_LIVE;
 +else
 +flags = VIR_DOMAIN_AFFECT_CONFIG;
 +}
 +
 +if ((info-total_bytes_sec  info-read_bytes_sec) ||
 +(info-total_bytes_sec  info-write_bytes_sec)) {
 +qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
 +_(bps and bps_rd/bps_wr cannot be used at the same 
 time));

These messages should use the user visible names for the fields (ie.
read_bytes_sec).

 +goto endjob;
 +}
 +
 +if ((info-total_iops_sec  info-read_iops_sec) ||
 +(info-total_iops_sec  info-write_iops_sec)) {
 +qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
 +_(iops and iops_rd/iops_wr cannot be used at the 
 same time));

Same here.

 +goto endjob;
 +}
 +
 +if (!isActive  (flags  VIR_DOMAIN_AFFECT_LIVE)) {
 +qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
 +_(domain is not running));
 +goto endjob;
 +}
 +
 +   if (flags  VIR_DOMAIN_AFFECT_CONFIG) {
 +if (!vm-persistent) {
 +qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
 +_(cannot change persistent config of a 
 transient domain));
 +goto endjob;
 +}
 +if (!(persistentDef = virDomainObjGetPersistentDef(driver-caps, 
 vm)))
 +goto endjob;
 +}
 +
 +if (flags  VIR_DOMAIN_AFFECT_LIVE) {
 +priv = vm-privateData;
 +qemuDomainObjEnterMonitorWithDriver(driver, vm);
 +ret = qemuMonitorSetBlockIoThrottle(priv-mon, device, info, 1);
 +qemuDomainObjExitMonitorWithDriver(driver, vm);
 +}
 +
 +if (flags  VIR_DOMAIN_AFFECT_CONFIG) {
 +sa_assert(persistentDef);
 +int i = virDomainDiskIndexByName(vm-def, disk, true);
 +if (i  0)
 +goto endjob;
 +persistentDef-disks[i]-blkdeviotune.total_bytes_sec = 
 info-total_bytes_sec;
 +persistentDef-disks[i]-blkdeviotune.read_bytes_sec = 
 info-read_bytes_sec;
 +persistentDef-disks[i]-blkdeviotune.write_bytes_sec = 
 info-write_bytes_sec;
 +persistentDef-disks[i]-blkdeviotune.total_iops_sec = 
 info-total_iops_sec;
 +persistentDef-disks[i]-blkdeviotune.read_iops_sec = 
 info-read_iops_sec;
 +persistentDef-disks[i]-blkdeviotune.write_iops_sec = 
 info-write_iops_sec;
 +persistentDef-disks[i]-blkdeviotune.mark = 1;
 +}
 +
 +if (flags  VIR_DOMAIN_AFFECT_CONFIG) {
 +ret = virDomainSaveConfig(driver-configDir, persistentDef);
 +if (ret  0) {
 +qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
 +   _(Write to config file failed));
 +goto endjob;
 +}
 +}
 +
 +endjob:
 +if (qemuDomainObjEndJob(driver, vm) == 0)
 +vm = NULL;
 +
 

[libvirt] [PATCH 3/8] Implement virDomain{Set, Get}BlockIoTune for the qemu driver

2011-11-09 Thread Lei Li
This patch implement the blk io throttle setting and getting support to qemu
driver.


Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
Signed-off-by: Lei Li li...@linux.vnet.ibm.com
---
 src/qemu/qemu_driver.c   |  216 ++
 src/qemu/qemu_monitor.c  |   36 +++
 src/qemu/qemu_monitor.h  |   10 ++
 src/qemu/qemu_monitor_json.c |  191 +
 src/qemu/qemu_monitor_json.h |   10 ++
 src/qemu/qemu_monitor_text.c |  152 +
 src/qemu/qemu_monitor_text.h |   10 ++
 7 files changed, 625 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index db2ac0d..7ca6719 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10759,6 +10759,220 @@ cleanup:
 return ret;
 }
 
+static int
+qemuDomainSetBlockIoTune(virDomainPtr dom,
+ const char *disk,
+ virDomainBlockIoTuneInfoPtr info,
+ unsigned int flags)
+{
+struct qemud_driver *driver = dom-conn-privateData;
+virDomainObjPtr vm = NULL;
+qemuDomainObjPrivatePtr priv;
+virDomainDefPtr persistentDef = NULL;
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+const char *device = NULL;
+int ret = -1;
+bool isActive;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+qemuDriverLock(driver);
+virUUIDFormat(dom-uuid, uuidstr);
+vm = virDomainFindByUUID(driver-domains, dom-uuid);
+if (!vm) {
+qemuReportError(VIR_ERR_NO_DOMAIN,
+_(no domain with matching uuid '%s'), uuidstr);
+goto cleanup;
+}
+
+device = qemuDiskPathToAlias(vm, disk);
+if (!device) {
+goto cleanup;
+}
+
+if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY)  0)
+goto cleanup;
+
+isActive = virDomainObjIsActive(vm);
+
+if (flags == VIR_DOMAIN_AFFECT_CURRENT) {
+if (isActive)
+flags = VIR_DOMAIN_AFFECT_LIVE;
+else
+flags = VIR_DOMAIN_AFFECT_CONFIG;
+}
+
+if ((info-total_bytes_sec  info-read_bytes_sec) ||
+(info-total_bytes_sec  info-write_bytes_sec)) {
+qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
+_(bps and bps_rd/bps_wr cannot be used at the same 
time));
+goto endjob;
+}
+
+if ((info-total_iops_sec  info-read_iops_sec) ||
+(info-total_iops_sec  info-write_iops_sec)) {
+qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
+_(iops and iops_rd/iops_wr cannot be used at the same 
time));
+goto endjob;
+}
+
+if (!isActive  (flags  VIR_DOMAIN_AFFECT_LIVE)) {
+qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
+_(domain is not running));
+goto endjob;
+}
+
+   if (flags  VIR_DOMAIN_AFFECT_CONFIG) {
+if (!vm-persistent) {
+qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
+_(cannot change persistent config of a transient 
domain));
+goto endjob;
+}
+if (!(persistentDef = virDomainObjGetPersistentDef(driver-caps, vm)))
+goto endjob;
+}
+
+if (flags  VIR_DOMAIN_AFFECT_LIVE) {
+priv = vm-privateData;
+qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ret = qemuMonitorSetBlockIoThrottle(priv-mon, device, info, 1);
+qemuDomainObjExitMonitorWithDriver(driver, vm);
+}
+
+if (flags  VIR_DOMAIN_AFFECT_CONFIG) {
+sa_assert(persistentDef);
+int i = virDomainDiskIndexByName(vm-def, disk, true);
+if (i  0)
+goto endjob;
+persistentDef-disks[i]-blkdeviotune.total_bytes_sec = 
info-total_bytes_sec;
+persistentDef-disks[i]-blkdeviotune.read_bytes_sec = 
info-read_bytes_sec;
+persistentDef-disks[i]-blkdeviotune.write_bytes_sec = 
info-write_bytes_sec;
+persistentDef-disks[i]-blkdeviotune.total_iops_sec = 
info-total_iops_sec;
+persistentDef-disks[i]-blkdeviotune.read_iops_sec = 
info-read_iops_sec;
+persistentDef-disks[i]-blkdeviotune.write_iops_sec = 
info-write_iops_sec;
+persistentDef-disks[i]-blkdeviotune.mark = 1;
+}
+
+if (flags  VIR_DOMAIN_AFFECT_CONFIG) {
+ret = virDomainSaveConfig(driver-configDir, persistentDef);
+if (ret  0) {
+qemuReportError(VIR_ERR_OPERATION_INVALID, %s,
+   _(Write to config file failed));
+goto endjob;
+}
+}
+
+endjob:
+if (qemuDomainObjEndJob(driver, vm) == 0)
+vm = NULL;
+
+cleanup:
+VIR_FREE(device);
+if (vm)
+virDomainObjUnlock(vm);
+qemuDriverUnlock(driver);
+return ret;
+}
+
+static int
+qemuDomainGetBlockIoTune(virDomainPtr dom,
+ const char *disk,
+ virDomainBlockIoTuneInfoPtr reply,
+