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 an old machine it is recommended that it does not have more\n"
120 "than 65535 cylinders, more than 255 heads, or more than\n"
126 " sectors per track.\n"
128 "Would you like to keep using the current geometry?\n",
129 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
131 Sanitize_Bios_Geom(d);
132 msgConfirm("A geometry of %lu/%lu/%lu was calculated for %s.\n"
134 "If you are not sure about this, please consult the Hardware Guide\n"
135 "in the Documentation submenu or use the (G)eometry command to\n"
136 "change it. Remember: you need to enter whatever your BIOS thinks\n"
137 "the geometry is! For IDE, it's what you were told in the BIOS\n"
138 "setup. For SCSI, it's the translation mode your controller is\n"
139 "using. Do NOT use a ``physical geometry''.\n",
140 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
146 print_chunks(Disk *d, int u)
153 szstr = (u == UNIT_GIG ? "GB" : (u == UNIT_MEG ? "MB" :
154 (u == UNIT_KILO ? "KB" : "ST")));
157 for (i = 0; chunk_info[i]; i++)
158 Total += chunk_info[i]->size;
160 mvaddstr(0, 0, "Disk name:\t");
162 attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL);
163 attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL);
165 "DISK Geometry:\t%lu cyls/%lu heads/%lu sectors = %jd sectors (%jdMB)",
166 d->bios_cyl, d->bios_hd, d->bios_sect,
167 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect,
168 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect / (1024/512) / 1024);
169 mvprintw(3, 0, "%6s %10s(%s) %10s %8s %6s %10s %8s %8s",
170 "Offset", "Size", szstr, "End", "Name", "PType", "Desc",
172 for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) {
174 default: /* fall thru */
176 sz = chunk_info[i]->size;
179 sz = chunk_info[i]->size / (1024/512);
182 sz = chunk_info[i]->size / (1024/512) / 1024;
185 sz = chunk_info[i]->size / (1024/512) / 1024 / 1024;
188 if (i == current_chunk)
189 attrset(ATTR_SELECTED);
190 mvprintw(row, 0, "%10jd %10jd %10jd %8s %6d %10s %8d\t%-6s",
191 (intmax_t)chunk_info[i]->offset, (intmax_t)sz,
192 (intmax_t)chunk_info[i]->end, chunk_info[i]->name,
194 slice_type_name(chunk_info[i]->type, chunk_info[i]->subtype),
195 chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i]));
196 if (i == current_chunk)
202 print_command_summary(void)
204 mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
205 mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice");
206 mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Expert m.");
207 mvprintw(18, 0, "T = Change Type U = Undo All Changes W = Write Changes Q = Finish");
208 mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
214 getBootMgr(char *dname, u_char **bootipl, size_t *bootipl_size,
215 u_char **bootmenu, size_t *bootmenu_size)
217 static u_char *boot0;
218 static size_t boot0_size;
219 static u_char *boot05;
220 static size_t boot05_size;
226 cp = variable_get(VAR_BOOTMGR);
228 /* Figure out what kind of IPL the user wants */
229 sprintf(str, "Install Boot Manager for drive %s?", dname);
230 MenuIPLType.title = str;
231 i = dmenuOpenSimple(&MenuIPLType, FALSE);
233 if (!strncmp(cp, "boot", 4))
241 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
243 *bootipl_size = boot0_size;
244 if (!boot05) boot05 = bootalloc("boot0.5", &boot05_size);
246 *bootmenu_size = boot05_size;
260 getBootMgr(char *dname, u_char **bootCode, size_t *bootCodeSize)
262 #if defined(__i386__) || defined(__amd64__) /* only meaningful on x86 */
263 static u_char *mbr, *boot0;
264 static size_t mbr_size, boot0_size;
269 cp = variable_get(VAR_BOOTMGR);
271 /* Figure out what kind of MBR the user wants */
272 sprintf(str, "Install Boot Manager for drive %s?", dname);
273 MenuMBRType.title = str;
274 i = dmenuOpenSimple(&MenuMBRType, FALSE);
277 if (!strncmp(cp, "boot", 4))
279 else if (!strcmp(cp, "standard"))
287 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
289 *bootCodeSize = boot0_size;
292 if (!mbr) mbr = bootalloc("mbr", &mbr_size);
294 *bootCodeSize = mbr_size;
306 #endif /* WITH_SLICES */
309 diskGetSelectCount(Device ***devs)
315 cp = variable_get(VAR_DISK);
316 dp = *devs = deviceFind(cp, DEVICE_TYPE_DISK);
317 cnt = deviceCount(dp);
320 for (i = 0, enabled = 0; i < cnt; i++) {
329 diskPartition(Device *dev)
340 size_t bootmenu_size;
345 WINDOW *w = savescr();
346 Disk *d = (Disk *)dev->private;
349 size_unit = UNIT_BLOCKS;
351 keypad(stdscr, TRUE);
353 /* Flush both the dialog and curses library views of the screen
354 since we don't always know who called us */
355 dialog_clear_norefresh(), clear();
358 /* Set up the chunk array */
361 /* Give the user a chance to sanitize the disk geometry, if necessary */
365 char *val, geometry[80];
367 /* Now print our overall state */
369 print_chunks(d, size_unit);
370 print_command_summary();
372 attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
381 /* Get command character */
383 switch (toupper(key)) {
384 case '\014': /* ^L (redraw) */
389 case '\020': /* ^P */
392 if (current_chunk != 0)
396 case '\016': /* ^N */
401 if (chunk_info[current_chunk + 1])
410 while (chunk_info[current_chunk + 1])
416 systemDisplayHelp("slice");
421 case 'F': /* Undocumented magic Dangerously Dedicated mode */
422 #if !defined(__i386__) && !defined(__amd64__)
424 #else /* The rest is only relevant on x86 */
425 cp = variable_get(VAR_DEDICATE_DISK);
426 if (cp && !strcasecmp(cp, "always"))
428 else if (toupper(key) == 'A')
431 rv = msgYesNo("Do you want to do this with a true partition entry\n"
432 "so as to remain cooperative with any future possible\n"
433 "operating systems on the drive(s)?\n"
434 "(See also the section about ``dangerously dedicated''\n"
435 "disks in the FreeBSD FAQ.)");
441 variable_set2(DISK_PARTITIONED, "yes", 0);
447 if (chunk_info[current_chunk]->type != unused)
448 msg = "Slice in use, delete it first or move to an unused one.";
450 char *val, tmp[20], name[16], *cp;
453 chunk_e partitiontype;
455 snprintf(name, sizeof (name), "%s", "FreeBSD");
456 val = msgGetInput(name,
457 "Please specify the name for new FreeBSD slice.");
459 strncpy(name, val, sizeof (name));
463 snprintf(tmp, 20, "%jd", (intmax_t)chunk_info[current_chunk]->size);
464 val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
465 "or append a trailing `M' for megabytes (e.g. 20M).");
466 if (val && (size = strtoimax(val, &cp, 0)) > 0) {
467 if (*cp && toupper(*cp) == 'M')
469 else if (*cp && toupper(*cp) == 'G')
471 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
472 val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
473 "Pressing Enter will choose the default, a native FreeBSD\n"
476 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
477 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
478 if (subtype == SUBTYPE_FREEBSD)
479 partitiontype = freebsd;
480 else if (subtype == SUBTYPE_FAT)
482 else if (subtype == SUBTYPE_EFI)
486 partitiontype = pc98;
490 Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
491 (chunk_info[current_chunk]->flags & CHUNK_ALIGN), name);
492 variable_set2(DISK_PARTITIONED, "yes", 0);
502 if (chunk_info[current_chunk]->type == unused)
503 msg = "Slice is already unused!";
505 Delete_Chunk(d, chunk_info[current_chunk]);
506 variable_set2(DISK_PARTITIONED, "yes", 0);
512 if (chunk_info[current_chunk]->type == unused)
513 msg = "Slice is currently unused (use create instead)";
517 chunk_e partitiontype;
519 sprintf(tmp, "%d", chunk_info[current_chunk]->subtype);
520 val = msgGetInput(tmp, "New partition type:\n\n"
521 "Pressing Enter will use the current type. To choose a native\n"
522 "FreeBSD slice enter %u. "
524 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
525 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
526 if (subtype == SUBTYPE_FREEBSD)
527 partitiontype = freebsd;
528 else if (subtype == SUBTYPE_FAT)
530 else if (subtype == SUBTYPE_EFI)
534 partitiontype = pc98;
538 chunk_info[current_chunk]->type = partitiontype;
539 chunk_info[current_chunk]->subtype = subtype;
545 snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
546 val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
547 "Don't forget to use the two slash (/) separator characters!\n"
548 "It's not possible to parse the field without them.");
551 nc = strtol(val, &val, 0);
552 nh = strtol(val + 1, &val, 0);
553 ns = strtol(val + 1, 0, 0);
554 Set_Bios_Geom(d, nc, nh, ns);
560 /* Clear active states so we won't have two */
561 for (i = 0; (chunk_info[i] != NULL) && (i < CHUNK_INFO_ENTRIES); i++)
562 chunk_info[i]->flags &= !CHUNK_ACTIVE;
565 chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
569 if (!variable_cmp(DISK_LABELLED, "written")) {
570 msgConfirm("You've already written this information out - you\n"
573 else if (!msgNoYes("Are you SURE you want to Undo everything?")) {
576 sstrncpy(cp, d->name, sizeof cp);
577 Free_Disk(dev->private);
580 msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", cp);
582 variable_unset(DISK_PARTITIONED);
583 variable_unset(DISK_LABELLED);
591 if (!msgNoYes("WARNING: You are about to modify an EXISTING installation.\n"
592 "You should simply type Q when you are finished\n"
593 "here and write to the disk from the label editor.\n\n"
594 "Are you absolutely sure you want to continue?")) {
595 variable_set2(DISK_PARTITIONED, "yes", 0);
599 * Don't trash the IPL if the first (and therefore only) chunk
600 * is marked for a truly dedicated disk (i.e., the disklabel
601 * starts at sector 0), even in cases where the user has
602 * requested a FreeBSD Boot Manager -- both would be fatal in
606 * Don't offer to update the IPL on this disk if the first
607 * "real" chunk looks like a FreeBSD "all disk" partition,
608 * or the disk is entirely FreeBSD.
610 if ((d->chunks->part->type != freebsd) ||
611 (d->chunks->part->offset > 1))
612 getBootMgr(d->name, &bootipl, &bootipl_size,
613 &bootmenu, &bootmenu_size);
620 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
623 * Don't trash the MBR if the first (and therefore only) chunk
624 * is marked for a truly dedicated disk (i.e., the disklabel
625 * starts at sector 0), even in cases where the user has
626 * requested booteasy or a "standard" MBR -- both would be
627 * fatal in this case.
630 * Don't offer to update the MBR on this disk if the first
631 * "real" chunk looks like a FreeBSD "all disk" partition,
632 * or the disk is entirely FreeBSD.
634 if ((d->chunks->part->type != freebsd) ||
635 (d->chunks->part->offset > 1))
636 getBootMgr(d->name, &mbrContents, &mbrSize);
641 Set_Boot_Mgr(d, mbrContents, mbrSize);
644 if (DITEM_STATUS(diskPartitionWrite(NULL)) != DITEM_SUCCESS)
645 msgConfirm("Disk partition write returned an error status!");
647 msgConfirm("Wrote FDISK partition information out successfully.");
653 if (!msgNoYes("Are you SURE you want to go into Wizard mode?\n"
654 "No seat belts whatsoever are provided!")) {
658 variable_set2(DISK_PARTITIONED, "yes", 0);
662 msg = "Wise choice!";
666 case '\033': /* ESC */
671 * Don't trash the IPL if the first (and therefore only) chunk
672 * is marked for a truly dedicated disk (i.e., the disklabel
673 * starts at sector 0), even in cases where the user has requested
674 * a FreeBSD Boot Manager -- both would be fatal in this case.
677 * Don't offer to update the IPL on this disk if the first "real"
678 * chunk looks like a FreeBSD "all disk" partition, or the disk is
681 if ((d->chunks->part->type != freebsd) ||
682 (d->chunks->part->offset > 1)) {
683 if (variable_cmp(DISK_PARTITIONED, "written")) {
684 getBootMgr(d->name, &bootipl, &bootipl_size,
685 &bootmenu, &bootmenu_size);
686 if (bootipl != NULL && bootmenu != NULL)
687 Set_Boot_Mgr(d, bootipl, bootipl_size,
688 bootmenu, bootmenu_size);
693 * Don't trash the MBR if the first (and therefore only) chunk
694 * is marked for a truly dedicated disk (i.e., the disklabel
695 * starts at sector 0), even in cases where the user has requested
696 * booteasy or a "standard" MBR -- both would be fatal in this case.
699 * Don't offer to update the MBR on this disk if the first "real"
700 * chunk looks like a FreeBSD "all disk" partition, or the disk is
703 if ((d->chunks->part->type != freebsd) ||
704 (d->chunks->part->offset > 1)) {
705 if (variable_cmp(DISK_PARTITIONED, "written")) {
706 getBootMgr(d->name, &mbrContents, &mbrSize);
707 if (mbrContents != NULL)
708 Set_Boot_Mgr(d, mbrContents, mbrSize);
715 size_unit = (size_unit + 1) % UNIT_SIZE;
720 msg = "Type F1 or ? for help";
726 char buf[FILENAME_MAX];
728 use_helpline("Press F1 to read more about disk slices.");
729 use_helpfile(systemHelpFile("partition", buf));
730 if (!variable_get(VAR_NO_WARN))
731 dialog_mesgbox("Disk slicing warning:", p, -1, -1);
736 #endif /* WITH_SLICES */
738 #if !defined(__ia64__)
740 bootalloc(char *name, size_t *size)
742 char buf[FILENAME_MAX];
745 snprintf(buf, sizeof buf, "/boot/%s", name);
746 if (stat(buf, &sb) != -1) {
749 fd = open(buf, O_RDONLY);
753 cp = malloc(sb.st_size);
754 if (read(fd, cp, sb.st_size) != sb.st_size) {
757 msgDebug("bootalloc: couldn't read %ld bytes from %s\n", (long)sb.st_size, buf);
765 msgDebug("bootalloc: couldn't open %s\n", buf);
768 msgDebug("bootalloc: can't stat %s\n", buf);
771 #endif /* !__ia64__ */
775 partitionHook(dialogMenuItem *selected)
777 Device **devs = NULL;
779 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
781 msgConfirm("Unable to find disk %s!", selected->prompt);
782 return DITEM_FAILURE;
784 /* Toggle enabled status? */
785 if (!devs[0]->enabled) {
786 devs[0]->enabled = TRUE;
787 diskPartition(devs[0]);
790 devs[0]->enabled = FALSE;
791 return DITEM_SUCCESS;
795 partitionCheck(dialogMenuItem *selected)
797 Device **devs = NULL;
799 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
800 if (!devs || devs[0]->enabled == FALSE)
806 diskPartitionEditor(dialogMenuItem *self)
812 cnt = diskGetSelectCount(&devs);
813 devcnt = deviceCount(devs);
815 msgConfirm("No disks found! Please verify that your disk controller is being\n"
816 "properly probed at boot time. See the Hardware Guide on the\n"
817 "Documentation menu for clues on diagnosing this type of problem.");
818 return DITEM_FAILURE;
821 /* Some are already selected */
822 for (i = 0; i < devcnt; i++) {
823 if (devs[i]->enabled) {
824 if (variable_get(VAR_NONINTERACTIVE) &&
825 !variable_get(VAR_DISKINTERACTIVE))
826 diskPartitionNonInteractive(devs[i]);
828 diskPartition(devs[i]);
833 /* No disks are selected, fall-back case now */
835 devs[0]->enabled = TRUE;
836 if (variable_get(VAR_NONINTERACTIVE) &&
837 !variable_get(VAR_DISKINTERACTIVE))
838 diskPartitionNonInteractive(devs[0]);
840 diskPartition(devs[0]);
841 return DITEM_SUCCESS;
844 menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook, partitionCheck);
846 msgConfirm("No devices suitable for installation found!\n\n"
847 "Please verify that your disk controller (and attached drives)\n"
848 "were detected properly. This can be done by pressing the\n"
849 "[Scroll Lock] key and using the Arrow keys to move back to\n"
850 "the boot messages. Press [Scroll Lock] again to return.");
851 return DITEM_FAILURE;
854 i = dmenuOpenSimple(menu, FALSE) ? DITEM_SUCCESS : DITEM_FAILURE;
860 return DITEM_SUCCESS;
862 #endif /* WITH_SLICES */
865 diskPartitionWrite(dialogMenuItem *self)
870 if (!variable_cmp(DISK_PARTITIONED, "written"))
871 return DITEM_SUCCESS;
873 devs = deviceFind(NULL, DEVICE_TYPE_DISK);
875 msgConfirm("Unable to find any disks to write to??");
876 return DITEM_FAILURE;
879 msgDebug("diskPartitionWrite: Examining %d devices\n", deviceCount(devs));
880 for (i = 0; devs[i]; i++) {
881 Disk *d = (Disk *)devs[i]->private;
882 #if !defined(__ia64__)
883 static u_char *boot1;
885 #if defined(__i386__) || defined(__amd64__)
886 static u_char *boot2;
889 if (!devs[i]->enabled)
892 #if defined(__i386__) || defined(__amd64__)
893 if (!boot1) boot1 = bootalloc("boot1", NULL);
894 if (!boot2) boot2 = bootalloc("boot2", NULL);
895 Set_Boot_Blocks(d, boot1, boot2);
896 #elif !defined(__ia64__)
897 if (!boot1) boot1 = bootalloc("boot1", NULL);
898 Set_Boot_Blocks(d, boot1, NULL);
901 msgNotify("Writing partition information to drive %s", d->name);
902 if (!Fake && Write_Disk(d)) {
903 msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
904 return DITEM_FAILURE;
907 /* Now it's not "yes", but "written" */
908 variable_set2(DISK_PARTITIONED, "written", 0);
909 return DITEM_SUCCESS | DITEM_RESTORE;
913 /* Partition a disk based wholly on which variables are set */
915 diskPartitionNonInteractive(Device *dev)
924 size_t bootmenu_size;
929 Disk *d = (Disk *)dev->private;
932 cp = variable_get(VAR_GEOMETRY);
934 if (!strcasecmp(cp, "sane")) {
936 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
938 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
941 msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
942 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
943 Sanitize_Bios_Geom(d);
944 msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
945 d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
948 msgDebug("Setting geometry from script to: %s\n", cp);
949 d->bios_cyl = strtol(cp, &cp, 0);
950 d->bios_hd = strtol(cp + 1, &cp, 0);
951 d->bios_sect = strtol(cp + 1, 0, 0);
955 cp = variable_get(VAR_PARTITION);
957 if (!strcmp(cp, "free")) {
958 /* Do free disk space case */
959 for (i = 0; chunk_info[i]; i++) {
960 /* If a chunk is at least 10MB in size, use it. */
961 if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
962 Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size,
964 (chunk_info[i]->flags & CHUNK_ALIGN),
966 variable_set2(DISK_PARTITIONED, "yes", 0);
970 if (!chunk_info[i]) {
971 msgConfirm("Unable to find any free space on this disk!");
975 else if (!strcmp(cp, "all")) {
976 /* Do all disk space case */
977 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
979 All_FreeBSD(d, FALSE);
981 else if (!strcmp(cp, "exclusive")) {
982 /* Do really-all-the-disk-space case */
983 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
985 All_FreeBSD(d, all_disk = TRUE);
987 else if ((sz = strtoimax(cp, &cp, 0))) {
988 /* Look for sz bytes free */
989 if (*cp && toupper(*cp) == 'M')
991 else if (*cp && toupper(*cp) == 'G')
993 for (i = 0; chunk_info[i]; i++) {
994 /* If a chunk is at least sz MB, use it. */
995 if (chunk_info[i]->type == unused && chunk_info[i]->size >= sz) {
996 Create_Chunk(d, chunk_info[i]->offset, sz, freebsd, 3,
997 (chunk_info[i]->flags & CHUNK_ALIGN),
999 variable_set2(DISK_PARTITIONED, "yes", 0);
1003 if (!chunk_info[i]) {
1004 msgConfirm("Unable to find %jd free blocks on this disk!",
1009 else if (!strcmp(cp, "existing")) {
1010 /* Do existing FreeBSD case */
1011 for (i = 0; chunk_info[i]; i++) {
1012 if (chunk_info[i]->type == freebsd)
1015 if (!chunk_info[i]) {
1016 msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
1021 msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
1026 getBootMgr(d->name, &bootipl, &bootipl_size,
1027 &bootmenu, &bootmenu_size);
1028 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
1030 getBootMgr(d->name, &mbrContents, &mbrSize);
1031 Set_Boot_Mgr(d, mbrContents, mbrSize);
1034 variable_set2(DISK_PARTITIONED, "yes", 0);
1037 #endif /* WITH_SLICES */