1 /* $NetBSD: swaplist.c,v 1.17 2009/04/06 12:38:35 lukem Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 #include <sys/cdefs.h> 29 30 #ifndef lint 31 __RCSID("$NetBSD: swaplist.c,v 1.17 2009/04/06 12:38:35 lukem Exp $"); 32 #endif 33 34 35 #include <sys/param.h> 36 #include <sys/stat.h> 37 #include <sys/swap.h> 38 39 #include <unistd.h> 40 #include <err.h> 41 #include <errno.h> 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <inttypes.h> 46 #include <util.h> 47 48 #define dbtoqb(b) dbtob((int64_t)(b)) 49 50 /* 51 * NOTE: This file is separate from swapctl.c so that pstat can grab it. 52 */ 53 54 #include "swapctl.h" 55 56 int 57 list_swap(int pri, int kflag, int pflag, int tflag, int dolong, int hflag) 58 { 59 struct swapent *sep, *fsep; 60 long blocksize; 61 char szbuf[5], usbuf[5], avbuf[5]; /* size, used, avail */ 62 const char *header, *suff; 63 size_t l; 64 int hlen, totalsize, size, totalinuse, inuse, ncounted, pathmax; 65 int rnswap, nswap = swapctl(SWAP_NSWAP, 0, 0), i; 66 67 if (nswap < 1) { 68 puts("no swap devices configured"); 69 return 0; 70 } 71 72 fsep = sep = (struct swapent *)malloc(nswap * sizeof(*sep)); 73 if (sep == NULL) 74 err(1, "malloc"); 75 rnswap = swapctl(SWAP_STATS, (void *)sep, nswap); 76 if (rnswap < 0) 77 err(1, "SWAP_STATS"); 78 if (nswap != rnswap) 79 warnx("SWAP_STATS different to SWAP_NSWAP (%d != %d)", 80 rnswap, nswap); 81 82 pathmax = 11; 83 switch(kflag) { 84 case 1: 85 header = "1K-blocks"; 86 blocksize = 1024; 87 suff = "KBytes"; 88 break; 89 case 2: 90 suff = "MBytes"; 91 header = "1M-blocks"; 92 blocksize = 1024 * 1024; 93 break; 94 case 3: 95 header = "1G-blocks"; 96 blocksize = 1024 * 1024 * 1024; 97 suff = "GBytes"; 98 break; 99 default: 100 suff = "blocks"; 101 if (!hflag) { 102 header = getbsize(&hlen, &blocksize); 103 } else { 104 header = "Size"; 105 blocksize = 1; suff = ""; /* unused */ 106 } 107 break; 108 } 109 if (hflag || kflag) 110 hlen = strlen(header); 111 112 if (dolong && tflag == 0) { 113 for (i = rnswap; i-- > 0; sep++) 114 if ((size_t)pathmax < (l = strlen(sep->se_path))) 115 pathmax = l; 116 sep = fsep; 117 (void)printf("%-*s %*s %8s %8s %8s %s\n", 118 pathmax, "Device", hlen, header, 119 "Used", "Avail", "Capacity", "Priority"); 120 } 121 totalsize = totalinuse = ncounted = 0; 122 for (; rnswap-- > 0; sep++) { 123 if (pflag && sep->se_priority != pri) 124 continue; 125 ncounted++; 126 size = sep->se_nblks; 127 inuse = sep->se_inuse; 128 totalsize += size; 129 totalinuse += inuse; 130 131 if (dolong && tflag == 0) { 132 if (hflag == 0) { 133 (void)printf("%-*s %*ld ", pathmax, sep->se_path, hlen, 134 (long)(dbtoqb(size) / blocksize)); 135 136 (void)printf("%8ld %8ld %5.0f%% %d\n", 137 (long)(dbtoqb(inuse) / blocksize), 138 (long)(dbtoqb(size - inuse) / blocksize), 139 (double)inuse / (double)size * 100.0, 140 sep->se_priority); 141 } else { 142 if ((humanize_number(szbuf, sizeof(szbuf), (dbtoqb(size)), 143 "", HN_AUTOSCALE, (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1) 144 err(1, "humanize_number"); 145 if ((humanize_number(usbuf, sizeof(usbuf), (dbtoqb(inuse)), 146 "", HN_AUTOSCALE, (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1) 147 err(1, "humanize_number"); 148 if ((humanize_number(avbuf, sizeof(avbuf), (dbtoqb(size-inuse)), 149 "", HN_AUTOSCALE, (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1) 150 err(1, "humanize_number"); 151 (void)printf("%-*s %*s ", pathmax, sep->se_path, hlen, szbuf); 152 153 (void)printf("%8s %8s %5.0f%% %d\n", 154 usbuf, avbuf, 155 (double)inuse / (double)size * 100.0, 156 sep->se_priority); 157 } 158 } 159 } 160 if (tflag) { 161 if (hflag) { 162 if ((humanize_number(usbuf, sizeof(usbuf), (dbtoqb(totalinuse)), 163 "", HN_AUTOSCALE, (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1) 164 err(1, "humanize_number"); 165 if ((humanize_number(szbuf, sizeof(szbuf), (dbtoqb(totalsize)), 166 "", HN_AUTOSCALE, (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1) 167 err(1, "humanize_number"); 168 (void)printf("%s/%s swap space\n", usbuf, szbuf); 169 } else { 170 (void)printf("%ld/%ld %s swap space\n", 171 (long)(dbtoqb(totalinuse) / blocksize), 172 (long)(dbtoqb(totalsize) / blocksize), 173 suff); 174 } 175 } 176 else if (dolong == 0) { 177 if (hflag) { 178 if ((humanize_number(szbuf, sizeof(szbuf), (dbtoqb(totalsize)), 179 "", HN_AUTOSCALE, (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1) 180 err(1, "humanize_number"); 181 if ((humanize_number(usbuf, sizeof(usbuf), (dbtoqb(totalinuse)), 182 "", HN_AUTOSCALE, (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1) 183 err(1, "humanize_number"); 184 if ((humanize_number(avbuf, sizeof(avbuf), (dbtoqb(totalsize-totalinuse)), 185 "", HN_AUTOSCALE, (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1) 186 err(1, "humanize_number"); 187 (void)printf("total: %s allocated = %s used, %s available.\n", 188 szbuf, usbuf, avbuf); 189 } else { 190 printf("total: %ld %s allocated = %ld %s used, " 191 "%ld %s available\n", 192 (long)(dbtoqb(totalsize) / blocksize), suff, 193 (long)(dbtoqb(totalinuse) / blocksize), suff, 194 (long)(dbtoqb(totalsize - totalinuse) / blocksize), suff); 195 } 196 } else if (ncounted > 1) { 197 if (hflag) { 198 if ((humanize_number(szbuf, sizeof(szbuf), (dbtoqb(totalsize)), 199 "", HN_AUTOSCALE, (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1) 200 err(1, "humanize_number"); 201 if ((humanize_number(usbuf, sizeof(usbuf), (dbtoqb(totalinuse)), 202 "", HN_AUTOSCALE, (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1) 203 err(1, "humanize_number"); 204 if ((humanize_number(avbuf, sizeof(avbuf), (dbtoqb(totalsize-totalinuse)), 205 "", HN_AUTOSCALE, (HN_DECIMAL | HN_B | HN_NOSPACE))) == -1) 206 err(1, "humanize_number"); 207 (void)printf("%-*s %*s %8s %8s %5.0f%%\n", pathmax, "Total", 208 hlen, szbuf, usbuf, avbuf, 209 (double)(totalinuse) / (double)totalsize * 100.0); 210 } else { 211 (void)printf("%-*s %*ld %8ld %8ld %5.0f%%\n", pathmax, "Total", 212 hlen, 213 (long)(dbtoqb(totalsize) / blocksize), 214 (long)(dbtoqb(totalinuse) / blocksize), 215 (long)(dbtoqb(totalsize - totalinuse) / blocksize), 216 (double)(totalinuse) / (double)totalsize * 100.0); 217 } 218 } 219 if (fsep) 220 (void)free(fsep); 221 222 return 1; 223 } 224