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"
43 #include <sys/disklabel.h>
46 enum size_units_t { UNIT_BLOCKS, UNIT_KILO, UNIT_MEG, UNIT_GIG, UNIT_SIZE };
49 #define SUBTYPE_FREEBSD 50324
50 #define SUBTYPE_FAT 37218
52 #define SUBTYPE_FREEBSD 165
55 #define SUBTYPE_EFI 239
58 #define OTHER_SLICE_VALUES \
59 "Other popular values are 37218 for a\n" \
60 "DOS FAT partition.\n\n"
62 #define OTHER_SLICE_VALUES \
63 "Other popular values are 6 for a\n" \
64 "DOS FAT partition, 131 for a Linux ext2fs partition, or\n" \
65 "130 for a Linux swap partition.\n\n"
67 #define NON_FREEBSD_NOTE \
68 "Note: If you choose a non-FreeBSD partition type, it will not\n" \
69 "be formatted or otherwise prepared, it will simply reserve space\n" \
70 "for you to use another tool, such as DOS format, to later format\n" \
71 "and actually use the partition."
73 /* Where we start displaying chunk information on the screen */
74 #define CHUNK_START_ROW 5
76 /* Where we keep track of MBR chunks */
77 #define CHUNK_INFO_ENTRIES 16
78 static struct chunk *chunk_info[CHUNK_INFO_ENTRIES];
79 static int current_chunk;
81 static void diskPartitionNonInteractive(Device *dev);
82 static u_char * bootalloc(char *name, size_t *size);
85 record_chunks(Disk *d)
87 struct chunk *c1 = NULL;
89 daddr_t last_free = 0;
92 msgFatal("No chunk list found for %s!", d->name);
94 for (c1 = d->chunks->part; c1; c1 = c1->next) {
95 if (c1->type == unused && c1->size > last_free) {
101 chunk_info[i] = NULL;
102 if (current_chunk >= i)
103 current_chunk = i - 1;
106 static daddr_t Total;
109 check_geometry(Disk *d)
114 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
116 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
119 dialog_clear_norefresh();
120 sg = msgYesNo("WARNING: It is safe to use a geometry of %lu/%lu/%lu for %s on\n"
121 "computers with modern BIOS versions. If this disk is to be used\n"
122 "on an old machine it is recommended that it does not have more\n"
123 "than 65535 cylinders, more than 255 heads, or more than\n"
129 " sectors per track.\n"
131 "Would you like to keep using the current geometry?\n",
132 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
134 Sanitize_Bios_Geom(d);
135 msgConfirm("A geometry of %lu/%lu/%lu was calculated for %s.\n"
137 "If you are not sure about this, please consult the Hardware Guide\n"
138 "in the Documentation submenu or use the (G)eometry command to\n"
139 "change it. Remember: you need to enter whatever your BIOS thinks\n"
140 "the geometry is! For IDE, it's what you were told in the BIOS\n"
141 "setup. For SCSI, it's the translation mode your controller is\n"
142 "using. Do NOT use a ``physical geometry''.\n",
143 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
149 print_chunks(Disk *d, int u)
156 szstr = (u == UNIT_GIG ? "GB" : (u == UNIT_MEG ? "MB" :
157 (u == UNIT_KILO ? "KB" : "ST")));
160 for (i = 0; chunk_info[i]; i++)
161 Total += chunk_info[i]->size;
163 mvaddstr(0, 0, "Disk name:\t");
165 attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL);
166 attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL);
168 "DISK Geometry:\t%lu cyls/%lu heads/%lu sectors = %jd sectors (%jdMB)",
169 d->bios_cyl, d->bios_hd, d->bios_sect,
170 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect,
171 (intmax_t)d->bios_cyl * d->bios_hd * d->bios_sect / (1024/512) / 1024);
172 mvprintw(3, 0, "%6s %10s(%s) %10s %8s %6s %10s %8s %8s",
173 "Offset", "Size", szstr, "End", "Name", "PType", "Desc",
175 for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) {
177 default: /* fall thru */
179 sz = chunk_info[i]->size;
182 sz = chunk_info[i]->size / (1024/512);
185 sz = chunk_info[i]->size / (1024/512) / 1024;
188 sz = chunk_info[i]->size / (1024/512) / 1024 / 1024;
191 if (i == current_chunk)
192 attrset(ATTR_SELECTED);
193 mvprintw(row, 0, "%10jd %10jd %10jd %8s %6d %10s %8d\t%-6s",
194 (intmax_t)chunk_info[i]->offset, (intmax_t)sz,
195 (intmax_t)chunk_info[i]->end, chunk_info[i]->name,
197 slice_type_name(chunk_info[i]->type, chunk_info[i]->subtype),
198 chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i]));
199 if (i == current_chunk)
205 print_command_summary(void)
207 mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
208 mvprintw(16, 0, "A = Use Entire Disk G = set Drive Geometry C = Create Slice");
209 mvprintw(17, 0, "D = Delete Slice Z = Toggle Size Units S = Set Bootable | = Expert m.");
210 mvprintw(18, 0, "T = Change Type U = Undo All Changes");
213 mvprintw(18, 47, "W = Write Changes Q = Finish");
215 mvprintw(18, 47, "Q = Finish");
216 mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
222 getBootMgr(char *dname, u_char **bootipl, size_t *bootipl_size,
223 u_char **bootmenu, size_t *bootmenu_size)
225 static u_char *boot0;
226 static size_t boot0_size;
227 static u_char *boot05;
228 static size_t boot05_size;
234 cp = variable_get(VAR_BOOTMGR);
236 /* Figure out what kind of IPL the user wants */
237 sprintf(str, "Install Boot Manager for drive %s?", dname);
238 MenuIPLType.title = str;
239 i = dmenuOpenSimple(&MenuIPLType, FALSE);
241 if (!strncmp(cp, "boot", 4))
249 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
251 *bootipl_size = boot0_size;
252 if (!boot05) boot05 = bootalloc("boot0.5", &boot05_size);
254 *bootmenu_size = boot05_size;
268 getBootMgr(char *dname, u_char **bootCode, size_t *bootCodeSize)
270 #if defined(__i386__) || defined(__amd64__) /* only meaningful on x86 */
271 static u_char *mbr, *boot0;
272 static size_t mbr_size, boot0_size;
277 cp = variable_get(VAR_BOOTMGR);
279 /* Figure out what kind of MBR the user wants */
280 sprintf(str, "Install Boot Manager for drive %s?", dname);
281 MenuMBRType.title = str;
282 i = dmenuOpenSimple(&MenuMBRType, FALSE);
285 if (!strncmp(cp, "boot", 4))
287 else if (!strcmp(cp, "standard"))
295 if (!boot0) boot0 = bootalloc("boot0", &boot0_size);
297 *bootCodeSize = boot0_size;
300 if (!mbr) mbr = bootalloc("mbr", &mbr_size);
302 *bootCodeSize = mbr_size;
314 #endif /* WITH_SLICES */
317 diskGetSelectCount(Device ***devs)
323 cp = variable_get(VAR_DISK);
324 dp = *devs = deviceFind(cp, DEVICE_TYPE_DISK);
325 cnt = deviceCount(dp);
328 for (i = 0, enabled = 0; i < cnt; i++) {
337 diskPartition(Device *dev)
348 size_t bootmenu_size;
353 WINDOW *w = savescr();
354 Disk *d = (Disk *)dev->private;
357 size_unit = UNIT_BLOCKS;
359 keypad(stdscr, TRUE);
361 /* Flush both the dialog and curses library views of the screen
362 since we don't always know who called us */
363 dialog_clear_norefresh(), clear();
366 /* Set up the chunk array */
369 /* Give the user a chance to sanitize the disk geometry, if necessary */
373 char *val, geometry[80];
375 /* Now print our overall state */
377 print_chunks(d, size_unit);
378 print_command_summary();
380 attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
389 /* Get command character */
391 switch (toupper(key)) {
392 case '\014': /* ^L (redraw) */
397 case '\020': /* ^P */
400 if (current_chunk != 0)
404 case '\016': /* ^N */
409 if (chunk_info[current_chunk + 1])
418 while (chunk_info[current_chunk + 1])
424 systemDisplayHelp("slice");
429 #if !defined(__i386__) && !defined(__amd64__)
431 #else /* The rest is only relevant on x86 */
435 variable_set2(DISK_PARTITIONED, "yes", 0);
441 if (chunk_info[current_chunk]->type != unused)
442 msg = "Slice in use, delete it first or move to an unused one.";
444 char *val, tmp[20], name[16], *cp;
448 chunk_e partitiontype;
450 snprintf(name, sizeof (name), "%s", "FreeBSD");
451 val = msgGetInput(name,
452 "Please specify the name for new FreeBSD slice.");
454 strncpy(name, val, sizeof (name));
458 snprintf(tmp, 20, "%jd", (intmax_t)chunk_info[current_chunk]->size);
459 val = msgGetInput(tmp, "Please specify the size for new FreeBSD slice in blocks\n"
460 "or append a trailing `M' for megabytes (e.g. 20M).");
461 if (val && (dsize = strtold(val, &cp)) > 0 && dsize < UINT32_MAX) {
462 if (*cp && toupper(*cp) == 'M')
463 size = (daddr_t) (dsize * ONE_MEG);
464 else if (*cp && toupper(*cp) == 'G')
465 size = (daddr_t) (dsize * ONE_GIG);
467 size = (daddr_t) dsize;
469 if (size < ONE_MEG) {
470 msgConfirm("The minimum slice size is 1MB");
475 sprintf(tmp, "%d", SUBTYPE_FREEBSD);
476 val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
477 "Pressing Enter will choose the default, a native FreeBSD\n"
480 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
481 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
482 if (subtype == SUBTYPE_FREEBSD)
483 partitiontype = freebsd;
484 else if (subtype == SUBTYPE_FAT)
486 else if (subtype == SUBTYPE_EFI)
490 partitiontype = pc98;
494 Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
495 (chunk_info[current_chunk]->flags & CHUNK_ALIGN), name);
496 variable_set2(DISK_PARTITIONED, "yes", 0);
506 if (chunk_info[current_chunk]->type == unused)
507 msg = "Slice is already unused!";
509 Delete_Chunk(d, chunk_info[current_chunk]);
510 variable_set2(DISK_PARTITIONED, "yes", 0);
516 if (chunk_info[current_chunk]->type == unused)
517 msg = "Slice is currently unused (use create instead)";
521 chunk_e partitiontype;
523 sprintf(tmp, "%d", chunk_info[current_chunk]->subtype);
524 val = msgGetInput(tmp, "New partition type:\n\n"
525 "Pressing Enter will use the current type. To choose a native\n"
526 "FreeBSD slice enter %u. "
528 NON_FREEBSD_NOTE, SUBTYPE_FREEBSD);
529 if (val && (subtype = strtol(val, NULL, 0)) > 0) {
530 if (subtype == SUBTYPE_FREEBSD)
531 partitiontype = freebsd;
532 else if (subtype == SUBTYPE_FAT)
534 else if (subtype == SUBTYPE_EFI)
538 partitiontype = pc98;
542 chunk_info[current_chunk]->type = partitiontype;
543 chunk_info[current_chunk]->subtype = subtype;
549 snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
550 val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
551 "Don't forget to use the two slash (/) separator characters!\n"
552 "It's not possible to parse the field without them.");
555 nc = strtol(val, &val, 0);
556 nh = strtol(val + 1, &val, 0);
557 ns = strtol(val + 1, 0, 0);
558 Set_Bios_Geom(d, nc, nh, ns);
564 /* Clear active states so we won't have two */
565 for (i = 0; (chunk_info[i] != NULL) && (i < CHUNK_INFO_ENTRIES); i++)
566 chunk_info[i]->flags &= !CHUNK_ACTIVE;
569 chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
573 if (!variable_cmp(DISK_LABELLED, "written")) {
574 msgConfirm("You've already written this information out - you\n"
577 else if (!msgNoYes("Are you SURE you want to Undo everything?")) {
580 sstrncpy(cp, d->name, sizeof cp);
581 Free_Disk(dev->private);
584 msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", cp);
586 variable_unset(DISK_PARTITIONED);
587 variable_unset(DISK_LABELLED);
595 if (!msgNoYes("WARNING: This should only be used when modifying an EXISTING\n"
596 "installation. If you are installing FreeBSD for the first time\n"
597 "then you should simply type Q when you're finished here and your\n"
598 "changes will be committed in one batch automatically at the end of\n"
599 "these questions. If you're adding a disk, you should NOT write\n"
600 "from this screen, you should do it from the label editor.\n\n"
601 "Are you absolutely sure you want to do this now?")) {
602 variable_set2(DISK_PARTITIONED, "yes", 0);
606 * Don't trash the IPL if the first (and therefore only) chunk
607 * is marked for a truly dedicated disk (i.e., the disklabel
608 * starts at sector 0), even in cases where the user has
609 * requested a FreeBSD Boot Manager -- both would be fatal in
613 * Don't offer to update the IPL on this disk if the first
614 * "real" chunk looks like a FreeBSD "all disk" partition,
615 * or the disk is entirely FreeBSD.
617 if ((d->chunks->part->type != freebsd) ||
618 (d->chunks->part->offset > 1))
619 getBootMgr(d->name, &bootipl, &bootipl_size,
620 &bootmenu, &bootmenu_size);
627 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
630 * Don't trash the MBR if the first (and therefore only) chunk
631 * is marked for a truly dedicated disk (i.e., the disklabel
632 * starts at sector 0), even in cases where the user has
633 * requested booteasy or a "standard" MBR -- both would be
634 * fatal in this case.
637 * Don't offer to update the MBR on this disk if the first
638 * "real" chunk looks like a FreeBSD "all disk" partition,
639 * or the disk is entirely FreeBSD.
641 if ((d->chunks->part->type != freebsd) ||
642 (d->chunks->part->offset > 1))
643 getBootMgr(d->name, &mbrContents, &mbrSize);
648 Set_Boot_Mgr(d, mbrContents, mbrSize);
651 if (DITEM_STATUS(diskPartitionWrite(NULL)) != DITEM_SUCCESS)
652 msgConfirm("Disk partition write returned an error status!");
654 msgConfirm("Wrote FDISK partition information out successfully.");
660 if (!msgNoYes("Are you SURE you want to go into Expert mode?\n"
661 "No seat belts whatsoever are provided!")) {
665 variable_set2(DISK_PARTITIONED, "yes", 0);
669 msg = "Wise choice!";
673 case '\033': /* ESC */
678 * Don't trash the IPL if the first (and therefore only) chunk
679 * is marked for a truly dedicated disk (i.e., the disklabel
680 * starts at sector 0), even in cases where the user has requested
681 * a FreeBSD Boot Manager -- both would be fatal in this case.
684 * Don't offer to update the IPL on this disk if the first "real"
685 * chunk looks like a FreeBSD "all disk" partition, or the disk is
688 if ((d->chunks->part->type != freebsd) ||
689 (d->chunks->part->offset > 1)) {
690 if (variable_cmp(DISK_PARTITIONED, "written")) {
691 getBootMgr(d->name, &bootipl, &bootipl_size,
692 &bootmenu, &bootmenu_size);
693 if (bootipl != NULL && bootmenu != NULL)
694 Set_Boot_Mgr(d, bootipl, bootipl_size,
695 bootmenu, bootmenu_size);
700 * Don't trash the MBR if the first (and therefore only) chunk
701 * is marked for a truly dedicated disk (i.e., the disklabel
702 * starts at sector 0), even in cases where the user has requested
703 * booteasy or a "standard" MBR -- both would be fatal in this case.
706 * Don't offer to update the MBR on this disk if the first "real"
707 * chunk looks like a FreeBSD "all disk" partition, or the disk is
710 if ((d->chunks->part->type != freebsd) ||
711 (d->chunks->part->offset > 1)) {
712 if (variable_cmp(DISK_PARTITIONED, "written")) {
713 getBootMgr(d->name, &mbrContents, &mbrSize);
714 if (mbrContents != NULL)
715 Set_Boot_Mgr(d, mbrContents, mbrSize);
722 size_unit = (size_unit + 1) % UNIT_SIZE;
727 msg = "Type F1 or ? for help";
733 char buf[FILENAME_MAX];
735 use_helpline("Press F1 to read more about disk slices.");
736 use_helpfile(systemHelpFile("partition", buf));
737 if (!variable_get(VAR_NO_WARN))
738 dialog_mesgbox("Disk slicing warning:", p, -1, -1);
743 #endif /* WITH_SLICES */
746 bootalloc(char *name, size_t *size)
748 char buf[FILENAME_MAX];
751 snprintf(buf, sizeof buf, "/boot/%s", name);
752 if (stat(buf, &sb) != -1) {
755 fd = open(buf, O_RDONLY);
759 cp = malloc(sb.st_size);
760 if (read(fd, cp, sb.st_size) != sb.st_size) {
763 msgDebug("bootalloc: couldn't read %ld bytes from %s\n", (long)sb.st_size, buf);
771 msgDebug("bootalloc: couldn't open %s\n", buf);
774 msgDebug("bootalloc: can't stat %s\n", buf);
780 partitionHook(dialogMenuItem *selected)
782 Device **devs = NULL;
784 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
786 msgConfirm("Unable to find disk %s!", selected->prompt);
787 return DITEM_FAILURE;
789 /* Toggle enabled status? */
790 if (!devs[0]->enabled) {
791 devs[0]->enabled = TRUE;
792 diskPartition(devs[0]);
795 devs[0]->enabled = FALSE;
796 return DITEM_SUCCESS;
800 partitionCheck(dialogMenuItem *selected)
802 Device **devs = NULL;
804 devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
805 if (!devs || devs[0]->enabled == FALSE)
811 diskPartitionEditor(dialogMenuItem *self)
817 cnt = diskGetSelectCount(&devs);
818 devcnt = deviceCount(devs);
820 msgConfirm("No disks found! Please verify that your disk controller is being\n"
821 "properly probed at boot time. See the Hardware Guide on the\n"
822 "Documentation menu for clues on diagnosing this type of problem.");
823 return DITEM_FAILURE;
826 /* Some are already selected */
827 for (i = 0; i < devcnt; i++) {
828 if (devs[i]->enabled) {
829 if (variable_get(VAR_NONINTERACTIVE) &&
830 !variable_get(VAR_DISKINTERACTIVE))
831 diskPartitionNonInteractive(devs[i]);
833 diskPartition(devs[i]);
838 /* No disks are selected, fall-back case now */
840 devs[0]->enabled = TRUE;
841 if (variable_get(VAR_NONINTERACTIVE) &&
842 !variable_get(VAR_DISKINTERACTIVE))
843 diskPartitionNonInteractive(devs[0]);
845 diskPartition(devs[0]);
846 return DITEM_SUCCESS;
849 menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook, partitionCheck);
851 msgConfirm("No devices suitable for installation found!\n\n"
852 "Please verify that your disk controller (and attached drives)\n"
853 "were detected properly. This can be done by pressing the\n"
854 "[Scroll Lock] key and using the Arrow keys to move back to\n"
855 "the boot messages. Press [Scroll Lock] again to return.");
856 return DITEM_FAILURE;
859 i = dmenuOpenSimple(menu, FALSE) ? DITEM_SUCCESS : DITEM_FAILURE;
865 return DITEM_SUCCESS;
867 #endif /* WITH_SLICES */
870 diskPartitionWrite(dialogMenuItem *self)
875 if (!variable_cmp(DISK_PARTITIONED, "written"))
876 return DITEM_SUCCESS;
878 devs = deviceFind(NULL, DEVICE_TYPE_DISK);
880 msgConfirm("Unable to find any disks to write to??");
881 return DITEM_FAILURE;
884 msgDebug("diskPartitionWrite: Examining %d devices\n", deviceCount(devs));
885 for (i = 0; devs[i]; i++) {
886 Disk *d = (Disk *)devs[i]->private;
887 static u_char *boot1;
888 #if defined(__i386__) || defined(__amd64__)
889 static u_char *boot2;
892 if (!devs[i]->enabled)
895 #if defined(__i386__) || defined(__amd64__)
896 if (!boot1) boot1 = bootalloc("boot1", NULL);
897 if (!boot2) boot2 = bootalloc("boot2", NULL);
898 Set_Boot_Blocks(d, boot1, boot2);
899 #elif !defined(__ia64__)
900 if (!boot1) boot1 = bootalloc("boot1", NULL);
901 Set_Boot_Blocks(d, boot1, NULL);
904 msgNotify("Writing partition information to drive %s", d->name);
905 if (!Fake && Write_Disk(d)) {
907 msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
909 msgConfirm("ERROR: Unable to write data to disk %s!\n\n"
910 "To edit the labels on a running system set\n"
911 "sysctl kern.geom.debugflags=16 and try again.", d->name);
913 return DITEM_FAILURE;
916 /* Now it's not "yes", but "written" */
917 variable_set2(DISK_PARTITIONED, "written", 0);
918 return DITEM_SUCCESS | DITEM_RESTORE;
922 /* Partition a disk based wholly on which variables are set */
924 diskPartitionNonInteractive(Device *dev)
934 size_t bootmenu_size;
939 Disk *d = (Disk *)dev->private;
942 cp = variable_get(VAR_GEOMETRY);
944 if (!strcasecmp(cp, "sane")) {
946 if (d->bios_cyl >= 65536 || d->bios_hd > 256 || d->bios_sect >= 256)
948 if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64)
951 msgDebug("Warning: A geometry of %lu/%lu/%lu for %s is incorrect.\n",
952 d->bios_cyl, d->bios_hd, d->bios_sect, d->name);
953 Sanitize_Bios_Geom(d);
954 msgDebug("Sanitized geometry for %s is %lu/%lu/%lu.\n",
955 d->name, d->bios_cyl, d->bios_hd, d->bios_sect);
958 msgDebug("Setting geometry from script to: %s\n", cp);
959 d->bios_cyl = strtol(cp, &cp, 0);
960 d->bios_hd = strtol(cp + 1, &cp, 0);
961 d->bios_sect = strtol(cp + 1, 0, 0);
965 cp = variable_get(VAR_PARTITION);
967 if (!strcmp(cp, "free")) {
968 /* Do free disk space case */
969 for (i = 0; chunk_info[i]; i++) {
970 /* If a chunk is at least 10MB in size, use it. */
971 if (chunk_info[i]->type == unused && chunk_info[i]->size > (10 * ONE_MEG)) {
972 Create_Chunk(d, chunk_info[i]->offset, chunk_info[i]->size,
973 freebsd, SUBTYPE_FREEBSD,
974 (chunk_info[i]->flags & CHUNK_ALIGN),
976 variable_set2(DISK_PARTITIONED, "yes", 0);
980 if (!chunk_info[i]) {
981 msgConfirm("Unable to find any free space on this disk!");
985 else if (!strcmp(cp, "all")) {
986 /* Do all disk space case */
987 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
989 All_FreeBSD(d, FALSE);
991 else if (!strcmp(cp, "exclusive")) {
992 /* Do really-all-the-disk-space case */
993 msgDebug("Warning: Devoting all of disk %s to FreeBSD.\n", d->name);
995 All_FreeBSD(d, all_disk = TRUE);
997 else if ((dsize = strtold(cp, &cp))) {
998 if (*cp && toupper(*cp) == 'M')
999 size *= (daddr_t) (dsize * ONE_MEG);
1000 else if (*cp && toupper(*cp) == 'G')
1001 size = (daddr_t) (dsize * ONE_GIG);
1003 size = (daddr_t) dsize;
1005 /* Look for size bytes free */
1006 for (i = 0; chunk_info[i]; i++) {
1007 /* If a chunk is at least sz MB, use it. */
1008 if (chunk_info[i]->type == unused && chunk_info[i]->size >= size) {
1009 Create_Chunk(d, chunk_info[i]->offset, size, freebsd, SUBTYPE_FREEBSD,
1010 (chunk_info[i]->flags & CHUNK_ALIGN),
1012 variable_set2(DISK_PARTITIONED, "yes", 0);
1016 if (!chunk_info[i]) {
1017 msgConfirm("Unable to find %jd free blocks on this disk!",
1022 else if (!strcmp(cp, "existing")) {
1023 /* Do existing FreeBSD case */
1024 for (i = 0; chunk_info[i]; i++) {
1025 if (chunk_info[i]->type == freebsd)
1028 if (!chunk_info[i]) {
1029 msgConfirm("Unable to find any existing FreeBSD partitions on this disk!");
1034 msgConfirm("`%s' is an invalid value for %s - is config file valid?", cp, VAR_PARTITION);
1039 getBootMgr(d->name, &bootipl, &bootipl_size,
1040 &bootmenu, &bootmenu_size);
1041 Set_Boot_Mgr(d, bootipl, bootipl_size, bootmenu, bootmenu_size);
1043 getBootMgr(d->name, &mbrContents, &mbrSize);
1044 Set_Boot_Mgr(d, mbrContents, mbrSize);
1047 variable_set2(DISK_PARTITIONED, "yes", 0);
1050 #endif /* WITH_SLICES */