diff options
-rw-r--r-- | usr.sbin/sade/help/partition.hlp | 27 | ||||
-rw-r--r-- | usr.sbin/sade/install.c | 91 | ||||
-rw-r--r-- | usr.sbin/sade/label.c | 200 | ||||
-rw-r--r-- | usr.sbin/sade/sade.h | 37 | ||||
-rw-r--r-- | usr.sbin/sysinstall/help/partition.hlp | 27 | ||||
-rw-r--r-- | usr.sbin/sysinstall/install.c | 91 | ||||
-rw-r--r-- | usr.sbin/sysinstall/label.c | 200 | ||||
-rw-r--r-- | usr.sbin/sysinstall/sysinstall.h | 37 |
8 files changed, 572 insertions, 138 deletions
diff --git a/usr.sbin/sade/help/partition.hlp b/usr.sbin/sade/help/partition.hlp index ef328df0e3c4..19cfb5abc592 100644 --- a/usr.sbin/sade/help/partition.hlp +++ b/usr.sbin/sade/help/partition.hlp @@ -126,6 +126,33 @@ with significant activity can temporarily overflow if the soft updates policy results in free'd blocks not being "garbage collected" as fast as they're being requested. +To make use of UFS2, press '2' on a UFS file system to toggle the +on-disk format revision. UFS2 provides native support for extended +attributes, larger disk sizes, and forward compatibility with new +on-disk high performance directory layout and storage extents. +However, UFS2 is unsupported on versions of FreeBSD prior to 5.0, +so it is not recommended for environments requiring backward +compatibility. Also, UFS2 is not currently recommended as a root +file system format for non-64-bit platforms due to increased size +of the boot loader; special local configuration is required to boot +UFS2 as a root file system on i386 and PC98. + +To add additional flags to the newfs command line for UFS file +systems, press 'N'. These options will be specified before the +device argument of the command line, but after any other options +placed there by sysinstall, such as the UFS version and soft +updates flag; as such, arguments provided may override existing +settings. To completely replace the newfs command used by +sysinstall, press 'Z' to convert a partition to a Custom +partition type. Sysinstall will prompt you with the newfs +command line that it would have used based on existing settings +prior to the change, but allow you to modify any aspect of the +command line. Once a partition has been converted to a custom +partition in the label editor, you will need to restart the +labeling process or delete and recreate the partition to restore +it to a non-custom state. Custom partitions are represented by +the letters "CST" instead of "UFS" or "FAT. + When you're done, type `Q' to exit. No actual changes will be made to the disk until you (C)ommit from the diff --git a/usr.sbin/sade/install.c b/usr.sbin/sade/install.c index 9862e5627a79..e1763ec8b424 100644 --- a/usr.sbin/sade/install.c +++ b/usr.sbin/sade/install.c @@ -50,6 +50,7 @@ #undef MSDOSFS #include <sys/stat.h> #include <sys/sysctl.h> +#include <limits.h> #include <unistd.h> #include <termios.h> @@ -878,6 +879,44 @@ installFixupXFree(dialogMenuItem *self) return DITEM_SUCCESS | DITEM_RESTORE; } +#define QUEUE_YES 1 +#define QUEUE_NO 0 +static int +performNewfs(PartInfo *pi, char *dname, int queue) +{ + char buffer[LINE_MAX]; + + if (pi->do_newfs) { + switch(pi->newfs_type) { + case NEWFS_UFS: + snprintf(buffer, LINE_MAX, "%s %s %s %s %s", + NEWFS_UFS_CMD, + pi->newfs_data.newfs_ufs.softupdates ? "-U" : "", + pi->newfs_data.newfs_ufs.ufs2 ? "-O2" : "-O1", + pi->newfs_data.newfs_ufs.user_options, + dname); + break; + + case NEWFS_MSDOS: + snprintf(buffer, LINE_MAX, "%s %s", NEWFS_MSDOS_CMD, + dname); + break; + + case NEWFS_CUSTOM: + snprintf(buffer, LINE_MAX, "%s %s", + pi->newfs_data.newfs_custom.command, dname); + break; + } + + if (queue == QUEUE_YES) { + command_shell_add(pi->mountpoint, buffer); + return (0); + } else + return (vsystem(buffer)); + } + return (0); +} + /* Go newfs and/or mount all the filesystems we've been asked to */ int installFilesystems(dialogMenuItem *self) @@ -940,12 +979,14 @@ installFilesystems(dialogMenuItem *self) if (strcmp(root->mountpoint, "/")) msgConfirm("Warning: %s is marked as a root partition but is mounted on %s", rootdev->name, root->mountpoint); - if (root->newfs && (!upgrade || !msgNoYes("You are upgrading - are you SURE you want to newfs the root partition?"))) { + if (root->do_newfs && (!upgrade || + !msgNoYes("You are upgrading - are you SURE you want to newfs " + "the root partition?"))) { int i; dialog_clear_norefresh(); msgNotify("Making a new root filesystem on %s", dname); - i = vsystem("%s %s", root->newfs_cmd, dname); + i = performNewfs(root, dname, QUEUE_NO); if (i) { msgConfirm("Unable to make new root filesystem on %s!\n" "Command returned status %d", dname, i); @@ -964,10 +1005,17 @@ installFilesystems(dialogMenuItem *self) msgConfirm("Warning: fsck returned status of %d for %s.\n" "This partition may be unsafe to use.", i, dname); } - if (root->soft) { - i = vsystem("tunefs -n enable %s", dname); - if (i) - msgConfirm("Warning: Unable to enable softupdates for root filesystem on %s", dname); + + /* + * If soft updates was enabled in the editor but we didn't newfs, + * use tunefs to update the soft updates flag on the file system. + */ + if (!root->do_newfs && root->newfs_type == NEWFS_UFS && + root->newfs_data.newfs_ufs.softupdates) { + i = vsystem("tunefs -n enable %s", dname); + if (i) + msgConfirm("Warning: Unable to enable soft updates" + " for root file system on %s", dname); } /* Switch to block device */ @@ -1021,12 +1069,23 @@ installFilesystems(dialogMenuItem *self) if (c2 == rootdev) continue; - if (tmp->newfs && (!upgrade || !msgNoYes("You are upgrading - are you SURE you want to newfs /dev/%s?", c2->name))) - command_shell_add(tmp->mountpoint, "%s %s/dev/%s", tmp->newfs_cmd, RunningAsInit ? "/mnt" : "", c2->name); + sprintf(dname, "%s/dev/%s", + RunningAsInit ? "/mnt" : "", c2->name); + + if (tmp->do_newfs && (!upgrade || + !msgNoYes("You are upgrading - are you SURE you" + " want to newfs /dev/%s?", c2->name))) + performNewfs(tmp, dname, QUEUE_YES); else - command_shell_add(tmp->mountpoint, "fsck_ffs -y %s/dev/%s", RunningAsInit ? "/mnt" : "", c2->name); + command_shell_add(tmp->mountpoint, + "fsck_ffs -y %s/dev/%s", RunningAsInit ? + "/mnt" : "", c2->name); +#if 0 if (tmp->soft) - command_shell_add(tmp->mountpoint, "tunefs -n enable %s/dev/%s", RunningAsInit ? "/mnt" : "", c2->name); + command_shell_add(tmp->mountpoint, + "tunefs -n enable %s/dev/%s", RunningAsInit ? + "/mnt" : "", c2->name); +#endif command_func_add(tmp->mountpoint, Mount, c2->name); } else if (c2->type == part && c2->subtype == FS_SWAP) { @@ -1047,7 +1106,8 @@ installFilesystems(dialogMenuItem *self) } } } - else if (c1->type == fat && c1->private_data && (root->newfs || upgrade)) { + else if (c1->type == fat && c1->private_data && + (root->do_newfs || upgrade)) { char name[FILENAME_MAX]; sprintf(name, "%s/%s", RunningAsInit ? "/mnt" : "", ((PartInfo *)c1->private_data)->mountpoint); @@ -1059,8 +1119,13 @@ installFilesystems(dialogMenuItem *self) PartInfo *pi = (PartInfo *)c1->private_data; char *p; - if (pi->newfs && (!upgrade || !msgNoYes("You are upgrading - are you SURE you want to newfs /dev/%s?", c1->name))) - command_shell_add(pi->mountpoint, "%s %s/dev/%s", pi->newfs_cmd, RunningAsInit ? "/mnt" : "", c1->name); + sprintf(dname, "%s/dev/%s", RunningAsInit ? "/mnt" : "", + c1->name); + + if (pi->do_newfs && (!upgrade || + !msgNoYes("You are upgrading - are you SURE you want to " + "newfs /dev/%s?", c1->name))) + performNewfs(pi, dname, QUEUE_YES); command_func_add(pi->mountpoint, Mount_msdosfs, c1->name); diff --git a/usr.sbin/sade/label.c b/usr.sbin/sade/label.c index 7964545a50d8..860e16a5a3f4 100644 --- a/usr.sbin/sade/label.c +++ b/usr.sbin/sade/label.c @@ -322,36 +322,42 @@ record_label_chunks(Device **devs, Device *dev) static PartInfo * new_part(char *mpoint, Boolean newfs) { - PartInfo *ret; + PartInfo *pi; if (!mpoint) mpoint = "/change_me"; - ret = (PartInfo *)safe_malloc(sizeof(PartInfo)); - sstrncpy(ret->mountpoint, mpoint, FILENAME_MAX); - strcpy(ret->newfs_cmd, "newfs "); - strcat(ret->newfs_cmd, variable_get(VAR_NEWFS_ARGS)); - ret->newfs = newfs; - ret->soft = strcmp(mpoint, "/") ? 1 : 0; - return ret; + pi = (PartInfo *)safe_malloc(sizeof(PartInfo)); + sstrncpy(pi->mountpoint, mpoint, FILENAME_MAX); + + pi->do_newfs = newfs; + + pi->newfs_type = NEWFS_UFS; + strcpy(pi->newfs_data.newfs_ufs.user_options, ""); + pi->newfs_data.newfs_ufs.acls = FALSE; + pi->newfs_data.newfs_ufs.multilabel = FALSE; + pi->newfs_data.newfs_ufs.softupdates = strcmp(mpoint, "/"); + pi->newfs_data.newfs_ufs.ufs2 = FALSE; + + return pi; } #if defined(__ia64__) static PartInfo * new_efi_part(char *mpoint, Boolean newfs) { - PartInfo *ret; + PartInfo *pi; if (!mpoint) mpoint = "/efi"; - ret = (PartInfo *)safe_malloc(sizeof(PartInfo)); - sstrncpy(ret->mountpoint, mpoint, FILENAME_MAX); - /* XXX */ - strcpy(ret->newfs_cmd, "newfs_msdos "); - ret->newfs = newfs; - ret->soft = 0; - return ret; + pi = (PartInfo *)safe_malloc(sizeof(PartInfo)); + sstrncpy(pi->mountpoint, mpoint, FILENAME_MAX); + + pi->do_newfs = newfs; + pi->newfs_type = NEWFS_MSDOS; + + return pi; } #endif @@ -404,7 +410,7 @@ get_mountpoint(struct chunk *old) newfs = TRUE; if (tmp) { - newfs = tmp->newfs; + newfs = tmp->do_newfs; safe_free(tmp); } val = string_skipwhite(string_prune(val)); @@ -448,13 +454,49 @@ get_partition_type(void) static void getNewfsCmd(PartInfo *p) { + char buffer[NEWFS_CMD_ARGS_MAX]; char *val; - val = msgGetInput(p->newfs_cmd, - "Please enter the newfs command and options you'd like to use in\n" - "creating this file system."); - if (val) - sstrncpy(p->newfs_cmd, val, NEWFS_CMD_MAX); + switch (p->newfs_type) { + case NEWFS_UFS: + snprintf(buffer, NEWFS_CMD_ARGS_MAX, "%s %s %s %s", + NEWFS_UFS_CMD, p->newfs_data.newfs_ufs.softupdates ? "-U" : "", + p->newfs_data.newfs_ufs.ufs2 ? "-O2" : "-O1", + p->newfs_data.newfs_ufs.user_options); + break; + case NEWFS_MSDOS: + snprintf(buffer, NEWFS_CMD_ARGS_MAX, "%s", NEWFS_MSDOS_CMD); + break; + case NEWFS_CUSTOM: + strcpy(buffer, p->newfs_data.newfs_custom.command); + break; + } + + val = msgGetInput(buffer, + "Please enter the newfs command and options you'd like to use in\n" + "creating this file system."); + if (val != NULL) { + p->newfs_type = NEWFS_CUSTOM; + strlcpy(p->newfs_data.newfs_custom.command, val, NEWFS_CMD_ARGS_MAX); + } +} + +static void +getNewfsOptionalArguments(PartInfo *p) +{ + char buffer[NEWFS_CMD_ARGS_MAX]; + char *val; + + /* Must be UFS, per argument checking in I/O routines. */ + + strlcpy(buffer, p->newfs_data.newfs_ufs.user_options, + NEWFS_CMD_ARGS_MAX); + val = msgGetInput(buffer, + "Please enter any additional UFS newfs options you'd like to\n" + "use in creating this file system."); + if (val != NULL) + strlcpy(p->newfs_data.newfs_ufs.user_options, val, + NEWFS_CMD_ARGS_MAX); } #define MAX_MOUNT_NAME 9 @@ -473,7 +515,7 @@ getNewfsCmd(PartInfo *p) static void print_label_chunks(void) { - int i, j, srow, prow, pcol; + int i, j, spaces, srow, prow, pcol; int sz; char clrmsg[80]; int ChunkPartStartRow; @@ -581,7 +623,7 @@ print_label_chunks(void) } /* Otherwise it's a DOS, swap or filesystem entry in the Chunk window */ else { - char onestr[PART_OFF], num[10], *mountpoint, newfs[10]; + char onestr[PART_OFF], num[10], *mountpoint, newfs[12]; /* * We copy this into a blank-padded string so that it looks like @@ -626,18 +668,34 @@ print_label_chunks(void) label_chunk_info[i].c->type == efi) { strcat(newfs, " "); PartInfo *pi = (PartInfo *)label_chunk_info[i].c->private_data; - strcat(newfs, pi->newfs ? " Y" : " N"); + strcat(newfs, pi->do_newfs ? " Y" : " N"); } #endif } else if (label_chunk_info[i].c->private_data && label_chunk_info[i].type == PART_FILESYSTEM) { - strcpy(newfs, "UFS"); - strcat(newfs, - ((PartInfo *)label_chunk_info[i].c->private_data)->soft ? - "+S" : " "); - strcat(newfs, - ((PartInfo *)label_chunk_info[i].c->private_data)->newfs ? - " Y" : " N"); + PartInfo *pi = (PartInfo *)label_chunk_info[i].c->private_data; + + switch (pi->newfs_type) { + case NEWFS_UFS: + strcpy(newfs, NEWFS_UFS_STRING); + if (pi->newfs_data.newfs_ufs.ufs2) + strcat(newfs, "2"); + else + strcat(newfs, "1"); + if (pi->newfs_data.newfs_ufs.softupdates) + strcat(newfs, "+S"); + else + strcat(newfs, " "); + + break; + case NEWFS_MSDOS: + strcpy(newfs, "FAT"); + break; + case NEWFS_CUSTOM: + strcpy(newfs, "CUST"); + break; + } + strcat(newfs, pi->do_newfs ? " Y" : " N "); } else if (label_chunk_info[i].type == PART_SWAP) strcpy(newfs, "SWAP"); @@ -695,9 +753,9 @@ print_command_summary(void) mvprintw(17, 0, "The following commands are valid here (upper or lower case):"); mvprintw(18, 0, "C = Create D = Delete M = Mount pt."); if (!RunningAsInit) - mvprintw(18, 47, "W = Write"); - mvprintw(19, 0, "N = Newfs Opts Q = Finish S = Toggle SoftUpdates"); - mvprintw(20, 0, "T = Toggle Newfs U = Undo A = Auto Defaults R = Delete+Merge"); + mvprintw(18, 56, "W = Write"); + mvprintw(19, 0, "N = Newfs Opts Q = Finish S = Toggle SoftUpdates Z = Custom Newfs"); + mvprintw(20, 0, "T = Toggle Newfs U = Undo A = Auto Defaults R = Delete+Merge"); mvprintw(22, 0, "Use F1 or ? to get more help, arrow keys to select."); move(0, 0); } @@ -799,6 +857,27 @@ diskLabel(Device *dev) clear_wins(); break; + case '2': + if (label_chunk_info[here].type == PART_FILESYSTEM) { + PartInfo *pi = + ((PartInfo *)label_chunk_info[here].c->private_data); + + if ((pi != NULL) && + (pi->newfs_type == NEWFS_UFS)) { +#ifdef __i386__ + if (label_chunk_info[here].c->flags & CHUNK_IS_ROOT) + msg = MSG_NOT_APPLICABLE; + else +#endif + pi->newfs_data.newfs_ufs.ufs2 = + !pi->newfs_data.newfs_ufs.ufs2; + } else + msg = MSG_NOT_APPLICABLE; + } else + msg = MSG_NOT_APPLICABLE; + break; + break; + case 'A': if (label_chunk_info[here].type != PART_SLICE) { msg = "You can only do this in a disk slice (at top of screen)"; @@ -987,7 +1066,7 @@ diskLabel(Device *dev) p = get_mountpoint(label_chunk_info[here].c); if (p) { if (!oldp) - p->newfs = FALSE; + p->do_newfs = FALSE; if (label_chunk_info[here].type == PART_FAT && (!strcmp(p->mountpoint, "/") || !strcmp(p->mountpoint, "/usr") || !strcmp(p->mountpoint, "/var"))) { @@ -1009,8 +1088,9 @@ diskLabel(Device *dev) case 'N': /* Set newfs options */ if (label_chunk_info[here].c->private_data && - ((PartInfo *)label_chunk_info[here].c->private_data)->newfs) - getNewfsCmd(label_chunk_info[here].c->private_data); + ((PartInfo *)label_chunk_info[here].c->private_data)->do_newfs) + getNewfsOptionalArguments( + label_chunk_info[here].c->private_data); else msg = MSG_NOT_APPLICABLE; clear_wins(); @@ -1019,8 +1099,10 @@ diskLabel(Device *dev) case 'S': /* Toggle soft updates flag */ if (label_chunk_info[here].type == PART_FILESYSTEM) { PartInfo *pi = ((PartInfo *)label_chunk_info[here].c->private_data); - if (pi) - pi->soft = !pi->soft; + if (pi != NULL && + pi->newfs_type == NEWFS_UFS) + pi->newfs_data.newfs_ufs.softupdates = + !pi->newfs_data.newfs_ufs.softupdates; else msg = MSG_NOT_APPLICABLE; } @@ -1032,15 +1114,20 @@ diskLabel(Device *dev) if ((label_chunk_info[here].type == PART_FILESYSTEM) && (label_chunk_info[here].c->private_data)) { PartInfo *pi = ((PartInfo *)label_chunk_info[here].c->private_data); - if (!pi->newfs) + if (!pi->do_newfs) label_chunk_info[here].c->flags |= CHUNK_NEWFS; else label_chunk_info[here].c->flags &= ~CHUNK_NEWFS; label_chunk_info[here].c->private_data = - new_part(pi ? pi->mountpoint : NULL, pi ? !pi->newfs : TRUE); - if (pi && pi->soft) - ((PartInfo *)label_chunk_info[here].c->private_data)->soft = 1; + new_part(pi ? pi->mountpoint : NULL, pi ? !pi->do_newfs + : TRUE); + if (pi != NULL && + pi->newfs_type == NEWFS_UFS) { + PartInfo *pi_new = label_chunk_info[here].c->private_data; + + pi_new->newfs_data.newfs_ufs = pi->newfs_data.newfs_ufs; + } safe_free(pi); label_chunk_info[here].c->private_free = safe_free; if (variable_cmp(DISK_LABELLED, "written")) @@ -1050,14 +1137,16 @@ diskLabel(Device *dev) else if (label_chunk_info[here].type == PART_FAT && label_chunk_info[here].c->type == efi && label_chunk_info[here].c->private_data) { - PartInfo *pi = ((PartInfo *)label_chunk_info[here].c->private_data); - if (!pi->newfs) + PartInfo *pi = + ((PartInfo *)label_chunk_info[here].c->private_data); + + if (!pi->do_newfs) label_chunk_info[here].c->flags |= CHUNK_NEWFS; else label_chunk_info[here].c->flags &= ~CHUNK_NEWFS; label_chunk_info[here].c->private_data = - new_efi_part(pi->mountpoint, !pi->newfs); + new_efi_part(pi->mountpoint, !pi->do_newfs); safe_free(pi); label_chunk_info[here].c->private_free = safe_free; if (variable_cmp(DISK_LABELLED, "written")) @@ -1113,6 +1202,16 @@ diskLabel(Device *dev) clear_wins(); break; + case 'Z': /* Set newfs command line */ + if (label_chunk_info[here].c->private_data && + ((PartInfo *)label_chunk_info[here].c->private_data)->do_newfs) + getNewfsCmd(label_chunk_info[here].c->private_data); + else + msg = MSG_NOT_APPLICABLE; + clear_wins(); + break; + + case '|': if (!msgNoYes("Are you sure you want to go into Wizard mode?\n\n" "This is an entirely undocumented feature which you are not\n" @@ -1437,9 +1536,10 @@ diskLabelNonInteractive(Device *dev) status = DITEM_FAILURE; break; } else { - tmp->private_data = new_part(mpoint, TRUE); + PartInfo *pi; + pi = tmp->private_data = new_part(mpoint, TRUE); tmp->private_free = safe_free; - ((PartInfo *)tmp->private_data)->soft = soft; + pi->newfs_data.newfs_ufs.softupdates = soft; } } } @@ -1459,7 +1559,7 @@ diskLabelNonInteractive(Device *dev) newfs = toupper(do_newfs[0]) == 'Y' ? TRUE : FALSE; if (c1->private_data) { p = c1->private_data; - p->newfs = newfs; + p->do_newfs = newfs; strcpy(p->mountpoint, mpoint); } else { diff --git a/usr.sbin/sade/sade.h b/usr.sbin/sade/sade.h index 1a0e20a7b94c..7ed0fab78be8 100644 --- a/usr.sbin/sade/sade.h +++ b/usr.sbin/sade/sade.h @@ -308,14 +308,39 @@ typedef enum { PART_FAT, } PartType; -/* The longest newfs command we'll hand to system() */ -#define NEWFS_CMD_MAX 256 +#define NEWFS_UFS_CMD "newfs" +#define NEWFS_MSDOS_CMD "newfs_msdos" + +enum newfs_type { NEWFS_UFS, NEWFS_MSDOS, NEWFS_CUSTOM }; +#define NEWFS_UFS_STRING "UFS" +#define NEWFS_MSDOS_STRING "FAT" +#define NEWFS_CUSTOM_STRING "CST" + +/* The longest set of custom command line arguments we'll pass. */ +#define NEWFS_CMD_ARGS_MAX 256 typedef struct _part_info { - Boolean newfs; - char mountpoint[FILENAME_MAX]; - char newfs_cmd[NEWFS_CMD_MAX]; - int soft; + char mountpoint[FILENAME_MAX]; + + /* Is invocation of newfs desired? */ + Boolean do_newfs; + + enum newfs_type newfs_type; + union { + struct { + char user_options[NEWFS_CMD_ARGS_MAX]; + Boolean acls; /* unused */ + Boolean multilabel; /* unused */ + Boolean softupdates; + Boolean ufs2; + } newfs_ufs; + struct { + /* unused */ + } newfs_msdos; + struct { + char command[NEWFS_CMD_ARGS_MAX]; + } newfs_custom; + } newfs_data; } PartInfo; /* An option */ diff --git a/usr.sbin/sysinstall/help/partition.hlp b/usr.sbin/sysinstall/help/partition.hlp index ef328df0e3c4..19cfb5abc592 100644 --- a/usr.sbin/sysinstall/help/partition.hlp +++ b/usr.sbin/sysinstall/help/partition.hlp @@ -126,6 +126,33 @@ with significant activity can temporarily overflow if the soft updates policy results in free'd blocks not being "garbage collected" as fast as they're being requested. +To make use of UFS2, press '2' on a UFS file system to toggle the +on-disk format revision. UFS2 provides native support for extended +attributes, larger disk sizes, and forward compatibility with new +on-disk high performance directory layout and storage extents. +However, UFS2 is unsupported on versions of FreeBSD prior to 5.0, +so it is not recommended for environments requiring backward +compatibility. Also, UFS2 is not currently recommended as a root +file system format for non-64-bit platforms due to increased size +of the boot loader; special local configuration is required to boot +UFS2 as a root file system on i386 and PC98. + +To add additional flags to the newfs command line for UFS file +systems, press 'N'. These options will be specified before the +device argument of the command line, but after any other options +placed there by sysinstall, such as the UFS version and soft +updates flag; as such, arguments provided may override existing +settings. To completely replace the newfs command used by +sysinstall, press 'Z' to convert a partition to a Custom +partition type. Sysinstall will prompt you with the newfs +command line that it would have used based on existing settings +prior to the change, but allow you to modify any aspect of the +command line. Once a partition has been converted to a custom +partition in the label editor, you will need to restart the +labeling process or delete and recreate the partition to restore +it to a non-custom state. Custom partitions are represented by +the letters "CST" instead of "UFS" or "FAT. + When you're done, type `Q' to exit. No actual changes will be made to the disk until you (C)ommit from the diff --git a/usr.sbin/sysinstall/install.c b/usr.sbin/sysinstall/install.c index 9862e5627a79..e1763ec8b424 100644 --- a/usr.sbin/sysinstall/install.c +++ b/usr.sbin/sysinstall/install.c @@ -50,6 +50,7 @@ #undef MSDOSFS #include <sys/stat.h> #include <sys/sysctl.h> +#include <limits.h> #include <unistd.h> #include <termios.h> @@ -878,6 +879,44 @@ installFixupXFree(dialogMenuItem *self) return DITEM_SUCCESS | DITEM_RESTORE; } +#define QUEUE_YES 1 +#define QUEUE_NO 0 +static int +performNewfs(PartInfo *pi, char *dname, int queue) +{ + char buffer[LINE_MAX]; + + if (pi->do_newfs) { + switch(pi->newfs_type) { + case NEWFS_UFS: + snprintf(buffer, LINE_MAX, "%s %s %s %s %s", + NEWFS_UFS_CMD, + pi->newfs_data.newfs_ufs.softupdates ? "-U" : "", + pi->newfs_data.newfs_ufs.ufs2 ? "-O2" : "-O1", + pi->newfs_data.newfs_ufs.user_options, + dname); + break; + + case NEWFS_MSDOS: + snprintf(buffer, LINE_MAX, "%s %s", NEWFS_MSDOS_CMD, + dname); + break; + + case NEWFS_CUSTOM: + snprintf(buffer, LINE_MAX, "%s %s", + pi->newfs_data.newfs_custom.command, dname); + break; + } + + if (queue == QUEUE_YES) { + command_shell_add(pi->mountpoint, buffer); + return (0); + } else + return (vsystem(buffer)); + } + return (0); +} + /* Go newfs and/or mount all the filesystems we've been asked to */ int installFilesystems(dialogMenuItem *self) @@ -940,12 +979,14 @@ installFilesystems(dialogMenuItem *self) if (strcmp(root->mountpoint, "/")) msgConfirm("Warning: %s is marked as a root partition but is mounted on %s", rootdev->name, root->mountpoint); - if (root->newfs && (!upgrade || !msgNoYes("You are upgrading - are you SURE you want to newfs the root partition?"))) { + if (root->do_newfs && (!upgrade || + !msgNoYes("You are upgrading - are you SURE you want to newfs " + "the root partition?"))) { int i; dialog_clear_norefresh(); msgNotify("Making a new root filesystem on %s", dname); - i = vsystem("%s %s", root->newfs_cmd, dname); + i = performNewfs(root, dname, QUEUE_NO); if (i) { msgConfirm("Unable to make new root filesystem on %s!\n" "Command returned status %d", dname, i); @@ -964,10 +1005,17 @@ installFilesystems(dialogMenuItem *self) msgConfirm("Warning: fsck returned status of %d for %s.\n" "This partition may be unsafe to use.", i, dname); } - if (root->soft) { - i = vsystem("tunefs -n enable %s", dname); - if (i) - msgConfirm("Warning: Unable to enable softupdates for root filesystem on %s", dname); + + /* + * If soft updates was enabled in the editor but we didn't newfs, + * use tunefs to update the soft updates flag on the file system. + */ + if (!root->do_newfs && root->newfs_type == NEWFS_UFS && + root->newfs_data.newfs_ufs.softupdates) { + i = vsystem("tunefs -n enable %s", dname); + if (i) + msgConfirm("Warning: Unable to enable soft updates" + " for root file system on %s", dname); } /* Switch to block device */ @@ -1021,12 +1069,23 @@ installFilesystems(dialogMenuItem *self) if (c2 == rootdev) continue; - if (tmp->newfs && (!upgrade || !msgNoYes("You are upgrading - are you SURE you want to newfs /dev/%s?", c2->name))) - command_shell_add(tmp->mountpoint, "%s %s/dev/%s", tmp->newfs_cmd, RunningAsInit ? "/mnt" : "", c2->name); + sprintf(dname, "%s/dev/%s", + RunningAsInit ? "/mnt" : "", c2->name); + + if (tmp->do_newfs && (!upgrade || + !msgNoYes("You are upgrading - are you SURE you" + " want to newfs /dev/%s?", c2->name))) + performNewfs(tmp, dname, QUEUE_YES); else - command_shell_add(tmp->mountpoint, "fsck_ffs -y %s/dev/%s", RunningAsInit ? "/mnt" : "", c2->name); + command_shell_add(tmp->mountpoint, + "fsck_ffs -y %s/dev/%s", RunningAsInit ? + "/mnt" : "", c2->name); +#if 0 if (tmp->soft) - command_shell_add(tmp->mountpoint, "tunefs -n enable %s/dev/%s", RunningAsInit ? "/mnt" : "", c2->name); + command_shell_add(tmp->mountpoint, + "tunefs -n enable %s/dev/%s", RunningAsInit ? + "/mnt" : "", c2->name); +#endif command_func_add(tmp->mountpoint, Mount, c2->name); } else if (c2->type == part && c2->subtype == FS_SWAP) { @@ -1047,7 +1106,8 @@ installFilesystems(dialogMenuItem *self) } } } - else if (c1->type == fat && c1->private_data && (root->newfs || upgrade)) { + else if (c1->type == fat && c1->private_data && + (root->do_newfs || upgrade)) { char name[FILENAME_MAX]; sprintf(name, "%s/%s", RunningAsInit ? "/mnt" : "", ((PartInfo *)c1->private_data)->mountpoint); @@ -1059,8 +1119,13 @@ installFilesystems(dialogMenuItem *self) PartInfo *pi = (PartInfo *)c1->private_data; char *p; - if (pi->newfs && (!upgrade || !msgNoYes("You are upgrading - are you SURE you want to newfs /dev/%s?", c1->name))) - command_shell_add(pi->mountpoint, "%s %s/dev/%s", pi->newfs_cmd, RunningAsInit ? "/mnt" : "", c1->name); + sprintf(dname, "%s/dev/%s", RunningAsInit ? "/mnt" : "", + c1->name); + + if (pi->do_newfs && (!upgrade || + !msgNoYes("You are upgrading - are you SURE you want to " + "newfs /dev/%s?", c1->name))) + performNewfs(pi, dname, QUEUE_YES); command_func_add(pi->mountpoint, Mount_msdosfs, c1->name); diff --git a/usr.sbin/sysinstall/label.c b/usr.sbin/sysinstall/label.c index 7964545a50d8..860e16a5a3f4 100644 --- a/usr.sbin/sysinstall/label.c +++ b/usr.sbin/sysinstall/label.c @@ -322,36 +322,42 @@ record_label_chunks(Device **devs, Device *dev) static PartInfo * new_part(char *mpoint, Boolean newfs) { - PartInfo *ret; + PartInfo *pi; if (!mpoint) mpoint = "/change_me"; - ret = (PartInfo *)safe_malloc(sizeof(PartInfo)); - sstrncpy(ret->mountpoint, mpoint, FILENAME_MAX); - strcpy(ret->newfs_cmd, "newfs "); - strcat(ret->newfs_cmd, variable_get(VAR_NEWFS_ARGS)); - ret->newfs = newfs; - ret->soft = strcmp(mpoint, "/") ? 1 : 0; - return ret; + pi = (PartInfo *)safe_malloc(sizeof(PartInfo)); + sstrncpy(pi->mountpoint, mpoint, FILENAME_MAX); + + pi->do_newfs = newfs; + + pi->newfs_type = NEWFS_UFS; + strcpy(pi->newfs_data.newfs_ufs.user_options, ""); + pi->newfs_data.newfs_ufs.acls = FALSE; + pi->newfs_data.newfs_ufs.multilabel = FALSE; + pi->newfs_data.newfs_ufs.softupdates = strcmp(mpoint, "/"); + pi->newfs_data.newfs_ufs.ufs2 = FALSE; + + return pi; } #if defined(__ia64__) static PartInfo * new_efi_part(char *mpoint, Boolean newfs) { - PartInfo *ret; + PartInfo *pi; if (!mpoint) mpoint = "/efi"; - ret = (PartInfo *)safe_malloc(sizeof(PartInfo)); - sstrncpy(ret->mountpoint, mpoint, FILENAME_MAX); - /* XXX */ - strcpy(ret->newfs_cmd, "newfs_msdos "); - ret->newfs = newfs; - ret->soft = 0; - return ret; + pi = (PartInfo *)safe_malloc(sizeof(PartInfo)); + sstrncpy(pi->mountpoint, mpoint, FILENAME_MAX); + + pi->do_newfs = newfs; + pi->newfs_type = NEWFS_MSDOS; + + return pi; } #endif @@ -404,7 +410,7 @@ get_mountpoint(struct chunk *old) newfs = TRUE; if (tmp) { - newfs = tmp->newfs; + newfs = tmp->do_newfs; safe_free(tmp); } val = string_skipwhite(string_prune(val)); @@ -448,13 +454,49 @@ get_partition_type(void) static void getNewfsCmd(PartInfo *p) { + char buffer[NEWFS_CMD_ARGS_MAX]; char *val; - val = msgGetInput(p->newfs_cmd, - "Please enter the newfs command and options you'd like to use in\n" - "creating this file system."); - if (val) - sstrncpy(p->newfs_cmd, val, NEWFS_CMD_MAX); + switch (p->newfs_type) { + case NEWFS_UFS: + snprintf(buffer, NEWFS_CMD_ARGS_MAX, "%s %s %s %s", + NEWFS_UFS_CMD, p->newfs_data.newfs_ufs.softupdates ? "-U" : "", + p->newfs_data.newfs_ufs.ufs2 ? "-O2" : "-O1", + p->newfs_data.newfs_ufs.user_options); + break; + case NEWFS_MSDOS: + snprintf(buffer, NEWFS_CMD_ARGS_MAX, "%s", NEWFS_MSDOS_CMD); + break; + case NEWFS_CUSTOM: + strcpy(buffer, p->newfs_data.newfs_custom.command); + break; + } + + val = msgGetInput(buffer, + "Please enter the newfs command and options you'd like to use in\n" + "creating this file system."); + if (val != NULL) { + p->newfs_type = NEWFS_CUSTOM; + strlcpy(p->newfs_data.newfs_custom.command, val, NEWFS_CMD_ARGS_MAX); + } +} + +static void +getNewfsOptionalArguments(PartInfo *p) +{ + char buffer[NEWFS_CMD_ARGS_MAX]; + char *val; + + /* Must be UFS, per argument checking in I/O routines. */ + + strlcpy(buffer, p->newfs_data.newfs_ufs.user_options, + NEWFS_CMD_ARGS_MAX); + val = msgGetInput(buffer, + "Please enter any additional UFS newfs options you'd like to\n" + "use in creating this file system."); + if (val != NULL) + strlcpy(p->newfs_data.newfs_ufs.user_options, val, + NEWFS_CMD_ARGS_MAX); } #define MAX_MOUNT_NAME 9 @@ -473,7 +515,7 @@ getNewfsCmd(PartInfo *p) static void print_label_chunks(void) { - int i, j, srow, prow, pcol; + int i, j, spaces, srow, prow, pcol; int sz; char clrmsg[80]; int ChunkPartStartRow; @@ -581,7 +623,7 @@ print_label_chunks(void) } /* Otherwise it's a DOS, swap or filesystem entry in the Chunk window */ else { - char onestr[PART_OFF], num[10], *mountpoint, newfs[10]; + char onestr[PART_OFF], num[10], *mountpoint, newfs[12]; /* * We copy this into a blank-padded string so that it looks like @@ -626,18 +668,34 @@ print_label_chunks(void) label_chunk_info[i].c->type == efi) { strcat(newfs, " "); PartInfo *pi = (PartInfo *)label_chunk_info[i].c->private_data; - strcat(newfs, pi->newfs ? " Y" : " N"); + strcat(newfs, pi->do_newfs ? " Y" : " N"); } #endif } else if (label_chunk_info[i].c->private_data && label_chunk_info[i].type == PART_FILESYSTEM) { - strcpy(newfs, "UFS"); - strcat(newfs, - ((PartInfo *)label_chunk_info[i].c->private_data)->soft ? - "+S" : " "); - strcat(newfs, - ((PartInfo *)label_chunk_info[i].c->private_data)->newfs ? - " Y" : " N"); + PartInfo *pi = (PartInfo *)label_chunk_info[i].c->private_data; + + switch (pi->newfs_type) { + case NEWFS_UFS: + strcpy(newfs, NEWFS_UFS_STRING); + if (pi->newfs_data.newfs_ufs.ufs2) + strcat(newfs, "2"); + else + strcat(newfs, "1"); + if (pi->newfs_data.newfs_ufs.softupdates) + strcat(newfs, "+S"); + else + strcat(newfs, " "); + + break; + case NEWFS_MSDOS: + strcpy(newfs, "FAT"); + break; + case NEWFS_CUSTOM: + strcpy(newfs, "CUST"); + break; + } + strcat(newfs, pi->do_newfs ? " Y" : " N "); } else if (label_chunk_info[i].type == PART_SWAP) strcpy(newfs, "SWAP"); @@ -695,9 +753,9 @@ print_command_summary(void) mvprintw(17, 0, "The following commands are valid here (upper or lower case):"); mvprintw(18, 0, "C = Create D = Delete M = Mount pt."); if (!RunningAsInit) - mvprintw(18, 47, "W = Write"); - mvprintw(19, 0, "N = Newfs Opts Q = Finish S = Toggle SoftUpdates"); - mvprintw(20, 0, "T = Toggle Newfs U = Undo A = Auto Defaults R = Delete+Merge"); + mvprintw(18, 56, "W = Write"); + mvprintw(19, 0, "N = Newfs Opts Q = Finish S = Toggle SoftUpdates Z = Custom Newfs"); + mvprintw(20, 0, "T = Toggle Newfs U = Undo A = Auto Defaults R = Delete+Merge"); mvprintw(22, 0, "Use F1 or ? to get more help, arrow keys to select."); move(0, 0); } @@ -799,6 +857,27 @@ diskLabel(Device *dev) clear_wins(); break; + case '2': + if (label_chunk_info[here].type == PART_FILESYSTEM) { + PartInfo *pi = + ((PartInfo *)label_chunk_info[here].c->private_data); + + if ((pi != NULL) && + (pi->newfs_type == NEWFS_UFS)) { +#ifdef __i386__ + if (label_chunk_info[here].c->flags & CHUNK_IS_ROOT) + msg = MSG_NOT_APPLICABLE; + else +#endif + pi->newfs_data.newfs_ufs.ufs2 = + !pi->newfs_data.newfs_ufs.ufs2; + } else + msg = MSG_NOT_APPLICABLE; + } else + msg = MSG_NOT_APPLICABLE; + break; + break; + case 'A': if (label_chunk_info[here].type != PART_SLICE) { msg = "You can only do this in a disk slice (at top of screen)"; @@ -987,7 +1066,7 @@ diskLabel(Device *dev) p = get_mountpoint(label_chunk_info[here].c); if (p) { if (!oldp) - p->newfs = FALSE; + p->do_newfs = FALSE; if (label_chunk_info[here].type == PART_FAT && (!strcmp(p->mountpoint, "/") || !strcmp(p->mountpoint, "/usr") || !strcmp(p->mountpoint, "/var"))) { @@ -1009,8 +1088,9 @@ diskLabel(Device *dev) case 'N': /* Set newfs options */ if (label_chunk_info[here].c->private_data && - ((PartInfo *)label_chunk_info[here].c->private_data)->newfs) - getNewfsCmd(label_chunk_info[here].c->private_data); + ((PartInfo *)label_chunk_info[here].c->private_data)->do_newfs) + getNewfsOptionalArguments( + label_chunk_info[here].c->private_data); else msg = MSG_NOT_APPLICABLE; clear_wins(); @@ -1019,8 +1099,10 @@ diskLabel(Device *dev) case 'S': /* Toggle soft updates flag */ if (label_chunk_info[here].type == PART_FILESYSTEM) { PartInfo *pi = ((PartInfo *)label_chunk_info[here].c->private_data); - if (pi) - pi->soft = !pi->soft; + if (pi != NULL && + pi->newfs_type == NEWFS_UFS) + pi->newfs_data.newfs_ufs.softupdates = + !pi->newfs_data.newfs_ufs.softupdates; else msg = MSG_NOT_APPLICABLE; } @@ -1032,15 +1114,20 @@ diskLabel(Device *dev) if ((label_chunk_info[here].type == PART_FILESYSTEM) && (label_chunk_info[here].c->private_data)) { PartInfo *pi = ((PartInfo *)label_chunk_info[here].c->private_data); - if (!pi->newfs) + if (!pi->do_newfs) label_chunk_info[here].c->flags |= CHUNK_NEWFS; else label_chunk_info[here].c->flags &= ~CHUNK_NEWFS; label_chunk_info[here].c->private_data = - new_part(pi ? pi->mountpoint : NULL, pi ? !pi->newfs : TRUE); - if (pi && pi->soft) - ((PartInfo *)label_chunk_info[here].c->private_data)->soft = 1; + new_part(pi ? pi->mountpoint : NULL, pi ? !pi->do_newfs + : TRUE); + if (pi != NULL && + pi->newfs_type == NEWFS_UFS) { + PartInfo *pi_new = label_chunk_info[here].c->private_data; + + pi_new->newfs_data.newfs_ufs = pi->newfs_data.newfs_ufs; + } safe_free(pi); label_chunk_info[here].c->private_free = safe_free; if (variable_cmp(DISK_LABELLED, "written")) @@ -1050,14 +1137,16 @@ diskLabel(Device *dev) else if (label_chunk_info[here].type == PART_FAT && label_chunk_info[here].c->type == efi && label_chunk_info[here].c->private_data) { - PartInfo *pi = ((PartInfo *)label_chunk_info[here].c->private_data); - if (!pi->newfs) + PartInfo *pi = + ((PartInfo *)label_chunk_info[here].c->private_data); + + if (!pi->do_newfs) label_chunk_info[here].c->flags |= CHUNK_NEWFS; else label_chunk_info[here].c->flags &= ~CHUNK_NEWFS; label_chunk_info[here].c->private_data = - new_efi_part(pi->mountpoint, !pi->newfs); + new_efi_part(pi->mountpoint, !pi->do_newfs); safe_free(pi); label_chunk_info[here].c->private_free = safe_free; if (variable_cmp(DISK_LABELLED, "written")) @@ -1113,6 +1202,16 @@ diskLabel(Device *dev) clear_wins(); break; + case 'Z': /* Set newfs command line */ + if (label_chunk_info[here].c->private_data && + ((PartInfo *)label_chunk_info[here].c->private_data)->do_newfs) + getNewfsCmd(label_chunk_info[here].c->private_data); + else + msg = MSG_NOT_APPLICABLE; + clear_wins(); + break; + + case '|': if (!msgNoYes("Are you sure you want to go into Wizard mode?\n\n" "This is an entirely undocumented feature which you are not\n" @@ -1437,9 +1536,10 @@ diskLabelNonInteractive(Device *dev) status = DITEM_FAILURE; break; } else { - tmp->private_data = new_part(mpoint, TRUE); + PartInfo *pi; + pi = tmp->private_data = new_part(mpoint, TRUE); tmp->private_free = safe_free; - ((PartInfo *)tmp->private_data)->soft = soft; + pi->newfs_data.newfs_ufs.softupdates = soft; } } } @@ -1459,7 +1559,7 @@ diskLabelNonInteractive(Device *dev) newfs = toupper(do_newfs[0]) == 'Y' ? TRUE : FALSE; if (c1->private_data) { p = c1->private_data; - p->newfs = newfs; + p->do_newfs = newfs; strcpy(p->mountpoint, mpoint); } else { diff --git a/usr.sbin/sysinstall/sysinstall.h b/usr.sbin/sysinstall/sysinstall.h index 1a0e20a7b94c..7ed0fab78be8 100644 --- a/usr.sbin/sysinstall/sysinstall.h +++ b/usr.sbin/sysinstall/sysinstall.h @@ -308,14 +308,39 @@ typedef enum { PART_FAT, } PartType; -/* The longest newfs command we'll hand to system() */ -#define NEWFS_CMD_MAX 256 +#define NEWFS_UFS_CMD "newfs" +#define NEWFS_MSDOS_CMD "newfs_msdos" + +enum newfs_type { NEWFS_UFS, NEWFS_MSDOS, NEWFS_CUSTOM }; +#define NEWFS_UFS_STRING "UFS" +#define NEWFS_MSDOS_STRING "FAT" +#define NEWFS_CUSTOM_STRING "CST" + +/* The longest set of custom command line arguments we'll pass. */ +#define NEWFS_CMD_ARGS_MAX 256 typedef struct _part_info { - Boolean newfs; - char mountpoint[FILENAME_MAX]; - char newfs_cmd[NEWFS_CMD_MAX]; - int soft; + char mountpoint[FILENAME_MAX]; + + /* Is invocation of newfs desired? */ + Boolean do_newfs; + + enum newfs_type newfs_type; + union { + struct { + char user_options[NEWFS_CMD_ARGS_MAX]; + Boolean acls; /* unused */ + Boolean multilabel; /* unused */ + Boolean softupdates; + Boolean ufs2; + } newfs_ufs; + struct { + /* unused */ + } newfs_msdos; + struct { + char command[NEWFS_CMD_ARGS_MAX]; + } newfs_custom; + } newfs_data; } PartInfo; /* An option */ |