On Wed, Dec 18, 2002 at 11:18:24AM -0800, Matthew Dillon wrote:
> 
> :I have made a small patch, added l, s and h switches to show
> :information about the swap devices. And the U switch to swapctl only
> :to remove all activated swap devices.
> :If anything else is needed let me know and I will add it.
> :
> :--=20
> :
> :Eirik Nygaard <[EMAIL PROTECTED]>
> :PGP Key: 83C55EDE
> 
>     That is a pretty good first attempt.  I have a few suggests and found 
>     one bug.  First the bug:
> 
> :+            is_swapctl ? "lsU" : "");
> 
>     I think that was supposed to be a call to is_swapctl, not a pointer
>     to the function.
> 
>     Suggestions:  Get rid of the is_swap*() functions and instead use
>     av[0] at the top of main() and use strstr() to determine if the
>     program is swapon, swapoff, or swapctl.  Check against "swapon" and
>     "swapoff" and if it is neither then default to swapctl (don't test
>     against "swapctl").  Store which program it is in a global variable,
>     e.g.  an enum like this:
> 
>     enum { SWAPON, SWAPOFF, SWAPCTL } which_prog = SWAPCTL;
> 
>     In regards to retrieving swap information, in -current there is a
>     sysctl() to do it.  Take a look at /usr/src/usr.sbin/pstat/pstat.c
>     (in the current source tree), at the swapmode_kvm() and swapmode_sysctl()
>     functions.  The sysctl is much, much faster then the kvm call because
>     the kvm call has to run through the swap radix tree to collect the useage
>     information.
> 

Added the enum instead of is_swap* commands and changed from kvm to
sysctl to get the swap information.

-- 

Eirik Nygaard <[EMAIL PROTECTED]>
PGP Key: 83C55EDE

? sbin/swapon/.swapon.c.swp
Index: sbin/swapon/Makefile
===================================================================
RCS file: /home/ncvs/src/sbin/swapon/Makefile,v
retrieving revision 1.7
diff -u -r1.7 Makefile
--- sbin/swapon/Makefile        15 Dec 2002 19:17:56 -0000      1.7
+++ sbin/swapon/Makefile        18 Dec 2002 20:35:53 -0000
@@ -3,7 +3,9 @@
 
 PROG=  swapon
 MAN=   swapon.8
-LINKS= ${BINDIR}/swapon ${BINDIR}/swapoff
-MLINKS=        swapon.8 swapoff.8
+LINKS= ${BINDIR}/swapoff ${BINDIR}/swapon
+LINKS+=        ${BINDIR}/swapctl ${BINDIR}/swapon
+MLINKS=        swapoff.8 swapon.8
+MLINKS=        swapctl.8 swapon.8
 
 .include <bsd.prog.mk>
Index: sbin/swapon/swapon.c
===================================================================
RCS file: /home/ncvs/src/sbin/swapon/swapon.c,v
retrieving revision 1.13
diff -u -r1.13 swapon.c
--- sbin/swapon/swapon.c        15 Dec 2002 19:17:56 -0000      1.13
+++ sbin/swapon/swapon.c        18 Dec 2002 20:35:53 -0000
@@ -45,6 +45,11 @@
   "$FreeBSD: src/sbin/swapon/swapon.c,v 1.13 2002/12/15 19:17:56 dillon Exp $";
 #endif /* not lint */
 
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+
 #include <err.h>
 #include <errno.h>
 #include <fstab.h>
@@ -52,10 +57,13 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
+
+static void usage(void);
+int    swap_on_off(char *name, int ignoreebusy);
+void   swaplist(int, int, int);
 
-static void usage(const char *);
-static int is_swapoff(const char *);
-int    swap_on_off(char *name, int ignoreebusy, int do_swapoff);
+enum { SWAPON, SWAPOFF, SWAPCTL } which_prog = SWAPCTL;
 
 int
 main(int argc, char **argv)
@@ -63,47 +71,80 @@
        struct fstab *fsp;
        int stat;
        int ch, doall;
-       int do_swapoff;
-       char *pname = argv[0];
-
-       do_swapoff = is_swapoff(pname);
-
+       int sflag = 0, lflag = 0, hflag = 0;
+       
+       if (strstr(argv[0], "swapon"))
+               which_prog = SWAPON;
+       else if (strstr(argv[0], "swapoff"))
+               which_prog = SWAPOFF;
+       
        doall = 0;
-       while ((ch = getopt(argc, argv, "a")) != -1)
-               switch((char)ch) {
+       while ((ch = getopt(argc, argv, "alhsU")) != -1)
+               switch(ch) {
                case 'a':
                        doall = 1;
                        break;
+               case 's':
+                       sflag = 1;
+                       break;
+               case 'l':
+                       lflag = 1;
+                       break;
+               case 'h':
+                       hflag = 1;
+                       break;
+               case 'U':
+                       if (which_prog != SWAPON) {
+                               doall = 1;
+                               which_prog = SWAPOFF;
+                               break;
+                       } /* Remove the if if you want the U switch to work with 
+swapon also, don't know if that is wanted */
                case '?':
                default:
-                       usage(pname);
+                       usage();
                }
        argv += optind;
-
+       
        stat = 0;
-       if (doall)
-               while ((fsp = getfsent()) != NULL) {
-                       if (strcmp(fsp->fs_type, FSTAB_SW))
-                               continue;
-                       if (strstr(fsp->fs_mntops, "noauto"))
-                               continue;
-                       if (swap_on_off(fsp->fs_spec, 1, do_swapoff))
-                               stat = 1;
-                       else
-                               printf("%s: %sing %s as swap device\n",
-                                   pname, do_swapoff ? "remov" : "add",
-                                   fsp->fs_spec);
+       if (which_prog == SWAPON || which_prog == SWAPOFF) {
+               if (doall) {
+                       while ((fsp = getfsent()) != NULL) {
+                               if (strcmp(fsp->fs_type, FSTAB_SW))
+                                       continue;
+                               if (strstr(fsp->fs_mntops, "noauto"))
+                                       continue;
+                               if (swap_on_off(fsp->fs_spec, 0))
+                                       stat = 1;
+                               else
+                                       printf("%s: %sing %s as swap device\n",
+                                           getprogname(), which_prog == SWAPOFF ? 
+"remov" : "add",
+                                           fsp->fs_spec);
+                       }
                }
-       else if (!*argv)
-               usage(pname);
-       for (; *argv; ++argv)
-               stat |= swap_on_off(*argv, 0, do_swapoff);
+               else if (!*argv)
+                       usage();
+               for (; *argv; ++argv)
+                       stat |= swap_on_off(*argv, 0);
+       }
+       else {
+               if (lflag == 1 || sflag == 1)
+                       swaplist(lflag, sflag, hflag);
+
+               else 
+                       usage();
+       }
+       
        exit(stat);
 }
 
 int
-swap_on_off(char *name, int ignoreebusy, int do_swapoff)
+swap_on_off(char *name, int ignoreebusy)
 {
+       int do_swapoff; 
+       
+       if (which_prog == SWAPOFF)
+               do_swapoff = 1;
+       
        if ((do_swapoff ? swapoff(name) : swapon(name)) == -1) {
                switch (errno) {
                case EBUSY:
@@ -120,23 +161,73 @@
 }
 
 static void
-usage(const char *pname)
+usage(void)
 {
-       fprintf(stderr, "usage: %s [-a] [special_file ...]\n", pname);
+       fprintf(stderr, "usage: %s [-a%s] [special_file ...]\n", getprogname(),
+               which_prog == SWAPCTL ? "lsU" : "");
        exit(1);
 }
 
-static int
-is_swapoff(const char *s)
+/* Some code is based on the code in the swapmode_sysctl command in pstat */
+void
+swaplist(int lflag, int sflag, int hflag)
 {
-       const char *u;
-
-       if ((u = strrchr(s, '/')) != NULL)
-               ++u;
-       else
-               u = s;
-       if (strcmp(u, "swapoff") == 0)
-               return 1;
-       else
-               return 0;
+       size_t mibsize, size;
+       struct xswdev xsw;
+       int mib[16], n, pagesize, used, total, i = 0;
+       
+       pagesize = getpagesize();
+       
+       mibsize = sizeof mib / sizeof mib[0];
+       if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1)
+               err(1, "sysctlnametomib()");
+       
+       if (lflag)
+               printf("%-*s %s%10s %s%10s\n",
+                                 13, "Device:", 
+                                 hflag ? " " : "", "Total:",
+                                 hflag ? " " : "", "Used:");
+       
+       used = total = 0;
+       for (n = 0; ; ++n) {
+               mib[mibsize] = n;
+               size = sizeof xsw;
+               if (sysctl(mib, mibsize + 1, &xsw, &size, NULL, NULL) == -1)
+                       break;
+               if (xsw.xsw_version != XSWDEV_VERSION)
+                       errx(1, "xswdev version mismatch");
+               
+               if (lflag) {
+                       total = xsw.xsw_nblks * pagesize / 1024;
+                       used  = xsw.xsw_used * pagesize / 1024;
+                       
+                       if (hflag) {
+                               total = total / 1000;
+                               used  = used / 1000;
+                       }
+               
+                       printf("/dev/%-*s %10d%s %10d%s\n", 
+                                         8, devname(xsw.xsw_dev, S_IFCHR),
+                                         total, hflag ? "M" : "",
+                                         used, hflag ? "M" : "");
+               }
+               if (sflag) {
+                       total += xsw.xsw_nblks * pagesize / 1024;
+                       used  += xsw.xsw_used * pagesize / 1024;
+               }
+               i++;
+       }
+       if (errno != ENOENT)
+               err(1, "sysctl()");
+       
+       if (hflag) {
+               total = total / 1000;
+               used  = used / 1000;
+       }
+       if (sflag)
+               printf("Swap: Total: %8d%s  Used: %8d%s\n",
+                      total, hflag ? "M" : "",
+                      used, hflag ? "M" : "");
+       
 }
+

Attachment: msg49011/pgp00000.pgp
Description: PGP signature

Reply via email to