]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sbin/swapon/swapon.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.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
58 static void usage(void);
59 static int swap_on_off(char *name, int ignoreebusy);
60 static void swaplist(int, int, int);
61
62 enum { SWAPON, SWAPOFF, SWAPCTL } orig_prog, which_prog = SWAPCTL;
63
64 int
65 main(int argc, char **argv)
66 {
67         struct fstab *fsp;
68         char *ptr;
69         int stat;
70         int ch, doall;
71         int sflag = 0, lflag = 0, hflag = 0;
72
73         if ((ptr = strrchr(argv[0], '/')) == NULL)
74                 ptr = argv[0];
75         if (strstr(ptr, "swapon"))
76                 which_prog = SWAPON;
77         else if (strstr(ptr, "swapoff"))
78                 which_prog = SWAPOFF;
79         orig_prog = which_prog;
80         
81         doall = 0;
82         while ((ch = getopt(argc, argv, "AadlhksU")) != -1) {
83                 switch(ch) {
84                 case 'A':
85                         if (which_prog == SWAPCTL) {
86                                 doall = 1;
87                                 which_prog = SWAPON;
88                         } else {
89                                 usage();
90                         }
91                         break;
92                 case 'a':
93                         if (which_prog == SWAPON || which_prog == SWAPOFF)
94                                 doall = 1;
95                         else
96                                 which_prog = SWAPON;
97                         break;
98                 case 'd':
99                         if (which_prog == SWAPCTL)
100                                 which_prog = SWAPOFF;
101                         else
102                                 usage();
103                         break;
104                 case 's':
105                         sflag = 1;
106                         break;
107                 case 'l':
108                         lflag = 1;
109                         break;
110                 case 'h':
111                         hflag = 'M';
112                         break;
113                 case 'k':
114                         hflag = 'K';
115                         break;
116                 case 'U':
117                         if (which_prog == SWAPCTL) {
118                                 doall = 1;
119                                 which_prog = SWAPOFF;
120                         } else {
121                                 usage();
122                         }
123                         break;
124                 case '?':
125                 default:
126                         usage();
127                 }
128         }
129         argv += optind;
130
131         stat = 0;
132         if (which_prog == SWAPON || which_prog == SWAPOFF) {
133                 if (doall) {
134                         while ((fsp = getfsent()) != NULL) {
135                                 if (strcmp(fsp->fs_type, FSTAB_SW))
136                                         continue;
137                                 if (strstr(fsp->fs_mntops, "noauto"))
138                                         continue;
139                                 if (swap_on_off(fsp->fs_spec, 1)) {
140                                         stat = 1;
141                                 } else {
142                                         printf("%s: %sing %s as swap device\n",
143                                             getprogname(), which_prog == SWAPOFF ? "remov" : "add",
144                                             fsp->fs_spec);
145                                 }
146                         }
147                 }
148                 else if (!*argv)
149                         usage();
150                 for (; *argv; ++argv) {
151                         if (swap_on_off(*argv, 0)) {
152                                 stat = 1;
153                         } else if (orig_prog == SWAPCTL) {
154                                 printf("%s: %sing %s as swap device\n",
155                                     getprogname(), which_prog == SWAPOFF ? "remov" : "add",
156                                     *argv);
157                         }
158                 }
159         } else {
160                 if (lflag || sflag)
161                         swaplist(lflag, sflag, hflag);
162                 else 
163                         usage();
164         }
165         exit(stat);
166 }
167
168 static int
169 swap_on_off(char *name, int doingall)
170 {
171         if ((which_prog == SWAPOFF ? swapoff(name) : swapon(name)) == -1) {
172                 switch (errno) {
173                 case EBUSY:
174                         if (!doingall)
175                                 warnx("%s: device already in use", name);
176                         break;
177                 case EINVAL:
178                         if (which_prog == SWAPON)
179                                 warnx("%s: NSWAPDEV limit reached", name);
180                         else if (!doingall)
181                                 warn("%s", name);
182                         break;
183                 default:
184                         warn("%s", name);
185                         break;
186                 }
187                 return(1);
188         }
189         return(0);
190 }
191
192 static void
193 usage(void)
194 {
195         fprintf(stderr, "usage: %s ", getprogname());
196         switch(orig_prog) {
197         case SWAPON:
198         case SWAPOFF:
199             fprintf(stderr, "-a | file ...\n");
200             break;
201         case SWAPCTL:
202             fprintf(stderr, "[-AhklsU] [-a file ... | -d file ...]\n");
203             break;
204         }
205         exit(1);
206 }
207
208 static void
209 swaplist(int lflag, int sflag, int hflag)
210 {
211         size_t mibsize, size;
212         struct xswdev xsw;
213         int hlen, mib[16], n, pagesize;
214         long blocksize;
215         long long total = 0;
216         long long used = 0;
217         long long tmp_total;
218         long long tmp_used;
219         
220         pagesize = getpagesize();
221         switch(hflag) {
222         case 'K':
223             blocksize = 1024;
224             hlen = 10;
225             break;
226         case 'M':
227             blocksize = 1024 * 1024;
228             hlen = 10;
229             break;
230         default:
231             getbsize(&hlen, &blocksize);
232             break;
233         }
234         
235         mibsize = sizeof mib / sizeof mib[0];
236         if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1)
237                 err(1, "sysctlnametomib()");
238         
239         if (lflag) {
240                 char buf[32];
241                 snprintf(buf, sizeof(buf), "%ld-blocks", blocksize);
242                 printf("%-13s %*s %*s\n",
243                     "Device:", 
244                     hlen, buf,
245                     hlen, "Used:");
246         }
247         
248         for (n = 0; ; ++n) {
249                 mib[mibsize] = n;
250                 size = sizeof xsw;
251                 if (sysctl(mib, mibsize + 1, &xsw, &size, NULL, 0) == -1)
252                         break;
253                 if (xsw.xsw_version != XSWDEV_VERSION)
254                         errx(1, "xswdev version mismatch");
255                 
256                 tmp_total = (long long)xsw.xsw_nblks * pagesize / blocksize;
257                 tmp_used  = (long long)xsw.xsw_used * pagesize / blocksize;
258                 total += tmp_total;
259                 used  += tmp_used;
260                 if (lflag) {
261                         printf("/dev/%-8s %*lld %*lld\n", 
262                             devname(xsw.xsw_dev, S_IFCHR),
263                             hlen, tmp_total,
264                             hlen, tmp_used);
265                 }
266         }
267         if (errno != ENOENT)
268                 err(1, "sysctl()");
269         
270         if (sflag) {
271                 printf("Total:        %*lld %*lld\n",
272                        hlen, total,
273                        hlen, used);
274         }
275 }
276