[BACK]Return to swap.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / systat

Diff for /src/usr.bin/systat/swap.c between version 1.10 and 1.11

version 1.10, 1998/11/22 23:29:37 version 1.11, 1999/05/22 21:41:58
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
 /*      $NetBSD: swap.c,v 1.5 1996/05/10 23:16:38 thorpej Exp $ */  /*      $NetBSD: swap.c,v 1.9 1998/12/26 07:05:08 marc Exp $    */
   
 /*-  /*-
    * Copyright (c) 1997 Matthew R. Green.  All rights reserved.
  * Copyright (c) 1980, 1992, 1993   * Copyright (c) 1980, 1992, 1993
  *      The Regents of the University of California.  All rights reserved.   *      The Regents of the University of California.  All rights reserved.
  *   *
Line 41 
Line 42 
 static char rcsid[] = "$OpenBSD$";  static char rcsid[] = "$OpenBSD$";
 #endif /* not lint */  #endif /* not lint */
   
 /*  
  * swapinfo - based on a program of the same name by Kevin Lahey  
  */  
   
   #include <sys/cdefs.h>
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/buf.h>  #include <sys/buf.h>
 #include <sys/conf.h>  #include <sys/conf.h>
 #include <sys/ioctl.h>  #include <sys/ioctl.h>
 #include <sys/map.h>  
 #include <sys/stat.h>  #include <sys/stat.h>
   #include <sys/swap.h>
   
 #include <kvm.h>  
 #include <nlist.h>  
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   #include <errno.h>
 #include <unistd.h>  #include <unistd.h>
   
 #include "systat.h"  #include "systat.h"
 #include "extern.h"  #include "extern.h"
   
 extern char *getbsize __P((int *headerlenp, long *blocksizep));  
 void showspace __P((char *header, int hlen, long blocksize));  void showspace __P((char *header, int hlen, long blocksize));
   
 struct nlist syms[] = {  static  long blocksize;
         { "_swapmap" }, /* list of free swap areas */  static  int hlen, nswap, rnswap;
 #define VM_SWAPMAP      0  static  int first = 1;
         { "_nswapmap" },/* size of the swap map */  static  struct swapent *swap_devices;
 #define VM_NSWAPMAP     1  
         { "_swdevt" },  /* list of swap devices and sizes */  
 #define VM_SWDEVT       2  
         { "_nswap" },   /* size of largest swap device */  
 #define VM_NSWAP        3  
         { "_nswdev" },  /* number of swap devices */  
 #define VM_NSWDEV       4  
         { "_dmmax" },   /* maximum size of a swap block */  
 #define VM_DMMAX        5  
         { 0 }  
 };  
   
 static int nswap, nswdev, dmmax, nswapmap;  
 static struct swdevt *sw;  
 static long *perdev, blocksize;  
 static struct map *swapmap, *kswapmap;  
 static struct mapent *mpp;  
 static int nfree, hlen;  
   
 #define SVAR(var) __STRING(var) /* to force expansion */  
 #define KGET(idx, var) \  
         KGET1(idx, &var, sizeof(var), SVAR(var))  
 #define KGET1(idx, p, s, msg) \  
         KGET2(syms[idx].n_value, p, s, msg)  
 #define KGET2(addr, p, s, msg) \  
         if (kvm_read(kd, addr, p, s) != s) { \  
                 error("cannot read %s: %s", msg, kvm_geterr(kd)); \  
                 return (0); \  
         }  
   
 WINDOW *  WINDOW *
 openswap()  openswap()
 {  {
Line 116 
Line 84 
         delwin(w);          delwin(w);
 }  }
   
   /* do nothing */
 int  int
 initswap()  initswap()
 {  {
         int i;  
         char msgbuf[BUFSIZ];  
         static int once = 0;  
   
         if (once)  
                 return (1);  
         if (kvm_nlist(kd, syms)) {  
                 strcpy(msgbuf, "systat: swap: cannot find");  
                 for (i = 0; syms[i].n_name != NULL; i++) {  
                         if (syms[i].n_value == 0) {  
                                 if (strlen(msgbuf) + strlen(syms[i].n_name) +2 >  
                                     sizeof (msgbuf))  
                                         continue;  
                                 strcat(msgbuf, " ");  
                                 strcat(msgbuf, syms[i].n_name);  
                         }  
                 }  
                 error(msgbuf);  
                 return (0);  
         }  
         KGET(VM_NSWAP, nswap);  
         KGET(VM_NSWDEV, nswdev);  
         KGET(VM_DMMAX, dmmax);  
         KGET(VM_NSWAPMAP, nswapmap);  
         KGET(VM_SWAPMAP, kswapmap);     /* kernel `swapmap' is a pointer */  
         if ((sw = malloc(nswdev * sizeof(*sw))) == NULL ||  
             (perdev = malloc(nswdev * sizeof(*perdev))) == NULL ||  
             (mpp = malloc(nswapmap * sizeof(*mpp))) == NULL) {  
                 error("swap malloc");  
                 return (0);  
         }  
         KGET1(VM_SWDEVT, sw, nswdev * sizeof(*sw), "swdevt");  
         once = 1;  
         return (1);          return (1);
 }  }
   
 void  void
 fetchswap()  fetchswap()
 {  {
         struct mapent *mp;          int     update_label = 0;
         int s, e, i;  
   
         s = nswapmap * sizeof(*mpp);          first = 0;
         mp = mpp;          nswap = swapctl(SWAP_NSWAP, 0, 0);
         if (kvm_read(kd, (long)kswapmap, mp, s) != s)          if (nswap < 0)
                 error("cannot read swapmap: %s", kvm_geterr(kd));                  error("error: %s", strerror(errno));
           if (nswap == 0)
                   return;
           update_label = (nswap != rnswap);
   
         /* first entry in map is `struct map'; rest are mapent's */          if (swap_devices)
         swapmap = (struct map *)mp;                  (void)free(swap_devices);
         if (nswapmap != swapmap->m_limit - (struct mapent *)kswapmap)          swap_devices = (struct swapent *)malloc(nswap * sizeof(*swap_devices));
                 error("panic: swap: nswapmap goof");          if (swap_devices == NULL)
                   /* XXX */ ;     /* XXX systat doesn't do errors! */
   
         /*          rnswap = swapctl(SWAP_STATS, (void *)swap_devices, nswap);
          * Count up swap space.          if (nswap < 0)
          */                  /* XXX */ ;     /* XXX systat doesn't do errors! */
         nfree = 0;          if (nswap != rnswap)
         bzero(perdev, nswdev * sizeof(*perdev));                  /* XXX */ ;     /* XXX systat doesn't do errors! */
         for (mp++; mp->m_addr != 0; mp++) {          if (update_label)
                 s = mp->m_addr;                 /* start of swap region */                  labelswap();
                 e = mp->m_addr + mp->m_size;    /* end of region */  
                 nfree += mp->m_size;  
   
                 /*  
                  * Swap space is split up among the configured disks.  
                  * The first dmmax blocks of swap space some from the  
                  * first disk, the next dmmax blocks from the next,  
                  * and so on.  The list of free space joins adjacent  
                  * free blocks, ignoring device boundries.  If we want  
                  * to keep track of this information per device, we'll  
                  * just have to extract it ourselves.  
                  */  
   
                 /* calculate first device on which this falls */  
                 i = (s / dmmax) % nswdev;  
                 while (s < e) {         /* XXX this is inefficient */  
                         int bound = roundup(s + 1, dmmax);  
   
                         if (bound > e)  
                                 bound = e;  
                         perdev[i] += bound - s;  
                         if (++i >= nswdev)  
                                 i = 0;  
                         s = bound;  
                 }  
         }  
 }  }
   
 void  void
 labelswap()  labelswap()
 {  {
         char *header, *p;          char    *header;
         int row, i;          int     row;
   
         row = 0;          row = 0;
         wmove(wnd, row, 0); wclrtobot(wnd);          wmove(wnd, row, 0);
           wclrtobot(wnd);
           if (first)
                   fetchswap();
           if (nswap == 0) {
                   mvwprintw(wnd, row++, 0, "No swap");
                   return;
           }
         header = getbsize(&hlen, &blocksize);          header = getbsize(&hlen, &blocksize);
         mvwprintw(wnd, row++, 0, "%-5s%*s%9s  %55s",          mvwprintw(wnd, row++, 0, "%-5s%*s%9s  %55s",
             "Disk", hlen, header, "Used",              "Disk", hlen, header, "Used",
             "/0%  /10% /20% /30% /40% /50% /60% /70% /80% /90% /100%");              "/0%  /10% /20% /30% /40% /50% /60% /70% /80% /90% /100%");
         for (i = 0; i < nswdev; i++) {  
                 p = devname(sw[i].sw_dev, S_IFBLK);  
                 mvwprintw(wnd, i + 1, 0, "%-5s", p == NULL ? "??" : p);  
         }  
 }  }
   
 void  void
 showswap()  showswap() {
 {          int     col, div, i, j, avail, used, xsize, free;
         int col, div, i, j, avail, npfree, used, xsize, xfree;          struct  swapent *sep;
           char    *p;
   
         div = blocksize / 512;          div = blocksize / 512;
         avail = npfree = 0;          free = avail = 0;
         for (i = 0; i < nswdev; i++) {          for (sep = swap_devices, i = 0; i < nswap; i++, sep++) {
                   if (sep == NULL)
                           continue;
   
                   p = strrchr(sep->se_path, '/');
                   p = p ? p+1 : sep->se_path;
   
                   mvwprintw(wnd, i + 1, 0, "%-5s", p);
   
                 col = 5;                  col = 5;
                 mvwprintw(wnd, i + 1, col, "%*d", hlen, sw[i].sw_nblks / div);                  mvwprintw(wnd, i + 1, col, "%*d", hlen, sep->se_nblks / div);
   
                 col += hlen;                  col += hlen;
                 /*                  xsize = sep->se_nblks;
                  * Don't report statistics for partitions which have not                  used = sep->se_inuse;
                  * yet been activated via swapon(8).                  avail += xsize;
                  */                  free += xsize - used;
                 if (!sw[i].sw_freed) {  
                         mvwprintw(wnd, i + 1, col + 8,  
                             "0  *** not available for swapping ***");  
                         continue;  
                 }  
                 xsize = sw[i].sw_nblks;  
                 xfree = perdev[i];  
                 used = xsize - xfree;  
                 mvwprintw(wnd, i + 1, col, "%9d  ", used / div);                  mvwprintw(wnd, i + 1, col, "%9d  ", used / div);
                 wclrtoeol(wnd);  
                 for (j = (100 * used / xsize + 1) / 2; j > 0; j--)                  for (j = (100 * used / xsize + 1) / 2; j > 0; j--)
                         waddch(wnd, 'X');                          waddch(wnd, 'X');
                 npfree++;                  wclrtoeol(wnd);
                 avail += xsize;  
         }          }
         /*          /* do total if necessary */
          * If only one partition has been set up via swapon(8), we don't          if (nswap > 1) {
          * need to bother with totals.                  used = avail - free;
          */  
         if (npfree > 1) {  
                 used = avail - nfree;  
                 mvwprintw(wnd, i + 1, 0, "%-5s%*d%9d  ",                  mvwprintw(wnd, i + 1, 0, "%-5s%*d%9d  ",
                     "Total", hlen, avail / div, used / div);                      "Total", hlen, avail / div, used / div);
                 wclrtoeol(wnd);  
                 for (j = (100 * used / avail + 1) / 2; j > 0; j--)                  for (j = (100 * used / avail + 1) / 2; j > 0; j--)
                         waddch(wnd, 'X');                          waddch(wnd, 'X');
                   wclrtoeol(wnd);
         }          }
 }  }

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11