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