/*
* lmon.c -- Curses based Performance Monitor for Linux
* Developer: Nigel Griffiths.
*/
/*
* Use the following Makefile
CFLAGS= -g -DPOWER -DPARTITIONS
LDFLAGS=-lcurses -lodm -lcfg
nmon: nmon.o
* end of Makefile
*/
#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 "12f"
char version[] = VERSION;
static char *SccsId = "nmon " VERSION;
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <ncurses.h>
#include <signal.h>
#include <pwd.h>
#include <fcntl.h>
#include <math.h>
#include <time.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/wait.h>
#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 */
#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_NUMBER 8 /* 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);
}
/* /proc/cpuinfo can be 512 bytes per CPU and we allow 256 CPUs */
/* and 20 lines per CPU so boost the buffers for this one */
#define PROC_MAXBUF (1024*4)
#define CPUINFO_MAXBUF (512*256)
#define PROC_MAXLINES (20*256*sizeof(char *))
int reread =0;
struct {
FILE *fp;
char *filename;
int lines;
char *line[PROC_MAXLINES];
char *buf;
} proc[P_NUMBER];
void proc_init()
{
int i;
/* Initialise the file pointers */
for(i=0;i<P_NUMBER;i++) {
proc[i].fp = 0;
if(i == P_CPUINFO)
proc[i].buf = (char *)malloc(CPUINFO_MAXBUF);
else
proc[i].buf = (char *)malloc(PROC_MAXBUF);
}
proc[P_CPUINFO].filename = "/proc/cpuinfo";
proc[P_STAT].filename = "/proc/stat";
proc[P_VERSION].filename = "/proc/version";
proc[P_MEMINFO].filename = "/proc/meminfo";
proc[P_UPTIME].filename = "/proc/uptime";
proc[P_LOADAVG].filename = "/proc/loadavg";
proc[P_NFS].filename = "/proc/net/rpc/nfs";
proc[P_NFSD].filename = "/proc/net/rpc/nfsd";
}
void proc_read(int num)
{
int i;
int size;
int found;
char buf[1024];
int bytes;
if(proc[num].fp == 0) {
if( (proc[num].fp = fopen(proc[num].filename,"r")) == NULL) {
sprintf(buf, "failed to open file %s", proc[num].filename);
error(buf);
proc[num].fp = 0;
return;
}
}
rewind(proc[num].fp);
if(num == P_CPUINFO)
bytes = CPUINFO_MAXBUF -1;
else
bytes = PROC_MAXBUF -1;
size = fread(proc[num].buf, 1, bytes, proc[num].fp);
proc[num].buf[size]=0;
proc[num].lines=0;
proc[num].line[0]=&proc[num].buf[0];
if(num == P_VERSION) {
found=0;
for(i=0;i<size;i++) { /* remove some weird stuff */
if( found== 0 &&
proc[num].buf[i] == ')' &&
proc[num].buf[i+1] == ' ' &&
proc[num].buf[i+2] == '(' ) {
proc[num].buf[i+1] = '\n';
found=1;
} else {
if(
proc[num].buf[i] == ')' &&
proc[num].buf[i+1] == ' ' &&
proc[num].buf[i+2] == '#' ) {
proc[num].buf[i+1] = '\n';
}
if(
proc[num].buf[i] == '#' &&
proc[num].buf[i+2] == '1' ) {
proc[num].buf[i] = '\n';
}
}
}
}
for(i=0;i<size;i++) {
if(proc[num].buf[i] == '\t')
proc[num].buf[i]= ' ';
if(proc[num].buf[i] == '\n') {
proc[num].lines++;
proc[num].buf[i] = 0;
proc[num].line[proc[num].lines] = &proc[num].buf[i+1];
}
if(proc[num].lines==PROC_MAXLINES-1)
break;
}
if(reread) {
fclose( proc[num].fp);
proc[num].fp = 0;
}
}
#include <dirent.h>
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;
long junk /* removed */;
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;
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 */
};
#include <mntent.h>
#include <fstab.h>
#include <sys/stat.h>
#include <sys/statfs.h>
#include <net/if.h>
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!) */
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; /
- 1
- 2
- 3
前往页