]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sbin/swapon/swapon.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sbin / swapon / swapon.c
1 /*
2  * Copyright (c) 1980, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #if 0
31 #ifndef lint
32 static const char copyright[] =
33 "@(#) Copyright (c) 1980, 1993\n\
34         The Regents of the University of California.  All rights reserved.\n";
35 #endif /* not lint */
36
37 #ifndef lint
38 static char sccsid[] = "@(#)swapon.c    8.1 (Berkeley) 6/5/93";
39 #endif /* not lint */
40 #endif
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43
44 #include <sys/stat.h>
45 #include <sys/param.h>
46 #include <sys/sysctl.h>
47 #include <vm/vm_param.h>
48
49 #include <err.h>
50 #include <errno.h>
51 #include <fstab.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <unistd.h>
56 #include <fcntl.h>
57 #include <libutil.h>
58
59 static void usage(void);
60 static int swap_on_off(char *name, int ignoreebusy);
61 static void swaplist(int, int, int);
62
63 enum { SWAPON, SWAPOFF, SWAPCTL } orig_prog, which_prog = SWAPCTL;
64
65 int
66 main(int argc, char **argv)
67 {
68         struct fstab *fsp;
69         char *ptr;
70         int ret;
71         int ch, doall;
72         int sflag = 0, lflag = 0, hflag = 0, qflag = 0;
73         const char *etc_fstab;
74
75         if ((ptr = strrchr(argv[0], '/')) == NULL)
76                 ptr = argv[0];
77         if (strstr(ptr, "swapon"))
78                 which_prog = SWAPON;
79         else if (strstr(ptr, "swapoff"))
80                 which_prog = SWAPOFF;
81         orig_prog = which_prog;
82         
83         doall = 0;
84         etc_fstab = NULL;
85         while ((ch = getopt(argc, argv, "AadghklmqsUF:")) != -1) {
86                 switch(ch) {
87                 case 'A':
88                         if (which_prog == SWAPCTL) {
89                                 doall = 1;
90                                 which_prog = SWAPON;
91                         } else {
92                                 usage();
93                         }
94                         break;
95                 case 'a':
96                         if (which_prog == SWAPON || which_prog == SWAPOFF)
97                                 doall = 1;
98                         else
99                                 which_prog = SWAPON;
100                         break;
101                 case 'd':
102                         if (which_prog == SWAPCTL)
103                                 which_prog = SWAPOFF;
104                         else
105                                 usage();
106                         break;
107                 case 'g':
108                         hflag = 'G';
109                         break;
110                 case 'h':
111                         hflag = 'H';
112                         break;
113                 case 'k':
114                         hflag = 'K';
115                         break;
116                 case 'l':
117                         lflag = 1;
118                         break;
119                 case 'm':
120                         hflag = 'M';
121                         break;
122                 case 'q':
123                         if (which_prog == SWAPON || which_prog == SWAPOFF)
124                                 qflag = 1;
125                         break;
126                 case 's':
127                         sflag = 1;
128                         break;
129                 case 'U':
130                         if (which_prog == SWAPCTL) {
131                                 doall = 1;
132                                 which_prog = SWAPOFF;
133                         } else {
134                                 usage();
135                         }
136                         break;
137                 case 'F':
138                         etc_fstab = optarg;
139                         break;
140                 case '?':
141                 default:
142                         usage();
143                 }
144         }
145         argv += optind;
146
147         ret = 0;
148         if (etc_fstab != NULL)
149                 setfstab(etc_fstab);
150         if (which_prog == SWAPON || which_prog == SWAPOFF) {
151                 if (doall) {
152                         while ((fsp = getfsent()) != NULL) {
153                                 if (strcmp(fsp->fs_type, FSTAB_SW))
154                                         continue;
155                                 if (strstr(fsp->fs_mntops, "noauto"))
156                                         continue;
157                                 if (swap_on_off(fsp->fs_spec, 1)) {
158                                         ret = 1;
159                                 } else {
160                                         if (!qflag) {
161                                                 printf("%s: %sing %s as swap device\n",
162                                                     getprogname(),
163                                                     which_prog == SWAPOFF ? "remov" : "add",
164                                                     fsp->fs_spec);
165                                         }
166                                 }
167                         }
168                 }
169                 else if (!*argv)
170                         usage();
171                 for (; *argv; ++argv) {
172                         if (swap_on_off(*argv, 0)) {
173                                 ret = 1;
174                         } else if (orig_prog == SWAPCTL) {
175                                 printf("%s: %sing %s as swap device\n",
176                                     getprogname(), which_prog == SWAPOFF ? "remov" : "add",
177                                     *argv);
178                         }
179                 }
180         } else {
181                 if (lflag || sflag)
182                         swaplist(lflag, sflag, hflag);
183                 else 
184                         usage();
185         }
186         exit(ret);
187 }
188
189 static int
190 swap_on_off(char *name, int doingall)
191 {
192         if ((which_prog == SWAPOFF ? swapoff(name) : swapon(name)) == -1) {
193                 switch (errno) {
194                 case EBUSY:
195                         if (!doingall)
196                                 warnx("%s: device already in use", name);
197                         break;
198                 case EINVAL:
199                         if (which_prog == SWAPON)
200                                 warnx("%s: NSWAPDEV limit reached", name);
201                         else if (!doingall)
202                                 warn("%s", name);
203                         break;
204                 default:
205                         warn("%s", name);
206                         break;
207                 }
208                 return(1);
209         }
210         return(0);
211 }
212
213 static void
214 usage(void)
215 {
216         fprintf(stderr, "usage: %s ", getprogname());
217         switch(orig_prog) {
218         case SWAPON:
219         case SWAPOFF:
220             fprintf(stderr, "[-F fstab] -aq | file ...\n");
221             break;
222         case SWAPCTL:
223             fprintf(stderr, "[-AghklmsU] [-a file ... | -d file ...]\n");
224             break;
225         }
226         exit(1);
227 }
228
229 static void
230 sizetobuf(char *buf, size_t bufsize, int hflag, long long val, int hlen,
231     long blocksize)
232 {
233
234         if (hflag == 'H') {
235                 char tmp[16];
236
237                 humanize_number(tmp, 5, (int64_t)val, "", HN_AUTOSCALE,
238                     HN_B | HN_NOSPACE | HN_DECIMAL);
239                 snprintf(buf, bufsize, "%*s", hlen, tmp);
240         } else {
241                 snprintf(buf, bufsize, "%*lld", hlen, val / blocksize);
242         }
243 }
244
245 static void
246 swaplist(int lflag, int sflag, int hflag)
247 {
248         size_t mibsize, size;
249         struct xswdev xsw;
250         int hlen, mib[16], n, pagesize;
251         long blocksize;
252         long long total = 0;
253         long long used = 0;
254         long long tmp_total;
255         long long tmp_used;
256         char buf[32];
257         
258         pagesize = getpagesize();
259         switch(hflag) {
260         case 'G':
261             blocksize = 1024 * 1024 * 1024;
262             strlcpy(buf, "1GB-blocks", sizeof(buf));
263             hlen = 10;
264             break;
265         case 'H':
266             blocksize = -1;
267             strlcpy(buf, "Bytes", sizeof(buf));
268             hlen = 10;
269             break;
270         case 'K':
271             blocksize = 1024;
272             strlcpy(buf, "1kB-blocks", sizeof(buf));
273             hlen = 10;
274             break;
275         case 'M':
276             blocksize = 1024 * 1024;
277             strlcpy(buf, "1MB-blocks", sizeof(buf));
278             hlen = 10;
279             break;
280         default:
281             getbsize(&hlen, &blocksize);
282             snprintf(buf, sizeof(buf), "%ld-blocks", blocksize);
283             break;
284         }
285         
286         mibsize = sizeof mib / sizeof mib[0];
287         if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1)
288                 err(1, "sysctlnametomib()");
289         
290         if (lflag) {
291                 printf("%-13s %*s %*s\n",
292                     "Device:", 
293                     hlen, buf,
294                     hlen, "Used:");
295         }
296         
297         for (n = 0; ; ++n) {
298                 mib[mibsize] = n;
299                 size = sizeof xsw;
300                 if (sysctl(mib, mibsize + 1, &xsw, &size, NULL, 0) == -1)
301                         break;
302                 if (xsw.xsw_version != XSWDEV_VERSION)
303                         errx(1, "xswdev version mismatch");
304                 
305                 tmp_total = (long long)xsw.xsw_nblks * pagesize;
306                 tmp_used  = (long long)xsw.xsw_used * pagesize;
307                 total += tmp_total;
308                 used  += tmp_used;
309                 if (lflag) {
310                         sizetobuf(buf, sizeof(buf), hflag, tmp_total, hlen,
311                             blocksize);
312                         printf("/dev/%-8s %s ", devname(xsw.xsw_dev, S_IFCHR),
313                             buf);
314                         sizetobuf(buf, sizeof(buf), hflag, tmp_used, hlen,
315                             blocksize);
316                         printf("%s\n", buf);
317                 }
318         }
319         if (errno != ENOENT)
320                 err(1, "sysctl()");
321         
322         if (sflag) {
323                 sizetobuf(buf, sizeof(buf), hflag, total, hlen, blocksize);
324                 printf("Total:        %s ", buf);
325                 sizetobuf(buf, sizeof(buf), hflag, used, hlen, blocksize);
326                 printf("%s\n", buf);
327         }
328 }
329