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)
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;
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 = dmenuOpen(&MenuIPLType);
234 if (!strncmp(cp, "boot", 4))
235 dlg_add_result(MenuIPLType.items[0].prompt);
237 dlg_add_result(MenuIPLType.items[1].prompt);
240 if (!strcmp(dialog_vars.input_result, MenuIPLType.items[0].prompt)) {
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;
257 getBootMgr(char *dname, u_char **bootCode, size_t *bootCodeSize)
259 #if defined(__i386__) || defined(__amd64__) /* only meaningful on x86 */
260 static u_char *mbr, *boot0;
261 static size_t mbr_size, boot0_size;
267 cp = variable_get(VAR_BOOTMGR);
269 /* Figure out what kind of MBR the user wants */
270 sprintf(str, "Install Boot Manager for drive %s?", dname);
271 MenuMBRType.title = str;
272 i = dmenuOpen(&MenuMBRType);
275 if (!strcmp(cp, "standard"))
276 dlg_add_result(MenuMBRType.items[0].prompt);
277 if (!strncmp(cp, "boot", 4))
278 dlg_add_result(MenuMBRType.items[1].prompt);
280 dlg_add_result(MenuMBRType.items[2].prompt);
283 if (!strcmp(dialog_vars.input_result, MenuMBRType.items[0].prompt)) {
284 if (!mbr) mbr = bootalloc("mbr", &mbr_size);
286 *bootCodeSize = mbr_size;
288 } else if (!strcmp(dialog_vars.input_result, MenuMBRType.items[1].prompt)) {
289 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
291 *bootCodeSize = boot0_size;
300 #endif /* WITH_SLICES */
304 diskPartition(Device *dev)
315 size_t bootmenu_size;
320 WINDOW *w = savescr();
321 Disk *d = (Disk *)dev->private;
324 size_unit = UNIT_BLOCKS;
326 keypad(stdscr, TRUE);
328 /* Flush both the dialog and curses library views of the screen
329 since we don't always know who called us */
330 dlg_clear(), clear();
333 /* Set up the chunk array */
336 /* Give the user a chance to sanitize the disk geometry, if necessary */
340 char *val, geometry[80];
342 /* Now print our overall state */
344 print_chunks(d, size_unit);
345 print_command_summary();
347 attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
356 /* Get command character */
358 switch (toupper(key)) {
359 case '\014': /* ^L (redraw) */
364 case '\020': /* ^P */
367 if (current_chunk != 0)
371 case '\016': /* ^N */
376 if (chunk_info[current_chunk + 1])
385 while (chunk_info[current_chunk + 1])
391 systemDisplayHelp("slice");
396 case 'F': /* Undocumented magic Dangerously Dedicated mode */
397 #if !defined(__i386__) && !defined(__amd64__)
399 #else /* The rest is only relevant on x86 */
400 cp = variable_get(VAR_DEDICATE_DISK);
401 if (cp && !strcasecmp(cp, "always"))
403 else if (toupper(key) == 'A')
406 rv = msgYesNo("Do you want to do this with a true partition entry\n"
407 "so as to remain cooperative with any future possible\n"
408 "operating systems on the drive(s)?\n"
409 "(See also the section about ``dangerously dedicated''\n"
410 "disks in the FreeBSD FAQ.)");
416 variable_set2(DISK_PARTITIONED, "yes", 0);
422 if (chunk_info[current_chunk]->type != unused)
423 msg = "Slice in use, delete it first or move to an unused one.";
425 char *val, tmp[20], name[16], *cp;
428 chunk_e partitiontype;
430 snprintf(name, sizeof (name), "%s", "FreeBSD");
431 val = msgGetInput(name,
432 "Please specify the name for new FreeBSD slice.");
434 strncpy(name, val, sizeof (name));
438 snprintf(tmp, 20, "%jd", (intmax_t)chunk_info[current_chunk]->size);
439 val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
440 "or append a trailing `M' for megabytes (e.g. 20M).");
441 if (val && (size = strtoimax(val, &cp, 0)) > 0) {
442 if (*cp && toupper(*cp) == 'M')
444 else if (*cp && toupper(*cp) == 'G')
446 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
447 val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
448 "Pressing Enter will choose the default, a native FreeBSD\n"
451 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
452 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
453 if (subtype == SUBTYPE_FREEBSD)
454 partitiontype = freebsd;
455 else if (subtype == SUBTYPE_FAT)
457 else if (subtype == SUBTYPE_EFI)
461 partitiontype = pc98;
465 Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
466 (chunk_info[current_chunk]->flags & CHUNK_ALIGN), name);
467 variable_set2(DISK_PARTITIONED, "yes", 0);
477 if (chunk_info[current_chunk]->type == unused)
478 msg = "Slice is already unused!";
480 Delete_Chunk(d, chunk_info[current_chunk]);
481 variable_set2(DISK_PARTITIONED, "yes", 0);
487 if (chunk_info[current_chunk]->type == unused)
488 msg = "Slice is currently unused (use create instead)";
492 chunk_e partitiontype;
494 sprintf(tmp, "%d", chunk_info[current_chunk]->subtype);
495 val = msgGetInput(tmp, "New partition type:\n\n"
496 "Pressing Enter will use the current type. To choose a native\n"
497 "FreeBSD slice enter %u. "
499 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
500 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
501 if (subtype == SUBTYPE_FREEBSD)
502 partitiontype = freebsd;
503 else if (subtype == SUBTYPE_FAT)
505 else if (subtype == SUBTYPE_EFI)
509 partitiontype = pc98;
513 chunk_info[current_chunk]->type = partitiontype;
514 chunk_info[current_chunk]->subtype = subtype;
520 snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
521 val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
522 "Don't forget to use the two slash (/) separator characters!\n"
523 "It's not possible to parse the field without them.");
526 nc = strtol(val, &val, 0);
527 nh = strtol(val + 1, &val, 0);
528 ns = strtol(val + 1, 0, 0);
529 Set_Bios_Geom(d, nc, nh, ns);
535 /* Clear active states so we won't have two */
536 for (i = 0; (chunk_info[i] != NULL) && (i < CHUNK_INFO_ENTRIES); i++)
537 chunk_info[i]->flags &= !CHUNK_ACTIVE;
540 chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
544 if (!variable_cmp(DISK_LABELLED, "written")) {
545 msgConfirm("You've already written this information out - you\n"
548 else if (!msgNoYes("Are you SURE you want to Undo everything?")) {
551 sstrncpy(cp, d->name, sizeof cp);
552 Free_Disk(dev->private);
555 msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", cp);
557 variable_unset(DISK_PARTITIONED);
558 variable_unset(DISK_LABELLED);
566 if (!msgNoYes("WARNING: You are about to modify an EXISTING installation.\n"
567 "You should simply type Q when you are finished\n"
568 "here and write to the disk from the label editor.\n\n"
569 "Are you absolutely sure you want to continue?")) {
570 variable_set2(DISK_PARTITIONED, "yes", 0);
574 * Don't trash the IPL if the first (and therefore only) chunk
575 * is marked for a truly dedicated disk (i.e., the disklabel
576 * starts at sector 0), even in cases where the user has
577 * requested a FreeBSD Boot Manager -- both would be fatal in
581 * Don't offer to update the IPL on this disk if the first
582 * "real" chunk looks like a FreeBSD "all disk" partition,
583 * or the disk is entirely FreeBSD.
585 if ((d->chunks->part->type != freebsd) ||
586 (d->chunks->part->offset > 1))
587 getBootMgr(d->name, &bootipl, &bootipl_size,
588 &bootmenu, &bootmenu_size);
595 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
598 * Don't trash the MBR if the first (and therefore only) chunk
599 * is marked for a truly dedicated disk (i.e., the disklabel
600 * starts at sector 0), even in cases where the user has
601 * requested booteasy or a "standard" MBR -- both would be
602 * fatal in this case.
605 * Don't offer to update the MBR on this disk if the first
606 * "real" chunk looks like a FreeBSD "all disk" partition,
607 * or the disk is entirely FreeBSD.
609 if ((d->chunks->part->type != freebsd) ||
610 (d->chunks->part->offset > 1))
611 getBootMgr(d->name, &mbrContents, &mbrSize);
616 Set_Boot_Mgr(d, mbrContents, mbrSize);
619 if (DITEM_STATUS(diskPartitionWrite(dev)) != DITEM_SUCCESS)
620 msgConfirm("Disk partition write returned an error status!");
622 msgConfirm("Wrote FDISK partition information out successfully.");
628 if (!msgNoYes("Are you SURE you want to go into Wizard mode?\n"
629 "No seat belts whatsoever are provided!")) {
633 variable_set2(DISK_PARTITIONED, "yes", 0);
637 msg = "Wise choice!";
641 case '\033': /* ESC */
646 * Don't trash the IPL if the first (and therefore only) chunk
647 * is marked for a truly dedicated disk (i.e., the disklabel
648 * starts at sector 0), even in cases where the user has requested
649 * a FreeBSD Boot Manager -- both would be fatal in this case.
652 * Don't offer to update the IPL on this disk if the first "real"
653 * chunk looks like a FreeBSD "all disk" partition, or the disk is
656 if ((d->chunks->part->type != freebsd) ||
657 (d->chunks->part->offset > 1)) {
658 if (variable_cmp(DISK_PARTITIONED, "written")) {
659 getBootMgr(d->name, &bootipl, &bootipl_size,
660 &bootmenu, &bootmenu_size);
661 if (bootipl != NULL && bootmenu != NULL)
662 Set_Boot_Mgr(d, bootipl, bootipl_size,
663 bootmenu, bootmenu_size);
668 * Don't trash the MBR if the first (and therefore only) chunk
669 * is marked for a truly dedicated disk (i.e., the disklabel
670 * starts at sector 0), even in cases where the user has requested
671 * booteasy or a "standard" MBR -- both would be fatal in this case.
674 * Don't offer to update the MBR on this disk if the first "real"
675 * chunk looks like a FreeBSD "all disk" partition, or the disk is
678 if ((d->chunks->part->type != freebsd) ||
679 (d->chunks->part->offset > 1)) {
680 if (variable_cmp(DISK_PARTITIONED, "written")) {
681 getBootMgr(d->name, &mbrContents, &mbrSize);
682 if (mbrContents != NULL)
683 Set_Boot_Mgr(d, mbrContents, mbrSize);
690 size_unit = (size_unit + 1) % UNIT_SIZE;
695 msg = "Type F1 or ? for help";
701 char buf[FILENAME_MAX];
702 DIALOG_VARS save_vars;
704 dlg_save_vars(&save_vars);
705 dialog_vars.help_line = "Press F1 to read more about disk slices.";
706 dialog_vars.help_file = systemHelpFile("partition", buf);
707 if (!variable_get(VAR_NO_WARN))
708 xdialog_msgbox("Disk slicing warning:", p, -1, -1, 1);
710 dlg_restore_vars(&save_vars);
714 #endif /* WITH_SLICES */
716 #if !defined(__ia64__)
718 bootalloc(char *name, size_t *size)
720 char buf[FILENAME_MAX];
723 snprintf(buf, sizeof buf, "/boot/%s", name);
724 if (stat(buf, &sb) != -1) {
727 fd = open(buf, O_RDONLY);
731 cp = malloc(sb.st_size);
732 if (read(fd, cp, sb.st_size) != sb.st_size) {
735 msgDebug("bootalloc: couldn't read %ld bytes from %s\n", (long)sb.st_size, buf);
743 msgDebug("bootalloc: couldn't open %s\n", buf);
746 msgDebug("bootalloc: can't stat %s\n", buf);
749 #endif /* !__ia64__ */
753 partitionHook(dialogMenuItem *selected)
755 Device **devs = NULL;
757 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
759 msgConfirm("Unable to find disk %s!", selected->prompt);
760 return DITEM_FAILURE;
762 diskPartition(devs[0]);
763 return DITEM_SUCCESS;
767 diskPartitionEditor(dialogMenuItem *self)
772 devs = deviceFind(variable_get(VAR_DISK), DEVICE_TYPE_DISK);
774 msgConfirm("No disks found! Please verify that your disk controller is being\n"
775 "properly probed at boot time. See the Hardware Guide on the\n"
776 "Documentation menu for clues on diagnosing this type of problem.");
777 return DITEM_FAILURE;
780 /* No disks are selected, fall-back case now */
781 int cnt = deviceCount(devs);
784 if (variable_get(VAR_NONINTERACTIVE) &&
785 !variable_get(VAR_DISKINTERACTIVE))
786 diskPartitionNonInteractive(devs[0]);
788 diskPartition(devs[0]);
789 return DITEM_SUCCESS;
794 menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook);
796 msgConfirm("No devices suitable for installation found!\n\n"
797 "Please verify that your disk controller (and attached drives)\n"
798 "were detected properly. This can be done by pressing the\n"
799 "[Scroll Lock] key and using the Arrow keys to move back to\n"
800 "the boot messages. Press [Scroll Lock] again to return.");
801 return DITEM_FAILURE;
804 result = dmenuOpen(menu) ? DITEM_SUCCESS : DITEM_FAILURE;
809 return DITEM_SUCCESS;
811 #endif /* WITH_SLICES */
814 diskPartitionWrite(Device *dev)
816 Disk *d = (Disk *)dev->private;
817 #if !defined(__ia64__)
818 static u_char *boot1;
820 #if defined(__i386__) || defined(__amd64__)
821 static u_char *boot2;
824 if (!variable_cmp(DISK_PARTITIONED, "written"))
825 return DITEM_SUCCESS;
827 #if defined(__i386__) || defined(__amd64__)
828 if (!boot1) boot1 = bootalloc("boot1", NULL);
829 if (!boot2) boot2 = bootalloc("boot2", NULL);
830 Set_Boot_Blocks(d, boot1, boot2);
831 #elif !defined(__ia64__)
832 if (!boot1) boot1 = bootalloc("boot1", NULL);
833 Set_Boot_Blocks(d, boot1, NULL);
836 msgNotify("Writing partition information to drive %s", d->name);
837 if (!Fake && Write_Disk(d)) {
838 msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
839 return DITEM_FAILURE;
842 /* Now it's not "yes", but "written" */
843 variable_set2(DISK_PARTITIONED, "written", 0);
844 return DITEM_SUCCESS | DITEM_RESTORE;
848 /* Partition a disk based wholly on which variables are set */
850 diskPartitionNonInteractive(Device *dev)
859 size_t bootmenu_size;
864 Disk *d = (Disk *)dev->private;
867 cp = variable_get(VAR_GEOMETRY);
869 if (!strcasecmp(cp, "sane")) {
871 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
873 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
876 msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
877 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
878 Sanitize_Bios_Geom(d);
879 msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
880 d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
883 msgDebug("Setting geometry from script to: %s\n", cp);
884 d->bios_cyl = strtol(cp, &cp, 0);
885 d->bios_hd = strtol(cp + 1, &cp, 0);
886 d->bios_sect = strtol(cp + 1, 0, 0);
890 cp = variable_get(VAR_PARTITION);
892 if (!strcmp(cp, "free")) {
893 /* Do free disk space case */
894 for (i = 0; chunk_info[i]; i++) {
895 /* If a chunk is at least 10MB in size, use it. */
896 if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
897 Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size,
899 (chunk_info[i]->flags & CHUNK_ALIGN),
901 variable_set2(DISK_PARTITIONED, "yes", 0);
905 if (!chunk_info[i]) {
906 msgConfirm("Unable to find any free space on this disk!");
910 else if (!strcmp(cp, "all")) {
911 /* Do all disk space case */
912 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
914 All_FreeBSD(d, FALSE);
916 else if (!strcmp(cp, "exclusive")) {
917 /* Do really-all-the-disk-space case */
918 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
920 All_FreeBSD(d, all_disk = TRUE);
922 else if ((sz = strtoimax(cp, &cp, 0))) {
923 /* Look for sz bytes free */
924 if (*cp && toupper(*cp) == 'M')
926 else if (*cp && toupper(*cp) == 'G')
928 for (i = 0; chunk_info[i]; i++) {
929 /* If a chunk is at least sz MB, use it. */
930 if (chunk_info[i]->type == unused && chunk_info[i]->size >= sz) {
931 Create_Chunk(d, chunk_info[i]->offset, sz, freebsd, 3,
932 (chunk_info[i]->flags & CHUNK_ALIGN),
934 variable_set2(DISK_PARTITIONED, "yes", 0);
938 if (!chunk_info[i]) {
939 msgConfirm("Unable to find %jd free blocks on this disk!",
944 else if (!strcmp(cp, "existing")) {
945 /* Do existing FreeBSD case */
946 for (i = 0; chunk_info[i]; i++) {
947 if (chunk_info[i]->type == freebsd)
950 if (!chunk_info[i]) {
951 msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
956 msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
961 getBootMgr(d->name, &bootipl, &bootipl_size,
962 &bootmenu, &bootmenu_size);
963 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
965 getBootMgr(d->name, &mbrContents, &mbrSize);
966 Set_Boot_Mgr(d, mbrContents, mbrSize);
969 variable_set2(DISK_PARTITIONED, "yes", 0);
972 #endif /* WITH_SLICES */