18fae3551SRodney W. Grimes /* 28fae3551SRodney W. Grimes * Copyright (c) 1980, 1993 38fae3551SRodney W. Grimes * The Regents of the University of California. All rights reserved. 48fae3551SRodney W. Grimes * 58fae3551SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 68fae3551SRodney W. Grimes * modification, are permitted provided that the following conditions 78fae3551SRodney W. Grimes * are met: 88fae3551SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 98fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 108fae3551SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 118fae3551SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 128fae3551SRodney W. Grimes * documentation and/or other materials provided with the distribution. 138fae3551SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 148fae3551SRodney W. Grimes * may be used to endorse or promote products derived from this software 158fae3551SRodney W. Grimes * without specific prior written permission. 168fae3551SRodney W. Grimes * 178fae3551SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 188fae3551SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 198fae3551SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 208fae3551SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 218fae3551SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 228fae3551SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 238fae3551SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 248fae3551SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 258fae3551SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 268fae3551SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 278fae3551SRodney W. Grimes * SUCH DAMAGE. 288fae3551SRodney W. Grimes */ 298fae3551SRodney W. Grimes 30c69284caSDavid E. O'Brien #if 0 318fae3551SRodney W. Grimes #ifndef lint 32e798a806SPhilippe Charnier static const char copyright[] = 338fae3551SRodney W. Grimes "@(#) Copyright (c) 1980, 1993\n\ 348fae3551SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 358fae3551SRodney W. Grimes #endif /* not lint */ 368fae3551SRodney W. Grimes 378fae3551SRodney W. Grimes #ifndef lint 388fae3551SRodney W. Grimes static char sccsid[] = "@(#)swapon.c 8.1 (Berkeley) 6/5/93"; 398fae3551SRodney W. Grimes #endif /* not lint */ 40c69284caSDavid E. O'Brien #endif 41c69284caSDavid E. O'Brien #include <sys/cdefs.h> 42c69284caSDavid E. O'Brien __FBSDID("$FreeBSD$"); 438fae3551SRodney W. Grimes 44a420c811SMatthew Dillon #include <sys/stat.h> 45a420c811SMatthew Dillon #include <sys/param.h> 46a420c811SMatthew Dillon #include <sys/sysctl.h> 476004362eSDavid Schultz #include <vm/vm_param.h> 48a420c811SMatthew Dillon 496da7f378SPhilippe Charnier #include <err.h> 50e798a806SPhilippe Charnier #include <errno.h> 51e798a806SPhilippe Charnier #include <fstab.h> 52e798a806SPhilippe Charnier #include <stdio.h> 53cafefe8cSDima Dorfman #include <stdlib.h> 54e798a806SPhilippe Charnier #include <string.h> 55e798a806SPhilippe Charnier #include <unistd.h> 56a420c811SMatthew Dillon #include <fcntl.h> 572e64768cSPawel Jakub Dawidek #include <libutil.h> 588fae3551SRodney W. Grimes 59a420c811SMatthew Dillon static void usage(void); 60a420c811SMatthew Dillon static int swap_on_off(char *name, int ignoreebusy); 61a420c811SMatthew Dillon static void swaplist(int, int, int); 62a420c811SMatthew Dillon 63a420c811SMatthew Dillon enum { SWAPON, SWAPOFF, SWAPCTL } orig_prog, which_prog = SWAPCTL; 6438994f93SPoul-Henning Kamp 6538994f93SPoul-Henning Kamp int 6638994f93SPoul-Henning Kamp main(int argc, char **argv) 678fae3551SRodney W. Grimes { 683d438ad6SDavid E. O'Brien struct fstab *fsp; 69a420c811SMatthew Dillon char *ptr; 703d438ad6SDavid E. O'Brien int stat; 718fae3551SRodney W. Grimes int ch, doall; 7245a5dc93SMike Makonnen int sflag = 0, lflag = 0, hflag = 0, qflag = 0; 7392da00bbSMatthew Dillon 74a420c811SMatthew Dillon if ((ptr = strrchr(argv[0], '/')) == NULL) 75a420c811SMatthew Dillon ptr = argv[0]; 76a420c811SMatthew Dillon if (strstr(ptr, "swapon")) 77a420c811SMatthew Dillon which_prog = SWAPON; 78a420c811SMatthew Dillon else if (strstr(ptr, "swapoff")) 79a420c811SMatthew Dillon which_prog = SWAPOFF; 80a420c811SMatthew Dillon orig_prog = which_prog; 818fae3551SRodney W. Grimes 828fae3551SRodney W. Grimes doall = 0; 8345a5dc93SMike Makonnen while ((ch = getopt(argc, argv, "AadghklmqsU")) != -1) { 84a420c811SMatthew Dillon switch(ch) { 85a420c811SMatthew Dillon case 'A': 86a420c811SMatthew Dillon if (which_prog == SWAPCTL) { 878fae3551SRodney W. Grimes doall = 1; 88a420c811SMatthew Dillon which_prog = SWAPON; 89a420c811SMatthew Dillon } else { 90a420c811SMatthew Dillon usage(); 91a420c811SMatthew Dillon } 92a420c811SMatthew Dillon break; 93a420c811SMatthew Dillon case 'a': 94a420c811SMatthew Dillon if (which_prog == SWAPON || which_prog == SWAPOFF) 95a420c811SMatthew Dillon doall = 1; 96a420c811SMatthew Dillon else 97a420c811SMatthew Dillon which_prog = SWAPON; 98a420c811SMatthew Dillon break; 99a420c811SMatthew Dillon case 'd': 100a420c811SMatthew Dillon if (which_prog == SWAPCTL) 101a420c811SMatthew Dillon which_prog = SWAPOFF; 102a420c811SMatthew Dillon else 103a420c811SMatthew Dillon usage(); 104a420c811SMatthew Dillon break; 1052e64768cSPawel Jakub Dawidek case 'g': 1062e64768cSPawel Jakub Dawidek hflag = 'G'; 1072e64768cSPawel Jakub Dawidek break; 1082e64768cSPawel Jakub Dawidek case 'h': 1092e64768cSPawel Jakub Dawidek hflag = 'H'; 1102e64768cSPawel Jakub Dawidek break; 1112e64768cSPawel Jakub Dawidek case 'k': 1122e64768cSPawel Jakub Dawidek hflag = 'K'; 113a420c811SMatthew Dillon break; 114a420c811SMatthew Dillon case 'l': 115a420c811SMatthew Dillon lflag = 1; 116a420c811SMatthew Dillon break; 1172e64768cSPawel Jakub Dawidek case 'm': 118a420c811SMatthew Dillon hflag = 'M'; 119a420c811SMatthew Dillon break; 12045a5dc93SMike Makonnen case 'q': 12145a5dc93SMike Makonnen if (which_prog == SWAPON || which_prog == SWAPOFF) 12245a5dc93SMike Makonnen qflag = 1; 12345a5dc93SMike Makonnen break; 1242e64768cSPawel Jakub Dawidek case 's': 1252e64768cSPawel Jakub Dawidek sflag = 1; 126a420c811SMatthew Dillon break; 127a420c811SMatthew Dillon case 'U': 128a420c811SMatthew Dillon if (which_prog == SWAPCTL) { 129a420c811SMatthew Dillon doall = 1; 130a420c811SMatthew Dillon which_prog = SWAPOFF; 131a420c811SMatthew Dillon } else { 132a420c811SMatthew Dillon usage(); 133a420c811SMatthew Dillon } 1348fae3551SRodney W. Grimes break; 1358fae3551SRodney W. Grimes case '?': 1368fae3551SRodney W. Grimes default: 137a420c811SMatthew Dillon usage(); 138a420c811SMatthew Dillon } 1398fae3551SRodney W. Grimes } 1408fae3551SRodney W. Grimes argv += optind; 1418fae3551SRodney W. Grimes 1428fae3551SRodney W. Grimes stat = 0; 143a420c811SMatthew Dillon if (which_prog == SWAPON || which_prog == SWAPOFF) { 144a420c811SMatthew Dillon if (doall) { 14538994f93SPoul-Henning Kamp while ((fsp = getfsent()) != NULL) { 1468fae3551SRodney W. Grimes if (strcmp(fsp->fs_type, FSTAB_SW)) 1478fae3551SRodney W. Grimes continue; 1487fc4a454SJordan K. Hubbard if (strstr(fsp->fs_mntops, "noauto")) 1497fc4a454SJordan K. Hubbard continue; 1504937798dSDavid Schultz if (swap_on_off(fsp->fs_spec, 1)) { 1518fae3551SRodney W. Grimes stat = 1; 152a420c811SMatthew Dillon } else { 15345a5dc93SMike Makonnen if (!qflag) { 15492da00bbSMatthew Dillon printf("%s: %sing %s as swap device\n", 15545a5dc93SMike Makonnen getprogname(), 15645a5dc93SMike Makonnen which_prog == SWAPOFF ? "remov" : "add", 1578fae3551SRodney W. Grimes fsp->fs_spec); 1588fae3551SRodney W. Grimes } 159a420c811SMatthew Dillon } 160a420c811SMatthew Dillon } 16145a5dc93SMike Makonnen } 1628fae3551SRodney W. Grimes else if (!*argv) 163a420c811SMatthew Dillon usage(); 164a420c811SMatthew Dillon for (; *argv; ++argv) { 165a420c811SMatthew Dillon if (swap_on_off(*argv, 0)) { 166a420c811SMatthew Dillon stat = 1; 167a420c811SMatthew Dillon } else if (orig_prog == SWAPCTL) { 168a420c811SMatthew Dillon printf("%s: %sing %s as swap device\n", 169a420c811SMatthew Dillon getprogname(), which_prog == SWAPOFF ? "remov" : "add", 170a420c811SMatthew Dillon *argv); 171a420c811SMatthew Dillon } 172a420c811SMatthew Dillon } 173a420c811SMatthew Dillon } else { 174a420c811SMatthew Dillon if (lflag || sflag) 175a420c811SMatthew Dillon swaplist(lflag, sflag, hflag); 176a420c811SMatthew Dillon else 177a420c811SMatthew Dillon usage(); 178a420c811SMatthew Dillon } 1798fae3551SRodney W. Grimes exit(stat); 1808fae3551SRodney W. Grimes } 1818fae3551SRodney W. Grimes 182a420c811SMatthew Dillon static int 1834937798dSDavid Schultz swap_on_off(char *name, int doingall) 1848fae3551SRodney W. Grimes { 185a420c811SMatthew Dillon if ((which_prog == SWAPOFF ? swapoff(name) : swapon(name)) == -1) { 1868fae3551SRodney W. Grimes switch (errno) { 1878fae3551SRodney W. Grimes case EBUSY: 1884937798dSDavid Schultz if (!doingall) 1896da7f378SPhilippe Charnier warnx("%s: device already in use", name); 1908fae3551SRodney W. Grimes break; 1914937798dSDavid Schultz case EINVAL: 1924937798dSDavid Schultz if (which_prog == SWAPON) 1934937798dSDavid Schultz warnx("%s: NSWAPDEV limit reached", name); 1944937798dSDavid Schultz else if (!doingall) 1954937798dSDavid Schultz warn("%s", name); 1964937798dSDavid Schultz break; 1978fae3551SRodney W. Grimes default: 1986da7f378SPhilippe Charnier warn("%s", name); 1998fae3551SRodney W. Grimes break; 2008fae3551SRodney W. Grimes } 2018fae3551SRodney W. Grimes return(1); 2028fae3551SRodney W. Grimes } 2038fae3551SRodney W. Grimes return(0); 2048fae3551SRodney W. Grimes } 2058fae3551SRodney W. Grimes 2066da7f378SPhilippe Charnier static void 207a420c811SMatthew Dillon usage(void) 2088fae3551SRodney W. Grimes { 209a420c811SMatthew Dillon fprintf(stderr, "usage: %s ", getprogname()); 210a420c811SMatthew Dillon switch(orig_prog) { 211a420c811SMatthew Dillon case SWAPON: 2128d646af5SRuslan Ermilov case SWAPOFF: 21345a5dc93SMike Makonnen fprintf(stderr, "-aq | file ...\n"); 214a420c811SMatthew Dillon break; 215a420c811SMatthew Dillon case SWAPCTL: 2162e64768cSPawel Jakub Dawidek fprintf(stderr, "[-AghklmsU] [-a file ... | -d file ...]\n"); 217a420c811SMatthew Dillon break; 218a420c811SMatthew Dillon } 2198fae3551SRodney W. Grimes exit(1); 2208fae3551SRodney W. Grimes } 22192da00bbSMatthew Dillon 222a420c811SMatthew Dillon static void 2232e64768cSPawel Jakub Dawidek sizetobuf(char *buf, size_t bufsize, int hflag, long long val, int hlen, 2242e64768cSPawel Jakub Dawidek long blocksize) 2252e64768cSPawel Jakub Dawidek { 2262e64768cSPawel Jakub Dawidek 2272e64768cSPawel Jakub Dawidek if (hflag == 'H') { 2282e64768cSPawel Jakub Dawidek char tmp[16]; 2292e64768cSPawel Jakub Dawidek 2302e64768cSPawel Jakub Dawidek humanize_number(tmp, 5, (int64_t)val, "", HN_AUTOSCALE, 2312e64768cSPawel Jakub Dawidek HN_B | HN_NOSPACE | HN_DECIMAL); 2322e64768cSPawel Jakub Dawidek snprintf(buf, bufsize, "%*s", hlen, tmp); 2332e64768cSPawel Jakub Dawidek } else { 2342e64768cSPawel Jakub Dawidek snprintf(buf, bufsize, "%*lld", hlen, val / blocksize); 2352e64768cSPawel Jakub Dawidek } 2362e64768cSPawel Jakub Dawidek } 2372e64768cSPawel Jakub Dawidek 2382e64768cSPawel Jakub Dawidek static void 239a420c811SMatthew Dillon swaplist(int lflag, int sflag, int hflag) 24092da00bbSMatthew Dillon { 241a420c811SMatthew Dillon size_t mibsize, size; 242a420c811SMatthew Dillon struct xswdev xsw; 24369095b02SMike Barcroft int hlen, mib[16], n, pagesize; 244a420c811SMatthew Dillon long blocksize; 245a420c811SMatthew Dillon long long total = 0; 246a420c811SMatthew Dillon long long used = 0; 247a420c811SMatthew Dillon long long tmp_total; 248a420c811SMatthew Dillon long long tmp_used; 2492e64768cSPawel Jakub Dawidek char buf[32]; 25092da00bbSMatthew Dillon 251a420c811SMatthew Dillon pagesize = getpagesize(); 252a420c811SMatthew Dillon switch(hflag) { 2532e64768cSPawel Jakub Dawidek case 'G': 2542e64768cSPawel Jakub Dawidek blocksize = 1024 * 1024 * 1024; 2552e64768cSPawel Jakub Dawidek strlcpy(buf, "1GB-blocks", sizeof(buf)); 2562e64768cSPawel Jakub Dawidek hlen = 10; 2572e64768cSPawel Jakub Dawidek break; 2582e64768cSPawel Jakub Dawidek case 'H': 2592e64768cSPawel Jakub Dawidek blocksize = -1; 2602e64768cSPawel Jakub Dawidek strlcpy(buf, "Bytes", sizeof(buf)); 2612e64768cSPawel Jakub Dawidek hlen = 10; 2622e64768cSPawel Jakub Dawidek break; 263a420c811SMatthew Dillon case 'K': 264a420c811SMatthew Dillon blocksize = 1024; 2652e64768cSPawel Jakub Dawidek strlcpy(buf, "1kB-blocks", sizeof(buf)); 266a420c811SMatthew Dillon hlen = 10; 267a420c811SMatthew Dillon break; 268a420c811SMatthew Dillon case 'M': 269a420c811SMatthew Dillon blocksize = 1024 * 1024; 2702e64768cSPawel Jakub Dawidek strlcpy(buf, "1MB-blocks", sizeof(buf)); 271a420c811SMatthew Dillon hlen = 10; 272a420c811SMatthew Dillon break; 273a420c811SMatthew Dillon default: 2749255f327SMike Barcroft getbsize(&hlen, &blocksize); 2752e64768cSPawel Jakub Dawidek snprintf(buf, sizeof(buf), "%ld-blocks", blocksize); 276a420c811SMatthew Dillon break; 27792da00bbSMatthew Dillon } 278a420c811SMatthew Dillon 279a420c811SMatthew Dillon mibsize = sizeof mib / sizeof mib[0]; 280a420c811SMatthew Dillon if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1) 281a420c811SMatthew Dillon err(1, "sysctlnametomib()"); 282a420c811SMatthew Dillon 283a420c811SMatthew Dillon if (lflag) { 284a420c811SMatthew Dillon printf("%-13s %*s %*s\n", 285a420c811SMatthew Dillon "Device:", 286a420c811SMatthew Dillon hlen, buf, 287a420c811SMatthew Dillon hlen, "Used:"); 288a420c811SMatthew Dillon } 289a420c811SMatthew Dillon 290a420c811SMatthew Dillon for (n = 0; ; ++n) { 291a420c811SMatthew Dillon mib[mibsize] = n; 292a420c811SMatthew Dillon size = sizeof xsw; 29316fc3635SMark Murray if (sysctl(mib, mibsize + 1, &xsw, &size, NULL, 0) == -1) 294a420c811SMatthew Dillon break; 295a420c811SMatthew Dillon if (xsw.xsw_version != XSWDEV_VERSION) 296a420c811SMatthew Dillon errx(1, "xswdev version mismatch"); 297a420c811SMatthew Dillon 2982e64768cSPawel Jakub Dawidek tmp_total = (long long)xsw.xsw_nblks * pagesize; 2992e64768cSPawel Jakub Dawidek tmp_used = (long long)xsw.xsw_used * pagesize; 300a420c811SMatthew Dillon total += tmp_total; 301a420c811SMatthew Dillon used += tmp_used; 302a420c811SMatthew Dillon if (lflag) { 3032e64768cSPawel Jakub Dawidek sizetobuf(buf, sizeof(buf), hflag, tmp_total, hlen, 3042e64768cSPawel Jakub Dawidek blocksize); 3052e64768cSPawel Jakub Dawidek printf("/dev/%-8s %s ", devname(xsw.xsw_dev, S_IFCHR), 3062e64768cSPawel Jakub Dawidek buf); 3072e64768cSPawel Jakub Dawidek sizetobuf(buf, sizeof(buf), hflag, tmp_used, hlen, 3082e64768cSPawel Jakub Dawidek blocksize); 3092e64768cSPawel Jakub Dawidek printf("%s\n", buf); 310a420c811SMatthew Dillon } 311a420c811SMatthew Dillon } 312a420c811SMatthew Dillon if (errno != ENOENT) 313a420c811SMatthew Dillon err(1, "sysctl()"); 314a420c811SMatthew Dillon 315a420c811SMatthew Dillon if (sflag) { 3162e64768cSPawel Jakub Dawidek sizetobuf(buf, sizeof(buf), hflag, total, hlen, blocksize); 3172e64768cSPawel Jakub Dawidek printf("Total: %s ", buf); 3182e64768cSPawel Jakub Dawidek sizetobuf(buf, sizeof(buf), hflag, used, hlen, blocksize); 3192e64768cSPawel Jakub Dawidek printf("%s\n", buf); 320a420c811SMatthew Dillon } 321a420c811SMatthew Dillon } 322a420c811SMatthew Dillon 323