diff options
-rw-r--r-- | toys/vmstat.c | 290 |
1 files changed, 149 insertions, 141 deletions
diff --git a/toys/vmstat.c b/toys/vmstat.c index 12669458..e186961d 100644 --- a/toys/vmstat.c +++ b/toys/vmstat.c @@ -21,161 +21,169 @@ config VMSTAT #include "toys.h" -void read_proc_stat(unsigned int * proc_running, unsigned int * proc_blocked, - uint64_t * sys_irq, uint64_t * sys_ctxt, - uint64_t * cpu_user, uint64_t * cpu_sys, uint64_t * cpu_idle, uint64_t * cpu_wait) +void read_proc_stat(unsigned int * proc_running, unsigned int * proc_blocked, + uint64_t * sys_irq, uint64_t * sys_ctxt, + uint64_t * cpu_user, uint64_t * cpu_sys, uint64_t * cpu_idle, uint64_t * cpu_wait) { - char * off; - uint64_t c_user, c_nice, c_sys, c_irq, c_sirq; - int fd = xopen("/proc/stat", O_RDONLY); - if (fdlength(fd) > sizeof(toybuf)) - error_exit("/proc/stat is too large"); - xread(fd, toybuf, sizeof(toybuf)); - - off = strstr(toybuf, "cpu "); - // Ignoring steal and guest fields for now. - if (off) sscanf(off, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &c_user, &c_nice, &c_sys, cpu_idle, cpu_wait, &c_irq, &c_sirq); - *cpu_user = c_user + c_nice; - *cpu_sys = c_sys + c_irq + c_sirq; - off = strstr(toybuf, "intr"); - if (off) sscanf(off, "intr %Lu", sys_irq); - - off = strstr(toybuf, "ctxt"); - if (off) sscanf(off, "ctxt %Lu", sys_ctxt); - - off = strstr(toybuf, "procs_running"); - if (off) sscanf(off, "procs_running %u", proc_running); - (*proc_running)--; // look, i'm invisible. - - off = strstr(toybuf, "procs_blocked"); - if (off) sscanf(off, "procs_blocked %u", proc_blocked); - - close(fd); + char * off; + uint64_t c_user, c_nice, c_sys, c_irq, c_sirq; + int fd = xopen("/proc/stat", O_RDONLY); + size_t s = xread(fd, toybuf, sizeof(toybuf)-1); + toybuf[s] = 0; + if ( s == sizeof(toybuf)-1) + error_exit("/proc/stat is too large"); + + off = strstr(toybuf, "cpu "); + // Ignoring steal and guest fields for now. + if (off) sscanf(off, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &c_user, &c_nice, &c_sys, cpu_idle, cpu_wait, &c_irq, &c_sirq); + *cpu_user = c_user + c_nice; + *cpu_sys = c_sys + c_irq + c_sirq; + off = strstr(toybuf, "intr"); + if (off) sscanf(off, "intr %Lu", sys_irq); + + off = strstr(toybuf, "ctxt"); + if (off) sscanf(off, "ctxt %Lu", sys_ctxt); + + off = strstr(toybuf, "procs_running"); + if (off) sscanf(off, "procs_running %u", proc_running); + (*proc_running)--; // look, i'm invisible. + + off = strstr(toybuf, "procs_blocked"); + if (off) sscanf(off, "procs_blocked %u", proc_blocked); + + close(fd); } -void read_proc_meminfo(unsigned long * mem_swapped, unsigned long * mem_free, - unsigned long * mem_buff, unsigned long * mem_cache) +void read_proc_meminfo(unsigned long * mem_swapped, unsigned long * mem_free, + unsigned long * mem_buff, unsigned long * mem_cache) { - char * off; - unsigned long swap_total, swap_free; - int fd = xopen("/proc/meminfo", O_RDONLY); - if (fdlength(fd) > sizeof(toybuf)) - error_exit("/proc/meminfo is too large"); - xread(fd, toybuf, sizeof(toybuf)); + char * off; + unsigned long swap_total, swap_free; + int fd = xopen("/proc/meminfo", O_RDONLY); + size_t s = xread(fd, toybuf, sizeof(toybuf)-1); + toybuf[s] = 0; + if ( s == sizeof(toybuf)-1) + error_exit("/proc/meminfo is too large"); - off = strstr(toybuf, "MemFree"); - if (off) sscanf(off, "MemFree: %lu kB", mem_free); + off = strstr(toybuf, "MemFree"); + if (off) sscanf(off, "MemFree: %lu kB", mem_free); - off = strstr(toybuf, "Buffers"); - if (off) sscanf(off, "Buffers: %lu kB", mem_buff); + off = strstr(toybuf, "Buffers"); + if (off) sscanf(off, "Buffers: %lu kB", mem_buff); - off = strstr(toybuf, "Cached"); - if (off) sscanf(off, "Cached: %lu kB", mem_cache); + off = strstr(toybuf, "Cached"); + if (off) sscanf(off, "Cached: %lu kB", mem_cache); - off = strstr(toybuf, "SwapFree"); - if (off) sscanf(off, "SwapFree: %lu kB", &swap_free); + off = strstr(toybuf, "SwapFree"); + if (off) sscanf(off, "SwapFree: %lu kB", &swap_free); - off = strstr(toybuf, "SwapTotal"); - if (off) sscanf(off, "SwapTotal: %lu kB", &swap_total); - *mem_swapped = swap_total - swap_free; + off = strstr(toybuf, "SwapTotal"); + if (off) sscanf(off, "SwapTotal: %lu kB", &swap_total); + *mem_swapped = swap_total - swap_free; - close(fd); + close(fd); } -void read_proc_vmstat(unsigned long * io_pages_in, unsigned long * io_pages_out, unsigned long * swap_bytes_in, unsigned long * swap_bytes_out) +void read_proc_vmstat(unsigned long * io_pages_in, unsigned long * io_pages_out, + unsigned long * swap_bytes_in, unsigned long * swap_bytes_out) { - char * off; - unsigned long s_pages_in, s_pages_out; - unsigned long pagesize_kb = sysconf(_SC_PAGESIZE) / 1024L; - int fd = xopen("/proc/vmstat", O_RDONLY); - if (fdlength(fd) > sizeof(toybuf)) - error_exit("/proc/vmstat is too large"); - xread(fd, toybuf, sizeof(toybuf)); - - off = strstr(toybuf, "pgpgin"); - if (off) sscanf(off, "pgpgin %lu", io_pages_in); - - off = strstr(toybuf, "pgpgout"); - if (off) sscanf(off, "pgpgout %lu", io_pages_out); - - off = strstr(toybuf, "pswpin"); - if (off) sscanf(off, "pswpin %lu", &s_pages_in); - *swap_bytes_in = s_pages_in * pagesize_kb; - - off = strstr(toybuf, "pswpout"); - if (off) sscanf(off, "pswpout %lu", &s_pages_out); - *swap_bytes_out = s_pages_out * pagesize_kb; - - close(fd); + char * off; + unsigned long s_pages_in, s_pages_out; + unsigned long pagesize_kb = sysconf(_SC_PAGESIZE) / 1024L; + int fd = xopen("/proc/vmstat", O_RDONLY); + size_t s = xread(fd, toybuf, sizeof(toybuf)-1); + toybuf[s] = 0; + if ( s == sizeof(toybuf)-1) + error_exit("/proc/vmstat is too large"); + + off = strstr(toybuf, "pgpgin"); + if (off) sscanf(off, "pgpgin %lu", io_pages_in); + + off = strstr(toybuf, "pgpgout"); + if (off) sscanf(off, "pgpgout %lu", io_pages_out); + + off = strstr(toybuf, "pswpin"); + if (off) sscanf(off, "pswpin %lu", &s_pages_in); + *swap_bytes_in = s_pages_in * pagesize_kb; + + off = strstr(toybuf, "pswpout"); + if (off) sscanf(off, "pswpout %lu", &s_pages_out); + *swap_bytes_out = s_pages_out * pagesize_kb; + + close(fd); } void vmstat_main(void) -{ - const char fmt[] = "%2u %2u %6lu %6lu %6lu %6lu %4u %4u %5u %5u %4u %4u %2u %2u %2u %2u\n"; - unsigned int loop_num = 0, loop_max_num = 0, loop_delay = 0; - unsigned int running = 0, blocked = 0; - unsigned long mem_swap = 0, mem_free = 0, mem_buff = 0, mem_cache = 0; - unsigned long io_pages_in[2], io_pages_out[2], swap_bytes_in[2], swap_bytes_out[2]; - uint64_t sys_irq[2], sys_ctxt[2], cpu_user[2], cpu_sys[2], cpu_idle[2], cpu_wait[2]; - int first_run = 1; - int no_header = toys.optflags & 0x1; - - if (toys.optc >= 1) - loop_delay = atoi(toys.optargs[0]); - if (toys.optc >= 2) - loop_max_num = atoi(toys.optargs[1]); - - if (loop_max_num < 0 || loop_delay < 0) - error_exit("Invalid arguments"); - - while(1) { - uint64_t total_jif; - int idx = loop_num%2; - - if(first_run || (!(loop_num % 22) && !no_header)) { - printf("procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----\n"); - printf(" r b swpd free buff cache si so bi bo in cs us sy id wa\n"); - } - - read_proc_stat(&running, &blocked, &sys_irq[idx], &sys_ctxt[idx], &cpu_user[idx], - &cpu_sys[idx], &cpu_idle[idx], &cpu_wait[idx]); - read_proc_meminfo(&mem_swap, &mem_free, &mem_buff, &mem_cache); - read_proc_vmstat(&io_pages_in[idx], &io_pages_out[idx], &swap_bytes_in[idx], &swap_bytes_out[idx]); - - if (first_run) { - struct sysinfo inf; - sysinfo(&inf); - first_run = 0; - total_jif = cpu_user[idx] + cpu_idle[idx] + cpu_wait[idx]; - printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache, - (unsigned) (swap_bytes_in[idx]/inf.uptime), - (unsigned) (swap_bytes_out[idx]/inf.uptime), - (unsigned) (io_pages_in[idx]/inf.uptime), - (unsigned) (io_pages_out[idx]/inf.uptime), - (unsigned) (sys_irq[idx]/inf.uptime), - (unsigned) (sys_ctxt[idx]/inf.uptime), - (unsigned) (100*cpu_user[idx]/total_jif), - (unsigned) (100*cpu_sys[idx]/total_jif), - (unsigned) (100*cpu_idle[idx]/total_jif), - (unsigned) (100*cpu_wait[idx]/total_jif)); - }else{ - total_jif = cpu_user[idx] - cpu_user[!idx] + cpu_idle[idx] - cpu_idle[!idx] + cpu_wait[idx] - cpu_wait[!idx]; - printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache, - (unsigned) ((swap_bytes_in[idx] - swap_bytes_in[!idx])/loop_delay), - (unsigned) ((swap_bytes_out[idx] - swap_bytes_out[!idx])/loop_delay), - (unsigned) ((io_pages_in[idx] - io_pages_in[!idx])/loop_delay), - (unsigned) ((io_pages_out[idx] - io_pages_out[!idx])/loop_delay), - (unsigned) ((sys_irq[idx] - sys_irq[!idx])/loop_delay), - (unsigned) ((sys_ctxt[idx] - sys_ctxt[!idx])/loop_delay), - (unsigned) (100*(cpu_user[idx] - cpu_user[!idx])/total_jif), - (unsigned) (100*(cpu_sys[idx] - cpu_sys[!idx]) /total_jif), - (unsigned) (100*(cpu_idle[idx] - cpu_idle[!idx])/total_jif), - (unsigned) (100*(cpu_wait[idx] - cpu_wait[!idx])/total_jif)); - } - - loop_num++; - if (loop_delay == 0 || (loop_max_num != 0 && loop_num >= loop_max_num)) - break; - sleep(loop_delay); - } +{ + const char fmt[] = "%2u %2u %6lu %6lu %6lu %6lu %4u %4u %5u %5u %4u %4u %2u %2u %2u %2u\n"; + unsigned int loop_num = 0, loop_max_num = 0, loop_delay = 0; + unsigned int running = 0, blocked = 0; + unsigned long mem_swap = 0, mem_free = 0, mem_buff = 0, mem_cache = 0; + unsigned long io_pages_in[2], io_pages_out[2], swap_bytes_in[2], swap_bytes_out[2]; + uint64_t sys_irq[2], sys_ctxt[2], cpu_user[2], cpu_sys[2], cpu_idle[2], cpu_wait[2]; + int first_run = 1; + int no_header = toys.optflags & 0x1; + unsigned num_rows = 22; + + if (toys.optc >= 1) + loop_delay = atoi(toys.optargs[0]); + if (toys.optc >= 2) + loop_max_num = atoi(toys.optargs[1]); + + if (loop_max_num < 0 || loop_delay < 0) + error_exit("Invalid arguments"); + + while(1) { + uint64_t total_jif; + int idx = loop_num%2; + + if(first_run || (!(loop_num % num_rows) && !no_header)) { + unsigned rows = 0, cols = 0; + terminal_size(&cols, &rows); + num_rows = (rows > 3)? rows - 3 : 22; + printf("procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----\n"); + printf(" r b swpd free buff cache si so bi bo in cs us sy id wa\n"); + } + + read_proc_stat(&running, &blocked, &sys_irq[idx], &sys_ctxt[idx], &cpu_user[idx], + &cpu_sys[idx], &cpu_idle[idx], &cpu_wait[idx]); + read_proc_meminfo(&mem_swap, &mem_free, &mem_buff, &mem_cache); + read_proc_vmstat(&io_pages_in[idx], &io_pages_out[idx], &swap_bytes_in[idx], &swap_bytes_out[idx]); + + if (first_run) { + struct sysinfo inf; + sysinfo(&inf); + first_run = 0; + total_jif = cpu_user[idx] + cpu_idle[idx] + cpu_wait[idx]; + printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache, + (unsigned) (swap_bytes_in[idx]/inf.uptime), + (unsigned) (swap_bytes_out[idx]/inf.uptime), + (unsigned) (io_pages_in[idx]/inf.uptime), + (unsigned) (io_pages_out[idx]/inf.uptime), + (unsigned) (sys_irq[idx]/inf.uptime), + (unsigned) (sys_ctxt[idx]/inf.uptime), + (unsigned) (100*cpu_user[idx]/total_jif), + (unsigned) (100*cpu_sys[idx]/total_jif), + (unsigned) (100*cpu_idle[idx]/total_jif), + (unsigned) (100*cpu_wait[idx]/total_jif)); + }else{ + total_jif = cpu_user[idx] - cpu_user[!idx] + cpu_idle[idx] - cpu_idle[!idx] + cpu_wait[idx] - cpu_wait[!idx]; + printf(fmt, running, blocked, mem_swap, mem_free, mem_buff, mem_cache, + (unsigned) ((swap_bytes_in[idx] - swap_bytes_in[!idx])/loop_delay), + (unsigned) ((swap_bytes_out[idx] - swap_bytes_out[!idx])/loop_delay), + (unsigned) ((io_pages_in[idx] - io_pages_in[!idx])/loop_delay), + (unsigned) ((io_pages_out[idx] - io_pages_out[!idx])/loop_delay), + (unsigned) ((sys_irq[idx] - sys_irq[!idx])/loop_delay), + (unsigned) ((sys_ctxt[idx] - sys_ctxt[!idx])/loop_delay), + (unsigned) (100*(cpu_user[idx] - cpu_user[!idx])/total_jif), + (unsigned) (100*(cpu_sys[idx] - cpu_sys[!idx]) /total_jif), + (unsigned) (100*(cpu_idle[idx] - cpu_idle[!idx])/total_jif), + (unsigned) (100*(cpu_wait[idx] - cpu_wait[!idx])/total_jif)); + } + + loop_num++; + if (loop_delay == 0 || (loop_max_num != 0 && loop_num >= loop_max_num)) + break; + sleep(loop_delay); + } } |