[libvirt] [PATCHv3 0/6] Add virNodeGetCpuTime() API

Hi, This is v3 of virNodeGetCpuTime() API. It returns cpu utilization or cumulative cpu time of the node from /proc/stat since node boots up. This patch only supports linux host. Changes v2->v3 - Change user I/F. It is able to request what the user want by the @flags. - Minor change of virsh nodecputime I/F. v1->v2 - Change user I/F like virDomainGetMemoryStats() - It can return either cpu utilization or cumulative cpu time of the node depends on each driver. Minoru Usui (6): [v3 1/6] virNodeGetCPUTime: Expose new API [v3 2/6] virNodeGetCPUTime: Define internal driver API [v3 3/6] virNodeGetCPUTime: Implement public API [v3 4/6] virNodeGetCPUTime: Implement remote protocol [v3 5/6] virNodeGetCPUTime: Implement virsh support [v3 6/6] virNodeGetCPUTime: Implement linux support daemon/remote.c | 46 +++++++++++++++++++ daemon/remote_dispatch_args.h | 1 + daemon/remote_dispatch_prototypes.h | 8 +++ daemon/remote_dispatch_ret.h | 1 + daemon/remote_dispatch_table.h | 5 ++ include/libvirt/libvirt.h.in | 50 +++++++++++++++++++++ src/driver.h | 8 +++ src/esx/esx_driver.c | 1 + src/libvirt.c | 79 ++++++++++++++++++++++++++++++++ src/libvirt_private.syms | 1 + src/libvirt_public.syms | 5 ++ src/libxl/libxl_driver.c | 1 + src/lxc/lxc_driver.c | 1 + src/nodeinfo.c | 78 ++++++++++++++++++++++++++++++++ src/nodeinfo.h | 5 ++- src/openvz/openvz_driver.c | 1 + src/phyp/phyp_driver.c | 1 + src/qemu/qemu_driver.c | 1 + src/remote/remote_driver.c | 37 +++++++++++++++ src/remote/remote_protocol.c | 22 +++++++++ src/remote/remote_protocol.h | 20 ++++++++ src/remote/remote_protocol.x | 15 ++++++- src/remote_protocol-structs | 10 ++++ 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 + tools/virsh.c | 84 +++++++++++++++++++++++++++++++++++ tools/virsh.pod | 4 ++ 31 files changed, 489 insertions(+), 2 deletions(-) -- Minoru Usui <usui@mxm.nes.nec.co.jp>

virNodeGetCPUTime: Expose new API Signed-off-by: Minoru Usui <usui@mxm.nes.nec.co.jp> --- include/libvirt/libvirt.h.in | 50 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 2 files changed, 55 insertions(+), 0 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 5783303..25cc08c 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -228,6 +228,51 @@ struct _virNodeInfo { unsigned int threads;/* number of threads per core */ }; +/** + * virNodeCpuTime: + */ + +/** + * virNodeCpuTimeFlags + * + * Flags when getting cpu statistics of the node. + */ +typedef enum { + /* + * The cumulative CPU time which spends by kernel, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_KERNEL = 1, + /* + * The cumulative CPU time which spends by user processes, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_USER = 2, + /* + * The cumulative idle CPU time, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_IDLE = 4, + /* + * The cumulative I/O wait CPU time, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_IOWAIT = 8, + /* + * The CPU utilization. + * The usage value is in percent and 100% represents all CPUs on + * the server. + */ + VIR_NODE_CPU_TIME_UTILIZATION = 16, + + /* + * The number of statistics supported by this version of the interface. + * To add new statistics, add them to the enum and increase this value. + */ + VIR_NODE_CPU_TIME_MAX = 32 +} virNodeCpuTimeFlags; + +#define VIR_NODE_CPU_TIME_MASK (VIR_NODE_CPU_TIME_MAX - 1) /** * virDomainSchedParameterType: @@ -593,6 +638,11 @@ int virNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info); char * virConnectGetCapabilities (virConnectPtr conn); +int virNodeGetCpuTime (virConnectPtr conn, + unsigned long long *stats, + unsigned int nr_stats, + unsigned int flags); + unsigned long long virNodeGetFreeMemory (virConnectPtr conn); int virNodeGetSecurityModel (virConnectPtr conn, diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index b4aed41..d292bdd 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -436,4 +436,9 @@ LIBVIRT_0.9.0 { virStorageVolUpload; } LIBVIRT_0.8.8; +LIBVIRT_0.9.1 { + global: + virNodeGetCpuTime; +} LIBVIRT_0.9.0; + # .... define new API here using predicted next version number .... -- 1.7.1 -- Minoru Usui <usui@mxm.nes.nec.co.jp>

On Thu, Apr 14, 2011 at 07:08:44PM +0900, Minoru Usui wrote:
virNodeGetCPUTime: Expose new API
Signed-off-by: Minoru Usui <usui@mxm.nes.nec.co.jp> --- include/libvirt/libvirt.h.in | 50 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 2 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 5783303..25cc08c 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -228,6 +228,51 @@ struct _virNodeInfo { unsigned int threads;/* number of threads per core */ };
+/** + * virNodeCpuTime: + */ + +/** + * virNodeCpuTimeFlags + * + * Flags when getting cpu statistics of the node. + */ +typedef enum { + /* + * The cumulative CPU time which spends by kernel, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_KERNEL = 1, + /* + * The cumulative CPU time which spends by user processes, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_USER = 2, + /* + * The cumulative idle CPU time, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_IDLE = 4, + /* + * The cumulative I/O wait CPU time, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_IOWAIT = 8, + /* + * The CPU utilization. + * The usage value is in percent and 100% represents all CPUs on + * the server. + */ + VIR_NODE_CPU_TIME_UTILIZATION = 16, + + /* + * The number of statistics supported by this version of the interface. + * To add new statistics, add them to the enum and increase this value. + */ + VIR_NODE_CPU_TIME_MAX = 32 +} virNodeCpuTimeFlags; + +#define VIR_NODE_CPU_TIME_MASK (VIR_NODE_CPU_TIME_MAX - 1)
/** * virDomainSchedParameterType: @@ -593,6 +638,11 @@ int virNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info); char * virConnectGetCapabilities (virConnectPtr conn);
+int virNodeGetCpuTime (virConnectPtr conn, + unsigned long long *stats, + unsigned int nr_stats, + unsigned int flags); + unsigned long long virNodeGetFreeMemory (virConnectPtr conn);
I'm sorry, but NACK to this API design. Your v2 design was consistent with the design of the other stats APIs we provide & better than this IMHO. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Hi, Daniel. On Mon, 18 Apr 2011 12:32:03 +0100 "Daniel P. Berrange" <berrange@redhat.com> wrote:
On Thu, Apr 14, 2011 at 07:08:44PM +0900, Minoru Usui wrote:
virNodeGetCPUTime: Expose new API
Signed-off-by: Minoru Usui <usui@mxm.nes.nec.co.jp> --- include/libvirt/libvirt.h.in | 50 ++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 ++++ 2 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 5783303..25cc08c 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -228,6 +228,51 @@ struct _virNodeInfo { unsigned int threads;/* number of threads per core */ };
+/** + * virNodeCpuTime: + */ + +/** + * virNodeCpuTimeFlags + * + * Flags when getting cpu statistics of the node. + */ +typedef enum { + /* + * The cumulative CPU time which spends by kernel, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_KERNEL = 1, + /* + * The cumulative CPU time which spends by user processes, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_USER = 2, + /* + * The cumulative idle CPU time, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_IDLE = 4, + /* + * The cumulative I/O wait CPU time, + * when the node booting up.(in nanoseconds). + */ + VIR_NODE_CPU_TIME_IOWAIT = 8, + /* + * The CPU utilization. + * The usage value is in percent and 100% represents all CPUs on + * the server. + */ + VIR_NODE_CPU_TIME_UTILIZATION = 16, + + /* + * The number of statistics supported by this version of the interface. + * To add new statistics, add them to the enum and increase this value. + */ + VIR_NODE_CPU_TIME_MAX = 32 +} virNodeCpuTimeFlags; + +#define VIR_NODE_CPU_TIME_MASK (VIR_NODE_CPU_TIME_MAX - 1)
/** * virDomainSchedParameterType: @@ -593,6 +638,11 @@ int virNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info); char * virConnectGetCapabilities (virConnectPtr conn);
+int virNodeGetCpuTime (virConnectPtr conn, + unsigned long long *stats, + unsigned int nr_stats, + unsigned int flags); + unsigned long long virNodeGetFreeMemory (virConnectPtr conn);
I'm sorry, but NACK to this API design. Your v2 design was consistent with the design of the other stats APIs we provide & better than this IMHO.
I understand. I drop this v3 design.
Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
-- Minoru Usui <usui@mxm.nes.nec.co.jp>

virNodeGetCPUTime: Define internal driver API Signed-off-by: Minoru Usui <usui@mxm.nes.nec.co.jp> --- src/driver.h | 8 ++++++++ src/esx/esx_driver.c | 1 + 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 + 14 files changed, 21 insertions(+), 0 deletions(-) diff --git a/src/driver.h b/src/driver.h index a8b79e6..0c9f96e 100644 --- a/src/driver.h +++ b/src/driver.h @@ -347,6 +347,13 @@ typedef struct _virDriver virDriver; typedef virDriver *virDriverPtr; typedef int + (*virDrvNodeGetCpuTime) + (virConnectPtr conn, + unsigned long long *stats, + unsigned int nr_stats, + unsigned int flags); + +typedef int (*virDrvNodeGetCellsFreeMemory) (virConnectPtr conn, unsigned long long *freeMems, @@ -602,6 +609,7 @@ struct _virDriver { virDrvDomainBlockPeek domainBlockPeek; virDrvDomainMemoryPeek domainMemoryPeek; virDrvDomainGetBlockInfo domainGetBlockInfo; + virDrvNodeGetCpuTime nodeGetCpuTime; virDrvNodeGetCellsFreeMemory nodeGetCellsFreeMemory; virDrvNodeGetFreeMemory getFreeMemory; virDrvDomainEventRegister domainEventRegister; diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index deda372..6e55949 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -4638,6 +4638,7 @@ static virDriver esxDriver = { NULL, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* domainGetBlockInfo */ + NULL, /* nodeGetCpuTime */ NULL, /* nodeGetCellsFreeMemory */ esxNodeGetFreeMemory, /* nodeGetFreeMemory */ NULL, /* domainEventRegister */ diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 3040914..8dcc5ff 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -2626,6 +2626,7 @@ static virDriver libxlDriver = { NULL, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* domainGetBlockInfo */ + NULL, /* nodeGetCpuTime */ NULL, /* nodeGetCellsFreeMemory */ libxlNodeGetFreeMemory, /* getFreeMemory */ libxlDomainEventRegister, /* domainEventRegister */ diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index e905302..0e0c325 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2869,6 +2869,7 @@ static virDriver lxcDriver = { NULL, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* domainGetBlockInfo */ + nodeGetCpuTime, /* nodeGetCpuTime */ nodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */ nodeGetFreeMemory, /* getFreeMemory */ lxcDomainEventRegister, /* domainEventRegister */ diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 4af28e9..3b4eae5 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -1630,6 +1630,7 @@ static virDriver openvzDriver = { NULL, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* domainGetBlockInfo */ + NULL, /* nodeGetCpuTime */ NULL, /* nodeGetCellsFreeMemory */ NULL, /* getFreeMemory */ NULL, /* domainEventRegister */ diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index a1b6819..46a5717 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -4595,6 +4595,7 @@ static virDriver phypDriver = { NULL, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* domainGetBlockInfo */ + NULL, /* nodeGetCpuTime */ NULL, /* nodeGetCellsFreeMemory */ NULL, /* getFreeMemory */ NULL, /* domainEventRegister */ diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 04a5f65..b73c702 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6933,6 +6933,7 @@ static virDriver qemuDriver = { qemudDomainBlockPeek, /* domainBlockPeek */ qemudDomainMemoryPeek, /* domainMemoryPeek */ qemuDomainGetBlockInfo, /* domainGetBlockInfo */ + nodeGetCpuTime, /* nodeGetCpuTime */ nodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */ nodeGetFreeMemory, /* getFreeMemory */ qemuDomainEventRegister, /* domainEventRegister */ diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index b979f71..ff48fa2 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -11264,6 +11264,7 @@ static virDriver remote_driver = { remoteDomainBlockPeek, /* domainBlockPeek */ remoteDomainMemoryPeek, /* domainMemoryPeek */ remoteDomainGetBlockInfo, /* domainGetBlockInfo */ + remoteNodeGetCpuTime, /* nodeGetCpuTime */ remoteNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */ remoteNodeGetFreeMemory, /* getFreeMemory */ remoteDomainEventRegister, /* domainEventRegister */ diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 17f5ad9..f122935 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -5410,6 +5410,7 @@ static virDriver testDriver = { NULL, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* domainGetBlockInfo */ + NULL, /* nodeGetCpuTime */ testNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */ NULL, /* getFreeMemory */ testDomainEventRegister, /* domainEventRegister */ diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 33849a0..87a3e41 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -2216,6 +2216,7 @@ static virDriver umlDriver = { umlDomainBlockPeek, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* domainGetBlockInfo */ + nodeGetCpuTime, /* nodeGetCpuTime */ nodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */ nodeGetFreeMemory, /* getFreeMemory */ NULL, /* domainEventRegister */ diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 0fbfba5..d500ab2 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -8600,6 +8600,7 @@ virDriver NAME(Driver) = { NULL, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* domainGetBlockInfo */ + NULL, /* nodeGetCpuTime */ nodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */ nodeGetFreeMemory, /* getFreeMemory */ #if VBOX_API_VERSION == 2002 || VBOX_API_VERSION == 4000 diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c index b5e416b..635aa59 100644 --- a/src/vmware/vmware_driver.c +++ b/src/vmware/vmware_driver.c @@ -970,6 +970,7 @@ static virDriver vmwareDriver = { NULL, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* domainGetBlockInfo */ + NULL, /* nodeGetCpuTime */ NULL, /* nodeGetCellsFreeMemory */ NULL, /* getFreeMemory */ NULL, /* domainEventRegister */ diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 9f47722..af18baa 100644 --- a/src/xen/xen_driver.c +++ b/src/xen/xen_driver.c @@ -2104,6 +2104,7 @@ static virDriver xenUnifiedDriver = { xenUnifiedDomainBlockPeek, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* domainGetBlockInfo */ + NULL, /* nodeGetCpuTime */ xenUnifiedNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */ xenUnifiedNodeGetFreeMemory, /* getFreeMemory */ xenUnifiedDomainEventRegister, /* domainEventRegister */ diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 60b23c7..6371d03 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -1852,6 +1852,7 @@ static virDriver xenapiDriver = { NULL, /* domainBlockPeek */ NULL, /* domainMemoryPeek */ NULL, /* domainGetBlockInfo */ + NULL, /* nodeGetCpuTime */ xenapiNodeGetCellsFreeMemory, /* nodeGetCellsFreeMemory */ xenapiNodeGetFreeMemory, /* getFreeMemory */ NULL, /* domainEventRegister */ -- 1.7.1 -- Minoru Usui <usui@mxm.nes.nec.co.jp>

virNodeGetCPUTime: Implement public API Signed-off-by: Minoru Usui <usui@mxm.nes.nec.co.jp> --- src/libvirt.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 79 insertions(+), 0 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index 0da9885..12d666d 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -14,6 +14,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <strings.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> @@ -4229,6 +4230,84 @@ error: } /** + * virNodeGetCpuTime: + * @stats: nr_stats-sized array of unsigned long long (returned) + * @nr_stats: number of cpu time statistics requested of the node. + * @flags: an OR'ed set of virNodeGetCpuTimeFlags + * + * This function provides cpu time statistics of the node. + * + * Up to 'nr_stats' elements of 'stats' will be populated with cpu + * time statistics of the node. Only statistics requested by the user + * will be returned. + * -1 will be returned, if requested statistics isn't supported by + * the driver or this version of libvirt. + * + * Cpu time Statistics(@flags): + * + * VIR_NODE_CPU_TIME_KERNEL: + * The cumulative CPU time which spends by kernel, + * when the node booting up.(nanoseconds) + * VIR_NODE_CPU_TIME_USER: + * The cumulative CPU time which spends by user processes, + * when the node booting up.(nanoseconds) + * VIR_NODE_CPU_TIME_IDLE: + * The cumulative idle CPU time, when the node booting up.(nanoseconds) + * VIR_NODE_CPU_TIME_IOWAIT: + * The cumulative I/O wait CPU time, when the node booting up.(nanoseconds) + * VIR_NODE_CPU_TIME_UTILIZATION: + * The CPU utilization. The usage value is in percent and 100% + * represents all CPUs on the server. + * + * Returns: The number of stats provided or -1 in case of failure. + */ +int virNodeGetCpuTime (virConnectPtr conn, unsigned long long *stats, + unsigned int nr_stats, unsigned int flags) +{ + unsigned long nr_stats_ret = 0; + unsigned int req_type; + int req_count = 0; + + VIR_DEBUG("conn=%p, stats=%p, nr_stats=%u", conn, stats, nr_stats); + + virResetLastError(); + + if (!VIR_IS_CONNECT (conn)) { + virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); + virDispatchError(NULL); + return 0; + } + + if (!stats || nr_stats == 0) + return 0; + + req_type = flags & VIR_NODE_CPU_TIME_MASK; + while (req_type) { + int bit_index; + + req_count++; + bit_index = ffs(req_type); + req_type &= ~(1 << (bit_index - 1)); + } + + if (nr_stats > req_count) + nr_stats = req_count; + + if (conn->driver->nodeGetCpuTime) { + nr_stats_ret = conn->driver->nodeGetCpuTime (conn, stats, nr_stats, flags); + if (nr_stats_ret == -1) + goto error; + return nr_stats_ret; + } + + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + virDispatchError(conn); + return -1; +} + +/** * virNodeGetFreeMemory: * @conn: pointer to the hypervisor connection * -- 1.7.1 -- Minoru Usui <usui@mxm.nes.nec.co.jp>

virNodeGetCPUTime: Implement remote protocol Signed-off-by: Minoru Usui <usui@mxm.nes.nec.co.jp> --- daemon/remote.c | 46 +++++++++++++++++++++++++++++++++++ daemon/remote_dispatch_args.h | 1 + daemon/remote_dispatch_prototypes.h | 8 ++++++ daemon/remote_dispatch_ret.h | 1 + daemon/remote_dispatch_table.h | 5 ++++ src/remote/remote_driver.c | 36 +++++++++++++++++++++++++++ src/remote/remote_protocol.c | 22 ++++++++++++++++ src/remote/remote_protocol.h | 20 +++++++++++++++ src/remote/remote_protocol.x | 15 ++++++++++- src/remote_protocol-structs | 10 +++++++ 10 files changed, 163 insertions(+), 1 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 5de1055..5cd5e6c 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -764,6 +764,52 @@ remoteDispatchNodeGetCellsFreeMemory(struct qemud_server *server ATTRIBUTE_UNUSE return 0; } +static int +remoteDispatchNodeGetCpuTime (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_message_header *hdr ATTRIBUTE_UNUSED, + remote_error *rerr, + remote_node_get_cpu_time_args *args, + remote_node_get_cpu_time_ret *ret) +{ + unsigned long long *stats; + unsigned int nr_stats, i; + + if (args->maxStats > REMOTE_NODE_CPU_TIME_MAX) { + remoteDispatchFormatError (rerr, "%s", + _("maxStats > REMOTE_NODE_CPU_TIME_MAX")); + return -1; + } + + /* Allocate stats array for making dispatch call */ + if (VIR_ALLOC_N(stats, args->maxStats) < 0) { + remoteDispatchOOMError(rerr); + return -1; + } + + nr_stats = virNodeGetCpuTime (conn, stats, args->maxStats, args->flags); + if (nr_stats == -1) { + VIR_FREE(stats); + remoteDispatchConnError(rerr, conn); + return -1; + } + + /* Allocate return buffer */ + if (VIR_ALLOC_N(ret->stats.stats_val, args->maxStats) < 0) { + VIR_FREE(stats); + remoteDispatchOOMError(rerr); + return -1; + } + + /* Copy the stats into the xdr return structure */ + for (i = 0; i < nr_stats; i++) + ret->stats.stats_val[i] = stats[i]; + + ret->stats.stats_len = nr_stats; + VIR_FREE(stats); + return 0; +} static int remoteDispatchNodeGetFreeMemory(struct qemud_server *server ATTRIBUTE_UNUSED, diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h index f9537d7..a757899 100644 --- a/daemon/remote_dispatch_args.h +++ b/daemon/remote_dispatch_args.h @@ -178,3 +178,4 @@ remote_domain_migrate_set_max_speed_args val_remote_domain_migrate_set_max_speed_args; remote_storage_vol_upload_args val_remote_storage_vol_upload_args; remote_storage_vol_download_args val_remote_storage_vol_download_args; + remote_node_get_cpu_time_args val_remote_node_get_cpu_time_args; diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h index 18bf41d..936ba23 100644 --- a/daemon/remote_dispatch_prototypes.h +++ b/daemon/remote_dispatch_prototypes.h @@ -1138,6 +1138,14 @@ static int remoteDispatchNodeGetCellsFreeMemory( remote_error *err, remote_node_get_cells_free_memory_args *args, remote_node_get_cells_free_memory_ret *ret); +static int remoteDispatchNodeGetCpuTime( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_message_header *hdr, + remote_error *err, + remote_node_get_cpu_time_args *args, + remote_node_get_cpu_time_ret *ret); static int remoteDispatchNodeGetFreeMemory( struct qemud_server *server, struct qemud_client *client, diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h index 114e832..dfed98b 100644 --- a/daemon/remote_dispatch_ret.h +++ b/daemon/remote_dispatch_ret.h @@ -140,3 +140,4 @@ remote_domain_is_updated_ret val_remote_domain_is_updated_ret; remote_get_sysinfo_ret val_remote_get_sysinfo_ret; remote_domain_get_blkio_parameters_ret val_remote_domain_get_blkio_parameters_ret; + remote_node_get_cpu_time_ret val_remote_node_get_cpu_time_ret; diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h index b39f7c2..5922d56 100644 --- a/daemon/remote_dispatch_table.h +++ b/daemon/remote_dispatch_table.h @@ -1052,3 +1052,8 @@ .args_filter = (xdrproc_t) xdr_remote_storage_vol_download_args, .ret_filter = (xdrproc_t) xdr_void, }, +{ /* NodeGetCpuTime => 210 */ + .fn = (dispatch_fn) remoteDispatchNodeGetCpuTime, + .args_filter = (xdrproc_t) xdr_remote_node_get_cpu_time_args, + .ret_filter = (xdrproc_t) xdr_remote_node_get_cpu_time_ret, +}, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index ff48fa2..7bfa747 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -1938,6 +1938,42 @@ done: } static int +remoteNodeGetCpuTime (virConnectPtr conn, + unsigned long long *stats, + unsigned int nr_stats, + unsigned int flags) +{ + int rv = -1; + remote_node_get_cpu_time_args args; + remote_node_get_cpu_time_ret ret; + struct private_data *priv = conn->privateData; + unsigned int i; + + remoteDriverLock(priv); + + args.maxStats = nr_stats; + args.flags = flags; + memset (&ret, 0, sizeof ret); + + if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_CPU_TIME, + (xdrproc_t) xdr_remote_node_get_cpu_time_args, + (char *) &args, + (xdrproc_t) xdr_remote_node_get_cpu_time_ret, + (char *) &ret) == -1) + goto done; + + for (i = 0; i < ret.stats.stats_len; i++) + stats[i] = ret.stats.stats_val[i]; + + rv = ret.stats.stats_len; + xdr_free((xdrproc_t) xdr_remote_node_get_cpu_time_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return rv; +} + +static int remoteNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *freeMems, int startCell, diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c index 5604371..a5c658a 100644 --- a/src/remote/remote_protocol.c +++ b/src/remote/remote_protocol.c @@ -607,6 +607,28 @@ xdr_remote_get_capabilities_ret (XDR *xdrs, remote_get_capabilities_ret *objp) } bool_t +xdr_remote_node_get_cpu_time_args (XDR *xdrs, remote_node_get_cpu_time_args *objp) +{ + + if (!xdr_u_int (xdrs, &objp->maxStats)) + return FALSE; + if (!xdr_u_int (xdrs, &objp->flags)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_node_get_cpu_time_ret (XDR *xdrs, remote_node_get_cpu_time_ret *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->stats.stats_val; + + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->stats.stats_len, REMOTE_NODE_CPU_TIME_MAX, + sizeof (uint64_t), (xdrproc_t) xdr_uint64_t)) + return FALSE; + return TRUE; +} + +bool_t xdr_remote_node_get_cells_free_memory_args (XDR *xdrs, remote_node_get_cells_free_memory_args *objp) { diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h index d9bf151..b254919 100644 --- a/src/remote/remote_protocol.h +++ b/src/remote/remote_protocol.h @@ -55,6 +55,7 @@ typedef remote_nonnull_string *remote_string; #define REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX 16 #define REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX 16 #define REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX 16 +#define REMOTE_NODE_CPU_TIME_MAX 8 #define REMOTE_NODE_MAX_CELLS 1024 #define REMOTE_AUTH_SASL_DATA_MAX 65536 #define REMOTE_AUTH_TYPE_LIST_MAX 20 @@ -304,6 +305,20 @@ struct remote_get_capabilities_ret { }; typedef struct remote_get_capabilities_ret remote_get_capabilities_ret; +struct remote_node_get_cpu_time_args { + u_int maxStats; + u_int flags; +}; +typedef struct remote_node_get_cpu_time_args remote_node_get_cpu_time_args; + +struct remote_node_get_cpu_time_ret { + struct { + u_int stats_len; + uint64_t *stats_val; + } stats; +}; +typedef struct remote_node_get_cpu_time_ret remote_node_get_cpu_time_ret; + struct remote_node_get_cells_free_memory_args { int startCell; int maxCells; @@ -2413,6 +2428,7 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207, REMOTE_PROC_STORAGE_VOL_UPLOAD = 208, REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209, + REMOTE_PROC_NODE_GET_CPU_TIME = 210, }; typedef enum remote_procedure remote_procedure; @@ -2486,6 +2502,8 @@ extern bool_t xdr_remote_get_max_vcpus_args (XDR *, remote_get_max_vcpus_args*) extern bool_t xdr_remote_get_max_vcpus_ret (XDR *, remote_get_max_vcpus_ret*); extern bool_t xdr_remote_node_get_info_ret (XDR *, remote_node_get_info_ret*); extern bool_t xdr_remote_get_capabilities_ret (XDR *, remote_get_capabilities_ret*); +extern bool_t xdr_remote_node_get_cpu_time_args (XDR *, remote_node_get_cpu_time_args*); +extern bool_t xdr_remote_node_get_cpu_time_ret (XDR *, remote_node_get_cpu_time_ret*); extern bool_t xdr_remote_node_get_cells_free_memory_args (XDR *, remote_node_get_cells_free_memory_args*); extern bool_t xdr_remote_node_get_cells_free_memory_ret (XDR *, remote_node_get_cells_free_memory_ret*); extern bool_t xdr_remote_node_get_free_memory_ret (XDR *, remote_node_get_free_memory_ret*); @@ -2843,6 +2861,8 @@ extern bool_t xdr_remote_get_max_vcpus_args (); extern bool_t xdr_remote_get_max_vcpus_ret (); extern bool_t xdr_remote_node_get_info_ret (); extern bool_t xdr_remote_get_capabilities_ret (); +extern bool_t xdr_remote_node_get_cpu_time_args (); +extern bool_t xdr_remote_node_get_cpu_time_ret (); extern bool_t xdr_remote_node_get_cells_free_memory_args (); extern bool_t xdr_remote_node_get_cells_free_memory_ret (); extern bool_t xdr_remote_node_get_free_memory_ret (); diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 675eccd..0e801c2 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -134,6 +134,9 @@ const REMOTE_DOMAIN_BLKIO_PARAMETERS_MAX = 16; /* Upper limit on list of memory parameters. */ const REMOTE_DOMAIN_MEMORY_PARAMETERS_MAX = 16; +/* Upper limit on list of cpu time stats. */ +const REMOTE_NODE_CPU_TIME_MAX = 8; + /* Upper limit on number of NUMA cells */ const REMOTE_NODE_MAX_CELLS = 1024; @@ -440,6 +443,15 @@ struct remote_get_capabilities_ret { remote_nonnull_string capabilities; }; +struct remote_node_get_cpu_time_args { + u_int maxStats; + u_int flags; +}; + +struct remote_node_get_cpu_time_ret { + unsigned hyper stats<REMOTE_NODE_CPU_TIME_MAX>; +}; + struct remote_node_get_cells_free_memory_args { int startCell; int maxCells; @@ -2176,7 +2188,8 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 206, REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207, REMOTE_PROC_STORAGE_VOL_UPLOAD = 208, - REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209 + REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209, + REMOTE_PROC_NODE_GET_CPU_TIME = 210 /* * Notice how the entries are grouped in sets of 10 ? diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 944553c..3c63695 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -151,6 +151,16 @@ struct remote_node_get_info_ret { struct remote_get_capabilities_ret { remote_nonnull_string capabilities; }; +struct remote_node_get_cpu_time_args { + u_int maxStats; + u_int flags; +}; +struct remote_node_get_cpu_time_ret { + struct { + u_int stats_len; + uint64_t *stats_val; + } stats; +}; struct remote_node_get_cells_free_memory_args { int startCell; int maxCells; -- 1.7.1 -- Minoru Usui <usui@mxm.nes.nec.co.jp>

virNodeGetCPUTime: Implement virsh support Add nodecputime subcommand to virsh. This subcommand prints below output. [Linux] # virsh nodecputime usage : 0.5% user : 0.0% system: 0.5% idle : 99.5% iowait: 0.0% [can get cpu utilization directly(ESX?)] # virsh nodecputime usage : 0.5% idle : 99.5% Signed-off-by: Minoru Usui <usui@mxm.nes.nec.co.jp> --- tools/virsh.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 4 ++ 2 files changed, 88 insertions(+), 0 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 2e35021..0d22a13 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -3427,6 +3427,89 @@ cmdNodeinfo(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) } /* + * "nodecputime" command + */ +static const vshCmdInfo info_nodecputime[] = { + {"help", N_("Prints cpu utilizatoin of the node.")}, + {"desc", N_("Returns cpu utilizatoin of the node.(%)")}, + {NULL, NULL} +}; + +static int +cmdNodeCpuTime(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) +{ + int i, sleep_done = FALSE; + unsigned long long stats[4]; + int nr_stats; + unsigned int flags; + struct cpu_time { + unsigned long long user; + unsigned long long sys; + unsigned long long idle; + unsigned long long iowait; + } cpu_time[2]; + double user_time, sys_time, idle_time, iowait_time, total_time; + + if (!vshConnectionUsability(ctl, ctl->conn)) + return FALSE; + + /* Get cpu utilization directly */ + memset(stats, 0, sizeof(unsigned long long) * 4); + flags = VIR_NODE_CPU_TIME_UTILIZATION; + nr_stats = virNodeGetCpuTime(ctl->conn, stats, 1, flags); + if (nr_stats > 0) { + vshPrint(ctl, "%-15s %5.1lf%%\n", _("usage:"), (double)stats[0]); + vshPrint(ctl, "%-15s %5.1lf%%\n", _("idle :"), 100 - (double)stats[0]); + return TRUE; + } + + /* Calculate cpu utilization by getting cpu time two times */ + memset(cpu_time, 0, sizeof(struct cpu_time) * 2); + for (i = 0; i < 2; i++) { + memset(stats, 0, sizeof(unsigned long long) * 4); + flags = (VIR_NODE_CPU_TIME_KERNEL | + VIR_NODE_CPU_TIME_USER | + VIR_NODE_CPU_TIME_IDLE | + VIR_NODE_CPU_TIME_IOWAIT); + nr_stats = virNodeGetCpuTime(ctl->conn, stats, 4, flags); + if (nr_stats != 4) { + vshError(ctl, "%s", _("failed to get cpu time of the node.")); + return FALSE; + } + + cpu_time[i].sys = stats[0]; + cpu_time[i].user = stats[1]; + cpu_time[i].idle = stats[2]; + cpu_time[i].iowait = stats[3]; + + if (sleep_done == FALSE) { + sleep(1); + sleep_done = TRUE; + } + } + + user_time = cpu_time[1].user - cpu_time[0].user; + sys_time = cpu_time[1].sys - cpu_time[0].sys; + idle_time = cpu_time[1].idle - cpu_time[0].idle; + iowait_time = cpu_time[1].iowait - cpu_time[0].iowait; + total_time = user_time + sys_time + idle_time + iowait_time; + + vshPrint(ctl, "%-15s %5.1lf%%\n", + _("usage :"), (user_time + sys_time) / total_time * 100); + vshPrint(ctl, "%-15s %5.1lf%%\n", + _(" user :"), user_time / total_time * 100); + vshPrint(ctl, "%-15s %5.1lf%%\n", + _(" system:"), sys_time / total_time * 100); + + vshPrint(ctl, "%-15s %5.1lf%%\n", + _("idle :"), idle_time / total_time * 100); + vshPrint(ctl, "%-15s %5.1lf%%\n", + _("iowait:"), iowait_time / total_time * 100); + + return TRUE; +} + +/* * "capabilities" command */ static const vshCmdInfo info_capabilities[] = { @@ -10891,6 +10974,7 @@ static const vshCmdDef hostAndHypervisorCmds[] = { {"freecell", cmdFreecell, opts_freecell, info_freecell}, {"hostname", cmdHostname, NULL, info_hostname}, {"nodeinfo", cmdNodeinfo, NULL, info_nodeinfo}, + {"nodecputime", cmdNodeCpuTime, NULL, info_nodecputime}, {"qemu-monitor-command", cmdQemuMonitorCommand, opts_qemu_monitor_command, info_qemu_monitor_command}, {"sysinfo", cmdSysinfo, NULL, info_sysinfo}, {"uri", cmdURI, NULL, info_uri}, diff --git a/tools/virsh.pod b/tools/virsh.pod index 2a708f6..8e3cd3e 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -237,6 +237,10 @@ Print the XML representation of the hypervisor sysinfo, if available. Returns basic information about the node, like number and type of CPU, and size of the physical memory. +=item B<nodecputime> + +Returns cpu utilization of the node. + =item B<capabilities> Print an XML document describing the capabilities of the hypervisor -- 1.7.1 -- Minoru Usui <usui@mxm.nes.nec.co.jp>

virNodeGetCPUTime: Implement linux support Signed-off-by: Minoru Usui <usui@mxm.nes.nec.co.jp> --- src/libvirt_private.syms | 1 + src/nodeinfo.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++ src/nodeinfo.h | 5 ++- 3 files changed, 83 insertions(+), 1 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 54e4482..70d4a61 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -651,6 +651,7 @@ virNodeDeviceObjUnlock; # nodeinfo.h nodeCapsInitNUMA; +nodeGetCpuTime; nodeGetCellsFreeMemory; nodeGetFreeMemory; nodeGetInfo; diff --git a/src/nodeinfo.c b/src/nodeinfo.c index 5d40aca..06bb4f9 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -57,12 +57,16 @@ #ifdef __linux__ # define CPUINFO_PATH "/proc/cpuinfo" # define CPU_SYS_PATH "/sys/devices/system/cpu" +# define PROCSTAT_PATH "/proc/stat" /* NB, this is not static as we need to call it from the testsuite */ int linuxNodeInfoCPUPopulate(FILE *cpuinfo, virNodeInfoPtr nodeinfo, bool need_hyperthreads); +int linuxNodeCpuTime(FILE *procstat, unsigned long long *stats, + unsigned int nr_stats ATTRIBUTE_UNUSED, unsigned int flags); + /* Return the positive decimal contents of the given * CPU_SYS_PATH/cpu%u/FILE, or -1 on error. If MISSING_OK and the * file could not be found, return 1 instead of an error; this is @@ -322,6 +326,53 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo, return 0; } +#define TICK_TO_NSEC (1000ull * 1000ull * 1000ull / sysconf(_SC_CLK_TCK)) + +int linuxNodeCpuTime(FILE *procstat, unsigned long long *stats, + unsigned int nr_stats ATTRIBUTE_UNUSED, unsigned int flags) +{ + char line[1024]; + unsigned long long usr, ni, sys, idle, iowait; + unsigned long long irq, softirq, steal, guest, guest_nice; + + if (flags & VIR_NODE_CPU_TIME_UTILIZATION) { + nodeReportError(VIR_ERR_INVALID_ARG, "%s", + _("VIR_NODE_CPU_TIME_UTILIZATOIN not supported on this platform.")); + return -1; + } + + while (fgets(line, sizeof(line), procstat) != NULL) { + char *buf = line; + int idx = 0; + + if (STRPREFIX(buf, "cpu ")) { /* aka total logical CPU time */ + if (sscanf(buf, + "%*s %llu %llu %llu %llu %llu" // user ~ iowait + "%llu %llu %llu %llu %llu", // irq ~ guest_nice + &usr, &ni, &sys, &idle, &iowait, + &irq, &softirq, &steal, &guest, &guest_nice) < 4) { + continue; + } + + if (VIR_NODE_CPU_TIME_KERNEL) + stats[idx++] = (sys + irq + softirq) * TICK_TO_NSEC; + + if (VIR_NODE_CPU_TIME_USER) + stats[idx++] = (usr + ni) * TICK_TO_NSEC; + + if (VIR_NODE_CPU_TIME_IDLE) + stats[idx++] = idle * TICK_TO_NSEC; + + if (VIR_NODE_CPU_TIME_IOWAIT) + stats[idx++] = iowait * TICK_TO_NSEC; + + return idx; + } + } + + nodeReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no \'cpu \' line found")); + return -1; +} #endif int nodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED, virNodeInfoPtr nodeinfo) { @@ -360,6 +411,33 @@ int nodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED, virNodeInfoPtr nodeinfo) { #endif } +int nodeGetCpuTime(virConnectPtr conn ATTRIBUTE_UNUSED, + unsigned long long *stats, + unsigned int nr_stats, + unsigned int flags) +{ + +#ifdef __linux__ + { + int ret; + FILE *procstat = fopen(PROCSTAT_PATH, "r"); + if (!procstat) { + virReportSystemError(errno, + _("cannot open %s"), PROCSTAT_PATH); + return -1; + } + ret = linuxNodeCpuTime(procstat, stats, nr_stats, flags); + VIR_FORCE_FCLOSE(procstat); + + return ret; + } +#else + nodeReportError(VIR_ERR_NO_SUPPORT, "%s", + _("node CPU time not implemented on this platform")); + return -1; +#endif +} + #if HAVE_NUMACTL # if LIBNUMA_API_VERSION <= 1 # define NUMA_MAX_N_CPUS 4096 diff --git a/src/nodeinfo.h b/src/nodeinfo.h index 88bac6c..6489cca 100644 --- a/src/nodeinfo.h +++ b/src/nodeinfo.h @@ -30,7 +30,10 @@ int nodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo); int nodeCapsInitNUMA(virCapsPtr caps); - +int nodeGetCpuTime(virConnectPtr conn ATTRIBUTE_UNUSED, + unsigned long long *stats, + unsigned int nr_stats, + unsigned int flags); int nodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *freeMems, int startCell, -- 1.7.1 -- Minoru Usui <usui@mxm.nes.nec.co.jp>
participants (2)
-
Daniel P. Berrange
-
Minoru Usui