Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Dec 2002 14:22:54 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        Eirik Nygaard <eirikn@bluezone.no>
Cc:        current@FreeBSD.ORG
Subject:   Re: swapoff code comitted.
Message-ID:  <200212182222.gBIMMsnw094344@apollo.backplane.com>
References:  <200212151946.gBFJktmo090730@apollo.backplane.com> <20021215223540.GA601@unixpages.org> <200212152247.gBFMlp4d098705@apollo.backplane.com> <20021218182724.GB853@eirikn.net> <200212181918.gBIJIOIV093115@apollo.backplane.com> <20021218203854.GC853@eirikn.net>

next in thread | previous in thread | raw e-mail | index | archive | help
:Added the enum instead of is_swap* commands and changed from kvm to
:sysctl to get the swap information.
:
:Eirik Nygaard <eirikn@bluezone.no>
: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 majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212182222.gBIMMsnw094344>