[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] vm-stat utility



Below is a utility which outputs utilization CPU by domain and by phys CPU. We used this for some OLS work last year, and we have received some requests for the patch. We needed this utility because we wanted to know which and how much of a phys CPU a domain was consuming, and we wanted output to be easily redirected to a text file, to be processed later. This patch is quite old (and very rough on the edges), but it should still apply to current xen-unstable. It was originally based off xentop code (I am certain there are many lines in there, originally for xentop, which are not even needed for vm-stat). I should also state that its ability to attribute a domain's vCPU time to a pCPU is not very accurate anymore with the addition of credit scheduler and load balancing. When we did not load balance, it was pretty easy to assume a vCPU's time was all spent on one pCPU -not the case anymore. If you want accurate vCPU->pCPU usage, I think we would need some additional data in vcpu struct, or just pin vCPUs to pCPUS for your tests.

I am not sure if this utility is of any use to anyone these days, but I wanted to make it available just in case. I am not asking to have this included in xen, but if someone else finds it useful and wants to clean it up, have fun!

-Andrew

<signed-off-by: Andrew Theurer habanero@xxxxxxxxxx>

diff -Naurp 1/tools/xenstat/libxenstat/src/xenstat.c 
2/tools/xenstat/libxenstat/src/xenstat.c
--- 1/tools/xenstat/libxenstat/src/xenstat.c    2005-10-26 11:07:15.000000000 
-0500
+++ 2/tools/xenstat/libxenstat/src/xenstat.c    2005-10-26 14:30:41.000000000 
-0500
@@ -63,6 +63,7 @@ struct xenstat_domain {
struct xenstat_vcpu {
        unsigned int online;
        unsigned long long ns;
+       int phys_cpu;
};

struct xenstat_network {
@@ -451,6 +452,7 @@ static int xenstat_collect_vcpus(xenstat

                        node->domains[i].vcpus[vcpu].online = info.online;
                        node->domains[i].vcpus[vcpu].ns = info.cpu_time;
+                       node->domains[i].vcpus[vcpu].phys_cpu = info.cpu;
                }
        }
        return 1;
@@ -475,6 +477,12 @@ unsigned int xenstat_vcpu_online(xenstat
        return vcpu->online;
}

+/* Get VCPU to PHYSCPU mapping */
+int xenstat_vcpu_physcpu(xenstat_vcpu * vcpu)
+{
+       return vcpu->phys_cpu;
+}
+
/* Get VCPU usage */
unsigned long long xenstat_vcpu_ns(xenstat_vcpu * vcpu)
{
diff -Naurp 1/tools/xenstat/libxenstat/src/xenstat.h 
2/tools/xenstat/libxenstat/src/xenstat.h
--- 1/tools/xenstat/libxenstat/src/xenstat.h    2005-10-26 11:07:15.000000000 
-0500
+++ 2/tools/xenstat/libxenstat/src/xenstat.h    2005-10-26 11:08:46.000000000 
-0500
@@ -118,6 +118,9 @@ xenstat_network *xenstat_domain_network(
 * VCPU functions - extract information from a xenstat_vcpu
 */

+/* Get VCPU to PHYSCPU mapping */
+int xenstat_vcpu_physcpu(xenstat_vcpu * vcpu);
+
/* Get VCPU usage */
unsigned int xenstat_vcpu_online(xenstat_vcpu * vcpu);
unsigned long long xenstat_vcpu_ns(xenstat_vcpu * vcpu);
diff -Naurp 1/tools/xenstat/Makefile 2/tools/xenstat/Makefile
--- 1/tools/xenstat/Makefile    2005-10-26 15:05:50.000000000 -0500
+++ 2/tools/xenstat/Makefile    2005-10-26 11:08:46.000000000 -0500
@@ -6,7 +6,7 @@ SUBDIRS += libxenstat

# This doesn't cross-compile (cross-compile environments rarely have curses)
ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
-SUBDIRS += xentop
+SUBDIRS += xentop vm-stat
endif

.PHONY: all install clean
diff -Naurp 1/tools/xenstat/vm-stat/Makefile 2/tools/xenstat/vm-stat/Makefile
--- 1/tools/xenstat/vm-stat/Makefile    1969-12-31 18:00:00.000000000 -0600
+++ 2/tools/xenstat/vm-stat/Makefile    2005-10-26 11:08:46.000000000 -0500
@@ -0,0 +1,43 @@
+# Copyright (C) International Business Machines Corp., 2005
+# Author: Josh Triplett <josht@xxxxxxxxxx>
+# +# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; under version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+XEN_ROOT=../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+ifneq ($(XENSTAT_XENTOP),y)
+all install vm-stat:
+else
+
+INSTALL         = install
+INSTALL_PROG    = $(INSTALL) -m0755 -D
+INSTALL_DATA    = $(INSTALL) -m0644 -D
+
+prefix=/usr
+mandir=$(prefix)/share/man
+man1dir=$(mandir)/man1
+sbindir=$(prefix)/sbin
+
+CFLAGS += -DGCC_PRINTF -Wall -Werror -I$(XEN_LIBXENSTAT)
+LDFLAGS += -L$(XEN_LIBXENSTAT)
+LDLIBS += -lxenstat -lncurses
+
+all:  vm-stat
+
+vm-stat: vm-stat.o
+
+install: vm-stat
+       $(INSTALL_PROG) vm-stat $(DESTDIR)$(sbindir)/vm-stat
+
+endif
+
+clean:
+       rm -f vm-stat vm-stat.o
diff -Naurp 1/tools/xenstat/vm-stat/vm-stat.c 2/tools/xenstat/vm-stat/vm-stat.c
--- 1/tools/xenstat/vm-stat/vm-stat.c   1969-12-31 18:00:00.000000000 -0600
+++ 2/tools/xenstat/vm-stat/vm-stat.c   2005-10-26 11:08:46.000000000 -0500
@@ -0,0 +1,164 @@
+/*
+ *  Copyright (C) International Business Machines  Corp., 2005
+ *  Author(s): Judy Fischbach <jfisch@xxxxxxxxxx>
+ *             David Hendricks <dhendrix@xxxxxxxxxx>
+ *             Josh Triplett <josht@xxxxxxxxxx>
+ *    based on code from Anthony Liguori <aliguori@xxxxxxxxxx>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <curses.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#include <xenstat.h>
+
+#define KEY_ESCAPE '\x1B'
+
+/*
+ * Function prototypes
+ */
+/* Utility functions */
+static void cleanup(void);
+static void fail(const char *);
+
+/* Section printing functions */
+static void top(void);
+
+
+/* Globals */
+struct timeval curtime, oldtime;
+xenstat_handle *xhandle = NULL;
+xenstat_node *prev_node = NULL;
+xenstat_node *cur_node = NULL;
+unsigned int delay = 3;
+
+/* Clean up any open resources */
+static void cleanup(void)
+{
+       if(prev_node != NULL)
+               xenstat_free_node(prev_node);
+       if(cur_node != NULL)
+               xenstat_free_node(cur_node);
+       if(xhandle != NULL)
+               xenstat_uninit(xhandle);
+}
+
+/* Display the given message and gracefully exit */
+static void fail(const char *str)
+{
+       fprintf(stderr, str);
+       exit(1);
+}
+
+static void top(void)
+{
+       xenstat_domain *cur_domain, *prev_domain;
+       unsigned int i, j, phys_cpu, num_domains = 0, num_vcpus;
+       xenstat_vcpu *prev_vcpu, *cur_vcpu;
+       unsigned long long vcpu_ns;
+       double us_elapsed;
+       typedef struct {
+               unsigned long long ns;
+               char detail[320];
+               int len;
+       } phys_cpu_t;
+
+       phys_cpu_t cpu[64];
+
+       double vcpu_pct;
+
+       for (i = 0; i < 64; i++) {
+               cpu[i].ns = 0;
+               cpu[i].len = 0;
+       }
+
+       prev_node = cur_node;
+       cur_node = xenstat_get_node(xhandle, XENSTAT_ALL);
+       if (cur_node == NULL)
+               fail("Failed to retrieve statistics from libxenstat\n");
+
+       /* Wait until we have 2 samples */
+       if (prev_node == NULL)
+               return;
+
+       printf("\nCPU  Total Pct   Virtual CPUs\n");
+       /* Count the number of domains for which to report data */
+       num_domains = xenstat_node_num_domains(cur_node);
+
+        us_elapsed = ((curtime.tv_sec-oldtime.tv_sec)*1000000.0
+               + (curtime.tv_usec - oldtime.tv_usec));
+
+       for (i=0; i < num_domains; i++) {
+               cur_domain = xenstat_node_domain_by_index(cur_node, i);
+               prev_domain = xenstat_node_domain_by_index(prev_node, i);
+
+               if (prev_domain && cur_domain) {
+                       unsigned int dom_id;
+                       dom_id = xenstat_domain_id(cur_domain);
+                       num_vcpus = xenstat_domain_num_vcpus(cur_domain);
+                       for (j = 0; j < num_vcpus; j++) {
+                               cur_vcpu = xenstat_domain_vcpu(cur_domain, j);
+                               prev_vcpu = xenstat_domain_vcpu(prev_domain, j);
+                               if (cur_vcpu >= 0 && prev_vcpu >= 0) {
+                                       phys_cpu = 
xenstat_vcpu_physcpu(cur_vcpu);
+                                       vcpu_ns = xenstat_vcpu_ns(cur_vcpu) - 
xenstat_vcpu_ns(prev_vcpu);
+                                       vcpu_pct = vcpu_ns / 10.0 / us_elapsed;
+                                       cpu[phys_cpu].ns += vcpu_ns;
+                                       cpu[phys_cpu].len += 
sprintf(&cpu[phys_cpu].detail[cpu[phys_cpu].len], " d%u-%u[%05.1f]", dom_id, j, 
vcpu_pct);
+
+                               }
+                       }
+               }
+       }
+       for (i = 0; i < 64; i++) {
+               double pct;
+               if (cpu[i].ns > 0) {
+
+                       pct = cpu[i].ns / 10.0 / us_elapsed;
+                       printf("%3i  [%05.1f]    %s\n", i, pct, cpu[i].detail);
+                       fflush(NULL);
+               }
+       }
+}
+
+int main(int argc, char **argv)
+{
+       if (argc >= 2) {
+               delay = atoi(argv[1]);
+       }
+       if (atexit(cleanup) != 0)
+               fail("Failed to install cleanup handler.\n");
+
+       /* Get xenstat handle */
+       xhandle = xenstat_init();
+       if (xhandle == NULL)
+               fail("Failed to initialize xenstat library\n");
+
+       do {
+               gettimeofday(&curtime, NULL);
+               top();
+               oldtime = curtime;
+               sleep(delay);
+       } while (0 == 0);
+
+       /* Cleanup occurs in cleanup(), so no work to do here. */
+
+       return 0;
+}



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.