Index: head/sbin/swapon/Makefile =================================================================== --- head/sbin/swapon/Makefile (revision 179153) +++ head/sbin/swapon/Makefile (revision 179154) @@ -1,11 +1,14 @@ # @(#)Makefile 8.1 (Berkeley) 6/5/93 # $FreeBSD$ 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 +DPADD= ${LIBUTIL} +LDADD= -lutil + .include Index: head/sbin/swapon/swapon.8 =================================================================== --- head/sbin/swapon/swapon.8 (revision 179153) +++ head/sbin/swapon/swapon.8 (revision 179154) @@ -1,177 +1,181 @@ .\" Copyright (c) 1980, 1991, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)swapon.8 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd December 28, 2002 +.Dd April 29, 2008 .Dt SWAPON 8 .Os .Sh NAME .Nm swapon , swapoff , swapctl .Nd "specify devices for paging and swapping" .Sh SYNOPSIS .Nm swapon Fl a | Ar .Nm swapoff Fl a | Ar .Nm swapctl -.Op Fl AhklsU +.Op Fl AghklmsU .Oo .Fl a Ar | .Fl d Ar .Oc .Sh DESCRIPTION The .Nm swapon , swapoff and .Nm swapctl utilities 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 use a fixed interleave; the maximum number of devices is specified by the kernel configuration option .Dv NSWAPDEV , which is typically set to 4. There is no priority mechanism. .Pp The .Nm swapon 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 .Dq noauto option is also set. .Pp The .Nm swapoff 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 .Dq noauto option is also set. Note that .Nm swapoff will fail and refuse to remove a swap device if there is insufficient VM (memory + remaining swap devices) to run the system. The .Nm swapoff utility must move swapped 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 The .Nm swapctl utility exists primarily for those familiar with other .Bx Ns s and may be used to add, remove, or list swap devices. Note that the .Fl a option is used differently 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 U options to .Nm swapctl operate on all swap entries in .Pa /etc/fstab which do not have their .Dq noauto option set. .Pp Swap information can be generated using the .Xr swapinfo 8 utility, .Nm pstat .Fl s , or .Nm swapctl .Fl l . The .Nm swapctl utility has the following options for listing swap: .Bl -tag -width indent .It Fl h -Output values in megabytes. +Output values in human-readable form. +.It Fl g +Output values in gigabytes. .It Fl k Output values in kilobytes. +.It Fl m +Output values in megabytes. .It Fl l List the devices making up system swap. .It Fl s Print a summary line for system swap. .Pp The .Ev BLOCKSIZE environment variable is used if not specifically overridden. 512 byte blocks are used by default. .El .Sh FILES .Bl -tag -width ".Pa /dev/{ad,da}?s?b" -compact .It Pa /dev/{ad,da}?s?b standard paging devices .It Pa /dev/md? memory disk devices .It Pa /etc/fstab .Tn ASCII file system description table .El .Sh DIAGNOSTICS These utilities may fail for the reasons described in .Xr swapon 2 . .Sh SEE ALSO .Xr swapon 2 , .Xr fstab 5 , .Xr init 8 , .Xr mdconfig 8 , .Xr pstat 8 , .Xr rc 8 .Sh HISTORY The .Nm swapon utility appeared in .Bx 4.0 . The .Nm swapoff and .Nm swapctl utilities appeared in .Fx 5.1 . Index: head/sbin/swapon/swapon.c =================================================================== --- head/sbin/swapon/swapon.c (revision 179153) +++ head/sbin/swapon/swapon.c (revision 179154) @@ -1,276 +1,315 @@ /* * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if 0 #ifndef lint static const char copyright[] = "@(#) Copyright (c) 1980, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint static char sccsid[] = "@(#)swapon.c 8.1 (Berkeley) 6/5/93"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include +#include static void usage(void); static int swap_on_off(char *name, int ignoreebusy); static void swaplist(int, int, int); enum { SWAPON, SWAPOFF, SWAPCTL } orig_prog, which_prog = SWAPCTL; int main(int argc, char **argv) { struct fstab *fsp; char *ptr; int stat; int ch, doall; int sflag = 0, lflag = 0, hflag = 0; if ((ptr = strrchr(argv[0], '/')) == NULL) ptr = argv[0]; if (strstr(ptr, "swapon")) which_prog = SWAPON; else if (strstr(ptr, "swapoff")) which_prog = SWAPOFF; orig_prog = which_prog; doall = 0; - while ((ch = getopt(argc, argv, "AadlhksU")) != -1) { + while ((ch = getopt(argc, argv, "AadghklmsU")) != -1) { switch(ch) { case 'A': if (which_prog == SWAPCTL) { doall = 1; which_prog = SWAPON; } else { usage(); } break; case 'a': 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; + case 'g': + hflag = 'G'; break; + case 'h': + hflag = 'H'; + break; + case 'k': + hflag = 'K'; + break; case 'l': lflag = 1; break; - case 'h': + case 'm': hflag = 'M'; break; - case 'k': - hflag = 'K'; + case 's': + sflag = 1; break; case 'U': if (which_prog == SWAPCTL) { doall = 1; which_prog = SWAPOFF; } else { usage(); } break; case '?': default: usage(); } } argv += optind; stat = 0; 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, 1)) { 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 if (orig_prog == SWAPCTL) { printf("%s: %sing %s as swap device\n", getprogname(), which_prog == SWAPOFF ? "remov" : "add", *argv); } } } else { if (lflag || sflag) swaplist(lflag, sflag, hflag); else usage(); } exit(stat); } static int swap_on_off(char *name, int doingall) { if ((which_prog == SWAPOFF ? swapoff(name) : swapon(name)) == -1) { switch (errno) { case EBUSY: if (!doingall) warnx("%s: device already in use", name); break; case EINVAL: if (which_prog == SWAPON) warnx("%s: NSWAPDEV limit reached", name); else if (!doingall) warn("%s", name); break; default: warn("%s", name); break; } return(1); } return(0); } static void usage(void) { fprintf(stderr, "usage: %s ", getprogname()); switch(orig_prog) { case SWAPON: case SWAPOFF: fprintf(stderr, "-a | file ...\n"); break; case SWAPCTL: - fprintf(stderr, "[-AhklsU] [-a file ... | -d file ...]\n"); + fprintf(stderr, "[-AghklmsU] [-a file ... | -d file ...]\n"); break; } exit(1); } static void +sizetobuf(char *buf, size_t bufsize, int hflag, long long val, int hlen, + long blocksize) +{ + + if (hflag == 'H') { + char tmp[16]; + + humanize_number(tmp, 5, (int64_t)val, "", HN_AUTOSCALE, + HN_B | HN_NOSPACE | HN_DECIMAL); + snprintf(buf, bufsize, "%*s", hlen, tmp); + } else { + snprintf(buf, bufsize, "%*lld", hlen, val / blocksize); + } +} + +static void swaplist(int lflag, int sflag, int hflag) { size_t mibsize, size; struct xswdev xsw; int hlen, mib[16], n, pagesize; long blocksize; long long total = 0; long long used = 0; long long tmp_total; long long tmp_used; + char buf[32]; pagesize = getpagesize(); switch(hflag) { + case 'G': + blocksize = 1024 * 1024 * 1024; + strlcpy(buf, "1GB-blocks", sizeof(buf)); + hlen = 10; + break; + case 'H': + blocksize = -1; + strlcpy(buf, "Bytes", sizeof(buf)); + hlen = 10; + break; case 'K': blocksize = 1024; + strlcpy(buf, "1kB-blocks", sizeof(buf)); hlen = 10; break; case 'M': blocksize = 1024 * 1024; + strlcpy(buf, "1MB-blocks", sizeof(buf)); hlen = 10; break; default: getbsize(&hlen, &blocksize); + snprintf(buf, sizeof(buf), "%ld-blocks", 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, 0) == -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; + tmp_total = (long long)xsw.xsw_nblks * pagesize; + tmp_used = (long long)xsw.xsw_used * pagesize; 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); + sizetobuf(buf, sizeof(buf), hflag, tmp_total, hlen, + blocksize); + printf("/dev/%-8s %s ", devname(xsw.xsw_dev, S_IFCHR), + buf); + sizetobuf(buf, sizeof(buf), hflag, tmp_used, hlen, + blocksize); + printf("%s\n", buf); } } if (errno != ENOENT) err(1, "sysctl()"); if (sflag) { - printf("Total: %*lld %*lld\n", - hlen, total, - hlen, used); + sizetobuf(buf, sizeof(buf), hflag, total, hlen, blocksize); + printf("Total: %s ", buf); + sizetobuf(buf, sizeof(buf), hflag, used, hlen, blocksize); + printf("%s\n", buf); } }