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

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

CVSweb <webmaster@jp.NetBSD.org>