diff --git a/CodingStyle b/CodingStyle index e40365f1..962207de 100644 --- a/CodingStyle +++ b/CodingStyle @@ -3,6 +3,9 @@ If you change an existing file, follow the existing style. Hard tabs are OK, as long as you consider the tab stops to be every 8 characters. You can also use 2, 3, or 4 spaces. +Tabs are kind of yucky, since cut-and-paste mangles them +sometimes and they make "diff -Naurd old new" output less +readable. Spaces within a line don't matter much, and won't be considered part of the style. Just make it readable: @@ -44,6 +47,8 @@ fprintf(fd, "%d %d %d %d %d %d\n", sfssss + wwwwfwfw ); +Keep these distinct: NULL, '\0', 0, 0.0 + Command-line parsers need to be bomb-proof. It is not acceptable to crash due to a messed up command-line. For an option "-x" that takes an argument, accept both "-x arg" and "-xarg". Remember to @@ -56,15 +61,22 @@ non-ASCII characters to be printed. Assuming the console is not in UTF-8 mode, all of these are bad: "\b\e\f\n\r\t\v\x9b". (the "\x9b" is valid in UTF-8 mode, but equivalent to "\e[" when not in UTF-8 mode -- which gives control of terminal -settings) +settings) It's best if you consider user-supplied data to +be unsafe, since this makes for less work in case the code +ends up needing to run setuid. Termcap data is user-supplied. +Except for the above security issues, don't bother to check +for something you can't handle... like printf() failing. +It is expected that /dev exists and so on. Remember that a read() may return early, with partial data or with -1 and errno set to EINTR. You then must try again. -char: may be signed or unsigned by default -int: always 32-bit +char: may be signed or unsigned by default +int: always 32-bit long long: always 64-bit -long: same size as a pointer, either 32-bit or 64-bit +pointer: either 32-bit or 64-bit +long: same size as a pointer +KLONG: same size as a pointer or long IN THE KERNEL Functions used in just one file must be marked static. Use the "const" and "restrict" keywords wherever you can. diff --git a/Makefile b/Makefile index 234cd34c..08a1ad9b 100644 --- a/Makefile +++ b/Makefile @@ -18,9 +18,9 @@ VERSION := 3 SUBVERSION := 1 -MINORVERSION := 9 -TARVERSION := 3.1.9 -LIBVERSION := 3.1.9 +MINORVERSION := 10 +TARVERSION := 3.1.10 +LIBVERSION := 3.1.10 ############ vars diff --git a/proc/library.map b/proc/library.map index 19669914..4433b227 100644 --- a/proc/library.map +++ b/proc/library.map @@ -10,7 +10,7 @@ global: Hertz; smp_num_cpus; sprint_uptime; uptime; user_from_uid; print_uptime; loadavg; pretty_print_signals; print_given_signals; unix_print_signals; signal_name_to_number; signal_number_to_name; - meminfo; vminfo; getstat; + meminfo; vminfo; getstat; getdiskstat; getslabinfo; kb_active; kb_inactive; kb_main_buffers; kb_main_cached; kb_main_free; kb_main_total; kb_main_used; kb_swap_free; kb_swap_total; kb_swap_used; kb_main_shared; diff --git a/proc/sysinfo.c b/proc/sysinfo.c index 933cb4e8..f7a65893 100644 --- a/proc/sysinfo.c +++ b/proc/sysinfo.c @@ -4,8 +4,10 @@ // This file is placed under the conditions of the GNU Library // General Public License, version 2, or any later version. // See file COPYING for information on distribution conditions. - -/* File for parsing top-level /proc entities. */ +// +// File for parsing top-level /proc entities. */ +// +// June 2003, Fabian Frederick, disk and slab info #include #include @@ -172,7 +174,9 @@ static void old_Hertz_hack(void){ #define AT_CLKTCK 17 /* frequency of times() */ #endif -extern char** environ; +#define NOTE_NOT_FOUND 42 + +//extern char** environ; /* for ELF executables, notes are pushed before environment and args */ static unsigned long find_elf_note(unsigned long findme){ @@ -182,7 +186,7 @@ static unsigned long find_elf_note(unsigned long findme){ if(ep[0]==findme) return ep[1]; ep+=2; } - return 42; + return NOTE_NOT_FOUND; } static void init_libproc(void) __attribute__((constructor)); @@ -195,7 +199,7 @@ static void init_libproc(void){ if(linux_version_code > LINUX_VERSION(2, 4, 0)){ Hertz = find_elf_note(AT_CLKTCK); - if(Hertz!=42) return; + if(Hertz!=NOTE_NOT_FOUND) return; fprintf(stderr, "2.4 kernel w/o ELF notes? -- report to albert@users.sf.net\n"); } old_Hertz_hack(); @@ -651,3 +655,105 @@ nextline: } } +/////////////////////////////////////////////////////////////////////// +// based on Fabian Frederick's /proc/diskstats parser + +static unsigned int getFileLines(const char* szFile){ + char szBuffer[1024]; + FILE *fdiskStat; + int lines=0; + if ((fdiskStat=fopen (szFile,"rb"))){ + while (fgets(szBuffer, 1024, fdiskStat)){ + lines++; + } + fclose(fdiskStat); + } + return lines; +} + +unsigned int getdiskstat(struct disk_stat **disks, struct partition_stat **partitions){ + FILE* fd; + buff[BUFFSIZE-1] = 0; + int units, + i, + disk_type, + disk_num, + cDisk=0, + cPartition=0; + *disks = NULL; + *partitions = NULL; + units = getFileLines("/proc/diskstats"); + fd = fopen("/proc/diskstats", "rb"); + if(!fd) crash("/proc/diskstats"); + + for (i=0; i Primary-site: http://procps.sf.net/ - 239kB procps-3.1.9.tar.gz + 239kB procps-3.1.10.tar.gz Alternate-site: http://www.debian.org/Packages/unstable/base/procps.html - 239kB procps-3.1.9.tar.gz + 239kB procps-3.1.10.tar.gz Copying-policy: mixed End diff --git a/procps.spec b/procps.spec index fb1f0203..7afd00e2 100644 --- a/procps.spec +++ b/procps.spec @@ -3,7 +3,7 @@ Summary: System and process monitoring utilities Name: procps %define major_version 3 %define minor_version 1 -%define revision 9 +%define revision 10 %define version %{major_version}.%{minor_version}.%{revision} Version: %{version} Release: 1 diff --git a/vmstat.8 b/vmstat.8 index e4a0afdf..7a7c2737 100644 --- a/vmstat.8 +++ b/vmstat.8 @@ -13,11 +13,15 @@ vmstat \- Report virtual memory statistics .B vmstat .RB [ "\-f" ] .RB [ "\-s" ] +.RB [ "\-m" ] .br .B vmstat .RB [ "\-S unit"] .br .B vmstat +.RB [ "\-d"] +.br +.B vmstat .RB [ "\-V" ] .SH DESCRIPTION \fBvmstat\fP reports information about processes, memory, paging, @@ -36,6 +40,8 @@ equivalent to the total number of tasks created. Each process is represented by one or more tasks, depending on thread usage. This display does not repeat. .PP +The \fB-m\fP displays slabinfo. +.PP The \fB-n\fP switch causes the header to be displayed only once rather than periodically. .PP The \fB-s\fP switch displays a table of various event counters @@ -49,11 +55,13 @@ only one report is printed with the average values since boot. is the number of updates. If no count is specified and delay is defined, \fIcount\fP defaults to infinity. .PP +The \fB-d\fP reports disk statistics (2.5.70 or above required) +.PP The \fB-S\fP followed by k or K or m or M switches outputs between 1000, 1024, 1000000, or 1048576 bytes .PP The \fB-V\fP switch results in displaying version information. .PP -.SH FIELD DESCRIPTIONS +.SH FIELD DESCRIPTION FOR VM MODE .SS .B "Procs" .nf @@ -101,7 +109,47 @@ us: Time spent running non-kernel code. (user time, including nice time) sy: Time spent running kernel code. (system time) id: Time spent idle. Prior to Linux 2.5.41, this includes IO-wait time. wa: Time spent waiting for IO. Prior to Linux 2.5.41, shown as zero. + +.PP +.SH FIELD DESCRIPTION FOR DISK MODE +.SS +.B "Reads" .nf +total: Total reads completed successfully +merged: grouped reads (resulting in one I/O) +sectors: Sectors read successfully +ms: milliseconds spent reading +.fi +.PP +.SS +.B "Writes" +.nf +total: Total writes completed successfully +merged: grouped writes (resulting in one I/O) +sectors: Sectors written successfully +ms: milliseconds spent writing +.fi +.PP +.SS +.B "IO" +.nf +cur: I/O in progress +s: seconds spent for I/O +.fi + + +.PP +.SH FIELD DESCRIPTION FOR SLAB MODE +.nf +cache: Cache name +num: Number of currently active objects +total: Total number of available objects +size: Size of each object +pages: Number of pages with at least one active object +totpages: Total number of allocated pages +pslab: Number of pages per slab +.fi + .SH NOTES .B "vmstat " does not require special permissions. @@ -113,8 +161,9 @@ does not count itself as a running process. All linux blocks are currently 1024 bytes. Old kernels may report blocks as 512 bytes, 2048 bytes, or 4096 bytes. .PP -Since procps 3.1.9, vmstat lets you choose units (k, K, m, M) +Since procps 3.1.9, vmstat lets you choose units (k, K, m, M) default is K (1024 bytes) in the default mode .PP +vmstat uses slabinfo 1.1 FIXME .SH FILES .ta .nf @@ -128,5 +177,7 @@ iostat(1), sar(1), mpstat(1), ps(1), top(1), free(1) .PP .SH BUGS Does not tabulate the block io per device or count the number of system calls. -.SH AUTHOR +.SH AUTHORS +.nf Written by Henry Ware . +Diskstat,slab mode and some improvements by Fabian Frederick diff --git a/vmstat.c b/vmstat.c index 740a6d6e..d7a13c16 100644 --- a/vmstat.c +++ b/vmstat.c @@ -3,6 +3,10 @@ // 27/05/2003 (Fabian) : Add unit conversion + interface // Export proc/stat access to libproc // Adapt vmstat helpfile +// 31/05/2003 (Fabian) : Add diskstat support (/libproc) +// June 2003 (Fabian) : -S -s & -s -S patch +// June 2003 (Fabian) : -Adding diskstat against 3.1.9, slabinfo +// -patching 'header' in disk & slab #include #include @@ -19,7 +23,21 @@ #include "proc/sysinfo.h" #include "proc/version.h" -#include "vmstat.h" + +static unsigned long dataUnit=1024; +static char szDataUnit [16]; +#define UNIT_B 1 +#define UNIT_k 1000 +#define UNIT_K 1024 +#define UNIT_m 1000000 +#define UNIT_M 1048576 + +#define VMSTAT 0 +#define DISKSTAT 0x00000001 +#define VMSUMSTAT 0x00000002 +#define SLABSTAT 0x00000004 + +static int statMode=VMSTAT; #define FALSE 0 #define TRUE 1 @@ -41,6 +59,8 @@ static void usage(void) { fprintf(stderr," -V prints version.\n"); fprintf(stderr," -n causes the headers not to be reprinted regularly.\n"); fprintf(stderr," -a print inactive/active page stats.\n"); + fprintf(stderr," -d prints disk statistics\n"); + fprintf(stderr," -m prints slabinfo\n"); fprintf(stderr," -S unit size\n"); fprintf(stderr," delay is the delay between updates in seconds. \n"); fprintf(stderr," unit size k:1000 K:1024 m:1000000 M:1048576 (default is K)\n"); @@ -132,10 +152,25 @@ static void new_header(void){ //////////////////////////////////////////////////////////////////////////// -unsigned long unitConvert(unsigned int kbsize) -{ +static void new_diskheader(void){ + printf("disk ----------reads------------ -----------writes----------- -------IO-------\n"); + + printf("%3s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n", " ", "total", "merged","sectors","ms","total","merged","sectors","ms","cur","s"); + +} + +//////////////////////////////////////////////////////////////////////////// + +static void new_slabheader(void){ + printf("%-24s %6s %6s %6s %6s\n","Cache","Num", "Total", "Size", "Pages"); +} + + +//////////////////////////////////////////////////////////////////////////// + +static unsigned long unitConvert(unsigned int size){ float cvSize; - cvSize=(float)kbsize/dataUnit*1024; + cvSize=(float)size/dataUnit*((statMode==SLABSTAT)?1:1024); return ((unsigned long) cvSize); } @@ -157,7 +192,6 @@ static void new_format(void) { sleep_half=(sleep_time/2); new_header(); - meminfo(); getstat(cpu_use,cpu_nic,cpu_sys,cpu_idl,cpu_iow, @@ -240,6 +274,98 @@ static void new_format(void) { //////////////////////////////////////////////////////////////////////////// +static void new_diskformat(void){ + FILE *fDiskstat; + struct disk_stat *disks; + struct partition_stat *partitions; + unsigned long ndisks,i,j,k; + const char format[]="%-3s %6u %6u %6llu %6u %6u %6u %6llu %6u %6u %6u\n"; + if ((fDiskstat=fopen("/proc/diskstats", "rb"))){ + fclose(fDiskstat); + ndisks=getdiskstat(&disks,&partitions); + for(k=0; k0)?tmp:22); } - setlinebuf(stdout); - - new_format(); + switch(statMode){ + case(VMSTAT): new_format(); + break; + case(VMSUMSTAT):sum_format(); + break; + case(DISKSTAT): new_diskformat(); + break; + case(SLABSTAT): new_slabformat(); + break; + default: usage(); + break; + } return 0; } diff --git a/vmstat.h b/vmstat.h index 8e7f1ce0..45e0965e 100644 --- a/vmstat.h +++ b/vmstat.h @@ -19,9 +19,16 @@ #define _IVMstat unsigned long dataUnit=1024; char szDataUnit [16]; +#define UNIT_B 1 #define UNIT_k 1000 #define UNIT_K 1024 #define UNIT_m 1000000 #define UNIT_M 1048576 +#define VMSTAT 1 +#define DISKSTAT 2 +#define VMSUMSTAT 3 +#define SLABSTAT 4 + +int statMode=VMSTAT; #endif /* _IVMstat */