: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

    All right, I found a couple more bugs and fleshed it out a bit.
    You got your LINKS and MLINKS reversed and forgot a +=, 
    you forgot to initialize the do_swapoff variable in swap_on_off(),
    and you reuse 'total' and 'used' in swaplist() in a manner which breaks
    the -s option.

    I have included an updated patch below based on these fixes and a few 
    other minor cleanups.  I also changed the block size for -h from 1000
    to 1024 bytes to make it consistent with pstat -s and friends (and
    also OpenBSD and NetBSD).

    I also added -A, -U, cleaned up usage(), and made the options conform
    to NetBSD and OpenBSD.

    The only thing really missing is for us to handle the BLOCKSIZE
    environment variable like 'df' does, and appropriate additions to
    the manual page (which I would be happy to do).  Once we get those in
    I will commit it.

    Here is an updated patch.

                                                -Matt

Index: Makefile
===================================================================
RCS file: /home/ncvs/src/sbin/swapon/Makefile,v
retrieving revision 1.7
diff -u -r1.7 Makefile
--- Makefile    15 Dec 2002 19:17:56 -0000      1.7
+++ Makefile    18 Dec 2002 21:31:41 -0000
@@ -4,6 +4,8 @@
 PROG=  swapon
 MAN=   swapon.8
 LINKS= ${BINDIR}/swapon ${BINDIR}/swapoff
+LINKS+=        ${BINDIR}/swapon ${BINDIR}/swapctl
 MLINKS=        swapon.8 swapoff.8
+MLINKS+=swapon.8 swapctl.8
 
 .include <bsd.prog.mk>
Index: swapon.c
===================================================================
RCS file: /home/ncvs/src/sbin/swapon/swapon.c,v
retrieving revision 1.13
diff -u -r1.13 swapon.c
--- swapon.c    15 Dec 2002 19:17:56 -0000      1.13
+++ swapon.c    18 Dec 2002 22:20:42 -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);
+static int swap_on_off(char *name, int ignoreebusy);
+static 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 } orig_prog, which_prog = SWAPCTL;
 
 int
 main(int argc, char **argv)
@@ -63,48 +71,105 @@
        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;
+       orig_prog = which_prog;
+       
        doall = 0;
-       while ((ch = getopt(argc, argv, "a")) != -1)
-               switch((char)ch) {
+       while ((ch = getopt(argc, argv, "AadlhksU")) != -1) {
+               switch(ch) {
+               case 'A':
+                       if (which_prog == SWAPCTL) {
+                               doall = 1;
+                               which_prog = SWAPON;
+                       } else {
+                               usage();
+                       }
+                       break;
                case 'a':
-                       doall = 1;
+                       if (which_prog == SWAPON || which_prog == SWAPOFF)
+                               doall = 1;
+                       else
+                               which_prog = SWAPON;
+                       break;
+               case 'd':
+                       if (which_prog == SWAPCTL)
+                               which_prog = SWAPOFF;
+                       else
+                               usage();
+                       break;
+               case 's':
+                       sflag = 1;
+                       break;
+               case 'l':
+                       lflag = 1;
+                       break;
+               case 'h':
+                       hflag = 'M';
+                       break;
+               case 'k':
+                       hflag = 'K';
+                       break;
+               case 'U':
+                       if (which_prog == SWAPCTL) {
+                               doall = 1;
+                               which_prog = SWAPOFF;
+                       } else {
+                               usage();
+                       }
                        break;
                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))
+       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();
+               for (; *argv; ++argv) {
+                       if (swap_on_off(*argv, 0)) {
                                stat = 1;
-                       else
+                       } else if (orig_prog == SWAPCTL) {
                                printf("%s: %sing %s as swap device\n",
-                                   pname, do_swapoff ? "remov" : "add",
-                                   fsp->fs_spec);
+                                   getprogname(), which_prog == SWAPOFF ? "remov" : 
+"add",
+                                   *argv);
+                       }
                }
-       else if (!*argv)
-               usage(pname);
-       for (; *argv; ++argv)
-               stat |= swap_on_off(*argv, 0, do_swapoff);
+       } else {
+               if (lflag || sflag)
+                       swaplist(lflag, sflag, hflag);
+               else 
+                       usage();
+       }
        exit(stat);
 }
 
-int
-swap_on_off(char *name, int ignoreebusy, int do_swapoff)
+static int
+swap_on_off(char *name, int ignoreebusy)
 {
-       if ((do_swapoff ? swapoff(name) : swapon(name)) == -1) {
+       if ((which_prog == SWAPOFF ? swapoff(name) : swapon(name)) == -1) {
                switch (errno) {
                case EBUSY:
                        if (!ignoreebusy)
@@ -120,23 +185,84 @@
 }
 
 static void
-usage(const char *pname)
+usage(void)
 {
-       fprintf(stderr, "usage: %s [-a] [special_file ...]\n", pname);
+       fprintf(stderr, "usage: %s ", getprogname());
+       switch(orig_prog) {
+       case SWAPOFF:
+           fprintf(stderr, "[-a] [special_file ...]\n");
+           break;
+       case SWAPON:
+           fprintf(stderr, "[-a] [special_file ...]\n");
+           break;
+       case SWAPCTL:
+           fprintf(stderr, "[-lshAU] [-a special_file ...]\n");
+           break;
+       }
        exit(1);
 }
 
-static int
-is_swapoff(const char *s)
+/* Some code is based on the code in the swapmode_sysctl command in pstat */
+static 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, blocksize;
+       long long total = 0;
+       long long used = 0;
+       long long tmp_total;
+       long long tmp_used;
+       
+       pagesize = getpagesize();
+       switch(hflag) {
+       case 'K':
+           blocksize = 1024;
+           break;
+       case 'M':
+           blocksize = 1024 * 1024;
+           break;
+       default:
+           blocksize = 1024;   /* default block size */
+           hflag = 'K';
+           break;
+       }
+       
+       mibsize = sizeof mib / sizeof mib[0];
+       if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1)
+               err(1, "sysctlnametomib()");
+       
+       if (lflag)
+               printf("%-*s %11s %11s\n",
+                                 13, "Device:", 
+                                 "Total:", "Used:");
+       
+       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");
+               
+               tmp_total = (long long)xsw.xsw_nblks * pagesize / blocksize;
+               tmp_used  = (long long)xsw.xsw_used * pagesize / blocksize;
+               total += tmp_total;
+               used  += tmp_used;
+               if (lflag) {
+                       printf("/dev/%-8s %10lld%c %10lld%c\n", 
+                                         devname(xsw.xsw_dev, S_IFCHR),
+                                         tmp_total, hflag,
+                                         tmp_used, hflag);
+               }
+       }
+       if (errno != ENOENT)
+               err(1, "sysctl()");
+       
+       if (sflag)
+               printf("Total:        %10lld%c %10lld%c\n",
+                      total, hflag,
+                      used, hflag);
+       
 }
+

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to