diff --git a/lmon16g.c b/lmon16m.c similarity index 96% rename from lmon16g.c rename to lmon16m.c index cb27e09..46ac536 100644 --- a/lmon16g.c +++ b/lmon16m.c @@ -20,13 +20,13 @@ /* * Use the following Makefile (for Linux on POWER) -CFLAGS=-g -D JFS -D GETUSER -Wall -D LARGEMEM -D POWER -D KERNEL_2_6_18lmon15ibeta10.c +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 - only one of these at a time +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: @@ -34,10 +34,8 @@ Bug / missing feature workarounds: LSBLK_NO_TYPE - SLES11.3 has not lsblk disk TYPE option Options which should always but switched on: -GETUSER - U optio to load user details -JFS - include FileSystem stats (most of which are now Journeled) -LARGMEM - most Linux's do not have older LOW and High Memory memory -KERNEL_2_6_18 1 kernel level and above adds the following to the disk stats +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, @@ -48,7 +46,7 @@ KERNEL_2_6_18 1 kernel level and above adds the following to the disk stats #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 "16g" +#define VERSION "16k" char version[] = VERSION; static char *SccsId = "nmon " VERSION; @@ -267,6 +265,7 @@ int error_on = 0; void error(char *err) { strncpy(errorstr, err, 69); + errorstr[69] = 0; } /* @@ -298,9 +297,9 @@ struct { void lscpu_init() { FILE *pop; - int i; -#define LSCPU_STRLEN 256 -#define NUMBER_COL 23 + int len; + int data_col = 21; +#define LSCPU_STRLEN 512 char tmpstr[LSCPU_STRLEN + 1]; if (lscpu_available == 1) @@ -309,18 +308,26 @@ void lscpu_init() if (pop != NULL) { lscpu_available = 1; tmpstr[0] = 0; - for (i = 0;; i++) { - if (fgets(tmpstr, LSCPU_STRLEN, pop) == NULL) - break; + while (fgets(tmpstr, LSCPU_STRLEN, pop) != NULL) { tmpstr[strlen(tmpstr) - 1] = 0; /* remove newline */ - if (strncmp("Architecture:", tmpstr, strlen("Architecture:")) - == 0) { - lscpu.arch = malloc(strlen(&tmpstr[NUMBER_COL]) + 1); - strcpy(lscpu.arch, &tmpstr[NUMBER_COL]); + 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/dev/null", "r"); #else pop = popen("cat /etc/*ease 2>/dev/null", "r"); @@ -761,7 +768,7 @@ void args_output(int pid, int loop, char *progname) if (arglist[i].pid == 0) /* got to empty slot */ break; } - sprintf(tmpstr, "ps -p %d -o args 2>/dev/null", pid); + snprintf(tmpstr, CMDLEN, "ps -p %d -o args 2>/dev/null", pid); pop = popen(tmpstr, "r"); if (pop == NULL) { return; @@ -835,7 +842,7 @@ void args_load() if (tmpstr[strlen(tmpstr) - 1] == ' ') tmpstr[strlen(tmpstr) - 1] = 0; arglist[i].pid = atoi(tmpstr); - arglist[i].args = MALLOC(strlen(tmpstr)); + arglist[i].args = MALLOC(strlen(tmpstr) + 1); strcpy(arglist[i].args, &tmpstr[6]); } pclose(pop); @@ -976,7 +983,7 @@ struct mem_stat { long lowfree; long swaptotal; long swapfree; -#ifdef LARGEMEM +#ifndef SMALLMEM long dirty; long writeback; long mapped; @@ -988,7 +995,7 @@ struct mem_stat { long hugesize; #else long bigfree; -#endif /*LARGEMEM*/ +#endif /*SMALLMEM*/ }; struct vm_stat { @@ -998,6 +1005,8 @@ struct vm_stat { 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; @@ -1207,12 +1216,12 @@ R7=0x1000000040004 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 DedDonMode; long group; long pool; long entitled_memory; @@ -1404,11 +1413,11 @@ int proc_lparcfg() GETDATA(entitled_memory_loan_request); /* AMS requesting more memory loaning */ } + GETDATA(DedDonMode); #ifdef EXPERIMENTAL GETDATA(DesEntCap); GETDATA(DesProcs); GETDATA(DesVarCapWt); - GETDATA(DedDonMode); GETDATA(group); GETDATA(pool); GETDATA(entitled_memory); @@ -1498,7 +1507,12 @@ int read_vmstat() GETVM(nr_unstable); GETVM(nr_page_table_pages); GETVM(nr_mapped); - GETVM(nr_slab); + 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); @@ -1657,14 +1671,15 @@ void get_intel_spec() } 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) || + (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][15]); + id = atoi(&proc[P_CPUINFO].line[i][14]); if (id < 256) physicalcpu[id] = 1; } @@ -2076,7 +2091,7 @@ void proc_disk_io(double elapsed) p->dk[i].dk_time += 100 * elapsed; p->dk[i].dk_time = fudged_busy; - sprintf(p->dk[i].dk_name, "dev-%d-%d", p->dk[i].dk_major, + 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++; @@ -2335,6 +2350,10 @@ void proc_mem() 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"); @@ -2346,7 +2365,7 @@ void proc_mem() p->mem.lowfree = proc_mem_search("LowFree"); p->mem.swaptotal = proc_mem_search("SwapTotal"); p->mem.swapfree = proc_mem_search("SwapFree"); -#ifdef LARGEMEM +#ifndef SMALLMEM p->mem.dirty = proc_mem_search("Dirty"); p->mem.writeback = proc_mem_search("Writeback"); p->mem.mapped = proc_mem_search("Mapped"); @@ -2358,7 +2377,7 @@ void proc_mem() p->mem.hugesize = proc_mem_search("Hugepagesize"); #else p->mem.bigfree = proc_mem_search("BigFree"); -#endif /*LARGEMEM*/ +#endif /*SMALLMEM*/ } #define MAX_SNAPS 72 @@ -2728,55 +2747,12 @@ char *get_state(char n) case 'W': return "Paging "; default: - sprintf(duff, "%d", n); + snprintf(duff, 64, "%d", n); return duff; } } -#ifdef GETUSER -/* Convert User id (UID) to a name with caching for speed - * getpwuid() should be NFS/yellow pages safe - */ -char *getuser(uid_t uid) -{ -#define NAMESIZE 16 - struct user_info { - uid_t uid; - char name[NAMESIZE]; - }; - static struct user_info *u = NULL; - static int used = 0; - int i; - struct passwd *pw; - - i = 0; - if (u != NULL) { - for (i = 0; i < used; i++) { - if (u[i].uid == uid) { - return u[i].name; - } - } - u = (struct user_info *) REALLOC(u, - (sizeof(struct user_info) * - (i + 1))); - } else - u = (struct user_info *) MALLOC(sizeof(struct user_info)); - used++; - - /* failed to find a match so add it */ - u[i].uid = uid; - pw = getpwuid(uid); - - if (pw != NULL) - strncpy(u[i].name, pw->pw_name, NAMESIZE); - else - sprintf(u[i].name, "unknown%d", uid); - return u[i].name; -} -#endif /* GETUSER */ - /* User Defined Disk Groups */ - char *save_word(char *in, char *out) { int len; @@ -2995,13 +2971,6 @@ void list_dgroup(struct dsk_stat *dk) fprintf(fp, ",%s", dgroup_name[i]); } fprintf(fp, "\n"); - fprintf(fp, "DGIOTIME,Disk Group time spent for IO (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, "DGBACKLOG,Disk Group Backlog time (ms) %s", hostname); for (i = 0; i < DGROUPS; i++) { if (dgroup_name[i] != 0) @@ -3304,9 +3273,9 @@ void help(void) #define JFSTYPELEN 8 struct jfs { - char name[JFSNAMELEN]; - char device[JFSNAMELEN]; - char type[JFSNAMELEN]; + char name[JFSNAMELEN+1]; + char device[JFSNAMELEN+1]; + char type[JFSNAMELEN+1]; int fd; int mounted; } jfs[JFSMAX]; @@ -3324,12 +3293,12 @@ void jfs_load(int 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); - strncpy(jfs[i].name, mp->mnt_dir, JFSNAMELEN); - strncpy(jfs[i].type, mp->mnt_type, JFSTYPELEN); - mp->mnt_fsname[JFSNAMELEN - 1] = 0; - mp->mnt_dir[JFSNAMELEN - 1] = 0; - mp->mnt_type[JFSTYPELEN - 1] = 0; + 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; @@ -3416,12 +3385,18 @@ int checkinput(void) use_env = 0; p = getenv("NMON"); if (p != 0) { - strcpy(buf, p); + strncpy(buf, p, 1024); + buf[1024 - 1] = 0; chars = strlen(buf); } else chars = 0; - } else + } 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++) { @@ -3775,9 +3750,9 @@ int proc_procsinfo(int pid, int index) int count = 0; int i; - sprintf(filename, "/proc/%d/stat", pid); + snprintf(filename, 64, "/proc/%d/stat", pid); if ((fp = fopen(filename, "r")) == NULL) { - sprintf(buf, "failed to open file %s", filename); + snprintf(buf, 1024 * 4, "failed to open file %s", filename); error(buf); return 0; } @@ -3815,7 +3790,7 @@ int proc_procsinfo(int pid, int index) count++; ret = sscanf(&buf[count], -#ifndef KERNEL_2_6_18 +#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", @@ -3836,7 +3811,7 @@ int proc_procsinfo(int pid, int index) &p->procs[index].pi_cutime, &p->procs[index].pi_cstime, &p->procs[index].pi_pri, &p->procs[index].pi_nice, -#ifndef KERNEL_2_6_18 +#ifdef PRE_KERNEL_2_6_18 &p->procs[index].junk, #else &p->procs[index].pi_num_threads, @@ -3859,14 +3834,14 @@ int proc_procsinfo(int pid, int index) &p->procs[index].pi_nswap, &p->procs[index].pi_cnswap, &p->procs[index].pi_exit_signal, &p->procs[index].pi_cpu -#ifdef KERNEL_2_6_18 +#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 ); -#ifndef KERNEL_2_6_18 +#ifdef PRE_KERNEL_2_6_18 if (ret != 37) { fprintf(stderr, "procsinfo2 sscanf wanted 37 returned = %d pid=%d line=%s\n", @@ -3880,9 +3855,9 @@ int proc_procsinfo(int pid, int index) return 0; } - sprintf(filename, "/proc/%d/statm", pid); + snprintf(filename, 64, "/proc/%d/statm", pid); if ((fp = fopen(filename, "r")) == NULL) { - sprintf(buf, "failed to open file %s", filename); + snprintf(buf, 1024 * 4, "failed to open file %s", filename); error(buf); return 0; } @@ -3890,7 +3865,7 @@ int proc_procsinfo(int pid, int index) 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) { - sprintf(buf, "failed to read file %s", filename); + snprintf(buf, 1024 * 4, "failed to read file %s", filename); error(buf); return 0; } @@ -3910,7 +3885,7 @@ int proc_procsinfo(int pid, int index) if (isroot) { p->procs[index].read_io = 0; p->procs[index].write_io = 0; - sprintf(filename, "/proc/%d/io", pid); + 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) { @@ -3956,7 +3931,7 @@ print_procs(int index) 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); -#ifndef KERNEL_2_6_18 +#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, @@ -3993,7 +3968,7 @@ print_procs(int index) printf("procs[%d].exit_signal =%d\n", index, procs[index].pi_exit_signal); printf("procs[%d].cpu =%d\n", index, procs[index].pi_cpu); -#ifdef KERNEL_2_6_18 +#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, @@ -4064,7 +4039,7 @@ void child_start(int when, { int i; pid_t child_pid; - char time_stamp_str[20] = ""; + char time_stamp_str[64] = ""; char *when_info = ""; struct tm *tim; /* used to work out the hour/min/second */ @@ -4106,11 +4081,11 @@ void child_start(int when, /* create requested timestamp */ if (timestamp_type == 1) { tim = localtime(&the_time); - sprintf(time_stamp_str, "%02d:%02d:%02d,%02d,%02d,%04d", + 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 { - sprintf(time_stamp_str, "T%04d", loop); + snprintf(time_stamp_str, 64, "T%04d", loop); } /* close all open file pointers except the defaults */ @@ -4161,6 +4136,7 @@ int main(int argc, char **argv) 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; @@ -4193,18 +4169,20 @@ int main(int argc, char **argv) double writers; /* for popen on oslevel */ - char str[512]; char *str_p; int varperftmp = 0; char *formatstring; - char user_filename[512]; + 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; @@ -4254,7 +4232,8 @@ int main(int argc, char **argv) char toprio_ch; unsigned long topwio; char topwio_ch; - + long long tmpslab; + char * slabstr; char truncated_command[257]; /* 256 +1 */ @@ -4328,20 +4307,22 @@ int main(int argc, char **argv) reread = 1; #endif for (i = 0; i < CMDMAX; i++) { - sprintf(cmdstr, "NMONCMD%d", 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)); - strcpy(fullhostname, 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) - strcpy(run_name, hostname); - + if (run_name_set == 0) { + strncpy(run_name, hostname, 256); + run_name[256 - 1] = 0; + } if (getuid() == 0) isroot = 1; @@ -4403,6 +4384,7 @@ int main(int argc, char **argv) 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); @@ -4472,7 +4454,8 @@ int main(int argc, char **argv) show_headings = 0; break; case 'r': - strcpy(run_name, optarg); + strncpy(run_name, optarg, 256); + run_name[256 - 1] = 0; run_name_set++; break; case 's': @@ -4660,29 +4643,38 @@ int main(int argc, char **argv) tim = localtime(&timer); tim->tm_year += 1900 - 2000; /* read localtime() manual page!! */ tim->tm_mon += 1; /* because it is 0 to 11 */ - if (varperftmp) - sprintf(str, "/var/perf/tmp/%s_%02d.nmon", hostname, + 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) - strcpy(str, user_filename); - else - sprintf(str, "%s_%02d%02d%02d_%02d%02d.nmon", + } + 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(str, "stdout", 6)) { + } + 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(str, "w")) == 0) { + if ((fp = fopen(open_filename, "w")) == 0) { perror("nmon: failed to open output file"); - printf("nmon: output filename=%s\n", str); + printf("nmon: output filename=%s\n", open_filename); exit(42); } } + free(open_filename); /* disconnect from terminal */ fflush(NULL); if (!debug && (childpid = fork()) != 0) { @@ -4883,7 +4875,7 @@ int main(int argc, char **argv) jfs_load(UNLOAD); } #ifdef POWER - if (proc_lparcfg() && lparcfg.shared_processor_mode != 0 + 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", @@ -4893,7 +4885,7 @@ int main(int argc, char **argv) #endif /*POWER*/ if (show_top) { fprintf(fp, "TOP,%%CPU Utilisation\n"); -#ifndef KERNEL_2_6_18 +#ifdef PRE_KERNEL_2_6_18 fprintf(fp, "TOP,+PID,Time,%%CPU,%%Usr,%%Sys,Size,ResSet,ResText,ResData,ShdLib,MinorFault,MajorFault,Command\n"); #else @@ -4977,7 +4969,7 @@ int main(int argc, char **argv) "/bin/cat /proc/partitions 2>/dev/null", WARNING); linux_bbbp("/proc/1/stat", "/bin/cat /proc/1/stat 2>/dev/null", WARNING); -#ifndef KERNEL_2_6_18 +#ifdef PRE_KERNEL_2_6_18 linux_bbbp("/proc/1/statm", "/bin/cat /proc/1/statm 2>/dev/null", WARNING); #endif @@ -5063,30 +5055,13 @@ int main(int argc, char **argv) if (welcome && getenv("NMON") == 0) { COLOUR wattrset(padwelcome, COLOR_PAIR(2)); -/* -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, "# ## # # # # # ##"); -mvwprintw(padwelcome,x+7, 3, "# # # # #### # #"); -mvwprintw(padwelcome,x+8, 3, "------------------------------"); -*/ - 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, - "------------------------------"); + 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 ..."); @@ -5099,6 +5074,13 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); #ifdef POWER get_cpu_cnt(); proc_read(P_CPUINFO); + /* find the highest MHz */ + for(i=0; i 0 + 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, 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 */ + 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, @@ -6358,8 +6334,7 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); sscanf(&proc[P_CPUINFO].line[lineno][DATACOL], "%f", &mhz); mvwprintw(padmhz, padline, col, "%3d=%4.0f", - (show_mhz != 1) ? cores : cpuno, - mhz); + (show_mhz != 1) ? cores : cpuno, mhz); if (show_mhz == 3) { if (mhz > avg_mhz) { COLOUR wattrset(padmhz, COLOR_PAIR(1)); @@ -6367,12 +6342,10 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); COLOUR wattrset(padmhz, COLOR_PAIR(2)); } for (i = 1; i < mhz / 100; i++) - mvwprintw(padmhz, padline, col + 9 + i, - "#"); + mvwprintw(padmhz, padline, col + 9 + i, "#"); COLOUR wattrset(padmhz, COLOR_PAIR(0)); for (; i < 60; i++) - mvwprintw(padmhz, padline, col + 9 + i, - " "); + mvwprintw(padmhz, padline, col + 9 + i, " "); } padline++; if (padline > 22) { @@ -6392,7 +6365,11 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); break; } avg_mhz = (min_mhz + max_mhz) / 2; - DISPLAY(padmhz, 23); + if(cores >= 20) + lineno = 23; + else + lineno = cores+3; + DISPLAY(padmhz, lineno); } else { if (!show_rrd) fprintf(fp, "MHZ,%s", LOOP); @@ -6480,7 +6457,7 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); mvwprintw(padmem, 5, 1, "Linux Kernel Internal Memory (MB)"); -#ifdef LARGEMEM +#ifndef SMALLMEM mvwprintw(padmem, 6, 1, " Cached=%10.1f Active=%10.1f", p->mem.cached / 1024.0, p->mem.active / 1024.0); @@ -6492,13 +6469,13 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); mvwprintw(padmem, 5, 68, "MB"); mvwprintw(padmem, 6, 55, "bigfree=%10.1f", p->mem.bigfree / 1024); -#endif /*LARGEMEM*/ +#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, @@ -6508,6 +6485,7 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); 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(); @@ -6550,11 +6528,11 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); p->mem.swapfree / 1024.0, p->mem.memshared / 1024.0, p->mem.cached / 1024.0, p->mem.active / 1024.0, -#ifdef LARGEMEM +#ifndef SMALLMEM -1.0, #else p->mem.bigfree / 1024.0, -#endif /*LARGEMEM*/ +#endif /*SMALLMEM*/ p->mem.buffers / 1024.0, p->mem.swapcached / 1024.0, p->mem.inactive / 1024.0); @@ -6603,6 +6581,7 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); p->mem.hugesize = 16*1024; */ } +#ifndef SMALLMEM if (show_large) { proc_read(P_MEMINFO); proc_mem(); @@ -6644,6 +6623,7 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); } } } +#endif /* SMALLMEM */ if (show_vm) { #define VMDELTA(variable) (p->vm.variable - q->vm.variable) #define VMCOUNT(variable) (p->vm.variable ) @@ -6680,12 +6660,21 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); mvwprintw(padpage, 5, 0, "nr_mapped =%9lld pgfree =%8lld", VMCOUNT(nr_mapped), VMDELTA(pgfree)); - mvwprintw(padpage, 6, 0, + 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, + 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), @@ -6738,8 +6727,12 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); 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,nr_slab,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"); + "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" @@ -6759,7 +6752,10 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); ",%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), @@ -6767,7 +6763,7 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); VMCOUNT(nr_unstable), VMCOUNT(nr_page_table_pages), VMCOUNT(nr_mapped), - VMCOUNT(nr_slab), + tmpslab, VMDELTA(pgpgin), VMDELTA(pgpgout), VMDELTA(pswpin), @@ -6894,7 +6890,7 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); p->cpu_total.idletime) / p->cpu_total.uptime * 100.0; if (average > 0.0) mvwprintw(padker, 5, BOOTCOL, - "Average CPU use=%6.2f%%", average); + "Average Busy Uptimee=%6.2f%%", average); else mvwprintw(padker, 5, BOOTCOL, "Uptime has overflowed"); mvwprintw(padker, 7, BOOTCOL, "%d CPU core threads", cpus); @@ -6909,24 +6905,25 @@ mvwprintw(padwelcome,x+8, 3, "------------------------------"); proc_first_time = 0; } if (show_rrd) - str_p = + 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 = + 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, /*runqueue */ - (float) p->cpu_total.blocked, /*swapin (# of processes waiting for IO completion */ - /*pswitch */ - (float) (p->cpu_total.ctxt - q->cpu_total.ctxt) / elapsed, -1.0, /*syscall */ - -1.0, /*read */ - -1.0, /*write */ - /*fork */ - (float) (p->cpu_total.procs - q->cpu_total.procs) / elapsed, -1.0, /*exec */ - -1.0, /*sem */ - -1.0); /*msg */ + 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 */ } } @@ -7332,7 +7329,7 @@ I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans if (show_neterror > 0) show_neterror--; } -#ifdef JFS + if (show_jfs) { if (cursed) { BANNER(padjfs, "File Systems"); @@ -7495,7 +7492,6 @@ I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans jfs_load(UNLOAD); } } -#endif /* JFS */ if (show_disk || show_verbose || show_diskmap || show_dgroup) { proc_read(P_STAT); @@ -8066,7 +8062,7 @@ I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans disk_total += DKDELTA(dk_rmsec); } } - fprintf(fp, ",%.1f", disk_total); + fprintf(fp, ",%.1f", disk_total / elapsed); } } fprintf(fp, "\n"); @@ -8108,7 +8104,7 @@ I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans disk_total += DKDELTA(dk_wmsec); } } - fprintf(fp, ",%.1f", disk_total); + fprintf(fp, ",%.1f", disk_total / elapsed); } } fprintf(fp, "\n"); @@ -8126,20 +8122,6 @@ I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans } } fprintf(fp, "\n"); - fprintf(fp, "DGIOTIME,%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); - } - } - 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) { @@ -8150,7 +8132,7 @@ I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans disk_total += DKDELTA(dk_backlog); } } - fprintf(fp, ",%.1f", disk_total); + fprintf(fp, ",%.1f", disk_total / elapsed); } } fprintf(fp, "\n"); @@ -8234,7 +8216,7 @@ I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans if (p->procs[i].pi_pgrp == p->procs[i].pi_pid) strcpy(pgrp, "none"); else - sprintf(&pgrp[0], "%d", p->procs[i].pi_pgrp); + snprintf(&pgrp[0], 32, "%d", p->procs[i].pi_pgrp); /* skip over processes with 0 CPU */ if (!show_all && (topper[j].time / elapsed < @@ -8342,7 +8324,7 @@ I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans 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[256] = 0; + truncated_command[255] = 0; /* worst longest case */ truncated_command[COLS - 24 - 2] = 0; mvwprintw(padtop, j + 3 - skipped, 24, "%-120s", truncated_command); @@ -8471,7 +8453,7 @@ I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans || (!cmdfound && ((topper[j].time / elapsed) > ignore_procdisk_threshold))) { -#ifndef KERNEL_2_6_18 +#ifdef PRE_KERNEL_2_6_18 fprintf(fp, "TOP,%07d,%s,%.2f,%.2f,%.2f,%lu,%lu,%lu,%lu,%lu,%d,%d,%s\n", #else @@ -8491,7 +8473,7 @@ I/F Name Recv=KB/s Trans=KB/s packin packout insize outsize Peak->Recv Trans /* 11 */ (int) (COUNTDELTA(pi_minflt) / elapsed), /* 12 */ (int) (COUNTDELTA(pi_majflt) / elapsed), /* 13 */ p->procs[i].pi_comm -#ifndef KERNEL_2_6_18 +#ifdef PRE_KERNEL_2_6_18 ); #else , diff --git a/nmon.spec b/nmon.spec index 1198af4..fd6dfc0 100644 --- a/nmon.spec +++ b/nmon.spec @@ -1,23 +1,32 @@ -Name: nmon -Version: 16g -Release: 1 -Summary: Nigel's performance Monitor for Linux -License: GPLv3 -URL: http://nmon.sourceforge.net -Source0: https://sourceforge.net/projects/nmon/files/lmon%{version}.c -Source1: https://sourceforge.net/projects/nmon/files/Documentation.txt -Source2: nmon.1 -BuildRequires: gcc ncurses-devel +Name: nmon +Version: 16m +Release: 1 +Summary: Nigel's performance Monitor for Linux + +License: GPLv3 +URL: http://nmon.sourceforge.net +Source0: https://sourceforge.net/projects/%{name}/files/lmon%{version}.c +Source1: https://sourceforge.net/projects/%{name}/files/Documentation.txt +# Manpage available from the patch archive: +# http://sourceforge.net/tracker/?func=detail&aid=2833213&group_id=271307&atid=1153693 +Source2: %{name}.1 + +BuildRequires: gcc +BuildRequires: ncurses-devel + + %description -nmon is a systems administrator, tuner, benchmark tool, which provides +nmon is a systems administrator, tuner, benchmark tool, which provides information about CPU, disks, network, etc., all in one view. + %prep %setup -T -c -n %{name} sed -e "s/\r//" %{SOURCE1} > Documentation.txt touch -c -r %{SOURCE1} Documentation.txt cp %{SOURCE0} . + %build %ifarch ppc %{power64} %{__cc} %{optflags} -D JFS -D GETUSER \ @@ -27,15 +36,21 @@ cp %{SOURCE0} . -D LARGEMEM -D X86 -lncurses -lm lmon%{version}.c -o %{name} %endif + %install install -D -p -m 0755 %{name} %{buildroot}%{_bindir}/%{name} install -D -p -m 0644 %{SOURCE2} %{buildroot}%{_mandir}/man1/%{name}.1 + %files -%doc Documentation.txt +%doc Documentation.txt %{_mandir}/man1/%{name}.1.* %{_bindir}/%{name} + %changelog +* Mon 28 Jun 2021 chenjian - 16m-1 +- Update to 16m-1 + * Mon Aug 3 2020 Jeffery.Gao - 16g-1 - Package init