| @@ -1,873 +1,881 @@ | | | @@ -1,873 +1,881 @@ |
1 | /* $NetBSD: swapctl.c,v 1.39 2013/01/01 19:01:10 dsl Exp $ */ | | 1 | /* $NetBSD: swapctl.c,v 1.40 2015/10/11 23:58:16 mrg Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1996, 1997, 1999 Matthew R. Green | | 4 | * Copyright (c) 1996, 1997, 1999, 2015 Matthew R. Green |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
15 | * | | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 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 | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 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 | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | /* | | 29 | /* |
30 | * swapctl command: | | 30 | * swapctl command: |
31 | * -A add all devices listed as `sw' in /etc/fstab (also | | 31 | * -A add all devices listed as `sw' in /etc/fstab (also |
32 | * (sets the dump device, if listed in fstab) | | 32 | * (sets the dump device, if listed in fstab) |
33 | * -D [<dev>|none] set dumpdev to <dev> or disable dumps | | 33 | * -D [<dev>|none] set dumpdev to <dev> or disable dumps |
34 | * -z show dumpdev | | 34 | * -z show dumpdev |
35 | * -U remove all devices listed as `sw' in /etc/fstab. | | 35 | * -U remove all devices listed as `sw' in /etc/fstab. |
36 | * -t [blk|noblk|auto] | | 36 | * -t [blk|noblk|auto] |
37 | * if -A or -U , add (remove) either all block device | | 37 | * if -A or -U , add (remove) either all block device |
38 | * or all non-block devices, or all swap partitions | | 38 | * or all non-block devices, or all swap partitions |
39 | * -q check if any swap or dump devices are defined in | | 39 | * -q check if any swap or dump devices are defined in |
40 | * /etc/fstab | | 40 | * /etc/fstab |
41 | * -a <dev> add this device | | 41 | * -a <dev> add this device |
42 | * -d <dev> remove this swap device | | 42 | * -d <dev> remove this swap device |
43 | * -f with -A -t auto, use the first swap as dump device | | 43 | * -f with -A -t auto, use the first swap as dump device |
44 | * -g use gigabytes | | 44 | * -g use gigabytes |
45 | * -h use humanize_number(3) for listing | | 45 | * -h use humanize_number(3) for listing |
46 | * -l list swap devices | | 46 | * -l list swap devices |
47 | * -m use megabytes | | 47 | * -m use megabytes |
48 | * -n print actions, but do not add/remove swap or | | 48 | * -n print actions, but do not add/remove swap or |
49 | * with -A/-U | | 49 | * with -A/-U |
50 | * -o with -A -t auto only configure the first swap as dump, | | 50 | * -o with -A -t auto only configure the first swap as dump, |
51 | * (similar to -f), but do not add any further swap devs | | 51 | * (similar to -f), but do not add any further swap devs |
52 | * -s short listing of swap devices | | 52 | * -s short listing of swap devices |
53 | * -k use kilobytes | | 53 | * -k use kilobytes |
54 | * -p <pri> use this priority | | 54 | * -p <pri> use this priority |
55 | * -c change priority | | 55 | * -c change priority |
56 | * | | 56 | * |
57 | * or, if invoked as "swapon" (compatibility mode): | | 57 | * or, if invoked as "swapon" (compatibility mode): |
58 | * | | 58 | * |
59 | * -a all devices listed as `sw' in /etc/fstab | | 59 | * -a all devices listed as `sw' in /etc/fstab |
60 | * -t same as -t above (feature not present in old | | 60 | * -t same as -t above (feature not present in old |
61 | * swapon(8) command) | | 61 | * swapon(8) command) |
62 | * <dev> add this device | | 62 | * <dev> add this device |
63 | */ | | 63 | */ |
64 | #include <sys/cdefs.h> | | 64 | #include <sys/cdefs.h> |
65 | | | 65 | |
66 | #ifndef lint | | 66 | #ifndef lint |
67 | __RCSID("$NetBSD: swapctl.c,v 1.39 2013/01/01 19:01:10 dsl Exp $"); | | 67 | __RCSID("$NetBSD: swapctl.c,v 1.40 2015/10/11 23:58:16 mrg Exp $"); |
68 | #endif | | 68 | #endif |
69 | | | 69 | |
70 | | | 70 | |
71 | #include <sys/param.h> | | 71 | #include <sys/param.h> |
72 | #include <sys/ioctl.h> | | 72 | #include <sys/ioctl.h> |
73 | #include <sys/stat.h> | | 73 | #include <sys/stat.h> |
74 | #include <sys/swap.h> | | 74 | #include <sys/swap.h> |
75 | #include <sys/sysctl.h> | | 75 | #include <sys/sysctl.h> |
76 | #include <sys/disk.h> | | 76 | #include <sys/disk.h> |
77 | #include <sys/disklabel.h> | | 77 | #include <sys/disklabel.h> |
78 | | | 78 | |
79 | #include <unistd.h> | | 79 | #include <unistd.h> |
80 | #include <err.h> | | 80 | #include <err.h> |
81 | #include <errno.h> | | 81 | #include <errno.h> |
82 | #include <stdio.h> | | 82 | #include <stdio.h> |
83 | #include <stdlib.h> | | 83 | #include <stdlib.h> |
84 | #include <string.h> | | 84 | #include <string.h> |
85 | #include <fstab.h> | | 85 | #include <fstab.h> |
86 | #include <fcntl.h> | | 86 | #include <fcntl.h> |
87 | #include <util.h> | | 87 | #include <util.h> |
88 | #include <paths.h> | | 88 | #include <paths.h> |
89 | | | 89 | |
90 | #include "swapctl.h" | | 90 | #include "swapctl.h" |
91 | | | 91 | |
92 | static int command; | | 92 | static int command; |
93 | | | 93 | |
94 | /* | | 94 | /* |
95 | * Commands for swapctl(8). These are mutually exclusive. | | 95 | * Commands for swapctl(8). These are mutually exclusive. |
96 | */ | | 96 | */ |
97 | #define CMD_A 0x01 /* process /etc/fstab for adding */ | | 97 | #define CMD_A 0x01 /* process /etc/fstab for adding */ |
98 | #define CMD_D 0x02 /* set dumpdev */ | | 98 | #define CMD_D 0x02 /* set dumpdev */ |
99 | #define CMD_U 0x04 /* process /etc/fstab for removing */ | | 99 | #define CMD_U 0x04 /* process /etc/fstab for removing */ |
100 | #define CMD_a 0x08 /* add a swap file/device */ | | 100 | #define CMD_a 0x08 /* add a swap file/device */ |
101 | #define CMD_c 0x10 /* change priority of a swap file/device */ | | 101 | #define CMD_c 0x10 /* change priority of a swap file/device */ |
102 | #define CMD_d 0x20 /* delete a swap file/device */ | | 102 | #define CMD_d 0x20 /* delete a swap file/device */ |
103 | #define CMD_l 0x40 /* list swap files/devices */ | | 103 | #define CMD_l 0x40 /* list swap files/devices */ |
104 | #define CMD_s 0x80 /* summary of swap files/devices */ | | 104 | #define CMD_s 0x80 /* summary of swap files/devices */ |
105 | #define CMD_z 0x100 /* show dump device */ | | 105 | #define CMD_z 0x100 /* show dump device */ |
106 | #define CMD_q 0x200 /* check for dump/swap in /etc/fstab */ | | 106 | #define CMD_q 0x200 /* check for dump/swap in /etc/fstab */ |
107 | | | 107 | |
108 | #define SET_COMMAND(cmd) \ | | 108 | #define SET_COMMAND(cmd) \ |
109 | do { \ | | 109 | do { \ |
110 | if (command) \ | | 110 | if (command) \ |
111 | usage(); \ | | 111 | usage(); \ |
112 | command = (cmd); \ | | 112 | command = (cmd); \ |
113 | } while (0) | | 113 | } while (0) |
114 | | | 114 | |
115 | /* | | 115 | /* |
116 | * Commands that require a "path" argument at the end of the command | | 116 | * Commands that require a "path" argument at the end of the command |
117 | * line, and the ones which require that none exist. | | 117 | * line, and the ones which require that none exist. |
118 | */ | | 118 | */ |
119 | #define REQUIRE_PATH (CMD_D | CMD_a | CMD_c | CMD_d) | | 119 | #define REQUIRE_PATH (CMD_D | CMD_a | CMD_c | CMD_d) |
120 | #define REQUIRE_NOPATH (CMD_A | CMD_U | CMD_l | CMD_s | CMD_z | CMD_q) | | 120 | #define REQUIRE_NOPATH (CMD_A | CMD_U | CMD_l | CMD_s | CMD_z | CMD_q) |
121 | | | 121 | |
122 | /* | | 122 | /* |
123 | * Option flags, and the commands with which they are valid. | | 123 | * Option flags, and the commands with which they are valid. |
124 | */ | | 124 | */ |
125 | static int kflag; /* display in 1K^x blocks */ | | 125 | static int kflag; /* display in 1K^x blocks */ |
126 | #define KFLAG_CMDS (CMD_l | CMD_s) | | 126 | #define KFLAG_CMDS (CMD_l | CMD_s) |
127 | #define MFLAG_CMDS (CMD_l | CMD_s) | | 127 | #define MFLAG_CMDS (CMD_l | CMD_s) |
128 | #define GFLAG_CMDS (CMD_l | CMD_s) | | 128 | #define GFLAG_CMDS (CMD_l | CMD_s) |
129 | | | 129 | |
130 | static int hflag; /* display with humanize_number */ | | 130 | static int hflag; /* display with humanize_number */ |
131 | #define HFLAG_CMDS (CMD_l | CMD_s) | | 131 | #define HFLAG_CMDS (CMD_l | CMD_s) |
132 | | | 132 | |
133 | static int pflag; /* priority was specified */ | | 133 | static int pflag; /* priority was specified */ |
134 | #define PFLAG_CMDS (CMD_A | CMD_a | CMD_c) | | 134 | #define PFLAG_CMDS (CMD_A | CMD_a | CMD_c) |
135 | | | 135 | |
136 | static char *tflag; /* swap device type (blk, noblk, auto) */ | | 136 | static char *tflag; /* swap device type (blk, noblk, auto) */ |
137 | static int autoflag; /* 1, if tflag is "auto" */ | | 137 | static int autoflag; /* 1, if tflag is "auto" */ |
138 | #define TFLAG_CMDS (CMD_A | CMD_U) | | 138 | #define TFLAG_CMDS (CMD_A | CMD_U) |
139 | | | 139 | |
140 | static int fflag; /* first swap becomes dump */ | | 140 | static int fflag; /* first swap becomes dump */ |
141 | #define FFLAG_CMDS (CMD_A) | | 141 | #define FFLAG_CMDS (CMD_A) |
142 | | | 142 | |
143 | static int oflag; /* only autoset dump device */ | | 143 | static int oflag; /* only autoset dump device */ |
144 | #define OFLAG_CMDS (CMD_A) | | 144 | #define OFLAG_CMDS (CMD_A) |
145 | | | 145 | |
146 | static int nflag; /* no execute, just print actions */ | | 146 | static int nflag; /* no execute, just print actions */ |
147 | #define NFLAG_CMDS (CMD_A | CMD_U) | | 147 | #define NFLAG_CMDS (CMD_A | CMD_U) |
148 | | | 148 | |
149 | static int pri; /* uses 0 as default pri */ | | 149 | static int pri; /* uses 0 as default pri */ |
150 | | | 150 | |
151 | static void change_priority(char *); | | 151 | static void change_priority(char *); |
152 | static int add_swap(char *, int); | | 152 | static int add_swap(char *, int); |
153 | static int delete_swap(char *); | | 153 | static int delete_swap(char *); |
154 | static void set_dumpdev1(char *); | | 154 | static int set_dumpdev1(char *); |
155 | static void set_dumpdev(char *); | | 155 | static void set_dumpdev(char *); |
156 | static int get_dumpdev(void); | | 156 | static int get_dumpdev(void); |
157 | __dead static void do_fstab(int); | | 157 | __dead static void do_fstab(int); |
158 | static int check_fstab(void); | | 158 | static int check_fstab(void); |
159 | static void do_localdevs(int); | | 159 | static void do_localdevs(int); |
160 | static void do_localdisk(const char *, int); | | 160 | static void do_localdisk(const char *, int); |
161 | static int do_wedgesofdisk(int fd, int); | | 161 | static int do_wedgesofdisk(int fd, int); |
162 | static int do_partitionsofdisk(const char *, int fd, int); | | 162 | static int do_partitionsofdisk(const char *, int fd, int); |
163 | __dead static void usage(void); | | 163 | __dead static void usage(void); |
164 | __dead static void swapon_command(int, char **); | | 164 | __dead static void swapon_command(int, char **); |
165 | #if 0 | | 165 | #if 0 |
166 | static void swapoff_command(int, char **); | | 166 | static void swapoff_command(int, char **); |
167 | #endif | | 167 | #endif |
168 | | | 168 | |
169 | int | | 169 | int |
170 | main(int argc, char *argv[]) | | 170 | main(int argc, char *argv[]) |
171 | { | | 171 | { |
172 | int c; | | 172 | int c; |
173 | | | 173 | |
174 | if (strcmp(getprogname(), "swapon") == 0) { | | 174 | if (strcmp(getprogname(), "swapon") == 0) { |
175 | swapon_command(argc, argv); | | 175 | swapon_command(argc, argv); |
176 | /* NOTREACHED */ | | 176 | /* NOTREACHED */ |
177 | } | | 177 | } |
178 | | | 178 | |
179 | #if 0 | | 179 | #if 0 |
180 | if (strcmp(getprogname(), "swapoff") == 0) { | | 180 | if (strcmp(getprogname(), "swapoff") == 0) { |
181 | swapoff_command(argc, argv); | | 181 | swapoff_command(argc, argv); |
182 | /* NOTREACHED */ | | 182 | /* NOTREACHED */ |
183 | } | | 183 | } |
184 | #endif | | 184 | #endif |
185 | | | 185 | |
186 | while ((c = getopt(argc, argv, "ADUacdfghklmnop:qst:z")) != -1) { | | 186 | while ((c = getopt(argc, argv, "ADUacdfghklmnop:qst:z")) != -1) { |
187 | switch (c) { | | 187 | switch (c) { |
188 | case 'A': | | 188 | case 'A': |
189 | SET_COMMAND(CMD_A); | | 189 | SET_COMMAND(CMD_A); |
190 | break; | | 190 | break; |
191 | | | 191 | |
192 | case 'D': | | 192 | case 'D': |
193 | SET_COMMAND(CMD_D); | | 193 | SET_COMMAND(CMD_D); |
194 | break; | | 194 | break; |
195 | | | 195 | |
196 | case 'U': | | 196 | case 'U': |
197 | SET_COMMAND(CMD_U); | | 197 | SET_COMMAND(CMD_U); |
198 | break; | | 198 | break; |
199 | | | 199 | |
200 | case 'a': | | 200 | case 'a': |
201 | SET_COMMAND(CMD_a); | | 201 | SET_COMMAND(CMD_a); |
202 | break; | | 202 | break; |
203 | | | 203 | |
204 | case 'c': | | 204 | case 'c': |
205 | SET_COMMAND(CMD_c); | | 205 | SET_COMMAND(CMD_c); |
206 | break; | | 206 | break; |
207 | | | 207 | |
208 | case 'd': | | 208 | case 'd': |
209 | SET_COMMAND(CMD_d); | | 209 | SET_COMMAND(CMD_d); |
210 | break; | | 210 | break; |
211 | | | 211 | |
212 | case 'f': | | 212 | case 'f': |
213 | fflag = 1; | | 213 | fflag = 1; |
214 | break; | | 214 | break; |
215 | | | 215 | |
216 | case 'g': | | 216 | case 'g': |
217 | kflag = 3; /* 1k ^ 3 */ | | 217 | kflag = 3; /* 1k ^ 3 */ |
218 | break; | | 218 | break; |
219 | | | 219 | |
220 | case 'h': | | 220 | case 'h': |
221 | hflag = 1; | | 221 | hflag = 1; |
222 | break; | | 222 | break; |
223 | | | 223 | |
224 | case 'k': | | 224 | case 'k': |
225 | kflag = 1; | | 225 | kflag = 1; |
226 | break; | | 226 | break; |
227 | | | 227 | |
228 | case 'l': | | 228 | case 'l': |
229 | SET_COMMAND(CMD_l); | | 229 | SET_COMMAND(CMD_l); |
230 | break; | | 230 | break; |
231 | | | 231 | |
232 | case 'm': | | 232 | case 'm': |
233 | kflag = 2; /* 1k ^ 2 */ | | 233 | kflag = 2; /* 1k ^ 2 */ |
234 | break; | | 234 | break; |
235 | | | 235 | |
236 | case 'n': | | 236 | case 'n': |
237 | nflag = 1; | | 237 | nflag = 1; |
238 | break; | | 238 | break; |
239 | | | 239 | |
240 | case 'o': | | 240 | case 'o': |
241 | oflag = 1; | | 241 | oflag = 1; |
242 | break; | | 242 | break; |
243 | | | 243 | |
244 | case 'p': | | 244 | case 'p': |
245 | pflag = 1; | | 245 | pflag = 1; |
246 | /* XXX strtol() */ | | 246 | /* XXX strtol() */ |
247 | pri = atoi(optarg); | | 247 | pri = atoi(optarg); |
248 | break; | | 248 | break; |
249 | | | 249 | |
250 | case 'q': | | 250 | case 'q': |
251 | SET_COMMAND(CMD_q); | | 251 | SET_COMMAND(CMD_q); |
252 | break; | | 252 | break; |
253 | | | 253 | |
254 | case 's': | | 254 | case 's': |
255 | SET_COMMAND(CMD_s); | | 255 | SET_COMMAND(CMD_s); |
256 | break; | | 256 | break; |
257 | | | 257 | |
258 | case 't': | | 258 | case 't': |
259 | if (tflag != NULL) | | 259 | if (tflag != NULL) |
260 | usage(); | | 260 | usage(); |
261 | tflag = optarg; | | 261 | tflag = optarg; |
262 | if (strcmp(tflag, "auto") == 0) | | 262 | if (strcmp(tflag, "auto") == 0) |
263 | autoflag = 1; | | 263 | autoflag = 1; |
264 | break; | | 264 | break; |
265 | | | 265 | |
266 | case 'z': | | 266 | case 'z': |
267 | SET_COMMAND(CMD_z); | | 267 | SET_COMMAND(CMD_z); |
268 | break; | | 268 | break; |
269 | | | 269 | |
270 | default: | | 270 | default: |
271 | usage(); | | 271 | usage(); |
272 | /* NOTREACHED */ | | 272 | /* NOTREACHED */ |
273 | } | | 273 | } |
274 | } | | 274 | } |
275 | | | 275 | |
276 | /* Did the user specify a command? */ | | 276 | /* Did the user specify a command? */ |
277 | if (command == 0) | | 277 | if (command == 0) |
278 | usage(); | | 278 | usage(); |
279 | | | 279 | |
280 | argv += optind; | | 280 | argv += optind; |
281 | argc -= optind; | | 281 | argc -= optind; |
282 | | | 282 | |
283 | switch (argc) { | | 283 | switch (argc) { |
284 | case 0: | | 284 | case 0: |
285 | if (command & REQUIRE_PATH) | | 285 | if (command & REQUIRE_PATH) |
286 | usage(); | | 286 | usage(); |
287 | break; | | 287 | break; |
288 | | | 288 | |
289 | case 1: | | 289 | case 1: |
290 | if (command & REQUIRE_NOPATH) | | 290 | if (command & REQUIRE_NOPATH) |
291 | usage(); | | 291 | usage(); |
292 | break; | | 292 | break; |
293 | | | 293 | |
294 | default: | | 294 | default: |
295 | usage(); | | 295 | usage(); |
296 | } | | 296 | } |
297 | | | 297 | |
298 | /* To change priority, you have to specify one. */ | | 298 | /* To change priority, you have to specify one. */ |
299 | if ((command == CMD_c) && pflag == 0) | | 299 | if ((command == CMD_c) && pflag == 0) |
300 | usage(); | | 300 | usage(); |
301 | | | 301 | |
302 | /* -f and -o are mutualy exclusive */ | | 302 | /* -f and -o are mutualy exclusive */ |
303 | if (fflag && oflag) | | 303 | if (fflag && oflag) |
304 | usage(); | | 304 | usage(); |
305 | | | 305 | |
306 | /* Sanity-check -t */ | | 306 | /* Sanity-check -t */ |
307 | if (tflag != NULL) { | | 307 | if (tflag != NULL) { |
308 | if (command != CMD_A && command != CMD_U) | | 308 | if (command != CMD_A && command != CMD_U) |
309 | usage(); | | 309 | usage(); |
310 | if (strcmp(tflag, "blk") != 0 && | | 310 | if (strcmp(tflag, "blk") != 0 && |
311 | strcmp(tflag, "noblk") != 0 && | | 311 | strcmp(tflag, "noblk") != 0 && |
312 | strcmp(tflag, "auto") != 0) | | 312 | strcmp(tflag, "auto") != 0) |
313 | usage(); | | 313 | usage(); |
314 | } | | 314 | } |
315 | | | 315 | |
316 | /* Dispatch the command. */ | | 316 | /* Dispatch the command. */ |
317 | switch (command) { | | 317 | switch (command) { |
318 | case CMD_l: | | 318 | case CMD_l: |
319 | if (!list_swap(pri, kflag, pflag, 0, 1, hflag)) | | 319 | if (!list_swap(pri, kflag, pflag, 0, 1, hflag)) |
320 | exit(1); | | 320 | exit(1); |
321 | break; | | 321 | break; |
322 | | | 322 | |
323 | case CMD_s: | | 323 | case CMD_s: |
324 | list_swap(pri, kflag, pflag, 0, 0, hflag); | | 324 | list_swap(pri, kflag, pflag, 0, 0, hflag); |
325 | break; | | 325 | break; |
326 | | | 326 | |
327 | case CMD_c: | | 327 | case CMD_c: |
328 | change_priority(argv[0]); | | 328 | change_priority(argv[0]); |
329 | break; | | 329 | break; |
330 | | | 330 | |
331 | case CMD_a: | | 331 | case CMD_a: |
332 | if (! add_swap(argv[0], pri)) | | 332 | if (! add_swap(argv[0], pri)) |
333 | exit(1); | | 333 | exit(1); |
334 | break; | | 334 | break; |
335 | | | 335 | |
336 | case CMD_d: | | 336 | case CMD_d: |
337 | if (! delete_swap(argv[0])) | | 337 | if (! delete_swap(argv[0])) |
338 | exit(1); | | 338 | exit(1); |
339 | break; | | 339 | break; |
340 | | | 340 | |
341 | case CMD_A: | | 341 | case CMD_A: |
342 | if (autoflag) | | 342 | if (autoflag) |
343 | do_localdevs(1); | | 343 | do_localdevs(1); |
344 | else | | 344 | else |
345 | do_fstab(1); | | 345 | do_fstab(1); |
346 | break; | | 346 | break; |
347 | | | 347 | |
348 | case CMD_D: | | 348 | case CMD_D: |
349 | set_dumpdev(argv[0]); | | 349 | set_dumpdev(argv[0]); |
350 | break; | | 350 | break; |
351 | | | 351 | |
352 | case CMD_z: | | 352 | case CMD_z: |
353 | if (!get_dumpdev()) | | 353 | if (!get_dumpdev()) |
354 | exit(1); | | 354 | exit(1); |
355 | break; | | 355 | break; |
356 | | | 356 | |
357 | case CMD_U: | | 357 | case CMD_U: |
358 | if (autoflag) | | 358 | if (autoflag) |
359 | do_localdevs(0); | | 359 | do_localdevs(0); |
360 | else | | 360 | else |
361 | do_fstab(0); | | 361 | do_fstab(0); |
362 | break; | | 362 | break; |
363 | case CMD_q: | | 363 | case CMD_q: |
364 | if (check_fstab()) { | | 364 | if (check_fstab()) { |
365 | printf("%s: there are swap or dump devices defined in " | | 365 | printf("%s: there are swap or dump devices defined in " |
366 | _PATH_FSTAB "\n", getprogname()); | | 366 | _PATH_FSTAB "\n", getprogname()); |
367 | exit(0); | | 367 | exit(0); |
368 | } else { | | 368 | } else { |
369 | printf("%s: no swap or dump devices in " | | 369 | printf("%s: no swap or dump devices in " |
370 | _PATH_FSTAB "\n", getprogname()); | | 370 | _PATH_FSTAB "\n", getprogname()); |
371 | exit(1); | | 371 | exit(1); |
372 | } | | 372 | } |
373 | } | | 373 | } |
374 | | | 374 | |
375 | exit(0); | | 375 | exit(0); |
376 | } | | 376 | } |
377 | | | 377 | |
378 | /* | | 378 | /* |
379 | * swapon_command: emulate the old swapon(8) program. | | 379 | * swapon_command: emulate the old swapon(8) program. |
380 | */ | | 380 | */ |
381 | static void | | 381 | static void |
382 | swapon_command(int argc, char **argv) | | 382 | swapon_command(int argc, char **argv) |
383 | { | | 383 | { |
384 | int ch, fiztab = 0; | | 384 | int ch, fiztab = 0; |
385 | | | 385 | |
386 | while ((ch = getopt(argc, argv, "at:")) != -1) { | | 386 | while ((ch = getopt(argc, argv, "at:")) != -1) { |
387 | switch (ch) { | | 387 | switch (ch) { |
388 | case 'a': | | 388 | case 'a': |
389 | fiztab = 1; | | 389 | fiztab = 1; |
390 | break; | | 390 | break; |
391 | case 't': | | 391 | case 't': |
392 | if (tflag != NULL) | | 392 | if (tflag != NULL) |
393 | usage(); | | 393 | usage(); |
394 | tflag = optarg; | | 394 | tflag = optarg; |
395 | break; | | 395 | break; |
396 | default: | | 396 | default: |
397 | goto swapon_usage; | | 397 | goto swapon_usage; |
398 | } | | 398 | } |
399 | } | | 399 | } |
400 | argc -= optind; | | 400 | argc -= optind; |
401 | argv += optind; | | 401 | argv += optind; |
402 | | | 402 | |
403 | if (fiztab) { | | 403 | if (fiztab) { |
404 | if (argc) | | 404 | if (argc) |
405 | goto swapon_usage; | | 405 | goto swapon_usage; |
406 | /* Sanity-check -t */ | | 406 | /* Sanity-check -t */ |
407 | if (tflag != NULL) { | | 407 | if (tflag != NULL) { |
408 | if (strcmp(tflag, "blk") != 0 && | | 408 | if (strcmp(tflag, "blk") != 0 && |
409 | strcmp(tflag, "noblk") != 0) | | 409 | strcmp(tflag, "noblk") != 0) |
410 | usage(); | | 410 | usage(); |
411 | } | | 411 | } |
412 | do_fstab(1); | | 412 | do_fstab(1); |
413 | exit(0); | | 413 | exit(0); |
414 | } else if (argc == 0 || tflag != NULL) | | 414 | } else if (argc == 0 || tflag != NULL) |
415 | goto swapon_usage; | | 415 | goto swapon_usage; |
416 | | | 416 | |
417 | while (argc) { | | 417 | while (argc) { |
418 | if (! add_swap(argv[0], pri)) | | 418 | if (! add_swap(argv[0], pri)) |
419 | exit(1); | | 419 | exit(1); |
420 | argc--; | | 420 | argc--; |
421 | argv++; | | 421 | argv++; |
422 | } | | 422 | } |
423 | exit(0); | | 423 | exit(0); |
424 | /* NOTREACHED */ | | 424 | /* NOTREACHED */ |
425 | | | 425 | |
426 | swapon_usage: | | 426 | swapon_usage: |
427 | fprintf(stderr, "usage: %s -a [-t blk|noblk]\n", getprogname()); | | 427 | fprintf(stderr, "usage: %s -a [-t blk|noblk]\n", getprogname()); |
428 | fprintf(stderr, " %s <path> ...\n", getprogname()); | | 428 | fprintf(stderr, " %s <path> ...\n", getprogname()); |
429 | exit(1); | | 429 | exit(1); |
430 | } | | 430 | } |
431 | | | 431 | |
432 | /* | | 432 | /* |
433 | * change_priority: change the priority of a swap device. | | 433 | * change_priority: change the priority of a swap device. |
434 | */ | | 434 | */ |
435 | static void | | 435 | static void |
436 | change_priority(char *path) | | 436 | change_priority(char *path) |
437 | { | | 437 | { |
438 | | | 438 | |
439 | if (swapctl(SWAP_CTL, path, pri) < 0) | | 439 | if (swapctl(SWAP_CTL, path, pri) < 0) |
440 | err(1, "%s", path); | | 440 | err(1, "%s", path); |
441 | } | | 441 | } |
442 | | | 442 | |
443 | /* | | 443 | /* |
444 | * add_swap: add the pathname to the list of swap devices. | | 444 | * add_swap: add the pathname to the list of swap devices. |
445 | */ | | 445 | */ |
446 | static int | | 446 | static int |
447 | add_swap(char *path, int priority) | | 447 | add_swap(char *path, int priority) |
448 | { | | 448 | { |
449 | struct stat sb; | | 449 | struct stat sb; |
450 | char buf[MAXPATHLEN]; | | 450 | char buf[MAXPATHLEN]; |
451 | char *spec; | | 451 | char *spec; |
452 | | | 452 | |
453 | if (getfsspecname(buf, sizeof(buf), path) == NULL) | | 453 | if (getfsspecname(buf, sizeof(buf), path) == NULL) |
454 | goto oops; | | 454 | goto oops; |
455 | spec = buf; | | 455 | spec = buf; |
456 | | | 456 | |
457 | if (stat(spec, &sb) < 0) | | 457 | if (stat(spec, &sb) < 0) |
458 | goto oops; | | 458 | goto oops; |
459 | | | 459 | |
460 | if (sb.st_mode & S_IROTH) | | 460 | if (sb.st_mode & S_IROTH) |
461 | warnx("WARNING: %s is readable by the world", path); | | 461 | warnx("WARNING: %s is readable by the world", path); |
462 | if (sb.st_mode & S_IWOTH) | | 462 | if (sb.st_mode & S_IWOTH) |
463 | warnx("WARNING: %s is writable by the world", path); | | 463 | warnx("WARNING: %s is writable by the world", path); |
464 | | | 464 | |
465 | if (fflag || oflag) { | | 465 | if (fflag || oflag) { |
466 | set_dumpdev1(spec); | | 466 | set_dumpdev1(spec); |
467 | if (oflag) | | 467 | if (oflag) |
468 | exit(0); | | 468 | exit(0); |
469 | else | | 469 | else |
470 | fflag = 0; | | 470 | fflag = 0; |
471 | } | | 471 | } |
472 | | | 472 | |
473 | if (nflag) | | 473 | if (nflag) |
474 | return 1; | | 474 | return 1; |
475 | | | 475 | |
476 | if (swapctl(SWAP_ON, spec, priority) < 0) { | | 476 | if (swapctl(SWAP_ON, spec, priority) < 0) { |
477 | oops: | | 477 | oops: |
478 | err(1, "%s", path); | | 478 | warn("%s", path); |
| | | 479 | return 0; |
479 | } | | 480 | } |
480 | return (1); | | 481 | return 1; |
481 | } | | 482 | } |
482 | | | 483 | |
483 | /* | | 484 | /* |
484 | * delete_swap: remove the pathname to the list of swap devices. | | 485 | * delete_swap: remove the pathname to the list of swap devices. |
485 | */ | | 486 | */ |
486 | static int | | 487 | static int |
487 | delete_swap(char *path) | | 488 | delete_swap(char *path) |
488 | { | | 489 | { |
489 | char buf[MAXPATHLEN]; | | 490 | char buf[MAXPATHLEN]; |
490 | char *spec; | | 491 | char *spec; |
491 | | | 492 | |
492 | if (getfsspecname(buf, sizeof(buf), path) == NULL) | | 493 | if (getfsspecname(buf, sizeof(buf), path) == NULL) { |
493 | err(1, "%s", path); | | 494 | warn("%s", path); |
| | | 495 | return 0; |
| | | 496 | } |
494 | spec = buf; | | 497 | spec = buf; |
495 | | | 498 | |
496 | if (nflag) | | 499 | if (nflag) |
497 | return 1; | | 500 | return 1; |
498 | | | 501 | |
499 | if (swapctl(SWAP_OFF, spec, pri) < 0) | | 502 | if (swapctl(SWAP_OFF, spec, pri) < 0) { |
500 | err(1, "%s", path); | | 503 | warn("%s", path); |
501 | return (1); | | 504 | return 0; |
| | | 505 | } |
| | | 506 | return 1; |
502 | } | | 507 | } |
503 | | | 508 | |
504 | static void | | 509 | static int |
505 | set_dumpdev1(char *spec) | | 510 | set_dumpdev1(char *spec) |
506 | { | | 511 | { |
507 | int rv = 0; | | 512 | int rv = 0; |
508 | | | 513 | |
509 | if (!nflag) { | | 514 | if (!nflag) { |
510 | if (strcmp(spec, "none") == 0) | | 515 | if (strcmp(spec, "none") == 0) |
511 | rv = swapctl(SWAP_DUMPOFF, NULL, 0); | | 516 | rv = swapctl(SWAP_DUMPOFF, NULL, 0); |
512 | else | | 517 | else |
513 | rv = swapctl(SWAP_DUMPDEV, spec, 0); | | 518 | rv = swapctl(SWAP_DUMPDEV, spec, 0); |
514 | } | | 519 | } |
515 | | | 520 | |
516 | if (rv == -1) | | 521 | if (rv == -1) |
517 | err(1, "could not set dump device to %s", spec); | | 522 | warn("could not set dump device to %s", spec); |
518 | else | | 523 | else |
519 | printf("%s: setting dump device to %s\n", getprogname(), spec); | | 524 | printf("%s: setting dump device to %s\n", getprogname(), spec); |
| | | 525 | |
| | | 526 | return rv == -1 ? 0 : 1; |
520 | } | | 527 | } |
521 | | | 528 | |
522 | static void | | 529 | static void |
523 | set_dumpdev(char *path) | | 530 | set_dumpdev(char *path) |
524 | { | | 531 | { |
525 | char buf[MAXPATHLEN]; | | 532 | char buf[MAXPATHLEN]; |
526 | char *spec; | | 533 | char *spec; |
527 | | | 534 | |
528 | if (getfsspecname(buf, sizeof(buf), path) == NULL) | | 535 | if (getfsspecname(buf, sizeof(buf), path) == NULL) |
529 | err(1, "%s", path); | | 536 | err(1, "%s", path); |
530 | spec = buf; | | 537 | spec = buf; |
531 | | | 538 | |
532 | return set_dumpdev1(spec); | | 539 | if (! set_dumpdev1(spec)) |
| | | 540 | exit(1); |
533 | } | | 541 | } |
534 | | | 542 | |
535 | static int | | 543 | static int |
536 | get_dumpdev(void) | | 544 | get_dumpdev(void) |
537 | { | | 545 | { |
538 | dev_t dev; | | 546 | dev_t dev; |
539 | char *name; | | 547 | char *name; |
540 | | | 548 | |
541 | if (swapctl(SWAP_GETDUMPDEV, &dev, 0) == -1) { | | 549 | if (swapctl(SWAP_GETDUMPDEV, &dev, 0) == -1) { |
542 | warn("could not get dump device"); | | 550 | warn("could not get dump device"); |
543 | return 0; | | 551 | return 0; |
544 | } else if (dev == NODEV) { | | 552 | } else if (dev == NODEV) { |
545 | printf("no dump device set\n"); | | 553 | printf("no dump device set\n"); |
546 | return 0; | | 554 | return 0; |
547 | } else { | | 555 | } else { |
548 | name = devname(dev, S_IFBLK); | | 556 | name = devname(dev, S_IFBLK); |
549 | printf("dump device is "); | | 557 | printf("dump device is "); |
550 | if (name) | | 558 | if (name) |
551 | printf("%s\n", name); | | 559 | printf("%s\n", name); |
552 | else | | 560 | else |
553 | printf("major %llu minor %llu\n", | | 561 | printf("major %llu minor %llu\n", |
554 | (unsigned long long)major(dev), | | 562 | (unsigned long long)major(dev), |
555 | (unsigned long long)minor(dev)); | | 563 | (unsigned long long)minor(dev)); |
556 | } | | 564 | } |
557 | return 1; | | 565 | return 1; |
558 | } | | 566 | } |
559 | | | 567 | |
560 | static void | | 568 | static void |
561 | do_localdevs(int add) | | 569 | do_localdevs(int add) |
562 | { | | 570 | { |
563 | size_t ressize; | | 571 | size_t ressize; |
564 | char *disknames, *disk; | | 572 | char *disknames, *disk; |
565 | static const char mibname[] = "hw.disknames"; | | 573 | static const char mibname[] = "hw.disknames"; |
566 | | | 574 | |
567 | ressize = 0; | | 575 | ressize = 0; |
568 | if (sysctlbyname(mibname, NULL, &ressize, NULL, 0)) | | 576 | if (sysctlbyname(mibname, NULL, &ressize, NULL, 0)) |
569 | return; | | 577 | return; |
570 | ressize += 200; /* add some arbitrary slope */ | | 578 | ressize += 200; /* add some arbitrary slope */ |
571 | disknames = malloc(ressize); | | 579 | disknames = malloc(ressize); |
572 | if (sysctlbyname(mibname, disknames, &ressize, NULL, 0) == 0) { | | 580 | if (sysctlbyname(mibname, disknames, &ressize, NULL, 0) == 0) { |
573 | for (disk = strtok(disknames, " "); disk; | | 581 | for (disk = strtok(disknames, " "); disk; |
574 | disk = strtok(NULL, " ")) | | 582 | disk = strtok(NULL, " ")) |
575 | do_localdisk(disk, add); | | 583 | do_localdisk(disk, add); |
576 | } | | 584 | } |
577 | free(disknames); | | 585 | free(disknames); |
578 | } | | 586 | } |
579 | | | 587 | |
580 | static void | | 588 | static void |
581 | do_localdisk(const char *disk, int add) | | 589 | do_localdisk(const char *disk, int add) |
582 | { | | 590 | { |
583 | int fd; | | 591 | int fd; |
584 | char dvname[MAXPATHLEN]; | | 592 | char dvname[MAXPATHLEN]; |
585 | | | 593 | |
586 | if ((fd = opendisk(disk, O_RDONLY, dvname, sizeof(dvname), 0)) == -1) | | 594 | if ((fd = opendisk(disk, O_RDONLY, dvname, sizeof(dvname), 0)) == -1) |
587 | return; | | 595 | return; |
588 | | | 596 | |
589 | if (!do_wedgesofdisk(fd, add)) | | 597 | if (!do_wedgesofdisk(fd, add)) |
590 | do_partitionsofdisk(disk, fd, add); | | 598 | do_partitionsofdisk(disk, fd, add); |
591 | | | 599 | |
592 | close(fd); | | 600 | close(fd); |
593 | } | | 601 | } |
594 | | | 602 | |
595 | static int | | 603 | static int |
596 | do_wedgesofdisk(int fd, int add) | | 604 | do_wedgesofdisk(int fd, int add) |
597 | { | | 605 | { |
598 | char devicename[MAXPATHLEN]; | | 606 | char devicename[MAXPATHLEN]; |
599 | struct dkwedge_info *dkw; | | 607 | struct dkwedge_info *dkw; |
600 | struct dkwedge_list dkwl; | | 608 | struct dkwedge_list dkwl; |
601 | size_t bufsize; | | 609 | size_t bufsize; |
602 | u_int i; | | 610 | u_int i; |
603 | | | 611 | |
604 | dkw = NULL; | | 612 | dkw = NULL; |
605 | dkwl.dkwl_buf = dkw; | | 613 | dkwl.dkwl_buf = dkw; |
606 | dkwl.dkwl_bufsize = 0; | | 614 | dkwl.dkwl_bufsize = 0; |
607 | | | 615 | |
608 | for (;;) { | | 616 | for (;;) { |
609 | if (ioctl(fd, DIOCLWEDGES, &dkwl) == -1) | | 617 | if (ioctl(fd, DIOCLWEDGES, &dkwl) == -1) |
610 | return 0; | | 618 | return 0; |
611 | if (dkwl.dkwl_nwedges == dkwl.dkwl_ncopied) | | 619 | if (dkwl.dkwl_nwedges == dkwl.dkwl_ncopied) |
612 | break; | | 620 | break; |
613 | bufsize = dkwl.dkwl_nwedges * sizeof(*dkw); | | 621 | bufsize = dkwl.dkwl_nwedges * sizeof(*dkw); |
614 | if (dkwl.dkwl_bufsize < bufsize) { | | 622 | if (dkwl.dkwl_bufsize < bufsize) { |
615 | dkw = realloc(dkwl.dkwl_buf, bufsize); | | 623 | dkw = realloc(dkwl.dkwl_buf, bufsize); |
616 | if (dkw == NULL) | | 624 | if (dkw == NULL) |
617 | return 0; | | 625 | return 0; |
618 | dkwl.dkwl_buf = dkw; | | 626 | dkwl.dkwl_buf = dkw; |
619 | dkwl.dkwl_bufsize = bufsize; | | 627 | dkwl.dkwl_bufsize = bufsize; |
620 | } | | 628 | } |
621 | } | | 629 | } |
622 | | | 630 | |
623 | for (i = 0; i < dkwl.dkwl_ncopied; i++) { | | 631 | for (i = 0; i < dkwl.dkwl_ncopied; i++) { |
624 | if (strcmp(dkw[i].dkw_ptype, DKW_PTYPE_SWAP) != 0) | | 632 | if (strcmp(dkw[i].dkw_ptype, DKW_PTYPE_SWAP) != 0) |
625 | continue; | | 633 | continue; |
626 | snprintf(devicename, sizeof(devicename), "%s%s", _PATH_DEV, | | 634 | snprintf(devicename, sizeof(devicename), "%s%s", _PATH_DEV, |
627 | dkw[i].dkw_devname); | | 635 | dkw[i].dkw_devname); |
628 | devicename[sizeof(devicename)-1] = '\0'; | | 636 | devicename[sizeof(devicename)-1] = '\0'; |
629 | | | 637 | |
630 | if (add) { | | 638 | if (add) { |
631 | if (add_swap(devicename, pri)) { | | 639 | if (add_swap(devicename, pri)) { |
632 | printf( | | 640 | printf( |
633 | "%s: adding %s as swap device at priority 0\n", | | 641 | "%s: adding %s as swap device at priority 0\n", |
634 | getprogname(), devicename); | | 642 | getprogname(), devicename); |
635 | } | | 643 | } |
636 | } else { | | 644 | } else { |
637 | if (delete_swap(devicename)) { | | 645 | if (delete_swap(devicename)) { |
638 | printf( | | 646 | printf( |
639 | "%s: removing %s as swap device\n", | | 647 | "%s: removing %s as swap device\n", |
640 | getprogname(), devicename); | | 648 | getprogname(), devicename); |
641 | } | | 649 | } |
642 | } | | 650 | } |
643 | | | 651 | |
644 | } | | 652 | } |
645 | | | 653 | |
646 | free(dkw); | | 654 | free(dkw); |
647 | return dkwl.dkwl_nwedges != 0; | | 655 | return dkwl.dkwl_nwedges != 0; |
648 | } | | 656 | } |
649 | | | 657 | |
650 | static int | | 658 | static int |
651 | do_partitionsofdisk(const char *prefix, int fd, int add) | | 659 | do_partitionsofdisk(const char *prefix, int fd, int add) |
652 | { | | 660 | { |
653 | char devicename[MAXPATHLEN]; | | 661 | char devicename[MAXPATHLEN]; |
654 | struct disklabel lab; | | 662 | struct disklabel lab; |
655 | uint i; | | 663 | uint i; |
656 | | | 664 | |
657 | if (ioctl(fd, DIOCGDINFO, &lab) != 0) | | 665 | if (ioctl(fd, DIOCGDINFO, &lab) != 0) |
658 | return 0; | | 666 | return 0; |
659 | | | 667 | |
660 | for (i = 0; i < lab.d_npartitions; i++) { | | 668 | for (i = 0; i < lab.d_npartitions; i++) { |
661 | if (lab.d_partitions[i].p_fstype != FS_SWAP) | | 669 | if (lab.d_partitions[i].p_fstype != FS_SWAP) |
662 | continue; | | 670 | continue; |
663 | snprintf(devicename, sizeof(devicename), "%s%s%c", _PATH_DEV, | | 671 | snprintf(devicename, sizeof(devicename), "%s%s%c", _PATH_DEV, |
664 | prefix, 'a'+i); | | 672 | prefix, 'a'+i); |
665 | devicename[sizeof(devicename)-1] = '\0'; | | 673 | devicename[sizeof(devicename)-1] = '\0'; |
666 | | | 674 | |
667 | if (add) { | | 675 | if (add) { |
668 | if (add_swap(devicename, pri)) { | | 676 | if (add_swap(devicename, pri)) { |
669 | printf( | | 677 | printf( |
670 | "%s: adding %s as swap device at priority 0\n", | | 678 | "%s: adding %s as swap device at priority 0\n", |
671 | getprogname(), devicename); | | 679 | getprogname(), devicename); |
672 | } | | 680 | } |
673 | } else { | | 681 | } else { |
674 | if (delete_swap(devicename)) { | | 682 | if (delete_swap(devicename)) { |
675 | printf( | | 683 | printf( |
676 | "%s: removing %s as swap device\n", | | 684 | "%s: removing %s as swap device\n", |
677 | getprogname(), devicename); | | 685 | getprogname(), devicename); |
678 | } | | 686 | } |
679 | } | | 687 | } |
680 | } | | 688 | } |
681 | | | 689 | |
682 | return 1; | | 690 | return 1; |
683 | } | | 691 | } |
684 | | | 692 | |
685 | static int | | 693 | static int |
686 | check_fstab(void) | | 694 | check_fstab(void) |
687 | { | | 695 | { |
688 | struct fstab *fp; | | 696 | struct fstab *fp; |
689 | | | 697 | |
690 | while ((fp = getfsent()) != NULL) { | | 698 | while ((fp = getfsent()) != NULL) { |
691 | if (strcmp(fp->fs_type, "dp") == 0) | | 699 | if (strcmp(fp->fs_type, "dp") == 0) |
692 | return 1; | | 700 | return 1; |
693 | | | 701 | |
694 | if (strcmp(fp->fs_type, "sw") == 0) | | 702 | if (strcmp(fp->fs_type, "sw") == 0) |
695 | return 1; | | 703 | return 1; |
696 | } | | 704 | } |
697 | | | 705 | |
698 | return 0; | | 706 | return 0; |
699 | } | | 707 | } |
700 | | | 708 | |
701 | static void | | 709 | static void |
702 | do_fstab(int add) | | 710 | do_fstab(int add) |
703 | { | | 711 | { |
704 | struct fstab *fp; | | 712 | struct fstab *fp; |
705 | char *s; | | 713 | char *s; |
706 | long priority; | | 714 | long priority; |
707 | struct stat st; | | 715 | struct stat st; |
708 | int isblk; | | 716 | int isblk; |
709 | int success = 0; /* set to 1 after a successful operation */ | | 717 | int success = 0; /* set to 1 after a successful operation */ |
710 | int error = 0; /* set to 1 after an error */ | | 718 | int error = 0; /* set to 1 after an error */ |
711 | | | 719 | |
712 | #ifdef RESCUEDIR | | 720 | #ifdef RESCUEDIR |
713 | #define PATH_MOUNT RESCUEDIR "/mount_nfs" | | 721 | #define PATH_MOUNT RESCUEDIR "/mount_nfs" |
714 | #define PATH_UMOUNT RESCUEDIR "/umount" | | 722 | #define PATH_UMOUNT RESCUEDIR "/umount" |
715 | #else | | 723 | #else |
716 | #define PATH_MOUNT "/sbin/mount_nfs" | | 724 | #define PATH_MOUNT "/sbin/mount_nfs" |
717 | #define PATH_UMOUNT "/sbin/umount" | | 725 | #define PATH_UMOUNT "/sbin/umount" |
718 | #endif | | 726 | #endif |
719 | | | 727 | |
720 | char cmd[2*PATH_MAX+sizeof(PATH_MOUNT)+2]; | | 728 | char cmd[2*PATH_MAX+sizeof(PATH_MOUNT)+2]; |
721 | | | 729 | |
722 | #define PRIORITYEQ "priority=" | | 730 | #define PRIORITYEQ "priority=" |
723 | #define NFSMNTPT "nfsmntpt=" | | 731 | #define NFSMNTPT "nfsmntpt=" |
724 | while ((fp = getfsent()) != NULL) { | | 732 | while ((fp = getfsent()) != NULL) { |
725 | char buf[MAXPATHLEN]; | | 733 | char buf[MAXPATHLEN]; |
726 | char *spec, *fsspec; | | 734 | char *spec, *fsspec; |
727 | | | 735 | |
728 | if (getfsspecname(buf, sizeof(buf), fp->fs_spec) == NULL) { | | 736 | if (getfsspecname(buf, sizeof(buf), fp->fs_spec) == NULL) { |
729 | warn("%s", buf); | | 737 | warn("%s", buf); |
730 | continue; | | 738 | continue; |
731 | } | | 739 | } |
732 | fsspec = spec = buf; | | 740 | fsspec = spec = buf; |
733 | cmd[0] = '\0'; | | 741 | cmd[0] = '\0'; |
734 | | | 742 | |
735 | if (strcmp(fp->fs_type, "dp") == 0 && add) { | | 743 | if (strcmp(fp->fs_type, "dp") == 0 && add) { |
736 | set_dumpdev1(spec); | | 744 | set_dumpdev1(spec); |
737 | continue; | | 745 | continue; |
738 | } | | 746 | } |
739 | | | 747 | |
740 | if (strcmp(fp->fs_type, "sw") != 0) | | 748 | if (strcmp(fp->fs_type, "sw") != 0) |
741 | continue; | | 749 | continue; |
742 | | | 750 | |
743 | /* handle dp as mnt option */ | | 751 | /* handle dp as mnt option */ |
744 | if (strstr(fp->fs_mntops, "dp") && add) | | 752 | if (strstr(fp->fs_mntops, "dp") && add) |
745 | set_dumpdev1(spec); | | 753 | set_dumpdev1(spec); |
746 | | | 754 | |
747 | isblk = 0; | | 755 | isblk = 0; |
748 | | | 756 | |
749 | if ((s = strstr(fp->fs_mntops, PRIORITYEQ)) != NULL) { | | 757 | if ((s = strstr(fp->fs_mntops, PRIORITYEQ)) != NULL) { |
750 | s += sizeof(PRIORITYEQ) - 1; | | 758 | s += sizeof(PRIORITYEQ) - 1; |
751 | priority = atol(s); | | 759 | priority = atol(s); |
752 | } else | | 760 | } else |
753 | priority = pri; | | 761 | priority = pri; |
754 | | | 762 | |
755 | if ((s = strstr(fp->fs_mntops, NFSMNTPT)) != NULL) { | | 763 | if ((s = strstr(fp->fs_mntops, NFSMNTPT)) != NULL) { |
756 | char *t; | | 764 | char *t; |
757 | | | 765 | |
758 | /* | | 766 | /* |
759 | * Skip this song and dance if we're only | | 767 | * Skip this song and dance if we're only |
760 | * doing block devices. | | 768 | * doing block devices. |
761 | */ | | 769 | */ |
762 | if (tflag != NULL && strcmp(tflag, "blk") == 0) | | 770 | if (tflag != NULL && strcmp(tflag, "blk") == 0) |
763 | continue; | | 771 | continue; |
764 | | | 772 | |
765 | t = strpbrk(s, ","); | | 773 | t = strpbrk(s, ","); |
766 | if (t != 0) | | 774 | if (t != 0) |
767 | *t = '\0'; | | 775 | *t = '\0'; |
768 | spec = strdup(s + strlen(NFSMNTPT)); | | 776 | spec = strdup(s + strlen(NFSMNTPT)); |
769 | if (t != 0) | | 777 | if (t != 0) |
770 | *t = ','; | | 778 | *t = ','; |
771 | | | 779 | |
772 | if (spec == NULL) | | 780 | if (spec == NULL) |
773 | errx(1, "Out of memory"); | | 781 | errx(1, "Out of memory"); |
774 | | | 782 | |
775 | if (strlen(spec) == 0) { | | 783 | if (strlen(spec) == 0) { |
776 | warnx("empty mountpoint"); | | 784 | warnx("empty mountpoint"); |
777 | free(spec); | | 785 | free(spec); |
778 | continue; | | 786 | continue; |
779 | } | | 787 | } |
780 | if (add) { | | 788 | if (add) { |
781 | snprintf(cmd, sizeof(cmd), "%s %s %s", | | 789 | snprintf(cmd, sizeof(cmd), "%s %s %s", |
782 | PATH_MOUNT, fsspec, spec); | | 790 | PATH_MOUNT, fsspec, spec); |
783 | if (system(cmd) != 0) { | | 791 | if (system(cmd) != 0) { |
784 | warnx("%s: mount failed", fsspec); | | 792 | warnx("%s: mount failed", fsspec); |
785 | continue; | | 793 | continue; |
786 | } | | 794 | } |
787 | } else { | | 795 | } else { |
788 | snprintf(cmd, sizeof(cmd), "%s %s", | | 796 | snprintf(cmd, sizeof(cmd), "%s %s", |
789 | PATH_UMOUNT, fsspec); | | 797 | PATH_UMOUNT, fsspec); |
790 | } | | 798 | } |
791 | } else { | | 799 | } else { |
792 | /* | | 800 | /* |
793 | * Determine blk-ness. | | 801 | * Determine blk-ness. |
794 | */ | | 802 | */ |
795 | if (stat(spec, &st) < 0) { | | 803 | if (stat(spec, &st) < 0) { |
796 | warn("%s", spec); | | 804 | warn("%s", spec); |
797 | continue; | | 805 | continue; |
798 | } | | 806 | } |
799 | if (S_ISBLK(st.st_mode)) | | 807 | if (S_ISBLK(st.st_mode)) |
800 | isblk = 1; | | 808 | isblk = 1; |
801 | } | | 809 | } |
802 | | | 810 | |
803 | /* | | 811 | /* |
804 | * Skip this type if we're told to. | | 812 | * Skip this type if we're told to. |
805 | */ | | 813 | */ |
806 | if (tflag != NULL) { | | 814 | if (tflag != NULL) { |
807 | if (strcmp(tflag, "blk") == 0 && isblk == 0) | | 815 | if (strcmp(tflag, "blk") == 0 && isblk == 0) |
808 | continue; | | 816 | continue; |
809 | if (strcmp(tflag, "noblk") == 0 && isblk == 1) | | 817 | if (strcmp(tflag, "noblk") == 0 && isblk == 1) |
810 | continue; | | 818 | continue; |
811 | } | | 819 | } |
812 | | | 820 | |
813 | if (add) { | | 821 | if (add) { |
814 | if (add_swap(spec, (int)priority)) { | | 822 | if (add_swap(spec, (int)priority)) { |
815 | success = 1; | | 823 | success = 1; |
816 | printf( | | 824 | printf( |
817 | "%s: adding %s as swap device at priority %d\n", | | 825 | "%s: adding %s as swap device at priority %d\n", |
818 | getprogname(), fsspec, (int)priority); | | 826 | getprogname(), fsspec, (int)priority); |
819 | } else { | | 827 | } else { |
820 | error = 1; | | 828 | error = 1; |
821 | fprintf(stderr, | | 829 | fprintf(stderr, |
822 | "%s: failed to add %s as swap device\n", | | 830 | "%s: failed to add %s as swap device\n", |
823 | getprogname(), fsspec); | | 831 | getprogname(), fsspec); |
824 | } | | 832 | } |
825 | } else { | | 833 | } else { |
826 | if (delete_swap(spec)) { | | 834 | if (delete_swap(spec)) { |
827 | success = 1; | | 835 | success = 1; |
828 | printf( | | 836 | printf( |
829 | "%s: removing %s as swap device\n", | | 837 | "%s: removing %s as swap device\n", |
830 | getprogname(), fsspec); | | 838 | getprogname(), fsspec); |
831 | } else { | | 839 | } else { |
832 | error = 1; | | 840 | error = 1; |
833 | fprintf(stderr, | | 841 | fprintf(stderr, |
834 | "%s: failed to remove %s as swap device\n", | | 842 | "%s: failed to remove %s as swap device\n", |
835 | getprogname(), fsspec); | | 843 | getprogname(), fsspec); |
836 | } | | 844 | } |
837 | if (cmd[0]) { | | 845 | if (cmd[0]) { |
838 | if (system(cmd) != 0) { | | 846 | if (system(cmd) != 0) { |
839 | warnx("%s: umount failed", fsspec); | | 847 | warnx("%s: umount failed", fsspec); |
840 | error = 1; | | 848 | error = 1; |
841 | continue; | | 849 | continue; |
842 | } | | 850 | } |
843 | } | | 851 | } |
844 | } | | 852 | } |
845 | | | 853 | |
846 | if (spec != fsspec) | | 854 | if (spec != fsspec) |
847 | free(spec); | | 855 | free(spec); |
848 | } | | 856 | } |
849 | if (error) | | 857 | if (error) |
850 | exit(1); | | 858 | exit(1); |
851 | else if (success) | | 859 | else if (success) |
852 | exit(0); | | 860 | exit(0); |
853 | else | | 861 | else |
854 | exit(2); /* not really an error, but no swap devices found */ | | 862 | exit(2); /* not really an error, but no swap devices found */ |
855 | } | | 863 | } |
856 | | | 864 | |
857 | static void | | 865 | static void |
858 | usage(void) | | 866 | usage(void) |
859 | { | | 867 | { |
860 | const char *progname = getprogname(); | | 868 | const char *progname = getprogname(); |
861 | | | 869 | |
862 | fprintf(stderr, "usage: %s -A [-f|-o] [-n] [-p priority] " | | 870 | fprintf(stderr, "usage: %s -A [-f|-o] [-n] [-p priority] " |
863 | "[-t blk|noblk|auto]\n", progname); | | 871 | "[-t blk|noblk|auto]\n", progname); |
864 | fprintf(stderr, " %s -a [-p priority] path\n", progname); | | 872 | fprintf(stderr, " %s -a [-p priority] path\n", progname); |
865 | fprintf(stderr, " %s -q\n", progname); | | 873 | fprintf(stderr, " %s -q\n", progname); |
866 | fprintf(stderr, " %s -c -p priority path\n", progname); | | 874 | fprintf(stderr, " %s -c -p priority path\n", progname); |
867 | fprintf(stderr, " %s -D dumpdev|none\n", progname); | | 875 | fprintf(stderr, " %s -D dumpdev|none\n", progname); |
868 | fprintf(stderr, " %s -d path\n", progname); | | 876 | fprintf(stderr, " %s -d path\n", progname); |
869 | fprintf(stderr, " %s -l | -s [-k|-m|-g|-h]\n", progname); | | 877 | fprintf(stderr, " %s -l | -s [-k|-m|-g|-h]\n", progname); |
870 | fprintf(stderr, " %s -U [-n] [-t blk|noblk|auto]\n", progname); | | 878 | fprintf(stderr, " %s -U [-n] [-t blk|noblk|auto]\n", progname); |
871 | fprintf(stderr, " %s -z\n", progname); | | 879 | fprintf(stderr, " %s -z\n", progname); |
872 | exit(1); | | 880 | exit(1); |
873 | } | | 881 | } |