On Tue, Jun 14, 2011 at 10:15:36AM +0100, Daniel P. Berrange wrote: > On Tue, Jun 07, 2011 at 10:02:55AM +0900, Minoru Usui wrote: > > virNodeGetCPUStats: Implement linux support > > > > Signed-off-by: Minoru Usui <usui@xxxxxxxxxxxxxxxxx> > > --- > > src/libvirt_private.syms | 1 + > > src/lxc/lxc_driver.c | 1 + > > src/nodeinfo.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++ > > src/nodeinfo.h | 6 ++- > > src/qemu/qemu_driver.c | 1 + > > src/uml/uml_driver.c | 1 + > > 6 files changed, 147 insertions(+), 1 deletions(-) > > > > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > > index e6ab870..a8c77f2 100644 > > --- a/src/libvirt_private.syms > > +++ b/src/libvirt_private.syms > > @@ -731,6 +731,7 @@ virNodeDeviceObjUnlock; > > > > # nodeinfo.h > > nodeCapsInitNUMA; > > +nodeGetCPUStats; > > nodeGetCellsFreeMemory; > > nodeGetFreeMemory; > > nodeGetInfo; > > diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c > > index 8eb87a2..3286154 100644 > > --- a/src/lxc/lxc_driver.c > > +++ b/src/lxc/lxc_driver.c > > @@ -2779,6 +2779,7 @@ static virDriver lxcDriver = { > > .domainSetSchedulerParameters = lxcSetSchedulerParameters, /* 0.5.0 */ > > .domainSetSchedulerParametersFlags = lxcSetSchedulerParametersFlags, /* 0.9.2 */ > > .domainInterfaceStats = lxcDomainInterfaceStats, /* 0.7.3 */ > > + .nodeGetCPUStats = nodeGetCPUStats, /* 0.9.3 */ > > .nodeGetCellsFreeMemory = nodeGetCellsFreeMemory, /* 0.6.5 */ > > .nodeGetFreeMemory = nodeGetFreeMemory, /* 0.6.5 */ > > .domainEventRegister = lxcDomainEventRegister, /* 0.7.0 */ > > diff --git a/src/nodeinfo.c b/src/nodeinfo.c > > index f55c83e..39afd0e 100644 > > --- a/src/nodeinfo.c > > +++ b/src/nodeinfo.c > > @@ -57,12 +57,20 @@ > > #ifdef __linux__ > > # define CPUINFO_PATH "/proc/cpuinfo" > > # define CPU_SYS_PATH "/sys/devices/system/cpu" > > +# define PROCSTAT_PATH "/proc/stat" > > + > > +# define LINUX_NB_CPU_STATS 4 > > > > /* NB, this is not static as we need to call it from the testsuite */ > > int linuxNodeInfoCPUPopulate(FILE *cpuinfo, > > virNodeInfoPtr nodeinfo, > > bool need_hyperthreads); > > > > +int linuxNodeGetCPUStats(FILE *procstat, > > + int cpuNum, > > + virCPUStatsPtr params, > > + int *nparams); > > + > > /* 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 > > @@ -378,6 +386,108 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo, > > return 0; > > } > > > > +#define TICK_TO_NSEC (1000ull * 1000ull * 1000ull / sysconf(_SC_CLK_TCK)) > > +#define CPU_HEADER_LEN 8 > > + > > +int linuxNodeGetCPUStats(FILE *procstat, > > + int cpuNum, > > + virCPUStatsPtr params, > > + int *nparams) > > +{ > > + int ret = -1; > > + char line[1024]; > > + unsigned long long usr, ni, sys, idle, iowait; > > + unsigned long long irq, softirq, steal, guest, guest_nice; > > + char cpu_header[CPU_HEADER_LEN]; > > + > > + if ((*nparams) == 0) { > > + /* Current number of cpu stats supported by linux */ > > + *nparams = LINUX_NB_CPU_STATS; > > + ret = 0; > > + goto cleanup; > > + } > > + > > + if ((*nparams) != LINUX_NB_CPU_STATS) { > > + nodeReportError(VIR_ERR_INVALID_ARG, > > + "%s", _("Invalid parameter count")); > > + goto cleanup; > > + } > > + > > + if (cpuNum == VIR_CPU_STATS_ALL_CPUS) { > > + strcpy(cpu_header, "cpu"); > > + } else { > > + sprintf(cpu_header, "cpu%d", cpuNum); > > + } > > cpu_header is declared to be 8 bytes in size, which only allows > for integers upto 4 digits long, before we get a buffer overflow > here. > > gnulib has some macro which can be used to declare a string buffer > large enough to hold an integer, but I can't remember what the > macro is called right now. Hopefully Eric will remind us shortly.... Jim Meyering reminded me that it is INT_BUFSIZE_BOUND. So eg you want todo char cpu_header[3 + INT_BUFSIZE_BOUND(cpuNum) + 1]; to allow enough space for 'cpu' + any cpuNum value formatted as a string + the trailing NULL. Regards, 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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list