12118f387SNathan Whitehorn /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 42118f387SNathan Whitehorn * Copyright (c) 2011 Nathan Whitehorn 52118f387SNathan Whitehorn * All rights reserved. 62118f387SNathan Whitehorn * 72118f387SNathan Whitehorn * Redistribution and use in source and binary forms, with or without 82118f387SNathan Whitehorn * modification, are permitted provided that the following conditions 92118f387SNathan Whitehorn * are met: 102118f387SNathan Whitehorn * 1. Redistributions of source code must retain the above copyright 112118f387SNathan Whitehorn * notice, this list of conditions and the following disclaimer. 122118f387SNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright 132118f387SNathan Whitehorn * notice, this list of conditions and the following disclaimer in the 142118f387SNathan Whitehorn * documentation and/or other materials provided with the distribution. 152118f387SNathan Whitehorn * 162118f387SNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 172118f387SNathan Whitehorn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 182118f387SNathan Whitehorn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 192118f387SNathan Whitehorn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 202118f387SNathan Whitehorn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 212118f387SNathan Whitehorn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 222118f387SNathan Whitehorn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 232118f387SNathan Whitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 242118f387SNathan Whitehorn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 252118f387SNathan Whitehorn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 262118f387SNathan Whitehorn * SUCH DAMAGE. 272118f387SNathan Whitehorn */ 282118f387SNathan Whitehorn 292118f387SNathan Whitehorn #include <sys/param.h> 3050e24496SAlfonso S. Siciliano 31d6f6b201SEnji Cooper #include <errno.h> 32d6f6b201SEnji Cooper #include <inttypes.h> 33d6f6b201SEnji Cooper #include <libutil.h> 3450e24496SAlfonso S. Siciliano #include <stdio.h> 3550e24496SAlfonso S. Siciliano #include <stdlib.h> 366e15678aSNathan Whitehorn #include <string.h> 376e15678aSNathan Whitehorn 382118f387SNathan Whitehorn #include <libgeom.h> 3950e24496SAlfonso S. Siciliano #include <bsddialog.h> 402118f387SNathan Whitehorn 412118f387SNathan Whitehorn #include "partedit.h" 422118f387SNathan Whitehorn 432118f387SNathan Whitehorn #define MIN_FREE_SPACE (1024*1024*1024) /* 1 GB */ 442118f387SNathan Whitehorn #define SWAP_SIZE(available) MIN(available/20, 4*1024*1024*1024LL) 452118f387SNathan Whitehorn 462118f387SNathan Whitehorn static char *wizard_partition(struct gmesh *mesh, const char *disk); 472118f387SNathan Whitehorn 482118f387SNathan Whitehorn int 49d547c56fSEnji Cooper part_wizard(const char *fsreq) 50d547c56fSEnji Cooper { 512118f387SNathan Whitehorn char *disk, *schemeroot; 526e15678aSNathan Whitehorn const char *fstype; 53d547c56fSEnji Cooper struct gmesh mesh; 54d547c56fSEnji Cooper int error; 5550e24496SAlfonso S. Siciliano struct bsddialog_conf conf; 5650e24496SAlfonso S. Siciliano 5750e24496SAlfonso S. Siciliano bsddialog_initconf(&conf); 586e15678aSNathan Whitehorn 596e15678aSNathan Whitehorn if (fsreq != NULL) 606e15678aSNathan Whitehorn fstype = fsreq; 616e15678aSNathan Whitehorn else 626e15678aSNathan Whitehorn fstype = "ufs"; 632118f387SNathan Whitehorn 642118f387SNathan Whitehorn startwizard: 652118f387SNathan Whitehorn error = geom_gettree(&mesh); 6623099099SJohn Baldwin if (error != 0) 6723099099SJohn Baldwin return (1); 682118f387SNathan Whitehorn 6950e24496SAlfonso S. Siciliano bsddialog_backtitle(&conf, "FreeBSD Installer"); 705140034cSNathan Whitehorn disk = boot_disk_select(&mesh); 7123099099SJohn Baldwin if (disk == NULL) { 7223099099SJohn Baldwin geom_deletetree(&mesh); 732118f387SNathan Whitehorn return (1); 7423099099SJohn Baldwin } 752118f387SNathan Whitehorn 7661ba55bcSBaptiste Daroussin bsddialog_clear(0); 7750e24496SAlfonso S. Siciliano bsddialog_backtitle(&conf, "FreeBSD Installer"); 782118f387SNathan Whitehorn schemeroot = wizard_partition(&mesh, disk); 792118f387SNathan Whitehorn free(disk); 8023099099SJohn Baldwin geom_deletetree(&mesh); 812118f387SNathan Whitehorn if (schemeroot == NULL) 822118f387SNathan Whitehorn return (1); 832118f387SNathan Whitehorn 8461ba55bcSBaptiste Daroussin bsddialog_clear(0); 8550e24496SAlfonso S. Siciliano bsddialog_backtitle(&conf, "FreeBSD Installer"); 862118f387SNathan Whitehorn error = geom_gettree(&mesh); 8723099099SJohn Baldwin if (error != 0) { 8823099099SJohn Baldwin free(schemeroot); 8923099099SJohn Baldwin return (1); 9023099099SJohn Baldwin } 912118f387SNathan Whitehorn 926e15678aSNathan Whitehorn error = wizard_makeparts(&mesh, schemeroot, fstype, 1); 9323099099SJohn Baldwin free(schemeroot); 9423099099SJohn Baldwin geom_deletetree(&mesh); 952118f387SNathan Whitehorn if (error) 962118f387SNathan Whitehorn goto startwizard; 972118f387SNathan Whitehorn 982118f387SNathan Whitehorn return (0); 992118f387SNathan Whitehorn } 1002118f387SNathan Whitehorn 1015140034cSNathan Whitehorn char * 1025140034cSNathan Whitehorn boot_disk_select(struct gmesh *mesh) 1032118f387SNathan Whitehorn { 1042118f387SNathan Whitehorn struct gclass *classp; 1052118f387SNathan Whitehorn struct gconfig *gc; 1062118f387SNathan Whitehorn struct ggeom *gp; 1072118f387SNathan Whitehorn struct gprovider *pp; 10850e24496SAlfonso S. Siciliano struct bsddialog_menuitem *disks = NULL; 1099636f84bSNathan Whitehorn const char *type, *desc; 1102118f387SNathan Whitehorn char diskdesc[512]; 1112118f387SNathan Whitehorn char *chosen; 1122c4499dcSBrad Davis int i, button, fd, selected, n = 0; 11350e24496SAlfonso S. Siciliano struct bsddialog_conf conf; 11450e24496SAlfonso S. Siciliano 11550e24496SAlfonso S. Siciliano bsddialog_initconf(&conf); 1162118f387SNathan Whitehorn 1172118f387SNathan Whitehorn LIST_FOREACH(classp, &mesh->lg_class, lg_class) { 1182118f387SNathan Whitehorn if (strcmp(classp->lg_name, "DISK") != 0 && 119bcc25b7eSNathan Whitehorn strcmp(classp->lg_name, "RAID") != 0 && 1202118f387SNathan Whitehorn strcmp(classp->lg_name, "MD") != 0) 1212118f387SNathan Whitehorn continue; 1222118f387SNathan Whitehorn 1232118f387SNathan Whitehorn LIST_FOREACH(gp, &classp->lg_geom, lg_geom) { 1242118f387SNathan Whitehorn if (LIST_EMPTY(&gp->lg_provider)) 1252118f387SNathan Whitehorn continue; 1262118f387SNathan Whitehorn 1272118f387SNathan Whitehorn LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { 1289636f84bSNathan Whitehorn desc = type = NULL; 1299636f84bSNathan Whitehorn LIST_FOREACH(gc, &pp->lg_config, lg_config) { 1302118f387SNathan Whitehorn if (strcmp(gc->lg_name, "type") == 0) 1312118f387SNathan Whitehorn type = gc->lg_val; 1329636f84bSNathan Whitehorn if (strcmp(gc->lg_name, "descr") == 0) 1339636f84bSNathan Whitehorn desc = gc->lg_val; 1349636f84bSNathan Whitehorn } 1352118f387SNathan Whitehorn 1369636f84bSNathan Whitehorn /* Skip swap-backed md and WORM devices */ 1372118f387SNathan Whitehorn if (strcmp(classp->lg_name, "MD") == 0 && 1382118f387SNathan Whitehorn type != NULL && strcmp(type, "swap") == 0) 1392118f387SNathan Whitehorn continue; 1409636f84bSNathan Whitehorn if (strncmp(pp->lg_name, "cd", 2) == 0) 1419636f84bSNathan Whitehorn continue; 142964ad27fSBrad Davis /* 143964ad27fSBrad Davis * Check if the disk is available to be opened for 144964ad27fSBrad Davis * write operations, it helps prevent the USB 145964ad27fSBrad Davis * stick used to boot from being listed as an option 146964ad27fSBrad Davis */ 147964ad27fSBrad Davis fd = g_open(pp->lg_name, 1); 148964ad27fSBrad Davis if (fd == -1) { 149964ad27fSBrad Davis continue; 150964ad27fSBrad Davis } 151964ad27fSBrad Davis g_close(fd); 1522118f387SNathan Whitehorn 1532118f387SNathan Whitehorn disks = realloc(disks, (++n)*sizeof(disks[0])); 1542118f387SNathan Whitehorn disks[n-1].name = pp->lg_name; 1552118f387SNathan Whitehorn humanize_number(diskdesc, 7, pp->lg_mediasize, 1562118f387SNathan Whitehorn "B", HN_AUTOSCALE, HN_DECIMAL); 1572118f387SNathan Whitehorn if (strncmp(pp->lg_name, "ad", 2) == 0) 1582118f387SNathan Whitehorn strcat(diskdesc, " ATA Hard Disk"); 1592118f387SNathan Whitehorn else if (strncmp(pp->lg_name, "md", 2) == 0) 1602118f387SNathan Whitehorn strcat(diskdesc, " Memory Disk"); 1619636f84bSNathan Whitehorn else 1629636f84bSNathan Whitehorn strcat(diskdesc, " Disk"); 1639636f84bSNathan Whitehorn 1649636f84bSNathan Whitehorn if (desc != NULL) 1659636f84bSNathan Whitehorn snprintf(diskdesc, sizeof(diskdesc), 1669636f84bSNathan Whitehorn "%s <%s>", diskdesc, desc); 1679636f84bSNathan Whitehorn 16850e24496SAlfonso S. Siciliano disks[n-1].prefix = ""; 16950e24496SAlfonso S. Siciliano disks[n-1].on = false; 17050e24496SAlfonso S. Siciliano disks[n-1].depth = 0; 17150e24496SAlfonso S. Siciliano disks[n-1].desc = strdup(diskdesc); 17250e24496SAlfonso S. Siciliano disks[n-1].bottomdesc = ""; 1732118f387SNathan Whitehorn } 1742118f387SNathan Whitehorn } 1752118f387SNathan Whitehorn } 1762118f387SNathan Whitehorn 1772118f387SNathan Whitehorn if (n > 1) { 17850e24496SAlfonso S. Siciliano conf.title = "Partitioning"; 17950e24496SAlfonso S. Siciliano button = bsddialog_menu(&conf, 180147585b4SBrad Davis "Select the disk on which to install " OSNAME ".", 0, 0, 0, 18150e24496SAlfonso S. Siciliano n, disks, &selected); 1822118f387SNathan Whitehorn 18350e24496SAlfonso S. Siciliano chosen = (button == BSDDIALOG_OK) ? 18450e24496SAlfonso S. Siciliano strdup(disks[selected].name) : NULL; 1852118f387SNathan Whitehorn } else if (n == 1) { 1862118f387SNathan Whitehorn chosen = strdup(disks[0].name); 1872118f387SNathan Whitehorn } else { 1882118f387SNathan Whitehorn chosen = NULL; 1892118f387SNathan Whitehorn } 1902118f387SNathan Whitehorn 1912118f387SNathan Whitehorn for (i = 0; i < n; i++) 19250e24496SAlfonso S. Siciliano free((char*)disks[i].desc); 1932118f387SNathan Whitehorn 1942118f387SNathan Whitehorn return (chosen); 1952118f387SNathan Whitehorn } 1962118f387SNathan Whitehorn 1972118f387SNathan Whitehorn static struct gprovider * 1982118f387SNathan Whitehorn provider_for_name(struct gmesh *mesh, const char *name) 1992118f387SNathan Whitehorn { 2002118f387SNathan Whitehorn struct gclass *classp; 2012118f387SNathan Whitehorn struct gprovider *pp = NULL; 2022118f387SNathan Whitehorn struct ggeom *gp; 2032118f387SNathan Whitehorn 2042118f387SNathan Whitehorn LIST_FOREACH(classp, &mesh->lg_class, lg_class) { 2052118f387SNathan Whitehorn LIST_FOREACH(gp, &classp->lg_geom, lg_geom) { 2062118f387SNathan Whitehorn if (LIST_EMPTY(&gp->lg_provider)) 2072118f387SNathan Whitehorn continue; 2082118f387SNathan Whitehorn 2092118f387SNathan Whitehorn LIST_FOREACH(pp, &gp->lg_provider, lg_provider) 2102118f387SNathan Whitehorn if (strcmp(pp->lg_name, name) == 0) 2112118f387SNathan Whitehorn break; 2122118f387SNathan Whitehorn 2132118f387SNathan Whitehorn if (pp != NULL) break; 2142118f387SNathan Whitehorn } 2152118f387SNathan Whitehorn 2162118f387SNathan Whitehorn if (pp != NULL) break; 2172118f387SNathan Whitehorn } 2182118f387SNathan Whitehorn 2192118f387SNathan Whitehorn return (pp); 2202118f387SNathan Whitehorn } 2212118f387SNathan Whitehorn 2222118f387SNathan Whitehorn static char * 2232118f387SNathan Whitehorn wizard_partition(struct gmesh *mesh, const char *disk) 2242118f387SNathan Whitehorn { 2252118f387SNathan Whitehorn struct gclass *classp; 2262118f387SNathan Whitehorn struct ggeom *gpart = NULL; 2272118f387SNathan Whitehorn struct gconfig *gc; 2282118f387SNathan Whitehorn char *retval = NULL; 229d547c56fSEnji Cooper const char *scheme = NULL; 230d547c56fSEnji Cooper char message[512]; 2312118f387SNathan Whitehorn int choice; 23250e24496SAlfonso S. Siciliano struct bsddialog_conf conf; 23350e24496SAlfonso S. Siciliano 23450e24496SAlfonso S. Siciliano bsddialog_initconf(&conf); 2352118f387SNathan Whitehorn 2362118f387SNathan Whitehorn LIST_FOREACH(classp, &mesh->lg_class, lg_class) 2372118f387SNathan Whitehorn if (strcmp(classp->lg_name, "PART") == 0) 2382118f387SNathan Whitehorn break; 2392118f387SNathan Whitehorn 2402118f387SNathan Whitehorn if (classp != NULL) { 2412118f387SNathan Whitehorn LIST_FOREACH(gpart, &classp->lg_geom, lg_geom) 2422118f387SNathan Whitehorn if (strcmp(gpart->lg_name, disk) == 0) 2432118f387SNathan Whitehorn break; 2442118f387SNathan Whitehorn } 2452118f387SNathan Whitehorn 2462118f387SNathan Whitehorn if (gpart != NULL) { 2472118f387SNathan Whitehorn LIST_FOREACH(gc, &gpart->lg_config, lg_config) { 2482118f387SNathan Whitehorn if (strcmp(gc->lg_name, "scheme") == 0) { 2492118f387SNathan Whitehorn scheme = gc->lg_val; 2502118f387SNathan Whitehorn break; 2512118f387SNathan Whitehorn } 2522118f387SNathan Whitehorn } 2532118f387SNathan Whitehorn } 2542118f387SNathan Whitehorn 255da42677dSNathan Whitehorn /* Treat uncommitted scheme deletions as no scheme */ 256da42677dSNathan Whitehorn if (scheme != NULL && strcmp(scheme, "(none)") == 0) 257da42677dSNathan Whitehorn scheme = NULL; 258da42677dSNathan Whitehorn 2592118f387SNathan Whitehorn query: 26050e24496SAlfonso S. Siciliano conf.button.ok_label = "Entire Disk"; 26150e24496SAlfonso S. Siciliano conf.button.cancel_label = "Partition"; 2622118f387SNathan Whitehorn if (gpart != NULL) 26350e24496SAlfonso S. Siciliano conf.button.default_cancel = true; 2642118f387SNathan Whitehorn 2652118f387SNathan Whitehorn snprintf(message, sizeof(message), "Would you like to use this entire " 266147585b4SBrad Davis "disk (%s) for " OSNAME " or partition it to share it with other " 2672118f387SNathan Whitehorn "operating systems? Using the entire disk will erase any data " 2682118f387SNathan Whitehorn "currently stored there.", disk); 26950e24496SAlfonso S. Siciliano conf.title = "Partition"; 27050e24496SAlfonso S. Siciliano choice = bsddialog_yesno(&conf, message, 9, 45); 2712118f387SNathan Whitehorn 27250e24496SAlfonso S. Siciliano conf.button.ok_label = NULL; 27350e24496SAlfonso S. Siciliano conf.button.cancel_label = NULL; 27450e24496SAlfonso S. Siciliano conf.button.default_cancel = false; 2752118f387SNathan Whitehorn 27650e24496SAlfonso S. Siciliano if (choice == BSDDIALOG_NO && scheme != NULL && !is_scheme_bootable(scheme)) { 2772118f387SNathan Whitehorn char warning[512]; 2782118f387SNathan Whitehorn int subchoice; 2792118f387SNathan Whitehorn 280*6e8bf240SJohn Baldwin snprintf(warning, sizeof(warning), 281*6e8bf240SJohn Baldwin "The existing partition scheme on this " 2822118f387SNathan Whitehorn "disk (%s) is not bootable on this platform. To install " 283147585b4SBrad Davis OSNAME ", it must be repartitioned. This will destroy all " 2842118f387SNathan Whitehorn "data on the disk. Are you sure you want to proceed?", 2852118f387SNathan Whitehorn scheme); 28650e24496SAlfonso S. Siciliano conf.title = "Non-bootable Disk"; 28750e24496SAlfonso S. Siciliano subchoice = bsddialog_yesno(&conf, warning, 0, 0); 28850e24496SAlfonso S. Siciliano if (subchoice != BSDDIALOG_YES) 2892118f387SNathan Whitehorn goto query; 2902118f387SNathan Whitehorn 291f36a5e0fSNathan Whitehorn gpart_destroy(gpart); 2927059fa6fSAllan Jude scheme = choose_part_type(default_scheme()); 2937059fa6fSAllan Jude if (scheme == NULL) 2947059fa6fSAllan Jude return NULL; 2957059fa6fSAllan Jude gpart_partition(disk, scheme); 2962118f387SNathan Whitehorn } 2972118f387SNathan Whitehorn 298da42677dSNathan Whitehorn if (scheme == NULL || choice == 0) { 299da42677dSNathan Whitehorn if (gpart != NULL && scheme != NULL) { 300da42677dSNathan Whitehorn /* Erase partitioned disk */ 30150e24496SAlfonso S. Siciliano conf.title = "Confirmation"; 30250e24496SAlfonso S. Siciliano choice = bsddialog_yesno(&conf, "This will erase " 3032118f387SNathan Whitehorn "the disk. Are you sure you want to proceed?", 0, 0); 30450e24496SAlfonso S. Siciliano if (choice != BSDDIALOG_YES) 3052118f387SNathan Whitehorn goto query; 3062118f387SNathan Whitehorn 307f36a5e0fSNathan Whitehorn gpart_destroy(gpart); 3082118f387SNathan Whitehorn } 3092118f387SNathan Whitehorn 3107059fa6fSAllan Jude scheme = choose_part_type(default_scheme()); 3117059fa6fSAllan Jude if (scheme == NULL) 3127059fa6fSAllan Jude return NULL; 3137059fa6fSAllan Jude gpart_partition(disk, scheme); 3142118f387SNathan Whitehorn } 3152118f387SNathan Whitehorn 3162b375b4eSYoshihiro Takahashi if (strcmp(scheme, "MBR") == 0) { 3172118f387SNathan Whitehorn struct gmesh submesh; 31823099099SJohn Baldwin 31923099099SJohn Baldwin if (geom_gettree(&submesh) == 0) { 3202118f387SNathan Whitehorn gpart_create(provider_for_name(&submesh, disk), 3212118f387SNathan Whitehorn "freebsd", NULL, NULL, &retval, 3222118f387SNathan Whitehorn choice /* Non-interactive for "Entire Disk" */); 3232118f387SNathan Whitehorn geom_deletetree(&submesh); 32423099099SJohn Baldwin } 3252118f387SNathan Whitehorn } else { 3262118f387SNathan Whitehorn retval = strdup(disk); 3272118f387SNathan Whitehorn } 3282118f387SNathan Whitehorn 3292118f387SNathan Whitehorn return (retval); 3302118f387SNathan Whitehorn } 3312118f387SNathan Whitehorn 332a6b612e9SNathan Whitehorn int 333d547c56fSEnji Cooper wizard_makeparts(struct gmesh *mesh, const char *disk, const char *fstype, 334d547c56fSEnji Cooper int interactive) 3352118f387SNathan Whitehorn { 3362118f387SNathan Whitehorn struct gclass *classp; 3372118f387SNathan Whitehorn struct ggeom *gp; 3382118f387SNathan Whitehorn struct gprovider *pp; 3396e15678aSNathan Whitehorn char *fsnames[] = {"freebsd-ufs", "freebsd-zfs"}; 340d547c56fSEnji Cooper char *fsname; 341d547c56fSEnji Cooper struct gmesh submesh; 342d547c56fSEnji Cooper char swapsizestr[10], rootsizestr[10]; 343d547c56fSEnji Cooper intmax_t swapsize, available; 34423099099SJohn Baldwin int error, retval; 34550e24496SAlfonso S. Siciliano struct bsddialog_conf conf; 3462118f387SNathan Whitehorn 3476e15678aSNathan Whitehorn if (strcmp(fstype, "zfs") == 0) { 3486e15678aSNathan Whitehorn fsname = fsnames[1]; 3496e15678aSNathan Whitehorn } else { 3506e15678aSNathan Whitehorn /* default to UFS */ 3516e15678aSNathan Whitehorn fsname = fsnames[0]; 3526e15678aSNathan Whitehorn } 3536e15678aSNathan Whitehorn 3542118f387SNathan Whitehorn LIST_FOREACH(classp, &mesh->lg_class, lg_class) 3552118f387SNathan Whitehorn if (strcmp(classp->lg_name, "PART") == 0) 3562118f387SNathan Whitehorn break; 3572118f387SNathan Whitehorn 3582118f387SNathan Whitehorn LIST_FOREACH(gp, &classp->lg_geom, lg_geom) 3592118f387SNathan Whitehorn if (strcmp(gp->lg_name, disk) == 0) 3602118f387SNathan Whitehorn break; 3612118f387SNathan Whitehorn 3622118f387SNathan Whitehorn pp = provider_for_name(mesh, disk); 3632118f387SNathan Whitehorn 3642118f387SNathan Whitehorn available = gpart_max_free(gp, NULL)*pp->lg_sectorsize; 365a6b612e9SNathan Whitehorn if (interactive && available < MIN_FREE_SPACE) { 3662118f387SNathan Whitehorn char availablestr[10], neededstr[10], message[512]; 3672118f387SNathan Whitehorn humanize_number(availablestr, 7, available, "B", HN_AUTOSCALE, 3682118f387SNathan Whitehorn HN_DECIMAL); 3692118f387SNathan Whitehorn humanize_number(neededstr, 7, MIN_FREE_SPACE, "B", HN_AUTOSCALE, 3702118f387SNathan Whitehorn HN_DECIMAL); 371*6e8bf240SJohn Baldwin snprintf(message, sizeof(message), 372*6e8bf240SJohn Baldwin "There is not enough free space on %s to " 373147585b4SBrad Davis "install " OSNAME " (%s free, %s required). Would you like " 3742118f387SNathan Whitehorn "to choose another disk or to open the partition editor?", 3752118f387SNathan Whitehorn disk, availablestr, neededstr); 3762118f387SNathan Whitehorn 37750e24496SAlfonso S. Siciliano bsddialog_initconf(&conf); 37850e24496SAlfonso S. Siciliano conf.button.ok_label = "Another Disk"; 37950e24496SAlfonso S. Siciliano conf.button.cancel_label = "Editor"; 38050e24496SAlfonso S. Siciliano conf.title = "Warning"; 38150e24496SAlfonso S. Siciliano retval = bsddialog_yesno(&conf, message, 0, 0); 3822118f387SNathan Whitehorn 3832118f387SNathan Whitehorn return (!retval); /* Editor -> return 0 */ 3842118f387SNathan Whitehorn } 3852118f387SNathan Whitehorn 3862118f387SNathan Whitehorn swapsize = SWAP_SIZE(available); 3872118f387SNathan Whitehorn humanize_number(swapsizestr, 7, swapsize, "B", HN_AUTOSCALE, 3882118f387SNathan Whitehorn HN_NOSPACE | HN_DECIMAL); 3892118f387SNathan Whitehorn humanize_number(rootsizestr, 7, available - swapsize - 1024*1024, 3902118f387SNathan Whitehorn "B", HN_AUTOSCALE, HN_NOSPACE | HN_DECIMAL); 3912118f387SNathan Whitehorn 39223099099SJohn Baldwin error = geom_gettree(&submesh); 39323099099SJohn Baldwin if (error != 0) 39423099099SJohn Baldwin return (error); 3952118f387SNathan Whitehorn pp = provider_for_name(&submesh, disk); 3966e15678aSNathan Whitehorn gpart_create(pp, fsname, rootsizestr, "/", NULL, 0); 3972118f387SNathan Whitehorn geom_deletetree(&submesh); 3982118f387SNathan Whitehorn 39923099099SJohn Baldwin error = geom_gettree(&submesh); 40023099099SJohn Baldwin if (error != 0) 40123099099SJohn Baldwin return (error); 4022118f387SNathan Whitehorn pp = provider_for_name(&submesh, disk); 4032118f387SNathan Whitehorn gpart_create(pp, "freebsd-swap", swapsizestr, NULL, NULL, 0); 4042118f387SNathan Whitehorn geom_deletetree(&submesh); 4052118f387SNathan Whitehorn 4062118f387SNathan Whitehorn return (0); 4072118f387SNathan Whitehorn } 408