[BACK]Return to disks.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / distrib / utils / sysinst

Annotation of src/distrib/utils/sysinst/disks.c, Revision 1.108

1.108   ! martin      1: /*     $NetBSD: disks.c,v 1.107 2009/10/01 10:41:03 jmcneill Exp $ */
1.1       phil        2:
                      3: /*
                      4:  * Copyright 1997 Piermont Information Systems Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Written by Philip A. Nelson for Piermont Information Systems Inc.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
1.27      cgd        19:  *      This product includes software developed for the NetBSD Project by
1.1       phil       20:  *      Piermont Information Systems Inc.
                     21:  * 4. The name of Piermont Information Systems Inc. may not be used to endorse
                     22:  *    or promote products derived from this software without specific prior
                     23:  *    written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
                     26:  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     27:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.51      dsl        28:  * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
                     29:  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     30:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1.1       phil       31:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     32:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     33:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.51      dsl        34:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
1.1       phil       35:  * THE POSSIBILITY OF SUCH DAMAGE.
                     36:  *
                     37:  */
                     38:
                     39: /* disks.c -- routines to deal with finding disks and labeling disks. */
                     40:
                     41:
1.11      jonathan   42: #include <errno.h>
1.1       phil       43: #include <stdio.h>
                     44: #include <stdlib.h>
1.3       phil       45: #include <unistd.h>
                     46: #include <fcntl.h>
1.9       jonathan   47: #include <util.h>
1.3       phil       48:
                     49: #include <sys/param.h>
1.58      dsl        50: #include <sys/swap.h>
1.3       phil       51: #include <ufs/ufs/dinode.h>
                     52: #include <ufs/ffs/fs.h>
1.48      christos   53: #define FSTYPENAMES
1.74      dsl        54: #define MOUNTNAMES
1.49      christos   55: #define static
1.48      christos   56: #include <sys/disklabel.h>
1.49      christos   57: #undef static
1.3       phil       58:
1.106     jmcneill   59: #include <dev/scsipi/scsipi_all.h>
                     60: #include <sys/scsiio.h>
                     61:
                     62: #include <dev/ata/atareg.h>
                     63: #include <sys/ataio.h>
                     64:
1.1       phil       65: #include "defs.h"
1.6       phil       66: #include "md.h"
1.1       phil       67: #include "msg_defs.h"
                     68: #include "menu_defs.h"
                     69: #include "txtwalk.h"
                     70:
1.64      dsl        71: /* Disk descriptions */
                     72: #define MAX_DISKS 15
                     73: struct disk_desc {
1.85      dsl        74:        char    dd_name[SSTRSIZE];
1.106     jmcneill   75:        char    dd_descr[70];
1.85      dsl        76:        uint    dd_no_mbr;
                     77:        uint    dd_cyl;
                     78:        uint    dd_head;
                     79:        uint    dd_sec;
                     80:        uint    dd_secsize;
                     81:        uint    dd_totsec;
1.64      dsl        82: };
1.8       jonathan   83:
1.2       phil       84: /* Local prototypes */
1.74      dsl        85: static int foundffs(struct data *, size_t);
1.91      tsutsui    86: #ifdef USE_SYSVBFS
                     87: static int foundsysvbfs(struct data *, size_t);
                     88: #endif
1.74      dsl        89: static int fsck_preen(const char *, int, const char *);
1.82      dbj        90: static void fixsb(const char *, const char *, char);
1.11      jonathan   91:
1.52      dsl        92: #ifndef DISK_NAMES
1.88      tron       93: #define DISK_NAMES "wd", "sd", "ld", "raid"
1.52      dsl        94: #endif
                     95:
1.65      dsl        96: static const char *disk_names[] = { DISK_NAMES, "vnd", NULL };
1.8       jonathan   97:
1.106     jmcneill   98: /* from src/sbin/atactl/atactl.c
                     99:  * extract_string: copy a block of bytes out of ataparams and make
                    100:  * a proper string out of it, truncating trailing spaces and preserving
                    101:  * strict typing. And also, not doing unaligned accesses.
                    102:  */
                    103: static void
                    104: ata_extract_string(char *buf, size_t bufmax,
                    105:                   uint8_t *bytes, unsigned numbytes,
                    106:                   int needswap)
                    107: {
                    108:        unsigned i;
                    109:        size_t j;
                    110:        unsigned char ch1, ch2;
                    111:
                    112:        for (i = 0, j = 0; i < numbytes; i += 2) {
                    113:                ch1 = bytes[i];
                    114:                ch2 = bytes[i+1];
                    115:                if (needswap && j < bufmax-1) {
                    116:                        buf[j++] = ch2;
                    117:                }
                    118:                if (j < bufmax-1) {
                    119:                        buf[j++] = ch1;
                    120:                }
                    121:                if (!needswap && j < bufmax-1) {
                    122:                        buf[j++] = ch2;
                    123:                }
                    124:        }
                    125:        while (j > 0 && buf[j-1] == ' ') {
                    126:                j--;
                    127:        }
                    128:        buf[j] = '\0';
                    129: }
                    130:
                    131: /*
                    132:  * from src/sbin/scsictl/scsi_subr.c
                    133:  */
                    134: #define STRVIS_ISWHITE(x) ((x) == ' ' || (x) == '\0' || (x) == (u_char)'\377')
                    135:
                    136: static void
                    137: scsi_strvis(char *sdst, size_t dlen, const char *ssrc, size_t slen)
                    138: {
                    139:        u_char *dst = (u_char *)sdst;
                    140:        const u_char *src = (const u_char *)ssrc;
                    141:
                    142:        /* Trim leading and trailing blanks and NULs. */
                    143:        while (slen > 0 && STRVIS_ISWHITE(src[0]))
                    144:                ++src, --slen;
                    145:        while (slen > 0 && STRVIS_ISWHITE(src[slen - 1]))
                    146:                --slen;
                    147:
                    148:        while (slen > 0) {
                    149:                if (*src < 0x20 || *src >= 0x80) {
                    150:                        /* non-printable characters */
                    151:                        dlen -= 4;
                    152:                        if (dlen < 1)
                    153:                                break;
                    154:                        *dst++ = '\\';
                    155:                        *dst++ = ((*src & 0300) >> 6) + '0';
                    156:                        *dst++ = ((*src & 0070) >> 3) + '0';
                    157:                        *dst++ = ((*src & 0007) >> 0) + '0';
                    158:                } else if (*src == '\\') {
                    159:                        /* quote characters */
                    160:                        dlen -= 2;
                    161:                        if (dlen < 1)
                    162:                                break;
                    163:                        *dst++ = '\\';
                    164:                        *dst++ = '\\';
                    165:                } else {
                    166:                        /* normal characters */
                    167:                        if (--dlen < 1)
                    168:                                break;
                    169:                        *dst++ = *src;
                    170:                }
                    171:                ++src, --slen;
                    172:        }
                    173:
                    174:        *dst++ = 0;
                    175: }
                    176:
                    177:
                    178: static int
                    179: get_descr_scsi(struct disk_desc *dd, int fd)
                    180: {
                    181:        struct scsipi_inquiry_data inqbuf;
                    182:        struct scsipi_inquiry cmd;
                    183:        scsireq_t req;
                    184:         /* x4 in case every character is escaped, +1 for NUL. */
                    185:        char vendor[(sizeof(inqbuf.vendor) * 4) + 1],
                    186:             product[(sizeof(inqbuf.product) * 4) + 1],
                    187:             revision[(sizeof(inqbuf.revision) * 4) + 1];
                    188:        char size[5];
                    189:        int error;
                    190:
                    191:        memset(&inqbuf, 0, sizeof(inqbuf));
                    192:        memset(&cmd, 0, sizeof(cmd));
                    193:        memset(&req, 0, sizeof(req));
                    194:
                    195:        cmd.opcode = INQUIRY;
                    196:        cmd.length = sizeof(inqbuf);
                    197:        memcpy(req.cmd, &cmd, sizeof(cmd));
                    198:        req.cmdlen = sizeof(cmd);
                    199:        req.databuf = &inqbuf;
                    200:        req.datalen = sizeof(inqbuf);
                    201:        req.timeout = 10000;
                    202:        req.flags = SCCMD_READ;
                    203:        req.senselen = SENSEBUFLEN;
                    204:
                    205:        error = ioctl(fd, SCIOCCOMMAND, &req);
                    206:        if (error == -1 || req.retsts != SCCMD_OK)
                    207:                return 0;
                    208:
                    209:        scsi_strvis(vendor, sizeof(vendor), inqbuf.vendor,
                    210:            sizeof(inqbuf.vendor));
                    211:        scsi_strvis(product, sizeof(product), inqbuf.product,
                    212:            sizeof(inqbuf.product));
                    213:        scsi_strvis(revision, sizeof(revision), inqbuf.revision,
                    214:            sizeof(inqbuf.revision));
                    215:
                    216:        humanize_number(size, sizeof(size),
                    217:            (uint64_t)dd->dd_secsize * (uint64_t)dd->dd_totsec,
                    218:            "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
                    219:
                    220:        snprintf(dd->dd_descr, sizeof(dd->dd_descr),
                    221:            "%s (%s, %s %s)",
                    222:            dd->dd_name, size, vendor, product);
                    223:
                    224:        return 1;
                    225: }
                    226:
                    227: static int
                    228: get_descr_ata(struct disk_desc *dd, int fd)
                    229: {
                    230:        struct atareq req;
                    231:        static union {
                    232:                unsigned char inbuf[DEV_BSIZE];
                    233:                struct ataparams inqbuf;
                    234:        } inbuf;
                    235:        struct ataparams *inqbuf = &inbuf.inqbuf;
                    236:        char model[sizeof(inqbuf->atap_model)+1];
                    237:        char size[5];
                    238:        int error, needswap = 0;
                    239:
                    240:        memset(&inbuf, 0, sizeof(inbuf));
                    241:        memset(&req, 0, sizeof(req));
                    242:
                    243:        req.flags = ATACMD_READ;
                    244:        req.command = WDCC_IDENTIFY;
                    245:        req.databuf = (void *)&inbuf;
                    246:        req.datalen = sizeof(inbuf);
                    247:        req.timeout = 1000;
                    248:
                    249:        error = ioctl(fd, ATAIOCCOMMAND, &req);
                    250:        if (error == -1 || req.retsts != ATACMD_OK)
                    251:                return 0;
                    252:
                    253: #if BYTE_ORDER == LITTLE_ENDIAN
                    254:        /*
                    255:         * On little endian machines, we need to shuffle the string
                    256:         * byte order.  However, we don't have to do this for NEC or
                    257:         * Mitsumi ATAPI devices
                    258:         */
                    259:
                    260:        if (!((inqbuf->atap_config & WDC_CFG_ATAPI_MASK) == WDC_CFG_ATAPI &&
                    261:              ((inqbuf->atap_model[0] == 'N' &&
                    262:                  inqbuf->atap_model[1] == 'E') ||
                    263:               (inqbuf->atap_model[0] == 'F' &&
                    264:                  inqbuf->atap_model[1] == 'X')))) {
                    265:                needswap = 1;
                    266:        }
                    267: #endif
                    268:
                    269:        ata_extract_string(model, sizeof(model),
                    270:            inqbuf->atap_model, sizeof(inqbuf->atap_model), needswap);
                    271:        humanize_number(size, sizeof(size),
                    272:            (uint64_t)dd->dd_secsize * (uint64_t)dd->dd_totsec,
                    273:            "", HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
                    274:
                    275:        snprintf(dd->dd_descr, sizeof(dd->dd_descr), "%s (%s, %s)",
                    276:            dd->dd_name, size, model);
                    277:
                    278:        return 1;
                    279: }
                    280:
                    281: static void
                    282: get_descr(struct disk_desc *dd)
                    283: {
                    284:        char diskpath[MAXPATHLEN];
                    285:        int fd = -1;
                    286:
                    287:        fd = opendisk(dd->dd_name, O_RDONLY, diskpath, sizeof(diskpath), 0);
                    288:        if (fd < 0)
                    289:                goto done;
                    290:
1.107     jmcneill  291:        dd->dd_descr[0] = '\0';
                    292:
1.106     jmcneill  293:        /* try ATA */
                    294:        if (get_descr_ata(dd, fd))
                    295:                goto done;
                    296:        /* try SCSI */
                    297:        if (get_descr_scsi(dd, fd))
                    298:                goto done;
                    299:
                    300: done:
                    301:        if (fd >= 0)
                    302:                close(fd);
                    303:        if (strlen(dd->dd_descr) == 0)
                    304:                strcpy(dd->dd_descr, dd->dd_name);
                    305: }
                    306:
1.64      dsl       307: static int
                    308: get_disks(struct disk_desc *dd)
1.4       phil      309: {
1.65      dsl       310:        const char **xd;
1.85      dsl       311:        char *cp;
1.4       phil      312:        struct disklabel l;
                    313:        int i;
1.64      dsl       314:        int numdisks;
1.4       phil      315:
1.51      dsl       316:        /* initialize */
                    317:        numdisks = 0;
                    318:
                    319:        for (xd = disk_names; *xd != NULL; xd++) {
                    320:                for (i = 0; i < MAX_DISKS; i++) {
1.85      dsl       321:                        strlcpy(dd->dd_name, *xd, sizeof dd->dd_name - 2);
                    322:                        cp = strchr(dd->dd_name, ':');
                    323:                        if (cp != NULL)
1.92      dsl       324:                                dd->dd_no_mbr = !strcmp(cp, ":no_mbr");
1.86      cube      325:                        else {
                    326:                                dd->dd_no_mbr = 0;
1.85      dsl       327:                                cp = strchr(dd->dd_name, 0);
1.86      cube      328:                        }
1.85      dsl       329:
                    330:                        snprintf(cp, 2 + 1, "%d", i);
                    331:                        if (!get_geom(dd->dd_name, &l)) {
1.52      dsl       332:                                if (errno == ENOENT)
                    333:                                        break;
1.51      dsl       334:                                continue;
1.52      dsl       335:                        }
1.51      dsl       336:                        dd->dd_cyl = l.d_ncylinders;
                    337:                        dd->dd_head = l.d_ntracks;
                    338:                        dd->dd_sec = l.d_nsectors;
                    339:                        dd->dd_secsize = l.d_secsize;
                    340:                        dd->dd_totsec = l.d_secperunit;
1.106     jmcneill  341:                        get_descr(dd);
1.51      dsl       342:                        dd++;
                    343:                        numdisks++;
                    344:                        if (numdisks >= MAX_DISKS)
1.64      dsl       345:                                return numdisks;
1.4       phil      346:                }
1.3       phil      347:        }
1.64      dsl       348:        return numdisks;
1.3       phil      349: }
1.51      dsl       350:
1.64      dsl       351: static int
1.66      dsl       352: set_dsk_select(menudesc *m, void *arg)
1.64      dsl       353: {
                    354:        *(int *)arg = m->cursel;
                    355:        return 1;
                    356: }
1.3       phil      357:
1.38      mrg       358: int
1.61      dsl       359: find_disks(const char *doingwhat)
1.1       phil      360: {
1.64      dsl       361:        struct disk_desc disks[MAX_DISKS];
                    362:        menu_ent dsk_menu[nelem(disks)];
                    363:        struct disk_desc *disk;
                    364:        int i;
                    365:        int numdisks;
                    366:        int selected_disk = 0;
                    367:        int menu_no;
1.1       phil      368:
1.4       phil      369:        /* Find disks. */
1.64      dsl       370:        numdisks = get_disks(disks);
1.1       phil      371:
1.20      garbled   372:        /* need a redraw here, kernel messages hose everything */
                    373:        touchwin(stdscr);
                    374:        refresh();
1.94      dsl       375:        /* Kill typeahead, it won't be what the user had in mind */
                    376:        fpurge(stdin);
1.20      garbled   377:
1.1       phil      378:        if (numdisks == 0) {
                    379:                /* No disks found! */
1.23      fvdl      380:                msg_display(MSG_nodisk);
1.53      dsl       381:                process_menu(MENU_ok, NULL);
1.20      garbled   382:                /*endwin();*/
1.1       phil      383:                return -1;
1.51      dsl       384:        }
                    385:
                    386:        if (numdisks == 1) {
1.1       phil      387:                /* One disk found! */
1.106     jmcneill  388:                msg_display(MSG_onedisk, disks[0].dd_descr, doingwhat);
1.53      dsl       389:                process_menu(MENU_ok, NULL);
1.1       phil      390:        } else {
                    391:                /* Multiple disks found! */
1.64      dsl       392:                for (i = 0; i < numdisks; i++) {
1.106     jmcneill  393:                        dsk_menu[i].opt_name = disks[i].dd_descr;
1.64      dsl       394:                        dsk_menu[i].opt_menu = OPT_NOMENU;
                    395:                        dsk_menu[i].opt_flags = OPT_EXIT;
                    396:                        dsk_menu[i].opt_action = set_dsk_select;
                    397:                }
                    398:                menu_no = new_menu(MSG_Available_disks,
                    399:                        dsk_menu, numdisks, -1, 4, 0, 0,
                    400:                        MC_SCROLL | MC_NOEXITOPT,
                    401:                        NULL, NULL, NULL, NULL, NULL);
                    402:                if (menu_no == -1)
                    403:                        return -1;
                    404:                msg_display(MSG_ask_disk);
                    405:                process_menu(menu_no, &selected_disk);
                    406:                free_menu(menu_no);
1.1       phil      407:        }
1.51      dsl       408:
1.64      dsl       409:        disk = disks + selected_disk;
                    410:        strlcpy(diskdev, disk->dd_name, sizeof diskdev);
1.3       phil      411:
1.92      dsl       412:        /* Use as a default disk if the user has the sets on a local disk */
                    413:        strlcpy(localfs_dev, disk->dd_name, sizeof localfs_dev);
                    414:
1.22      fvdl      415:        sectorsize = disk->dd_secsize;
1.23      fvdl      416:        dlcyl = disk->dd_cyl;
                    417:        dlhead = disk->dd_head;
                    418:        dlsec = disk->dd_sec;
                    419:        dlsize = disk->dd_totsec;
1.85      dsl       420:        no_mbr = disk->dd_no_mbr;
1.64      dsl       421:        if (dlsize == 0)
                    422:                dlsize = disk->dd_cyl * disk->dd_head * disk->dd_sec;
1.105     sborrill  423:        if (dlsize > UINT32_MAX) {
                    424:                msg_display(MSG_toobigdisklabel);
                    425:                process_menu(MENU_ok, NULL);
                    426:                return -1;
                    427:        }
1.23      fvdl      428:        dlcylsize = dlhead * dlsec;
1.1       phil      429:
1.62      dsl       430:        /* Get existing/default label */
1.76      dsl       431:        memset(&oldlabel, 0, sizeof oldlabel);
1.62      dsl       432:        incorelabel(diskdev, oldlabel);
                    433:
1.75      dsl       434:        /* Set 'target' label to current label in case we don't change it */
                    435:        memcpy(&bsdlabel, &oldlabel, sizeof bsdlabel);
                    436:
1.1       phil      437:        return numdisks;
                    438: }
                    439:
1.57      dsl       440: void
1.62      dsl       441: fmt_fspart(menudesc *m, int ptn, void *arg)
1.57      dsl       442: {
1.105     sborrill  443:        unsigned int poffset, psize, pend;
1.57      dsl       444:        const char *desc;
1.62      dsl       445:        static const char *Yes, *No;
1.74      dsl       446:        partinfo *p = bsdlabel + ptn;
1.62      dsl       447:
                    448:        if (Yes == NULL) {
                    449:                Yes = msg_string(MSG_Yes);
                    450:                No = msg_string(MSG_No);
                    451:        }
1.57      dsl       452:
1.74      dsl       453:        poffset = p->pi_offset / sizemult;
                    454:        psize = p->pi_size / sizemult;
1.57      dsl       455:        if (psize == 0)
                    456:                pend = 0;
                    457:        else
1.74      dsl       458:                pend = (p->pi_offset + p->pi_size) / sizemult - 1;
                    459:
                    460:        if (p->pi_fstype == FS_BSDFFS)
                    461:                if (p->pi_flags & PIF_FFSv2)
                    462:                        desc = "FFSv2";
                    463:                else
                    464:                        desc = "FFSv1";
                    465:        else
                    466:                desc = fstypenames[p->pi_fstype];
1.57      dsl       467:
                    468: #ifdef PART_BOOT
                    469:        if (ptn == PART_BOOT)
                    470:                desc = msg_string(MSG_Boot_partition_cant_change);
                    471: #endif
                    472:        if (ptn == getrawpartition())
                    473:                desc = msg_string(MSG_Whole_disk_cant_change);
                    474:        else {
1.74      dsl       475:                if (ptn == PART_C)
1.57      dsl       476:                        desc = msg_string(MSG_NetBSD_partition_cant_change);
                    477:        }
                    478:
1.62      dsl       479:        wprintw(m->mw, msg_string(MSG_fspart_row),
                    480:                        poffset, pend, psize, desc,
1.74      dsl       481:                        p->pi_flags & PIF_NEWFS ? Yes : "",
                    482:                        p->pi_flags & PIF_MOUNT ? Yes : "",
                    483:                        p->pi_mount);
1.1       phil      484: }
                    485:
1.13      jonathan  486: /*
                    487:  * Label a disk using an MD-specific string DISKLABEL_CMD for
1.60      dsl       488:  * to invoke disklabel.
1.13      jonathan  489:  * if MD code does not define DISKLABEL_CMD, this is a no-op.
                    490:  *
1.60      dsl       491:  * i386 port uses "/sbin/disklabel -w -r", just like i386
1.13      jonathan  492:  * miniroot scripts, though this may leave a bogus incore label.
                    493:  *
1.60      dsl       494:  * Sun ports should use DISKLABEL_CMD "/sbin/disklabel -w"
                    495:  * to get incore to ondisk inode translation for the Sun proms.
1.13      jonathan  496:  */
1.38      mrg       497: int
                    498: write_disklabel (void)
1.1       phil      499: {
1.13      jonathan  500:
                    501: #ifdef DISKLABEL_CMD
1.1       phil      502:        /* disklabel the disk */
1.74      dsl       503:        return run_program(RUN_DISPLAY, "%s -f /tmp/disktab %s '%s'",
1.73      dsl       504:            DISKLABEL_CMD, diskdev, bsddiskname);
1.48      christos  505: #else
                    506:        return 0;
1.13      jonathan  507: #endif
1.1       phil      508: }
                    509:
1.62      dsl       510:
                    511: static int
                    512: ptn_sort(const void *a, const void *b)
                    513: {
1.65      dsl       514:        return strcmp(bsdlabel[*(const int *)a].pi_mount,
                    515:                      bsdlabel[*(const int *)b].pi_mount);
1.62      dsl       516: }
                    517:
1.38      mrg       518: int
                    519: make_filesystems(void)
1.1       phil      520: {
                    521:        int i;
1.62      dsl       522:        int ptn;
                    523:        int ptn_order[nelem(bsdlabel)];
1.74      dsl       524:        int error = 0;
1.62      dsl       525:        int maxpart = getmaxpartitions();
1.74      dsl       526:        char *newfs;
                    527:        const char *mnt_opts;
                    528:        const char *fsname;
                    529:        partinfo *lbl;
1.62      dsl       530:
                    531:        if (maxpart > nelem(bsdlabel))
                    532:                maxpart = nelem(bsdlabel);
                    533:
                    534:        /* Making new file systems and mounting them */
                    535:
                    536:        /* sort to ensure /usr/local is mounted after /usr (etc) */
                    537:        for (i = 0; i < maxpart; i++)
                    538:                ptn_order[i] = i;
                    539:        qsort(ptn_order, maxpart, sizeof ptn_order[0], ptn_sort);
1.1       phil      540:
1.62      dsl       541:        for (i = 0; i < maxpart; i++) {
1.9       jonathan  542:                /*
1.51      dsl       543:                 * newfs and mount. For now, process only BSD filesystems.
1.40      mrg       544:                 * but if this is the mounted-on root, has no mount
1.51      dsl       545:                 * point defined, or is marked preserve, don't touch it!
1.9       jonathan  546:                 */
1.62      dsl       547:                ptn = ptn_order[i];
1.74      dsl       548:                lbl = bsdlabel + ptn;
                    549:
1.72      dsl       550:                if (is_active_rootpart(diskdev, ptn))
                    551:                        continue;
1.1       phil      552:
1.74      dsl       553:                if (*lbl->pi_mount == 0)
                    554:                        /* No mount point */
                    555:                        continue;
1.57      dsl       556:
1.74      dsl       557:                newfs = NULL;
                    558:                mnt_opts = NULL;
                    559:                fsname = NULL;
                    560:                switch (lbl->pi_fstype) {
                    561:                case FS_APPLEUFS:
                    562:                        asprintf(&newfs, "/sbin/newfs %s%.0d",
                    563:                                lbl->pi_isize != 0 ? "-i" : "", lbl->pi_isize);
                    564:                        mnt_opts = "-tffs -o async";
                    565:                        fsname = "ffs";
                    566:                        break;
1.57      dsl       567:                case FS_BSDFFS:
1.93      dsl       568:                        asprintf(&newfs,
                    569:                            "/sbin/newfs -V2 -O %d -b %d -f %d%s%.0d",
                    570:                            lbl->pi_flags & PIF_FFSv2 ? 2 : 1,
                    571:                            lbl->pi_fsize * lbl->pi_frag, lbl->pi_fsize,
                    572:                            lbl->pi_isize != 0 ? " -i " : "", lbl->pi_isize);
1.100     simonb    573:                        if (lbl->pi_flags & PIF_LOG)
                    574:                                mnt_opts = "-tffs -o log";
                    575:                        else
                    576:                                mnt_opts = "-tffs -o async";
1.74      dsl       577:                        fsname = "ffs";
1.57      dsl       578:                        break;
                    579:                case FS_BSDLFS:
1.74      dsl       580:                        asprintf(&newfs, "/sbin/newfs_lfs -b %d",
                    581:                                lbl->pi_fsize * lbl->pi_frag);
                    582:                        mnt_opts = "-tlfs";
                    583:                        fsname = "lfs";
                    584:                        break;
                    585:                case FS_MSDOS:
1.98      tsutsui   586: #ifdef USE_NEWFS_MSDOS
                    587:                        asprintf(&newfs, "/sbin/newfs_msdos");
                    588: #endif
1.74      dsl       589:                        mnt_opts = "-tmsdos";
                    590:                        fsname = "msdos";
1.57      dsl       591:                        break;
1.91      tsutsui   592: #ifdef USE_SYSVBFS
                    593:                case FS_SYSVBFS:
                    594:                        asprintf(&newfs, "/sbin/newfs_sysvbfs");
                    595:                        mnt_opts = "-tsysvbfs";
                    596:                        fsname = "sysvbfs";
                    597:                        break;
                    598: #endif
1.99      tsutsui   599: #ifdef USE_EXT2FS
                    600:                case FS_EX2FS:
                    601:                        asprintf(&newfs, "/sbin/newfs_ext2fs");
                    602:                        mnt_opts = "-text2fs";
                    603:                        fsname = "ext2fs";
                    604:                        break;
                    605: #endif
1.57      dsl       606:                }
1.74      dsl       607:                if (lbl->pi_flags & PIF_NEWFS && newfs != NULL) {
1.98      tsutsui   608: #ifdef USE_NEWFS_MSDOS
                    609:                        if (lbl->pi_fstype == FS_MSDOS) {
                    610:                                /* newfs only if mount fails */
                    611:                                if (run_program(RUN_SILENT | RUN_ERROR_OK,
                    612:                                    "mount -rt msdos /dev/%s%c /mnt2",
                    613:                                    diskdev, 'a' + ptn) != 0)
                    614:                                        error = run_program(
                    615:                                            RUN_DISPLAY | RUN_PROGRESS,
                    616:                                            "%s /dev/r%s%c",
                    617:                                            newfs, diskdev, 'a' + ptn);
                    618:                                else {
                    619:                                        run_program(RUN_SILENT | RUN_ERROR_OK,
                    620:                                            "umount /mnt2");
                    621:                                        error = 0;
                    622:                                }
                    623:                        } else
                    624: #endif
1.74      dsl       625:                        error = run_program(RUN_DISPLAY | RUN_PROGRESS,
                    626:                            "%s /dev/r%s%c", newfs, diskdev, 'a' + ptn);
                    627:                } else {
                    628:                        /* We'd better check it isn't dirty */
                    629:                        error = fsck_preen(diskdev, ptn, fsname);
                    630:                }
                    631:                free(newfs);
                    632:                if (error != 0)
                    633:                        return error;
                    634:
                    635:                if (lbl->pi_flags & PIF_MOUNT && mnt_opts != NULL) {
                    636:                        make_target_dir(lbl->pi_mount);
                    637:                        error = target_mount(mnt_opts, diskdev, ptn,
                    638:                                            lbl->pi_mount);
                    639:                        if (error) {
                    640:                                msg_display(MSG_mountfail,
                    641:                                            diskdev, 'a' + ptn, lbl->pi_mount);
                    642:                                process_menu(MENU_ok, NULL);
                    643:                                return error;
                    644:                        }
1.25      bouyer    645:                }
1.9       jonathan  646:        }
1.74      dsl       647:        return 0;
1.1       phil      648: }
                    649:
1.38      mrg       650: int
                    651: make_fstab(void)
1.1       phil      652: {
                    653:        FILE *f;
1.48      christos  654:        int i, swap_dev = -1;
1.108   ! martin    655:        const char *dump_dev;
1.1       phil      656:
                    657:        /* Create the fstab. */
1.8       jonathan  658:        make_target_dir("/etc");
1.23      fvdl      659:        f = target_fopen("/etc/fstab", "w");
1.20      garbled   660:        if (logging)
1.47      fvdl      661:                (void)fprintf(logfp,
                    662:                    "Creating %s/etc/fstab.\n", target_prefix());
1.40      mrg       663:        scripting_fprintf(NULL, "cat <<EOF >%s/etc/fstab\n", target_prefix());
1.20      garbled   664:
1.1       phil      665:        if (f == NULL) {
                    666: #ifndef DEBUG
1.24      bouyer    667:                msg_display(MSG_createfstab);
1.20      garbled   668:                if (logging)
1.47      fvdl      669:                        (void)fprintf(logfp, "Failed to make /etc/fstab!\n");
1.53      dsl       670:                process_menu(MENU_ok, NULL);
1.25      bouyer    671:                return 1;
1.1       phil      672: #else
                    673:                f = stdout;
1.51      dsl       674: #endif
1.1       phil      675:        }
1.40      mrg       676:
1.90      christos  677:        scripting_fprintf(f, "# NetBSD /etc/fstab\n# See /usr/share/examples/"
                    678:                "fstab/ for more examples.\n", target_prefix());
1.57      dsl       679:        for (i = 0; i < getmaxpartitions(); i++) {
                    680:                const char *s = "";
                    681:                const char *mp = bsdlabel[i].pi_mount;
                    682:                const char *fstype = "ffs";
1.69      dsl       683:                int fsck_pass = 0, dump_freq = 0;
1.57      dsl       684:
                    685:                if (!*mp) {
                    686:                        /*
                    687:                         * No mount point specified, comment out line and
                    688:                         * use /mnt as a placeholder for the mount point.
                    689:                         */
                    690:                        s = "# ";
                    691:                        mp = "/mnt";
                    692:                }
                    693:
                    694:                switch (bsdlabel[i].pi_fstype) {
1.69      dsl       695:                case FS_UNUSED:
                    696:                        continue;
1.57      dsl       697:                case FS_BSDLFS:
1.40      mrg       698:                        /* If there is no LFS, just comment it out. */
1.95      dsl       699:                        if (!check_lfs_progs())
1.57      dsl       700:                                s = "# ";
                    701:                        fstype = "lfs";
                    702:                        /* FALLTHROUGH */
                    703:                case FS_BSDFFS:
1.74      dsl       704:                        fsck_pass = (strcmp(mp, "/") == 0) ? 1 : 2;
1.69      dsl       705:                        dump_freq = 1;
1.57      dsl       706:                        break;
                    707:                case FS_MSDOS:
1.69      dsl       708:                        fstype = "msdos";
1.57      dsl       709:                        break;
                    710:                case FS_SWAP:
1.108   ! martin    711:                        if (swap_dev == -1) {
1.48      christos  712:                                swap_dev = i;
1.108   ! martin    713:                                dump_dev = ",dp";
        !           714:                        } else {
        !           715:                                dump_dev ="";
        !           716:                        }
        !           717:                        scripting_fprintf(f, "/dev/%s%c\t\tnone\tswap\tsw%s\t\t 0 0\n",
        !           718:                                diskdev, 'a' + i, dump_dev);
1.69      dsl       719:                        continue;
1.91      tsutsui   720: #ifdef USE_SYSVBFS
                    721:                case FS_SYSVBFS:
                    722:                        fstype = "sysvbfs";
                    723:                        make_target_dir("/stand");
                    724:                        break;
                    725: #endif
1.69      dsl       726:                default:
                    727:                        fstype = "???";
                    728:                        s = "# ";
1.57      dsl       729:                        break;
1.20      garbled   730:                }
1.89      dsl       731:                /* The code that remounts root rw doesn't check the partition */
                    732:                if (strcmp(mp, "/") == 0 && !(bsdlabel[i].pi_flags & PIF_MOUNT))
                    733:                        s = "# ";
                    734:
1.100     simonb    735:                scripting_fprintf(f,
1.101     ad        736:                  "%s/dev/%s%c\t\t%s\t%s\trw%s%s%s%s%s%s%s%s\t\t %d %d\n",
1.69      dsl       737:                   s, diskdev, 'a' + i, mp, fstype,
1.100     simonb    738:                   bsdlabel[i].pi_flags & PIF_LOG ? ",log" : "",
1.69      dsl       739:                   bsdlabel[i].pi_flags & PIF_MOUNT ? "" : ",noauto",
                    740:                   bsdlabel[i].pi_flags & PIF_ASYNC ? ",async" : "",
                    741:                   bsdlabel[i].pi_flags & PIF_NOATIME ? ",noatime" : "",
1.71      dsl       742:                   bsdlabel[i].pi_flags & PIF_NODEV ? ",nodev" : "",
1.69      dsl       743:                   bsdlabel[i].pi_flags & PIF_NODEVMTIME ? ",nodevmtime" : "",
1.71      dsl       744:                   bsdlabel[i].pi_flags & PIF_NOEXEC ? ",noexec" : "",
                    745:                   bsdlabel[i].pi_flags & PIF_NOSUID ? ",nosuid" : "",
1.69      dsl       746:                   dump_freq, fsck_pass);
1.57      dsl       747:        }
                    748:
1.56      dsl       749:        if (tmp_mfs_size != 0) {
1.48      christos  750:                if (swap_dev != -1)
1.90      christos  751:                        scripting_fprintf(f, "/dev/%s%c\t\t/tmp\tmfs\trw,-s=%d\n",
1.56      dsl       752:                                diskdev, 'a' + swap_dev, tmp_mfs_size);
1.40      mrg       753:                else
1.90      christos  754:                        scripting_fprintf(f, "swap\t\t/tmp\tmfs\trw,-s=%d\n",
1.68      skrll     755:                                tmp_mfs_size);
1.20      garbled   756:        }
1.57      dsl       757:
1.96      xtraeme   758:        /* Add /kern, /proc and /dev/pts to fstab and make mountpoint. */
1.103     ad        759:        scripting_fprintf(f, "kernfs\t\t/kern\tkernfs\trw\n");
1.96      xtraeme   760:        scripting_fprintf(f, "ptyfs\t\t/dev/pts\tptyfs\trw\n");
1.102     ad        761:        scripting_fprintf(f, "procfs\t\t/proc\tprocfs\trw\n");
1.97      hubertf   762:        scripting_fprintf(f, "/dev/cd0a\t\t/cdrom\tcd9660\tro,noauto\n");
1.57      dsl       763:        make_target_dir("/kern");
1.69      dsl       764:        make_target_dir("/proc");
1.96      xtraeme   765:        make_target_dir("/dev/pts");
1.97      hubertf   766:        make_target_dir("/cdrom");
1.57      dsl       767:
1.40      mrg       768:        scripting_fprintf(NULL, "EOF\n");
                    769:
1.1       phil      770: #ifndef DEBUG
                    771:        fclose(f);
1.20      garbled   772:        fflush(NULL);
1.1       phil      773: #endif
1.24      bouyer    774:        return 0;
1.1       phil      775: }
1.14      jonathan  776:
1.40      mrg       777:
1.1       phil      778:
1.74      dsl       779: static int
1.48      christos  780: /*ARGSUSED*/
                    781: foundffs(struct data *list, size_t num)
1.3       phil      782: {
1.74      dsl       783:        int error;
1.3       phil      784:
1.74      dsl       785:        if (num < 2 || strcmp(list[1].u.s_val, "/") == 0 ||
                    786:            strstr(list[2].u.s_val, "noauto") != NULL)
                    787:                return 0;
1.3       phil      788:
1.74      dsl       789:        error = fsck_preen(list[0].u.s_val, ' '-'a', "ffs");
                    790:        if (error != 0)
                    791:                return error;
1.2       phil      792:
1.74      dsl       793:        error = target_mount("", list[0].u.s_val, ' '-'a', list[1].u.s_val);
                    794:        if (error != 0)
                    795:                return error;
                    796:        return 0;
1.2       phil      797: }
                    798:
1.91      tsutsui   799: #ifdef USE_SYSVBFS
                    800: static int
                    801: /*ARGSUSED*/
                    802: foundsysvbfs(struct data *list, size_t num)
                    803: {
                    804:        int error;
                    805:
                    806:        if (num < 2 || strcmp(list[1].u.s_val, "/") == 0 ||
                    807:            strstr(list[2].u.s_val, "noauto") != NULL)
                    808:                return 0;
                    809:
                    810:        error = target_mount("", list[0].u.s_val, ' '-'a', list[1].u.s_val);
                    811:        if (error != 0)
                    812:                return error;
                    813:        return 0;
                    814: }
                    815: #endif
                    816:
1.11      jonathan  817: /*
1.81      dsl       818:  * Do an fsck. On failure, inform the user by showing a warning
1.11      jonathan  819:  * message and doing menu_ok() before proceeding.
1.74      dsl       820:  * Returns 0 on success, or nonzero return code from fsck() on failure.
1.11      jonathan  821:  */
1.74      dsl       822: static int
                    823: fsck_preen(const char *disk, int ptn, const char *fsname)
1.10      jonathan  824: {
1.74      dsl       825:        char *prog;
1.40      mrg       826:        int error;
1.74      dsl       827:
                    828:        ptn += 'a';
                    829:        if (fsname == NULL)
                    830:                return 0;
                    831:        /* first check fsck program exists, if not assue ok */
                    832:        asprintf(&prog, "/sbin/fsck_%s", fsname);
                    833:        if (prog == NULL)
                    834:                return 0;
                    835:        if (access(prog, X_OK) != 0)
                    836:                return 0;
1.77      dbj       837:        if (!strcmp(fsname,"ffs"))
1.82      dbj       838:                fixsb(prog, disk, ptn);
1.74      dsl       839:        error = run_program(0, "%s -p -q /dev/r%s%c", prog, disk, ptn);
                    840:        free(prog);
                    841:        if (error != 0) {
                    842:                msg_display(MSG_badfs, disk, ptn, error);
1.53      dsl       843:                process_menu(MENU_ok, NULL);
1.81      dsl       844:                /* XXX at this point maybe we should run a full fsck? */
1.3       phil      845:        }
1.11      jonathan  846:        return error;
                    847: }
                    848:
1.82      dbj       849: /* This performs the same function as the etc/rc.d/fixsb script
                    850:  * which attempts to correct problems with ffs1 filesystems
                    851:  * which may have been introduced by booting a netbsd-current kernel
                    852:  * from between April of 2003 and January 2004. For more information
                    853:  * This script was developed as a response to NetBSD pr install/25138
                    854:  * Additional prs regarding the original issue include:
                    855:  *  bin/17910 kern/21283 kern/21404 port-macppc/23925 port-macppc/23926
1.81      dsl       856:  */
1.77      dbj       857: static void
1.82      dbj       858: fixsb(const char *prog, const char *disk, char ptn)
1.77      dbj       859: {
                    860:        int fd;
1.78      dbj       861:        int rval;
1.82      dbj       862:        union {
                    863:                struct fs fs;
                    864:                char buf[SBLOCKSIZE];
                    865:        } sblk;
                    866:        struct fs *fs = &sblk.fs;
                    867:
1.84      dsl       868:        snprintf(sblk.buf, sizeof(sblk.buf), "/dev/r%s%c",
                    869:                disk, ptn == ' ' ? 0 : ptn);
1.82      dbj       870:        fd = open(sblk.buf, O_RDONLY);
1.77      dbj       871:        if (fd == -1)
                    872:                return;
1.81      dsl       873:
                    874:        /* Read ffsv1 main superblock */
1.82      dbj       875:        rval = pread(fd, sblk.buf, sizeof sblk.buf, SBLOCK_UFS1);
1.77      dbj       876:        close(fd);
1.82      dbj       877:        if (rval != sizeof sblk.buf)
1.77      dbj       878:                return;
                    879:
                    880:        if (fs->fs_magic != FS_UFS1_MAGIC &&
                    881:            fs->fs_magic != FS_UFS1_MAGIC_SWAPPED)
1.81      dsl       882:                /* Not FFSv1 */
1.77      dbj       883:                return;
                    884:        if (fs->fs_old_flags & FS_FLAGS_UPDATED)
1.81      dsl       885:                /* properly updated fslevel 4 */
1.77      dbj       886:                return;
                    887:        if (fs->fs_bsize != fs->fs_maxbsize)
1.81      dsl       888:                /* not messed up */
1.77      dbj       889:                return;
                    890:
1.81      dsl       891:        /*
                    892:         * OK we have a munged fs, first 'upgrade' to fslevel 4,
                    893:         * We specify -b16 in order to stop fsck bleating that the
                    894:         * sb doesn't match the first alternate.
                    895:         */
1.82      dbj       896:        run_program(RUN_DISPLAY | RUN_PROGRESS,
1.83      dbj       897:            "%s -p -b 16 -c 4 /dev/r%s%c", prog, disk, ptn);
1.81      dsl       898:        /* Then downgrade to fslevel 3 */
1.82      dbj       899:        run_program(RUN_DISPLAY | RUN_PROGRESS,
                    900:            "%s -p -c 3 /dev/r%s%c", prog, disk, ptn);
1.77      dbj       901: }
                    902:
1.11      jonathan  903: /*
                    904:  * fsck and mount the root partition.
                    905:  */
1.92      dsl       906: static int
1.74      dsl       907: mount_root(void)
1.11      jonathan  908: {
1.60      dsl       909:        int     error;
1.11      jonathan  910:
1.74      dsl       911:        error = fsck_preen(diskdev, rootpart, "ffs");
1.11      jonathan  912:        if (error != 0)
                    913:                return error;
                    914:
1.60      dsl       915:        /* Mount /dev/<diskdev>a on target's "".
1.51      dsl       916:         * If we pass "" as mount-on, Prefixing will DTRT.
1.11      jonathan  917:         * for now, use no options.
                    918:         * XXX consider -o remount in case target root is
1.60      dsl       919:         * current root, still readonly from single-user?
1.11      jonathan  920:         */
1.74      dsl       921:        return target_mount("", diskdev, rootpart, "");
                    922: }
1.11      jonathan  923:
1.74      dsl       924: /* Get information on the file systems mounted from the root filesystem.
                    925:  * Offer to convert them into 4.4BSD inodes if they are not 4.4BSD
                    926:  * inodes.  Fsck them.  Mount them.
                    927:  */
1.10      jonathan  928:
                    929: int
1.74      dsl       930: mount_disks(void)
1.59      dsl       931: {
                    932:        char *fstab;
1.10      jonathan  933:        int   fstabsize;
1.11      jonathan  934:        int   error;
1.10      jonathan  935:
1.74      dsl       936:        static struct lookfor fstabbuf[] = {
                    937:                {"/dev/", "/dev/%s %s ffs %s", "c", NULL, 0, 0, foundffs},
                    938:                {"/dev/", "/dev/%s %s ufs %s", "c", NULL, 0, 0, foundffs},
1.91      tsutsui   939: #ifdef USE_SYSVBFS
                    940:                {"/dev/", "/dev/%s %s sysvbfs %s", "c", NULL, 0, 0,
                    941:                    foundsysvbfs},
                    942: #endif
1.74      dsl       943:        };
                    944:        static size_t numfstabbuf = sizeof(fstabbuf) / sizeof(struct lookfor);
                    945:
1.10      jonathan  946:        /* First the root device. */
1.92      dsl       947:        if (target_already_root())
                    948:                /* avoid needing to call target_already_root() again */
                    949:                targetroot_mnt[0] = 0;
                    950:        else {
1.74      dsl       951:                error = mount_root();
1.51      dsl       952:                if (error != 0 && error != EBUSY)
1.10      jonathan  953:                        return 0;
1.2       phil      954:        }
                    955:
1.11      jonathan  956:        /* Check the target /etc/fstab exists before trying to parse it. */
1.51      dsl       957:        if (target_dir_exists_p("/etc") == 0 ||
1.16      jonathan  958:            target_file_exists_p("/etc/fstab") == 0) {
1.11      jonathan  959:                msg_display(MSG_noetcfstab, diskdev);
1.53      dsl       960:                process_menu(MENU_ok, NULL);
1.11      jonathan  961:                return 0;
                    962:        }
                    963:
                    964:
1.10      jonathan  965:        /* Get fstab entries from the target-root /etc/fstab. */
1.23      fvdl      966:        fstabsize = target_collect_file(T_FILE, &fstab, "/etc/fstab");
1.2       phil      967:        if (fstabsize < 0) {
                    968:                /* error ! */
1.11      jonathan  969:                msg_display(MSG_badetcfstab, diskdev);
1.53      dsl       970:                process_menu(MENU_ok, NULL);
1.2       phil      971:                return 0;
                    972:        }
1.74      dsl       973:        error = walk(fstab, (size_t)fstabsize, fstabbuf, numfstabbuf);
1.2       phil      974:        free(fstab);
                    975:
1.74      dsl       976:        return error;
1.32      fvdl      977: }
                    978:
                    979: int
1.65      dsl       980: set_swap(const char *disk, partinfo *pp)
1.32      fvdl      981: {
1.62      dsl       982:        int i;
1.58      dsl       983:        char *cp;
                    984:        int rval;
1.32      fvdl      985:
1.62      dsl       986:        if (pp == NULL)
                    987:                pp = oldlabel;
1.32      fvdl      988:
1.62      dsl       989:        for (i = 0; i < MAXPARTITIONS; i++) {
1.58      dsl       990:                if (pp[i].pi_fstype != FS_SWAP)
                    991:                        continue;
1.65      dsl       992:                asprintf(&cp, "/dev/%s%c", disk, 'a' + i);
1.58      dsl       993:                rval = swapctl(SWAP_ON, cp, 0);
                    994:                free(cp);
                    995:                if (rval != 0)
                    996:                        return -1;
                    997:        }
                    998:
                    999:        return 0;
                   1000: }
                   1001:
                   1002: int
1.65      dsl      1003: check_swap(const char *disk, int remove_swap)
1.58      dsl      1004: {
                   1005:        struct swapent *swap;
                   1006:        char *cp;
                   1007:        int nswap;
                   1008:        int l;
                   1009:        int rval = 0;
                   1010:
                   1011:        nswap = swapctl(SWAP_NSWAP, 0, 0);
                   1012:        if (nswap <= 0)
                   1013:                return 0;
                   1014:
                   1015:        swap = malloc(nswap * sizeof *swap);
                   1016:        if (swap == NULL)
                   1017:                return -1;
                   1018:
                   1019:        nswap = swapctl(SWAP_STATS, swap, nswap);
                   1020:        if (nswap < 0)
                   1021:                goto bad_swap;
                   1022:
1.65      dsl      1023:        l = strlen(disk);
1.58      dsl      1024:        while (--nswap >= 0) {
                   1025:                /* Should we check the se_dev or se_path? */
                   1026:                cp = swap[nswap].se_path;
                   1027:                if (memcmp(cp, "/dev/", 5) != 0)
                   1028:                        continue;
1.65      dsl      1029:                if (memcmp(cp + 5, disk, l) != 0)
1.58      dsl      1030:                        continue;
                   1031:                if (!isalpha(*(unsigned char *)(cp + 5 + l)))
                   1032:                        continue;
                   1033:                if (cp[5 + l + 1] != 0)
                   1034:                        continue;
                   1035:                /* ok path looks like it is for this device */
1.65      dsl      1036:                if (!remove_swap) {
1.58      dsl      1037:                        /* count active swap areas */
                   1038:                        rval++;
                   1039:                        continue;
1.32      fvdl     1040:                }
1.58      dsl      1041:                if (swapctl(SWAP_OFF, cp, 0) == -1)
                   1042:                        rval = -1;
1.32      fvdl     1043:        }
                   1044:
1.58      dsl      1045:     done:
                   1046:        free(swap);
                   1047:        return rval;
                   1048:
                   1049:     bad_swap:
                   1050:        rval = -1;
                   1051:        goto done;
1.1       phil     1052: }
1.104     tsutsui  1053:
                   1054: #ifdef HAVE_BOOTXX_xFS
                   1055: char *
                   1056: bootxx_name(void)
                   1057: {
                   1058:        int fstype;
                   1059:        const char *bootxxname;
                   1060:        char *bootxx;
                   1061:
                   1062:        /* check we have boot code for the root partition type */
                   1063:        fstype = bsdlabel[rootpart].pi_fstype;
                   1064:        switch (fstype) {
                   1065: #if defined(BOOTXX_FFSV1) || defined(BOOTXX_FFSV2)
                   1066:        case FS_BSDFFS:
                   1067:                if (bsdlabel[rootpart].pi_flags & PIF_FFSv2) {
                   1068: #ifdef BOOTXX_FFSV2
                   1069:                        bootxxname = BOOTXX_FFSV2;
                   1070: #else
                   1071:                        bootxxname = NULL;
                   1072: #endif
                   1073:                } else {
                   1074: #ifdef BOOTXX_FFSV1
                   1075:                        bootxxname = BOOTXX_FFSV1;
                   1076: #else
                   1077:                        bootxxname = NULL;
                   1078: #endif
                   1079:                }
                   1080:                break;
                   1081: #endif
                   1082: #ifdef BOOTXX_LFS
                   1083:        case FS_BSDLFS:
                   1084:                bootxxname = BOOTXX_LFS;
                   1085:                break;
                   1086: #endif
                   1087:        default:
                   1088:                bootxxname = NULL;
                   1089:                break;
                   1090:        }
                   1091:
                   1092:        if (bootxxname == NULL)
                   1093:                return NULL;
                   1094:
                   1095:        asprintf(&bootxx, "%s/%s", BOOTXXDIR, bootxxname);
                   1096:        return bootxx;
                   1097: }
                   1098: #endif

CVSweb <webmaster@jp.NetBSD.org>