| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: disks.c,v 1.14 2018/05/01 09:01:45 martin Exp $ */ | | 1 | /* $NetBSD: disks.c,v 1.15 2018/06/03 13:16:30 martin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright 1997 Piermont Information Systems Inc. | | 4 | * Copyright 1997 Piermont Information Systems Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Written by Philip A. Nelson for Piermont Information Systems Inc. | | 7 | * Written by Philip A. Nelson for Piermont Information Systems Inc. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -58,27 +58,27 @@ | | | @@ -58,27 +58,27 @@ |
58 | #include <dev/ata/atareg.h> | | 58 | #include <dev/ata/atareg.h> |
59 | #include <sys/ataio.h> | | 59 | #include <sys/ataio.h> |
60 | | | 60 | |
61 | #include "defs.h" | | 61 | #include "defs.h" |
62 | #include "md.h" | | 62 | #include "md.h" |
63 | #include "msg_defs.h" | | 63 | #include "msg_defs.h" |
64 | #include "menu_defs.h" | | 64 | #include "menu_defs.h" |
65 | #include "txtwalk.h" | | 65 | #include "txtwalk.h" |
66 | | | 66 | |
67 | /* Disk descriptions */ | | 67 | /* Disk descriptions */ |
68 | struct disk_desc { | | 68 | struct disk_desc { |
69 | char dd_name[SSTRSIZE]; | | 69 | char dd_name[SSTRSIZE]; |
70 | char dd_descr[70]; | | 70 | char dd_descr[70]; |
71 | uint dd_no_mbr; | | 71 | bool dd_no_mbr, dd_no_part; |
72 | uint dd_cyl; | | 72 | uint dd_cyl; |
73 | uint dd_head; | | 73 | uint dd_head; |
74 | uint dd_sec; | | 74 | uint dd_sec; |
75 | uint dd_secsize; | | 75 | uint dd_secsize; |
76 | uint dd_totsec; | | 76 | uint dd_totsec; |
77 | }; | | 77 | }; |
78 | | | 78 | |
79 | /* gpt(8) use different filesystem names. | | 79 | /* gpt(8) use different filesystem names. |
80 | So, we cant use ./common/lib/libutil/getfstypename.c */ | | 80 | So, we cant use ./common/lib/libutil/getfstypename.c */ |
81 | struct gptfs_t { | | 81 | struct gptfs_t { |
82 | const char *name; | | 82 | const char *name; |
83 | int id; | | 83 | int id; |
84 | uuid_t uuid; | | 84 | uuid_t uuid; |
| @@ -94,36 +94,37 @@ static const struct gptfs_t gpt_filesyst | | | @@ -94,36 +94,37 @@ static const struct gptfs_t gpt_filesyst |
94 | { "ccd", FS_CCD, GPT_ENT_TYPE_NETBSD_CCD, }, | | 94 | { "ccd", FS_CCD, GPT_ENT_TYPE_NETBSD_CCD, }, |
95 | { "raid", FS_RAID, GPT_ENT_TYPE_NETBSD_RAIDFRAME, }, | | 95 | { "raid", FS_RAID, GPT_ENT_TYPE_NETBSD_RAIDFRAME, }, |
96 | { "cgd", FS_CGD, GPT_ENT_TYPE_NETBSD_CGD, }, | | 96 | { "cgd", FS_CGD, GPT_ENT_TYPE_NETBSD_CGD, }, |
97 | { "efi", FS_OTHER, GPT_ENT_TYPE_EFI, }, | | 97 | { "efi", FS_OTHER, GPT_ENT_TYPE_EFI, }, |
98 | { "bios", FS_OTHER, GPT_ENT_TYPE_BIOS, }, | | 98 | { "bios", FS_OTHER, GPT_ENT_TYPE_BIOS, }, |
99 | { NULL, -1, GPT_ENT_TYPE_UNUSED, }, | | 99 | { NULL, -1, GPT_ENT_TYPE_UNUSED, }, |
100 | }; | | 100 | }; |
101 | | | 101 | |
102 | /* Local prototypes */ | | 102 | /* Local prototypes */ |
103 | static int foundffs(struct data *, size_t); | | 103 | static int foundffs(struct data *, size_t); |
104 | #ifdef USE_SYSVBFS | | 104 | #ifdef USE_SYSVBFS |
105 | static int foundsysvbfs(struct data *, size_t); | | 105 | static int foundsysvbfs(struct data *, size_t); |
106 | #endif | | 106 | #endif |
107 | static int fsck_preen(const char *, int, const char *); | | 107 | static int fsck_preen(const char *, int, const char *, bool silent); |
108 | static void fixsb(const char *, const char *, char); | | 108 | static void fixsb(const char *, const char *, char); |
109 | static bool is_gpt(const char *); | | 109 | static bool is_gpt(const char *); |
110 | static int incoregpt(pm_devs_t *, partinfo *); | | 110 | static int incoregpt(pm_devs_t *, partinfo *); |
111 | | | 111 | |
112 | #ifndef DISK_NAMES | | 112 | #ifndef DISK_NAMES |
113 | #define DISK_NAMES "wd", "sd", "ld", "raid" | | 113 | #define DISK_NAMES "wd", "sd", "ld", "raid" |
114 | #endif | | 114 | #endif |
115 | | | 115 | |
116 | static const char *disk_names[] = { DISK_NAMES, "vnd", "cgd", NULL }; | | 116 | static const char *disk_names[] = { DISK_NAMES, |
| | | 117 | "vnd", "cgd", "dk:no_part", NULL }; |
117 | | | 118 | |
118 | static bool tmpfs_on_var_shm(void); | | 119 | static bool tmpfs_on_var_shm(void); |
119 | | | 120 | |
120 | const char * | | 121 | const char * |
121 | getfslabelname(uint8_t f) | | 122 | getfslabelname(uint8_t f) |
122 | { | | 123 | { |
123 | if (f >= __arraycount(fstypenames) || fstypenames[f] == NULL) | | 124 | if (f >= __arraycount(fstypenames) || fstypenames[f] == NULL) |
124 | return "invalid"; | | 125 | return "invalid"; |
125 | return fstypenames[f]; | | 126 | return fstypenames[f]; |
126 | } | | 127 | } |
127 | | | 128 | |
128 | /* | | 129 | /* |
129 | * Decide wether we want to mount a tmpfs on /var/shm: we do this always | | 130 | * Decide wether we want to mount a tmpfs on /var/shm: we do this always |
| @@ -386,127 +387,260 @@ get_default_cdrom(void) | | | @@ -386,127 +387,260 @@ get_default_cdrom(void) |
386 | if (strncmp(cd_dev, name, strlen(cd_dev) - 2) != 0) | | 387 | if (strncmp(cd_dev, name, strlen(cd_dev) - 2) != 0) |
387 | continue; | | 388 | continue; |
388 | if (name != disknames) | | 389 | if (name != disknames) |
389 | strcpy(disknames, name); | | 390 | strcpy(disknames, name); |
390 | strcat(disknames, "a"); | | 391 | strcat(disknames, "a"); |
391 | /* XXX: leaks, but so what? */ | | 392 | /* XXX: leaks, but so what? */ |
392 | return disknames; | | 393 | return disknames; |
393 | } | | 394 | } |
394 | } | | 395 | } |
395 | free(disknames); | | 396 | free(disknames); |
396 | return cdrom_devices[0]; | | 397 | return cdrom_devices[0]; |
397 | } | | 398 | } |
398 | | | 399 | |
| | | 400 | static void |
| | | 401 | get_wedge_descr(struct disk_desc *dd) |
| | | 402 | { |
| | | 403 | struct dkwedge_info dkw; |
| | | 404 | char buf[MAXPATHLEN]; |
| | | 405 | int fd; |
| | | 406 | |
| | | 407 | fd = opendisk(dd->dd_name, O_RDONLY, buf, sizeof(buf), 0); |
| | | 408 | if (fd == -1) |
| | | 409 | return; |
| | | 410 | |
| | | 411 | if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == 0) { |
| | | 412 | fprintf(stderr, "device %s\n", dd->dd_name); |
| | | 413 | sprintf(dd->dd_descr, "%s (%s@%s)", |
| | | 414 | dkw.dkw_wname, dkw.dkw_devname, dkw.dkw_parent); |
| | | 415 | } |
| | | 416 | close(fd); |
| | | 417 | } |
| | | 418 | |
| | | 419 | static bool |
| | | 420 | get_name_and_parent(const char *dev, char *name, char *parent) |
| | | 421 | { |
| | | 422 | struct dkwedge_info dkw; |
| | | 423 | char buf[MAXPATHLEN]; |
| | | 424 | int fd; |
| | | 425 | bool res = false; |
| | | 426 | |
| | | 427 | fd = opendisk(dev, O_RDONLY, buf, sizeof(buf), 0); |
| | | 428 | if (fd == -1) |
| | | 429 | return false; |
| | | 430 | |
| | | 431 | if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == 0) { |
| | | 432 | strcpy(name, (const char *)dkw.dkw_wname); |
| | | 433 | strcpy(parent, dkw.dkw_parent); |
| | | 434 | res = true; |
| | | 435 | } |
| | | 436 | close(fd); |
| | | 437 | return res; |
| | | 438 | } |
| | | 439 | |
| | | 440 | static bool |
| | | 441 | find_swap_part_on(const char *dev, char *swap_name) |
| | | 442 | { |
| | | 443 | struct dkwedge_info *dkw; |
| | | 444 | struct dkwedge_list dkwl; |
| | | 445 | char buf[MAXPATHLEN]; |
| | | 446 | size_t bufsize; |
| | | 447 | int fd; |
| | | 448 | u_int i; |
| | | 449 | bool res = false; |
| | | 450 | |
| | | 451 | dkw = NULL; |
| | | 452 | dkwl.dkwl_buf = dkw; |
| | | 453 | dkwl.dkwl_bufsize = 0; |
| | | 454 | |
| | | 455 | fd = opendisk(dev, O_RDONLY, buf, sizeof(buf), 0); |
| | | 456 | if (fd == -1) |
| | | 457 | return false; |
| | | 458 | |
| | | 459 | for (;;) { |
| | | 460 | if (ioctl(fd, DIOCLWEDGES, &dkwl) == -1) { |
| | | 461 | dkwl.dkwl_ncopied = 0; |
| | | 462 | break; |
| | | 463 | } |
| | | 464 | if (dkwl.dkwl_nwedges == dkwl.dkwl_ncopied) |
| | | 465 | break; |
| | | 466 | bufsize = dkwl.dkwl_nwedges * sizeof(*dkw); |
| | | 467 | if (dkwl.dkwl_bufsize < bufsize) { |
| | | 468 | dkw = realloc(dkwl.dkwl_buf, bufsize); |
| | | 469 | if (dkw == NULL) |
| | | 470 | break; |
| | | 471 | dkwl.dkwl_buf = dkw; |
| | | 472 | dkwl.dkwl_bufsize = bufsize; |
| | | 473 | } |
| | | 474 | } |
| | | 475 | |
| | | 476 | for (i = 0; i < dkwl.dkwl_nwedges; i++) { |
| | | 477 | res = strcmp(dkw[i].dkw_ptype, DKW_PTYPE_SWAP) == 0; |
| | | 478 | if (res) { |
| | | 479 | strcpy(swap_name, (const char*)dkw[i].dkw_wname); |
| | | 480 | break; |
| | | 481 | } |
| | | 482 | } |
| | | 483 | |
| | | 484 | close(fd); |
| | | 485 | |
| | | 486 | return res; |
| | | 487 | } |
| | | 488 | |
| | | 489 | static bool |
| | | 490 | is_ffs_wedge(const char *dev) |
| | | 491 | { |
| | | 492 | struct dkwedge_info dkw; |
| | | 493 | char buf[MAXPATHLEN]; |
| | | 494 | int fd; |
| | | 495 | bool res; |
| | | 496 | |
| | | 497 | fd = opendisk(dev, O_RDONLY, buf, sizeof(buf), 0); |
| | | 498 | if (fd == -1) |
| | | 499 | return false; |
| | | 500 | |
| | | 501 | if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == -1) |
| | | 502 | return false; |
| | | 503 | |
| | | 504 | res = strcmp(dkw.dkw_ptype, DKW_PTYPE_FFS) == 0; |
| | | 505 | close(fd); |
| | | 506 | |
| | | 507 | return res; |
| | | 508 | } |
| | | 509 | |
399 | static int | | 510 | static int |
400 | get_disks(struct disk_desc *dd) | | 511 | get_disks(struct disk_desc *dd, bool with_non_partitionable) |
401 | { | | 512 | { |
402 | const char **xd; | | 513 | const char **xd; |
403 | char *cp; | | 514 | char *cp; |
404 | struct disklabel l; | | 515 | struct disklabel l; |
405 | int i; | | 516 | int i; |
406 | int numdisks; | | 517 | int numdisks; |
407 | | | 518 | |
408 | /* initialize */ | | 519 | /* initialize */ |
409 | numdisks = 0; | | 520 | numdisks = 0; |
410 | | | 521 | |
411 | for (xd = disk_names; *xd != NULL; xd++) { | | 522 | for (xd = disk_names; *xd != NULL; xd++) { |
412 | for (i = 0; i < MAX_DISKS; i++) { | | 523 | for (i = 0; i < MAX_DISKS; i++) { |
413 | strlcpy(dd->dd_name, *xd, sizeof dd->dd_name - 2); | | 524 | strlcpy(dd->dd_name, *xd, sizeof dd->dd_name - 2); |
414 | cp = strchr(dd->dd_name, ':'); | | 525 | cp = strchr(dd->dd_name, ':'); |
415 | if (cp != NULL) | | 526 | if (cp != NULL) { |
416 | dd->dd_no_mbr = !strcmp(cp, ":no_mbr"); | | 527 | dd->dd_no_mbr = !strcmp(cp, ":no_mbr"); |
417 | else { | | 528 | dd->dd_no_part = !strcmp(cp, ":no_part"); |
418 | dd->dd_no_mbr = 0; | | 529 | } else { |
| | | 530 | dd->dd_no_mbr = false; |
| | | 531 | dd->dd_no_part = false; |
419 | cp = strchr(dd->dd_name, 0); | | 532 | cp = strchr(dd->dd_name, 0); |
420 | } | | 533 | } |
| | | 534 | if (dd->dd_no_part && !with_non_partitionable) |
| | | 535 | continue; |
421 | | | 536 | |
422 | snprintf(cp, 2 + 1, "%d", i); | | 537 | snprintf(cp, 2 + 1, "%d", i); |
423 | if (!get_geom(dd->dd_name, &l)) { | | 538 | if (!get_geom(dd->dd_name, &l)) { |
424 | if (errno == ENOENT) | | 539 | if (errno == ENOENT) |
425 | break; | | 540 | break; |
426 | continue; | | 541 | if (errno != ENOTTY || !dd->dd_no_part) |
| | | 542 | /* |
| | | 543 | * Allow plain partitions, |
| | | 544 | * like already existing wedges |
| | | 545 | * (like dk0) if marked as |
| | | 546 | * non-partitioning device. |
| | | 547 | * For all other cases, continue |
| | | 548 | * with the next disk. |
| | | 549 | */ |
| | | 550 | continue; |
| | | 551 | if (!is_ffs_wedge(dd->dd_name)) |
| | | 552 | continue; |
427 | } | | 553 | } |
428 | | | 554 | |
429 | /* | | 555 | /* |
430 | * Exclude a disk mounted as root partition, | | 556 | * Exclude a disk mounted as root partition, |
431 | * in case of install-image on a USB memstick. | | 557 | * in case of install-image on a USB memstick. |
432 | */ | | 558 | */ |
433 | if (is_active_rootpart(dd->dd_name, 0)) | | 559 | if (is_active_rootpart(dd->dd_name, 0)) |
434 | continue; | | 560 | continue; |
435 | | | 561 | |
436 | dd->dd_cyl = l.d_ncylinders; | | 562 | if (!dd->dd_no_part) { |
437 | dd->dd_head = l.d_ntracks; | | 563 | dd->dd_cyl = l.d_ncylinders; |
438 | dd->dd_sec = l.d_nsectors; | | 564 | dd->dd_head = l.d_ntracks; |
439 | dd->dd_secsize = l.d_secsize; | | 565 | dd->dd_sec = l.d_nsectors; |
440 | dd->dd_totsec = l.d_secperunit; | | 566 | dd->dd_secsize = l.d_secsize; |
441 | get_descr(dd); | | 567 | dd->dd_totsec = l.d_secperunit; |
| | | 568 | } |
| | | 569 | if (dd->dd_no_part) |
| | | 570 | get_wedge_descr(dd); |
| | | 571 | else |
| | | 572 | get_descr(dd); |
442 | dd++; | | 573 | dd++; |
443 | numdisks++; | | 574 | numdisks++; |
444 | if (numdisks >= MAX_DISKS) | | 575 | if (numdisks >= MAX_DISKS) |
445 | return numdisks; | | 576 | return numdisks; |
446 | } | | 577 | } |
447 | } | | 578 | } |
448 | return numdisks; | | 579 | return numdisks; |
449 | } | | 580 | } |
450 | | | 581 | |
451 | int | | 582 | int |
452 | find_disks(const char *doingwhat) | | 583 | find_disks(const char *doingwhat) |
453 | { | | 584 | { |
454 | struct disk_desc disks[MAX_DISKS]; | | 585 | struct disk_desc disks[MAX_DISKS]; |
455 | menu_ent dsk_menu[nelem(disks) + 1]; // + 1 for extended partitioning entry | | 586 | menu_ent dsk_menu[nelem(disks) + 1]; // + 1 for extended partitioning entry |
456 | struct disk_desc *disk; | | 587 | struct disk_desc *disk; |
457 | int i, already_found; | | 588 | int i = 0, skipped = 0; |
458 | int numdisks, selected_disk = -1; | | 589 | int already_found, numdisks, selected_disk = -1; |
459 | int menu_no; | | 590 | int menu_no; |
460 | pm_devs_t *pm_i, *pm_last = NULL; | | 591 | pm_devs_t *pm_i, *pm_last = NULL; |
461 | | | 592 | |
462 | /* Find disks. */ | | 593 | /* Find disks. */ |
463 | numdisks = get_disks(disks); | | 594 | numdisks = get_disks(disks, partman_go <= 0); |
464 | | | 595 | |
465 | /* need a redraw here, kernel messages hose everything */ | | 596 | /* need a redraw here, kernel messages hose everything */ |
466 | touchwin(stdscr); | | 597 | touchwin(stdscr); |
467 | refresh(); | | 598 | refresh(); |
468 | /* Kill typeahead, it won't be what the user had in mind */ | | 599 | /* Kill typeahead, it won't be what the user had in mind */ |
469 | fpurge(stdin); | | 600 | fpurge(stdin); |
470 | | | 601 | |
471 | /* | | 602 | /* |
472 | * partman_go: <0 - we want to see menu with extended partitioning | | 603 | * partman_go: <0 - we want to see menu with extended partitioning |
473 | * ==0 - we want to see simple select disk menu | | 604 | * ==0 - we want to see simple select disk menu |
474 | * >0 - we do not want to see any menus, just detect | | 605 | * >0 - we do not want to see any menus, just detect |
475 | * all disks | | 606 | * all disks |
476 | */ | | 607 | */ |
477 | if (partman_go <= 0) { | | 608 | if (partman_go <= 0) { |
478 | if (numdisks == 0) { | | 609 | if (numdisks == 0) { |
479 | /* No disks found! */ | | 610 | /* No disks found! */ |
480 | msg_display(MSG_nodisk); | | 611 | msg_display(MSG_nodisk); |
481 | process_menu(MENU_ok, NULL); | | 612 | process_menu(MENU_ok, NULL); |
482 | /*endwin();*/ | | 613 | /*endwin();*/ |
483 | return -1; | | 614 | return -1; |
484 | } else { | | 615 | } else { |
485 | /* One or more disks found! */ | | 616 | /* One or more disks found! */ |
486 | for (i = 0; i < numdisks; i++) { | | 617 | for (i = 0; i < numdisks; i++) { |
487 | dsk_menu[i].opt_name = disks[i].dd_descr; | | 618 | dsk_menu[i].opt_name = |
| | | 619 | disks[i].dd_descr; |
488 | dsk_menu[i].opt_menu = OPT_NOMENU; | | 620 | dsk_menu[i].opt_menu = OPT_NOMENU; |
489 | dsk_menu[i].opt_flags = OPT_EXIT; | | 621 | dsk_menu[i].opt_flags = OPT_EXIT; |
490 | dsk_menu[i].opt_action = set_menu_select; | | 622 | dsk_menu[i].opt_action = set_menu_select; |
491 | } | | 623 | } |
492 | if (partman_go < 0) { | | 624 | if (partman_go < 0) { |
493 | dsk_menu[i].opt_name = MSG_partman; | | 625 | dsk_menu[i].opt_name = MSG_partman; |
494 | dsk_menu[i].opt_menu = OPT_NOMENU; | | 626 | dsk_menu[i].opt_menu = OPT_NOMENU; |
495 | dsk_menu[i].opt_flags = OPT_EXIT; | | 627 | dsk_menu[i].opt_flags = OPT_EXIT; |
496 | dsk_menu[i].opt_action = set_menu_select; | | 628 | dsk_menu[i].opt_action = set_menu_select; |
497 | } | | 629 | } |
498 | menu_no = new_menu(MSG_Available_disks, | | 630 | menu_no = new_menu(MSG_Available_disks, |
499 | dsk_menu, numdisks + ((partman_go<0)?1:0), -1, 4, 0, 0, MC_SCROLL, | | 631 | dsk_menu, numdisks |
| | | 632 | + ((partman_go<0)?1:0), -1, |
| | | 633 | 4, 0, 0, MC_SCROLL, |
500 | NULL, NULL, NULL, NULL, NULL); | | 634 | NULL, NULL, NULL, NULL, NULL); |
501 | if (menu_no == -1) | | 635 | if (menu_no == -1) |
502 | return -1; | | 636 | return -1; |
503 | msg_display(MSG_ask_disk, doingwhat); | | 637 | msg_display(MSG_ask_disk, doingwhat); |
504 | process_menu(menu_no, &selected_disk); | | 638 | process_menu(menu_no, &selected_disk); |
505 | free_menu(menu_no); | | 639 | free_menu(menu_no); |
506 | } | | 640 | } |
507 | if (partman_go < 0 && selected_disk == numdisks) { | | 641 | if (partman_go < 0 && selected_disk == numdisks) { |
508 | partman_go = 1; | | 642 | partman_go = 1; |
509 | return -2; | | 643 | return -2; |
510 | } else | | 644 | } else |
511 | partman_go = 0; | | 645 | partman_go = 0; |
512 | if (selected_disk < 0 || selected_disk >= numdisks) | | 646 | if (selected_disk < 0 || selected_disk >= numdisks) |
| @@ -535,64 +669,80 @@ find_disks(const char *doingwhat) | | | @@ -535,64 +669,80 @@ find_disks(const char *doingwhat) |
535 | pm = pm_new; | | 669 | pm = pm_new; |
536 | pm->found = 1; | | 670 | pm->found = 1; |
537 | pm->bootable = 0; | | 671 | pm->bootable = 0; |
538 | pm->pi.menu_no = -1; | | 672 | pm->pi.menu_no = -1; |
539 | pm->disktype = "unknown"; | | 673 | pm->disktype = "unknown"; |
540 | pm->doessf = ""; | | 674 | pm->doessf = ""; |
541 | strlcpy(pm->diskdev, disk->dd_name, sizeof pm->diskdev); | | 675 | strlcpy(pm->diskdev, disk->dd_name, sizeof pm->diskdev); |
542 | strlcpy(pm->diskdev_descr, disk->dd_descr, sizeof pm->diskdev_descr); | | 676 | strlcpy(pm->diskdev_descr, disk->dd_descr, sizeof pm->diskdev_descr); |
543 | /* Use as a default disk if the user has the sets on a local disk */ | | 677 | /* Use as a default disk if the user has the sets on a local disk */ |
544 | strlcpy(localfs_dev, disk->dd_name, sizeof localfs_dev); | | 678 | strlcpy(localfs_dev, disk->dd_name, sizeof localfs_dev); |
545 | | | 679 | |
546 | pm->gpt = is_gpt(pm->diskdev); | | 680 | pm->gpt = is_gpt(pm->diskdev); |
547 | pm->no_mbr = disk->dd_no_mbr || pm->gpt; | | 681 | pm->no_mbr = disk->dd_no_mbr || pm->gpt; |
548 | pm->sectorsize = disk->dd_secsize; | | 682 | pm->no_part = disk->dd_no_part; |
549 | pm->dlcyl = disk->dd_cyl; | | 683 | if (!pm->no_part) { |
550 | pm->dlhead = disk->dd_head; | | 684 | pm->sectorsize = disk->dd_secsize; |
551 | pm->dlsec = disk->dd_sec; | | 685 | pm->dlcyl = disk->dd_cyl; |
552 | pm->dlsize = disk->dd_totsec; | | 686 | pm->dlhead = disk->dd_head; |
553 | if (pm->dlsize == 0) | | 687 | pm->dlsec = disk->dd_sec; |
554 | pm->dlsize = disk->dd_cyl * disk->dd_head * disk->dd_sec; | | 688 | pm->dlsize = disk->dd_totsec; |
555 | if (pm->dlsize > UINT32_MAX && ! partman_go) { | | 689 | if (pm->dlsize == 0) |
556 | if (logfp) | | 690 | pm->dlsize = disk->dd_cyl * disk->dd_head * disk->dd_sec; |
557 | fprintf(logfp, "Cannot process disk %s: too big size (%d)\n", | | 691 | if (pm->dlsize > UINT32_MAX && ! partman_go) { |
558 | pm->diskdev, (int)pm->dlsize); | | 692 | if (logfp) |
559 | msg_display(MSG_toobigdisklabel); | | 693 | fprintf(logfp, "Cannot process disk %s: too big size (%d)\n", |
560 | process_menu(MENU_ok, NULL); | | 694 | pm->diskdev, (int)pm->dlsize); |
561 | return -1; | | 695 | msg_display(MSG_toobigdisklabel); |
| | | 696 | process_menu(MENU_ok, NULL); |
| | | 697 | return -1; |
| | | 698 | } |
| | | 699 | } else { |
| | | 700 | pm->sectorsize = 0; |
| | | 701 | pm->dlcyl = 0; |
| | | 702 | pm->dlhead = 0; |
| | | 703 | pm->dlsec = 0; |
| | | 704 | pm->dlsize = 0; |
| | | 705 | pm->rootpart = -1; |
| | | 706 | pm->no_mbr = 1; |
| | | 707 | memset(&pm->bsdlabel, 0, sizeof(pm->bsdlabel)); |
562 | } | | 708 | } |
563 | pm->dlcylsize = pm->dlhead * pm->dlsec; | | 709 | pm->dlcylsize = pm->dlhead * pm->dlsec; |
564 | | | 710 | |
565 | label_read(); | | 711 | label_read(); |
566 | if (partman_go) { | | 712 | if (partman_go) { |
567 | pm_getrefdev(pm_new); | | 713 | pm_getrefdev(pm_new); |
568 | if (SLIST_EMPTY(&pm_head) || pm_last == NULL) | | 714 | if (SLIST_EMPTY(&pm_head) || pm_last == NULL) |
569 | SLIST_INSERT_HEAD(&pm_head, pm_new, l); | | 715 | SLIST_INSERT_HEAD(&pm_head, pm_new, l); |
570 | else | | 716 | else |
571 | SLIST_INSERT_AFTER(pm_last, pm_new, l); | | 717 | SLIST_INSERT_AFTER(pm_last, pm_new, l); |
572 | pm_new = malloc(sizeof (pm_devs_t)); | | 718 | pm_new = malloc(sizeof (pm_devs_t)); |
573 | memset(pm_new, 0, sizeof *pm_new); | | 719 | memset(pm_new, 0, sizeof *pm_new); |
574 | } else | | 720 | } else |
575 | /* We is not in partman and do not want to process all devices, exit */ | | 721 | /* We is not in partman and do not want to process all devices, exit */ |
576 | break; | | 722 | break; |
577 | } | | 723 | } |
578 | | | 724 | |
579 | return numdisks; | | 725 | return numdisks-skipped; |
580 | } | | 726 | } |
581 | | | 727 | |
582 | | | 728 | |
583 | void | | 729 | void |
584 | label_read(void) | | 730 | label_read(void) |
585 | { | | 731 | { |
| | | 732 | |
| | | 733 | if (pm->no_part) |
| | | 734 | return; |
| | | 735 | |
586 | check_available_binaries(); | | 736 | check_available_binaries(); |
587 | | | 737 | |
588 | /* Get existing/default label */ | | 738 | /* Get existing/default label */ |
589 | memset(&pm->oldlabel, 0, sizeof pm->oldlabel); | | 739 | memset(&pm->oldlabel, 0, sizeof pm->oldlabel); |
590 | if (!have_gpt || !pm->gpt) | | 740 | if (!have_gpt || !pm->gpt) |
591 | incorelabel(pm->diskdev, pm->oldlabel); | | 741 | incorelabel(pm->diskdev, pm->oldlabel); |
592 | else | | 742 | else |
593 | incoregpt(pm, pm->oldlabel); | | 743 | incoregpt(pm, pm->oldlabel); |
594 | /* Set 'target' label to current label in case we don't change it */ | | 744 | /* Set 'target' label to current label in case we don't change it */ |
595 | memcpy(&pm->bsdlabel, &pm->oldlabel, sizeof pm->bsdlabel); | | 745 | memcpy(&pm->bsdlabel, &pm->oldlabel, sizeof pm->bsdlabel); |
596 | #ifndef NO_DISKLABEL | | 746 | #ifndef NO_DISKLABEL |
597 | if (! pm->gpt) | | 747 | if (! pm->gpt) |
598 | savenewlabel(pm->oldlabel, getmaxpartitions()); | | 748 | savenewlabel(pm->oldlabel, getmaxpartitions()); |
| @@ -649,26 +799,29 @@ fmt_fspart(menudesc *m, int ptn, void *a | | | @@ -649,26 +799,29 @@ fmt_fspart(menudesc *m, int ptn, void *a |
649 | * if MD code does not define DISKLABEL_CMD, this is a no-op. | | 799 | * if MD code does not define DISKLABEL_CMD, this is a no-op. |
650 | * | | 800 | * |
651 | * i386 port uses "/sbin/disklabel -w -r", just like i386 | | 801 | * i386 port uses "/sbin/disklabel -w -r", just like i386 |
652 | * miniroot scripts, though this may leave a bogus incore label. | | 802 | * miniroot scripts, though this may leave a bogus incore label. |
653 | * | | 803 | * |
654 | * Sun ports should use DISKLABEL_CMD "/sbin/disklabel -w" | | 804 | * Sun ports should use DISKLABEL_CMD "/sbin/disklabel -w" |
655 | * to get incore to ondisk inode translation for the Sun proms. | | 805 | * to get incore to ondisk inode translation for the Sun proms. |
656 | */ | | 806 | */ |
657 | int | | 807 | int |
658 | write_disklabel (void) | | 808 | write_disklabel (void) |
659 | { | | 809 | { |
660 | int rv = 0; | | 810 | int rv = 0; |
661 | | | 811 | |
| | | 812 | if (pm && pm->no_part) |
| | | 813 | return 0; |
| | | 814 | |
662 | #ifdef DISKLABEL_CMD | | 815 | #ifdef DISKLABEL_CMD |
663 | /* disklabel the disk */ | | 816 | /* disklabel the disk */ |
664 | rv = run_program(RUN_DISPLAY, "%s -f /tmp/disktab %s '%s'", | | 817 | rv = run_program(RUN_DISPLAY, "%s -f /tmp/disktab %s '%s'", |
665 | DISKLABEL_CMD, pm->diskdev, pm->bsddiskname); | | 818 | DISKLABEL_CMD, pm->diskdev, pm->bsddiskname); |
666 | if (rv == 0) | | 819 | if (rv == 0) |
667 | update_wedges(pm->diskdev); | | 820 | update_wedges(pm->diskdev); |
668 | #endif | | 821 | #endif |
669 | return rv; | | 822 | return rv; |
670 | } | | 823 | } |
671 | | | 824 | |
672 | | | 825 | |
673 | static int | | 826 | static int |
674 | ptn_sort(const void *a, const void *b) | | 827 | ptn_sort(const void *a, const void *b) |
| @@ -678,26 +831,52 @@ ptn_sort(const void *a, const void *b) | | | @@ -678,26 +831,52 @@ ptn_sort(const void *a, const void *b) |
678 | } | | 831 | } |
679 | | | 832 | |
680 | int | | 833 | int |
681 | make_filesystems(void) | | 834 | make_filesystems(void) |
682 | { | | 835 | { |
683 | unsigned int i; | | 836 | unsigned int i; |
684 | int ptn; | | 837 | int ptn; |
685 | int ptn_order[nelem(pm->bsdlabel)]; | | 838 | int ptn_order[nelem(pm->bsdlabel)]; |
686 | int error = 0; | | 839 | int error = 0; |
687 | unsigned int maxpart = getmaxpartitions(); | | 840 | unsigned int maxpart = getmaxpartitions(); |
688 | char *newfs = NULL, *dev = NULL, *devdev = NULL; | | 841 | char *newfs = NULL, *dev = NULL, *devdev = NULL; |
689 | partinfo *lbl; | | 842 | partinfo *lbl; |
690 | | | 843 | |
| | | 844 | if (pm->no_part) { |
| | | 845 | /* check if this target device already has a ffs */ |
| | | 846 | error = fsck_preen(pm->diskdev, -1, "ffs", true); |
| | | 847 | if (error) { |
| | | 848 | if (!ask_noyes(MSG_No_filesystem_newfs)) |
| | | 849 | return EINVAL; |
| | | 850 | error = run_program(RUN_DISPLAY | RUN_PROGRESS, |
| | | 851 | "/sbin/newfs -V2 -O2 /dev/r%s", pm->diskdev); |
| | | 852 | } |
| | | 853 | |
| | | 854 | md_pre_mount(); |
| | | 855 | |
| | | 856 | make_target_dir("/"); |
| | | 857 | asprintf(&devdev, "/dev/%s", pm->diskdev); |
| | | 858 | if (devdev == NULL) |
| | | 859 | return (ENOMEM); |
| | | 860 | error = target_mount_do("-o async", devdev, "/"); |
| | | 861 | if (error) { |
| | | 862 | msg_display(MSG_mountfail, devdev, ' ', |
| | | 863 | "/"); |
| | | 864 | process_menu(MENU_ok, NULL); |
| | | 865 | } |
| | | 866 | free(devdev); |
| | | 867 | return error; |
| | | 868 | } |
| | | 869 | |
691 | if (maxpart > nelem(pm->bsdlabel)) | | 870 | if (maxpart > nelem(pm->bsdlabel)) |
692 | maxpart = nelem(pm->bsdlabel); | | 871 | maxpart = nelem(pm->bsdlabel); |
693 | | | 872 | |
694 | /* Making new file systems and mounting them */ | | 873 | /* Making new file systems and mounting them */ |
695 | | | 874 | |
696 | /* sort to ensure /usr/local is mounted after /usr (etc) */ | | 875 | /* sort to ensure /usr/local is mounted after /usr (etc) */ |
697 | for (i = 0; i < maxpart; i++) | | 876 | for (i = 0; i < maxpart; i++) |
698 | ptn_order[i] = i; | | 877 | ptn_order[i] = i; |
699 | qsort(ptn_order, maxpart, sizeof ptn_order[0], ptn_sort); | | 878 | qsort(ptn_order, maxpart, sizeof ptn_order[0], ptn_sort); |
700 | | | 879 | |
701 | for (i = 0; i < maxpart; i++) { | | 880 | for (i = 0; i < maxpart; i++) { |
702 | /* | | 881 | /* |
703 | * newfs and mount. For now, process only BSD filesystems. | | 882 | * newfs and mount. For now, process only BSD filesystems. |
| @@ -787,27 +966,27 @@ make_filesystems(void) | | | @@ -787,27 +966,27 @@ make_filesystems(void) |
787 | "%s /dev/r%s", | | 966 | "%s /dev/r%s", |
788 | newfs, dev); | | 967 | newfs, dev); |
789 | else { | | 968 | else { |
790 | run_program(RUN_SILENT | RUN_ERROR_OK, | | 969 | run_program(RUN_SILENT | RUN_ERROR_OK, |
791 | "umount /mnt2"); | | 970 | "umount /mnt2"); |
792 | error = 0; | | 971 | error = 0; |
793 | } | | 972 | } |
794 | } else | | 973 | } else |
795 | #endif | | 974 | #endif |
796 | error = run_program(RUN_DISPLAY | RUN_PROGRESS, | | 975 | error = run_program(RUN_DISPLAY | RUN_PROGRESS, |
797 | "%s /dev/r%s", newfs, dev); | | 976 | "%s /dev/r%s", newfs, dev); |
798 | } else { | | 977 | } else { |
799 | /* We'd better check it isn't dirty */ | | 978 | /* We'd better check it isn't dirty */ |
800 | error = fsck_preen(pm->diskdev, ptn, lbl->fsname); | | 979 | error = fsck_preen(pm->diskdev, ptn, lbl->fsname, false); |
801 | } | | 980 | } |
802 | free(newfs); | | 981 | free(newfs); |
803 | if (error != 0) { | | 982 | if (error != 0) { |
804 | free(devdev); | | 983 | free(devdev); |
805 | free(dev); | | 984 | free(dev); |
806 | return error; | | 985 | return error; |
807 | } | | 986 | } |
808 | | | 987 | |
809 | lbl->pi_flags ^= PIF_NEWFS; | | 988 | lbl->pi_flags ^= PIF_NEWFS; |
810 | md_pre_mount(); | | 989 | md_pre_mount(); |
811 | | | 990 | |
812 | if (partman_go == 0 && lbl->pi_flags & PIF_MOUNT && | | 991 | if (partman_go == 0 && lbl->pi_flags & PIF_MOUNT && |
813 | lbl->mnt_opts != NULL) { | | 992 | lbl->mnt_opts != NULL) { |
| @@ -852,26 +1031,48 @@ make_fstab(void) | | | @@ -852,26 +1031,48 @@ make_fstab(void) |
852 | msg_display(MSG_createfstab); | | 1031 | msg_display(MSG_createfstab); |
853 | if (logfp) | | 1032 | if (logfp) |
854 | (void)fprintf(logfp, "Failed to make /etc/fstab!\n"); | | 1033 | (void)fprintf(logfp, "Failed to make /etc/fstab!\n"); |
855 | process_menu(MENU_ok, NULL); | | 1034 | process_menu(MENU_ok, NULL); |
856 | #ifndef DEBUG | | 1035 | #ifndef DEBUG |
857 | return 1; | | 1036 | return 1; |
858 | #else | | 1037 | #else |
859 | f = stdout; | | 1038 | f = stdout; |
860 | #endif | | 1039 | #endif |
861 | } | | 1040 | } |
862 | | | 1041 | |
863 | scripting_fprintf(f, "# NetBSD %s/etc/fstab\n# See /usr/share/examples/" | | 1042 | scripting_fprintf(f, "# NetBSD %s/etc/fstab\n# See /usr/share/examples/" |
864 | "fstab/ for more examples.\n", target_prefix()); | | 1043 | "fstab/ for more examples.\n", target_prefix()); |
| | | 1044 | |
| | | 1045 | if (pm->no_part) { |
| | | 1046 | /* single dk? target */ |
| | | 1047 | char buf[200], parent[200], swap[200], *prompt; |
| | | 1048 | int res; |
| | | 1049 | |
| | | 1050 | if (!get_name_and_parent(pm->diskdev, buf, parent)) |
| | | 1051 | goto done_with_disks; |
| | | 1052 | scripting_fprintf(f, "NAME=%s\t/\tffs\trw\t\t1 1\n", |
| | | 1053 | buf); |
| | | 1054 | if (!find_swap_part_on(parent, swap)) |
| | | 1055 | goto done_with_disks; |
| | | 1056 | asprintf(&prompt, msg_string(MSG_Auto_add_swap_part), |
| | | 1057 | swap, parent); |
| | | 1058 | res = ask_yesno(prompt); |
| | | 1059 | free(prompt); |
| | | 1060 | if (res) |
| | | 1061 | scripting_fprintf(f, "NAME=%s\tnone" |
| | | 1062 | "\tswap\tsw,dp\t\t0 0\n", swap); |
| | | 1063 | goto done_with_disks; |
| | | 1064 | } |
| | | 1065 | |
865 | if (! partman_go) { | | 1066 | if (! partman_go) { |
866 | /* We want to process only one disk... */ | | 1067 | /* We want to process only one disk... */ |
867 | pm_i = pm; | | 1068 | pm_i = pm; |
868 | goto onlyonediskinfstab; | | 1069 | goto onlyonediskinfstab; |
869 | } | | 1070 | } |
870 | SLIST_FOREACH(pm_i, &pm_head, l) { | | 1071 | SLIST_FOREACH(pm_i, &pm_head, l) { |
871 | onlyonediskinfstab: | | 1072 | onlyonediskinfstab: |
872 | for (i = 0; i < getmaxpartitions(); i++) { | | 1073 | for (i = 0; i < getmaxpartitions(); i++) { |
873 | const char *s = ""; | | 1074 | const char *s = ""; |
874 | const char *mp = pm_i->bsdlabel[i].pi_mount; | | 1075 | const char *mp = pm_i->bsdlabel[i].pi_mount; |
875 | const char *fstype = "ffs"; | | 1076 | const char *fstype = "ffs"; |
876 | int fsck_pass = 0, dump_freq = 0; | | 1077 | int fsck_pass = 0, dump_freq = 0; |
877 | | | 1078 | |
| @@ -949,26 +1150,27 @@ make_fstab(void) | | | @@ -949,26 +1150,27 @@ make_fstab(void) |
949 | pm_i->bsdlabel[i].pi_flags & PIF_NODEV ? ",nodev" : "", | | 1150 | pm_i->bsdlabel[i].pi_flags & PIF_NODEV ? ",nodev" : "", |
950 | pm_i->bsdlabel[i].pi_flags & PIF_NODEVMTIME ? ",nodevmtime" : "", | | 1151 | pm_i->bsdlabel[i].pi_flags & PIF_NODEVMTIME ? ",nodevmtime" : "", |
951 | pm_i->bsdlabel[i].pi_flags & PIF_NOEXEC ? ",noexec" : "", | | 1152 | pm_i->bsdlabel[i].pi_flags & PIF_NOEXEC ? ",noexec" : "", |
952 | pm_i->bsdlabel[i].pi_flags & PIF_NOSUID ? ",nosuid" : "", | | 1153 | pm_i->bsdlabel[i].pi_flags & PIF_NOSUID ? ",nosuid" : "", |
953 | dump_freq, fsck_pass); | | 1154 | dump_freq, fsck_pass); |
954 | if (pm_i->isspecial) | | 1155 | if (pm_i->isspecial) |
955 | /* Special device (such as dk*) have only one partition */ | | 1156 | /* Special device (such as dk*) have only one partition */ |
956 | break; | | 1157 | break; |
957 | } | | 1158 | } |
958 | /* Simple install, only one disk */ | | 1159 | /* Simple install, only one disk */ |
959 | if (!partman_go) | | 1160 | if (!partman_go) |
960 | break; | | 1161 | break; |
961 | } | | 1162 | } |
| | | 1163 | done_with_disks: |
962 | if (tmp_ramdisk_size != 0) { | | 1164 | if (tmp_ramdisk_size != 0) { |
963 | #ifdef HAVE_TMPFS | | 1165 | #ifdef HAVE_TMPFS |
964 | scripting_fprintf(f, "tmpfs\t\t/tmp\ttmpfs\trw,-m=1777,-s=%" | | 1166 | scripting_fprintf(f, "tmpfs\t\t/tmp\ttmpfs\trw,-m=1777,-s=%" |
965 | PRIi64 "\n", | | 1167 | PRIi64 "\n", |
966 | tmp_ramdisk_size * 512); | | 1168 | tmp_ramdisk_size * 512); |
967 | #else | | 1169 | #else |
968 | if (swap_dev != -1 && pm_with_swap != NULL) | | 1170 | if (swap_dev != -1 && pm_with_swap != NULL) |
969 | scripting_fprintf(f, "/dev/%s%c\t\t/tmp\tmfs\trw,-s=%" | | 1171 | scripting_fprintf(f, "/dev/%s%c\t\t/tmp\tmfs\trw,-s=%" |
970 | PRIi64 "\n", | | 1172 | PRIi64 "\n", |
971 | pm_with_swap->diskdev, 'a' + swap_dev, tmp_ramdisk_size); | | 1173 | pm_with_swap->diskdev, 'a' + swap_dev, tmp_ramdisk_size); |
972 | else | | 1174 | else |
973 | scripting_fprintf(f, "swap\t\t/tmp\tmfs\trw,-s=%" | | 1175 | scripting_fprintf(f, "swap\t\t/tmp\tmfs\trw,-s=%" |
974 | PRIi64 "\n", | | 1176 | PRIi64 "\n", |
| @@ -1001,27 +1203,27 @@ make_fstab(void) | | | @@ -1001,27 +1203,27 @@ make_fstab(void) |
1001 | | | 1203 | |
1002 | | | 1204 | |
1003 | | | 1205 | |
1004 | static int | | 1206 | static int |
1005 | /*ARGSUSED*/ | | 1207 | /*ARGSUSED*/ |
1006 | foundffs(struct data *list, size_t num) | | 1208 | foundffs(struct data *list, size_t num) |
1007 | { | | 1209 | { |
1008 | int error; | | 1210 | int error; |
1009 | | | 1211 | |
1010 | if (num < 2 || strcmp(list[1].u.s_val, "/") == 0 || | | 1212 | if (num < 2 || strcmp(list[1].u.s_val, "/") == 0 || |
1011 | strstr(list[2].u.s_val, "noauto") != NULL) | | 1213 | strstr(list[2].u.s_val, "noauto") != NULL) |
1012 | return 0; | | 1214 | return 0; |
1013 | | | 1215 | |
1014 | error = fsck_preen(list[0].u.s_val, ' '-'a', "ffs"); | | 1216 | error = fsck_preen(list[0].u.s_val, ' '-'a', "ffs", false); |
1015 | if (error != 0) | | 1217 | if (error != 0) |
1016 | return error; | | 1218 | return error; |
1017 | | | 1219 | |
1018 | error = target_mount("", list[0].u.s_val, ' '-'a', list[1].u.s_val); | | 1220 | error = target_mount("", list[0].u.s_val, ' '-'a', list[1].u.s_val); |
1019 | if (error != 0) { | | 1221 | if (error != 0) { |
1020 | msg_display(MSG_mount_failed, list[0].u.s_val); | | 1222 | msg_display(MSG_mount_failed, list[0].u.s_val); |
1021 | if (!ask_noyes(NULL)) | | 1223 | if (!ask_noyes(NULL)) |
1022 | return error; | | 1224 | return error; |
1023 | } | | 1225 | } |
1024 | return 0; | | 1226 | return 0; |
1025 | } | | 1227 | } |
1026 | | | 1228 | |
1027 | #ifdef USE_SYSVBFS | | 1229 | #ifdef USE_SYSVBFS |
| @@ -1038,47 +1240,47 @@ foundsysvbfs(struct data *list, size_t n | | | @@ -1038,47 +1240,47 @@ foundsysvbfs(struct data *list, size_t n |
1038 | error = target_mount("", list[0].u.s_val, ' '-'a', list[1].u.s_val); | | 1240 | error = target_mount("", list[0].u.s_val, ' '-'a', list[1].u.s_val); |
1039 | if (error != 0) | | 1241 | if (error != 0) |
1040 | return error; | | 1242 | return error; |
1041 | return 0; | | 1243 | return 0; |
1042 | } | | 1244 | } |
1043 | #endif | | 1245 | #endif |
1044 | | | 1246 | |
1045 | /* | | 1247 | /* |
1046 | * Do an fsck. On failure, inform the user by showing a warning | | 1248 | * Do an fsck. On failure, inform the user by showing a warning |
1047 | * message and doing menu_ok() before proceeding. | | 1249 | * message and doing menu_ok() before proceeding. |
1048 | * Returns 0 on success, or nonzero return code from fsck() on failure. | | 1250 | * Returns 0 on success, or nonzero return code from fsck() on failure. |
1049 | */ | | 1251 | */ |
1050 | static int | | 1252 | static int |
1051 | fsck_preen(const char *disk, int ptn, const char *fsname) | | 1253 | fsck_preen(const char *disk, int ptn, const char *fsname, bool silent) |
1052 | { | | 1254 | { |
1053 | char *prog; | | 1255 | char *prog; |
1054 | int error; | | 1256 | int error; |
1055 | | | 1257 | |
1056 | ptn = (ptn < 0)? 0 : 'a' + ptn; | | 1258 | ptn = (ptn < 0)? 0 : 'a' + ptn; |
1057 | if (fsname == NULL) | | 1259 | if (fsname == NULL) |
1058 | return 0; | | 1260 | return 0; |
1059 | /* first, check if fsck program exists, if not, assume ok */ | | 1261 | /* first, check if fsck program exists, if not, assume ok */ |
1060 | asprintf(&prog, "/sbin/fsck_%s", fsname); | | 1262 | asprintf(&prog, "/sbin/fsck_%s", fsname); |
1061 | if (prog == NULL) | | 1263 | if (prog == NULL) |
1062 | return 0; | | 1264 | return 0; |
1063 | if (access(prog, X_OK) != 0) { | | 1265 | if (access(prog, X_OK) != 0) { |
1064 | free(prog); | | 1266 | free(prog); |
1065 | return 0; | | 1267 | return 0; |
1066 | } | | 1268 | } |
1067 | if (!strcmp(fsname,"ffs")) | | 1269 | if (!strcmp(fsname,"ffs")) |
1068 | fixsb(prog, disk, ptn); | | 1270 | fixsb(prog, disk, ptn); |
1069 | error = run_program(0, "%s -p -q /dev/r%s%c", prog, disk, ptn); | | 1271 | error = run_program(silent? RUN_SILENT|RUN_ERROR_OK : 0, "%s -p -q /dev/r%s%c", prog, disk, ptn); |
1070 | free(prog); | | 1272 | free(prog); |
1071 | if (error != 0) { | | 1273 | if (error != 0 && !silent) { |
1072 | msg_display(MSG_badfs, disk, ptn, error); | | 1274 | msg_display(MSG_badfs, disk, ptn, error); |
1073 | if (ask_noyes(NULL)) | | 1275 | if (ask_noyes(NULL)) |
1074 | error = 0; | | 1276 | error = 0; |
1075 | /* XXX at this point maybe we should run a full fsck? */ | | 1277 | /* XXX at this point maybe we should run a full fsck? */ |
1076 | } | | 1278 | } |
1077 | return error; | | 1279 | return error; |
1078 | } | | 1280 | } |
1079 | | | 1281 | |
1080 | /* This performs the same function as the etc/rc.d/fixsb script | | 1282 | /* This performs the same function as the etc/rc.d/fixsb script |
1081 | * which attempts to correct problems with ffs1 filesystems | | 1283 | * which attempts to correct problems with ffs1 filesystems |
1082 | * which may have been introduced by booting a netbsd-current kernel | | 1284 | * which may have been introduced by booting a netbsd-current kernel |
1083 | * from between April of 2003 and January 2004. For more information | | 1285 | * from between April of 2003 and January 2004. For more information |
1084 | * This script was developed as a response to NetBSD pr install/25138 | | 1286 | * This script was developed as a response to NetBSD pr install/25138 |
| @@ -1130,27 +1332,27 @@ fixsb(const char *prog, const char *disk | | | @@ -1130,27 +1332,27 @@ fixsb(const char *prog, const char *disk |
1130 | run_program(RUN_DISPLAY | RUN_PROGRESS, | | 1332 | run_program(RUN_DISPLAY | RUN_PROGRESS, |
1131 | "%s -p -c 3 /dev/r%s%c", prog, disk, ptn); | | 1333 | "%s -p -c 3 /dev/r%s%c", prog, disk, ptn); |
1132 | } | | 1334 | } |
1133 | | | 1335 | |
1134 | /* | | 1336 | /* |
1135 | * fsck and mount the root partition. | | 1337 | * fsck and mount the root partition. |
1136 | */ | | 1338 | */ |
1137 | static int | | 1339 | static int |
1138 | mount_root(void) | | 1340 | mount_root(void) |
1139 | { | | 1341 | { |
1140 | int error; | | 1342 | int error; |
1141 | int ptn = (pm->isspecial)? 0 - 'a' : pm->rootpart; | | 1343 | int ptn = (pm->isspecial)? 0 - 'a' : pm->rootpart; |
1142 | | | 1344 | |
1143 | error = fsck_preen(pm->diskdev, ptn, "ffs"); | | 1345 | error = fsck_preen(pm->diskdev, ptn, "ffs", false); |
1144 | if (error != 0) | | 1346 | if (error != 0) |
1145 | return error; | | 1347 | return error; |
1146 | | | 1348 | |
1147 | md_pre_mount(); | | 1349 | md_pre_mount(); |
1148 | | | 1350 | |
1149 | /* Mount /dev/<diskdev>a on target's "". | | 1351 | /* Mount /dev/<diskdev>a on target's "". |
1150 | * If we pass "" as mount-on, Prefixing will DTRT. | | 1352 | * If we pass "" as mount-on, Prefixing will DTRT. |
1151 | * for now, use no options. | | 1353 | * for now, use no options. |
1152 | * XXX consider -o remount in case target root is | | 1354 | * XXX consider -o remount in case target root is |
1153 | * current root, still readonly from single-user? | | 1355 | * current root, still readonly from single-user? |
1154 | */ | | 1356 | */ |
1155 | return target_mount("", pm->diskdev, ptn, ""); | | 1357 | return target_mount("", pm->diskdev, ptn, ""); |
1156 | } | | 1358 | } |