ia64/xen-unstable
changeset 6337:173b918160e2
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@us.ibm.com
# 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.
# HG changeset patch
# User josht@us.ibm.com
# 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.
author | josht@us.ibm.com |
---|---|
date | Wed Aug 17 16:50:33 2005 +0000 (2005-08-17) |
parents | b38cbc8f4d98 |
children | 59a6a0350158 |
files | Config.mk tools/python/xen/xm/main.py tools/xenstat/Makefile tools/xenstat/libxenstat/Makefile tools/xenstat/xentop/Makefile tools/xenstat/xentop/TODO tools/xenstat/xentop/xentop.1 tools/xenstat/xentop/xentop.c |
line diff
1.1 --- a/Config.mk Mon Aug 15 18:25:33 2005 +0000 1.2 +++ b/Config.mk Wed Aug 17 16:50:33 2005 +0000 1.3 @@ -14,6 +14,7 @@ LD = $(CROSS_COMPILE)ld 1.4 CC = $(CROSS_COMPILE)gcc 1.5 CPP = $(CROSS_COMPILE)gcc -E 1.6 AR = $(CROSS_COMPILE)ar 1.7 +RANLIB = $(CROSS_COMPILE)ranlib 1.8 NM = $(CROSS_COMPILE)nm 1.9 STRIP = $(CROSS_COMPILE)strip 1.10 OBJCOPY = $(CROSS_COMPILE)objcopy 1.11 @@ -37,6 +38,4 @@ CFLAGS += $(foreach i, $(EXTRA_INCLUDES) 1.12 KERNEL_REPO = http://www.kernel.org 1.13 1.14 # Optional components 1.15 -XENSTAT_PERL_BINDINGS ?= n 1.16 -XENSTAT_PYTHON_BINDINGS ?= y 1.17 -XENSTAT_VM_TOP ?= y 1.18 +XENSTAT_XENTOP ?= y
2.1 --- a/tools/python/xen/xm/main.py Mon Aug 15 18:25:33 2005 +0000 2.2 +++ b/tools/python/xen/xm/main.py Wed Aug 17 16:50:33 2005 +0000 2.3 @@ -49,6 +49,7 @@ xm common subcommands: 2.4 restore <File> create a domain from a saved state file 2.5 save <DomId> <File> save domain state (and config) to file 2.6 shutdown <DomId> shutdown a domain 2.7 + top monitor system and domains in real-time 2.8 unpause <DomId> unpause a paused domain 2.9 2.10 For a complete list of subcommands run 'xm help --long' 2.11 @@ -87,6 +88,7 @@ xm full list of subcommands: 2.12 dmesg [--clear] read or clear Xen's message buffer 2.13 info get information about the xen host 2.14 log print the xend log 2.15 + top monitor system and domains in real-time 2.16 2.17 Scheduler Commands: 2.18 bvt <options> set BVT scheduler parameters 2.19 @@ -452,6 +454,9 @@ def xm_console(args): 2.20 os.execvp('/usr/libexec/xen/xenconsole', cmd.split()) 2.21 console = sxp.child(info, "console") 2.22 2.23 +def xm_top(args): 2.24 + os.execv('/usr/sbin/xentop', ['/usr/sbin/xentop']) 2.25 + 2.26 def xm_dmesg(args): 2.27 2.28 gopts = Opts(use="""[-c|--clear] 2.29 @@ -540,6 +545,8 @@ def xm_block_destroy(args): 2.30 commands = { 2.31 # console commands 2.32 "console": xm_console, 2.33 + # xenstat commands 2.34 + "top": xm_top, 2.35 # domain commands 2.36 "domid": xm_domid, 2.37 "domname": xm_domname,
3.1 --- a/tools/xenstat/Makefile Mon Aug 15 18:25:33 2005 +0000 3.2 +++ b/tools/xenstat/Makefile Wed Aug 17 16:50:33 2005 +0000 3.3 @@ -3,7 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk 3.4 3.5 SUBDIRS := 3.6 SUBDIRS += libxenstat 3.7 -SUBDIRS += vm-top 3.8 +SUBDIRS += xentop 3.9 3.10 .PHONY: all install clean 3.11
4.1 --- a/tools/xenstat/libxenstat/Makefile Mon Aug 15 18:25:33 2005 +0000 4.2 +++ b/tools/xenstat/libxenstat/Makefile Wed Aug 17 16:50:33 2005 +0000 4.3 @@ -30,8 +30,9 @@ MAKE_LINK=ln -sf 4.4 MAJOR=0 4.5 MINOR=0 4.6 4.7 -LIB=src/libxenstat.so.$(MAJOR).$(MINOR) 4.8 -LINKS=src/libxenstat.so.$(MAJOR) src/libxenstat.so 4.9 +LIB=src/libxenstat.a 4.10 +SHLIB=src/libxenstat.so.$(MAJOR).$(MINOR) 4.11 +SHLIB_LINKS=src/libxenstat.so.$(MAJOR) src/libxenstat.so 4.12 OBJECTS=src/xenstat.o src/xen-interface.o 4.13 SONAME_FLAGS=-Wl,-soname -Wl,libxenstat.so.$(MAJOR) 4.14 4.15 @@ -42,9 +43,13 @@ CFLAGS+=-I$(XEN_ROOT)/xen/include/public 4.16 CFLAGS+=-I$(LINUX_ROOT)/include/asm-xen/linux-public/ 4.17 LDFLAGS+=-Lsrc 4.18 4.19 -all: $(LIB) $(LINKS) 4.20 +all: $(LIB) 4.21 4.22 $(LIB): $(OBJECTS) 4.23 + $(AR) rc $@ $^ 4.24 + $(RANLIB) $@ 4.25 + 4.26 +$(SHLIB): $(OBJECTS) 4.27 $(CC) $(LDFLAGS) $(SONAME_FLAGS) -shared -o $@ $(OBJECTS) 4.28 4.29 src/xenstat.o: src/xenstat.c src/xenstat.h src/xen-interface.h 4.30 @@ -59,15 +64,17 @@ src/libxenstat.so.$(MAJOR): $(LIB) 4.31 src/libxenstat.so: src/libxenstat.so.$(MAJOR) 4.32 $(MAKE_LINK) $(<F) $@ 4.33 4.34 -install: all 4.35 - $(INSTALL_DATA) src/xenstat.h $(DESTDIR)$(includedir)/xenstat.h 4.36 - $(INSTALL_PROG) $(LIB) \ 4.37 - $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR).$(MINOR) 4.38 - $(MAKE_LINK) libxenstat.so.$(MAJOR).$(MINOR) \ 4.39 - $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR) 4.40 - $(MAKE_LINK) libxenstat.so.$(MAJOR) \ 4.41 - $(DESTDIR)$(libdir)/libxenstat.so 4.42 - -$(LDCONFIG) 4.43 +install: 4.44 +#install: all 4.45 +# $(INSTALL_DATA) src/xenstat.h $(DESTDIR)$(includedir)/xenstat.h 4.46 +# $(INSTALL_PROG) $(LIB) $(DESTDIR)$(libdir)/libxenstat.a 4.47 +# $(INSTALL_PROG) $(SHLIB) \ 4.48 +# $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR).$(MINOR) 4.49 +# $(MAKE_LINK) libxenstat.so.$(MAJOR).$(MINOR) \ 4.50 +# $(DESTDIR)$(libdir)/libxenstat.so.$(MAJOR) 4.51 +# $(MAKE_LINK) libxenstat.so.$(MAJOR) \ 4.52 +# $(DESTDIR)$(libdir)/libxenstat.so 4.53 +# -$(LDCONFIG) 4.54 4.55 PYLIB=bindings/swig/python/_xenstat.so 4.56 PYMOD=bindings/swig/python/xenstat.py 4.57 @@ -84,7 +91,7 @@ all-bindings: perl-bindings python-bindi 4.58 # The install-bindings target installs all the language bindings 4.59 install-bindings: install-perl-bindings install-python-bindings 4.60 4.61 -$(BINDINGS): $(LIB) $(LINKS) src/xenstat.h 4.62 +$(BINDINGS): $(SHLIB) $(SHLIB_LINKS) src/xenstat.h 4.63 4.64 SWIG_FLAGS=-module xenstat -Isrc 4.65 4.66 @@ -131,4 +138,5 @@ install: install-perl-bindings 4.67 endif 4.68 4.69 clean: 4.70 - rm -f $(LIB) $(OBJECTS) $(LINKS) $(BINDINGS) $(BINDINGSRC) 4.71 + rm -f $(LIB) $(SHLIB) $(SHLIB_LINKS) $(OBJECTS) \ 4.72 + $(BINDINGS) $(BINDINGSRC)
5.1 --- a/tools/xenstat/vm-top/Makefile Mon Aug 15 18:25:33 2005 +0000 5.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 5.3 @@ -1,43 +0,0 @@ 5.4 -# Copyright (C) International Business Machines Corp., 2005 5.5 -# Author: Josh Triplett <josht@us.ibm.com> 5.6 -# 5.7 -# This program is free software; you can redistribute it and/or modify 5.8 -# it under the terms of the GNU General Public License as published by 5.9 -# the Free Software Foundation; under version 2 of the License. 5.10 -# 5.11 -# This program is distributed in the hope that it will be useful, 5.12 -# but WITHOUT ANY WARRANTY; without even the implied warranty of 5.13 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 5.14 -# GNU General Public License for more details. 5.15 - 5.16 -XEN_ROOT=../../.. 5.17 -include $(XEN_ROOT)/tools/Rules.mk 5.18 - 5.19 -ifneq ($(XENSTAT_VM_TOP),y) 5.20 -all install vm-top: 5.21 -else 5.22 - 5.23 -INSTALL = install 5.24 -INSTALL_PROG = $(INSTALL) -m0755 -D 5.25 -INSTALL_DATA = $(INSTALL) -m0644 -D 5.26 - 5.27 -prefix=/usr 5.28 -mandir=$(prefix)/share/man 5.29 -man1dir=$(mandir)/man1 5.30 -sbindir=$(prefix)/sbin 5.31 - 5.32 -CFLAGS += -DGCC_PRINTF -Wall -Werror -I$(XEN_LIBXENSTAT) 5.33 -LDFLAGS += -L$(XEN_LIBXENSTAT) -lxenstat -lcurses 5.34 - 5.35 -all: vm-top 5.36 - 5.37 -vm-top: vm-top.o 5.38 - 5.39 -install: vm-top vm-top.1 5.40 - $(INSTALL_PROG) vm-top $(DESTDIR)$(sbindir)/vm-top 5.41 - $(INSTALL_DATA) vm-top.1 $(DESTDIR)$(man1dir)/vm-top.1 5.42 - 5.43 -endif 5.44 - 5.45 -clean: 5.46 - rm -f vm-top vm-top.o
6.1 --- a/tools/xenstat/vm-top/TODO Mon Aug 15 18:25:33 2005 +0000 6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 @@ -1,37 +0,0 @@ 6.4 -Inefficient about how it handles newlines in vm-top 6.5 -for proc/net/dev. Fix. 6.6 - 6.7 -Display error messages on the help line after bad input at a prompt. 6.8 -Fractional delay times 6.9 -Use prompting to search for domains 6.10 -Better line editing? 6.11 - 6.12 -* Make CPU in % more accurate 6.13 -* Domain total network TX % and RX % 6.14 - 6.15 -Like Top, f feature, field select of domain columns, toggle the display of 6.16 -field by typing the letter associated with field, if displayed it shows in 6.17 -bold and the letter is Capitalized along with a leading asterisk for the 6.18 -field, if not selected for display letter is lowercase, no leading asterisk 6.19 -and field is not bolded. 6.20 - 6.21 -Like Top, ordering of domain columns, o feature Capital letter shifts left, 6.22 -lowercase letter shifts right? 6.23 - 6.24 -Color 6.25 -Full management: pause, destroy, create domains 6.26 - 6.27 -Add support for Virtual Block Devices (vbd) 6.28 - 6.29 -To think about: 6.30 -Support for one than one node display (distributed monitoring 6.31 -from any node of all other nodes in a cluster) 6.32 -Bottom line option (Switch node, Search node [tab completion?]) 6.33 - 6.34 -Capture/Logging of resource information generated during a time interval. 6.35 --b batch mode dump snapshots to standard output (used with -n) 6.36 --n number of iterations to dump to standard output (unlimited if not specified) 6.37 --d monitor DomIDs as -dD1,-dD2 or -dD1,D2... 6.38 - Monitor only domains with specified domain IDs 6.39 --m monitor nodeIDs as -mN1,-mN2 or -mN1,N2... 6.40 - Monitor only domains with specified node IDs
7.1 --- a/tools/xenstat/vm-top/vm-top.1 Mon Aug 15 18:25:33 2005 +0000 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,88 +0,0 @@ 7.4 -.\" Copyright (C) International Business Machines Corp., 2005 7.5 -.\" Author: Josh Triplett <josht@us.ibm.com> 7.6 -.\" 7.7 -.\" This program is free software; you can redistribute it and/or modify 7.8 -.\" it under the terms of the GNU General Public License as published by 7.9 -.\" the Free Software Foundation; under version 2 of the License. 7.10 -.\" 7.11 -.\" This program is distributed in the hope that it will be useful, 7.12 -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of 7.13 -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 7.14 -.\" GNU General Public License for more details. 7.15 -.\" 7.16 -.\" You should have received a copy of the GNU General Public License 7.17 -.\" along with this program; if not, write to the Free Software 7.18 -.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7.19 -.TH vm-top 1 "August 2005" 7.20 -.SH NAME 7.21 -\fBvm-top\fR \- displays real-time information about a Xen system and domains 7.22 - 7.23 -.SH SYNOPSIS 7.24 -.B vm-top 7.25 -[\fB\-h\fR] 7.26 -[\fB\-V\fR] 7.27 -[\fB\-d\fRSECONDS] 7.28 -[\fB\-n\fR] 7.29 -[\fB\-r\fR] 7.30 -[\fB\-v\fR] 7.31 - 7.32 -.SH DESCRIPTION 7.33 -\fBvm-top\fR displays information about the Xen system and domains, in a 7.34 -continually-updating manner. Command-line options and interactive commands 7.35 -can change the detail and format of the information displayed by \fBvm-top\fR. 7.36 - 7.37 -.SH OPTIONS 7.38 -.TP 7.39 -\fB\-h\fR, \fB\-\-help\fR 7.40 -display help and exit 7.41 -.TP 7.42 -\fB\-V\fR, \fB\-\-version\fR 7.43 -output version information and exit 7.44 -.TP 7.45 -\fB\-d\fR, \fB\-\-delay\fR=\fISECONDS\fR 7.46 -seconds between updates (default 1) 7.47 -.TP 7.48 -\fB\-n\fR, \fB\-\-networks\fR 7.49 -output network information 7.50 -.TP 7.51 -\fB\-r\fR, \fB\-\-repeat\-header\fR 7.52 -repeat table header before each domain 7.53 -.TP 7.54 -\fB\-v\fR, \fB\-\-vcpus\fR 7.55 -output VCPU data 7.56 - 7.57 -.SH "INTERACTIVE COMMANDS" 7.58 -All interactive commands are case-insensitive. 7.59 -.TP 7.60 -.B D 7.61 -set delay between updates 7.62 -.TP 7.63 -.B N 7.64 -toggle display of network information 7.65 -.TP 7.66 -.B Q, Esc 7.67 -quit 7.68 -.TP 7.69 -.B R 7.70 -toggle table header before each domain 7.71 -.TP 7.72 -.B S 7.73 -cycle sort order 7.74 -.TP 7.75 -.B V 7.76 -toggle display of VCPU information 7.77 -.TP 7.78 -.B Arrows 7.79 -scroll domain display 7.80 - 7.81 -.SH AUTHORS 7.82 -Written by Judy Fischbach, David Hendricks, and Josh Triplett 7.83 - 7.84 -.SH "REPORTING BUGS" 7.85 -Report bugs to <dsteklof@us.ibm.com>. 7.86 - 7.87 -.SH COPYRIGHT 7.88 -Copyright \(co 2005 International Business Machines Corp 7.89 -.br 7.90 -This is free software; see the source for copying conditions. There is NO 7.91 -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8.1 --- a/tools/xenstat/vm-top/vm-top.c Mon Aug 15 18:25:33 2005 +0000 8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 8.3 @@ -1,880 +0,0 @@ 8.4 -/* 8.5 - * Copyright (C) International Business Machines Corp., 2005 8.6 - * Author(s): Judy Fischbach <jfisch@us.ibm.com> 8.7 - * David Hendricks <dhendrix@us.ibm.com> 8.8 - * Josh Triplett <josht@us.ibm.com> 8.9 - * based on code from Anthony Liguori <aliguori@us.ibm.com> 8.10 - * 8.11 - * This program is free software; you can redistribute it and/or modify 8.12 - * it under the terms of the GNU General Public License as published by 8.13 - * the Free Software Foundation; under version 2 of the License. 8.14 - * 8.15 - * This program is distributed in the hope that it will be useful, 8.16 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 8.17 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.18 - * GNU General Public License for more details. 8.19 - * 8.20 - * You should have received a copy of the GNU General Public License 8.21 - * along with this program; if not, write to the Free Software 8.22 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 8.23 - */ 8.24 -#include <curses.h> 8.25 -#include <ctype.h> 8.26 -#include <errno.h> 8.27 -#include <stdio.h> 8.28 -#include <stdlib.h> 8.29 -#include <string.h> 8.30 -#include <sys/time.h> 8.31 -#include <time.h> 8.32 -#include <unistd.h> 8.33 - 8.34 -#include <xenstat.h> 8.35 - 8.36 -#define VM_TOP_VERSION "1.0" 8.37 - 8.38 -#define VM_TOP_DISCLAIMER \ 8.39 -"Copyright (C) 2005 International Business Machines Corp\n"\ 8.40 -"This is free software; see the source for copying conditions.There is NO\n"\ 8.41 -"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" 8.42 -#define VM_TOP_BUGSTO "Report bugs to <dsteklof@us.ibm.com>.\n" 8.43 - 8.44 -#define _GNU_SOURCE 8.45 -#include <getopt.h> 8.46 - 8.47 -#if !defined(__GNUC__) && !defined(__GNUG__) 8.48 -#define __attribute__(arg) /* empty */ 8.49 -#endif 8.50 - 8.51 -#define KEY_ESCAPE '\x1B' 8.52 - 8.53 -/* 8.54 - * Function prototypes 8.55 - */ 8.56 -/* Utility functions */ 8.57 -static void usage(const char *); 8.58 -static void version(void); 8.59 -static void cleanup(void); 8.60 -static void fail(const char *); 8.61 -static int current_row(void); 8.62 -static int lines(void); 8.63 -static void print(const char *, ...) __attribute__((format(printf,1,2))); 8.64 -static void attr_addstr(int attr, const char *str); 8.65 -static void set_delay(char *value); 8.66 -static void set_prompt(char *new_prompt, void (*func)(char *)); 8.67 -static int handle_key(int); 8.68 -static int compare(unsigned long long, unsigned long long); 8.69 -static int compare_domains(xenstat_domain **, xenstat_domain **); 8.70 -static unsigned long long tot_net_bytes( xenstat_domain *, int); 8.71 - 8.72 -/* Field functions */ 8.73 -static int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2); 8.74 -static void print_domid(xenstat_domain *domain); 8.75 -static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2); 8.76 -static void print_state(xenstat_domain *domain); 8.77 -static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2); 8.78 -static void print_cpu(xenstat_domain *domain); 8.79 -static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2); 8.80 -static void print_cpu_pct(xenstat_domain *domain); 8.81 -static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2); 8.82 -static void print_mem(xenstat_domain *domain); 8.83 -static void print_mem_pct(xenstat_domain *domain); 8.84 -static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2); 8.85 -static void print_maxmem(xenstat_domain *domain); 8.86 -static void print_max_pct(xenstat_domain *domain); 8.87 -static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2); 8.88 -static void print_vcpus(xenstat_domain *domain); 8.89 -static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2); 8.90 -static void print_nets(xenstat_domain *domain); 8.91 -static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2); 8.92 -static void print_net_tx(xenstat_domain *domain); 8.93 -static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2); 8.94 -static void print_net_rx(xenstat_domain *domain); 8.95 -static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2); 8.96 -static void print_ssid(xenstat_domain *domain); 8.97 - 8.98 -/* Section printing functions */ 8.99 -static void do_summary(void); 8.100 -static void do_header(void); 8.101 -static void do_bottom_line(void); 8.102 -static void do_domain(xenstat_domain *); 8.103 -static void do_vcpu(xenstat_domain *); 8.104 -static void do_network(xenstat_domain *); 8.105 -static void top(void); 8.106 - 8.107 -/* Field types */ 8.108 -typedef enum field_id { 8.109 - FIELD_DOMID, 8.110 - FIELD_STATE, 8.111 - FIELD_CPU, 8.112 - FIELD_CPU_PCT, 8.113 - FIELD_MEM, 8.114 - FIELD_MEM_PCT, 8.115 - FIELD_MAXMEM, 8.116 - FIELD_MAX_PCT, 8.117 - FIELD_VCPUS, 8.118 - FIELD_NETS, 8.119 - FIELD_NET_TX, 8.120 - FIELD_NET_RX, 8.121 - FIELD_SSID 8.122 -} field_id; 8.123 - 8.124 -typedef struct field { 8.125 - field_id num; 8.126 - const char *header; 8.127 - unsigned int default_width; 8.128 - int (*compare)(xenstat_domain *domain1, xenstat_domain *domain2); 8.129 - void (*print)(xenstat_domain *domain); 8.130 -} field; 8.131 - 8.132 -field fields[] = { 8.133 - { FIELD_DOMID, "DOMID", 5, compare_domid, print_domid }, 8.134 - { FIELD_STATE, "STATE", 6, compare_state, print_state }, 8.135 - { FIELD_CPU, "CPU(sec)", 10, compare_cpu, print_cpu }, 8.136 - { FIELD_CPU_PCT, "CPU(%)", 6, compare_cpu_pct, print_cpu_pct }, 8.137 - { FIELD_MEM, "MEM(k)", 10, compare_mem, print_mem }, 8.138 - { FIELD_MEM_PCT, "MEM(%)", 6, compare_mem, print_mem_pct }, 8.139 - { FIELD_MAXMEM, "MAXMEM(k)", 10, compare_maxmem, print_maxmem }, 8.140 - { FIELD_MAX_PCT, "MAXMEM(%)", 9, compare_maxmem, print_max_pct }, 8.141 - { FIELD_VCPUS, "VCPUS", 5, compare_vcpus, print_vcpus }, 8.142 - { FIELD_NETS, "NETS", 4, compare_nets, print_nets }, 8.143 - { FIELD_NET_TX, "NETTX(k)", 8, compare_net_tx, print_net_tx }, 8.144 - { FIELD_NET_RX, "NETRX(k)", 8, compare_net_rx, print_net_rx }, 8.145 - { FIELD_SSID, "SSID", 4, compare_ssid, print_ssid } 8.146 -}; 8.147 - 8.148 -const unsigned int NUM_FIELDS = sizeof(fields)/sizeof(field); 8.149 - 8.150 -/* Globals */ 8.151 -struct timeval curtime, oldtime; 8.152 -xenstat_handle *xhandle = NULL; 8.153 -xenstat_node *prev_node = NULL; 8.154 -xenstat_node *cur_node = NULL; 8.155 -field_id sort_field = FIELD_DOMID; 8.156 -unsigned int first_domain_index = 0; 8.157 -unsigned int delay = 1; 8.158 -int show_vcpus = 0; 8.159 -int show_networks = 0; 8.160 -int repeat_header = 0; 8.161 -#define PROMPT_VAL_LEN 80 8.162 -char *prompt = NULL; 8.163 -char prompt_val[PROMPT_VAL_LEN]; 8.164 -int prompt_val_len = 0; 8.165 -void (*prompt_complete_func)(char *); 8.166 - 8.167 -/* 8.168 - * Function definitions 8.169 - */ 8.170 - 8.171 -/* Utility functions */ 8.172 - 8.173 -/* Print usage message, using given program name */ 8.174 -static void usage(const char *program) 8.175 -{ 8.176 - printf("Usage: %s [OPTION]\n" 8.177 - "Displays ongoing information about xen vm resources \n\n" 8.178 - "-h, --help display this help and exit\n" 8.179 - "-V, --version output version information and exit\n" 8.180 - "-d, --delay=SECONDS seconds between updates (default 1)\n" 8.181 - "-n, --networks output vif network data\n" 8.182 - "-r, --repeat-header repeat table header before each domain\n" 8.183 - "-v, --vcpus output vcpu data\n" 8.184 - "\n" VM_TOP_BUGSTO, 8.185 - program); 8.186 - return; 8.187 -} 8.188 - 8.189 -/* Print program version information */ 8.190 -static void version(void) 8.191 -{ 8.192 - printf("vm-top " VM_TOP_VERSION "\n" 8.193 - "Written by Judy Fischbach, David Hendricks, Josh Triplett\n" 8.194 - "\n" VM_TOP_DISCLAIMER); 8.195 -} 8.196 - 8.197 -/* Clean up any open resources */ 8.198 -static void cleanup(void) 8.199 -{ 8.200 - if(!isendwin()) 8.201 - endwin(); 8.202 - if(prev_node != NULL) 8.203 - xenstat_free_node(prev_node); 8.204 - if(cur_node != NULL) 8.205 - xenstat_free_node(cur_node); 8.206 - if(xhandle != NULL) 8.207 - xenstat_uninit(xhandle); 8.208 -} 8.209 - 8.210 -/* Display the given message and gracefully exit */ 8.211 -static void fail(const char *str) 8.212 -{ 8.213 - if(!isendwin()) 8.214 - endwin(); 8.215 - fprintf(stderr, str); 8.216 - exit(1); 8.217 -} 8.218 - 8.219 -/* Return the row containing the cursor. */ 8.220 -static int current_row(void) 8.221 -{ 8.222 - int y, x; 8.223 - getyx(stdscr, y, x); 8.224 - return y; 8.225 -} 8.226 - 8.227 -/* Return the number of lines on the screen. */ 8.228 -static int lines(void) 8.229 -{ 8.230 - int y, x; 8.231 - getmaxyx(stdscr, y, x); 8.232 - return y; 8.233 -} 8.234 - 8.235 -/* printf-style print function which calls printw, but only if the cursor is 8.236 - * not on the last line. */ 8.237 -static void print(const char *fmt, ...) 8.238 -{ 8.239 - va_list args; 8.240 - 8.241 - if(current_row() < lines()-1) { 8.242 - va_start(args, fmt); 8.243 - vw_printw(stdscr, fmt, args); 8.244 - va_end(args); 8.245 - } 8.246 -} 8.247 - 8.248 -/* Print a string with the given attributes set. */ 8.249 -static void attr_addstr(int attr, const char *str) 8.250 -{ 8.251 - attron(attr); 8.252 - addstr(str); 8.253 - attroff(attr); 8.254 -} 8.255 - 8.256 -/* Handle setting the delay from the user-supplied value in prompt_val */ 8.257 -static void set_delay(char *value) 8.258 -{ 8.259 - int new_delay; 8.260 - new_delay = atoi(prompt_val); 8.261 - if(new_delay > 0) 8.262 - delay = new_delay; 8.263 -} 8.264 - 8.265 -/* Enable prompting mode with the given prompt string; call the given function 8.266 - * when a value is available. */ 8.267 -static void set_prompt(char *new_prompt, void (*func)(char *)) 8.268 -{ 8.269 - prompt = new_prompt; 8.270 - prompt_val[0] = '\0'; 8.271 - prompt_val_len = 0; 8.272 - prompt_complete_func = func; 8.273 -} 8.274 - 8.275 -/* Handle user input, return 0 if the program should quit, or 1 if not */ 8.276 -static int handle_key(int ch) 8.277 -{ 8.278 - if(prompt == NULL) { 8.279 - /* Not prompting for input; handle interactive commands */ 8.280 - switch(ch) { 8.281 - case 'n': case 'N': 8.282 - show_networks ^= 1; 8.283 - break; 8.284 - case 'r': case 'R': 8.285 - repeat_header ^= 1; 8.286 - break; 8.287 - case 's': case 'S': 8.288 - sort_field = (sort_field + 1) % NUM_FIELDS; 8.289 - break; 8.290 - case 'v': case 'V': 8.291 - show_vcpus ^= 1; 8.292 - break; 8.293 - case KEY_DOWN: 8.294 - first_domain_index++; 8.295 - break; 8.296 - case KEY_UP: 8.297 - if(first_domain_index > 0) 8.298 - first_domain_index--; 8.299 - break; 8.300 - case 'd': case 'D': 8.301 - set_prompt("Delay(sec)", set_delay); 8.302 - break; 8.303 - case 'q': case 'Q': case KEY_ESCAPE: 8.304 - return 0; 8.305 - } 8.306 - } else { 8.307 - /* Prompting for input; handle line editing */ 8.308 - switch(ch) { 8.309 - case '\r': 8.310 - prompt_complete_func(prompt_val); 8.311 - set_prompt(NULL, NULL); 8.312 - break; 8.313 - case KEY_ESCAPE: 8.314 - set_prompt(NULL, NULL); 8.315 - break; 8.316 - case KEY_BACKSPACE: 8.317 - if(prompt_val_len > 0) 8.318 - prompt_val[--prompt_val_len] = '\0'; 8.319 - default: 8.320 - if((prompt_val_len+1) < PROMPT_VAL_LEN 8.321 - && isprint(ch)) { 8.322 - prompt_val[prompt_val_len++] = (char)ch; 8.323 - prompt_val[prompt_val_len] = '\0'; 8.324 - } 8.325 - } 8.326 - } 8.327 - 8.328 - return 1; 8.329 -} 8.330 - 8.331 -/* Compares two integers, returning -1,0,1 for <,=,> */ 8.332 -static int compare(unsigned long long i1, unsigned long long i2) 8.333 -{ 8.334 - if(i1 < i2) 8.335 - return -1; 8.336 - if(i1 > i2) 8.337 - return 1; 8.338 - return 0; 8.339 -} 8.340 - 8.341 -/* Comparison function for use with qsort. Compares two domains using the 8.342 - * current sort field. */ 8.343 -static int compare_domains(xenstat_domain **domain1, xenstat_domain **domain2) 8.344 -{ 8.345 - return fields[sort_field].compare(*domain1, *domain2); 8.346 -} 8.347 - 8.348 -/* Field functions */ 8.349 - 8.350 -/* Compares domain ids of two domains, returning -1,0,1 for <,=,> */ 8.351 -int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2) 8.352 -{ 8.353 - return compare(xenstat_domain_id(domain1), xenstat_domain_id(domain2)); 8.354 -} 8.355 - 8.356 -/* Prints domain identification number */ 8.357 -void print_domid(xenstat_domain *domain) 8.358 -{ 8.359 - print("%5u", xenstat_domain_id(domain)); 8.360 -} 8.361 - 8.362 -struct { 8.363 - unsigned int (*get)(xenstat_domain *); 8.364 - char ch; 8.365 -} state_funcs[] = { 8.366 - { xenstat_domain_dying, 'd' }, 8.367 - { xenstat_domain_shutdown, 's' }, 8.368 - { xenstat_domain_blocked, 'b' }, 8.369 - { xenstat_domain_crashed, 'c' }, 8.370 - { xenstat_domain_paused, 'p' }, 8.371 - { xenstat_domain_running, 'r' } 8.372 -}; 8.373 -const unsigned int NUM_STATES = sizeof(state_funcs)/sizeof(*state_funcs); 8.374 - 8.375 -/* Compare states of two domains, returning -1,0,1 for <,=,> */ 8.376 -static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2) 8.377 -{ 8.378 - unsigned int i, d1s, d2s; 8.379 - for(i = 0; i < NUM_STATES; i++) { 8.380 - d1s = state_funcs[i].get(domain1); 8.381 - d2s = state_funcs[i].get(domain2); 8.382 - if(d1s && !d2s) 8.383 - return -1; 8.384 - if(d2s && !d1s) 8.385 - return 1; 8.386 - } 8.387 - return 0; 8.388 -} 8.389 - 8.390 -/* Prints domain state in abbreviated letter format */ 8.391 -static void print_state(xenstat_domain *domain) 8.392 -{ 8.393 - unsigned int i; 8.394 - for(i = 0; i < NUM_STATES; i++) 8.395 - print("%c", state_funcs[i].get(domain) ? state_funcs[i].ch 8.396 - : '-'); 8.397 -} 8.398 - 8.399 -/* Compares cpu usage of two domains, returning -1,0,1 for <,=,> */ 8.400 -static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2) 8.401 -{ 8.402 - return -compare(xenstat_domain_cpu_ns(domain1), 8.403 - xenstat_domain_cpu_ns(domain2)); 8.404 -} 8.405 - 8.406 -/* Prints domain cpu usage in seconds */ 8.407 -static void print_cpu(xenstat_domain *domain) 8.408 -{ 8.409 - print("%10llu", xenstat_domain_cpu_ns(domain)/1000000000); 8.410 -} 8.411 - 8.412 -/* Computes the CPU percentage used for a specified domain */ 8.413 -static double get_cpu_pct(xenstat_domain *domain) 8.414 -{ 8.415 - xenstat_domain *old_domain; 8.416 - double us_elapsed; 8.417 - 8.418 - /* Can't calculate CPU percentage without a previous sample. */ 8.419 - if(prev_node == NULL) 8.420 - return 0.0; 8.421 - 8.422 - old_domain = xenstat_node_domain(prev_node, xenstat_domain_id(domain)); 8.423 - if(old_domain == NULL) 8.424 - return 0.0; 8.425 - 8.426 - /* Calculate the time elapsed in microseconds */ 8.427 - us_elapsed = ((curtime.tv_sec-oldtime.tv_sec)*1000000.0 8.428 - +(curtime.tv_usec - oldtime.tv_usec)); 8.429 - 8.430 - /* In the following, nanoseconds must be multiplied by 1000.0 to 8.431 - * convert to microseconds, then divided by 100.0 to get a percentage, 8.432 - * resulting in a multiplication by 10.0 */ 8.433 - return ((xenstat_domain_cpu_ns(domain) 8.434 - -xenstat_domain_cpu_ns(old_domain))/10.0)/us_elapsed; 8.435 -} 8.436 - 8.437 -static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2) 8.438 -{ 8.439 - return -compare(get_cpu_pct(domain1), get_cpu_pct(domain2)); 8.440 -} 8.441 - 8.442 -/* Prints cpu percentage statistic */ 8.443 -static void print_cpu_pct(xenstat_domain *domain) 8.444 -{ 8.445 - print("%6.1f", get_cpu_pct(domain)); 8.446 -} 8.447 - 8.448 -/* Compares current memory of two domains, returning -1,0,1 for <,=,> */ 8.449 -static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2) 8.450 -{ 8.451 - return -compare(xenstat_domain_cur_mem(domain1), 8.452 - xenstat_domain_cur_mem(domain2)); 8.453 -} 8.454 - 8.455 -/* Prints current memory statistic */ 8.456 -static void print_mem(xenstat_domain *domain) 8.457 -{ 8.458 - print("%10llu", xenstat_domain_cur_mem(domain)/1024); 8.459 -} 8.460 - 8.461 -/* Prints memory percentage statistic, ratio of current domain memory to total 8.462 - * node memory */ 8.463 -static void print_mem_pct(xenstat_domain *domain) 8.464 -{ 8.465 - print("%6.1f", (double)xenstat_domain_cur_mem(domain) / 8.466 - (double)xenstat_node_tot_mem(cur_node) * 100); 8.467 -} 8.468 - 8.469 -/* Compares maximum memory of two domains, returning -1,0,1 for <,=,> */ 8.470 -static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2) 8.471 -{ 8.472 - return -compare(xenstat_domain_max_mem(domain1), 8.473 - xenstat_domain_max_mem(domain2)); 8.474 -} 8.475 - 8.476 -/* Prints maximum domain memory statistic in KB */ 8.477 -static void print_maxmem(xenstat_domain *domain) 8.478 -{ 8.479 - unsigned long long max_mem = xenstat_domain_max_mem(domain); 8.480 - if(max_mem == ((unsigned long long)-1)) 8.481 - print("%10s", "no limit"); 8.482 - else 8.483 - print("%10llu", max_mem/1024); 8.484 -} 8.485 - 8.486 -/* Prints memory percentage statistic, ratio of current domain memory to total 8.487 - * node memory */ 8.488 -static void print_max_pct(xenstat_domain *domain) 8.489 -{ 8.490 - if (xenstat_domain_max_mem(domain) == (unsigned long long)-1) 8.491 - print("%9s", "n/a"); 8.492 - else 8.493 - print("%9.1f", (double)xenstat_domain_max_mem(domain) / 8.494 - (double)xenstat_node_tot_mem(cur_node) * 100); 8.495 -} 8.496 - 8.497 -/* Compares number of virtual CPUs of two domains, returning -1,0,1 for 8.498 - * <,=,> */ 8.499 -static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2) 8.500 -{ 8.501 - return -compare(xenstat_domain_num_vcpus(domain1), 8.502 - xenstat_domain_num_vcpus(domain2)); 8.503 -} 8.504 - 8.505 -/* Prints number of virtual CPUs statistic */ 8.506 -static void print_vcpus(xenstat_domain *domain) 8.507 -{ 8.508 - print("%5u", xenstat_domain_num_vcpus(domain)); 8.509 -} 8.510 - 8.511 -/* Compares number of virtual networks of two domains, returning -1,0,1 for 8.512 - * <,=,> */ 8.513 -static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2) 8.514 -{ 8.515 - return -compare(xenstat_domain_num_networks(domain1), 8.516 - xenstat_domain_num_networks(domain2)); 8.517 -} 8.518 - 8.519 -/* Prints number of virtual networks statistic */ 8.520 -static void print_nets(xenstat_domain *domain) 8.521 -{ 8.522 - print("%4u", xenstat_domain_num_networks(domain)); 8.523 -} 8.524 - 8.525 -/* Compares number of total network tx bytes of two domains, returning -1,0,1 for 8.526 - * <,=,> */ 8.527 -static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2) 8.528 -{ 8.529 - return -compare(tot_net_bytes(domain1, FALSE), 8.530 - tot_net_bytes(domain2, FALSE)); 8.531 -} 8.532 - 8.533 -/* Prints number of total network tx bytes statistic */ 8.534 -static void print_net_tx(xenstat_domain *domain) 8.535 -{ 8.536 - print("%8llu", tot_net_bytes(domain, FALSE)/1024); 8.537 -} 8.538 - 8.539 -/* Compares number of total network rx bytes of two domains, returning -1,0,1 for 8.540 - * <,=,> */ 8.541 -static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2) 8.542 -{ 8.543 - return -compare(tot_net_bytes(domain1, TRUE), 8.544 - tot_net_bytes(domain2, TRUE)); 8.545 -} 8.546 - 8.547 -/* Prints number of total network rx bytes statistic */ 8.548 -static void print_net_rx(xenstat_domain *domain) 8.549 -{ 8.550 - print("%8llu", tot_net_bytes(domain, TRUE)/1024); 8.551 -} 8.552 - 8.553 -/* Gets number of total network bytes statistic, if rx true, then rx bytes 8.554 - * otherwise tx bytes 8.555 - */ 8.556 -static unsigned long long tot_net_bytes(xenstat_domain *domain, int rx_flag) 8.557 -{ 8.558 - int i = 0; 8.559 - xenstat_network *network; 8.560 - unsigned num_networks = 0; 8.561 - unsigned long long total = 0; 8.562 - 8.563 - /* How many networks? */ 8.564 - num_networks = xenstat_domain_num_networks(domain); 8.565 - 8.566 - /* Dump information for each network */ 8.567 - for (i=0; i < num_networks; i++) { 8.568 - /* Next get the network information */ 8.569 - network = xenstat_domain_network(domain,i); 8.570 - if (rx_flag) 8.571 - total += xenstat_network_rbytes(network); 8.572 - else 8.573 - total += xenstat_network_tbytes(network); 8.574 - } 8.575 - return (total); 8.576 -} 8.577 - 8.578 -/* Compares security id (ssid) of two domains, returning -1,0,1 for <,=,> */ 8.579 -static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2) 8.580 -{ 8.581 - return compare(xenstat_domain_ssid(domain1), 8.582 - xenstat_domain_ssid(domain2)); 8.583 -} 8.584 - 8.585 -/* Prints ssid statistic */ 8.586 -static void print_ssid(xenstat_domain *domain) 8.587 -{ 8.588 - print("%4u", xenstat_domain_ssid(domain)); 8.589 -} 8.590 - 8.591 -/* Section printing functions */ 8.592 -/* Prints three line summary header */ 8.593 -void do_summary(void) 8.594 -{ 8.595 -#define TIME_STR_LEN 9 8.596 - const char *TIME_STR_FORMAT = "%H:%M:%S"; 8.597 - char time_str[TIME_STR_LEN]; 8.598 - unsigned run = 0, block = 0, pause = 0, 8.599 - crash = 0, dying = 0, shutdown = 0; 8.600 - unsigned i, num_domains = 0; 8.601 - unsigned long long used = 0; 8.602 - xenstat_domain *domain; 8.603 - 8.604 - /* Print program name, current time, and number of domains */ 8.605 - strftime(time_str, TIME_STR_LEN, TIME_STR_FORMAT, 8.606 - localtime(&curtime.tv_sec)); 8.607 - num_domains = xenstat_node_num_domains(cur_node); 8.608 - print("vm-top - %s\n", time_str); 8.609 - 8.610 - /* Tabulate what states domains are in for summary */ 8.611 - for (i=0; i < num_domains; i++) { 8.612 - domain = xenstat_node_domain_by_index(cur_node,i); 8.613 - if (xenstat_domain_running(domain)) run++; 8.614 - else if (xenstat_domain_blocked(domain)) block++; 8.615 - else if (xenstat_domain_paused(domain)) pause++; 8.616 - else if (xenstat_domain_shutdown(domain)) shutdown++; 8.617 - else if (xenstat_domain_crashed(domain)) crash++; 8.618 - else if (xenstat_domain_dying(domain)) dying++; 8.619 - } 8.620 - 8.621 - print("%u domains: %u running, %u blocked, %u paused, " 8.622 - "%u crashed, %u dying, %u shutdown \n", 8.623 - num_domains, run, block, pause, crash, dying, shutdown); 8.624 - 8.625 - used = xenstat_node_tot_mem(cur_node)-xenstat_node_free_mem(cur_node); 8.626 - 8.627 - /* Dump node memory and cpu information */ 8.628 - print("Mem: %lluk total, %lluk used, %lluk free " 8.629 - "CPUs: %u @ %lluMHz\n", 8.630 - xenstat_node_tot_mem(cur_node)/1024, used/1024, 8.631 - xenstat_node_free_mem(cur_node)/1024, 8.632 - xenstat_node_num_cpus(cur_node), 8.633 - xenstat_node_cpu_hz(cur_node)/1000000); 8.634 -} 8.635 - 8.636 -/* Display top portion of vm-top */ 8.637 -void do_header(void) 8.638 -{ 8.639 - field_id i; 8.640 - 8.641 - /* Turn on REVERSE highlight attribute for headings */ 8.642 - attron(A_REVERSE); 8.643 - for(i = 0; i < NUM_FIELDS; i++) { 8.644 - if(i != 0) 8.645 - print(" "); 8.646 - /* The BOLD attribute is turned on for the sort column */ 8.647 - if(i == sort_field) 8.648 - attron(A_BOLD); 8.649 - print("%*s", fields[i].default_width, fields[i].header); 8.650 - if(i == sort_field) 8.651 - attroff(A_BOLD); 8.652 - } 8.653 - attroff(A_REVERSE); 8.654 - print("\n"); 8.655 -} 8.656 - 8.657 -/* Displays bottom portion of vm-top, interactive options 8.658 - * N toggles network information display, V toggles CPU information 8.659 - * display, S toggles sort order of information (ascending/descending), 8.660 - * R toggles whether header is repeated for each domain 8.661 - */ 8.662 -void do_bottom_line(void) 8.663 -{ 8.664 - move(lines()-1, 2); 8.665 - 8.666 - if (prompt != NULL) { 8.667 - printw("%s: %s", prompt, prompt_val); 8.668 - } else { 8.669 - addch(A_REVERSE | 'D'); addstr("elay "); 8.670 - 8.671 - /* network */ 8.672 - addch(A_REVERSE | 'N'); 8.673 - attr_addstr(show_networks ? COLOR_PAIR(1) : 0, "etworks"); 8.674 - addstr(" "); 8.675 - 8.676 - /* vcpus */ 8.677 - addch(A_REVERSE | 'V'); 8.678 - attr_addstr(show_vcpus ? COLOR_PAIR(1) : 0, "CPUs"); 8.679 - addstr(" "); 8.680 - 8.681 - /* repeat */ 8.682 - addch(A_REVERSE | 'R'); 8.683 - attr_addstr(repeat_header ? COLOR_PAIR(1) : 0, "epeat header"); 8.684 - addstr(" "); 8.685 - 8.686 - /* sort order */ 8.687 - addch(A_REVERSE | 'S'); addstr("ort order "); 8.688 - 8.689 - addch(A_REVERSE | 'Q'); addstr("uit "); 8.690 - } 8.691 -} 8.692 - 8.693 -/* Prints Domain information */ 8.694 -void do_domain(xenstat_domain *domain) 8.695 -{ 8.696 - unsigned int i; 8.697 - for(i = 0; i < NUM_FIELDS; i++) { 8.698 - if(i != 0) 8.699 - print(" "); 8.700 - if(i == sort_field) 8.701 - attron(A_BOLD); 8.702 - fields[i].print(domain); 8.703 - if(i == sort_field) 8.704 - attroff(A_BOLD); 8.705 - } 8.706 - print("\n"); 8.707 -} 8.708 - 8.709 -/* Output all vcpu information */ 8.710 -void do_vcpu(xenstat_domain *domain) 8.711 -{ 8.712 - int i = 0; 8.713 - unsigned num_vcpus = 0; 8.714 - xenstat_vcpu *vcpu; 8.715 - 8.716 - print("VCPUs(sec): "); 8.717 - 8.718 - num_vcpus = xenstat_domain_num_vcpus(domain); 8.719 - 8.720 - /* for all vcpus dump out values */ 8.721 - for (i=0; i< num_vcpus; i++) { 8.722 - vcpu = xenstat_domain_vcpu(domain,i); 8.723 - 8.724 - if (i != 0 && (i%5)==0) 8.725 - print("\n "); 8.726 - print(" %2u: %10llus", i, xenstat_vcpu_ns(vcpu)/1000000000); 8.727 - } 8.728 - print("\n"); 8.729 -} 8.730 - 8.731 -/* Output all network information */ 8.732 -void do_network(xenstat_domain *domain) 8.733 -{ 8.734 - int i = 0; 8.735 - xenstat_network *network; 8.736 - unsigned num_networks = 0; 8.737 - 8.738 - /* How many networks? */ 8.739 - num_networks = xenstat_domain_num_networks(domain); 8.740 - 8.741 - /* Dump information for each network */ 8.742 - for (i=0; i < num_networks; i++) { 8.743 - /* Next get the network information */ 8.744 - network = xenstat_domain_network(domain,i); 8.745 - 8.746 - print("Net%d RX: %8llubytes %8llupkts %8lluerr %8lludrop ", 8.747 - i, 8.748 - xenstat_network_rbytes(network), 8.749 - xenstat_network_rpackets(network), 8.750 - xenstat_network_rerrs(network), 8.751 - xenstat_network_rdrop(network)); 8.752 - 8.753 - print("TX: %8llubytes %8llupkts %8lluerr %8lludrop\n", 8.754 - xenstat_network_tbytes(network), 8.755 - xenstat_network_tpackets(network), 8.756 - xenstat_network_terrs(network), 8.757 - xenstat_network_tdrop(network)); 8.758 - } 8.759 -} 8.760 - 8.761 -static void top(void) 8.762 -{ 8.763 - xenstat_domain **domains; 8.764 - unsigned int i, num_domains = 0; 8.765 - 8.766 - /* Now get the node information */ 8.767 - if (prev_node != NULL) 8.768 - xenstat_free_node(prev_node); 8.769 - prev_node = cur_node; 8.770 - cur_node = xenstat_get_node(xhandle, XENSTAT_ALL); 8.771 - if (cur_node == NULL) 8.772 - fail("Failed to retrieve statistics from libxenstat\n"); 8.773 - 8.774 - /* dump summary top information */ 8.775 - do_summary(); 8.776 - 8.777 - /* Count the number of domains for which to report data */ 8.778 - num_domains = xenstat_node_num_domains(cur_node); 8.779 - 8.780 - domains = malloc(num_domains*sizeof(xenstat_domain *)); 8.781 - if(domains == NULL) 8.782 - fail("Failed to allocate memory\n"); 8.783 - 8.784 - for (i=0; i < num_domains; i++) 8.785 - domains[i] = xenstat_node_domain_by_index(cur_node, i); 8.786 - 8.787 - /* Sort */ 8.788 - qsort(domains, num_domains, sizeof(xenstat_domain *), 8.789 - (int(*)(const void *, const void *))compare_domains); 8.790 - 8.791 - if(first_domain_index >= num_domains) 8.792 - first_domain_index = num_domains-1; 8.793 - 8.794 - for (i = first_domain_index; i < num_domains; i++) { 8.795 - if(current_row() == lines()-1) 8.796 - break; 8.797 - if (i == first_domain_index || repeat_header) 8.798 - do_header(); 8.799 - do_domain(domains[i]); 8.800 - if (show_vcpus) 8.801 - do_vcpu(domains[i]); 8.802 - if (show_networks) 8.803 - do_network(domains[i]); 8.804 - } 8.805 - 8.806 - do_bottom_line(); 8.807 -} 8.808 - 8.809 -int main(int argc, char **argv) 8.810 -{ 8.811 - int opt, optind = 0; 8.812 - int ch = ERR; 8.813 - 8.814 - struct option lopts[] = { 8.815 - { "help", no_argument, NULL, 'h' }, 8.816 - { "version", no_argument, NULL, 'V' }, 8.817 - { "networks", no_argument, NULL, 'n' }, 8.818 - { "repeat-header", no_argument, NULL, 'r' }, 8.819 - { "vcpus", no_argument, NULL, 'v' }, 8.820 - { "delay", required_argument, NULL, 'd' }, 8.821 - { 0, 0, 0, 0 }, 8.822 - }; 8.823 - const char *sopts = "hVbnvd:"; 8.824 - 8.825 - if (atexit(cleanup) != 0) 8.826 - fail("Failed to install cleanup handler.\n"); 8.827 - 8.828 - while ((opt = getopt_long(argc, argv, sopts, lopts, &optind)) != -1) { 8.829 - switch (opt) { 8.830 - case 'h': 8.831 - case '?': 8.832 - default: 8.833 - usage(argv[0]); 8.834 - exit(0); 8.835 - case 'V': 8.836 - version(); 8.837 - exit(0); 8.838 - case 'n': 8.839 - show_networks = 1; 8.840 - break; 8.841 - case 'r': 8.842 - repeat_header = 1; 8.843 - break; 8.844 - case 'v': 8.845 - show_vcpus = 1; 8.846 - break; 8.847 - case 'd': 8.848 - delay = atoi(optarg); 8.849 - break; 8.850 - } 8.851 - } 8.852 - 8.853 - /* Get xenstat handle */ 8.854 - xhandle = xenstat_init(); 8.855 - if (xhandle == NULL) 8.856 - fail("Failed to initialize xenstat library\n"); 8.857 - 8.858 - /* Begin curses stuff */ 8.859 - initscr(); 8.860 - start_color(); 8.861 - cbreak(); 8.862 - noecho(); 8.863 - nonl(); 8.864 - keypad(stdscr, TRUE); 8.865 - halfdelay(5); 8.866 - use_default_colors(); 8.867 - init_pair(1, -1, COLOR_YELLOW); 8.868 - 8.869 - do { 8.870 - gettimeofday(&curtime, NULL); 8.871 - if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) { 8.872 - clear(); 8.873 - top(); 8.874 - oldtime = curtime; 8.875 - refresh(); 8.876 - } 8.877 - ch = getch(); 8.878 - } while (handle_key(ch)); 8.879 - 8.880 - /* Cleanup occurs in cleanup(), so no work to do here. */ 8.881 - 8.882 - return 0; 8.883 -}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/tools/xenstat/xentop/Makefile Wed Aug 17 16:50:33 2005 +0000 9.3 @@ -0,0 +1,43 @@ 9.4 +# Copyright (C) International Business Machines Corp., 2005 9.5 +# Author: Josh Triplett <josht@us.ibm.com> 9.6 +# 9.7 +# This program is free software; you can redistribute it and/or modify 9.8 +# it under the terms of the GNU General Public License as published by 9.9 +# the Free Software Foundation; under version 2 of the License. 9.10 +# 9.11 +# This program is distributed in the hope that it will be useful, 9.12 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 9.13 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9.14 +# GNU General Public License for more details. 9.15 + 9.16 +XEN_ROOT=../../.. 9.17 +include $(XEN_ROOT)/tools/Rules.mk 9.18 + 9.19 +ifneq ($(XENSTAT_XENTOP),y) 9.20 +all install xentop: 9.21 +else 9.22 + 9.23 +INSTALL = install 9.24 +INSTALL_PROG = $(INSTALL) -m0755 -D 9.25 +INSTALL_DATA = $(INSTALL) -m0644 -D 9.26 + 9.27 +prefix=/usr 9.28 +mandir=$(prefix)/share/man 9.29 +man1dir=$(mandir)/man1 9.30 +sbindir=$(prefix)/sbin 9.31 + 9.32 +CFLAGS += -DGCC_PRINTF -Wall -Werror -I$(XEN_LIBXENSTAT) 9.33 +LDFLAGS += -L$(XEN_LIBXENSTAT) -lxenstat -lcurses 9.34 + 9.35 +all: xentop 9.36 + 9.37 +xentop: xentop.o 9.38 + 9.39 +install: xentop xentop.1 9.40 + $(INSTALL_PROG) xentop $(DESTDIR)$(sbindir)/xentop 9.41 + $(INSTALL_DATA) xentop.1 $(DESTDIR)$(man1dir)/xentop.1 9.42 + 9.43 +endif 9.44 + 9.45 +clean: 9.46 + rm -f xentop xentop.o
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/tools/xenstat/xentop/TODO Wed Aug 17 16:50:33 2005 +0000 10.3 @@ -0,0 +1,34 @@ 10.4 +Display error messages on the help line after bad input at a prompt. 10.5 +Fractional delay times 10.6 +Use prompting to search for domains 10.7 +Better line editing? 10.8 + 10.9 +* Make CPU in % more accurate 10.10 +* Domain total network TX % and RX % 10.11 + 10.12 +Like Top, f feature, field select of domain columns, toggle the display of 10.13 +field by typing the letter associated with field, if displayed it shows in 10.14 +bold and the letter is Capitalized along with a leading asterisk for the 10.15 +field, if not selected for display letter is lowercase, no leading asterisk 10.16 +and field is not bolded. 10.17 + 10.18 +Like Top, ordering of domain columns, o feature Capital letter shifts left, 10.19 +lowercase letter shifts right? 10.20 + 10.21 +Color 10.22 +Full management: pause, destroy, create domains 10.23 + 10.24 +Add support for Virtual Block Devices (vbd) 10.25 + 10.26 +To think about: 10.27 +Support for one than one node display (distributed monitoring 10.28 +from any node of all other nodes in a cluster) 10.29 +Bottom line option (Switch node, Search node [tab completion?]) 10.30 + 10.31 +Capture/Logging of resource information generated during a time interval. 10.32 +-b batch mode dump snapshots to standard output (used with -n) 10.33 +-n number of iterations to dump to standard output (unlimited if not specified) 10.34 +-d monitor DomIDs as -dD1,-dD2 or -dD1,D2... 10.35 + Monitor only domains with specified domain IDs 10.36 +-m monitor nodeIDs as -mN1,-mN2 or -mN1,N2... 10.37 + Monitor only domains with specified node IDs
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/tools/xenstat/xentop/xentop.1 Wed Aug 17 16:50:33 2005 +0000 11.3 @@ -0,0 +1,88 @@ 11.4 +.\" Copyright (C) International Business Machines Corp., 2005 11.5 +.\" Author: Josh Triplett <josht@us.ibm.com> 11.6 +.\" 11.7 +.\" This program is free software; you can redistribute it and/or modify 11.8 +.\" it under the terms of the GNU General Public License as published by 11.9 +.\" the Free Software Foundation; under version 2 of the License. 11.10 +.\" 11.11 +.\" This program is distributed in the hope that it will be useful, 11.12 +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of 11.13 +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11.14 +.\" GNU General Public License for more details. 11.15 +.\" 11.16 +.\" You should have received a copy of the GNU General Public License 11.17 +.\" along with this program; if not, write to the Free Software 11.18 +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 11.19 +.TH xentop 1 "August 2005" 11.20 +.SH NAME 11.21 +\fBxentop\fR \- displays real-time information about a Xen system and domains 11.22 + 11.23 +.SH SYNOPSIS 11.24 +.B xentop 11.25 +[\fB\-h\fR] 11.26 +[\fB\-V\fR] 11.27 +[\fB\-d\fRSECONDS] 11.28 +[\fB\-n\fR] 11.29 +[\fB\-r\fR] 11.30 +[\fB\-v\fR] 11.31 + 11.32 +.SH DESCRIPTION 11.33 +\fBxentop\fR displays information about the Xen system and domains, in a 11.34 +continually-updating manner. Command-line options and interactive commands 11.35 +can change the detail and format of the information displayed by \fBxentop\fR. 11.36 + 11.37 +.SH OPTIONS 11.38 +.TP 11.39 +\fB\-h\fR, \fB\-\-help\fR 11.40 +display help and exit 11.41 +.TP 11.42 +\fB\-V\fR, \fB\-\-version\fR 11.43 +output version information and exit 11.44 +.TP 11.45 +\fB\-d\fR, \fB\-\-delay\fR=\fISECONDS\fR 11.46 +seconds between updates (default 1) 11.47 +.TP 11.48 +\fB\-n\fR, \fB\-\-networks\fR 11.49 +output network information 11.50 +.TP 11.51 +\fB\-r\fR, \fB\-\-repeat\-header\fR 11.52 +repeat table header before each domain 11.53 +.TP 11.54 +\fB\-v\fR, \fB\-\-vcpus\fR 11.55 +output VCPU data 11.56 + 11.57 +.SH "INTERACTIVE COMMANDS" 11.58 +All interactive commands are case-insensitive. 11.59 +.TP 11.60 +.B D 11.61 +set delay between updates 11.62 +.TP 11.63 +.B N 11.64 +toggle display of network information 11.65 +.TP 11.66 +.B Q, Esc 11.67 +quit 11.68 +.TP 11.69 +.B R 11.70 +toggle table header before each domain 11.71 +.TP 11.72 +.B S 11.73 +cycle sort order 11.74 +.TP 11.75 +.B V 11.76 +toggle display of VCPU information 11.77 +.TP 11.78 +.B Arrows 11.79 +scroll domain display 11.80 + 11.81 +.SH AUTHORS 11.82 +Written by Judy Fischbach, David Hendricks, and Josh Triplett 11.83 + 11.84 +.SH "REPORTING BUGS" 11.85 +Report bugs to <dsteklof@us.ibm.com>. 11.86 + 11.87 +.SH COPYRIGHT 11.88 +Copyright \(co 2005 International Business Machines Corp 11.89 +.br 11.90 +This is free software; see the source for copying conditions. There is NO 11.91 +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/tools/xenstat/xentop/xentop.c Wed Aug 17 16:50:33 2005 +0000 12.3 @@ -0,0 +1,876 @@ 12.4 +/* 12.5 + * Copyright (C) International Business Machines Corp., 2005 12.6 + * Author(s): Judy Fischbach <jfisch@us.ibm.com> 12.7 + * David Hendricks <dhendrix@us.ibm.com> 12.8 + * Josh Triplett <josht@us.ibm.com> 12.9 + * based on code from Anthony Liguori <aliguori@us.ibm.com> 12.10 + * 12.11 + * This program is free software; you can redistribute it and/or modify 12.12 + * it under the terms of the GNU General Public License as published by 12.13 + * the Free Software Foundation; under version 2 of the License. 12.14 + * 12.15 + * This program is distributed in the hope that it will be useful, 12.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12.18 + * GNU General Public License for more details. 12.19 + * 12.20 + * You should have received a copy of the GNU General Public License 12.21 + * along with this program; if not, write to the Free Software 12.22 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 12.23 + */ 12.24 +#include <curses.h> 12.25 +#include <ctype.h> 12.26 +#include <errno.h> 12.27 +#include <stdio.h> 12.28 +#include <stdlib.h> 12.29 +#include <string.h> 12.30 +#include <sys/time.h> 12.31 +#include <time.h> 12.32 +#include <unistd.h> 12.33 + 12.34 +#include <xenstat.h> 12.35 + 12.36 +#define XENTOP_VERSION "1.0" 12.37 + 12.38 +#define XENTOP_DISCLAIMER \ 12.39 +"Copyright (C) 2005 International Business Machines Corp\n"\ 12.40 +"This is free software; see the source for copying conditions.There is NO\n"\ 12.41 +"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" 12.42 +#define XENTOP_BUGSTO "Report bugs to <dsteklof@us.ibm.com>.\n" 12.43 + 12.44 +#define _GNU_SOURCE 12.45 +#include <getopt.h> 12.46 + 12.47 +#if !defined(__GNUC__) && !defined(__GNUG__) 12.48 +#define __attribute__(arg) /* empty */ 12.49 +#endif 12.50 + 12.51 +#define KEY_ESCAPE '\x1B' 12.52 + 12.53 +/* 12.54 + * Function prototypes 12.55 + */ 12.56 +/* Utility functions */ 12.57 +static void usage(const char *); 12.58 +static void version(void); 12.59 +static void cleanup(void); 12.60 +static void fail(const char *); 12.61 +static int current_row(void); 12.62 +static int lines(void); 12.63 +static void print(const char *, ...) __attribute__((format(printf,1,2))); 12.64 +static void attr_addstr(int attr, const char *str); 12.65 +static void set_delay(char *value); 12.66 +static void set_prompt(char *new_prompt, void (*func)(char *)); 12.67 +static int handle_key(int); 12.68 +static int compare(unsigned long long, unsigned long long); 12.69 +static int compare_domains(xenstat_domain **, xenstat_domain **); 12.70 +static unsigned long long tot_net_bytes( xenstat_domain *, int); 12.71 + 12.72 +/* Field functions */ 12.73 +static int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2); 12.74 +static void print_domid(xenstat_domain *domain); 12.75 +static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2); 12.76 +static void print_state(xenstat_domain *domain); 12.77 +static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2); 12.78 +static void print_cpu(xenstat_domain *domain); 12.79 +static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2); 12.80 +static void print_cpu_pct(xenstat_domain *domain); 12.81 +static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2); 12.82 +static void print_mem(xenstat_domain *domain); 12.83 +static void print_mem_pct(xenstat_domain *domain); 12.84 +static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2); 12.85 +static void print_maxmem(xenstat_domain *domain); 12.86 +static void print_max_pct(xenstat_domain *domain); 12.87 +static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2); 12.88 +static void print_vcpus(xenstat_domain *domain); 12.89 +static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2); 12.90 +static void print_nets(xenstat_domain *domain); 12.91 +static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2); 12.92 +static void print_net_tx(xenstat_domain *domain); 12.93 +static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2); 12.94 +static void print_net_rx(xenstat_domain *domain); 12.95 +static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2); 12.96 +static void print_ssid(xenstat_domain *domain); 12.97 + 12.98 +/* Section printing functions */ 12.99 +static void do_summary(void); 12.100 +static void do_header(void); 12.101 +static void do_bottom_line(void); 12.102 +static void do_domain(xenstat_domain *); 12.103 +static void do_vcpu(xenstat_domain *); 12.104 +static void do_network(xenstat_domain *); 12.105 +static void top(void); 12.106 + 12.107 +/* Field types */ 12.108 +typedef enum field_id { 12.109 + FIELD_DOMID, 12.110 + FIELD_STATE, 12.111 + FIELD_CPU, 12.112 + FIELD_CPU_PCT, 12.113 + FIELD_MEM, 12.114 + FIELD_MEM_PCT, 12.115 + FIELD_MAXMEM, 12.116 + FIELD_MAX_PCT, 12.117 + FIELD_VCPUS, 12.118 + FIELD_NETS, 12.119 + FIELD_NET_TX, 12.120 + FIELD_NET_RX, 12.121 + FIELD_SSID 12.122 +} field_id; 12.123 + 12.124 +typedef struct field { 12.125 + field_id num; 12.126 + const char *header; 12.127 + unsigned int default_width; 12.128 + int (*compare)(xenstat_domain *domain1, xenstat_domain *domain2); 12.129 + void (*print)(xenstat_domain *domain); 12.130 +} field; 12.131 + 12.132 +field fields[] = { 12.133 + { FIELD_DOMID, "DOMID", 5, compare_domid, print_domid }, 12.134 + { FIELD_STATE, "STATE", 6, compare_state, print_state }, 12.135 + { FIELD_CPU, "CPU(sec)", 10, compare_cpu, print_cpu }, 12.136 + { FIELD_CPU_PCT, "CPU(%)", 6, compare_cpu_pct, print_cpu_pct }, 12.137 + { FIELD_MEM, "MEM(k)", 10, compare_mem, print_mem }, 12.138 + { FIELD_MEM_PCT, "MEM(%)", 6, compare_mem, print_mem_pct }, 12.139 + { FIELD_MAXMEM, "MAXMEM(k)", 10, compare_maxmem, print_maxmem }, 12.140 + { FIELD_MAX_PCT, "MAXMEM(%)", 9, compare_maxmem, print_max_pct }, 12.141 + { FIELD_VCPUS, "VCPUS", 5, compare_vcpus, print_vcpus }, 12.142 + { FIELD_NETS, "NETS", 4, compare_nets, print_nets }, 12.143 + { FIELD_NET_TX, "NETTX(k)", 8, compare_net_tx, print_net_tx }, 12.144 + { FIELD_NET_RX, "NETRX(k)", 8, compare_net_rx, print_net_rx }, 12.145 + { FIELD_SSID, "SSID", 4, compare_ssid, print_ssid } 12.146 +}; 12.147 + 12.148 +const unsigned int NUM_FIELDS = sizeof(fields)/sizeof(field); 12.149 + 12.150 +/* Globals */ 12.151 +struct timeval curtime, oldtime; 12.152 +xenstat_handle *xhandle = NULL; 12.153 +xenstat_node *prev_node = NULL; 12.154 +xenstat_node *cur_node = NULL; 12.155 +field_id sort_field = FIELD_DOMID; 12.156 +unsigned int first_domain_index = 0; 12.157 +unsigned int delay = 1; 12.158 +int show_vcpus = 0; 12.159 +int show_networks = 0; 12.160 +int repeat_header = 0; 12.161 +#define PROMPT_VAL_LEN 80 12.162 +char *prompt = NULL; 12.163 +char prompt_val[PROMPT_VAL_LEN]; 12.164 +int prompt_val_len = 0; 12.165 +void (*prompt_complete_func)(char *); 12.166 + 12.167 +/* 12.168 + * Function definitions 12.169 + */ 12.170 + 12.171 +/* Utility functions */ 12.172 + 12.173 +/* Print usage message, using given program name */ 12.174 +static void usage(const char *program) 12.175 +{ 12.176 + printf("Usage: %s [OPTION]\n" 12.177 + "Displays ongoing information about xen vm resources \n\n" 12.178 + "-h, --help display this help and exit\n" 12.179 + "-V, --version output version information and exit\n" 12.180 + "-d, --delay=SECONDS seconds between updates (default 1)\n" 12.181 + "-n, --networks output vif network data\n" 12.182 + "-r, --repeat-header repeat table header before each domain\n" 12.183 + "-v, --vcpus output vcpu data\n" 12.184 + "\n" XENTOP_BUGSTO, 12.185 + program); 12.186 + return; 12.187 +} 12.188 + 12.189 +/* Print program version information */ 12.190 +static void version(void) 12.191 +{ 12.192 + printf("xentop " XENTOP_VERSION "\n" 12.193 + "Written by Judy Fischbach, David Hendricks, Josh Triplett\n" 12.194 + "\n" XENTOP_DISCLAIMER); 12.195 +} 12.196 + 12.197 +/* Clean up any open resources */ 12.198 +static void cleanup(void) 12.199 +{ 12.200 + if(!isendwin()) 12.201 + endwin(); 12.202 + if(prev_node != NULL) 12.203 + xenstat_free_node(prev_node); 12.204 + if(cur_node != NULL) 12.205 + xenstat_free_node(cur_node); 12.206 + if(xhandle != NULL) 12.207 + xenstat_uninit(xhandle); 12.208 +} 12.209 + 12.210 +/* Display the given message and gracefully exit */ 12.211 +static void fail(const char *str) 12.212 +{ 12.213 + if(!isendwin()) 12.214 + endwin(); 12.215 + fprintf(stderr, str); 12.216 + exit(1); 12.217 +} 12.218 + 12.219 +/* Return the row containing the cursor. */ 12.220 +static int current_row(void) 12.221 +{ 12.222 + int y, x; 12.223 + getyx(stdscr, y, x); 12.224 + return y; 12.225 +} 12.226 + 12.227 +/* Return the number of lines on the screen. */ 12.228 +static int lines(void) 12.229 +{ 12.230 + int y, x; 12.231 + getmaxyx(stdscr, y, x); 12.232 + return y; 12.233 +} 12.234 + 12.235 +/* printf-style print function which calls printw, but only if the cursor is 12.236 + * not on the last line. */ 12.237 +static void print(const char *fmt, ...) 12.238 +{ 12.239 + va_list args; 12.240 + 12.241 + if(current_row() < lines()-1) { 12.242 + va_start(args, fmt); 12.243 + vw_printw(stdscr, fmt, args); 12.244 + va_end(args); 12.245 + } 12.246 +} 12.247 + 12.248 +/* Print a string with the given attributes set. */ 12.249 +static void attr_addstr(int attr, const char *str) 12.250 +{ 12.251 + attron(attr); 12.252 + addstr(str); 12.253 + attroff(attr); 12.254 +} 12.255 + 12.256 +/* Handle setting the delay from the user-supplied value in prompt_val */ 12.257 +static void set_delay(char *value) 12.258 +{ 12.259 + int new_delay; 12.260 + new_delay = atoi(prompt_val); 12.261 + if(new_delay > 0) 12.262 + delay = new_delay; 12.263 +} 12.264 + 12.265 +/* Enable prompting mode with the given prompt string; call the given function 12.266 + * when a value is available. */ 12.267 +static void set_prompt(char *new_prompt, void (*func)(char *)) 12.268 +{ 12.269 + prompt = new_prompt; 12.270 + prompt_val[0] = '\0'; 12.271 + prompt_val_len = 0; 12.272 + prompt_complete_func = func; 12.273 +} 12.274 + 12.275 +/* Handle user input, return 0 if the program should quit, or 1 if not */ 12.276 +static int handle_key(int ch) 12.277 +{ 12.278 + if(prompt == NULL) { 12.279 + /* Not prompting for input; handle interactive commands */ 12.280 + switch(ch) { 12.281 + case 'n': case 'N': 12.282 + show_networks ^= 1; 12.283 + break; 12.284 + case 'r': case 'R': 12.285 + repeat_header ^= 1; 12.286 + break; 12.287 + case 's': case 'S': 12.288 + sort_field = (sort_field + 1) % NUM_FIELDS; 12.289 + break; 12.290 + case 'v': case 'V': 12.291 + show_vcpus ^= 1; 12.292 + break; 12.293 + case KEY_DOWN: 12.294 + first_domain_index++; 12.295 + break; 12.296 + case KEY_UP: 12.297 + if(first_domain_index > 0) 12.298 + first_domain_index--; 12.299 + break; 12.300 + case 'd': case 'D': 12.301 + set_prompt("Delay(sec)", set_delay); 12.302 + break; 12.303 + case 'q': case 'Q': case KEY_ESCAPE: 12.304 + return 0; 12.305 + } 12.306 + } else { 12.307 + /* Prompting for input; handle line editing */ 12.308 + switch(ch) { 12.309 + case '\r': 12.310 + prompt_complete_func(prompt_val); 12.311 + set_prompt(NULL, NULL); 12.312 + break; 12.313 + case KEY_ESCAPE: 12.314 + set_prompt(NULL, NULL); 12.315 + break; 12.316 + case KEY_BACKSPACE: 12.317 + if(prompt_val_len > 0) 12.318 + prompt_val[--prompt_val_len] = '\0'; 12.319 + default: 12.320 + if((prompt_val_len+1) < PROMPT_VAL_LEN 12.321 + && isprint(ch)) { 12.322 + prompt_val[prompt_val_len++] = (char)ch; 12.323 + prompt_val[prompt_val_len] = '\0'; 12.324 + } 12.325 + } 12.326 + } 12.327 + 12.328 + return 1; 12.329 +} 12.330 + 12.331 +/* Compares two integers, returning -1,0,1 for <,=,> */ 12.332 +static int compare(unsigned long long i1, unsigned long long i2) 12.333 +{ 12.334 + if(i1 < i2) 12.335 + return -1; 12.336 + if(i1 > i2) 12.337 + return 1; 12.338 + return 0; 12.339 +} 12.340 + 12.341 +/* Comparison function for use with qsort. Compares two domains using the 12.342 + * current sort field. */ 12.343 +static int compare_domains(xenstat_domain **domain1, xenstat_domain **domain2) 12.344 +{ 12.345 + return fields[sort_field].compare(*domain1, *domain2); 12.346 +} 12.347 + 12.348 +/* Field functions */ 12.349 + 12.350 +/* Compares domain ids of two domains, returning -1,0,1 for <,=,> */ 12.351 +int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2) 12.352 +{ 12.353 + return compare(xenstat_domain_id(domain1), xenstat_domain_id(domain2)); 12.354 +} 12.355 + 12.356 +/* Prints domain identification number */ 12.357 +void print_domid(xenstat_domain *domain) 12.358 +{ 12.359 + print("%5u", xenstat_domain_id(domain)); 12.360 +} 12.361 + 12.362 +struct { 12.363 + unsigned int (*get)(xenstat_domain *); 12.364 + char ch; 12.365 +} state_funcs[] = { 12.366 + { xenstat_domain_dying, 'd' }, 12.367 + { xenstat_domain_shutdown, 's' }, 12.368 + { xenstat_domain_blocked, 'b' }, 12.369 + { xenstat_domain_crashed, 'c' }, 12.370 + { xenstat_domain_paused, 'p' }, 12.371 + { xenstat_domain_running, 'r' } 12.372 +}; 12.373 +const unsigned int NUM_STATES = sizeof(state_funcs)/sizeof(*state_funcs); 12.374 + 12.375 +/* Compare states of two domains, returning -1,0,1 for <,=,> */ 12.376 +static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2) 12.377 +{ 12.378 + unsigned int i, d1s, d2s; 12.379 + for(i = 0; i < NUM_STATES; i++) { 12.380 + d1s = state_funcs[i].get(domain1); 12.381 + d2s = state_funcs[i].get(domain2); 12.382 + if(d1s && !d2s) 12.383 + return -1; 12.384 + if(d2s && !d1s) 12.385 + return 1; 12.386 + } 12.387 + return 0; 12.388 +} 12.389 + 12.390 +/* Prints domain state in abbreviated letter format */ 12.391 +static void print_state(xenstat_domain *domain) 12.392 +{ 12.393 + unsigned int i; 12.394 + for(i = 0; i < NUM_STATES; i++) 12.395 + print("%c", state_funcs[i].get(domain) ? state_funcs[i].ch 12.396 + : '-'); 12.397 +} 12.398 + 12.399 +/* Compares cpu usage of two domains, returning -1,0,1 for <,=,> */ 12.400 +static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2) 12.401 +{ 12.402 + return -compare(xenstat_domain_cpu_ns(domain1), 12.403 + xenstat_domain_cpu_ns(domain2)); 12.404 +} 12.405 + 12.406 +/* Prints domain cpu usage in seconds */ 12.407 +static void print_cpu(xenstat_domain *domain) 12.408 +{ 12.409 + print("%10llu", xenstat_domain_cpu_ns(domain)/1000000000); 12.410 +} 12.411 + 12.412 +/* Computes the CPU percentage used for a specified domain */ 12.413 +static double get_cpu_pct(xenstat_domain *domain) 12.414 +{ 12.415 + xenstat_domain *old_domain; 12.416 + double us_elapsed; 12.417 + 12.418 + /* Can't calculate CPU percentage without a previous sample. */ 12.419 + if(prev_node == NULL) 12.420 + return 0.0; 12.421 + 12.422 + old_domain = xenstat_node_domain(prev_node, xenstat_domain_id(domain)); 12.423 + if(old_domain == NULL) 12.424 + return 0.0; 12.425 + 12.426 + /* Calculate the time elapsed in microseconds */ 12.427 + us_elapsed = ((curtime.tv_sec-oldtime.tv_sec)*1000000.0 12.428 + +(curtime.tv_usec - oldtime.tv_usec)); 12.429 + 12.430 + /* In the following, nanoseconds must be multiplied by 1000.0 to 12.431 + * convert to microseconds, then divided by 100.0 to get a percentage, 12.432 + * resulting in a multiplication by 10.0 */ 12.433 + return ((xenstat_domain_cpu_ns(domain) 12.434 + -xenstat_domain_cpu_ns(old_domain))/10.0)/us_elapsed; 12.435 +} 12.436 + 12.437 +static int compare_cpu_pct(xenstat_domain *domain1, xenstat_domain *domain2) 12.438 +{ 12.439 + return -compare(get_cpu_pct(domain1), get_cpu_pct(domain2)); 12.440 +} 12.441 + 12.442 +/* Prints cpu percentage statistic */ 12.443 +static void print_cpu_pct(xenstat_domain *domain) 12.444 +{ 12.445 + print("%6.1f", get_cpu_pct(domain)); 12.446 +} 12.447 + 12.448 +/* Compares current memory of two domains, returning -1,0,1 for <,=,> */ 12.449 +static int compare_mem(xenstat_domain *domain1, xenstat_domain *domain2) 12.450 +{ 12.451 + return -compare(xenstat_domain_cur_mem(domain1), 12.452 + xenstat_domain_cur_mem(domain2)); 12.453 +} 12.454 + 12.455 +/* Prints current memory statistic */ 12.456 +static void print_mem(xenstat_domain *domain) 12.457 +{ 12.458 + print("%10llu", xenstat_domain_cur_mem(domain)/1024); 12.459 +} 12.460 + 12.461 +/* Prints memory percentage statistic, ratio of current domain memory to total 12.462 + * node memory */ 12.463 +static void print_mem_pct(xenstat_domain *domain) 12.464 +{ 12.465 + print("%6.1f", (double)xenstat_domain_cur_mem(domain) / 12.466 + (double)xenstat_node_tot_mem(cur_node) * 100); 12.467 +} 12.468 + 12.469 +/* Compares maximum memory of two domains, returning -1,0,1 for <,=,> */ 12.470 +static int compare_maxmem(xenstat_domain *domain1, xenstat_domain *domain2) 12.471 +{ 12.472 + return -compare(xenstat_domain_max_mem(domain1), 12.473 + xenstat_domain_max_mem(domain2)); 12.474 +} 12.475 + 12.476 +/* Prints maximum domain memory statistic in KB */ 12.477 +static void print_maxmem(xenstat_domain *domain) 12.478 +{ 12.479 + unsigned long long max_mem = xenstat_domain_max_mem(domain); 12.480 + if(max_mem == ((unsigned long long)-1)) 12.481 + print("%10s", "no limit"); 12.482 + else 12.483 + print("%10llu", max_mem/1024); 12.484 +} 12.485 + 12.486 +/* Prints memory percentage statistic, ratio of current domain memory to total 12.487 + * node memory */ 12.488 +static void print_max_pct(xenstat_domain *domain) 12.489 +{ 12.490 + if (xenstat_domain_max_mem(domain) == (unsigned long long)-1) 12.491 + print("%9s", "n/a"); 12.492 + else 12.493 + print("%9.1f", (double)xenstat_domain_max_mem(domain) / 12.494 + (double)xenstat_node_tot_mem(cur_node) * 100); 12.495 +} 12.496 + 12.497 +/* Compares number of virtual CPUs of two domains, returning -1,0,1 for 12.498 + * <,=,> */ 12.499 +static int compare_vcpus(xenstat_domain *domain1, xenstat_domain *domain2) 12.500 +{ 12.501 + return -compare(xenstat_domain_num_vcpus(domain1), 12.502 + xenstat_domain_num_vcpus(domain2)); 12.503 +} 12.504 + 12.505 +/* Prints number of virtual CPUs statistic */ 12.506 +static void print_vcpus(xenstat_domain *domain) 12.507 +{ 12.508 + print("%5u", xenstat_domain_num_vcpus(domain)); 12.509 +} 12.510 + 12.511 +/* Compares number of virtual networks of two domains, returning -1,0,1 for 12.512 + * <,=,> */ 12.513 +static int compare_nets(xenstat_domain *domain1, xenstat_domain *domain2) 12.514 +{ 12.515 + return -compare(xenstat_domain_num_networks(domain1), 12.516 + xenstat_domain_num_networks(domain2)); 12.517 +} 12.518 + 12.519 +/* Prints number of virtual networks statistic */ 12.520 +static void print_nets(xenstat_domain *domain) 12.521 +{ 12.522 + print("%4u", xenstat_domain_num_networks(domain)); 12.523 +} 12.524 + 12.525 +/* Compares number of total network tx bytes of two domains, returning -1,0,1 for 12.526 + * <,=,> */ 12.527 +static int compare_net_tx(xenstat_domain *domain1, xenstat_domain *domain2) 12.528 +{ 12.529 + return -compare(tot_net_bytes(domain1, FALSE), 12.530 + tot_net_bytes(domain2, FALSE)); 12.531 +} 12.532 + 12.533 +/* Prints number of total network tx bytes statistic */ 12.534 +static void print_net_tx(xenstat_domain *domain) 12.535 +{ 12.536 + print("%8llu", tot_net_bytes(domain, FALSE)/1024); 12.537 +} 12.538 + 12.539 +/* Compares number of total network rx bytes of two domains, returning -1,0,1 for 12.540 + * <,=,> */ 12.541 +static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2) 12.542 +{ 12.543 + return -compare(tot_net_bytes(domain1, TRUE), 12.544 + tot_net_bytes(domain2, TRUE)); 12.545 +} 12.546 + 12.547 +/* Prints number of total network rx bytes statistic */ 12.548 +static void print_net_rx(xenstat_domain *domain) 12.549 +{ 12.550 + print("%8llu", tot_net_bytes(domain, TRUE)/1024); 12.551 +} 12.552 + 12.553 +/* Gets number of total network bytes statistic, if rx true, then rx bytes 12.554 + * otherwise tx bytes 12.555 + */ 12.556 +static unsigned long long tot_net_bytes(xenstat_domain *domain, int rx_flag) 12.557 +{ 12.558 + int i = 0; 12.559 + xenstat_network *network; 12.560 + unsigned num_networks = 0; 12.561 + unsigned long long total = 0; 12.562 + 12.563 + /* How many networks? */ 12.564 + num_networks = xenstat_domain_num_networks(domain); 12.565 + 12.566 + /* Dump information for each network */ 12.567 + for (i=0; i < num_networks; i++) { 12.568 + /* Next get the network information */ 12.569 + network = xenstat_domain_network(domain,i); 12.570 + if (rx_flag) 12.571 + total += xenstat_network_rbytes(network); 12.572 + else 12.573 + total += xenstat_network_tbytes(network); 12.574 + } 12.575 + return (total); 12.576 +} 12.577 + 12.578 +/* Compares security id (ssid) of two domains, returning -1,0,1 for <,=,> */ 12.579 +static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2) 12.580 +{ 12.581 + return compare(xenstat_domain_ssid(domain1), 12.582 + xenstat_domain_ssid(domain2)); 12.583 +} 12.584 + 12.585 +/* Prints ssid statistic */ 12.586 +static void print_ssid(xenstat_domain *domain) 12.587 +{ 12.588 + print("%4u", xenstat_domain_ssid(domain)); 12.589 +} 12.590 + 12.591 +/* Section printing functions */ 12.592 +/* Prints the top summary, above the domain table */ 12.593 +void do_summary(void) 12.594 +{ 12.595 +#define TIME_STR_LEN 9 12.596 + const char *TIME_STR_FORMAT = "%H:%M:%S"; 12.597 + char time_str[TIME_STR_LEN]; 12.598 + unsigned run = 0, block = 0, pause = 0, 12.599 + crash = 0, dying = 0, shutdown = 0; 12.600 + unsigned i, num_domains = 0; 12.601 + unsigned long long used = 0; 12.602 + xenstat_domain *domain; 12.603 + 12.604 + /* Print program name, current time, and number of domains */ 12.605 + strftime(time_str, TIME_STR_LEN, TIME_STR_FORMAT, 12.606 + localtime(&curtime.tv_sec)); 12.607 + num_domains = xenstat_node_num_domains(cur_node); 12.608 + print("xentop - %s\n", time_str); 12.609 + 12.610 + /* Tabulate what states domains are in for summary */ 12.611 + for (i=0; i < num_domains; i++) { 12.612 + domain = xenstat_node_domain_by_index(cur_node,i); 12.613 + if (xenstat_domain_running(domain)) run++; 12.614 + else if (xenstat_domain_blocked(domain)) block++; 12.615 + else if (xenstat_domain_paused(domain)) pause++; 12.616 + else if (xenstat_domain_shutdown(domain)) shutdown++; 12.617 + else if (xenstat_domain_crashed(domain)) crash++; 12.618 + else if (xenstat_domain_dying(domain)) dying++; 12.619 + } 12.620 + 12.621 + print("%u domains: %u running, %u blocked, %u paused, " 12.622 + "%u crashed, %u dying, %u shutdown \n", 12.623 + num_domains, run, block, pause, crash, dying, shutdown); 12.624 + 12.625 + used = xenstat_node_tot_mem(cur_node)-xenstat_node_free_mem(cur_node); 12.626 + 12.627 + /* Dump node memory and cpu information */ 12.628 + print("Mem: %lluk total, %lluk used, %lluk free " 12.629 + "CPUs: %u @ %lluMHz\n", 12.630 + xenstat_node_tot_mem(cur_node)/1024, used/1024, 12.631 + xenstat_node_free_mem(cur_node)/1024, 12.632 + xenstat_node_num_cpus(cur_node), 12.633 + xenstat_node_cpu_hz(cur_node)/1000000); 12.634 +} 12.635 + 12.636 +/* Display the top header for the domain table */ 12.637 +void do_header(void) 12.638 +{ 12.639 + field_id i; 12.640 + 12.641 + /* Turn on REVERSE highlight attribute for headings */ 12.642 + attron(A_REVERSE); 12.643 + for(i = 0; i < NUM_FIELDS; i++) { 12.644 + if(i != 0) 12.645 + print(" "); 12.646 + /* The BOLD attribute is turned on for the sort column */ 12.647 + if(i == sort_field) 12.648 + attron(A_BOLD); 12.649 + print("%*s", fields[i].default_width, fields[i].header); 12.650 + if(i == sort_field) 12.651 + attroff(A_BOLD); 12.652 + } 12.653 + attroff(A_REVERSE); 12.654 + print("\n"); 12.655 +} 12.656 + 12.657 +/* Displays bottom status line or current prompt */ 12.658 +void do_bottom_line(void) 12.659 +{ 12.660 + move(lines()-1, 2); 12.661 + 12.662 + if (prompt != NULL) { 12.663 + printw("%s: %s", prompt, prompt_val); 12.664 + } else { 12.665 + addch(A_REVERSE | 'D'); addstr("elay "); 12.666 + 12.667 + /* network */ 12.668 + addch(A_REVERSE | 'N'); 12.669 + attr_addstr(show_networks ? COLOR_PAIR(1) : 0, "etworks"); 12.670 + addstr(" "); 12.671 + 12.672 + /* vcpus */ 12.673 + addch(A_REVERSE | 'V'); 12.674 + attr_addstr(show_vcpus ? COLOR_PAIR(1) : 0, "CPUs"); 12.675 + addstr(" "); 12.676 + 12.677 + /* repeat */ 12.678 + addch(A_REVERSE | 'R'); 12.679 + attr_addstr(repeat_header ? COLOR_PAIR(1) : 0, "epeat header"); 12.680 + addstr(" "); 12.681 + 12.682 + /* sort order */ 12.683 + addch(A_REVERSE | 'S'); addstr("ort order "); 12.684 + 12.685 + addch(A_REVERSE | 'Q'); addstr("uit "); 12.686 + } 12.687 +} 12.688 + 12.689 +/* Prints Domain information */ 12.690 +void do_domain(xenstat_domain *domain) 12.691 +{ 12.692 + unsigned int i; 12.693 + for(i = 0; i < NUM_FIELDS; i++) { 12.694 + if(i != 0) 12.695 + print(" "); 12.696 + if(i == sort_field) 12.697 + attron(A_BOLD); 12.698 + fields[i].print(domain); 12.699 + if(i == sort_field) 12.700 + attroff(A_BOLD); 12.701 + } 12.702 + print("\n"); 12.703 +} 12.704 + 12.705 +/* Output all vcpu information */ 12.706 +void do_vcpu(xenstat_domain *domain) 12.707 +{ 12.708 + int i = 0; 12.709 + unsigned num_vcpus = 0; 12.710 + xenstat_vcpu *vcpu; 12.711 + 12.712 + print("VCPUs(sec): "); 12.713 + 12.714 + num_vcpus = xenstat_domain_num_vcpus(domain); 12.715 + 12.716 + /* for all vcpus dump out values */ 12.717 + for (i=0; i< num_vcpus; i++) { 12.718 + vcpu = xenstat_domain_vcpu(domain,i); 12.719 + 12.720 + if (i != 0 && (i%5)==0) 12.721 + print("\n "); 12.722 + print(" %2u: %10llus", i, xenstat_vcpu_ns(vcpu)/1000000000); 12.723 + } 12.724 + print("\n"); 12.725 +} 12.726 + 12.727 +/* Output all network information */ 12.728 +void do_network(xenstat_domain *domain) 12.729 +{ 12.730 + int i = 0; 12.731 + xenstat_network *network; 12.732 + unsigned num_networks = 0; 12.733 + 12.734 + /* How many networks? */ 12.735 + num_networks = xenstat_domain_num_networks(domain); 12.736 + 12.737 + /* Dump information for each network */ 12.738 + for (i=0; i < num_networks; i++) { 12.739 + /* Next get the network information */ 12.740 + network = xenstat_domain_network(domain,i); 12.741 + 12.742 + print("Net%d RX: %8llubytes %8llupkts %8lluerr %8lludrop ", 12.743 + i, 12.744 + xenstat_network_rbytes(network), 12.745 + xenstat_network_rpackets(network), 12.746 + xenstat_network_rerrs(network), 12.747 + xenstat_network_rdrop(network)); 12.748 + 12.749 + print("TX: %8llubytes %8llupkts %8lluerr %8lludrop\n", 12.750 + xenstat_network_tbytes(network), 12.751 + xenstat_network_tpackets(network), 12.752 + xenstat_network_terrs(network), 12.753 + xenstat_network_tdrop(network)); 12.754 + } 12.755 +} 12.756 + 12.757 +static void top(void) 12.758 +{ 12.759 + xenstat_domain **domains; 12.760 + unsigned int i, num_domains = 0; 12.761 + 12.762 + /* Now get the node information */ 12.763 + if (prev_node != NULL) 12.764 + xenstat_free_node(prev_node); 12.765 + prev_node = cur_node; 12.766 + cur_node = xenstat_get_node(xhandle, XENSTAT_ALL); 12.767 + if (cur_node == NULL) 12.768 + fail("Failed to retrieve statistics from libxenstat\n"); 12.769 + 12.770 + /* dump summary top information */ 12.771 + do_summary(); 12.772 + 12.773 + /* Count the number of domains for which to report data */ 12.774 + num_domains = xenstat_node_num_domains(cur_node); 12.775 + 12.776 + domains = malloc(num_domains*sizeof(xenstat_domain *)); 12.777 + if(domains == NULL) 12.778 + fail("Failed to allocate memory\n"); 12.779 + 12.780 + for (i=0; i < num_domains; i++) 12.781 + domains[i] = xenstat_node_domain_by_index(cur_node, i); 12.782 + 12.783 + /* Sort */ 12.784 + qsort(domains, num_domains, sizeof(xenstat_domain *), 12.785 + (int(*)(const void *, const void *))compare_domains); 12.786 + 12.787 + if(first_domain_index >= num_domains) 12.788 + first_domain_index = num_domains-1; 12.789 + 12.790 + for (i = first_domain_index; i < num_domains; i++) { 12.791 + if(current_row() == lines()-1) 12.792 + break; 12.793 + if (i == first_domain_index || repeat_header) 12.794 + do_header(); 12.795 + do_domain(domains[i]); 12.796 + if (show_vcpus) 12.797 + do_vcpu(domains[i]); 12.798 + if (show_networks) 12.799 + do_network(domains[i]); 12.800 + } 12.801 + 12.802 + do_bottom_line(); 12.803 +} 12.804 + 12.805 +int main(int argc, char **argv) 12.806 +{ 12.807 + int opt, optind = 0; 12.808 + int ch = ERR; 12.809 + 12.810 + struct option lopts[] = { 12.811 + { "help", no_argument, NULL, 'h' }, 12.812 + { "version", no_argument, NULL, 'V' }, 12.813 + { "networks", no_argument, NULL, 'n' }, 12.814 + { "repeat-header", no_argument, NULL, 'r' }, 12.815 + { "vcpus", no_argument, NULL, 'v' }, 12.816 + { "delay", required_argument, NULL, 'd' }, 12.817 + { 0, 0, 0, 0 }, 12.818 + }; 12.819 + const char *sopts = "hVbnvd:"; 12.820 + 12.821 + if (atexit(cleanup) != 0) 12.822 + fail("Failed to install cleanup handler.\n"); 12.823 + 12.824 + while ((opt = getopt_long(argc, argv, sopts, lopts, &optind)) != -1) { 12.825 + switch (opt) { 12.826 + case 'h': 12.827 + case '?': 12.828 + default: 12.829 + usage(argv[0]); 12.830 + exit(0); 12.831 + case 'V': 12.832 + version(); 12.833 + exit(0); 12.834 + case 'n': 12.835 + show_networks = 1; 12.836 + break; 12.837 + case 'r': 12.838 + repeat_header = 1; 12.839 + break; 12.840 + case 'v': 12.841 + show_vcpus = 1; 12.842 + break; 12.843 + case 'd': 12.844 + delay = atoi(optarg); 12.845 + break; 12.846 + } 12.847 + } 12.848 + 12.849 + /* Get xenstat handle */ 12.850 + xhandle = xenstat_init(); 12.851 + if (xhandle == NULL) 12.852 + fail("Failed to initialize xenstat library\n"); 12.853 + 12.854 + /* Begin curses stuff */ 12.855 + initscr(); 12.856 + start_color(); 12.857 + cbreak(); 12.858 + noecho(); 12.859 + nonl(); 12.860 + keypad(stdscr, TRUE); 12.861 + halfdelay(5); 12.862 + use_default_colors(); 12.863 + init_pair(1, -1, COLOR_YELLOW); 12.864 + 12.865 + do { 12.866 + gettimeofday(&curtime, NULL); 12.867 + if(ch != ERR || (curtime.tv_sec - oldtime.tv_sec) >= delay) { 12.868 + clear(); 12.869 + top(); 12.870 + oldtime = curtime; 12.871 + refresh(); 12.872 + } 12.873 + ch = getch(); 12.874 + } while (handle_key(ch)); 12.875 + 12.876 + /* Cleanup occurs in cleanup(), so no work to do here. */ 12.877 + 12.878 + return 0; 12.879 +}