: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