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/param.h> 45268a55bcSHiroki Sato #include <sys/types.h> 46268a55bcSHiroki Sato #include <sys/mdioctl.h> 47268a55bcSHiroki Sato #include <sys/stat.h> 48a420c811SMatthew Dillon #include <sys/sysctl.h> 49268a55bcSHiroki Sato #include <sys/wait.h> 506004362eSDavid Schultz #include <vm/vm_param.h> 51a420c811SMatthew Dillon 526da7f378SPhilippe Charnier #include <err.h> 53e798a806SPhilippe Charnier #include <errno.h> 54268a55bcSHiroki Sato #include <fcntl.h> 55268a55bcSHiroki Sato #include <fnmatch.h> 56e798a806SPhilippe Charnier #include <fstab.h> 57268a55bcSHiroki Sato #include <libgen.h> 58268a55bcSHiroki Sato #include <libutil.h> 59268a55bcSHiroki Sato #include <limits.h> 60268a55bcSHiroki Sato #include <paths.h> 61268a55bcSHiroki Sato #include <stdarg.h> 62e798a806SPhilippe Charnier #include <stdio.h> 63cafefe8cSDima Dorfman #include <stdlib.h> 64e798a806SPhilippe Charnier #include <string.h> 65e798a806SPhilippe Charnier #include <unistd.h> 668fae3551SRodney W. Grimes 67a420c811SMatthew Dillon static void usage(void); 688f8de1e1SXin LI static const char *swap_on_off(const char *, int, char *); 698f8de1e1SXin LI static const char *swap_on_off_gbde(const char *, int); 708f8de1e1SXin LI static const char *swap_on_off_geli(const char *, char *, int); 718f8de1e1SXin LI static const char *swap_on_off_md(const char *, char *, int); 728f8de1e1SXin LI static const char *swap_on_off_sfile(const char *, int); 73a420c811SMatthew Dillon static void swaplist(int, int, int); 74268a55bcSHiroki Sato static int run_cmd(int *, const char *, ...) __printflike(2, 3); 75a420c811SMatthew Dillon 761efe3c6bSEd Schouten static enum { SWAPON, SWAPOFF, SWAPCTL } orig_prog, which_prog = SWAPCTL; 7738994f93SPoul-Henning Kamp 78268a55bcSHiroki Sato static int qflag; 79268a55bcSHiroki Sato 8038994f93SPoul-Henning Kamp int 8138994f93SPoul-Henning Kamp main(int argc, char **argv) 828fae3551SRodney W. Grimes { 833d438ad6SDavid E. O'Brien struct fstab *fsp; 84268a55bcSHiroki Sato const char *swfile; 85a420c811SMatthew Dillon char *ptr; 86ce458f42SEd Schouten int ret; 878fae3551SRodney W. Grimes int ch, doall; 88268a55bcSHiroki Sato int sflag = 0, lflag = 0, late = 0, hflag = 0; 89633d2bc5SMaxim Sobolev const char *etc_fstab; 9092da00bbSMatthew Dillon 91a420c811SMatthew Dillon if ((ptr = strrchr(argv[0], '/')) == NULL) 92a420c811SMatthew Dillon ptr = argv[0]; 93a420c811SMatthew Dillon if (strstr(ptr, "swapon")) 94a420c811SMatthew Dillon which_prog = SWAPON; 95a420c811SMatthew Dillon else if (strstr(ptr, "swapoff")) 96a420c811SMatthew Dillon which_prog = SWAPOFF; 97a420c811SMatthew Dillon orig_prog = which_prog; 988fae3551SRodney W. Grimes 998fae3551SRodney W. Grimes doall = 0; 100633d2bc5SMaxim Sobolev etc_fstab = NULL; 101268a55bcSHiroki Sato while ((ch = getopt(argc, argv, "AadghklLmqsUF:")) != -1) { 102a420c811SMatthew Dillon switch(ch) { 103a420c811SMatthew Dillon case 'A': 104a420c811SMatthew Dillon if (which_prog == SWAPCTL) { 1058fae3551SRodney W. Grimes doall = 1; 106a420c811SMatthew Dillon which_prog = SWAPON; 107a420c811SMatthew Dillon } else { 108a420c811SMatthew Dillon usage(); 109a420c811SMatthew Dillon } 110a420c811SMatthew Dillon break; 111a420c811SMatthew Dillon case 'a': 112a420c811SMatthew Dillon if (which_prog == SWAPON || which_prog == SWAPOFF) 113a420c811SMatthew Dillon doall = 1; 114a420c811SMatthew Dillon else 115a420c811SMatthew Dillon which_prog = SWAPON; 116a420c811SMatthew Dillon break; 117a420c811SMatthew Dillon case 'd': 118a420c811SMatthew Dillon if (which_prog == SWAPCTL) 119a420c811SMatthew Dillon which_prog = SWAPOFF; 120a420c811SMatthew Dillon else 121a420c811SMatthew Dillon usage(); 122a420c811SMatthew Dillon break; 1232e64768cSPawel Jakub Dawidek case 'g': 1242e64768cSPawel Jakub Dawidek hflag = 'G'; 1252e64768cSPawel Jakub Dawidek break; 1262e64768cSPawel Jakub Dawidek case 'h': 1272e64768cSPawel Jakub Dawidek hflag = 'H'; 1282e64768cSPawel Jakub Dawidek break; 1292e64768cSPawel Jakub Dawidek case 'k': 1302e64768cSPawel Jakub Dawidek hflag = 'K'; 131a420c811SMatthew Dillon break; 132a420c811SMatthew Dillon case 'l': 133a420c811SMatthew Dillon lflag = 1; 134a420c811SMatthew Dillon break; 135268a55bcSHiroki Sato case 'L': 136268a55bcSHiroki Sato late = 1; 137268a55bcSHiroki Sato break; 1382e64768cSPawel Jakub Dawidek case 'm': 139a420c811SMatthew Dillon hflag = 'M'; 140a420c811SMatthew Dillon break; 14145a5dc93SMike Makonnen case 'q': 14245a5dc93SMike Makonnen if (which_prog == SWAPON || which_prog == SWAPOFF) 14345a5dc93SMike Makonnen qflag = 1; 14445a5dc93SMike Makonnen break; 1452e64768cSPawel Jakub Dawidek case 's': 1462e64768cSPawel Jakub Dawidek sflag = 1; 147a420c811SMatthew Dillon break; 148a420c811SMatthew Dillon case 'U': 149a420c811SMatthew Dillon if (which_prog == SWAPCTL) { 150a420c811SMatthew Dillon doall = 1; 151a420c811SMatthew Dillon which_prog = SWAPOFF; 152a420c811SMatthew Dillon } else { 153a420c811SMatthew Dillon usage(); 154a420c811SMatthew Dillon } 1558fae3551SRodney W. Grimes break; 156633d2bc5SMaxim Sobolev case 'F': 157633d2bc5SMaxim Sobolev etc_fstab = optarg; 158633d2bc5SMaxim Sobolev break; 1598fae3551SRodney W. Grimes case '?': 1608fae3551SRodney W. Grimes default: 161a420c811SMatthew Dillon usage(); 162a420c811SMatthew Dillon } 1638fae3551SRodney W. Grimes } 1648fae3551SRodney W. Grimes argv += optind; 1658fae3551SRodney W. Grimes 166ce458f42SEd Schouten ret = 0; 167268a55bcSHiroki Sato swfile = NULL; 168633d2bc5SMaxim Sobolev if (etc_fstab != NULL) 169633d2bc5SMaxim Sobolev setfstab(etc_fstab); 170a420c811SMatthew Dillon if (which_prog == SWAPON || which_prog == SWAPOFF) { 171a420c811SMatthew Dillon if (doall) { 17238994f93SPoul-Henning Kamp while ((fsp = getfsent()) != NULL) { 1738fae3551SRodney W. Grimes if (strcmp(fsp->fs_type, FSTAB_SW)) 1748fae3551SRodney W. Grimes continue; 1757fc4a454SJordan K. Hubbard if (strstr(fsp->fs_mntops, "noauto")) 1767fc4a454SJordan K. Hubbard continue; 177268a55bcSHiroki Sato if (which_prog != SWAPOFF && 178268a55bcSHiroki Sato strstr(fsp->fs_mntops, "late") && 179268a55bcSHiroki Sato !late) 180268a55bcSHiroki Sato continue; 181268a55bcSHiroki Sato swfile = swap_on_off(fsp->fs_spec, 1, 182268a55bcSHiroki Sato fsp->fs_mntops); 183268a55bcSHiroki Sato if (swfile == NULL) { 184ce458f42SEd Schouten ret = 1; 185268a55bcSHiroki Sato continue; 186268a55bcSHiroki Sato } 18745a5dc93SMike Makonnen if (!qflag) { 18892da00bbSMatthew Dillon printf("%s: %sing %s as swap device\n", 18945a5dc93SMike Makonnen getprogname(), 190268a55bcSHiroki Sato (which_prog == SWAPOFF) ? 191268a55bcSHiroki Sato "remov" : "add", swfile); 192a420c811SMatthew Dillon } 193a420c811SMatthew Dillon } 19445a5dc93SMike Makonnen } 1958fae3551SRodney W. Grimes else if (!*argv) 196a420c811SMatthew Dillon usage(); 197a420c811SMatthew Dillon for (; *argv; ++argv) { 198268a55bcSHiroki Sato swfile = swap_on_off(*argv, 0, NULL); 199268a55bcSHiroki Sato if (swfile == NULL) { 200ce458f42SEd Schouten ret = 1; 201268a55bcSHiroki Sato continue; 202268a55bcSHiroki Sato } 203268a55bcSHiroki Sato if (orig_prog == SWAPCTL) { 204a420c811SMatthew Dillon printf("%s: %sing %s as swap device\n", 205268a55bcSHiroki Sato getprogname(), 206268a55bcSHiroki Sato (which_prog == SWAPOFF) ? "remov" : "add", 207268a55bcSHiroki Sato swfile); 208a420c811SMatthew Dillon } 209a420c811SMatthew Dillon } 210a420c811SMatthew Dillon } else { 211a420c811SMatthew Dillon if (lflag || sflag) 212a420c811SMatthew Dillon swaplist(lflag, sflag, hflag); 213a420c811SMatthew Dillon else 214a420c811SMatthew Dillon usage(); 215a420c811SMatthew Dillon } 216ce458f42SEd Schouten exit(ret); 2178fae3551SRodney W. Grimes } 2188fae3551SRodney W. Grimes 219268a55bcSHiroki Sato static const char * 2208f8de1e1SXin LI swap_on_off(const char *name, int doingall, char *mntops) 2218fae3551SRodney W. Grimes { 222268a55bcSHiroki Sato char base[PATH_MAX]; 223268a55bcSHiroki Sato 224268a55bcSHiroki Sato /* Swap on vnode-backed md(4) device. */ 225268a55bcSHiroki Sato if (mntops != NULL && 2268f8de1e1SXin LI (fnmatch(_PATH_DEV MD_NAME "[0-9]*", name, 0) == 0 || 2278f8de1e1SXin LI fnmatch(MD_NAME "[0-9]*", name, 0) == 0 || 228268a55bcSHiroki Sato strncmp(_PATH_DEV MD_NAME, name, 229268a55bcSHiroki Sato sizeof(_PATH_DEV) + sizeof(MD_NAME)) == 0 || 230268a55bcSHiroki Sato strncmp(MD_NAME, name, sizeof(MD_NAME)) == 0)) 231268a55bcSHiroki Sato return (swap_on_off_md(name, mntops, doingall)); 232268a55bcSHiroki Sato 233268a55bcSHiroki Sato basename_r(name, base); 2348f8de1e1SXin LI 2358f8de1e1SXin LI /* Swap on encrypted device by GEOM_BDE. */ 2368f8de1e1SXin LI if (fnmatch("*.bde", base, 0) == 0) 237268a55bcSHiroki Sato return (swap_on_off_gbde(name, doingall)); 238268a55bcSHiroki Sato 239268a55bcSHiroki Sato /* Swap on encrypted device by GEOM_ELI. */ 2408f8de1e1SXin LI if (fnmatch("*.eli", base, 0) == 0) 241268a55bcSHiroki Sato return (swap_on_off_geli(name, mntops, doingall)); 242268a55bcSHiroki Sato 243268a55bcSHiroki Sato /* Swap on special file. */ 244268a55bcSHiroki Sato return (swap_on_off_sfile(name, doingall)); 245268a55bcSHiroki Sato } 246268a55bcSHiroki Sato 2478f8de1e1SXin LI /* Strip off .bde or .eli suffix from swap device name */ 2488f8de1e1SXin LI static char * 2498f8de1e1SXin LI swap_basename(const char *name) 250268a55bcSHiroki Sato { 251cb754f61SHiroki Sato char *dname, *p; 252268a55bcSHiroki Sato 253cb754f61SHiroki Sato dname = strdup(name); 254cb754f61SHiroki Sato p = strrchr(dname, '.'); 2558f8de1e1SXin LI /* assert(p != NULL); */ 256268a55bcSHiroki Sato *p = '\0'; 257268a55bcSHiroki Sato 2588f8de1e1SXin LI return (dname); 2598f8de1e1SXin LI } 2608f8de1e1SXin LI 2618f8de1e1SXin LI static const char * 2628f8de1e1SXin LI swap_on_off_gbde(const char *name, int doingall) 2638f8de1e1SXin LI { 2648f8de1e1SXin LI const char *ret; 2658f8de1e1SXin LI char pass[64 * 2 + 1], bpass[64]; 2668f8de1e1SXin LI char *dname; 2678f8de1e1SXin LI int i, error; 2688f8de1e1SXin LI 2698f8de1e1SXin LI dname = swap_basename(name); 2708f8de1e1SXin LI if (dname == NULL) 2718f8de1e1SXin LI return (NULL); 2728f8de1e1SXin LI 2738f8de1e1SXin LI if (which_prog == SWAPON) { 274268a55bcSHiroki Sato arc4random_buf(bpass, sizeof(bpass)); 275268a55bcSHiroki Sato for (i = 0; i < (int)sizeof(bpass); i++) 276268a55bcSHiroki Sato sprintf(&pass[2 * i], "%02x", bpass[i]); 277268a55bcSHiroki Sato pass[sizeof(pass) - 1] = '\0'; 278268a55bcSHiroki Sato 2798f8de1e1SXin LI error = run_cmd(NULL, "%s init %s -P %s", _PATH_GBDE, 280cb754f61SHiroki Sato dname, pass); 281268a55bcSHiroki Sato if (error) { 282268a55bcSHiroki Sato /* bde device found. Ignore it. */ 2838f8de1e1SXin LI free(dname); 284268a55bcSHiroki Sato if (!qflag) 285268a55bcSHiroki Sato warnx("%s: Device already in use", name); 286268a55bcSHiroki Sato return (NULL); 287268a55bcSHiroki Sato } 2888f8de1e1SXin LI error = run_cmd(NULL, "%s attach %s -p %s", _PATH_GBDE, 289cb754f61SHiroki Sato dname, pass); 2908f8de1e1SXin LI free(dname); 291268a55bcSHiroki Sato if (error) { 292268a55bcSHiroki Sato warnx("gbde (attach) error: %s", name); 293268a55bcSHiroki Sato return (NULL); 294268a55bcSHiroki Sato } 295268a55bcSHiroki Sato } 2968f8de1e1SXin LI 297268a55bcSHiroki Sato ret = swap_on_off_sfile(name, doingall); 298268a55bcSHiroki Sato 2998f8de1e1SXin LI if (which_prog == SWAPOFF) { 3008f8de1e1SXin LI error = run_cmd(NULL, "%s detach %s", _PATH_GBDE, dname); 3018f8de1e1SXin LI free(dname); 302268a55bcSHiroki Sato if (error) { 303268a55bcSHiroki Sato /* bde device not found. Ignore it. */ 304268a55bcSHiroki Sato if (!qflag) 3058f8de1e1SXin LI warnx("%s: Device not found", name); 306268a55bcSHiroki Sato return (NULL); 307268a55bcSHiroki Sato } 308268a55bcSHiroki Sato } 309268a55bcSHiroki Sato 310268a55bcSHiroki Sato return (ret); 311268a55bcSHiroki Sato } 312268a55bcSHiroki Sato 3130d8a14f9SXin LI /* Build geli(8) arguments from mntops */ 3148f8de1e1SXin LI static char * 3158f8de1e1SXin LI swap_on_geli_args(const char *mntops) 316268a55bcSHiroki Sato { 3178f8de1e1SXin LI const char *aalgo, *ealgo, *keylen_str, *sectorsize_str; 3188f8de1e1SXin LI const char *aflag, *eflag, *lflag, *sflag; 3198f8de1e1SXin LI char *p; 3208f8de1e1SXin LI char *args; 3218f8de1e1SXin LI char *token, *string, *ops; 3228f8de1e1SXin LI int argsize, pagesize; 3238f8de1e1SXin LI size_t pagesize_len; 324268a55bcSHiroki Sato u_long ul; 325268a55bcSHiroki Sato 3268f8de1e1SXin LI /* Use built-in defaults for geli(8) */ 3278f8de1e1SXin LI aalgo = ealgo = keylen_str = ""; 3288f8de1e1SXin LI aflag = eflag = lflag = ""; 329268a55bcSHiroki Sato 3308f8de1e1SXin LI /* We will always specify sectorsize */ 3318f8de1e1SXin LI sflag = " -s "; 3328f8de1e1SXin LI sectorsize_str = NULL; 333268a55bcSHiroki Sato 3348f8de1e1SXin LI if (mntops != NULL) { 3358f8de1e1SXin LI string = ops = strdup(mntops); 336268a55bcSHiroki Sato 3378f8de1e1SXin LI while ((token = strsep(&string, ",")) != NULL) { 3388f8de1e1SXin LI if ((p = strstr(token, "aalgo=")) == token) { 339268a55bcSHiroki Sato aalgo = p + sizeof("aalgo=") - 1; 3408f8de1e1SXin LI aflag = " -a "; 3418f8de1e1SXin LI } else if ((p = strstr(token, "ealgo=")) == token) { 342268a55bcSHiroki Sato ealgo = p + sizeof("ealgo=") - 1; 3438f8de1e1SXin LI eflag = " -e "; 3448f8de1e1SXin LI } else if ((p = strstr(token, "keylen=")) == token) { 345268a55bcSHiroki Sato keylen_str = p + sizeof("keylen=") - 1; 346268a55bcSHiroki Sato errno = 0; 347268a55bcSHiroki Sato ul = strtoul(keylen_str, &p, 10); 348268a55bcSHiroki Sato if (errno == 0) { 349268a55bcSHiroki Sato if (*p != '\0' || ul > INT_MAX) 350268a55bcSHiroki Sato errno = EINVAL; 351268a55bcSHiroki Sato } 352268a55bcSHiroki Sato if (errno) { 353268a55bcSHiroki Sato warn("Invalid keylen: %s", keylen_str); 3548f8de1e1SXin LI free(ops); 355268a55bcSHiroki Sato return (NULL); 356268a55bcSHiroki Sato } 3578f8de1e1SXin LI lflag = " -l "; 3588f8de1e1SXin LI } else if ((p = strstr(token, "sectorsize=")) == token) { 359268a55bcSHiroki Sato sectorsize_str = p + sizeof("sectorsize=") - 1; 360268a55bcSHiroki Sato errno = 0; 361268a55bcSHiroki Sato ul = strtoul(sectorsize_str, &p, 10); 362268a55bcSHiroki Sato if (errno == 0) { 363268a55bcSHiroki Sato if (*p != '\0' || ul > INT_MAX) 364268a55bcSHiroki Sato errno = EINVAL; 365268a55bcSHiroki Sato } 366268a55bcSHiroki Sato if (errno) { 367268a55bcSHiroki Sato warn("Invalid sectorsize: %s", sectorsize_str); 3688f8de1e1SXin LI free(ops); 369268a55bcSHiroki Sato return (NULL); 370268a55bcSHiroki Sato } 3718f8de1e1SXin LI } else if (strcmp(token, "sw") != 0) { 3728f8de1e1SXin LI warnx("Invalid option: %s", token); 3738f8de1e1SXin LI free(ops); 3748f8de1e1SXin LI return (NULL); 375268a55bcSHiroki Sato } 3768f8de1e1SXin LI } 3778f8de1e1SXin LI } else 3788f8de1e1SXin LI ops = NULL; 379268a55bcSHiroki Sato 3808f8de1e1SXin LI /* 3818f8de1e1SXin LI * If we do not have a sector size at this point, fill in 3828f8de1e1SXin LI * pagesize as sector size. 3838f8de1e1SXin LI */ 3848f8de1e1SXin LI if (sectorsize_str == NULL) { 3858f8de1e1SXin LI /* Use pagesize as default sectorsize */ 3868f8de1e1SXin LI pagesize = getpagesize(); 3878f8de1e1SXin LI pagesize_len = snprintf(NULL, 0, "%d", pagesize) + 1; 3888f8de1e1SXin LI p = alloca(pagesize_len); 3898f8de1e1SXin LI snprintf(p, pagesize_len, "%d", pagesize); 3908f8de1e1SXin LI sectorsize_str = p; 3918f8de1e1SXin LI } 3928f8de1e1SXin LI 3938f8de1e1SXin LI argsize = asprintf(&args, "%s%s%s%s%s%s%s%s -d", 3948f8de1e1SXin LI aflag, aalgo, eflag, ealgo, lflag, keylen_str, 3958f8de1e1SXin LI sflag, sectorsize_str); 3968f8de1e1SXin LI 3978f8de1e1SXin LI free(ops); 3988f8de1e1SXin LI return (args); 3998f8de1e1SXin LI } 4008f8de1e1SXin LI 4018f8de1e1SXin LI static const char * 4028f8de1e1SXin LI swap_on_off_geli(const char *name, char *mntops, int doingall) 4038f8de1e1SXin LI { 4048f8de1e1SXin LI char *dname; 4058f8de1e1SXin LI char *args; 4068f8de1e1SXin LI struct stat sb; 4078f8de1e1SXin LI int error; 4088f8de1e1SXin LI 4098f8de1e1SXin LI error = stat(name, &sb); 4108f8de1e1SXin LI 4118f8de1e1SXin LI if (which_prog == SWAPON) do { 4128f8de1e1SXin LI /* Skip if the .eli device already exists */ 4138f8de1e1SXin LI if (error == 0) 4148f8de1e1SXin LI break; 4158f8de1e1SXin LI 4168f8de1e1SXin LI args = swap_on_geli_args(mntops); 4178f8de1e1SXin LI if (args == NULL) 4188f8de1e1SXin LI return (NULL); 4198f8de1e1SXin LI 4208f8de1e1SXin LI dname = swap_basename(name); 4218f8de1e1SXin LI if (dname == NULL) { 4228f8de1e1SXin LI free(args); 4238f8de1e1SXin LI return (NULL); 4248f8de1e1SXin LI } 4258f8de1e1SXin LI 4268f8de1e1SXin LI error = run_cmd(NULL, "%s onetime%s %s", _PATH_GELI, args, 427cb754f61SHiroki Sato dname); 4288f8de1e1SXin LI 4298f8de1e1SXin LI free(dname); 4308f8de1e1SXin LI free(args); 4318f8de1e1SXin LI 432268a55bcSHiroki Sato if (error) { 4338f8de1e1SXin LI /* error occured during creation */ 434268a55bcSHiroki Sato if (!qflag) 4358f8de1e1SXin LI warnx("%s: Invalid parameters", name); 436268a55bcSHiroki Sato return (NULL); 437268a55bcSHiroki Sato } 4388f8de1e1SXin LI } while (0); 439268a55bcSHiroki Sato 440268a55bcSHiroki Sato return (swap_on_off_sfile(name, doingall)); 441268a55bcSHiroki Sato } 442268a55bcSHiroki Sato 443268a55bcSHiroki Sato static const char * 4448f8de1e1SXin LI swap_on_off_md(const char *name, char *mntops, int doingall) 445268a55bcSHiroki Sato { 446268a55bcSHiroki Sato FILE *sfd; 447268a55bcSHiroki Sato int fd, mdunit, error; 448268a55bcSHiroki Sato const char *ret; 449268a55bcSHiroki Sato char mdpath[PATH_MAX], linebuf[PATH_MAX]; 450268a55bcSHiroki Sato char *p, *vnodefile; 451268a55bcSHiroki Sato size_t linelen; 452268a55bcSHiroki Sato u_long ul; 453268a55bcSHiroki Sato 454268a55bcSHiroki Sato fd = -1; 455268a55bcSHiroki Sato sfd = NULL; 456268a55bcSHiroki Sato if (strlen(name) == (sizeof(MD_NAME) - 1)) 457268a55bcSHiroki Sato mdunit = -1; 458268a55bcSHiroki Sato else { 459268a55bcSHiroki Sato errno = 0; 460268a55bcSHiroki Sato ul = strtoul(name + 2, &p, 10); 461268a55bcSHiroki Sato if (errno == 0) { 462268a55bcSHiroki Sato if (*p != '\0' || ul > INT_MAX) 463268a55bcSHiroki Sato errno = EINVAL; 464268a55bcSHiroki Sato } 465268a55bcSHiroki Sato if (errno) { 466268a55bcSHiroki Sato warn("Bad device unit: %s", name); 467268a55bcSHiroki Sato return (NULL); 468268a55bcSHiroki Sato } 469268a55bcSHiroki Sato mdunit = (int)ul; 470268a55bcSHiroki Sato } 471268a55bcSHiroki Sato 472268a55bcSHiroki Sato vnodefile = NULL; 473268a55bcSHiroki Sato if ((p = strstr(mntops, "file=")) != NULL) { 474268a55bcSHiroki Sato vnodefile = strdup(p + sizeof("file=") - 1); 475268a55bcSHiroki Sato p = strchr(vnodefile, ','); 476268a55bcSHiroki Sato if (p != NULL) 477268a55bcSHiroki Sato *p = '\0'; 478268a55bcSHiroki Sato } 479268a55bcSHiroki Sato if (vnodefile == NULL) { 480268a55bcSHiroki Sato warnx("file option not found for %s", name); 481268a55bcSHiroki Sato return (NULL); 482268a55bcSHiroki Sato } 483268a55bcSHiroki Sato 4848f8de1e1SXin LI if (which_prog == SWAPON) { 485268a55bcSHiroki Sato if (mdunit == -1) { 486268a55bcSHiroki Sato error = run_cmd(&fd, "%s -l -n -f %s", 487268a55bcSHiroki Sato _PATH_MDCONFIG, vnodefile); 488268a55bcSHiroki Sato if (error == 0) { 489268a55bcSHiroki Sato /* md device found. Ignore it. */ 490268a55bcSHiroki Sato close(fd); 491268a55bcSHiroki Sato if (!qflag) 492268a55bcSHiroki Sato warnx("%s: Device already in use", 493268a55bcSHiroki Sato vnodefile); 494*1bf9e66cSXin LI free(vnodefile); 495268a55bcSHiroki Sato return (NULL); 496268a55bcSHiroki Sato } 497268a55bcSHiroki Sato error = run_cmd(&fd, "%s -a -t vnode -n -f %s", 498268a55bcSHiroki Sato _PATH_MDCONFIG, vnodefile); 499268a55bcSHiroki Sato if (error) { 500268a55bcSHiroki Sato warnx("mdconfig (attach) error: file=%s", 501268a55bcSHiroki Sato vnodefile); 502*1bf9e66cSXin LI free(vnodefile); 503268a55bcSHiroki Sato return (NULL); 504268a55bcSHiroki Sato } 505268a55bcSHiroki Sato sfd = fdopen(fd, "r"); 506268a55bcSHiroki Sato if (sfd == NULL) { 507268a55bcSHiroki Sato warn("mdconfig (attach) fdopen error"); 508268a55bcSHiroki Sato ret = NULL; 509268a55bcSHiroki Sato goto err; 510268a55bcSHiroki Sato } 511268a55bcSHiroki Sato p = fgetln(sfd, &linelen); 512268a55bcSHiroki Sato if (p == NULL && 513268a55bcSHiroki Sato (linelen < 2 || linelen > sizeof(linebuf))) { 514268a55bcSHiroki Sato warn("mdconfig (attach) unexpected output"); 515268a55bcSHiroki Sato ret = NULL; 516268a55bcSHiroki Sato goto err; 517268a55bcSHiroki Sato } 518268a55bcSHiroki Sato strncpy(linebuf, p, linelen); 519268a55bcSHiroki Sato linebuf[linelen - 1] = '\0'; 520268a55bcSHiroki Sato errno = 0; 521268a55bcSHiroki Sato ul = strtoul(linebuf, &p, 10); 522268a55bcSHiroki Sato if (errno == 0) { 523268a55bcSHiroki Sato if (*p != '\0' || ul > INT_MAX) 524268a55bcSHiroki Sato errno = EINVAL; 525268a55bcSHiroki Sato } 526268a55bcSHiroki Sato if (errno) { 527268a55bcSHiroki Sato warn("mdconfig (attach) unexpected output: %s", 528268a55bcSHiroki Sato linebuf); 529268a55bcSHiroki Sato ret = NULL; 530268a55bcSHiroki Sato goto err; 531268a55bcSHiroki Sato } 532268a55bcSHiroki Sato mdunit = (int)ul; 533268a55bcSHiroki Sato } else { 534268a55bcSHiroki Sato error = run_cmd(&fd, "%s -l -n -f %s -u %d", 535268a55bcSHiroki Sato _PATH_MDCONFIG, vnodefile, mdunit); 536268a55bcSHiroki Sato if (error == 0) { 537268a55bcSHiroki Sato /* md device found. Ignore it. */ 538268a55bcSHiroki Sato close(fd); 539268a55bcSHiroki Sato if (!qflag) 540268a55bcSHiroki Sato warnx("md%d on %s: Device already " 541268a55bcSHiroki Sato "in use", mdunit, vnodefile); 542*1bf9e66cSXin LI free(vnodefile); 543268a55bcSHiroki Sato return (NULL); 544268a55bcSHiroki Sato } 545268a55bcSHiroki Sato error = run_cmd(NULL, "%s -a -t vnode -u %d -f %s", 546268a55bcSHiroki Sato _PATH_MDCONFIG, mdunit, vnodefile); 547268a55bcSHiroki Sato if (error) { 548268a55bcSHiroki Sato warnx("mdconfig (attach) error: " 549268a55bcSHiroki Sato "md%d on file=%s", mdunit, vnodefile); 550*1bf9e66cSXin LI free(vnodefile); 551268a55bcSHiroki Sato return (NULL); 552268a55bcSHiroki Sato } 553268a55bcSHiroki Sato } 5548f8de1e1SXin LI } else /* SWAPOFF */ { 555268a55bcSHiroki Sato if (mdunit == -1) { 556268a55bcSHiroki Sato error = run_cmd(&fd, "%s -l -n -f %s", 557268a55bcSHiroki Sato _PATH_MDCONFIG, vnodefile); 558268a55bcSHiroki Sato if (error) { 559268a55bcSHiroki Sato /* md device not found. Ignore it. */ 560268a55bcSHiroki Sato close(fd); 561268a55bcSHiroki Sato if (!qflag) 562268a55bcSHiroki Sato warnx("md on %s: Device not found", 563268a55bcSHiroki Sato vnodefile); 564*1bf9e66cSXin LI free(vnodefile); 565268a55bcSHiroki Sato return (NULL); 566268a55bcSHiroki Sato } 567268a55bcSHiroki Sato sfd = fdopen(fd, "r"); 568268a55bcSHiroki Sato if (sfd == NULL) { 569268a55bcSHiroki Sato warn("mdconfig (list) fdopen error"); 570268a55bcSHiroki Sato ret = NULL; 571268a55bcSHiroki Sato goto err; 572268a55bcSHiroki Sato } 573268a55bcSHiroki Sato p = fgetln(sfd, &linelen); 574268a55bcSHiroki Sato if (p == NULL && 575268a55bcSHiroki Sato (linelen < 2 || linelen > sizeof(linebuf) - 1)) { 576268a55bcSHiroki Sato warn("mdconfig (list) unexpected output"); 577268a55bcSHiroki Sato ret = NULL; 578268a55bcSHiroki Sato goto err; 579268a55bcSHiroki Sato } 580268a55bcSHiroki Sato strncpy(linebuf, p, linelen); 581268a55bcSHiroki Sato linebuf[linelen - 1] = '\0'; 582268a55bcSHiroki Sato p = strchr(linebuf, ' '); 583268a55bcSHiroki Sato if (p != NULL) 584268a55bcSHiroki Sato *p = '\0'; 585268a55bcSHiroki Sato errno = 0; 586268a55bcSHiroki Sato ul = strtoul(linebuf, &p, 10); 587268a55bcSHiroki Sato if (errno == 0) { 588268a55bcSHiroki Sato if (*p != '\0' || ul > INT_MAX) 589268a55bcSHiroki Sato errno = EINVAL; 590268a55bcSHiroki Sato } 591268a55bcSHiroki Sato if (errno) { 592268a55bcSHiroki Sato warn("mdconfig (list) unexpected output: %s", 593268a55bcSHiroki Sato linebuf); 594268a55bcSHiroki Sato ret = NULL; 595268a55bcSHiroki Sato goto err; 596268a55bcSHiroki Sato } 597268a55bcSHiroki Sato mdunit = (int)ul; 598268a55bcSHiroki Sato } else { 599268a55bcSHiroki Sato error = run_cmd(&fd, "%s -l -n -f %s -u %d", 600268a55bcSHiroki Sato _PATH_MDCONFIG, vnodefile, mdunit); 601268a55bcSHiroki Sato if (error) { 602268a55bcSHiroki Sato /* md device not found. Ignore it. */ 603268a55bcSHiroki Sato close(fd); 604268a55bcSHiroki Sato if (!qflag) 605268a55bcSHiroki Sato warnx("md%d on %s: Device not found", 606268a55bcSHiroki Sato mdunit, vnodefile); 607*1bf9e66cSXin LI free(vnodefile); 608268a55bcSHiroki Sato return (NULL); 609268a55bcSHiroki Sato } 610268a55bcSHiroki Sato } 611268a55bcSHiroki Sato } 612268a55bcSHiroki Sato snprintf(mdpath, sizeof(mdpath), "%s%s%d", _PATH_DEV, 613268a55bcSHiroki Sato MD_NAME, mdunit); 614268a55bcSHiroki Sato mdpath[sizeof(mdpath) - 1] = '\0'; 615268a55bcSHiroki Sato ret = swap_on_off_sfile(mdpath, doingall); 616268a55bcSHiroki Sato 6178f8de1e1SXin LI if (which_prog == SWAPOFF) { 618268a55bcSHiroki Sato if (ret != NULL) { 619268a55bcSHiroki Sato error = run_cmd(NULL, "%s -d -u %d", 620268a55bcSHiroki Sato _PATH_MDCONFIG, mdunit); 621268a55bcSHiroki Sato if (error) 622268a55bcSHiroki Sato warn("mdconfig (detach) detach failed: %s%s%d", 623268a55bcSHiroki Sato _PATH_DEV, MD_NAME, mdunit); 624268a55bcSHiroki Sato } 625268a55bcSHiroki Sato } 626268a55bcSHiroki Sato err: 627268a55bcSHiroki Sato if (sfd != NULL) 628268a55bcSHiroki Sato fclose(sfd); 629268a55bcSHiroki Sato if (fd != -1) 630268a55bcSHiroki Sato close(fd); 631*1bf9e66cSXin LI free(vnodefile); 632268a55bcSHiroki Sato return (ret); 633268a55bcSHiroki Sato } 634268a55bcSHiroki Sato 635268a55bcSHiroki Sato static int 636268a55bcSHiroki Sato run_cmd(int *ofd, const char *cmdline, ...) 637268a55bcSHiroki Sato { 638268a55bcSHiroki Sato va_list ap; 639268a55bcSHiroki Sato char **argv, **argvp, *cmd, *p; 640268a55bcSHiroki Sato int argc, pid, status, rv; 641268a55bcSHiroki Sato int pfd[2], nfd, dup2dn; 642268a55bcSHiroki Sato 643268a55bcSHiroki Sato va_start(ap, cmdline); 644268a55bcSHiroki Sato rv = vasprintf(&cmd, cmdline, ap); 645268a55bcSHiroki Sato if (rv == -1) { 646268a55bcSHiroki Sato warn("%s", __func__); 647268a55bcSHiroki Sato return (rv); 648268a55bcSHiroki Sato } 649268a55bcSHiroki Sato va_end(ap); 650268a55bcSHiroki Sato 651268a55bcSHiroki Sato for (argc = 1, p = cmd; (p = strchr(p, ' ')) != NULL; p++) 652268a55bcSHiroki Sato argc++; 653268a55bcSHiroki Sato argv = (char **)malloc(sizeof(*argv) * (argc + 1)); 654268a55bcSHiroki Sato for (p = cmd, argvp = argv; (*argvp = strsep(&p, " ")) != NULL;) 655268a55bcSHiroki Sato if (**argvp != '\0' && (++argvp > &argv[argc])) { 656268a55bcSHiroki Sato *argvp = NULL; 657268a55bcSHiroki Sato break; 658268a55bcSHiroki Sato } 659268a55bcSHiroki Sato /* The argv array ends up NULL-terminated here. */ 660268a55bcSHiroki Sato #if 0 661268a55bcSHiroki Sato { 662268a55bcSHiroki Sato int i; 663268a55bcSHiroki Sato 664268a55bcSHiroki Sato fprintf(stderr, "DEBUG: running:"); 665268a55bcSHiroki Sato /* Should be equivalent to 'cmd' (before strsep, of course). */ 666268a55bcSHiroki Sato for (i = 0; argv[i] != NULL; i++) 667268a55bcSHiroki Sato fprintf(stderr, " %s", argv[i]); 668268a55bcSHiroki Sato fprintf(stderr, "\n"); 669268a55bcSHiroki Sato } 670268a55bcSHiroki Sato #endif 671268a55bcSHiroki Sato dup2dn = 1; 672268a55bcSHiroki Sato if (ofd != NULL) { 673268a55bcSHiroki Sato if (pipe(&pfd[0]) == -1) { 674268a55bcSHiroki Sato warn("%s: pipe", __func__); 675268a55bcSHiroki Sato return (-1); 676268a55bcSHiroki Sato } 677268a55bcSHiroki Sato *ofd = pfd[0]; 678268a55bcSHiroki Sato dup2dn = 0; 679268a55bcSHiroki Sato } 680268a55bcSHiroki Sato pid = fork(); 681268a55bcSHiroki Sato switch (pid) { 682268a55bcSHiroki Sato case 0: 683268a55bcSHiroki Sato /* Child process. */ 684268a55bcSHiroki Sato if (ofd != NULL) 685268a55bcSHiroki Sato if (dup2(pfd[1], STDOUT_FILENO) < 0) 686268a55bcSHiroki Sato err(1, "dup2 in %s", __func__); 687268a55bcSHiroki Sato nfd = open(_PATH_DEVNULL, O_RDWR); 688268a55bcSHiroki Sato if (nfd == -1) 689268a55bcSHiroki Sato err(1, "%s: open %s", __func__, _PATH_DEVNULL); 690268a55bcSHiroki Sato if (dup2(nfd, STDIN_FILENO) < 0) 691268a55bcSHiroki Sato err(1, "%s: dup2", __func__); 692268a55bcSHiroki Sato if (dup2dn && dup2(nfd, STDOUT_FILENO) < 0) 693268a55bcSHiroki Sato err(1, "%s: dup2", __func__); 694268a55bcSHiroki Sato if (dup2(nfd, STDERR_FILENO) < 0) 695268a55bcSHiroki Sato err(1, "%s: dup2", __func__); 696268a55bcSHiroki Sato execv(argv[0], argv); 697268a55bcSHiroki Sato warn("exec: %s", argv[0]); 698268a55bcSHiroki Sato _exit(-1); 699268a55bcSHiroki Sato case -1: 700268a55bcSHiroki Sato err(1, "%s: fork", __func__); 701268a55bcSHiroki Sato } 702268a55bcSHiroki Sato free(cmd); 703268a55bcSHiroki Sato free(argv); 704268a55bcSHiroki Sato while (waitpid(pid, &status, 0) != pid) 705268a55bcSHiroki Sato ; 706268a55bcSHiroki Sato return (WEXITSTATUS(status)); 707268a55bcSHiroki Sato } 708268a55bcSHiroki Sato 709268a55bcSHiroki Sato static const char * 7108f8de1e1SXin LI swap_on_off_sfile(const char *name, int doingall) 711268a55bcSHiroki Sato { 712268a55bcSHiroki Sato int error; 713268a55bcSHiroki Sato 7148f8de1e1SXin LI if (which_prog == SWAPON) 715268a55bcSHiroki Sato error = swapon(name); 7168f8de1e1SXin LI else /* SWAPOFF */ 717268a55bcSHiroki Sato error = swapoff(name); 7188f8de1e1SXin LI 719268a55bcSHiroki Sato if (error == -1) { 7208fae3551SRodney W. Grimes switch (errno) { 7218fae3551SRodney W. Grimes case EBUSY: 7224937798dSDavid Schultz if (!doingall) 723268a55bcSHiroki Sato warnx("%s: Device already in use", name); 7248fae3551SRodney W. Grimes break; 7254937798dSDavid Schultz case EINVAL: 7264937798dSDavid Schultz if (which_prog == SWAPON) 7274937798dSDavid Schultz warnx("%s: NSWAPDEV limit reached", name); 7284937798dSDavid Schultz else if (!doingall) 7294937798dSDavid Schultz warn("%s", name); 7304937798dSDavid Schultz break; 7318fae3551SRodney W. Grimes default: 7326da7f378SPhilippe Charnier warn("%s", name); 7338fae3551SRodney W. Grimes break; 7348fae3551SRodney W. Grimes } 735268a55bcSHiroki Sato return (NULL); 7368fae3551SRodney W. Grimes } 737268a55bcSHiroki Sato return (name); 7388fae3551SRodney W. Grimes } 7398fae3551SRodney W. Grimes 7406da7f378SPhilippe Charnier static void 741a420c811SMatthew Dillon usage(void) 7428fae3551SRodney W. Grimes { 743a420c811SMatthew Dillon fprintf(stderr, "usage: %s ", getprogname()); 744a420c811SMatthew Dillon switch(orig_prog) { 745a420c811SMatthew Dillon case SWAPON: 7468d646af5SRuslan Ermilov case SWAPOFF: 747268a55bcSHiroki Sato fprintf(stderr, "[-F fstab] -aLq | file ...\n"); 748a420c811SMatthew Dillon break; 749a420c811SMatthew Dillon case SWAPCTL: 7502e64768cSPawel Jakub Dawidek fprintf(stderr, "[-AghklmsU] [-a file ... | -d file ...]\n"); 751a420c811SMatthew Dillon break; 752a420c811SMatthew Dillon } 7538fae3551SRodney W. Grimes exit(1); 7548fae3551SRodney W. Grimes } 75592da00bbSMatthew Dillon 756a420c811SMatthew Dillon static void 7572e64768cSPawel Jakub Dawidek sizetobuf(char *buf, size_t bufsize, int hflag, long long val, int hlen, 7582e64768cSPawel Jakub Dawidek long blocksize) 7592e64768cSPawel Jakub Dawidek { 7602e64768cSPawel Jakub Dawidek 7612e64768cSPawel Jakub Dawidek if (hflag == 'H') { 7622e64768cSPawel Jakub Dawidek char tmp[16]; 7632e64768cSPawel Jakub Dawidek 7642e64768cSPawel Jakub Dawidek humanize_number(tmp, 5, (int64_t)val, "", HN_AUTOSCALE, 7652e64768cSPawel Jakub Dawidek HN_B | HN_NOSPACE | HN_DECIMAL); 7662e64768cSPawel Jakub Dawidek snprintf(buf, bufsize, "%*s", hlen, tmp); 7672e64768cSPawel Jakub Dawidek } else { 7682e64768cSPawel Jakub Dawidek snprintf(buf, bufsize, "%*lld", hlen, val / blocksize); 7692e64768cSPawel Jakub Dawidek } 7702e64768cSPawel Jakub Dawidek } 7712e64768cSPawel Jakub Dawidek 7722e64768cSPawel Jakub Dawidek static void 773a420c811SMatthew Dillon swaplist(int lflag, int sflag, int hflag) 77492da00bbSMatthew Dillon { 775a420c811SMatthew Dillon size_t mibsize, size; 776a420c811SMatthew Dillon struct xswdev xsw; 77769095b02SMike Barcroft int hlen, mib[16], n, pagesize; 778a420c811SMatthew Dillon long blocksize; 779a420c811SMatthew Dillon long long total = 0; 780a420c811SMatthew Dillon long long used = 0; 781a420c811SMatthew Dillon long long tmp_total; 782a420c811SMatthew Dillon long long tmp_used; 7832e64768cSPawel Jakub Dawidek char buf[32]; 78492da00bbSMatthew Dillon 785a420c811SMatthew Dillon pagesize = getpagesize(); 786a420c811SMatthew Dillon switch(hflag) { 7872e64768cSPawel Jakub Dawidek case 'G': 7882e64768cSPawel Jakub Dawidek blocksize = 1024 * 1024 * 1024; 7892e64768cSPawel Jakub Dawidek strlcpy(buf, "1GB-blocks", sizeof(buf)); 7902e64768cSPawel Jakub Dawidek hlen = 10; 7912e64768cSPawel Jakub Dawidek break; 7922e64768cSPawel Jakub Dawidek case 'H': 7932e64768cSPawel Jakub Dawidek blocksize = -1; 7942e64768cSPawel Jakub Dawidek strlcpy(buf, "Bytes", sizeof(buf)); 7952e64768cSPawel Jakub Dawidek hlen = 10; 7962e64768cSPawel Jakub Dawidek break; 797a420c811SMatthew Dillon case 'K': 798a420c811SMatthew Dillon blocksize = 1024; 7992e64768cSPawel Jakub Dawidek strlcpy(buf, "1kB-blocks", sizeof(buf)); 800a420c811SMatthew Dillon hlen = 10; 801a420c811SMatthew Dillon break; 802a420c811SMatthew Dillon case 'M': 803a420c811SMatthew Dillon blocksize = 1024 * 1024; 8042e64768cSPawel Jakub Dawidek strlcpy(buf, "1MB-blocks", sizeof(buf)); 805a420c811SMatthew Dillon hlen = 10; 806a420c811SMatthew Dillon break; 807a420c811SMatthew Dillon default: 8089255f327SMike Barcroft getbsize(&hlen, &blocksize); 8092e64768cSPawel Jakub Dawidek snprintf(buf, sizeof(buf), "%ld-blocks", blocksize); 810a420c811SMatthew Dillon break; 81192da00bbSMatthew Dillon } 812a420c811SMatthew Dillon 813a420c811SMatthew Dillon mibsize = sizeof mib / sizeof mib[0]; 814a420c811SMatthew Dillon if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1) 815a420c811SMatthew Dillon err(1, "sysctlnametomib()"); 816a420c811SMatthew Dillon 817a420c811SMatthew Dillon if (lflag) { 818a420c811SMatthew Dillon printf("%-13s %*s %*s\n", 819a420c811SMatthew Dillon "Device:", 820a420c811SMatthew Dillon hlen, buf, 821a420c811SMatthew Dillon hlen, "Used:"); 822a420c811SMatthew Dillon } 823a420c811SMatthew Dillon 824a420c811SMatthew Dillon for (n = 0; ; ++n) { 825a420c811SMatthew Dillon mib[mibsize] = n; 826a420c811SMatthew Dillon size = sizeof xsw; 82716fc3635SMark Murray if (sysctl(mib, mibsize + 1, &xsw, &size, NULL, 0) == -1) 828a420c811SMatthew Dillon break; 829a420c811SMatthew Dillon if (xsw.xsw_version != XSWDEV_VERSION) 830a420c811SMatthew Dillon errx(1, "xswdev version mismatch"); 831a420c811SMatthew Dillon 8322e64768cSPawel Jakub Dawidek tmp_total = (long long)xsw.xsw_nblks * pagesize; 8332e64768cSPawel Jakub Dawidek tmp_used = (long long)xsw.xsw_used * pagesize; 834a420c811SMatthew Dillon total += tmp_total; 835a420c811SMatthew Dillon used += tmp_used; 836a420c811SMatthew Dillon if (lflag) { 8372e64768cSPawel Jakub Dawidek sizetobuf(buf, sizeof(buf), hflag, tmp_total, hlen, 8382e64768cSPawel Jakub Dawidek blocksize); 8392e64768cSPawel Jakub Dawidek printf("/dev/%-8s %s ", devname(xsw.xsw_dev, S_IFCHR), 8402e64768cSPawel Jakub Dawidek buf); 8412e64768cSPawel Jakub Dawidek sizetobuf(buf, sizeof(buf), hflag, tmp_used, hlen, 8422e64768cSPawel Jakub Dawidek blocksize); 8432e64768cSPawel Jakub Dawidek printf("%s\n", buf); 844a420c811SMatthew Dillon } 845a420c811SMatthew Dillon } 846a420c811SMatthew Dillon if (errno != ENOENT) 847a420c811SMatthew Dillon err(1, "sysctl()"); 848a420c811SMatthew Dillon 849a420c811SMatthew Dillon if (sflag) { 8502e64768cSPawel Jakub Dawidek sizetobuf(buf, sizeof(buf), hflag, total, hlen, blocksize); 8512e64768cSPawel Jakub Dawidek printf("Total: %s ", buf); 8522e64768cSPawel Jakub Dawidek sizetobuf(buf, sizeof(buf), hflag, used, hlen, blocksize); 8532e64768cSPawel Jakub Dawidek printf("%s\n", buf); 854a420c811SMatthew Dillon } 855a420c811SMatthew Dillon } 856a420c811SMatthew Dillon 857