📄 xentop.c
字号:
/* * Copyright (C) International Business Machines Corp., 2005 * Author(s): Judy Fischbach <jfisch@cs.pdx.edu> * David Hendricks <cro_marmot@comcast.net> * Josh Triplett <josh@kernel.org> * based on code from Anthony Liguori <aliguori@us.ibm.com> * * 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 <stdarg.h>#include <string.h>#include <sys/time.h>#include <time.h>#include <unistd.h>#include <signal.h>#if defined(__linux__)#include <linux/kdev_t.h>#endif#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 <xen-tools@lists.xensource.com>.\n"#define _GNU_SOURCE#include <getopt.h>#if !defined(__GNUC__) && !defined(__GNUG__)#define __attribute__(arg) /* empty */#endif#define KEY_ESCAPE '\x1B'#ifdef HOST_SunOS/* Old curses library on Solaris takes non-const strings. Also, ERR interferes * with curse's definition. */#undef ERR#define ERR (-1)#define curses_str_t char *#else#define curses_str_t const char *#endif/* * 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);static unsigned long long tot_vbd_reqs( xenstat_domain *, int);/* Field functions */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);static int compare_name(xenstat_domain *domain1, xenstat_domain *domain2);static void print_name(xenstat_domain *domain);static int compare_vbds(xenstat_domain *domain1, xenstat_domain *domain2);static void print_vbds(xenstat_domain *domain);static int compare_vbd_oo(xenstat_domain *domain1, xenstat_domain *domain2);static void print_vbd_oo(xenstat_domain *domain);static int compare_vbd_rd(xenstat_domain *domain1, xenstat_domain *domain2);static void print_vbd_rd(xenstat_domain *domain);static int compare_vbd_wr(xenstat_domain *domain1, xenstat_domain *domain2);static void print_vbd_wr(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 do_vbd(xenstat_domain *);static void top(void);/* Field types */typedef enum field_id { FIELD_DOMID, FIELD_NAME, 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_VBDS, FIELD_VBD_OO, FIELD_VBD_RD, FIELD_VBD_WR, 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_NAME, "NAME", 10, compare_name, print_name }, { 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_VBDS, "VBDS", 4, compare_vbds, print_vbds }, { FIELD_VBD_OO, "VBD_OO", 8, compare_vbd_oo, print_vbd_oo }, { FIELD_VBD_RD, "VBD_RD", 8, compare_vbd_rd, print_vbd_rd }, { FIELD_VBD_WR, "VBD_WR", 8, compare_vbd_wr, print_vbd_wr }, { 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 = 3;unsigned int batch = 0;unsigned int loop = 1;unsigned int iterations = 0;int show_vcpus = 0;int show_networks = 0;int show_vbds = 0;int repeat_header = 0;#define PROMPT_VAL_LEN 80char *prompt = NULL;char prompt_val[PROMPT_VAL_LEN];int prompt_val_len = 0;void (*prompt_complete_func)(char *);static WINDOW *cwin;/* * 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 3)\n" "-n, --networks output vif network data\n" "-x, --vbds output vbd block device data\n" "-r, --repeat-header repeat table header before each domain\n" "-v, --vcpus output vcpu data\n" "-b, --batch output in batch mode, no user input accepted\n" "-i, --iterations number of iterations before exiting\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(cwin != NULL && !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(cwin != NULL && !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 (!batch) { if((current_row() < lines()-1)) { va_start(args, fmt); vwprintw(stdscr, (curses_str_t)fmt, args); va_end(args); } } else { va_start(args, fmt); vprintf(fmt, args); va_end(args); }}static void xentop_attron(int attr){ if (!batch) attron(attr);}static void xentop_attroff(int attr){ if (!batch) attroff(attr);}/* Print a string with the given attributes set. */static void attr_addstr(int attr, const char *str){ xentop_attron(attr); addstr((curses_str_t)str); xentop_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(value); 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 'b': case 'B': show_vbds ^= 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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -