fix vmstat -d
This commit is contained in:
parent
6a48d37343
commit
c8a8290ef2
1
NEWS
1
NEWS
@ -3,6 +3,7 @@ procps-3.2.1 --> procps-3.2.2
|
|||||||
avoid warning about -lncurses when not linking -- thanks FLWM
|
avoid warning about -lncurses when not linking -- thanks FLWM
|
||||||
ps: personality-specific -x support (HP-UX and SVR4-MP)
|
ps: personality-specific -x support (HP-UX and SVR4-MP)
|
||||||
ps: k option, same as --sort
|
ps: k option, same as --sort
|
||||||
|
vmstat: fixed -d
|
||||||
|
|
||||||
procps-3.2.0 --> procps-3.2.1
|
procps-3.2.0 --> procps-3.2.1
|
||||||
|
|
||||||
|
@ -674,20 +674,6 @@ nextline:
|
|||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
// based on Fabian Frederick's /proc/diskstats parser
|
// 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 getpartitions_num(struct disk_stat *disks, int ndisks){
|
unsigned int getpartitions_num(struct disk_stat *disks, int ndisks){
|
||||||
int i=0;
|
int i=0;
|
||||||
@ -704,31 +690,28 @@ unsigned int getpartitions_num(struct disk_stat *disks, int ndisks){
|
|||||||
|
|
||||||
unsigned int getdiskstat(struct disk_stat **disks, struct partition_stat **partitions){
|
unsigned int getdiskstat(struct disk_stat **disks, struct partition_stat **partitions){
|
||||||
FILE* fd;
|
FILE* fd;
|
||||||
int units,
|
int cDisk = 0;
|
||||||
i,
|
int cPartition = 0;
|
||||||
disk_type,
|
int fields;
|
||||||
disk_num,
|
unsigned dummy;
|
||||||
cDisk=0,
|
|
||||||
cPartition=0;
|
|
||||||
|
|
||||||
*disks = NULL;
|
*disks = NULL;
|
||||||
*partitions = NULL;
|
*partitions = NULL;
|
||||||
buff[BUFFSIZE-1] = 0;
|
buff[BUFFSIZE-1] = 0;
|
||||||
units = getFileLines("/proc/diskstats");
|
|
||||||
fd = fopen("/proc/diskstats", "rb");
|
fd = fopen("/proc/diskstats", "rb");
|
||||||
if(!fd) crash("/proc/diskstats");
|
if(!fd) crash("/proc/diskstats");
|
||||||
|
|
||||||
for (i=0; i<units; i++){
|
for (;;) {
|
||||||
if (!fgets(buff,BUFFSIZE-1,fd)){
|
if (!fgets(buff,BUFFSIZE-1,fd)){
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
crash("/proc/diskstats");
|
break;
|
||||||
}
|
}
|
||||||
sscanf(buff, " %d %d", &disk_type, &disk_num);
|
fields = sscanf(buff, " %*d %*d %*s %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %u", &dummy);
|
||||||
if (disk_num == 0){
|
if (fields == 1){
|
||||||
(*disks) = realloc(*disks, (cDisk+1)*sizeof(struct disk_stat));
|
(*disks) = realloc(*disks, (cDisk+1)*sizeof(struct disk_stat));
|
||||||
sscanf(buff, " %d %*d %15s %u %u %llu %u %u %u %llu %u %u %u %u",
|
sscanf(buff, " %*d %*d %15s %u %u %llu %u %u %u %llu %u %u %u %u",
|
||||||
&(*disks)[cDisk].disk_type,
|
//&disk_major,
|
||||||
//&unused,
|
//&disk_minor,
|
||||||
(*disks)[cDisk].disk_name,
|
(*disks)[cDisk].disk_name,
|
||||||
&(*disks)[cDisk].reads,
|
&(*disks)[cDisk].reads,
|
||||||
&(*disks)[cDisk].merged_reads,
|
&(*disks)[cDisk].merged_reads,
|
||||||
@ -747,20 +730,20 @@ unsigned int getdiskstat(struct disk_stat **disks, struct partition_stat **parti
|
|||||||
}else{
|
}else{
|
||||||
(*partitions) = realloc(*partitions, (cPartition+1)*sizeof(struct partition_stat));
|
(*partitions) = realloc(*partitions, (cPartition+1)*sizeof(struct partition_stat));
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
sscanf(buff, " %d %d %15s %u %llu %u %u",
|
sscanf(buff, " %*d %*d %15s %u %llu %u %u",
|
||||||
&(*partitions)[cPartition].disk_type,
|
//&part_major,
|
||||||
&(*partitions)[cPartition].partition_num,
|
//&part_minor,
|
||||||
(*partitions)[cPartition].partition_name,
|
(*partitions)[cPartition].partition_name,
|
||||||
&(*partitions)[cPartition].reads,
|
&(*partitions)[cPartition].reads,
|
||||||
&(*partitions)[cPartition].reads_sectors,
|
&(*partitions)[cPartition].reads_sectors,
|
||||||
&(*partitions)[cPartition].writes,
|
&(*partitions)[cPartition].writes,
|
||||||
&(*partitions)[cPartition].requested_writes
|
&(*partitions)[cPartition].requested_writes
|
||||||
);
|
);
|
||||||
(*partitions)[cPartition++].parent_disk = &((*disks)[cDisk-1]);
|
(*partitions)[cPartition++].parent_disk = cDisk-1;
|
||||||
(*disks)[cDisk-1].partitions++;
|
(*disks)[cDisk-1].partitions++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fd);
|
|
||||||
return cDisk;
|
return cDisk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,6 @@ typedef struct disk_stat{
|
|||||||
unsigned long long reads_sectors;
|
unsigned long long reads_sectors;
|
||||||
unsigned long long written_sectors;
|
unsigned long long written_sectors;
|
||||||
char disk_name [16];
|
char disk_name [16];
|
||||||
unsigned int disk_type;
|
|
||||||
unsigned inprogress_IO;
|
unsigned inprogress_IO;
|
||||||
unsigned merged_reads;
|
unsigned merged_reads;
|
||||||
unsigned merged_writes;
|
unsigned merged_writes;
|
||||||
@ -108,11 +107,9 @@ typedef struct disk_stat{
|
|||||||
}disk_stat;
|
}disk_stat;
|
||||||
|
|
||||||
typedef struct partition_stat{
|
typedef struct partition_stat{
|
||||||
unsigned int disk_type;
|
|
||||||
unsigned int partition_num;
|
|
||||||
char partition_name [16];
|
char partition_name [16];
|
||||||
unsigned long long reads_sectors;
|
unsigned long long reads_sectors;
|
||||||
struct disk_stat* parent_disk;
|
unsigned parent_disk; // index into a struct disk_stat array
|
||||||
unsigned reads;
|
unsigned reads;
|
||||||
unsigned writes;
|
unsigned writes;
|
||||||
unsigned requested_writes;
|
unsigned requested_writes;
|
||||||
|
@ -1085,6 +1085,7 @@ static const format_struct format_array[] = {
|
|||||||
{"inblk", "INBLK", pr_nop, sr_nop, 5, 0, BSD, AN|RIGHT}, /*inblock*/
|
{"inblk", "INBLK", pr_nop, sr_nop, 5, 0, BSD, AN|RIGHT}, /*inblock*/
|
||||||
{"inblock", "INBLK", pr_nop, sr_nop, 5, 0, DEC, AN|RIGHT}, /*inblk*/
|
{"inblock", "INBLK", pr_nop, sr_nop, 5, 0, DEC, AN|RIGHT}, /*inblk*/
|
||||||
{"intpri", "PRI", pr_opri, sr_priority, 3, 0, HPU, TO|RIGHT},
|
{"intpri", "PRI", pr_opri, sr_priority, 3, 0, HPU, TO|RIGHT},
|
||||||
|
{"jid", "JID", pr_nop, sr_nop, 1, 0, SGI, PO|RIGHT},
|
||||||
{"jobc", "JOBC", pr_nop, sr_nop, 4, 0, XXX, AN|RIGHT},
|
{"jobc", "JOBC", pr_nop, sr_nop, 4, 0, XXX, AN|RIGHT},
|
||||||
{"ktrace", "KTRACE", pr_nop, sr_nop, 8, 0, BSD, AN|RIGHT},
|
{"ktrace", "KTRACE", pr_nop, sr_nop, 8, 0, BSD, AN|RIGHT},
|
||||||
{"ktracep", "KTRACEP", pr_nop, sr_nop, 8, 0, BSD, AN|RIGHT},
|
{"ktracep", "KTRACEP", pr_nop, sr_nop, 8, 0, BSD, AN|RIGHT},
|
||||||
|
36
ps/parser.c
36
ps/parser.c
@ -253,6 +253,16 @@ static const char *parse_sysv_option(void){
|
|||||||
trace("-H Process hierarchy (like ASCII art forest option)\n");
|
trace("-H Process hierarchy (like ASCII art forest option)\n");
|
||||||
forest_type = 'u';
|
forest_type = 'u';
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
|
case 'J': // specify list of job IDs in hex (IRIX) -- like HP "-R" maybe?
|
||||||
|
trace("-J select by job ID\n"); // want a JID ("jid") for "-j" too
|
||||||
|
arg=get_opt_arg();
|
||||||
|
if(!arg) return "List of jobs must follow -J.";
|
||||||
|
err=parse_list(arg, parse_jid);
|
||||||
|
if(err) return err;
|
||||||
|
selection_list->typecode = SEL_JID;
|
||||||
|
return NULL; /* can't have any more options */
|
||||||
|
#endif
|
||||||
case 'L': /* */
|
case 'L': /* */
|
||||||
/* In spite of the insane 2-level thread system, Sun appears to
|
/* In spite of the insane 2-level thread system, Sun appears to
|
||||||
* have made this option Linux-compatible. If a process has N
|
* have made this option Linux-compatible. If a process has N
|
||||||
@ -264,7 +274,7 @@ static const char *parse_sysv_option(void){
|
|||||||
thread_flags |= TF_U_L;
|
thread_flags |= TF_U_L;
|
||||||
// format_modifiers |= FM_L;
|
// format_modifiers |= FM_L;
|
||||||
break;
|
break;
|
||||||
case 'M': /* someday, maybe, we will have MAC like SGI's Irix */
|
case 'M': // typically the SE Linux context
|
||||||
trace("-M Print security label for Mandatory Access Control.\n");
|
trace("-M Print security label for Mandatory Access Control.\n");
|
||||||
format_modifiers |= FM_M;
|
format_modifiers |= FM_M;
|
||||||
break;
|
break;
|
||||||
@ -279,14 +289,18 @@ static const char *parse_sysv_option(void){
|
|||||||
defer_sf_option(arg, SF_U_O);
|
defer_sf_option(arg, SF_U_O);
|
||||||
return NULL; /* can't have any more options */
|
return NULL; /* can't have any more options */
|
||||||
case 'P': /* SunOS 5 "psr" or unknown HP/UX feature */
|
case 'P': /* SunOS 5 "psr" or unknown HP/UX feature */
|
||||||
trace("-P adds columns of PRM info (HP) or PSR column (Sun)\n");
|
trace("-P adds columns of PRM info (HP-UX), PSR (SunOS), or capabilities (IRIX)\n");
|
||||||
format_modifiers |= FM_P;
|
format_modifiers |= FM_P;
|
||||||
break;
|
break;
|
||||||
#ifdef WE_UNDERSTAND_THIS
|
#if 0
|
||||||
case 'R': /* unknown HP/UX feature */
|
case 'R': // unknown HP/UX feature, like IRIX "-J" maybe?
|
||||||
trace("-R selects PRM groups\n");
|
trace("-R select by PRM group\n");
|
||||||
return "Don't understand PRM on Linux.";
|
arg=get_opt_arg();
|
||||||
break;
|
if(!arg) return "List of PRM groups must follow -R.";
|
||||||
|
err=parse_list(arg, parse_prm);
|
||||||
|
if(err) return err;
|
||||||
|
selection_list->typecode = SEL_PRM;
|
||||||
|
return NULL; /* can't have any more options */
|
||||||
#endif
|
#endif
|
||||||
case 'T':
|
case 'T':
|
||||||
/* IRIX 6.5 docs suggest POSIX threads get shown individually.
|
/* IRIX 6.5 docs suggest POSIX threads get shown individually.
|
||||||
@ -312,9 +326,10 @@ static const char *parse_sysv_option(void){
|
|||||||
display_version();
|
display_version();
|
||||||
exit(0);
|
exit(0);
|
||||||
#if 0
|
#if 0
|
||||||
|
// This must be verified against SVR4-MP (UnixWare or Powermax)
|
||||||
case 'Z': /* full Mandatory Access Control level info */
|
case 'Z': /* full Mandatory Access Control level info */
|
||||||
trace("-Z shows full MAC info\n");
|
trace("-Z shows full MAC info\n");
|
||||||
return "Don't understand MAC on Linux.";
|
format_modifiers |= FM_M;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 'a':
|
case 'a':
|
||||||
@ -394,7 +409,7 @@ static const char *parse_sysv_option(void){
|
|||||||
if(err) return err;
|
if(err) return err;
|
||||||
selection_list->typecode = SEL_PID;
|
selection_list->typecode = SEL_PID;
|
||||||
return NULL; /* can't have any more options */
|
return NULL; /* can't have any more options */
|
||||||
#ifdef KNOW_WHAT_TO_DO_WITH_THIS
|
#if 0
|
||||||
case 'r':
|
case 'r':
|
||||||
trace("-r some Digital Unix thing about warnings...\n");
|
trace("-r some Digital Unix thing about warnings...\n");
|
||||||
trace(" or SCO's option to chroot() for new /proc and /dev.\n");
|
trace(" or SCO's option to chroot() for new /proc and /dev.\n");
|
||||||
@ -448,9 +463,10 @@ static const char *parse_sysv_option(void){
|
|||||||
format_modifiers |= FM_y;
|
format_modifiers |= FM_y;
|
||||||
break;
|
break;
|
||||||
#if 0
|
#if 0
|
||||||
|
// This must be verified against SVR4-MP (UnixWare or Powermax)
|
||||||
case 'z': /* alias of Mandatory Access Control level info */
|
case 'z': /* alias of Mandatory Access Control level info */
|
||||||
trace("-z shows aliased MAC info\n");
|
trace("-z shows aliased MAC info\n");
|
||||||
return "Don't understand MAC aliases on Linux.";
|
format_modifiers |= FM_M;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case '-':
|
case '-':
|
||||||
|
59
vmstat.c
59
vmstat.c
@ -163,27 +163,6 @@ static void new_header(void){
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void 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 diskpartition_header(const char *partition_name){
|
|
||||||
printf("%-10s %10s %10s %10s %10s\n",partition_name, "reads ", "read sectors", "writes ", "requested writes");
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static void slabheader(void){
|
|
||||||
printf("%-24s %6s %6s %6s %6s\n","Cache","Num", "Total", "Size", "Pages");
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
static unsigned long unitConvert(unsigned int size){
|
static unsigned long unitConvert(unsigned int size){
|
||||||
float cvSize;
|
float cvSize;
|
||||||
cvSize=(float)size/dataUnit*((statMode==SLABSTAT)?1:1024);
|
cvSize=(float)size/dataUnit*((statMode==SLABSTAT)?1:1024);
|
||||||
@ -290,6 +269,12 @@ static void new_format(void) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void diskpartition_header(const char *partition_name){
|
||||||
|
printf("%-10s %10s %10s %10s %10s\n",partition_name, "reads ", "read sectors", "writes ", "requested writes");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static int diskpartition_format(const char* partition_name){
|
static int diskpartition_format(const char* partition_name){
|
||||||
FILE *fDiskstat;
|
FILE *fDiskstat;
|
||||||
struct disk_stat *disks;
|
struct disk_stat *disks;
|
||||||
@ -345,19 +330,41 @@ static int diskpartition_format(const char* partition_name){
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void diskheader(void){
|
||||||
|
printf("disk- ------------reads------------ ------------writes----------- -----IO------\n");
|
||||||
|
|
||||||
|
printf("%5s %6s %6s %7s %7s %6s %6s %7s %7s %6s %6s\n",
|
||||||
|
" ", "total", "merged","sectors","ms","total","merged","sectors","ms","cur","sec");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void diskformat(void){
|
static void diskformat(void){
|
||||||
FILE *fDiskstat;
|
FILE *fDiskstat;
|
||||||
struct disk_stat *disks;
|
struct disk_stat *disks;
|
||||||
struct partition_stat *partitions;
|
struct partition_stat *partitions;
|
||||||
unsigned long ndisks,i,j,k;
|
unsigned long ndisks,i,j,k;
|
||||||
const char format[]="%-3s %6u %6u %6llu %6u %6u %6u %6llu %6u %6u %6u\n";
|
const char format[]="%-5s %6u %6u %7llu %7u %6u %6u %7llu %7u %6u %6u\n";
|
||||||
if ((fDiskstat=fopen("/proc/diskstats", "rb"))){
|
if ((fDiskstat=fopen("/proc/diskstats", "rb"))){
|
||||||
fclose(fDiskstat);
|
fclose(fDiskstat);
|
||||||
ndisks=getdiskstat(&disks,&partitions);
|
ndisks=getdiskstat(&disks,&partitions);
|
||||||
for(k=0; k<ndisks; k++){
|
for(k=0; k<ndisks; k++){
|
||||||
if (moreheaders && ((k%height)==0)) diskheader();
|
if (moreheaders && ((k%height)==0)) diskheader();
|
||||||
printf(format,
|
printf(format,
|
||||||
disks[k].disk_name,disks[k].reads, disks[k].merged_reads,disks[k].reads_sectors, disks[k].milli_reading, disks[k].writes, disks[k].merged_writes, disks[k].written_sectors,disks[k].milli_writing, disks[k].inprogress_IO?disks[k].inprogress_IO/1000:0, disks[k].milli_spent_IO?disks[k].milli_spent_IO/1000:0/*, disks[i].weighted_milli_spent_IO/1000*/);
|
disks[k].disk_name,
|
||||||
|
disks[k].reads,
|
||||||
|
disks[k].merged_reads,
|
||||||
|
disks[k].reads_sectors,
|
||||||
|
disks[k].milli_reading,
|
||||||
|
disks[k].writes,
|
||||||
|
disks[k].merged_writes,
|
||||||
|
disks[k].written_sectors,
|
||||||
|
disks[k].milli_writing,
|
||||||
|
disks[k].inprogress_IO?disks[k].inprogress_IO/1000:0,
|
||||||
|
disks[k].milli_spent_IO?disks[k].milli_spent_IO/1000:0/*,
|
||||||
|
disks[i].weighted_milli_spent_IO/1000*/
|
||||||
|
);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
free(disks);
|
free(disks);
|
||||||
@ -394,6 +401,12 @@ static void diskformat(void){
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void slabheader(void){
|
||||||
|
printf("%-24s %6s %6s %6s %6s\n","Cache","Num", "Total", "Size", "Pages");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void slabformat (void){
|
static void slabformat (void){
|
||||||
FILE *fSlab;
|
FILE *fSlab;
|
||||||
struct slab_cache *slabs;
|
struct slab_cache *slabs;
|
||||||
|
Loading…
Reference in New Issue
Block a user