Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Dec 2002 15:00:35 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        Matthew Dillon <dillon@apollo.backplane.com>
Cc:        Eirik Nygaard <eirikn@bluezone.no>, current@FreeBSD.ORG
Subject:   patch #3 Re: swapoff code comitted.
Message-ID:  <200212182300.gBIN0ZW7094554@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> <200212182222.gBIMMsnw094344@apollo.backplane.com>

next in thread | previous in thread | raw e-mail | index | archive | help
    Here's another update.  I cleaned things up even more, add BLOCKSIZE
    support, and updated the manual page.  It looks quite nice now.

						-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.8
===================================================================
RCS file: /home/ncvs/src/sbin/swapon/swapon.8,v
retrieving revision 1.21
diff -u -r1.21 swapon.8
--- swapon.8	15 Dec 2002 19:17:56 -0000	1.21
+++ swapon.8	18 Dec 2002 22:46:01 -0000
@@ -43,45 +43,101 @@
 .Fl a
 .Nm swap[on|off]
 .Ar special_file ...
+.Nm swapctl
+.Fl lshk
+.Nm swapctl
+.Fl AU
+.Nm swapctl
+.Fl a
+.Ar special_file ...
+.Nm swapctl
+.Fl d
+.Ar special_file ...
 .Sh DESCRIPTION
 The
+.Nm swap[on,off,ctl]
+utilties are used to control swap devices in the system.  At boot time all
+swap entries in 
+.Pa /etc/fstab
+are added automatically when the system goes multi-user.
+Swap devices are interleaved and kernels are typically configured
+to handle a maximum of 4 swap devices.  There is no priority mechanism.
+.Pp
+The
 .Nm swapon
-utility is used to specify additional devices on which paging and swapping
-are to take place.
-The system begins by swapping and paging on only a single device
-so that only one disk is required at bootstrap time.
-Calls to
-.Nm swapon
-normally occur in the system multi-user initialization file
-.Pa /etc/rc
-making all swap devices available, so that the paging and swapping
-activity is interleaved across several devices.
+utility adds the specified swap devices to the system.  If the
+.Fl a
+option is used, all swap devices in
+.Pa /etc/fstab
+will be added, unless their ``noauto'' option is also set.
 .Pp
 The
 .Nm swapoff
-utility disables paging and swapping on a device.
-Calls to
+utility removes the specified swap devices from the system.  If the
+.Fl a
+option is used, all swap devices in
+.Pa /etc/fstab
+will be removed, unless their ``noauto'' option is also set.
+Note that
 .Nm swapoff
-succeed only if disabling the device would leave enough
-remaining virtual memory to accomodate all running programs.
+will fail and refuse to remove a swap device if there is insufficient
+VM (memory + remaining swap devices) to run the system.
+.Nm Swapoff
+must move sawpped pages out of the device being removed which could
+lead to high system loads for a period of time, depending on how
+much data has been swapped out to that device.
 .Pp
-Normally, the first form is used:
-.Bl -tag -width indent
-.It Fl a
-All devices marked as ``sw''
-swap devices in
+The
+.Nm swapctl
+utility exists primarily for those familiar with other BSDs and may be
+used to add, remove, or list swap.  Note that the
+.Fl a
+option is used diferently in
+.Nm swapctl
+and indicates that a specific list of devices should be added.
+The 
+.Fl d
+option indicates that a specific list should be removed.  The
+.Fl A
+and 
+.Fl D
+options to
+.Nm swapctl
+operate on all swap entries in
 .Pa /etc/fstab
-are added to or removed from the pool of available swap
-unless their ``noauto'' option is also set.
-.El
+which do not have their ``noauto'' option set.
+.Pp
+Swap information can be generated using the
+.Nm swapinfo
+program,
+.Nm pstat
+.Fl s ,
+or
+.Nm swapctl
+.Fl lshk .
+The
+.Nm swapctl
+utility has the following options for listing swap:
+.Bl -tag -width indent
+.It Fl l
+List the devices making up system swap.
+.It Fl s
+Print a summary line for system swap.
+.It Fl h
+Output values in megabytes.
+.It Fl k
+Output values in kilobytes.
 .Pp
-The second form is used to configure or disable individual devices.
+The BLOCKSIZE environment variable is used if not specifically
+overridden.  512 byte blocks are used by default.
+.El
 .Sh SEE ALSO
 .Xr swapon 2 ,
 .Xr fstab 5 ,
 .Xr init 8 ,
 .Xr mdconfig 8 ,
 .Xr pstat 8 ,
+.Xr swapinfo 8 ,
 .Xr rc 8
 .Sh FILES
 .Bl -tag -width "/dev/{ad,da}?s?b" -compact
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:53:52 -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,90 @@
 }
 
 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)
+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;
+	size_t hlen;
+	long 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;
+	    hlen = 10;
+	    break;
+	case 'M':
+	    blocksize = 1024 * 1024;
+	    hlen = 10;
+	    break;
+	default:
+	    getbsize(&hlen, &blocksize);
+	    break;
+	}
+	
+	mibsize = sizeof mib / sizeof mib[0];
+	if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1)
+		err(1, "sysctlnametomib()");
+	
+	if (lflag) {
+		char buf[32];
+		snprintf(buf, sizeof(buf), "%ld-blocks", blocksize);
+		printf("%-13s %*s %*s\n",
+		    "Device:", 
+		    hlen, buf,
+		    hlen, "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 %*lld %*lld\n", 
+			    devname(xsw.xsw_dev, S_IFCHR),
+			    hlen, tmp_total,
+			    hlen, tmp_used);
+		}
+	}
+	if (errno != ENOENT)
+		err(1, "sysctl()");
+	
+	if (sflag) {
+		printf("Total:        %*lld %*lld\n",
+		       hlen, total,
+		       hlen, used);
+	}
 }
+

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?200212182300.gBIN0ZW7094554>