5 * Jordan Hubbard. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer,
12 * verbatim and that no modifications are made prior to this
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.
18 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 #include <sys/disklabel.h>
41 enum size_units_t { UNIT_BLOCKS, UNIT_KILO, UNIT_MEG, UNIT_GIG, UNIT_SIZE };
44 #define SUBTYPE_FREEBSD 50324
45 #define SUBTYPE_FAT 37218
47 #define SUBTYPE_FREEBSD 165
50 #define SUBTYPE_EFI 239
53 #define OTHER_SLICE_VALUES \
54 "Other popular values are 37218 for a\n" \
55 "DOS FAT partition.\n\n"
57 #define OTHER_SLICE_VALUES \
58 "Other popular values are 6 for a\n" \
59 "DOS FAT partition, 131 for a Linux ext2fs partition, or\n" \
60 "130 for a Linux swap partition.\n\n"
62 #define NON_FREEBSD_NOTE \
63 "Note: If you choose a non-FreeBSD partition type, it will not\n" \
64 "be formatted or otherwise prepared, it will simply reserve space\n" \
65 "for you to use another tool, such as DOS format, to later format\n" \
66 "and actually use the partition."
68 /* Where we start displaying chunk information on the screen */
69 #define CHUNK_START_ROW 5
71 /* Where we keep track of MBR chunks */
72 #define CHUNK_INFO_ENTRIES 16
73 static struct chunk *chunk_info[CHUNK_INFO_ENTRIES];
74 static int current_chunk;
76 static void diskPartitionNonInteractive(Device *dev);
77 #if !defined(__ia64__)
78 static u_char * bootalloc(char *name, size_t *size);
82 record_chunks(Disk *d)
84 struct chunk *c1 = NULL;
86 daddr_t last_free = 0;
89 msgFatal("No chunk list found for %s!", d->name);
91 for (c1 = d->chunks->part; c1; c1 = c1->next) {
92 if (c1->type == unused && c1->size > last_free) {
99 if (current_chunk >= i)
100 current_chunk = i - 1;
103 static daddr_t Total;
106 check_geometry(Disk *d)
111 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
113 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
116 dialog_clear_norefresh();
117 sg = msgYesNo("WARNING: It is safe to use a geometry of %lu/%lu/%lu for %s on\n"
118 "computers with modern BIOS versions. If this disk is to be used\n"
119 "on rather old machines, however, it is recommended to ensure that\n"
120 "it does not have more than 65535 cylinders, or more than 255 heads\n"
127 " sectors per track.\n"
129 "Would you like that to keep using the current geometry?\n",
130 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
132 Sanitize_Bios_Geom(d);
133 msgConfirm("A geometry of %lu/%lu/%lu was calculated for %s.\n"
135 "If you are not sure about this, please consult the Hardware Guide\n"
136 "in the Documentation submenu or use the (G)eometry command to\n"
137 "change it. Remember: you need to enter whatever your BIOS thinks\n"
138 "the geometry is! For IDE, it's what you were told in the BIOS\n"
139 "setup. For SCSI, it's the translation mode your controller is\n"
140 "using. Do NOT use a ``physical geometry''.\n",
141 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
147 print_chunks(Disk *d, int u)
154 szstr = (u == UNIT_GIG ? "GB" : (u == UNIT_MEG ? "MB" :
155 (u == UNIT_KILO ? "KB" : "ST")));
158 for (i = 0; chunk_info[i]; i++)
159 Total += chunk_info[i]->size;
161 mvaddstr(0, 0, "Disk name:\t");
163 attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL);
164 attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL);
166 "DISK Geometry:\t%lu cyls/%lu heads/%lu sectors = %jd sectors (%jdMB)",
167 d->bios_cyl, d->bios_hd, d->bios_sect,
168 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect,
169 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect / (1024/512) / 1024);
170 mvprintw(3, 0, "%6s %10s(%s) %10s %8s %6s %10s %8s %8s",
171 "Offset", "Size", szstr, "End", "Name", "PType", "Desc",
173 for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) {
175 default: /* fall thru */
177 sz = chunk_info[i]->size;
180 sz = chunk_info[i]->size / (1024/512);
183 sz = chunk_info[i]->size / (1024/512) / 1024;
186 sz = chunk_info[i]->size / (1024/512) / 1024 / 1024;
189 if (i == current_chunk)
190 attrset(ATTR_SELECTED);
191 mvprintw(row, 0, "%10jd %10jd %10jd %8s %6d %10s %8d\t%-6s",
192 (intmax_t)chunk_info[i]->offset, (intmax_t)sz,
193 (intmax_t)chunk_info[i]->end, chunk_info[i]->name,
195 slice_type_name(chunk_info[i]->type, chunk_info[i]->subtype),
196 chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i]));
197 if (i == current_chunk)
203 print_command_summary(void)
205 mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
206 mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice F = `DD' mode");
207 mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Wizard m.");
208 mvprintw(18, 0, "T = Change Type U = Undo All Changes Q = Finish");
209 mvprintw(18, 47, "W = Write Changes");
210 mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
216 getBootMgr(char *dname, u_char **bootipl, size_t *bootipl_size,
217 u_char **bootmenu, size_t *bootmenu_size)
219 static u_char *boot0;
220 static size_t boot0_size;
221 static u_char *boot05;
222 static size_t boot05_size;
228 cp = variable_get(VAR_BOOTMGR);
230 /* Figure out what kind of IPL the user wants */
231 sprintf(str, "Install Boot Manager for drive %s?", dname);
232 MenuIPLType.title = str;
233 i = dmenuOpenSimple(&MenuIPLType, FALSE);
235 if (!strncmp(cp, "boot", 4))
243 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
245 *bootipl_size = boot0_size;
246 if (!boot05) boot05 = bootalloc("boot0.5", &boot05_size);
248 *bootmenu_size = boot05_size;
262 getBootMgr(char *dname, u_char **bootCode, size_t *bootCodeSize)
264 #if defined(__i386__) || defined(__amd64__) /* only meaningful on x86 */
265 static u_char *mbr, *boot0;
266 static size_t mbr_size, boot0_size;
271 cp = variable_get(VAR_BOOTMGR);
273 /* Figure out what kind of MBR the user wants */
274 sprintf(str, "Install Boot Manager for drive %s?", dname);
275 MenuMBRType.title = str;
276 i = dmenuOpenSimple(&MenuMBRType, FALSE);
279 if (!strncmp(cp, "boot", 4))
281 else if (!strcmp(cp, "standard"))
289 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
291 *bootCodeSize = boot0_size;
294 if (!mbr) mbr = bootalloc("mbr", &mbr_size);
296 *bootCodeSize = mbr_size;
308 #endif /* WITH_SLICES */
311 diskGetSelectCount(Device ***devs)
317 cp = variable_get(VAR_DISK);
318 dp = *devs = deviceFind(cp, DEVICE_TYPE_DISK);
319 cnt = deviceCount(dp);
322 for (i = 0, enabled = 0; i < cnt; i++) {
331 diskPartition(Device *dev)
342 size_t bootmenu_size;
347 WINDOW *w = savescr();
348 Disk *d = (Disk *)dev->private;
351 size_unit = UNIT_BLOCKS;
353 keypad(stdscr, TRUE);
355 /* Flush both the dialog and curses library views of the screen
356 since we don't always know who called us */
357 dialog_clear_norefresh(), clear();
360 /* Set up the chunk array */
363 /* Give the user a chance to sanitize the disk geometry, if necessary */
367 char *val, geometry[80];
369 /* Now print our overall state */
371 print_chunks(d, size_unit);
372 print_command_summary();
374 attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
383 /* Get command character */
385 switch (toupper(key)) {
386 case '\014': /* ^L (redraw) */
391 case '\020': /* ^P */
394 if (current_chunk != 0)
398 case '\016': /* ^N */
403 if (chunk_info[current_chunk + 1])
412 while (chunk_info[current_chunk + 1])
418 systemDisplayHelp("slice");
423 case 'F': /* Undocumented magic Dangerously Dedicated mode */
424 #if !defined(__i386__) && !defined(__amd64__)
426 #else /* The rest is only relevant on x86 */
427 cp = variable_get(VAR_DEDICATE_DISK);
428 if (cp && !strcasecmp(cp, "always"))
430 else if (toupper(key) == 'A')
433 rv = msgYesNo("Do you want to do this with a true partition entry\n"
434 "so as to remain cooperative with any future possible\n"
435 "operating systems on the drive(s)?\n"
436 "(See also the section about ``dangerously dedicated''\n"
437 "disks in the FreeBSD FAQ.)");
443 variable_set2(DISK_PARTITIONED, "yes", 0);
449 if (chunk_info[current_chunk]->type != unused)
450 msg = "Slice in use, delete it first or move to an unused one.";
452 char *val, tmp[20], name[16], *cp;
455 chunk_e partitiontype;
457 snprintf(name, sizeof (name), "%s", "FreeBSD");
458 val = msgGetInput(name,
459 "Please specify the name for new FreeBSD slice.");
461 strncpy(name, val, sizeof (name));
465 snprintf(tmp, 20, "%jd", (intmax_t)chunk_info[current_chunk]->size);
466 val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
467 "or append a trailing `M' for megabytes (e.g. 20M).");
468 if (val && (size = strtoimax(val, &cp, 0)) > 0) {
469 if (*cp && toupper(*cp) == 'M')
471 else if (*cp && toupper(*cp) == 'G')
473 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
474 val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
475 "Pressing Enter will choose the default, a native FreeBSD\n"
478 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
479 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
480 if (subtype == SUBTYPE_FREEBSD)
481 partitiontype = freebsd;
482 else if (subtype == SUBTYPE_FAT)
484 else if (subtype == SUBTYPE_EFI)
488 partitiontype = pc98;
492 Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
493 (chunk_info[current_chunk]->flags & CHUNK_ALIGN), name);
494 variable_set2(DISK_PARTITIONED, "yes", 0);
504 if (chunk_info[current_chunk]->type == unused)
505 msg = "Slice is already unused!";
507 Delete_Chunk(d, chunk_info[current_chunk]);
508 variable_set2(DISK_PARTITIONED, "yes", 0);
514 if (chunk_info[current_chunk]->type == unused)
515 msg = "Slice is currently unused (use create instead)";
519 chunk_e partitiontype;
521 sprintf(tmp, "%d", chunk_info[current_chunk]->subtype);
522 val = msgGetInput(tmp, "New partition type:\n\n"
523 "Pressing Enter will use the current type. To choose a native\n"
524 "FreeBSD slice enter %u. "
526 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
527 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
528 if (subtype == SUBTYPE_FREEBSD)
529 partitiontype = freebsd;
530 else if (subtype == SUBTYPE_FAT)
532 else if (subtype == SUBTYPE_EFI)
536 partitiontype = pc98;
540 chunk_info[current_chunk]->type = partitiontype;
541 chunk_info[current_chunk]->subtype = subtype;
547 snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
548 val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
549 "Don't forget to use the two slash (/) separator characters!\n"
550 "It's not possible to parse the field without them.");
553 nc = strtol(val, &val, 0);
554 nh = strtol(val + 1, &val, 0);
555 ns = strtol(val + 1, 0, 0);
556 Set_Bios_Geom(d, nc, nh, ns);
562 /* Clear active states so we won't have two */
563 for (i = 0; (chunk_info[i] != NULL) && (i < CHUNK_INFO_ENTRIES); i++)
564 chunk_info[i]->flags &= !CHUNK_ACTIVE;
567 chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
571 if (!variable_cmp(DISK_LABELLED, "written")) {
572 msgConfirm("You've already written this information out - you\n"
575 else if (!msgNoYes("Are you SURE you want to Undo everything?")) {
578 sstrncpy(cp, d->name, sizeof cp);
579 Free_Disk(dev->private);
582 msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", cp);
584 variable_unset(DISK_PARTITIONED);
585 variable_unset(DISK_LABELLED);
593 if (!msgNoYes("WARNING: You are about to modify an EXISTING installation.\n"
594 "You should simply type Q when you are finished\n"
595 "here and write to the disk from the label editor.\n\n"
596 "Are you absolutely sure you want to continue?")) {
597 variable_set2(DISK_PARTITIONED, "yes", 0);
601 * Don't trash the IPL if the first (and therefore only) chunk
602 * is marked for a truly dedicated disk (i.e., the disklabel
603 * starts at sector 0), even in cases where the user has
604 * requested a FreeBSD Boot Manager -- both would be fatal in
608 * Don't offer to update the IPL on this disk if the first
609 * "real" chunk looks like a FreeBSD "all disk" partition,
610 * or the disk is entirely FreeBSD.
612 if ((d->chunks->part->type != freebsd) ||
613 (d->chunks->part->offset > 1))
614 getBootMgr(d->name, &bootipl, &bootipl_size,
615 &bootmenu, &bootmenu_size);
622 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
625 * Don't trash the MBR if the first (and therefore only) chunk
626 * is marked for a truly dedicated disk (i.e., the disklabel
627 * starts at sector 0), even in cases where the user has
628 * requested booteasy or a "standard" MBR -- both would be
629 * fatal in this case.
632 * Don't offer to update the MBR on this disk if the first
633 * "real" chunk looks like a FreeBSD "all disk" partition,
634 * or the disk is entirely FreeBSD.
636 if ((d->chunks->part->type != freebsd) ||
637 (d->chunks->part->offset > 1))
638 getBootMgr(d->name, &mbrContents, &mbrSize);
643 Set_Boot_Mgr(d, mbrContents, mbrSize);
646 if (DITEM_STATUS(diskPartitionWrite(NULL)) != DITEM_SUCCESS)
647 msgConfirm("Disk partition write returned an error status!");
649 msgConfirm("Wrote FDISK partition information out successfully.");
655 if (!msgNoYes("Are you SURE you want to go into Wizard mode?\n"
656 "No seat belts whatsoever are provided!")) {
660 variable_set2(DISK_PARTITIONED, "yes", 0);
664 msg = "Wise choice!";
668 case '\033': /* ESC */
673 * Don't trash the IPL if the first (and therefore only) chunk
674 * is marked for a truly dedicated disk (i.e., the disklabel
675 * starts at sector 0), even in cases where the user has requested
676 * a FreeBSD Boot Manager -- both would be fatal in this case.
679 * Don't offer to update the IPL on this disk if the first "real"
680 * chunk looks like a FreeBSD "all disk" partition, or the disk is
683 if ((d->chunks->part->type != freebsd) ||
684 (d->chunks->part->offset > 1)) {
685 if (variable_cmp(DISK_PARTITIONED, "written")) {
686 getBootMgr(d->name, &bootipl, &bootipl_size,
687 &bootmenu, &bootmenu_size);
688 if (bootipl != NULL && bootmenu != NULL)
689 Set_Boot_Mgr(d, bootipl, bootipl_size,
690 bootmenu, bootmenu_size);
695 * Don't trash the MBR if the first (and therefore only) chunk
696 * is marked for a truly dedicated disk (i.e., the disklabel
697 * starts at sector 0), even in cases where the user has requested
698 * booteasy or a "standard" MBR -- both would be fatal in this case.
701 * Don't offer to update the MBR on this disk if the first "real"
702 * chunk looks like a FreeBSD "all disk" partition, or the disk is
705 if ((d->chunks->part->type != freebsd) ||
706 (d->chunks->part->offset > 1)) {
707 if (variable_cmp(DISK_PARTITIONED, "written")) {
708 getBootMgr(d->name, &mbrContents, &mbrSize);
709 if (mbrContents != NULL)
710 Set_Boot_Mgr(d, mbrContents, mbrSize);
717 size_unit = (size_unit + 1) % UNIT_SIZE;
722 msg = "Type F1 or ? for help";
728 char buf[FILENAME_MAX];
730 use_helpline("Press F1 to read more about disk slices.");
731 use_helpfile(systemHelpFile("partition", buf));
732 if (!variable_get(VAR_NO_WARN))
733 dialog_mesgbox("Disk slicing warning:", p, -1, -1);
738 #endif /* WITH_SLICES */
740 #if !defined(__ia64__)
742 bootalloc(char *name, size_t *size)
744 char buf[FILENAME_MAX];
747 snprintf(buf, sizeof buf, "/boot/%s", name);
748 if (stat(buf, &sb) != -1) {
751 fd = open(buf, O_RDONLY);
755 cp = malloc(sb.st_size);
756 if (read(fd, cp, sb.st_size) != sb.st_size) {
759 msgDebug("bootalloc: couldn't read %ld bytes from %s\n", (long)sb.st_size, buf);
767 msgDebug("bootalloc: couldn't open %s\n", buf);
770 msgDebug("bootalloc: can't stat %s\n", buf);
773 #endif /* !__ia64__ */
777 partitionHook(dialogMenuItem *selected)
779 Device **devs = NULL;
781 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
783 msgConfirm("Unable to find disk %s!", selected->prompt);
784 return DITEM_FAILURE;
786 /* Toggle enabled status? */
787 if (!devs[0]->enabled) {
788 devs[0]->enabled = TRUE;
789 diskPartition(devs[0]);
792 devs[0]->enabled = FALSE;
793 return DITEM_SUCCESS;
797 partitionCheck(dialogMenuItem *selected)
799 Device **devs = NULL;
801 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
802 if (!devs || devs[0]->enabled == FALSE)
808 diskPartitionEditor(dialogMenuItem *self)
814 cnt = diskGetSelectCount(&devs);
815 devcnt = deviceCount(devs);
817 msgConfirm("No disks found! Please verify that your disk controller is being\n"
818 "properly probed at boot time. See the Hardware Guide on the\n"
819 "Documentation menu for clues on diagnosing this type of problem.");
820 return DITEM_FAILURE;
823 /* Some are already selected */
824 for (i = 0; i < devcnt; i++) {
825 if (devs[i]->enabled) {
826 if (variable_get(VAR_NONINTERACTIVE) &&
827 !variable_get(VAR_DISKINTERACTIVE))
828 diskPartitionNonInteractive(devs[i]);
830 diskPartition(devs[i]);
835 /* No disks are selected, fall-back case now */
837 devs[0]->enabled = TRUE;
838 if (variable_get(VAR_NONINTERACTIVE) &&
839 !variable_get(VAR_DISKINTERACTIVE))
840 diskPartitionNonInteractive(devs[0]);
842 diskPartition(devs[0]);
843 return DITEM_SUCCESS;
846 menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook, partitionCheck);
848 msgConfirm("No devices suitable for installation found!\n\n"
849 "Please verify that your disk controller (and attached drives)\n"
850 "were detected properly. This can be done by pressing the\n"
851 "[Scroll Lock] key and using the Arrow keys to move back to\n"
852 "the boot messages. Press [Scroll Lock] again to return.");
853 return DITEM_FAILURE;
856 i = dmenuOpenSimple(menu, FALSE) ? DITEM_SUCCESS : DITEM_FAILURE;
862 return DITEM_SUCCESS;
864 #endif /* WITH_SLICES */
867 diskPartitionWrite(dialogMenuItem *self)
872 if (!variable_cmp(DISK_PARTITIONED, "written"))
873 return DITEM_SUCCESS;
875 devs = deviceFind(NULL, DEVICE_TYPE_DISK);
877 msgConfirm("Unable to find any disks to write to??");
878 return DITEM_FAILURE;
881 msgDebug("diskPartitionWrite: Examining %d devices\n", deviceCount(devs));
882 for (i = 0; devs[i]; i++) {
883 Disk *d = (Disk *)devs[i]->private;
884 #if !defined(__ia64__)
885 static u_char *boot1;
887 #if defined(__i386__) || defined(__amd64__)
888 static u_char *boot2;
891 if (!devs[i]->enabled)
894 #if defined(__i386__) || defined(__amd64__)
895 if (!boot1) boot1 = bootalloc("boot1", NULL);
896 if (!boot2) boot2 = bootalloc("boot2", NULL);
897 Set_Boot_Blocks(d, boot1, boot2);
898 #elif !defined(__ia64__)
899 if (!boot1) boot1 = bootalloc("boot1", NULL);
900 Set_Boot_Blocks(d, boot1, NULL);
903 msgNotify("Writing partition information to drive %s", d->name);
904 if (!Fake && Write_Disk(d)) {
905 msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
906 return DITEM_FAILURE;
909 /* Now it's not "yes", but "written" */
910 variable_set2(DISK_PARTITIONED, "written", 0);
911 return DITEM_SUCCESS | DITEM_RESTORE;
915 /* Partition a disk based wholly on which variables are set */
917 diskPartitionNonInteractive(Device *dev)
926 size_t bootmenu_size;
931 Disk *d = (Disk *)dev->private;
934 cp = variable_get(VAR_GEOMETRY);
936 if (!strcasecmp(cp, "sane")) {
938 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
940 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
943 msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
944 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
945 Sanitize_Bios_Geom(d);
946 msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
947 d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
950 msgDebug("Setting geometry from script to: %s\n", cp);
951 d->bios_cyl = strtol(cp, &cp, 0);
952 d->bios_hd = strtol(cp + 1, &cp, 0);
953 d->bios_sect = strtol(cp + 1, 0, 0);
957 cp = variable_get(VAR_PARTITION);
959 if (!strcmp(cp, "free")) {
960 /* Do free disk space case */
961 for (i = 0; chunk_info[i]; i++) {
962 /* If a chunk is at least 10MB in size, use it. */
963 if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
964 Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size,
966 (chunk_info[i]->flags & CHUNK_ALIGN),
968 variable_set2(DISK_PARTITIONED, "yes", 0);
972 if (!chunk_info[i]) {
973 msgConfirm("Unable to find any free space on this disk!");
977 else if (!strcmp(cp, "all")) {
978 /* Do all disk space case */
979 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
981 All_FreeBSD(d, FALSE);
983 else if (!strcmp(cp, "exclusive")) {
984 /* Do really-all-the-disk-space case */
985 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
987 All_FreeBSD(d, all_disk = TRUE);
989 else if ((sz = strtoimax(cp, &cp, 0))) {
990 /* Look for sz bytes free */
991 if (*cp && toupper(*cp) == 'M')
993 else if (*cp && toupper(*cp) == 'G')
995 for (i = 0; chunk_info[i]; i++) {
996 /* If a chunk is at least sz MB, use it. */
997 if (chunk_info[i]->type == unused && chunk_info[i]->size >= sz) {
998 Create_Chunk(d, chunk_info[i]->offset, sz, freebsd, 3,
999 (chunk_info[i]->flags & CHUNK_ALIGN),
1001 variable_set2(DISK_PARTITIONED, "yes", 0);
1005 if (!chunk_info[i]) {
1006 msgConfirm("Unable to find %jd free blocks on this disk!",
1011 else if (!strcmp(cp, "existing")) {
1012 /* Do existing FreeBSD case */
1013 for (i = 0; chunk_info[i]; i++) {
1014 if (chunk_info[i]->type == freebsd)
1017 if (!chunk_info[i]) {
1018 msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
1023 msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
1028 getBootMgr(d->name, &bootipl, &bootipl_size,
1029 &bootmenu, &bootmenu_size);
1030 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
1032 getBootMgr(d->name, &mbrContents, &mbrSize);
1033 Set_Boot_Mgr(d, mbrContents, mbrSize);
1036 variable_set2(DISK_PARTITIONED, "yes", 0);
1039 #endif /* WITH_SLICES */