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" : ""); + } +
msg49011/pgp00000.pgp
Description: PGP signature