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 print_chunks(Disk *d, int u)
113 szstr = (u == UNIT_GIG ? "GB" : (u == UNIT_MEG ? "MB" :
114 (u == UNIT_KILO ? "KB" : "ST")));
117 for (i = 0; chunk_info[i]; i++)
118 Total += chunk_info[i]->size;
120 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256) {
122 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) {
124 dialog_clear_norefresh();
125 msgConfirm("WARNING: A geometry of %lu/%lu/%lu for %s is incorrect. Using\n"
126 "a more likely geometry. If this geometry is incorrect or you\n"
127 "are unsure as to whether or not it's correct, please consult\n"
128 "the Hardware Guide in the Documentation submenu or use the\n"
129 "(G)eometry command to change it now.\n\n"
130 "Remember: you need to enter whatever your BIOS thinks the\n"
131 "geometry is! For IDE, it's what you were told in the BIOS\n"
132 "setup. For SCSI, it's the translation mode your controller is\n"
133 "using. Do NOT use a ``physical geometry''.",
134 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
135 Sanitize_Bios_Geom(d);
136 msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
137 d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
140 mvaddstr(0, 0, "Disk name:\t");
142 attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL);
143 attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL);
145 "DISK Geometry:\t%lu cyls/%lu heads/%lu sectors = %jd sectors (%jdMB)",
146 d->bios_cyl, d->bios_hd, d->bios_sect,
147 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect,
148 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect / (1024/512) / 1024);
149 mvprintw(3, 0, "%6s %10s(%s) %10s %8s %6s %10s %8s %8s",
150 "Offset", "Size", szstr, "End", "Name", "PType", "Desc",
152 for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) {
154 default: /* fall thru */
156 sz = chunk_info[i]->size;
159 sz = chunk_info[i]->size / (1024/512);
162 sz = chunk_info[i]->size / (1024/512) / 1024;
165 sz = chunk_info[i]->size / (1024/512) / 1024 / 1024;
168 if (i == current_chunk)
169 attrset(ATTR_SELECTED);
170 mvprintw(row, 0, "%10jd %10jd %10jd %8s %6d %10s %8d\t%-6s",
171 (intmax_t)chunk_info[i]->offset, (intmax_t)sz,
172 (intmax_t)chunk_info[i]->end, chunk_info[i]->name,
174 slice_type_name(chunk_info[i]->type, chunk_info[i]->subtype),
175 chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i]));
176 if (i == current_chunk)
182 print_command_summary(void)
184 mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
185 mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice F = `DD' mode");
186 mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Wizard m.");
187 mvprintw(18, 0, "T = Change Type U = Undo All Changes Q = Finish");
188 mvprintw(18, 47, "W = Write Changes");
189 mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
195 getBootMgr(char *dname, u_char **bootipl, size_t *bootipl_size,
196 u_char **bootmenu, size_t *bootmenu_size)
198 static u_char *boot0;
199 static size_t boot0_size;
200 static u_char *boot05;
201 static size_t boot05_size;
207 cp = variable_get(VAR_BOOTMGR);
209 /* Figure out what kind of IPL the user wants */
210 sprintf(str, "Install Boot Manager for drive %s?", dname);
211 MenuIPLType.title = str;
212 i = dmenuOpenSimple(&MenuIPLType, FALSE);
214 if (!strncmp(cp, "boot", 4))
222 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
224 *bootipl_size = boot0_size;
225 if (!boot05) boot05 = bootalloc("boot0.5", &boot05_size);
227 *bootmenu_size = boot05_size;
241 getBootMgr(char *dname, u_char **bootCode, size_t *bootCodeSize)
243 #if defined(__i386__) || defined(__amd64__) /* only meaningful on x86 */
244 static u_char *mbr, *boot0;
245 static size_t mbr_size, boot0_size;
250 cp = variable_get(VAR_BOOTMGR);
252 /* Figure out what kind of MBR the user wants */
253 sprintf(str, "Install Boot Manager for drive %s?", dname);
254 MenuMBRType.title = str;
255 i = dmenuOpenSimple(&MenuMBRType, FALSE);
258 if (!strncmp(cp, "boot", 4))
260 else if (!strcmp(cp, "standard"))
268 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
270 *bootCodeSize = boot0_size;
273 if (!mbr) mbr = bootalloc("mbr", &mbr_size);
275 *bootCodeSize = mbr_size;
287 #endif /* WITH_SLICES */
290 diskGetSelectCount(Device ***devs)
296 cp = variable_get(VAR_DISK);
297 dp = *devs = deviceFind(cp, DEVICE_TYPE_DISK);
298 cnt = deviceCount(dp);
301 for (i = 0, enabled = 0; i < cnt; i++) {
310 diskPartition(Device *dev)
321 size_t bootmenu_size;
326 WINDOW *w = savescr();
327 Disk *d = (Disk *)dev->private;
330 size_unit = UNIT_BLOCKS;
332 keypad(stdscr, TRUE);
334 /* Flush both the dialog and curses library views of the screen
335 since we don't always know who called us */
336 dialog_clear_norefresh(), clear();
339 /* Set up the chunk array */
343 char *val, geometry[80];
345 /* Now print our overall state */
347 print_chunks(d, size_unit);
348 print_command_summary();
350 attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
359 /* Get command character */
361 switch (toupper(key)) {
362 case '\014': /* ^L (redraw) */
367 case '\020': /* ^P */
370 if (current_chunk != 0)
374 case '\016': /* ^N */
379 if (chunk_info[current_chunk + 1])
388 while (chunk_info[current_chunk + 1])
394 systemDisplayHelp("slice");
399 case 'F': /* Undocumented magic Dangerously Dedicated mode */
400 #if !defined(__i386__) && !defined(__amd64__)
402 #else /* The rest is only relevant on x86 */
403 cp = variable_get(VAR_DEDICATE_DISK);
404 if (cp && !strcasecmp(cp, "always"))
406 else if (toupper(key) == 'A')
409 rv = msgYesNo("Do you want to do this with a true partition entry\n"
410 "so as to remain cooperative with any future possible\n"
411 "operating systems on the drive(s)?\n"
412 "(See also the section about ``dangerously dedicated''\n"
413 "disks in the FreeBSD FAQ.)");
419 variable_set2(DISK_PARTITIONED, "yes", 0);
425 if (chunk_info[current_chunk]->type != unused)
426 msg = "Slice in use, delete it first or move to an unused one.";
428 char *val, tmp[20], name[16], *cp;
431 chunk_e partitiontype;
433 snprintf(name, sizeof (name), "%s", "FreeBSD");
434 val = msgGetInput(name,
435 "Please specify the name for new FreeBSD slice.");
437 strncpy(name, val, sizeof (name));
441 snprintf(tmp, 20, "%jd", (intmax_t)chunk_info[current_chunk]->size);
442 val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
443 "or append a trailing `M' for megabytes (e.g. 20M).");
444 if (val && (size = strtoimax(val, &cp, 0)) > 0) {
445 if (*cp && toupper(*cp) == 'M')
447 else if (*cp && toupper(*cp) == 'G')
449 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
450 val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
451 "Pressing Enter will choose the default, a native FreeBSD\n"
454 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
455 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
456 if (subtype == SUBTYPE_FREEBSD)
457 partitiontype = freebsd;
458 else if (subtype == SUBTYPE_FAT)
460 else if (subtype == SUBTYPE_EFI)
464 partitiontype = pc98;
468 Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
469 (chunk_info[current_chunk]->flags & CHUNK_ALIGN), name);
470 variable_set2(DISK_PARTITIONED, "yes", 0);
480 if (chunk_info[current_chunk]->type == unused)
481 msg = "Slice is already unused!";
483 Delete_Chunk(d, chunk_info[current_chunk]);
484 variable_set2(DISK_PARTITIONED, "yes", 0);
490 if (chunk_info[current_chunk]->type == unused)
491 msg = "Slice is currently unused (use create instead)";
495 chunk_e partitiontype;
497 sprintf(tmp, "%d", chunk_info[current_chunk]->subtype);
498 val = msgGetInput(tmp, "New partition type:\n\n"
499 "Pressing Enter will use the current type. To choose a native\n"
500 "FreeBSD slice enter %u. "
502 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
503 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
504 if (subtype == SUBTYPE_FREEBSD)
505 partitiontype = freebsd;
506 else if (subtype == SUBTYPE_FAT)
508 else if (subtype == SUBTYPE_EFI)
512 partitiontype = pc98;
516 chunk_info[current_chunk]->type = partitiontype;
517 chunk_info[current_chunk]->subtype = subtype;
523 snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
524 val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
525 "Don't forget to use the two slash (/) separator characters!\n"
526 "It's not possible to parse the field without them.");
529 nc = strtol(val, &val, 0);
530 nh = strtol(val + 1, &val, 0);
531 ns = strtol(val + 1, 0, 0);
532 Set_Bios_Geom(d, nc, nh, ns);
538 /* Clear active states so we won't have two */
539 for (i = 0; (chunk_info[i] != NULL) && (i < CHUNK_INFO_ENTRIES); i++)
540 chunk_info[i]->flags &= !CHUNK_ACTIVE;
543 chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
547 if (!variable_cmp(DISK_LABELLED, "written")) {
548 msgConfirm("You've already written this information out - you\n"
551 else if (!msgNoYes("Are you SURE you want to Undo everything?")) {
554 sstrncpy(cp, d->name, sizeof cp);
555 Free_Disk(dev->private);
558 msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", cp);
560 variable_unset(DISK_PARTITIONED);
561 variable_unset(DISK_LABELLED);
569 if (!msgNoYes("WARNING: This should only be used when modifying an EXISTING\n"
570 "installation. If you are installing FreeBSD for the first time\n"
571 "then you should simply type Q when you're finished here and your\n"
572 "changes will be committed in one batch automatically at the end of\n"
573 "these questions. If you're adding a disk, you should NOT write\n"
574 "from this screen, you should do it from the label editor.\n\n"
575 "Are you absolutely sure you want to do this now?")) {
576 variable_set2(DISK_PARTITIONED, "yes", 0);
580 * Don't trash the IPL if the first (and therefore only) chunk
581 * is marked for a truly dedicated disk (i.e., the disklabel
582 * starts at sector 0), even in cases where the user has
583 * requested a FreeBSD Boot Manager -- both would be fatal in
587 * Don't offer to update the IPL on this disk if the first
588 * "real" chunk looks like a FreeBSD "all disk" partition,
589 * or the disk is entirely FreeBSD.
591 if ((d->chunks->part->type != freebsd) ||
592 (d->chunks->part->offset > 1))
593 getBootMgr(d->name, &bootipl, &bootipl_size,
594 &bootmenu, &bootmenu_size);
601 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
604 * Don't trash the MBR if the first (and therefore only) chunk
605 * is marked for a truly dedicated disk (i.e., the disklabel
606 * starts at sector 0), even in cases where the user has
607 * requested booteasy or a "standard" MBR -- both would be
608 * fatal in this case.
611 * Don't offer to update the MBR on this disk if the first
612 * "real" chunk looks like a FreeBSD "all disk" partition,
613 * or the disk is entirely FreeBSD.
615 if ((d->chunks->part->type != freebsd) ||
616 (d->chunks->part->offset > 1))
617 getBootMgr(d->name, &mbrContents, &mbrSize);
622 Set_Boot_Mgr(d, mbrContents, mbrSize);
625 if (DITEM_STATUS(diskPartitionWrite(NULL)) != DITEM_SUCCESS)
626 msgConfirm("Disk partition write returned an error status!");
628 msgConfirm("Wrote FDISK partition information out successfully.");
634 if (!msgNoYes("Are you SURE you want to go into Wizard mode?\n"
635 "No seat belts whatsoever are provided!")) {
639 variable_set2(DISK_PARTITIONED, "yes", 0);
643 msg = "Wise choice!";
647 case '\033': /* ESC */
652 * Don't trash the IPL if the first (and therefore only) chunk
653 * is marked for a truly dedicated disk (i.e., the disklabel
654 * starts at sector 0), even in cases where the user has requested
655 * a FreeBSD Boot Manager -- both would be fatal in this case.
658 * Don't offer to update the IPL on this disk if the first "real"
659 * chunk looks like a FreeBSD "all disk" partition, or the disk is
662 if ((d->chunks->part->type != freebsd) ||
663 (d->chunks->part->offset > 1)) {
664 if (variable_cmp(DISK_PARTITIONED, "written")) {
665 getBootMgr(d->name, &bootipl, &bootipl_size,
666 &bootmenu, &bootmenu_size);
667 if (bootipl != NULL && bootmenu != NULL)
668 Set_Boot_Mgr(d, bootipl, bootipl_size,
669 bootmenu, bootmenu_size);
674 * Don't trash the MBR if the first (and therefore only) chunk
675 * is marked for a truly dedicated disk (i.e., the disklabel
676 * starts at sector 0), even in cases where the user has requested
677 * booteasy or a "standard" MBR -- both would be fatal in this case.
680 * Don't offer to update the MBR on this disk if the first "real"
681 * chunk looks like a FreeBSD "all disk" partition, or the disk is
684 if ((d->chunks->part->type != freebsd) ||
685 (d->chunks->part->offset > 1)) {
686 if (variable_cmp(DISK_PARTITIONED, "written")) {
687 getBootMgr(d->name, &mbrContents, &mbrSize);
688 if (mbrContents != NULL)
689 Set_Boot_Mgr(d, mbrContents, mbrSize);
696 size_unit = (size_unit + 1) % UNIT_SIZE;
701 msg = "Type F1 or ? for help";
707 char buf[FILENAME_MAX];
709 use_helpline("Press F1 to read more about disk slices.");
710 use_helpfile(systemHelpFile("partition", buf));
711 if (!variable_get(VAR_NO_WARN))
712 dialog_mesgbox("Disk slicing warning:", p, -1, -1);
717 #endif /* WITH_SLICES */
719 #if !defined(__ia64__)
721 bootalloc(char *name, size_t *size)
723 char buf[FILENAME_MAX];
726 snprintf(buf, sizeof buf, "/boot/%s", name);
727 if (stat(buf, &sb) != -1) {
730 fd = open(buf, O_RDONLY);
734 cp = malloc(sb.st_size);
735 if (read(fd, cp, sb.st_size) != sb.st_size) {
738 msgDebug("bootalloc: couldn't read %ld bytes from %s\n", (long)sb.st_size, buf);
746 msgDebug("bootalloc: couldn't open %s\n", buf);
749 msgDebug("bootalloc: can't stat %s\n", buf);
752 #endif /* !__ia64__ */
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 #if !defined(__ia64__)
864 static u_char *boot1;
866 #if defined(__i386__) || defined(__amd64__)
867 static u_char *boot2;
870 if (!devs[i]->enabled)
873 #if defined(__i386__) || defined(__amd64__)
874 if (!boot1) boot1 = bootalloc("boot1", NULL);
875 if (!boot2) boot2 = bootalloc("boot2", NULL);
876 Set_Boot_Blocks(d, boot1, boot2);
877 #elif !defined(__ia64__)
878 if (!boot1) boot1 = bootalloc("boot1", NULL);
879 Set_Boot_Blocks(d, boot1, NULL);
882 msgNotify("Writing partition information to drive %s", d->name);
883 if (!Fake && Write_Disk(d)) {
884 msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
885 return DITEM_FAILURE;
888 /* Now it's not "yes", but "written" */
889 variable_set2(DISK_PARTITIONED, "written", 0);
890 return DITEM_SUCCESS | DITEM_RESTORE;
894 /* Partition a disk based wholly on which variables are set */
896 diskPartitionNonInteractive(Device *dev)
905 size_t bootmenu_size;
910 Disk *d = (Disk *)dev->private;
913 cp = variable_get(VAR_GEOMETRY);
915 msgDebug("Setting geometry from script to: %s\n", cp);
916 d->bios_cyl = strtol(cp, &cp, 0);
917 d->bios_hd = strtol(cp + 1, &cp, 0);
918 d->bios_sect = strtol(cp + 1, 0, 0);
922 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256) {
924 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) {
926 msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
927 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
928 Sanitize_Bios_Geom(d);
929 msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
930 d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
933 cp = variable_get(VAR_PARTITION);
935 if (!strcmp(cp, "free")) {
936 /* Do free disk space case */
937 for (i = 0; chunk_info[i]; i++) {
938 /* If a chunk is at least 10MB in size, use it. */
939 if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
940 Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size,
942 (chunk_info[i]->flags & CHUNK_ALIGN),
944 variable_set2(DISK_PARTITIONED, "yes", 0);
948 if (!chunk_info[i]) {
949 msgConfirm("Unable to find any free space on this disk!");
953 else if (!strcmp(cp, "all")) {
954 /* Do all disk space case */
955 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
957 All_FreeBSD(d, FALSE);
959 else if (!strcmp(cp, "exclusive")) {
960 /* Do really-all-the-disk-space case */
961 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
963 All_FreeBSD(d, all_disk = TRUE);
965 else if ((sz = strtoimax(cp, &cp, 0))) {
966 /* Look for sz bytes free */
967 if (*cp && toupper(*cp) == 'M')
969 else if (*cp && toupper(*cp) == 'G')
971 for (i = 0; chunk_info[i]; i++) {
972 /* If a chunk is at least sz MB, use it. */
973 if (chunk_info[i]->type == unused && chunk_info[i]->size >= sz) {
974 Create_Chunk(d, chunk_info[i]->offset, sz, freebsd, 3,
975 (chunk_info[i]->flags & CHUNK_ALIGN),
977 variable_set2(DISK_PARTITIONED, "yes", 0);
981 if (!chunk_info[i]) {
982 msgConfirm("Unable to find %jd free blocks on this disk!",
987 else if (!strcmp(cp, "existing")) {
988 /* Do existing FreeBSD case */
989 for (i = 0; chunk_info[i]; i++) {
990 if (chunk_info[i]->type == freebsd)
993 if (!chunk_info[i]) {
994 msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
999 msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
1004 getBootMgr(d->name, &bootipl, &bootipl_size,
1005 &bootmenu, &bootmenu_size);
1006 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
1008 getBootMgr(d->name, &mbrContents, &mbrSize);
1009 Set_Boot_Mgr(d, mbrContents, mbrSize);
1012 variable_set2(DISK_PARTITIONED, "yes", 0);
1015 #endif /* WITH_SLICES */