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 check_geometry(Disk *d)
114 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
116 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
119 dialog_clear_norefresh();
120 sg = msgYesNo("WARNING: It is safe to use a geometry of %lu/%lu/%lu for %s on\n"
121 "computers with modern BIOS versions. If this disk is to be used\n"
122 "on an old machine it is recommended that it does not have more\n"
123 "than 65535 cylinders, more than 255 heads, or more than\n"
129 " sectors per track.\n"
131 "Would you like to keep using the current geometry?\n",
132 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
134 Sanitize_Bios_Geom(d);
135 msgConfirm("A geometry of %lu/%lu/%lu was calculated for %s.\n"
137 "If you are not sure about this, please consult the Hardware Guide\n"
138 "in the Documentation submenu or use the (G)eometry command to\n"
139 "change it. Remember: you need to enter whatever your BIOS thinks\n"
140 "the geometry is! For IDE, it's what you were told in the BIOS\n"
141 "setup. For SCSI, it's the translation mode your controller is\n"
142 "using. Do NOT use a ``physical geometry''.\n",
143 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
149 print_chunks(Disk *d, int u)
156 szstr = (u == UNIT_GIG ? "GB" : (u == UNIT_MEG ? "MB" :
157 (u == UNIT_KILO ? "KB" : "ST")));
160 for (i = 0; chunk_info[i]; i++)
161 Total += chunk_info[i]->size;
163 mvaddstr(0, 0, "Disk name:\t");
165 attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL);
166 attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL);
168 "DISK Geometry:\t%lu cyls/%lu heads/%lu sectors = %jd sectors (%jdMB)",
169 d->bios_cyl, d->bios_hd, d->bios_sect,
170 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect,
171 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect / (1024/512) / 1024);
172 mvprintw(3, 0, "%6s %10s(%s) %10s %8s %6s %10s %8s %8s",
173 "Offset", "Size", szstr, "End", "Name", "PType", "Desc",
175 for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) {
177 default: /* fall thru */
179 sz = chunk_info[i]->size;
182 sz = chunk_info[i]->size / (1024/512);
185 sz = chunk_info[i]->size / (1024/512) / 1024;
188 sz = chunk_info[i]->size / (1024/512) / 1024 / 1024;
191 if (i == current_chunk)
192 attrset(ATTR_SELECTED);
193 mvprintw(row, 0, "%10jd %10jd %10jd %8s %6d %10s %8d\t%-6s",
194 (intmax_t)chunk_info[i]->offset, (intmax_t)sz,
195 (intmax_t)chunk_info[i]->end, chunk_info[i]->name,
197 slice_type_name(chunk_info[i]->type, chunk_info[i]->subtype),
198 chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i]));
199 if (i == current_chunk)
205 print_command_summary(void)
207 mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
208 mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice");
209 mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Expert m.");
210 mvprintw(18, 0, "T = Change Type U = Undo All Changes Q = Finish");
212 mvprintw(18, 47, "W = Write Changes");
213 mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
219 getBootMgr(char *dname, u_char **bootipl, size_t *bootipl_size,
220 u_char **bootmenu, size_t *bootmenu_size)
222 static u_char *boot0;
223 static size_t boot0_size;
224 static u_char *boot05;
225 static size_t boot05_size;
231 cp = variable_get(VAR_BOOTMGR);
233 /* Figure out what kind of IPL the user wants */
234 sprintf(str, "Install Boot Manager for drive %s?", dname);
235 MenuIPLType.title = str;
236 i = dmenuOpenSimple(&MenuIPLType, FALSE);
238 if (!strncmp(cp, "boot", 4))
246 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
248 *bootipl_size = boot0_size;
249 if (!boot05) boot05 = bootalloc("boot0.5", &boot05_size);
251 *bootmenu_size = boot05_size;
265 getBootMgr(char *dname, u_char **bootCode, size_t *bootCodeSize)
267 #if defined(__i386__) || defined(__amd64__) /* only meaningful on x86 */
268 static u_char *mbr, *boot0;
269 static size_t mbr_size, boot0_size;
274 cp = variable_get(VAR_BOOTMGR);
276 /* Figure out what kind of MBR the user wants */
277 sprintf(str, "Install Boot Manager for drive %s?", dname);
278 MenuMBRType.title = str;
279 i = dmenuOpenSimple(&MenuMBRType, FALSE);
282 if (!strncmp(cp, "boot", 4))
284 else if (!strcmp(cp, "standard"))
292 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
294 *bootCodeSize = boot0_size;
297 if (!mbr) mbr = bootalloc("mbr", &mbr_size);
299 *bootCodeSize = mbr_size;
311 #endif /* WITH_SLICES */
314 diskGetSelectCount(Device ***devs)
320 cp = variable_get(VAR_DISK);
321 dp = *devs = deviceFind(cp, DEVICE_TYPE_DISK);
322 cnt = deviceCount(dp);
325 for (i = 0, enabled = 0; i < cnt; i++) {
334 diskPartition(Device *dev)
345 size_t bootmenu_size;
350 WINDOW *w = savescr();
351 Disk *d = (Disk *)dev->private;
354 size_unit = UNIT_BLOCKS;
356 keypad(stdscr, TRUE);
358 /* Flush both the dialog and curses library views of the screen
359 since we don't always know who called us */
360 dialog_clear_norefresh(), clear();
363 /* Set up the chunk array */
366 /* Give the user a chance to sanitize the disk geometry, if necessary */
370 char *val, geometry[80];
372 /* Now print our overall state */
374 print_chunks(d, size_unit);
375 print_command_summary();
377 attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
386 /* Get command character */
388 switch (toupper(key)) {
389 case '\014': /* ^L (redraw) */
394 case '\020': /* ^P */
397 if (current_chunk != 0)
401 case '\016': /* ^N */
406 if (chunk_info[current_chunk + 1])
415 while (chunk_info[current_chunk + 1])
421 systemDisplayHelp("slice");
426 #if !defined(__i386__) && !defined(__amd64__)
428 #else /* The rest is only relevant on x86 */
432 variable_set2(DISK_PARTITIONED, "yes", 0);
438 if (chunk_info[current_chunk]->type != unused)
439 msg = "Slice in use, delete it first or move to an unused one.";
441 char *val, tmp[20], name[16], *cp;
444 chunk_e partitiontype;
446 snprintf(name, sizeof (name), "%s", "FreeBSD");
447 val = msgGetInput(name,
448 "Please specify the name for new FreeBSD slice.");
450 strncpy(name, val, sizeof (name));
454 snprintf(tmp, 20, "%jd", (intmax_t)chunk_info[current_chunk]->size);
455 val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
456 "or append a trailing `M' for megabytes (e.g. 20M).");
457 if (val && (size = strtoimax(val, &cp, 0)) > 0) {
458 if (*cp && toupper(*cp) == 'M')
460 else if (*cp && toupper(*cp) == 'G')
462 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
463 val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
464 "Pressing Enter will choose the default, a native FreeBSD\n"
467 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
468 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
469 if (subtype == SUBTYPE_FREEBSD)
470 partitiontype = freebsd;
471 else if (subtype == SUBTYPE_FAT)
473 else if (subtype == SUBTYPE_EFI)
477 partitiontype = pc98;
481 Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
482 (chunk_info[current_chunk]->flags & CHUNK_ALIGN), name);
483 variable_set2(DISK_PARTITIONED, "yes", 0);
493 if (chunk_info[current_chunk]->type == unused)
494 msg = "Slice is already unused!";
496 Delete_Chunk(d, chunk_info[current_chunk]);
497 variable_set2(DISK_PARTITIONED, "yes", 0);
503 if (chunk_info[current_chunk]->type == unused)
504 msg = "Slice is currently unused (use create instead)";
508 chunk_e partitiontype;
510 sprintf(tmp, "%d", chunk_info[current_chunk]->subtype);
511 val = msgGetInput(tmp, "New partition type:\n\n"
512 "Pressing Enter will use the current type. To choose a native\n"
513 "FreeBSD slice enter %u. "
515 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
516 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
517 if (subtype == SUBTYPE_FREEBSD)
518 partitiontype = freebsd;
519 else if (subtype == SUBTYPE_FAT)
521 else if (subtype == SUBTYPE_EFI)
525 partitiontype = pc98;
529 chunk_info[current_chunk]->type = partitiontype;
530 chunk_info[current_chunk]->subtype = subtype;
536 snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
537 val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
538 "Don't forget to use the two slash (/) separator characters!\n"
539 "It's not possible to parse the field without them.");
542 nc = strtol(val, &val, 0);
543 nh = strtol(val + 1, &val, 0);
544 ns = strtol(val + 1, 0, 0);
545 Set_Bios_Geom(d, nc, nh, ns);
551 /* Clear active states so we won't have two */
552 for (i = 0; (chunk_info[i] != NULL) && (i < CHUNK_INFO_ENTRIES); i++)
553 chunk_info[i]->flags &= !CHUNK_ACTIVE;
556 chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
560 if (!variable_cmp(DISK_LABELLED, "written")) {
561 msgConfirm("You've already written this information out - you\n"
564 else if (!msgNoYes("Are you SURE you want to Undo everything?")) {
567 sstrncpy(cp, d->name, sizeof cp);
568 Free_Disk(dev->private);
571 msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", cp);
573 variable_unset(DISK_PARTITIONED);
574 variable_unset(DISK_LABELLED);
582 if (!msgNoYes("WARNING: This should only be used when modifying an EXISTING\n"
583 "installation. If you are installing FreeBSD for the first time\n"
584 "then you should simply type Q when you're finished here and your\n"
585 "changes will be committed in one batch automatically at the end of\n"
586 "these questions. If you're adding a disk, you should NOT write\n"
587 "from this screen, you should do it from the label editor.\n\n"
588 "Are you absolutely sure you want to do this now?")) {
589 variable_set2(DISK_PARTITIONED, "yes", 0);
593 * Don't trash the IPL if the first (and therefore only) chunk
594 * is marked for a truly dedicated disk (i.e., the disklabel
595 * starts at sector 0), even in cases where the user has
596 * requested a FreeBSD Boot Manager -- both would be fatal in
600 * Don't offer to update the IPL on this disk if the first
601 * "real" chunk looks like a FreeBSD "all disk" partition,
602 * or the disk is entirely FreeBSD.
604 if ((d->chunks->part->type != freebsd) ||
605 (d->chunks->part->offset > 1))
606 getBootMgr(d->name, &bootipl, &bootipl_size,
607 &bootmenu, &bootmenu_size);
614 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
617 * Don't trash the MBR if the first (and therefore only) chunk
618 * is marked for a truly dedicated disk (i.e., the disklabel
619 * starts at sector 0), even in cases where the user has
620 * requested booteasy or a "standard" MBR -- both would be
621 * fatal in this case.
624 * Don't offer to update the MBR on this disk if the first
625 * "real" chunk looks like a FreeBSD "all disk" partition,
626 * or the disk is entirely FreeBSD.
628 if ((d->chunks->part->type != freebsd) ||
629 (d->chunks->part->offset > 1))
630 getBootMgr(d->name, &mbrContents, &mbrSize);
635 Set_Boot_Mgr(d, mbrContents, mbrSize);
638 if (DITEM_STATUS(diskPartitionWrite(NULL)) != DITEM_SUCCESS)
639 msgConfirm("Disk partition write returned an error status!");
641 msgConfirm("Wrote FDISK partition information out successfully.");
647 if (!msgNoYes("Are you SURE you want to go into Expert mode?\n"
648 "No seat belts whatsoever are provided!")) {
652 variable_set2(DISK_PARTITIONED, "yes", 0);
656 msg = "Wise choice!";
660 case '\033': /* ESC */
665 * Don't trash the IPL if the first (and therefore only) chunk
666 * is marked for a truly dedicated disk (i.e., the disklabel
667 * starts at sector 0), even in cases where the user has requested
668 * a FreeBSD Boot Manager -- both would be fatal in this case.
671 * Don't offer to update the IPL on this disk if the first "real"
672 * chunk looks like a FreeBSD "all disk" partition, or the disk is
675 if ((d->chunks->part->type != freebsd) ||
676 (d->chunks->part->offset > 1)) {
677 if (variable_cmp(DISK_PARTITIONED, "written")) {
678 getBootMgr(d->name, &bootipl, &bootipl_size,
679 &bootmenu, &bootmenu_size);
680 if (bootipl != NULL && bootmenu != NULL)
681 Set_Boot_Mgr(d, bootipl, bootipl_size,
682 bootmenu, bootmenu_size);
687 * Don't trash the MBR if the first (and therefore only) chunk
688 * is marked for a truly dedicated disk (i.e., the disklabel
689 * starts at sector 0), even in cases where the user has requested
690 * booteasy or a "standard" MBR -- both would be fatal in this case.
693 * Don't offer to update the MBR on this disk if the first "real"
694 * chunk looks like a FreeBSD "all disk" partition, or the disk is
697 if ((d->chunks->part->type != freebsd) ||
698 (d->chunks->part->offset > 1)) {
699 if (variable_cmp(DISK_PARTITIONED, "written")) {
700 getBootMgr(d->name, &mbrContents, &mbrSize);
701 if (mbrContents != NULL)
702 Set_Boot_Mgr(d, mbrContents, mbrSize);
709 size_unit = (size_unit + 1) % UNIT_SIZE;
714 msg = "Type F1 or ? for help";
720 char buf[FILENAME_MAX];
722 use_helpline("Press F1 to read more about disk slices.");
723 use_helpfile(systemHelpFile("partition", buf));
724 if (!variable_get(VAR_NO_WARN))
725 dialog_mesgbox("Disk slicing warning:", p, -1, -1);
730 #endif /* WITH_SLICES */
733 bootalloc(char *name, size_t *size)
735 char buf[FILENAME_MAX];
738 snprintf(buf, sizeof buf, "/boot/%s", name);
739 if (stat(buf, &sb) != -1) {
742 fd = open(buf, O_RDONLY);
746 cp = malloc(sb.st_size);
747 if (read(fd, cp, sb.st_size) != sb.st_size) {
750 msgDebug("bootalloc: couldn't read %ld bytes from %s\n", (long)sb.st_size, buf);
758 msgDebug("bootalloc: couldn't open %s\n", buf);
761 msgDebug("bootalloc: can't stat %s\n", buf);
767 partitionHook(dialogMenuItem *selected)
769 Device **devs = NULL;
771 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
773 msgConfirm("Unable to find disk %s!", selected->prompt);
774 return DITEM_FAILURE;
776 /* Toggle enabled status? */
777 if (!devs[0]->enabled) {
778 devs[0]->enabled = TRUE;
779 diskPartition(devs[0]);
782 devs[0]->enabled = FALSE;
783 return DITEM_SUCCESS;
787 partitionCheck(dialogMenuItem *selected)
789 Device **devs = NULL;
791 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
792 if (!devs || devs[0]->enabled == FALSE)
798 diskPartitionEditor(dialogMenuItem *self)
804 cnt = diskGetSelectCount(&devs);
805 devcnt = deviceCount(devs);
807 msgConfirm("No disks found! Please verify that your disk controller is being\n"
808 "properly probed at boot time. See the Hardware Guide on the\n"
809 "Documentation menu for clues on diagnosing this type of problem.");
810 return DITEM_FAILURE;
813 /* Some are already selected */
814 for (i = 0; i < devcnt; i++) {
815 if (devs[i]->enabled) {
816 if (variable_get(VAR_NONINTERACTIVE) &&
817 !variable_get(VAR_DISKINTERACTIVE))
818 diskPartitionNonInteractive(devs[i]);
820 diskPartition(devs[i]);
825 /* No disks are selected, fall-back case now */
827 devs[0]->enabled = TRUE;
828 if (variable_get(VAR_NONINTERACTIVE) &&
829 !variable_get(VAR_DISKINTERACTIVE))
830 diskPartitionNonInteractive(devs[0]);
832 diskPartition(devs[0]);
833 return DITEM_SUCCESS;
836 menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook, partitionCheck);
838 msgConfirm("No devices suitable for installation found!\n\n"
839 "Please verify that your disk controller (and attached drives)\n"
840 "were detected properly. This can be done by pressing the\n"
841 "[Scroll Lock] key and using the Arrow keys to move back to\n"
842 "the boot messages. Press [Scroll Lock] again to return.");
843 return DITEM_FAILURE;
846 i = dmenuOpenSimple(menu, FALSE) ? DITEM_SUCCESS : DITEM_FAILURE;
852 return DITEM_SUCCESS;
854 #endif /* WITH_SLICES */
857 diskPartitionWrite(dialogMenuItem *self)
862 if (!variable_cmp(DISK_PARTITIONED, "written"))
863 return DITEM_SUCCESS;
865 devs = deviceFind(NULL, DEVICE_TYPE_DISK);
867 msgConfirm("Unable to find any disks to write to??");
868 return DITEM_FAILURE;
871 msgDebug("diskPartitionWrite: Examining %d devices\n", deviceCount(devs));
872 for (i = 0; devs[i]; i++) {
873 Disk *d = (Disk *)devs[i]->private;
874 static u_char *boot1;
875 #if defined(__i386__) || defined(__amd64__)
876 static u_char *boot2;
879 if (!devs[i]->enabled)
882 #if defined(__i386__) || defined(__amd64__)
883 if (!boot1) boot1 = bootalloc("boot1", NULL);
884 if (!boot2) boot2 = bootalloc("boot2", NULL);
885 Set_Boot_Blocks(d, boot1, boot2);
886 #elif !defined(__ia64__)
887 if (!boot1) boot1 = bootalloc("boot1", NULL);
888 Set_Boot_Blocks(d, boot1, NULL);
891 msgNotify("Writing partition information to drive %s", d->name);
892 if (!Fake && Write_Disk(d)) {
894 msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
896 msgConfirm("ERROR: Unable to write data to disk %s!\n\n"
897 "To edit the labels on a running system set\n"
898 "sysctl kern.geom.debugflags=16 and try again.", d->name);
900 return DITEM_FAILURE;
903 /* Now it's not "yes", but "written" */
904 variable_set2(DISK_PARTITIONED, "written", 0);
905 return DITEM_SUCCESS | DITEM_RESTORE;
909 /* Partition a disk based wholly on which variables are set */
911 diskPartitionNonInteractive(Device *dev)
920 size_t bootmenu_size;
925 Disk *d = (Disk *)dev->private;
928 cp = variable_get(VAR_GEOMETRY);
930 if (!strcasecmp(cp, "sane")) {
932 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
934 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
937 msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
938 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
939 Sanitize_Bios_Geom(d);
940 msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
941 d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
944 msgDebug("Setting geometry from script to: %s\n", cp);
945 d->bios_cyl = strtol(cp, &cp, 0);
946 d->bios_hd = strtol(cp + 1, &cp, 0);
947 d->bios_sect = strtol(cp + 1, 0, 0);
951 cp = variable_get(VAR_PARTITION);
953 if (!strcmp(cp, "free")) {
954 /* Do free disk space case */
955 for (i = 0; chunk_info[i]; i++) {
956 /* If a chunk is at least 10MB in size, use it. */
957 if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
958 Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size,
960 (chunk_info[i]->flags & CHUNK_ALIGN),
962 variable_set2(DISK_PARTITIONED, "yes", 0);
966 if (!chunk_info[i]) {
967 msgConfirm("Unable to find any free space on this disk!");
971 else if (!strcmp(cp, "all")) {
972 /* Do all disk space case */
973 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
975 All_FreeBSD(d, FALSE);
977 else if (!strcmp(cp, "exclusive")) {
978 /* Do really-all-the-disk-space case */
979 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
981 All_FreeBSD(d, all_disk = TRUE);
983 else if ((sz = strtoimax(cp, &cp, 0))) {
984 /* Look for sz bytes free */
985 if (*cp && toupper(*cp) == 'M')
987 else if (*cp && toupper(*cp) == 'G')
989 for (i = 0; chunk_info[i]; i++) {
990 /* If a chunk is at least sz MB, use it. */
991 if (chunk_info[i]->type == unused && chunk_info[i]->size >= sz) {
992 Create_Chunk(d, chunk_info[i]->offset, sz, freebsd, 3,
993 (chunk_info[i]->flags & CHUNK_ALIGN),
995 variable_set2(DISK_PARTITIONED, "yes", 0);
999 if (!chunk_info[i]) {
1000 msgConfirm("Unable to find %jd free blocks on this disk!",
1005 else if (!strcmp(cp, "existing")) {
1006 /* Do existing FreeBSD case */
1007 for (i = 0; chunk_info[i]; i++) {
1008 if (chunk_info[i]->type == freebsd)
1011 if (!chunk_info[i]) {
1012 msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
1017 msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
1022 getBootMgr(d->name, &bootipl, &bootipl_size,
1023 &bootmenu, &bootmenu_size);
1024 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
1026 getBootMgr(d->name, &mbrContents, &mbrSize);
1027 Set_Boot_Mgr(d, mbrContents, mbrSize);
1030 variable_set2(DISK_PARTITIONED, "yes", 0);
1033 #endif /* WITH_SLICES */