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

[Xen-changelog] Rename vm-top to xentop. Make "xm top" invoke xentop. Make libxenstat a static library, and do not install it.



# HG changeset patch
# User josht@xxxxxxxxxx
# Node ID 173b918160e27ae385258cf8dd6dfd266974ba90
# Parent  b38cbc8f4d983652803be188a6d7f90220d80692
Rename vm-top to xentop.  Make "xm top" invoke xentop.  Make libxenstat a 
static library, and do not install it.
# HG changeset patch
# User josht@xxxxxxxxxx
# Node ID ea025493dfe39540075ee9e4e75b2146f25bdbd3
# Parent  ce557cc4fdc764ac2ce07b8d4bcae77ecf847c29
Rename vm-top to xentop.  Make "xm top" invoke xentop.  Make libxenstat a 
static library, and do not install it.

diff -r b38cbc8f4d98 -r 173b918160e2 Config.mk
--- a/Config.mk Mon Aug 15 18:25:33 2005
+++ b/Config.mk Wed Aug 17 16:50:33 2005
@@ -14,6 +14,7 @@
 CC         = $(CROSS_COMPILE)gcc
 CPP        = $(CROSS_COMPILE)gcc -E
 AR         = $(CROSS_COMPILE)ar
+RANLIB     = $(CROSS_COMPILE)ranlib
 NM         = $(CROSS_COMPILE)nm
 STRIP      = $(CROSS_COMPILE)strip
 OBJCOPY    = $(CROSS_COMPILE)objcopy
@@ -37,6 +38,4 @@
 KERNEL_REPO = http://www.kernel.org
 
 # Optional components
-XENSTAT_PERL_BINDINGS   ?= n
-XENSTAT_PYTHON_BINDINGS ?= y
-XENSTAT_VM_TOP          ?= y
+XENSTAT_XENTOP ?= y
diff -r b38cbc8f4d98 -r 173b918160e2 tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py       Mon Aug 15 18:25:33 2005
+++ b/tools/python/xen/xm/main.py       Wed Aug 17 16:50:33 2005
@@ -49,6 +49,7 @@
     restore <File>          create a domain from a saved state file
     save <DomId> <File>     save domain state (and config) to file
     shutdown <DomId>        shutdown a domain
+    top                     monitor system and domains in real-time
     unpause <DomId>         unpause a paused domain
 
 For a complete list of subcommands run 'xm help --long'
@@ -87,6 +88,7 @@
     dmesg   [--clear]         read or clear Xen's message buffer
     info                      get information about the xen host
     log                       print the xend log
+    top                       monitor system and domains in real-time
 
   Scheduler Commands:
     bvt <options>             set BVT scheduler parameters
@@ -452,6 +454,9 @@
     os.execvp('/usr/libexec/xen/xenconsole', cmd.split())
     console = sxp.child(info, "console")
 
+def xm_top(args):
+    os.execv('/usr/sbin/xentop', ['/usr/sbin/xentop'])
+
 def xm_dmesg(args):
     
     gopts = Opts(use="""[-c|--clear]
@@ -540,6 +545,8 @@
 commands = {
     # console commands
     "console": xm_console,
+    # xenstat commands
+    "top": xm_top,
     # domain commands
     "domid": xm_domid,
     "domname": xm_domname,
diff -r b38cbc8f4d98 -r 173b918160e2 tools/xenstat/Makefile
--- a/tools/xenstat/Makefile    Mon Aug 15 18:25:33 2005
+++ b/tools/xenstat/Makefile    Wed Aug 17 16:50:33 2005
@@ -3,7 +3,7 @@
 
 SUBDIRS :=
 SUBDIRS += libxenstat
-SUBDIRS += vm-top
+SUBDIRS += xentop
 
 .PHONY: all install clean
 
diff -r b38cbc8f4d98 -r 173b918160e2 tools/xenstat/libxenstat/Makefile
--- a/tools/xenstat/libxenstat/Makefile Mon Aug 15 18:25:33 2005
+++ b/tools/xenstat/libxenstat/Makefile Wed Aug 17 16:50:33 2005
@@ -30,8 +30,9 @@
 MAJOR=0
 MINOR=0
 
-LIB=src/libxenstat.so.$(MAJOR).$(MINOR)
-LINKS=src/libxenstat.so.$(MAJOR) src/libxenstat.so
+LIB=src/libxenstat.a
+SHLIB=src/libxenstat.so.$(MAJOR).$(MINOR)
+SHLIB_LINKS=src/libxenstat.so.$(MAJOR) src/libxenstat.so
 OBJECTS=src/xenstat.o src/xen-interface.o
 SONAME_FLAGS=-Wl,-soname -Wl,libxenstat.so.$(MAJOR)
 
@@ -42,9 +43,13 @@
 CFLAGS+=-I$(LINUX_ROOT)/include/asm-xen/linux-public/
 LDFLAGS+=-Lsrc
 
-all: $(LIB) $(LINKS)
+all: $(LIB)
 
 $(LIB): $(OBJECTS)
+       $(AR) rc $@ $^
+       $(RANLIB) $@
+
+$(SHLIB): $(OBJECTS)
        $(CC) $(LDFLAGS) $(SONAME_FLAGS) -shared -o $@ $(OBJECTS)
 
 src/xenstat.o: src/xenstat.c src/xenstat.h src/xen-interface.h
@@ -59,15 +64,17 @@
 src/libxenstat.so: src/libxenstat.so.$(MAJOR)
        $(MAKE_LINK) $(<F) $@
 
-install: all
-       $(INSTALL_DATA) src/xenstat.h $(DESTDIR)$(includedir)/xenstat.h
-       $(INSTALL_PROG) $(LIB) \
-                       $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR).$(MINOR)
-       $(MAKE_LINK) libxenstat.so.$(MAJOR).$(MINOR) \
-                    $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR)
-       $(MAKE_LINK) libxenstat.so.$(MAJOR) \
-                    $(DESTDIR)$(libdir)/libxenstat.so
-       -$(LDCONFIG)
+install:
+#install: all
+#      $(INSTALL_DATA) src/xenstat.h $(DESTDIR)$(includedir)/xenstat.h
+#      $(INSTALL_PROG) $(LIB) $(DESTDIR)$(libdir)/libxenstat.a
+#      $(INSTALL_PROG) $(SHLIB) \
+#                      $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR).$(MINOR)
+#      $(MAKE_LINK) libxenstat.so.$(MAJOR).$(MINOR) \
+#                   $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR)
+#      $(MAKE_LINK) libxenstat.so.$(MAJOR) \
+#                   $(DESTDIR)$(libdir)/libxenstat.so
+#      -$(LDCONFIG)
 
 PYLIB=bindings/swig/python/_xenstat.so
 PYMOD=bindings/swig/python/xenstat.py
@@ -84,7 +91,7 @@
 # The install-bindings target installs all the language bindings
 install-bindings: install-perl-bindings install-python-bindings
 
-$(BINDINGS): $(LIB) $(LINKS) src/xenstat.h
+$(BINDINGS): $(SHLIB) $(SHLIB_LINKS) src/xenstat.h
 
 SWIG_FLAGS=-module xenstat -Isrc
 
@@ -131,4 +138,5 @@
 endif
 
 clean:
-       rm -f $(LIB) $(OBJECTS) $(LINKS) $(BINDINGS) $(BINDINGSRC)
+       rm -f $(LIB) $(SHLIB) $(SHLIB_LINKS) $(OBJECTS) \
+             $(BINDINGS) $(BINDINGSRC)
diff -r b38cbc8f4d98 -r 173b918160e2 tools/xenstat/xentop/Makefile
--- /dev/null   Mon Aug 15 18:25:33 2005
+++ b/tools/xenstat/xentop/Makefile     Wed Aug 17 16:50:33 2005
@@ -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 xentop:
+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) -lxenstat -lcurses
+
+all: xentop
+
+xentop: xentop.o
+
+install: xentop xentop.1
+       $(INSTALL_PROG) xentop $(DESTDIR)$(sbindir)/xentop
+       $(INSTALL_DATA) xentop.1 $(DESTDIR)$(man1dir)/xentop.1
+
+endif
+
+clean:
+       rm -f xentop xentop.o
diff -r b38cbc8f4d98 -r 173b918160e2 tools/xenstat/xentop/TODO
--- /dev/null   Mon Aug 15 18:25:33 2005
+++ b/tools/xenstat/xentop/TODO Wed Aug 17 16:50:33 2005
@@ -0,0 +1,34 @@
+Display error messages on the help line after bad input at a prompt.
+Fractional delay times
+Use prompting to search for domains
+Better line editing?
+
+* Make CPU in % more accurate
+* Domain total network TX % and RX %
+
+Like Top, f feature, field select of domain columns, toggle the display of
+field by typing the letter associated with field, if displayed it shows in
+bold and the letter is Capitalized along with a leading asterisk for the
+field, if not selected for display letter is lowercase, no leading asterisk
+and field is not bolded.
+
+Like Top, ordering of domain columns, o feature Capital letter shifts left,
+lowercase letter shifts right?
+
+Color
+Full management: pause, destroy, create domains
+
+Add support for Virtual Block Devices (vbd)
+
+To think about:
+Support for one than one node display (distributed monitoring 
+from any node of all other nodes in a cluster)
+Bottom line option (Switch node, Search node [tab completion?])
+
+Capture/Logging of resource information generated during a time interval.
+-b batch mode dump snapshots to standard output (used with -n)
+-n number of iterations to dump to standard output (unlimited if not specified)
+-d monitor DomIDs as -dD1,-dD2 or -dD1,D2...
+   Monitor only domains with specified domain IDs
+-m monitor nodeIDs as -mN1,-mN2 or -mN1,N2...
+   Monitor only domains with specified node IDs
diff -r b38cbc8f4d98 -r 173b918160e2 tools/xenstat/xentop/xentop.1
--- /dev/null   Mon Aug 15 18:25:33 2005
+++ b/tools/xenstat/xentop/xentop.1     Wed Aug 17 16:50:33 2005
@@ -0,0 +1,88 @@
+.\" 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.
+.\"
+.\" 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
+.TH xentop 1 "August 2005"
+.SH NAME
+\fBxentop\fR \- displays real-time information about a Xen system and domains
+
+.SH SYNOPSIS
+.B xentop
+[\fB\-h\fR]
+[\fB\-V\fR]
+[\fB\-d\fRSECONDS]
+[\fB\-n\fR]
+[\fB\-r\fR]
+[\fB\-v\fR]
+
+.SH DESCRIPTION
+\fBxentop\fR displays information about the Xen system and domains, in a
+continually-updating manner.  Command-line options and interactive commands
+can change the detail and format of the information displayed by \fBxentop\fR.
+
+.SH OPTIONS
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+display help and exit
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+output version information and exit
+.TP
+\fB\-d\fR, \fB\-\-delay\fR=\fISECONDS\fR
+seconds between updates (default 1)
+.TP
+\fB\-n\fR, \fB\-\-networks\fR
+output network information
+.TP
+\fB\-r\fR, \fB\-\-repeat\-header\fR
+repeat table header before each domain
+.TP
+\fB\-v\fR, \fB\-\-vcpus\fR
+output VCPU data
+
+.SH "INTERACTIVE COMMANDS"
+All interactive commands are case-insensitive.
+.TP
+.B D
+set delay between updates
+.TP
+.B N
+toggle display of network information
+.TP
+.B Q, Esc
+quit
+.TP
+.B R
+toggle table header before each domain
+.TP
+.B S
+cycle sort order
+.TP
+.B V
+toggle display of VCPU information
+.TP
+.B Arrows
+scroll domain display
+
+.SH AUTHORS
+Written by Judy Fischbach, David Hendricks, and Josh Triplett
+
+.SH "REPORTING BUGS"
+Report bugs to <dsteklof@xxxxxxxxxx>.
+
+.SH COPYRIGHT
+Copyright \(co 2005  International Business Machines  Corp
+.br
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff -r b38cbc8f4d98 -r 173b918160e2 tools/xenstat/xentop/xentop.c
--- /dev/null   Mon Aug 15 18:25:33 2005
+++ b/tools/xenstat/xentop/xentop.c     Wed Aug 17 16:50:33 2005
@@ -0,0 +1,876 @@
+/*
+ *  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 XENTOP_VERSION "1.0"
+
+#define XENTOP_DISCLAIMER \
+"Copyright (C) 2005  International Business Machines  Corp\n"\
+"This is free software; see the source for copying conditions.There is NO\n"\
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+#define XENTOP_BUGSTO "Report bugs to <dsteklof@xxxxxxxxxx>.\n"
+
+#define _GNU_SOURCE
+#include <getopt.h>
+
+#if !defined(__GNUC__) && !defined(__GNUG__)
+#define __attribute__(arg) /* empty */
+#endif
+
+#define KEY_ESCAPE '\x1B'
+
+/*
+ * Function prototypes
+ */
+/* Utility functions */
+static void usage(const char *);
+static void version(void);
+static void cleanup(void);
+static void fail(const char *);
+static int current_row(void);
+static int lines(void);
+static void print(const char *, ...) __attribute__((format(printf,1,2)));
+static void attr_addstr(int attr, const char *str);
+static void set_delay(char *value);
+static void set_prompt(char *new_prompt, void (*func)(char *));
+static int handle_key(int);
+static int compare(unsigned long long, unsigned long long);
+static int compare_domains(xenstat_domain **, xenstat_domain **);
+static unsigned long long tot_net_bytes( xenstat_domain *, int);
+
+/* Field functions */
+static int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_domid(xenstat_domain *domain);
+static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_state(xenstat_domain *domain);
+static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_cpu(xenstat_domain *domain);
+static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_cpu_pct(xenstat_domain *domain);
+static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_mem(xenstat_domain *domain);
+static void print_mem_pct(xenstat_domain *domain);
+static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_maxmem(xenstat_domain *domain);
+static void print_max_pct(xenstat_domain *domain);
+static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_vcpus(xenstat_domain *domain);
+static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_nets(xenstat_domain *domain);
+static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_net_tx(xenstat_domain *domain);
+static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_net_rx(xenstat_domain *domain);
+static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2);
+static void print_ssid(xenstat_domain *domain);
+
+/* Section printing functions */
+static void do_summary(void);
+static void do_header(void);
+static void do_bottom_line(void);
+static void do_domain(xenstat_domain *);
+static void do_vcpu(xenstat_domain *);
+static void do_network(xenstat_domain *);
+static void top(void);
+
+/* Field types */
+typedef enum field_id {
+       FIELD_DOMID,
+       FIELD_STATE,
+       FIELD_CPU,
+       FIELD_CPU_PCT,
+       FIELD_MEM,
+       FIELD_MEM_PCT,
+       FIELD_MAXMEM,
+       FIELD_MAX_PCT,
+       FIELD_VCPUS,
+       FIELD_NETS,
+       FIELD_NET_TX,
+       FIELD_NET_RX,
+       FIELD_SSID
+} field_id;
+
+typedef struct field {
+       field_id num;
+       const char *header;
+       unsigned int default_width;
+       int (*compare)(xenstat_domain *domain1, xenstat_domain *domain2);
+       void (*print)(xenstat_domain *domain);
+} field;
+
+field fields[] = {
+       { FIELD_DOMID,   "DOMID",      5, compare_domid,   print_domid   },
+       { FIELD_STATE,   "STATE",      6, compare_state,   print_state   },
+       { FIELD_CPU,     "CPU(sec)",  10, compare_cpu,     print_cpu     },
+       { FIELD_CPU_PCT, "CPU(%)",     6, compare_cpu_pct, print_cpu_pct },
+       { FIELD_MEM,     "MEM(k)",    10, compare_mem,     print_mem     },
+       { FIELD_MEM_PCT, "MEM(%)",     6, compare_mem,     print_mem_pct },
+       { FIELD_MAXMEM,  "MAXMEM(k)", 10, compare_maxmem,  print_maxmem  },
+       { FIELD_MAX_PCT, "MAXMEM(%)",  9, compare_maxmem,  print_max_pct },
+       { FIELD_VCPUS,   "VCPUS",      5, compare_vcpus,   print_vcpus   },
+       { FIELD_NETS,    "NETS",       4, compare_nets,    print_nets    },
+       { FIELD_NET_TX,  "NETTX(k)",   8, compare_net_tx,  print_net_tx  },
+       { FIELD_NET_RX,  "NETRX(k)",   8, compare_net_rx,  print_net_rx  },
+       { FIELD_SSID,    "SSID",       4, compare_ssid,    print_ssid    }
+};
+
+const unsigned int NUM_FIELDS = sizeof(fields)/sizeof(field);
+
+/* Globals */
+struct timeval curtime, oldtime;
+xenstat_handle *xhandle = NULL;
+xenstat_node *prev_node = NULL;
+xenstat_node *cur_node = NULL;
+field_id sort_field = FIELD_DOMID;
+unsigned int first_domain_index = 0;
+unsigned int delay = 1;
+int show_vcpus = 0;
+int show_networks = 0;
+int repeat_header = 0;
+#define PROMPT_VAL_LEN 80
+char *prompt = NULL;
+char prompt_val[PROMPT_VAL_LEN];
+int prompt_val_len = 0;
+void (*prompt_complete_func)(char *);
+
+/*
+ * Function definitions
+ */
+
+/* Utility functions */
+
+/* Print usage message, using given program name */
+static void usage(const char *program)
+{
+       printf("Usage: %s [OPTION]\n"
+              "Displays ongoing information about xen vm resources \n\n"
+              "-h, --help           display this help and exit\n"
+              "-V, --version        output version information and exit\n"
+              "-d, --delay=SECONDS  seconds between updates (default 1)\n"
+              "-n, --networks       output vif network data\n"
+              "-r, --repeat-header  repeat table header before each domain\n"
+              "-v, --vcpus          output vcpu data\n"
+              "\n" XENTOP_BUGSTO,
+              program);
+       return;
+}
+
+/* Print program version information */
+static void version(void)
+{
+       printf("xentop " XENTOP_VERSION "\n"
+              "Written by Judy Fischbach, David Hendricks, Josh Triplett\n"
+              "\n" XENTOP_DISCLAIMER);
+}
+
+/* Clean up any open resources */
+static void cleanup(void)
+{
+       if(!isendwin())
+               endwin();
+       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)
+{
+       if(!isendwin())
+               endwin();
+       fprintf(stderr, str);
+       exit(1);
+}
+
+/* Return the row containing the cursor. */
+static int current_row(void)
+{
+       int y, x;
+       getyx(stdscr, y, x);
+       return y;
+}
+
+/* Return the number of lines on the screen. */
+static int lines(void)
+{
+       int y, x;
+       getmaxyx(stdscr, y, x);
+       return y;
+}
+
+/* printf-style print function which calls printw, but only if the cursor is
+ * not on the last line. */
+static void print(const char *fmt, ...)
+{
+       va_list args;
+
+       if(current_row() < lines()-1) {
+               va_start(args, fmt);
+               vw_printw(stdscr, fmt, args);
+               va_end(args);
+       }
+}
+
+/* Print a string with the given attributes set. */
+static void attr_addstr(int attr, const char *str)
+{
+       attron(attr);
+       addstr(str);
+       attroff(attr);
+}
+
+/* Handle setting the delay from the user-supplied value in prompt_val */
+static void set_delay(char *value)
+{
+       int new_delay;
+       new_delay = atoi(prompt_val);
+       if(new_delay > 0)
+               delay = new_delay;
+}
+
+/* Enable prompting mode with the given prompt string; call the given function
+ * when a value is available. */
+static void set_prompt(char *new_prompt, void (*func)(char *))
+{
+       prompt = new_prompt;
+       prompt_val[0] = '\0';
+       prompt_val_len = 0;
+       prompt_complete_func = func;
+}
+
+/* Handle user input, return 0 if the program should quit, or 1 if not */
+static int handle_key(int ch)
+{
+       if(prompt == NULL) {
+               /* Not prompting for input; handle interactive commands */
+               switch(ch) {
+               case 'n': case 'N':
+                       show_networks ^= 1;
+                       break;
+               case 'r': case 'R':
+                       repeat_header ^= 1;
+                       break;
+               case 's': case 'S':
+                       sort_field = (sort_field + 1) % NUM_FIELDS;
+                       break;
+               case 'v': case 'V':
+                       show_vcpus ^= 1;
+                       break;
+               case KEY_DOWN:
+                       first_domain_index++;
+                       break;
+               case KEY_UP:
+                       if(first_domain_index > 0)
+                               first_domain_index--;
+                       break;
+               case 'd': case 'D':
+                       set_prompt("Delay(sec)", set_delay);
+                       break;
+               case 'q': case 'Q': case KEY_ESCAPE:
+                       return 0;
+               }
+       } else {
+               /* Prompting for input; handle line editing */
+               switch(ch) {
+               case '\r':
+                       prompt_complete_func(prompt_val);
+                       set_prompt(NULL, NULL);
+                       break;
+               case KEY_ESCAPE:
+                       set_prompt(NULL, NULL);
+                       break;
+               case KEY_BACKSPACE:
+                       if(prompt_val_len > 0)
+                               prompt_val[--prompt_val_len] = '\0';
+               default:
+                       if((prompt_val_len+1) < PROMPT_VAL_LEN
+                          && isprint(ch)) {
+                               prompt_val[prompt_val_len++] = (char)ch;
+                               prompt_val[prompt_val_len] = '\0';
+                       }
+               }
+       }
+
+       return 1;
+}
+
+/* Compares two integers, returning -1,0,1 for <,=,> */
+static int compare(unsigned long long i1, unsigned long long i2)
+{
+       if(i1 < i2)
+               return -1;
+       if(i1 > i2)
+               return 1;
+       return 0;
+}
+
+/* Comparison function for use with qsort.  Compares two domains using the
+ * current sort field. */
+static int compare_domains(xenstat_domain **domain1, xenstat_domain **domain2)
+{
+       return fields[sort_field].compare(*domain1, *domain2);
+}
+
+/* Field functions */
+
+/* Compares domain ids of two domains, returning -1,0,1 for <,=,> */
+int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return compare(xenstat_domain_id(domain1), xenstat_domain_id(domain2));
+}
+
+/* Prints domain identification number */
+void print_domid(xenstat_domain *domain)
+{
+       print("%5u", xenstat_domain_id(domain));
+}
+
+struct {
+       unsigned int (*get)(xenstat_domain *);
+       char ch;
+} state_funcs[] = {
+       { xenstat_domain_dying,    'd' },
+       { xenstat_domain_shutdown, 's' },
+       { xenstat_domain_blocked,  'b' },
+       { xenstat_domain_crashed,  'c' },
+       { xenstat_domain_paused,   'p' },
+       { xenstat_domain_running,  'r' }
+};
+const unsigned int NUM_STATES = sizeof(state_funcs)/sizeof(*state_funcs);
+
+/* Compare states of two domains, returning -1,0,1 for <,=,> */
+static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       unsigned int i, d1s, d2s;
+       for(i = 0; i < NUM_STATES; i++) {
+               d1s = state_funcs[i].get(domain1);
+               d2s = state_funcs[i].get(domain2);
+               if(d1s && !d2s)
+                       return -1;
+               if(d2s && !d1s)
+                       return 1;
+       }
+       return 0;
+}
+
+/* Prints domain state in abbreviated letter format */
+static void print_state(xenstat_domain *domain)
+{
+       unsigned int i;
+       for(i = 0; i < NUM_STATES; i++)
+               print("%c", state_funcs[i].get(domain) ? state_funcs[i].ch
+                                                      : '-');
+}
+
+/* Compares cpu usage of two domains, returning -1,0,1 for <,=,> */
+static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(xenstat_domain_cpu_ns(domain1),
+                       xenstat_domain_cpu_ns(domain2));
+}
+
+/* Prints domain cpu usage in seconds */
+static void print_cpu(xenstat_domain *domain)
+{
+       print("%10llu", xenstat_domain_cpu_ns(domain)/1000000000);
+}
+
+/* Computes the CPU percentage used for a specified domain */
+static double get_cpu_pct(xenstat_domain *domain)
+{
+       xenstat_domain *old_domain;
+       double us_elapsed;
+
+       /* Can't calculate CPU percentage without a previous sample. */
+       if(prev_node == NULL)
+               return 0.0;
+
+       old_domain = xenstat_node_domain(prev_node, xenstat_domain_id(domain));
+       if(old_domain == NULL)
+               return 0.0;
+
+       /* Calculate the time elapsed in microseconds */
+       us_elapsed = ((curtime.tv_sec-oldtime.tv_sec)*1000000.0
+                     +(curtime.tv_usec - oldtime.tv_usec));
+
+       /* In the following, nanoseconds must be multiplied by 1000.0 to
+        * convert to microseconds, then divided by 100.0 to get a percentage,
+        * resulting in a multiplication by 10.0 */
+       return ((xenstat_domain_cpu_ns(domain)
+                -xenstat_domain_cpu_ns(old_domain))/10.0)/us_elapsed;
+}
+
+static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(get_cpu_pct(domain1), get_cpu_pct(domain2));
+}
+
+/* Prints cpu percentage statistic */
+static void print_cpu_pct(xenstat_domain *domain)
+{
+       print("%6.1f", get_cpu_pct(domain));
+}
+
+/* Compares current memory of two domains, returning -1,0,1 for <,=,> */
+static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(xenstat_domain_cur_mem(domain1),
+                       xenstat_domain_cur_mem(domain2));
+}
+
+/* Prints current memory statistic */
+static void print_mem(xenstat_domain *domain)
+{
+       print("%10llu", xenstat_domain_cur_mem(domain)/1024);
+}
+
+/* Prints memory percentage statistic, ratio of current domain memory to total
+ * node memory */
+static void print_mem_pct(xenstat_domain *domain)
+{
+       print("%6.1f", (double)xenstat_domain_cur_mem(domain) /
+                      (double)xenstat_node_tot_mem(cur_node) * 100);
+}
+
+/* Compares maximum memory of two domains, returning -1,0,1 for <,=,> */
+static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(xenstat_domain_max_mem(domain1),
+                       xenstat_domain_max_mem(domain2));
+}
+
+/* Prints maximum domain memory statistic in KB */
+static void print_maxmem(xenstat_domain *domain)
+{
+       unsigned long long max_mem = xenstat_domain_max_mem(domain);
+       if(max_mem == ((unsigned long long)-1))
+               print("%10s", "no limit");
+       else
+               print("%10llu", max_mem/1024);
+}
+
+/* Prints memory percentage statistic, ratio of current domain memory to total
+ * node memory */
+static void print_max_pct(xenstat_domain *domain)
+{
+       if (xenstat_domain_max_mem(domain) == (unsigned long long)-1)
+               print("%9s", "n/a");
+       else
+               print("%9.1f", (double)xenstat_domain_max_mem(domain) /
+                              (double)xenstat_node_tot_mem(cur_node) * 100);
+}
+
+/* Compares number of virtual CPUs of two domains, returning -1,0,1 for
+ * <,=,> */
+static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(xenstat_domain_num_vcpus(domain1),
+                       xenstat_domain_num_vcpus(domain2));
+}
+
+/* Prints number of virtual CPUs statistic */
+static void print_vcpus(xenstat_domain *domain)
+{
+       print("%5u", xenstat_domain_num_vcpus(domain));
+}
+
+/* Compares number of virtual networks of two domains, returning -1,0,1 for
+ * <,=,> */
+static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(xenstat_domain_num_networks(domain1),
+                       xenstat_domain_num_networks(domain2));
+}
+
+/* Prints number of virtual networks statistic */
+static void print_nets(xenstat_domain *domain)
+{
+       print("%4u", xenstat_domain_num_networks(domain));
+}
+
+/* Compares number of total network tx bytes of two domains, returning -1,0,1 
for
+ * <,=,> */
+static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(tot_net_bytes(domain1, FALSE),
+                       tot_net_bytes(domain2, FALSE));
+}
+
+/* Prints number of total network tx bytes statistic */
+static void print_net_tx(xenstat_domain *domain)
+{
+       print("%8llu", tot_net_bytes(domain, FALSE)/1024);
+}
+
+/* Compares number of total network rx bytes of two domains, returning -1,0,1 
for
+ * <,=,> */
+static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return -compare(tot_net_bytes(domain1, TRUE),
+                       tot_net_bytes(domain2, TRUE));
+}
+
+/* Prints number of total network rx bytes statistic */
+static void print_net_rx(xenstat_domain *domain)
+{
+       print("%8llu", tot_net_bytes(domain, TRUE)/1024);
+}
+
+/* Gets number of total network bytes statistic, if rx true, then rx bytes
+ * otherwise tx bytes
+ */
+static unsigned long long tot_net_bytes(xenstat_domain *domain, int rx_flag)
+{
+       int i = 0;
+       xenstat_network *network;
+       unsigned num_networks = 0;
+        unsigned long long total = 0;
+
+       /* How many networks? */
+       num_networks = xenstat_domain_num_networks(domain);
+
+       /* Dump information for each network */
+       for (i=0; i < num_networks; i++) {
+               /* Next get the network information */
+               network = xenstat_domain_network(domain,i);
+                if (rx_flag) 
+                       total += xenstat_network_rbytes(network);
+                else 
+                       total += xenstat_network_tbytes(network);
+       }
+        return (total);
+}
+
+/* Compares security id (ssid) of two domains, returning -1,0,1 for <,=,> */
+static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2)
+{
+       return compare(xenstat_domain_ssid(domain1),
+                      xenstat_domain_ssid(domain2));
+}
+
+/* Prints ssid statistic */
+static void print_ssid(xenstat_domain *domain)
+{
+       print("%4u", xenstat_domain_ssid(domain));
+}
+
+/* Section printing functions */
+/* Prints the top summary, above the domain table */
+void do_summary(void)
+{
+#define TIME_STR_LEN 9
+       const char *TIME_STR_FORMAT = "%H:%M:%S";
+       char time_str[TIME_STR_LEN];
+       unsigned run = 0, block = 0, pause = 0,
+                crash = 0, dying = 0, shutdown = 0;
+       unsigned i, num_domains = 0;
+       unsigned long long used = 0;
+       xenstat_domain *domain;
+
+       /* Print program name, current time, and number of domains */
+       strftime(time_str, TIME_STR_LEN, TIME_STR_FORMAT,
+                localtime(&curtime.tv_sec));
+       num_domains = xenstat_node_num_domains(cur_node);
+       print("xentop - %s\n", time_str);
+
+       /* Tabulate what states domains are in for summary */
+       for (i=0; i < num_domains; i++) {
+               domain = xenstat_node_domain_by_index(cur_node,i);
+               if (xenstat_domain_running(domain)) run++;
+               else if (xenstat_domain_blocked(domain)) block++;
+               else if (xenstat_domain_paused(domain)) pause++;
+               else if (xenstat_domain_shutdown(domain)) shutdown++;
+               else if (xenstat_domain_crashed(domain)) crash++;
+               else if (xenstat_domain_dying(domain)) dying++;
+       }
+
+       print("%u domains: %u running, %u blocked, %u paused, "
+             "%u crashed, %u dying, %u shutdown \n",
+             num_domains, run, block, pause, crash, dying, shutdown);
+
+       used = xenstat_node_tot_mem(cur_node)-xenstat_node_free_mem(cur_node);
+
+       /* Dump node memory and cpu information */
+       print("Mem: %lluk total, %lluk used, %lluk free    "
+             "CPUs: %u @ %lluMHz\n",
+             xenstat_node_tot_mem(cur_node)/1024, used/1024,
+             xenstat_node_free_mem(cur_node)/1024,
+             xenstat_node_num_cpus(cur_node),
+             xenstat_node_cpu_hz(cur_node)/1000000);
+}
+
+/* Display the top header for the domain table */
+void do_header(void)
+{
+       field_id i;
+
+       /* Turn on REVERSE highlight attribute for headings */
+       attron(A_REVERSE);
+       for(i = 0; i < NUM_FIELDS; i++) {
+               if(i != 0)
+                       print(" ");
+               /* The BOLD attribute is turned on for the sort column */
+               if(i == sort_field)
+                       attron(A_BOLD);
+               print("%*s", fields[i].default_width, fields[i].header);
+               if(i == sort_field)
+                       attroff(A_BOLD);
+       }
+       attroff(A_REVERSE);
+       print("\n");
+}
+
+/* Displays bottom status line or current prompt */
+void do_bottom_line(void)
+{
+       move(lines()-1, 2);
+
+       if (prompt != NULL) {
+               printw("%s: %s", prompt, prompt_val);
+       } else {
+               addch(A_REVERSE | 'D'); addstr("elay  ");
+
+               /* network */
+               addch(A_REVERSE | 'N');
+               attr_addstr(show_networks ? COLOR_PAIR(1) : 0, "etworks");
+               addstr("  ");
+
+               /* vcpus */
+               addch(A_REVERSE | 'V');
+               attr_addstr(show_vcpus ? COLOR_PAIR(1) : 0, "CPUs");
+               addstr("  ");
+
+               /* repeat */
+               addch(A_REVERSE | 'R');
+               attr_addstr(repeat_header ? COLOR_PAIR(1) : 0, "epeat header");
+               addstr("  ");
+
+               /* sort order */
+               addch(A_REVERSE | 'S'); addstr("ort order  ");
+
+               addch(A_REVERSE | 'Q'); addstr("uit  ");
+       }
+}
+
+/* Prints Domain information */
+void do_domain(xenstat_domain *domain)
+{
+       unsigned int i;
+       for(i = 0; i < NUM_FIELDS; i++) {
+               if(i != 0)
+                       print(" ");
+               if(i == sort_field)
+                       attron(A_BOLD);
+               fields[i].print(domain);
+               if(i == sort_field)
+                       attroff(A_BOLD);
+       }
+       print("\n");
+}
+
+/* Output all vcpu information */
+void do_vcpu(xenstat_domain *domain)
+{
+       int i = 0;
+       unsigned num_vcpus = 0;
+       xenstat_vcpu *vcpu;
+
+       print("VCPUs(sec): ");
+
+       num_vcpus = xenstat_domain_num_vcpus(domain);
+
+       /* for all vcpus dump out values */
+       for (i=0; i< num_vcpus; i++) {
+               vcpu = xenstat_domain_vcpu(domain,i);
+
+               if (i != 0 && (i%5)==0)
+                       print("\n        ");
+               print(" %2u: %10llus", i, xenstat_vcpu_ns(vcpu)/1000000000);
+       }
+       print("\n");
+}
+
+/* Output all network information */
+void do_network(xenstat_domain *domain)
+{
+       int i = 0;
+       xenstat_network *network;
+       unsigned num_networks = 0;
+
+       /* How many networks? */
+       num_networks = xenstat_domain_num_networks(domain);
+
+       /* Dump information for each network */
+       for (i=0; i < num_networks; i++) {
+               /* Next get the network information */
+               network = xenstat_domain_network(domain,i);
+
+               print("Net%d RX: %8llubytes %8llupkts %8lluerr %8lludrop  ",
+                     i,
+                     xenstat_network_rbytes(network),
+                     xenstat_network_rpackets(network),
+                     xenstat_network_rerrs(network),
+                     xenstat_network_rdrop(network));
+
+               print("TX: %8llubytes %8llupkts %8lluerr %8lludrop\n",
+                     xenstat_network_tbytes(network),
+                     xenstat_network_tpackets(network),
+                     xenstat_network_terrs(network),
+                     xenstat_network_tdrop(network));
+       }
+}
+
+static void top(void)
+{
+       xenstat_domain **domains;
+       unsigned int i, num_domains = 0;
+
+       /* Now get the node information */
+       if (prev_node != NULL)
+               xenstat_free_node(prev_node);
+       prev_node = cur_node;
+       cur_node = xenstat_get_node(xhandle, XENSTAT_ALL);
+       if (cur_node == NULL)
+               fail("Failed to retrieve statistics from libxenstat\n");
+
+       /* dump summary top information */
+       do_summary();
+
+       /* Count the number of domains for which to report data */
+       num_domains = xenstat_node_num_domains(cur_node);
+
+       domains = malloc(num_domains*sizeof(xenstat_domain *));
+       if(domains == NULL)
+               fail("Failed to allocate memory\n");
+
+       for (i=0; i < num_domains; i++)
+               domains[i] = xenstat_node_domain_by_index(cur_node, i);
+
+       /* Sort */
+       qsort(domains, num_domains, sizeof(xenstat_domain *),
+             (int(*)(const void *, const void *))compare_domains);
+
+       if(first_domain_index >= num_domains)
+               first_domain_index = num_domains-1;
+
+       for (i = first_domain_index; i < num_domains; i++) {
+               if(current_row() == lines()-1)
+                       break;
+               if (i == first_domain_index || repeat_header)
+                       do_header();
+               do_domain(domains[i]);
+               if (show_vcpus)
+                       do_vcpu(domains[i]);
+               if (show_networks)
+                       do_network(domains[i]);
+       }
+
+       do_bottom_line();
+}
+
+int main(int argc, char **argv)
+{
+       int opt, optind = 0;
+       int ch = ERR;
+
+       struct option lopts[] = {
+               { "help",          no_argument,       NULL, 'h' },
+               { "version",       no_argument,       NULL, 'V' },
+               { "networks",      no_argument,       NULL, 'n' },
+               { "repeat-header", no_argument,       NULL, 'r' },
+               { "vcpus",         no_argument,       NULL, 'v' },
+               { "delay",         required_argument, NULL, 'd' },
+               { 0, 0, 0, 0 },
+       };
+       const char *sopts = "hVbnvd:";
+
+       if (atexit(cleanup) != 0)
+               fail("Failed to install cleanup handler.\n");
+
+       while ((opt = getopt_long(argc, argv, sopts, lopts, &optind)) != -1) {
+               switch (opt) {
+               case 'h':
+               case '?':
+               default:
+                       usage(argv[0]);
+                       exit(0);
+               case 'V':
+                       version();
+                       exit(0);
+               case 'n':
+                       show_networks = 1;
+                       break;
+               case 'r':
+                       repeat_header = 1;
+                       break;
+               case 'v':
+                       show_vcpus = 1;
+                       break;
+               case 'd':
+                       delay = atoi(optarg);
+                       break;
+               }
+       }
+
+       /* Get xenstat handle */
+       xhandle = xenstat_init();
+       if (xhandle == NULL)
+               fail("Failed to initialize xenstat library\n");
+
+       /* Begin curses stuff */
+       initscr();
+       start_color();
+       cbreak();
+       noecho();
+       nonl();
+       keypad(stdscr, TRUE);
+       halfdelay(5);
+       use_default_colors();
+       init_pair(1, -1, COLOR_YELLOW);
+
+       do {
+               gettimeofday(&curtime, NULL);
+               if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) {
+                       clear();
+                       top();
+                       oldtime = curtime;
+                       refresh();
+               }
+               ch = getch();
+       } while (handle_key(ch));
+
+       /* Cleanup occurs in cleanup(), so no work to do here. */
+
+       return 0;
+}
diff -r b38cbc8f4d98 -r 173b918160e2 tools/xenstat/vm-top/Makefile
--- a/tools/xenstat/vm-top/Makefile     Mon Aug 15 18:25:33 2005
+++ /dev/null   Wed Aug 17 16:50:33 2005
@@ -1,43 +0,0 @@
-# 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_VM_TOP),y)
-all install vm-top:
-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) -lxenstat -lcurses
-
-all: vm-top
-
-vm-top: vm-top.o
-
-install: vm-top vm-top.1
-       $(INSTALL_PROG) vm-top $(DESTDIR)$(sbindir)/vm-top
-       $(INSTALL_DATA) vm-top.1 $(DESTDIR)$(man1dir)/vm-top.1
-
-endif
-
-clean:
-       rm -f vm-top vm-top.o
diff -r b38cbc8f4d98 -r 173b918160e2 tools/xenstat/vm-top/TODO
--- a/tools/xenstat/vm-top/TODO Mon Aug 15 18:25:33 2005
+++ /dev/null   Wed Aug 17 16:50:33 2005
@@ -1,37 +0,0 @@
-Inefficient about how it handles newlines in vm-top 
-for proc/net/dev. Fix.
-
-Display error messages on the help line after bad input at a prompt.
-Fractional delay times
-Use prompting to search for domains
-Better line editing?
-
-* Make CPU in % more accurate
-* Domain total network TX % and RX %
-
-Like Top, f feature, field select of domain columns, toggle the display of
-field by typing the letter associated with field, if displayed it shows in
-bold and the letter is Capitalized along with a leading asterisk for the
-field, if not selected for display letter is lowercase, no leading asterisk
-and field is not bolded.
-
-Like Top, ordering of domain columns, o feature Capital letter shifts left,
-lowercase letter shifts right?
-
-Color
-Full management: pause, destroy, create domains
-
-Add support for Virtual Block Devices (vbd)
-
-To think about:
-Support for one than one node display (distributed monitoring 
-from any node of all other nodes in a cluster)
-Bottom line option (Switch node, Search node [tab completion?])
-
-Capture/Logging of resource information generated during a time interval.
--b batch mode dump snapshots to standard output (used with -n)
--n number of iterations to dump to standard output (unlimited if not specified)
--d monitor DomIDs as -dD1,-dD2 or -dD1,D2...
-   Monitor only domains with specified domain IDs
--m monitor nodeIDs as -mN1,-mN2 or -mN1,N2...
-   Monitor only domains with specified node IDs
diff -r b38cbc8f4d98 -r 173b918160e2 tools/xenstat/vm-top/vm-top.1
--- a/tools/xenstat/vm-top/vm-top.1     Mon Aug 15 18:25:33 2005
+++ /dev/null   Wed Aug 17 16:50:33 2005
@@ -1,88 +0,0 @@
-.\" 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.
-.\"
-.\" 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
-.TH vm-top 1 "August 2005"
-.SH NAME
-\fBvm-top\fR \- displays real-time information about a Xen system and domains
-
-.SH SYNOPSIS
-.B vm-top
-[\fB\-h\fR]
-[\fB\-V\fR]
-[\fB\-d\fRSECONDS]
-[\fB\-n\fR]
-[\fB\-r\fR]
-[\fB\-v\fR]
-
-.SH DESCRIPTION
-\fBvm-top\fR displays information about the Xen system and domains, in a
-continually-updating manner.  Command-line options and interactive commands
-can change the detail and format of the information displayed by \fBvm-top\fR.
-
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-display help and exit
-.TP
-\fB\-V\fR, \fB\-\-version\fR
-output version information and exit
-.TP
-\fB\-d\fR, \fB\-\-delay\fR=\fISECONDS\fR
-seconds between updates (default 1)
-.TP
-\fB\-n\fR, \fB\-\-networks\fR
-output network information
-.TP
-\fB\-r\fR, \fB\-\-repeat\-header\fR
-repeat table header before each domain
-.TP
-\fB\-v\fR, \fB\-\-vcpus\fR
-output VCPU data
-
-.SH "INTERACTIVE COMMANDS"
-All interactive commands are case-insensitive.
-.TP
-.B D
-set delay between updates
-.TP
-.B N
-toggle display of network information
-.TP
-.B Q, Esc
-quit
-.TP
-.B R
-toggle table header before each domain
-.TP
-.B S
-cycle sort order
-.TP
-.B V
-toggle display of VCPU information
-.TP
-.B Arrows
-scroll domain display
-
-.SH AUTHORS
-Written by Judy Fischbach, David Hendricks, and Josh Triplett
-
-.SH "REPORTING BUGS"
-Report bugs to <dsteklof@xxxxxxxxxx>.
-
-.SH COPYRIGHT
-Copyright \(co 2005  International Business Machines  Corp
-.br
-This is free software; see the source for copying conditions.  There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff -r b38cbc8f4d98 -r 173b918160e2 tools/xenstat/vm-top/vm-top.c
--- a/tools/xenstat/vm-top/vm-top.c     Mon Aug 15 18:25:33 2005
+++ /dev/null   Wed Aug 17 16:50:33 2005
@@ -1,880 +0,0 @@
-/*
- *  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 VM_TOP_VERSION "1.0"
-
-#define VM_TOP_DISCLAIMER \
-"Copyright (C) 2005  International Business Machines  Corp\n"\
-"This is free software; see the source for copying conditions.There is NO\n"\
-"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
-#define VM_TOP_BUGSTO "Report bugs to <dsteklof@xxxxxxxxxx>.\n"
-
-#define _GNU_SOURCE
-#include <getopt.h>
-
-#if !defined(__GNUC__) && !defined(__GNUG__)
-#define __attribute__(arg) /* empty */
-#endif
-
-#define KEY_ESCAPE '\x1B'
-
-/*
- * Function prototypes
- */
-/* Utility functions */
-static void usage(const char *);
-static void version(void);
-static void cleanup(void);
-static void fail(const char *);
-static int current_row(void);
-static int lines(void);
-static void print(const char *, ...) __attribute__((format(printf,1,2)));
-static void attr_addstr(int attr, const char *str);
-static void set_delay(char *value);
-static void set_prompt(char *new_prompt, void (*func)(char *));
-static int handle_key(int);
-static int compare(unsigned long long, unsigned long long);
-static int compare_domains(xenstat_domain **, xenstat_domain **);
-static unsigned long long tot_net_bytes( xenstat_domain *, int);
-
-/* Field functions */
-static int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2);
-static void print_domid(xenstat_domain *domain);
-static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2);
-static void print_state(xenstat_domain *domain);
-static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2);
-static void print_cpu(xenstat_domain *domain);
-static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2);
-static void print_cpu_pct(xenstat_domain *domain);
-static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2);
-static void print_mem(xenstat_domain *domain);
-static void print_mem_pct(xenstat_domain *domain);
-static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2);
-static void print_maxmem(xenstat_domain *domain);
-static void print_max_pct(xenstat_domain *domain);
-static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2);
-static void print_vcpus(xenstat_domain *domain);
-static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2);
-static void print_nets(xenstat_domain *domain);
-static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2);
-static void print_net_tx(xenstat_domain *domain);
-static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2);
-static void print_net_rx(xenstat_domain *domain);
-static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2);
-static void print_ssid(xenstat_domain *domain);
-
-/* Section printing functions */
-static void do_summary(void);
-static void do_header(void);
-static void do_bottom_line(void);
-static void do_domain(xenstat_domain *);
-static void do_vcpu(xenstat_domain *);
-static void do_network(xenstat_domain *);
-static void top(void);
-
-/* Field types */
-typedef enum field_id {
-       FIELD_DOMID,
-       FIELD_STATE,
-       FIELD_CPU,
-       FIELD_CPU_PCT,
-       FIELD_MEM,
-       FIELD_MEM_PCT,
-       FIELD_MAXMEM,
-       FIELD_MAX_PCT,
-       FIELD_VCPUS,
-       FIELD_NETS,
-       FIELD_NET_TX,
-       FIELD_NET_RX,
-       FIELD_SSID
-} field_id;
-
-typedef struct field {
-       field_id num;
-       const char *header;
-       unsigned int default_width;
-       int (*compare)(xenstat_domain *domain1, xenstat_domain *domain2);
-       void (*print)(xenstat_domain *domain);
-} field;
-
-field fields[] = {
-       { FIELD_DOMID,   "DOMID",      5, compare_domid,   print_domid   },
-       { FIELD_STATE,   "STATE",      6, compare_state,   print_state   },
-       { FIELD_CPU,     "CPU(sec)",  10, compare_cpu,     print_cpu     },
-       { FIELD_CPU_PCT, "CPU(%)",     6, compare_cpu_pct, print_cpu_pct },
-       { FIELD_MEM,     "MEM(k)",    10, compare_mem,     print_mem     },
-       { FIELD_MEM_PCT, "MEM(%)",     6, compare_mem,     print_mem_pct },
-       { FIELD_MAXMEM,  "MAXMEM(k)", 10, compare_maxmem,  print_maxmem  },
-       { FIELD_MAX_PCT, "MAXMEM(%)",  9, compare_maxmem,  print_max_pct },
-       { FIELD_VCPUS,   "VCPUS",      5, compare_vcpus,   print_vcpus   },
-       { FIELD_NETS,    "NETS",       4, compare_nets,    print_nets    },
-       { FIELD_NET_TX,  "NETTX(k)",   8, compare_net_tx,  print_net_tx  },
-       { FIELD_NET_RX,  "NETRX(k)",   8, compare_net_rx,  print_net_rx  },
-       { FIELD_SSID,    "SSID",       4, compare_ssid,    print_ssid    }
-};
-
-const unsigned int NUM_FIELDS = sizeof(fields)/sizeof(field);
-
-/* Globals */
-struct timeval curtime, oldtime;
-xenstat_handle *xhandle = NULL;
-xenstat_node *prev_node = NULL;
-xenstat_node *cur_node = NULL;
-field_id sort_field = FIELD_DOMID;
-unsigned int first_domain_index = 0;
-unsigned int delay = 1;
-int show_vcpus = 0;
-int show_networks = 0;
-int repeat_header = 0;
-#define PROMPT_VAL_LEN 80
-char *prompt = NULL;
-char prompt_val[PROMPT_VAL_LEN];
-int prompt_val_len = 0;
-void (*prompt_complete_func)(char *);
-
-/*
- * Function definitions
- */
-
-/* Utility functions */
-
-/* Print usage message, using given program name */
-static void usage(const char *program)
-{
-       printf("Usage: %s [OPTION]\n"
-              "Displays ongoing information about xen vm resources \n\n"
-              "-h, --help           display this help and exit\n"
-              "-V, --version        output version information and exit\n"
-              "-d, --delay=SECONDS  seconds between updates (default 1)\n"
-              "-n, --networks       output vif network data\n"
-              "-r, --repeat-header  repeat table header before each domain\n"
-              "-v, --vcpus          output vcpu data\n"
-              "\n" VM_TOP_BUGSTO,
-              program);
-       return;
-}
-
-/* Print program version information */
-static void version(void)
-{
-       printf("vm-top " VM_TOP_VERSION "\n"
-              "Written by Judy Fischbach, David Hendricks, Josh Triplett\n"
-              "\n" VM_TOP_DISCLAIMER);
-}
-
-/* Clean up any open resources */
-static void cleanup(void)
-{
-       if(!isendwin())
-               endwin();
-       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)
-{
-       if(!isendwin())
-               endwin();
-       fprintf(stderr, str);
-       exit(1);
-}
-
-/* Return the row containing the cursor. */
-static int current_row(void)
-{
-       int y, x;
-       getyx(stdscr, y, x);
-       return y;
-}
-
-/* Return the number of lines on the screen. */
-static int lines(void)
-{
-       int y, x;
-       getmaxyx(stdscr, y, x);
-       return y;
-}
-
-/* printf-style print function which calls printw, but only if the cursor is
- * not on the last line. */
-static void print(const char *fmt, ...)
-{
-       va_list args;
-
-       if(current_row() < lines()-1) {
-               va_start(args, fmt);
-               vw_printw(stdscr, fmt, args);
-               va_end(args);
-       }
-}
-
-/* Print a string with the given attributes set. */
-static void attr_addstr(int attr, const char *str)
-{
-       attron(attr);
-       addstr(str);
-       attroff(attr);
-}
-
-/* Handle setting the delay from the user-supplied value in prompt_val */
-static void set_delay(char *value)
-{
-       int new_delay;
-       new_delay = atoi(prompt_val);
-       if(new_delay > 0)
-               delay = new_delay;
-}
-
-/* Enable prompting mode with the given prompt string; call the given function
- * when a value is available. */
-static void set_prompt(char *new_prompt, void (*func)(char *))
-{
-       prompt = new_prompt;
-       prompt_val[0] = '\0';
-       prompt_val_len = 0;
-       prompt_complete_func = func;
-}
-
-/* Handle user input, return 0 if the program should quit, or 1 if not */
-static int handle_key(int ch)
-{
-       if(prompt == NULL) {
-               /* Not prompting for input; handle interactive commands */
-               switch(ch) {
-               case 'n': case 'N':
-                       show_networks ^= 1;
-                       break;
-               case 'r': case 'R':
-                       repeat_header ^= 1;
-                       break;
-               case 's': case 'S':
-                       sort_field = (sort_field + 1) % NUM_FIELDS;
-                       break;
-               case 'v': case 'V':
-                       show_vcpus ^= 1;
-                       break;
-               case KEY_DOWN:
-                       first_domain_index++;
-                       break;
-               case KEY_UP:
-                       if(first_domain_index > 0)
-                               first_domain_index--;
-                       break;
-               case 'd': case 'D':
-                       set_prompt("Delay(sec)", set_delay);
-                       break;
-               case 'q': case 'Q': case KEY_ESCAPE:
-                       return 0;
-               }
-       } else {
-               /* Prompting for input; handle line editing */
-               switch(ch) {
-               case '\r':
-                       prompt_complete_func(prompt_val);
-                       set_prompt(NULL, NULL);
-                       break;
-               case KEY_ESCAPE:
-                       set_prompt(NULL, NULL);
-                       break;
-               case KEY_BACKSPACE:
-                       if(prompt_val_len > 0)
-                               prompt_val[--prompt_val_len] = '\0';
-               default:
-                       if((prompt_val_len+1) < PROMPT_VAL_LEN
-                          && isprint(ch)) {
-                               prompt_val[prompt_val_len++] = (char)ch;
-                               prompt_val[prompt_val_len] = '\0';
-                       }
-               }
-       }
-
-       return 1;
-}
-
-/* Compares two integers, returning -1,0,1 for <,=,> */
-static int compare(unsigned long long i1, unsigned long long i2)
-{
-       if(i1 < i2)
-               return -1;
-       if(i1 > i2)
-               return 1;
-       return 0;
-}
-
-/* Comparison function for use with qsort.  Compares two domains using the
- * current sort field. */
-static int compare_domains(xenstat_domain **domain1, xenstat_domain **domain2)
-{
-       return fields[sort_field].compare(*domain1, *domain2);
-}
-
-/* Field functions */
-
-/* Compares domain ids of two domains, returning -1,0,1 for <,=,> */
-int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2)
-{
-       return compare(xenstat_domain_id(domain1), xenstat_domain_id(domain2));
-}
-
-/* Prints domain identification number */
-void print_domid(xenstat_domain *domain)
-{
-       print("%5u", xenstat_domain_id(domain));
-}
-
-struct {
-       unsigned int (*get)(xenstat_domain *);
-       char ch;
-} state_funcs[] = {
-       { xenstat_domain_dying,    'd' },
-       { xenstat_domain_shutdown, 's' },
-       { xenstat_domain_blocked,  'b' },
-       { xenstat_domain_crashed,  'c' },
-       { xenstat_domain_paused,   'p' },
-       { xenstat_domain_running,  'r' }
-};
-const unsigned int NUM_STATES = sizeof(state_funcs)/sizeof(*state_funcs);
-
-/* Compare states of two domains, returning -1,0,1 for <,=,> */
-static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2)
-{
-       unsigned int i, d1s, d2s;
-       for(i = 0; i < NUM_STATES; i++) {
-               d1s = state_funcs[i].get(domain1);
-               d2s = state_funcs[i].get(domain2);
-               if(d1s && !d2s)
-                       return -1;
-               if(d2s && !d1s)
-                       return 1;
-       }
-       return 0;
-}
-
-/* Prints domain state in abbreviated letter format */
-static void print_state(xenstat_domain *domain)
-{
-       unsigned int i;
-       for(i = 0; i < NUM_STATES; i++)
-               print("%c", state_funcs[i].get(domain) ? state_funcs[i].ch
-                                                      : '-');
-}
-
-/* Compares cpu usage of two domains, returning -1,0,1 for <,=,> */
-static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2)
-{
-       return -compare(xenstat_domain_cpu_ns(domain1),
-                       xenstat_domain_cpu_ns(domain2));
-}
-
-/* Prints domain cpu usage in seconds */
-static void print_cpu(xenstat_domain *domain)
-{
-       print("%10llu", xenstat_domain_cpu_ns(domain)/1000000000);
-}
-
-/* Computes the CPU percentage used for a specified domain */
-static double get_cpu_pct(xenstat_domain *domain)
-{
-       xenstat_domain *old_domain;
-       double us_elapsed;
-
-       /* Can't calculate CPU percentage without a previous sample. */
-       if(prev_node == NULL)
-               return 0.0;
-
-       old_domain = xenstat_node_domain(prev_node, xenstat_domain_id(domain));
-       if(old_domain == NULL)
-               return 0.0;
-
-       /* Calculate the time elapsed in microseconds */
-       us_elapsed = ((curtime.tv_sec-oldtime.tv_sec)*1000000.0
-                     +(curtime.tv_usec - oldtime.tv_usec));
-
-       /* In the following, nanoseconds must be multiplied by 1000.0 to
-        * convert to microseconds, then divided by 100.0 to get a percentage,
-        * resulting in a multiplication by 10.0 */
-       return ((xenstat_domain_cpu_ns(domain)
-                -xenstat_domain_cpu_ns(old_domain))/10.0)/us_elapsed;
-}
-
-static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2)
-{
-       return -compare(get_cpu_pct(domain1), get_cpu_pct(domain2));
-}
-
-/* Prints cpu percentage statistic */
-static void print_cpu_pct(xenstat_domain *domain)
-{
-       print("%6.1f", get_cpu_pct(domain));
-}
-
-/* Compares current memory of two domains, returning -1,0,1 for <,=,> */
-static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2)
-{
-       return -compare(xenstat_domain_cur_mem(domain1),
-                       xenstat_domain_cur_mem(domain2));
-}
-
-/* Prints current memory statistic */
-static void print_mem(xenstat_domain *domain)
-{
-       print("%10llu", xenstat_domain_cur_mem(domain)/1024);
-}
-
-/* Prints memory percentage statistic, ratio of current domain memory to total
- * node memory */
-static void print_mem_pct(xenstat_domain *domain)
-{
-       print("%6.1f", (double)xenstat_domain_cur_mem(domain) /
-                      (double)xenstat_node_tot_mem(cur_node) * 100);
-}
-
-/* Compares maximum memory of two domains, returning -1,0,1 for <,=,> */
-static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2)
-{
-       return -compare(xenstat_domain_max_mem(domain1),
-                       xenstat_domain_max_mem(domain2));
-}
-
-/* Prints maximum domain memory statistic in KB */
-static void print_maxmem(xenstat_domain *domain)
-{
-       unsigned long long max_mem = xenstat_domain_max_mem(domain);
-       if(max_mem == ((unsigned long long)-1))
-               print("%10s", "no limit");
-       else
-               print("%10llu", max_mem/1024);
-}
-
-/* Prints memory percentage statistic, ratio of current domain memory to total
- * node memory */
-static void print_max_pct(xenstat_domain *domain)
-{
-       if (xenstat_domain_max_mem(domain) == (unsigned long long)-1)
-               print("%9s", "n/a");
-       else
-               print("%9.1f", (double)xenstat_domain_max_mem(domain) /
-                              (double)xenstat_node_tot_mem(cur_node) * 100);
-}
-
-/* Compares number of virtual CPUs of two domains, returning -1,0,1 for
- * <,=,> */
-static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2)
-{
-       return -compare(xenstat_domain_num_vcpus(domain1),
-                       xenstat_domain_num_vcpus(domain2));
-}
-
-/* Prints number of virtual CPUs statistic */
-static void print_vcpus(xenstat_domain *domain)
-{
-       print("%5u", xenstat_domain_num_vcpus(domain));
-}
-
-/* Compares number of virtual networks of two domains, returning -1,0,1 for
- * <,=,> */
-static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2)
-{
-       return -compare(xenstat_domain_num_networks(domain1),
-                       xenstat_domain_num_networks(domain2));
-}
-
-/* Prints number of virtual networks statistic */
-static void print_nets(xenstat_domain *domain)
-{
-       print("%4u", xenstat_domain_num_networks(domain));
-}
-
-/* Compares number of total network tx bytes of two domains, returning -1,0,1 
for
- * <,=,> */
-static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2)
-{
-       return -compare(tot_net_bytes(domain1, FALSE),
-                       tot_net_bytes(domain2, FALSE));
-}
-
-/* Prints number of total network tx bytes statistic */
-static void print_net_tx(xenstat_domain *domain)
-{
-       print("%8llu", tot_net_bytes(domain, FALSE)/1024);
-}
-
-/* Compares number of total network rx bytes of two domains, returning -1,0,1 
for
- * <,=,> */
-static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2)
-{
-       return -compare(tot_net_bytes(domain1, TRUE),
-                       tot_net_bytes(domain2, TRUE));
-}
-
-/* Prints number of total network rx bytes statistic */
-static void print_net_rx(xenstat_domain *domain)
-{
-       print("%8llu", tot_net_bytes(domain, TRUE)/1024);
-}
-
-/* Gets number of total network bytes statistic, if rx true, then rx bytes
- * otherwise tx bytes
- */
-static unsigned long long tot_net_bytes(xenstat_domain *domain, int rx_flag)
-{
-       int i = 0;
-       xenstat_network *network;
-       unsigned num_networks = 0;
-        unsigned long long total = 0;
-
-       /* How many networks? */
-       num_networks = xenstat_domain_num_networks(domain);
-
-       /* Dump information for each network */
-       for (i=0; i < num_networks; i++) {
-               /* Next get the network information */
-               network = xenstat_domain_network(domain,i);
-                if (rx_flag) 
-                       total += xenstat_network_rbytes(network);
-                else 
-                       total += xenstat_network_tbytes(network);
-       }
-        return (total);
-}
-
-/* Compares security id (ssid) of two domains, returning -1,0,1 for <,=,> */
-static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2)
-{
-       return compare(xenstat_domain_ssid(domain1),
-                      xenstat_domain_ssid(domain2));
-}
-
-/* Prints ssid statistic */
-static void print_ssid(xenstat_domain *domain)
-{
-       print("%4u", xenstat_domain_ssid(domain));
-}
-
-/* Section printing functions */
-/* Prints three line summary header */
-void do_summary(void)
-{
-#define TIME_STR_LEN 9
-       const char *TIME_STR_FORMAT = "%H:%M:%S";
-       char time_str[TIME_STR_LEN];
-       unsigned run = 0, block = 0, pause = 0,
-                crash = 0, dying = 0, shutdown = 0;
-       unsigned i, num_domains = 0;
-       unsigned long long used = 0;
-       xenstat_domain *domain;
-
-       /* Print program name, current time, and number of domains */
-       strftime(time_str, TIME_STR_LEN, TIME_STR_FORMAT,
-                localtime(&curtime.tv_sec));
-       num_domains = xenstat_node_num_domains(cur_node);
-       print("vm-top - %s\n", time_str);
-
-       /* Tabulate what states domains are in for summary */
-       for (i=0; i < num_domains; i++) {
-               domain = xenstat_node_domain_by_index(cur_node,i);
-               if (xenstat_domain_running(domain)) run++;
-               else if (xenstat_domain_blocked(domain)) block++;
-               else if (xenstat_domain_paused(domain)) pause++;
-               else if (xenstat_domain_shutdown(domain)) shutdown++;
-               else if (xenstat_domain_crashed(domain)) crash++;
-               else if (xenstat_domain_dying(domain)) dying++;
-       }
-
-       print("%u domains: %u running, %u blocked, %u paused, "
-             "%u crashed, %u dying, %u shutdown \n",
-             num_domains, run, block, pause, crash, dying, shutdown);
-
-       used = xenstat_node_tot_mem(cur_node)-xenstat_node_free_mem(cur_node);
-
-       /* Dump node memory and cpu information */
-       print("Mem: %lluk total, %lluk used, %lluk free    "
-             "CPUs: %u @ %lluMHz\n",
-             xenstat_node_tot_mem(cur_node)/1024, used/1024,
-             xenstat_node_free_mem(cur_node)/1024,
-             xenstat_node_num_cpus(cur_node),
-             xenstat_node_cpu_hz(cur_node)/1000000);
-}
-
-/* Display top portion of vm-top */
-void do_header(void)
-{
-       field_id i;
-
-       /* Turn on REVERSE highlight attribute for headings */
-       attron(A_REVERSE);
-       for(i = 0; i < NUM_FIELDS; i++) {
-               if(i != 0)
-                       print(" ");
-               /* The BOLD attribute is turned on for the sort column */
-               if(i == sort_field)
-                       attron(A_BOLD);
-               print("%*s", fields[i].default_width, fields[i].header);
-               if(i == sort_field)
-                       attroff(A_BOLD);
-       }
-       attroff(A_REVERSE);
-       print("\n");
-}
-
-/* Displays bottom portion of vm-top, interactive options
- * N toggles network information display, V toggles CPU information
- * display, S toggles sort order of information (ascending/descending),
- * R toggles whether header is repeated for each domain
- */
-void do_bottom_line(void)
-{
-       move(lines()-1, 2);
-
-       if (prompt != NULL) {
-               printw("%s: %s", prompt, prompt_val);
-       } else {
-               addch(A_REVERSE | 'D'); addstr("elay  ");
-
-               /* network */
-               addch(A_REVERSE | 'N');
-               attr_addstr(show_networks ? COLOR_PAIR(1) : 0, "etworks");
-               addstr("  ");
-
-               /* vcpus */
-               addch(A_REVERSE | 'V');
-               attr_addstr(show_vcpus ? COLOR_PAIR(1) : 0, "CPUs");
-               addstr("  ");
-
-               /* repeat */
-               addch(A_REVERSE | 'R');
-               attr_addstr(repeat_header ? COLOR_PAIR(1) : 0, "epeat header");
-               addstr("  ");
-
-               /* sort order */
-               addch(A_REVERSE | 'S'); addstr("ort order  ");
-
-               addch(A_REVERSE | 'Q'); addstr("uit  ");
-       }
-}
-
-/* Prints Domain information */
-void do_domain(xenstat_domain *domain)
-{
-       unsigned int i;
-       for(i = 0; i < NUM_FIELDS; i++) {
-               if(i != 0)
-                       print(" ");
-               if(i == sort_field)
-                       attron(A_BOLD);
-               fields[i].print(domain);
-               if(i == sort_field)
-                       attroff(A_BOLD);
-       }
-       print("\n");
-}
-
-/* Output all vcpu information */
-void do_vcpu(xenstat_domain *domain)
-{
-       int i = 0;
-       unsigned num_vcpus = 0;
-       xenstat_vcpu *vcpu;
-
-       print("VCPUs(sec): ");
-
-       num_vcpus = xenstat_domain_num_vcpus(domain);
-
-       /* for all vcpus dump out values */
-       for (i=0; i< num_vcpus; i++) {
-               vcpu = xenstat_domain_vcpu(domain,i);
-
-               if (i != 0 && (i%5)==0)
-                       print("\n        ");
-               print(" %2u: %10llus", i, xenstat_vcpu_ns(vcpu)/1000000000);
-       }
-       print("\n");
-}
-
-/* Output all network information */
-void do_network(xenstat_domain *domain)
-{
-       int i = 0;
-       xenstat_network *network;
-       unsigned num_networks = 0;
-
-       /* How many networks? */
-       num_networks = xenstat_domain_num_networks(domain);
-
-       /* Dump information for each network */
-       for (i=0; i < num_networks; i++) {
-               /* Next get the network information */
-               network = xenstat_domain_network(domain,i);
-
-               print("Net%d RX: %8llubytes %8llupkts %8lluerr %8lludrop  ",
-                     i,
-                     xenstat_network_rbytes(network),
-                     xenstat_network_rpackets(network),
-                     xenstat_network_rerrs(network),
-                     xenstat_network_rdrop(network));
-
-               print("TX: %8llubytes %8llupkts %8lluerr %8lludrop\n",
-                     xenstat_network_tbytes(network),
-                     xenstat_network_tpackets(network),
-                     xenstat_network_terrs(network),
-                     xenstat_network_tdrop(network));
-       }
-}
-
-static void top(void)
-{
-       xenstat_domain **domains;
-       unsigned int i, num_domains = 0;
-
-       /* Now get the node information */
-       if (prev_node != NULL)
-               xenstat_free_node(prev_node);
-       prev_node = cur_node;
-       cur_node = xenstat_get_node(xhandle, XENSTAT_ALL);
-       if (cur_node == NULL)
-               fail("Failed to retrieve statistics from libxenstat\n");
-
-       /* dump summary top information */
-       do_summary();
-
-       /* Count the number of domains for which to report data */
-       num_domains = xenstat_node_num_domains(cur_node);
-
-       domains = malloc(num_domains*sizeof(xenstat_domain *));
-       if(domains == NULL)
-               fail("Failed to allocate memory\n");
-
-       for (i=0; i < num_domains; i++)
-               domains[i] = xenstat_node_domain_by_index(cur_node, i);
-
-       /* Sort */
-       qsort(domains, num_domains, sizeof(xenstat_domain *),
-             (int(*)(const void *, const void *))compare_domains);
-
-       if(first_domain_index >= num_domains)
-               first_domain_index = num_domains-1;
-
-       for (i = first_domain_index; i < num_domains; i++) {
-               if(current_row() == lines()-1)
-                       break;
-               if (i == first_domain_index || repeat_header)
-                       do_header();
-               do_domain(domains[i]);
-               if (show_vcpus)
-                       do_vcpu(domains[i]);
-               if (show_networks)
-                       do_network(domains[i]);
-       }
-
-       do_bottom_line();
-}
-
-int main(int argc, char **argv)
-{
-       int opt, optind = 0;
-       int ch = ERR;
-
-       struct option lopts[] = {
-               { "help",          no_argument,       NULL, 'h' },
-               { "version",       no_argument,       NULL, 'V' },
-               { "networks",      no_argument,       NULL, 'n' },
-               { "repeat-header", no_argument,       NULL, 'r' },
-               { "vcpus",         no_argument,       NULL, 'v' },
-               { "delay",         required_argument, NULL, 'd' },
-               { 0, 0, 0, 0 },
-       };
-       const char *sopts = "hVbnvd:";
-
-       if (atexit(cleanup) != 0)
-               fail("Failed to install cleanup handler.\n");
-
-       while ((opt = getopt_long(argc, argv, sopts, lopts, &optind)) != -1) {
-               switch (opt) {
-               case 'h':
-               case '?':
-               default:
-                       usage(argv[0]);
-                       exit(0);
-               case 'V':
-                       version();
-                       exit(0);
-               case 'n':
-                       show_networks = 1;
-                       break;
-               case 'r':
-                       repeat_header = 1;
-                       break;
-               case 'v':
-                       show_vcpus = 1;
-                       break;
-               case 'd':
-                       delay = atoi(optarg);
-                       break;
-               }
-       }
-
-       /* Get xenstat handle */
-       xhandle = xenstat_init();
-       if (xhandle == NULL)
-               fail("Failed to initialize xenstat library\n");
-
-       /* Begin curses stuff */
-       initscr();
-       start_color();
-       cbreak();
-       noecho();
-       nonl();
-       keypad(stdscr, TRUE);
-       halfdelay(5);
-       use_default_colors();
-       init_pair(1, -1, COLOR_YELLOW);
-
-       do {
-               gettimeofday(&curtime, NULL);
-               if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) {
-                       clear();
-                       top();
-                       oldtime = curtime;
-                       refresh();
-               }
-               ch = getch();
-       } while (handle_key(ch));
-
-       /* Cleanup occurs in cleanup(), so no work to do here. */
-
-       return 0;
-}

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


 


Rackspace

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