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>