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 F = `DD' mode");
206 mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Wizard m.");
207 mvprintw(18, 0, "T = Change Type U = Undo All Changes Q = Finish");
208 mvprintw(18, 47, "W = Write Changes");
209 mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
215 getBootMgr(char *dname, u_char **bootipl, size_t *bootipl_size,
216 u_char **bootmenu, size_t *bootmenu_size)
218 static u_char *boot0;
219 static size_t boot0_size;
220 static u_char *boot05;
221 static size_t boot05_size;
227 cp = variable_get(VAR_BOOTMGR);
229 /* Figure out what kind of IPL the user wants */
230 sprintf(str, "Install Boot Manager for drive %s?", dname);
231 MenuIPLType.title = str;
232 i = dmenuOpenSimple(&MenuIPLType, FALSE);
234 if (!strncmp(cp, "boot", 4))
242 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
244 *bootipl_size = boot0_size;
245 if (!boot05) boot05 = bootalloc("boot0.5", &boot05_size);
247 *bootmenu_size = boot05_size;
261 getBootMgr(char *dname, u_char **bootCode, size_t *bootCodeSize)
263 #if defined(__i386__) || defined(__amd64__) /* only meaningful on x86 */
264 static u_char *mbr, *boot0;
265 static size_t mbr_size, boot0_size;
270 cp = variable_get(VAR_BOOTMGR);
272 /* Figure out what kind of MBR the user wants */
273 sprintf(str, "Install Boot Manager for drive %s?", dname);
274 MenuMBRType.title = str;
275 i = dmenuOpenSimple(&MenuMBRType, FALSE);
278 if (!strncmp(cp, "boot", 4))
280 else if (!strcmp(cp, "standard"))
288 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
290 *bootCodeSize = boot0_size;
293 if (!mbr) mbr = bootalloc("mbr", &mbr_size);
295 *bootCodeSize = mbr_size;
307 #endif /* WITH_SLICES */
310 diskGetSelectCount(Device ***devs)
316 cp = variable_get(VAR_DISK);
317 dp = *devs = deviceFind(cp, DEVICE_TYPE_DISK);
318 cnt = deviceCount(dp);
321 for (i = 0, enabled = 0; i < cnt; i++) {
330 diskPartition(Device *dev)
341 size_t bootmenu_size;
346 WINDOW *w = savescr();
347 Disk *d = (Disk *)dev->private;
350 size_unit = UNIT_BLOCKS;
352 keypad(stdscr, TRUE);
354 /* Flush both the dialog and curses library views of the screen
355 since we don't always know who called us */
356 dialog_clear_norefresh(), clear();
359 /* Set up the chunk array */
362 /* Give the user a chance to sanitize the disk geometry, if necessary */
366 char *val, geometry[80];
368 /* Now print our overall state */
370 print_chunks(d, size_unit);
371 print_command_summary();
373 attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
382 /* Get command character */
384 switch (toupper(key)) {
385 case '\014': /* ^L (redraw) */
390 case '\020': /* ^P */
393 if (current_chunk != 0)
397 case '\016': /* ^N */
402 if (chunk_info[current_chunk + 1])
411 while (chunk_info[current_chunk + 1])
417 systemDisplayHelp("slice");
422 case 'F': /* Undocumented magic Dangerously Dedicated mode */
423 #if !defined(__i386__) && !defined(__amd64__)
425 #else /* The rest is only relevant on x86 */
426 cp = variable_get(VAR_DEDICATE_DISK);
427 if (cp && !strcasecmp(cp, "always"))
429 else if (toupper(key) == 'A')
432 rv = msgYesNo("Do you want to do this with a true partition entry\n"
433 "so as to remain cooperative with any future possible\n"
434 "operating systems on the drive(s)?\n"
435 "(See also the section about ``dangerously dedicated''\n"
436 "disks in the FreeBSD FAQ.)");
442 variable_set2(DISK_PARTITIONED, "yes", 0);
448 if (chunk_info[current_chunk]->type != unused)
449 msg = "Slice in use, delete it first or move to an unused one.";
451 char *val, tmp[20], name[16], *cp;
454 chunk_e partitiontype;
456 snprintf(name, sizeof (name), "%s", "FreeBSD");
457 val = msgGetInput(name,
458 "Please specify the name for new FreeBSD slice.");
460 strncpy(name, val, sizeof (name));
464 snprintf(tmp, 20, "%jd", (intmax_t)chunk_info[current_chunk]->size);
465 val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
466 "or append a trailing `M' for megabytes (e.g. 20M).");
467 if (val && (size = strtoimax(val, &cp, 0)) > 0) {
468 if (*cp && toupper(*cp) == 'M')
470 else if (*cp && toupper(*cp) == 'G')
472 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
473 val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
474 "Pressing Enter will choose the default, a native FreeBSD\n"
477 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
478 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
479 if (subtype == SUBTYPE_FREEBSD)
480 partitiontype = freebsd;
481 else if (subtype == SUBTYPE_FAT)
483 else if (subtype == SUBTYPE_EFI)
487 partitiontype = pc98;
491 Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
492 (chunk_info[current_chunk]->flags & CHUNK_ALIGN), name);
493 variable_set2(DISK_PARTITIONED, "yes", 0);
503 if (chunk_info[current_chunk]->type == unused)
504 msg = "Slice is already unused!";
506 Delete_Chunk(d, chunk_info[current_chunk]);
507 variable_set2(DISK_PARTITIONED, "yes", 0);
513 if (chunk_info[current_chunk]->type == unused)
514 msg = "Slice is currently unused (use create instead)";
518 chunk_e partitiontype;
520 sprintf(tmp, "%d", chunk_info[current_chunk]->subtype);
521 val = msgGetInput(tmp, "New partition type:\n\n"
522 "Pressing Enter will use the current type. To choose a native\n"
523 "FreeBSD slice enter %u. "
525 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
526 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
527 if (subtype == SUBTYPE_FREEBSD)
528 partitiontype = freebsd;
529 else if (subtype == SUBTYPE_FAT)
531 else if (subtype == SUBTYPE_EFI)
535 partitiontype = pc98;
539 chunk_info[current_chunk]->type = partitiontype;
540 chunk_info[current_chunk]->subtype = subtype;
546 snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
547 val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
548 "Don't forget to use the two slash (/) separator characters!\n"
549 "It's not possible to parse the field without them.");
552 nc = strtol(val, &val, 0);
553 nh = strtol(val + 1, &val, 0);
554 ns = strtol(val + 1, 0, 0);
555 Set_Bios_Geom(d, nc, nh, ns);
561 /* Clear active states so we won't have two */
562 for (i = 0; (chunk_info[i] != NULL) && (i < CHUNK_INFO_ENTRIES); i++)
563 chunk_info[i]->flags &= !CHUNK_ACTIVE;
566 chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
570 if (!variable_cmp(DISK_LABELLED, "written")) {
571 msgConfirm("You've already written this information out - you\n"
574 else if (!msgNoYes("Are you SURE you want to Undo everything?")) {
577 sstrncpy(cp, d->name, sizeof cp);
578 Free_Disk(dev->private);
581 msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", cp);
583 variable_unset(DISK_PARTITIONED);
584 variable_unset(DISK_LABELLED);
592 if (!msgNoYes("WARNING: You are about to modify an EXISTING installation.\n"
593 "You should simply type Q when you are finished\n"
594 "here and write to the disk from the label editor.\n\n"
595 "Are you absolutely sure you want to continue?")) {
596 variable_set2(DISK_PARTITIONED, "yes", 0);
600 * Don't trash the IPL if the first (and therefore only) chunk
601 * is marked for a truly dedicated disk (i.e., the disklabel
602 * starts at sector 0), even in cases where the user has
603 * requested a FreeBSD Boot Manager -- both would be fatal in
607 * Don't offer to update the IPL on this disk if the first
608 * "real" chunk looks like a FreeBSD "all disk" partition,
609 * or the disk is entirely FreeBSD.
611 if ((d->chunks->part->type != freebsd) ||
612 (d->chunks->part->offset > 1))
613 getBootMgr(d->name, &bootipl, &bootipl_size,
614 &bootmenu, &bootmenu_size);
621 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
624 * Don't trash the MBR if the first (and therefore only) chunk
625 * is marked for a truly dedicated disk (i.e., the disklabel
626 * starts at sector 0), even in cases where the user has
627 * requested booteasy or a "standard" MBR -- both would be
628 * fatal in this case.
631 * Don't offer to update the MBR on this disk if the first
632 * "real" chunk looks like a FreeBSD "all disk" partition,
633 * or the disk is entirely FreeBSD.
635 if ((d->chunks->part->type != freebsd) ||
636 (d->chunks->part->offset > 1))
637 getBootMgr(d->name, &mbrContents, &mbrSize);
642 Set_Boot_Mgr(d, mbrContents, mbrSize);
645 if (DITEM_STATUS(diskPartitionWrite(NULL)) != DITEM_SUCCESS)
646 msgConfirm("Disk partition write returned an error status!");
648 msgConfirm("Wrote FDISK partition information out successfully.");
654 if (!msgNoYes("Are you SURE you want to go into Wizard mode?\n"
655 "No seat belts whatsoever are provided!")) {
659 variable_set2(DISK_PARTITIONED, "yes", 0);
663 msg = "Wise choice!";
667 case '\033': /* ESC */
672 * Don't trash the IPL if the first (and therefore only) chunk
673 * is marked for a truly dedicated disk (i.e., the disklabel
674 * starts at sector 0), even in cases where the user has requested
675 * a FreeBSD Boot Manager -- both would be fatal in this case.
678 * Don't offer to update the IPL on this disk if the first "real"
679 * chunk looks like a FreeBSD "all disk" partition, or the disk is
682 if ((d->chunks->part->type != freebsd) ||
683 (d->chunks->part->offset > 1)) {
684 if (variable_cmp(DISK_PARTITIONED, "written")) {
685 getBootMgr(d->name, &bootipl, &bootipl_size,
686 &bootmenu, &bootmenu_size);
687 if (bootipl != NULL && bootmenu != NULL)
688 Set_Boot_Mgr(d, bootipl, bootipl_size,
689 bootmenu, bootmenu_size);
694 * Don't trash the MBR if the first (and therefore only) chunk
695 * is marked for a truly dedicated disk (i.e., the disklabel
696 * starts at sector 0), even in cases where the user has requested
697 * booteasy or a "standard" MBR -- both would be fatal in this case.
700 * Don't offer to update the MBR on this disk if the first "real"
701 * chunk looks like a FreeBSD "all disk" partition, or the disk is
704 if ((d->chunks->part->type != freebsd) ||
705 (d->chunks->part->offset > 1)) {
706 if (variable_cmp(DISK_PARTITIONED, "written")) {
707 getBootMgr(d->name, &mbrContents, &mbrSize);
708 if (mbrContents != NULL)
709 Set_Boot_Mgr(d, mbrContents, mbrSize);
716 size_unit = (size_unit + 1) % UNIT_SIZE;
721 msg = "Type F1 or ? for help";
727 char buf[FILENAME_MAX];
729 use_helpline("Press F1 to read more about disk slices.");
730 use_helpfile(systemHelpFile("partition", buf));
731 if (!variable_get(VAR_NO_WARN))
732 dialog_mesgbox("Disk slicing warning:", p, -1, -1);
737 #endif /* WITH_SLICES */
739 #if !defined(__ia64__)
741 bootalloc(char *name, size_t *size)
743 char buf[FILENAME_MAX];
746 snprintf(buf, sizeof buf, "/boot/%s", name);
747 if (stat(buf, &sb) != -1) {
750 fd = open(buf, O_RDONLY);
754 cp = malloc(sb.st_size);
755 if (read(fd, cp, sb.st_size) != sb.st_size) {
758 msgDebug("bootalloc: couldn't read %ld bytes from %s\n", (long)sb.st_size, buf);
766 msgDebug("bootalloc: couldn't open %s\n", buf);
769 msgDebug("bootalloc: can't stat %s\n", buf);
772 #endif /* !__ia64__ */
776 partitionHook(dialogMenuItem *selected)
778 Device **devs = NULL;
780 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
782 msgConfirm("Unable to find disk %s!", selected->prompt);
783 return DITEM_FAILURE;
785 /* Toggle enabled status? */
786 if (!devs[0]->enabled) {
787 devs[0]->enabled = TRUE;
788 diskPartition(devs[0]);
791 devs[0]->enabled = FALSE;
792 return DITEM_SUCCESS;
796 partitionCheck(dialogMenuItem *selected)
798 Device **devs = NULL;
800 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
801 if (!devs || devs[0]->enabled == FALSE)
807 diskPartitionEditor(dialogMenuItem *self)
813 cnt = diskGetSelectCount(&devs);
814 devcnt = deviceCount(devs);
816 msgConfirm("No disks found! Please verify that your disk controller is being\n"
817 "properly probed at boot time. See the Hardware Guide on the\n"
818 "Documentation menu for clues on diagnosing this type of problem.");
819 return DITEM_FAILURE;
822 /* Some are already selected */
823 for (i = 0; i < devcnt; i++) {
824 if (devs[i]->enabled) {
825 if (variable_get(VAR_NONINTERACTIVE) &&
826 !variable_get(VAR_DISKINTERACTIVE))
827 diskPartitionNonInteractive(devs[i]);
829 diskPartition(devs[i]);
834 /* No disks are selected, fall-back case now */
836 devs[0]->enabled = TRUE;
837 if (variable_get(VAR_NONINTERACTIVE) &&
838 !variable_get(VAR_DISKINTERACTIVE))
839 diskPartitionNonInteractive(devs[0]);
841 diskPartition(devs[0]);
842 return DITEM_SUCCESS;
845 menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook, partitionCheck);
847 msgConfirm("No devices suitable for installation found!\n\n"
848 "Please verify that your disk controller (and attached drives)\n"
849 "were detected properly. This can be done by pressing the\n"
850 "[Scroll Lock] key and using the Arrow keys to move back to\n"
851 "the boot messages. Press [Scroll Lock] again to return.");
852 return DITEM_FAILURE;
855 i = dmenuOpenSimple(menu, FALSE) ? DITEM_SUCCESS : DITEM_FAILURE;
861 return DITEM_SUCCESS;
863 #endif /* WITH_SLICES */
866 diskPartitionWrite(dialogMenuItem *self)
871 if (!variable_cmp(DISK_PARTITIONED, "written"))
872 return DITEM_SUCCESS;
874 devs = deviceFind(NULL, DEVICE_TYPE_DISK);
876 msgConfirm("Unable to find any disks to write to??");
877 return DITEM_FAILURE;
880 msgDebug("diskPartitionWrite: Examining %d devices\n", deviceCount(devs));
881 for (i = 0; devs[i]; i++) {
882 Disk *d = (Disk *)devs[i]->private;
883 #if !defined(__ia64__)
884 static u_char *boot1;
886 #if defined(__i386__) || defined(__amd64__)
887 static u_char *boot2;
890 if (!devs[i]->enabled)
893 #if defined(__i386__) || defined(__amd64__)
894 if (!boot1) boot1 = bootalloc("boot1", NULL);
895 if (!boot2) boot2 = bootalloc("boot2", NULL);
896 Set_Boot_Blocks(d, boot1, boot2);
897 #elif !defined(__ia64__)
898 if (!boot1) boot1 = bootalloc("boot1", NULL);
899 Set_Boot_Blocks(d, boot1, NULL);
902 msgNotify("Writing partition information to drive %s", d->name);
903 if (!Fake && Write_Disk(d)) {
904 msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
905 return DITEM_FAILURE;
908 /* Now it's not "yes", but "written" */
909 variable_set2(DISK_PARTITIONED, "written", 0);
910 return DITEM_SUCCESS | DITEM_RESTORE;
914 /* Partition a disk based wholly on which variables are set */
916 diskPartitionNonInteractive(Device *dev)
925 size_t bootmenu_size;
930 Disk *d = (Disk *)dev->private;
933 cp = variable_get(VAR_GEOMETRY);
935 if (!strcasecmp(cp, "sane")) {
937 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
939 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
942 msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
943 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
944 Sanitize_Bios_Geom(d);
945 msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
946 d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
949 msgDebug("Setting geometry from script to: %s\n", cp);
950 d->bios_cyl = strtol(cp, &cp, 0);
951 d->bios_hd = strtol(cp + 1, &cp, 0);
952 d->bios_sect = strtol(cp + 1, 0, 0);
956 cp = variable_get(VAR_PARTITION);
958 if (!strcmp(cp, "free")) {
959 /* Do free disk space case */
960 for (i = 0; chunk_info[i]; i++) {
961 /* If a chunk is at least 10MB in size, use it. */
962 if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
963 Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size,
965 (chunk_info[i]->flags & CHUNK_ALIGN),
967 variable_set2(DISK_PARTITIONED, "yes", 0);
971 if (!chunk_info[i]) {
972 msgConfirm("Unable to find any free space on this disk!");
976 else if (!strcmp(cp, "all")) {
977 /* Do all disk space case */
978 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
980 All_FreeBSD(d, FALSE);
982 else if (!strcmp(cp, "exclusive")) {
983 /* Do really-all-the-disk-space case */
984 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
986 All_FreeBSD(d, all_disk = TRUE);
988 else if ((sz = strtoimax(cp, &cp, 0))) {
989 /* Look for sz bytes free */
990 if (*cp && toupper(*cp) == 'M')
992 else if (*cp && toupper(*cp) == 'G')
994 for (i = 0; chunk_info[i]; i++) {
995 /* If a chunk is at least sz MB, use it. */
996 if (chunk_info[i]->type == unused && chunk_info[i]->size >= sz) {
997 Create_Chunk(d, chunk_info[i]->offset, sz, freebsd, 3,
998 (chunk_info[i]->flags & CHUNK_ALIGN),
1000 variable_set2(DISK_PARTITIONED, "yes", 0);
1004 if (!chunk_info[i]) {
1005 msgConfirm("Unable to find %jd free blocks on this disk!",
1010 else if (!strcmp(cp, "existing")) {
1011 /* Do existing FreeBSD case */
1012 for (i = 0; chunk_info[i]; i++) {
1013 if (chunk_info[i]->type == freebsd)
1016 if (!chunk_info[i]) {
1017 msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
1022 msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
1027 getBootMgr(d->name, &bootipl, &bootipl_size,
1028 &bootmenu, &bootmenu_size);
1029 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
1031 getBootMgr(d->name, &mbrContents, &mbrSize);
1032 Set_Boot_Mgr(d, mbrContents, mbrSize);
1035 variable_set2(DISK_PARTITIONED, "yes", 0);
1038 #endif /* WITH_SLICES */