Re: [libvirt] [PATCH] tests: add missing files

2011-09-05 Thread Osier Yang

于 2011年09月02日 22:44, Eric Blake 写道:

Created by copying from qemuxml2argv-disk-drive-v2-wb.*, then
s/writeback/directsync/.  Hopefully this matches Osier's intentions.

* tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.args:
* tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml:
Add missing files needed by 'make check'.
---

Pushing under the build-breaker rule.  Osier, if this conflicts
with the files you have locally, then feel free to update the
test to use the version you tested.


It's same with what I created, thanks.



  .../qemuxml2argv-disk-drive-cache-directsync.args  |5 +++
  .../qemuxml2argv-disk-drive-cache-directsync.xml   |   33 
  2 files changed, 38 insertions(+), 0 deletions(-)
  create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.args
  create mode 100644 
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml

diff --git 
a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.args 
b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.args
new file mode 100644
index 000..3e78726
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.args
@@ -0,0 +1,5 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,\
+format=qcow2,cache=directsync -drive file=/dev/HostVG/QEMUGuest2,if=ide,\
+media=cdrom,bus=1,unit=0,format=raw -net none -serial none -parallel none -usb
diff --git 
a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml 
b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml
new file mode 100644
index 000..17d7c1c
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-directsync.xml
@@ -0,0 +1,33 @@
+domain type='qemu'
+nameQEMUGuest1/name
+uuidc7a5fdbd-edaf-9455-926a-d65c16db1809/uuid
+memory219136/memory
+currentMemory219136/currentMemory
+vcpu1/vcpu
+os
+type arch='i686' machine='pc'hvm/type
+boot dev='hd'/
+/os
+clock offset='utc'/
+on_poweroffdestroy/on_poweroff
+on_rebootrestart/on_reboot
+on_crashdestroy/on_crash
+devices
+emulator/usr/bin/qemu/emulator
+disk type='block' device='disk'
+driver name='qemu' type='qcow2' cache='directsync'/
+source dev='/dev/HostVG/QEMUGuest1'/
+target dev='hda' bus='ide'/
+address type='drive' controller='0' bus='0' unit='0'/
+/disk
+disk type='block' device='cdrom'
+driver name='qemu' type='raw'/
+source dev='/dev/HostVG/QEMUGuest2'/
+target dev='hdc' bus='ide'/
+readonly/
+address type='drive' controller='0' bus='1' unit='0'/
+/disk
+controller type='ide' index='0'/
+memballoon model='virtio'/
+/devices
+/domain


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

Re: [libvirt] [PATCH] Fix localtime handling for Xen-PV domains

2011-09-05 Thread Daniel Veillard
On Mon, Aug 15, 2011 at 07:52:20PM +0200, Philipp Hahn wrote:
 At least Xen-3.4.3 translates the /vm/localtime SXPR value to
 /domain/platform/localtime and /domain/image/{linux,hvm}/localtime when
 the domain is defined.  When reading back that information libvirt only
 handles HVM domains, but not PV domains: This results in libvirtd always
 returning
   clock offset=utc/
 while Xend used (localtime 1).
 
 For PV domains use /domain/image/linux/localtime.
 
 Signed-off-by: Philipp Hahn h...@univention.de
 ---
 This is tracked at 
 https://forge.univention.org/bugzilla/show_bug.cgi?id=22321
 ---
  src/xenxs/xen_sxpr.c |3 +++
  1 files changed, 3 insertions(+), 0 deletions(-)
 
 diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c
 index 1f5be5f..ff8326f 100644
 --- a/src/xenxs/xen_sxpr.c
 +++ b/src/xenxs/xen_sxpr.c
 @@ -1195,6 +1195,9 @@ xenParseSxpr(const struct sexpr *root,
  def-clock.ntimers = 1;
  def-clock.timers[0] = timer;
  }
 +} else { /* !hvm */
 +if (sexpr_int(root, domain/image/linux/localtime))
 +def-clock.offset = VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME;
  }
  
  /* Current XenD allows localtime here, for PV and HVM */

  Sounds reasonnable :-) ACK

   pushed, thanks !

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

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


Re: [libvirt] migration of vnlink VMs

2011-09-05 Thread Daniel Veillard
On Tue, May 24, 2011 at 10:29:00PM +0200, Jérémie Tarot wrote:
 Hi,
 
 2011/5/24 Daniel P. Berrange berra...@redhat.com
 
  ...
 
  And new bridging modes would be
 
forward layer='link'
  mode='bridge-brctl|vepa|private|passthru|bridge-macvtap'/
 
 
 VDE ? Openvswitch ?

  I would be very happy to push openvswitch and suggest to people
to rely on it ... once it is accepted in the upstream kernel.
Unfortunately that's still not the case, and history of hypervisors
like openvz and xen really shows why this should be their #1 focus,
instead of being put in the backburner TODO list as it seems [*]

Daniel

[*] I would love to be proved wrong on this !

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

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


Re: [libvirt] [PATCH 1/3] PIIX3 USB controller is on function 2

2011-09-05 Thread Daniel Veillard
On Fri, Sep 02, 2011 at 07:43:31PM +0200, Marc-André Lureau wrote:
 Current code reserves slot 1 function 2 even if there is a user
 defined PIIX3 USB controller there.
 ---
  src/qemu/qemu_command.c |3 ++-
  1 files changed, 2 insertions(+), 1 deletions(-)
 
 diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
 index 6ff1b2c..e4bdb57 100644
 --- a/src/qemu/qemu_command.c
 +++ b/src/qemu/qemu_command.c
 @@ -1181,7 +1181,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, 
 qemuDomainPCIAddressSetPtr addrs)
   * hardcoded slot=1, multifunction device
   */
  for (function = 0; function  QEMU_PCI_ADDRESS_LAST_FUNCTION; 
 function++) {
 -if (function == 1  (reservedIDE || reservedUSB))
 +if ((function == 1  reservedIDE) ||
 +(function == 2  reservedUSB))
  /* we have reserved this pci address */
  continue;

  Yeah, I had to manually tweak that part on the rebase and of course
got it wrong ! Thanks for the quick fix :-)

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

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


Re: [libvirt] [PATCH 3/3] Add a usb1 usb2 qemuxml2argv test

2011-09-05 Thread Daniel Veillard
On Fri, Sep 02, 2011 at 07:43:33PM +0200, Marc-André Lureau wrote:
 ---
  tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.args |   15 
  tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.xml  |   74 
 
  tests/qemuxml2argvtest.c   |4 +
  3 files changed, 93 insertions(+), 0 deletions(-)
  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.args
  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.xml

  Okay that time this one applies and run fine,

I commited the 3 patches from the series

 thanks !

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

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


Re: [libvirt] [PATCH v2] Source control for storage pool

2011-09-05 Thread Daniel Veillard
On Sat, Sep 03, 2011 at 02:59:18AM +0800, Lei Li wrote:
 Fix bug #611823 storage driver should prohibit pools with duplicate underlying
 storage.
 
 Add API virStoragePoolSourceFindDuplicate() to do uniqueness check based on
 source location infomation for pool type.

  Okay I tweaked the subject and description a little bit

 
 Signed-off-by: Lei Li li...@linux.vnet.ibm.com
 ---
  src/conf/storage_conf.c  |   80 
 ++
  src/conf/storage_conf.h  |5 +++
  src/libvirt_private.syms |2 +
  src/storage/storage_driver.c |6 +++
  4 files changed, 93 insertions(+), 0 deletions(-)
 
 diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
 index 8d14e87..1e7da69 100644
 --- a/src/conf/storage_conf.c
 +++ b/src/conf/storage_conf.c
 @@ -1311,6 +1311,21 @@ virStoragePoolObjFindByName(virStoragePoolObjListPtr 
 pools,
  return NULL;
  }
  
 +virStoragePoolObjPtr
 +virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool,
 + virStoragePoolDefPtr def) {
 +unsigned int i, j;
 +
 +for (i = 0; i  pool-def-source.ndevice; i++) {
 +for (j = 0; j  def-source.ndevice; j++) {
 +if (STREQ(pool-def-source.devices[i].path, 
 def-source.devices[j].path))
 +return pool;
 +}
 +}
 +
 +return NULL;
 +}
 +
  void
  virStoragePoolObjClearVols(virStoragePoolObjPtr pool)
  {
 @@ -1701,6 +1716,71 @@ cleanup:
  return ret;
  }
  
 +int virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools,
 +  virStoragePoolDefPtr def)
 +{
 +int i;
 +int ret = 1;
 +virStoragePoolObjPtr pool = NULL;
 +virStoragePoolObjPtr matchpool = NULL;
 +
 +/* Check the pool list for duplicate underlying storage */
 +for (i = 0; i  pools-count; i++) {
 +pool = pools-objs[i];
 +if (def-type != pool-def-type)
 +continue;
 +
 +virStoragePoolObjLock(pool);
 +
 +switch (pool-def-type) {
 +case VIR_STORAGE_POOL_DIR:
 +if (STREQ(pool-def-target.path, def-target.path))
 +matchpool = pool;
 +break;
 +case VIR_STORAGE_POOL_NETFS:
 +if ((STREQ(pool-def-source.dir, def-source.dir)) \
 + (STREQ(pool-def-source.host.name, 
 def-source.host.name)))
 +matchpool = pool;
 +break;
 +case VIR_STORAGE_POOL_SCSI:
 +if (STREQ(pool-def-source.adapter, def-source.adapter))
 +matchpool = pool;
 +break;
 +case VIR_STORAGE_POOL_ISCSI:
 +{
 +matchpool = virStoragePoolSourceFindDuplicateDevices(pool, def);
 +if (matchpool) {
 +if (STREQ(matchpool-def-source.host.name, 
 def-source.host.name)) {
 +if ((matchpool-def-source.initiator.iqn)  
 (def-source.initiator.iqn)) {
 +if (STREQ(matchpool-def-source.initiator.iqn, 
 def-source.initiator.iqn))
 +break;
 +matchpool = NULL;
 +}
 +break;
 +}
 +matchpool = NULL;
 +}
 +break;
 +}
 +case VIR_STORAGE_POOL_FS:
 +case VIR_STORAGE_POOL_LOGICAL:
 +case VIR_STORAGE_POOL_DISK:
 +matchpool = virStoragePoolSourceFindDuplicateDevices(pool, def);
 +break;
 +default:
 +break;
 +}
 +virStoragePoolObjUnlock(pool);
 +}
 +
 +if (matchpool) {
 +virStorageReportError(VIR_ERR_OPERATION_FAILED,
 +  _(Storage source conflict with pool: '%s'),
 +  matchpool-def-name);
 +ret = -1;
 +}
 +return ret;
 +}
  
  void virStoragePoolObjLock(virStoragePoolObjPtr obj)
  {
 diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
 index 271441a..d115a15 100644
 --- a/src/conf/storage_conf.h
 +++ b/src/conf/storage_conf.h
 @@ -335,6 +335,8 @@ virStoragePoolObjPtr 
 virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools,
   const unsigned char *uuid);
  virStoragePoolObjPtr virStoragePoolObjFindByName(virStoragePoolObjListPtr 
 pools,
   const char *name);
 +virStoragePoolObjPtr 
 virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool,
 +  
 virStoragePoolDefPtr def);
  
  virStorageVolDefPtr virStorageVolDefFindByKey(virStoragePoolObjPtr pool,
const char *key);
 @@ -388,6 +390,9 @@ int virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr 
 pools,
   virStoragePoolDefPtr def,
   unsigned int check_active);
  
 +int 

[libvirt] [PATCH 0/8 v2] Report disk latency info

2011-09-05 Thread Osier Yang
This patch series introduces a new API to report the disk latency
related information, which is supported by upstream QEMU just a
few days ago (commit c488c7f649, Thu Aug 25).

Per previous dicussion on the ABI compatiblity, and API design
principle, the new API is defined with style:

int virDomainBlockStatsFlags (virDomainPtr dom,
  const char *path,
  virTypeParamsPtr params,
  int *nparams,
  unsigned int flags)

V1 - V2:
  * Use virTypedParameter instead of creating a new struct for the
new API.
  * Update comments for the API, (Eric's suggestion).

[PATCH 1/8] latency: Define new public API and structure
[PATCH 2/8] latency: Define the internal driver callback
[PATCH 3/8] latency: Implemente the public API
[PATCH 4/8] latency: Wire up the remote protocol
[PATCH 5/8] latency: Update monitor functions for new latency fields
[PATCH 6/8] latency: Implemente internal API for qemu driver
[PATCH 7/8] latency: Expose the new API for Python binding
[PATCH 8/8] latency: Update cmdBlkStats to use new API

Regards,
Osier

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


[libvirt] [PATCH 2/8] latency: Define the internal driver callback

2011-09-05 Thread Osier Yang
---
 src/driver.h |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/src/driver.h b/src/driver.h
index 21b2bd3..fc7a931 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -348,6 +348,13 @@ typedef int
  const char *path,
  struct _virDomainBlockStats *stats);
 typedef int
+(*virDrvDomainBlockStatsFlags)
+(virDomainPtr domain,
+ const char *path,
+ virTypedParameterPtr params,
+ int *nparams,
+ unsigned int flags);
+typedef int
 (*virDrvDomainInterfaceStats)
 (virDomainPtr domain,
  const char *path,
@@ -806,6 +813,7 @@ struct _virDriver {
 virDrvDomainMigratePerform domainMigratePerform;
 virDrvDomainMigrateFinish  domainMigrateFinish;
 virDrvDomainBlockStats  domainBlockStats;
+virDrvDomainBlockStatsFlags domainBlockStatsFlags;
 virDrvDomainInterfaceStats  domainInterfaceStats;
 virDrvDomainMemoryStats domainMemoryStats;
 virDrvDomainBlockPeek  domainBlockPeek;
-- 
1.7.6

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


[libvirt] [PATCH 1/8] latency: Define new public API and structure

2011-09-05 Thread Osier Yang
---
 include/libvirt/libvirt.h.in |   84 ++
 src/libvirt_public.syms  |1 +
 2 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 8864865..735ea94 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -574,6 +574,85 @@ struct _virDomainBlockStats {
  */
 typedef virDomainBlockStatsStruct *virDomainBlockStatsPtr;
 
+
+/**
+ * VIR_DOMAIN_BLOCK_STATS_FIELD_LENGTH:
+ *
+ * Macro providing the field length of virDomainBlockStatsFlagsStruct
+ */
+#define VIR_DOMAIN_BLOCK_STATS_FIELD_LENGTH 80
+
+/**
+ * VIR_DOMAIN_BLOCK_STATS_READ_BYTES:
+ *
+ * Macro represents the total number of read bytes of the
+ * block device.
+ */
+#define VIR_DOMAIN_BLOCK_STATS_READ_BYTES rd_bytes
+
+/**
+ * VIR_DOMAIN_BLOCK_STATS_READ_REQ:
+ *
+ * Macro represents the total read requests of the
+ * block device.
+ */
+#define VIR_DOMAIN_BLOCK_STATS_READ_REQ rd_operations
+
+/**
+ * VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES:
+ *
+ * Macro represents the total time spend on cache reads in
+ * nano-seconds of the block device.
+ */
+#define VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES rd_total_times
+
+/**
+ * VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES:
+ *
+ * Macro represents the total number of write bytes of the
+ * block device.
+ */
+#define VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES wr_bytes
+
+/**
+ * VIR_DOMAIN_BLOCK_STATS_WRITE_REQ:
+ *
+ * Macro represents the total write requests of the
+ * block device.
+ */
+#define VIR_DOMAIN_BLOCK_STATS_WRITE_REQ wr_operations
+
+/**
+ * VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES:
+ *
+ * Macro represents the total time spend on cache writes in
+ * nano-seconds of the block device.
+ */
+#define VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES wr_total_times
+
+/**
+ * VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ:
+ *
+ * Macro represents the total flush requests of the
+ * block device.
+ */
+#define VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ flush_operations
+
+/**
+ * VIR_DOMAIN_BLOCK_STATS_FLUSH_TOTAL_TIMES:
+ *
+ * Macro represents the total time spend on cache flushing in
+ * nano-seconds of the block device.
+ */
+#define VIR_DOMAIN_BLOCK_STATS_FLUSH_TOTAL_TIMES flush_total_times
+
+/**
+ * VIR_DOMAIN_BLOCK_STATS_ERRS:
+ *
+ * In Xen this returns the mysterious 'oo_req'
+ */
+#define VIR_DOMAIN_BLOCK_STATS_ERRS errs
+
 /**
  * virDomainInterfaceStats:
  *
@@ -1178,6 +1257,11 @@ int virDomainBlockStats 
(virDomainPtr dom,
  const char *path,
  virDomainBlockStatsPtr stats,
  size_t size);
+int virDomainBlockStatsFlags (virDomainPtr dom,
+  const char *path,
+  virTypedParameterPtr params,
+  int *nparams,
+  unsigned int flags);
 int virDomainInterfaceStats (virDomainPtr dom,
  const char *path,
  virDomainInterfaceStatsPtr 
stats,
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 169c3ee..dc5a80b 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -483,6 +483,7 @@ LIBVIRT_0.9.4 {
 LIBVIRT_0.9.5 {
 global:
 virDomainMigrateGetMaxSpeed;
+virDomainBlockStatsFlags;
 } LIBVIRT_0.9.4;
 
 #  define new API here using predicted next version number 
-- 
1.7.6

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


[libvirt] [PATCH 5/8] latency: Update monitor functions for new latency fields

2011-09-05 Thread Osier Yang
The mainly changes are:

1) Update qemuMonitorGetBlockStatsInfo and it's children (Text/JSON)
   functions to return the value of new latency fields.
2) Add new function qemuMonitorGetBlockStatsParamsNumber, which is
   to count how many parameters the underlying QEMU supports.
3) Update virDomainBlockStats in src/qemu/qemu_driver.c to be
   compatible with the changes by 1).
---
 src/qemu/qemu_driver.c   |4 ++
 src/qemu/qemu_monitor.c  |   35 
 src/qemu/qemu_monitor.h  |6 ++
 src/qemu/qemu_monitor_json.c |  124 +-
 src/qemu/qemu_monitor_json.h |6 ++
 src/qemu/qemu_monitor_text.c |  121 +
 src/qemu/qemu_monitor_text.h |6 ++
 7 files changed, 291 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7028d72..c5809d2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7224,8 +7224,12 @@ qemudDomainBlockStats (virDomainPtr dom,
disk-info.alias,
stats-rd_req,
stats-rd_bytes,
+   NULL,
stats-wr_req,
stats-wr_bytes,
+   NULL,
+   NULL,
+   NULL,
stats-errs);
 qemuDomainObjExitMonitor(driver, vm);
 
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index db6107c..92631ae 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1201,8 +1201,12 @@ int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
  const char *devname,
  long long *rd_req,
  long long *rd_bytes,
+ long long *rd_total_times,
  long long *wr_req,
  long long *wr_bytes,
+ long long *wr_total_times,
+ long long *flush_req,
+ long long *flush_total_times,
  long long *errs)
 {
 int ret;
@@ -1217,16 +1221,47 @@ int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
 if (mon-json)
 ret = qemuMonitorJSONGetBlockStatsInfo(mon, devname,
rd_req, rd_bytes,
+   rd_total_times,
wr_req, wr_bytes,
+   wr_total_times,
+   flush_req,
+   flush_total_times,
errs);
 else
 ret = qemuMonitorTextGetBlockStatsInfo(mon, devname,
rd_req, rd_bytes,
+   rd_total_times,
wr_req, wr_bytes,
+   wr_total_times,
+   flush_req,
+   flush_total_times,
errs);
 return ret;
 }
 
+/* Return 0 and update @nparams with the number of block stats
+ * QEMU supports if success. Return -1 if failure.
+ */
+int qemuMonitorGetBlockStatsParamsNumber(qemuMonitorPtr mon,
+ int *nparams)
+{
+int ret;
+VIR_DEBUG(mon=%p nparams=%p, mon, nparams);
+
+if (!mon) {
+qemuReportError(VIR_ERR_INVALID_ARG, %s,
+_(monitor must not be NULL));
+return -1;
+}
+
+if (mon-json)
+ret = qemuMonitorJSONGetBlockStatsParamsNumber(mon, nparams);
+else
+ret = qemuMonitorTextGetBlockStatsParamsNumber(mon, nparams);
+
+return ret;
+}
+
 int qemuMonitorGetBlockExtent(qemuMonitorPtr mon,
   const char *devname,
   unsigned long long *extent)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index f241c9e..1b9d98d 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -212,9 +212,15 @@ int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
  const char *devname,
  long long *rd_req,
  long long *rd_bytes,
+ long long *rd_total_times,
  long long *wr_req,
  long long *wr_bytes,
+ long long *wr_total_times,
+ long 

[libvirt] [PATCH 6/8] latency: Implemente internal API for qemu driver

2011-09-05 Thread Osier Yang
---
 src/qemu/qemu_driver.c |  189 
 1 files changed, 189 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c5809d2..a8b2b6d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7243,6 +7243,194 @@ cleanup:
 return ret;
 }
 
+static int
+qemudDomainBlockStatsFlags (virDomainPtr dom,
+const char *path,
+virTypedParameterPtr params,
+int *nparams,
+unsigned int flags)
+{
+struct qemud_driver *driver = dom-conn-privateData;
+int i, tmp, ret = -1;
+virDomainObjPtr vm;
+virDomainDiskDefPtr disk = NULL;
+qemuDomainObjPrivatePtr priv;
+long long rd_req, rd_bytes, wr_req, wr_bytes, rd_total_times;
+long long wr_total_times, flush_req, flush_total_times, errs;
+
+virCheckFlags(0, -1);
+
+qemuDriverLock(driver);
+vm = virDomainFindByUUID(driver-domains, dom-uuid);
+qemuDriverUnlock(driver);
+if (!vm) {
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+virUUIDFormat(dom-uuid, uuidstr);
+qemuReportError(VIR_ERR_NO_DOMAIN,
+_(no domain with matching uuid '%s'), uuidstr);
+goto cleanup;
+}
+
+if (!virDomainObjIsActive(vm)) {
+qemuReportError(VIR_ERR_OPERATION_INVALID,
+%s, _(domain is not running));
+goto cleanup;
+}
+
+if (*nparams != 0) {
+for (i = 0 ; i  vm-def-ndisks ; i++) {
+if (STREQ(path, vm-def-disks[i]-dst)) {
+disk = vm-def-disks[i];
+break;
+}
+}
+
+if (!disk) {
+qemuReportError(VIR_ERR_INVALID_ARG,
+_(invalid path: %s), path);
+goto cleanup;
+}
+
+if (!disk-info.alias) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _(missing disk device alias name for %s), 
disk-dst);
+ goto cleanup;
+}
+}
+
+priv = vm-privateData;
+VIR_DEBUG(priv=%p, params=%p, flags=%x, priv, params, flags);
+
+if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY)  0)
+goto cleanup;
+
+qemuDomainObjEnterMonitor(driver, vm);
+tmp = *nparams;
+ret = qemuMonitorGetBlockStatsParamsNumber(priv-mon, nparams);
+
+if (tmp == 0) {
+qemuDomainObjExitMonitor(driver, vm);
+goto endjob;
+}
+
+ret = qemuMonitorGetBlockStatsInfo(priv-mon,
+   disk-info.alias,
+   rd_req,
+   rd_bytes,
+   rd_total_times,
+   wr_req,
+   wr_bytes,
+   wr_total_times,
+   flush_req,
+   flush_total_times,
+   errs);
+
+qemuDomainObjExitMonitor(driver, vm);
+
+if (ret  0)
+goto endjob;
+
+/* Field 'errs' is meaningless for QEMU, won't set it. */
+for (i = 0; i  *nparams; i++) {
+virTypedParameterPtr param = params[i];
+
+switch (i) {
+case 0: /* fill write_bytes here */
+if (virStrcpyStatic(param-field, 
VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES) == NULL) {
+qemuReportError(VIR_ERR_INTERNAL_ERROR,
+%s, _(Field write bytes too long for 
destination));
+goto cleanup;
+}
+param-type = VIR_TYPED_PARAM_LLONG;
+param-value.l = wr_bytes;
+break;
+
+case 1: /* fill wr_operations here */
+if (virStrcpyStatic(param-field, 
VIR_DOMAIN_BLOCK_STATS_WRITE_REQ) == NULL) {
+qemuReportError(VIR_ERR_INTERNAL_ERROR,
+%s, _(Field write requests too long for 
destination));
+goto cleanup;
+}
+param-type = VIR_TYPED_PARAM_LLONG;
+param-value.l = wr_req;
+break;
+
+case 2: /* fill read_bytes here */
+if (virStrcpyStatic(param-field, 
VIR_DOMAIN_BLOCK_STATS_READ_BYTES) == NULL) {
+qemuReportError(VIR_ERR_INTERNAL_ERROR,
+%s, _(Field read bytes too long for 
destination));
+goto cleanup;
+}
+param-type = VIR_TYPED_PARAM_LLONG;
+param-value.l = rd_bytes;
+break;
+
+case 3: /* fill rd_operations here */
+if (virStrcpyStatic(param-field, VIR_DOMAIN_BLOCK_STATS_READ_REQ) 
== NULL) {
+qemuReportError(VIR_ERR_INTERNAL_ERROR,
+%s, _(Field read requests too long for 
destination));
+goto cleanup;
+}

[libvirt] [PATCH 3/8] latency: Implemente the public API

2011-09-05 Thread Osier Yang
---
 src/libvirt.c |   71 +
 1 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/src/libvirt.c b/src/libvirt.c
index 4d80e2f..a921e4d 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -6442,6 +6442,77 @@ error:
 }
 
 /**
+ * virDomainBlockStatsFlags:
+ * @dom: pointer to domain object
+ * @path: path to the block device
+ * @params: pointer to block stats parameter object
+ *  (return value)
+ * @nparams: pointer to number of block stats
+ * @flags: unused, always passes 0
+ *
+ * This function is to get block stats parameters for block
+ * devices attached to the domain.
+ *
+ * The @path is the name of the block device.  Get this
+ * by calling virDomainGetXMLDesc and finding the target dev='...'
+ * attribute within //domain/devices/disk.  (For example, xvda).
+ *
+ * Domains may have more than one block device.  To get stats for
+ * each you should make multiple calls to this function.
+ *
+ * The @params array will be filled with the value equal to the number of
+ * parameters suggested by @nparams.
+ *
+ * As the value of @nparams is dynamic, call the API setting @nparams to 0 and
+ * @params as NULL, the API returns the number of parameters supported by the
+ * HV by updating @nparams on SUCCESS. (Note that block device of different 
type
+ * might support different parameters numbers, so it might be necessary to 
compute
+ * @nparams for each block device type). The caller should then allocate 
@params
+ * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
+ * again. See virDomainGetMemoryParameters for more details.
+ *
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int virDomainBlockStatsFlags (virDomainPtr dom,
+  const char *path,
+  virTypedParameterPtr params,
+  int *nparams,
+  unsigned int flags)
+{
+virConnectPtr conn;
+
+VIR_DOMAIN_DEBUG(dom, path=%s, params=%p, nparams=%d, flags=%x,
+ path, params, nparams ? *nparams : -1, flags);
+
+virResetLastError();
+
+if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
+virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+virDispatchError(NULL);
+return -1;
+}
+if (!path || (nparams == NULL) || (*nparams  0)) {
+virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+goto error;
+}
+conn = dom-conn;
+
+if (conn-driver-domainBlockStatsFlags) {
+int ret;
+ret = conn-driver-domainBlockStatsFlags(dom, path, params, nparams, 
flags);
+if (ret  0)
+goto error;
+return ret;
+}
+virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+virDispatchError(dom-conn);
+return -1;
+}
+
+
+/**
  * virDomainInterfaceStats:
  * @dom: pointer to the domain object
  * @path: path to the interface
-- 
1.7.6

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


[libvirt] [PATCH 4/8] latency: Wire up the remote protocol

2011-09-05 Thread Osier Yang
---
 daemon/remote.c  |   69 ++
 src/remote/remote_driver.c   |   64 ++
 src/remote/remote_protocol.x |   19 +++-
 3 files changed, 151 insertions(+), 1 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index d5ead81..38bbb10 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -933,6 +933,75 @@ cleanup:
 }
 
 static int
+remoteDispatchDomainBlockStatsFlags(virNetServerPtr server ATTRIBUTE_UNUSED,
+virNetServerClientPtr client 
ATTRIBUTE_UNUSED,
+virNetMessageHeaderPtr hdr 
ATTRIBUTE_UNUSED,
+virNetMessageErrorPtr rerr,
+remote_domain_block_stats_flags_args *args,
+remote_domain_block_stats_flags_ret *ret)
+{
+virTypedParameterPtr params = NULL;
+virDomainPtr dom = NULL;
+int i;
+const char *path = args-path;
+int nparams = args-nparams;
+unsigned int flags;
+int rv = -1;
+struct daemonClientPrivate *priv =
+virNetServerClientGetPrivateData(client);
+
+if (!priv-conn) {
+virNetError(VIR_ERR_INTERNAL_ERROR, %s, _(connection not open));
+goto cleanup;
+}
+
+if (!(dom = get_nonnull_domain(priv-conn, args-dom)))
+goto cleanup;
+flags = args-flags;
+
+if (nparams  REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX) {
+virNetError(VIR_ERR_INTERNAL_ERROR, %s, _(nparams too large));
+goto cleanup;
+}
+if (VIR_ALLOC_N(params, nparams)  0) {
+virReportOOMError();
+goto cleanup;
+}
+
+if (virDomainBlockStatsFlags(dom, path, params, nparams, flags)  0)
+goto cleanup;
+
+/* In this case, we need to send back the number of parameters
+ * supported
+ */
+if (args-nparams == 0) {
+ret-nparams = nparams;
+goto success;
+}
+
+/* Serialise the block stats. */
+if (remoteSerializeTypedParameters(params, nparams,
+   ret-params.params_val,
+   ret-params.params_len)  0)
+goto cleanup;
+
+success:
+rv = 0;
+
+cleanup:
+if (rv  0) {
+virNetMessageSaveError(rerr);
+if (ret-params.params_val) {
+for (i = 0; i  nparams; i++)
+VIR_FREE(ret-params.params_val[i].field);
+VIR_FREE(ret-params.params_val);
+}
+}
+VIR_FREE(params);
+return rv;
+}
+
+static int
 remoteDispatchDomainMemoryPeek(virNetServerPtr server ATTRIBUTE_UNUSED,
virNetServerClientPtr client ATTRIBUTE_UNUSED,
virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 783c404..9d34b7e 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -1361,6 +1361,69 @@ cleanup:
 }
 
 static int
+remoteDomainBlockStatsFlags(virDomainPtr domain,
+const char *path,
+virTypedParameterPtr params,
+int *nparams,
+unsigned int flags)
+{
+int rv = -1;
+remote_domain_block_stats_flags_args args;
+remote_domain_block_stats_flags_ret ret;
+struct private_data *priv = domain-conn-privateData;
+
+remoteDriverLock(priv);
+
+make_nonnull_domain (args.dom, domain);
+args.nparams = *nparams;
+args.path = (char *) path;
+args.flags = flags;
+
+memset (ret, 0, sizeof ret);
+if (call (domain-conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_STATS_FLAGS,
+  (xdrproc_t) xdr_remote_domain_block_stats_flags_args, (char *) 
args,
+  (xdrproc_t) xdr_remote_domain_block_stats_flags_ret, (char *) 
ret) == -1)
+goto done;
+
+/* Check the length of the returned list carefully. */
+if (ret.params.params_len  REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX ||
+ret.params.params_len  *nparams) {
+remoteError(VIR_ERR_RPC, %s,
+_(remoteDomainBlockStatsFlags: 
+  returned number of stats exceeds limit));
+goto cleanup;
+}
+
+/* Handle the case when the caller does not know the number of stats
+ * and is asking for the number of stats supported
+ */
+if (*nparams == 0) {
+*nparams = ret.nparams;
+rv = 0;
+goto cleanup;
+}
+
+*nparams = ret.params.params_len;
+
+/* Deserialise the result. */
+if (remoteDeserializeTypedParameters(ret.params.params_val,
+ ret.params.params_len,
+ REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX,
+ params,
+ nparams)  0)
+goto cleanup;
+
+rv = 0;
+
+cleanup:
+xdr_free 

[libvirt] [PATCH 7/8] latency: Expose the new API for Python binding

2011-09-05 Thread Osier Yang
---
 python/generator.py |1 +
 python/libvirt-override-api.xml |7 +++
 python/libvirt-override.c   |   85 +++
 3 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/python/generator.py b/python/generator.py
index cc253cf..d17fb26 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -373,6 +373,7 @@ skip_impl = (
 'virNodeGetMemoryStats',
 'virDomainGetBlockJobInfo',
 'virDomainMigrateGetMaxSpeed',
+'virDomainBlockStatsFlags',
 )
 
 
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index 1cf115c..3013e46 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ -128,6 +128,13 @@
   arg name='domain' type='virDomainPtr' info='a domain object'/
   arg name='path' type='char *' info='the path for the block device'/
 /function
+function name='virDomainBlockStatsFlags' file='python'
+  infoExtracts block device statistics parameters of a running 
domain/info
+  return type='virTypedParameterPtr' info='None in case of error, returns 
a dictionary of params'/
+  arg name='domain' type='virDomainPtr' info='pointer to domain object'/
+  arg name='path' type='char *' info='the path for the block device'/
+  arg name='flags' type='int' info='flags (unused; pass 0)'/
+/function
 function name='virDomainInterfaceStats' file='python'
   infoExtracts interface device statistics for a domain/info
   return type='virDomainInterfaceStats' info='a tuple of statistics'/
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index b020342..d65423d 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -100,6 +100,90 @@ libvirt_virDomainBlockStats(PyObject *self 
ATTRIBUTE_UNUSED, PyObject *args) {
 }
 
 static PyObject *
+libvirt_virDomainBlockStatsFlags(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args) {
+virDomainPtr domain;
+PyObject *pyobj_domain, *info;
+int i_retval;
+int nparams = 0, i;
+unsigned int flags;
+virTypedParameterPtr params;
+const char *path;
+
+if (!PyArg_ParseTuple(args, (char *)Ozi:virDomainBlockStatsFlags,
+  pyobj_domain, path, flags))
+return(NULL);
+domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+LIBVIRT_BEGIN_ALLOW_THREADS;
+i_retval = virDomainBlockStatsFlags(domain, path, NULL, nparams, flags);
+LIBVIRT_END_ALLOW_THREADS;
+
+if (i_retval  0)
+return VIR_PY_NONE;
+
+if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+return VIR_PY_NONE;
+
+LIBVIRT_BEGIN_ALLOW_THREADS;
+i_retval = virDomainBlockStatsFlags(domain, path, params, nparams, flags);
+LIBVIRT_END_ALLOW_THREADS;
+
+if (i_retval  0) {
+free(params);
+return VIR_PY_NONE;
+}
+
+/* convert to a Python tuple of long objects */
+if ((info = PyDict_New()) == NULL) {
+free(params);
+return VIR_PY_NONE;
+}
+
+for (i = 0 ; i  nparams ; i++) {
+PyObject *key, *val;
+
+switch (params[i].type) {
+case VIR_TYPED_PARAM_INT:
+val = PyInt_FromLong((long)params[i].value.i);
+break;
+
+case VIR_TYPED_PARAM_UINT:
+val = PyInt_FromLong((long)params[i].value.ui);
+break;
+
+case VIR_TYPED_PARAM_LLONG:
+val = PyLong_FromLongLong((long long)params[i].value.l);
+break;
+
+case VIR_TYPED_PARAM_ULLONG:
+val = PyLong_FromLongLong((long long)params[i].value.ul);
+break;
+
+case VIR_TYPED_PARAM_DOUBLE:
+val = PyFloat_FromDouble((double)params[i].value.d);
+break;
+
+case VIR_TYPED_PARAM_BOOLEAN:
+val = PyBool_FromLong((long)params[i].value.b);
+break;
+
+default:
+free(params);
+Py_DECREF(info);
+return VIR_PY_NONE;
+}
+
+key = libvirt_constcharPtrWrap(params[i].field);
+PyDict_SetItem(info, key, val);
+}
+
+free(params);
+return(info);
+}
+
+
+static PyObject *
 libvirt_virDomainInterfaceStats(PyObject *self ATTRIBUTE_UNUSED, PyObject 
*args) {
 virDomainPtr domain;
 PyObject *pyobj_domain;
@@ -4605,6 +4689,7 @@ static PyMethodDef libvirtMethods[] = {
 {(char *) virDomainGetAutostart, libvirt_virDomainGetAutostart, 
METH_VARARGS, NULL},
 {(char *) virNetworkGetAutostart, libvirt_virNetworkGetAutostart, 
METH_VARARGS, NULL},
 {(char *) virDomainBlockStats, libvirt_virDomainBlockStats, 
METH_VARARGS, NULL},
+{(char *) virDomainBlockStatsFlags, libvirt_virDomainBlockStatsFlags, 
METH_VARARGS, NULL},
 {(char *) virDomainInterfaceStats, libvirt_virDomainInterfaceStats, 
METH_VARARGS, NULL},
 {(char *) virDomainMemoryStats, libvirt_virDomainMemoryStats, 
METH_VARARGS, NULL},
 {(char *) 

[libvirt] [PATCH 8/8] latency: Update cmdBlkStats to use new API

2011-09-05 Thread Osier Yang
The modified function fallbacks to use virDomainBlockStats if
virDomainBlockStatsFlags is not supported by the hypervisor driver.
If the new API is supported, it will be invoked instead of the
old API.
---
 tools/virsh.c |  104 ++---
 1 files changed, 84 insertions(+), 20 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index c7240e5..ea41221 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1070,6 +1070,9 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd)
 virDomainPtr dom;
 const char *name = NULL, *device = NULL;
 struct _virDomainBlockStats stats;
+virTypedParameterPtr params = NULL;
+int rc, nparams = 0;
+bool ret = false;
 
 if (!vshConnectionUsability (ctl, ctl-conn))
 return false;
@@ -1077,34 +1080,95 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd)
 if (!(dom = vshCommandOptDomain (ctl, cmd, name)))
 return false;
 
-if (vshCommandOptString (cmd, device, device) = 0) {
-virDomainFree(dom);
-return false;
-}
+if (vshCommandOptString (cmd, device, device) = 0)
+goto cleanup;
 
-if (virDomainBlockStats (dom, device, stats, sizeof stats) == -1) {
-vshError(ctl, _(Failed to get block stats %s %s), name, device);
-virDomainFree(dom);
-return false;
-}
+rc = virDomainBlockStatsFlags(dom, device, NULL, nparams, 0);
 
-if (stats.rd_req = 0)
-vshPrint (ctl, %s rd_req %lld\n, device, stats.rd_req);
+/* It might fail when virDomainBlockStatsFlags is not
+ * supported on older libvirt, fallback to use virDomainBlockStats
+ * then.
+ */
+if (rc  0) {
+if (last_error-code != VIR_ERR_NO_SUPPORT) {
+virshReportError(ctl);
+goto cleanup;
+} else {
+virFreeError(last_error);
+last_error = NULL;
 
-if (stats.rd_bytes = 0)
-vshPrint (ctl, %s rd_bytes %lld\n, device, stats.rd_bytes);
+if (virDomainBlockStats (dom, device, stats,
+ sizeof stats) == -1) {
+vshError(ctl, _(Failed to get block stats %s %s),
+ name, device);
+goto cleanup;
+}
+
+if (stats.rd_req = 0)
+vshPrint (ctl, %s rd_req %lld\n, device, stats.rd_req);
 
-if (stats.wr_req = 0)
-vshPrint (ctl, %s wr_req %lld\n, device, stats.wr_req);
+if (stats.rd_bytes = 0)
+vshPrint (ctl, %s rd_bytes %lld\n, device, stats.rd_bytes);
 
-if (stats.wr_bytes = 0)
-vshPrint (ctl, %s wr_bytes %lld\n, device, stats.wr_bytes);
+if (stats.wr_req = 0)
+vshPrint (ctl, %s wr_req %lld\n, device, stats.wr_req);
 
-if (stats.errs = 0)
-vshPrint (ctl, %s errs %lld\n, device, stats.errs);
+if (stats.wr_bytes = 0)
+vshPrint (ctl, %s wr_bytes %lld\n, device, stats.wr_bytes);
 
+if (stats.errs = 0)
+vshPrint (ctl, %s errs %lld\n, device, stats.errs);
+}
+} else {
+params = vshMalloc(ctl, sizeof(*params) * nparams);
+memset(params, 0, sizeof(*params) * nparams);
+
+if (virDomainBlockStatsFlags (dom, device, params, nparams, 0)  0) {
+vshError(ctl, _(Failed to get block stats %s %s), name, device);
+goto cleanup;
+}
+
+int i;
+/* XXX: The output sequence will be different. */
+for (i = 0; i  nparams; i++) {
+switch(params[i].type) {
+case VIR_TYPED_PARAM_INT:
+vshPrint (ctl, %s %s %d\n, device,
+  params[i].field, params[i].value.i);
+break;
+case VIR_TYPED_PARAM_UINT:
+vshPrint (ctl, %s %s %u\n, device,
+  params[i].field, params[i].value.ui);
+break;
+case VIR_TYPED_PARAM_LLONG:
+vshPrint (ctl, %s %s %lld\n, device,
+  params[i].field, params[i].value.l);
+break;
+case VIR_TYPED_PARAM_ULLONG:
+vshPrint (ctl, %s %s %llu\n, device,
+  params[i].field, params[i].value.ul);
+break;
+case VIR_TYPED_PARAM_DOUBLE:
+vshPrint (ctl, %s %s %f\n, device,
+  params[i].field, params[i].value.d);
+break;
+case VIR_TYPED_PARAM_BOOLEAN:
+vshPrint (ctl, %s %s %s\n, device,
+  params[i].field, params[i].value.b ? _(yes) : 
_(no));
+break;
+default:
+vshError(ctl, _(unimplemented block statistics parameter 
type));
+}
+
+}
+}
+
+ret = true;
+
+cleanup:
+VIR_FREE(params);
 virDomainFree(dom);
-return true;
+return ret;
 }
 
 /* domifstat command
-- 
1.7.6


[libvirt] [PATCH RFC 0/2] XML: Improve XML parse error reporting

2011-09-05 Thread Peter Krempa
First patch modifies the error reporting function on parse errors of XML files.
A new, more informative message is presented to the user, containing filename
of the offending file, error description and context of the error in libxml2 
style.

Second patch changes default filenames used while parsing XML strings in memory
to NULL, so that the error reporting function does not print bougus filename.


 src/conf/domain_conf.c- change domain.xml to NULL
 src/security/virt-aa-helper.c - change domain.xml to NULL
 src/util/xml.c- modify error reporting function

Peter Krempa (2):
  XML: Improve XML parsing error messages
  XML: Suppress printing domain.xml for parse errors on XML strings

 src/conf/domain_conf.c|2 +-
 src/security/virt-aa-helper.c |2 +-
 src/util/xml.c|   88 +++--
 3 files changed, 78 insertions(+), 14 deletions(-)

-- 
1.7.3.4

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


[libvirt] [PATCH RFC 1/2] XML: Improve XML parsing error messages

2011-09-05 Thread Peter Krempa
This patch modifies error handling function for the XML parser provided
by libxml2.

Originaly only a line number and error message were logged. With this
new error handler function, the user is provided with a more complex
description of the parsing error.

Context of the error is printed in libXML2 style and filename of the
file, that caused the error is printed. Example of an parse error:

13:41:36.262: 16032: error : catchXMLError:706 :
/etc/libvirt/qemu/rh_bad.xml:58: Opening and ending tag mismatch: name
line 2 and domain
/domain
-^

Context of the error gives the user hints that may help to quickly
locate a corrupt xml file.

fixes BZs:
--
Bug 708735 - [RFE] Show column and line on XML parsing error
https://bugzilla.redhat.com/show_bug.cgi?id=708735

Bug 726771 - libvirt does not specify problem file if persistent xml is
invalid
https://bugzilla.redhat.com/show_bug.cgi?id=726771
---
 src/util/xml.c |   88 ---
 1 files changed, 76 insertions(+), 12 deletions(-)

diff --git a/src/util/xml.c b/src/util/xml.c
index d301af6..b0942da 100644
--- a/src/util/xml.c
+++ b/src/util/xml.c
@@ -633,28 +633,92 @@ virXPathNodeSet(const char *xpath,
  * catchXMLError:
  *
  * Called from SAX on parsing errors in the XML.
+ *
+ * This version is heavily based on xmlParserPrintFileContextInternal from 
libxml2.
  */
 static void
 catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...)
 {
-int domcode = VIR_FROM_XML;
 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;

-if (ctxt) {
-if (ctxt-_private)
+const xmlChar *cur, *base;
+unsigned int n, col;   /* GCC warns if signed, because compared with 
sizeof() */
+int domcode = VIR_FROM_XML;
+
+virBuffer buf = VIR_BUFFER_INITIALIZER;
+char *contextstr = NULL;
+char *pointerstr = NULL;
+
+
+/* conditions for error printing */
+if (!ctxt ||
+(virGetLastError() != NULL) ||
+ctxt-input == NULL ||
+ctxt-lastError.level != XML_ERR_FATAL ||
+ctxt-lastError.message == NULL)
+return;
+
+if (ctxt-_private)
 domcode = ((struct virParserData *) ctxt-_private)-domcode;

-if (virGetLastError() == NULL 
-ctxt-lastError.level == XML_ERR_FATAL 
-ctxt-lastError.message != NULL) {
-virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
-  _(at line %d: %s),
-  ctxt-lastError.line,
-  ctxt-lastError.message);
-}
+
+cur = ctxt-input-cur;
+base = ctxt-input-base;
+
+/* skip backwards over any end-of-lines */
+while ((cur  base)  ((*(cur) == '\n') || (*(cur) == '\r'))) {
+cur--;
 }
-}

+/* search backwards for beginning-of-line (to max buff size) */
+while ((cur  base)  (*(cur) != '\n')  (*(cur) != '\r'))
+cur--;
+if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
+
+/* calculate the error position in terms of the current position */
+col = ctxt-input-cur - cur;
+
+/* search forward for end-of-line (to max buff size) */
+/* copy selected text to our buffer */
+while ((*cur != 0)  (*(cur) != '\n')  (*(cur) != '\r')) {
+virBufferAddChar(buf, *cur++);
+}
+
+/* create blank line with problem pointer */
+contextstr = virBufferContentAndReset(buf);
+
+/* (leave buffer space for pointer + line terminator) */
+for  (n = 0; (ncol)  (contextstr[n] != 0); n++) {
+if (contextstr[n] == '\t')
+virBufferAddChar(buf, '\t');
+else
+virBufferAddChar(buf, '-');
+}
+
+virBufferAddChar(buf, '^');
+
+pointerstr = virBufferContentAndReset(buf);
+
+if (ctxt-lastError.file) {
+virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
+  _(%s:%d: %s%s\n%s),
+  ctxt-lastError.file,
+  ctxt-lastError.line,
+  ctxt-lastError.message,
+  contextstr,
+  pointerstr);
+} else {
+ virGenericReportError(domcode, VIR_ERR_XML_DETAIL,
+  _(at line %d: %s%s\n%s),
+  ctxt-lastError.line,
+  ctxt-lastError.message,
+  contextstr,
+  pointerstr);
+}
+
+VIR_FREE(contextstr);
+VIR_FREE(pointerstr);
+}

 /**
  * virXMLParseHelper:
-- 
1.7.3.4

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


[libvirt] [PATCH v4] daemon: Create priority workers pool

2011-09-05 Thread Michal Privoznik
This patch annotates APIs with low or high priority.
In low set MUST be all APIs which might eventually access monitor
(and thus block indefinitely). Other APIs may be marked as high
priority. However, some must be (e.g. domainDestroy).

For high priority calls (HPC), there are some high priority workers
(HPW) created in the pool. HPW can execute only HPC, although normal
worker can process any call regardless priority. Therefore, only those
APIs which are guaranteed to end in reasonable small amount of time
can be marked as HPC.

The size of this HPC pool is static, because HPC are expected to end
quickly, therefore jobs assigned to this pool will be served quickly.
It can be configured in libvirtd.conf via prio_workers variable.
Default is set to 5.

To mark API with low or high priority, append priority:{low|high} to
it's comment in src/remote/remote_protocol.x. This is similar to
autogen|skipgen. If not marked, the generator assumes low as default.
---
diff to v3:
-make 'priority:low' as default which can be left out
-rearrange some APIs to be HPC or LPC

 daemon/libvirtd.aug   |1 +
 daemon/libvirtd.c |7 +
 daemon/libvirtd.conf  |6 +
 src/qemu/qemu_driver.c|2 +-
 src/qemu/qemu_process.c   |2 +-
 src/remote/qemu_protocol.x|   13 ++-
 src/remote/remote_protocol.x  |  294 +
 src/rpc/gendispatch.pl|   20 +++-
 src/rpc/virnetserver.c|   60 +
 src/rpc/virnetserver.h|1 +
 src/rpc/virnetserverprogram.c |   11 ++
 src/rpc/virnetserverprogram.h |4 +
 src/util/threadpool.c |  158 +++
 src/util/threadpool.h |4 +-
 14 files changed, 382 insertions(+), 201 deletions(-)

diff --git a/daemon/libvirtd.aug b/daemon/libvirtd.aug
index 3f47ebb..ce00db5 100644
--- a/daemon/libvirtd.aug
+++ b/daemon/libvirtd.aug
@@ -57,6 +57,7 @@ module Libvirtd =
 | int_entry max_clients
 | int_entry max_requests
 | int_entry max_client_requests
+| int_entry prio_workers
 
let logging_entry = int_entry log_level
  | str_entry log_filters
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 423c3d7..7b445a2 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -134,6 +134,8 @@ struct daemonConfig {
 int max_workers;
 int max_clients;
 
+int prio_workers;
+
 int max_requests;
 int max_client_requests;
 
@@ -886,6 +888,8 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
 data-max_workers = 20;
 data-max_clients = 20;
 
+data-prio_workers = 5;
+
 data-max_requests = 20;
 data-max_client_requests = 5;
 
@@ -1042,6 +1046,8 @@ daemonConfigLoad(struct daemonConfig *data,
 GET_CONF_INT (conf, filename, max_workers);
 GET_CONF_INT (conf, filename, max_clients);
 
+GET_CONF_INT (conf, filename, prio_workers);
+
 GET_CONF_INT (conf, filename, max_requests);
 GET_CONF_INT (conf, filename, max_client_requests);
 
@@ -1430,6 +1436,7 @@ int main(int argc, char **argv) {
 config-auth_unix_ro == REMOTE_AUTH_POLKIT;
 if (!(srv = virNetServerNew(config-min_workers,
 config-max_workers,
+config-prio_workers,
 config-max_clients,
 config-mdns_adv ? config-mdns_name : NULL,
 use_polkit_dbus,
diff --git a/daemon/libvirtd.conf b/daemon/libvirtd.conf
index 95e43dd..da3983e 100644
--- a/daemon/libvirtd.conf
+++ b/daemon/libvirtd.conf
@@ -257,6 +257,12 @@
 #min_workers = 5
 #max_workers = 20
 
+
+# The number of priority workers. If all workers from above
+# pool will stuck, some calls marked as high priority
+# (notably domainDestroy) can be executed in this pool.
+#prio_workers = 5
+
 # Total global limit on concurrent RPC calls. Should be
 # at least as large as max_workers. Beyond this, RPC requests
 # will be read into memory and queued. This directly impact
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f21122d..b26a0cb 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -656,7 +656,7 @@ qemudStartup(int privileged) {
 virHashForEach(qemu_driver-domains.objs, qemuDomainSnapshotLoad,
qemu_driver-snapshotDir);
 
-qemu_driver-workerPool = virThreadPoolNew(0, 1, processWatchdogEvent, 
qemu_driver);
+qemu_driver-workerPool = virThreadPoolNew(0, 1, 0, processWatchdogEvent, 
qemu_driver);
 if (!qemu_driver-workerPool)
 goto error;
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 58b4d36..878805a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -576,7 +576,7 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon 
ATTRIBUTE_UNUSED,
  * deleted before handling watchdog event is finished.
  */

Re: [libvirt] [PATCHv4 00/51] another round of snapshot patches

2011-09-05 Thread Eric Blake

On 09/02/2011 03:57 AM, Daniel Veillard wrote:

On Thu, Sep 01, 2011 at 10:24:37PM -0600, Eric Blake wrote:

I think I've addressed most findings from round 3 - by implementing



  35, 36 ACK
  37 ACK
  38 ACK
  39 ACK to new API flag
  40 ACK
  41 ACK
  42 ACK
  43 ACK
  44 nice improvement, hopefully can't lead to regressions, and also
 end up cleaning up the code in a few places, ACK
  45 useful for scripting, ACK
  46 ACK
  47 ACK
  48 ACK
  49 ACK, mechnical mostly
  50 ACK
  51 ACK


All of these remaining patches are now pushed, all tied to BZ 638510.

There's certainly more work that can be done for snapshot improvements, 
but I'm feeling pretty good about the current state of things for the 
purposes of making the 0.9.5 release candidate build.  And while I won't 
be online much this week, I will definitely make it a priority to 
respond to any regression reports on the times that I am online.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

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


Re: [libvirt] [PATCH] conf: Assign newDef of active domain as persistent conf if it is NULL

2011-09-05 Thread Osier Yang
于 2011年09月01日 21:44, Osier Yang 写道:
 Libvirt loads the domain conf from status XML if it's running when
 starting up. The problem is there is no record of the original conf.
 (dom-newDef is NULL here).

 So libvirt won't be able to restore the domain conf to original one
 when destroying/shutdown. E.g.

 1) attach a device without --persistent
 2) restart libvirtd
 3) destroy domain
 4) start domain

 One will see the the disk still exists.

 This patch is to fix the peoblem by assigning persistent domain conf
 to dom-newDef if it's NULL and the domain is running.
 ---
  src/conf/domain_conf.c |8 +++-
  1 files changed, 7 insertions(+), 1 deletions(-)

 diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
 index 00212db..cbb99d3 100644
 --- a/src/conf/domain_conf.c
 +++ b/src/conf/domain_conf.c
 @@ -10533,9 +10533,15 @@ static virDomainObjPtr 
 virDomainLoadConfig(virCapsPtr caps,
  if ((dom = virDomainFindByUUID(doms, def-uuid))) {
  dom-autostart = autostart;
  
 +if (virDomainObjIsActive(dom) 
 +!dom-newDef) {
 +virDomainObjAssignDef(dom, def, false);
 +} else {
 +virDomainDefFree(def);
 +}
 +
  VIR_FREE(configFile);
  VIR_FREE(autostartLink);
 -virDomainDefFree(def);
  return dom;
  }
  

With my testing, this patch solve the problem well. Could
someone review/ACK this? Thanks

Osier

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

[libvirt] [PATCH 2/2] XML: Suppress printing domain.xml for parse errors on XML strings

2011-09-05 Thread Peter Krempa
Patch e81778d6184f1850a10eb661eb756b50421d5ac4 introduces printing
file name on XML errors. This corrects the URL string to be NULL and
therefore to print an error message not containing bogus filename
domain.xml.

NULL is a valid parameter for the file name value, as the only usage is
for error handlers. Functions touching the value either in libxml2 or in
libvirt check this parameter for NULL and behave according to it.
---
 src/conf/domain_conf.c|2 +-
 src/security/virt-aa-helper.c |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cce9955..06baaaf 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7367,7 +7367,7 @@ virDomainDefParse(const char *xmlStr,
 xmlDocPtr xml;
 virDomainDefPtr def = NULL;

-if ((xml = virXMLParse(filename, xmlStr, domain.xml))) {
+if ((xml = virXMLParse(filename, xmlStr, NULL))) {
 def = virDomainDefParseNode(caps, xml, xmlDocGetRootElement(xml),
 expectedVirtTypes, flags);
 xmlFreeDoc(xml);
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index bb577d3..1de2f77 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -641,7 +641,7 @@ caps_mockup(vahControl * ctl, const char *xmlStr)
 xmlDocPtr xml = NULL;
 xmlXPathContextPtr ctxt = NULL;

-if (!(xml = virXMLParseStringCtxt(xmlStr, domain.xml, ctxt))) {
+if (!(xml = virXMLParseStringCtxt(xmlStr, NULL, ctxt))) {
 goto cleanup;
 }

-- 
1.7.3.4

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


[libvirt] [PATCH] redirdev: allows to specify device address

2011-09-05 Thread Marc-André Lureau
It is important to be able to attach USB redirected devices to a
particular controller (one that supports USB2 for instance).
Without this patch, only the default bus was used.

 redirdev bus='usb' type='spicevmc'
   address type='usb' bus='0' port='4'/
 /redirdev
---
 docs/formatdomain.html.in  |   19 +--
 docs/schemas/domaincommon.rng  |3 +++
 src/conf/domain_conf.c |   14 ++
 tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args |2 +-
 tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml  |1 +
 5 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index b960381..399388f 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1417,14 +1417,21 @@
 tunnel; codetype='tcp'/code
 or codetype='spicevmc'/code (which uses the usbredir
 channel of a a href=#elementsGraphicsSPICE graphics
-device/a) are typical.  Further sub-elements, such
-as codelt;sourcegt;/code, may be required according to
-the given type, although a codelt;targetgt;/code
-sub-element is not required (since the consumer of the
-character device is the hypervisor itself, rather than a
-device visible in the guest)./dd
+device/a) are typical./dd
 
 /dl
+p
+  The redirdev element has an optional sub-element
+  codelt;addressgt;/code which can tie the device to a
+  particular controller.
+/p
+p
+  Further sub-elements, such as codelt;sourcegt;/code, may
+  be required according to the given type, although
+  a codelt;targetgt;/code sub-element is not required (since
+  the consumer of the character device is the hypervisor itself,
+  rather than a device visible in the guest).
+/p
 
 h4a name=elementsSmartcardSmartcard devices/a/h4
 
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 8e7fd63..02c3c7f 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1986,6 +1986,9 @@
 ref name=qemucdevSrcTypeChoice/
   /attribute
   ref name=qemucdevSrcDef/
+  optional
+ref name=address/
+  /optional
 /element
   /define
   define name=hostdev
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cce9955..706f445 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5518,6 +5518,18 @@ virDomainRedirdevDefParseXML(const xmlNodePtr node,
 def-source.chr.data.spicevmc = VIR_DOMAIN_CHR_SPICEVMC_USBREDIR;
 }
 
+if (virDomainDeviceInfoParseXML(node, def-info, flags)  0)
+goto error;
+
+if (def-bus == VIR_DOMAIN_REDIRDEV_BUS_USB 
+def-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE 
+def-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
+virDomainReportError(VIR_ERR_XML_ERROR, %s,
+ _(Invalid address for a USB device));
+goto error;
+}
+
+
 cleanup:
 VIR_FREE(bus);
 VIR_FREE(type);
@@ -10274,6 +10286,8 @@ virDomainRedirdevDefFormat(virBufferPtr buf,
 virBufferAsprintf(buf, redirdev bus='%s', bus);
 if (virDomainChrSourceDefFormat(buf, def-source.chr, false, flags)  0)
 return -1;
+if (virDomainDeviceInfoFormat(buf, def-info, flags)  0)
+return -1;
 virBufferAddLit(buf, /redirdev\n);
 
 return 0;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args 
b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
index 4d4f30a..f6270d5 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
@@ -6,5 +6,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test 
/usr/bin/qemu -S -M pc
 -chardev socket,id=charredir0,host=localhost,port=4000 \
 -device usb-redir,chardev=charredir0,id=redir0 \
 -chardev spicevmc,id=charredir1,name=usbredir \
--device usb-redir,chardev=charredir1,id=redir1 \
+-device usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=4 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml 
b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
index c73e569..1dac3fb 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
@@ -34,6 +34,7 @@
   protocol type='raw'/
 /redirdev
 redirdev bus='usb' type='spicevmc'
+  address type='usb' bus='0' port='4'/
 /redirdev
 memballoon model='virtio'/
   /devices
-- 
1.7.6

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


[libvirt] [PATCH v3 1/5] link-state: util: Add equality comparision functions for structures

2011-09-05 Thread Peter Krempa
This patch adds functions to compare structures containing network
device configuration for equality. They serve for the purpose of
disallowing unsupported changes to live network devices.
---
 src/util/network.c |   62 
 src/util/network.h |5 
 2 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/src/util/network.c b/src/util/network.c
index 6fcdab2..ee69557 100644
--- a/src/util/network.c
+++ b/src/util/network.c
@@ -842,6 +842,43 @@ error:
 return ret;
 }

+bool
+virVirtualPortProfileEqual(virVirtualPortProfileParamsPtr a, 
virVirtualPortProfileParamsPtr b)
+{
+/* NULL resistant */
+if (!a  !b)
+return true;
+
+if (!a || !b)
+return false;
+
+if (a-virtPortType != b-virtPortType)
+return false;
+
+switch (a-virtPortType) {
+case VIR_VIRTUALPORT_NONE:
+break;
+
+case VIR_VIRTUALPORT_8021QBG:
+if (a-u.virtPort8021Qbg.managerID != b-u.virtPort8021Qbg.managerID ||
+a-u.virtPort8021Qbg.typeID != b-u.virtPort8021Qbg.typeID ||
+a-u.virtPort8021Qbg.typeIDVersion != 
b-u.virtPort8021Qbg.typeIDVersion ||
+memcmp(a-u.virtPort8021Qbg.instanceID, 
b-u.virtPort8021Qbg.instanceID, VIR_UUID_BUFLEN) != 0)
+return false;
+break;
+
+case VIR_VIRTUALPORT_8021QBH:
+if (STRNEQ(a-u.virtPort8021Qbh.profileID, 
b-u.virtPort8021Qbh.profileID))
+return false;
+break;
+
+default:
+break;
+}
+
+return true;
+}
+
 void
 virVirtualPortProfileFormat(virBufferPtr buf,
 virVirtualPortProfileParamsPtr virtPort,
@@ -1321,3 +1358,28 @@ cleanup:
 }
 return ret;
 }
+
+bool
+virBandwidthEqual(virBandwidthPtr a,
+  virBandwidthPtr b)
+{
+if (!a  !b)
+return true;
+
+if (!a || !b)
+return false;
+
+/* in */
+if (a-in-average != b-in-average ||
+a-in-peak != b-in-peak ||
+a-in-burst != b-in-burst)
+return false;
+
+/*out*/
+if (a-out-average != b-out-average ||
+a-out-peak != b-out-peak ||
+a-out-burst != b-out-burst)
+return false;
+
+return true;
+}
diff --git a/src/util/network.h b/src/util/network.h
index 6ceaa6d..4d195af 100644
--- a/src/util/network.h
+++ b/src/util/network.h
@@ -150,6 +150,8 @@ virVirtualPortProfileFormat(virBufferPtr buf,
 virVirtualPortProfileParamsPtr virtPort,
 const char *indent);

+bool virVirtualPortProfileEqual(virVirtualPortProfileParamsPtr a, 
virVirtualPortProfileParamsPtr b);
+
 virBandwidthPtr virBandwidthDefParseNode(xmlNodePtr node);
 void virBandwidthDefFree(virBandwidthPtr def);
 int virBandwidthDefFormat(virBufferPtr buf,
@@ -160,4 +162,7 @@ int virBandwidthEnable(virBandwidthPtr bandwidth, const 
char *iface);
 int virBandwidthDisable(const char *iface, bool may_fail);
 int virBandwidthCopy(virBandwidthPtr *dest, const virBandwidthPtr src);

+bool virBandwidthEqual(virBandwidthPtr a, virBandwidthPtr b);
+
+
 #endif /* __VIR_NETWORK_H__ */
-- 
1.7.3.4

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


Re: [libvirt] [PATCH v4] daemon: Create priority workers pool

2011-09-05 Thread Daniel Veillard
On Mon, Sep 05, 2011 at 02:36:13PM +0200, Michal Privoznik wrote:
 This patch annotates APIs with low or high priority.
 In low set MUST be all APIs which might eventually access monitor
 (and thus block indefinitely). Other APIs may be marked as high
 priority. However, some must be (e.g. domainDestroy).
 
 For high priority calls (HPC), there are some high priority workers
 (HPW) created in the pool. HPW can execute only HPC, although normal
 worker can process any call regardless priority. Therefore, only those
 APIs which are guaranteed to end in reasonable small amount of time
 can be marked as HPC.
 
 The size of this HPC pool is static, because HPC are expected to end
 quickly, therefore jobs assigned to this pool will be served quickly.
 It can be configured in libvirtd.conf via prio_workers variable.
 Default is set to 5.
 
 To mark API with low or high priority, append priority:{low|high} to
 it's comment in src/remote/remote_protocol.x. This is similar to
 autogen|skipgen. If not marked, the generator assumes low as default.
 ---
 diff to v3:
 -make 'priority:low' as default which can be left out
 -rearrange some APIs to be HPC or LPC
 
  daemon/libvirtd.aug   |1 +
  daemon/libvirtd.c |7 +
  daemon/libvirtd.conf  |6 +
  src/qemu/qemu_driver.c|2 +-
  src/qemu/qemu_process.c   |2 +-
  src/remote/qemu_protocol.x|   13 ++-
  src/remote/remote_protocol.x  |  294 
 +
  src/rpc/gendispatch.pl|   20 +++-
  src/rpc/virnetserver.c|   60 +
  src/rpc/virnetserver.h|1 +
  src/rpc/virnetserverprogram.c |   11 ++
  src/rpc/virnetserverprogram.h |4 +
  src/util/threadpool.c |  158 +++
  src/util/threadpool.h |4 +-
  14 files changed, 382 insertions(+), 201 deletions(-)
 
 diff --git a/daemon/libvirtd.aug b/daemon/libvirtd.aug
 index 3f47ebb..ce00db5 100644
 --- a/daemon/libvirtd.aug
 +++ b/daemon/libvirtd.aug
 @@ -57,6 +57,7 @@ module Libvirtd =
  | int_entry max_clients
  | int_entry max_requests
  | int_entry max_client_requests
 +| int_entry prio_workers
  
 let logging_entry = int_entry log_level
   | str_entry log_filters
 diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
 index 423c3d7..7b445a2 100644
 --- a/daemon/libvirtd.c
 +++ b/daemon/libvirtd.c
 @@ -134,6 +134,8 @@ struct daemonConfig {
  int max_workers;
  int max_clients;
  
 +int prio_workers;
 +
  int max_requests;
  int max_client_requests;
  
 @@ -886,6 +888,8 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
  data-max_workers = 20;
  data-max_clients = 20;
  
 +data-prio_workers = 5;
 +
  data-max_requests = 20;
  data-max_client_requests = 5;
  
 @@ -1042,6 +1046,8 @@ daemonConfigLoad(struct daemonConfig *data,
  GET_CONF_INT (conf, filename, max_workers);
  GET_CONF_INT (conf, filename, max_clients);
  
 +GET_CONF_INT (conf, filename, prio_workers);
 +
  GET_CONF_INT (conf, filename, max_requests);
  GET_CONF_INT (conf, filename, max_client_requests);
  
 @@ -1430,6 +1436,7 @@ int main(int argc, char **argv) {
  config-auth_unix_ro == REMOTE_AUTH_POLKIT;
  if (!(srv = virNetServerNew(config-min_workers,
  config-max_workers,
 +config-prio_workers,
  config-max_clients,
  config-mdns_adv ? config-mdns_name : NULL,
  use_polkit_dbus,
 diff --git a/daemon/libvirtd.conf b/daemon/libvirtd.conf
 index 95e43dd..da3983e 100644
 --- a/daemon/libvirtd.conf
 +++ b/daemon/libvirtd.conf
 @@ -257,6 +257,12 @@
  #min_workers = 5
  #max_workers = 20
  
 +
 +# The number of priority workers. If all workers from above
 +# pool will stuck, some calls marked as high priority
 +# (notably domainDestroy) can be executed in this pool.
 +#prio_workers = 5
 +
  # Total global limit on concurrent RPC calls. Should be
  # at least as large as max_workers. Beyond this, RPC requests
  # will be read into memory and queued. This directly impact
 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index f21122d..b26a0cb 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -656,7 +656,7 @@ qemudStartup(int privileged) {
  virHashForEach(qemu_driver-domains.objs, qemuDomainSnapshotLoad,
 qemu_driver-snapshotDir);
  
 -qemu_driver-workerPool = virThreadPoolNew(0, 1, processWatchdogEvent, 
 qemu_driver);
 +qemu_driver-workerPool = virThreadPoolNew(0, 1, 0, 
 processWatchdogEvent, qemu_driver);
  if (!qemu_driver-workerPool)
  goto error;
  
 diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
 index 58b4d36..878805a 100644
 --- a/src/qemu/qemu_process.c
 +++ 

[libvirt] [PATCH v3 4/5] link-state: qemu: Add net intf modification to virUpdateDeviceFlags

2011-09-05 Thread Peter Krempa
This patch enables modifying network device configuration using the
virUpdateDeviceFlags API method. Matching of devices is accomplished
using MAC addresses.

While updating live configuration of a running domain, the user is
allowed only to change link state of the interface. Additional
modifications may be added later. For now the code checks for
unsupported changes and tereafer changes the link state, if applicable.

When updating persistent configuration of guest's network interface the
whole configuration (except for the MAC address) may be modified and
is stored for the next startup.

  src/qemu/qemu_driver.c   - Add dispatching of virUpdateDevice for
 network devices update (live/config)
  src/qemu/qemu_hotplug.c  - add setting of initial link state on live
 device addition
   - add function to change network device
 configuration. By now it supports only
 changing of link state
  src/qemu/qemu_hotplug.h  - Headers to above functions
  src/qemu/qemu_process.c  - set link states before virtual machine
 start. Qemu does not support setting of
 this on the command line.
---
 src/qemu/qemu_driver.c  |   24 +++
 src/qemu/qemu_hotplug.c |  176 +++
 src/qemu/qemu_hotplug.h |8 ++
 src/qemu/qemu_process.c |   47 -
 4 files changed, 254 insertions(+), 1 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7028d72..648afae 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5474,6 +5474,9 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm,
 case VIR_DOMAIN_DEVICE_GRAPHICS:
 ret = qemuDomainChangeGraphics(driver, vm, dev-data.graphics);
 break;
+case VIR_DOMAIN_DEVICE_NET:
+ret = qemuDomainChangeNet(driver, vm, dom, dev-data.net);
+break;
 default:
 qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 _(device type '%s' cannot be updated),
@@ -5608,6 +5611,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
  virDomainDeviceDefPtr dev)
 {
 virDomainDiskDefPtr orig, disk;
+virDomainNetDefPtr net;
 int pos;

 switch (dev-type) {
@@ -5646,6 +5650,26 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
 }
 disk-src = NULL;
 break;
+
+case VIR_DOMAIN_DEVICE_NET:
+net = dev-data.net;
+if ((pos = virDomainNetIndexByMac(vmdef, net-mac))  0) {
+char macbuf[VIR_MAC_STRING_BUFLEN];
+virFormatMacAddr(net-mac, macbuf);
+qemuReportError(VIR_ERR_INVALID_ARG,
+_(mac %s doesn't exist), macbuf);
+return -1;
+}
+
+VIR_FREE(vmdef-nets[pos]);
+
+vmdef-nets[pos] = net;
+dev-data.net = NULL;
+
+if (qemuDomainAssignPCIAddresses(vmdef)  0)
+return -1;
+break;
+
 default:
 qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s,
  _(persistent update of device is not supported));
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 6ae834c..ad57b2f 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -751,6 +751,30 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
 }
 qemuDomainObjExitMonitorWithDriver(driver, vm);

+/* set link state */
+if (net-linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) {
+if (!net-info.alias) {
+qemuReportError(VIR_ERR_OPERATION_FAILED,
+_(device alias not found: cannot set link state 
to down));
+} else {
+qemuDomainObjEnterMonitorWithDriver(driver, vm);
+
+if (qemuCapsGet(priv-qemuCaps, QEMU_CAPS_NETDEV)) {
+if (qemuMonitorSetLink(priv-mon, net-info.alias, 
VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN)  0) {
+qemuDomainObjExitMonitorWithDriver(driver, vm);
+virDomainAuditNet(vm, NULL, net, attach, false);
+goto try_remove;
+}
+} else {
+qemuReportError(VIR_ERR_OPERATION_FAILED,
+_(setting of link state not supported: Link 
is up));
+}
+
+qemuDomainObjExitMonitorWithDriver(driver, vm);
+}
+/* link set to down */
+}
+
 virDomainAuditNet(vm, NULL, net, attach, true);

 ret = 0;
@@ -1082,6 +1106,158 @@ error:
 return -1;
 }

+static virDomainNetDefPtr qemuDomainFindNet(virDomainObjPtr vm,
+virDomainNetDefPtr dev)
+{
+int i;
+
+for (i = 0; i  vm-def-nnets; i++) {
+if (memcmp(vm-def-nets[i]-mac, dev-mac, VIR_MAC_BUFLEN) == 0)
+return vm-def-nets[i];
+}
+
+return NULL;
+}
+
+int 

Re: [libvirt] [PATCH 2/2] XML: Suppress printing domain.xml for parse errors on XML strings

2011-09-05 Thread Peter Krempa

On 09/05/2011 05:02 PM, Eric Blake wrote:

On 09/05/2011 06:33 AM, Peter Krempa wrote:

Patch e81778d6184f1850a10eb661eb756b50421d5ac4 introduces printing
file name on XML errors. This corrects the URL string to be NULL and
therefore to print an error message not containing bogus filename
domain.xml.

NULL is a valid parameter for the file name value, as the only usage is
for error handlers. Functions touching the value either in libxml2 or in
libvirt check this parameter for NULL and behave according to it.
---
  src/conf/domain_conf.c|2 +-
  src/security/virt-aa-helper.c |2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)


I still think a lot of the virXMLParseStringCtxt() calls in virsh.c 
need the same treatment.



Uhm, yes. You're right. I forgot about that.

I'll post another patch to this series.

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


[libvirt] [PATCH v3 0/5] Virtual interface link state modification

2011-09-05 Thread Peter Krempa
This patchset adds the ability for libvirt users to control interface
link state of the virtual network devices provided by hypervisors.

Modification of the link state is accomplished by adding a new XML
element link stateup or down to the domain XML. The corresponding
network interface is thereafter initialised with the desired state.

Live modification of the link state is achieved by calling
virDomainUpdateDeviceFlags containing a modified interface configuration.
Yet, users may modify only link state of an interface.

This feature allows propagation of network topology changes to guests,
testing scenarios in complex virtual networks, etc ...

Future upgrade:
- add support for VirtualBox

Modifications to v2:
- Rebase to curent HEAD

Modifications to v1:
- use virUpdateDeviceFlags instead of dedicated API
- incorporate helpful comments by Eric Blake

https://bugzilla.redhat.com/show_bug.cgi?id=643373

Peter Krempa (5):
  link-state: util: Add equality comparision functions for structures
  link-state: conf: Add element to XML for controling link state
  link-state: qemu: Add monitor handling for link state modification
  link-state: qemu: Add net intf modification to virUpdateDeviceFlags
  link-state: virsh: Add wrapper commands for changing link state

 docs/formatdomain.html.in|   21 +++
 docs/schemas/network.rng |   11 ++
 src/conf/domain_conf.c   |   24 
 src/conf/domain_conf.h   |   11 ++
 src/qemu/qemu_driver.c   |   24 
 src/qemu/qemu_hotplug.c  |  176 ++
 src/qemu/qemu_hotplug.h  |8 ++
 src/qemu/qemu_monitor.c  |   19 +++
 src/qemu/qemu_monitor.h  |4 +
 src/qemu/qemu_monitor_json.c |   23 
 src/qemu/qemu_monitor_json.h |4 +
 src/qemu/qemu_monitor_text.c |   46 +++
 src/qemu/qemu_monitor_text.h |4 +
 src/qemu/qemu_process.c  |   47 +++-
 src/util/network.c   |   62 +
 src/util/network.h   |5 +
 tools/virsh.c|  286 ++
 tools/virsh.pod  |   11 ++
 18 files changed, 785 insertions(+), 1 deletions(-)

-- 
1.7.3.4

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


Re: [libvirt] [PATCH 2/2] XML: Suppress printing domain.xml for parse errors on XML strings

2011-09-05 Thread Eric Blake

On 09/05/2011 06:33 AM, Peter Krempa wrote:

Patch e81778d6184f1850a10eb661eb756b50421d5ac4 introduces printing
file name on XML errors. This corrects the URL string to be NULL and
therefore to print an error message not containing bogus filename
domain.xml.

NULL is a valid parameter for the file name value, as the only usage is
for error handlers. Functions touching the value either in libxml2 or in
libvirt check this parameter for NULL and behave according to it.
---
  src/conf/domain_conf.c|2 +-
  src/security/virt-aa-helper.c |2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)


I still think a lot of the virXMLParseStringCtxt() calls in virsh.c need 
the same treatment.


--
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org

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


[libvirt] [PATCH v2] virsh: Add more human-friendly output of domblkstat command

2011-09-05 Thread Peter Krempa
Users of virsh complain that output of the domblkstat command
is not intuitive enough. This patch adds explanation of fields
returned by this command to the help section for domblkstat and
the man page of virsh. Also a switch --human is added for
domblkstat that prints the fields with more descriptive texts.

https://bugzilla.redhat.com/show_bug.cgi?id=731656

Changes to v1:
-Rebased to current head
---
 tools/virsh.c   |   52 +---
 tools/virsh.pod |   11 ++-
 2 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index c7240e5..09337cb 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1054,13 +1054,21 @@ cleanup:
  */
 static const vshCmdInfo info_domblkstat[] = {
 {help, N_(get device block stats for a domain)},
-{desc, N_(Get device block stats for a running domain.)},
+{desc, N_(Get device block stats for a running domain.\n\n
+Explanation of fields:\n
+  rd_req   - count of read requests\n
+  rd_bytes - count of read bytes\n
+  wr_req   - count of write requests\n
+  wr_bytes - count of written bytes\n
+  errs - error count)},
 {NULL,NULL}
 };

 static const vshCmdOptDef opts_domblkstat[] = {
 {domain, VSH_OT_DATA, VSH_OFLAG_REQ, N_(domain name, id or uuid)},
 {device, VSH_OT_DATA, VSH_OFLAG_REQ, N_(block device)},
+{human,  VSH_OT_BOOL, 0, N_(print a more human readable output)},
+
 {NULL, 0, 0, NULL}
 };

@@ -1070,6 +1078,7 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd)
 virDomainPtr dom;
 const char *name = NULL, *device = NULL;
 struct _virDomainBlockStats stats;
+int humanReadable = vshCommandOptBool(cmd, human);

 if (!vshConnectionUsability (ctl, ctl-conn))
 return false;
@@ -1088,20 +1097,41 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd)
 return false;
 }

-if (stats.rd_req = 0)
-vshPrint (ctl, %s rd_req %lld\n, device, stats.rd_req);
+if (humanReadable) {
+/* human friendly output */
+vshPrint(ctl, N_(Device: %s\n), device);
+
+if (stats.rd_req = 0)
+vshPrint (ctl, N_(read request count:  %lld\n),  
stats.rd_req);
+
+if (stats.rd_bytes = 0)
+vshPrint (ctl, N_(number of read bytes:%lld\n), 
stats.rd_bytes);
+
+if (stats.wr_req = 0)
+vshPrint (ctl, N_(write request count: %lld\n), 
stats.wr_req);

-if (stats.rd_bytes = 0)
-vshPrint (ctl, %s rd_bytes %lld\n, device, stats.rd_bytes);
+if (stats.wr_bytes = 0)
+vshPrint (ctl, N_(number of written bytes: %lld\n), 
stats.wr_bytes);

-if (stats.wr_req = 0)
-vshPrint (ctl, %s wr_req %lld\n, device, stats.wr_req);
+if (stats.errs = 0)
+vshPrint (ctl, N_(error count: %lld\n), stats.errs);
+} else {
+/* script friendly output */
+if (stats.rd_req = 0)
+vshPrint (ctl, %s rd_req %lld\n, device, stats.rd_req);
+
+if (stats.rd_bytes = 0)
+vshPrint (ctl, %s rd_bytes %lld\n, device, stats.rd_bytes);

-if (stats.wr_bytes = 0)
-vshPrint (ctl, %s wr_bytes %lld\n, device, stats.wr_bytes);
+if (stats.wr_req = 0)
+vshPrint (ctl, %s wr_req %lld\n, device, stats.wr_req);

-if (stats.errs = 0)
-vshPrint (ctl, %s errs %lld\n, device, stats.errs);
+if (stats.wr_bytes = 0)
+vshPrint (ctl, %s wr_bytes %lld\n, device, stats.wr_bytes);
+
+if (stats.errs = 0)
+vshPrint (ctl, %s errs %lld\n, device, stats.errs);
+}

 virDomainFree(dom);
 return true;
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 30c0721..c333b2a 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -501,10 +501,19 @@ be lost once the guest stops running, but the snapshot 
contents still
 exist, and a new domain with the same name and UUID can restore the
 snapshot metadata with Bsnapshot-create.

-=item Bdomblkstat Idomain Iblock-device
+=item Bdomblkstat Idomain Iblock-device [I--human]

 Get device block stats for a running domain.

+Use I--human for a more human readable output.
+
+BExplanation of fields:
+  rd_req   - count of read requests
+  rd_bytes - count of read bytes
+  wr_req   - count of write requests
+  wr_bytes - count of written bytes
+  errs - error count
+
 =item Bdomifstat Idomain Iinterface-device

 Get network interface stats for a running domain.
-- 
1.7.3.4

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


Re: [libvirt] [PATCH v4] daemon: Create priority workers pool

2011-09-05 Thread Michal Privoznik
On 05.09.2011 17:00, Daniel Veillard wrote:
 On Mon, Sep 05, 2011 at 02:36:13PM +0200, Michal Privoznik wrote:
 This patch annotates APIs with low or high priority.
 In low set MUST be all APIs which might eventually access monitor
 (and thus block indefinitely). Other APIs may be marked as high
 priority. However, some must be (e.g. domainDestroy).

 For high priority calls (HPC), there are some high priority workers
 (HPW) created in the pool. HPW can execute only HPC, although normal
 worker can process any call regardless priority. Therefore, only those
 APIs which are guaranteed to end in reasonable small amount of time
 can be marked as HPC.

 The size of this HPC pool is static, because HPC are expected to end
 quickly, therefore jobs assigned to this pool will be served quickly.
 It can be configured in libvirtd.conf via prio_workers variable.
 Default is set to 5.

 To mark API with low or high priority, append priority:{low|high} to
 it's comment in src/remote/remote_protocol.x. This is similar to
 autogen|skipgen. If not marked, the generator assumes low as default.
 ---
 diff to v3:
 -make 'priority:low' as default which can be left out
 -rearrange some APIs to be HPC or LPC

  daemon/libvirtd.aug   |1 +
  daemon/libvirtd.c |7 +
  daemon/libvirtd.conf  |6 +
  src/qemu/qemu_driver.c|2 +-
  src/qemu/qemu_process.c   |2 +-
  src/remote/qemu_protocol.x|   13 ++-
  src/remote/remote_protocol.x  |  294 
 +
  src/rpc/gendispatch.pl|   20 +++-
  src/rpc/virnetserver.c|   60 +
  src/rpc/virnetserver.h|1 +
  src/rpc/virnetserverprogram.c |   11 ++
  src/rpc/virnetserverprogram.h |4 +
  src/util/threadpool.c |  158 +++
  src/util/threadpool.h |4 +-
  14 files changed, 382 insertions(+), 201 deletions(-)

 diff --git a/daemon/libvirtd.aug b/daemon/libvirtd.aug
 index 3f47ebb..ce00db5 100644
 --- a/daemon/libvirtd.aug
 +++ b/daemon/libvirtd.aug
 @@ -57,6 +57,7 @@ module Libvirtd =
  | int_entry max_clients
  | int_entry max_requests
  | int_entry max_client_requests
 +| int_entry prio_workers
  
 let logging_entry = int_entry log_level
   | str_entry log_filters
 diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
 index 423c3d7..7b445a2 100644
 --- a/daemon/libvirtd.c
 +++ b/daemon/libvirtd.c
 @@ -134,6 +134,8 @@ struct daemonConfig {
  int max_workers;
  int max_clients;
  
 +int prio_workers;
 +
  int max_requests;
  int max_client_requests;
  
 @@ -886,6 +888,8 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
  data-max_workers = 20;
  data-max_clients = 20;
  
 +data-prio_workers = 5;
 +
  data-max_requests = 20;
  data-max_client_requests = 5;
  
 @@ -1042,6 +1046,8 @@ daemonConfigLoad(struct daemonConfig *data,
  GET_CONF_INT (conf, filename, max_workers);
  GET_CONF_INT (conf, filename, max_clients);
  
 +GET_CONF_INT (conf, filename, prio_workers);
 +
  GET_CONF_INT (conf, filename, max_requests);
  GET_CONF_INT (conf, filename, max_client_requests);
  
 @@ -1430,6 +1436,7 @@ int main(int argc, char **argv) {
  config-auth_unix_ro == REMOTE_AUTH_POLKIT;
  if (!(srv = virNetServerNew(config-min_workers,
  config-max_workers,
 +config-prio_workers,
  config-max_clients,
  config-mdns_adv ? config-mdns_name : NULL,
  use_polkit_dbus,
 diff --git a/daemon/libvirtd.conf b/daemon/libvirtd.conf
 index 95e43dd..da3983e 100644
 --- a/daemon/libvirtd.conf
 +++ b/daemon/libvirtd.conf
 @@ -257,6 +257,12 @@
  #min_workers = 5
  #max_workers = 20
  
 +
 +# The number of priority workers. If all workers from above
 +# pool will stuck, some calls marked as high priority
 +# (notably domainDestroy) can be executed in this pool.
 +#prio_workers = 5
 +
  # Total global limit on concurrent RPC calls. Should be
  # at least as large as max_workers. Beyond this, RPC requests
  # will be read into memory and queued. This directly impact
 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index f21122d..b26a0cb 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -656,7 +656,7 @@ qemudStartup(int privileged) {
  virHashForEach(qemu_driver-domains.objs, qemuDomainSnapshotLoad,
 qemu_driver-snapshotDir);
  
 -qemu_driver-workerPool = virThreadPoolNew(0, 1, processWatchdogEvent, 
 qemu_driver);
 +qemu_driver-workerPool = virThreadPoolNew(0, 1, 0, 
 processWatchdogEvent, qemu_driver);
  if (!qemu_driver-workerPool)
  goto error;
  
 diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
 index 58b4d36..878805a 

[libvirt] [PATCH v3 2/5] link-state: conf: Add element to XML for controling link state

2011-09-05 Thread Peter Krempa
A new element is introduced to XML that allows to control
state of virtual network interfaces in hypervisors.

Live modification of the link state allows networking tools
propagate topology changes to guest OS or testing of
scenarios in complex (virtual) networks.

This patch adds elements to XML grammars and parsing and generating
code.

 docs/formatdomain.html.in  - Documentation of new element
 docs/schemas/network.rng   - Grammar for the new element
 src/conf/domain_conf.c - Parsing and generating code
 src/conf/domain_conf.h - Enum of available link states
---
 docs/formatdomain.html.in |   21 +
 docs/schemas/network.rng  |   11 +++
 src/conf/domain_conf.c|   24 
 src/conf/domain_conf.h|   11 +++
 4 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index b960381..53de6c8 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2092,6 +2092,27 @@ qemu-kvm -net nic,model=? /dev/null
   span class=sinceSince 0.9.4/span
 /p

+h5a name=elementLinkModyfing virtual link state/a/h5
+pre
+  ...
+  lt;devicesgt;
+lt;interface type='network'gt;
+  lt;source network='default'/gt;
+  lt;target dev='vnet0'/gt;
+  blt;link state='down'/gt;/b
+lt;/interfacegt;
+  lt;devicesgt;
+  .../pre
+
+p
+  This element provides means of setting state of the virtual network link.
+  Possible values for attribute codestate/code are codeup/code and
+  codedown/code. If codedown/code is specified as the value, the 
interface
+  behaves as if it had the network cable disconnected. Default behavior if 
this
+  element is unspecified is to have the link state codeup/code.
+  span class=sinceSince 0.9.5/span
+/p
+
 h4a name=elementsInputInput devices/a/h4

 p
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 1c44471..937e180 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -150,6 +150,17 @@
optional
  ref name=bandwidth/
/optional
+   optional
+ element name=link
+   attribute name=state
+ choice
+   valueup/value
+   valuedown/value
+ /choice
+   /attribute
+   empty/
+ /element
+/optional

 !-- ip element --
 zeroOrMore
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cce9955..75431fb 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -251,6 +251,11 @@ VIR_ENUM_IMPL(virDomainNetVirtioTxMode, 
VIR_DOMAIN_NET_VIRTIO_TX_MODE_LAST,
   iothread,
   timer)

+VIR_ENUM_IMPL(virDomainNetInterfaceLinkState, 
VIR_DOMAIN_NET_INTERFACE_LINK_STATE_LAST,
+  default,
+  up,
+  down)
+
 VIR_ENUM_IMPL(virDomainChrChannelTarget,
   VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST,
   guestfwd,
@@ -2945,6 +2950,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
 char *internal = NULL;
 char *devaddr = NULL;
 char *mode = NULL;
+char *linkstate = NULL;
 virNWFilterHashTablePtr filterparams = NULL;
 virVirtualPortProfileParamsPtr virtPort = NULL;
 virDomainActualNetDefPtr actual = NULL;
@@ -3021,6 +3027,9 @@ virDomainNetDefParseXML(virCapsPtr caps,
 /* An auto-generated target name, blank it out */
 VIR_FREE(ifname);
 }
+} else if ((linkstate == NULL) 
+   xmlStrEqual(cur-name, BAD_CAST link)) {
+linkstate = virXMLPropString(cur, state);
 } else if ((script == NULL) 
(def-type == VIR_DOMAIN_NET_TYPE_ETHERNET ||
 def-type == VIR_DOMAIN_NET_TYPE_BRIDGE) 
@@ -3285,6 +3294,16 @@ virDomainNetDefParseXML(virCapsPtr caps,
 }
 }

+def-linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DEFAULT;
+if (linkstate != NULL) {
+if ((def-linkstate = 
virDomainNetInterfaceLinkStateTypeFromString(linkstate)) = 0) {
+virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _(unknown interface link state '%s'),
+ linkstate);
+goto error;
+}
+}
+
 if (filter != NULL) {
 switch (def-type) {
 case VIR_DOMAIN_NET_TYPE_ETHERNET:
@@ -3332,6 +3351,7 @@ cleanup:
 VIR_FREE(internal);
 VIR_FREE(devaddr);
 VIR_FREE(mode);
+VIR_FREE(linkstate);
 virNWFilterHashTableFree(filterparams);

 return def;
@@ -9429,6 +9449,10 @@ virDomainNetDefFormat(virBufferPtr buf,
 virBufferAddLit(buf, /tune\n);
 }

+if (def-linkstate)
+virBufferAsprintf(buf,   link state='%s'/\n,
+  
virDomainNetInterfaceLinkStateTypeToString(def-linkstate));
+
 if (virBandwidthDefFormat(buf, 

[libvirt] [PATCH 3/2] virsh: Change domain.xml to NULL in XML parsing of strings

2011-09-05 Thread Peter Krempa
Clean up instances of domain.xml in context of parsing XML documents
in memory to support new XML parse error reporting function.
---
 tools/virsh.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index c7240e5..1b11f79 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -8616,7 +8616,7 @@ makeCloneXML(const char *origxml, const char *newname) {
 xmlChar *newxml = NULL;
 int size;

-doc = virXMLParseStringCtxt(origxml, domain.xml, ctxt);
+doc = virXMLParseStringCtxt(origxml, NULL, ctxt);
 if (!doc)
 goto cleanup;

@@ -10407,7 +10407,7 @@ cmdVNCDisplay(vshControl *ctl, const vshCmd *cmd)
 if (!doc)
 goto cleanup;

-xml = virXMLParseStringCtxt(doc, domain.xml, ctxt);
+xml = virXMLParseStringCtxt(doc, NULL, ctxt);
 VIR_FREE(doc);
 if (!xml)
 goto cleanup;
@@ -10475,7 +10475,7 @@ cmdTTYConsole(vshControl *ctl, const vshCmd *cmd)
 if (!doc)
 goto cleanup;

-xml = virXMLParseStringCtxt(doc, domain.xml, ctxt);
+xml = virXMLParseStringCtxt(doc, NULL, ctxt);
 VIR_FREE(doc);
 if (!xml)
 goto cleanup;
@@ -10862,7 +10862,7 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd)
 if (!doc)
 goto cleanup;

-xml = virXMLParseStringCtxt(doc, domain.xml, ctxt);
+xml = virXMLParseStringCtxt(doc, NULL, ctxt);
 VIR_FREE(doc);
 if (!xml) {
 vshError(ctl, %s, _(Failed to get interface information));
@@ -11329,7 +11329,7 @@ cmdDetachDisk(vshControl *ctl, const vshCmd *cmd)
 if (!doc)
 goto cleanup;

-xml = virXMLParseStringCtxt(doc, domain.xml, ctxt);
+xml = virXMLParseStringCtxt(doc, NULL, ctxt);
 VIR_FREE(doc);
 if (!xml) {
 vshError(ctl, %s, _(Failed to get disk information));
-- 
1.7.3.4

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


[libvirt] [PATCH v3 3/5] link-state: qemu: Add monitor handling for link state modification

2011-09-05 Thread Peter Krempa
This patch adds handlers for modification of guest's interface
link state. Both HMP and QMP commands are supported, but as the
link state functionality is from the beginning supported in QMP
the HMP code will probably never be used.

  src/qemu/qemu_monitor.c- Add command dispatcher
  src/qemu/qemu_monitor.h- Add headar for command
  src/qemu/qemu_monitor_json.c   - Add QMP command handling
  src/qemu/qemu_monitor_json.h   - Add header for command
  src/qemu/qemu_monitor_text.c   - Add HMP command handling
  src/qemu/qemu_monitor_text.h   - Add header for command
---
 src/qemu/qemu_monitor.c  |   19 +
 src/qemu/qemu_monitor.h  |4 +++
 src/qemu/qemu_monitor_json.c |   23 +
 src/qemu/qemu_monitor_json.h |4 +++
 src/qemu/qemu_monitor_text.c |   46 ++
 src/qemu/qemu_monitor_text.h |4 +++
 6 files changed, 100 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index db6107c..5738116 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1135,6 +1135,25 @@ int qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
 return ret;
 }

+int qemuMonitorSetLink(qemuMonitorPtr mon,
+   const char *name,
+   enum virDomainNetInterfaceLinkState state)
+{
+int ret;
+VIR_DEBUG(mon=%p, name=%p:%s, state=%u, mon, name, name, state);
+
+if (!mon || !name) {
+qemuReportError(VIR_ERR_INVALID_ARG,
+_(monitor || name must not be NULL));
+return -1;
+}
+
+if (mon-json)
+ret = qemuMonitorJSONSetLink(mon, name, state);
+else
+ret = qemuMonitorTextSetLink(mon, name, state);
+return ret;
+}

 int qemuMonitorGetVirtType(qemuMonitorPtr mon,
int *virtType)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index f241c9e..cd46608 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -145,6 +145,10 @@ void qemuMonitorUnlock(qemuMonitorPtr mon);
 int qemuMonitorRef(qemuMonitorPtr mon);
 int qemuMonitorUnref(qemuMonitorPtr mon) ATTRIBUTE_RETURN_CHECK;

+int qemuMonitorSetLink(qemuMonitorPtr mon,
+   const char *name,
+   enum virDomainNetInterfaceLinkState state) ;
+
 /* These APIs are for use by the internal Text/JSON monitor impl code only */
 char *qemuMonitorNextCommandID(qemuMonitorPtr mon);
 int qemuMonitorSend(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 4ceb536..c502b72 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -955,6 +955,29 @@ int qemuMonitorJSONSystemPowerdown(qemuMonitorPtr mon)
 return ret;
 }

+int qemuMonitorJSONSetLink(qemuMonitorPtr mon,
+   const char *name,
+   enum virDomainNetInterfaceLinkState state)
+{
+
+int ret;
+virJSONValuePtr reply = NULL;
+virJSONValuePtr cmd = qemuMonitorJSONMakeCommand(set_link,
+ s:name, name,
+ b:up, state != 
VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN,
+ NULL);
+
+if (!cmd)
+return -1;
+
+if ((ret = qemuMonitorJSONCommand(mon, cmd, reply)) == 0)
+ret = qemuMonitorJSONCheckError(cmd, reply);
+
+virJSONValueFree(cmd);
+virJSONValueFree(reply);
+
+return ret;
+}

 int qemuMonitorJSONSystemReset(qemuMonitorPtr mon)
 {
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 9512793..2611b07 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -231,4 +231,8 @@ int qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
 virDomainBlockJobInfoPtr info,
 int mode);

+int qemuMonitorJSONSetLink(qemuMonitorPtr mon,
+   const char *name,
+   enum virDomainNetInterfaceLinkState state);
+
 #endif /* QEMU_MONITOR_JSON_H */
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 854ee7f..0fdc223 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -433,6 +433,52 @@ int qemuMonitorTextSystemPowerdown(qemuMonitorPtr mon) {
 return 0;
 }

+int qemuMonitorTextSetLink(qemuMonitorPtr mon, const char *name, enum 
virDomainNetInterfaceLinkState state) {
+char *info = NULL;
+char *cmd = NULL;
+const char *st_str = NULL;
+
+/* determine state */
+if (state == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN)
+st_str = off;
+else
+st_str = on;
+
+if (virAsprintf(cmd, set_link %s %s, name, st_str)  0) {
+virReportOOMError();
+goto error;
+}
+if (qemuMonitorHMPCommand(mon, cmd, info)  0) {
+qemuReportError(VIR_ERR_OPERATION_FAILED,
+   

[libvirt] [PATCH v3 5/5] link-state: virsh: Add wrapper commands for changing link state

2011-09-05 Thread Peter Krempa
Two new commands are added to virsh that wrap usage of
virDomainUpdateDeviceFlags for changing link state of domain's network
interfaces. These wrappers extract network devices's xml configuration
and modify the link state for easy manipulation from user's perspective.

 * domif-setlink - set link state of a domains virtual network interface
 * domif-getlink - get link state

  tools/virsh.c   - Add functionality to virsh
  tools/virsh.pod - Manpage documentation
---
 tools/virsh.c   |  286 +++
 tools/virsh.pod |   11 ++
 2 files changed, 297 insertions(+), 0 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index c7240e5..dff048a 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1173,6 +1173,290 @@ cmdDomIfstat (vshControl *ctl, const vshCmd *cmd)
 return true;
 }

+/* domif-setlink command
+ */
+static const vshCmdInfo info_domif_setlink[] = {
+{help, N_(set link state of a virtual interface)},
+{desc, N_(Set link state of a domain's virtual interface. This command 
wraps usage of update-device command.)},
+{NULL,NULL}
+};
+
+static const vshCmdOptDef opts_domif_setlink[] = {
+{domain, VSH_OT_DATA, VSH_OFLAG_REQ, N_(domain name, id or uuid)},
+{interface, VSH_OT_DATA, VSH_OFLAG_REQ, N_(interface device (MAC 
Address))},
+{state, VSH_OT_DATA, VSH_OFLAG_REQ, N_(new state of the device)},
+{persistent, VSH_OT_BOOL, 0, N_(persist interface state)},
+{NULL, 0, 0, NULL}
+};
+
+static bool
+cmdDomIfSetLink (vshControl *ctl, const vshCmd *cmd)
+{
+
+virDomainPtr dom;
+const char *interface;
+const char *state;
+const char *mac;
+const char *desc;
+bool persistent;
+bool ret = false;
+unsigned int flags = 0;
+int i;
+
+xmlDocPtr xml = NULL;
+xmlXPathContextPtr ctxt = NULL;
+xmlXPathObjectPtr obj = NULL;
+xmlNodePtr cur = NULL;
+xmlBufferPtr xml_buf = NULL;
+
+
+if (!vshConnectionUsability(ctl, ctl-conn))
+return false;
+
+if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+return false;
+
+if (vshCommandOptString(cmd, interface, interface) = 0)
+goto cleanup;
+
+if (vshCommandOptString(cmd, state, state) = 0)
+goto cleanup;
+
+persistent = vshCommandOptBool(cmd, persistent);
+
+if (STRNEQ(state, up)  STRNEQ(state, down)) {
+vshError(ctl, _(invalid link state '%s'), state);
+goto cleanup;
+}
+
+/* get persistent or live description of network device */
+desc = virDomainGetXMLDesc(dom, persistent?VIR_DOMAIN_XML_INACTIVE:0);
+if (desc == NULL) {
+vshError(ctl, _(Failed to get domain description xml));
+goto cleanup;
+}
+
+if (persistent)
+flags = VIR_DOMAIN_AFFECT_CONFIG;
+else
+flags = VIR_DOMAIN_AFFECT_LIVE;
+
+if (virDomainIsActive(dom) == 0)
+flags = VIR_DOMAIN_AFFECT_CONFIG;
+
+/* extract current network device description */
+xml = virXMLParseStringCtxt(desc, domain configuration, ctxt);
+VIR_FREE(desc);
+if (!xml) {
+vshError(ctl, _(Failed to parse domain description xml));
+goto cleanup;
+}
+
+obj = xmlXPathEval(BAD_CAST /domain/devices/interface, ctxt);
+if (obj == NULL || obj-type != XPATH_NODESET ||
+obj-nodesetval == NULL || obj-nodesetval-nodeNr == 0) {
+vshError(ctl, _(Failed to extract interface information or no 
interfaces found));
+goto cleanup;
+}
+
+/* find interface with matching mac addr */
+for (i = 0; i  obj-nodesetval-nodeNr; i++) {
+cur = obj-nodesetval-nodeTab[i]-children;
+
+while (cur) {
+if (cur-type == XML_ELEMENT_NODE 
+xmlStrEqual(cur-name, BAD_CAST mac)) {
+mac = virXMLPropString(cur, address);
+
+if (STRCASEEQ(mac, interface)) {
+VIR_FREE(mac);
+goto hit;
+}
+VIR_FREE(mac);
+}
+cur = cur-next;
+}
+}
+
+vshError(ctl, _(interface with address '%s' not found), interface);
+goto cleanup;
+
+hit:
+/* find and modify/add link state node */
+/* try to find link element */
+cur = obj-nodesetval-nodeTab[i]-children;
+
+while (cur) {
+if (cur-type == XML_ELEMENT_NODE 
+xmlStrEqual(cur-name, BAD_CAST link)) {
+/* found, just modify the property */
+xmlSetProp(cur, BAD_CAST state, BAD_CAST state);
+
+break;
+}
+cur = cur-next;
+}
+
+if (!cur) {
+/* element link not found, add one */
+cur = xmlNewChild(obj-nodesetval-nodeTab[i],
+  NULL,
+  BAD_CAST link,
+  NULL);
+if (!cur)
+goto cleanup;
+
+if (xmlNewProp(cur, BAD_CAST state, BAD_CAST state) == NULL)
+goto cleanup;
+}
+
+xml_buf = xmlBufferCreate();
+if 

[libvirt] [PATCH] Don't treat pci_system_init failure as fatal if no PCI bus is present

2011-09-05 Thread Soren Hansen
Xen PV domU's have no PCI bus. node_device_udev.c calls pci_system_init
which looks for /sys/bus/pci. If it does not find /sys/bus/pci (which it
won't in a Xen PV domU) it returns unsuccesfully (ENOENT), which libvirt
considers fatal. This makes libvirt unusable in this environment, even
though there are plenty of valid virtualisation options that work
there (LXC, UML, and QEmu spring to mind)

https://bugzilla.redhat.com/show_bug.cgi?id=709471

Signed-off-by: Soren Hansen so...@linux2go.dk
---
 src/node_device/node_device_udev.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index badf241..08ef856 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1620,7 +1620,7 @@ static int udevDeviceMonitorStartup(int privileged)
 /* Ignore failure as non-root; udev is not as helpful in that
  * situation, but a non-privileged user won't benefit much
  * from udev in the first place.  */
-if (privileged || errno != EACCES) {
+if (errno != ENOENT  (privileged  || errno != EACCES)) {
 char ebuf[256];
 VIR_ERROR(_(Failed to initialize libpciaccess: %s),
   virStrerror(pciret, ebuf, sizeof ebuf));
-- 
1.7.5.4

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


Re: [libvirt] [test-API][PATCH 2/2] Modify migration.py to support testing with tcp and tls

2011-09-05 Thread Nan Zhang

On 09/02/2011 03:23 PM, Guannan Ren wrote:

---
  repos/domain/migrate.py |7 +--
  1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/repos/domain/migrate.py b/repos/domain/migrate.py
index 3f80bd0..6b86188 100644
--- a/repos/domain/migrate.py
+++ b/repos/domain/migrate.py
@@ -1,6 +1,8 @@
  #!/usr/bin/env python
  this script is for migration testing
 domain:migrate
+   transport
+   tcp|tls|ssh
 target_machine
 10.66.5.5
 username
@@ -105,7 +107,7 @@ def env_clean(src, dst, srcdom, dstdom, target_machine, 
guestname, logger):
  def check_params(params):
  check out the arguments requried for migration
  logger = params['logger']
-keys = ['target_machine', 'username', 'password', 'guestname', 'flags']
+keys = ['transport', 'target_machine', 'username', 'password', 
'guestname', 'flags']
  for key in keys:
  if key not in params:
  logger.error(Argument %s is required % key)
@@ -194,6 +196,7 @@ def migrate(params):
  if params_check_result:
  return 1

+transport = params['transport']
  target_machine = params['target_machine']
  username = params['username']
  password = params['password']
@@ -243,7 +246,7 @@ def migrate(params):
  commands.getstatusoutput(ssh-add)

  srcuri = qemu:///system
-dsturi = qemu+ssh://%s/system % target_machine
+dsturi = qemu+%s://%s/system % (transport, target_machine)

  # Connect to local hypervisor connection URI
  util = utils.Utils()

ACK.

- nzhang

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


Re: [libvirt] [test-API][PATCH 1/2] Remove cases/migrate.conf testcases and create a set of migration testcases

2011-09-05 Thread Nan Zhang

On 09/02/2011 03:23 PM, Guannan Ren wrote:

  *cases/migrate.conf remove it.
  *cases/migration/* create a new set of migraion testcases with
   tcp, tls and sasl combination

  It's huge, so I send the header of commit here.
---
  cases/migrate.conf |   97 
  cases/migration/ssh_persistent_paused_no_dst.conf  |  459 +++
  .../migration/ssh_persistent_paused_with_dst.conf  |  459 +++
  cases/migration/ssh_persistent_running_no_dst.conf |  435 ++
  .../migration/ssh_persistent_running_with_dst.conf |  435 ++
  cases/migration/ssh_transient_paused_no_dst.conf   |  403 +
  cases/migration/ssh_transient_paused_with_dst.conf |  403 +
  cases/migration/ssh_transient_running_no_dst.conf  |  388 
  .../migration/ssh_transient_running_with_dst.conf  |  382 
  cases/migration/tcp_persistent_paused_no_dst.conf  |  471 
  .../migration/tcp_persistent_paused_with_dst.conf  |  471 
  cases/migration/tcp_persistent_running_no_dst.conf |  447 +++
  .../migration/tcp_persistent_running_with_dst.conf |  447 +++
  .../tcp_sasl_persistent_paused_no_dst.conf |  167 +++
  .../tcp_sasl_persistent_paused_with_dst.conf   |  168 +++
  .../tcp_sasl_persistent_running_no_dst.conf|  159 +++
  .../tcp_sasl_persistent_running_with_dst.conf  |  159 +++
  .../tcp_sasl_transient_paused_no_dst.conf  |  151 +++
  .../tcp_sasl_transient_paused_with_dst.conf|  151 +++
  .../tcp_sasl_transient_running_no_dst.conf |  143 ++
  .../tcp_sasl_transient_running_with_dst.conf   |  143 ++
  cases/migration/tcp_transient_paused_no_dst.conf   |  415 +
  cases/migration/tcp_transient_paused_with_dst.conf |  415 +
  cases/migration/tcp_transient_running_no_dst.conf  |  400 +
  .../migration/tcp_transient_running_with_dst.conf  |  394 
  cases/migration/tls_persistent_paused_no_dst.conf  |  471 
  .../migration/tls_persistent_paused_with_dst.conf  |  471 
  cases/migration/tls_persistent_running_no_dst.conf |  447 +++
  .../migration/tls_persistent_running_with_dst.conf |  447 +++
  .../tls_sasl_persistent_paused_no_dst.conf |  167 +++
  .../tls_sasl_persistent_paused_with_dst.conf   |  167 +++
  .../tls_sasl_persistent_running_no_dst.conf|  159 +++
  .../tls_sasl_persistent_running_with_dst.conf  |  159 +++
  .../tls_sasl_transient_paused_no_dst.conf  |  151 +++
  .../tls_sasl_transient_paused_with_dst.conf|  151 +++
  .../tls_sasl_transient_running_no_dst.conf |  143 ++
  .../tls_sasl_transient_running_with_dst.conf   |  143 ++
  cases/migration/tls_transient_paused_no_dst.conf   |  415 +
  cases/migration/tls_transient_paused_with_dst.conf |  415 +
  cases/migration/tls_transient_running_no_dst.conf  |  400 +
  .../migration/tls_transient_running_with_dst.conf  |  394 
  41 files changed, 12765 insertions(+), 97 deletions(-)
  delete mode 100644 cases/migrate.conf
  create mode 100644 cases/migration/ssh_persistent_paused_no_dst.conf
  create mode 100644 cases/migration/ssh_persistent_paused_with_dst.conf
  create mode 100644 cases/migration/ssh_persistent_running_no_dst.conf
  create mode 100644 cases/migration/ssh_persistent_running_with_dst.conf
  create mode 100644 cases/migration/ssh_transient_paused_no_dst.conf
  create mode 100644 cases/migration/ssh_transient_paused_with_dst.conf
  create mode 100644 cases/migration/ssh_transient_running_no_dst.conf
  create mode 100644 cases/migration/ssh_transient_running_with_dst.conf
  create mode 100644 cases/migration/tcp_persistent_paused_no_dst.conf
  create mode 100644 cases/migration/tcp_persistent_paused_with_dst.conf
  create mode 100644 cases/migration/tcp_persistent_running_no_dst.conf
  create mode 100644 cases/migration/tcp_persistent_running_with_dst.conf
  create mode 100644 cases/migration/tcp_sasl_persistent_paused_no_dst.conf
  create mode 100644 cases/migration/tcp_sasl_persistent_paused_with_dst.conf
  create mode 100644 cases/migration/tcp_sasl_persistent_running_no_dst.conf
  create mode 100644 cases/migration/tcp_sasl_persistent_running_with_dst.conf
  create mode 100644 cases/migration/tcp_sasl_transient_paused_no_dst.conf
  create mode 100644 cases/migration/tcp_sasl_transient_paused_with_dst.conf
  create mode 100644 cases/migration/tcp_sasl_transient_running_no_dst.conf
  create mode 100644 cases/migration/tcp_sasl_transient_running_with_dst.conf
  create mode 100644 cases/migration/tcp_transient_paused_no_dst.conf
  create mode 100644 

Re: [libvirt] [PATCH 1/8] latency: Define new public API and structure

2011-09-05 Thread Daniel Veillard
On Mon, Sep 05, 2011 at 04:38:28PM +0800, Osier Yang wrote:
 ---
  include/libvirt/libvirt.h.in |   84 
 ++
  src/libvirt_public.syms  |1 +
  2 files changed, 85 insertions(+), 0 deletions(-)
 
 diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
 index 8864865..735ea94 100644
 --- a/include/libvirt/libvirt.h.in
 +++ b/include/libvirt/libvirt.h.in
 @@ -574,6 +574,85 @@ struct _virDomainBlockStats {
   */
  typedef virDomainBlockStatsStruct *virDomainBlockStatsPtr;
  
 +
 +/**
 + * VIR_DOMAIN_BLOCK_STATS_FIELD_LENGTH:
 + *
 + * Macro providing the field length of virDomainBlockStatsFlagsStruct
 + */
 +#define VIR_DOMAIN_BLOCK_STATS_FIELD_LENGTH 80
 +
 +/**
 + * VIR_DOMAIN_BLOCK_STATS_READ_BYTES:
 + *
 + * Macro represents the total number of read bytes of the
 + * block device.
 + */
 +#define VIR_DOMAIN_BLOCK_STATS_READ_BYTES rd_bytes
 +
 +/**
 + * VIR_DOMAIN_BLOCK_STATS_READ_REQ:
 + *
 + * Macro represents the total read requests of the
 + * block device.
 + */
 +#define VIR_DOMAIN_BLOCK_STATS_READ_REQ rd_operations
 +
 +/**
 + * VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES:
 + *
 + * Macro represents the total time spend on cache reads in
 + * nano-seconds of the block device.
 + */
 +#define VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES rd_total_times
 +
 +/**
 + * VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES:
 + *
 + * Macro represents the total number of write bytes of the
 + * block device.
 + */
 +#define VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES wr_bytes
 +
 +/**
 + * VIR_DOMAIN_BLOCK_STATS_WRITE_REQ:
 + *
 + * Macro represents the total write requests of the
 + * block device.
 + */
 +#define VIR_DOMAIN_BLOCK_STATS_WRITE_REQ wr_operations
 +
 +/**
 + * VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES:
 + *
 + * Macro represents the total time spend on cache writes in
 + * nano-seconds of the block device.
 + */
 +#define VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES wr_total_times
 +
 +/**
 + * VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ:
 + *
 + * Macro represents the total flush requests of the
 + * block device.
 + */
 +#define VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ flush_operations
 +
 +/**
 + * VIR_DOMAIN_BLOCK_STATS_FLUSH_TOTAL_TIMES:
 + *
 + * Macro represents the total time spend on cache flushing in
 + * nano-seconds of the block device.
 + */
 +#define VIR_DOMAIN_BLOCK_STATS_FLUSH_TOTAL_TIMES flush_total_times
 +
 +/**
 + * VIR_DOMAIN_BLOCK_STATS_ERRS:
 + *
 + * In Xen this returns the mysterious 'oo_req'
 + */
 +#define VIR_DOMAIN_BLOCK_STATS_ERRS errs
 +
  /**
   * virDomainInterfaceStats:
   *
 @@ -1178,6 +1257,11 @@ int virDomainBlockStats 
 (virDomainPtr dom,
   const char *path,
   virDomainBlockStatsPtr 
 stats,
   size_t size);
 +int virDomainBlockStatsFlags (virDomainPtr dom,
 +  const char *path,
 +  virTypedParameterPtr 
 params,
 +  int *nparams,
 +  unsigned int flags);
  int virDomainInterfaceStats (virDomainPtr dom,
   const char *path,
   virDomainInterfaceStatsPtr 
 stats,
 diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
 index 169c3ee..dc5a80b 100644
 --- a/src/libvirt_public.syms
 +++ b/src/libvirt_public.syms
 @@ -483,6 +483,7 @@ LIBVIRT_0.9.4 {
  LIBVIRT_0.9.5 {
  global:
  virDomainMigrateGetMaxSpeed;
 +virDomainBlockStatsFlags;
  } LIBVIRT_0.9.4;
  
  #  define new API here using predicted next version number 
 -- 
 1.7.6

  ACK now, thanks !

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

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


Re: [libvirt] [PATCH 2/8] latency: Define the internal driver callback

2011-09-05 Thread Daniel Veillard
On Mon, Sep 05, 2011 at 04:38:29PM +0800, Osier Yang wrote:
 ---
  src/driver.h |8 
  1 files changed, 8 insertions(+), 0 deletions(-)
 
 diff --git a/src/driver.h b/src/driver.h
 index 21b2bd3..fc7a931 100644
 --- a/src/driver.h
 +++ b/src/driver.h
 @@ -348,6 +348,13 @@ typedef int
   const char *path,
   struct _virDomainBlockStats *stats);
  typedef int
 +(*virDrvDomainBlockStatsFlags)
 +(virDomainPtr domain,
 + const char *path,
 + virTypedParameterPtr params,
 + int *nparams,
 + unsigned int flags);
 +typedef int
  (*virDrvDomainInterfaceStats)
  (virDomainPtr domain,
   const char *path,
 @@ -806,6 +813,7 @@ struct _virDriver {
  virDrvDomainMigratePerform   domainMigratePerform;
  virDrvDomainMigrateFinishdomainMigrateFinish;
  virDrvDomainBlockStats  domainBlockStats;
 +virDrvDomainBlockStatsFlags domainBlockStatsFlags;
  virDrvDomainInterfaceStats  domainInterfaceStats;
  virDrvDomainMemoryStats domainMemoryStats;
  virDrvDomainBlockPeekdomainBlockPeek;

  ACK,

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

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


Re: [libvirt] [PATCH 1/2] make remote_exec_pexpect return the output of command

2011-09-05 Thread Nan Zhang

On 09/01/2011 10:19 AM, Guannan Ren wrote:

 *utils/Python/utils.py return 0,child.before intead
 *repos/remoteAccess/tcp_setup.py repos/remoteAccess/tls_setup.py
  switch over to use new remote_exec_pexpect()
---
  repos/remoteAccess/tcp_setup.py |   18 +-
  repos/remoteAccess/tls_setup.py |   20 ++--
  utils/Python/utils.py   |4 ++--
  3 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/repos/remoteAccess/tcp_setup.py b/repos/remoteAccess/tcp_setup.py
index 8f88810..b3877f7 100644
--- a/repos/remoteAccess/tcp_setup.py
+++ b/repos/remoteAccess/tcp_setup.py
@@ -56,7 +56,7 @@ def sasl_user_add(target_machine, username, password, util, 
logger):
   execute saslpasswd2 to add sasl user 
  logger.info(add sasl user on server side)
  saslpasswd2_add = echo %s | %s -a libvirt %s % (password, SASLPASSWD2, 
username)
-ret = util.remote_exec_pexpect(target_machine, username,
+ret, output = util.remote_exec_pexpect(target_machine, username,
  password, saslpasswd2_add)
  if ret:
  logger.error(failed to add sasl user)
@@ -70,7 +70,7 @@ def tcp_libvirtd_set(target_machine, username, password,
  logger.info(setting libvirtd.conf on libvirt server)
  # open libvirtd --listen option
  listen_open_cmd = echo 'LIBVIRTD_ARGS=\--listen\'  %s % 
SYSCONFIG_LIBVIRTD
-ret = util.remote_exec_pexpect(target_machine, username,
+ret, output = util.remote_exec_pexpect(target_machine, username,
  password, listen_open_cmd)
  if ret:
  logger.error(failed to uncomment --listen in %s % 
SYSCONFIG_LIBVIRTD)
@@ -79,7 +79,7 @@ def tcp_libvirtd_set(target_machine, username, password,
  # set listen_tls
  logger.info(set listen_tls to 0 in %s % LIBVIRTD_CONF)
  listen_tls_disable = echo \listen_tls = 0\  %s % LIBVIRTD_CONF
-ret = util.remote_exec_pexpect(target_machine, username,
+ret, output = util.remote_exec_pexpect(target_machine, username,
  password, listen_tls_disable)
  if ret:
  logger.error(failed to set listen_tls to 0 in %s % LIBVIRTD_CONF)
@@ -89,7 +89,7 @@ def tcp_libvirtd_set(target_machine, username, password,
  if listen_tcp == 'enable':
  logger.info(enable listen_tcp = 1 in %s % LIBVIRTD_CONF)
  listen_tcp_set = echo 'listen_tcp = 1'  %s % LIBVIRTD_CONF
-ret = util.remote_exec_pexpect(target_machine, username,
+ret, output = util.remote_exec_pexpect(target_machine, username,
  password, listen_tcp_set)
  if ret:
  logger.error(failed to set listen_tcp in %s % LIBVIRTD_CONF)
@@ -98,7 +98,7 @@ def tcp_libvirtd_set(target_machine, username, password,
  # set auth_tcp
  logger.info(set auth_tcp to \%s\ in %s % (auth_tcp, LIBVIRTD_CONF))
  auth_tcp_set = echo 'auth_tcp = \%s\'  %s % (auth_tcp, 
LIBVIRTD_CONF)
-ret = util.remote_exec_pexpect(target_machine, username,
+ret, output = util.remote_exec_pexpect(target_machine, username,
 password, auth_tcp_set)
  if ret:
  logger.error(failed to set auth_tcp in %s % LIBVIRTD_CONF)
@@ -107,7 +107,7 @@ def tcp_libvirtd_set(target_machine, username, password,
  # restart remote libvirtd service
  libvirtd_restart_cmd = service libvirtd restart
  logger.info(libvirtd restart)
-ret = util.remote_exec_pexpect(target_machine, username,
+ret, output = util.remote_exec_pexpect(target_machine, username,
  password, libvirtd_restart_cmd)
  if ret:
  logger.error(failed to restart libvirtd service)
@@ -225,18 +225,18 @@ def tcp_setup_clean(params):

  if auth_tcp == 'sasl':
  saslpasswd2_delete = %s -a libvirt -d %s % (SASLPASSWD2, username)
-ret = util.remote_exec_pexpect(target_machine, username,
+ret, output = util.remote_exec_pexpect(target_machine, username,
  password, saslpasswd2_delete)
  if ret:
  logger.error(failed to delete sasl user)
  libvirtd_conf_retore = sed -i -n '/^[ #]/p' %s % LIBVIRTD_CONF
-ret = util.remote_exec_pexpect(target_machine, username,
+ret, output = util.remote_exec_pexpect(target_machine, username,
  password, libvirtd_conf_retore)
  if ret:
  logger.error(failed to restore %s % LIBVIRTD_CONF)

  sysconfig_libvirtd_restore = sed -i -n '/^[ #]/p' %s % 
SYSCONFIG_LIBVIRTD
-ret = util.remote_exec_pexpect(target_machine, username,
+ret, output = util.remote_exec_pexpect(target_machine, username,
  password, sysconfig_libvirtd_restore)
  if ret:
  logger.error(failed to restore %s % SYSCONFIG_LIBVIRTD)
diff --git a/repos/remoteAccess/tls_setup.py 

Re: [libvirt] [PATCH 3/8] latency: Implemente the public API

2011-09-05 Thread Daniel Veillard
On Mon, Sep 05, 2011 at 04:38:30PM +0800, Osier Yang wrote:
 ---
  src/libvirt.c |   71 
 +
  1 files changed, 71 insertions(+), 0 deletions(-)
 
 diff --git a/src/libvirt.c b/src/libvirt.c
 index 4d80e2f..a921e4d 100644
 --- a/src/libvirt.c
 +++ b/src/libvirt.c
 @@ -6442,6 +6442,77 @@ error:
  }
  
  /**
 + * virDomainBlockStatsFlags:
 + * @dom: pointer to domain object
 + * @path: path to the block device
 + * @params: pointer to block stats parameter object

  objects (plural)

 + *  (return value)
 + * @nparams: pointer to number of block stats

  need to describe the behaviour of allocation, i.e. who allocate,
and what happens if the caller doesn't allocate enough parameters

 + * @flags: unused, always passes 0
 + *
 + * This function is to get block stats parameters for block
 + * devices attached to the domain.
 + *
 + * The @path is the name of the block device.  Get this
 + * by calling virDomainGetXMLDesc and finding the target dev='...'
 + * attribute within //domain/devices/disk.  (For example, xvda).
 + *
 + * Domains may have more than one block device.  To get stats for
 + * each you should make multiple calls to this function.
 + *
 + * The @params array will be filled with the value equal to the number of
 + * parameters suggested by @nparams.

  still unclear if it is too much or too many

 + * As the value of @nparams is dynamic, call the API setting @nparams to 0 
 and
 + * @params as NULL, the API returns the number of parameters supported by the
 + * HV by updating @nparams on SUCCESS. (Note that block device of different 
 type
 + * might support different parameters numbers, so it might be necessary to 
 compute
 + * @nparams for each block device type). The caller should then allocate 
 @params
 + * array, i.e. (sizeof(@virTypedParameter) * @nparams) bytes and call the API
 + * again. See virDomainGetMemoryParameters for more details.

  tend to disagree, we should document the behaviour here, not reference
  another function docuemntation, copy as needed

 + * Returns -1 in case of error, 0 in case of success.
 + */
 +int virDomainBlockStatsFlags (virDomainPtr dom,
 +  const char *path,
 +  virTypedParameterPtr params,
 +  int *nparams,
 +  unsigned int flags)
 +{
 +virConnectPtr conn;
 +
 +VIR_DOMAIN_DEBUG(dom, path=%s, params=%p, nparams=%d, flags=%x,
 + path, params, nparams ? *nparams : -1, flags);
 +
 +virResetLastError();
 +
 +if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
 +virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
 +virDispatchError(NULL);
 +return -1;
 +}
 +if (!path || (nparams == NULL) || (*nparams  0)) {

  okay we accept param == NULL here,

 +virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__);
 +goto error;
 +}
 +conn = dom-conn;
 +
 +if (conn-driver-domainBlockStatsFlags) {
 +int ret;
 +ret = conn-driver-domainBlockStatsFlags(dom, path, params, 
 nparams, flags);
 +if (ret  0)
 +goto error;
 +return ret;
 +}
 +virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
 +
 +error:
 +virDispatchError(dom-conn);
 +return -1;
 +}
 +
 +
 +/**
   * virDomainInterfaceStats:
   * @dom: pointer to the domain object
   * @path: path to the interface

  ACK,

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

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


Re: [libvirt] [PATCH 2/2] Add new testcase for cpu topology testing

2011-09-05 Thread Nan Zhang

On 09/01/2011 10:19 AM, Guannan Ren wrote:

 *repos/domain/cpu_topology.py
---
  repos/domain/cpu_topology.py |  248 ++
  1 files changed, 248 insertions(+), 0 deletions(-)
  create mode 100644 repos/domain/cpu_topology.py

diff --git a/repos/domain/cpu_topology.py b/repos/domain/cpu_topology.py
new file mode 100644
index 000..7202559
--- /dev/null
+++ b/repos/domain/cpu_topology.py
@@ -0,0 +1,248 @@
+#!/usr/bin/env python
+ To test guest cpu topology
+domain:cpu_topology
+guestname
+xxx
+username
+root
+password
+xx
+sockets
+2
+cores
+1
+threads
+2
+
+
+__author__ = 'Guannan Ren: g...@redhat.com'
+__date__ = 'Tue Aug 30, 2011'
+__version__ = '0.1.0'
+__credits__ = 'Copyright (C) 2011 Red Hat, Inc.'
+__all__ = []
+
+import os
+import re
+import sys
+import time
+from xml.dom import minidom
+
+def append_path(path):
+Append root path of package
+if path in sys.path:
+pass
+else:
+sys.path.append(path)
+
+pwd = os.getcwd()
+result = re.search('(.*)libvirt-test-API', pwd)
+append_path(result.group(0))
+
+from lib import connectAPI
+from lib import domainAPI
+from utils.Python import utils
+from exception import LibvirtAPI
+
+def check_params(params):
+check out the arguments requried for testing
+logger = params['logger']
+keys = ['guestname', 'username', 'password',
+'sockets', 'cores', 'threads']
+for key in keys:
+if key not in params:
+logger.error(Argument %s is required % key)
+return 1
+return 0
+
+def check_domain_running(domobj, guestname, logger):
+check if the domain exists, may or may not be active
+defined_guest_names = domobj.get_defined_list()
+
+if guestname not in defined_guest_names:
+logger.error(%s doesn't exist or still in running % guestname)
+return 1
+else:
+return 0
+
+def add_cpu_xml(domobj, guestname, sockets, cores, threads, logger):
+edit domain xml description and insertcpu  element
+
+guestxml = domobj.get_xml_desc(guestname)
+logger.debug('''original guest %s xml :\n%s''' %(guestname, guestxml))
+
+doc = minidom.parseString(guestxml)
+cpu = doc.createElement('cpu')
+topology = doc.createElement('topology')
+topology.setAttribute('sockets', sockets)
+topology.setAttribute('cores', cores)
+topology.setAttribute('threads', threads)
+cpu.appendChild(topology)
+
+vcpuval = int(sockets) * int(cores) * int(threads)
+newvcpu = doc.createElement('vcpu')
+newvcpuval = doc.createTextNode(str(vcpuval))
+newvcpu.appendChild(newvcpuval)
+oldvcpu = doc.getElementsByTagName('vcpu')[0]
+
+domain = doc.getElementsByTagName('domain')[0]
+domain.appendChild(cpu)
+domain.replaceChild(newvcpu, oldvcpu)
+
+return doc.toxml()
+
+def guest_undefine(domobj, guestname, logger):
+undefine original guest
+try:
+logger.info(undefine guest)
+domobj.undefine(guestname)
+logger.info(undefine the domain is successful)
+except LibvirtAPI, e:
+logger.error(API error message: %s, error code is %s % \
+ (e.response()['message'], e.response()['code']))
+logger.error(fail to undefine domain)
+return 1
+
+return 0
+
+def guest_define(domobj, domxml, logger):
+define new guest xml
+try:
+logger.info(define guest)
+domobj.define(domxml)
+logger.info(success to define new domain xml description)
+except LibvirtAPI, e:
+logger.error(API error message: %s, error code is %s % \
+ (e.response()['message'], e.response()['code']))
+logger.error(fail to define domain)
+return 1
+
+return 0
+
+def guest_start(domobj, guestname, util, logger):
+start guest
+timeout = 600
+ip = ''
+mac = util.get_dom_mac_addr(guestname)
+
+try:
+logger.info(start guest)
+domobj.start(guestname)
+except LibvirtAPI, e:
+logger.error(API error message: %s, error code is %s % \
+ (e.response()['message'], e.response()['code']))
+logger.error(fail to start domain)
+return 1
+
+while timeout:
+time.sleep(10)
+timeout -= 10
+
+ip = util.mac_to_ip(mac, 180)
+
+if not ip:
+logger.info(str(timeout) + s left)
+else:
+logger.info(vm %s power on successfully % guestname)
+logger.info(the ip address of vm %s is %s % (guestname, ip))
+break
+
+if timeout= 0:
+logger.info(fail to power on vm %s % guestname)
+return 1, ip
+
+return 0, ip
+
+def cpu_topology_check(ip, username, password,
+   sockets, cores, threads, util, logger):
+login the guest, run lscpu command to check the result
+lscpu = 

Re: [libvirt] [PATCH 6/8] latency: Implemente internal API for qemu driver

2011-09-05 Thread Daniel Veillard
On Mon, Sep 05, 2011 at 04:38:33PM +0800, Osier Yang wrote:
 ---
  src/qemu/qemu_driver.c |  189 
 
  1 files changed, 189 insertions(+), 0 deletions(-)
 
 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index c5809d2..a8b2b6d 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -7243,6 +7243,194 @@ cleanup:
  return ret;
  }
  
 +static int
 +qemudDomainBlockStatsFlags (virDomainPtr dom,
 +const char *path,
 +virTypedParameterPtr params,
 +int *nparams,
 +unsigned int flags)
 +{
 +struct qemud_driver *driver = dom-conn-privateData;
 +int i, tmp, ret = -1;
 +virDomainObjPtr vm;
 +virDomainDiskDefPtr disk = NULL;
 +qemuDomainObjPrivatePtr priv;
 +long long rd_req, rd_bytes, wr_req, wr_bytes, rd_total_times;
 +long long wr_total_times, flush_req, flush_total_times, errs;
 +
 +virCheckFlags(0, -1);
 +
 +qemuDriverLock(driver);
 +vm = virDomainFindByUUID(driver-domains, dom-uuid);
 +qemuDriverUnlock(driver);
 +if (!vm) {
 +char uuidstr[VIR_UUID_STRING_BUFLEN];
 +virUUIDFormat(dom-uuid, uuidstr);
 +qemuReportError(VIR_ERR_NO_DOMAIN,
 +_(no domain with matching uuid '%s'), uuidstr);
 +goto cleanup;
 +}
 +
 +if (!virDomainObjIsActive(vm)) {
 +qemuReportError(VIR_ERR_OPERATION_INVALID,
 +%s, _(domain is not running));
 +goto cleanup;
 +}
 +
 +if (*nparams != 0) {
 +for (i = 0 ; i  vm-def-ndisks ; i++) {
 +if (STREQ(path, vm-def-disks[i]-dst)) {
 +disk = vm-def-disks[i];
 +break;
 +}
 +}
 +
 +if (!disk) {
 +qemuReportError(VIR_ERR_INVALID_ARG,
 +_(invalid path: %s), path);
 +goto cleanup;
 +}
 +
 +if (!disk-info.alias) {
 + qemuReportError(VIR_ERR_INTERNAL_ERROR,
 + _(missing disk device alias name for %s), 
 disk-dst);
 + goto cleanup;
 +}
 +}
 +
 +priv = vm-privateData;
 +VIR_DEBUG(priv=%p, params=%p, flags=%x, priv, params, flags);
 +
 +if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY)  0)
 +goto cleanup;
 +
 +qemuDomainObjEnterMonitor(driver, vm);
 +tmp = *nparams;
 +ret = qemuMonitorGetBlockStatsParamsNumber(priv-mon, nparams);
 +
 +if (tmp == 0) {
 +qemuDomainObjExitMonitor(driver, vm);
 +goto endjob;
 +}
 +
 +ret = qemuMonitorGetBlockStatsInfo(priv-mon,
 +   disk-info.alias,
 +   rd_req,
 +   rd_bytes,
 +   rd_total_times,
 +   wr_req,
 +   wr_bytes,
 +   wr_total_times,
 +   flush_req,
 +   flush_total_times,
 +   errs);
 +
 +qemuDomainObjExitMonitor(driver, vm);
 +
 +if (ret  0)
 +goto endjob;
 +
 +/* Field 'errs' is meaningless for QEMU, won't set it. */
 +for (i = 0; i  *nparams; i++) {
 +virTypedParameterPtr param = params[i];
 +
 +switch (i) {
 +case 0: /* fill write_bytes here */
 +if (virStrcpyStatic(param-field, 
 VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES) == NULL) {
 +qemuReportError(VIR_ERR_INTERNAL_ERROR,
 +%s, _(Field write bytes too long for 
 destination));
 +goto cleanup;
 +}
 +param-type = VIR_TYPED_PARAM_LLONG;
 +param-value.l = wr_bytes;
 +break;
 +
 +case 1: /* fill wr_operations here */
 +if (virStrcpyStatic(param-field, 
 VIR_DOMAIN_BLOCK_STATS_WRITE_REQ) == NULL) {
 +qemuReportError(VIR_ERR_INTERNAL_ERROR,
 +%s, _(Field write requests too long for 
 destination));
 +goto cleanup;
 +}
 +param-type = VIR_TYPED_PARAM_LLONG;
 +param-value.l = wr_req;
 +break;
 +
 +case 2: /* fill read_bytes here */
 +if (virStrcpyStatic(param-field, 
 VIR_DOMAIN_BLOCK_STATS_READ_BYTES) == NULL) {
 +qemuReportError(VIR_ERR_INTERNAL_ERROR,
 +%s, _(Field read bytes too long for 
 destination));
 +goto cleanup;
 +}
 +param-type = VIR_TYPED_PARAM_LLONG;
 +param-value.l = rd_bytes;
 +break;
 +
 +case 3: /* fill rd_operations here */
 +if (virStrcpyStatic(param-field, 
 

Re: [libvirt] [PATCH 5/8] latency: Update monitor functions for new latency fields

2011-09-05 Thread Daniel Veillard
On Mon, Sep 05, 2011 at 04:38:32PM +0800, Osier Yang wrote:
 The mainly changes are:
 
 1) Update qemuMonitorGetBlockStatsInfo and it's children (Text/JSON)
functions to return the value of new latency fields.
 2) Add new function qemuMonitorGetBlockStatsParamsNumber, which is
to count how many parameters the underlying QEMU supports.
 3) Update virDomainBlockStats in src/qemu/qemu_driver.c to be
compatible with the changes by 1).
 ---
  src/qemu/qemu_driver.c   |4 ++
  src/qemu/qemu_monitor.c  |   35 
  src/qemu/qemu_monitor.h  |6 ++
  src/qemu/qemu_monitor_json.c |  124 
 +-
  src/qemu/qemu_monitor_json.h |6 ++
  src/qemu/qemu_monitor_text.c |  121 +
  src/qemu/qemu_monitor_text.h |6 ++
  7 files changed, 291 insertions(+), 11 deletions(-)
 
 diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
 index 7028d72..c5809d2 100644
 --- a/src/qemu/qemu_driver.c
 +++ b/src/qemu/qemu_driver.c
 @@ -7224,8 +7224,12 @@ qemudDomainBlockStats (virDomainPtr dom,
 disk-info.alias,
 stats-rd_req,
 stats-rd_bytes,
 +   NULL,
 stats-wr_req,
 stats-wr_bytes,
 +   NULL,
 +   NULL,
 +   NULL,
 stats-errs);
  qemuDomainObjExitMonitor(driver, vm);
  
 diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
 index db6107c..92631ae 100644
 --- a/src/qemu/qemu_monitor.c
 +++ b/src/qemu/qemu_monitor.c
 @@ -1201,8 +1201,12 @@ int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
   const char *devname,
   long long *rd_req,
   long long *rd_bytes,
 + long long *rd_total_times,
   long long *wr_req,
   long long *wr_bytes,
 + long long *wr_total_times,
 + long long *flush_req,
 + long long *flush_total_times,
   long long *errs)
  {
  int ret;
 @@ -1217,16 +1221,47 @@ int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
  if (mon-json)
  ret = qemuMonitorJSONGetBlockStatsInfo(mon, devname,
 rd_req, rd_bytes,
 +   rd_total_times,
 wr_req, wr_bytes,
 +   wr_total_times,
 +   flush_req,
 +   flush_total_times,
 errs);
  else
  ret = qemuMonitorTextGetBlockStatsInfo(mon, devname,
 rd_req, rd_bytes,
 +   rd_total_times,
 wr_req, wr_bytes,
 +   wr_total_times,
 +   flush_req,
 +   flush_total_times,
 errs);
  return ret;
  }
  
 +/* Return 0 and update @nparams with the number of block stats
 + * QEMU supports if success. Return -1 if failure.
 + */
 +int qemuMonitorGetBlockStatsParamsNumber(qemuMonitorPtr mon,
 + int *nparams)
 +{
 +int ret;
 +VIR_DEBUG(mon=%p nparams=%p, mon, nparams);
 +
 +if (!mon) {
 +qemuReportError(VIR_ERR_INVALID_ARG, %s,
 +_(monitor must not be NULL));
 +return -1;
 +}
 +
 +if (mon-json)
 +ret = qemuMonitorJSONGetBlockStatsParamsNumber(mon, nparams);
 +else
 +ret = qemuMonitorTextGetBlockStatsParamsNumber(mon, nparams);
 +
 +return ret;
 +}
 +
  int qemuMonitorGetBlockExtent(qemuMonitorPtr mon,
const char *devname,
unsigned long long *extent)
 diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
 index f241c9e..1b9d98d 100644
 --- a/src/qemu/qemu_monitor.h
 +++ b/src/qemu/qemu_monitor.h
 @@ -212,9 +212,15 @@ int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
   const char *devname,
   long long *rd_req,
   long long *rd_bytes,
 + long long *rd_total_times,
   long 

Re: [libvirt] [PATCH 4/8] latency: Wire up the remote protocol

2011-09-05 Thread Daniel Veillard
On Mon, Sep 05, 2011 at 04:38:31PM +0800, Osier Yang wrote:
 ---
  daemon/remote.c  |   69 
 ++
  src/remote/remote_driver.c   |   64 ++
  src/remote/remote_protocol.x |   19 +++-
  3 files changed, 151 insertions(+), 1 deletions(-)
 
 diff --git a/daemon/remote.c b/daemon/remote.c
 index d5ead81..38bbb10 100644
 --- a/daemon/remote.c
 +++ b/daemon/remote.c
 @@ -933,6 +933,75 @@ cleanup:
  }
  
  static int
 +remoteDispatchDomainBlockStatsFlags(virNetServerPtr server ATTRIBUTE_UNUSED,
 +virNetServerClientPtr client 
 ATTRIBUTE_UNUSED,
 +virNetMessageHeaderPtr hdr 
 ATTRIBUTE_UNUSED,
 +virNetMessageErrorPtr rerr,
 +remote_domain_block_stats_flags_args 
 *args,
 +remote_domain_block_stats_flags_ret *ret)
 +{
 +virTypedParameterPtr params = NULL;
 +virDomainPtr dom = NULL;
 +int i;
 +const char *path = args-path;
 +int nparams = args-nparams;
 +unsigned int flags;
 +int rv = -1;
 +struct daemonClientPrivate *priv =
 +virNetServerClientGetPrivateData(client);
 +
 +if (!priv-conn) {
 +virNetError(VIR_ERR_INTERNAL_ERROR, %s, _(connection not open));
 +goto cleanup;
 +}
 +
 +if (!(dom = get_nonnull_domain(priv-conn, args-dom)))
 +goto cleanup;
 +flags = args-flags;
 +
 +if (nparams  REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX) {
 +virNetError(VIR_ERR_INTERNAL_ERROR, %s, _(nparams too large));
 +goto cleanup;
 +}
 +if (VIR_ALLOC_N(params, nparams)  0) {
 +virReportOOMError();
 +goto cleanup;
 +}
 +
 +if (virDomainBlockStatsFlags(dom, path, params, nparams, flags)  0)
 +goto cleanup;
 +
 +/* In this case, we need to send back the number of parameters
 + * supported
 + */
 +if (args-nparams == 0) {
 +ret-nparams = nparams;
 +goto success;
 +}
 +
 +/* Serialise the block stats. */
 +if (remoteSerializeTypedParameters(params, nparams,
 +   ret-params.params_val,
 +   ret-params.params_len)  0)
 +goto cleanup;
 +
 +success:
 +rv = 0;
 +
 +cleanup:
 +if (rv  0) {
 +virNetMessageSaveError(rerr);
 +if (ret-params.params_val) {
 +for (i = 0; i  nparams; i++)
 +VIR_FREE(ret-params.params_val[i].field);
 +VIR_FREE(ret-params.params_val);
 +}
 +}
 +VIR_FREE(params);
 +return rv;
 +}
 +
 +static int
  remoteDispatchDomainMemoryPeek(virNetServerPtr server ATTRIBUTE_UNUSED,
 virNetServerClientPtr client ATTRIBUTE_UNUSED,
 virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
 diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
 index 783c404..9d34b7e 100644
 --- a/src/remote/remote_driver.c
 +++ b/src/remote/remote_driver.c
 @@ -1361,6 +1361,69 @@ cleanup:
  }
  
  static int
 +remoteDomainBlockStatsFlags(virDomainPtr domain,
 +const char *path,
 +virTypedParameterPtr params,
 +int *nparams,
 +unsigned int flags)
 +{
 +int rv = -1;
 +remote_domain_block_stats_flags_args args;
 +remote_domain_block_stats_flags_ret ret;
 +struct private_data *priv = domain-conn-privateData;
 +
 +remoteDriverLock(priv);
 +
 +make_nonnull_domain (args.dom, domain);
 +args.nparams = *nparams;
 +args.path = (char *) path;
 +args.flags = flags;
 +
 +memset (ret, 0, sizeof ret);
 +if (call (domain-conn, priv, 0, REMOTE_PROC_DOMAIN_BLOCK_STATS_FLAGS,
 +  (xdrproc_t) xdr_remote_domain_block_stats_flags_args, (char *) 
 args,
 +  (xdrproc_t) xdr_remote_domain_block_stats_flags_ret, (char *) 
 ret) == -1)
 +goto done;
 +
 +/* Check the length of the returned list carefully. */
 +if (ret.params.params_len  REMOTE_DOMAIN_BLOCK_STATS_PARAMETERS_MAX ||
 +ret.params.params_len  *nparams) {
 +remoteError(VIR_ERR_RPC, %s,
 +_(remoteDomainBlockStatsFlags: 
 +  returned number of stats exceeds limit));
 +goto cleanup;
 +}
 +
 +/* Handle the case when the caller does not know the number of stats
 + * and is asking for the number of stats supported
 + */
 +if (*nparams == 0) {
 +*nparams = ret.nparams;
 +rv = 0;
 +goto cleanup;
 +}
 +
 +*nparams = ret.params.params_len;
 +
 +/* Deserialise the result. */
 +if (remoteDeserializeTypedParameters(ret.params.params_val,
 + ret.params.params_len,
 + 

Re: [libvirt] [PATCH 8/8] latency: Update cmdBlkStats to use new API

2011-09-05 Thread Daniel Veillard
On Mon, Sep 05, 2011 at 04:38:35PM +0800, Osier Yang wrote:
 The modified function fallbacks to use virDomainBlockStats if
 virDomainBlockStatsFlags is not supported by the hypervisor driver.
 If the new API is supported, it will be invoked instead of the
 old API.
 ---
  tools/virsh.c |  104 
 ++---
  1 files changed, 84 insertions(+), 20 deletions(-)
 
 diff --git a/tools/virsh.c b/tools/virsh.c
 index c7240e5..ea41221 100644
 --- a/tools/virsh.c
 +++ b/tools/virsh.c
 @@ -1070,6 +1070,9 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd)
  virDomainPtr dom;
  const char *name = NULL, *device = NULL;
  struct _virDomainBlockStats stats;
 +virTypedParameterPtr params = NULL;
 +int rc, nparams = 0;
 +bool ret = false;
  
  if (!vshConnectionUsability (ctl, ctl-conn))
  return false;
 @@ -1077,34 +1080,95 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd)
  if (!(dom = vshCommandOptDomain (ctl, cmd, name)))
  return false;
  
 -if (vshCommandOptString (cmd, device, device) = 0) {
 -virDomainFree(dom);
 -return false;
 -}
 +if (vshCommandOptString (cmd, device, device) = 0)
 +goto cleanup;
  
 -if (virDomainBlockStats (dom, device, stats, sizeof stats) == -1) {
 -vshError(ctl, _(Failed to get block stats %s %s), name, device);
 -virDomainFree(dom);
 -return false;
 -}
 +rc = virDomainBlockStatsFlags(dom, device, NULL, nparams, 0);
  
 -if (stats.rd_req = 0)
 -vshPrint (ctl, %s rd_req %lld\n, device, stats.rd_req);
 +/* It might fail when virDomainBlockStatsFlags is not
 + * supported on older libvirt, fallback to use virDomainBlockStats
 + * then.
 + */
 +if (rc  0) {
 +if (last_error-code != VIR_ERR_NO_SUPPORT) {
 +virshReportError(ctl);
 +goto cleanup;
 +} else {
 +virFreeError(last_error);
 +last_error = NULL;
  
 -if (stats.rd_bytes = 0)
 -vshPrint (ctl, %s rd_bytes %lld\n, device, stats.rd_bytes);
 +if (virDomainBlockStats (dom, device, stats,
 + sizeof stats) == -1) {
 +vshError(ctl, _(Failed to get block stats %s %s),
 + name, device);
 +goto cleanup;
 +}
 +
 +if (stats.rd_req = 0)
 +vshPrint (ctl, %s rd_req %lld\n, device, stats.rd_req);
  
 -if (stats.wr_req = 0)
 -vshPrint (ctl, %s wr_req %lld\n, device, stats.wr_req);
 +if (stats.rd_bytes = 0)
 +vshPrint (ctl, %s rd_bytes %lld\n, device, stats.rd_bytes);
  
 -if (stats.wr_bytes = 0)
 -vshPrint (ctl, %s wr_bytes %lld\n, device, stats.wr_bytes);
 +if (stats.wr_req = 0)
 +vshPrint (ctl, %s wr_req %lld\n, device, stats.wr_req);
  
 -if (stats.errs = 0)
 -vshPrint (ctl, %s errs %lld\n, device, stats.errs);
 +if (stats.wr_bytes = 0)
 +vshPrint (ctl, %s wr_bytes %lld\n, device, stats.wr_bytes);
  
 +if (stats.errs = 0)
 +vshPrint (ctl, %s errs %lld\n, device, stats.errs);
 +}
 +} else {
 +params = vshMalloc(ctl, sizeof(*params) * nparams);
 +memset(params, 0, sizeof(*params) * nparams);
 +
 +if (virDomainBlockStatsFlags (dom, device, params, nparams, 0)  0) 
 {
 +vshError(ctl, _(Failed to get block stats %s %s), name, 
 device);
 +goto cleanup;
 +}
 +
 +int i;
 +/* XXX: The output sequence will be different. */
 +for (i = 0; i  nparams; i++) {
 +switch(params[i].type) {
 +case VIR_TYPED_PARAM_INT:
 +vshPrint (ctl, %s %s %d\n, device,
 +  params[i].field, params[i].value.i);
 +break;
 +case VIR_TYPED_PARAM_UINT:
 +vshPrint (ctl, %s %s %u\n, device,
 +  params[i].field, params[i].value.ui);
 +break;
 +case VIR_TYPED_PARAM_LLONG:
 +vshPrint (ctl, %s %s %lld\n, device,
 +  params[i].field, params[i].value.l);
 +break;
 +case VIR_TYPED_PARAM_ULLONG:
 +vshPrint (ctl, %s %s %llu\n, device,
 +  params[i].field, params[i].value.ul);
 +break;
 +case VIR_TYPED_PARAM_DOUBLE:
 +vshPrint (ctl, %s %s %f\n, device,
 +  params[i].field, params[i].value.d);
 +break;
 +case VIR_TYPED_PARAM_BOOLEAN:
 +vshPrint (ctl, %s %s %s\n, device,
 +  params[i].field, params[i].value.b ? _(yes) : 
 _(no));
 +break;
 +default:
 +vshError(ctl, _(unimplemented block statistics parameter 
 

Re: [libvirt] [PATCH 7/8] latency: Expose the new API for Python binding

2011-09-05 Thread Daniel Veillard
On Mon, Sep 05, 2011 at 04:38:34PM +0800, Osier Yang wrote:
 ---
  python/generator.py |1 +
  python/libvirt-override-api.xml |7 +++
  python/libvirt-override.c   |   85 
 +++
  3 files changed, 93 insertions(+), 0 deletions(-)
 
 diff --git a/python/generator.py b/python/generator.py
 index cc253cf..d17fb26 100755
 --- a/python/generator.py
 +++ b/python/generator.py
 @@ -373,6 +373,7 @@ skip_impl = (
  'virNodeGetMemoryStats',
  'virDomainGetBlockJobInfo',
  'virDomainMigrateGetMaxSpeed',
 +'virDomainBlockStatsFlags',
  )
  
  
 diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
 index 1cf115c..3013e46 100644
 --- a/python/libvirt-override-api.xml
 +++ b/python/libvirt-override-api.xml
 @@ -128,6 +128,13 @@
arg name='domain' type='virDomainPtr' info='a domain object'/
arg name='path' type='char *' info='the path for the block device'/
  /function
 +function name='virDomainBlockStatsFlags' file='python'
 +  infoExtracts block device statistics parameters of a running 
 domain/info
 +  return type='virTypedParameterPtr' info='None in case of error, 
 returns a dictionary of params'/
 +  arg name='domain' type='virDomainPtr' info='pointer to domain 
 object'/
 +  arg name='path' type='char *' info='the path for the block device'/
 +  arg name='flags' type='int' info='flags (unused; pass 0)'/
 +/function
  function name='virDomainInterfaceStats' file='python'
infoExtracts interface device statistics for a domain/info
return type='virDomainInterfaceStats' info='a tuple of statistics'/
 diff --git a/python/libvirt-override.c b/python/libvirt-override.c
 index b020342..d65423d 100644
 --- a/python/libvirt-override.c
 +++ b/python/libvirt-override.c
 @@ -100,6 +100,90 @@ libvirt_virDomainBlockStats(PyObject *self 
 ATTRIBUTE_UNUSED, PyObject *args) {
  }
  
  static PyObject *
 +libvirt_virDomainBlockStatsFlags(PyObject *self ATTRIBUTE_UNUSED,
 + PyObject *args) {
 +virDomainPtr domain;
 +PyObject *pyobj_domain, *info;
 +int i_retval;
 +int nparams = 0, i;
 +unsigned int flags;
 +virTypedParameterPtr params;
 +const char *path;
 +
 +if (!PyArg_ParseTuple(args, (char *)Ozi:virDomainBlockStatsFlags,
 +  pyobj_domain, path, flags))
 +return(NULL);
 +domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
 +
 +LIBVIRT_BEGIN_ALLOW_THREADS;
 +i_retval = virDomainBlockStatsFlags(domain, path, NULL, nparams, flags);
 +LIBVIRT_END_ALLOW_THREADS;
 +
 +if (i_retval  0)
 +return VIR_PY_NONE;
 +
 +if ((params = malloc(sizeof(*params)*nparams)) == NULL)
 +return VIR_PY_NONE;
 +
 +LIBVIRT_BEGIN_ALLOW_THREADS;
 +i_retval = virDomainBlockStatsFlags(domain, path, params, nparams, 
 flags);
 +LIBVIRT_END_ALLOW_THREADS;
 +
 +if (i_retval  0) {
 +free(params);
 +return VIR_PY_NONE;
 +}
 +
 +/* convert to a Python tuple of long objects */
 +if ((info = PyDict_New()) == NULL) {
 +free(params);
 +return VIR_PY_NONE;
 +}
 +
 +for (i = 0 ; i  nparams ; i++) {
 +PyObject *key, *val;
 +
 +switch (params[i].type) {
 +case VIR_TYPED_PARAM_INT:
 +val = PyInt_FromLong((long)params[i].value.i);
 +break;
 +
 +case VIR_TYPED_PARAM_UINT:
 +val = PyInt_FromLong((long)params[i].value.ui);
 +break;
 +
 +case VIR_TYPED_PARAM_LLONG:
 +val = PyLong_FromLongLong((long long)params[i].value.l);
 +break;
 +
 +case VIR_TYPED_PARAM_ULLONG:
 +val = PyLong_FromLongLong((long long)params[i].value.ul);
 +break;
 +
 +case VIR_TYPED_PARAM_DOUBLE:
 +val = PyFloat_FromDouble((double)params[i].value.d);
 +break;
 +
 +case VIR_TYPED_PARAM_BOOLEAN:
 +val = PyBool_FromLong((long)params[i].value.b);
 +break;
 +
 +default:
 +free(params);
 +Py_DECREF(info);
 +return VIR_PY_NONE;
 +}
 +
 +key = libvirt_constcharPtrWrap(params[i].field);
 +PyDict_SetItem(info, key, val);
 +}
 +
 +free(params);
 +return(info);
 +}
 +
 +
 +static PyObject *
  libvirt_virDomainInterfaceStats(PyObject *self ATTRIBUTE_UNUSED, PyObject 
 *args) {
  virDomainPtr domain;
  PyObject *pyobj_domain;
 @@ -4605,6 +4689,7 @@ static PyMethodDef libvirtMethods[] = {
  {(char *) virDomainGetAutostart, libvirt_virDomainGetAutostart, 
 METH_VARARGS, NULL},
  {(char *) virNetworkGetAutostart, libvirt_virNetworkGetAutostart, 
 METH_VARARGS, NULL},
  {(char *) virDomainBlockStats, libvirt_virDomainBlockStats, 
 METH_VARARGS, NULL},
 +{(char *) virDomainBlockStatsFlags, libvirt_virDomainBlockStatsFlags, 
 METH_VARARGS, NULL},
  {(char 

Re: [libvirt] [PATCH 8/8] latency: Update cmdBlkStats to use new API

2011-09-05 Thread Osier Yang

于 2011年09月06日 11:59, Daniel Veillard 写道:

On Mon, Sep 05, 2011 at 04:38:35PM +0800, Osier Yang wrote:

The modified function fallbacks to use virDomainBlockStats if
virDomainBlockStatsFlags is not supported by the hypervisor driver.
If the new API is supported, it will be invoked instead of the
old API.
---
  tools/virsh.c |  104 ++---
  1 files changed, 84 insertions(+), 20 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index c7240e5..ea41221 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1070,6 +1070,9 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd)
  virDomainPtr dom;
  const char *name = NULL, *device = NULL;
  struct _virDomainBlockStats stats;
+virTypedParameterPtr params = NULL;
+int rc, nparams = 0;
+bool ret = false;

  if (!vshConnectionUsability (ctl, ctl-conn))
  return false;
@@ -1077,34 +1080,95 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd)
  if (!(dom = vshCommandOptDomain (ctl, cmd,name)))
  return false;

-if (vshCommandOptString (cmd, device,device)= 0) {
-virDomainFree(dom);
-return false;
-}
+if (vshCommandOptString (cmd, device,device)= 0)
+goto cleanup;

-if (virDomainBlockStats (dom, device,stats, sizeof stats) == -1) {
-vshError(ctl, _(Failed to get block stats %s %s), name, device);
-virDomainFree(dom);
-return false;
-}
+rc = virDomainBlockStatsFlags(dom, device, NULL,nparams, 0);

-if (stats.rd_req= 0)
-vshPrint (ctl, %s rd_req %lld\n, device, stats.rd_req);
+/* It might fail when virDomainBlockStatsFlags is not
+ * supported on older libvirt, fallback to use virDomainBlockStats
+ * then.
+ */
+if (rc  0) {
+if (last_error-code != VIR_ERR_NO_SUPPORT) {
+virshReportError(ctl);
+goto cleanup;
+} else {
+virFreeError(last_error);
+last_error = NULL;

-if (stats.rd_bytes= 0)
-vshPrint (ctl, %s rd_bytes %lld\n, device, stats.rd_bytes);
+if (virDomainBlockStats (dom, device,stats,
+ sizeof stats) == -1) {
+vshError(ctl, _(Failed to get block stats %s %s),
+ name, device);
+goto cleanup;
+}
+
+if (stats.rd_req= 0)
+vshPrint (ctl, %s rd_req %lld\n, device, stats.rd_req);

-if (stats.wr_req= 0)
-vshPrint (ctl, %s wr_req %lld\n, device, stats.wr_req);
+if (stats.rd_bytes= 0)
+vshPrint (ctl, %s rd_bytes %lld\n, device, stats.rd_bytes);

-if (stats.wr_bytes= 0)
-vshPrint (ctl, %s wr_bytes %lld\n, device, stats.wr_bytes);
+if (stats.wr_req= 0)
+vshPrint (ctl, %s wr_req %lld\n, device, stats.wr_req);

-if (stats.errs= 0)
-vshPrint (ctl, %s errs %lld\n, device, stats.errs);
+if (stats.wr_bytes= 0)
+vshPrint (ctl, %s wr_bytes %lld\n, device, stats.wr_bytes);

+if (stats.errs= 0)
+vshPrint (ctl, %s errs %lld\n, device, stats.errs);
+}
+} else {
+params = vshMalloc(ctl, sizeof(*params) * nparams);
+memset(params, 0, sizeof(*params) * nparams);
+
+if (virDomainBlockStatsFlags (dom, device, params,nparams, 0)  0) {
+vshError(ctl, _(Failed to get block stats %s %s), name, device);
+goto cleanup;
+}
+
+int i;
+/* XXX: The output sequence will be different. */
+for (i = 0; i  nparams; i++) {
+switch(params[i].type) {
+case VIR_TYPED_PARAM_INT:
+vshPrint (ctl, %s %s %d\n, device,
+  params[i].field, params[i].value.i);
+break;
+case VIR_TYPED_PARAM_UINT:
+vshPrint (ctl, %s %s %u\n, device,
+  params[i].field, params[i].value.ui);
+break;
+case VIR_TYPED_PARAM_LLONG:
+vshPrint (ctl, %s %s %lld\n, device,
+  params[i].field, params[i].value.l);
+break;
+case VIR_TYPED_PARAM_ULLONG:
+vshPrint (ctl, %s %s %llu\n, device,
+  params[i].field, params[i].value.ul);
+break;
+case VIR_TYPED_PARAM_DOUBLE:
+vshPrint (ctl, %s %s %f\n, device,
+  params[i].field, params[i].value.d);
+break;
+case VIR_TYPED_PARAM_BOOLEAN:
+vshPrint (ctl, %s %s %s\n, device,
+  params[i].field, params[i].value.b ? _(yes) : 
_(no));
+break;
+default:
+vshError(ctl, _(unimplemented block statistics parameter 
type));
+}
+
+}
+}
+
+ret = true;
+
+cleanup:
+VIR_FREE(params);