[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.61

1.61    ! dsl         1: /*     $NetBSD: disks.c,v 1.60 2003/06/16 20:10:02 dsl 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.49      christos   54: #define static
1.48      christos   55: #include <sys/disklabel.h>
1.49      christos   56: #undef static
1.3       phil       57:
1.1       phil       58: #include "defs.h"
1.6       phil       59: #include "md.h"
1.1       phil       60: #include "msg_defs.h"
                     61: #include "menu_defs.h"
                     62: #include "txtwalk.h"
                     63:
1.11      jonathan   64:
1.8       jonathan   65:
1.2       phil       66: /* Local prototypes */
1.4       phil       67: static void get_disks (void);
1.51      dsl        68: static void foundffs(struct data *, size_t);
                     69: static int do_fsck(const char *);
                     70: static int fsck_root(void);
                     71: static int do_flfs_newfs(const char *, int, const char *);
                     72: static int fsck_num(const char *);
                     73:
                     74: static int fsck_with_error_menu(const char *);
                     75: static int target_mount_with_error_menu(const char *, char *, const char *);
1.11      jonathan   76:
1.52      dsl        77: #ifndef DISK_NAMES
                     78: #define DISK_NAMES "wd", "sd", "ld"
                     79: #endif
                     80:
                     81: static char *disk_names[] = { DISK_NAMES, NULL };
1.8       jonathan   82:
1.38      mrg        83: static void
                     84: get_disks(void)
1.4       phil       85: {
1.51      dsl        86:        char **xd;
1.4       phil       87:        char d_name[SSTRSIZE];
                     88:        struct disklabel l;
1.51      dsl        89:        struct disk_desc *dd;
1.4       phil       90:        int i;
                     91:
1.51      dsl        92:        /* initialize */
                     93:        disknames[0] = 0;
                     94:        numdisks = 0;
                     95:        dd = disks;
                     96:
                     97:        for (xd = disk_names; *xd != NULL; xd++) {
                     98:                for (i = 0; i < MAX_DISKS; i++) {
                     99:                        snprintf(d_name, sizeof d_name, "%s%d", *xd, i);
1.52      dsl       100:                        if (!get_geom(d_name, &l)) {
                    101:                                if (errno == ENOENT)
                    102:                                        break;
1.51      dsl       103:                                continue;
1.52      dsl       104:                        }
1.51      dsl       105:                        strncpy(dd->dd_name, d_name, sizeof dd->dd_name);
                    106:                        strlcat(disknames, d_name, sizeof disknames);
                    107:                        strlcat(disknames, " ", sizeof disknames);
                    108:                        dd->dd_cyl = l.d_ncylinders;
                    109:                        dd->dd_head = l.d_ntracks;
                    110:                        dd->dd_sec = l.d_nsectors;
                    111:                        dd->dd_secsize = l.d_secsize;
                    112:                        dd->dd_totsec = l.d_secperunit;
                    113:                        dd++;
                    114:                        numdisks++;
                    115:                        if (numdisks >= MAX_DISKS)
                    116:                                return;
1.4       phil      117:                }
1.3       phil      118:        }
                    119: }
1.51      dsl       120:
1.3       phil      121:
1.38      mrg       122: int
1.61    ! dsl       123: find_disks(const char *doingwhat)
1.1       phil      124: {
                    125:        char *tp;
1.51      dsl       126:        const char *prompt;
1.3       phil      127:        char defname[STRSIZE];
                    128:        int  i;
1.1       phil      129:
1.4       phil      130:        /* Find disks. */
                    131:        get_disks();
1.1       phil      132:
1.20      garbled   133:        /* need a redraw here, kernel messages hose everything */
                    134:        touchwin(stdscr);
                    135:        refresh();
                    136:
1.1       phil      137:        if (numdisks == 0) {
                    138:                /* No disks found! */
1.23      fvdl      139:                msg_display(MSG_nodisk);
1.53      dsl       140:                process_menu(MENU_ok, NULL);
1.20      garbled   141:                /*endwin();*/
1.1       phil      142:                return -1;
1.51      dsl       143:        }
                    144:
                    145:        if (numdisks == 1) {
1.1       phil      146:                /* One disk found! */
                    147:                /* Remove that space we added. */
1.51      dsl       148:                disknames[strlen(disknames) - 1] = 0;
1.23      fvdl      149:                msg_display(MSG_onedisk, disknames, doingwhat);
1.53      dsl       150:                process_menu(MENU_ok, NULL);
1.51      dsl       151:                strlcpy(diskdev, disknames, sizeof diskdev);
1.1       phil      152:        } else {
                    153:                /* Multiple disks found! */
1.23      fvdl      154:                strcpy(defname, disknames);
1.1       phil      155:                tp = defname;
                    156:                strsep(&tp, " ");
1.51      dsl       157:                prompt = MSG_askdisk;
                    158:                do {
                    159:                        msg_prompt(prompt, defname,  diskdev, 10, disknames);
                    160:                        prompt = MSG_badname;
1.1       phil      161:                        tp = diskdev;
                    162:                        strsep(&tp, " ");
1.51      dsl       163:                        diskdev[strlen(diskdev) + 1] = 0;
1.1       phil      164:                        diskdev[strlen(diskdev)] = ' ';
1.51      dsl       165:                        tp = strstr(disknames, diskdev);
                    166:                } while (tp == NULL || (tp != disknames && tp[-1] != ' '));
1.1       phil      167:
                    168:                /* Remove that space we added. */
1.51      dsl       169:                diskdev[strlen(diskdev) - 1] = 0;
1.1       phil      170:        }
1.51      dsl       171:
1.3       phil      172:        /* Set disk. */
1.23      fvdl      173:        for (i = 0; i < numdisks; i++)
1.22      fvdl      174:                if (strcmp(diskdev, disks[i].dd_name) == 0)
1.3       phil      175:                        disk = &disks[i];
                    176:
1.22      fvdl      177:        sectorsize = disk->dd_secsize;
                    178:        if (disk->dd_totsec == 0)
                    179:                disk->dd_totsec = disk->dd_cyl * disk->dd_head * disk->dd_sec;
1.23      fvdl      180:        dlcyl = disk->dd_cyl;
                    181:        dlhead = disk->dd_head;
                    182:        dlsec = disk->dd_sec;
                    183:        dlsize = disk->dd_totsec;
                    184:        dlcylsize = dlhead * dlsec;
1.1       phil      185:
                    186:        return numdisks;
                    187: }
                    188:
1.57      dsl       189: void
                    190: fmt_fspart(char *buf, size_t len, int ptn)
                    191: {
                    192:        int poffset, psize, pend;
                    193:        int l;
                    194:        const char *desc;
                    195:
                    196:        poffset = bsdlabel[ptn].pi_offset / sizemult;
                    197:        psize = bsdlabel[ptn].pi_size / sizemult;
                    198:        if (psize == 0)
                    199:                pend = 0;
                    200:        else
                    201:                pend = (bsdlabel[ptn].pi_offset +
                    202:                        bsdlabel[ptn].pi_size) / sizemult - 1;
                    203:
                    204:        desc = fstypenames[bsdlabel[ptn].pi_fstype];
                    205: #ifdef PART_BOOT
                    206:        if (ptn == PART_BOOT)
                    207:                desc = msg_string(MSG_Boot_partition_cant_change);
                    208: #endif
                    209:        if (ptn == getrawpartition())
                    210:                desc = msg_string(MSG_Whole_disk_cant_change);
                    211:        else {
                    212:                if (ptn == C)
                    213:                        desc = msg_string(MSG_NetBSD_partition_cant_change);
                    214:        }
                    215:
                    216:        l = snprintf(buf, len, msg_string(MSG_fspart_row_start),
                    217:                        poffset, pend, psize, desc);
                    218:        buf += l;
                    219:        len -= l;
                    220:        if (len <= 0)
                    221:                return;
                    222:        if (PI_ISBSDFS(&bsdlabel[ptn]))
                    223:                snprintf(buf, len, msg_string(MSG_fspart_row_end_bsd),
                    224:                            bsdlabel[ptn].pi_bsize,
                    225:                            bsdlabel[ptn].pi_fsize,
                    226:                            bsdlabel[ptn].pi_newfs ? "No" : "Yes",
                    227:                            bsdlabel[ptn].pi_mount);
                    228:        else if (bsdlabel[ptn].pi_fstype == FS_MSDOS)
                    229:                snprintf(buf, len, msg_string(MSG_fspart_row_end_msdos),
                    230:                                bsdlabel[ptn].pi_mount);
                    231:        else
                    232:                snprintf(buf, len, msg_string(MSG_fspart_row_end_other));
                    233: }
1.1       phil      234:
1.38      mrg       235: void
                    236: disp_cur_fspart(int disp, int showall)
1.1       phil      237: {
                    238:        int i;
                    239:        int start, stop;
1.19      simonb    240:        int poffset, psize, pend;
1.1       phil      241:
                    242:        if (disp < 0) {
                    243:                start = 0;
1.9       jonathan  244:                stop = getmaxpartitions();
1.1       phil      245:        } else {
                    246:                start = disp;
                    247:                stop = disp+1;
                    248:        }
                    249:
1.28      cgd       250:        msg_table_add (MSG_fspart_header);
1.23      fvdl      251:        for (i = start; i < stop; i++) {
                    252:                if (showall || bsdlabel[i].pi_size > 0) {
                    253:                        poffset = bsdlabel[i].pi_offset / sizemult;
                    254:                        psize = bsdlabel[i].pi_size / sizemult;
1.19      simonb    255:                        if (psize == 0)
                    256:                                pend = 0;
                    257:                        else
1.23      fvdl      258:                                pend = (bsdlabel[i].pi_offset +
                    259:                                bsdlabel[i].pi_size) / sizemult - 1;
1.57      dsl       260:                        msg_table_add("%c: ", 'a' + i);
1.28      cgd       261:                        msg_table_add(MSG_fspart_row_start,
1.57      dsl       262:                                        poffset, pend, psize,
1.23      fvdl      263:                                        fstypenames[bsdlabel[i].pi_fstype]);
1.40      mrg       264:                        if (PI_ISBSDFS(&bsdlabel[i]))
1.28      cgd       265:                                msg_table_add(MSG_fspart_row_end_bsd,
1.54      dsl       266:                                            bsdlabel[i].pi_bsize,
                    267:                                            bsdlabel[i].pi_fsize,
                    268:                                            bsdlabel[i].pi_newfs ? "No" : "Yes",
                    269:                                            bsdlabel[i].pi_mount);
1.23      fvdl      270:                        else if (bsdlabel[i].pi_fstype == FS_MSDOS)
1.28      cgd       271:                                msg_table_add(MSG_fspart_row_end_msdos,
1.54      dsl       272:                                                bsdlabel[i].pi_mount);
1.28      cgd       273:                        else
                    274:                                msg_table_add(MSG_fspart_row_end_other);
1.1       phil      275:                }
                    276:        }
1.30      cgd       277:        msg_display_add(MSG_newline);
1.1       phil      278: }
                    279:
1.13      jonathan  280: /*
                    281:  * Label a disk using an MD-specific string DISKLABEL_CMD for
1.60      dsl       282:  * to invoke disklabel.
1.13      jonathan  283:  * if MD code does not define DISKLABEL_CMD, this is a no-op.
                    284:  *
1.60      dsl       285:  * i386 port uses "/sbin/disklabel -w -r", just like i386
1.13      jonathan  286:  * miniroot scripts, though this may leave a bogus incore label.
                    287:  *
1.60      dsl       288:  * Sun ports should use DISKLABEL_CMD "/sbin/disklabel -w"
                    289:  * to get incore to ondisk inode translation for the Sun proms.
1.13      jonathan  290:  */
1.38      mrg       291: int
                    292: write_disklabel (void)
1.1       phil      293: {
1.13      jonathan  294:
                    295: #ifdef DISKLABEL_CMD
1.1       phil      296:        /* disklabel the disk */
1.33      fvdl      297:        return run_prog(RUN_DISPLAY, MSG_cmdfail,
1.24      bouyer    298:            "%s %s %s", DISKLABEL_CMD, diskdev, bsddiskname);
1.48      christos  299: #else
                    300:        return 0;
1.13      jonathan  301: #endif
1.1       phil      302: }
                    303:
1.38      mrg       304: int
                    305: make_filesystems(void)
1.1       phil      306: {
                    307:        int i;
1.9       jonathan  308:        char partname[STRSIZE];
1.24      bouyer    309:        int error;
1.1       phil      310:
                    311:        /* Making new file systems and mounting them*/
1.23      fvdl      312:        for (i = 0; i < getmaxpartitions(); i++) {
1.9       jonathan  313:                /*
1.51      dsl       314:                 * newfs and mount. For now, process only BSD filesystems.
1.40      mrg       315:                 * but if this is the mounted-on root, has no mount
1.51      dsl       316:                 * point defined, or is marked preserve, don't touch it!
1.9       jonathan  317:                 */
1.51      dsl       318:                snprintf(partname, STRSIZE, "%s%c", diskdev, 'a' + i);
1.40      mrg       319:                if (PI_ISBSDFS(&bsdlabel[i]) && !is_active_rootpart(partname)) {
1.54      dsl       320:                        error = do_flfs_newfs(partname, i, bsdlabel[i].pi_mount);
1.24      bouyer    321:                        if (error)
                    322:                                return error;
1.1       phil      323:                }
1.9       jonathan  324:        }
1.24      bouyer    325:        return 0;
1.9       jonathan  326: }
1.1       phil      327:
1.9       jonathan  328: /* newfs and mount an ffs filesystem. */
1.51      dsl       329: static int
1.40      mrg       330: do_flfs_newfs(const char *partname, int partno, const char *mountpoint)
1.9       jonathan  331: {
1.48      christos  332:        char dev_name[STRSIZE];
1.24      bouyer    333:        int error;
1.57      dsl       334:        const char *newfs;
                    335:
                    336:        if (!*mountpoint)
                    337:                return 0;
1.24      bouyer    338:
1.57      dsl       339:        if (bsdlabel[partno].pi_newfs) {
                    340:                switch (bsdlabel[partno].pi_fstype) {
                    341:                case FS_BSDFFS:
                    342:                        newfs = "/sbin/newfs";
                    343:                        break;
                    344:                case FS_BSDLFS:
                    345:                        newfs = "/sbin/newfs_lfs";
                    346:                        break;
                    347:                default:
                    348:                        return 0;
                    349:                }
1.40      mrg       350:                error = run_prog(RUN_DISPLAY, MSG_cmdfail, "%s /dev/r%s",
1.57      dsl       351:                    newfs, partname);
                    352:        } else
1.40      mrg       353:                error = 0;
1.57      dsl       354:
                    355:        if (error == 0) {
1.48      christos  356:                snprintf(dev_name, sizeof(dev_name), "/dev/%s", partname);
1.40      mrg       357:                if (partno > 0) /* XXX strcmp(mountpoint, "/") ? XXX */
1.9       jonathan  358:                        make_target_dir(mountpoint);
1.40      mrg       359:                error = target_mount(bsdlabel[partno].pi_fstype == FS_BSDFFS ?
1.48      christos  360:                    "-v -o async" : "-v", dev_name, mountpoint);
1.25      bouyer    361:                if (error) {
1.48      christos  362:                        msg_display(MSG_mountfail, dev_name, mountpoint);
1.53      dsl       363:                        process_menu(MENU_ok, NULL);
1.25      bouyer    364:                }
1.9       jonathan  365:        }
1.24      bouyer    366:        return error;
1.1       phil      367: }
                    368:
1.38      mrg       369: int
                    370: make_fstab(void)
1.1       phil      371: {
                    372:        FILE *f;
1.48      christos  373:        int i, swap_dev = -1;
1.1       phil      374:
                    375:        /* Create the fstab. */
1.8       jonathan  376:        make_target_dir("/etc");
1.23      fvdl      377:        f = target_fopen("/etc/fstab", "w");
1.20      garbled   378:        if (logging)
1.47      fvdl      379:                (void)fprintf(logfp,
                    380:                    "Creating %s/etc/fstab.\n", target_prefix());
1.40      mrg       381:        scripting_fprintf(NULL, "cat <<EOF >%s/etc/fstab\n", target_prefix());
1.20      garbled   382:
1.1       phil      383:        if (f == NULL) {
                    384: #ifndef DEBUG
1.24      bouyer    385:                msg_display(MSG_createfstab);
1.20      garbled   386:                if (logging)
1.47      fvdl      387:                        (void)fprintf(logfp, "Failed to make /etc/fstab!\n");
1.53      dsl       388:                process_menu(MENU_ok, NULL);
1.25      bouyer    389:                return 1;
1.1       phil      390: #else
                    391:                f = stdout;
1.51      dsl       392: #endif
1.1       phil      393:        }
1.40      mrg       394:
1.57      dsl       395:        for (i = 0; i < getmaxpartitions(); i++) {
                    396:                const char *s = "";
                    397:                const char *mp = bsdlabel[i].pi_mount;
                    398:                const char *fstype = "ffs";
                    399:
                    400:                if (!*mp) {
                    401:                        /*
                    402:                         * No mount point specified, comment out line and
                    403:                         * use /mnt as a placeholder for the mount point.
                    404:                         */
                    405:                        s = "# ";
                    406:                        mp = "/mnt";
                    407:                }
                    408:
                    409:                switch (bsdlabel[i].pi_fstype) {
                    410:                case FS_BSDLFS:
1.40      mrg       411:                        /* If there is no LFS, just comment it out. */
1.57      dsl       412:                        if (check_lfs_progs())
                    413:                                s = "# ";
                    414:                        fstype = "lfs";
                    415:                        /* FALLTHROUGH */
                    416:                case FS_BSDFFS:
                    417:                        scripting_fprintf(f, "%s/dev/%s%c %s %s rw 1 %d\n",
                    418:                               s, diskdev, 'a' + i, mp, fstype, fsck_num(mp));
                    419:                        break;
                    420:                case FS_MSDOS:
                    421:                        scripting_fprintf(f, "%s/dev/%s%c %s msdos rw 0 0\n",
                    422:                               s, diskdev, 'a' + i, mp);
                    423:                        break;
                    424:                case FS_SWAP:
1.48      christos  425:                        if (swap_dev == -1)
                    426:                                swap_dev = i;
1.51      dsl       427:                        scripting_fprintf(f, "/dev/%s%c none swap sw 0 0\n",
                    428:                                diskdev, 'a' + i);
1.57      dsl       429:                        break;
1.20      garbled   430:                }
1.57      dsl       431:        }
                    432:
1.56      dsl       433:        if (tmp_mfs_size != 0) {
1.48      christos  434:                if (swap_dev != -1)
1.56      dsl       435:                        scripting_fprintf(f, "/dev/%s%c /tmp mfs rw,-s=%d\n",
                    436:                                diskdev, 'a' + swap_dev, tmp_mfs_size);
1.40      mrg       437:                else
1.56      dsl       438:                        scripting_fprintf(f, "swap /tmp mfs rw,-s=%d\n,
                    439:                                tmp_mfs_size");
1.20      garbled   440:        }
1.57      dsl       441:
                    442:        /* Add /kern to fstab and make mountpoint. */
1.40      mrg       443:        scripting_fprintf(script, "/kern /kern kernfs rw\n");
1.57      dsl       444:        make_target_dir("/kern");
                    445:
1.40      mrg       446:        scripting_fprintf(NULL, "EOF\n");
                    447:
1.1       phil      448: #ifndef DEBUG
                    449:        fclose(f);
1.20      garbled   450:        fflush(NULL);
1.1       phil      451: #endif
1.24      bouyer    452:        return 0;
1.1       phil      453: }
1.14      jonathan  454:
1.44      scottr    455: /* Return the appropriate fs_passno field, as specified by fstab(5) */
1.40      mrg       456: static int
                    457: fsck_num(const char *mp)
                    458: {
1.44      scottr    459:        return (strcmp(mp, "/") == 0) ? 1 : 2;
1.40      mrg       460: }
                    461:
1.1       phil      462:
1.2       phil      463: /* Get information on the file systems mounted from the root filesystem.
                    464:  * Offer to convert them into 4.4BSD inodes if they are not 4.4BSD
                    465:  * inodes.  Fsck them.  Mount them.
                    466:  */
                    467:
1.3       phil      468:
                    469: static struct lookfor fstabbuf[] = {
1.37      fvdl      470:        {"/dev/", "/dev/%s %s ffs %s", "c", NULL, 0, 0, foundffs},
                    471:        {"/dev/", "/dev/%s %s ufs %s", "c", NULL, 0, 0, foundffs},
1.2       phil      472: };
1.48      christos  473: static size_t numfstabbuf = sizeof(fstabbuf) / sizeof(struct lookfor);
1.3       phil      474:
                    475: #define MAXDEVS 40
                    476:
                    477: static char dev[MAXDEVS][SSTRSIZE];
                    478: static char mnt[MAXDEVS][STRSIZE];
                    479: static int  devcnt = 0;
1.2       phil      480:
1.3       phil      481: static void
1.48      christos  482: /*ARGSUSED*/
                    483: foundffs(struct data *list, size_t num)
1.3       phil      484: {
1.37      fvdl      485:        if (strcmp(list[1].u.s_val, "/") != 0 &&
                    486:            strstr(list[2].u.s_val, "noauto") == NULL) {
1.3       phil      487:                strncpy(dev[devcnt], list[0].u.s_val, SSTRSIZE);
                    488:                strncpy(mnt[devcnt], list[1].u.s_val, STRSIZE);
                    489:                devcnt++;
                    490:        }
                    491: }
                    492:
1.11      jonathan  493: /*
1.50      fvdl      494:  * Run a check on the specified filesystem.
1.11      jonathan  495:  */
1.3       phil      496: static int
1.11      jonathan  497: do_fsck(const char *diskpart)
1.2       phil      498: {
1.48      christos  499:        char rraw[SSTRSIZE];
1.50      fvdl      500:        char *prog = "/sbin/fsck";
1.11      jonathan  501:        int err;
1.3       phil      502:
1.11      jonathan  503:        /* cons up raw partition name. */
1.48      christos  504:        snprintf (rraw, sizeof(rraw), "/dev/r%s", diskpart);
1.2       phil      505:
1.31      wiz       506: #ifndef        DEBUG_SETS
1.50      fvdl      507:        err = run_prog(RUN_DISPLAY, NULL, "%s %s", prog, rraw);
1.16      jonathan  508: #else
1.50      fvdl      509:        err = run_prog(RUN_DISPLAY, NULL, "%s -f %s", prog, rraw);
1.51      dsl       510: #endif
1.40      mrg       511:        wrefresh(stdscr);
1.11      jonathan  512:        return err;
1.2       phil      513: }
                    514:
1.11      jonathan  515: /*
                    516:  * Do an fsck. On failure,  inform the user by showing a warning
                    517:  * message and doing menu_ok() before proceeding.
                    518:  * acknowledge the warning before continuing.
                    519:  * Returns 0 on success, or nonzero return code from do_fsck() on failure.
                    520:  */
1.2       phil      521: int
1.11      jonathan  522: fsck_with_error_menu(const char *diskpart)
1.10      jonathan  523: {
1.40      mrg       524:        int error;
                    525:
                    526:        if ((error = do_fsck(diskpart)) != 0) {
1.11      jonathan  527: #ifdef DEBUG
                    528:                fprintf(stderr, "sysinst: do_fsck() returned err %d\n", error);
                    529: #endif
1.23      fvdl      530:                msg_display(MSG_badfs, diskpart, "", error);
1.53      dsl       531:                process_menu(MENU_ok, NULL);
1.3       phil      532:        }
1.11      jonathan  533:        return error;
                    534: }
                    535:
1.2       phil      536:
1.11      jonathan  537: /*
                    538:  * Do target_mount, but print a message and do menu_ok() before
                    539:  * proceeding, to inform the user.
1.60      dsl       540:  * returns 0 if the mount completed without indicating errors,
                    541:  * and an nonzero error code from target_mount() otherwise.
1.11      jonathan  542:  */
1.51      dsl       543: int target_mount_with_error_menu(const char *opt,
1.11      jonathan  544:                 char *diskpart, const char *mntpoint)
                    545: {
1.40      mrg       546:        int error;
1.48      christos  547:        char dev_name[STRSIZE];
1.11      jonathan  548:
1.48      christos  549:        snprintf(dev_name, sizeof(dev_name), "/dev/%s", diskpart);
1.11      jonathan  550: #ifdef DEBUG
                    551:        fprintf(stderr, "sysinst: mount_with_error_menu: %s %s %s\n",
1.48      christos  552:                opt, dev_name, mntpoint);
1.11      jonathan  553: #endif
                    554:
1.48      christos  555:        if ((error = target_mount(opt, dev_name, mntpoint)) != 0) {
                    556:                msg_display (MSG_badmount, dev_name, "");
1.53      dsl       557:                process_menu (MENU_ok, NULL);
1.11      jonathan  558:                return error;
                    559:        } else {
                    560: #ifdef DEBUG
1.60      dsl       561:                printf("mount %s %s %s OK\n", opt, diskpart, mntpoint);
1.11      jonathan  562: #endif
1.10      jonathan  563:        }
1.11      jonathan  564:
                    565:        return error;
                    566: }
                    567:
                    568: /*
                    569:  * fsck and mount the root partition.
                    570:  */
                    571: int
1.59      dsl       572: fsck_root(void)
1.11      jonathan  573: {
1.60      dsl       574:        int     error;
1.11      jonathan  575:        char    rootdev[STRSIZE];
                    576:
1.60      dsl       577:        /* cons up the root name: partition 'a' on the target diskdev.*/
1.11      jonathan  578:        snprintf(rootdev, STRSIZE, "%s%c", diskdev, 'a');
                    579: #ifdef DEBUG
                    580:        printf("fsck_root: rootdev is %s\n", rootdev);
                    581: #endif
                    582:        error = fsck_with_error_menu(rootdev);
                    583:        if (error != 0)
                    584:                return error;
                    585:
                    586:        if (target_already_root()) {
                    587:                return (0);
                    588:        }
                    589:
1.60      dsl       590:        /* Mount /dev/<diskdev>a on target's "".
1.51      dsl       591:         * If we pass "" as mount-on, Prefixing will DTRT.
1.11      jonathan  592:         * for now, use no options.
                    593:         * XXX consider -o remount in case target root is
1.60      dsl       594:         * current root, still readonly from single-user?
1.11      jonathan  595:         */
                    596:        error = target_mount_with_error_menu("", rootdev, "");
                    597:
                    598: #ifdef DEBUG
                    599:        printf("fsck_root: mount of %s returns %d\n", rootdev, error);
                    600: #endif
                    601:        return (error);
1.10      jonathan  602: }
                    603:
                    604: int
1.23      fvdl      605: fsck_disks(void)
1.59      dsl       606: {
                    607:        char *fstab;
1.10      jonathan  608:        int   fstabsize;
                    609:        int   i;
1.11      jonathan  610:        int   error;
1.10      jonathan  611:
                    612:        /* First the root device. */
                    613:        if (!target_already_root()) {
1.11      jonathan  614:                error = fsck_root();
1.51      dsl       615:                if (error != 0 && error != EBUSY)
1.10      jonathan  616:                        return 0;
1.2       phil      617:        }
                    618:
1.11      jonathan  619:        /* Check the target /etc/fstab exists before trying to parse it. */
1.51      dsl       620:        if (target_dir_exists_p("/etc") == 0 ||
1.16      jonathan  621:            target_file_exists_p("/etc/fstab") == 0) {
1.11      jonathan  622:                msg_display(MSG_noetcfstab, diskdev);
1.53      dsl       623:                process_menu(MENU_ok, NULL);
1.11      jonathan  624:                return 0;
                    625:        }
                    626:
                    627:
1.10      jonathan  628:        /* Get fstab entries from the target-root /etc/fstab. */
1.23      fvdl      629:        fstabsize = target_collect_file(T_FILE, &fstab, "/etc/fstab");
1.2       phil      630:        if (fstabsize < 0) {
                    631:                /* error ! */
1.11      jonathan  632:                msg_display(MSG_badetcfstab, diskdev);
1.53      dsl       633:                process_menu(MENU_ok, NULL);
1.2       phil      634:                return 0;
                    635:        }
1.48      christos  636:        walk(fstab, (size_t)fstabsize, fstabbuf, numfstabbuf);
1.2       phil      637:        free(fstab);
                    638:
1.23      fvdl      639:        for (i = 0; i < devcnt; i++) {
1.60      dsl       640:                if (fsck_with_error_menu(dev[i]))
1.3       phil      641:                        return 0;
1.11      jonathan  642:
1.16      jonathan  643: #ifdef DEBUG
1.11      jonathan  644:                printf("sysinst: mount %s\n", dev[i]);
1.16      jonathan  645: #endif
1.51      dsl       646:                if (target_mount_with_error_menu("", dev[i], mnt[i]) != 0)
1.3       phil      647:                        return 0;
                    648:        }
1.51      dsl       649:
1.2       phil      650:        return 1;
1.32      fvdl      651: }
                    652:
                    653: int
1.59      dsl       654: set_swap(const char *dev, partinfo *pp)
1.32      fvdl      655: {
                    656:        partinfo parts[16];
                    657:        int i, maxpart;
1.58      dsl       658:        char *cp;
                    659:        int rval;
1.32      fvdl      660:
                    661:        if (pp == NULL) {
                    662:                emptylabel(parts);
                    663:                if (incorelabel(dev, parts) < 0)
                    664:                        return -1;
                    665:                pp = parts;
                    666:        }
                    667:
                    668:        maxpart = getmaxpartitions();
                    669:
                    670:        for (i = 0; i < maxpart; i++) {
1.58      dsl       671:                if (pp[i].pi_fstype != FS_SWAP)
                    672:                        continue;
                    673:                asprintf(&cp, "/dev/%s%c", dev, 'a' + i);
                    674:                rval = swapctl(SWAP_ON, cp, 0);
                    675:                free(cp);
                    676:                if (rval != 0)
                    677:                        return -1;
                    678:        }
                    679:
                    680:        return 0;
                    681: }
                    682:
                    683: int
                    684: check_swap(const char *dev, int remove)
                    685: {
                    686:        struct swapent *swap;
                    687:        char *cp;
                    688:        int nswap;
                    689:        int l;
                    690:        int rval = 0;
                    691:
                    692:        nswap = swapctl(SWAP_NSWAP, 0, 0);
                    693:        if (nswap <= 0)
                    694:                return 0;
                    695:
                    696:        swap = malloc(nswap * sizeof *swap);
                    697:        if (swap == NULL)
                    698:                return -1;
                    699:
                    700:        nswap = swapctl(SWAP_STATS, swap, nswap);
                    701:        if (nswap < 0)
                    702:                goto bad_swap;
                    703:
                    704:        l = strlen(dev);
                    705:        while (--nswap >= 0) {
                    706:                /* Should we check the se_dev or se_path? */
                    707:                cp = swap[nswap].se_path;
                    708:                if (memcmp(cp, "/dev/", 5) != 0)
                    709:                        continue;
                    710:                if (memcmp(cp + 5, dev, l) != 0)
                    711:                        continue;
                    712:                if (!isalpha(*(unsigned char *)(cp + 5 + l)))
                    713:                        continue;
                    714:                if (cp[5 + l + 1] != 0)
                    715:                        continue;
                    716:                /* ok path looks like it is for this device */
                    717:                if (!remove) {
                    718:                        /* count active swap areas */
                    719:                        rval++;
                    720:                        continue;
1.32      fvdl      721:                }
1.58      dsl       722:                if (swapctl(SWAP_OFF, cp, 0) == -1)
                    723:                        rval = -1;
1.32      fvdl      724:        }
                    725:
1.58      dsl       726:     done:
                    727:        free(swap);
                    728:        return rval;
                    729:
                    730:     bad_swap:
                    731:        rval = -1;
                    732:        goto done;
1.1       phil      733: }

CVSweb <webmaster@jp.NetBSD.org>