[libvirt] [RFC][PATCHv1 2/5] libvirt - new API for getting percpu statistics of VM

KAMEZAWA Hiroyuki kamezawa.hiroyu at jp.fujitsu.com
Fri Apr 15 07:04:52 UTC 2011


Per (host) cpu activity of VMs are very insterested numbers
when running VMs on large SMPs. virt-top -1 mode tries to
provide the information. (But it's not implemented.)

This patch adds a libvirt interface to get per cpu statistics
of each nodes. This patch just adds an interface and driver
entry points. So,
  - doesn't include patches for python.
  - doesn't include any driver.

Following patches will add some drivers and codes for python.

Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu at jp.fujitsu.com>
---
 include/libvirt/libvirt.h.in |   13 ++++++++++
 src/driver.h                 |    6 ++++
 src/esx/esx_driver.c         |    1 +
 src/libvirt.c                |   55 ++++++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms      |    4 +++
 src/libxl/libxl_driver.c     |    1 +
 src/lxc/lxc_driver.c         |    1 +
 src/openvz/openvz_driver.c   |    1 +
 src/phyp/phyp_driver.c       |    1 +
 src/qemu/qemu_driver.c       |    1 +
 src/remote/remote_driver.c   |    1 +
 src/test/test_driver.c       |    1 +
 src/uml/uml_driver.c         |    1 +
 src/vbox/vbox_tmpl.c         |    1 +
 src/vmware/vmware_driver.c   |    1 +
 src/xen/xen_driver.c         |    1 +
 src/xenapi/xenapi_driver.c   |    1 +
 17 files changed, 91 insertions(+), 0 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 5783303..6b9292c 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -400,6 +400,13 @@ struct _virDomainMemoryStat {
 
 typedef virDomainMemoryStatStruct *virDomainMemoryStatPtr;
 
+typedef struct _virDomainPcpuStat virDomainPcpuStatStruct;
+
+struct _virDomainPcpuStat {
+    unsigned long long cpuTime;
+};
+
+typedef virDomainPcpuStatStruct *virDomainPcpuStatPtr;
 
 /* Domain core dump flags. */
 typedef enum {
@@ -923,6 +930,12 @@ int                     virDomainMemoryStats (virDomainPtr dom,
                                               virDomainMemoryStatPtr stats,
                                               unsigned int nr_stats,
                                               unsigned int flags);
+
+int                     virDomainPcpuStats (virDomainPtr dom,
+                                            virDomainPcpuStatPtr stats,
+                                            unsigned int nr_stats,
+                                            unsigned int flags);
+
 int                     virDomainBlockPeek (virDomainPtr dom,
                                             const char *path,
                                             unsigned long long offset,
diff --git a/src/driver.h b/src/driver.h
index a8b79e6..ee1dac7 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -291,6 +291,11 @@ typedef int
                     (virDomainPtr domain,
                      struct _virDomainMemoryStat *stats,
                      unsigned int nr_stats);
+typedef int
+    (*virDrvDomainPcpuStats)
+                    (virDomainPtr domain,
+                     struct _virDomainPcpuStat *stats,
+                     unsigned int nr_stats);
 
 typedef int
     (*virDrvDomainBlockPeek)
@@ -599,6 +604,7 @@ struct _virDriver {
     virDrvDomainBlockStats      domainBlockStats;
     virDrvDomainInterfaceStats  domainInterfaceStats;
     virDrvDomainMemoryStats     domainMemoryStats;
+    virDrvDomainPcpuStats       domainPcpuStats;
     virDrvDomainBlockPeek	domainBlockPeek;
     virDrvDomainMemoryPeek      domainMemoryPeek;
     virDrvDomainGetBlockInfo    domainGetBlockInfo;
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 50c631b..34a31f0 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -4632,6 +4632,7 @@ static virDriver esxDriver = {
     NULL,                            /* domainBlockStats */
     NULL,                            /* domainInterfaceStats */
     NULL,                            /* domainMemoryStats */
+    NULL,                            /* domainPcpuStats */
     NULL,                            /* domainBlockPeek */
     NULL,                            /* domainMemoryPeek */
     NULL,                            /* domainGetBlockInfo */
diff --git a/src/libvirt.c b/src/libvirt.c
index 0da9885..24ef621 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -4595,6 +4595,61 @@ error:
 }
 
 /**
+ * virDomainPcpuStats:
+ * @dom: pointer to the domain object
+ * @stats: nr_stats-sized array of stat structures (returned)
+ * @nr_stats: number of cpu statistics requested
+ * @flags: unused, always pass 0
+ *
+ * This function provides per-cpu statistics for the domain. 'cpu' here means
+ * not vcpu.
+ *
+ * Up to 'nr_stats' elements of 'stats' will be populated with cpu statistics
+ * from the domain.  Only statistics supported by the domain, the driver, and
+ * this version of libvirt will be returned.
+ *
+ * Now, only cpuTime per cpu is reported in nanoseconds.
+ *
+ * Returns: The number of stats provided or -1 in case of failure.
+ */
+int virDomainPcpuStats (virDomainPtr dom, virDomainPcpuStatPtr stats,
+                          unsigned int nr_stats, unsigned int flags)
+{
+    virConnectPtr conn;
+    unsigned long nr_stats_ret = 0;
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
+        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+    if (flags != 0) {
+        virLibDomainError(VIR_ERR_INVALID_ARG,
+                           _("flags must be zero"));
+        goto error;
+    }
+
+    if (!stats || nr_stats == 0)
+        return 0;
+
+    conn = dom->conn;
+    if (conn->driver->domainPcpuStats) {
+        nr_stats_ret = conn->driver->domainPcpuStats (dom, stats, nr_stats);
+        if (nr_stats_ret == -1)
+            goto error;
+        return nr_stats_ret;
+    }
+
+    virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(dom->conn);
+    return -1;
+}
+
+/**
  * virDomainBlockPeek:
  * @dom: pointer to the domain object
  * @path: path to the block device
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index b4aed41..312ba66 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -436,4 +436,8 @@ LIBVIRT_0.9.0 {
         virStorageVolUpload;
 } LIBVIRT_0.8.8;
 
+LIBVIRT_0.9.1 {
+    global:
+        virDomainPcpuStats;
+} LIBVIRT_0.9.0;
 # .... define new API here using predicted next version number ....
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 3040914..285dcaa 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -2623,6 +2623,7 @@ static virDriver libxlDriver = {
     NULL,                       /* domainBlockStats */
     NULL,                       /* domainInterfaceStats */
     NULL,                       /* domainMemoryStats */
+    NULL,                       /* domainPcpuStats */
     NULL,                       /* domainBlockPeek */
     NULL,                       /* domainMemoryPeek */
     NULL,                       /* domainGetBlockInfo */
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index e905302..9046a58 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -2866,6 +2866,7 @@ static virDriver lxcDriver = {
     NULL, /* domainBlockStats */
     lxcDomainInterfaceStats, /* domainInterfaceStats */
     NULL, /* domainMemoryStats */
+    NULL, /* domainPcpuStats */
     NULL, /* domainBlockPeek */
     NULL, /* domainMemoryPeek */
     NULL, /* domainGetBlockInfo */
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 4af28e9..0c0004d 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -1627,6 +1627,7 @@ static virDriver openvzDriver = {
     NULL, /* domainBlockStats */
     NULL, /* domainInterfaceStats */
     NULL, /* domainMemoryStats */
+    NULL, /* domainPcpuStats */
     NULL, /* domainBlockPeek */
     NULL, /* domainMemoryPeek */
     NULL, /* domainGetBlockInfo */
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index 3862c9c..ac62d62 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -4579,6 +4579,7 @@ static virDriver phypDriver = {
     NULL,                       /* domainBlockStats */
     NULL,                       /* domainInterfaceStats */
     NULL,                       /* domainMemoryStats */
+    NULL,                       /* domainPcpuStats */
     NULL,                       /* domainBlockPeek */
     NULL,                       /* domainMemoryPeek */
     NULL,                       /* domainGetBlockInfo */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c1a44c9..0a78a70 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6981,6 +6981,7 @@ static virDriver qemuDriver = {
     qemudDomainBlockStats, /* domainBlockStats */
     qemudDomainInterfaceStats, /* domainInterfaceStats */
     qemudDomainMemoryStats, /* domainMemoryStats */
+    NULL, /* domainPcpuStats */
     qemudDomainBlockPeek, /* domainBlockPeek */
     qemudDomainMemoryPeek, /* domainMemoryPeek */
     qemuDomainGetBlockInfo, /* domainGetBlockInfo */
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index b979f71..d00b9ee 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -11261,6 +11261,7 @@ static virDriver remote_driver = {
     remoteDomainBlockStats, /* domainBlockStats */
     remoteDomainInterfaceStats, /* domainInterfaceStats */
     remoteDomainMemoryStats, /* domainMemoryStats */
+    NULL,                   /* domainPcpuStats */
     remoteDomainBlockPeek, /* domainBlockPeek */
     remoteDomainMemoryPeek, /* domainMemoryPeek */
     remoteDomainGetBlockInfo, /* domainGetBlockInfo */
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 17f5ad9..0489492 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -5407,6 +5407,7 @@ static virDriver testDriver = {
     testDomainBlockStats, /* domainBlockStats */
     testDomainInterfaceStats, /* domainInterfaceStats */
     NULL, /* domainMemoryStats */
+    NULL, /* domainPcpuStats */
     NULL, /* domainBlockPeek */
     NULL, /* domainMemoryPeek */
     NULL, /* domainGetBlockInfo */
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 33849a0..f3372fa 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -2213,6 +2213,7 @@ static virDriver umlDriver = {
     NULL, /* domainBlockStats */
     NULL, /* domainInterfaceStats */
     NULL, /* domainMemoryStats */
+    NULL, /* domainPcpuStats */
     umlDomainBlockPeek, /* domainBlockPeek */
     NULL, /* domainMemoryPeek */
     NULL, /* domainGetBlockInfo */
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 3ca34dd..4467866 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -8602,6 +8602,7 @@ virDriver NAME(Driver) = {
     NULL, /* domainBlockStats */
     NULL, /* domainInterfaceStats */
     NULL, /* domainMemoryStats */
+    NULL, /* domainPcpuStats */
     NULL, /* domainBlockPeek */
     NULL, /* domainMemoryPeek */
     NULL, /* domainGetBlockInfo */
diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c
index bbfb1a4..d98ea45 100644
--- a/src/vmware/vmware_driver.c
+++ b/src/vmware/vmware_driver.c
@@ -967,6 +967,7 @@ static virDriver vmwareDriver = {
     NULL,                       /* domainBlockStats */
     NULL,                       /* domainInterfaceStats */
     NULL,                       /* domainMemoryStats */
+    NULL,                       /* domainPcpuStats */
     NULL,                       /* domainBlockPeek */
     NULL,                       /* domainMemoryPeek */
     NULL,                       /* domainGetBlockInfo */
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 9f47722..1a76623 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -2101,6 +2101,7 @@ static virDriver xenUnifiedDriver = {
     xenUnifiedDomainBlockStats, /* domainBlockStats */
     xenUnifiedDomainInterfaceStats, /* domainInterfaceStats */
     NULL, /* domainMemoryStats */
+    NULL, /* domainPcpuStats */
     xenUnifiedDomainBlockPeek, /* domainBlockPeek */
     NULL, /* domainMemoryPeek */
     NULL, /* domainGetBlockInfo */
diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c
index 60b23c7..62d83d8 100644
--- a/src/xenapi/xenapi_driver.c
+++ b/src/xenapi/xenapi_driver.c
@@ -1849,6 +1849,7 @@ static virDriver xenapiDriver = {
     NULL, /* domainBlockStats */
     NULL, /* domainInterfaceStats */
     NULL, /* domainMemoryStats */
+    NULL, /* domainPcpuStats */
     NULL, /* domainBlockPeek */
     NULL, /* domainMemoryPeek */
     NULL, /* domainGetBlockInfo */
-- 
1.7.4.1





More information about the libvir-list mailing list