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>