2 * The new sysinstall program.
4 * This is probably the last program in the `sysinstall' line - the next
5 * generation being essentially a complete rewrite.
10 * Jordan Hubbard. All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer,
17 * verbatim and that no modifications are made prior to this
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
23 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include "sysinstall.h"
41 #include <sys/disklabel.h>
43 enum size_units_t { UNIT_BLOCKS, UNIT_KILO, UNIT_MEG, UNIT_SIZE };
46 #define SUBTYPE_FREEBSD 50324
47 #define SUBTYPE_FAT 37218
49 #define SUBTYPE_FREEBSD 165
53 /* Where we start displaying chunk information on the screen */
54 #define CHUNK_START_ROW 5
56 /* Where we keep track of MBR chunks */
57 static struct chunk *chunk_info[16];
58 static int current_chunk;
60 static void diskPartitionNonInteractive(Device *dev);
61 static u_char * bootalloc(char *name, size_t *size);
64 record_chunks(Disk *d)
66 struct chunk *c1 = NULL;
71 msgFatal("No chunk list found for %s!", d->name);
73 for (c1 = d->chunks->part; c1; c1 = c1->next) {
74 if (c1->type == unused && c1->size > last_free) {
81 if (current_chunk >= i)
82 current_chunk = i - 1;
88 print_chunks(Disk *d, int u)
95 szstr = (u == UNIT_MEG ? "MB" : (u == UNIT_KILO ? "KB" : "ST"));
97 for (i = Total = 0; chunk_info[i]; i++)
98 Total += chunk_info[i]->size;
100 if (d->bios_cyl >= 65536 || d->bios_hd > 16 || d->bios_sect >= 256) {
102 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) {
104 dialog_clear_norefresh();
105 msgConfirm("WARNING: A geometry of %lu/%lu/%lu for %s is incorrect. Using\n"
106 "a more likely geometry. If this geometry is incorrect or you\n"
107 "are unsure as to whether or not it's correct, please consult\n"
108 "the Hardware Guide in the Documentation submenu or use the\n"
109 "(G)eometry command to change it now.\n\n"
110 "Remember: you need to enter whatever your BIOS thinks the\n"
111 "geometry is! For IDE, it's what you were told in the BIOS\n"
112 "setup. For SCSI, it's the translation mode your controller is\n"
113 "using. Do NOT use a ``physical geometry''.",
114 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
115 Sanitize_Bios_Geom(d);
118 mvaddstr(0, 0, "Disk name:\t");
120 attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL);
121 attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL);
123 "DISK Geometry:\t%lu cyls/%lu heads/%lu sectors = %lu sectors (%luMB)",
124 d->bios_cyl, d->bios_hd, d->bios_sect,
125 d->bios_cyl * d->bios_hd * d->bios_sect,
126 d->bios_cyl * d->bios_hd * d->bios_sect / (1024/512) / 1024);
127 mvprintw(3, 0, "%6s %10s(%s) %10s %8s %6s %10s %8s %8s",
128 "Offset", "Size", szstr, "End", "Name", "PType", "Desc",
130 for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) {
132 default: /* fall thru */
134 sz = chunk_info[i]->size;
137 sz = chunk_info[i]->size / (1024/512);
140 sz = chunk_info[i]->size / (1024/512) / 1024;
143 if (i == current_chunk)
144 attrset(ATTR_SELECTED);
145 mvprintw(row, 0, "%10ld %10lu %10lu %8s %6d %10s %8d\t%-6s",
146 chunk_info[i]->offset, sz,
147 chunk_info[i]->end, chunk_info[i]->name,
149 slice_type_name(chunk_info[i]->type, chunk_info[i]->subtype),
150 chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i]));
151 if (i == current_chunk)
157 print_command_summary()
159 mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
160 mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice F = `DD' mode");
161 mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Wizard m.");
162 mvprintw(18, 0, "T = Change Type U = Undo All Changes Q = Finish");
164 mvprintw(18, 47, "W = Write Changes");
165 mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
171 getBootMgr(char *dname, u_char **bootipl, size_t *bootipl_size,
172 u_char **bootmenu, size_t *bootmenu_size)
174 static u_char *boot0;
175 static size_t boot0_size;
176 static u_char *boot05;
177 static size_t boot05_size;
183 cp = variable_get(VAR_BOOTMGR);
185 /* Figure out what kind of MBR the user wants */
186 sprintf(str, "Install Boot Manager for drive %s?", dname);
187 MenuMBRType.title = str;
188 i = dmenuOpenSimple(&MenuMBRType, FALSE);
190 if (!strncmp(cp, "boot", 4))
198 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
200 *bootipl_size = boot0_size;
201 if (!boot05) boot05 = bootalloc("boot0.5", &boot05_size);
203 *bootmenu_size = boot05_size;
217 getBootMgr(char *dname, u_char **bootCode, size_t *bootCodeSize)
219 #ifdef __i386__ /* only meaningful on x86 */
220 static u_char *mbr, *boot0;
221 static size_t mbr_size, boot0_size;
226 cp = variable_get(VAR_BOOTMGR);
228 /* Figure out what kind of MBR the user wants */
229 sprintf(str, "Install Boot Manager for drive %s?", dname);
230 MenuMBRType.title = str;
231 i = dmenuOpenSimple(&MenuMBRType, FALSE);
234 if (!strncmp(cp, "boot", 4))
236 else if (!strcmp(cp, "standard"))
244 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
246 *bootCodeSize = boot0_size;
249 if (!mbr) mbr = bootalloc("mbr", &mbr_size);
251 *bootCodeSize = mbr_size;
265 diskGetSelectCount(Device ***devs)
271 cp = variable_get(VAR_DISK);
272 dp = *devs = deviceFind(cp, DEVICE_TYPE_DISK);
273 cnt = deviceCount(dp);
276 for (i = 0, enabled = 0; i < cnt; i++) {
284 diskPartition(Device *dev)
294 size_t bootmenu_size;
299 WINDOW *w = savescr();
300 Disk *d = (Disk *)dev->private;
303 size_unit = UNIT_BLOCKS;
305 keypad(stdscr, TRUE);
307 /* Flush both the dialog and curses library views of the screen
308 since we don't always know who called us */
309 dialog_clear_norefresh(), clear();
312 /* Set up the chunk array */
316 char *val, geometry[80];
318 /* Now print our overall state */
320 print_chunks(d, size_unit);
321 print_command_summary();
323 attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
332 /* Get command character */
334 switch (toupper(key)) {
335 case '\014': /* ^L (redraw) */
340 case '\020': /* ^P */
343 if (current_chunk != 0)
347 case '\016': /* ^N */
352 if (chunk_info[current_chunk + 1])
361 while (chunk_info[current_chunk + 1])
367 systemDisplayHelp("slice");
372 case 'F': /* Undocumented magic Dangerously Dedicated mode */
373 #if defined(__alpha__) || defined(__sparc64__)
375 #else /* The rest is only relevant on x86 */
376 cp = variable_get(VAR_DEDICATE_DISK);
377 if (cp && !strcasecmp(cp, "always"))
379 else if (toupper(key) == 'A')
382 rv = msgYesNo("Do you want to do this with a true partition entry\n"
383 "so as to remain cooperative with any future possible\n"
384 "operating systems on the drive(s)?\n"
385 "(See also the section about ``dangerously dedicated''\n"
386 "disks in the FreeBSD FAQ.)");
392 variable_set2(DISK_PARTITIONED, "yes", 0);
398 if (chunk_info[current_chunk]->type != unused)
399 msg = "Slice in use, delete it first or move to an unused one.";
401 char *val, tmp[20], *cp;
406 snprintf(name, 16, "%s", "FreeBSD");
407 val = msgGetInput(name,
408 "Please specify the name for new FreeBSD slice.");
410 strncpy(name, val, 16);
413 chunk_e partitiontype;
415 snprintf(tmp, 20, "%lu", chunk_info[current_chunk]->size);
416 val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
417 "or append a trailing `M' for megabytes (e.g. 20M).");
418 if (val && (size = strtol(val, &cp, 0)) > 0) {
419 if (*cp && toupper(*cp) == 'M')
421 else if (*cp && toupper(*cp) == 'G')
424 Create_Chunk(d, chunk_info[current_chunk]->offset, size,
426 (chunk_info[current_chunk]->flags & CHUNK_ALIGN),
428 variable_set2(DISK_PARTITIONED, "yes", 0);
431 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
432 val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
433 "Pressing Enter will choose the default, a native FreeBSD\n"
434 "slice (type 165). You can choose other types, 6 for a\n"
435 "DOS partition or 131 for a Linux partition, for example.\n\n"
436 "Note: If you choose a non-FreeBSD partition type, it will not\n"
437 "be formatted or otherwise prepared, it will simply reserve space\n"
438 "for you to use another tool, such as DOS FORMAT, to later format\n"
439 "and use the partition.");
440 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
441 if (subtype == SUBTYPE_FREEBSD)
442 partitiontype = freebsd;
443 else if (subtype == SUBTYPE_FAT)
446 partitiontype = unknown;
447 #if defined(__alpha__) || defined(__sparc64__)
448 if (partitiontype == freebsd && size == chunk_info[current_chunk]->size)
452 Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
453 (chunk_info[current_chunk]->flags & CHUNK_ALIGN), "");
454 variable_set2(DISK_PARTITIONED, "yes", 0);
465 if (chunk_info[current_chunk]->type == unused)
466 msg = "Slice is already unused!";
468 Delete_Chunk(d, chunk_info[current_chunk]);
469 variable_set2(DISK_PARTITIONED, "yes", 0);
475 if (chunk_info[current_chunk]->type == unused)
476 msg = "Slice is currently unused (use create instead)";
480 chunk_e partitiontype;
482 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
484 val = msgGetInput(tmp, "New partition type:\n\n"
485 "Pressing Enter will choose the default, a native FreeBSD\n"
486 "slice (type 50324). Other popular values are 37218 for\n"
487 "DOS FAT partition.\n\n"
488 "Note: If you choose a non-FreeBSD partition type, it will not\n"
489 "be formatted or otherwise prepared, it will simply reserve space\n"
490 "for you to use another tool, such as DOS format, to later format\n"
491 "and actually use the partition.");
493 val = msgGetInput(tmp, "New partition type:\n\n"
494 "Pressing Enter will choose the default, a native FreeBSD\n"
495 "slice (type 165). Other popular values are 6 for\n"
496 "DOS FAT partition, 131 for a Linux ext2fs partition or\n"
497 "130 for a Linux swap partition.\n\n"
498 "Note: If you choose a non-FreeBSD partition type, it will not\n"
499 "be formatted or otherwise prepared, it will simply reserve space\n"
500 "for you to use another tool, such as DOS format, to later format\n"
501 "and actually use the partition.");
503 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
504 if (subtype == SUBTYPE_FREEBSD)
505 partitiontype = freebsd;
506 else if (subtype == SUBTYPE_FAT)
509 partitiontype = unknown;
510 chunk_info[current_chunk]->type = partitiontype;
511 chunk_info[current_chunk]->subtype = subtype;
517 snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
518 val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
519 "Don't forget to use the two slash (/) separator characters!\n"
520 "It's not possible to parse the field without them.");
523 nc = strtol(val, &val, 0);
524 nh = strtol(val + 1, &val, 0);
525 ns = strtol(val + 1, 0, 0);
526 Set_Bios_Geom(d, nc, nh, ns);
533 chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
537 if (!variable_cmp(DISK_LABELLED, "written")) {
538 msgConfirm("You've already written this information out - you\n"
541 else if (!msgNoYes("Are you SURE you want to Undo everything?")) {
544 sstrncpy(cp, d->name, sizeof cp);
545 Free_Disk(dev->private);
548 msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", cp);
550 variable_unset(DISK_PARTITIONED);
551 variable_unset(DISK_LABELLED);
559 if (!msgNoYes("WARNING: This should only be used when modifying an EXISTING\n"
560 "installation. If you are installing FreeBSD for the first time\n"
561 "then you should simply type Q when you're finished here and your\n"
562 "changes will be committed in one batch automatically at the end of\n"
563 "these questions. If you're adding a disk, you should NOT write\n"
564 "from this screen, you should do it from the label editor.\n\n"
565 "Are you absolutely sure you want to do this now?")) {
566 variable_set2(DISK_PARTITIONED, "yes", 0);
569 * Don't trash the MBR if the first (and therefore only) chunk
570 * is marked for a truly dedicated disk (i.e., the disklabel
571 * starts at sector 0), even in cases where the user has
572 * requested booteasy or a "standard" MBR -- both would be
573 * fatal in this case.
576 * Don't offer to update the MBR on this disk if the first
577 * "real" chunk looks like a FreeBSD "all disk" partition,
578 * or the disk is entirely FreeBSD.
581 if ((d->chunks->part->type != freebsd) ||
582 (d->chunks->part->offset > 1))
583 getBootMgr(d->name, &bootipl, &bootipl_size,
584 &bootmenu, &bootmenu_size);
591 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
593 if ((d->chunks->part->type != freebsd) ||
594 (d->chunks->part->offset > 1))
595 getBootMgr(d->name, &mbrContents, &mbrSize);
600 Set_Boot_Mgr(d, mbrContents, mbrSize);
603 if (DITEM_STATUS(diskPartitionWrite(NULL)) != DITEM_SUCCESS)
604 msgConfirm("Disk partition write returned an error status!");
606 msgConfirm("Wrote FDISK partition information out successfully.");
612 if (!msgNoYes("Are you SURE you want to go into Wizard mode?\n"
613 "No seat belts whatsoever are provided!")) {
617 variable_set2(DISK_PARTITIONED, "yes", 0);
621 msg = "Wise choice!";
625 case '\033': /* ESC */
629 * Don't trash the MBR if the first (and therefore only) chunk
630 * is marked for a truly dedicated disk (i.e., the disklabel
631 * starts at sector 0), even in cases where the user has requested
632 * booteasy or a "standard" MBR -- both would be fatal in this case.
635 * Don't offer to update the MBR on this disk if the first "real"
636 * chunk looks like a FreeBSD "all disk" partition, or the disk is
639 if ((d->chunks->part->type != freebsd) ||
640 (d->chunks->part->offset > 1)) {
641 if (variable_cmp(DISK_PARTITIONED, "written")) {
643 getBootMgr(d->name, &bootipl, &bootipl_size,
644 &bootmenu, &bootmenu_size);
645 if (bootipl != NULL && bootmenu != NULL)
646 Set_Boot_Mgr(d, bootipl, bootipl_size,
647 bootmenu, bootmenu_size);
649 getBootMgr(d->name, &mbrContents, &mbrSize);
650 if (mbrContents != NULL)
651 Set_Boot_Mgr(d, mbrContents, mbrSize);
658 size_unit = (size_unit + 1) % UNIT_SIZE;
663 msg = "Type F1 or ? for help";
669 char buf[FILENAME_MAX];
671 use_helpline("Press F1 to read more about disk slices.");
672 use_helpfile(systemHelpFile("partition", buf));
673 if (!variable_get(VAR_NO_WARN))
674 dialog_mesgbox("Disk slicing warning:", p, -1, -1);
681 bootalloc(char *name, size_t *size)
683 char buf[FILENAME_MAX];
686 snprintf(buf, sizeof buf, "/boot/%s", name);
687 if (stat(buf, &sb) != -1) {
690 fd = open(buf, O_RDONLY);
694 cp = malloc(sb.st_size);
695 if (read(fd, cp, sb.st_size) != sb.st_size) {
698 msgDebug("bootalloc: couldn't read %ld bytes from %s\n", (long)sb.st_size, buf);
706 msgDebug("bootalloc: couldn't open %s\n", buf);
709 msgDebug("bootalloc: can't stat %s\n", buf);
714 partitionHook(dialogMenuItem *selected)
716 Device **devs = NULL;
718 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
720 msgConfirm("Unable to find disk %s!", selected->prompt);
721 return DITEM_FAILURE;
723 /* Toggle enabled status? */
724 if (!devs[0]->enabled) {
725 devs[0]->enabled = TRUE;
726 diskPartition(devs[0]);
729 devs[0]->enabled = FALSE;
730 return DITEM_SUCCESS;
734 partitionCheck(dialogMenuItem *selected)
736 Device **devs = NULL;
738 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
739 if (!devs || devs[0]->enabled == FALSE)
745 diskPartitionEditor(dialogMenuItem *self)
751 cnt = diskGetSelectCount(&devs);
752 devcnt = deviceCount(devs);
754 msgConfirm("No disks found! Please verify that your disk controller is being\n"
755 "properly probed at boot time. See the Hardware Guide on the\n"
756 "Documentation menu for clues on diagnosing this type of problem.");
757 return DITEM_FAILURE;
760 /* Some are already selected */
761 for (i = 0; i < devcnt; i++) {
762 if (devs[i]->enabled) {
763 if (variable_get(VAR_NONINTERACTIVE) &&
764 !variable_get(VAR_DISKINTERACTIVE))
765 diskPartitionNonInteractive(devs[i]);
767 diskPartition(devs[i]);
772 /* No disks are selected, fall-back case now */
774 devs[0]->enabled = TRUE;
775 if (variable_get(VAR_NONINTERACTIVE) &&
776 !variable_get(VAR_DISKINTERACTIVE))
777 diskPartitionNonInteractive(devs[0]);
779 diskPartition(devs[0]);
780 return DITEM_SUCCESS;
783 menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook, partitionCheck);
785 msgConfirm("No devices suitable for installation found!\n\n"
786 "Please verify that your disk controller (and attached drives)\n"
787 "were detected properly. This can be done by pressing the\n"
788 "[Scroll Lock] key and using the Arrow keys to move back to\n"
789 "the boot messages. Press [Scroll Lock] again to return.");
790 return DITEM_FAILURE;
793 i = dmenuOpenSimple(menu, FALSE) ? DITEM_SUCCESS : DITEM_FAILURE;
799 return DITEM_SUCCESS;
803 diskPartitionWrite(dialogMenuItem *self)
808 if (!variable_cmp(DISK_PARTITIONED, "written"))
809 return DITEM_SUCCESS;
811 devs = deviceFind(NULL, DEVICE_TYPE_DISK);
813 msgConfirm("Unable to find any disks to write to??");
814 return DITEM_FAILURE;
817 msgDebug("diskPartitionWrite: Examining %d devices\n", deviceCount(devs));
818 for (i = 0; devs[i]; i++) {
819 Disk *d = (Disk *)devs[i]->private;
820 static u_char *boot1;
821 #if defined(__i386__) || defined(__ia64__)
822 static u_char *boot2;
825 if (!devs[i]->enabled)
828 #if defined(__i386__) || defined(__ia64__)
829 if (!boot1) boot1 = bootalloc("boot1", NULL);
830 if (!boot2) boot2 = bootalloc("boot2", NULL);
831 Set_Boot_Blocks(d, boot1, boot2);
833 if (!boot1) boot1 = bootalloc("boot1", NULL);
834 Set_Boot_Blocks(d, boot1, NULL);
837 msgNotify("Writing partition information to drive %s", d->name);
838 if (!Fake && Write_Disk(d)) {
839 msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
840 return DITEM_FAILURE;
843 /* Now it's not "yes", but "written" */
844 variable_set2(DISK_PARTITIONED, "written", 0);
845 return DITEM_SUCCESS | DITEM_RESTORE;
848 /* Partition a disk based wholly on which variables are set */
850 diskPartitionNonInteractive(Device *dev)
853 int i, sz, all_disk = 0;
858 size_t bootmenu_size;
863 Disk *d = (Disk *)dev->private;
866 cp = variable_get(VAR_GEOMETRY);
868 msgDebug("Setting geometry from script to: %s\n", cp);
869 d->bios_cyl = strtol(cp, &cp, 0);
870 d->bios_hd = strtol(cp + 1, &cp, 0);
871 d->bios_sect = strtol(cp + 1, 0, 0);
874 cp = variable_get(VAR_PARTITION);
876 if (!strcmp(cp, "free")) {
877 /* Do free disk space case */
878 for (i = 0; chunk_info[i]; i++) {
879 /* If a chunk is at least 10MB in size, use it. */
880 if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
881 Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size,
883 (chunk_info[i]->flags & CHUNK_ALIGN),
885 variable_set2(DISK_PARTITIONED, "yes", 0);
889 if (!chunk_info[i]) {
890 msgConfirm("Unable to find any free space on this disk!");
894 else if (!strcmp(cp, "all")) {
895 /* Do all disk space case */
896 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
898 All_FreeBSD(d, FALSE);
900 else if (!strcmp(cp, "exclusive")) {
901 /* Do really-all-the-disk-space case */
902 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
904 All_FreeBSD(d, all_disk = TRUE);
906 else if ((sz = strtol(cp, &cp, 0))) {
907 /* Look for sz bytes free */
908 if (*cp && toupper(*cp) == 'M')
910 else if (*cp && toupper(*cp) == 'G')
912 for (i = 0; chunk_info[i]; i++) {
913 /* If a chunk is at least sz MB, use it. */
914 if (chunk_info[i]->type == unused && chunk_info[i]->size >= sz) {
915 Create_Chunk(d, chunk_info[i]->offset, sz, freebsd, 3,
916 (chunk_info[i]->flags & CHUNK_ALIGN),
918 variable_set2(DISK_PARTITIONED, "yes", 0);
922 if (!chunk_info[i]) {
923 msgConfirm("Unable to find %d free blocks on this disk!", sz);
927 else if (!strcmp(cp, "existing")) {
928 /* Do existing FreeBSD case */
929 for (i = 0; chunk_info[i]; i++) {
930 if (chunk_info[i]->type == freebsd)
933 if (!chunk_info[i]) {
934 msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
939 msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
944 getBootMgr(d->name, &bootipl, &bootipl_size,
945 &bootmenu, &bootmenu_size);
946 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
948 getBootMgr(d->name, &mbrContents, &mbrSize);
949 Set_Boot_Mgr(d, mbrContents, mbrSize);
952 variable_set2(DISK_PARTITIONED, "yes", 0);