label.c revision 107565
18549Sjkh/* 28549Sjkh * The new sysinstall program. 38549Sjkh * 48549Sjkh * This is probably the last program in the `sysinstall' line - the next 58549Sjkh * generation being essentially a complete rewrite. 68549Sjkh * 750479Speter * $FreeBSD: head/usr.sbin/sysinstall/label.c 107565 2002-12-03 22:25:47Z rwatson $ 88549Sjkh * 98549Sjkh * Copyright (c) 1995 108549Sjkh * Jordan Hubbard. All rights reserved. 118549Sjkh * 128549Sjkh * Redistribution and use in source and binary forms, with or without 138549Sjkh * modification, are permitted provided that the following conditions 148549Sjkh * are met: 158549Sjkh * 1. Redistributions of source code must retain the above copyright 168881Srgrimes * notice, this list of conditions and the following disclaimer, 178881Srgrimes * verbatim and that no modifications are made prior to this 188549Sjkh * point in the file. 198549Sjkh * 2. Redistributions in binary form must reproduce the above copyright 208549Sjkh * notice, this list of conditions and the following disclaimer in the 218549Sjkh * documentation and/or other materials provided with the distribution. 228549Sjkh * 238549Sjkh * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 248549Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 258549Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 268549Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 278549Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 288549Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 298549Sjkh * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 308549Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 318549Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 328549Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 338549Sjkh * SUCH DAMAGE. 348549Sjkh * 358549Sjkh */ 368549Sjkh 378549Sjkh#include "sysinstall.h" 388549Sjkh#include <ctype.h> 398549Sjkh#include <sys/disklabel.h> 4010882Speter#include <sys/param.h> 4110882Speter#include <sys/sysctl.h> 428549Sjkh 4388996Sdillon#define AUTO_HOME 0 /* do not create /home automatically */ 4488996Sdillon 458549Sjkh/* 468549Sjkh * Everything to do with editing the contents of disk labels. 478549Sjkh */ 488549Sjkh 498549Sjkh/* A nice message we use a lot in the disklabel editor */ 508549Sjkh#define MSG_NOT_APPLICABLE "That option is not applicable here" 518549Sjkh 528549Sjkh/* Where to start printing the freebsd slices */ 538549Sjkh#define CHUNK_SLICE_START_ROW 2 548622Sjkh#define CHUNK_PART_START_ROW 11 558549Sjkh 568549Sjkh/* The smallest filesystem we're willing to create */ 578702Sjkh#define FS_MIN_SIZE ONE_MEG 588549Sjkh 5987557Sdillon/* 6087557Sdillon * Minimum partition sizes 6187557Sdillon */ 62104940Sobrien#if defined(__alpha__) || defined(__ia64__) || defined(__sparc64__) 6345127Sjkh#define ROOT_MIN_SIZE 40 6444601Sjkh#else 6545127Sjkh#define ROOT_MIN_SIZE 30 6644601Sjkh#endif 6787557Sdillon#define SWAP_MIN_SIZE 32 6887557Sdillon#define USR_MIN_SIZE 80 6987557Sdillon#define VAR_MIN_SIZE 20 7087583Sdillon#define TMP_MIN_SIZE 20 7187557Sdillon#define HOME_MIN_SIZE 20 728549Sjkh 7387557Sdillon/* 7487557Sdillon * Swap size limit for auto-partitioning (4G). 7587557Sdillon */ 7687557Sdillon#define SWAP_AUTO_LIMIT_SIZE 4096 7744601Sjkh 7887557Sdillon/* 7987557Sdillon * Default partition sizes. If we do not have sufficient disk space 8087557Sdillon * for this configuration we scale things relative to the NOM vs DEFAULT 8187557Sdillon * sizes. If the disk is larger then /home will get any remaining space. 8287557Sdillon */ 8387557Sdillon#define ROOT_DEFAULT_SIZE 128 8487557Sdillon#define USR_DEFAULT_SIZE 3072 8587557Sdillon#define VAR_DEFAULT_SIZE 256 8687583Sdillon#define TMP_DEFAULT_SIZE 256 8787557Sdillon#define HOME_DEFAULT_SIZE USR_DEFAULT_SIZE 8812661Speter 8987557Sdillon/* 9087557Sdillon * Nominal partition sizes. These are used to scale the default sizes down 9187557Sdillon * when we have insufficient disk space. If this isn't sufficient we scale 9287557Sdillon * down using the MIN sizes instead. 9387557Sdillon */ 9487557Sdillon#define ROOT_NOMINAL_SIZE 128 9587557Sdillon#define USR_NOMINAL_SIZE 512 9687557Sdillon#define VAR_NOMINAL_SIZE 64 9787583Sdillon#define TMP_NOMINAL_SIZE 64 9887557Sdillon#define HOME_NOMINAL_SIZE USR_NOMINAL_SIZE 9912661Speter 10015440Sjkh/* The bottom-most row we're allowed to scribble on */ 10129249Sjkh#define CHUNK_ROW_MAX 16 10215440Sjkh 10315440Sjkh 1048549Sjkh/* All the chunks currently displayed on the screen */ 1058549Sjkhstatic struct { 1068549Sjkh struct chunk *c; 1078549Sjkh PartType type; 1088549Sjkh} label_chunk_info[MAX_CHUNKS + 1]; 1098549Sjkhstatic int here; 1108549Sjkh 11129249Sjkh/*** with this value we try to track the most recently added label ***/ 11229249Sjkhstatic int label_focus = 0, pslice_focus = 0; 11329249Sjkh 11430345Sjkhstatic int diskLabel(Device *dev); 11530345Sjkhstatic int diskLabelNonInteractive(Device *dev); 11687557Sdillonstatic char *try_auto_label(Device **devs, Device *dev, int perc, int *req); 11712661Speter 11830345Sjkhstatic int 11930345SjkhlabelHook(dialogMenuItem *selected) 12030345Sjkh{ 12130345Sjkh Device **devs = NULL; 12230345Sjkh 12330345Sjkh devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK); 12430345Sjkh if (!devs) { 12530345Sjkh msgConfirm("Unable to find disk %s!", selected->prompt); 12630345Sjkh return DITEM_FAILURE; 12730345Sjkh } 12830345Sjkh /* Toggle enabled status? */ 12930345Sjkh if (!devs[0]->enabled) { 13030345Sjkh devs[0]->enabled = TRUE; 13130345Sjkh diskLabel(devs[0]); 13230345Sjkh } 13330345Sjkh else 13430345Sjkh devs[0]->enabled = FALSE; 13554587Sjkh return DITEM_SUCCESS; 13630345Sjkh} 13730345Sjkh 13830345Sjkhstatic int 13930345SjkhlabelCheck(dialogMenuItem *selected) 14030345Sjkh{ 14130345Sjkh Device **devs = NULL; 14230345Sjkh 14330345Sjkh devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK); 14430345Sjkh if (!devs || devs[0]->enabled == FALSE) 14530345Sjkh return FALSE; 14630345Sjkh return TRUE; 14730345Sjkh} 14830345Sjkh 14912661Speterint 15015091SjkhdiskLabelEditor(dialogMenuItem *self) 15112661Speter{ 15230345Sjkh DMenu *menu; 15312661Speter Device **devs; 15430345Sjkh int i, cnt; 15512661Speter 15630345Sjkh i = 0; 15730345Sjkh cnt = diskGetSelectCount(&devs); 15830345Sjkh if (cnt == -1) { 15912661Speter msgConfirm("No disks found! Please verify that your disk controller is being\n" 16012661Speter "properly probed at boot time. See the Hardware Guide on the\n" 16112661Speter "Documentation menu for clues on diagnosing this type of problem."); 16215242Sjkh return DITEM_FAILURE; 16312661Speter } 16430345Sjkh else if (cnt) { 16530345Sjkh /* Some are already selected */ 16697667Sjhb if (variable_get(VAR_NONINTERACTIVE) && 16797667Sjhb !variable_get(VAR_DISKINTERACTIVE)) 16834543Sjkh i = diskLabelNonInteractive(NULL); 16930381Sjkh else 17034543Sjkh i = diskLabel(NULL); 17112661Speter } 17230345Sjkh else { 17330345Sjkh /* No disks are selected, fall-back case now */ 17430345Sjkh cnt = deviceCount(devs); 17530345Sjkh if (cnt == 1) { 17630345Sjkh devs[0]->enabled = TRUE; 17797667Sjhb if (variable_get(VAR_NONINTERACTIVE) && 17897667Sjhb !variable_get(VAR_DISKINTERACTIVE)) 17930345Sjkh i = diskLabelNonInteractive(devs[0]); 18030345Sjkh else 18130345Sjkh i = diskLabel(devs[0]); 18230345Sjkh } 18330345Sjkh else { 18430345Sjkh menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, labelHook, labelCheck); 18530345Sjkh if (!menu) { 18630345Sjkh msgConfirm("No devices suitable for installation found!\n\n" 18730345Sjkh "Please verify that your disk controller (and attached drives)\n" 18830345Sjkh "were detected properly. This can be done by pressing the\n" 18930345Sjkh "[Scroll Lock] key and using the Arrow keys to move back to\n" 19030345Sjkh "the boot messages. Press [Scroll Lock] again to return."); 19130345Sjkh i = DITEM_FAILURE; 19230345Sjkh } 19330345Sjkh else { 19430345Sjkh i = dmenuOpenSimple(menu, FALSE) ? DITEM_SUCCESS : DITEM_FAILURE; 19530345Sjkh free(menu); 19630345Sjkh } 19730345Sjkh } 19812661Speter } 19918744Sjkh if (DITEM_STATUS(i) != DITEM_FAILURE) { 20074156Sjkh if (variable_cmp(DISK_LABELLED, "written")) 20143685Sjkh variable_set2(DISK_LABELLED, "yes", 0); 20218744Sjkh } 20312661Speter return i; 20412661Speter} 20512661Speter 20612661Speterint 20715091SjkhdiskLabelCommit(dialogMenuItem *self) 20812661Speter{ 20912661Speter char *cp; 21012661Speter int i; 21112661Speter 21212661Speter /* Already done? */ 21317025Sjkh if ((cp = variable_get(DISK_LABELLED)) && strcmp(cp, "yes")) 21415242Sjkh i = DITEM_SUCCESS; 21512661Speter else if (!cp) { 21612661Speter msgConfirm("You must assign disk labels before this option can be used."); 21715242Sjkh i = DITEM_FAILURE; 21812661Speter } 21912661Speter /* The routine will guard against redundant writes, just as this one does */ 22015419Sjkh else if (DITEM_STATUS(diskPartitionWrite(self)) != DITEM_SUCCESS) 22115242Sjkh i = DITEM_FAILURE; 22215419Sjkh else if (DITEM_STATUS(installFilesystems(self)) != DITEM_SUCCESS) 22315242Sjkh i = DITEM_FAILURE; 22412661Speter else { 22512661Speter msgInfo("All filesystem information written successfully."); 22643685Sjkh variable_set2(DISK_LABELLED, "written", 0); 22715242Sjkh i = DITEM_SUCCESS; 22812661Speter } 22912661Speter return i; 23012661Speter} 23112661Speter 2328549Sjkh/* See if we're already using a desired partition name */ 2338549Sjkhstatic Boolean 2348549Sjkhcheck_conflict(char *name) 2358549Sjkh{ 2368549Sjkh int i; 2378549Sjkh 2388751Sjkh for (i = 0; label_chunk_info[i].c; i++) 23923729Sjkh if ((label_chunk_info[i].type == PART_FILESYSTEM || label_chunk_info[i].type == PART_FAT) 24023729Sjkh && label_chunk_info[i].c->private_data 24114793Sjoerg && !strcmp(((PartInfo *)label_chunk_info[i].c->private_data)->mountpoint, name)) 2428549Sjkh return TRUE; 2438549Sjkh return FALSE; 2448549Sjkh} 2458549Sjkh 2468549Sjkh/* How much space is in this FreeBSD slice? */ 2478549Sjkhstatic int 2488549Sjkhspace_free(struct chunk *c) 2498549Sjkh{ 25012661Speter struct chunk *c1; 2518549Sjkh int sz = c->size; 2528549Sjkh 25312661Speter for (c1 = c->part; c1; c1 = c1->next) { 2548549Sjkh if (c1->type != unused) 2558549Sjkh sz -= c1->size; 2568549Sjkh } 2578549Sjkh if (sz < 0) 2588549Sjkh msgFatal("Partitions are larger than actual chunk??"); 2598549Sjkh return sz; 2608549Sjkh} 2618549Sjkh 2628549Sjkh/* Snapshot the current situation into the displayed chunks structure */ 2638549Sjkhstatic void 26430345Sjkhrecord_label_chunks(Device **devs, Device *dev) 2658549Sjkh{ 2668549Sjkh int i, j, p; 2678549Sjkh struct chunk *c1, *c2; 2688556Sjkh Disk *d; 2698549Sjkh 2708549Sjkh j = p = 0; 2718556Sjkh /* First buzz through and pick up the FreeBSD slices */ 2728549Sjkh for (i = 0; devs[i]; i++) { 27330345Sjkh if ((dev && devs[i] != dev) || !devs[i]->enabled) 2748556Sjkh continue; 2758556Sjkh d = (Disk *)devs[i]->private; 2768556Sjkh if (!d->chunks) 2778556Sjkh msgFatal("No chunk list found for %s!", d->name); 2788549Sjkh 2798556Sjkh /* Put the slice entries first */ 2808556Sjkh for (c1 = d->chunks->part; c1; c1 = c1->next) { 2818549Sjkh if (c1->type == freebsd) { 2828549Sjkh label_chunk_info[j].type = PART_SLICE; 2838549Sjkh label_chunk_info[j].c = c1; 2848549Sjkh ++j; 2858549Sjkh } 2868549Sjkh } 2878549Sjkh } 28812661Speter 2898556Sjkh /* Now run through again and get the FreeBSD partition entries */ 2908556Sjkh for (i = 0; devs[i]; i++) { 2918556Sjkh if (!devs[i]->enabled) 2928556Sjkh continue; 2938556Sjkh d = (Disk *)devs[i]->private; 2948549Sjkh /* Then buzz through and pick up the partitions */ 2958556Sjkh for (c1 = d->chunks->part; c1; c1 = c1->next) { 2968549Sjkh if (c1->type == freebsd) { 2978549Sjkh for (c2 = c1->part; c2; c2 = c2->next) { 2988549Sjkh if (c2->type == part) { 2998549Sjkh if (c2->subtype == FS_SWAP) 3008549Sjkh label_chunk_info[j].type = PART_SWAP; 3018549Sjkh else 3028549Sjkh label_chunk_info[j].type = PART_FILESYSTEM; 3038549Sjkh label_chunk_info[j].c = c2; 3048549Sjkh ++j; 3058549Sjkh } 3068549Sjkh } 3078549Sjkh } 308106839Smarcel else if (c1->type == fat || c1->type == efi) { 3098549Sjkh label_chunk_info[j].type = PART_FAT; 3108549Sjkh label_chunk_info[j].c = c1; 3118702Sjkh ++j; 3128549Sjkh } 3138549Sjkh } 3148549Sjkh } 3158549Sjkh label_chunk_info[j].c = NULL; 31629249Sjkh if (here >= j) { 3178549Sjkh here = j ? j - 1 : 0; 31829249Sjkh } 3198549Sjkh} 3208549Sjkh 3218549Sjkh/* A new partition entry */ 3228549Sjkhstatic PartInfo * 323106826Sjhbnew_part(char *mpoint, Boolean newfs) 3248549Sjkh{ 325107565Srwatson PartInfo *pi; 3268549Sjkh 3279202Srgrimes if (!mpoint) 3289202Srgrimes mpoint = "/change_me"; 3299202Srgrimes 330107565Srwatson pi = (PartInfo *)safe_malloc(sizeof(PartInfo)); 331107565Srwatson sstrncpy(pi->mountpoint, mpoint, FILENAME_MAX); 332107565Srwatson 333107565Srwatson pi->do_newfs = newfs; 334107565Srwatson 335107565Srwatson pi->newfs_type = NEWFS_UFS; 336107565Srwatson strcpy(pi->newfs_data.newfs_ufs.user_options, ""); 337107565Srwatson pi->newfs_data.newfs_ufs.acls = FALSE; 338107565Srwatson pi->newfs_data.newfs_ufs.multilabel = FALSE; 339107565Srwatson pi->newfs_data.newfs_ufs.softupdates = strcmp(mpoint, "/"); 340107565Srwatson pi->newfs_data.newfs_ufs.ufs2 = FALSE; 341107565Srwatson 342107565Srwatson return pi; 3438549Sjkh} 3448549Sjkh 345106885Smarcel#if defined(__ia64__) 346106885Smarcelstatic PartInfo * 347106885Smarcelnew_efi_part(char *mpoint, Boolean newfs) 348106885Smarcel{ 349107565Srwatson PartInfo *pi; 350106885Smarcel 351106885Smarcel if (!mpoint) 352106885Smarcel mpoint = "/efi"; 353106885Smarcel 354107565Srwatson pi = (PartInfo *)safe_malloc(sizeof(PartInfo)); 355107565Srwatson sstrncpy(pi->mountpoint, mpoint, FILENAME_MAX); 356107565Srwatson 357107565Srwatson pi->do_newfs = newfs; 358107565Srwatson pi->newfs_type = NEWFS_MSDOS; 359107565Srwatson 360107565Srwatson return pi; 361106885Smarcel} 362106885Smarcel#endif 363106885Smarcel 3648549Sjkh/* Get the mountpoint for a partition and save it away */ 36512661Speterstatic PartInfo * 3668589Sjkhget_mountpoint(struct chunk *old) 3678549Sjkh{ 3688549Sjkh char *val; 3698549Sjkh PartInfo *tmp; 370106822Sjhb Boolean newfs; 3718549Sjkh 37214793Sjoerg if (old && old->private_data) 37314793Sjoerg tmp = old->private_data; 3748810Sjkh else 3758810Sjkh tmp = NULL; 3768810Sjkh val = msgGetInput(tmp ? tmp->mountpoint : NULL, "Please specify a mount point for the partition"); 3778764Sjkh if (!val || !*val) { 3788751Sjkh if (!old) 3798751Sjkh return NULL; 3808751Sjkh else { 38114793Sjoerg free(old->private_data); 38214793Sjoerg old->private_data = NULL; 3838751Sjkh } 3848669Sphk return NULL; 3858751Sjkh } 3868669Sphk 3878669Sphk /* Is it just the same value? */ 3888810Sjkh if (tmp && !strcmp(tmp->mountpoint, val)) 3898669Sphk return NULL; 3908810Sjkh 3918810Sjkh /* Did we use it already? */ 3928669Sphk if (check_conflict(val)) { 3938669Sphk msgConfirm("You already have a mount point for %s assigned!", val); 3948669Sphk return NULL; 3958549Sjkh } 3968810Sjkh 3978810Sjkh /* Is it bogus? */ 3988669Sphk if (*val != '/') { 3998669Sphk msgConfirm("Mount point must start with a / character"); 4008669Sphk return NULL; 4018669Sphk } 4028810Sjkh 4038810Sjkh /* Is it going to be mounted on root? */ 4048669Sphk if (!strcmp(val, "/")) { 4058669Sphk if (old) 4068669Sphk old->flags |= CHUNK_IS_ROOT; 4078810Sjkh } 4088810Sjkh else if (old) 4098669Sphk old->flags &= ~CHUNK_IS_ROOT; 4108810Sjkh 411106823Sjhb newfs = TRUE; 412106822Sjhb if (tmp) { 413107565Srwatson newfs = tmp->do_newfs; 414106822Sjhb safe_free(tmp); 415106822Sjhb } 41646615Sjkh val = string_skipwhite(string_prune(val)); 417106826Sjhb tmp = new_part(val, newfs); 4188669Sphk if (old) { 41914793Sjoerg old->private_data = tmp; 4208669Sphk old->private_free = safe_free; 4218669Sphk } 4228669Sphk return tmp; 4238549Sjkh} 4248549Sjkh 4258549Sjkh/* Get the type of the new partiton */ 4268549Sjkhstatic PartType 4278549Sjkhget_partition_type(void) 4288549Sjkh{ 4298549Sjkh char selection[20]; 4308669Sphk int i; 4318549Sjkh static unsigned char *fs_types[] = { 4328549Sjkh "FS", 4338549Sjkh "A file system", 4348549Sjkh "Swap", 4358549Sjkh "A swap partition.", 4368549Sjkh }; 43754587Sjkh WINDOW *w = savescr(); 43854587Sjkh 4398669Sphk i = dialog_menu("Please choose a partition type", 44012661Speter "If you want to use this partition for swap space, select Swap.\n" 44112661Speter "If you want to put a filesystem on it, choose FS.", 44212661Speter -1, -1, 2, 2, fs_types, selection, NULL, NULL); 44354587Sjkh restorescr(w); 4448669Sphk if (!i) { 4458549Sjkh if (!strcmp(selection, "FS")) 4468549Sjkh return PART_FILESYSTEM; 4478549Sjkh else if (!strcmp(selection, "Swap")) 4488549Sjkh return PART_SWAP; 4498549Sjkh } 4508549Sjkh return PART_NONE; 4518549Sjkh} 4528549Sjkh 4538549Sjkh/* If the user wants a special newfs command for this, set it */ 4548549Sjkhstatic void 4558549SjkhgetNewfsCmd(PartInfo *p) 4568549Sjkh{ 457107565Srwatson char buffer[NEWFS_CMD_ARGS_MAX]; 4588549Sjkh char *val; 4598549Sjkh 460107565Srwatson switch (p->newfs_type) { 461107565Srwatson case NEWFS_UFS: 462107565Srwatson snprintf(buffer, NEWFS_CMD_ARGS_MAX, "%s %s %s %s", 463107565Srwatson NEWFS_UFS_CMD, p->newfs_data.newfs_ufs.softupdates ? "-U" : "", 464107565Srwatson p->newfs_data.newfs_ufs.ufs2 ? "-O2" : "-O1", 465107565Srwatson p->newfs_data.newfs_ufs.user_options); 466107565Srwatson break; 467107565Srwatson case NEWFS_MSDOS: 468107565Srwatson snprintf(buffer, NEWFS_CMD_ARGS_MAX, "%s", NEWFS_MSDOS_CMD); 469107565Srwatson break; 470107565Srwatson case NEWFS_CUSTOM: 471107565Srwatson strcpy(buffer, p->newfs_data.newfs_custom.command); 472107565Srwatson break; 473107565Srwatson } 474107565Srwatson 475107565Srwatson val = msgGetInput(buffer, 476107565Srwatson "Please enter the newfs command and options you'd like to use in\n" 477107565Srwatson "creating this file system."); 478107565Srwatson if (val != NULL) { 479107565Srwatson p->newfs_type = NEWFS_CUSTOM; 480107565Srwatson strlcpy(p->newfs_data.newfs_custom.command, val, NEWFS_CMD_ARGS_MAX); 481107565Srwatson } 4828549Sjkh} 4838549Sjkh 484107565Srwatsonstatic void 485107565SrwatsongetNewfsOptionalArguments(PartInfo *p) 486107565Srwatson{ 487107565Srwatson char buffer[NEWFS_CMD_ARGS_MAX]; 488107565Srwatson char *val; 489107565Srwatson 490107565Srwatson /* Must be UFS, per argument checking in I/O routines. */ 491107565Srwatson 492107565Srwatson strlcpy(buffer, p->newfs_data.newfs_ufs.user_options, 493107565Srwatson NEWFS_CMD_ARGS_MAX); 494107565Srwatson val = msgGetInput(buffer, 495107565Srwatson "Please enter any additional UFS newfs options you'd like to\n" 496107565Srwatson "use in creating this file system."); 497107565Srwatson if (val != NULL) 498107565Srwatson strlcpy(p->newfs_data.newfs_ufs.user_options, val, 499107565Srwatson NEWFS_CMD_ARGS_MAX); 500107565Srwatson} 501107565Srwatson 50276299Sjkh#define MAX_MOUNT_NAME 9 5038549Sjkh 5048549Sjkh#define PART_PART_COL 0 50554014Sjkh#define PART_MOUNT_COL 10 5068549Sjkh#define PART_SIZE_COL (PART_MOUNT_COL + MAX_MOUNT_NAME + 3) 50749202Sbrian#define PART_NEWFS_COL (PART_SIZE_COL + 8) 50876299Sjkh#define PART_OFF 38 5098549Sjkh 51029249Sjkh#define TOTAL_AVAIL_LINES (10) 51129249Sjkh#define PSLICE_SHOWABLE (4) 51229249Sjkh 51329249Sjkh 5148549Sjkh/* stick this all up on the screen */ 5158549Sjkhstatic void 5168549Sjkhprint_label_chunks(void) 5178549Sjkh{ 518107565Srwatson int i, j, spaces, srow, prow, pcol; 51929249Sjkh int sz; 52029249Sjkh char clrmsg[80]; 52129633Sjkh int ChunkPartStartRow; 52229633Sjkh WINDOW *ChunkWin; 5238549Sjkh 52429249Sjkh /********************************************************/ 52529249Sjkh /*** These values are for controling screen resources ***/ 52629249Sjkh /*** Each label line holds up to 2 labels, so beware! ***/ 52729249Sjkh /*** strategy will be to try to always make sure the ***/ 52829249Sjkh /*** highlighted label is in the active display area. ***/ 52929249Sjkh /********************************************************/ 53029249Sjkh int pslice_max, label_max; 53129249Sjkh int pslice_count, label_count, label_focus_found, pslice_focus_found; 53229249Sjkh 5338549Sjkh attrset(A_REVERSE); 5348549Sjkh mvaddstr(0, 25, "FreeBSD Disklabel Editor"); 5358549Sjkh attrset(A_NORMAL); 5368549Sjkh 53729633Sjkh /*** Count the number of parition slices ***/ 53829633Sjkh pslice_count = 0; 53929633Sjkh for (i = 0; label_chunk_info[i].c ; i++) { 54029633Sjkh if (label_chunk_info[i].type == PART_SLICE) 54129633Sjkh ++pslice_count; 54229633Sjkh } 54329633Sjkh pslice_max = pslice_count; 54429633Sjkh 54529633Sjkh /*** 4 line max for partition slices ***/ 54629633Sjkh if (pslice_max > PSLICE_SHOWABLE) { 54729633Sjkh pslice_max = PSLICE_SHOWABLE; 54829633Sjkh } 54929633Sjkh ChunkPartStartRow = CHUNK_SLICE_START_ROW + 3 + pslice_max; 55029633Sjkh 55129633Sjkh /*** View partition slices modulo pslice_max ***/ 55229633Sjkh label_max = TOTAL_AVAIL_LINES - pslice_max; 55329633Sjkh 5548549Sjkh for (i = 0; i < 2; i++) { 55515440Sjkh mvaddstr(ChunkPartStartRow - 2, PART_PART_COL + (i * PART_OFF), "Part"); 55615440Sjkh mvaddstr(ChunkPartStartRow - 1, PART_PART_COL + (i * PART_OFF), "----"); 5578549Sjkh 55815440Sjkh mvaddstr(ChunkPartStartRow - 2, PART_MOUNT_COL + (i * PART_OFF), "Mount"); 55915440Sjkh mvaddstr(ChunkPartStartRow - 1, PART_MOUNT_COL + (i * PART_OFF), "-----"); 5608549Sjkh 56149202Sbrian mvaddstr(ChunkPartStartRow - 2, PART_SIZE_COL + (i * PART_OFF) + 3, "Size"); 56249202Sbrian mvaddstr(ChunkPartStartRow - 1, PART_SIZE_COL + (i * PART_OFF) + 3, "----"); 5638549Sjkh 56415440Sjkh mvaddstr(ChunkPartStartRow - 2, PART_NEWFS_COL + (i * PART_OFF), "Newfs"); 56515440Sjkh mvaddstr(ChunkPartStartRow - 1, PART_NEWFS_COL + (i * PART_OFF), "-----"); 5668549Sjkh } 5678549Sjkh srow = CHUNK_SLICE_START_ROW; 56815440Sjkh prow = 0; 5698549Sjkh pcol = 0; 5708549Sjkh 57129249Sjkh /*** these variables indicate that the focused item is shown currently ***/ 57229249Sjkh label_focus_found = 0; 57329249Sjkh pslice_focus_found = 0; 57429249Sjkh 57529249Sjkh label_count = 0; 57629249Sjkh pslice_count = 0; 57729249Sjkh mvprintw(CHUNK_SLICE_START_ROW - 1, 0, " "); 57829249Sjkh mvprintw(CHUNK_SLICE_START_ROW + pslice_max, 0, " "); 57929249Sjkh 58029633Sjkh ChunkWin = newwin(CHUNK_ROW_MAX - ChunkPartStartRow, 76, ChunkPartStartRow, 0); 58129633Sjkh 58229633Sjkh wclear(ChunkWin); 58329633Sjkh /*** wrefresh(ChunkWin); ***/ 58429633Sjkh 5858751Sjkh for (i = 0; label_chunk_info[i].c; i++) { 5868549Sjkh /* Is it a slice entry displayed at the top? */ 5878549Sjkh if (label_chunk_info[i].type == PART_SLICE) { 58829249Sjkh /*** This causes the new pslice to replace the previous display ***/ 58929249Sjkh /*** focus must remain on the most recently active pslice ***/ 59029249Sjkh if (pslice_count == pslice_max) { 59129249Sjkh if (pslice_focus_found) { 59229249Sjkh /*** This is where we can mark the more following ***/ 59329249Sjkh attrset(A_BOLD); 59429249Sjkh mvprintw(CHUNK_SLICE_START_ROW + pslice_max, 0, "***MORE***"); 59529249Sjkh attrset(A_NORMAL); 59629249Sjkh continue; 59729249Sjkh } 59829249Sjkh else { 59929249Sjkh /*** this is where we set the more previous ***/ 60029249Sjkh attrset(A_BOLD); 60129249Sjkh mvprintw(CHUNK_SLICE_START_ROW - 1, 0, "***MORE***"); 60229249Sjkh attrset(A_NORMAL); 60329249Sjkh pslice_count = 0; 60429249Sjkh srow = CHUNK_SLICE_START_ROW; 60529249Sjkh } 60629249Sjkh } 60729249Sjkh 6088549Sjkh sz = space_free(label_chunk_info[i].c); 60915440Sjkh if (i == here) 61016208Sjkh attrset(ATTR_SELECTED); 61129249Sjkh if (i == pslice_focus) 61229249Sjkh pslice_focus_found = -1; 61329249Sjkh 61429249Sjkh mvprintw(srow++, 0, 61529249Sjkh "Disk: %s\tPartition name: %s\tFree: %d blocks (%dMB)", 61629249Sjkh label_chunk_info[i].c->disk->name, label_chunk_info[i].c->name, 61729249Sjkh sz, (sz / ONE_MEG)); 61815440Sjkh attrset(A_NORMAL); 61915440Sjkh clrtoeol(); 62015440Sjkh move(0, 0); 62129633Sjkh /*** refresh(); ***/ 62229249Sjkh ++pslice_count; 6238549Sjkh } 62415440Sjkh /* Otherwise it's a DOS, swap or filesystem entry in the Chunk window */ 6258549Sjkh else { 626107565Srwatson char onestr[PART_OFF], num[10], *mountpoint, newfs[12]; 6278549Sjkh 6288549Sjkh /* 6298549Sjkh * We copy this into a blank-padded string so that it looks like 6308549Sjkh * a solid bar in reverse-video 6318549Sjkh */ 6328549Sjkh memset(onestr, ' ', PART_OFF - 1); 6338549Sjkh onestr[PART_OFF - 1] = '\0'; 63429249Sjkh 63529249Sjkh /*** Track how many labels have been displayed ***/ 63629249Sjkh if (label_count == ((label_max - 1 ) * 2)) { 63729249Sjkh if (label_focus_found) { 63829249Sjkh continue; 63929249Sjkh } 64029249Sjkh else { 64129249Sjkh label_count = 0; 64229249Sjkh prow = 0; 64329249Sjkh pcol = 0; 64429249Sjkh } 64529249Sjkh } 64629249Sjkh 64715440Sjkh /* Go for two columns if we've written one full columns worth */ 64829249Sjkh /*** if (prow == (CHUNK_ROW_MAX - ChunkPartStartRow)) ***/ 64929249Sjkh if (label_count == label_max - 1) { 6508549Sjkh pcol = PART_OFF; 65115440Sjkh prow = 0; 6528549Sjkh } 6538705Sjkh memcpy(onestr + PART_PART_COL, label_chunk_info[i].c->name, strlen(label_chunk_info[i].c->name)); 6548549Sjkh /* If it's a filesystem, display the mountpoint */ 65514793Sjoerg if (label_chunk_info[i].c->private_data 65610882Speter && (label_chunk_info[i].type == PART_FILESYSTEM || label_chunk_info[i].type == PART_FAT)) 65714793Sjoerg mountpoint = ((PartInfo *)label_chunk_info[i].c->private_data)->mountpoint; 65823529Sjkh else if (label_chunk_info[i].type == PART_SWAP) 65923529Sjkh mountpoint = "swap"; 66010882Speter else 66110882Speter mountpoint = "<none>"; 66210882Speter 66310882Speter /* Now display the newfs field */ 664106885Smarcel if (label_chunk_info[i].type == PART_FAT) { 665106885Smarcel strcpy(newfs, "DOS"); 666106885Smarcel#if defined(__ia64__) 667106885Smarcel if (label_chunk_info[i].c->private_data && 668106885Smarcel label_chunk_info[i].c->type == efi) { 669106885Smarcel strcat(newfs, " "); 670106885Smarcel PartInfo *pi = (PartInfo *)label_chunk_info[i].c->private_data; 671107565Srwatson strcat(newfs, pi->do_newfs ? " Y" : " N"); 672106885Smarcel } 673106885Smarcel#endif 674106885Smarcel } 67574086Sjkh else if (label_chunk_info[i].c->private_data && label_chunk_info[i].type == PART_FILESYSTEM) { 676107565Srwatson PartInfo *pi = (PartInfo *)label_chunk_info[i].c->private_data; 677107565Srwatson 678107565Srwatson switch (pi->newfs_type) { 679107565Srwatson case NEWFS_UFS: 680107565Srwatson strcpy(newfs, NEWFS_UFS_STRING); 681107565Srwatson if (pi->newfs_data.newfs_ufs.ufs2) 682107565Srwatson strcat(newfs, "2"); 683107565Srwatson else 684107565Srwatson strcat(newfs, "1"); 685107565Srwatson if (pi->newfs_data.newfs_ufs.softupdates) 686107565Srwatson strcat(newfs, "+S"); 687107565Srwatson else 688107565Srwatson strcat(newfs, " "); 689107565Srwatson 690107565Srwatson break; 691107565Srwatson case NEWFS_MSDOS: 692107565Srwatson strcpy(newfs, "FAT"); 693107565Srwatson break; 694107565Srwatson case NEWFS_CUSTOM: 695107565Srwatson strcpy(newfs, "CUST"); 696107565Srwatson break; 697107565Srwatson } 698107565Srwatson strcat(newfs, pi->do_newfs ? " Y" : " N "); 69974086Sjkh } 70010882Speter else if (label_chunk_info[i].type == PART_SWAP) 70174086Sjkh strcpy(newfs, "SWAP"); 70210882Speter else 70374086Sjkh strcpy(newfs, "*"); 7048549Sjkh for (j = 0; j < MAX_MOUNT_NAME && mountpoint[j]; j++) 7058549Sjkh onestr[PART_MOUNT_COL + j] = mountpoint[j]; 70649202Sbrian snprintf(num, 10, "%5ldMB", label_chunk_info[i].c->size ? label_chunk_info[i].c->size / ONE_MEG : 0); 7078549Sjkh memcpy(onestr + PART_SIZE_COL, num, strlen(num)); 7088549Sjkh memcpy(onestr + PART_NEWFS_COL, newfs, strlen(newfs)); 7098549Sjkh onestr[PART_NEWFS_COL + strlen(newfs)] = '\0'; 71029633Sjkh if (i == label_focus) { 71129633Sjkh label_focus_found = -1; 71229633Sjkh wattrset(ChunkWin, A_BOLD); 71329633Sjkh } 71415440Sjkh if (i == here) 71516208Sjkh wattrset(ChunkWin, ATTR_SELECTED); 71629249Sjkh 71774086Sjkh /*** lazy man's way of expensively padding this string ***/ 71874086Sjkh while (strlen(onestr) < 37) 71929249Sjkh strcat(onestr, " "); 72029249Sjkh 72115440Sjkh mvwaddstr(ChunkWin, prow, pcol, onestr); 72215440Sjkh wattrset(ChunkWin, A_NORMAL); 72315440Sjkh move(0, 0); 7248549Sjkh ++prow; 72529249Sjkh ++label_count; 7268549Sjkh } 7278549Sjkh } 72829249Sjkh 72929249Sjkh /*** this will erase all the extra stuff ***/ 73029249Sjkh memset(clrmsg, ' ', 37); 73129249Sjkh clrmsg[37] = '\0'; 73229249Sjkh 73329249Sjkh while (pslice_count < pslice_max) { 73429249Sjkh mvprintw(srow++, 0, clrmsg); 73529249Sjkh clrtoeol(); 73629249Sjkh ++pslice_count; 73729249Sjkh } 73829633Sjkh while (label_count < (2 * (label_max - 1))) { 73929633Sjkh mvwaddstr(ChunkWin, prow++, pcol, clrmsg); 74029633Sjkh ++label_count; 74129633Sjkh if (prow == (label_max - 1)) { 74229633Sjkh prow = 0; 74329633Sjkh pcol = PART_OFF; 74429633Sjkh } 74529249Sjkh } 74629633Sjkh refresh(); 74729633Sjkh wrefresh(ChunkWin); 7488549Sjkh} 7498549Sjkh 7508549Sjkhstatic void 75118619Sjkhprint_command_summary(void) 7528549Sjkh{ 7538820Sjkh mvprintw(17, 0, "The following commands are valid here (upper or lower case):"); 75474086Sjkh mvprintw(18, 0, "C = Create D = Delete M = Mount pt."); 75515440Sjkh if (!RunningAsInit) 756107565Srwatson mvprintw(18, 56, "W = Write"); 757107565Srwatson mvprintw(19, 0, "N = Newfs Opts Q = Finish S = Toggle SoftUpdates Z = Custom Newfs"); 758107565Srwatson mvprintw(20, 0, "T = Toggle Newfs U = Undo A = Auto Defaults R = Delete+Merge"); 75915695Sjkh mvprintw(22, 0, "Use F1 or ? to get more help, arrow keys to select."); 7608549Sjkh move(0, 0); 7618549Sjkh} 7628549Sjkh 76318619Sjkhstatic void 76418619Sjkhclear_wins(void) 76518619Sjkh{ 76629633Sjkh extern void print_label_chunks(); 76718619Sjkh clear(); 76829633Sjkh print_label_chunks(); 76918619Sjkh} 77018619Sjkh 77112661Speterstatic int 77230345SjkhdiskLabel(Device *dev) 7738549Sjkh{ 77418619Sjkh int sz, key = 0; 7758549Sjkh Boolean labeling; 7768549Sjkh char *msg = NULL; 7779202Srgrimes PartInfo *p, *oldp; 7788549Sjkh PartType type; 7798824Sjkh Device **devs; 78054587Sjkh WINDOW *w = savescr(); 7818549Sjkh 78229628Sjkh label_focus = 0; 78329628Sjkh pslice_focus = 0; 78429633Sjkh here = 0; 78530345Sjkh 78612661Speter devs = deviceFind(NULL, DEVICE_TYPE_DISK); 78712661Speter if (!devs) { 78812661Speter msgConfirm("No disks found!"); 78954587Sjkh restorescr(w); 79015242Sjkh return DITEM_FAILURE; 79112661Speter } 7928549Sjkh labeling = TRUE; 7938549Sjkh keypad(stdscr, TRUE); 79430345Sjkh record_label_chunks(devs, dev); 7958549Sjkh 79618619Sjkh clear(); 7978549Sjkh while (labeling) { 79818744Sjkh char *cp; 79988996Sdillon int rflags = DELCHUNK_NORMAL; 80018744Sjkh 8018549Sjkh print_label_chunks(); 80218619Sjkh print_command_summary(); 8038549Sjkh if (msg) { 80415695Sjkh attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL); 80512661Speter clrtoeol(); 8068549Sjkh beep(); 8078549Sjkh msg = NULL; 8088549Sjkh } 80915442Sjkh else { 81015442Sjkh move(23, 0); 81115442Sjkh clrtoeol(); 81215442Sjkh } 81318744Sjkh 81418619Sjkh refresh(); 81517397Sjkh key = getch(); 81617397Sjkh switch (toupper(key)) { 81715440Sjkh int i; 81817362Sjkh static char _msg[40]; 8198549Sjkh 8208751Sjkh case '\014': /* ^L */ 82118619Sjkh clear_wins(); 82218619Sjkh break; 8238751Sjkh 82421698Sjkh case '\020': /* ^P */ 8258549Sjkh case KEY_UP: 8268549Sjkh case '-': 8278549Sjkh if (here != 0) 8288549Sjkh --here; 8298751Sjkh else 8308751Sjkh while (label_chunk_info[here + 1].c) 8318751Sjkh ++here; 8328549Sjkh break; 8338549Sjkh 83421698Sjkh case '\016': /* ^N */ 8358549Sjkh case KEY_DOWN: 8368549Sjkh case '+': 8378549Sjkh case '\r': 8388549Sjkh case '\n': 8398751Sjkh if (label_chunk_info[here + 1].c) 8408549Sjkh ++here; 8418751Sjkh else 8428751Sjkh here = 0; 8438549Sjkh break; 8448549Sjkh 8458549Sjkh case KEY_HOME: 8468549Sjkh here = 0; 8478549Sjkh break; 8488549Sjkh 8498549Sjkh case KEY_END: 8508751Sjkh while (label_chunk_info[here + 1].c) 8518549Sjkh ++here; 8528549Sjkh break; 8538549Sjkh 8548549Sjkh case KEY_F(1): 8558549Sjkh case '?': 85612661Speter systemDisplayHelp("partition"); 85718619Sjkh clear_wins(); 8588549Sjkh break; 8598549Sjkh 860107565Srwatson case '2': 861107565Srwatson if (label_chunk_info[here].type == PART_FILESYSTEM) { 862107565Srwatson PartInfo *pi = 863107565Srwatson ((PartInfo *)label_chunk_info[here].c->private_data); 864107565Srwatson 865107565Srwatson if ((pi != NULL) && 866107565Srwatson (pi->newfs_type == NEWFS_UFS)) { 867107565Srwatson#ifdef __i386__ 868107565Srwatson if (label_chunk_info[here].c->flags & CHUNK_IS_ROOT) 869107565Srwatson msg = MSG_NOT_APPLICABLE; 870107565Srwatson else 871107565Srwatson#endif 872107565Srwatson pi->newfs_data.newfs_ufs.ufs2 = 873107565Srwatson !pi->newfs_data.newfs_ufs.ufs2; 874107565Srwatson } else 875107565Srwatson msg = MSG_NOT_APPLICABLE; 876107565Srwatson } else 877107565Srwatson msg = MSG_NOT_APPLICABLE; 878107565Srwatson break; 879107565Srwatson break; 880107565Srwatson 88110882Speter case 'A': 88210882Speter if (label_chunk_info[here].type != PART_SLICE) { 88315440Sjkh msg = "You can only do this in a disk slice (at top of screen)"; 88410882Speter break; 88510882Speter } 88687557Sdillon /* 88787557Sdillon * Generate standard partitions automatically. If we do not 88887557Sdillon * have sufficient space we attempt to scale-down the size 88987557Sdillon * of the partitions within certain bounds. 89087557Sdillon */ 89187557Sdillon { 89287557Sdillon int perc; 89387557Sdillon int req = 0; 89412661Speter 89587557Sdillon for (perc = 100; perc > 0; perc -= 5) { 89687557Sdillon req = 0; /* reset for each loop */ 89787557Sdillon if ((msg = try_auto_label(devs, dev, perc, &req)) == NULL) 89817362Sjkh break; 89915440Sjkh } 90087557Sdillon if (msg) { 90187557Sdillon if (req) { 90287557Sdillon msgConfirm(msg); 90318619Sjkh clear_wins(); 90487557Sdillon msg = NULL; 90517362Sjkh } 90615440Sjkh } 90710882Speter } 90815440Sjkh break; 90910882Speter 9108549Sjkh case 'C': 9118549Sjkh if (label_chunk_info[here].type != PART_SLICE) { 9128549Sjkh msg = "You can only do this in a master partition (see top of screen)"; 9138549Sjkh break; 9148549Sjkh } 9158549Sjkh sz = space_free(label_chunk_info[here].c); 9168669Sphk if (sz <= FS_MIN_SIZE) { 91712661Speter msg = "Not enough space to create an additional FreeBSD partition"; 9188669Sphk break; 9198669Sphk } 92015440Sjkh else { 92118744Sjkh char *val; 9228702Sjkh int size; 9238702Sjkh struct chunk *tmp; 9248820Sjkh char osize[80]; 9258702Sjkh u_long flags = 0; 9268549Sjkh 9278820Sjkh sprintf(osize, "%d", sz); 92818619Sjkh val = msgGetInput(osize, 92957617Sjkh "Please specify the partition size in blocks or append a trailing G for\n" 93057617Sjkh "gigabytes, M for megabytes, or C for cylinders.\n" 93157617Sjkh "%d blocks (%dMB) are free.", 93218619Sjkh sz, sz / ONE_MEG); 93318619Sjkh if (!val || (size = strtol(val, &cp, 0)) <= 0) { 93418619Sjkh clear_wins(); 9358702Sjkh break; 93618619Sjkh } 9378549Sjkh 9388751Sjkh if (*cp) { 9398751Sjkh if (toupper(*cp) == 'M') 9408751Sjkh size *= ONE_MEG; 94157617Sjkh else if (toupper(*cp) == 'G') 94257617Sjkh size *= ONE_GIG; 9438751Sjkh else if (toupper(*cp) == 'C') 9448751Sjkh size *= (label_chunk_info[here].c->disk->bios_hd * label_chunk_info[here].c->disk->bios_sect); 9458751Sjkh } 9468820Sjkh if (size <= FS_MIN_SIZE) { 9478820Sjkh msgConfirm("The minimum filesystem size is %dMB", FS_MIN_SIZE / ONE_MEG); 94818619Sjkh clear_wins(); 9498820Sjkh break; 9508820Sjkh } 9518702Sjkh type = get_partition_type(); 95218619Sjkh if (type == PART_NONE) { 95318619Sjkh clear_wins(); 95418619Sjkh beep(); 9558669Sphk break; 95618619Sjkh } 9578669Sphk 9588702Sjkh if (type == PART_FILESYSTEM) { 95918619Sjkh if ((p = get_mountpoint(NULL)) == NULL) { 96018619Sjkh clear_wins(); 96118619Sjkh beep(); 9628702Sjkh break; 96318619Sjkh } 9648702Sjkh else if (!strcmp(p->mountpoint, "/")) 9658702Sjkh flags |= CHUNK_IS_ROOT; 9668702Sjkh else 9678702Sjkh flags &= ~CHUNK_IS_ROOT; 96818619Sjkh } 96918619Sjkh else 9708702Sjkh p = NULL; 9718702Sjkh 97276237Sjkh if ((flags & CHUNK_IS_ROOT) && (size < (ROOT_MIN_SIZE * ONE_MEG))) { 97376237Sjkh msgConfirm("Warning: This is smaller than the recommended size for a\n" 97476237Sjkh "root partition. For a variety of reasons, root\n" 97576237Sjkh "partitions should usually be at least %dMB in size", ROOT_MIN_SIZE); 9768672Sjkh } 9778751Sjkh tmp = Create_Chunk_DWIM(label_chunk_info[here].c->disk, 9788702Sjkh label_chunk_info[here].c, 9798702Sjkh size, part, 9808702Sjkh (type == PART_SWAP) ? FS_SWAP : FS_BSDFFS, 9818702Sjkh flags); 9828702Sjkh if (!tmp) { 9838702Sjkh msgConfirm("Unable to create the partition. Too big?"); 98418619Sjkh clear_wins(); 9858672Sjkh break; 9868672Sjkh } 98779678Sobrien 98879678Sobrien#ifdef __alpha__ 98979678Sobrien /* 99079680Sobrien * SRM requires that the root partition is at the 99179678Sobrien * begining of the disk and cannot boot otherwise. 99279678Sobrien * Warn Alpha users if they are about to shoot themselves in 99379678Sobrien * the foot in this way. 99479678Sobrien * 99579678Sobrien * Since partitions may not start precisely at offset 0 we 99679678Sobrien * check for a "close to 0" instead. :-( 99779678Sobrien */ 99879678Sobrien if ((flags & CHUNK_IS_ROOT) && (tmp->offset > 1024)) { 99979680Sobrien msgConfirm("Your root partition `a' does not seem to be the first\n" 100079680Sobrien "partition. The Alpha's firmware can only boot from the\n" 100179680Sobrien "first partition. So it is unlikely that your current\n" 100279680Sobrien "disk layout will be bootable boot after installation.\n" 100379678Sobrien "\n" 100479678Sobrien "Please allocate the root partition before allocating\n" 100579678Sobrien "any others.\n"); 100679678Sobrien } 100779678Sobrien#endif /* alpha */ 100879678Sobrien 1009106826Sjhb tmp->private_data = p; 10108702Sjkh tmp->private_free = safe_free; 101174156Sjkh if (variable_cmp(DISK_LABELLED, "written")) 101243685Sjkh variable_set2(DISK_LABELLED, "yes", 0); 101330345Sjkh record_label_chunks(devs, dev); 101418619Sjkh clear_wins(); 101579678Sobrien /* This is where we assign focus to new label so it shows. */ 101629249Sjkh { 101729249Sjkh int i; 101829249Sjkh label_focus = -1; 101929249Sjkh for (i = 0; label_chunk_info[i].c; ++i) { 102029249Sjkh if (label_chunk_info[i].c == tmp) { 102129249Sjkh label_focus = i; 102229249Sjkh break; 102329249Sjkh } 102429249Sjkh } 102529249Sjkh if (label_focus == -1) 102629249Sjkh label_focus = i - 1; 102729249Sjkh } 10288549Sjkh } 10298549Sjkh break; 10308549Sjkh 103117397Sjkh case KEY_DC: 103288996Sdillon case 'R': /* recover space (delete w/ recover) */ 103388996Sdillon /* 103488996Sdillon * Delete the partition w/ space recovery. 103588996Sdillon */ 103688996Sdillon rflags = DELCHUNK_RECOVER; 103788996Sdillon /* fall through */ 10388549Sjkh case 'D': /* delete */ 10398549Sjkh if (label_chunk_info[here].type == PART_SLICE) { 10408549Sjkh msg = MSG_NOT_APPLICABLE; 10418549Sjkh break; 10428549Sjkh } 10438549Sjkh else if (label_chunk_info[here].type == PART_FAT) { 10448705Sjkh msg = "Use the Disk Partition Editor to delete DOS partitions"; 10458549Sjkh break; 10468549Sjkh } 104788996Sdillon Delete_Chunk2(label_chunk_info[here].c->disk, label_chunk_info[here].c, rflags); 104874156Sjkh if (variable_cmp(DISK_LABELLED, "written")) 104943685Sjkh variable_set2(DISK_LABELLED, "yes", 0); 105030345Sjkh record_label_chunks(devs, dev); 10518549Sjkh break; 10528549Sjkh 10538549Sjkh case 'M': /* mount */ 10548549Sjkh switch(label_chunk_info[here].type) { 10558549Sjkh case PART_SLICE: 10568549Sjkh msg = MSG_NOT_APPLICABLE; 10578549Sjkh break; 10588549Sjkh 10598549Sjkh case PART_SWAP: 10608549Sjkh msg = "You don't need to specify a mountpoint for a swap partition."; 10618549Sjkh break; 10628549Sjkh 10638556Sjkh case PART_FAT: 10648549Sjkh case PART_FILESYSTEM: 106514793Sjoerg oldp = label_chunk_info[here].c->private_data; 10668589Sjkh p = get_mountpoint(label_chunk_info[here].c); 10678549Sjkh if (p) { 10689202Srgrimes if (!oldp) 1069107565Srwatson p->do_newfs = FALSE; 10708722Sjkh if (label_chunk_info[here].type == PART_FAT 10718722Sjkh && (!strcmp(p->mountpoint, "/") || !strcmp(p->mountpoint, "/usr") 10728722Sjkh || !strcmp(p->mountpoint, "/var"))) { 10738722Sjkh msgConfirm("%s is an invalid mount point for a DOS partition!", p->mountpoint); 10748722Sjkh strcpy(p->mountpoint, "/bogus"); 10758722Sjkh } 10768549Sjkh } 107774156Sjkh if (variable_cmp(DISK_LABELLED, "written")) 107843685Sjkh variable_set2(DISK_LABELLED, "yes", 0); 107930345Sjkh record_label_chunks(devs, dev); 108018636Sjkh clear_wins(); 10818549Sjkh break; 10828549Sjkh 10838549Sjkh default: 10848549Sjkh msgFatal("Bogus partition under cursor???"); 10858549Sjkh break; 10868549Sjkh } 10878549Sjkh break; 10888549Sjkh 10898549Sjkh case 'N': /* Set newfs options */ 109014793Sjoerg if (label_chunk_info[here].c->private_data && 1091107565Srwatson ((PartInfo *)label_chunk_info[here].c->private_data)->do_newfs) 1092107565Srwatson getNewfsOptionalArguments( 1093107565Srwatson label_chunk_info[here].c->private_data); 10948549Sjkh else 10958549Sjkh msg = MSG_NOT_APPLICABLE; 109618636Sjkh clear_wins(); 10978549Sjkh break; 10988549Sjkh 109974086Sjkh case 'S': /* Toggle soft updates flag */ 110074086Sjkh if (label_chunk_info[here].type == PART_FILESYSTEM) { 110174086Sjkh PartInfo *pi = ((PartInfo *)label_chunk_info[here].c->private_data); 1102107565Srwatson if (pi != NULL && 1103107565Srwatson pi->newfs_type == NEWFS_UFS) 1104107565Srwatson pi->newfs_data.newfs_ufs.softupdates = 1105107565Srwatson !pi->newfs_data.newfs_ufs.softupdates; 110674086Sjkh else 110774086Sjkh msg = MSG_NOT_APPLICABLE; 110874086Sjkh } 110974156Sjkh else 111074156Sjkh msg = MSG_NOT_APPLICABLE; 111174086Sjkh break; 111274086Sjkh 11138549Sjkh case 'T': /* Toggle newfs state */ 111489968Smurray if ((label_chunk_info[here].type == PART_FILESYSTEM) && 111589968Smurray (label_chunk_info[here].c->private_data)) { 111623729Sjkh PartInfo *pi = ((PartInfo *)label_chunk_info[here].c->private_data); 1117107565Srwatson if (!pi->do_newfs) 111887581Sdillon label_chunk_info[here].c->flags |= CHUNK_NEWFS; 111987581Sdillon else 112087581Sdillon label_chunk_info[here].c->flags &= ~CHUNK_NEWFS; 112187581Sdillon 112223729Sjkh label_chunk_info[here].c->private_data = 1123107565Srwatson new_part(pi ? pi->mountpoint : NULL, pi ? !pi->do_newfs 1124107565Srwatson : TRUE); 1125107565Srwatson if (pi != NULL && 1126107565Srwatson pi->newfs_type == NEWFS_UFS) { 1127107565Srwatson PartInfo *pi_new = label_chunk_info[here].c->private_data; 1128107565Srwatson 1129107565Srwatson pi_new->newfs_data.newfs_ufs = pi->newfs_data.newfs_ufs; 1130107565Srwatson } 113123729Sjkh safe_free(pi); 113223729Sjkh label_chunk_info[here].c->private_free = safe_free; 113374156Sjkh if (variable_cmp(DISK_LABELLED, "written")) 113443685Sjkh variable_set2(DISK_LABELLED, "yes", 0); 113518619Sjkh } 1136106885Smarcel#if defined(__ia64__) 1137106885Smarcel else if (label_chunk_info[here].type == PART_FAT && 1138106885Smarcel label_chunk_info[here].c->type == efi && 1139106885Smarcel label_chunk_info[here].c->private_data) { 1140107565Srwatson PartInfo *pi = 1141107565Srwatson ((PartInfo *)label_chunk_info[here].c->private_data); 1142107565Srwatson 1143107565Srwatson if (!pi->do_newfs) 1144106885Smarcel label_chunk_info[here].c->flags |= CHUNK_NEWFS; 1145106885Smarcel else 1146106885Smarcel label_chunk_info[here].c->flags &= ~CHUNK_NEWFS; 1147106885Smarcel 1148106885Smarcel label_chunk_info[here].c->private_data = 1149107565Srwatson new_efi_part(pi->mountpoint, !pi->do_newfs); 1150106885Smarcel safe_free(pi); 1151106885Smarcel label_chunk_info[here].c->private_free = safe_free; 1152106885Smarcel if (variable_cmp(DISK_LABELLED, "written")) 1153106885Smarcel variable_set2(DISK_LABELLED, "yes", 0); 1154106885Smarcel } 1155106885Smarcel#endif 11568549Sjkh else 11578549Sjkh msg = MSG_NOT_APPLICABLE; 11588549Sjkh break; 11598549Sjkh 11608820Sjkh case 'U': 116112661Speter clear(); 116274156Sjkh if (!variable_cmp(DISK_LABELLED, "written")) { 116318744Sjkh msgConfirm("You've already written out your changes -\n" 116418744Sjkh "it's too late to undo!"); 116518744Sjkh } 116670005Sjkh else if (!msgNoYes("Are you SURE you want to Undo everything?")) { 116718744Sjkh variable_unset(DISK_PARTITIONED); 116818744Sjkh variable_unset(DISK_LABELLED); 116918744Sjkh for (i = 0; devs[i]; i++) { 117018744Sjkh Disk *d; 117112661Speter 117218744Sjkh if (!devs[i]->enabled) 117318744Sjkh continue; 117418744Sjkh else if ((d = Open_Disk(devs[i]->name)) != NULL) { 117518744Sjkh Free_Disk(devs[i]->private); 117618744Sjkh devs[i]->private = d; 1177107341Sjhb#ifdef WITH_SLICES 117830345Sjkh diskPartition(devs[i]); 1179107341Sjhb#endif 118018744Sjkh } 11818824Sjkh } 118230345Sjkh record_label_chunks(devs, dev); 11838824Sjkh } 118418636Sjkh clear_wins(); 11858824Sjkh break; 11868820Sjkh 11878549Sjkh case 'W': 118874156Sjkh if (!variable_cmp(DISK_LABELLED, "written")) { 118918744Sjkh msgConfirm("You've already written out your changes - if you\n" 119074156Sjkh "wish to overwrite them, you'll have to restart\n" 119174156Sjkh "sysinstall first."); 119218744Sjkh } 119370005Sjkh else if (!msgNoYes("WARNING: This should only be used when modifying an EXISTING\n" 119418687Sjkh "installation. If you are installing FreeBSD for the first time\n" 119518687Sjkh "then you should simply type Q when you're finished here and your\n" 119618687Sjkh "changes will be committed in one batch automatically at the end of\n" 119718687Sjkh "these questions.\n\n" 119818687Sjkh "Are you absolutely sure you want to do this now?")) { 119943685Sjkh variable_set2(DISK_LABELLED, "yes", 0); 120012661Speter diskLabelCommit(NULL); 120112661Speter } 120218636Sjkh clear_wins(); 120310882Speter break; 120410882Speter 1205107565Srwatson case 'Z': /* Set newfs command line */ 1206107565Srwatson if (label_chunk_info[here].c->private_data && 1207107565Srwatson ((PartInfo *)label_chunk_info[here].c->private_data)->do_newfs) 1208107565Srwatson getNewfsCmd(label_chunk_info[here].c->private_data); 1209107565Srwatson else 1210107565Srwatson msg = MSG_NOT_APPLICABLE; 1211107565Srwatson clear_wins(); 1212107565Srwatson break; 1213107565Srwatson 1214107565Srwatson 121510882Speter case '|': 121670005Sjkh if (!msgNoYes("Are you sure you want to go into Wizard mode?\n\n" 121712661Speter "This is an entirely undocumented feature which you are not\n" 121812661Speter "expected to understand!")) { 12198549Sjkh int i; 12208549Sjkh Device **devs; 12218549Sjkh 12228549Sjkh dialog_clear(); 12238549Sjkh end_dialog(); 12248549Sjkh DialogActive = FALSE; 12258549Sjkh devs = deviceFind(NULL, DEVICE_TYPE_DISK); 12268549Sjkh if (!devs) { 122712661Speter msgConfirm("Can't find any disk devices!"); 12288549Sjkh break; 12298549Sjkh } 12308668Sphk for (i = 0; devs[i] && ((Disk *)devs[i]->private); i++) { 12318613Sjkh if (devs[i]->enabled) 12328613Sjkh slice_wizard(((Disk *)devs[i]->private)); 12338613Sjkh } 123474156Sjkh if (variable_cmp(DISK_LABELLED, "written")) 123543685Sjkh variable_set2(DISK_LABELLED, "yes", 0); 12368665Sphk DialogActive = TRUE; 123730345Sjkh record_label_chunks(devs, dev); 123818636Sjkh clear_wins(); 12398549Sjkh } 12408549Sjkh else 12418549Sjkh msg = "A most prudent choice!"; 12428549Sjkh break; 12438549Sjkh 124421698Sjkh case '\033': /* ESC */ 12459202Srgrimes case 'Q': 12468549Sjkh labeling = FALSE; 12478549Sjkh break; 12488549Sjkh 12498549Sjkh default: 12508549Sjkh beep(); 125117362Sjkh sprintf(_msg, "Invalid key %d - Type F1 or ? for help", key); 125217362Sjkh msg = _msg; 12538549Sjkh break; 12548549Sjkh } 125529633Sjkh if (label_chunk_info[here].type == PART_SLICE) 125629633Sjkh pslice_focus = here; 125729633Sjkh else 125829633Sjkh label_focus = here; 12598549Sjkh } 126054587Sjkh restorescr(w); 126154587Sjkh return DITEM_SUCCESS; 12628549Sjkh} 126326456Sjkh 126487557Sdillonstatic __inline int 126587557Sdillonrequested_part_size(char *varName, int nom, int def, int perc) 126687557Sdillon{ 126787557Sdillon char *cp; 126887557Sdillon int sz; 126987557Sdillon 127098018Sjhb if ((cp = variable_get(varName)) != NULL) 127187557Sdillon sz = atoi(cp); 127287557Sdillon else 127387557Sdillon sz = nom + (def - nom) * perc / 100; 127487557Sdillon return(sz * ONE_MEG); 127587557Sdillon} 127687557Sdillon 127787557Sdillon/* 127887557Sdillon * Attempt to auto-label the disk. 'perc' (0-100) scales 127987557Sdillon * the size of the various partitions within appropriate 128087557Sdillon * bounds (NOMINAL through DEFAULT sizes). The procedure 128187557Sdillon * succeeds of NULL is returned. A non-null return message 128287557Sdillon * is either a failure-status message (*req == 0), or 128387557Sdillon * a confirmation requestor (*req == 1). *req is 0 on 128487557Sdillon * entry to this call. 128587557Sdillon * 128687583Sdillon * We autolabel the following partitions: /, swap, /var, /tmp, /usr, 128787557Sdillon * and /home. /home receives any extra left over disk space. 128887557Sdillon */ 128987557Sdillonstatic char * 129087557Sdillontry_auto_label(Device **devs, Device *dev, int perc, int *req) 129187557Sdillon{ 129287557Sdillon int sz; 129387557Sdillon struct chunk *root_chunk = NULL; 129487557Sdillon struct chunk *swap_chunk = NULL; 129587557Sdillon struct chunk *usr_chunk = NULL; 129687557Sdillon struct chunk *var_chunk = NULL; 129787581Sdillon struct chunk *tmp_chunk = NULL; 129887557Sdillon struct chunk *home_chunk = NULL; 129987557Sdillon int mib[2]; 1300106348Stmm unsigned long physmem; 130187557Sdillon size_t size; 130287557Sdillon Chunk *rootdev, *swapdev, *usrdev, *vardev; 130387581Sdillon Chunk *tmpdev, *homedev; 130487557Sdillon char *msg = NULL; 130587557Sdillon 130687557Sdillon sz = space_free(label_chunk_info[here].c); 130787557Sdillon if (sz <= FS_MIN_SIZE) 130887557Sdillon return("Not enough free space to create a new partition in the slice"); 130987557Sdillon 131087557Sdillon (void)checkLabels(FALSE, &rootdev, &swapdev, &usrdev, 131187581Sdillon &vardev, &tmpdev, &homedev); 131287557Sdillon if (!rootdev) { 131387557Sdillon sz = requested_part_size(VAR_ROOT_SIZE, ROOT_NOMINAL_SIZE, ROOT_DEFAULT_SIZE, perc); 131487557Sdillon 131587581Sdillon root_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, 131687581Sdillon label_chunk_info[here].c, sz, part, 131787581Sdillon FS_BSDFFS, CHUNK_IS_ROOT | CHUNK_AUTO_SIZE); 131887557Sdillon if (!root_chunk) { 131987557Sdillon *req = 1; 132087557Sdillon msg = "Unable to create the root partition. Too big?"; 132187557Sdillon goto done; 132287557Sdillon } 1323106826Sjhb root_chunk->private_data = new_part("/", TRUE); 132487557Sdillon root_chunk->private_free = safe_free; 132587581Sdillon root_chunk->flags |= CHUNK_NEWFS; 132687557Sdillon record_label_chunks(devs, dev); 132787557Sdillon } 132887557Sdillon if (!swapdev) { 132987557Sdillon sz = requested_part_size(VAR_SWAP_SIZE, 0, 0, perc); 133087557Sdillon if (sz == 0) { 133187557Sdillon int nom; 133287557Sdillon int def; 133387557Sdillon 133487557Sdillon mib[0] = CTL_HW; 133587557Sdillon mib[1] = HW_PHYSMEM; 133687557Sdillon size = sizeof physmem; 133787557Sdillon sysctl(mib, 2, &physmem, &size, (void *)0, (size_t)0); 133887557Sdillon def = 2 * (int)(physmem / 512); 133987557Sdillon if (def < SWAP_MIN_SIZE * ONE_MEG) 134087557Sdillon def = SWAP_MIN_SIZE * ONE_MEG; 134187557Sdillon if (def > SWAP_AUTO_LIMIT_SIZE * ONE_MEG) 134287557Sdillon def = SWAP_AUTO_LIMIT_SIZE * ONE_MEG; 134387557Sdillon nom = (int)(physmem / 512) / 2; 134487557Sdillon sz = nom + (def - nom) * perc / 100; 134587557Sdillon } 134687581Sdillon swap_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, 134787581Sdillon label_chunk_info[here].c, sz, part, 134887581Sdillon FS_SWAP, CHUNK_AUTO_SIZE); 134987557Sdillon if (!swap_chunk) { 135087557Sdillon *req = 1; 135187557Sdillon msg = "Unable to create the swap partition. Too big?"; 135287557Sdillon goto done; 135387557Sdillon } 135487557Sdillon swap_chunk->private_data = 0; 135587557Sdillon swap_chunk->private_free = safe_free; 135687557Sdillon record_label_chunks(devs, dev); 135787557Sdillon } 135887557Sdillon if (!vardev) { 135987557Sdillon sz = requested_part_size(VAR_VAR_SIZE, VAR_NOMINAL_SIZE, VAR_DEFAULT_SIZE, perc); 136087557Sdillon 136187581Sdillon var_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, 136287581Sdillon label_chunk_info[here].c, sz, part, 136387581Sdillon FS_BSDFFS, CHUNK_AUTO_SIZE); 136487557Sdillon if (!var_chunk) { 136587557Sdillon *req = 1; 136687557Sdillon msg = "Not enough free space for /var - you will need to\n" 136787557Sdillon "partition your disk manually with a custom install!"; 136887557Sdillon goto done; 136987557Sdillon } 1370106826Sjhb var_chunk->private_data = new_part("/var", TRUE); 137187557Sdillon var_chunk->private_free = safe_free; 137287581Sdillon var_chunk->flags |= CHUNK_NEWFS; 137387557Sdillon record_label_chunks(devs, dev); 137487557Sdillon } 137587583Sdillon if (!tmpdev && !variable_get(VAR_NO_TMP)) { 137687583Sdillon sz = requested_part_size(VAR_TMP_SIZE, TMP_NOMINAL_SIZE, TMP_DEFAULT_SIZE, perc); 137787557Sdillon 137887581Sdillon tmp_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, 137987581Sdillon label_chunk_info[here].c, sz, part, 138087581Sdillon FS_BSDFFS, CHUNK_AUTO_SIZE); 138187581Sdillon if (!tmp_chunk) { 138287557Sdillon *req = 1; 138387583Sdillon msg = "Not enough free space for /tmp - you will need to\n" 138487557Sdillon "partition your disk manually with a custom install!"; 138587557Sdillon goto done; 138687557Sdillon } 1387106826Sjhb tmp_chunk->private_data = new_part("/tmp", TRUE); 138887581Sdillon tmp_chunk->private_free = safe_free; 138987581Sdillon tmp_chunk->flags |= CHUNK_NEWFS; 139087557Sdillon record_label_chunks(devs, dev); 139187557Sdillon } 139287557Sdillon if (!usrdev && !variable_get(VAR_NO_USR)) { 139387557Sdillon sz = requested_part_size(VAR_USR_SIZE, USR_NOMINAL_SIZE, USR_DEFAULT_SIZE, perc); 139488996Sdillon#if AUTO_HOME == 0 139587557Sdillon sz = space_free(label_chunk_info[here].c); 139687557Sdillon#endif 139787557Sdillon if (sz) { 139887557Sdillon if (sz < (USR_MIN_SIZE * ONE_MEG)) { 139987557Sdillon *req = 1; 140087557Sdillon msg = "Not enough free space for /usr - you will need to\n" 140187557Sdillon "partition your disk manually with a custom install!"; 140287557Sdillon } 140387557Sdillon 140487557Sdillon usr_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, 140587581Sdillon label_chunk_info[here].c, sz, part, 140687581Sdillon FS_BSDFFS, CHUNK_AUTO_SIZE); 140787557Sdillon if (!usr_chunk) { 140887557Sdillon msg = "Unable to create the /usr partition. Not enough space?\n" 140987557Sdillon "You will need to partition your disk manually with a custom install!"; 141087557Sdillon goto done; 141187557Sdillon } 1412106826Sjhb usr_chunk->private_data = new_part("/usr", TRUE); 141387557Sdillon usr_chunk->private_free = safe_free; 141487581Sdillon usr_chunk->flags |= CHUNK_NEWFS; 141587557Sdillon record_label_chunks(devs, dev); 141687557Sdillon } 141787557Sdillon } 141888996Sdillon#if AUTO_HOME == 1 141987557Sdillon if (!homedev && !variable_get(VAR_NO_HOME)) { 142087557Sdillon sz = requested_part_size(VAR_HOME_SIZE, HOME_NOMINAL_SIZE, HOME_DEFAULT_SIZE, perc); 142187557Sdillon if (sz < space_free(label_chunk_info[here].c)) 142287557Sdillon sz = space_free(label_chunk_info[here].c); 142387557Sdillon if (sz) { 142487557Sdillon if (sz < (HOME_MIN_SIZE * ONE_MEG)) { 142587557Sdillon *req = 1; 142687557Sdillon msg = "Not enough free space for /home - you will need to\n" 142787557Sdillon "partition your disk manually with a custom install!"; 142887557Sdillon goto done; 142987557Sdillon } 143087557Sdillon 143187557Sdillon home_chunk = Create_Chunk_DWIM(label_chunk_info[here].c->disk, 143287581Sdillon label_chunk_info[here].c, sz, part, 143387581Sdillon FS_BSDFFS, CHUNK_AUTO_SIZE); 143487557Sdillon if (!home_chunk) { 143587557Sdillon msg = "Unable to create the /home partition. Not enough space?\n" 143687557Sdillon "You will need to partition your disk manually with a custom install!"; 143787557Sdillon goto done; 143887557Sdillon } 1439106826Sjhb home_chunk->private_data = new_part("/home", TRUE); 144087557Sdillon home_chunk->private_free = safe_free; 144187581Sdillon home_chunk->flags |= CHUNK_NEWFS; 144287557Sdillon record_label_chunks(devs, dev); 144387557Sdillon } 144487557Sdillon } 144588996Sdillon#endif 144687557Sdillon 144787557Sdillon /* At this point, we're reasonably "labelled" */ 144887557Sdillon if (variable_cmp(DISK_LABELLED, "written")) 144987557Sdillon variable_set2(DISK_LABELLED, "yes", 0); 145087557Sdillon 145187557Sdillondone: 145287557Sdillon if (msg) { 145387557Sdillon if (root_chunk) 145487557Sdillon Delete_Chunk(root_chunk->disk, root_chunk); 145587557Sdillon if (swap_chunk) 145687557Sdillon Delete_Chunk(swap_chunk->disk, swap_chunk); 145787557Sdillon if (var_chunk) 145887557Sdillon Delete_Chunk(var_chunk->disk, var_chunk); 145987581Sdillon if (tmp_chunk) 146087581Sdillon Delete_Chunk(tmp_chunk->disk, tmp_chunk); 146187557Sdillon if (usr_chunk) 146287557Sdillon Delete_Chunk(usr_chunk->disk, usr_chunk); 146387557Sdillon if (home_chunk) 146487557Sdillon Delete_Chunk(home_chunk->disk, home_chunk); 146587557Sdillon record_label_chunks(devs, dev); 146687557Sdillon } 146787557Sdillon return(msg); 146887557Sdillon} 146987557Sdillon 147026456Sjkhstatic int 147130345SjkhdiskLabelNonInteractive(Device *dev) 147226456Sjkh{ 147326456Sjkh char *cp; 147426456Sjkh PartType type; 147526456Sjkh PartInfo *p; 1476106830Sjhb u_long flags; 147726456Sjkh int i, status; 147826456Sjkh Device **devs; 147926456Sjkh Disk *d; 148054587Sjkh 148126456Sjkh status = DITEM_SUCCESS; 148226456Sjkh cp = variable_get(VAR_DISK); 148326456Sjkh if (!cp) { 148426456Sjkh msgConfirm("diskLabel: No disk selected - can't label automatically."); 148526456Sjkh return DITEM_FAILURE; 148626456Sjkh } 148726456Sjkh devs = deviceFind(cp, DEVICE_TYPE_DISK); 148826456Sjkh if (!devs) { 148926456Sjkh msgConfirm("diskLabel: No disk device %s found!", cp); 149026456Sjkh return DITEM_FAILURE; 149126456Sjkh } 149230345Sjkh if (dev) 149330345Sjkh d = dev->private; 149430345Sjkh else 149530345Sjkh d = devs[0]->private; 149630345Sjkh record_label_chunks(devs, dev); 149726456Sjkh for (i = 0; label_chunk_info[i].c; i++) { 149826456Sjkh Chunk *c1 = label_chunk_info[i].c; 149926456Sjkh 150026456Sjkh if (label_chunk_info[i].type == PART_SLICE) { 150128075Sjkh char name[512]; 1502106827Sjhb char typ[10], mpoint[50]; 1503106827Sjhb int entries; 150426456Sjkh 1505106827Sjhb for (entries = 1;; entries++) { 1506106827Sjhb int sz, soft = 0; 150728075Sjkh snprintf(name, sizeof name, "%s-%d", c1->name, entries); 1508106827Sjhb if ((cp = variable_get(name)) == NULL) 1509106827Sjhb break; 1510106827Sjhb if (sscanf(cp, "%s %d %s %d", typ, &sz, mpoint, &soft) < 3) { 1511106827Sjhb msgConfirm("For slice entry %s, got an invalid detail entry of: %s", c1->name, cp); 1512106827Sjhb status = DITEM_FAILURE; 1513106827Sjhb break; 1514106827Sjhb } else { 1515106827Sjhb Chunk *tmp; 151626456Sjkh 1517106830Sjhb flags = 0; 1518106827Sjhb if (!strcmp(typ, "swap")) { 1519106827Sjhb type = PART_SWAP; 1520106827Sjhb strcpy(mpoint, "SWAP"); 1521106827Sjhb } else { 1522106827Sjhb type = PART_FILESYSTEM; 1523106827Sjhb if (!strcmp(mpoint, "/")) 1524106827Sjhb flags |= CHUNK_IS_ROOT; 1525106827Sjhb } 1526106827Sjhb if (!sz) 1527106827Sjhb sz = space_free(c1); 1528106827Sjhb if (sz > space_free(c1)) { 1529106827Sjhb msgConfirm("Not enough free space to create partition: %s", mpoint); 153026456Sjkh status = DITEM_FAILURE; 1531106827Sjhb break; 153226456Sjkh } 1533106827Sjhb if (!(tmp = Create_Chunk_DWIM(d, c1, sz, part, 1534106827Sjhb (type == PART_SWAP) ? FS_SWAP : FS_BSDFFS, flags))) { 1535106827Sjhb msgConfirm("Unable to create from partition spec: %s. Too big?", cp); 1536106827Sjhb status = DITEM_FAILURE; 1537106827Sjhb break; 1538106827Sjhb } else { 1539107565Srwatson PartInfo *pi; 1540107565Srwatson pi = tmp->private_data = new_part(mpoint, TRUE); 1541106827Sjhb tmp->private_free = safe_free; 1542107565Srwatson pi->newfs_data.newfs_ufs.softupdates = soft; 154326456Sjkh } 154426456Sjkh } 154526456Sjkh } 1546106827Sjhb } else { 154728075Sjkh /* Must be something we can set a mountpoint for */ 154826456Sjkh cp = variable_get(c1->name); 154926456Sjkh if (cp) { 155028075Sjkh char mpoint[50], do_newfs[8]; 155126456Sjkh Boolean newfs = FALSE; 155226456Sjkh 155328075Sjkh do_newfs[0] = '\0'; 155428075Sjkh if (sscanf(cp, "%s %s", mpoint, do_newfs) != 2) { 155526456Sjkh msgConfirm("For slice entry %s, got an invalid detail entry of: %s", c1->name, cp); 155626456Sjkh status = DITEM_FAILURE; 1557106828Sjhb break; 155826456Sjkh } 155928075Sjkh newfs = toupper(do_newfs[0]) == 'Y' ? TRUE : FALSE; 156026456Sjkh if (c1->private_data) { 156126456Sjkh p = c1->private_data; 1562107565Srwatson p->do_newfs = newfs; 156326456Sjkh strcpy(p->mountpoint, mpoint); 156426456Sjkh } 156526456Sjkh else { 1566106826Sjhb c1->private_data = new_part(mpoint, newfs); 156726456Sjkh c1->private_free = safe_free; 156826456Sjkh } 156926456Sjkh if (!strcmp(mpoint, "/")) 157026456Sjkh c1->flags |= CHUNK_IS_ROOT; 157126456Sjkh else 157226456Sjkh c1->flags &= ~CHUNK_IS_ROOT; 157326456Sjkh } 157426456Sjkh } 157526456Sjkh } 157626456Sjkh if (status == DITEM_SUCCESS) 157743685Sjkh variable_set2(DISK_LABELLED, "yes", 0); 157826456Sjkh return status; 157926456Sjkh} 1580