From fcafbac50463aa446730611da5c907b663976c27 Mon Sep 17 00:00:00 2001 From: KZ Date: Fri, 18 Dec 2020 19:18:37 -0800 Subject: [PATCH] Add nmon version 16m --- packages/6.8/nmon-16m-x86_64-1_SBo.txz | Bin 0 -> 142952 bytes packages/6.9/nmon-16m-x86_64-1_SBo.txz | Bin 0 -> 142952 bytes source/SlackBuild/nmon/README.md | 13 + source/SlackBuild/nmon/lmon16m.c | 8584 ++++++++++++++++++++++++ source/SlackBuild/nmon/nmon.SlackBuild | 88 + source/SlackBuild/nmon/slack-desc | 19 + 6 files changed, 8704 insertions(+) create mode 100644 packages/6.8/nmon-16m-x86_64-1_SBo.txz create mode 100644 packages/6.9/nmon-16m-x86_64-1_SBo.txz create mode 100644 source/SlackBuild/nmon/README.md create mode 100644 source/SlackBuild/nmon/lmon16m.c create mode 100755 source/SlackBuild/nmon/nmon.SlackBuild create mode 100644 source/SlackBuild/nmon/slack-desc diff --git a/packages/6.8/nmon-16m-x86_64-1_SBo.txz b/packages/6.8/nmon-16m-x86_64-1_SBo.txz new file mode 100644 index 0000000000000000000000000000000000000000..726aad4034fe9b8eb3d6c60f9eeb7c6277335adb GIT binary patch literal 142952 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

Lx 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 C;je`N literal 0 HcmV?d00001 diff --git a/packages/6.9/nmon-16m-x86_64-1_SBo.txz b/packages/6.9/nmon-16m-x86_64-1_SBo.txz new file mode 100644 index 0000000000000000000000000000000000000000..726aad4034fe9b8eb3d6c60f9eeb7c6277335adb GIT binary patch literal 142952 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

Lx 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 C;je`N literal 0 HcmV?d00001 diff --git a/source/SlackBuild/nmon/README.md b/source/SlackBuild/nmon/README.md new file mode 100644 index 00000000..ed8c0b28 --- /dev/null +++ b/source/SlackBuild/nmon/README.md @@ -0,0 +1,13 @@ +## README for nmon + +- http://nmon.sourceforge.net/pmwiki.php?n=Site.CompilingNmon has the .c source files. It ALSO has a makefile that includes ARM and X86 and X86_64 compilation flag options. + - Ncurses needs to be installed. I'm using Slackware-current, which has `ncurses-6.2_20201024-x86_64-1.txz`. It also calls for GCC, so I have `gcc-10.2.0-x86_64-2.txz` installed. Finally, I have `make-4.2.1-x86_64-7.txz` installed, though I guess if I'm calling GCC directly, it's perhaps not necessary +- https://slackbuilds.org/repository/14.2/system/nmon/ has a SlackBuild file, but was made for version 14i which is at least older than April 2015 (nmon15c was released). + - The GCC flags are a little out of date in comparison to the makefile, so I copied/merged the flags over. (The changelog notes the deprecation of some of these flags, such as -D LARGEMEM and JFS and GETUSER). + - NOTE: I did this on an X86_64 system and did not update the compile flags in the SlackBuild for other architectures. + - The SlackBuild also has scatterings of hardcoded version numbers, which I updated to be generic `lmon.c` as it is in the makefile. + - I also increased the set flags for more verbose output. + - Finally, the output was changed from `tgz` to `txz` +- There was a "bug" in the 16m release of nmon where the version number string wasn't bumped from "16k" to "16m". I changed that string so the nmon executable properly shows that it is version 16m. +- I copied the compiled `nmon-16m-x86_64-1_SBo.txz` file to Unraid 6.8.3 and 6.9-rc1 systems and confirmed that after `installpkg nmon-16m-x86_64-1_SBo.txz` I was able to call `nmon` and start up the utility without issue + - I thought Ncurses might need to be installed on Unraid for this to work, but it seems to only be needed at compile time. diff --git a/source/SlackBuild/nmon/lmon16m.c b/source/SlackBuild/nmon/lmon16m.c new file mode 100644 index 00000000..982838fd --- /dev/null +++ b/source/SlackBuild/nmon/lmon16m.c @@ -0,0 +1,8584 @@ +/* + * lmon.c -- Curses based Performance Monitor for Linux + * with saving performance stats to a CSV file mode. + * Developer: Nigel Griffiths. + * (C) Copyright 2009 Nigel Griffiths + + 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, either version 3 of the License, or + (at your option) any later version. + + 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, see . + */ + +/* + * Use the following Makefile (for Linux on POWER) +CFLAGS=-g -Wall -D POWER +LDFLAGS=-lcurses -lm +nmon: lmon.o + * end of Makefile + */ +/* Other #ifdef's for specific features or platforms +Platforms: POWER MAINFRAME X86 ARM - Mandatory one of these at a time +Specific Linux versions: RHEL7 SLES113 SLES12 +Specific feature: NVIDIA_GPU +Bug / missing feature workarounds: + REREAD - for RHEL3 + LSBLK_NO_TYPE - SLES11.3 has not lsblk disk TYPE option + +Options which should always but switched on: +SMALLMEM - removes huge memory, dirty, whritebak, mapped, slab, pagethreads as not in older kernels +PRE_KERNEL_2_6_18 1 kernel levels before removed the following to the disk stats + pi_num_threads, + pi_rt_priority, + pi_policy, + pi_delayacct_blkio_ticks +*/ + +/* note: RAW assumes you are using the index "i" to select the CPU */ +#define RAW(member) (long)((long)(p->cpuN[i].member) - (long)(q->cpuN[i].member)) +#define RAWTOTAL(member) (long)((long)(p->cpu_total.member) - (long)(q->cpu_total.member)) + +#define VERSION "16m" +char version[] = VERSION; +static char *SccsId = "nmon " VERSION; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Windows moved here so they can be cleared when the screen mode changes */ +WINDOW *padwelcome = NULL; +WINDOW *padtop = NULL; +WINDOW *padmem = NULL; +WINDOW *padlarge = NULL; +WINDOW *padpage = NULL; +WINDOW *padker = NULL; +WINDOW *padnet = NULL; +WINDOW *padneterr = NULL; +WINDOW *padnfs = NULL; +WINDOW *padres = NULL; +WINDOW *padsmp = NULL; +WINDOW *padutil = NULL; +WINDOW *padwide = NULL; +WINDOW *padgpu = NULL; +WINDOW *padmhz = NULL; +WINDOW *padlong = NULL; +WINDOW *paddisk = NULL; +WINDOW *paddg = NULL; +WINDOW *padmap = NULL; +WINDOW *padjfs = NULL; +#ifdef POWER +WINDOW *padlpar = NULL; +#endif +WINDOW *padverb = NULL; +WINDOW *padhelp = NULL; + + +/* for Disk Busy rain style output covering 100's of diskss on one screen */ +const char disk_busy_map_ch[] = + "_____.....----------++++++++++oooooooooo0000000000OOOOOOOOOO8888888888XXXXXXXXXX##########@@@@@@@@@@*"; +/*"00000555551111111111222222222233333333334444444444555555555566666666667777777777888888888899999999991"*/ + +int extended_disk = 0; /* report additional data from /proc/diskstats to spreadsheet output */ + +#define FLIP(variable) if(variable) variable=0; else variable=1; + +#ifdef MALLOC_DEBUG +#define MALLOC(argument) mymalloc(argument,__LINE__) +#define FREE(argument) myfree(argument,__LINE__) +#define REALLOC(argument1,argument2) myrealloc(argument1,argument2,__LINE__) +void *mymalloc(int size, int line) +{ + void *ptr; + ptr = malloc(size); + fprintf(stderr, "0x%x = malloc(%d) at line=%d\n", ptr, size, line); + return ptr; +} + +void myfree(void *ptr, int line) +{ + fprintf(stderr, "free(0x%x) at line=%d\n", ptr, line); + free(ptr); +} + +void *myrealloc(void *oldptr, int size, int line) +{ + void *ptr; + ptr = realloc(oldptr, size); + fprintf(stderr, "0x%x = realloc(0x%x, %d) at line=%d\n", ptr, oldptr, + size, line); + return ptr; +} +#else +#define MALLOC(argument) malloc(argument) +#define FREE(argument) free(argument) +#define REALLOC(argument1,argument2) realloc(argument1,argument2) +#endif /* MALLOC STUFF */ + +#ifdef NVIDIA_GPU +typedef int nvmlReturn_t; +#define NVML_SUCCESS 0 + +typedef struct nvmlUtilization_st { + unsigned int gpu; + unsigned int memory; +} nvmlUtilization_t; + +struct nvmlDevice_st; +typedef struct nvmlDevice_st *nvmlDevice_t; + +nvmlReturn_t nvmlInit(void); +nvmlReturn_t nvmlShutdown(void); +nvmlReturn_t nvmlDeviceGetCount(unsigned int *count); +nvmlReturn_t nvmlDeviceGetHandleByIndex(unsigned int index, + nvmlDevice_t * device); +nvmlReturn_t nvmlDeviceGetUtilizationRates(nvmlDevice_t device, + nvmlUtilization_t * + utilization); +nvmlReturn_t nvmlSystemGetDriverVersion(char *version, int count); +nvmlReturn_t nvmlSystemGetNVMLVersion(char *version, int count); +nvmlReturn_t nvmlDeviceGetName(nvmlDevice_t device, char *name, int count); +nvmlReturn_t nvmlDeviceGetTemperature(nvmlDevice_t device, int type, + unsigned int *temp); +nvmlReturn_t nvmlDeviceGetPowerUsage(nvmlDevice_t device, + unsigned int *watts); +nvmlReturn_t nvmlDeviceGetClockInfo(nvmlDevice_t device, int type, + unsigned int *mhz); + +#define NVML_TEMPERATURE_GPU 0 +#define NVML_CLOCK_GRAPHICS 0 + +nvmlDevice_t gpu_device[4]; +nvmlUtilization_t gpu_util[4]; +unsigned int gpu_devices; +char gpu_name[4][1024]; +unsigned int gpu_temp[4]; +unsigned int gpu_watts[4]; +unsigned int gpu_clock[4]; +char gpu_driver_version[1024]; +char gpu_nvml_version[1024]; +int first_time_gpu = 1; + +void gpu_init() +{ + int i; + nvmlReturn_t nvres; + if ((nvres = nvmlInit()) != NVML_SUCCESS) { + printf("nvmlInit failed %d\n", nvres); + return; + } + + if ((nvres = + nvmlSystemGetDriverVersion(&gpu_driver_version[0], + 1024)) != NVML_SUCCESS) { + printf("nvmlSystemGetDriverVersion failed %d\n", nvres); + return; + } + if ((nvres = + nvmlSystemGetNVMLVersion(&gpu_nvml_version[0], + 1024)) != NVML_SUCCESS) { + printf("nvmlSystemGetDriverVersion failed %d\n", nvres); + return; + } + + if ((nvres = nvmlDeviceGetCount(&gpu_devices)) != NVML_SUCCESS) { + printf("nvmlDeviceGetCount failed %d\n", nvres); + return; + } + if (gpu_devices > 4) + gpu_devices = 4; + + for (i = 0; i < gpu_devices; i++) { + if (nvmlDeviceGetHandleByIndex(i, &gpu_device[i]) != NVML_SUCCESS) { + printf("nvmlDeviceGetHandleByIndex(%d) failed %d\n", i, nvres); + return; + } + } +} +#endif /* NVIDIA_GPU */ + +#define P_CPUINFO 0 +#define P_STAT 1 +#define P_VERSION 2 +#define P_MEMINFO 3 +#define P_UPTIME 4 +#define P_LOADAVG 5 +#define P_NFS 6 +#define P_NFSD 7 +#define P_VMSTAT 8 /* new in 13h */ +#define P_NUMBER 9 /* one more than the max */ + +char *month[12] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", + "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" +}; + +/* Cut of everything after the first space in callback + * Delete any '&' just before the space + */ +char *check_call_string(char *callback, const char *name) +{ + char *tmp_ptr = callback; + + if (strlen(callback) > 256) { + fprintf(stderr, "ERROR nmon: ignoring %s - too long\n", name); + return (char *) NULL; + } + + for (; *tmp_ptr != '\0' && *tmp_ptr != ' ' && *tmp_ptr != '&'; + ++tmp_ptr); + + *tmp_ptr = '\0'; + + if (tmp_ptr == callback) + return (char *) NULL; + else + return callback; +} + +/* Remove error output to this buffer and display it if NMONDEBUG=1 */ +char errorstr[70]; +int error_on = 0; +void error(char *err) +{ + strncpy(errorstr, err, 69); + errorstr[69] = 0; +} + +/* + * lscpu command output save +*/ +int lscpu_available = 0; + +struct { + char *arch; + char *byte_order; +#define ORDER_UNKNOWN 0 +#define ORDER_LITTLE 1 +#define ORDER_BIG 2 + int order; + int cpus; + char *cpu_online; + char *cpu_offline; + int threads; + int cores; + int sockets; + int numa_nodes; + char *model; + char *model_name; + int mhz; + int mhz_min; + int mhz_max; +} lscpu; + +void lscpu_init() +{ + FILE *pop; + int len; + int data_col = 21; +#define LSCPU_STRLEN 512 + char tmpstr[LSCPU_STRLEN + 1]; + + if (lscpu_available == 1) + return; + pop = popen("/usr/bin/lscpu 2>/dev/null", "r"); + if (pop != NULL) { + lscpu_available = 1; + tmpstr[0] = 0; + while (fgets(tmpstr, LSCPU_STRLEN, pop) != NULL) { + tmpstr[strlen(tmpstr) - 1] = 0; /* remove newline */ + if (strncmp("Architecture:", tmpstr, strlen("Architecture:")) == 0) { + + /* Architecture: SOMETHING OR OTHER + 0123456789012345678901 + |-> ^ */ + /* start from char after the : looking for some leters or numbers */ + len = strlen(tmpstr); + for(data_col=14;data_col + +struct procsinfo { + int pi_pid; + char pi_comm[64]; + char pi_state; + int pi_ppid; + int pi_pgrp; + int pi_session; + int pi_tty_nr; + int pi_tty_pgrp; + unsigned long pi_flags; + unsigned long pi_minflt; + unsigned long pi_cmin_flt; + unsigned long pi_majflt; + unsigned long pi_cmaj_flt; + unsigned long pi_utime; + unsigned long pi_stime; + long pi_cutime; + long pi_cstime; + long pi_pri; + long pi_nice; +#ifdef PRE_KERNEL_2_6_18 + long junk /* removed */ ; +#else + long pi_num_threads; +#endif + long pi_it_real_value; + unsigned long pi_start_time; + unsigned long pi_vsize; + long pi_rss; /* - 3 */ + unsigned long pi_rlim_cur; + unsigned long pi_start_code; + unsigned long pi_end_code; + unsigned long pi_start_stack; + unsigned long pi_esp; + unsigned long pi_eip; + /* The signal information here is obsolete. */ + unsigned long pi_pending_signal; + unsigned long pi_blocked_sig; + unsigned long pi_sigign; + unsigned long pi_sigcatch; + unsigned long pi_wchan; + unsigned long pi_nswap; + unsigned long pi_cnswap; + int pi_exit_signal; + int pi_cpu; +#ifndef PRE_KERNEL_2_6_18 + unsigned long pi_rt_priority; + unsigned long pi_policy; + unsigned long long pi_delayacct_blkio_ticks; +#endif + unsigned long statm_size; /* total program size */ + unsigned long statm_resident; /* resident set size */ + unsigned long statm_share; /* shared pages */ + unsigned long statm_trs; /* text (code) */ + unsigned long statm_drs; /* data/stack */ + unsigned long statm_lrs; /* library */ + unsigned long statm_dt; /* dirty pages */ + + unsigned long long read_io; /* storage read bytes */ + unsigned long long write_io; /* storage write bytes */ +}; +int isroot = 0; + +#include +#include +#include +#include +#include + +int debug = 0; +time_t timer; /* used to work out the hour/min/second */ + +/* Counts of resources */ +int cpus = 1; /* number of CPUs in system (lets hope its more than zero!) */ +#if X86 || ARM +int cores = 0; +int siblings = 0; +int processorchips = 0; +int hyperthreads = 0; +char *vendor_ptr = "not-set"; +char *model_ptr = "not-set"; +char *mhz_ptr = "not-set"; +char *bogo_ptr = "not-set"; +#endif +int old_cpus = 1; /* Number of CPU seen in previuos interval */ +int max_cpus = 1; /* highest number of CPUs in DLPAR */ +int networks = 0; /* number of networks in system */ +int partitions = 0; /* number of partitions in system */ +int partitions_short = 0; /* partitions file data short form (i.e. data missing) */ +int disks = 0; /* number of disks in system */ +int seconds = -1; /* pause interval */ +int maxloops = -1; /* stop after this number of updates */ +char hostname[256]; +char run_name[256]; +int run_name_set = 0; +char fullhostname[256]; +int loop; + +#define DPL 150 /* Disks per line for file output to ensure it + does not overflow the spreadsheet input line max */ + +int disks_per_line = DPL; + +#define NEWDISKGROUP(disk) ( (disk) % disks_per_line == 0) + +/* Mode of output variables */ +int show_aaa = 1; +int show_para = 1; +int show_headings = 1; +int show_res = 0; +int show_smp = 0; +int show_util = 0; +int first_util = 1; +int show_wide = 0; +int show_gpu = 0; +int show_mhz = 0; +int show_longterm = 0; +int show_disk = 0; +#define SHOW_DISK_NONE 0 +#define SHOW_DISK_STATS 1 +#define SHOW_DISK_GRAPH 2 +int show_diskmap = 0; +int show_memory = 0; +int show_large = 0; +int show_kernel = 0; +int show_nfs = 0; +int show_net = 0; +int show_neterror = 0; +int show_help = 0; +int show_top = 0; +int show_topmode = 1; +#define ARGS_NONE 0 +#define ARGS_ONLY 1 +int show_args = 0; +int show_all = 1; /* 1=all procs& disk 0=only if 1% or more busy */ +int show_verbose = 0; +int show_jfs = 0; +int show_jfs_minimum = 0; +int flash_on = 0; +int first_huge = 1; +int first_steal = 1; +long huge_peak = 0; +int welcome = 1; +int dotline = 0; +int show_rrd = 0; +int show_lpar = 0; +int show_vm = 0; +int show_dgroup = 0; /* disk groups */ +int auto_dgroup = 0; /* disk groups defined via -g auto */ +int disk_only_mode = 0; /* disk stats shows disks only if user used -g auto */ +int dgroup_loaded = 0; /* 0 = no, 1=needed, 2=loaded */ + +#define RRD if(show_rrd) + +double ignore_procdisk_threshold = 0.1; +double ignore_io_threshold = 0.1; +/* Curses support */ +#define CURSE if(cursed) /* Only use this for single line curses calls */ +#define COLOUR if(colour) /* Only use this for single line colour curses calls */ +int cursed = 1; /* 1 = using curses and + 0 = loging output for a spreadsheet */ +int colour = 1; /* 1 = using colour curses and + 0 = using black and white curses (see -b flag) */ +#define MVPRINTW(row,col,string) {move((row),(col)); \ + attron(A_STANDOUT); \ + printw(string); \ + attroff(A_STANDOUT); } +FILE *fp; /* filepointer for spreadsheet output */ + + +char *timestamp(int loop, time_t eon) +{ + static char string[64]; + if (show_rrd) + snprintf(string, 64, "%ld", (long) eon); + else + snprintf(string, 64, "T%04d", loop); + return string; +} + +#define LOOP timestamp(loop,timer) + +char *easy[5] = { "not found", 0, 0, 0, 0 }; +char *lsb_release[5] = { "not found", 0, 0, 0, 0 }; + +void find_release() +{ + FILE *pop; + int i; + char tmpstr[1024+1]; + +#if defined(SLES12) || defined(SLES15) + pop = popen("cat /etc/os-release 2>/dev/null", "r"); +#else + pop = popen("cat /etc/*ease 2>/dev/null", "r"); +#endif /* SLES12 */ + if (pop != NULL) { + tmpstr[0] = 0; + for (i = 0; i < 4; i++) { + if (fgets(tmpstr, 1024, pop) == NULL) + break; + tmpstr[strlen(tmpstr) - 1] = 0; /* remove newline */ + easy[i] = MALLOC(strlen(tmpstr) + 1); + strcpy(easy[i], tmpstr); + } + pclose(pop); + } + pop = popen("/usr/bin/lsb_release -idrc 2>/dev/null", "r"); + if (pop != NULL) { + tmpstr[0] = 0; + for (i = 0; i < 4; i++) { + if (fgets(tmpstr, 70, pop) == NULL) + break; + tmpstr[strlen(tmpstr) - 1] = 0; /* remove newline */ + lsb_release[i] = MALLOC(strlen(tmpstr) + 1); + strcpy(lsb_release[i], tmpstr); + } + pclose(pop); + } +} + + + +/* Full Args Mode stuff here */ + +#define ARGSMAX 1024*8 +#define CMDLEN 4096 + +struct { + int pid; + char *args; +} arglist[ARGSMAX]; + +void args_output(int pid, int loop, char *progname) +{ + FILE *pop; + int i, j, n; + char tmpstr[CMDLEN]; + static int arg_first_time = 1; + + if (pid == 0) + return; /* ignore init */ + for (i = 0; i < ARGSMAX - 1; i++) { /* clear data out */ + if (arglist[i].pid == pid) { + return; + } + if (arglist[i].pid == 0) /* got to empty slot */ + break; + } + snprintf(tmpstr, CMDLEN, "ps -p %d -o args 2>/dev/null", pid); + pop = popen(tmpstr, "r"); + if (pop == NULL) { + return; + } else { + if (fgets(tmpstr, CMDLEN, pop) == NULL) { /* throw away header */ + pclose(pop); + return; + } + tmpstr[0] = 0; + if (fgets(tmpstr, CMDLEN, pop) == NULL) { + pclose(pop); + return; + } + tmpstr[strlen(tmpstr) - 1] = 0; + if (tmpstr[strlen(tmpstr) - 1] == ' ') + tmpstr[strlen(tmpstr) - 1] = 0; + arglist[i].pid = pid; + if (arg_first_time) { + fprintf(fp, "UARG,+Time,PID,ProgName,FullCommand\n"); + arg_first_time = 0; + } + n = strlen(tmpstr); + for (i = 0; i < n; i++) { + /*strip out stuff that confused Excel i.e. starting with maths symbol */ + if (tmpstr[i] == ',' && + ((tmpstr[i + 1] == '-') || tmpstr[i + 1] == '+')) + tmpstr[i + 1] = '_'; + /*strip out double spaces */ + if (tmpstr[i] == ' ' && tmpstr[i + 1] == ' ') { + for (j = 0; j < n - i; j++) + tmpstr[i + j] = tmpstr[i + j + 1]; + i--; /* rescan to remove triple space etc */ + } + } + + fprintf(fp, "UARG,%s,%07d,%s,%s\n", LOOP, pid, progname, tmpstr); + pclose(pop); + return; + } +} + +void args_load() +{ + FILE *pop; + int i; + char tmpstr[CMDLEN]; + + for (i = 0; i < ARGSMAX; i++) { /* clear data out */ + if (arglist[i].pid == -1) + break; + if (arglist[i].pid != 0) { + arglist[i].pid = -1; + free(arglist[i].args); + } + } + pop = popen("ps -eo pid,args 2>/dev/null", "r"); + if (pop == NULL) { + return; + } else { + if (fgets(tmpstr, CMDLEN, pop) == NULL) { /* throw away header */ + pclose(pop); + return; + } + for (i = 0; i < ARGSMAX; i++) { + tmpstr[0] = 0; + if (fgets(tmpstr, CMDLEN, pop) == NULL) { + pclose(pop); + return; + } + tmpstr[strlen(tmpstr) - 1] = 0; + if (tmpstr[strlen(tmpstr) - 1] == ' ') + tmpstr[strlen(tmpstr) - 1] = 0; + arglist[i].pid = atoi(tmpstr); + arglist[i].args = MALLOC(strlen(tmpstr) + 1); + strcpy(arglist[i].args, &tmpstr[6]); + } + pclose(pop); + } +} + +char *args_lookup(int pid, char *progname) +{ + int i; + for (i = 0; i < ARGSMAX; i++) { + if (arglist[i].pid == pid) + return arglist[i].args; + if (arglist[i].pid == -1) + return progname; + } + return progname; +} + +/* end args mode stuff here */ + +void linux_bbbp(char *name, char *cmd, char *err) +{ + int i; + int j; + int len; +#define STRLEN 4096 + char str[STRLEN]; + FILE *pop; + static int lineno = 0; + + pop = popen(cmd, "r"); + if (pop == NULL) { + fprintf(fp, "BBBP,%03d,%s failed to run %s\n", lineno++, cmd, err); + } else { + fprintf(fp, "BBBP,%03d,%s\n", lineno++, name); + for (i = 0; i < 2048 && (fgets(str, STRLEN, pop) != NULL); i++) { /* 2048=sanity check only */ + len = strlen(str); + if (len > STRLEN) + len = STRLEN; + if (str[len - 1] == '\n') /*strip off the newline */ + str[len - 1] = 0; + /* fix text starting characters that confuses spread sheets */ + if (str[0] == '+') + str[0] = 'p'; + if (str[0] == '*') + str[0] = 'm'; + if (str[0] == '-') + str[0] = 'n'; + if (str[0] == '/') + str[0] = 'd'; + if (str[0] == '=') + str[0] = 'e'; + /* remove double quotes as it confuses spread sheets */ + for (j = 0; str[j] != 0; j++) + if (str[j] == '"') + str[j] = 'Q'; + fprintf(fp, "BBBP,%03d,%s,\"%s\"\n", lineno++, name, str); + } + pclose(pop); + } +} + +#define WARNING "needs root permission or file not present" + +/* Global name of programme for printing it */ +char *progname; + +/* Seconds since epoc and the sting version */ +long long boottime = 0; +char boottime_str[64] = "not found"; +/* Main data structure for collected stats. + * Two versions are previous and current data. + * Often its the difference that is printed. + * The pointers are swaped i.e. current becomes the previous + * and the previous over written rather than moving data around. + */ +struct cpu_stat { /* changed the order here to match this years kernel (man 5 /proc/stat) */ + long long user; + long long nice; + long long sys; + long long idle; + long long wait; /* for IO */ + long long irq; + long long softirq; + long long steal; + long long guest; + long long guest_nice; + /* below are non-cpu based numbers in the same file */ + long long intr; + long long ctxt; + long long procs; + long long running; + long long blocked; + float uptime; + float idletime; + float mins1; + float mins5; + float mins15; +}; + +#define ulong unsigned long +struct dsk_stat { + char dk_name[32]; + int dk_major; + int dk_minor; + long dk_noinfo; + ulong dk_reads; + ulong dk_rmerge; + ulong dk_rmsec; + ulong dk_rkb; + ulong dk_writes; + ulong dk_wmerge; + ulong dk_wmsec; + ulong dk_wkb; + ulong dk_xfers; + ulong dk_bsize; + ulong dk_time; + ulong dk_inflight; + ulong dk_backlog; + ulong dk_partition; + ulong dk_blocks; /* in /proc/partitions only */ + ulong dk_use; + ulong dk_aveq; +}; + +struct mem_stat { + long memtotal; + long memfree; + long memshared; + long buffers; + long cached; + long swapcached; + long active; + long inactive; + long hightotal; + long highfree; + long lowtotal; + long lowfree; + long swaptotal; + long swapfree; +#ifndef SMALLMEM + long dirty; + long writeback; + long mapped; + long slab; + long committed_as; + long pagetables; + long hugetotal; + long hugefree; + long hugesize; +#else + long bigfree; +#endif /*SMALLMEM*/ +}; + +struct vm_stat { + long long nr_dirty; + long long nr_writeback; + long long nr_unstable; + long long nr_page_table_pages; + long long nr_mapped; + long long nr_slab; + long long nr_slab_reclaimable; + long long nr_slab_unreclaimable; + long long pgpgin; + long long pgpgout; + long long pswpin; + long long pswpout; + long long pgalloc_high; + long long pgalloc_normal; + long long pgalloc_dma; + long long pgfree; + long long pgactivate; + long long pgdeactivate; + long long pgfault; + long long pgmajfault; + long long pgrefill_high; + long long pgrefill_normal; + long long pgrefill_dma; + long long pgsteal_high; + long long pgsteal_normal; + long long pgsteal_dma; + long long pgscan_kswapd_high; + long long pgscan_kswapd_normal; + long long pgscan_kswapd_dma; + long long pgscan_direct_high; + long long pgscan_direct_normal; + long long pgscan_direct_dma; + long long pginodesteal; + long long slabs_scanned; + long long kswapd_steal; + long long kswapd_inodesteal; + long long pageoutrun; + long long allocstall; + long long pgrotated; +}; + + +#define NFS_V2_NAMES_COUNT 18 +char *nfs_v2_names[NFS_V2_NAMES_COUNT] = { + "null", "getattr", "setattr", "root", "lookup", "readlink", + "read", "wrcache", "write", "create", "remove", "rename", + "link", "symlink", "mkdir", "rmdir", "readdir", "fsstat" +}; + +#define NFS_V3_NAMES_COUNT 22 +char *nfs_v3_names[22] = { + "null", "getattr", "setattr", "lookup", "access", "readlink", + "read", "write", "create", "mkdir", "symlink", "mknod", + "remove", "rmdir", "rename", "link", "readdir", "readdirplus", + "fsstat", "fsinfo", "pathconf", "commit" +}; + +#define NFS_V4S_NAMES_COUNT 72 +int nfs_v4s_names_count = NFS_V4S_NAMES_COUNT; +char *nfs_v4s_names[NFS_V4S_NAMES_COUNT] = { /* get these names from nfsstat as they are NOT documented */ + "op0-unused", "op1-unused", "op2-future", "access", "close", "commit", /* 1 - 6 */ + "create", "delegpurge", "delegreturn", "getattr", "getfh", "link", /* 7 - 12 */ + "lock", "lockt", "locku", "lookup", "lookup_root", "nverify", /* 13 - 18 */ + "open", "openattr", "open_conf", "open_dgrd", "putfh", "putpubfh", /* 19 - 24 */ + "putrootfh", "read", "readdir", "readlink", "remove", "rename", /* 25 - 30 */ + "renew", "restorefh", "savefh", "secinfo", "setattr", "setcltid", /* 31 - 36 */ + "setcltidconf", "verify", "write", "rellockowner", "bc_ctl", "blind_conn", /* 37 - 42 */ + "exchange_id", "create_ses", "destroy_ses", "free_statid", "getdirdelag", "getdevinfo", /* 43 - 48 */ + "getdevlist", "layoutcommit", "layoutget", "layoutreturn", "secunfononam", "sequence", /* 49 - 54 */ + "set_ssv", "test_stateid", "want_deleg", "destory_clid", "reclaim_comp", "stat60", /* 55 - 60 */ + "stat61", "stat62", "stat63", "stat64", "stat65", "stat66", /* 61 - 66 */ + "stat67", "stat68", "stat69", "stat70", "stat71", "stat72" /* 67 - 72 */ +}; + +#define NFS_V4C_NAMES_COUNT 60 +int nfs_v4c_names_count = NFS_V4C_NAMES_COUNT; +char *nfs_v4c_names[NFS_V4C_NAMES_COUNT] = { /* get these names from nfsstat as they are NOT documented */ + "null", "read", "write", "commit", "open", "open_conf", /* 1 - 6 */ + "open_noat", "open_dgrd", "close", "setattr", "fsinfo", "renew", /* 7 - 12 */ + "setclntid", "confirm", "lock", "lockt", "locku", "access", /* 13 - 18 */ + "getattr", "lookup", "lookup_root", "remove", "rename", "link", /* 19 - 24 */ + "symlink", "create", "pathconf", "statfs", "readlink", "readdir", /* 25 - 30 */ + "server_caps", "delegreturn", "getacl", "setacl", "fs_locations", "rel_lkowner", /* 31 - 36 */ + "secinfo", "exchange_id", "create_ses", "destroy_ses", "sequence", "get_lease_t", /* 37 - 42 */ + "reclaim_comp", "layoutget", "getdevinfo", "layoutcommit", "layoutreturn", "getdevlist", /* 43 - 48 */ + "stat49", "stat50", "stat51", "stat52", "start53", "stat54", /* 49 - 54 */ + "stat55", "stat56", "stat57", "stat58", "start59", "stat60" /* 55 - 60 */ +}; + + +int nfs_v2c_found = 0; +int nfs_v2s_found = 0; +int nfs_v3c_found = 0; +int nfs_v3s_found = 0; +int nfs_v4c_found = 0; +int nfs_v4s_found = 0; +int nfs_clear = 0; + +struct nfs_stat { + long v2c[NFS_V2_NAMES_COUNT]; /* verison 2 client */ + long v3c[NFS_V3_NAMES_COUNT]; /* verison 3 client */ + long v4c[NFS_V4C_NAMES_COUNT]; /* verison 4 client */ + long v2s[NFS_V2_NAMES_COUNT]; /* verison 2 SERVER */ + long v3s[NFS_V3_NAMES_COUNT]; /* verison 3 SERVER */ + long v4s[NFS_V4S_NAMES_COUNT]; /* verison 4 SERVER */ +}; + +#define NETMAX 32 +struct net_stat { + unsigned long if_name[17]; + unsigned long long if_ibytes; + unsigned long long if_obytes; + unsigned long long if_ipackets; + unsigned long long if_opackets; + unsigned long if_ierrs; + unsigned long if_oerrs; + unsigned long if_idrop; + unsigned long if_ififo; + unsigned long if_iframe; + unsigned long if_odrop; + unsigned long if_ofifo; + unsigned long if_ocarrier; + unsigned long if_ocolls; +}; +#ifdef PARTITIONS +#define PARTMAX 256 +struct part_stat { + int part_major; + int part_minor; + unsigned long part_blocks; + char part_name[16]; + unsigned long part_rio; + unsigned long part_rmerge; + unsigned long part_rsect; + unsigned long part_ruse; + unsigned long part_wio; + unsigned long part_wmerge; + unsigned long part_wsect; + unsigned long part_wuse; + unsigned long part_run; + unsigned long part_use; + unsigned long part_aveq; +}; +#endif /*PARTITIONS*/ +#ifdef POWER +#define VM_UNKNOWN 0 +#define VM_POWERVM 1 +#define VM_POWERKVM_GUEST 2 +#define VM_POWERKVM_HOST 3 +#define VM_NATIVE 4 +int power_vm_type = VM_UNKNOWN; + +/* XXXXXXX need to test if rewind() worked or not for lparcfg */ +int lparcfg_reread = 1; +/* Reset at end of each interval so LPAR cfg is only read once each interval + * even if proc_lparcfg() is called multiple times + * Note: lparcfg is not read via proc_read() ! + */ +int lparcfg_processed = 0; + +struct { + char version_string[16]; /*lparcfg 1.3 */ + int version; + char serial_number[16]; /*HAL,0210033EA */ + char system_type[64]; /*HAL,9124-720 */ + /* new record is "IBM pSeries (emulated by qemu)" instead of "IBM 9119-MME" */ + int partition_id; /*11 */ +/* +R4=0x14 +R5=0x0 +R6=0x800b0000 +R7=0x1000000040004 +*/ + int BoundThrds; /*=1*/ + int CapInc; /*=1*/ + long long DisWheRotPer; /*=2070000*/ + int MinEntCap; /*=10*/ + int MinEntCapPerVP; /*=10*/ + int MinMem; /*=2048*/ + int DesMem; /*=4096*/ + int MinProcs; /*=1*/ + int partition_max_entitled_capacity;/*=400*/ + int system_potential_processors; /*=4*/ + /**/ int partition_entitled_capacity; + /*=20*/ + int system_active_processors; /*=4*/ + int pool_capacity; /*=4*/ + int unallocated_capacity_weight; /*=0*/ + int capacity_weight; /*=0*/ + int capped; /*=1*/ + int unallocated_capacity; /*=0*/ + long long pool_idle_time; /*=0*/ + long long pool_idle_saved; + long long pool_idle_diff; + int pool_num_procs; /*=0*/ + long long purr; /*=0*/ + long long purr_saved; + long long purr_diff; + long long timebase; + int partition_active_processors; /*=1*/ + int partition_potential_processors; /*=40*/ + int shared_processor_mode; /*=1*/ + int smt_mode; /* 1: off, 2: SMT-2, 4: SMT-4 */ + int cmo_enabled; /* 1 means AMS is Active */ + int entitled_memory_pool_number; /* pool number = 0 */ + int entitled_memory_weight; /* 0 to 255 */ + long cmo_faults; /* Hypervisor Page-in faults = big number */ + long cmo_faults_save; /* above saved */ + long cmo_faults_diff; /* delta */ + long cmo_fault_time_usec; /* Hypervisor time in micro seconds = big */ + long cmo_fault_time_usec_save; /* above saved */ + long cmo_fault_time_usec_diff; /* delta */ + long backing_memory; /* AIX pmem in bytes */ + long cmo_page_size; /* AMS page size in bytes */ + long entitled_memory_pool_size; /* AMS whole pool size in bytes */ + long entitled_memory_loan_request; /* AMS requesting more memory loaning */ + + long DedDonMode; +#ifdef EXPERIMENTAL +/* new data in SLES11 for POWER 2.6.27 (may be a little earlier too) */ + long DesEntCap; + long DesProcs; + long DesVarCapWt; + long group; + long pool; + long entitled_memory; + long entitled_memory_group_number; + long unallocated_entitled_memory_weight; + long unallocated_io_mapping_entitlement; +/* new data in SLES11 for POWER 2.6.27 */ +#endif /* EXPERIMENTAL */ + +} lparcfg; + +int lpar_count = 0; + +#define LPAR_LINE_MAX 100 /* MAGIC COOKIE WARNING */ +#define LPAR_LINE_WIDTH 80 +char lpar_buffer[LPAR_LINE_MAX][LPAR_LINE_WIDTH]; + +int lpar_sanity = 55; + +char *locate(char *s) +{ + int i; + int len; + len = strlen(s); + for (i = 0; i < lpar_count; i++) + if (!strncmp(s, lpar_buffer[i], len)) + return lpar_buffer[i]; + return ""; +} + +#define NUMBER_NOT_VALID -999 + +long long read_longlong(char *s) +{ + long long x; + int ret; + int len; + int i; + char *str; + str = locate(s); + len = strlen(str); + if (len == 0) { + return NUMBER_NOT_VALID; + } + for (i = 0; i < len; i++) { + if (str[i] == '=') { + ret = sscanf(&str[i + 1], "%lld", &x); + if (ret != 1) { + fprintf(stderr, + "sscanf for %s failed returned = %d line=%s\n", s, + ret, str); + return -1; + } +/* fprintf(fp,"DEBUG read %s value %lld\n",s,x);*/ + return x; + } + } + fprintf(stderr, "read_long_long failed returned line=%s\n", str); + return -2; +} + + +/* Return of 0 means data not available */ +int proc_lparcfg() +{ + static FILE *fp = (FILE *) - 1; +/* Only try to read /proc/ppc64/lparcfg once - remember if it's readable */ + static int lparinfo_not_available = 0; + int i; + char *str; + /* If we already read and processed /proc/lparcfg in this interval - just return */ + if (lparcfg_processed == 1) + return 1; + + if (lparinfo_not_available == 1) + return 0; + + if (fp == (FILE *) - 1) { + if ((fp = fopen("/proc/ppc64/lparcfg", "r")) == NULL) { + error("failed to open - /proc/ppc64/lparcfg"); + fp = (FILE *) - 1; + lparinfo_not_available = 1; + if (power_vm_type == VM_UNKNOWN) { + /* Heuristics for spotting PowerKVM Host + a) inside ifdef POWER so can't be x86 + b) /proc/ppc64/lparcfg is missing + c) /etc/ *ease files have hints + Confirmed true for IBM_POWERKVM 2.1 + */ + if (strncmp("IBM_PowerKVM", easy[1], 12) == 0) + power_vm_type = VM_POWERKVM_HOST; + else + power_vm_type = VM_NATIVE; + } + return 0; + } + } + + for (lpar_count = 0; lpar_count < LPAR_LINE_MAX - 1; lpar_count++) { + if (fgets(lpar_buffer[lpar_count], LPAR_LINE_WIDTH - 1, fp) == + NULL) + break; + } + if (lparcfg_reread) { /* XXXX unclear if close+open is necessary - unfortunately this requires version many of Linux on POWER install to test early releases */ + fclose(fp); + fp = (FILE *) - 1; + } else + rewind(fp); + + str = locate("lparcfg"); + sscanf(str, "lparcfg %s", lparcfg.version_string); + str = locate("serial_number"); + sscanf(str, "serial_number=%s", lparcfg.serial_number); + str = locate("system_type"); + for (i = 0; i < strlen(str); i++) /* Remove new spaces in massive string meaning PowerKVM Guest !! */ + if (str[i] == ' ') + str[i] = '-'; + sscanf(str, "system_type=%s", lparcfg.system_type); + if (power_vm_type == VM_UNKNOWN) { + /* Heuristics for spotting PowerKVM Guest + a) inside ifdef POWER so can't be x86 + b) we have a /proc/ppc64/lparcfg - probably mostly missing (1.9) + c) system type string includes "qemu" + Confirmed true for SLES11.3 RHEL6.5 and Ubuntu 14.4.1 + */ + if (strstr(lparcfg.system_type, "(emulated-by-qemu)") == 0) + power_vm_type = VM_POWERVM; /* not found */ + else + power_vm_type = VM_POWERKVM_GUEST; + } +#define GETDATA(variable) lparcfg.variable = read_longlong( __STRING(variable) ); + + GETDATA(partition_id); + GETDATA(BoundThrds); + GETDATA(CapInc); + GETDATA(DisWheRotPer); + GETDATA(MinEntCap); + GETDATA(MinEntCapPerVP); + GETDATA(MinMem); + GETDATA(DesMem); + GETDATA(MinProcs); + GETDATA(partition_max_entitled_capacity); + GETDATA(system_potential_processors); + GETDATA(partition_entitled_capacity); + GETDATA(system_active_processors); + GETDATA(pool_capacity); + GETDATA(unallocated_capacity_weight); + GETDATA(capacity_weight); + GETDATA(capped); + GETDATA(unallocated_capacity); + lparcfg.pool_idle_saved = lparcfg.pool_idle_time; + GETDATA(pool_idle_time); + lparcfg.pool_idle_diff = + lparcfg.pool_idle_time - lparcfg.pool_idle_saved; + GETDATA(pool_num_procs); + lparcfg.purr_saved = lparcfg.purr; + GETDATA(purr); + lparcfg.purr_diff = lparcfg.purr - lparcfg.purr_saved; + GETDATA(partition_active_processors); + GETDATA(partition_potential_processors); + GETDATA(shared_processor_mode); + /* Brute force, may provide temporary incorrect data during + * dynamic reconfiguraiton envents + */ + lparcfg.smt_mode = cpus / lparcfg.partition_active_processors; + + /* AMS additions */ + GETDATA(cmo_enabled); + if (lparcfg.cmo_enabled == NUMBER_NOT_VALID) { + lparcfg.cmo_enabled = 0; + } + if (lparcfg.cmo_enabled) { + GETDATA(entitled_memory_pool_number); /* pool number = 0 */ + GETDATA(entitled_memory_weight); /* 0 to 255 */ + + lparcfg.cmo_faults_save = lparcfg.cmo_faults; + GETDATA(cmo_faults); /* Hypervisor Page-in faults = big number */ + lparcfg.cmo_faults_diff = + lparcfg.cmo_faults - lparcfg.cmo_faults_save; + + lparcfg.cmo_fault_time_usec_save = lparcfg.cmo_fault_time_usec; + GETDATA(cmo_fault_time_usec); /* Hypervisor time in micro seconds = big number */ + lparcfg.cmo_fault_time_usec_diff = + lparcfg.cmo_fault_time_usec - lparcfg.cmo_fault_time_usec_save; + + GETDATA(backing_memory); /* AIX pmem in bytes */ + GETDATA(cmo_page_size); /* AMS page size in bytes */ + GETDATA(entitled_memory_pool_size); /* AMS whole pool size in bytes */ + GETDATA(entitled_memory_loan_request); /* AMS requesting more memory loaning */ + + } + GETDATA(DedDonMode); +#ifdef EXPERIMENTAL + GETDATA(DesEntCap); + GETDATA(DesProcs); + GETDATA(DesVarCapWt); + GETDATA(group); + GETDATA(pool); + GETDATA(entitled_memory); + GETDATA(entitled_memory_group_number); + GETDATA(unallocated_entitled_memory_weight); + GETDATA(unallocated_io_mapping_entitlement); +#endif /* EXPERIMENTAL */ + + lparcfg_processed = 1; + return 1; +} +#endif /*POWER*/ +#define DISKMIN 256 +#define DISKMAX diskmax +int diskmax = DISKMIN; + +/* Supports up to 780, but not POWER6 595 follow-up with POWER7 */ +/* XXXX needs rework to cope to with fairly rare but interesting higher numbers of CPU machines */ +#define CPUMAX (192 * 8) /* MAGIC COOKIE WARNING */ + +struct data { + struct dsk_stat *dk; + struct cpu_stat cpu_total; + struct cpu_stat cpuN[CPUMAX]; + struct mem_stat mem; + struct vm_stat vm; + struct nfs_stat nfs; + struct net_stat ifnets[NETMAX]; +#ifdef PARTITIONS + struct part_stat parts[PARTMAX]; +#endif /*PARTITIONS*/ + struct timeval tv; + double time; + struct procsinfo *procs; + + int proc_records; + int processes; +} database[2], *p, *q; + + +long long get_vm_value(char *s) +{ + int currline; + int currchar; + long long result = -1; + char *check; + int len; + int found; + + for (currline = 0; currline < proc[P_VMSTAT].lines; currline++) { + len = strlen(s); + for (currchar = 0, found = 1; currchar < len; currchar++) { + if (proc[P_VMSTAT].line[currline][currchar] == 0 || + s[currchar] != proc[P_VMSTAT].line[currline][currchar]) { + found = 0; + break; + } + } + if (found && proc[P_VMSTAT].line[currline][currchar] == ' ') { + result = + strtoll(&proc[P_VMSTAT].line[currline][currchar + 1], + &check, 10); + if (*check == proc[P_VMSTAT].line[currline][currchar + 1]) { + fprintf(stderr, "%s has an unexpected format: >%s<\n", + proc[P_VMSTAT].filename, + proc[P_VMSTAT].line[currline]); + return -1; + } + return result; + } + } + return -1; +} + +#define GETVM(variable) p->vm.variable = get_vm_value(__STRING(variable) ); + +int read_vmstat() +{ + proc_read(P_VMSTAT); + if (proc[P_VMSTAT].read_this_interval == 0 + || proc[P_VMSTAT].lines == 0) + return (-1); + + /* Note: if the variable requested is not found in /proc/vmstat then it is set to -1 */ + GETVM(nr_dirty); + GETVM(nr_writeback); + GETVM(nr_unstable); + GETVM(nr_page_table_pages); + GETVM(nr_mapped); + if(p->vm.nr_slab != -1) + GETVM(nr_slab); + if(p->vm.nr_slab == -1) { + GETVM(nr_slab_reclaimable); + GETVM(nr_slab_unreclaimable); + } + GETVM(pgpgin); + GETVM(pgpgout); + GETVM(pswpin); + GETVM(pswpout); + GETVM(pgalloc_high); + GETVM(pgalloc_normal); + GETVM(pgalloc_dma); + GETVM(pgfree); + GETVM(pgactivate); + GETVM(pgdeactivate); + GETVM(pgfault); + GETVM(pgmajfault); + GETVM(pgrefill_high); + GETVM(pgrefill_normal); + GETVM(pgrefill_dma); + GETVM(pgsteal_high); + GETVM(pgsteal_normal); + GETVM(pgsteal_dma); + GETVM(pgscan_kswapd_high); + GETVM(pgscan_kswapd_normal); + GETVM(pgscan_kswapd_dma); + GETVM(pgscan_direct_high); + GETVM(pgscan_direct_normal); + GETVM(pgscan_direct_dma); + GETVM(pginodesteal); + GETVM(slabs_scanned); + GETVM(kswapd_steal); + GETVM(kswapd_inodesteal); + GETVM(pageoutrun); + GETVM(allocstall); + GETVM(pgrotated); + return 1; +} + + +/* These macro simplify the access to the Main data structure */ +#define DKDELTA(member) ( (q->dk[i].member > p->dk[i].member) ? 0 : (p->dk[i].member - q->dk[i].member)) +#define SIDELTA(member) ( (q->si.member > p->si.member) ? 0 : (p->si.member - q->si.member)) + +#define IFNAME 64 + +#define TIMEDELTA(member,index1,index2) ((p->procs[index1].member) - (q->procs[index2].member)) +#define IODELTA(member,index1,index2) ( (q->procs[index2].member > p->procs[index1].member) ? 0 : (p->procs[index1].member - q->procs[index2].member) ) +#define COUNTDELTA(member) ( (q->procs[topper[j].other].member > p->procs[i].member) ? 0 : (p->procs[i].member - q->procs[topper[j].other].member) ) + +#define TIMED(member) ((double)(p->procs[i].member.tv_sec)) + +double *cpu_peak; /* ptr to array - 1 for each cpu - 0 = average for machine */ +double *disk_busy_peak; +double *disk_rate_peak; +double net_read_peak[NETMAX]; +double net_write_peak[NETMAX]; +int aiorunning; +int aiorunning_max = 0; +int aiocount; +int aiocount_max = 0; +float aiotime; +float aiotime_max = 0.0; + +char *dskgrp(int i) +{ + static char error_string[] = { "Too-Many-Disks" }; + static char *string[16] = { "", "1", "2", "3", + "4", "5", "6", "7", + "8", "9", "10", "11", + "12", "13", "14", "15" + }; + + i = (int) ((float) i / (float) disks_per_line); + if (0 <= i && i <= 15) + return string[i]; + return error_string; +} + +/* command checking against a list */ + +#define CMDMAX 64 + +char *cmdlist[CMDMAX]; +int cmdfound = 0; + +int cmdcheck(char *cmd) +{ + int i; +#ifdef CMDDEBUG + fprintf(stderr, "cmdfound=%d\n", cmdfound); + for (i = 0; i < cmdfound; i++) + fprintf(stderr, "cmdlist[%d]=\"%s\"\n", i, cmdlist[i]); +#endif /* CMDDEBUG */ + for (i = 0; i < cmdfound; i++) { + if (strlen(cmdlist[i]) == 0) + continue; + if (!strncmp(cmdlist[i], cmd, strlen(cmdlist[i]))) + return 1; + } + return 0; +} + +/* Convert secs + micro secs to a double */ +double doubletime(void) +{ + + gettimeofday(&p->tv, 0); + return ((double) p->tv.tv_sec + p->tv.tv_usec * 1.0e-6); +} + +void get_cpu_cnt() +{ + int i; + + /* Get CPU info from /proc/stat and populate proc[P_STAT] */ + proc_read(P_STAT); + + /* Start with index [1] as [0] contains overall CPU statistics */ + for (i = 1; i < proc[P_STAT].lines; i++) { + if (strncmp("cpu", proc[P_STAT].line[i], 3) == 0) + cpus = i; + else + break; + } + if (cpus > CPUMAX) { + printf + ("This nmon supports only %d CPU threads (Logical CPUs) and the machine appears to have %d.\nnmon stopping as its unsafe to continue.\n", + CPUMAX, cpus); + exit(44); + } +} + +#if X86 || ARM +void get_intel_spec() +{ + int i; + int physicalcpu[256]; + int id; + + /* Get CPU info from /proc/stat and populate proc[P_STAT] */ + proc_read(P_CPUINFO); + + for (i = 0; i < 256; i++) + physicalcpu[i] = 0; + + for (i = 0; i < proc[P_CPUINFO].lines; i++) { + if (strncmp("vendor_id", proc[P_CPUINFO].line[i], 9) == 0) { + vendor_ptr = &proc[P_CPUINFO].line[i][12]; + } + } + for (i = 0; i < proc[P_CPUINFO].lines; i++) { + if (strncmp("model name", proc[P_CPUINFO].line[i], 10) == 0) { + model_ptr = &proc[P_CPUINFO].line[i][13]; + } + } + for (i = 0; i < proc[P_CPUINFO].lines; i++) { + if (strncmp("cpu MHz", proc[P_CPUINFO].line[i], 7) == 0) { + mhz_ptr = &proc[P_CPUINFO].line[i][11]; + } + } + for (i = 0; i < proc[P_CPUINFO].lines; i++) { + if((strncmp("bogomips", proc[P_CPUINFO].line[i], 8) == 0) || + (strncmp("bogoMIPS", proc[P_CPUINFO].line[i], 8) == 0) || + (strncmp("BogoMIPS", proc[P_CPUINFO].line[i], 8) == 0)){ + bogo_ptr = &proc[P_CPUINFO].line[i][11]; + } + } + + for (i = 0; i < proc[P_CPUINFO].lines; i++) { + if (strncmp("physical id", proc[P_CPUINFO].line[i], 11) == 0) { + id = atoi(&proc[P_CPUINFO].line[i][14]); + if (id < 256) + physicalcpu[id] = 1; + } + } + for (i = 0; i < 256; i++) + if (physicalcpu[i] == 1) + processorchips++; + + /* Start with index [1] as [0] contains overall CPU statistics */ + for (i = 0; i < proc[P_CPUINFO].lines; i++) { + if (strncmp("siblings", proc[P_CPUINFO].line[i], 8) == 0) { + siblings = atoi(&proc[P_CPUINFO].line[i][11]); + break; + } + } + for (i = 0; i < proc[P_CPUINFO].lines; i++) { + if (strncmp("cpu cores", proc[P_CPUINFO].line[i], 9) == 0) { + cores = atoi(&proc[P_CPUINFO].line[i][12]); + break; + } + } + if (siblings > cores) + hyperthreads = siblings / cores; + else + hyperthreads = 0; +} +#endif + +int stat8 = 0; /* used to determine the number of variables on a cpu line in /proc/stat */ +int stat10 = 0; /* used to determine the number of variables on a cpu line in /proc/stat */ + + +void proc_cpu() +{ + int i; + int row; + static int intr_line = 0; + static int ctxt_line = 0; + static int btime_line = 0; + static int proc_line = 0; + static int run_line = 0; + static int block_line = 0; + static int proc_cpu_first_time = 1; + long long user; + long long nice; + long long sys; + long long idle; + long long iowait; + long long hardirq; + long long softirq; + long long steal; + long long guest; + long long guest_nice; + + /* Only read data once per interval */ + if (proc_cpu_done == 1) + return; + + /* If number of CPUs changed, then we need to find the index of intr_line, ... again */ + if (old_cpus != cpus) + intr_line = 0; + + if (proc_cpu_first_time) { + stat8 = + sscanf(&proc[P_STAT].line[0][5], + "%lld %lld %lld %lld %lld %lld %lld %lld", &user, &nice, + &sys, &idle, &iowait, &hardirq, &softirq, &steal); + stat10 = + sscanf(&proc[P_STAT].line[0][5], + "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld", + &user, &nice, &sys, &idle, &iowait, &hardirq, &softirq, + &steal, &guest, &guest_nice); + proc_cpu_first_time = 0; + } + user = nice = sys = idle = iowait = hardirq = softirq = steal = guest = + guest_nice = 0; + if (stat10 == 10) { + sscanf(&proc[P_STAT].line[0][5], + "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld", &user, + &nice, &sys, &idle, &iowait, &hardirq, &softirq, &steal, + &guest, &guest_nice); + } else { + if (stat8 == 8) { + sscanf(&proc[P_STAT].line[0][5], + "%lld %lld %lld %lld %lld %lld %lld %lld", &user, &nice, + &sys, &idle, &iowait, &hardirq, &softirq, &steal); + } else { /* stat 4 variables here as older Linux proc */ + sscanf(&proc[P_STAT].line[0][5], "%lld %lld %lld %lld", + &user, &nice, &sys, &idle); + } + } + p->cpu_total.user = user; + p->cpu_total.nice = nice; + p->cpu_total.idle = idle; + p->cpu_total.sys = sys; + p->cpu_total.wait = iowait; /* in the case of 4 variables = 0 */ + /* p->cpu_total.sys = sys + hardirq + softirq + steal; */ + + p->cpu_total.irq = hardirq; + p->cpu_total.softirq = softirq; + p->cpu_total.steal = steal; + p->cpu_total.guest = guest; + p->cpu_total.guest_nice = guest_nice; + +#ifdef DEBUG + if (debug) + fprintf(stderr, "XX user=%lld wait=%lld sys=%lld idle=%lld\n", + p->cpu_total.user, + p->cpu_total.wait, p->cpu_total.sys, p->cpu_total.idle); +#endif /*DEBUG*/ + for (i = 0; i < cpus; i++) { + user = nice = sys = idle = iowait = hardirq = softirq = steal = 0; + + /* allow for large CPU numbers */ + if (i + 1 > 1000) + row = 8; + else if (i + 1 > 100) + row = 7; + else if (i + 1 > 10) + row = 6; + else + row = 5; + + if (stat10 == 10) { + sscanf(&proc[P_STAT].line[i + 1][row], + "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld", + &user, + &nice, + &sys, + &idle, + &iowait, + &hardirq, &softirq, &steal, &guest, &guest_nice); + + } else if (stat8 == 8) { + sscanf(&proc[P_STAT].line[i + 1][row], + "%lld %lld %lld %lld %lld %lld %lld %lld", + &user, + &nice, + &sys, &idle, &iowait, &hardirq, &softirq, &steal); + } else { + sscanf(&proc[P_STAT].line[i + 1][row], "%lld %lld %lld %lld", + &user, &nice, &sys, &idle); + } + p->cpuN[i].user = user; + p->cpuN[i].nice = nice; + p->cpuN[i].sys = sys; + p->cpuN[i].idle = idle; + p->cpuN[i].wait = iowait; + p->cpuN[i].irq = hardirq; + p->cpuN[i].softirq = softirq; + p->cpuN[i].steal = steal; + p->cpuN[i].guest = guest; + p->cpuN[i].guest_nice = guest_nice; + } + + if (intr_line == 0) { + if (proc[P_STAT].line[i + 1][0] == 'p' && + proc[P_STAT].line[i + 1][1] == 'a' && + proc[P_STAT].line[i + 1][2] == 'g' && + proc[P_STAT].line[i + 1][3] == 'e') { + /* 2.4 kernel */ + intr_line = i + 3; + ctxt_line = i + 5; + btime_line = i + 6; + proc_line = i + 7; + run_line = i + 8; + block_line = i + 9; + } else { + /* 2.6 kernel */ + intr_line = i + 1; + ctxt_line = i + 2; + btime_line = i + 3; + proc_line = i + 4; + run_line = i + 5; + block_line = i + 6; + } + } + p->cpu_total.intr = -1; + p->cpu_total.ctxt = -1; + p->cpu_total.procs = -1; + p->cpu_total.running = -1; + p->cpu_total.blocked = -1; + if (proc[P_STAT].lines >= intr_line) + sscanf(&proc[P_STAT].line[intr_line][0], "intr %lld", + &p->cpu_total.intr); + if (proc[P_STAT].lines >= ctxt_line) + sscanf(&proc[P_STAT].line[ctxt_line][0], "ctxt %lld", + &p->cpu_total.ctxt); + if(boottime == 0) { + struct tm ts; + if (proc[P_STAT].lines >= btime_line) + sscanf(&proc[P_STAT].line[btime_line][0], "btime %lld", &boottime); + ts = *localtime((time_t *)&boottime); + strftime (boottime_str, 64, "%I:%M %p %d-%b-%Y", &ts); + } + if (proc[P_STAT].lines >= proc_line) + sscanf(&proc[P_STAT].line[proc_line][0], "processes %lld", + &p->cpu_total.procs); + if (proc[P_STAT].lines >= run_line) + sscanf(&proc[P_STAT].line[run_line][0], "procs_running %lld", + &p->cpu_total.running); + if (proc[P_STAT].lines >= block_line) + sscanf(&proc[P_STAT].line[block_line][0], "procs_blocked %lld", + &p->cpu_total.blocked); + + /* If we had a change in the number of CPUs, copy current interval data to the previous, so we + * get a "0" utilization interval, but better than negative or 100%. + * Heads-up - This effects POWER SMT changes too. + */ + if (old_cpus != cpus) { + memcpy((void *) &(q->cpu_total), (void *) &(p->cpu_total), + sizeof(struct cpu_stat)); + memcpy((void *) q->cpuN, (void *) p->cpuN, + sizeof(struct cpu_stat) * cpus); + } + + /* Flag that we processed /proc/stat data; re-set in proc_read() when we re-read /proc/stat */ + proc_cpu_done = 1; +} + +void proc_nfs() +{ + int i; + int j; + int len; + int lineno; + +/* sample /proc/net/rpc/nfs +net 0 0 0 0 +rpc 70137 0 0 +proc2 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +proc3 22 0 27364 0 32 828 22 40668 0 1 0 0 0 0 0 0 0 0 1212 6 2 1 0 +proc4 35 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +*/ + if (proc[P_NFS].fp != 0) { + for (lineno = 0; lineno < proc[P_NFS].lines; lineno++) { + if (!strncmp("proc2 ", proc[P_NFS].line[lineno], 6)) { + /* client version 2 line readers "proc2 18 num num etc" */ + len = strlen(proc[P_NFS].line[lineno]); + for (j = 0, i = 8; i < len && j < NFS_V2_NAMES_COUNT; i++) { + if (proc[P_NFS].line[lineno][i] == ' ') { + p->nfs.v2c[j] = + atol(&proc[P_NFS].line[lineno][i + 1]); + nfs_v2c_found = 1; + j++; + } + } + } + if (!strncmp("proc3 ", proc[P_NFS].line[lineno], 6)) { + /* client version 3 line readers "proc3 22 num num etc" */ + len = strlen(proc[P_NFS].line[lineno]); + for (j = 0, i = 8; i < len && j < NFS_V3_NAMES_COUNT; i++) { + if (proc[P_NFS].line[lineno][i] == ' ') { + p->nfs.v3c[j] = + atol(&proc[P_NFS].line[lineno][i + 1]); + nfs_v3c_found = 1; + j++; + } + } + } + if (!strncmp("proc4 ", proc[P_NFS].line[lineno], 6)) { + /* client version 4 line readers "proc4 35 num num etc" */ + nfs_v4c_names_count = atoi(&proc[P_NFS].line[lineno][6]); + len = strlen(proc[P_NFS].line[lineno]); + for (j = 0, i = 8; i < len && j < nfs_v4c_names_count; i++) { + if (proc[P_NFS].line[lineno][i] == ' ') { + p->nfs.v4c[j] = + atol(&proc[P_NFS].line[lineno][i + 1]); + nfs_v4c_found = 1; + j++; + } + } + } + } + } +/* sample /proc/net/rpc/nfsd +rc 0 0 0 +fh 0 0 0 0 0 +io 0 0 +th 4 0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 +ra 32 0 0 0 0 0 0 0 0 0 0 0 +net 0 0 0 0 +rpc 0 0 0 0 0 +proc2 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +proc3 22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +proc4 2 0 0 +proc4ops 40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +*/ + if (proc[P_NFSD].fp != 0) { + for (lineno = 0; lineno < proc[P_NFSD].lines; lineno++) { + if (!strncmp("proc2 ", proc[P_NFSD].line[lineno], 6)) { + /* server version 2 line readers "proc2 18 num num etc" */ + len = strlen(proc[P_NFSD].line[lineno]); + for (j = 0, i = 8; i < len && j < NFS_V2_NAMES_COUNT; i++) { + if (proc[P_NFSD].line[lineno][i] == ' ') { + p->nfs.v2s[j] = + atol(&proc[P_NFSD].line[lineno][i + 1]); + nfs_v2s_found = 1; + j++; + } + } + } + if (!strncmp("proc3 ", proc[P_NFSD].line[lineno], 6)) { + /* server version 3 line readers "proc3 22 num num etc" */ + len = strlen(proc[P_NFSD].line[lineno]); + for (j = 0, i = 8; i < len && j < NFS_V2_NAMES_COUNT; i++) { + if (proc[P_NFSD].line[lineno][i] == ' ') { + p->nfs.v3s[j] = + atol(&proc[P_NFSD].line[lineno][i + 1]); + nfs_v3s_found = 1; + j++; + } + } + } + if (!strncmp("proc4ops ", proc[P_NFSD].line[lineno], 9)) { + /* server version 4 line readers "proc4ops 40 num num etc" + NOTE: the "ops" hence starting in column 9 */ + nfs_v4s_names_count = atol(&proc[P_NFSD].line[lineno][9]); + len = strlen(proc[P_NFSD].line[lineno]); + for (j = 0, i = 11; i < len && j < nfs_v4s_names_count; + i++) { + if (proc[P_NFSD].line[lineno][i] == ' ') { + p->nfs.v4s[j] = + atol(&proc[P_NFSD].line[lineno][i + 1]); + nfs_v4s_found = 1; + j++; + } + } + } + } + } +} + +void proc_kernel() +{ + int i; + p->cpu_total.uptime = 0.0; + p->cpu_total.idletime = 0.0; + p->cpu_total.uptime = atof(proc[P_UPTIME].line[0]); + for (i = 0; i < strlen(proc[P_UPTIME].line[0]); i++) { + if (proc[P_UPTIME].line[0][i] == ' ') { + p->cpu_total.idletime = atof(&proc[P_UPTIME].line[0][i + 1]); + break; + } + } + + sscanf(&proc[P_LOADAVG].line[0][0], "%f %f %f", + &p->cpu_total.mins1, &p->cpu_total.mins5, &p->cpu_total.mins15); + +} + +char *proc_find_sb(char *p) +{ + for (; *p != 0; p++) + if (*p == ' ' && *(p + 1) == '(') + return p; + return 0; +} + +#define DISK_MODE_IO 1 +#define DISK_MODE_DISKSTATS 2 +#define DISK_MODE_PARTITIONS 3 + +int disk_mode = 0; + +void proc_disk_io(double elapsed) +{ + int diskline; + int i; + int ret; + char *str; + int fudged_busy; + + disks = 0; + for (diskline = 0; diskline < proc[P_STAT].lines; diskline++) { + if (strncmp("disk_io", proc[P_STAT].line[diskline], 7) == 0) + break; + } + for (i = 8; i < strlen(proc[P_STAT].line[diskline]); i++) { + if (proc[P_STAT].line[diskline][i] == ':') + disks++; + } + + str = &proc[P_STAT].line[diskline][0]; + for (i = 0; i < disks; i++) { + str = proc_find_sb(str); + if (str == 0) + break; + ret = sscanf(str, " (%d,%d):(%ld,%ld,%ld,%ld,%ld", + &p->dk[i].dk_major, + &p->dk[i].dk_minor, + &p->dk[i].dk_noinfo, + &p->dk[i].dk_reads, + &p->dk[i].dk_rkb, + &p->dk[i].dk_writes, &p->dk[i].dk_wkb); + if (ret != 7) + exit(7); + p->dk[i].dk_xfers = p->dk[i].dk_noinfo; + /* blocks are 512 bytes */ + p->dk[i].dk_rkb = p->dk[i].dk_rkb / 2; + p->dk[i].dk_wkb = p->dk[i].dk_wkb / 2; + + p->dk[i].dk_bsize = + (p->dk[i].dk_rkb + p->dk[i].dk_wkb) / p->dk[i].dk_xfers * 1024; + + /* assume a disk does 200 op per second */ + fudged_busy = (p->dk[i].dk_reads + p->dk[i].dk_writes) / 2; + if (fudged_busy > 100 * elapsed) + p->dk[i].dk_time += 100 * elapsed; + p->dk[i].dk_time = fudged_busy; + + snprintf(p->dk[i].dk_name, 32, "dev-%d-%d", p->dk[i].dk_major, + p->dk[i].dk_minor); +/* fprintf(stderr,"disk=%d name=\"%s\" major=%d minor=%d\n", i,p->dk[i].dk_name, p->dk[i].dk_major,p->dk[i].dk_minor); */ + str++; + } +} + +void proc_diskstats(double elapsed) +{ + static FILE *fp = (FILE *) - 1; + char buf[1024]; + int i; + int ret; + + if (fp == (FILE *) - 1) { + if ((fp = fopen("/proc/diskstats", "r")) == NULL) { + /* DEBUG if( (fp = fopen("diskstats","r")) == NULL) { */ + error("failed to open - /proc/diskstats"); + disks = 0; + return; + } + } +/* + 2 0 fd0 1 0 2 13491 0 0 0 0 0 13491 13491 + 3 0 hda 41159 53633 1102978 620181 39342 67538 857108 4042631 0 289150 4668250 + 3 1 hda1 58209 58218 0 0 + 3 2 hda2 148 4794 10 20 + 3 3 hda3 65 520 0 0 + 3 4 hda4 35943 1036092 107136 857088 + 22 0 hdc 167 5394 22308 32250 0 0 0 0 0 22671 32250 <-- USB !! + 8 0 sda 990 2325 4764 6860 9 3 12 417 0 6003 7277 + 8 1 sda1 3264 4356 12 12 +*/ + for (i = 0; i < DISKMAX;) { + if (fgets(buf, 1024, fp) == NULL) + break; + /* zero the data ready for reading */ + p->dk[i].dk_major = + p->dk[i].dk_minor = + p->dk[i].dk_name[0] = + p->dk[i].dk_reads = + p->dk[i].dk_rmerge = + p->dk[i].dk_rkb = + p->dk[i].dk_rmsec = + p->dk[i].dk_writes = + p->dk[i].dk_wmerge = + p->dk[i].dk_wkb = + p->dk[i].dk_wmsec = + p->dk[i].dk_inflight = + p->dk[i].dk_time = p->dk[i].dk_backlog = 0; + + ret = + sscanf(&buf[0], + "%d %d %s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", + &p->dk[i].dk_major, &p->dk[i].dk_minor, + &p->dk[i].dk_name[0], &p->dk[i].dk_reads, + &p->dk[i].dk_rmerge, &p->dk[i].dk_rkb, + &p->dk[i].dk_rmsec, &p->dk[i].dk_writes, + &p->dk[i].dk_wmerge, &p->dk[i].dk_wkb, + &p->dk[i].dk_wmsec, &p->dk[i].dk_inflight, + &p->dk[i].dk_time, &p->dk[i].dk_backlog); + if (ret == 7) { /* shuffle the data around due to missing columns for partitions */ + p->dk[i].dk_partition = 1; + p->dk[i].dk_wkb = p->dk[i].dk_rmsec; + p->dk[i].dk_writes = p->dk[i].dk_rkb; + p->dk[i].dk_rkb = p->dk[i].dk_rmerge; + p->dk[i].dk_rmsec = 0; + p->dk[i].dk_rmerge = 0; + + } else if (ret == 14) + p->dk[i].dk_partition = 0; + else + fprintf(stderr, + "disk sscanf wanted 14 but returned=%d line=%s\n", ret, + buf); + + p->dk[i].dk_rkb /= 2; /* sectors = 512 bytes */ + p->dk[i].dk_wkb /= 2; + p->dk[i].dk_xfers = p->dk[i].dk_reads + p->dk[i].dk_writes; + if (p->dk[i].dk_xfers == 0) + p->dk[i].dk_bsize = 0; + else + p->dk[i].dk_bsize = + ((p->dk[i].dk_rkb + + p->dk[i].dk_wkb) / p->dk[i].dk_xfers) * 1024; + + p->dk[i].dk_time /= 10.0; /* in milli-seconds to make it upto 100%, 1000/100 = 10 */ + + if (p->dk[i].dk_xfers > 0) + i++; + } + if (reread) { + fclose(fp); + fp = (FILE *) - 1; + } else + rewind(fp); + disks = i; +} + +void strip_spaces(char *s) +{ + char *p; + int spaced = 1; + + p = s; + for (p = s; *p != 0; p++) { + if (*p == ':') + *p = ' '; + if (*p != ' ') { + *s = *p; + s++; + spaced = 0; + } else if (spaced) { + /* do no thing as this is second space */ + } else { + *s = *p; + s++; + spaced = 1; + } + + } + *s = 0; +} + +void proc_partitions(double elapsed) +{ + static FILE *fp = (FILE *) - 1; + char buf[1024]; + int i = 0; + int ret; + + if (fp == (FILE *) - 1) { + if ((fp = fopen("/proc/partitions", "r")) == NULL) { + error("failed to open - /proc/partitions"); + partitions = 0; + return; + } + } + if (fgets(buf, 1024, fp) == NULL) + goto end; /* throw away the header lines */ + if (fgets(buf, 1024, fp) == NULL) + goto end; +/* +major minor #blocks name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq + + 33 0 1052352 hde 2855 15 2890 4760 0 0 0 0 -4 7902400 11345292 + 33 1 1050304 hde1 2850 0 2850 3930 0 0 0 0 0 3930 3930 + 3 0 39070080 hda 9287 19942 226517 90620 8434 25707 235554 425790 -12 7954830 33997658 + 3 1 31744408 hda1 651 90 5297 2030 0 0 0 0 0 2030 2030 + 3 2 6138720 hda2 7808 19561 218922 79430 7299 20529 222872 241980 0 59950 321410 + 3 3 771120 hda3 13 41 168 80 0 0 0 0 0 80 80 + 3 4 1 hda4 0 0 0 0 0 0 0 0 0 0 0 + 3 5 408208 hda5 812 241 2106 9040 1135 5178 12682 183810 0 11230 192850 +*/ + for (i = 0; i < DISKMAX; i++) { + if (fgets(buf, 1024, fp) == NULL) + break; + strip_spaces(buf); + ret = + sscanf(&buf[0], + "%d %d %lu %s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", + &p->dk[i].dk_major, &p->dk[i].dk_minor, + &p->dk[i].dk_blocks, (char *) &p->dk[i].dk_name, + &p->dk[i].dk_reads, &p->dk[i].dk_rmerge, + &p->dk[i].dk_rkb, &p->dk[i].dk_rmsec, + &p->dk[i].dk_writes, &p->dk[i].dk_wmerge, + &p->dk[i].dk_wkb, &p->dk[i].dk_wmsec, + &p->dk[i].dk_inflight, &p->dk[i].dk_use, + &p->dk[i].dk_aveq); + p->dk[i].dk_rkb /= 2; /* sectors = 512 bytes */ + p->dk[i].dk_wkb /= 2; + p->dk[i].dk_xfers = p->dk[i].dk_rkb + p->dk[i].dk_wkb; + if (p->dk[i].dk_xfers == 0) + p->dk[i].dk_bsize = 0; + else + p->dk[i].dk_bsize = + (p->dk[i].dk_rkb + + p->dk[i].dk_wkb) / p->dk[i].dk_xfers * 1024; + + p->dk[i].dk_time /= 10.0; /* in milli-seconds to make it upto 100%, 1000/100 = 10 */ + + if (ret != 15) { +#ifdef DEBUG + if (debug) + fprintf(stderr, "sscanf wanted 15 returned = %d line=%s\n", + ret, buf); +#endif /*DEBUG*/ + partitions_short = 1; + } else + partitions_short = 0; + } + end: + if (reread) { + fclose(fp); + fp = (FILE *) - 1; + } else + rewind(fp); + disks = i; +} + +void proc_disk(double elapsed) +{ + struct stat buf; + int ret; + if (disk_mode == 0) { + ret = stat("/proc/diskstats", &buf); + if (ret == 0) { + disk_mode = DISK_MODE_DISKSTATS; + } else { + ret = stat("/proc/partitions", &buf); + if (ret == 0) { + disk_mode = DISK_MODE_PARTITIONS; + } else { + disk_mode = DISK_MODE_IO; + } + } + } + switch (disk_mode) { + case DISK_MODE_IO: + proc_disk_io(elapsed); + break; + case DISK_MODE_DISKSTATS: + proc_diskstats(elapsed); + break; + case DISK_MODE_PARTITIONS: + proc_partitions(elapsed); + break; + } +} + +#undef isdigit +#define isdigit(ch) ( ( '0' <= (ch) && (ch) >= '9')? 0: 1 ) + +long proc_mem_search(char *s) +{ + int i; + int j; + int len; + len = strlen(s); + for (i = 0; i < proc[P_MEMINFO].lines; i++) { + if (!strncmp(s, proc[P_MEMINFO].line[i], len)) { + for (j = len; + !isdigit(proc[P_MEMINFO].line[i][j]) && + proc[P_MEMINFO].line[i][j] != 0; j++) + /* do nothing */ ; + return atol(&proc[P_MEMINFO].line[i][j]); + } + } + return -1; +} + +void proc_mem() +{ + if (proc[P_MEMINFO].read_this_interval == 0) + proc_read(P_MEMINFO); + + p->mem.memtotal = proc_mem_search("MemTotal"); + p->mem.memfree = proc_mem_search("MemFree"); + p->mem.memshared = proc_mem_search("MemShared"); + /* memshared was renamed (pointlessly) Sheme and includes RAM disks in later kernels */ + if(p->mem.memshared <= 0) + p->mem.memshared = proc_mem_search("Shmem"); + + p->mem.buffers = proc_mem_search("Buffers"); + p->mem.cached = proc_mem_search("Cached"); + p->mem.swapcached = proc_mem_search("SwapCached"); + p->mem.active = proc_mem_search("Active"); + p->mem.inactive = proc_mem_search("Inactive"); + p->mem.hightotal = proc_mem_search("HighTotal"); + p->mem.highfree = proc_mem_search("HighFree"); + p->mem.lowtotal = proc_mem_search("LowTotal"); + p->mem.lowfree = proc_mem_search("LowFree"); + p->mem.swaptotal = proc_mem_search("SwapTotal"); + p->mem.swapfree = proc_mem_search("SwapFree"); +#ifndef SMALLMEM + p->mem.dirty = proc_mem_search("Dirty"); + p->mem.writeback = proc_mem_search("Writeback"); + p->mem.mapped = proc_mem_search("Mapped"); + p->mem.slab = proc_mem_search("Slab"); + p->mem.committed_as = proc_mem_search("Committed_AS"); + p->mem.pagetables = proc_mem_search("PageTables"); + p->mem.hugetotal = proc_mem_search("HugePages_Total"); + p->mem.hugefree = proc_mem_search("HugePages_Free"); + p->mem.hugesize = proc_mem_search("Hugepagesize"); +#else + p->mem.bigfree = proc_mem_search("BigFree"); +#endif /*SMALLMEM*/ +} + +#define MAX_SNAPS 72 +#define MAX_SNAP_ROWS 20 +#define SNAP_OFFSET 6 + +int next_cpu_snap = 0; +int cpu_snap_all = 0; + +struct { + double user; + double kernel; + double iowait; + double idle; + double steal; +} cpu_snap[MAX_SNAPS]; + +int snap_average() +{ + int i; + int end; + int total = 0; + + if (cpu_snap_all) + end = MAX_SNAPS; + else + end = next_cpu_snap; + + for (i = 0; i < end; i++) { + total = total + cpu_snap[i].user + cpu_snap[i].kernel; + } + return (total / end); +} + +void snap_clear() +{ + int i; + for (i = 0; i < MAX_SNAPS; i++) { + cpu_snap[i].user = 0; + cpu_snap[i].kernel = 0; + cpu_snap[i].iowait = 0; + cpu_snap[i].idle = 0; + cpu_snap[i].steal = 0; + } + next_cpu_snap = 0; + cpu_snap_all = 0; +} + +void plot_snap(WINDOW * pad) +{ + int i; + int j; + double k; + if (cursed) { + mvwprintw(pad, 0, 0, + " CPU +---Long-Term-------------------------------------------------------------+"); + mvwprintw(pad, 1, 0, "100%%-|"); + mvwprintw(pad, 2, 1, "95%%-|"); + mvwprintw(pad, 3, 1, "90%%-|"); + mvwprintw(pad, 4, 1, "85%%-|"); + mvwprintw(pad, 5, 1, "80%%-|"); + mvwprintw(pad, 6, 1, "75%%-|"); + mvwprintw(pad, 7, 1, "70%%-|"); + mvwprintw(pad, 8, 1, "65%%-|"); + mvwprintw(pad, 9, 1, "60%%-|"); + mvwprintw(pad, 10, 1, "55%%-|"); + mvwprintw(pad, 11, 1, "50%%-|"); + mvwprintw(pad, 12, 1, "45%%-|"); + mvwprintw(pad, 13, 1, "40%%-|"); + mvwprintw(pad, 14, 1, "35%%-|"); + mvwprintw(pad, 15, 1, "30%%-|"); + mvwprintw(pad, 16, 1, "25%%-|"); + mvwprintw(pad, 17, 1, "20%%-|"); + mvwprintw(pad, 18, 1, "15%%-|"); + mvwprintw(pad, 19, 1, "10%%-|"); + mvwprintw(pad, 20, 1, " 5%%-|"); + + mvwprintw(pad, 21, 4, + " +-------------------------------------------------------------------------+"); + if (colour) { + COLOUR wattrset(pad, COLOR_PAIR(2)); + mvwprintw(pad, 0, 26, "User%%"); + COLOUR wattrset(pad, COLOR_PAIR(1)); + mvwprintw(pad, 0, 36, "System%%"); + COLOUR wattrset(pad, COLOR_PAIR(4)); + mvwprintw(pad, 0, 49, "Wait%%"); + COLOUR wattrset(pad, COLOR_PAIR(5)); + mvwprintw(pad, 0, 59, "Steal%%"); + COLOUR wattrset(pad, COLOR_PAIR(0)); + } + + for (j = 0; j < MAX_SNAPS; j++) { + for (i = 0; i < MAX_SNAP_ROWS; i++) { + wmove(pad, MAX_SNAP_ROWS - i, j + SNAP_OFFSET); + if (cpu_snap[j].user + cpu_snap[j].kernel + cpu_snap[j].iowait + cpu_snap[j].idle + cpu_snap[j].steal == 0) { /* if not all zeros */ + COLOUR wattrset(pad, COLOR_PAIR(0)); + wprintw(pad, " "); + } else if ((cpu_snap[j].user / 100 * MAX_SNAP_ROWS) > + i + 0.5) { + COLOUR wattrset(pad, COLOR_PAIR(9)); + wprintw(pad, "U"); + } else if ((cpu_snap[j].user + cpu_snap[j].kernel) / 100 * + MAX_SNAP_ROWS > i + 0.5) { + COLOUR wattrset(pad, COLOR_PAIR(8)); + wprintw(pad, "s"); + } else + if ((cpu_snap[j].user + cpu_snap[j].kernel + + cpu_snap[j].iowait) / 100 * MAX_SNAP_ROWS > + i + 0.5) { + COLOUR wattrset(pad, COLOR_PAIR(10)); + wprintw(pad, "w"); + } else if ((cpu_snap[j].user + cpu_snap[j].kernel + cpu_snap[j].iowait + cpu_snap[j].idle) / 100 * MAX_SNAP_ROWS > i) { /*no +0.5 or too few Steal's */ + COLOUR wattrset(pad, COLOR_PAIR(0)); + wprintw(pad, " "); + } else if (cpu_snap[j].user + cpu_snap[j].kernel + cpu_snap[j].iowait + cpu_snap[j].idle + cpu_snap[j].steal > i) { /* if not all zeros */ + COLOUR wattrset(pad, COLOR_PAIR(5)); + wprintw(pad, "S"); + } + } + k = cpu_snap[j].user + cpu_snap[j].kernel + cpu_snap[j].iowait; + if (0.1 < k && k < 5.0) { /* not zero but less than 5% */ + wmove(pad, MAX_SNAP_ROWS, j + SNAP_OFFSET); + COLOUR wattrset(pad, COLOR_PAIR(2)); + wprintw(pad, "_"); + } + } + COLOUR wattrset(pad, COLOR_PAIR(0)); + for (i = 0; i < MAX_SNAP_ROWS; i++) { + wmove(pad, MAX_SNAP_ROWS - i, next_cpu_snap + SNAP_OFFSET); + wprintw(pad, "|"); + } + wmove(pad, MAX_SNAP_ROWS + 1 - (snap_average() / 5), + next_cpu_snap + SNAP_OFFSET); + wprintw(pad, "+"); + if (dotline) { + for (i = 0; i < MAX_SNAPS; i++) { + wmove(pad, MAX_SNAP_ROWS + 1 - dotline * 2, + i + SNAP_OFFSET); + wprintw(pad, "+"); + } + dotline = 0; + } + } +} + +/* This saves the CPU overall usage for later ploting on the screen */ +void save_snap(double user, double kernel, double iowait, double idle, + double steal) +{ + cpu_snap[next_cpu_snap].user = user; + cpu_snap[next_cpu_snap].kernel = kernel; + cpu_snap[next_cpu_snap].iowait = iowait; + cpu_snap[next_cpu_snap].idle = idle; + cpu_snap[next_cpu_snap].steal = steal; + next_cpu_snap++; + if (next_cpu_snap >= MAX_SNAPS) { + next_cpu_snap = 0; + cpu_snap_all = 1; + } +} + +void plot_smp(WINDOW * pad, int cpu_no, int row, double user, + double kernel, double iowait, double idle, double steal) +{ + int i; + int peak_col; + + if (show_rrd) + return; + + if (cpu_peak[cpu_no] < (user + kernel + iowait)) + cpu_peak[cpu_no] = + (double) ((int) user / 2 + (int) kernel / 2 + + (int) iowait / 2) * 2.0; + + if (cursed) { + if (cpu_no == 0) + mvwprintw(pad, row, 0, "Avg"); + else + mvwprintw(pad, row, 0, "%3d", cpu_no); + mvwprintw(pad, row, 3, "% 6.1lf", user); + mvwprintw(pad, row, 9, "% 6.1lf", kernel); + mvwprintw(pad, row, 15, "% 6.1lf", iowait); + if (steal) { + mvwprintw(pad, row, 21, "% 6.1lf", steal); + } else { + mvwprintw(pad, row, 21, "% 6.1lf", idle); + } + mvwprintw(pad, row, 27, "|"); + wmove(pad, row, 28); + for (i = 0; i < (int) (user / 2); i++) { + COLOUR wattrset(pad, COLOR_PAIR(9)); + wprintw(pad, "U"); + } + for (i = 0; i < (int) (kernel / 2); i++) { + COLOUR wattrset(pad, COLOR_PAIR(8)); + wprintw(pad, "s"); + } + for (i = 0; i < (int) (iowait / 2); i++) { + COLOUR wattrset(pad, COLOR_PAIR(10)); + wprintw(pad, "W"); + } + COLOUR wattrset(pad, COLOR_PAIR(0)); + for (i = 0; i <= (int) (idle / 2); i++) { /* added "=" to try to conteract missing halves */ +#ifdef POWER + if (lparcfg.smt_mode > 1 + && ((cpu_no - 1) % lparcfg.smt_mode) == 0 && (i % 2)) + wprintw(pad, "."); + else +#endif + wprintw(pad, " "); + } + for (i = 0; i < (int) ((steal + 1) / 2); i++) { + COLOUR wattrset(pad, COLOR_PAIR(5)); + wprintw(pad, "S"); + } + COLOUR wattrset(pad, COLOR_PAIR(0)); + mvwprintw(pad, row, 77, "| "); + + peak_col = 28 + (int) (cpu_peak[cpu_no] / 2); + if (peak_col > 77) + peak_col = 77; + mvwprintw(pad, row, peak_col, ">"); + } else { + /* Sanity check the numnbers */ + if (user < 0.0 || kernel < 0.0 || iowait < 0.0 || idle < 0.0 + || idle > 100.0 || steal < 0) { + user = kernel = iowait = idle = steal = 0; + } + + if (first_steal && steal > 0) { + fprintf(fp, "AAA,steal,1\n"); + first_steal = 0; + } + if (cpu_no == 0) + fprintf(fp, "CPU_ALL,%s,%.1lf,%.1lf,%.1lf,%.1f,%.1lf,,%d\n", + LOOP, user, kernel, iowait, idle, steal, cpus); + else { + fprintf(fp, "CPU%03d,%s,%.1lf,%.1lf,%.1lf,%.1lf,%.1f\n", + cpu_no, LOOP, user, kernel, iowait, idle, steal); + } + } +} + +/* Added variable to remember started children + * 0 - start + * 1 - snap + * 2 - end +*/ +#define CHLD_START 0 +#define CHLD_SNAP 1 +#define CHLD_END 2 +int nmon_children[3] = { -1, -1, -1 }; + +void init_pairs() +{ + COLOUR init_pair((short) 0, (short) 7, (short) 0); /* White */ + COLOUR init_pair((short) 1, (short) 1, (short) 0); /* Red */ + COLOUR init_pair((short) 2, (short) 2, (short) 0); /* Green */ + COLOUR init_pair((short) 3, (short) 3, (short) 0); /* Yellow */ + COLOUR init_pair((short) 4, (short) 4, (short) 0); /* Blue */ + COLOUR init_pair((short) 5, (short) 5, (short) 0); /* Magenta */ + COLOUR init_pair((short) 6, (short) 6, (short) 0); /* Cyan */ + COLOUR init_pair((short) 7, (short) 7, (short) 0); /* White */ + COLOUR init_pair((short) 8, (short) 0, (short) 1); /* Red background, red text */ + COLOUR init_pair((short) 9, (short) 0, (short) 2); /* Green background, green text */ + COLOUR init_pair((short) 10, (short) 0, (short) 4); /* Blue background, blue text */ + COLOUR init_pair((short) 11, (short) 0, (short) 3); /* Yellow background, yellow text */ + COLOUR init_pair((short) 12, (short) 0, (short) 6); /* Cyan background, cyan text */ +} + +/* Signal handler + * SIGUSR1 or 2 is used to stop nmon cleanly + * SIGWINCH is used when the window size is changed + */ +void interrupt(int signum) +{ + int child_pid; + int waitstatus; + if (signum == SIGCHLD) { + while ((child_pid = waitpid(0, &waitstatus, 0)) == -1) { + if (errno == EINTR) /* retry */ + continue; + return; /* ECHLD, EFAULT */ + } + if (child_pid == nmon_children[CHLD_SNAP]) + nmon_children[CHLD_SNAP] = -1; + signal(SIGCHLD, interrupt); + return; + } + if (signum == SIGUSR1 || signum == SIGUSR2) { + maxloops = loop; + return; + } + if (signum == SIGWINCH) { + CURSE endwin(); /* stop + start curses so it works out the # of row and cols */ + CURSE initscr(); + CURSE cbreak(); + signal(SIGWINCH, interrupt); + COLOUR colour = has_colors(); + COLOUR start_color(); + COLOUR init_pairs(); + CURSE clear(); + return; + } + CURSE endwin(); + exit(0); +} + + +/* only place the q=previous and p=currect pointers are modified */ +void switcher(void) +{ + static int which = 1; + int i; + + if (which) { + p = &database[0]; + q = &database[1]; + which = 0; + } else { + p = &database[1]; + q = &database[0]; + which = 1; + } + if (flash_on) + flash_on = 0; + else + flash_on = 1; + + /* Reset flags so /proc/... is re-read in next interval */ + for (i = 0; i < P_NUMBER; i++) { + proc[i].read_this_interval = 0; + } +#ifdef POWER + lparcfg_processed = 0; +#endif +} + + +/* Lookup the right string */ +char *status(int n) +{ + switch (n) { + case 0: + return "Run "; + default: + return "Sleep"; + } +} + +/* Lookup the right process state string */ +char *get_state(char n) +{ + static char duff[64]; + switch (n) { + case 'R': + return "Running "; + case 'S': + return "Sleeping "; + case 'D': + return "DiskSleep"; + case 'Z': + return "Zombie "; + case 'T': + return "Traced "; + case 'W': + return "Paging "; + default: + snprintf(duff, 64, "%d", n); + return duff; + } +} + +/* User Defined Disk Groups */ +char *save_word(char *in, char *out) +{ + int len; + int i; + len = strlen(in); + out[0] = 0; + for (i = 0; i < len; i++) { + if (isalnum(in[i]) || in[i] == '_' || in[i] == '-' || in[i] == '/') { + out[i] = in[i]; + out[i + 1] = 0; + } else + break; + } + for (; i < len; i++) + if (isalnum(in[i])) + return &in[i]; + return &in[i]; +} + +#define DGROUPS 64 +#define DGROUPITEMS 512 + +char *dgroup_filename; +char *dgroup_name[DGROUPS]; +int *dgroup_data; +int dgroup_disks[DGROUPS]; +int dgroup_total_disks = 0; +int dgroup_total_groups; + +void load_dgroup(struct dsk_stat *dk) +{ + FILE *gp; + char line[4096]; + char name[1024]; + int i, j; + char *nextp; + + if (dgroup_loaded == 2) + return; + dgroup_data = MALLOC(sizeof(int) * DGROUPS * DGROUPITEMS); + for (i = 0; i < DGROUPS; i++) + for (j = 0; j < DGROUPITEMS; j++) + dgroup_data[i * DGROUPITEMS + j] = -1; + + gp = fopen(dgroup_filename, "r"); + + if (gp == NULL) { + perror("opening disk group file"); + fprintf(stderr, "ERROR: failed to open %s\n", dgroup_filename); + exit(9); + } + + for (dgroup_total_groups = 0; + fgets(line, 4096 - 1, gp) != NULL + && dgroup_total_groups < DGROUPS; dgroup_total_groups++) { + /* ignore lines starting with # */ + if (line[0] == '#') { /* was a comment line */ + /* Decrement dgroup_total_groups by 1 to correct index for next loop */ + --dgroup_total_groups; + continue; + } + /* save the name */ + nextp = save_word(line, name); + if (strlen(name) == 0) { /* was a blank line */ + fprintf(stderr, + "ERROR nmon:ignoring odd line in diskgroup file \"%s\"\n", + line); + /* Decrement dgroup_total_groups by 1 to correct index for next loop */ + --dgroup_total_groups; + continue; + } + /* Added +1 to be able to correctly store the terminating \0 character */ + dgroup_name[dgroup_total_groups] = MALLOC(strlen(name) + 1); + strcpy(dgroup_name[dgroup_total_groups], name); + + /* save the hdisks */ + for (i = 0; i < DGROUPITEMS && *nextp != 0; i++) { + nextp = save_word(nextp, name); + for (j = 0; j < disks; j++) { + if (strcmp(dk[j].dk_name, name) == 0) { + /*DEBUG printf("DGadd group=%s,name=%s,disk=%s,dgroup_total_groups=%d,dgroup_total_disks=%d,j=%d,i=%d,index=%d.\n", + dgroup_name[dgroup_total_groups], + name, dk[j].dk_name, dgroup_total_groups, dgroup_total_disks, j, i,dgroup_total_groups*DGROUPITEMS+i); + */ + dgroup_data[dgroup_total_groups * DGROUPITEMS + i] = j; + dgroup_disks[dgroup_total_groups]++; + dgroup_total_disks++; + break; + } + } + if (j == disks) + fprintf(stderr, + "ERROR nmon:diskgroup file - failed to find disk=%s for group=%s disks known=%d\n", + name, dgroup_name[dgroup_total_groups], disks); + } + } + fclose(gp); + dgroup_loaded = 2; +} + + +void list_dgroup(struct dsk_stat *dk) +{ + int i, j, k, n; + int first = 1; + + /* DEBUG for (n = 0, i = 0; i < dgroup_total_groups; i++) { + fprintf(fp, "CCCG,%03d,%s", n++, dgroup_name[i]); + for (j = 0; j < dgroup_disks[i]; j++) { + if (dgroup_data[i*DGROUPITEMS+j] != -1) { + fprintf(fp, ",%d=%d", j, dgroup_data[i*DGROUPITEMS+j]); + } + } + fprintf(fp, "\n"); + } + */ + if (!show_dgroup) + return; + + for (n = 0, i = 0; i < dgroup_total_groups; i++) { + if (first) { + fprintf(fp, "BBBG,%03d,User Defined Disk Groups Name,Disks\n", + n++); + first = 0; + } + fprintf(fp, "BBBG,%03d,%s", n++, dgroup_name[i]); + for (k = 0, j = 0; j < dgroup_disks[i]; j++) { + if (dgroup_data[i * DGROUPITEMS + j] != -1) { + fprintf(fp, ",%s", + dk[dgroup_data[i * DGROUPITEMS + j]].dk_name); + k++; + } + /* add extra line if we have lots to stop spreadsheet line width problems */ + if (k == 128) { + fprintf(fp, "\nBBBG,%03d,%s continued", n++, + dgroup_name[i]); + } + } + fprintf(fp, "\n"); + } + fprintf(fp, "DGBUSY,Disk Group Busy %s", hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "DGREAD,Disk Group Read KB/s %s", hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "DGWRITE,Disk Group Write KB/s %s", hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "DGSIZE,Disk Group Block Size KB %s", hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "DGXFER,Disk Group Transfers/s %s", hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + + /* If requested provide additional data available in /proc/diskstats */ + if (extended_disk == 1 && disk_mode == DISK_MODE_DISKSTATS) { + fprintf(fp, "DGREADS,Disk Group read/s %s", hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "DGREADMERGE,Disk Group merged read/s %s", hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "DGREADSERV,Disk Group read service time (SUM ms) %s", + hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "DGWRITES,Disk Group write/s %s", hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "DGWRITEMERGE,Disk Group merged write/s %s", hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + fprintf(fp, + "DGWRITESERV,Disk Group write service time (SUM ms) %s", + hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "DGINFLIGHT,Disk Group in flight IO %s", hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + fprintf(fp, "DGBACKLOG,Disk Group Backlog time (ms) %s", hostname); + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] != 0) + fprintf(fp, ",%s", dgroup_name[i]); + } + fprintf(fp, "\n"); + } +} + +int is_dgroup_name(char *name) +{ + int i; + for (i = 0; i < DGROUPS; i++) { + if (dgroup_name[i] == (char *) 0) + return 0; + if (strncmp(name, dgroup_name[i], strlen(name)) == 0) + return 1; + } + return 0; +} + + + +void hint(void) +{ + printf("Hint for %s version %s\n", progname, VERSION); + printf("\tFull Help Info : %s -h\n\n", progname); + printf("\tOn-screen Stats: %s\n", progname); + printf + ("\tData Collection: %s -f [-s ] [-c ] [-t|-T]\n", + progname); + printf("\tCapacity Plan : %s -x\n", progname); + printf("Interactive-Mode:\n"); + printf + ("\tRead the Welcome screen & at any time type: \"h\" for more help\n"); + printf("\tType \"q\" to exit nmon\n\n"); + printf("For Data-Collect-Mode\n"); + printf + ("\t-f Must be the first option on the line (switches off interactive mode)\n"); + printf + ("\t Saves data to a CSV Spreadsheet format .nmon file in then local directory\n"); + printf + ("\t Note: -f sets a defaults -s300 -c288 which you can then modify\n"); + printf("\tFurther Data Collection Options:\n"); + printf("\t-s time between data snapshots\n"); + printf("\t-c of snapshots before exiting\n"); + printf + ("\t-t Includes Top Processes stats (-T also collects command arguments)\n"); + printf + ("\t-x Capacity Planning=15 min snapshots for 1 day. (nmon -ft -s 900 -c 96)\n"); + printf("---- End of Hints\n"); +} + +void help(void) +{ + hint(); + printf("---- Full Help Information for %s\n\n", SccsId); + printf("For Interactive and Data Collection Mode:\n"); + printf("\tUser Defined Disk Groups (DG) - This works in both modes\n"); + printf ("\tIt is a work around Linux issues, where disks & partitions are mixed up in /proc files\n"); + printf ("\t& drive driver developers use bizarre device names, making it trick to separate them.\n"); + printf("\t-g Use this file to define the groups\n"); + printf ("\t - On each line: group-name (space separated list)\n"); + printf("\t - Example line: database sdb sdc sdd sde\n"); + printf("\t - Up to 64 disk groups, 512 disks per line\n"); + printf ("\t - Disks names can appear more than one group\n"); + printf ("\t-g auto - Will generate a file called \"auto\" with just disks from \"lsblk|grep disk\" output\n"); + printf("\t For Interactive use define the groups then type: g or G\n"); + printf ("\t For Data Capture defining the groups switches on data collection\n"); + printf("\n"); + printf ("Data-Collect-Mode = spreadsheet format (i.e. comma separated values)\n"); + printf ("\tNote: Use only one of f, F, R, x, X or z to switch on Data Collection mode\n"); + printf ("\tNote: Make it the first argument then use other options to modify the defaults\n"); + printf ("\tNote: Don't collect data that you don't want - it just makes the files too large\n"); + printf ("\tNote: Too many snapshots = too much data and crashes Analyser and other tools\n"); + printf ("\tNote: 500 to 800 snapshots make a good graph on a normal size screen\n"); + printf ("\tRecommended normal minimal options: snapshots every 2 minutes all day: \n"); + printf("\t\tSimple capture: nmon -f -s 120 -c 720\n"); + printf("\t\tWith Top Procs: nmon -fT -s 120 -c 720\n"); + printf ("\t\tSet the directory: nmon -fT -s 120 -c 720 -m /home/nag/nmon\n"); + printf + ("\t\tCapture a busy hour: nmon -fT -s 5 -c 720 -m /home/nag/nmon\n"); + printf("\n"); + printf("For Data-Collect-Mode Options\n"); + printf + ("\t-f spreadsheet output format [note: default -s300 -c288]\n"); + printf("\t\t\t output file is _YYYYMMDD_HHMM.nmon\n"); + printf("\t-F same as -f but user supplied filename\n"); + printf("\t\t\t Not recommended as the default file name is perfect\n"); + printf("\tThe other options in alphabetical order:\n"); + printf("\t-a Include Accelerator GPU stats\n"); + printf + ("\t-b Online only: for black and white mode (switch off colour)\n"); + printf("\t-c The number of snapshots before nmon stops\n"); + printf + ("\t-d To set the maximum number of disks [default 256]\n"); + printf + ("\t Ignores disks if the systems has 100's of disk or the config is odd!\n"); + printf + ("\t-D Use with -g to add the Disk Wait/Service Time & in-flight stats\n"); + printf("\t-f and -F See above\n"); + printf + ("\t-g User Defined Disk Groups (see above) - Data Capture: Generates BBBG & DG lines\n"); + printf + ("\t-g auto See above but makes the file \"auto\" for you of just the disks like sda etc.\n"); + printf("\t-h This help output\n"); + printf + ("\t-I Set the ignore process & disks busy threshold (default 0.1%%)\n"); + printf + ("\t Don't save or show proc/disk using less than this percent\n"); + printf + ("\t-J Switch-off Journel Filesystem stats collection (can causes issues with automound NFS)\n"); + printf + ("\t-l Disks per line in data capture to avoid spreadsheet width issues. Default 150. EMC=64.\n"); + printf + ("\t-m nmon changes to this directory before saving to file\n"); + printf("\t Useful when starting nmon via cron\n"); + printf + ("\t-M Adds MHz stats for each CPU thread. Some POWER8 model CPU cores can be different frequencies\n"); + printf + ("\t-N Include NFS Network File System for V2, V3 and V4\n"); + printf + ("\t-p nmon outputs the PID when it starts. Useful in scripts to capture the PID for a later safe stop.\n"); + printf + ("\t-r Use in a benchmark to record the run details for later analysis [default hostname]\n"); + printf + ("\t-R Old rrdtool format used by some - may be removed in the future. If you use this email Nigel\n"); + printf + ("\t-s Time between snap shots - with \"-c count\" decides duration of the data capture\n"); + printf("\t-t Include Top Processes in the output\n"); + printf + ("\t-T As -t plus it saves command line arguments in UARG section\n"); + printf + ("\t-U Include the Linux 10 CPU utilisation stats (CPUUTIL lines in the file)\n"); + printf("\t-V Print nmon version & exit immediately\n"); + printf("\n"); + printf("\tTo manually load nmon files into a spreadsheet:\n"); + printf("\t\tsort -A *nmon >stats.csv\n"); + printf("\t\tTransfer the stats.csv file to your PC\n"); + printf + ("\t\tStart spreadsheet & then Open with type=comma-separated-value ASCII file\n"); + printf("\t\tThis puts every datum in a different cell\n"); + printf + ("\t\tNow select the data of one type (same 1st column) and graph it\n"); + printf + ("\t\tThe nmon Analyser & other tools do not need the file sorted.\n"); + printf("\n"); + printf("Capacity Planning mode - use cron to run each day\n"); + printf("\t-x Sensible spreadsheet output for one day\n"); + printf + ("\t Every 15 mins for 1 day ( i.e. -ft -s 900 -c 96)\n"); + printf("\t-X Sensible spreadsheet output for busy hour\n"); + printf + ("\t Every 30 secs for 1 hour ( i.e. -ft -s 30 -c 120)\n"); + printf + ("\t-z Like -x but the output saved in /var/perf/tmp assuming root user\n"); + printf("\n"); + + printf("Interactive Mode Keys in Alphabetical Order\n"); + printf + (" Start nmon then type the letters below to switch on & off particular stats\n"); + printf(" The stats are always in the same order on-screen\n"); + printf + (" To see more stats: make the font smaller or use two windows\n\n"); + printf("\tKey --- Toggles on off to control what is displayed ---\n"); +#ifdef NVIDIA_GPU + printf("\ta = Accelerator from Nvidia GPUs\n"); +#endif /*NVIDIA_GPU */ + printf + ("\tb = Black and white mode (or use -b command line option)\n"); + printf + ("\tc = CPU Utilisation stats with bar graphs (CPU core threads)\n"); + printf + ("\tC = CPU Utilisation as above but concise wide view (up to 192 CPUs)\n"); + printf("\td = Disk I/O Busy%% & Graphs of Read and Write KB/s\n"); + printf + ("\tD = Disk I/O Numbers including Transfers, Average Block Size & Peaks (type: 0 to reset)\n"); + printf + ("\tg = User Defined Disk Groups (assumes -g when starting nmon)\n"); + printf + ("\tG = Change Disk stats (d) to just disks (assumes -g auto when starting nmon)\n"); + printf("\th = This help information\n"); + printf("\tj = File Systems including Journal File Systems\n"); + printf("\tJ = Reduces \"j\" output by removing unreal File Systems\n"); + printf + ("\tk = Kernel stats Run Queue, context-switch, fork, Load Average & Uptime\n"); + printf + ("\tl = Long term Total CPU (over 75 snapshots) via bar graphs\n"); + printf("\tL = Large and =Huge memory page stats\n"); + printf("\tm = Memory & Swap stats\n"); + printf + ("\tM = MHz for machines with variable frequency 1st=Threads 2nd=Cores 3=Graphs\n"); + printf + ("\tn = Network stats & errors (if no errors it disappears)\n"); + printf("\tN = NFS - Network File System\n"); + printf("\t 1st NFS V2 & V3, 2nd=NFS4-Client & 3rd=NFS4-Server\n"); + printf + ("\to = Disk I/O Map (one character per disk pixels showing how busy it is)\n"); + printf("\t Particularly good if you have 100's of disks \n"); +#ifdef PARTITIONS + printf("\tP = Partitions Disk I/O Stats\n"); +#endif +#ifdef POWER + printf("\tp = PowerVM LPAR Stats from /proc/ppc64/lparcfg\n"); +#endif + printf("\tq = Quit\n"); + printf + ("\tr = Resources: Machine type, name, cache details & OS version & Distro + LPAR\n"); + printf + ("\tt = Top Processes: select the data & order 1=Basic, 3=Perf 4=Size 5=I/O=root only\n"); + printf("\tu = Top Process with command line details\n"); + printf("\tU = CPU utilisation stats - all 10 Linux stats:\n"); + printf + ("\t user, user_nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice\n"); + printf + ("\tv = Experimental Verbose mode - tries to make recommendations\n"); + printf("\tV = Virtual Memory stats\n"); + printf("\n"); + printf("\tKey --- Other Interactive Controls ---\n"); + printf("\t+ = Double the screen refresh time\n"); + printf("\t- = Halves the screen refresh time\n"); + printf + ("\t0 = Reset peak counts to zero (peak highlight with \">\")\n"); + printf("\t1 = Top Processes mode 1 Nice, Priority, Status\n"); + printf("\t3 = Top Processes mode 3 CPU, Memory, Faults\n"); + printf("\t4 = Top Processes mode 4 as 3 but order by memory\n"); + printf + ("\t5 = Top Processes mode 5 as 3 but order by I/O (if root user)\n"); + printf("\t6 = Highlights 60%% row on Long Term CPU view\n"); + printf("\t7 = Highlights 70%% row on Long Term CPU view\n"); + printf("\t8 = Highlights 80%% row on Long Term CPU view\n"); + printf("\t9 = Highlights 90%% row on Long Term CPU view\n"); + printf + ("\t. = Minimum mode i.e. only busy disks and processes shown\n"); + printf("\tspace = Refresh screen now\n"); + + printf("\n"); + printf("Interactive Start-up Control\n"); + printf + ("\tIf you find you always type the same toggles every time you start\n"); + printf("\tthen place them in the NMON shell variable. For example:\n"); + printf("\t export NMON=cmdrtn\n"); + + printf("\n"); + printf("Other items for Interactive and Data Collection mode:\n"); + printf + ("\ta) To limit the processes nmon lists (online and to a file)\n"); + printf + ("\t either set NMONCMD0 to NMONCMD63 to the program names\n"); + printf("\t or use -C cmd:cmd:cmd etc. example: -C ksh:vi:syncd\n"); + printf("Other items for Data Collection mode:\n"); + printf("\tb) To you want to stop nmon use: kill -USR2 \n"); + printf("\tc) Use -p and nmon outputs the background process pid\n"); + printf + ("\td) If you want to pipe nmon output to other commands use a FIFO:\n"); + printf("\t mkfifo /tmp/mypipe\n"); + printf("\t nmon -F /tmp/mypipe &\n"); + printf("\t tail -f /tmp/mypipe\n"); + printf("\te) If nmon fails please report it with:\n"); + printf("\t 1) nmon version like: %s\n", VERSION); + printf + ("\t 2) the output of: cd /proc; cat cpuinfo meminfo partitions stat vmstat\n"); + printf("\t 3) some clue of what you were doing\n"); + printf + ("\t 4) I may ask you to run the debug version or collect data files\n"); + printf + ("\tf) If box & line characters are letters then check: terminal emulator & $TERM\n"); + printf + ("\tg) External Data Collectors - nmon will execute a command or script at each snapshot time\n"); + printf + ("\t They must output to a different file which is merge afterwards with the nmon output\n"); + printf("\t Set the following shell variables:\n"); + printf + ("\t NMON_START = script to generate CVS Header test line explaining the columns\n"); + printf + ("\t Generate: TabName,DataDescription,Column_name_and_units,Column_name_and_units ... \n"); + printf + ("\t NMON_SNAP = script for each snapshots data, the parameter is the T0000 snapshot number\n"); + printf("\t Generate: TabName,T00NN,Data,Data,Data ...\n"); + printf + ("\t NMON_END = script to clean up or finalise the data\n"); + printf + ("\t NMON_ONE_IN = call NMON_START less often (if it is heavy in CPU terms)\n"); + printf + ("\t Once capture done: cat nmon-file data-file >merged-file ; ready for Analyser or other tools\n"); + printf + ("\t The nmon Analyser will automatically do its best to graph the data on a new Tab sheet\n"); + printf("\n"); + printf + ("\tDeveloper: Nigel Griffiths See http://nmon.sourceforge.net\n"); + printf("\tFeedback welcome - On the current release only\n"); + printf("\tNo warranty given or implied. (C) Copyright 2009 Nigel Griffiths GPLv3\n"); + exit(0); +} + +#define JFSMAX 128 +#define LOAD 1 +#define UNLOAD 0 +#define JFSNAMELEN 64 +#define JFSTYPELEN 8 + +struct jfs { + char name[JFSNAMELEN+1]; + char device[JFSNAMELEN+1]; + char type[JFSNAMELEN+1]; + int fd; + int mounted; +} jfs[JFSMAX]; + +int jfses = 0; +void jfs_load(int load) +{ + int i; + struct stat stat_buffer; + FILE *mfp; /* FILE pointer for mtab file */ + struct mntent *mp; /* mnt point stats */ + static int jfs_loaded = 0; + + if (load == LOAD) { + if (jfs_loaded == 0) { + mfp = setmntent("/etc/mtab", "r"); + for (i = 0; i < JFSMAX && (mp = getmntent(mfp)) != NULL; i++) { + strncpy(jfs[i].device, mp->mnt_fsname, JFSNAMELEN + 1); + strncpy(jfs[i].name, mp->mnt_dir, JFSNAMELEN + 1); + strncpy(jfs[i].type, mp->mnt_type, JFSTYPELEN + 1); + mp->mnt_fsname[JFSNAMELEN] = 0; + mp->mnt_dir[JFSNAMELEN] = 0; + mp->mnt_type[JFSTYPELEN] = 0; + } + endmntent(mfp); + jfs_loaded = 1; + jfses = i; + } + + /* 1st or later time - just reopen the mount points */ + for (jfses = 0, i = 0; i < JFSMAX && jfs[i].name[0] != 0; i++) { + if (stat(jfs[i].name, &stat_buffer) != -1) { + jfs[i].fd = open(jfs[i].name, O_RDONLY); + if (jfs[i].fd != -1) { + jfs[i].mounted = 1; + } else { + jfs[i].mounted = 0; + } + } else + jfs[i].mounted = 0; + } + for (jfses = 0, i = 0; i < JFSMAX && jfs[i].name[0] != 0; i++) { + if (jfs[i].mounted == 1) + jfses++; + } + } else { /* this is an unload request */ + if (jfs_loaded) { + for (i = 0; i < JFSMAX && jfs[i].name[0] != 0; i++) { + if (jfs[i].fd != 0) + close(jfs[i].fd); + jfs[i].fd = 0; + } + } + } +} + +/* We order this array rather than the actual process tables + * the index is the position in the process table and + * the size is the memory used in bytes + * the io is the storge I/O performed in the the last period in bytes + * the time is the CPU used in the last period in seconds + */ +struct topper { + int index; + int other; + double size; + double io; + int time; +} *topper; +int topper_size = 200; + +/* Routine used by qsort to order the processes by CPU usage */ +int cpu_compare(const void *a, const void *b) +{ + return (int) (((struct topper *) b)->time - + ((struct topper *) a)->time); +} + +int size_compare(const void *a, const void *b) +{ + return (int) ((((struct topper *) b)->size - + ((struct topper *) a)->size)); +} + +int disk_compare(const void *a, const void *b) +{ + return (int) ((((struct topper *) b)->io - ((struct topper *) a)->io)); +} + + +/* checkinput is the subroutine to handle user input */ +int checkinput(void) +{ + static int use_env = 1; + char buf[1024]; + int bytes; + int chars; + int i; + char *p; + + if (!cursed) /* not user input so stop with control-C */ + return 0; + ioctl(fileno(stdin), FIONREAD, &bytes); + + if (bytes > 0 || use_env) { + if (use_env) { + use_env = 0; + p = getenv("NMON"); + if (p != 0) { + strncpy(buf, p, 1024); + buf[1024 - 1] = 0; + chars = strlen(buf); + } else + chars = 0; + } else { + if(bytes > 1024) { /* block over flowing the buffer */ + bytes = 1023; + buf[1023]=0; + } + chars = read(fileno(stdin), buf, bytes); + } + if (chars > 0) { + welcome = 0; + for (i = 0; i < chars; i++) { + switch (buf[i]) { + case '1': + show_topmode = 1; + show_top = 1; + wclear(padtop); + break; +/* case '2': + show_topmode = 2; + show_top = 1; + clear(); + break; +*/ + case '3': + show_topmode = 3; + show_top = 1; + wclear(padtop); + break; + case '4': + show_topmode = 4; + show_top = 1; + wclear(padtop); + break; + case '5': + if (isroot) { + show_topmode = 5; + show_top = 1; + wclear(padtop); + } + break; + case '0': + for (i = 0; i < (max_cpus + 1); i++) + cpu_peak[i] = 0; + for (i = 0; i < networks; i++) { + net_read_peak[i] = 0.0; + net_write_peak[i] = 0.0; + } + for (i = 0; i < disks; i++) { + disk_busy_peak[i] = 0.0; + disk_rate_peak[i] = 0.0; + } + snap_clear(); + aiocount_max = 0; + aiotime_max = 0.0; + aiorunning_max = 0; + huge_peak = 0; + break; + case '6': + case '7': + case '8': + case '9': + dotline = buf[i] - '0'; + break; + case ' ': /* attempt to refresh the screen */ + clear(); + break; + case '+': + seconds = seconds * 2; + break; + case '-': + seconds = seconds / 2; + if (seconds < 1) + seconds = 1; + break; + case '.': /* limit output to processes and disks actually doing work */ + if (show_all) + show_all = 0; + else { + show_all = 1; +/* Switching to Nigel's favourite view is confusing to others + so disable this feature. + show_disk = SHOW_DISK_STATS; + show_top = 1; + show_topmode = 3; +*/ + } + wclear(paddisk); + break; + case '?': + case 'h': + case 'H': + if (show_help) + show_help = 0; + else { + show_help = 1; + show_verbose = 0; + } + wclear(padhelp); + break; +/* alphabetic order from here */ +#ifdef NVIDIA_GPU + case 'a': /* Accelerator */ + case 'E': /* Emily mode */ + FLIP(show_gpu); + wclear(padgpu); + break; +#endif /* NVIDIA_GPU */ + case 'b': + FLIP(colour); + clear(); + break; + case 'c': + FLIP(show_smp); + wclear(padsmp); + break; + case 'C': + FLIP(show_wide); + wclear(padwide); + break; + case 'D': + switch (show_disk) { + case SHOW_DISK_NONE: + show_disk = SHOW_DISK_STATS; + break; + case SHOW_DISK_STATS: + show_disk = SHOW_DISK_NONE; + break; + case SHOW_DISK_GRAPH: + show_disk = SHOW_DISK_STATS; + break; + } + wclear(paddisk); + break; + case 'd': + switch (show_disk) { + case SHOW_DISK_NONE: + show_disk = SHOW_DISK_GRAPH; + break; + case SHOW_DISK_STATS: + show_disk = SHOW_DISK_GRAPH; + break; + case SHOW_DISK_GRAPH: + show_disk = 0; + break; + } + wclear(paddisk); + break; + + break; + case 'G': + if (auto_dgroup) { + FLIP(disk_only_mode); + clear(); + } + break; + case 'g': + FLIP(show_dgroup); + wclear(paddg); + break; + + case 'j': + FLIP(show_jfs); + jfs_load(show_jfs); + wclear(padjfs); + break; + case 'J': + FLIP(show_jfs_minimum); + wclear(padjfs); + break; + case 'k': + FLIP(show_kernel); + wclear(padker); + break; + case 'l': + FLIP(show_longterm); + wclear(padlong); + break; + case 'L': + FLIP(show_large); + wclear(padlarge); + break; + case 'm': + FLIP(show_memory); + wclear(padmem); + break; + case 'M': + show_mhz++; + if (show_mhz == 4) + show_mhz = 0; + wclear(padmhz); + break; + case 'n': + if (show_net) { + show_net = 0; + show_neterror = 0; + } else { + show_net = 1; + show_neterror = 3; + } + wclear(padnet); + break; + case 'N': + if (show_nfs == 0) + show_nfs = 1; + else if (show_nfs == 1) + show_nfs = 2; + else if (show_nfs == 2) + show_nfs = 3; + else if (show_nfs == 3) + show_nfs = 0; + nfs_clear = 1; + wclear(padnfs); + break; + case 'o': + FLIP(show_diskmap); + wclear(padmap); + break; +#ifdef POWER + case 'p': + FLIP(show_lpar); + wclear(padlpar); + break; +#endif + case 'r': + FLIP(show_res); + wclear(padres); + break; + case 't': + show_topmode = 3; /* Fall Through */ + case 'T': + FLIP(show_top); + wclear(padtop); + break; + case 'v': + FLIP(show_verbose); + wclear(padverb); + break; + case 'u': + if (show_args == ARGS_NONE) { + args_load(); + show_args = ARGS_ONLY; + show_top = 1; + if (show_topmode != 3 && + show_topmode != 4 && show_topmode != 5) + show_topmode = 3; + } else + show_args = ARGS_NONE; + wclear(padtop); + break; + case 'U': + FLIP(show_util); + wclear(padutil); + break; + case 'V': + FLIP(show_vm); + wclear(padpage); + break; + case 'x': + case 'q': + nocbreak(); + endwin(); + exit(0); + default: + return 0; + } + } + return 1; + } + } + return 0; +} + +void go_background(int def_loops, int def_secs) +{ + cursed = 0; + if (maxloops == -1) + maxloops = def_loops; + if (seconds == -1) + seconds = def_secs; + show_res = 1; + show_smp = 1; + show_disk = SHOW_DISK_STATS; + show_jfs = 1; + show_memory = 1; + show_large = 1; + show_kernel = 1; + show_net = 1; + show_all = 1; + show_top = 0; /* top process */ + show_topmode = 3; + show_lpar = 1; + show_vm = 1; +} + +void proc_net() +{ + static FILE *fp = (FILE *) - 1; + char buf[1024]; + int i = 0; + int ret; + unsigned long junk; + + if (fp == (FILE *) - 1) { + if ((fp = fopen("/proc/net/dev", "r")) == NULL) { + error("failed to open - /proc/net/dev"); + networks = 0; + return; + } + } + if (fgets(buf, 1024, fp) == NULL) + goto end; /* throw away the header lines */ + if (fgets(buf, 1024, fp) == NULL) + goto end; /* throw away the header lines */ +/* +Inter-| Receive | Transmit + face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed + lo: 1956 30 0 0 0 0 0 0 1956 30 0 0 0 0 0 0 + eth0: 0 0 0 0 0 0 0 0 458718 0 781 0 0 0 781 0 + sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + eth1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +*/ + for (i = 0; i < NETMAX; i++) { + if (fgets(buf, 1024, fp) == NULL) + break; + strip_spaces(buf); + /* 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 */ + ret = + sscanf(&buf[0], + "%s %llu %llu %lu %lu %lu %lu %lu %lu %llu %llu %lu %lu %lu %lu %lu", + (char *) &p->ifnets[i].if_name, &p->ifnets[i].if_ibytes, + &p->ifnets[i].if_ipackets, &p->ifnets[i].if_ierrs, + &p->ifnets[i].if_idrop, &p->ifnets[i].if_ififo, + &p->ifnets[i].if_iframe, &junk, &junk, + &p->ifnets[i].if_obytes, &p->ifnets[i].if_opackets, + &p->ifnets[i].if_oerrs, &p->ifnets[i].if_odrop, + &p->ifnets[i].if_ofifo, &p->ifnets[i].if_ocolls, + &p->ifnets[i].if_ocarrier); + if (ret != 16) + fprintf(stderr, "sscanf wanted 16 returned = %d line=%s\n", + ret, (char *) buf); + } + end: + if (reread) { + fclose(fp); + fp = (FILE *) - 1; + } else + rewind(fp); + networks = i; +} + + +int proc_procsinfo(int pid, int index) +{ + FILE *fp; + char filename[64]; + char buf[1024 * 4]; + int size = 0; + int ret = 0; + int count = 0; + int i; + + snprintf(filename, 64, "/proc/%d/stat", pid); + if ((fp = fopen(filename, "r")) == NULL) { + snprintf(buf, 1024 * 4, "failed to open file %s", filename); + error(buf); + return 0; + } + size = fread(buf, 1, 1024 - 1, fp); + fclose(fp); + if (size == -1) { +#ifdef DEBUG + fprintf(stderr, + "procsinfo read returned = %d assuming process stopped pid=%d\n", + ret, pid); +#endif /*DEBUG*/ + return 0; + } + ret = sscanf(buf, "%d (%s)", + &p->procs[index].pi_pid, &p->procs[index].pi_comm[0]); + if (ret != 2) { + fprintf(stderr, "procsinfo sscanf returned = %d line=%s\n", ret, + buf); + return 0; + } + p->procs[index].pi_comm[strlen(p->procs[index].pi_comm) - 1] = 0; + + for (count = 0; count < size; count++) /* now look for ") " as dumb Infiniban driver includes "()" */ + if (buf[count] == ')' && buf[count + 1] == ' ') + break; + + if (count == size) { +#ifdef DEBUG + fprintf(stderr, "procsinfo failed to find end of command buf=%s\n", + buf); +#endif /*DEBUG*/ + return 0; + } + count++; + count++; + + ret = sscanf(&buf[count], +#ifdef PRE_KERNEL_2_6_18 + "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d", +#else + "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu", +#endif + &p->procs[index].pi_state, + &p->procs[index].pi_ppid, + &p->procs[index].pi_pgrp, + &p->procs[index].pi_session, + &p->procs[index].pi_tty_nr, + &p->procs[index].pi_tty_pgrp, + &p->procs[index].pi_flags, + &p->procs[index].pi_minflt, + &p->procs[index].pi_cmin_flt, + &p->procs[index].pi_majflt, + &p->procs[index].pi_cmaj_flt, + &p->procs[index].pi_utime, + &p->procs[index].pi_stime, + &p->procs[index].pi_cutime, + &p->procs[index].pi_cstime, + &p->procs[index].pi_pri, &p->procs[index].pi_nice, +#ifdef PRE_KERNEL_2_6_18 + &p->procs[index].junk, +#else + &p->procs[index].pi_num_threads, +#endif + &p->procs[index].pi_it_real_value, + &p->procs[index].pi_start_time, + &p->procs[index].pi_vsize, + &p->procs[index].pi_rss, + &p->procs[index].pi_rlim_cur, + &p->procs[index].pi_start_code, + &p->procs[index].pi_end_code, + &p->procs[index].pi_start_stack, + &p->procs[index].pi_esp, + &p->procs[index].pi_eip, + &p->procs[index].pi_pending_signal, + &p->procs[index].pi_blocked_sig, + &p->procs[index].pi_sigign, + &p->procs[index].pi_sigcatch, + &p->procs[index].pi_wchan, + &p->procs[index].pi_nswap, + &p->procs[index].pi_cnswap, + &p->procs[index].pi_exit_signal, &p->procs[index].pi_cpu +#ifndef PRE_KERNEL_2_6_18 + , + &p->procs[index].pi_rt_priority, + &p->procs[index].pi_policy, + &p->procs[index].pi_delayacct_blkio_ticks +#endif + ); +#ifdef PRE_KERNEL_2_6_18 + if (ret != 37) { + fprintf(stderr, + "procsinfo2 sscanf wanted 37 returned = %d pid=%d line=%s\n", + ret, pid, buf); +#else + if (ret != 40) { + fprintf(stderr, + "procsinfo2 sscanf wanted 40 returned = %d pid=%d line=%s\n", + ret, pid, buf); +#endif + return 0; + } + + snprintf(filename, 64, "/proc/%d/statm", pid); + if ((fp = fopen(filename, "r")) == NULL) { + snprintf(buf, 1024 * 4, "failed to open file %s", filename); + error(buf); + return 0; + } + size = fread(buf, 1, 1024 * 4 - 1, fp); + fclose(fp); /* close it even if the read failed, the file could have been removed + between open & read i.e. the device driver does not behave like a file */ + if (size == -1) { + snprintf(buf, 1024 * 4, "failed to read file %s", filename); + error(buf); + return 0; + } + + ret = sscanf(&buf[0], "%lu %lu %lu %lu %lu %lu %lu", + &p->procs[index].statm_size, + &p->procs[index].statm_resident, + &p->procs[index].statm_share, + &p->procs[index].statm_trs, + &p->procs[index].statm_lrs, + &p->procs[index].statm_drs, &p->procs[index].statm_dt); + if (ret != 7) { + fprintf(stderr, "sscanf wanted 7 returned = %d line=%s\n", ret, + buf); + return 0; + } + if (isroot) { + p->procs[index].read_io = 0; + p->procs[index].write_io = 0; + snprintf(filename, 64, "/proc/%d/io", pid); + if ((fp = fopen(filename, "r")) != NULL) { + for (i = 0; i < 6; i++) { + if (fgets(buf, 1024, fp) == NULL) { + break; + } + if (strncmp("read_bytes:", buf, 11) == 0) + sscanf(&buf[12], "%lld", &p->procs[index].read_io); + if (strncmp("write_bytes:", buf, 12) == 0) + sscanf(&buf[13], "%lld", &p->procs[index].write_io); + } + } + + if (fp != NULL) + fclose(fp); + } + return 1; +} + +#ifdef DEBUGPROC +print_procs(int index) +{ + printf("procs[%d].pid =%d\n", index, procs[index].pi_pid); + printf("procs[%d].comm[0] =%s\n", index, + &procs[index].pi_comm[0]); + printf("procs[%d].state =%c\n", index, procs[index].pi_state); + printf("procs[%d].ppid =%d\n", index, procs[index].pi_ppid); + printf("procs[%d].pgrp =%d\n", index, procs[index].pi_pgrp); + printf("procs[%d].session =%d\n", index, + procs[index].pi_session); + printf("procs[%d].tty_nr =%d\n", index, procs[index].pi_tty_nr); + printf("procs[%d].tty_pgrp =%d\n", index, + procs[index].pi_tty_pgrp); + printf("procs[%d].flags =%lu\n", index, procs[index].pi_flags); + printf("procs[%d].minflt =%lu\n", index, procs[index].pi_minflt); + printf("procs[%d].cmin_flt =%lu\n", index, + procs[index].pi_cmin_flt); + printf("procs[%d].majflt =%lu\n", index, procs[index].pi_majflt); + printf("procs[%d].cmaj_flt =%lu\n", index, + procs[index].pi_cmaj_flt); + printf("procs[%d].utime =%lu\n", index, procs[index].pi_utime); + printf("procs[%d].stime =%lu\n", index, procs[index].pi_stime); + printf("procs[%d].cutime =%ld\n", index, procs[index].pi_cutime); + printf("procs[%d].cstime =%ld\n", index, procs[index].pi_cstime); + printf("procs[%d].pri =%d\n", index, procs[index].pi_pri); + printf("procs[%d].nice =%d\n", index, procs[index].pi_nice); +#ifdef PRE_KERNEL_2_6_18 + printf("procs[%d].junk =%d\n", index, procs[index].junk); +#else + printf("procs[%d].num_threads =%ld\n", index, + procs[index].num_threads); +#endif + printf("procs[%d].it_real_value =%lu\n", index, + procs[index].pi_it_real_value); + printf("procs[%d].start_time =%lu\n", index, + procs[index].pi_start_time); + printf("procs[%d].vsize =%lu\n", index, procs[index].pi_vsize); + printf("procs[%d].rss =%lu\n", index, procs[index].pi_rss); + printf("procs[%d].rlim_cur =%lu\n", index, + procs[index].pi_rlim_cur); + printf("procs[%d].start_code =%lu\n", index, + procs[index].pi_start_code); + printf("procs[%d].end_code =%lu\n", index, + procs[index].pi_end_code); + printf("procs[%d].start_stack =%lu\n", index, + procs[index].pi_start_stack); + printf("procs[%d].esp =%lu\n", index, procs[index].pi_esp); + printf("procs[%d].eip =%lu\n", index, procs[index].pi_eip); + printf("procs[%d].pending_signal=%lu\n", index, + procs[index].pi_pending_signal); + printf("procs[%d].blocked_sig =%lu\n", index, + procs[index].pi_blocked_sig); + printf("procs[%d].sigign =%lu\n", index, + procs[index].pi_sigign); + printf("procs[%d].sigcatch =%lu\n", index, + procs[index].pi_sigcatch); + printf("procs[%d].wchan =%lu\n", index, procs[index].pi_wchan); + printf("procs[%d].nswap =%lu\n", index, procs[index].pi_nswap); + printf("procs[%d].cnswap =%lu\n", index, + procs[index].pi_cnswap); + printf("procs[%d].exit_signal =%d\n", index, + procs[index].pi_exit_signal); + printf("procs[%d].cpu =%d\n", index, procs[index].pi_cpu); +#ifndef PRE_KERNEL_2_6_18 + printf("procs[%d].rt_priority =%lu\n", index, + procs[index].pi_rt_priority); + printf("procs[%d].policy =%lu\n", index, + procs[index].pi_policy); + printf("procs[%d].delayacct_blkio_ticks=%llu\n", index, + procs[index].pi_delayacct_blkio_ticks); +#endif + printf("OK\n"); +} +#endif /*DEBUG*/ +/* --- */ +int isnumbers(char *s) +{ + while (*s != 0) { + if (*s < '0' || *s > '9') + return 0; + s++; + } + return 1; +} + +int getprocs(int records) +{ + struct dirent *dent; + DIR *procdir; + int count = 0; + + if ((char *) (procdir = opendir("/proc")) == NULL) { + printf("opendir(/proc) failed"); + return 0; + } + while ((char *) (dent = readdir(procdir)) != NULL) { + if (dent->d_type == 4) { /* is this a directlory */ + /* mainframes report 0 = unknown every time !!!! */ + if (isnumbers(dent->d_name)) { + if (records != 0) { + /* getting the details mode */ + count = count + proc_procsinfo(atoi(dent->d_name), count); + if(count == records) { + break; + } + } else { + /* just counting the processes mode */ + count++; + } + } + } + } + closedir(procdir); + return count; +} + +/* --- */ + +char cpu_line[] = + "---------------------------+-------------------------------------------------+"; +/* Start process as specified in cmd in a child process without waiting + * for completion + * not sure if want to prevent this funcitonality for root user + * when: CHLD_START, CHLD_SNAP or CHLD_END + * cmd: pointer to command string - assumed to be cleansed .... + * timestamp_type: 0 - T%04d, 1 - detailed time stamp + * loop: loop id (0 for CHLD_START) + * the_time: time to use for timestamp generation + */ +void child_start(int when, + char *cmd, int timestamp_type, int loop, time_t the_time) +{ + int i; + pid_t child_pid; + char time_stamp_str[64] = ""; + char *when_info = ""; + struct tm *tim; /* used to work out the hour/min/second */ + +#ifdef DEBUG2 + fprintf(fp, "child start when=%d cmd=%s time=%d loop=%d\n", when, cmd, + timestamp_type, loop); +#endif + /* Validate parameter and initialize error text */ + switch (when) { + case CHLD_START: + when_info = "nmon fork exec failure CHLD_START"; + break; + case CHLD_END: + when_info = "nmon fork exec failure CHLD_END"; + break; + + case CHLD_SNAP: + /* check if old child has finished - otherwise we do nothing */ + if (nmon_children[CHLD_SNAP] != -1) { + if (!cursed) + fprintf(fp, + "ERROR,T%04d, Starting snap command \"%s\" failed as previous child still running - killing it now\n", + loop, cmd); + kill(nmon_children[CHLD_SNAP], 9); + } + + when_info = "nmon fork exec failure CHLD_SNAP"; + break; + } + + + /* now fork off a child process. */ + switch (child_pid = fork()) { + case -1: /* fork failed. */ + perror(when_info); + return; + + case 0: /* inside child process. */ + /* create requested timestamp */ + if (timestamp_type == 1) { + tim = localtime(&the_time); + snprintf(time_stamp_str, 64, "%02d:%02d:%02d,%02d,%02d,%04d", + tim->tm_hour, tim->tm_min, tim->tm_sec, + tim->tm_mday, tim->tm_mon + 1, tim->tm_year + 1900); + } else { + snprintf(time_stamp_str, 64, "T%04d", loop); + } + + /* close all open file pointers except the defaults */ + for (i = 3; i < 5; ++i) + close(i); + + /* Now switch to the defined command */ + execlp(cmd, cmd, time_stamp_str, (void *) 0); + + /* If we get here the specified command could not be started */ + perror(when_info); + exit(1); /* We can't do anything more */ + /* never reached */ + + default: /* inside parent process. */ + /* In father - remember child pid for future */ + nmon_children[when] = child_pid; + } +} + +int main(int argc, char **argv) +{ + int secs; + int cpu_idle; + int cpu_user; + int cpu_sys; + int cpu_wait; + int cpu_steal; + int current_procs = 0; + int adjusted_procs = 0; + int n = 0; /* reusable counters */ + int i = 0; + int j = 0; + int k = 0; + int ret = 0; + int max_sorted; + int skipped; + int x = 0; /* curses row */ + int y = 0; /* curses column */ + double elapsed; /* actual seconds between screen updates */ + double cpu_sum; + double ftmp; + int top_first_time = 1; + int disk_first_time = 1; + int nfs_first_time = 1; + int vm_first_time = 1; + int bbbr_line = 0; + double cpu_busy; +#ifdef POWER + int lpar_first_time = 1; + long max_speed = 0; +#endif /* POWER */ + int smp_first_time = 1; + int wide_first_time = 1; + int proc_first_time = 1; + int first_key_pressed = 0; + pid_t childpid = -1; + int ralfmode = 0; + char pgrp[32]; + struct tm *tim; /* used to work out the hour/min/second */ + float total_busy; /* general totals */ + float total_rbytes; /* general totals */ + float total_wbytes; + float total_xfers; + struct utsname uts; /* UNIX name, version, etc */ + double top_disk_busy = 0.0; + char *top_disk_name = ""; + int disk_mb; + double disk_total; + double disk_busy; + double disk_read; + double disk_read_tmp; + double disk_write; + double disk_write_tmp; + double disk_size; + double disk_xfers; + double total_disk_read; + double total_disk_write; + double total_disk_xfers; + double readers; + double writers; + + /* for popen on oslevel */ + char *str_p; + int varperftmp = 0; + char *formatstring; + char *open_filename = 0; + char *user_filename = 0; + char user_filename_set = 0; + char using_stdout = 0; + struct statfs statfs_buffer; + + float fs_size; + float fs_bsize; + float fs_free; + float fs_size_used; + + char cmdstr[256]; + long updays, uphours, upmins; + float v2c_total; + float v2s_total; + float v3c_total; + float v3s_total; + float v4c_total; + float v4s_total; + int errors = 0; + + char *nmon_start = (char *) NULL; + char *nmon_end = (char *) NULL; + char *nmon_snap = (char *) NULL; + char *nmon_tmp = (char *) NULL; + int nmon_one_in = 1; + /* Flag what kind of time stamp we give to started children + * 0: "T%04d" + * 1: "hh:mm:ss,dd,mm,yyyy" + */ + int time_stamp_type = 0; + long ticks = 100; /* Clock ticks per second used in /proc/stat cpu lines */ + unsigned long pagesize = 1024 * 4; /* Default page size is 4 KB but newer servers compiled with 64 KB pages */ + float average; + struct timeval nmon_tv; /* below is used to workout the nmon run, accumalate it and the + allow for in in the sleep time to reduce time drift */ + double nmon_start_time = 0.0; + double nmon_end_time = 0.0; + double nmon_run_time = -1.0; + int seconds_over = 0; + float mhz; + float min_mhz; + float max_mhz; + float avg_mhz = 0.0; + unsigned long topsize; + char topsize_ch; + unsigned long toprset; + char toprset_ch; + unsigned long toptrs; + char toptrs_ch; + unsigned long topdrs; + char topdrs_ch; + unsigned long toplrs; + char toplrs_ch; + unsigned long topshare; + char topshare_ch; + unsigned long toprio; + char toprio_ch; + unsigned long topwio; + char topwio_ch; + long long tmpslab; + char * slabstr; + char truncated_command[257]; /* 256 +1 */ + + +#define MAXROWS 256 +#define MAXCOLS 150 /* changed to allow maximum column widths */ +#define BANNER(pad,string) {mvwhline(pad, 0, 0, ACS_HLINE,COLS-2); \ + wmove(pad,0,0); \ + wattron(pad,A_STANDOUT); \ + wprintw(pad," "); \ + wprintw(pad,string); \ + wprintw(pad," "); \ + wattroff(pad,A_STANDOUT); } + +#define DISPLAY(pad,rows) { \ + if(x+2+(rows)>LINES)\ + pnoutrefresh(pad, 0,0,x,1,LINES-2, COLS-2); \ + else \ + pnoutrefresh(pad, 0,0,x,1,x+rows+1,COLS-2); \ + x=x+(rows); \ + if(x+4>LINES) { \ + mvwprintw(stdscr,LINES-1,10,"Warning: Some Statistics may not shown"); \ + } \ + } + + /* check the user supplied options */ + progname = argv[0]; + for (i = (int) strlen(progname) - 1; i > 0; i--) + if (progname[i] == '/') { + progname = &progname[i + 1]; + } + + if (getenv("NMONDEBUG") != NULL) + debug = 1; + if (getenv("NMONERROR") != NULL) + error_on = 1; + if (getenv("NMONBUG1") != NULL) + reread = 1; + +/* External Data Collector Controls */ + if ((nmon_start = getenv("NMON_START")) != NULL) { + nmon_start = check_call_string(nmon_start, "NMON_START"); + } + if ((nmon_end = getenv("NMON_END")) != NULL) { + nmon_end = check_call_string(nmon_end, "NMON_END"); + } + if ((nmon_tmp = getenv("NMON_ONE_IN")) != NULL) { + nmon_one_in = atoi(nmon_tmp); + if (errno != 0) { + fprintf(stderr, + "ERROR nmon: invalid NMON_ONE_IN shell variable\n"); + nmon_one_in = 1; + } + } + if ((nmon_snap = getenv("NMON_SNAP")) != NULL) { + nmon_snap = check_call_string(nmon_snap, "NMON_SNAP"); + } + if ((nmon_tmp = getenv("NMON_TIMESTAMP")) != NULL) { + time_stamp_type = atoi(nmon_tmp); + if (time_stamp_type != 0 && time_stamp_type != 1) + time_stamp_type = 1; + } +#ifdef DEBUG2 + printf("NMON_START=%s.\n", nmon_start); + printf("NMON_END=%s.\n", nmon_end); + printf("NMON_SNAP=%s.\n", nmon_snap); + printf("ONE_IN=%d.\n", nmon_one_in); + printf("TIMESTAMP=%d.\n", time_stamp_type); +#endif + +#ifdef REREAD + reread = 1; +#endif + for (i = 0; i < CMDMAX; i++) { + snprintf(cmdstr, 256, "NMONCMD%d", i); + cmdlist[i] = getenv(cmdstr); + if (cmdlist[i] != 0) + cmdfound = i + 1; + } + /* Setup long and short Hostname */ + gethostname(hostname, sizeof(hostname)); + strncpy(fullhostname, hostname, 256); + fullhostname[256 - 1] = 0; + for (i = 0; i < sizeof(hostname); i++) + if (hostname[i] == '.') + hostname[i] = 0; + if (run_name_set == 0) { + strncpy(run_name, hostname, 256); + run_name[256 - 1] = 0; + } + if (getuid() == 0) + isroot = 1; + + /* Check the version of OS */ + uname(&uts); + /* Get the clock ticks persecond for CPU counters in /proc/stat cpu stats */ + ticks = sysconf(_SC_CLK_TCK); + if (ticks == -1 || ticks == 0) + ticks = 100; + /* Check if we have the large 64 KB memory page sizes compiled into the kernel */ + if (sysconf(_SC_PAGESIZE) > 1024 * 4) + pagesize = sysconf(_SC_PAGESIZE); + proc_init(); + + while (-1 != + (i = + getopt(argc, argv, + "?abc:C:Dd:EfF:g:hI:Jl:m:MNpr:Rs:tTUVxXz"))) { + switch (i) { + case '?': + hint(); + exit(0); + case 'a': /* Acelerator */ + case 'E': /* Emily */ + show_gpu = 1; + break; + case 'b': + colour = 0; + break; + case 'c': + maxloops = atoi(optarg); + break; + case 'C': /* commandlist argument */ + cmdlist[0] = MALLOC(strlen(optarg) + 1); /* create buffer */ + strcpy(cmdlist[0], optarg); + if (cmdlist[0][0] != 0) + cmdfound = 1; + for (i = 0, j = 1; cmdlist[0][i] != 0; i++) { + if (cmdlist[0][i] == ':') { + cmdlist[0][i] = 0; + cmdlist[j] = &cmdlist[0][i + 1]; + j++; + cmdfound = j; + if (j >= CMDMAX) + break; + } + } + break; + case 'd': + diskmax = atoi(optarg); + if (diskmax < DISKMIN) { + printf + ("nmon: ignoring -d %d option as the minimum is %d\n", + diskmax, DISKMIN); + diskmax = DISKMIN; + } + break; + case 'D': + extended_disk = 1; + break; + case 'F': /* background mode with user supplied filename */ + user_filename = MALLOC(strlen(optarg) + 1); + strcpy(user_filename, optarg); + user_filename_set++; + go_background(288, 300); + break; + case 'f': /* background mode i.e. for spread sheet output */ + go_background(288, 300); + break; + case 'g': /* disk groups */ + show_dgroup = 1; + dgroup_loaded = 1; + dgroup_filename = optarg; + if (strncmp("auto", dgroup_filename, 5) == 0) { + auto_dgroup++; + printf + ("Generating disk group file from lsblk output to file: \"auto\"\n"); +#ifdef SLES113 +#define LSBLK_NO_TYPE /* define this to work around missing --output TYPE feature */ +#endif /* SLES113 */ + +#ifdef LSBLK_NO_TYPE +#define LSBLK_STRING "lsblk --nodeps --output NAME --noheadings | awk 'BEGIN {printf \"# This file created by: nmon -g auto\\n# It is an automatically generated disk-group file which excluses disk paritions\\n\" } { printf \"%s %s\\n\", $1, $1 }' >auto" +#else +#define LSBLK_STRING "lsblk --nodeps --output NAME,TYPE --raw | grep disk | awk 'BEGIN {printf \"# This file created by: nmon -g auto\\n# It is an automatically generated disk-group file which excluses disk paritions\\n\" } { printf \"%s %s\\n\", $1, $1 }' >auto" +#endif /* LSBLK_NO_TYPE */ + ret = system(LSBLK_STRING); + if (ret != 0) { + printf("Create auto file command was: %s\n", LSBLK_STRING); + printf("Creating auto file returned a status of %d\n", ret); + } + } + break; + case 'h': + help(); + break; + case 'I': + ignore_procdisk_threshold = atof(optarg); + break; + case 'J': + show_jfs = 0; + break; + case 'l': + disks_per_line = atoi(optarg); + if (disks_per_line < 3 || disks_per_line > 250) + disks_per_line = 100; + break; + case 'm': + if (chdir(optarg) == -1) { + perror("changing directory failed"); + printf("Directory attempted was:%s\n", optarg); + exit(993); + } + break; + case 'M': /* MHz */ + show_mhz = 1; + break; + case 'N': + show_nfs = 1; + break; + case 'p': + ralfmode = 1; + break; + case 'R': + show_rrd = 1; + go_background(288, 300); + show_aaa = 0; + show_para = 0; + show_headings = 0; + break; + case 'r': + strncpy(run_name, optarg, 256); + run_name[256 - 1] = 0; + run_name_set++; + break; + case 's': + seconds = atoi(optarg); + break; + case 'T': + show_args = ARGS_ONLY; /* drop through */ + case 't': + show_top = 1; /* put top process output in spreadsheet mode */ + show_topmode = 3; + break; + case 'U': + show_util = 1; + break; + case 'V': /* nmon version */ + printf("nmon version %s\n", VERSION); + exit(0); + break; + case 'x': /* background mode for 1 day capacity planning */ + go_background(4 * 24, 15 * 60); + show_top = 1; + show_topmode = 3; + break; + case 'X': /* background mode for 1 hour capacity planning */ + go_background(120, 30); + show_top = 1; + show_topmode = 3; + break; + case 'z': /* background mode for 1 day output to /var/perf/tmp */ + varperftmp++; + go_background(4 * 24, 15 * 60); + break; + } + } + /* Set parameters if not set by above */ + if (maxloops == -1) + maxloops = 9999999; + if (seconds == -1) + seconds = 2; + if (cursed) + show_dgroup = 0; + + /* -D need -g filename */ + if (extended_disk == 1 && show_dgroup == 0) { + printf + ("nmon: ignoring -D (extended disk stats) as -g filename is missing\n"); + extended_disk = 0; + } +#ifdef NVIDIA_GPU + if (cursed) { + gpu_init(); + } +#endif /* NVIDIA_GPU */ + + /* To get the pointers setup */ + switcher(); + + /* Initialise the time stamps for the first loop */ + p->time = doubletime(); + q->time = doubletime(); + + find_release(); + + /* Determine number of active LOGICAL cpu - depends on SMT mode ! */ + get_cpu_cnt(); + max_cpus = old_cpus = cpus; +#if X86 || ARM + get_intel_spec(); +#endif + proc_read(P_STAT); + proc_cpu(); + proc_read(P_UPTIME); + proc_read(P_LOADAVG); + proc_kernel(); + memcpy(&q->cpu_total, &p->cpu_total, sizeof(struct cpu_stat)); + + p->dk = MALLOC(sizeof(struct dsk_stat) * diskmax + 1); + q->dk = MALLOC(sizeof(struct dsk_stat) * diskmax + 1); + disk_busy_peak = MALLOC(sizeof(double) * diskmax); + disk_rate_peak = MALLOC(sizeof(double) * diskmax); + for (i = 0; i < diskmax; i++) { + disk_busy_peak[i] = 0.0; + disk_rate_peak[i] = 0.0; + } + + cpu_peak = MALLOC(sizeof(double) * (CPUMAX + 1)); /* MAGIC */ + for (i = 0; i < max_cpus + 1; i++) + cpu_peak[i] = 0.0; + + current_procs = getprocs(0); + adjusted_procs = current_procs + 128; /*allows for more processes */ + p->procs = MALLOC(sizeof(struct procsinfo) * adjusted_procs); + q->procs = MALLOC(sizeof(struct procsinfo) * adjusted_procs); + p->proc_records = adjusted_procs; + q->proc_records = adjusted_procs; + p->processes = 0; + q->processes = 0; + + /* Initialise the top processes table */ + topper_size = n; + topper = MALLOC(sizeof(struct topper) * topper_size); /* round up */ + + /* Get Disk Stats. */ + proc_disk(0.0); + memcpy(q->dk, p->dk, sizeof(struct dsk_stat) * disks); + + /* load dgroup - if required */ + if (dgroup_loaded == 1) { + load_dgroup(p->dk); + } + + /* Get Network Stats. */ + proc_net(); + memcpy(q->ifnets, p->ifnets, sizeof(struct net_stat) * networks); + for (i = 0; i < networks; i++) { + net_read_peak[i] = 0.0; + net_write_peak[i] = 0.0; + } + + /* If we are running in spreadsheet mode initialize all other data sets as well + * so we do not get incorrect data for the first reported interval + */ + if (!cursed) { + /* Get VM Stats */ + read_vmstat(); + + /* Get Memory info */ + proc_mem(); + +#ifdef POWER + /* Get LPAR Stats */ + proc_lparcfg(); +#endif + } + /* Set the pointer ready for the next round */ + switcher(); + + /* Initialise signal handlers so we can tidy up curses on exit */ + signal(SIGUSR1, interrupt); + signal(SIGUSR2, interrupt); + signal(SIGINT, interrupt); + signal(SIGWINCH, interrupt); + signal(SIGCHLD, interrupt); + + /* Start Curses */ + if (cursed) { + initscr(); + cbreak(); + move(0, 0); + refresh(); + COLOUR colour = has_colors(); + COLOUR start_color(); + COLOUR init_pairs(); + clear(); +#ifdef POWER + padlpar = newpad(11, MAXCOLS); +#endif + padwelcome = newpad(24, MAXCOLS); + padmap = newpad(24, MAXCOLS); + padhelp = newpad(24, MAXCOLS); + padmem = newpad(20, MAXCOLS); + padlarge = newpad(20, MAXCOLS); + padpage = newpad(20, MAXCOLS); + padres = newpad(20, MAXCOLS); + padsmp = newpad(MAXROWS, MAXCOLS); + padutil = newpad(MAXROWS, MAXCOLS); + padlong = newpad(MAXROWS, MAXCOLS); + padwide = newpad(MAXROWS, MAXCOLS); + padmhz = newpad(24, MAXCOLS); + padgpu = newpad(10, MAXCOLS); + padnet = newpad(MAXROWS, MAXCOLS); + padneterr = newpad(MAXROWS, MAXCOLS); + paddisk = newpad(MAXROWS, MAXCOLS); + paddg = newpad(MAXROWS, MAXCOLS); + padjfs = newpad(MAXROWS, MAXCOLS); + padker = newpad(12, MAXCOLS); + padverb = newpad(8, MAXCOLS); + padnfs = newpad(25, MAXCOLS); + padtop = newpad(MAXROWS, MAXCOLS * 2); + + + } else { + /* Output the header lines for the spread sheet */ + timer = time(0); + tim = localtime(&timer); + tim->tm_year += 1900 - 2000; /* read localtime() manual page!! */ + tim->tm_mon += 1; /* because it is 0 to 11 */ + if (varperftmp) { + if(strlen(hostname) > 1024 ) + hostname[255] = 0; + open_filename = MALLOC(strlen(hostname) + 64); /* hostname plus directory size plus the number */ + snprintf(open_filename, strlen(hostname) + 63, "/var/perf/tmp/%s_%02d.nmon", hostname, + tim->tm_mday); + } + else if (user_filename_set && user_filename != 0) { + open_filename = MALLOC(strlen(user_filename) + 1); + strcpy(open_filename, user_filename); + } + else { + open_filename = MALLOC(strlen(hostname) + 64); + snprintf(open_filename, strlen(hostname) + 63, "%s_%02d%02d%02d_%02d%02d.nmon", + hostname, + tim->tm_year, + tim->tm_mon, tim->tm_mday, tim->tm_hour, tim->tm_min); + } + if (!strncmp(open_filename, "stdout", 6)) { + using_stdout = 1; + if ((fp = fdopen(1, "w")) == 0) { + perror("nmon: failed to open standard output"); + exit(41); + } + } else { + if ((fp = fopen(open_filename, "w")) == 0) { + perror("nmon: failed to open output file"); + printf("nmon: output filename=%s\n", open_filename); + exit(42); + } + } + free(open_filename); + /* disconnect from terminal */ + fflush(NULL); + if (!debug && (childpid = fork()) != 0) { + if (ralfmode) + printf("%d\n", childpid); + exit(0); /* parent returns OK */ + } + if (!debug) { + close(0); + if(using_stdout == 0) + close(1); + close(2); + setpgrp(); /* become process group leader */ + signal(SIGHUP, SIG_IGN); /* ignore hangups */ + } + /* Do the nmon_start activity early on */ + if (nmon_start) { + timer = time(0); + child_start(CHLD_START, nmon_start, time_stamp_type, 1, timer); + } + + if (show_aaa) { + fprintf(fp, "AAA,progname,%s\n", progname); + fprintf(fp, "AAA,command,"); + for (i = 0; i < argc; i++) + fprintf(fp, "%s ", argv[i]); + fprintf(fp, "\n"); + fprintf(fp, "AAA,version,%s\n", VERSION); + fprintf(fp, "AAA,disks_per_line,%d\n", disks_per_line); + fprintf(fp, "AAA,max_disks,%d,set by -d option\n", diskmax); + fprintf(fp, "AAA,disks,%d,\n", disks); + + fprintf(fp, "AAA,host,%s\n", hostname); + fprintf(fp, "AAA,user,%s\n", getenv("USER")); + fprintf(fp, "AAA,OS,Linux,%s,%s,%s\n", uts.release, + uts.version, uts.machine); + fprintf(fp, "AAA,runname,%s\n", run_name); + fprintf(fp, "AAA,time,%02d:%02d.%02d\n", tim->tm_hour, + tim->tm_min, tim->tm_sec); + fprintf(fp, "AAA,date,%02d-%3s-%02d\n", tim->tm_mday, + month[tim->tm_mon - 1], tim->tm_year + 2000); + fprintf(fp, "AAA,interval,%d\n", seconds); + fprintf(fp, "AAA,snapshots,%d\n", maxloops); +#ifdef POWER + fprintf(fp, "AAA,cpus,%d,%d\n", cpus / lparcfg.smt_mode, cpus); /* physical CPU, logical CPU */ + fprintf(fp, "AAA,CPU ID length,3\n"); /* Give analyzer a chance to easily find length of CPU number - 3 digits here! */ +#else + fprintf(fp, "AAA,cpus,%d\n", cpus); +#endif +#ifdef X86 + fprintf(fp, "AAA,x86,VendorId,%s\n", vendor_ptr); + fprintf(fp, "AAA,x86,ModelName,%s\n", model_ptr); + fprintf(fp, "AAA,x86,MHz,%s\n", mhz_ptr); + fprintf(fp, "AAA,x86,bogomips,%s\n", bogo_ptr); + fprintf(fp, "AAA,x86,ProcessorChips,%d\n", processorchips); + fprintf(fp, "AAA,x86,Cores,%d\n", cores); + fprintf(fp, "AAA,x86,hyperthreads,%d\n", hyperthreads); + fprintf(fp, "AAA,x86,VirtualCPUs,%d\n", cpus); +#endif +#ifdef ARM + fprintf(fp, "AAA,ARM,VendorId,%s\n", vendor_ptr); + fprintf(fp, "AAA,ARM,ModelName,%s\n", model_ptr); + fprintf(fp, "AAA,ARM,MHz,%s\n", mhz_ptr); + fprintf(fp, "AAA,ARM,bogomips,%s\n", bogo_ptr); + fprintf(fp, "AAA,ARM,ProcessorChips,%d\n", processorchips); + fprintf(fp, "AAA,ARM,Cores,%d\n", cores); + fprintf(fp, "AAA,ARM,hyperthreads,%d\n", hyperthreads); + fprintf(fp, "AAA,ARM,VirtualCPUs,%d\n", cpus); +#endif + fprintf(fp, "AAA,proc_stat_variables,%d\n", stat8); + fprintf(fp, "AAA,boottime,%s\n", boottime_str); + + fprintf(fp, + "AAA,note0, Warning - use the UNIX sort command to order this file before loading into a spreadsheet\n"); + fprintf(fp, + "AAA,note1, The First Column is simply to get the output sorted in the right order\n"); + fprintf(fp, + "AAA,note2, The T0001-T9999 column is a snapshot number. To work out the actual time; see the ZZZ section at the end\n"); + } + fflush(NULL); + + for (i = 1; i <= cpus; i++) + fprintf(fp, + "CPU%03d,CPU %d %s,User%%,Sys%%,Wait%%,Idle%%,Steal%%\n", + i, i, run_name); + fprintf(fp, + "CPU_ALL,CPU Total %s,User%%,Sys%%,Wait%%,Idle%%,Steal%%,Busy,CPUs\n", + run_name); + if (show_mhz) { + fprintf(fp, "MHZ,Clock Speed (MHz) %s", run_name); + for (i = 1; i <= cpus; i++) + fprintf(fp, ",CPU%03d", i); + fprintf(fp, "\n"); + } + fprintf(fp, + "MEM,Memory MB %s,memtotal,hightotal,lowtotal,swaptotal,memfree,highfree,lowfree,swapfree,memshared,cached,active,bigfree,buffers,swapcached,inactive\n", + run_name); + +#ifdef POWER + proc_lparcfg(); + if (lparcfg.cmo_enabled) + fprintf(fp, + "MEMAMS,AMS %s,Poolid,Weight,Hypervisor-Page-in/s,HypervisorTime(seconds),not_available_1,not_available_2,not_available_3,Physical-Memory(MB),Page-Size(KB),Pool-Size(MB),Loan-Request(KB)\n", + run_name); + +#ifdef EXPERIMENTAL + fprintf(fp, + "MEMEXPERIMENTAL,New lparcfg numbers %s,DesEntCap,DesProcs,DesVarCapWt,DedDonMode,group,pool,entitled_memory,entitled_memory_group_number,unallocated_entitled_memory_weight,unallocated_io_mapping_entitlement\n", + run_name); +#endif /* EXPERIMENTAL */ +#endif /* POWER */ + + fprintf(fp, + "PROC,Processes %s,Runnable,Blocked,pswitch,syscall,read,write,fork,exec,sem,msg\n", + run_name); +/* + fprintf(fp,"PAGE,Paging %s,faults,pgin,pgout,pgsin,pgsout,reclaims,scans,cycles\n", run_name); + fprintf(fp,"FILE,File I/O %s,iget,namei,dirblk,readch,writech,ttyrawch,ttycanch,ttyoutch\n", run_name); +*/ + + + fprintf(fp, "NET,Network I/O %s", run_name); + for (i = 0; i < networks; i++) + fprintf(fp, ",%-2s-read-KB/s", (char *) p->ifnets[i].if_name); + for (i = 0; i < networks; i++) + fprintf(fp, ",%-2s-write-KB/s", (char *) p->ifnets[i].if_name); + fprintf(fp, "\n"); + fprintf(fp, "NETPACKET,Network Packets %s", run_name); + for (i = 0; i < networks; i++) + fprintf(fp, ",%-2s-read/s", (char *) p->ifnets[i].if_name); + for (i = 0; i < networks; i++) + fprintf(fp, ",%-2s-write/s", (char *) p->ifnets[i].if_name); + /* iremoved as it is not below in the BUSY line fprintf(fp,"\n"); */ +#ifdef DEBUG + if (debug) + printf("disks=%d x%sx\n", (char *) disks, p->dk[0].dk_name); +#endif /*DEBUG*/ + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, "\nDISKBUSY%s,Disk %%Busy %s", dskgrp(i), + run_name); + fprintf(fp, ",%s", (char *) p->dk[i].dk_name); + } + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, "\nDISKREAD%s,Disk Read KB/s %s", dskgrp(i), + run_name); + fprintf(fp, ",%s", (char *) p->dk[i].dk_name); + } + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, "\nDISKWRITE%s,Disk Write KB/s %s", + (char *) dskgrp(i), run_name); + fprintf(fp, ",%s", (char *) p->dk[i].dk_name); + } + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, "\nDISKXFER%s,Disk transfers per second %s", + (char *) dskgrp(i), run_name); + fprintf(fp, ",%s", p->dk[i].dk_name); + } + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, "\nDISKBSIZE%s,Disk Block Size %s", dskgrp(i), + run_name); + fprintf(fp, ",%s", (char *) p->dk[i].dk_name); + } + if (extended_disk == 1 && disk_mode == DISK_MODE_DISKSTATS) { + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, "\nDISKREADS%s,Disk Rd/s %s", dskgrp(i), + run_name); + fprintf(fp, ",%s", (char *) p->dk[i].dk_name); + } + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, "\nDISKWRITES%s,Disk Wrt/s %s", dskgrp(i), + run_name); + fprintf(fp, ",%s", (char *) p->dk[i].dk_name); + } + } + + fprintf(fp, "\n"); + list_dgroup(p->dk); + if(show_jfs) { + jfs_load(LOAD); + fprintf(fp, "JFSFILE,JFS Filespace %%Used %s", hostname); + for (k = 0; k < jfses; k++) { + if (jfs[k].mounted && strncmp(jfs[k].name, "/proc", 5) + && strncmp(jfs[k].name, "/sys", 4) + && strncmp(jfs[k].name, "/run/", 5) + && strncmp(jfs[k].name, "/dev/", 5) + && strncmp(jfs[k].name, "/var/lib/nfs/rpc", 16) + ) /* /proc gives invalid/insane values */ + fprintf(fp, ",%s", jfs[k].name); + } + fprintf(fp, "\n"); + jfs_load(UNLOAD); + } +#ifdef POWER + if (proc_lparcfg() && (lparcfg.shared_processor_mode != 0 || lparcfg.DedDonMode > 0) + && power_vm_type == VM_POWERVM) { + fprintf(fp, + "LPAR,Shared CPU LPAR Stats %s,PhysicalCPU,capped,shared_processor_mode,system_potential_processors,system_active_processors,pool_capacity,MinEntCap,partition_entitled_capacity,partition_max_entitled_capacity,MinProcs,Logical CPU,partition_active_processors,partition_potential_processors,capacity_weight,unallocated_capacity_weight,BoundThrds,MinMem,unallocated_capacity,pool_idle_time,smt_mode\n", + hostname); + + } +#endif /*POWER*/ + if (show_top) { + fprintf(fp, "TOP,%%CPU Utilisation\n"); +#ifdef PRE_KERNEL_2_6_18 + fprintf(fp, + "TOP,+PID,Time,%%CPU,%%Usr,%%Sys,Size,ResSet,ResText,ResData,ShdLib,MinorFault,MajorFault,Command\n"); +#else + fprintf(fp, + "TOP,+PID,Time,%%CPU,%%Usr,%%Sys,Size,ResSet,ResText,ResData,ShdLib,MinorFault,MajorFault,Command,Threads,IOwaitTime\n"); +#endif + } + linux_bbbp("/etc/release", "/bin/cat /etc/*ease 2>/dev/null", + WARNING); + linux_bbbp("lsb_release", "/usr/bin/lsb_release -a 2>/dev/null", + WARNING); + linux_bbbp("fdisk-l", "/sbin/fdisk -l 2>/dev/null", WARNING); + linux_bbbp("lsblk", "/usr/bin/lsblk 2>/dev/null", WARNING); + linux_bbbp("lscpu", "/usr/bin/lscpu 2>/dev/null", WARNING); + linux_bbbp("lshw", "/usr/bin/lshw 2>/dev/null", WARNING); + linux_bbbp("/proc/cpuinfo", "/bin/cat /proc/cpuinfo 2>/dev/null", + WARNING); + linux_bbbp("/proc/meminfo", "/bin/cat /proc/meminfo 2>/dev/null", + WARNING); + linux_bbbp("/proc/stat", "/bin/cat /proc/stat 2>/dev/null", + WARNING); + linux_bbbp("/proc/version", "/bin/cat /proc/version 2>/dev/null", + WARNING); + linux_bbbp("/proc/net/dev", "/bin/cat /proc/net/dev 2>/dev/null", + WARNING); +#ifdef POWER + /* PowerKVM useful information */ + linux_bbbp("/proc/device-tree/host-model", + "/bin/cat /proc/device-tree/host-model 2>/dev/null", WARNING); + linux_bbbp("/proc/device-tree/host-serial", + "/bin/cat /proc/device-tree/host-serial 2>/dev/null", WARNING); + linux_bbbp("/proc/device-tree/ibm,partition-name", + "/bin/cat /proc/device-tree/ibm,partition-name 2>/dev/null", WARNING); + + linux_bbbp("ppc64_utils - lscfg", "/usr/sbin/lscfg 2>/dev/null", WARNING); + linux_bbbp("ppc64_utils - ls-vdev", + "/usr/sbin/ls-vdev 2>/dev/null", WARNING); + linux_bbbp("ppc64_utils - ls-veth", + "/usr/sbin/ls-veth 2>/dev/null", WARNING); + linux_bbbp("ppc64_utils - ls-vscsi", + "/usr/sbin/ls-vscsi 2>/dev/null", WARNING); + linux_bbbp("ppc64_utils - lsmcode", + "/usr/sbin/lsmcode 2>/dev/null", WARNING); + linux_bbbp("ppc64_cpu - smt", + "/usr/sbin/ppc64_cpu --smt 2>/dev/null", WARNING); + linux_bbbp("ppc64_cpu - cores", + "/usr/sbin/ppc64_cpu --cores-present 2>/dev/null", WARNING); + linux_bbbp("ppc64_cpu - DSCR", + "/usr/sbin/ppc64_cpu --dscr 2>/dev/null", WARNING); + linux_bbbp("ppc64_cpu - snooze", + "/usr/sbin/ppc64_cpu --smt-snooze-delay 2>/dev/null", WARNING); + linux_bbbp("ppc64_cpu - run-mode", + "/usr/sbin/ppc64_cpu --run-mode 2>/dev/null", WARNING); + linux_bbbp("ppc64_cpu - frequency", + "/usr/sbin/ppc64_cpu --frequency 2>/dev/null", WARNING); + + linux_bbbp("bootlist -m nmonal -o", + "/usr/sbin/bootlist -m normal -o 2>/dev/null", WARNING); + linux_bbbp("lsslot", "/usr/sbin/lsslot 2>/dev/null", WARNING); + linux_bbbp("lparstat -i", "/usr/sbin/lparstat -i 2>/dev/null", WARNING); + linux_bbbp("lsdevinfo", "/usr/sbin/lsdevinfo 2>/dev/null", WARNING); + linux_bbbp("ls-vdev", "/usr/sbin/ls-vdev 2>/dev/null", WARNING); + linux_bbbp("ls-veth", "/usr/sbin/ls-veth 2>/dev/null", WARNING); + linux_bbbp("ls-vscsi", "/usr/sbin/ls-vscsi 2>/dev/null", WARNING); + +#endif + linux_bbbp("/proc/diskinfo", "/bin/cat /proc/diskinfo 2>/dev/null", + WARNING); + linux_bbbp("/proc/diskstats", + "/bin/cat /proc/diskstats 2>/dev/null", WARNING); + + linux_bbbp("/sbin/multipath", "/sbin/multipath -l 2>/dev/null", + WARNING); + linux_bbbp("/dev/mapper", "ls -l /dev/mapper 2>/dev/null", + WARNING); + linux_bbbp("/dev/mpath", "ls -l /dev/mpath 2>/dev/null", WARNING); + linux_bbbp("/dev/dm-*", "ls -l /dev/dm-* 2>/dev/null", WARNING); + linux_bbbp("/dev/md*", "ls -l /dev/md* 2>/dev/null", WARNING); + linux_bbbp("/dev/sd*", "ls -l /dev/sd* 2>/dev/null", WARNING); + linux_bbbp("/proc/partitions", + "/bin/cat /proc/partitions 2>/dev/null", WARNING); + linux_bbbp("/proc/1/stat", "/bin/cat /proc/1/stat 2>/dev/null", + WARNING); +#ifdef PRE_KERNEL_2_6_18 + linux_bbbp("/proc/1/statm", "/bin/cat /proc/1/statm 2>/dev/null", + WARNING); +#endif +#ifdef MAINFRAME + linux_bbbp("/proc/sysinfo", "/bin/cat /proc/sysinfo 2>/dev/null", + WARNING); +#endif + linux_bbbp("/proc/net/rpc/nfs", + "/bin/cat /proc/net/rpc/nfs 2>/dev/null", WARNING); + linux_bbbp("/proc/net/rpc/nfsd", + "/bin/cat /proc/net/rpc/nfsd 2>/dev/null", WARNING); + linux_bbbp("/proc/modules", "/bin/cat /proc/modules 2>/dev/null", + WARNING); + linux_bbbp("ifconfig", "/sbin/ifconfig 2>/dev/null", WARNING); + linux_bbbp("/bin/df-m", "/bin/df -m 2>/dev/null", WARNING); + linux_bbbp("/bin/mount", "/bin/mount 2>/dev/null", WARNING); + linux_bbbp("/etc/fstab", "/bin/cat /etc/fstab 2>/dev/null", + WARNING); + linux_bbbp("netstat -r", "/bin/netstat -r 2>/dev/null", WARNING); + linux_bbbp("uptime", "/usr/bin/uptime 2>/dev/null", WARNING); + linux_bbbp("getconf PAGESIZE", + "/usr/bin/getconf PAGESIZE 2>/dev/null", WARNING); + +#ifdef POWER + linux_bbbp("/proc/ppc64/lparcfg", + "/bin/cat /proc/ppc64/lparcfg 2>/dev/null", WARNING); + linux_bbbp("lscfg-v", "/usr/sbin/lscfg -v 2>/dev/null", WARNING); +#endif + sleep(1); /* to get the first stats to cover this one second and avoids divide by zero issues */ + } + /* To get the pointers setup */ + /* Was already done earlier, DONT'T switch back here to the old pointer! - switcher(); */ + /*checkinput(); */ + clear(); + fflush(NULL); +#ifdef POWER + lparcfg.timebase = -1; +#endif + + /* Main loop of the code */ + for (loop = 1;; loop++) { + /* Save the time and work out how long we were actually asleep + * Do this as early as possible and close to reading the CPU statistics in /proc/stat + */ + p->time = doubletime(); + elapsed = p->time - q->time; + timer = time(0); + tim = localtime(&timer); + + /* Get current count of CPU + * As side effect /proc/stat is read + */ + old_cpus = cpus; + get_cpu_cnt(); +#ifdef POWER + /* Always get lpar info as well so we can report physical CPU usage + * to make data more meaningful. Return value is ignored here, but + * remembered in proc_lparcfg() ! + */ + proc_lparcfg(); +#endif + + if (loop <= 3) /* This stops the nmon causing the cpu peak at startup */ + for (i = 0; i < max_cpus + 1; i++) + cpu_peak[i] = 0.0; + + /* Reset the cursor position to top left */ + y = x = 0; + + if (cursed) { /* Top line */ + box(stdscr, 0, 0); + mvprintw(x, 1, "nmon"); + mvprintw(x, 6, "%s", VERSION); + if (flash_on) + mvprintw(x, 15, "[H for help]"); + mvprintw(x, 30, "Hostname=%s", hostname); + mvprintw(x, 52, "Refresh=%2.0fsecs ", elapsed); + mvprintw(x, 70, "%02d:%02d.%02d", + tim->tm_hour, tim->tm_min, tim->tm_sec); + wnoutrefresh(stdscr); + x = x + 1; + + if (welcome && getenv("NMON") == 0) { + + COLOUR wattrset(padwelcome, COLOR_PAIR(2)); + mvwprintw(padwelcome, x + 0, 3, "------------------------------"); + mvwprintw(padwelcome, x + 1, 3, " _ __ _ __ ___ ___ _ __ "); + mvwprintw(padwelcome, x + 2, 3, "| '_ \\| '_ ` _ \\ / _ \\| '_ \\ "); + mvwprintw(padwelcome, x + 3, 3, "| | | | | | | | | (_) | | | | "); + mvwprintw(padwelcome, x + 4, 3, "|_| |_|_| |_| |_|\\___/|_| |_| "); + mvwprintw(padwelcome, x + 5, 3, " "); + mvwprintw(padwelcome, x + 6, 3, "------------------------------"); + + COLOUR wattrset(padwelcome, COLOR_PAIR(0)); + mvwprintw(padwelcome, x + 1, 40, "For help type H or ..."); + mvwprintw(padwelcome, x + 2, 40, " nmon -? - hint"); + mvwprintw(padwelcome, x + 3, 40, + " nmon -h - full details"); + mvwprintw(padwelcome, x + 5, 40, + "To stop nmon type q to Quit"); + COLOUR wattrset(padwelcome, COLOR_PAIR(1)); +#ifdef POWER + get_cpu_cnt(); + proc_read(P_CPUINFO); + /* find the highest MHz */ + for(i=0; itm_hour, tim->tm_min, tim->tm_sec, + tim->tm_mday, month[tim->tm_mon], + tim->tm_year + 1900); + fflush(NULL); + } + if (show_verbose && cursed) { + BANNER(padverb, "Verbose Mode"); + mvwprintw(padverb, 1, 0, + " Code Resource Stats Now\tWarn\tDanger "); + /* DISPLAY(padverb,7); */ + /* move(x,0); */ + x = x + 6; + } + if (show_help && cursed) { + + COLOUR wattrset(padhelp, COLOR_PAIR(2)); + BANNER(padhelp, + "HELP: Hit h to remove this Info Hit q to Quit"); + mvwprintw(padhelp, 1, 1, + "Letters which toggle on/off statistics:"); + mvwprintw(padhelp, 2, 1, + "h = This help | r = Resources OS & Proc"); + mvwprintw(padhelp, 3, 1, + "c = CPU Util C = wide view | l = longer term CPU averages"); + mvwprintw(padhelp, 4, 1, + "m = Memory & Swap L=Huge | V = Virtual Memory"); + mvwprintw(padhelp, 5, 1, + "n = Network | N = NFS"); + mvwprintw(padhelp, 6, 1, + "d = Disk I/O Graphs D=Stats | o = Disks %%Busy Map"); + mvwprintw(padhelp, 7, 1, + "k = Kernel stats & loadavg | j = Filesystem Usage J=reduced"); + mvwprintw(padhelp, 8, 1, "M = MHz by thread & CPU"); +#ifdef NVIDIA_GPU + mvwprintw(padhelp, 8, 39, "| a = Accelerator Nvidia GPU "); +#else /*NVIDIA_GPU */ +#ifdef POWER + mvwprintw(padhelp, 8, 39, "| p = if(PowerVM) LPAR details"); +#endif /*POWER*/ +#endif /*NVIDIA_GPU */ + mvwprintw(padhelp, 9, 1, + "t = TopProcess 1=Priority/Nice/State | u = TopProc with command line"); + mvwprintw(padhelp, 10, 1, + " ReOrder by: 3=CPU 4=RAM 5=I/O | Hit u twice to update"); + mvwprintw(padhelp, 11, 1, + "g = User Defined Disk Groups | G = with -g switches Disk graphs"); + mvwprintw(padhelp, 12, 1, + " [start nmon with -g ] | to disk groups only"); + mvwprintw(padhelp, 13, 39, "| b = black & white mode"); + mvwprintw(padhelp, 14, 1, + "Other Controls: |"); + mvwprintw(padhelp, 15, 1, + "+ = double the screen refresh time | 0 = reset peak marks (\">\") to zero"); + mvwprintw(padhelp, 16, 1, + "- = half the screen refresh time | space refresh screen now"); + mvwprintw(padhelp, 17, 1, + ". = Display only busy disks & CPU | q = Quit"); +/* mvwprintw(padhelp,18, 1, "v = Verbose Simple Checks - OK/Warnings/Danger"); */ + + mvwprintw(padhelp, 19, 1, + "(C) Copyright 2009 Nigel Griffiths | See http://nmon.sourceforge.net"); + mvwprintw(padhelp, 20, 1, "Colour:"); + for (i = 0; i < 13; i++) { + COLOUR wattrset(padhelp, COLOR_PAIR(i)); + mvwprintw(padhelp, 20, 8 + i * 5, "#%d#", i); + } + COLOUR wattrset(padhelp, COLOR_PAIR(0)); + DISPLAY(padhelp, 21); + + } +/* for debugging use only + if(error_on && errorstr[0] != 0) { + mvprintw(x, 0, "Error: %s ",errorstr); + x = x + 1; + } +*/ + if (show_res && cursed) { + proc_read(P_CPUINFO); + proc_read(P_VERSION); + + BANNER(padres, "Resources Linux & Processor"); + COLOUR wattrset(padres, COLOR_PAIR(2)); + mvwprintw(padres, 1, 4, "Linux: %s", proc[P_VERSION].line[0]); + mvwprintw(padres, 2, 4, "Build: %s", proc[P_VERSION].line[1]); + mvwprintw(padres, 3, 4, "Release : %s", uts.release); + mvwprintw(padres, 4, 4, "Version : %s", uts.version); + COLOUR wattrset(padres, COLOR_PAIR(3)); +#ifdef POWER + mvwprintw(padres, 5, 4, "cpuinfo: %s", + proc[P_CPUINFO].line[1]); + mvwprintw(padres, 6, 4, "cpuinfo: %s", + proc[P_CPUINFO].line[2]); + mvwprintw(padres, 7, 4, "cpuinfo: %s", + proc[P_CPUINFO].line[3]); + mvwprintw(padres, 8, 4, "cpuinfo: %s %s", + proc[P_CPUINFO].line[proc[P_CPUINFO].lines - 2], + proc[P_CPUINFO].line[proc[P_CPUINFO].lines - 1]); + /* needs lparcfg to be already processed */ + proc_lparcfg(); + switch (power_vm_type) { + case VM_POWERKVM_GUEST: + mvwprintw(padres, 9, 20, + "PowerKVM Guest Physical CPU:%d & Virtual CPU (SMT):%d %s", + lparcfg.partition_active_processors, cpus, + lscpu.byte_order); + break; + case VM_POWERKVM_HOST: + mvwprintw(padres, 9, 20, + "PowerKVM Host Physical CPU:%d %s", cpus, + lscpu.byte_order); + break; + case VM_POWERVM: + mvwprintw(padres, 9, 20, + "PowerVM Physical CPU:%d & Logical CPU:%d %s", + lparcfg.partition_active_processors, cpus, + lscpu.byte_order); + break; + case VM_NATIVE: + mvwprintw(padres, 9, 20, "Native Mode Physical CPU:%d %s", + cpus, lscpu.byte_order); + break; + } +#endif /* POWER */ +#ifdef MAINFRAME + mvwprintw(padres, 5, 4, "cpuinfo: %s", + proc[P_CPUINFO].line[1]); + mvwprintw(padres, 6, 4, "cpuinfo: %s", + proc[P_CPUINFO].line[2]); + mvwprintw(padres, 7, 4, "cpuinfo: %s", + proc[P_CPUINFO].line[3]); + mvwprintw(padres, 8, 4, "cpuinfo: %s", + proc[P_CPUINFO].line[4]); +#endif/* MAINFRAME */ +#ifdef X86 + mvwprintw(padres, 5, 4, "cpuinfo: Vendor=%s Model=%s", vendor_ptr, model_ptr); + mvwprintw(padres, 6, 4, "cpuinfo: Hz=%s bogomips=%s", mhz_ptr, bogo_ptr); + + if (processorchips || cores || hyperthreads || cpus) { + mvwprintw(padres, 7, 4, + "cpuinfo: ProcessorChips=%d PhysicalCores=%d", + processorchips, cores); + mvwprintw(padres, 8, 4, + "cpuinfo: Hyperthreads =%d VirtualCPUs =%d", + hyperthreads, cpus); + } +#endif /* X86 */ +#ifdef ARM + mvwprintw(padres, 5, 4, "cpuinfo: Vendor=%s Model=%s BogoMIPS=%s", vendor_ptr, model_ptr, bogo_ptr); + mvwprintw(padres, 6, 4, "lscpu: CPU=%d %s", lscpu.cpus, lscpu.byte_order); + mvwprintw(padres, 7, 4, "lscpu: Sockets=%d Cores=%d Thrds=%d", lscpu.sockets, lscpu.cores, lscpu.threads); + mvwprintw(padres, 8, 4, "lscpu: max=%d min=%d", lscpu.mhz_max, lscpu.mhz_min); + +#endif /* ARM */ + mvwprintw(padres, 9, 4, "# of CPUs: %d", cpus); + COLOUR wattrset(padres, COLOR_PAIR(5)); + mvwprintw(padres, 10, 4, "Machine : %s", uts.machine); + mvwprintw(padres, 11, 4, "Nodename : %s", uts.nodename); + COLOUR wattrset(padres, COLOR_PAIR(6)); + mvwprintw(padres, 12, 4, "/etc/*ease[1]: %s", easy[0]); + mvwprintw(padres, 13, 4, "/etc/*ease[2]: %s", easy[1]); + mvwprintw(padres, 14, 4, "/etc/*ease[3]: %s", easy[2]); + mvwprintw(padres, 15, 4, "/etc/*ease[4]: %s", easy[3]); + COLOUR wattrset(padres, COLOR_PAIR(2)); + mvwprintw(padres, 16, 4, "lsb_release: %s", lsb_release[0]); + mvwprintw(padres, 17, 4, "lsb_release: %s", lsb_release[1]); + mvwprintw(padres, 18, 4, "lsb_release: %s", lsb_release[2]); + mvwprintw(padres, 19, 4, "lsb_release: %s", lsb_release[3]); + COLOUR wattrset(padres, COLOR_PAIR(0)); + DISPLAY(padres, 20); + } + if (show_longterm) { + proc_read(P_STAT); + proc_cpu(); + cpu_user = RAWTOTAL(user) + RAWTOTAL(nice); + cpu_sys = + RAWTOTAL(sys) + RAWTOTAL(irq) + RAWTOTAL(softirq) ; + /* + RAWTOTAL(guest) + RAWTOTAL(guest_nice); these are in addition to the 100% */ + cpu_wait = RAWTOTAL(wait); + cpu_idle = RAWTOTAL(idle); + cpu_steal = RAWTOTAL(steal); + /* DEBUG inject steal cpu_steal = cpu_sys; */ + cpu_sum = cpu_idle + cpu_user + cpu_sys + cpu_wait + cpu_steal; + + save_snap((double) cpu_user / (double) cpu_sum * 100.0, + (double) cpu_sys / (double) cpu_sum * 100.0, + (double) cpu_wait / (double) cpu_sum * 100.0, + (double) cpu_idle / (double) cpu_sum * 100.0, + (double) cpu_steal / (double) cpu_sum * 100.0); + plot_snap(padlong); + DISPLAY(padlong, MAX_SNAP_ROWS + 2); + } + if (show_smp || show_verbose || show_wide) { + proc_read(P_STAT); + proc_cpu(); + if (cpus > max_cpus && !cursed) { + for (i = max_cpus + 1; i <= cpus; i++) + fprintf(fp, + "CPU%03d,CPU %d %s,User%%,Sys%%,Wait%%,Idle%%\n", + i, i, run_name); + max_cpus = cpus; + } + if (old_cpus != cpus) { + if (!cursed) { + if (bbbr_line == 0) { + fprintf(fp, "BBBR,0,Reconfig,action,old,new\n"); + bbbr_line++; + } + fprintf(fp, "BBBR,%03d,%s,cpuchg,%d,%d\n", bbbr_line++, + LOOP, old_cpus, cpus); + } else { + /* wmove(padsmp,0,0); */ + /* doesn't work CURSE wclrtobot(padsmp); */ + /* Do BRUTE force overwrite of previous data */ + if (cpus < old_cpus) { + for (i = cpus; i < old_cpus; i++) + mvwprintw(padsmp, i + 4, 0, + " "); + } + } + } + if (show_smp) { + if (cursed) { + BANNER(padsmp, "CPU Utilisation"); + + /* mvwprintw(padsmp,1, 0, cpu_line); */ + /* + *mvwprintw(padsmp,2, 0, "CPU User%% Sys%% Wait%% Idle|0 |25 |50 |75 100|"); + */ + mvwprintw(padsmp, 1, 0, cpu_line); + mvwprintw(padsmp, 2, 0, "CPU "); + COLOUR wattrset(padsmp, COLOR_PAIR(2)); /* Green */ + mvwprintw(padsmp, 2, 4, "User%%"); + COLOUR wattrset(padsmp, COLOR_PAIR(1)); /* Red */ + mvwprintw(padsmp, 2, 9, " Sys%%"); + COLOUR wattrset(padsmp, COLOR_PAIR(4)); /* Blue */ + mvwprintw(padsmp, 2, 15, " Wait%%"); + if (p->cpu_total.steal != q->cpu_total.steal) { + COLOUR wattrset(padsmp, COLOR_PAIR(5)); + mvwprintw(padsmp, 2, 22, "Steal"); + } else { + COLOUR wattrset(padsmp, COLOR_PAIR(0)); + mvwprintw(padsmp, 2, 22, " Idle"); + } + COLOUR wattrset(padsmp, COLOR_PAIR(0)); + mvwprintw(padsmp, 2, 27, + "|0 |25 |50 |75 100|"); + } /* if (show_smp) AND if(cursed) */ +#ifdef POWER + /* Always get lpar info as well so we can report physical CPU usage + * to make data more meaningful + * This assumes that LPAR info is available in q and p ! + */ + if (proc_lparcfg() > 0) { + if (lparcfg.shared_processor_mode == 1) { + if (lparcfg.timebase == -1) { + lparcfg.timebase = 0; + proc_read(P_CPUINFO); + for (i = 0; i < proc[P_CPUINFO].lines - 1; i++) { + if (!strncmp + ("timebase", proc[P_CPUINFO].line[i], + 8)) { + sscanf(proc[P_CPUINFO].line[i], + "timebase : %lld", + &lparcfg.timebase); + break; + } + } + } else { + /* PowerKVM Host or Guest or Native have not Entitlement stats */ + if (power_vm_type == VM_POWERVM) + mvwprintw(padsmp, 1, 30, + "EntitledCPU=% 6.3f", + (double) lparcfg. + partition_entitled_capacity / + 100.0); + /* Only if the calculation is working */ + if (lparcfg.purr_diff != 0) + mvwprintw(padsmp, 1, 50, + "PhysicalCPUused=% 7.3f", + (double) lparcfg.purr_diff / + (double) lparcfg.timebase / + elapsed); + } + } + } +#endif + for (i = 0; i < cpus; i++) { + cpu_user = RAW(user) + RAW(nice); + cpu_sys = + RAW(sys) + RAW(irq) + RAW(softirq); + /* + RAW(guest) + RAW(guest_nice); these are in addition to the 100% */ + cpu_wait = RAW(wait); + cpu_idle = RAW(idle); + cpu_steal = RAW(steal); +/* DEBUG inject steal cpu_steal = cpu_sys; */ + cpu_sum = + cpu_idle + cpu_user + cpu_sys + cpu_wait + + cpu_steal; + /* Check if we had a CPU # change and have to set idle to 100 */ + if (cpu_sum == 0) + cpu_sum = cpu_idle = 100.0; + if (smp_first_time && cursed) { + if (i == 0) + mvwprintw(padsmp, 3 + i, 27, + "| Please wait gathering CPU statistics"); + else + mvwprintw(padsmp, 3 + i, 27, "|"); + mvwprintw(padsmp, 3 + i, 77, "|"); + } else { +#ifdef POWER + /* lparcfg gathered above */ + if (lparcfg.smt_mode > 1 + && i % lparcfg.smt_mode == 0) { + mvwprintw(padsmp, 3 + i, 27, "*"); + mvwprintw(padsmp, 3 + i, 77, "*"); + } +#endif + plot_smp(padsmp, i + 1, 3 + i, + (double) cpu_user / (double) cpu_sum * + 100.0, + (double) cpu_sys / (double) cpu_sum * + 100.0, + (double) cpu_wait / (double) cpu_sum * + 100.0, + (double) cpu_idle / (double) cpu_sum * + 100.0, + (double) cpu_steal / (double) cpu_sum * + 100.0); +#ifdef POWER + /* lparcfg gathered above */ + if (lparcfg.smt_mode > 1 + && i % lparcfg.smt_mode == 0) { + mvwprintw(padsmp, 3 + i, 27, "*"); + mvwprintw(padsmp, 3 + i, 77, "*"); + } +#endif + + RRD fprintf(fp, + "rrdtool update cpu%02d.rrd %s:%.1f:%.1f:%.1f:%.1f\n", + i, LOOP, + (double) cpu_user / (double) cpu_sum * + 100.0, + (double) cpu_sys / (double) cpu_sum * + 100.0, + (double) cpu_wait / (double) cpu_sum * + 100.0, + (double) cpu_idle / (double) cpu_sum * + 100.0); + } + } /* for (i = 0; i < cpus; i++) */ + CURSE mvwprintw(padsmp, i + 3, 0, cpu_line); +#ifdef POWER + /* proc_lparcfg called above in previous ifdef + */ + if (lparcfg.shared_processor_mode == 1) { + if (lparcfg.timebase == -1) { + lparcfg.timebase = 0; + proc_read(P_CPUINFO); + for (i = 0; i < proc[P_CPUINFO].lines - 1; i++) { + if (!strncmp + ("timebase", proc[P_CPUINFO].line[i], 8)) { + sscanf(proc[P_CPUINFO].line[i], + "timebase : %lld", + &lparcfg.timebase); + break; + } + } + } else { + mvwprintw(padsmp, i + 3, 29, "%s", + lparcfg. + shared_processor_mode ? "Shared" : + "Dedicated"); + mvwprintw(padsmp, i + 3, 39, "|"); + /* PowerKVM has no Capped concept */ + if (power_vm_type == VM_POWERVM) + mvwprintw(padsmp, i + 3, 41, "%s", + lparcfg. + capped ? "--Capped" : "Uncapped"); + mvwprintw(padsmp, i + 3, 51, "|"); + mvwprintw(padsmp, i + 3, 54, "SMT=%d", + lparcfg.smt_mode); + mvwprintw(padsmp, i + 3, 64, "|"); + mvwprintw(padsmp, i + 3, 67, "VP=%.0f", + (float) lparcfg. + partition_active_processors); + } + } +#endif + cpu_user = RAWTOTAL(user) + RAWTOTAL(nice); + cpu_sys = + RAWTOTAL(sys) + RAWTOTAL(irq) + RAWTOTAL(softirq); + /* + RAWTOTAL(guest) + RAWTOTAL(guest_nice); these are in addition to the 100% */ + cpu_wait = RAWTOTAL(wait); + cpu_idle = RAWTOTAL(idle); + cpu_steal = RAWTOTAL(steal); +/* DEBUG inject steal cpu_steal = cpu_sys; */ + cpu_sum = + cpu_idle + cpu_user + cpu_sys + cpu_wait + cpu_steal; + + /* Check if we had a CPU # change and have to set idle to 100 */ + if (cpu_sum == 0) + cpu_sum = cpu_idle = 100.0; + + RRD fprintf(fp, + "rrdtool update cpu.rrd %s:%.1f:%.1f:%.1f:%.1f%.1f\n", + LOOP, + (double) cpu_user / (double) cpu_sum * 100.0, + (double) cpu_sys / (double) cpu_sum * 100.0, + (double) cpu_wait / (double) cpu_sum * 100.0, + (double) cpu_idle / (double) cpu_sum * 100.0, + (double) cpu_steal / (double) cpu_sum * 100.0); + if (cpus > 1 || !cursed) { + if (!smp_first_time || !cursed) { + plot_smp(padsmp, 0, 4 + i, + (double) cpu_user / (double) cpu_sum * + 100.0, + (double) cpu_sys / (double) cpu_sum * + 100.0, + (double) cpu_wait / (double) cpu_sum * + 100.0, + (double) cpu_idle / (double) cpu_sum * + 100.0, + (double) cpu_steal / (double) cpu_sum * + 100.0); + } + + CURSE mvwprintw(padsmp, i + 5, 0, cpu_line); + i = i + 2; + } /* if (cpus > 1 || !cursed) */ + smp_first_time = 0; + DISPLAY(padsmp, i + 4); + } /* if (show_smp) */ + if (show_wide) { + if (cursed) { + int rows = 0; + BANNER(padwide, "CPU Utilisation Wide View"); + char *wide1 = + "100%%-+--------+---------+---------+---------+---------+---------+-----+100%%"; + char *wide2 = + " 90%%-| |-90%%"; + char *wide3 = + " 80%%-| |-80%%"; + char *wide4 = + " 70%%-| |-70%%"; + char *wide5 = + " 60%%-| |-60%%"; + char *wide6 = + " 50%%-| |-50%%"; + char *wide7 = + " 40%%-| |-40%%"; + char *wide8 = + " 30%%-| |-30%%"; + char *wide9 = + " 20%%-| |-20%%"; + char *wide10 = + " 10%%-| |-10%%"; + + mvwprintw(padwide, 1, 0, wide1); + mvwprintw(padwide, 2, 0, wide2); + mvwprintw(padwide, 3, 0, wide3); + mvwprintw(padwide, 4, 0, wide4); + mvwprintw(padwide, 5, 0, wide5); + mvwprintw(padwide, 6, 0, wide6); + mvwprintw(padwide, 7, 0, wide7); + mvwprintw(padwide, 8, 0, wide8); + mvwprintw(padwide, 9, 0, wide9); + mvwprintw(padwide, 10, 0, wide10); + mvwprintw(padwide, 11, 0, + " CPU +1--------+10-------+20-------+30-------+40-------+50-------+60--+--0%%"); + mvwprintw(padwide, 1, 6, "CPU(s)=%d", cpus); + if (wide_first_time) { + mvwprintw(padwide, 3, 7, + " Please wait gathering CPU statistics"); + } else { + for (i = 0; i < cpus && i < 64; i++) { + cpu_user = RAW(user) + RAW(nice); + cpu_sys = + RAW(sys) + RAW(irq) + RAW(softirq); + /* + RAW(guest) + RAW(guest_nice); these are in addition to the 100% */ + cpu_sum = cpu_user + cpu_sys; + COLOUR wattrset(padwide, COLOR_PAIR(4)); /* blue */ + if (i % 2) { + mvwprintw(padwide, 6, 6 + i, "."); + } + if (cpu_sum > 75) { + COLOUR wattrset(padwide, COLOR_PAIR(1)); /*red */ + } else { + if (cpu_sum > 50) { + COLOUR wattrset(padwide, COLOR_PAIR(5)); /*magenta */ + } else { + COLOUR wattrset(padwide, COLOR_PAIR(2)); /*green */ + } + } + for (j = 1, k = 10; j < 10; j++, k--) + if (cpu_sum > j * 10.0) + mvwprintw(padwide, k, 6 + i, "#"); + COLOUR wattrset(padwide, COLOR_PAIR(0)); /* white */ + if (0.1 < cpu_sum && cpu_sum < 5.0) + mvwprintw(padwide, 10, 6 + i, "."); + if (5.1 <= cpu_sum && cpu_sum < 10.0) + mvwprintw(padwide, 10, 6 + i, "o"); + } + if (cpus < 64) + for (j = 2; j <= 10; j++) + mvwprintw(padwide, j, 6 + i, "|"); + rows = 12; + } + if (cpus > 63) { + mvwprintw(padwide, rows + 0, 0, wide1); + mvwprintw(padwide, rows + 1, 0, wide2); + mvwprintw(padwide, rows + 2, 0, wide3); + mvwprintw(padwide, rows + 3, 0, wide4); + mvwprintw(padwide, rows + 4, 0, wide5); + mvwprintw(padwide, rows + 5, 0, wide6); + mvwprintw(padwide, rows + 6, 0, wide7); + mvwprintw(padwide, rows + 7, 0, wide8); + mvwprintw(padwide, rows + 8, 0, wide9); + mvwprintw(padwide, rows + 9, 0, wide10); + mvwprintw(padwide, rows + 10, 0, + " CPU +65---+70-------+80-------+90-------+100------+110------+120-----+--0%%"); + if (wide_first_time) { + mvwprintw(padwide, rows + 3, 7, + " Please wait gathering CPU statistics"); + } else { + for (i = 64; i < cpus && i < 128; i++) { + cpu_user = RAW(user) + RAW(nice); + cpu_sys = + RAW(sys) + RAW(irq) + RAW(softirq); + /* + RAW(guest) + RAW(guest_nice); these are in addition to the 100% */ + cpu_sum = cpu_user + cpu_sys; + COLOUR wattrset(padwide, COLOR_PAIR(4)); /* blue */ + if (i % 2) { + mvwprintw(padwide, rows + 5, + 6 + i - 64, "."); + } + if (cpu_sum > 75) { + COLOUR wattrset(padwide, COLOR_PAIR(1)); /*red */ + } else { + if (cpu_sum > 50) { + COLOUR wattrset(padwide, COLOR_PAIR(5)); /*magenta */ + } else { + COLOUR wattrset(padwide, COLOR_PAIR(2)); /*green */ + } + } + for (j = 1, k = rows + 9; j < 10; j++, k--) + if (cpu_sum > j * 10.0) + mvwprintw(padwide, k, 6 + i - 64, + "#"); + COLOUR wattrset(padwide, COLOR_PAIR(0)); /* white */ + if (0.1 < cpu_sum && cpu_sum < 5.0) + mvwprintw(padwide, rows + 9, + 6 + i - 64, "."); + if (5.1 <= cpu_sum && cpu_sum < 10.0) + mvwprintw(padwide, rows + 9, + 6 + i - 64, "o"); + } + + if (cpus < 128) + COLOUR wattrset(padwide, COLOR_PAIR(4)); /* blue */ + for (j = rows; j <= rows + 9; j++) + mvwprintw(padwide, j, 6 + i - 64, "<"); + COLOUR wattrset(padwide, COLOR_PAIR(0)); /* white */ + } + rows = 23; + } + if (cpus > 127) { + mvwprintw(padwide, rows + 0, 0, wide1); + mvwprintw(padwide, rows + 1, 0, wide2); + mvwprintw(padwide, rows + 2, 0, wide3); + mvwprintw(padwide, rows + 3, 0, wide4); + mvwprintw(padwide, rows + 4, 0, wide5); + mvwprintw(padwide, rows + 5, 0, wide6); + mvwprintw(padwide, rows + 6, 0, wide7); + mvwprintw(padwide, rows + 7, 0, wide8); + mvwprintw(padwide, rows + 8, 0, wide9); + mvwprintw(padwide, rows + 9, 0, wide10); + mvwprintw(padwide, rows + 10, 0, + " CPU +129--------+140------+150------+160------+170------+180------+190--0%%"); + if (wide_first_time) { + mvwprintw(padwide, rows + 3, 7, + " Please wait gathering CPU statistics"); + } else { + for (i = 128; i < cpus && i < 196; i++) { + cpu_user = RAW(user) + RAW(nice); + cpu_sys = + RAW(sys) + RAW(irq) + RAW(softirq); + /* + RAW(guest) + RAW(guest_nice); these are in addition of the 100% */ + cpu_sum = cpu_user + cpu_sys; + COLOUR wattrset(padwide, COLOR_PAIR(4)); /* blue */ + if (i % 2) { + mvwprintw(padwide, rows + 5, + 6 + i - 128, "."); + } + if (cpu_sum > 75) { + COLOUR wattrset(padwide, COLOR_PAIR(1)); /*red */ + } else { + if (cpu_sum > 50) { + COLOUR wattrset(padwide, COLOR_PAIR(5)); /*magenta */ + } else { + COLOUR wattrset(padwide, COLOR_PAIR(2)); /*green */ + } + } + for (j = 1, k = rows + 9; j < 10; j++, k--) + if (cpu_sum > j * 10.0) + mvwprintw(padwide, k, 6 + i - 128, + "#"); + COLOUR wattrset(padwide, COLOR_PAIR(0)); /* white */ + if (0.1 < cpu_sum && cpu_sum < 5.0) + mvwprintw(padwide, rows + 9, + 6 + i - 128, "."); + if (5.1 <= cpu_sum && cpu_sum < 10.0) + mvwprintw(padwide, rows + 9, + 6 + i - 128, "o"); + } + + if (cpus < 196) + COLOUR wattrset(padwide, COLOR_PAIR(4)); /* blue */ + for (j = rows; j <= rows + 9; j++) + mvwprintw(padwide, j, 6 + i - 128, "<"); + COLOUR wattrset(padwide, COLOR_PAIR(0)); /* white */ + } + rows = 34; + } + wide_first_time = 0; + DISPLAY(padwide, rows); + } + proc_read(P_STAT); + proc_cpu(); + + if (show_verbose && cursed) { + cpu_user = RAWTOTAL(user) + RAWTOTAL(nice); + cpu_sys = + RAWTOTAL(sys) + RAWTOTAL(irq) + RAWTOTAL(softirq); + /* + RAWTOTAL(guest) + RAWTOTAL(guest_nice); these are in addition to the 100% */ + cpu_wait = RAWTOTAL(wait); + cpu_idle = RAWTOTAL(idle) + RAWTOTAL(steal); + cpu_sum = cpu_idle + cpu_user + cpu_sys + cpu_wait; + + cpu_busy = + (double) (cpu_user + + cpu_sys) / (double) cpu_sum *100.0; + mvwprintw(padverb, 2, 0, + " -> CPU %%busy %5.1f%%\t>80%%\t>90%% ", + cpu_busy); + if (cpu_busy > 90.0) { + COLOUR wattrset(padverb, COLOR_PAIR(1)); + mvwprintw(padverb, 2, 0, " DANGER"); + } else if (cpu_busy > 80.0) { + COLOUR wattrset(padverb, COLOR_PAIR(4)); + mvwprintw(padverb, 2, 0, "Warning"); + } else { + COLOUR wattrset(padverb, COLOR_PAIR(2)); + mvwprintw(padverb, 2, 0, " OK"); + } + COLOUR wattrset(padverb, COLOR_PAIR(0)); + } + + } /* if (cursed) */ + } /* if (show_smp || show_verbose) */ + if (show_util) { + proc_read(P_STAT); + proc_cpu(); + if (cursed) { + BANNER(padutil, "CPU Utilisation Stats"); + mvwprintw(padutil, 2, 0, "CPU"); + for (i = 0; i < cpus; i++) + mvwprintw(padutil, 3 + i, 0, "%3d", i + 1); + mvwprintw(padutil, 1, 0, "ALL"); + if (first_util) { + mvwprintw(padutil, 5, 27, + " Please wait gathering CPU statistics"); + } else { + COLOUR wattrset(padutil, COLOR_PAIR(2)); /* Green */ + mvwprintw(padutil, 2, 4, " User%%"); + for (i = 0; i < cpus; i++) + mvwprintw(padutil, 3 + i, 4, "%7.1f", + RAW(user) / elapsed); + mvwprintw(padutil, 1, 4, "%7.1f", + RAWTOTAL(user) / elapsed); + mvwprintw(padutil, 2, 11, " Nice%%"); + for (i = 0; i < cpus; i++) + mvwprintw(padutil, 3 + i, 11, "%7.1f", + RAW(nice) / elapsed); + mvwprintw(padutil, 1, 11, "%7.1f", + RAWTOTAL(nice) / elapsed); + + COLOUR wattrset(padutil, COLOR_PAIR(1)); /* Red */ + mvwprintw(padutil, 2, 18, " Sys%%"); + for (i = 0; i < cpus; i++) + mvwprintw(padutil, 3 + i, 18, "%7.1f", + RAW(sys) / elapsed); + mvwprintw(padutil, 1, 18, "%7.1f", + RAWTOTAL(sys) / elapsed); + + COLOUR wattrset(padutil, COLOR_PAIR(3)); /* Yellow */ + mvwprintw(padutil, 2, 25, " Idle%%"); + for (i = 0; i < cpus; i++) + mvwprintw(padutil, 3 + i, 25, "%7.1f", + RAW(idle) / elapsed); + mvwprintw(padutil, 1, 25, "%7.1f", + RAWTOTAL(idle) / elapsed); + mvwprintw(padutil, 2, 32, " Wait%%"); + for (i = 0; i < cpus; i++) + mvwprintw(padutil, 3 + i, 32, "%7.1f", + RAW(wait) / elapsed); + mvwprintw(padutil, 1, 32, "%7.1f", + RAWTOTAL(wait) / elapsed); + + COLOUR wattrset(padutil, COLOR_PAIR(1)); /* Red */ + mvwprintw(padutil, 2, 39, " HWirq%%"); + for (i = 0; i < cpus; i++) + mvwprintw(padutil, 3 + i, 39, "%7.1f", + RAW(irq) / elapsed); + mvwprintw(padutil, 1, 39, "%7.1f", + RAWTOTAL(irq) / elapsed); + mvwprintw(padutil, 2, 46, " SWirq%%"); + for (i = 0; i < cpus; i++) + mvwprintw(padutil, 3 + i, 46, "%7.1f", + RAW(softirq) / elapsed); + mvwprintw(padutil, 1, 46, "%7.1f", + RAWTOTAL(softirq) / elapsed); + + COLOUR wattrset(padutil, COLOR_PAIR(5)); /* Magenta */ + mvwprintw(padutil, 2, 53, " Steal%%"); + for (i = 0; i < cpus; i++) + mvwprintw(padutil, 3 + i, 53, "%7.1f", + RAW(steal) / elapsed); + mvwprintw(padutil, 1, 53, "%7.1f", + RAWTOTAL(steal) / elapsed); + + COLOUR wattrset(padutil, COLOR_PAIR(6)); /* Cyan */ + mvwprintw(padutil, 2, 60, " Guest%%"); + for (i = 0; i < cpus; i++) + mvwprintw(padutil, 3 + i, 60, "%7.1f", + RAW(guest) / elapsed); + mvwprintw(padutil, 1, 60, "%7.1f", + RAWTOTAL(guest) / elapsed); + mvwprintw(padutil, 2, 67, " GuestNice%%"); + for (i = 0; i < cpus; i++) + mvwprintw(padutil, 3 + i, 67, "%7.1f", + RAW(guest_nice) / elapsed); + mvwprintw(padutil, 1, 67, "%7.1f", + RAWTOTAL(guest_nice) / elapsed); + } + COLOUR wattrset(padutil, COLOR_PAIR(0)); + DISPLAY(padutil, i + 3); + } else { + if (first_util) { + fprintf(fp, + "CPUUTIL_ALL,CPU Util Stats %s,User%%,Nice%%,Sys%%,Idle%%,Wait%%,Irq%%,Softirq%%,Steal%%,Guest%%,Guest_nice%%\n", + run_name); + for (i = 1; i <= cpus; i++) + fprintf(fp, + "CPUUTIL%03d,CPU Util Stats CPU%d %s,User%%,Nice%%,Sys%%,Idle%%,Wait%%,Irq%%,Softirq%%,Steal%%,Guest%%,Guest_nice%%\n", + i, i, run_name); + } + fprintf(fp, + "CPUUTIL_ALL,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f\n", + LOOP, RAWTOTAL(user) / elapsed, + RAWTOTAL(nice) / elapsed, RAWTOTAL(sys) / elapsed, + RAWTOTAL(idle) / elapsed, RAWTOTAL(wait) / elapsed, + RAWTOTAL(irq) / elapsed, + RAWTOTAL(softirq) / elapsed, + RAWTOTAL(steal) / elapsed, + RAWTOTAL(guest) / elapsed, + RAWTOTAL(guest_nice) / elapsed); + for (i = 0; i < cpus; i++) { + fprintf(fp, + "CPUUTIL%03d,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f\n", + i, LOOP, RAW(user) / elapsed, + RAW(nice) / elapsed, RAW(sys) / elapsed, + RAW(idle) / elapsed, RAW(wait) / elapsed, + RAW(irq) / elapsed, RAW(softirq) / elapsed, + RAW(steal) / elapsed, RAW(guest) / elapsed, + RAW(guest_nice) / elapsed); + } + } + first_util = 0; + } +#ifdef POWER + if (show_lpar) { + if (lparcfg.timebase == -1) { + lparcfg.timebase = 0; + proc_read(P_CPUINFO); + for (i = 0; i < proc[P_CPUINFO].lines - 1; i++) { + if (!strncmp("timebase", proc[P_CPUINFO].line[i], 8)) { + sscanf(proc[P_CPUINFO].line[i], "timebase : %lld", + &lparcfg.timebase); + break; + } + } + } + ret = proc_lparcfg(); + if (cursed) { + BANNER(padlpar, "PowerVM LPAR"); + if (ret == 0) { + COLOUR wattrset(padlpar, COLOR_PAIR(1)); + mvwprintw(padlpar, 2, 0, + "Reading data from /proc/ppc64/lparcfg failed"); + mvwprintw(padlpar, 3, 0, + "This is probably a Native Virtual Machine"); + COLOUR wattrset(padlpar, COLOR_PAIR(0)); + } else + if (power_vm_type == VM_POWERKVM_HOST + || power_vm_type == VM_POWERKVM_GUEST) { + COLOUR wattrset(padlpar, COLOR_PAIR(5)); + mvwprintw(padlpar, 2, 0, + "Reading data from /proc/ppc64/lparcfg mostly failed"); + mvwprintw(padlpar, 3, 0, + "PowerKVM does not many of these stats"); + COLOUR wattrset(padlpar, COLOR_PAIR(0)); + } else { + mvwprintw(padlpar, 1, 0, + "LPAR=%d SerialNumber=%s Type=%s", + lparcfg.partition_id, lparcfg.serial_number, + lparcfg.system_type); + mvwprintw(padlpar, 2, 0, + "Flags: Shared-CPU=%-5s Capped=%-5s SMT-mode=%d", + lparcfg. + shared_processor_mode ? "true" : "false", + lparcfg.capped ? "true" : "false", + lparcfg.smt_mode); + COLOUR wattrset(padlpar, COLOR_PAIR(2)); + mvwprintw(padlpar, 3, 0, + "Systems CPU Pool=%8.2f Active=%8.2f Total=%8.2f", + (float) lparcfg.pool_capacity / 100.0, + (float) lparcfg.system_active_processors, + (float) lparcfg.system_potential_processors); + COLOUR wattrset(padlpar, COLOR_PAIR(3)); + mvwprintw(padlpar, 4, 0, + "LPARs CPU Min=%8.2f Entitlement=%8.2f Max=%8.2f", + lparcfg.MinEntCap / 100.0, + lparcfg.partition_entitled_capacity / 100.0, + lparcfg.partition_max_entitled_capacity / + 100.0); + COLOUR wattrset(padlpar, COLOR_PAIR(5)); + mvwprintw(padlpar, 5, 0, + "Virtual CPU Min=%8.2f VP Now=%8.2f Max=%8.2f", + (float) lparcfg.MinProcs, + (float) lparcfg.partition_active_processors, + (float) lparcfg. + partition_potential_processors); + COLOUR wattrset(padlpar, COLOR_PAIR(6)); + mvwprintw(padlpar, 6, 0, + "Memory Min=%8.2f Desired=%8.2f ", + (float) lparcfg.MinMem, + (float) lparcfg.DesMem); + COLOUR wattrset(padlpar, COLOR_PAIR(0)); + mvwprintw(padlpar, 7, 0, + "Other Weight=%8.2f UnallocWeight=%8.2f Capacity=%8.2f", + (float) lparcfg.capacity_weight, + (float) lparcfg.unallocated_capacity_weight, + (float) lparcfg.CapInc / 100.0); + + mvwprintw(padlpar, 8, 0, + " BoundThrds=%8.2f UnallocCapacity=%8.2f Increment", + (float) lparcfg.BoundThrds, + (float) lparcfg.unallocated_capacity); + if (lparcfg.purr_diff == 0 || lparcfg.timebase < 1) { + mvwprintw(padlpar, 9, 0, + "lparcfg: purr field always zero, upgrade to SLES9+sp1 or RHEL4+u1"); + } else { + if (lpar_first_time) { + mvwprintw(padlpar, 9, 0, + "Please wait gathering data"); + + lpar_first_time = 0; + } else { + COLOUR wattrset(padlpar, COLOR_PAIR(1)); + mvwprintw(padlpar, 9, 0, + "Physical CPU use=%8.3f ", + (double) lparcfg.purr_diff / + (double) lparcfg.timebase / elapsed); + if (lparcfg.pool_idle_time != NUMBER_NOT_VALID + && lparcfg.pool_idle_saved != 0) + mvwprintw(padlpar, 9, 29, + "PoolIdleTime=%8.2f", + (double) lparcfg.pool_idle_diff / + (double) lparcfg.timebase / + elapsed); + COLOUR wattrset(padlpar, COLOR_PAIR(0)); + mvwprintw(padlpar, 9, 54, "[timebase=%lld]", + lparcfg.timebase); + } + } + } + DISPLAY(padlpar, 10); + } else { + /* Only print LPAR info to spreadsheet if in shared processor mode */ + if (ret != 0 && (lparcfg.shared_processor_mode > 0 || lparcfg.DedDonMode > 0) + && power_vm_type == VM_POWERVM) + fprintf(fp, "LPAR,%s,%9.6f,%d,%d,%d,%d,%d,%.2f,%.2f,%.2f,%d,%d,%d,%d,%d,%d,%d,%d,%d,%.2f,%d\n", LOOP, (double) lparcfg.purr_diff / (double) lparcfg.timebase / elapsed, lparcfg.capped, lparcfg.shared_processor_mode, lparcfg.system_potential_processors, lparcfg.system_active_processors, lparcfg.pool_capacity /100, lparcfg.MinEntCap / 100.0, lparcfg.partition_entitled_capacity / 100.0, lparcfg.partition_max_entitled_capacity / 100.0, lparcfg.MinProcs, cpus, /* report logical CPU here so analyser graph CPU% vs VPs reports correctly */ + lparcfg.partition_active_processors, + lparcfg.partition_potential_processors, + lparcfg.capacity_weight, + lparcfg.unallocated_capacity_weight, + lparcfg.BoundThrds, + lparcfg.MinMem, + lparcfg.unallocated_capacity, + (double) lparcfg.pool_idle_diff / + (double) lparcfg.timebase / elapsed, + lparcfg.smt_mode); + } + } +#endif /*POWER*/ +#ifdef NVIDIA_GPU + if (show_gpu) { + if (!cursed && first_time_gpu) + gpu_init(); + for (i = 0; i < gpu_devices; i++) { + if (cursed && first_time_gpu) { + if (nvmlDeviceGetName + (gpu_device[i], &gpu_name[i][0], + 1024) != NVML_SUCCESS) + strcpy(gpu_name[i], "NVML API Failed"); + } + if (nvmlDeviceGetUtilizationRates + (gpu_device[i], &gpu_util[i]) != NVML_SUCCESS) { + gpu_util[i].gpu = 999; + gpu_util[i].memory = 999; + } + if (nvmlDeviceGetTemperature + (gpu_device[i], NVML_TEMPERATURE_GPU, + &gpu_temp[i]) != NVML_SUCCESS) + gpu_temp[i] = 999; + if (nvmlDeviceGetPowerUsage(gpu_device[i], &gpu_watts[i]) + != NVML_SUCCESS) + gpu_watts[i] = 999000; + if (nvmlDeviceGetClockInfo + (gpu_device[i], NVML_CLOCK_GRAPHICS, + &gpu_clock[i]) != NVML_SUCCESS) + gpu_clock[i] = 999; + } + if (cursed) { + first_time_gpu = 0; + BANNER(padgpu, "NVIDIA GPU Accelerator"); + + mvwprintw(padgpu, 1, 1, + "Driver Version:%s NVML Version: %s", + gpu_driver_version, gpu_nvml_version); + + mvwprintw(padgpu, 2, 1, "GPU"); + mvwprintw(padgpu, 3, 1, "No."); + COLOUR wattrset(padgpu, COLOR_PAIR(1)); + mvwprintw(padgpu, 3, 5, "GPU-MHz"); + COLOUR wattrset(padgpu, COLOR_PAIR(2)); + mvwprintw(padgpu, 2, 14, "GPU-Utilisation"); + mvwprintw(padgpu, 3, 14, "Processor-Memory"); + COLOUR wattrset(padgpu, COLOR_PAIR(3)); + mvwprintw(padgpu, 2, 31, "Temperature"); + mvwprintw(padgpu, 3, 31, " Centigrade"); + COLOUR wattrset(padgpu, COLOR_PAIR(5)); + mvwprintw(padgpu, 2, 44, "Power-Use"); + mvwprintw(padgpu, 3, 44, " Watts"); + COLOUR wattrset(padgpu, COLOR_PAIR(0)); + mvwprintw(padgpu, 2, 55, "Name"); + + for (i = 0; i < gpu_devices; i++) { + mvwprintw(padgpu, 4 + i, 1, "%3d", i); + COLOUR wattrset(padgpu, COLOR_PAIR(1)); + mvwprintw(padgpu, 4 + i, 5, "%7d", (int) gpu_clock[i]); + COLOUR wattrset(padgpu, COLOR_PAIR(2)); + mvwprintw(padgpu, 4 + i, 14, "%7d%% %7d%%", + (int) gpu_util[i].gpu, + (int) gpu_util[i].memory); + COLOUR wattrset(padgpu, COLOR_PAIR(3)); + mvwprintw(padgpu, 4 + i, 31, "%7d", (int) gpu_temp[i]); + COLOUR wattrset(padgpu, COLOR_PAIR(5)); + mvwprintw(padgpu, 4 + i, 44, "%7.2f", + (int) gpu_watts[i] / 1000.0); + COLOUR wattrset(padgpu, COLOR_PAIR(0)); + mvwprintw(padgpu, 4 + i, 55, "%-s", &gpu_name[i][0]); + } + DISPLAY(padgpu, 8); + } else { + if (!show_rrd) { + if (first_time_gpu) { + first_time_gpu = 0; + fprintf(fp, + "GPU_UTIL,NVidia GPU Utilisation Percent"); + for (i = 0; i < gpu_devices; i++) + fprintf(fp, ",GPU%d", i + 1); + fprintf(fp, "\n"); + fprintf(fp, + "GPU_MEM,NVidia Memory Utilisation Percent"); + for (i = 0; i < gpu_devices; i++) + fprintf(fp, ",GPU%d", i + 1); + fprintf(fp, "\n"); + fprintf(fp, "GPU_TEMP,NVidia Temperature C"); + for (i = 0; i < gpu_devices; i++) + fprintf(fp, ",GPU%d", i + 1); + fprintf(fp, "\n"); + fprintf(fp, "GPU_WATTS,NVidia Power Draw Watts"); + for (i = 0; i < gpu_devices; i++) + fprintf(fp, ",GPU%d", i + 1); + fprintf(fp, "\n"); + fprintf(fp, "GPU_MHZ,NVidia GPU MHz"); + for (i = 0; i < gpu_devices; i++) + fprintf(fp, ",GPU%d", i + 1); + fprintf(fp, "\n"); + } + fprintf(fp, "GPU_UTIL,%s", LOOP); + for (i = 0; i < gpu_devices; i++) + fprintf(fp, ",%d", (int) gpu_util[i].gpu); + fprintf(fp, "\n"); + fprintf(fp, "GPU_MEM,%s", LOOP); + for (i = 0; i < gpu_devices; i++) + fprintf(fp, ",%d", (int) gpu_util[i].memory); + fprintf(fp, "\n"); + fprintf(fp, "GPU_TEMP,%s", LOOP); + for (i = 0; i < gpu_devices; i++) + fprintf(fp, ",%d", (int) gpu_temp[i]); + fprintf(fp, "\n"); + fprintf(fp, "GPU_WATTS,%s", LOOP); + for (i = 0; i < gpu_devices; i++) + fprintf(fp, ",%d", (int) gpu_watts[i] / 1000); + fprintf(fp, "\n"); + fprintf(fp, "GPU_MHZ,%s", LOOP); + for (i = 0; i < gpu_devices; i++) + fprintf(fp, ",%d", (int) gpu_clock[i]); + fprintf(fp, "\n"); + } + } + } +#endif /*NVIDIA_GPU */ + if (show_mhz) { + int padline, lineno, cpuno, col, thrds, cores; +#ifdef POWER + char *clockstr = "clock "; +#define DATACOL 9 +#else + char *clockstr = "cpu MHz"; +#define DATACOL 11 +#endif /* POWER */ + proc_read(P_CPUINFO); + + if (cursed) { + /* + 0123456789012345678 + cpu MHz : 3336.183 Intel + clock : 3425.000000MHz Power + */ + lscpu_init(); +#ifdef POWER + if (lparcfg.smt_mode > lscpu.threads) + thrds = lparcfg.smt_mode; + else +#endif /*POWER*/ + thrds = lscpu.threads; + if (thrds < 1) + thrds = 1; + BANNER(padmhz, "CPU MHz per Core and Thread"); +#ifdef POWER + mvwprintw(padmhz, 1, 10, + "lparcfgSMT=%d lscpu.threads=%d mode=%d [1=AllCPUs 2=Cores 3=Graphs]", + lparcfg.smt_mode, lscpu.threads, show_mhz); +#else /*POWER */ + mvwprintw(padmhz, 1, 10, + "lscpu.threads=%d mode=%d [1=AllCPUs 2=Cores 3=Graphs]", + lscpu.threads, show_mhz); +#endif /*POWER */ + if (show_mhz == 1) + mvwprintw(padmhz, 2, 1, "CPU MHz "); + else + mvwprintw(padmhz, 2, 1, "Core MHz "); + if (show_mhz == 3) + mvwprintw(padmhz, 2, 10, + "---------1---------2---------3---------4---------5---------6 GHz"); + + col = 0; + cpuno = 1; + cores = 0; + padline = 3; + min_mhz = 999999999999999999.0; + max_mhz = 0.0; + for (lineno = 0; lineno < proc[P_CPUINFO].lines; lineno++) { + if (strncmp + (clockstr, proc[P_CPUINFO].line[lineno], + strlen(clockstr)) == 0) { + if (show_mhz == 1 + || ((show_mhz == 2 || show_mhz == 3) + && ((cpuno + 7) % thrds) == 0)) { + cores++; + mhz = 0.0; + sscanf(&proc[P_CPUINFO].line[lineno][DATACOL], + "%f", &mhz); + mvwprintw(padmhz, padline, col, "%3d=%4.0f", + (show_mhz != 1) ? cores : cpuno, mhz); + if (show_mhz == 3) { + if (mhz > avg_mhz) { + COLOUR wattrset(padmhz, COLOR_PAIR(1)); + } else { + COLOUR wattrset(padmhz, COLOR_PAIR(2)); + } + for (i = 1; i < mhz / 100; i++) + mvwprintw(padmhz, padline, col + 9 + i, "#"); + COLOUR wattrset(padmhz, COLOR_PAIR(0)); + for (; i < 60; i++) + mvwprintw(padmhz, padline, col + 9 + i, " "); + } + padline++; + if (padline > 22) { + padline = 3; + col = col + 9; + } + if (mhz != 0.0) { + if (mhz < min_mhz) + min_mhz = mhz; + if (mhz > max_mhz) + max_mhz = mhz; + } + } + cpuno++; + } + if (cpuno > 160) + break; + } + avg_mhz = (min_mhz + max_mhz) / 2; + if(cores >= 20) + lineno = 23; + else + lineno = cores+3; + DISPLAY(padmhz, lineno); + } else { + if (!show_rrd) + fprintf(fp, "MHZ,%s", LOOP); + for (lineno = 0; lineno < proc[P_CPUINFO].lines; lineno++) { + if (strncmp + (clockstr, proc[P_CPUINFO].line[lineno], + strlen(clockstr)) == 0) { + mhz = 0.0; + sscanf(&proc[P_CPUINFO].line[lineno][DATACOL], + "%f", &mhz); + if (!show_rrd) + fprintf(fp, ",%.0f", mhz); + } + } + if (!show_rrd) + fprintf(fp, "\n"); + } + } + if (show_memory) { + proc_read(P_MEMINFO); + proc_mem(); + if (cursed) { +#define RAMCOL 16 +#define SWAPCOL 28 +#define HIGHCOL 45 +#define LOWCOL 60 + + BANNER(padmem, "Memory and Swap"); + + COLOUR wattrset(padmem, COLOR_PAIR(1)); + mvwprintw(padmem, 1, 1, "PageSize:%dKB", pagesize / 1024); + COLOUR wattrset(padmem, COLOR_PAIR(0)); + mvwprintw(padmem, 2, 1, "Total (MB)"); + mvwprintw(padmem, 3, 1, "Free (MB)"); + mvwprintw(padmem, 4, 1, "Free Percent"); + + COLOUR wattrset(padmem, COLOR_PAIR(2)); + mvwprintw(padmem, 1, RAMCOL, "RAM-Memory"); + mvwprintw(padmem, 2, RAMCOL, "%10.1f", + p->mem.memtotal / 1024.0); + mvwprintw(padmem, 3, RAMCOL, "%10.1f", + p->mem.memfree / 1024.0); + mvwprintw(padmem, 4, RAMCOL, "%10.1f%%", + p->mem.memfree == + 0 ? 0.0 : 100.0 * (float) p->mem.memfree / + (float) p->mem.memtotal); + COLOUR wattrset(padmem, COLOR_PAIR(3)); + mvwprintw(padmem, 1, SWAPCOL, "Swap-Space"); + mvwprintw(padmem, 2, SWAPCOL, "%10.1f", + p->mem.swaptotal / 1024.0); + mvwprintw(padmem, 3, SWAPCOL, "%10.1f", + p->mem.swapfree / 1024.0); + mvwprintw(padmem, 4, SWAPCOL, "%10.1f%%", + p->mem.swapfree == + 0 ? 0.0 : 100.0 * (float) p->mem.swapfree / + (float) p->mem.swaptotal); + COLOUR wattrset(padmem, COLOR_PAIR(4)); + mvwprintw(padmem, 1, HIGHCOL, "High-Memory"); + if (p->mem.hightotal > 0.0) { + mvwprintw(padmem, 2, HIGHCOL, "%8.1f", + p->mem.hightotal / 1024.0); + mvwprintw(padmem, 3, HIGHCOL, "%8.1f", + p->mem.highfree / 1024.0); + mvwprintw(padmem, 4, HIGHCOL, "%8.1f%%", + p->mem.highfree == + 0 ? 0.0 : 100.0 * (float) p->mem.highfree / + (float) p->mem.hightotal); + } else + mvwprintw(padmem, 2, HIGHCOL, "- not in use"); + COLOUR wattrset(padmem, COLOR_PAIR(6)); + mvwprintw(padmem, 1, LOWCOL, " Low-Memory"); + if (p->mem.lowtotal > 0.0) { + mvwprintw(padmem, 2, LOWCOL, "%8.1f", + p->mem.lowtotal / 1024.0); + mvwprintw(padmem, 3, LOWCOL, "%8.1f", + p->mem.lowfree / 1024.0); + mvwprintw(padmem, 4, LOWCOL, "%8.1f%%", + p->mem.lowfree == + 0 ? 0.0 : 100.0 * (float) p->mem.lowfree / + (float) p->mem.lowtotal); + } else + mvwprintw(padmem, 2, LOWCOL, "- not in use"); + COLOUR wattrset(padmem, COLOR_PAIR(5)); + + + mvwprintw(padmem, 5, 1, + "Linux Kernel Internal Memory (MB)"); +#ifndef SMALLMEM + mvwprintw(padmem, 6, 1, + " Cached=%10.1f Active=%10.1f", + p->mem.cached / 1024.0, p->mem.active / 1024.0); +#else + mvwprintw(padmem, 6, 1, + " Shared=%10.1f Cached=%10.1f Active=%10.1f", + p->mem.memshared / 1024.0, + p->mem.cached / 1024.0, p->mem.active / 1024.0); + mvwprintw(padmem, 5, 68, "MB"); + mvwprintw(padmem, 6, 55, "bigfree=%10.1f", + p->mem.bigfree / 1024); +#endif /*SMALLMEM*/ + mvwprintw(padmem, 7, 1, + "Buffers=%10.1f Swapcached=%10.1f Inactive =%10.1f", + p->mem.buffers / 1024.0, + p->mem.swapcached / 1024.0, + p->mem.inactive / 1024.0); +#ifndef SMALLMEM + mvwprintw(padmem, 8, 1, + "Dirty =%10.1f Writeback =%10.1f Mapped =%10.1f", + p->mem.dirty / 1024.0, p->mem.writeback / 1024.0, + p->mem.mapped / 1024.0); + mvwprintw(padmem, 9, 1, + "Slab =%10.1f Commit_AS =%10.1f PageTables=%10.1f", + p->mem.slab / 1024.0, + p->mem.committed_as / 1024.0, + p->mem.pagetables / 1024.0); +#endif /*SMALLMEM */ +#ifdef POWER + if (!show_lpar) /* check if already called above */ + proc_lparcfg(); + if (lparcfg.cmo_enabled == 0) + mvwprintw(padmem, 10, 1, "AMS is not active"); + else + mvwprintw(padmem, 10, 1, + "AMS id=%d Weight=%-3d pmem=%ldMB hpi=%.1f/s hpit=%.1f(sec) Pool=%ldMB Loan=%ldKB ", + (int) lparcfg.entitled_memory_pool_number, + (int) lparcfg.entitled_memory_weight, + (long) (lparcfg.backing_memory) / 1024 / + 1024, + (double) (lparcfg.cmo_faults_diff) / elapsed, + (double) (lparcfg.cmo_fault_time_usec_diff) / + 1000 / 1000 / elapsed, + (long) lparcfg.entitled_memory_pool_size / + 1024 / 1024, + (long) lparcfg.entitled_memory_loan_request / + 1024); + + COLOUR wattrset(padmem, COLOR_PAIR(0)); + DISPLAY(padmem, 11); +#else /* POWER */ + COLOUR wattrset(padmem, COLOR_PAIR(0)); + DISPLAY(padmem, 10); +#endif /* POWER */ + } else { + + if (show_rrd) + str_p = + "rrdtool update mem.rrd %s:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f\n"; + else + str_p = + "MEM,%s,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f\n"; + fprintf(fp, str_p, LOOP, p->mem.memtotal / 1024.0, + p->mem.hightotal / 1024.0, + p->mem.lowtotal / 1024.0, + p->mem.swaptotal / 1024.0, p->mem.memfree / 1024.0, + p->mem.highfree / 1024.0, p->mem.lowfree / 1024.0, + p->mem.swapfree / 1024.0, + p->mem.memshared / 1024.0, p->mem.cached / 1024.0, + p->mem.active / 1024.0, +#ifndef SMALLMEM + -1.0, +#else + p->mem.bigfree / 1024.0, +#endif /*SMALLMEM*/ + p->mem.buffers / 1024.0, + p->mem.swapcached / 1024.0, + p->mem.inactive / 1024.0); +#ifdef POWER + if (lparcfg.cmo_enabled != 0) { + if (!show_rrd) + fprintf(fp, + "MEMAMS,%s,%d,%d,%.1f,%.3lf,0,0,0,%.1f,%ld,%ld,%ld\n", + LOOP, + (int) lparcfg.entitled_memory_pool_number, + (int) lparcfg.entitled_memory_weight, + (float) (lparcfg.cmo_faults_diff) / + elapsed, + (float) (lparcfg. + cmo_fault_time_usec_diff) / 1000 / + 1000 / elapsed, + /* three zeros here */ + (float) (lparcfg.backing_memory) / 1024 / + 1024, lparcfg.cmo_page_size / 1024, + lparcfg.entitled_memory_pool_size / 1024 / + 1024, + lparcfg.entitled_memory_loan_request / + 1024); + } +#ifdef EXPERIMENTAL + if (!show_rrd) + fprintf(fp, + "MEMEXPERIMENTAL,%s,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld,%ld\n", + LOOP, (long) lparcfg.DesEntCap, + (long) lparcfg.DesProcs, + (long) lparcfg.DesVarCapWt, + (long) lparcfg.DedDonMode, + (long) lparcfg.group, (long) lparcfg.pool, + (long) lparcfg.entitled_memory, + (long) lparcfg.entitled_memory_group_number, + (long) lparcfg. + unallocated_entitled_memory_weight, + (long) lparcfg. + unallocated_io_mapping_entitlement); +#endif /* EXPERIMENTAL */ +#endif /* POWER */ + } +/* for testing large page + p->mem.hugefree = 250; + p->mem.hugetotal = 1000; + p->mem.hugesize = 16*1024; +*/ + } +#ifndef SMALLMEM + if (show_large) { + proc_read(P_MEMINFO); + proc_mem(); + if (cursed) { + BANNER(padlarge, "Large (Huge) Page"); + if (p->mem.hugetotal > 0) { + if (p->mem.hugetotal - p->mem.hugefree > huge_peak) + huge_peak = p->mem.hugetotal - p->mem.hugefree; + mvwprintw(padlarge, 1, 1, + "Total Pages=%7ld 100.0%% Huge Page Size =%ld KB", + p->mem.hugetotal, p->mem.hugesize); + mvwprintw(padlarge, 2, 1, + "Used Pages=%7ld %5.1f%% Used Pages Peak=%-8ld", + (long) (p->mem.hugetotal - p->mem.hugefree), + (p->mem.hugetotal - + p->mem.hugefree) / + (float) p->mem.hugetotal * 100.0, huge_peak); + mvwprintw(padlarge, 3, 1, "Free Pages=%7ld %5.1f%%", + p->mem.hugefree, + p->mem.hugefree / (float) p->mem.hugetotal * + 100.0); + } else { + mvwprintw(padlarge, 1, 1, " There are no Huge Pages"); + mvwprintw(padlarge, 2, 1, " - see /proc/meminfo"); + } + DISPLAY(padlarge, 4); + } else { + if (p->mem.hugetotal > 0) { + if (first_huge == 1) { + first_huge = 0; + fprintf(fp, + "HUGEPAGES,Huge Page Use %s,HugeTotal,HugeFree,HugeSizeMB\n", + run_name); + } + fprintf(fp, "HUGEPAGES,%s,%ld,%ld,%.1f\n", + LOOP, + p->mem.hugetotal, + p->mem.hugefree, p->mem.hugesize / 1024.0); + } + } + } +#endif /* SMALLMEM */ + if (show_vm) { +#define VMDELTA(variable) (p->vm.variable - q->vm.variable) +#define VMCOUNT(variable) (p->vm.variable ) + ret = read_vmstat(); + if (cursed) { + BANNER(padpage, "Virtual Memory"); + + COLOUR wattrset(padpage, COLOR_PAIR(6)); + if (ret < 0) { + mvwprintw(padpage, 2, 2, + "Virtual Memory stats not supported with this kernel"); + mvwprintw(padpage, 3, 2, + "/proc/vmstat only seems to appear in 2.6 onwards"); + + } else { + if (vm_first_time) { + mvwprintw(padpage, 2, 2, + "Please wait - collecting data"); + vm_first_time = 0; + } else { + mvwprintw(padpage, 1, 0, + "nr_dirty =%9lld pgpgin =%8lld", + VMCOUNT(nr_dirty), VMDELTA(pgpgin)); + mvwprintw(padpage, 2, 0, + "nr_writeback=%9lld pgpgout =%8lld", + VMCOUNT(nr_writeback), VMDELTA(pgpgout)); + mvwprintw(padpage, 3, 0, + "nr_unstable =%9lld pgpswpin =%8lld", + VMCOUNT(nr_unstable), VMDELTA(pswpin)); + mvwprintw(padpage, 4, 0, + "nr_table_pgs=%9lld pgpswpout =%8lld", + VMCOUNT(nr_page_table_pages), + VMDELTA(pswpout)); + mvwprintw(padpage, 5, 0, + "nr_mapped =%9lld pgfree =%8lld", + VMCOUNT(nr_mapped), VMDELTA(pgfree)); + if(VMCOUNT(nr_slab) != -1 ) { /* older nr_slab only */ + mvwprintw(padpage, 6, 0, + "nr_slab =%9lld pgactivate =%8lld", + VMCOUNT(nr_slab), VMDELTA(pgactivate)); + mvwprintw(padpage, 7, 0, + " pgdeactivate=%8lld", + VMDELTA(pgdeactivate)); + } else { /*new nr_slab_reclaimable / nr_slab_unreclaimable Kernel 2.6.19+ */ + mvwprintw(padpage, 6, 0, + "slab_reclaim=%9lld pgactivate =%8lld", + VMCOUNT(nr_slab_reclaimable), VMDELTA(pgactivate)); + mvwprintw(padpage, 7, 0, + "slab_unreclm=%9lld pgdeactivate=%8lld", + VMCOUNT(nr_slab_unreclaimable), VMDELTA(pgdeactivate)); + } + mvwprintw(padpage, 8, 0, + "allocstall =%9lld pgfault =%8lld kswapd_steal =%7lld", + VMDELTA(allocstall), VMDELTA(pgfault), + VMDELTA(kswapd_steal)); + mvwprintw(padpage, 9, 0, + "pageoutrun =%9lld pgmajfault =%8lld kswapd_inodesteal=%7lld", + VMDELTA(pageoutrun), VMDELTA(pgmajfault), + VMDELTA(kswapd_inodesteal)); + mvwprintw(padpage, 10, 0, + "slabs_scanned=%8lld pgrotated =%8lld pginodesteal =%7lld", + VMDELTA(slabs_scanned), + VMDELTA(pgrotated), + VMDELTA(pginodesteal)); + + + + mvwprintw(padpage, 1, 46, + " High Normal DMA"); + mvwprintw(padpage, 2, 46, + "alloc %7lld%7lld%7lld", + VMDELTA(pgalloc_high), + VMDELTA(pgalloc_normal), + VMDELTA(pgalloc_dma)); + mvwprintw(padpage, 3, 46, + "refill %7lld%7lld%7lld", + VMDELTA(pgrefill_high), + VMDELTA(pgrefill_normal), + VMDELTA(pgrefill_dma)); + mvwprintw(padpage, 4, 46, + "steal %7lld%7lld%7lld", + VMDELTA(pgsteal_high), + VMDELTA(pgsteal_normal), + VMDELTA(pgsteal_dma)); + mvwprintw(padpage, 5, 46, + "scan_kswapd%7lld%7lld%7lld", + VMDELTA(pgscan_kswapd_high), + VMDELTA(pgscan_kswapd_normal), + VMDELTA(pgscan_kswapd_dma)); + mvwprintw(padpage, 6, 46, + "scan_direct%7lld%7lld%7lld", + VMDELTA(pgscan_direct_high), + VMDELTA(pgscan_direct_normal), + VMDELTA(pgscan_direct_dma)); + } + } + COLOUR wattrset(padpage, COLOR_PAIR(0)); + DISPLAY(padpage, 11); + } else { + if (ret < 0) { + show_vm = 0; + } else if (vm_first_time) { + vm_first_time = 0; + if(VMCOUNT(nr_slab) == -1 ) + slabstr = "nr_slab_reclaimable"; + else + slabstr = "nr_slab"; + fprintf(fp, + "VM,Paging and Virtual Memory,nr_dirty,nr_writeback,nr_unstable,nr_page_table_pages,nr_mapped,%s,pgpgin,pgpgout,pswpin,pswpout,pgfree,pgactivate,pgdeactivate,pgfault,pgmajfault,pginodesteal,slabs_scanned,kswapd_steal,kswapd_inodesteal,pageoutrun,allocstall,pgrotated,pgalloc_high,pgalloc_normal,pgalloc_dma,pgrefill_high,pgrefill_normal,pgrefill_dma,pgsteal_high,pgsteal_normal,pgsteal_dma,pgscan_kswapd_high,pgscan_kswapd_normal,pgscan_kswapd_dma,pgscan_direct_high,pgscan_direct_normal,pgscan_direct_dma\n", slabstr); + } + if (show_rrd) + str_p = "rrdtool update vm.rrd %s" + ":%lld:%lld:%lld:%lld:%lld" + ":%lld:%lld:%lld:%lld:%lld" + ":%lld:%lld:%lld:%lld:%lld" + ":%lld:%lld:%lld:%lld:%lld" + ":%lld:%lld:%lld:%lld:%lld" + ":%lld:%lld:%lld:%lld:%lld" + ":%lld:%lld:%lld:%lld:%lld" ":%lld:%lld\n"; + else + str_p = "VM,%s" + ",%lld,%lld,%lld,%lld,%lld" + ",%lld,%lld,%lld,%lld,%lld" + ",%lld,%lld,%lld,%lld,%lld" + ",%lld,%lld,%lld,%lld,%lld" + ",%lld,%lld,%lld,%lld,%lld" + ",%lld,%lld,%lld,%lld,%lld" + ",%lld,%lld,%lld,%lld,%lld" ",%lld,%lld\n"; + if(VMCOUNT(nr_slab) != -1) + tmpslab = VMCOUNT(nr_slab); + else + tmpslab = VMCOUNT(nr_slab_reclaimable); + fprintf(fp, str_p, + LOOP, + VMCOUNT(nr_dirty), + VMCOUNT(nr_writeback), + VMCOUNT(nr_unstable), + VMCOUNT(nr_page_table_pages), + VMCOUNT(nr_mapped), + tmpslab, + VMDELTA(pgpgin), + VMDELTA(pgpgout), + VMDELTA(pswpin), + VMDELTA(pswpout), + VMDELTA(pgfree), + VMDELTA(pgactivate), + VMDELTA(pgdeactivate), + VMDELTA(pgfault), + VMDELTA(pgmajfault), + VMDELTA(pginodesteal), + VMDELTA(slabs_scanned), + VMDELTA(kswapd_steal), + VMDELTA(kswapd_inodesteal), + VMDELTA(pageoutrun), + VMDELTA(allocstall), + VMDELTA(pgrotated), + VMDELTA(pgalloc_high), + VMDELTA(pgalloc_normal), + VMDELTA(pgalloc_dma), + VMDELTA(pgrefill_high), + VMDELTA(pgrefill_normal), + VMDELTA(pgrefill_dma), + VMDELTA(pgsteal_high), + VMDELTA(pgsteal_normal), + VMDELTA(pgsteal_dma), + VMDELTA(pgscan_kswapd_high), + VMDELTA(pgscan_kswapd_normal), + VMDELTA(pgscan_kswapd_dma), + VMDELTA(pgscan_direct_high), + VMDELTA(pgscan_direct_normal), + VMDELTA(pgscan_direct_dma)); + } + } + if (show_kernel) { + proc_read(P_STAT); + proc_cpu(); + proc_read(P_UPTIME); + proc_read(P_LOADAVG); + proc_kernel(); + if (cursed) { + BANNER(padker, "Kernel and Load Average"); +#define MORECOL 21 +#define LOADCOL 41 +#define BOOTCOL 55 + COLOUR wattrset(padker, COLOR_PAIR(1)); + mvwprintw(padker, 1, 0, "Global-CPU-Stats---->"); + mvwprintw(padker, 2, 0, " /proc/stat line 1"); + mvwprintw(padker, 3, 0, "%ld ticks per second", ticks); + mvwprintw(padker, 4, 0, "100%%=1 CPUcoreThread"); + COLOUR wattrset(padker, COLOR_PAIR(2)); + mvwprintw(padker, 5, 0, "%8lld RunQueue", + p->cpu_total.running); + mvwprintw(padker, 6, 0, "%8lld Blocked", + p->cpu_total.blocked); + mvwprintw(padker, 7, 0, "%10.1f Context", + (float) (p->cpu_total.ctxt - + q->cpu_total.ctxt) / elapsed); + mvwprintw(padker, 8, 0, " Switch"); + mvwprintw(padker, 9, 0, "%10.1f Forks", + (float) (p->cpu_total.procs - + q->cpu_total.procs) / elapsed); + mvwprintw(padker, 10, 0, "%10.1f Interrupts", + (float) (p->cpu_total.intr - + q->cpu_total.intr) / elapsed); + + COLOUR wattrset(padker, COLOR_PAIR(1)); + mvwprintw(padker, 1, MORECOL, "%8.1f%% user", + (float) (RAWTOTAL(user)) / elapsed); + mvwprintw(padker, 2, MORECOL, "%8.1f%% user_nice", + (float) (RAWTOTAL(nice)) / elapsed); + mvwprintw(padker, 3, MORECOL, "%8.1f%% system", + (float) (RAWTOTAL(sys)) / elapsed); + mvwprintw(padker, 4, MORECOL, "%8.1f%% idle", + (float) (RAWTOTAL(idle)) / elapsed); + mvwprintw(padker, 5, MORECOL, "%8.1f%% iowait", + (float) (RAWTOTAL(wait)) / elapsed); + mvwprintw(padker, 6, MORECOL, "%8.1f%% irq", + (float) (RAWTOTAL(irq)) / elapsed); + mvwprintw(padker, 7, MORECOL, "%8.1f%% softirq", + (float) (RAWTOTAL(softirq)) / elapsed); + mvwprintw(padker, 8, MORECOL, "%8.1f%% steal", + (float) (RAWTOTAL(steal)) / elapsed); + mvwprintw(padker, 9, MORECOL, "%8.1f%% guest", + (float) (RAWTOTAL(guest)) / elapsed); + mvwprintw(padker, 10, MORECOL, "%8.1f%% guest_nice", + (float) (RAWTOTAL(guest_nice)) / elapsed); + + COLOUR wattrset(padker, COLOR_PAIR(3)); + mvwprintw(padker, 1, LOADCOL, "Load Average"); + mvwprintw(padker, 2, LOADCOL, " 1 mins %5.2f", + (float) p->cpu_total.mins1); + mvwprintw(padker, 3, LOADCOL, " 5 mins %5.2f", + (float) p->cpu_total.mins5); + mvwprintw(padker, 4, LOADCOL, "15 mins %5.2f", + (float) p->cpu_total.mins15); + + + COLOUR wattrset(padker, COLOR_PAIR(5)); + mvwprintw(padker, 1, BOOTCOL, "CPU use since boottime"); + + updays = p->cpu_total.uptime / 60 / 60 / 24; + uphours = + (p->cpu_total.uptime - + updays * 60 * 60 * 24) / 60 / 60; + upmins = + (p->cpu_total.uptime - updays * 60 * 60 * 24 - + uphours * 60 * 60) / 60; + mvwprintw(padker, 2, BOOTCOL, "Uptime Days Hours Mins"); + mvwprintw(padker, 3, BOOTCOL, "Uptime %4ld %5ld %4ld", + updays, uphours, upmins); + + updays = p->cpu_total.idletime / 60 / 60 / 24 / cpus; + uphours = + (p->cpu_total.idletime - + updays * 60 * 60 * 24) / 60 / 60 / cpus; + upmins = + (p->cpu_total.idletime - updays * 60 * 60 * 24 - + uphours * 60 * 60) / 60 / cpus; + mvwprintw(padker, 4, BOOTCOL, "Idle %4ld %5ld %4ld", + updays, uphours, upmins); + + average = + (p->cpu_total.uptime - + p->cpu_total.idletime) / p->cpu_total.uptime * 100.0; + if (average > 0.0) + mvwprintw(padker, 5, BOOTCOL, + "Average Busy Uptimee=%6.2f%%", average); + else + mvwprintw(padker, 5, BOOTCOL, "Uptime has overflowed"); + mvwprintw(padker, 7, BOOTCOL, "%d CPU core threads", cpus); + mvwprintw(padker, 9, BOOTCOL, "Boot time %d", boottime); + mvwprintw(padker,10, BOOTCOL, "%s", boottime_str); + COLOUR wattrset(padker, COLOR_PAIR(0)); + DISPLAY(padker, 11); + } else { + if (proc_first_time) { + q->cpu_total.ctxt = p->cpu_total.ctxt; + q->cpu_total.procs = p->cpu_total.procs; + proc_first_time = 0; + } + if (show_rrd) + str_p = /* LOOP 1 2 3 4 5 6 7 8 9 */ + "rrdtool update proc.rrd %s:%.0f:%.0f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f:%.1f\n"; + else + str_p = /* LOOP 1 2 3 4 5 6 7 8 9 */ + "PROC,%s,%.0f,%.0f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f\n"; + + /* These "-1"'s looks bad but it keeps the nmon for AIX format */ + /* The stats are not available in Linux . . . unless you know better! */ + fprintf(fp, str_p, LOOP, + (float) p->cpu_total.running, /*1 runqueue */ + (float) p->cpu_total.blocked, /*2 swapin (# of processes waiting for IO completion */ + (float) (p->cpu_total.ctxt - q->cpu_total.ctxt) / elapsed, /*3 pswitch */ + -1.0, /*4 syscall */ + -1.0, /*4 read */ + -1.0, /*5 write */ + (float) (p->cpu_total.procs - q->cpu_total.procs) / elapsed, /*6 fork */ + -1.0, /*7 exec */ + -1.0, /*8 sem */ + -1.0); /*9 msg */ + } + } + + if (show_nfs) { + proc_read(P_NFS); + proc_read(P_NFSD); + proc_nfs(); + + if (cursed) { + if (nfs_first_time) { + memcpy(&q->nfs, &p->nfs, sizeof(struct nfs_stat)); + nfs_first_time = 0; + } + if (nfs_clear) { + nfs_clear = 0; + for (i = 0; i < 25; i++) + mvwprintw(padnfs, i, 0, + " "); + } + BANNER(padnfs, + "Network Filesystem (NFS) I/O Operations per second"); + if (show_nfs == 1) { + if (nfs_v2c_found || nfs_v2s_found) + mvwprintw(padnfs, 1, 0, + " Version 2 Client Server"); + else + mvwprintw(padnfs, 1, 0, " Version 2 not active"); + + if (nfs_v3c_found || nfs_v3s_found) + mvwprintw(padnfs, 1, 41, + "Version 3 Client Server"); + else + mvwprintw(padnfs, 1, 41, " Version 3 not active"); + } + if (show_nfs == 2) { + if (nfs_v4c_found) + mvwprintw(padnfs, 1, 0, + " Version 4 Client (%d Stats found)", + nfs_v4c_names_count); + else + mvwprintw(padnfs, 1, 0, + " Version 4 Client side not active"); + } + if (show_nfs == 3) { + if (nfs_v4s_found) + mvwprintw(padnfs, 1, 0, + " Version 4 Server (%d Stats found)", + nfs_v4s_names_count); + else + mvwprintw(padnfs, 1, 0, + " Version 4 Server side not active"); + } +#define NFS_TOTAL(member) (double)(p->member) +#define NFS_DELTA(member) (((double)(p->member - q->member)/elapsed)) + v2c_total = 0; + v2s_total = 0; + v3c_total = 0; + v3s_total = 0; + v4c_total = 0; + v4s_total = 0; + if (nfs_v3c_found || nfs_v3s_found) { + for (i = 0; i < 18; i++) { /* NFS V2 Client & Server */ + if (show_nfs == 1) + mvwprintw(padnfs, 2 + i, 3, "%12s %8.1f %8.1f", + nfs_v2_names[i], + NFS_DELTA(nfs.v2c[i]), + NFS_DELTA(nfs.v2s[i])); + v2c_total += NFS_DELTA(nfs.v2c[i]); + v2s_total += NFS_DELTA(nfs.v2s[i]); + } + } + if (nfs_v3c_found || nfs_v3s_found) { + for (i = 0; i < 22; i++) { /* NFS V3 Client & Server */ + if (show_nfs == 1) + mvwprintw(padnfs, 2 + i, 41, + "%12s %8.1f %8.1f", nfs_v3_names[i], + NFS_DELTA(nfs.v3c[i]), + NFS_DELTA(nfs.v3s[i])); + v3c_total += NFS_DELTA(nfs.v3c[i]); + v3s_total += NFS_DELTA(nfs.v3s[i]); + } + } + + if (nfs_v4c_found) { + for (i = 0; i < 18; i++) { /* NFS V4 Client */ + if (show_nfs == 2) { + mvwprintw(padnfs, 2 + i, 0, "%12s%7.1f", + nfs_v4c_names[i], + NFS_DELTA(nfs.v4c[i])); + } + v4c_total += NFS_DELTA(nfs.v4c[i]); + } + for (i = 18; i < 35; i++) { /* NFS V4 Client */ + if (show_nfs == 2) { + mvwprintw(padnfs, 2 + i - 18, 20, "%12s%7.1f", + nfs_v4c_names[i], + NFS_DELTA(nfs.v4c[i])); + } + v4c_total += NFS_DELTA(nfs.v4c[i]); + } + } + + if (nfs_v4s_found) { + for (i = 0; i < 18; i++) { /* NFS V4 Server */ + if (show_nfs == 3) { + mvwprintw(padnfs, 2 + i, 0, "%12s%7.1f", + nfs_v4s_names[i], + NFS_DELTA(nfs.v4s[i])); + } + v4s_total += NFS_DELTA(nfs.v4s[i]); + } + for (i = 18; i < 36; i++) { /* NFS V4 Server */ + if (show_nfs == 3) { + mvwprintw(padnfs, 2 + i - 18, 19, "%12s%7.1f", + nfs_v4s_names[i], + NFS_DELTA(nfs.v4s[i])); + } + v4s_total += NFS_DELTA(nfs.v4s[i]); + } + for (i = 36; i < 54 && i < nfs_v4s_names_count; i++) { /* NFS V4 Server */ + if (show_nfs == 3) { + mvwprintw(padnfs, 2 + i - 36, 39, "%12s%7.1f", + nfs_v4s_names[i], + NFS_DELTA(nfs.v4s[i])); + } + v4s_total += NFS_DELTA(nfs.v4s[i]); + } + for (i = 54; i <= 70 && i < nfs_v4s_names_count; i++) { /* NFS V4 Server */ + if (show_nfs == 3) { + mvwprintw(padnfs, 2 + i - 54, 59, "%12s%7.1f", + nfs_v4s_names[i], + NFS_DELTA(nfs.v4s[i])); + } + v4s_total += NFS_DELTA(nfs.v4s[i]); + } + } + mvwprintw(padnfs, 2 + 18, 1, + "--NFS-Totals->---Client----Server--"); + /* if(nfs_v2c_found || nfs_v2s_found) */ + mvwprintw(padnfs, 2 + 19, 1, "NFSv2 Totals->%9.1f %9.1f", + v2c_total, v2s_total); + /* if(nfs_v3c_found || nfs_v3s_found) */ + mvwprintw(padnfs, 2 + 20, 1, "NFSv3 Totals->%9.1f %9.1f", + v3c_total, v3s_total); + /* if(nfs_v4c_found || nfs_v4s_found) */ + mvwprintw(padnfs, 2 + 21, 1, "NFSv4 Totals->%9.1f %9.1f", + v4c_total, v4s_total); + + DISPLAY(padnfs, 24); + } else { + if (nfs_first_time && !show_rrd) { + if (nfs_v2c_found) { + fprintf(fp, "NFSCLIV2,NFS Client v2"); + for (i = 0; i < 18; i++) + fprintf(fp, ",%s", nfs_v2_names[i]); + fprintf(fp, "\n"); + } + if (nfs_v2s_found) { + fprintf(fp, "NFSSVRV2,NFS Server v2"); + for (i = 0; i < 18; i++) + fprintf(fp, ",%s", nfs_v2_names[i]); + fprintf(fp, "\n"); + } + + if (nfs_v3c_found) { + fprintf(fp, "NFSCLIV3,NFS Client v3"); + for (i = 0; i < 22; i++) + fprintf(fp, ",%s", nfs_v3_names[i]); + fprintf(fp, "\n"); + } + if (nfs_v3s_found) { + fprintf(fp, "NFSSVRV3,NFS Server v3"); + for (i = 0; i < 22; i++) + fprintf(fp, ",%s", nfs_v3_names[i]); + fprintf(fp, "\n"); + } + + if (nfs_v4c_found) { + fprintf(fp, "NFSCLIV4,NFS Client v4"); + for (i = 0; i < nfs_v4c_names_count; i++) + fprintf(fp, ",%s", nfs_v4c_names[i]); + fprintf(fp, "\n"); + } + if (nfs_v4s_found) { + fprintf(fp, "NFSSVRV4,NFS Server v4"); + for (i = 0; i < nfs_v4s_names_count; i++) + fprintf(fp, ",%s", nfs_v4s_names[i]); + fprintf(fp, "\n"); + } + memcpy(&q->nfs, &p->nfs, sizeof(struct nfs_stat)); + nfs_first_time = 0; + } + if (nfs_v2c_found) { + fprintf(fp, + show_rrd ? "rrdtool update nfscliv2.rrd %s" : + "NFSCLIV2,%s", LOOP); + for (i = 0; i < 18; i++) { + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + (double) NFS_DELTA(nfs.v2c[i])); + } + fprintf(fp, "\n"); + } + if (nfs_v2s_found) { + fprintf(fp, + show_rrd ? "rrdtool update nfsvrv2.rrd %s" : + "NFSSVRV2,%s", LOOP); + for (i = 0; i < 18; i++) { + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + (double) NFS_DELTA(nfs.v2s[i])); + } + fprintf(fp, "\n"); + } + if (nfs_v3c_found) { + fprintf(fp, + show_rrd ? "rrdtool update nfscliv3.rrd %s" : + "NFSCLIV3,%s", LOOP); + for (i = 0; i < 22; i++) { + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + (double) NFS_DELTA(nfs.v3c[i])); + } + fprintf(fp, "\n"); + } + if (nfs_v3s_found) { + fprintf(fp, + show_rrd ? "rrdtool update nfsvrv3.rrd %s" : + "NFSSVRV3,%s", LOOP); + for (i = 0; i < 22; i++) { + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + (double) NFS_DELTA(nfs.v3s[i])); + } + fprintf(fp, "\n"); + } + + if (nfs_v4c_found) { + fprintf(fp, + show_rrd ? "rrdtool update nfscliv4.rrd %s" : + "NFSCLIV4,%s", LOOP); + for (i = 0; i < nfs_v4c_names_count; i++) { + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + (double) NFS_DELTA(nfs.v4c[i])); + } + fprintf(fp, "\n"); + } + if (nfs_v4s_found) { + fprintf(fp, + show_rrd ? "rrdtool update nfsvrv4.rrd %s" : + "NFSSVRV4,%s", LOOP); + for (i = 0; i < nfs_v4c_names_count; i++) { + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + (double) NFS_DELTA(nfs.v4s[i])); + } + fprintf(fp, "\n"); + } + } + } + if (show_net) { + if (cursed) { + BANNER(padnet, "Network I/O"); +#define RKB 9 +#define TKB 19 +#define PIN 30 +#define POUT 37 +#define SIN 45 +#define SOUT 52 +#define PKHEAD 60 +#define PKIN 66 +#define PKOUT 71 +/* + 1 2 3 4 5 6 7 + 01234567890123456789012345678901234567890123456789012345678901234567890123456789 + mvwprintw(padnet,1, 0, "I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans"); +*/ + COLOUR wattrset(padnet, COLOR_PAIR(0)); + mvwprintw(padnet, 1, 0, "I/F Name"); + COLOUR wattrset(padnet, COLOR_PAIR(2)); + mvwprintw(padnet, 1, RKB, "Recv=KB/s"); + COLOUR wattrset(padnet, COLOR_PAIR(3)); + mvwprintw(padnet, 1, TKB, "Trans=KB/s"); + COLOUR wattrset(padnet, COLOR_PAIR(2)); + mvwprintw(padnet, 1, PIN, "packin"); + COLOUR wattrset(padnet, COLOR_PAIR(3)); + mvwprintw(padnet, 1, POUT, "packout"); + COLOUR wattrset(padnet, COLOR_PAIR(2)); + mvwprintw(padnet, 1, SIN, "insize"); + COLOUR wattrset(padnet, COLOR_PAIR(3)); + mvwprintw(padnet, 1, SOUT, "outsize"); + COLOUR wattrset(padnet, COLOR_PAIR(0)); + mvwprintw(padnet, 1, PKHEAD, "Peak->"); + COLOUR wattrset(padnet, COLOR_PAIR(2)); + mvwprintw(padnet, 1, PKIN, "Recv"); + COLOUR wattrset(padnet, COLOR_PAIR(3)); + mvwprintw(padnet, 1, PKOUT, "Trans"); + COLOUR wattrset(padnet, COLOR_PAIR(0)); + } + proc_net(); + for (i = 0; i < networks; i++) { + +#define IFDELTA(member) ((float)( (q->ifnets[i].member > p->ifnets[i].member) ? 0 : (p->ifnets[i].member - q->ifnets[i].member)/elapsed) ) +#define IFDELTA_ZERO(member1,member2) ((IFDELTA(member1) == 0) || (IFDELTA(member2)== 0)? 0.0 : IFDELTA(member1)/IFDELTA(member2) ) + + if (net_read_peak[i] < IFDELTA(if_ibytes) / 1024.0) + net_read_peak[i] = IFDELTA(if_ibytes) / 1024.0; + if (net_write_peak[i] < IFDELTA(if_obytes) / 1024.0) + net_write_peak[i] = IFDELTA(if_obytes) / 1024.0; +/* + 1 2 3 4 5 6 7 +01234567890123456789012345678901234567890123456789012345678901234567890123456789 +I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans + eth3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + lo 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + eth2 0.5 0.2 8.5 0.5 64.0 314.0 53.4 24.6 + eth1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + eth0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +*/ + if (cursed) { + COLOUR wattrset(padnet, COLOR_PAIR(0)); + mvwprintw(padnet, 2 + i, 0, "%8s", + &p->ifnets[i].if_name[0]); + COLOUR wattrset(padnet, COLOR_PAIR(2)); + mvwprintw(padnet, 2 + i, RKB, "%8.1f", + IFDELTA(if_ibytes) / 1024.0); + COLOUR wattrset(padnet, COLOR_PAIR(3)); + mvwprintw(padnet, 2 + i, TKB, "%8.1f", + IFDELTA(if_obytes) / 1024.0); + COLOUR wattrset(padnet, COLOR_PAIR(2)); + mvwprintw(padnet, 2 + i, PIN, "%7.1f", + IFDELTA(if_ipackets)); + COLOUR wattrset(padnet, COLOR_PAIR(3)); + mvwprintw(padnet, 2 + i, POUT, "%7.1f", + IFDELTA(if_opackets)); + COLOUR wattrset(padnet, COLOR_PAIR(2)); + mvwprintw(padnet, 2 + i, SIN, "%7.1f", + IFDELTA_ZERO(if_ibytes, if_ipackets)); + COLOUR wattrset(padnet, COLOR_PAIR(3)); + mvwprintw(padnet, 2 + i, SOUT, "%7.1f", + IFDELTA_ZERO(if_obytes, if_opackets)); + COLOUR wattrset(padnet, COLOR_PAIR(2)); + mvwprintw(padnet, 2 + i, PKIN - 4, "%8.1f", + net_read_peak[i]); + COLOUR wattrset(padnet, COLOR_PAIR(3)); + mvwprintw(padnet, 2 + i, PKOUT, "%8.1f", + net_write_peak[i]); + } + } + DISPLAY(padnet, networks + 2); + if (!cursed) { + fprintf(fp, + show_rrd ? "rrdtool update net.rrd %s" : "NET,%s", + LOOP); + for (i = 0; i < networks; i++) { + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + IFDELTA(if_ibytes) / 1024.0); + } + for (i = 0; i < networks; i++) { + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + IFDELTA(if_obytes) / 1024.0); + } + fprintf(fp, "\n"); + fprintf(fp, + show_rrd ? "rrdtool update netpacket.rrd %s" : + "NETPACKET,%s", LOOP); + for (i = 0; i < networks; i++) { + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + IFDELTA(if_ipackets)); + } + for (i = 0; i < networks; i++) { + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + IFDELTA(if_opackets)); + } + fprintf(fp, "\n"); + } + } + errors = 0; + for (i = 0; i < networks; i++) { + errors += p->ifnets[i].if_ierrs - q->ifnets[i].if_ierrs + + p->ifnets[i].if_oerrs - q->ifnets[i].if_oerrs + + p->ifnets[i].if_ocolls - q->ifnets[i].if_ocolls; + } + if (errors) + show_neterror = 3; + if (show_neterror) { + if (cursed) { + BANNER(padneterr, "Network Error Counters"); + mvwprintw(padneterr, 1, 0, + "I/F Name iErrors iDrop iOverrun iFrame oErrors oDrop oOverrun oCarrier oColls "); + } + for (i = 0; i < networks; i++) { + CURSE mvwprintw(padneterr, 2 + i, 0, + "%8s %7lu %7lu %7lu %7lu %7lu %7lu %7lu %7lu %7lu", + &p->ifnets[i].if_name[0], + p->ifnets[i].if_ierrs, + p->ifnets[i].if_idrop, + p->ifnets[i].if_ififo, + p->ifnets[i].if_iframe, + p->ifnets[i].if_oerrs, + p->ifnets[i].if_odrop, + p->ifnets[i].if_ofifo, + p->ifnets[i].if_ocarrier, + p->ifnets[i].if_ocolls); + + } + DISPLAY(padneterr, networks + 2); + if (show_neterror > 0) + show_neterror--; + } + + if (show_jfs) { + if (cursed) { + BANNER(padjfs, "File Systems"); + mvwprintw(padjfs, 1, 0, "Filesystem SizeMB FreeMB Use%% Type MountPoint"); + + for (k =0, j = 0; k < JFSMAX && j < jfses; k++) { + fs_size = 0; + fs_bsize = 0; + fs_free = 0; + fs_size_used = 100.0; + if (jfs[k].mounted == 0) + continue; + if (!strncmp(jfs[k].name, "/proc/", 6) /* sub directorys have to be fake too */ + ||!strncmp(jfs[k].name, "/sys/", 5) + || !strncmp(jfs[k].name, "/dev/", 5) + || !strncmp(jfs[k].name, "/proc", 6) /* one more than the string to ensure the NULL */ + ||!strncmp(jfs[k].name, "/sys", 5) + || !strncmp(jfs[k].name, "/dev", 5) + || !strncmp(jfs[i].name, "/var/lib/nfs/rpc", 16) + || !strncmp(jfs[k].name, "/rpc_pipe", 10) + ) { /* /proc gives invalid/insane values */ + if(show_jfs_minimum) /* just skip outputing this JFS */ + continue; + mvwprintw(padjfs, 2 + j, 0, "%-14s", jfs[k].name); + mvwprintw(padjfs, 2 + j, 27, "-"); + mvwprintw(padjfs, 2 + j, 35, "-"); + mvwprintw(padjfs, 2 + j, 41, "-"); + COLOUR wattrset(padjfs, COLOR_PAIR(4)); + mvwprintw(padjfs, 2 + j, 43, "%-8s not a real filesystem", jfs[k].type); + COLOUR wattrset(padjfs, COLOR_PAIR(0)); + } else { + statfs_buffer.f_blocks = 0; + if ((ret = + fstatfs(jfs[k].fd, + &statfs_buffer)) != -1) { + if (statfs_buffer.f_blocks != 0) { + /* older Linux seemed to always report in 4KB blocks but + newer Linux release use the f_bsize block sizes but + the man statfs docs the field as the natural I/O size so + the blocks reported here are ambigous in size */ + if (statfs_buffer.f_bsize == 0) + fs_bsize = 4.0 * 1024.0; + else + fs_bsize = statfs_buffer.f_bsize; + /* convert blocks to MB */ + fs_size = + (float) statfs_buffer.f_blocks * + fs_bsize / 1024.0 / 1024.0; + + /* find the best size info available f_bavail is like df reports + otherwise use f_bsize (this includes inode blocks) */ + if (statfs_buffer.f_bavail == 0) + fs_free = + (float) statfs_buffer.f_bfree * + fs_bsize / 1024.0 / 1024.0; + else + fs_free = + (float) statfs_buffer. + f_bavail * fs_bsize / 1024.0 / + 1024.0; + + /* this is a percentage */ + fs_size_used = + (fs_size - + (float) statfs_buffer.f_bfree * + fs_bsize / 1024.0 / 1024.0) / + fs_size * 100.0; + /* try to get the same number as df using kludge */ + /*fs_size_used += 1.0; */ + if (fs_size_used > 100.0) + fs_size_used = 100.0; + + if ((i = strlen(jfs[k].device)) < 20) + str_p = &jfs[k].device[0]; + else { + str_p = &jfs[k].device[i - 20]; + } + mvwprintw(padjfs, 2 + j, 0, + "%-20s %7.0f %7.0f %4.0f%% %-8s %s", + str_p, fs_size, fs_free, + ceil(fs_size_used), + jfs[k].type, jfs[k].name); + + } else { + mvwprintw(padjfs, 2 + j, 0, "%s", + jfs[k].name); + COLOUR wattrset(padjfs, COLOR_PAIR(5)); + mvwprintw(padjfs, 2 + j, 43, + "%-8s size=zero blocks!", + jfs[k].type); + COLOUR wattrset(padjfs, COLOR_PAIR(0)); + } + } else { + mvwprintw(padjfs, 2 + j, 0, "%s", + jfs[k].name); + COLOUR wattrset(padjfs, COLOR_PAIR(3)); + mvwprintw(padjfs, 2 + j, 43, + "%-8s statfs failed", + jfs[k].type); + COLOUR wattrset(padjfs, COLOR_PAIR(0)); + } + } + j++; + } + DISPLAY(padjfs, 2 + j); + } else { + jfs_load(LOAD); + fprintf(fp, + show_rrd ? "rrdtool update jfsfile.rrd %s" : + "JFSFILE,%s", LOOP); + for (k = 0; k < jfses; k++) { + if (jfs[k].mounted && strncmp(jfs[k].name, "/proc", 5) + && strncmp(jfs[k].name, "/sys", 4) + && strncmp(jfs[k].name, "/dev/", 5) + && strncmp(jfs[k].name, "/run/", 5) + && strncmp(jfs[k].name, "/var/lib/nfs/rpc", 16) + ) { /* /proc gives invalid/insane values */ + if (fstatfs(jfs[k].fd, &statfs_buffer) != -1) { + if (statfs_buffer.f_bsize == 0) + fs_bsize = 4.0 * 1024.0; + else + fs_bsize = statfs_buffer.f_bsize; + /* convert blocks to MB */ + fs_size = + (float) statfs_buffer.f_blocks * fs_bsize / + 1024.0 / 1024.0; + + /* find the best size info available f_bavail is like df reports + otherwise use f_bsize (this includes inode blocks) */ + if (statfs_buffer.f_bavail == 0) + fs_free = + (float) statfs_buffer.f_bfree * + fs_bsize / 1024.0 / 1024.0; + else + fs_free = + (float) statfs_buffer.f_bavail * + fs_bsize / 1024.0 / 1024.0; + + + + if (fs_size <= 0.0 || fs_bsize <= 0.0) /* some pseudo filesystems have zero size but we get a -nan result */ + fs_size_used = 0.0; + else + fs_size_used = + (fs_size - + (float) statfs_buffer.f_bfree * + fs_bsize / 1024.0 / 1024.0) / + fs_size * 100.0; + + if (fs_size_used > 100.0) + fs_size_used = 100.0; + + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + fs_size_used); + } else + fprintf(fp, show_rrd ? ":U" : ",0.0"); + } + } + fprintf(fp, "\n"); + jfs_load(UNLOAD); + } + } + + if (show_disk || show_verbose || show_diskmap || show_dgroup) { + proc_read(P_STAT); + proc_disk(elapsed); + } + if (show_diskmap) { + BANNER(padmap, "Disk %%Busy Map"); + mvwprintw(padmap, 0, 18, + "Key: @=90 #=80 X=70 8=60 O=50 0=40 o=30 +=20 -=10 .=5 _=0%%"); + mvwprintw(padmap, 1, 0, + " Disk No. 1 2 3 4 5 6 "); + if (disk_first_time) { + disk_first_time = 0; + mvwprintw(padmap, 2, 0, + "Please wait - collecting disk data"); + } else { + mvwprintw(padmap, 2, 0, + "Disks=%-4d 0123456789012345678901234567890123456789012345678901234567890123", + disks); + mvwprintw(padmap, 3, 0, "disk 0 to 63 "); + for (i = 0; i < disks; i++) { + disk_busy = DKDELTA(dk_time) / elapsed; + disk_read = DKDELTA(dk_rkb) / elapsed; + disk_write = DKDELTA(dk_wkb) / elapsed; + /* ensure boundaries */ + if (disk_busy < 0) + disk_busy = 0; + else if (disk_busy > 99) + disk_busy = 99; + +#define MAPWRAP 64 + mvwprintw(padmap, 3 + (int) (i / MAPWRAP), + 13 + (i % MAPWRAP), "%c", + disk_busy_map_ch[(int) disk_busy]); + } + } + DISPLAY(padmap, 4 + disks / MAPWRAP); + } + if (show_verbose) { + top_disk_busy = 0.0; + top_disk_name = ""; + for (i = 0, k = 0; i < disks; i++) { + disk_busy = DKDELTA(dk_time) / elapsed; + if (disk_busy > top_disk_busy) { + top_disk_busy = disk_busy; + top_disk_name = p->dk[i].dk_name; + } + } + if (top_disk_busy > 80.0) { + COLOUR wattrset(padverb, COLOR_PAIR(1)); + mvwprintw(padverb, 3, 0, " DANGER"); + } else if (top_disk_busy > 60.0) { + COLOUR wattrset(padverb, COLOR_PAIR(4)); + mvwprintw(padverb, 3, 0, "Warning"); + } else { + COLOUR wattrset(padverb, COLOR_PAIR(2)); + mvwprintw(padverb, 3, 0, " OK"); + } + COLOUR wattrset(padverb, COLOR_PAIR(0)); + mvwprintw(padverb, 3, 8, + "-> Top Disk %8s %%busy %5.1f%%\t>40%%\t>60%% ", + top_disk_name, top_disk_busy); + move(x, 0); + } + if (show_disk) { + if (cursed) { + if (show_disk) { + BANNER(paddisk, "Disk I/O"); + switch (disk_mode) { + case DISK_MODE_PARTITIONS: + mvwprintw(paddisk, 0, 12, "/proc/partitions"); + break; + case DISK_MODE_DISKSTATS: + mvwprintw(paddisk, 0, 12, "/proc/diskstats"); + break; + case DISK_MODE_IO: + mvwprintw(paddisk, 0, 12, "/proc/stat+disk_io"); + break; + } + mvwprintw(paddisk, 0, 31, "mostly in KB/s"); + mvwprintw(paddisk, 0, 50, + "Warning:contains duplicates"); + switch (show_disk) { + case SHOW_DISK_STATS: + mvwprintw(paddisk, 1, 0, "DiskName Busy"); + COLOUR wattrset(paddisk, COLOR_PAIR(6)); + mvwprintw(paddisk, 1, 17, "Read"); + COLOUR wattrset(paddisk, COLOR_PAIR(3)); + mvwprintw(paddisk, 1, 25, "Write"); + COLOUR wattrset(paddisk, COLOR_PAIR(0)); + mvwprintw(paddisk, 1, 37, + "Xfers Size Peak%% Peak=R+W InFlight "); + break; + case SHOW_DISK_GRAPH: + mvwprintw(paddisk, 1, 0, "DiskName Busy "); + COLOUR wattrset(paddisk, COLOR_PAIR(6)); + mvwprintw(paddisk, 1, 15, "Read "); + COLOUR wattrset(paddisk, COLOR_PAIR(3)); + mvwprintw(paddisk, 1, 20, "Write"); + COLOUR wattrset(paddisk, COLOR_PAIR(0)); + mvwprintw(paddisk, 1, 25, + "KB|0 |25 |50 |75 100|"); + break; + } + } + if (disk_first_time) { + disk_first_time = 0; + mvwprintw(paddisk, 2, 0, + "Please wait - collecting disk data"); + } else { + total_disk_read = 0.0; + total_disk_write = 0.0; + total_disk_xfers = 0.0; + disk_mb = 0; + for (i = 0, k = 0; i < disks; i++) { + disk_read = DKDELTA(dk_rkb) / elapsed; + disk_write = DKDELTA(dk_wkb) / elapsed; + if ((show_disk == SHOW_DISK_GRAPH) + && (disk_read > 9999.9 + || disk_write > 9999.9)) { + disk_mb = 1; + COLOUR wattrset(paddisk, COLOR_PAIR(1)); + mvwprintw(paddisk, 1, 25, "MB"); + COLOUR wattrset(paddisk, COLOR_PAIR(0)); + break; + } + } + for (i = 0, k = 0; i < disks; i++) { + if (disk_only_mode + && is_dgroup_name(p->dk[i].dk_name) == 0) + continue; + +/* + if(p->dk[i].dk_name[0] == 'h') + continue; +*/ + disk_busy = DKDELTA(dk_time) / elapsed; + disk_read = DKDELTA(dk_rkb) / elapsed; + disk_write = DKDELTA(dk_wkb) / elapsed; + disk_xfers = DKDELTA(dk_xfers); + + total_disk_read += disk_read; + total_disk_write += disk_write; + total_disk_xfers += disk_xfers; + + if (disk_busy_peak[i] < disk_busy) + disk_busy_peak[i] = disk_busy; + if (disk_rate_peak[i] < (disk_read + disk_write)) + disk_rate_peak[i] = disk_read + disk_write; + if (!show_all && disk_busy < 1) + continue; + + if (strlen(p->dk[i].dk_name) > 8) + str_p = + &p->dk[i]. + dk_name[strlen(p->dk[i].dk_name) - 8]; + else + str_p = &p->dk[i].dk_name[0]; + + if (show_disk == SHOW_DISK_STATS) { + /* output disks stats */ + mvwprintw(paddisk, 2 + k, 0, "%-8s%4.0f%%", + str_p, disk_busy); + COLOUR wattrset(paddisk, COLOR_PAIR(6)); + mvwprintw(paddisk, 2 + k, 13, "%9.1f", + disk_read); + COLOUR wattrset(paddisk, COLOR_PAIR(3)); + mvwprintw(paddisk, 2 + k, 22, "%9.1fKB/s", + disk_write); + COLOUR wattrset(paddisk, COLOR_PAIR(5)); + mvwprintw(paddisk, 2 + k, 36, "%6.1f", disk_xfers / elapsed); + COLOUR wattrset(paddisk, COLOR_PAIR(4)); + mvwprintw(paddisk, 2 + k, 43, "%5.1fKB", + disk_xfers == 0.0 ? 0.0 : (DKDELTA(dk_rkb) + DKDELTA(dk_wkb)) / disk_xfers); + COLOUR wattrset(paddisk, COLOR_PAIR(2)); + mvwprintw(paddisk, 2 + k, 52, + "%3.0f%% %9.1fKB/s", + disk_busy_peak[i], + disk_rate_peak[i]); + COLOUR wattrset(paddisk, COLOR_PAIR(3)); + mvwprintw(paddisk, 2 + k, 70, "%3d", p->dk[i].dk_inflight); + COLOUR wattrset(paddisk, COLOR_PAIR(0)); + k++; + } + if (show_disk == SHOW_DISK_GRAPH) { + /* output disk bar graphs */ + if (disk_mb) { + disk_read_tmp = disk_read / 1024.0; + disk_write_tmp = disk_write / 1024.0; + } else { + disk_read_tmp = disk_read; + disk_write_tmp = disk_write; + } + + mvwprintw(paddisk, 2 + k, 0, "%-8s %3.0f%%", + str_p, disk_busy); + COLOUR wattrset(paddisk, COLOR_PAIR(6)); + mvwprintw(paddisk, 2 + k, 13, "%7.1f", + disk_read_tmp); + COLOUR wattrset(paddisk, COLOR_PAIR(3)); + mvwprintw(paddisk, 2 + k, 20, "%7.1f", + disk_write_tmp); + COLOUR wattrset(paddisk, COLOR_PAIR(0)); + + mvwprintw(paddisk, 2 + k, 27, + "| "); + wmove(paddisk, 2 + k, 28); + if (disk_busy > 100) + disk_busy = 100; + if (disk_busy > 0.0 + && (disk_write + disk_read) > 0.1) { + /* 50 columns in the disk graph area so divide % by two */ + readers = + disk_busy * disk_read / (disk_write + + disk_read) / + 2; + writers = + disk_busy * disk_write / (disk_write + + disk_read) / + 2; + if (readers + writers > 50) { + readers = 0; + writers = 0; + } + /* don't go beyond row 78 i.e. j = 28 + 50 */ + for (j = 0; j < readers && j < 50; j++) { + COLOUR wattrset(paddisk, + COLOR_PAIR(12)); + wprintw(paddisk, "R"); + COLOUR wattrset(paddisk, + COLOR_PAIR(0)); + } + for (; j < readers + writers && j < 50; + j++) { + COLOUR wattrset(paddisk, + COLOR_PAIR(11)); + wprintw(paddisk, "W"); + COLOUR wattrset(paddisk, + COLOR_PAIR(0)); + } + for (j = disk_busy; j < 50; j++) + wprintw(paddisk, " "); + } else { + for (j = 0; j < 50; j++) + wprintw(paddisk, " "); + if (p->dk[i].dk_time == 0.0) + mvwprintw(paddisk, 2 + k, 27, + "| disk busy not available"); + } + if (disk_busy_peak[i] > 100) + disk_busy_peak[i] = 100; + + mvwprintw(paddisk, 2 + i, 77, "|"); + /* check rounding has not got the peak ">" over the 100% */ + j = 28 + (int) (disk_busy_peak[i] / 2); + if (j > 77) + j = 77; + mvwprintw(paddisk, 2 + i, j, ">"); + k++; + } + } + mvwprintw(paddisk, 2 + k, 0, + "Totals Read-MB/s=%-8.1f Writes-MB/s=%-8.1f Transfers/sec=%-8.1f", + total_disk_read / 1024.0, + total_disk_write / 1024.0, + total_disk_xfers / elapsed); + + } + DISPLAY(paddisk, 3 + k); + } else { + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, + show_rrd ? + "%srrdtool update diskbusy%s.rrd %s" : + "%sDISKBUSY%s,%s", i == 0 ? "" : "\n", + dskgrp(i), LOOP); + /* check percentage is correct */ + ftmp = DKDELTA(dk_time) / elapsed; + if (ftmp > 100.0 || ftmp < 0.0) + fprintf(fp, show_rrd ? ":U" : ",101.00"); + else + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + DKDELTA(dk_time) / elapsed); + } + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, + show_rrd ? + "\nrrdtool update diskread%s.rrd %s" : + "\nDISKREAD%s,%s", dskgrp(i), LOOP); + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + DKDELTA(dk_rkb) / elapsed); + } + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, + show_rrd ? + "\nrrdtool update diskwrite%s.rrd %s" : + "\nDISKWRITE%s,%s", dskgrp(i), LOOP); + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + DKDELTA(dk_wkb) / elapsed); + } + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, + show_rrd ? + "\nrrdtool update diskxfer%s.rrd %s" : + "\nDISKXFER%s,%s", dskgrp(i), LOOP); + disk_xfers = DKDELTA(dk_xfers); + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + disk_xfers / elapsed); + } + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) + fprintf(fp, + show_rrd ? + "\nrrdtool update diskbsize%s.rrd %s" : + "\nDISKBSIZE%s,%s", dskgrp(i), LOOP); + disk_xfers = DKDELTA(dk_xfers); + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + disk_xfers == 0.0 ? 0.0 : + (DKDELTA(dk_rkb) + + DKDELTA(dk_wkb)) / disk_xfers); + } + + if (extended_disk == 1 && disk_mode == DISK_MODE_DISKSTATS) { + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) { + fprintf(fp, "\nDISKREADS%s,%s", dskgrp(i), + LOOP); + } + disk_read = DKDELTA(dk_reads); + fprintf(fp, ",%.1f", disk_read / elapsed); + } + + for (i = 0; i < disks; i++) { + if (NEWDISKGROUP(i)) { + fprintf(fp, "\nDISKWRITES%s,%s", dskgrp(i), + LOOP); + } + disk_write = DKDELTA(dk_writes); + fprintf(fp, ",%.1f", disk_write / elapsed); + } + } + fprintf(fp, "\n"); + } + } + if ((show_dgroup || (!cursed && dgroup_loaded))) { + if (cursed) { + BANNER(paddg, "Disk Group I/O"); + if (dgroup_loaded != 2 || dgroup_total_disks == 0) { + mvwprintw(paddg, 1, 1, + "No Disk Groups found use -g groupfile when starting nmon"); + } else if (disk_first_time) { + disk_first_time = 0; + mvwprintw(paddg, 1, 1, + "Please wait - collecting disk data"); + } else { + mvwprintw(paddg, 1, 1, + "Name Disks AvgBusy | TotalMB/s xfers/s BlockSizeKB"); + COLOUR wattrset(paddg, COLOR_PAIR(6)); + mvwprintw(paddg, 1, 29, "Read-KB/s"); + COLOUR wattrset(paddg, COLOR_PAIR(3)); + mvwprintw(paddg, 1, 39, "Write"); + COLOUR wattrset(paddg, COLOR_PAIR(0)); + total_busy = 0.0; + total_rbytes = 0.0; + total_wbytes = 0.0; + total_xfers = 0.0; + for (k = n = 0; k < dgroup_total_groups; k++) { +/* + if (dgroup_name[k] == 0 ) + continue; +*/ + disk_busy = 0.0; + disk_read = 0.0; + disk_write = 0.0; + disk_xfers = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { + disk_busy += DKDELTA(dk_time) / elapsed; +/* + disk_read += DKDELTA(dk_reads) * p->dk[i].dk_bsize / 1024.0 /elapsed; + disk_write += DKDELTA(dk_writes) * p->dk[i].dk_bsize / 1024.0 /elapsed; +*/ + disk_read += DKDELTA(dk_rkb) / elapsed; + disk_write += DKDELTA(dk_wkb) / elapsed; + disk_xfers += DKDELTA(dk_xfers) / elapsed; + } + } + if (dgroup_disks[k] == 0) + disk_busy = 0.0; + else + disk_busy = disk_busy / dgroup_disks[k]; + total_busy += disk_busy; + total_rbytes += disk_read; + total_wbytes += disk_write; + total_xfers += disk_xfers; +/* if (!show_all && (disk_read < 1.0 && disk_write < 1.0)) + continue; +*/ + if ((disk_read + disk_write) == 0 + || disk_xfers == 0) + disk_size = 0.0; + else + disk_size = + ((float) disk_read + + (float) disk_write) / (float) disk_xfers; + mvwprintw(paddg, n + 2, 1, "%-14s %3d %5.1f%% | %6.1f %9.1f %6.1f ", dgroup_name[k], dgroup_disks[k], disk_busy, (disk_read + disk_write) / 1024, /* in MB */ + disk_xfers, disk_size); + COLOUR wattrset(paddg, COLOR_PAIR(6)); + mvwprintw(paddg, n + 2, 29, "%9.1f", disk_read); + COLOUR wattrset(paddg, COLOR_PAIR(3)); + mvwprintw(paddg, n + 2, 39, "%-9.1f", disk_write); + COLOUR wattrset(paddg, COLOR_PAIR(0)); + n++; + } + mvwprintw(paddg, n + 2, 1, "Groups=%2d TOTALS %3d %5.1f%% %9.1f|%-9.1f %6.1f %9.1f", n, dgroup_total_disks, total_busy / dgroup_total_disks, total_rbytes, total_wbytes, (((double) total_rbytes + (double) total_wbytes)) / 1024, /* in MB */ + total_xfers); + } + DISPLAY(paddg, 3 + dgroup_total_groups); + } else { + if (dgroup_loaded == 2) { + fprintf(fp, + show_rrd ? "rrdtool update dgbusy.rdd %s" : + "DGBUSY,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { + disk_total += + DKDELTA(dk_time) / elapsed; + } + } + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + (float) (disk_total / + dgroup_disks[k])); + } + } + fprintf(fp, "\n"); + fprintf(fp, + show_rrd ? "rrdtool update dgread.rdd %s" : + "DGREAD,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { +/* + disk_total += DKDELTA(dk_reads) * p->dk[i].dk_bsize / 1024.0; +*/ + disk_total += DKDELTA(dk_rkb); + } + } + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + disk_total / elapsed); + } + } + fprintf(fp, "\n"); + fprintf(fp, + show_rrd ? "rrdtool update dgwrite.rdd %s" : + "DGWRITE,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { +/* + disk_total += DKDELTA(dk_writes) * p->dk[i].dk_bsize / 1024.0; +*/ + disk_total += DKDELTA(dk_wkb); + } + } + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + disk_total / elapsed); + } + } + fprintf(fp, "\n"); + fprintf(fp, + show_rrd ? "rrdtool update dgbsize.rdd %s" : + "DGSIZE,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_write = 0.0; + disk_xfers = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { +/* + disk_write += (DKDELTA(dk_reads) + DKDELTA(dk_writes) ) * p->dk[i].dk_bsize / 1024.0; +*/ + disk_write += + (DKDELTA(dk_rkb) + + DKDELTA(dk_wkb)); + disk_xfers += DKDELTA(dk_xfers); + } + } + if (disk_write == 0.0 || disk_xfers == 0.0) + disk_size = 0.0; + else + disk_size = disk_write / disk_xfers; + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + disk_size); + } + } + fprintf(fp, "\n"); + fprintf(fp, + show_rrd ? "rrdtool update dgxfer.rdd %s" : + "DGXFER,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { + disk_total += DKDELTA(dk_xfers); + } + } + fprintf(fp, show_rrd ? ":%.1f" : ",%.1f", + disk_total / elapsed); + } + } + fprintf(fp, "\n"); + + if (extended_disk == 1 + && disk_mode == DISK_MODE_DISKSTATS) { + fprintf(fp, "DGREADS,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { + disk_total += DKDELTA(dk_reads); + } + } + fprintf(fp, ",%.1f", disk_total / elapsed); + } + } + fprintf(fp, "\n"); + fprintf(fp, "DGREADMERGE,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { + disk_total += DKDELTA(dk_rmerge); + } + } + fprintf(fp, ",%.1f", disk_total / elapsed); + } + } + fprintf(fp, "\n"); + fprintf(fp, "DGREADSERV,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { + disk_total += DKDELTA(dk_rmsec); + } + } + fprintf(fp, ",%.1f", disk_total / elapsed); + } + } + fprintf(fp, "\n"); + fprintf(fp, "DGWRITES,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { + disk_total += DKDELTA(dk_writes); + } + } + fprintf(fp, ",%.1f", disk_total / elapsed); + } + } + fprintf(fp, "\n"); + fprintf(fp, "DGWRITEMERGE,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { + disk_total += DKDELTA(dk_wmerge); + } + } + fprintf(fp, ",%.1f", disk_total / elapsed); + } + } + fprintf(fp, "\n"); + fprintf(fp, "DGWRITESERV,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { + disk_total += DKDELTA(dk_wmsec); + } + } + fprintf(fp, ",%.1f", disk_total / elapsed); + } + } + fprintf(fp, "\n"); + fprintf(fp, "DGINFLIGHT,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { + disk_total += p->dk[i].dk_inflight; + } + } + fprintf(fp, ",%.1f", disk_total); + } + } + fprintf(fp, "\n"); + fprintf(fp, "DGBACKLOG,%s", LOOP); + for (k = 0; k < dgroup_total_groups; k++) { + if (dgroup_name[k] != 0) { + disk_total = 0.0; + for (j = 0; j < dgroup_disks[k]; j++) { + i = dgroup_data[k * DGROUPITEMS + j]; + if (i != -1) { + disk_total += DKDELTA(dk_backlog); + } + } + fprintf(fp, ",%.1f", disk_total / elapsed); + } + } + fprintf(fp, "\n"); + } /* if( extended_disk == 1 && disk_mode == DISK_MODE_DISKSTATS */ + } /* if (dgroup_loaded == 2) */ + } /* else from if(cursed) */ + } + /* if ((show_dgroup || (!cursed && dgroup_loaded))) */ + if (show_top) { + wmove(padtop, 1, 1); + wclrtobot(padtop); + /* Get the details of the running processes */ + skipped = 0; + current_procs = getprocs(0); + if (current_procs > p->proc_records) { + adjusted_procs = current_procs + 128; /* allow for growth in the number of processes in the mean time */ + p->procs = REALLOC(p->procs, sizeof(struct procsinfo) * adjusted_procs); + p->proc_records = adjusted_procs; + } + + p->processes = getprocs(p->proc_records); + + if (topper_size < p->processes) { + topper = REALLOC(topper, sizeof(struct topper) * (p->processes +1));/* add one to avoid overrun */ + topper_size = p->processes; + } + /* Sort the processes by CPU utilisation */ + for (i = 0, max_sorted = 0; i < p->processes; i++) { + /* move forward in the previous array to find a match */ + for (j = 0; j < q->processes; j++) { + if (p->procs[i].pi_pid == q->procs[j].pi_pid) { /* found a match */ + topper[max_sorted].index = i; + topper[max_sorted].other = j; + topper[max_sorted].time = + TIMEDELTA(pi_utime, i, j) + TIMEDELTA(pi_stime, i, j); + topper[max_sorted].size = + p->procs[i].statm_resident; + if (isroot && cursed) /* we don't sort on this in data capture */ + topper[max_sorted].io = + IODELTA(read_io, i, j) + IODELTA(write_io, i, j); + + max_sorted++; + break; + } + } + } + switch (show_topmode) { + default: + case 3: + qsort((void *) &topper[0], max_sorted, + sizeof(struct topper), &cpu_compare); + break; + case 4: + qsort((void *) &topper[0], max_sorted, + sizeof(struct topper), &size_compare); + break; + case 5: + qsort((void *) &topper[0], max_sorted, + sizeof(struct topper), &disk_compare); + break; + } + CURSE BANNER(padtop, "Top Processes"); + if (isroot) { + formatstring = "Procs=%d-mode=%d-1=Base 3=Perf 4=Size 5=I/O u=Args"; + } else { + formatstring = "Procs=%d-mode=%d-1=Base 3=Perf 4=Size 5=I/O[RootOnly] u=Args"; + } + CURSE mvwprintw(padtop, 0, 15, formatstring, p->processes, show_topmode); + if (cursed && top_first_time) { + top_first_time = 0; + mvwprintw(padtop, 1, 1, + "Please wait - information being collected"); + } else { + switch (show_topmode) { + case 1: /* Basic */ + if(cursed) { + mvwprintw(padtop, 1, 1, + " PID PPID Pgrp Nice Prior Status Proc-Flag Command"); + for (j = 0; j < max_sorted; j++) { + i = topper[j].index; + if (p->procs[i].pi_pgrp == p->procs[i].pi_pid) + strcpy(pgrp, "none"); + else + snprintf(&pgrp[0], 32, "%d", p->procs[i].pi_pgrp); + /* skip over processes with 0 CPU */ + if (!show_all + && (topper[j].time / elapsed < + ignore_procdisk_threshold) && !cmdfound) + break; + if (x + j + 2 - skipped > LINES + 2) /* +2 to for safety :-) */ + break; + mvwprintw(padtop, j + 2 - skipped, 1, "%7d %7d %6s", + p->procs[i].pi_pid, + p->procs[i].pi_ppid, + pgrp); + COLOUR wattrset(padtop, COLOR_PAIR(5)); + mvwprintw(padtop, j + 2 - skipped, 24, "%4d %4d", + p->procs[i].pi_nice, + p->procs[i].pi_pri); + if (topper[j].time * 100 / elapsed) { + COLOUR wattrset(padtop, COLOR_PAIR(1)); + } else { + COLOUR wattrset(padtop, COLOR_PAIR(2)); + } + mvwprintw(padtop, j + 2 - skipped, 35, "%9s", + (topper[j].time * 100 / elapsed) ? "Running " : get_state(p->procs[i].pi_state)); + + COLOUR wattrset(padtop, COLOR_PAIR(6)); + mvwprintw(padtop, j + 2 - skipped, 45, "0x%08x", + p->procs[i].pi_flags); + COLOUR wattrset(padtop, COLOR_PAIR(1)); + mvwprintw(padtop, j + 2 - skipped, 54, "%1s", + (p->procs[i].pi_tty_nr ? "F" : " ")); + COLOUR wattrset(padtop, COLOR_PAIR(3)); + mvwprintw(padtop, j + 2 - skipped, 57, "%-32s", p->procs[i].pi_comm); + COLOUR wattrset(padtop, COLOR_PAIR(0)); + } + } + break; + case 3: + case 4: + case 5: + + if (show_args == ARGS_ONLY) { + formatstring = + " PID %%CPU ResSize Command "; + } else if (COLS > 119) { + if (show_topmode == 5) + formatstring = + " PID %%CPU Size Res Res Res Res Shared StorageKB Command"; + else + formatstring = + " PID %%CPU Size Res Res Res Res Shared Faults Faults Command"; + } else { + if (show_topmode == 5) + formatstring = + " PID %%CPU Size Res Res Res Res Shared StorageKB Command"; + else + formatstring = + " PID %%CPU Size Res Res Res Res Shared Faults Command"; + } + CURSE mvwprintw(padtop, 1, y, formatstring); + + if (show_args == ARGS_ONLY) { + formatstring = + " Used KB "; + } else if (COLS > 119) { + if (show_topmode == 5) + formatstring = + " Used KB Set Text Data Lib KB Read Write"; + else + formatstring = + " Used KB Set Text Data Lib KB Min Maj"; + } else { + if (show_topmode == 5) + formatstring = + " Used KB Set Text Data Lib KB ReadWrite "; + else + formatstring = + " Used KB Set Text Data Lib KB Min Maj "; + } + CURSE mvwprintw(padtop, 2, 1, formatstring); + for (j = 0; j < max_sorted; j++) { + i = topper[j].index; + if (!show_all) { + /* skip processes with zero CPU/io */ + if (show_topmode == 3 + && (topper[j].time / elapsed) < + ignore_procdisk_threshold && !cmdfound) + break; + if (show_topmode == 5 + && (topper[j].io < ignore_io_threshold + && !cmdfound)) + break; + } + if (cursed) { + if (x + j + 3 - skipped > LINES + 2) /* +2 to for safety :-) XYZXYZ */ + break; + if (cmdfound && !cmdcheck(p->procs[i].pi_comm)) { + skipped++; + continue; + } + if (show_args == ARGS_ONLY) { + + mvwprintw(padtop, j + 3 - skipped, 1, "%7d", p->procs[i].pi_pid); + COLOUR wattrset(padtop, COLOR_PAIR(1)); + mvwprintw(padtop, j + 3 - skipped, 9, "%5.1f", topper[j].time / elapsed); + COLOUR wattrset(padtop, COLOR_PAIR(2)); + mvwprintw(padtop, j + 3 - skipped, 16, "%7lu", p->procs[i].statm_resident * pagesize / 1024); /* in KB */ + COLOUR wattrset(padtop, COLOR_PAIR(3)); + strncpy( truncated_command, args_lookup(p->procs[i].pi_pid, p->procs[i].pi_comm), 256); + truncated_command[255] = 0; /* worst longest case */ + truncated_command[COLS - 24 - 2] = 0; + + mvwprintw(padtop, j + 3 - skipped, 24, "%-120s", truncated_command); + COLOUR wattrset(padtop, COLOR_PAIR(0)); + } else { + topsize = p->procs[i].statm_size * pagesize / 1024UL; /* in KB */ + topsize_ch = ' '; + toprset = p->procs[i].statm_resident * pagesize / 1024UL; /* in KB */ + toprset_ch = ' '; + toptrs = p->procs[i].statm_trs * pagesize / 1024UL; /* in KB */ + toptrs_ch = ' '; + topdrs = p->procs[i].statm_drs * pagesize / 1024UL; /* in KB */ + topdrs_ch = ' '; + toplrs = p->procs[i].statm_lrs * pagesize / 1024UL; /* in KB */ + toplrs_ch = ' '; + topshare = p->procs[i].statm_share * pagesize / 1024UL; /* in KB */ + topshare_ch = ' '; + toprio = (int) (COUNTDELTA(read_io) / elapsed / 1024); + toprio_ch = ' '; + topwio = (int) (COUNTDELTA(write_io) / elapsed / 1024); + topwio_ch = ' '; +/* + if (COLS > 119) + formatstring = "%8d %8.1f %9lu%c%9lu%c%9lu%c%9lu%c%9lu%c%9lu%c%8d%c%8d%c%-32s"; + else { + formatstring = "%7d %5.1f %5lu%c%5lu%c%5lu%c%5lu%c%5lu%c%5lu%c%4d%c%4d%c%-32s"; +*/ + if (COLS < 119) { + if(topsize > 99999UL) { + topsize = topsize / 1024UL; + topsize_ch = 'm'; + } + if(toprset > 99999UL) { + toprset = toprset / 1024UL; + toprset_ch = 'm'; + } + if(toptrs > 99999UL) { + toptrs = toptrs / 1024UL; + toptrs_ch = 'm'; + } + if(topdrs > 99999UL) { + topdrs = topdrs / 1024UL; + topdrs_ch = 'm'; + } + if(toptrs > 99999UL) { + toplrs = toplrs / 1024UL; + toplrs_ch = 'm'; + } + if(toptrs > 99999UL) { + topshare = topshare / 1024UL; + topshare_ch = 'm'; + } + if(toprio > 99999UL) { + toprio = toprio / 1024UL; + topwio_ch = 'm'; + } + if(topwio > 99999UL) { + topwio = topwio / 1024UL; + topwio_ch = 'm'; + } + /* now repeat incase we get many tens of GB sizes */ + if(topsize > 99999UL) { + topsize = topsize / 1024UL; + topsize_ch = 'g'; + } + if(toprset > 99999UL) { + toprset = toprset / 1024UL; + toprset_ch = 'g'; + } + if(toptrs > 99999UL) { + toptrs = toptrs / 1024UL; + toptrs_ch = 'g'; + } + if(topdrs > 99999UL) { + topdrs = topdrs / 1024UL; + topdrs_ch = 'g'; + } + if(toptrs > 99999UL) { + toplrs = toplrs / 1024UL; + toplrs_ch = 'g'; + } + if(toptrs > 99999UL) { + topshare = topshare / 1024UL; + topshare_ch = 'g'; + } + if(toprio > 99999UL) { + toprio = toprio / 1024UL; + topwio_ch = 'g'; + } + if(topwio > 99999UL) { + topwio = topwio / 1024UL; + topwio_ch = 'g'; + } + } + + mvwprintw(padtop, j + 3 - skipped, 1, (COLS>119)?"%8d":"%7d", p->procs[i].pi_pid); + + COLOUR wattrset(padtop, COLOR_PAIR(1)); + mvwprintw(padtop, j + 3 - skipped, (COLS >119)?10:9, (COLS>119)?"%8.1f":"%5.1f", topper[j].time / elapsed); + + COLOUR wattrset(padtop, COLOR_PAIR(2)); + mvwprintw(padtop, j + 3 - skipped, (COLS >119)?19:15, + (COLS>119)?"%9lu%c%9lu%c%9lu%c%9lu%c%9lu%c%9lu%c":"%5lu%c%5lu%c%5lu%c%5lu%c%5lu%c%5lu%c", + topsize, topsize_ch, + toprset, toprset_ch, + toptrs, toptrs_ch, + topdrs, topdrs_ch, + toplrs, toplrs_ch, + topshare, topshare_ch); + + if(show_topmode == 5) { + COLOUR wattrset(padtop, COLOR_PAIR(5)); + mvwprintw(padtop, j + 3 - skipped, (COLS >119)?79:51, (COLS>119)?"%8d%c%8d%c":"%4d%c%4d%c", + (int)toprio, toprio_ch, (int)topwio, topwio_ch); + } else { + COLOUR wattrset(padtop, COLOR_PAIR(6)); + mvwprintw(padtop, j + 3 - skipped, (COLS >119)?79:51, (COLS>119)?"%8d %8d":"%4d %4d", + (int) (COUNTDELTA(pi_minflt) / elapsed), (int) (COUNTDELTA(pi_majflt) / elapsed) ); + } + COLOUR wattrset(padtop, COLOR_PAIR(3)); + mvwprintw(padtop, j + 3 - skipped, (COLS >119)?97:61, "%-32s", p->procs[i].pi_comm); + COLOUR wattrset(padtop, COLOR_PAIR(0)); + } + } else { + if ((cmdfound && cmdcheck(p->procs[i].pi_comm)) + || (!cmdfound + && ((topper[j].time / elapsed) > + ignore_procdisk_threshold))) { +#ifdef PRE_KERNEL_2_6_18 + fprintf(fp, + "TOP,%07d,%s,%.2f,%.2f,%.2f,%lu,%lu,%lu,%lu,%lu,%d,%d,%s\n", +#else + fprintf(fp, + "TOP,%07d,%s,%.2f,%.2f,%.2f,%lu,%lu,%lu,%lu,%lu,%d,%d,%s,%ld,%llu\n", +#endif + /* 1 */ p->procs[i].pi_pid, + /* 2 */ LOOP, + /* 3 */ topper[j].time / elapsed, + /* 4 */ TIMEDELTA(pi_utime, i, topper[j]. other) / elapsed, + /* 5 */ TIMEDELTA(pi_stime, i, topper[j]. other) / elapsed, + /* 6 */ p->procs[i].statm_size * pagesize / 1024UL, /* in KB */ + /* 7 */ p->procs[i].statm_resident * pagesize / 1024UL, /* in KB */ + /* 8 */ p->procs[i].statm_trs * pagesize / 1024UL, /* in KB */ + /* 9 */ p->procs[i].statm_drs * pagesize / 1024UL, /* in KB */ + /* 10 */ p->procs[i].statm_share * pagesize / 1024UL, /* in KB */ + /* 11 */ (int) (COUNTDELTA(pi_minflt) / elapsed), + /* 12 */ (int) (COUNTDELTA(pi_majflt) / elapsed), + /* 13 */ p->procs[i].pi_comm +#ifdef PRE_KERNEL_2_6_18 + ); +#else + , + p->procs[i].pi_num_threads, COUNTDELTA(pi_delayacct_blkio_ticks) + ); +#endif + + if (show_args) + args_output(p->procs[i].pi_pid, loop, + p->procs[i].pi_comm); + + } else + skipped++; + } + } + break; + } + } + DISPLAY(padtop, 3 + j); + } + + if (cursed) { + if (show_verbose) { + y = x; + x = 1; + DISPLAY(padverb, 4); + x = y; + } + /* underline the end of the stats area border */ + if (x < LINES - 2) + mvwhline(stdscr, x, 1, ACS_HLINE, COLS - 2); + + wmove(stdscr, 0, 0); + wrefresh(stdscr); + doupdate(); + + for (i = 0; i < seconds; i++) { + sleep(1); + if (checkinput()) + break; + } + if (x < LINES - 2) + mvwhline(stdscr, x, 1, ' ', COLS - 2); + if (first_key_pressed == 0) { + first_key_pressed = 1; + wmove(stdscr, 0, 0); + wclear(stdscr); + wmove(stdscr, 0, 0); + wclrtobot(stdscr); + wrefresh(stdscr); + doupdate(); + } + + } else { + fflush(NULL); + + gettimeofday(&nmon_tv, 0); + nmon_end_time = + (double) nmon_tv.tv_sec + + (double) nmon_tv.tv_usec * 1.0e-6; + if (nmon_run_time < 0.0) { + nmon_start_time = nmon_end_time; + nmon_run_time = 0.0; + } + nmon_run_time += (nmon_end_time - nmon_start_time); + if (nmon_run_time < 1.0) { + secs = seconds; /* sleep for the requested number of seconds */ + } else { + seconds_over = (int) nmon_run_time; /* reduce the sleep time by whole number of seconds */ + secs = seconds - seconds_over; + nmon_run_time -= (double) seconds_over; + } + if (secs < 1) /* sanity check in case CPUs are flat out and nmon taking far to long to complete */ + secs = 1; + + redo: + errno = 0; + ret = sleep(secs); + if ((ret != 0 || errno != 0) && loop != maxloops) { + fprintf(fp, + "ERROR,%s, sleep interrupted, sleep(%d seconds), return value=%d", + LOOP, secs, ret); + fprintf(fp, ", errno=%d\n", errno); + secs = ret; + goto redo; + } + gettimeofday(&nmon_tv, 0); + nmon_start_time = + (double) nmon_tv.tv_sec + + (double) nmon_tv.tv_usec * 1.0e-6; + } + + switcher(); + + if (loop >= maxloops) { + CURSE endwin(); + if (nmon_end) { + child_start(CHLD_END, nmon_end, time_stamp_type, loop, + timer); + /* Give the end - processing some time - 5s for now */ + sleep(5); + } + + fflush(NULL); + exit(0); + } + } +} diff --git a/source/SlackBuild/nmon/nmon.SlackBuild b/source/SlackBuild/nmon/nmon.SlackBuild new file mode 100755 index 00000000..6df43aa3 --- /dev/null +++ b/source/SlackBuild/nmon/nmon.SlackBuild @@ -0,0 +1,88 @@ +#!/bin/sh + +# Slackware build script for nmon + +# Copyright 2014 Georgi Kolev, Bulgaria +# All rights reserved. +# +# Redistribution and use of this script, with or without modification, is +# permitted provided that the following conditions are met: +# +# 1. Redistributions of this script must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +PRGNAM=nmon +VERSION=${VERSION:-16m} +BUILD=${BUILD:-1} +TAG=${TAG:-_SBo} + +if [ -z "$ARCH" ]; then + case "$( uname -m )" in + i?86) ARCH=i486 ;; + arm*) ARCH=arm ;; + *) ARCH=$( uname -m ) ;; + esac +fi + +CWD=$(pwd) +TMP=${TMP:-/tmp/SBo} +PKG=$TMP/package-$PRGNAM +OUTPUT=${OUTPUT:-/tmp} + +if [ "$ARCH" = "i486" ]; then + SLKCFLAGS="-g -O2 -march=i486 -mtune=i686 -D JFS -D GETUSER -Wall -D LARGEMEM -lncurses -g -D X86" + LIBDIRSUFFIX="" +elif [ "$ARCH" = "i686" ]; then + SLKCFLAGS="-g -O2 -march=i686 -mtune=i686 -D JFS -D GETUSER -Wall -D LARGEMEM -lncurses -g -D X86" + LIBDIRSUFFIX="" +elif [ "$ARCH" = "x86_64" ]; then + SLKCFLAGS="-g -O3 -Wall -lncurses -lm -D X86" + LIBDIRSUFFIX="64" +else + SLKCFLAGS="-g -O2 -D JFS -D GETUSER -Wall -D LARGEMEM -lncurses -g -D X86" + LIBDIRSUFFIX="" +fi + +set -eux + +rm -rf $PKG +mkdir -p $TMP $PKG $OUTPUT +cd $TMP +rm -rf $PRGNAM +mkdir -p $PRGNAM +cp $CWD/lmon.c $PRGNAM +cd $TMP/$PRGNAM +chown -R root:root . +find -L . \ + \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \ + -o -perm 511 \) -exec chmod 755 {} \; -o \ + \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \ + -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \; + +cc -o $TMP/$PRGNAM/nmon $TMP/$PRGNAM/lmon.c $SLKCFLAGS + +find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \ + | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true + +mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION +cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild + +mkdir -p $PKG/install +cat $CWD/slack-desc > $PKG/install/slack-desc + +mkdir -p $PKG/usr/bin +cp $TMP/$PRGNAM/nmon $PKG/usr/bin/ + +cd $PKG +/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-txz} diff --git a/source/SlackBuild/nmon/slack-desc b/source/SlackBuild/nmon/slack-desc new file mode 100644 index 00000000..53d56d8c --- /dev/null +++ b/source/SlackBuild/nmon/slack-desc @@ -0,0 +1,19 @@ +# HOW TO EDIT THIS FILE: +# The "handy ruler" below makes it easier to edit a package description. +# Line up the first '|' above the ':' following the base package name, and +# the '|' on the right side marks the last column you can put a character in. +# You must make exactly 11 lines for the formatting to be correct. It's also +# customary to leave one space after the ':' except on otherwise blank lines. + + |-----handy-ruler------------------------------------------------------| +nmon: nmon (Nigel's performance MONitor) +nmon: +nmon: This systems administrator, tuner, benchmark tool gives you a huge +nmon: amount of important performance information in one go. It can output +nmon: the data in two ways. +nmon: +nmon: 1) You can display the CPU, memory, network, disks +nmon: (mini graphs or numbers), file systems, NFS, top processes, resources +nmon: 2) Save the data to a comma separated file for analysis and longer +nmon: term data capture. +nmon: