[BACK]Return to swapctl.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / swapctl

Annotation of src/sbin/swapctl/swapctl.c, Revision 1.41

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

CVSweb <webmaster@jp.NetBSD.org>