2 * The new sysinstall program.
4 * This is probably the last program in the `sysinstall' line - the next
5 * generation being essentially a complete rewrite.
10 * Jordan Hubbard. All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer,
17 * verbatim and that no modifications are made prior to this
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
23 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include "sysinstall.h"
43 #include <sys/disklabel.h>
46 enum size_units_t { UNIT_BLOCKS, UNIT_KILO, UNIT_MEG, UNIT_GIG, UNIT_SIZE };
49 #define SUBTYPE_FREEBSD 50324
50 #define SUBTYPE_FAT 37218
52 #define SUBTYPE_FREEBSD 165
55 #define SUBTYPE_EFI 239
58 #define OTHER_SLICE_VALUES \
59 "Other popular values are 37218 for a\n" \
60 "DOS FAT partition.\n\n"
62 #define OTHER_SLICE_VALUES \
63 "Other popular values are 6 for a\n" \
64 "DOS FAT partition, 131 for a Linux ext2fs partition, or\n" \
65 "130 for a Linux swap partition.\n\n"
67 #define NON_FREEBSD_NOTE \
68 "Note: If you choose a non-FreeBSD partition type, it will not\n" \
69 "be formatted or otherwise prepared, it will simply reserve space\n" \
70 "for you to use another tool, such as DOS format, to later format\n" \
71 "and actually use the partition."
73 /* Where we start displaying chunk information on the screen */
74 #define CHUNK_START_ROW 5
76 /* Where we keep track of MBR chunks */
77 #define CHUNK_INFO_ENTRIES 16
78 static struct chunk *chunk_info[CHUNK_INFO_ENTRIES];
79 static int current_chunk;
81 static void diskPartitionNonInteractive(Device *dev);
82 static u_char * bootalloc(char *name, size_t *size);
85 record_chunks(Disk *d)
87 struct chunk *c1 = NULL;
89 daddr_t last_free = 0;
92 msgFatal("No chunk list found for %s!", d->name);
94 for (c1 = d->chunks->part; c1; c1 = c1->next) {
95 if (c1->type == unused && c1->size > last_free) {
101 chunk_info[i] = NULL;
102 if (current_chunk >= i)
103 current_chunk = i - 1;
106 static daddr_t Total;
109 print_chunks(Disk *d, int u)
116 szstr = (u == UNIT_GIG ? "GB" : (u == UNIT_MEG ? "MB" :
117 (u == UNIT_KILO ? "KB" : "ST")));
120 for (i = 0; chunk_info[i]; i++)
121 Total += chunk_info[i]->size;
123 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256) {
125 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) {
127 dialog_clear_norefresh();
128 msgConfirm("WARNING: A geometry of %lu/%lu/%lu for %s is incorrect. Using\n"
129 "a more likely geometry. If this geometry is incorrect or you\n"
130 "are unsure as to whether or not it's correct, please consult\n"
131 "the Hardware Guide in the Documentation submenu or use the\n"
132 "(G)eometry command to change it now.\n\n"
133 "Remember: you need to enter whatever your BIOS thinks the\n"
134 "geometry is! For IDE, it's what you were told in the BIOS\n"
135 "setup. For SCSI, it's the translation mode your controller is\n"
136 "using. Do NOT use a ``physical geometry''.",
137 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
138 Sanitize_Bios_Geom(d);
141 mvaddstr(0, 0, "Disk name:\t");
143 attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL);
144 attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL);
146 "DISK Geometry:\t%lu cyls/%lu heads/%lu sectors = %jd sectors (%jdMB)",
147 d->bios_cyl, d->bios_hd, d->bios_sect,
148 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect,
149 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect / (1024/512) / 1024);
150 mvprintw(3, 0, "%6s %10s(%s) %10s %8s %6s %10s %8s %8s",
151 "Offset", "Size", szstr, "End", "Name", "PType", "Desc",
153 for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) {
155 default: /* fall thru */
157 sz = chunk_info[i]->size;
160 sz = chunk_info[i]->size / (1024/512);
163 sz = chunk_info[i]->size / (1024/512) / 1024;
166 sz = chunk_info[i]->size / (1024/512) / 1024 / 1024;
169 if (i == current_chunk)
170 attrset(ATTR_SELECTED);
171 mvprintw(row, 0, "%10jd %10jd %10jd %8s %6d %10s %8d\t%-6s",
172 (intmax_t)chunk_info[i]->offset, (intmax_t)sz,
173 (intmax_t)chunk_info[i]->end, chunk_info[i]->name,
175 slice_type_name(chunk_info[i]->type, chunk_info[i]->subtype),
176 chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i]));
177 if (i == current_chunk)
183 print_command_summary(void)
185 mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
186 mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice F = `DD' mode");
187 mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Wizard m.");
188 mvprintw(18, 0, "T = Change Type U = Undo All Changes Q = Finish");
190 mvprintw(18, 47, "W = Write Changes");
191 mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
197 getBootMgr(char *dname, u_char **bootipl, size_t *bootipl_size,
198 u_char **bootmenu, size_t *bootmenu_size)
200 static u_char *boot0;
201 static size_t boot0_size;
202 static u_char *boot05;
203 static size_t boot05_size;
209 cp = variable_get(VAR_BOOTMGR);
211 /* Figure out what kind of IPL the user wants */
212 sprintf(str, "Install Boot Manager for drive %s?", dname);
213 MenuIPLType.title = str;
214 i = dmenuOpenSimple(&MenuIPLType, FALSE);
216 if (!strncmp(cp, "boot", 4))
224 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
226 *bootipl_size = boot0_size;
227 if (!boot05) boot05 = bootalloc("boot0.5", &boot05_size);
229 *bootmenu_size = boot05_size;
243 getBootMgr(char *dname, u_char **bootCode, size_t *bootCodeSize)
245 #if defined(__i386__) || defined(__amd64__) /* only meaningful on x86 */
246 static u_char *mbr, *boot0;
247 static size_t mbr_size, boot0_size;
252 cp = variable_get(VAR_BOOTMGR);
254 /* Figure out what kind of MBR the user wants */
255 sprintf(str, "Install Boot Manager for drive %s?", dname);
256 MenuMBRType.title = str;
257 i = dmenuOpenSimple(&MenuMBRType, FALSE);
260 if (!strncmp(cp, "boot", 4))
262 else if (!strcmp(cp, "standard"))
270 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
272 *bootCodeSize = boot0_size;
275 if (!mbr) mbr = bootalloc("mbr", &mbr_size);
277 *bootCodeSize = mbr_size;
289 #endif /* WITH_SLICES */
292 diskGetSelectCount(Device ***devs)
298 cp = variable_get(VAR_DISK);
299 dp = *devs = deviceFind(cp, DEVICE_TYPE_DISK);
300 cnt = deviceCount(dp);
303 for (i = 0, enabled = 0; i < cnt; i++) {
312 diskPartition(Device *dev)
323 size_t bootmenu_size;
328 WINDOW *w = savescr();
329 Disk *d = (Disk *)dev->private;
332 size_unit = UNIT_BLOCKS;
334 keypad(stdscr, TRUE);
336 /* Flush both the dialog and curses library views of the screen
337 since we don't always know who called us */
338 dialog_clear_norefresh(), clear();
341 /* Set up the chunk array */
345 char *val, geometry[80];
347 /* Now print our overall state */
349 print_chunks(d, size_unit);
350 print_command_summary();
352 attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
361 /* Get command character */
363 switch (toupper(key)) {
364 case '\014': /* ^L (redraw) */
369 case '\020': /* ^P */
372 if (current_chunk != 0)
376 case '\016': /* ^N */
381 if (chunk_info[current_chunk + 1])
390 while (chunk_info[current_chunk + 1])
396 systemDisplayHelp("slice");
401 case 'F': /* Undocumented magic Dangerously Dedicated mode */
402 #if !defined(__i386__) && !defined(__amd64__)
404 #else /* The rest is only relevant on x86 */
405 cp = variable_get(VAR_DEDICATE_DISK);
406 if (cp && !strcasecmp(cp, "always"))
408 else if (toupper(key) == 'A')
411 rv = msgYesNo("Do you want to do this with a true partition entry\n"
412 "so as to remain cooperative with any future possible\n"
413 "operating systems on the drive(s)?\n"
414 "(See also the section about ``dangerously dedicated''\n"
415 "disks in the FreeBSD FAQ.)");
421 variable_set2(DISK_PARTITIONED, "yes", 0);
427 if (chunk_info[current_chunk]->type != unused)
428 msg = "Slice in use, delete it first or move to an unused one.";
430 char *val, tmp[20], name[16], *cp;
433 chunk_e partitiontype;
435 snprintf(name, sizeof (name), "%s", "FreeBSD");
436 val = msgGetInput(name,
437 "Please specify the name for new FreeBSD slice.");
439 strncpy(name, val, sizeof (name));
443 snprintf(tmp, 20, "%jd", (intmax_t)chunk_info[current_chunk]->size);
444 val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
445 "or append a trailing `M' for megabytes (e.g. 20M).");
446 if (val && (size = strtoimax(val, &cp, 0)) > 0) {
447 if (*cp && toupper(*cp) == 'M')
449 else if (*cp && toupper(*cp) == 'G')
451 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
452 val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
453 "Pressing Enter will choose the default, a native FreeBSD\n"
456 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
457 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
458 if (subtype == SUBTYPE_FREEBSD)
459 partitiontype = freebsd;
460 else if (subtype == SUBTYPE_FAT)
462 else if (subtype == SUBTYPE_EFI)
466 partitiontype = pc98;
470 Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
471 (chunk_info[current_chunk]->flags & CHUNK_ALIGN), name);
472 variable_set2(DISK_PARTITIONED, "yes", 0);
482 if (chunk_info[current_chunk]->type == unused)
483 msg = "Slice is already unused!";
485 Delete_Chunk(d, chunk_info[current_chunk]);
486 variable_set2(DISK_PARTITIONED, "yes", 0);
492 if (chunk_info[current_chunk]->type == unused)
493 msg = "Slice is currently unused (use create instead)";
497 chunk_e partitiontype;
499 sprintf(tmp, "%d", chunk_info[current_chunk]->subtype);
500 val = msgGetInput(tmp, "New partition type:\n\n"
501 "Pressing Enter will use the current type. To choose a native\n"
502 "FreeBSD slice enter %u. "
504 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
505 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
506 if (subtype == SUBTYPE_FREEBSD)
507 partitiontype = freebsd;
508 else if (subtype == SUBTYPE_FAT)
510 else if (subtype == SUBTYPE_EFI)
514 partitiontype = pc98;
518 chunk_info[current_chunk]->type = partitiontype;
519 chunk_info[current_chunk]->subtype = subtype;
525 snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
526 val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
527 "Don't forget to use the two slash (/) separator characters!\n"
528 "It's not possible to parse the field without them.");
531 nc = strtol(val, &val, 0);
532 nh = strtol(val + 1, &val, 0);
533 ns = strtol(val + 1, 0, 0);
534 Set_Bios_Geom(d, nc, nh, ns);
540 /* Clear active states so we won't have two */
541 for (i = 0; (chunk_info[i] != NULL) && (i < CHUNK_INFO_ENTRIES); i++)
542 chunk_info[i]->flags &= !CHUNK_ACTIVE;
545 chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
549 if (!variable_cmp(DISK_LABELLED, "written")) {
550 msgConfirm("You've already written this information out - you\n"
553 else if (!msgNoYes("Are you SURE you want to Undo everything?")) {
556 sstrncpy(cp, d->name, sizeof cp);
557 Free_Disk(dev->private);
560 msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", cp);
562 variable_unset(DISK_PARTITIONED);
563 variable_unset(DISK_LABELLED);
571 if (!msgNoYes("WARNING: This should only be used when modifying an EXISTING\n"
572 "installation. If you are installing FreeBSD for the first time\n"
573 "then you should simply type Q when you're finished here and your\n"
574 "changes will be committed in one batch automatically at the end of\n"
575 "these questions. If you're adding a disk, you should NOT write\n"
576 "from this screen, you should do it from the label editor.\n\n"
577 "Are you absolutely sure you want to do this now?")) {
578 variable_set2(DISK_PARTITIONED, "yes", 0);
582 * Don't trash the IPL if the first (and therefore only) chunk
583 * is marked for a truly dedicated disk (i.e., the disklabel
584 * starts at sector 0), even in cases where the user has
585 * requested a FreeBSD Boot Manager -- both would be fatal in
589 * Don't offer to update the IPL on this disk if the first
590 * "real" chunk looks like a FreeBSD "all disk" partition,
591 * or the disk is entirely FreeBSD.
593 if ((d->chunks->part->type != freebsd) ||
594 (d->chunks->part->offset > 1))
595 getBootMgr(d->name, &bootipl, &bootipl_size,
596 &bootmenu, &bootmenu_size);
603 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
606 * Don't trash the MBR if the first (and therefore only) chunk
607 * is marked for a truly dedicated disk (i.e., the disklabel
608 * starts at sector 0), even in cases where the user has
609 * requested booteasy or a "standard" MBR -- both would be
610 * fatal in this case.
613 * Don't offer to update the MBR on this disk if the first
614 * "real" chunk looks like a FreeBSD "all disk" partition,
615 * or the disk is entirely FreeBSD.
617 if ((d->chunks->part->type != freebsd) ||
618 (d->chunks->part->offset > 1))
619 getBootMgr(d->name, &mbrContents, &mbrSize);
624 Set_Boot_Mgr(d, mbrContents, mbrSize);
627 if (DITEM_STATUS(diskPartitionWrite(NULL)) != DITEM_SUCCESS)
628 msgConfirm("Disk partition write returned an error status!");
630 msgConfirm("Wrote FDISK partition information out successfully.");
636 if (!msgNoYes("Are you SURE you want to go into Wizard mode?\n"
637 "No seat belts whatsoever are provided!")) {
641 variable_set2(DISK_PARTITIONED, "yes", 0);
645 msg = "Wise choice!";
649 case '\033': /* ESC */
654 * Don't trash the IPL if the first (and therefore only) chunk
655 * is marked for a truly dedicated disk (i.e., the disklabel
656 * starts at sector 0), even in cases where the user has requested
657 * a FreeBSD Boot Manager -- both would be fatal in this case.
660 * Don't offer to update the IPL on this disk if the first "real"
661 * chunk looks like a FreeBSD "all disk" partition, or the disk is
664 if ((d->chunks->part->type != freebsd) ||
665 (d->chunks->part->offset > 1)) {
666 if (variable_cmp(DISK_PARTITIONED, "written")) {
667 getBootMgr(d->name, &bootipl, &bootipl_size,
668 &bootmenu, &bootmenu_size);
669 if (bootipl != NULL && bootmenu != NULL)
670 Set_Boot_Mgr(d, bootipl, bootipl_size,
671 bootmenu, bootmenu_size);
676 * Don't trash the MBR if the first (and therefore only) chunk
677 * is marked for a truly dedicated disk (i.e., the disklabel
678 * starts at sector 0), even in cases where the user has requested
679 * booteasy or a "standard" MBR -- both would be fatal in this case.
682 * Don't offer to update the MBR on this disk if the first "real"
683 * chunk looks like a FreeBSD "all disk" partition, or the disk is
686 if ((d->chunks->part->type != freebsd) ||
687 (d->chunks->part->offset > 1)) {
688 if (variable_cmp(DISK_PARTITIONED, "written")) {
689 getBootMgr(d->name, &mbrContents, &mbrSize);
690 if (mbrContents != NULL)
691 Set_Boot_Mgr(d, mbrContents, mbrSize);
698 size_unit = (size_unit + 1) % UNIT_SIZE;
703 msg = "Type F1 or ? for help";
709 char buf[FILENAME_MAX];
711 use_helpline("Press F1 to read more about disk slices.");
712 use_helpfile(systemHelpFile("partition", buf));
713 if (!variable_get(VAR_NO_WARN))
714 dialog_mesgbox("Disk slicing warning:", p, -1, -1);
719 #endif /* WITH_SLICES */
722 bootalloc(char *name, size_t *size)
724 char buf[FILENAME_MAX];
727 snprintf(buf, sizeof buf, "/boot/%s", name);
728 if (stat(buf, &sb) != -1) {
731 fd = open(buf, O_RDONLY);
735 cp = malloc(sb.st_size);
736 if (read(fd, cp, sb.st_size) != sb.st_size) {
739 msgDebug("bootalloc: couldn't read %ld bytes from %s\n", (long)sb.st_size, buf);
747 msgDebug("bootalloc: couldn't open %s\n", buf);
750 msgDebug("bootalloc: can't stat %s\n", buf);
756 partitionHook(dialogMenuItem *selected)
758 Device **devs = NULL;
760 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
762 msgConfirm("Unable to find disk %s!", selected->prompt);
763 return DITEM_FAILURE;
765 /* Toggle enabled status? */
766 if (!devs[0]->enabled) {
767 devs[0]->enabled = TRUE;
768 diskPartition(devs[0]);
771 devs[0]->enabled = FALSE;
772 return DITEM_SUCCESS;
776 partitionCheck(dialogMenuItem *selected)
778 Device **devs = NULL;
780 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
781 if (!devs || devs[0]->enabled == FALSE)
787 diskPartitionEditor(dialogMenuItem *self)
793 cnt = diskGetSelectCount(&devs);
794 devcnt = deviceCount(devs);
796 msgConfirm("No disks found! Please verify that your disk controller is being\n"
797 "properly probed at boot time. See the Hardware Guide on the\n"
798 "Documentation menu for clues on diagnosing this type of problem.");
799 return DITEM_FAILURE;
802 /* Some are already selected */
803 for (i = 0; i < devcnt; i++) {
804 if (devs[i]->enabled) {
805 if (variable_get(VAR_NONINTERACTIVE) &&
806 !variable_get(VAR_DISKINTERACTIVE))
807 diskPartitionNonInteractive(devs[i]);
809 diskPartition(devs[i]);
814 /* No disks are selected, fall-back case now */
816 devs[0]->enabled = TRUE;
817 if (variable_get(VAR_NONINTERACTIVE) &&
818 !variable_get(VAR_DISKINTERACTIVE))
819 diskPartitionNonInteractive(devs[0]);
821 diskPartition(devs[0]);
822 return DITEM_SUCCESS;
825 menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook, partitionCheck);
827 msgConfirm("No devices suitable for installation found!\n\n"
828 "Please verify that your disk controller (and attached drives)\n"
829 "were detected properly. This can be done by pressing the\n"
830 "[Scroll Lock] key and using the Arrow keys to move back to\n"
831 "the boot messages. Press [Scroll Lock] again to return.");
832 return DITEM_FAILURE;
835 i = dmenuOpenSimple(menu, FALSE) ? DITEM_SUCCESS : DITEM_FAILURE;
841 return DITEM_SUCCESS;
843 #endif /* WITH_SLICES */
846 diskPartitionWrite(dialogMenuItem *self)
851 if (!variable_cmp(DISK_PARTITIONED, "written"))
852 return DITEM_SUCCESS;
854 devs = deviceFind(NULL, DEVICE_TYPE_DISK);
856 msgConfirm("Unable to find any disks to write to??");
857 return DITEM_FAILURE;
860 msgDebug("diskPartitionWrite: Examining %d devices\n", deviceCount(devs));
861 for (i = 0; devs[i]; i++) {
862 Disk *d = (Disk *)devs[i]->private;
863 static u_char *boot1;
864 #if defined(__i386__) || defined(__amd64__)
865 static u_char *boot2;
868 if (!devs[i]->enabled)
871 #if defined(__i386__) || defined(__amd64__)
872 if (!boot1) boot1 = bootalloc("boot1", NULL);
873 if (!boot2) boot2 = bootalloc("boot2", NULL);
874 Set_Boot_Blocks(d, boot1, boot2);
875 #elif !defined(__ia64__)
876 if (!boot1) boot1 = bootalloc("boot1", NULL);
877 Set_Boot_Blocks(d, boot1, NULL);
880 msgNotify("Writing partition information to drive %s", d->name);
881 if (!Fake && Write_Disk(d)) {
882 msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
883 return DITEM_FAILURE;
886 /* Now it's not "yes", but "written" */
887 variable_set2(DISK_PARTITIONED, "written", 0);
888 return DITEM_SUCCESS | DITEM_RESTORE;
892 /* Partition a disk based wholly on which variables are set */
894 diskPartitionNonInteractive(Device *dev)
903 size_t bootmenu_size;
908 Disk *d = (Disk *)dev->private;
911 cp = variable_get(VAR_GEOMETRY);
913 msgDebug("Setting geometry from script to: %s\n", cp);
914 d->bios_cyl = strtol(cp, &cp, 0);
915 d->bios_hd = strtol(cp + 1, &cp, 0);
916 d->bios_sect = strtol(cp + 1, 0, 0);
920 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256) {
922 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) {
924 msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
925 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
926 Sanitize_Bios_Geom(d);
927 msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
928 d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
931 cp = variable_get(VAR_PARTITION);
933 if (!strcmp(cp, "free")) {
934 /* Do free disk space case */
935 for (i = 0; chunk_info[i]; i++) {
936 /* If a chunk is at least 10MB in size, use it. */
937 if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
938 Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size,
940 (chunk_info[i]->flags & CHUNK_ALIGN),
942 variable_set2(DISK_PARTITIONED, "yes", 0);
946 if (!chunk_info[i]) {
947 msgConfirm("Unable to find any free space on this disk!");
951 else if (!strcmp(cp, "all")) {
952 /* Do all disk space case */
953 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
955 All_FreeBSD(d, FALSE);
957 else if (!strcmp(cp, "exclusive")) {
958 /* Do really-all-the-disk-space case */
959 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
961 All_FreeBSD(d, all_disk = TRUE);
963 else if ((sz = strtoimax(cp, &cp, 0))) {
964 /* Look for sz bytes free */
965 if (*cp && toupper(*cp) == 'M')
967 else if (*cp && toupper(*cp) == 'G')
969 for (i = 0; chunk_info[i]; i++) {
970 /* If a chunk is at least sz MB, use it. */
971 if (chunk_info[i]->type == unused && chunk_info[i]->size >= sz) {
972 Create_Chunk(d, chunk_info[i]->offset, sz, freebsd, 3,
973 (chunk_info[i]->flags & CHUNK_ALIGN),
975 variable_set2(DISK_PARTITIONED, "yes", 0);
979 if (!chunk_info[i]) {
980 msgConfirm("Unable to find %jd free blocks on this disk!",
985 else if (!strcmp(cp, "existing")) {
986 /* Do existing FreeBSD case */
987 for (i = 0; chunk_info[i]; i++) {
988 if (chunk_info[i]->type == freebsd)
991 if (!chunk_info[i]) {
992 msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
997 msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
1002 getBootMgr(d->name, &bootipl, &bootipl_size,
1003 &bootmenu, &bootmenu_size);
1004 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
1006 getBootMgr(d->name, &mbrContents, &mbrSize);
1007 Set_Boot_Mgr(d, mbrContents, mbrSize);
1010 variable_set2(DISK_PARTITIONED, "yes", 0);
1013 #endif /* WITH_SLICES */