summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bsdinstall
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2014-11-19 01:07:58 +0000
committersjg <sjg@FreeBSD.org>2014-11-19 01:07:58 +0000
commitb137080f19736ee33fede2e88bb54438604cf86b (patch)
tree377ac0ac449528621eb192cd245adadb5fd53668 /usr.sbin/bsdinstall
parentab21a29eb607d4dfe389b965fbdee27558e791aa (diff)
parent4a8d07956d121238d006d34ffe7d6269744e8b1a (diff)
downloadFreeBSD-src-b137080f19736ee33fede2e88bb54438604cf86b.zip
FreeBSD-src-b137080f19736ee33fede2e88bb54438604cf86b.tar.gz
Merge from head@274682
Diffstat (limited to 'usr.sbin/bsdinstall')
-rw-r--r--usr.sbin/bsdinstall/bsdinstall.868
-rw-r--r--usr.sbin/bsdinstall/distextract/distextract.c301
-rw-r--r--usr.sbin/bsdinstall/distfetch/distfetch.c72
-rw-r--r--usr.sbin/bsdinstall/partedit/gpart_ops.c129
-rw-r--r--usr.sbin/bsdinstall/partedit/part_wizard.c37
-rw-r--r--usr.sbin/bsdinstall/partedit/partedit.c9
-rw-r--r--usr.sbin/bsdinstall/partedit/partedit.h8
-rw-r--r--usr.sbin/bsdinstall/partedit/partedit_generic.c7
-rw-r--r--usr.sbin/bsdinstall/partedit/partedit_pc98.c11
-rw-r--r--usr.sbin/bsdinstall/partedit/partedit_powerpc.c11
-rw-r--r--usr.sbin/bsdinstall/partedit/partedit_sparc64.c22
-rw-r--r--usr.sbin/bsdinstall/partedit/partedit_x86.c78
-rw-r--r--usr.sbin/bsdinstall/partedit/sade.84
-rw-r--r--usr.sbin/bsdinstall/partedit/scripted.c2
-rwxr-xr-xusr.sbin/bsdinstall/scripts/auto51
-rwxr-xr-xusr.sbin/bsdinstall/scripts/config1
-rwxr-xr-xusr.sbin/bsdinstall/scripts/jail24
-rwxr-xr-xusr.sbin/bsdinstall/scripts/services1
-rwxr-xr-xusr.sbin/bsdinstall/scripts/zfsboot62
19 files changed, 626 insertions, 272 deletions
diff --git a/usr.sbin/bsdinstall/bsdinstall.8 b/usr.sbin/bsdinstall/bsdinstall.8
index 98bab0a..f3d06fa 100644
--- a/usr.sbin/bsdinstall/bsdinstall.8
+++ b/usr.sbin/bsdinstall/bsdinstall.8
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 15, 2013
+.Dd October 31, 2014
.Dt BSDINSTALL 8
.Os
.Sh NAME
@@ -73,10 +73,6 @@ targets.
.Bl -tag -width ".Cm jail Ar destination"
.It Cm auto
Run the standard interactive installation, including disk partitioning.
-.It Cm entropy
-Reads a small amount of data from
-.Pa /dev/random
-and stores it in a file in the new system's root directory.
.It Cm jail Ar destination
Sets up a new chroot system at
.Pa destination ,
@@ -95,6 +91,8 @@ for more information on this target.
.It Cm keymap
If the current controlling TTY is a
.Xr syscons 4
+or
+.Xr vt 4
console, asks the user to set the current keymap, and saves the result to the
new system's
.Pa rc.conf .
@@ -117,32 +115,28 @@ If
is set, also configures the network interfaces of the current system to match.
.It Cm autopart
Provides the installer's interactive guided disk partitioner for single-disk
-installations. Partitions disks, runs
-.Xr newfs 8 ,
-and writes the new system's
-.Pa fstab .
+installations. Defaults to UFS.
.It Cm zfsboot
-Provides the installer's
-.Pq experimental
-interactive/scriptable ZFS partitioner for multi-disk installations.
+Provides an alternative ZFS-only automatic interactive disk partitioner.
Creates a single
.Ic zpool
-with datasets and writes to the new system's
-.Pa rc.conf ,
-.Pa loader.conf ,
+with separate datasets for
+.Pa /tmp ,
+.Pa /usr ,
+.Pa /usr/home ,
+.Pa /usr/ports ,
+.Pa /usr/src ,
and
-.Pa fstab .
-Supports
-.Xr geli 8 ,
-.Xr gnop 8 ,
-and many other features.
+.Pa /var .
+Optionally can set up
+.Xr geli 8
+to encrypt the disk.
.It Cm partedit
-Provides the installer's interactive manual disk partitioner, with support
-for multi disk setups, non-UFS file systems, and manual selection of
-partition schemes. Partitions disks, runs
-.Xr newfs 8 ,
-and writes the new system's
-.Pa fstab .
+Provides the installer's interactive manual disk partitioner with an interface
+identical to
+.Xr sade 8 .
+Supports multiple disks as well as UFS, ZFS, and FAT file systems. ZFS
+is set up with one pool and dataset per partition.
.It Cm scriptedpart Ar parameters
Sets up disks like
.Cm autopart
@@ -188,13 +182,19 @@ keyword causes the partition to take all the remaining space on the disk. The
.Ar type
option chooses the
.Xr gpart 8
-filesystem type (e.g. freebsd-ufs or freebsd-swap).
+filesystem type (e.g. freebsd-ufs, freebsd-zfs, or freebsd-swap).
The optional
.Ar mount point
argument sets where the created partition is to be mounted in the installed
system. As an example, a typical invocation looks like:
.Pp
bsdinstall scriptedpart ada0 { 20G freebsd-ufs /, 4G freebsd-swap, 20G freebsd-ufs /var, auto freebsd-ufs /usr }
+.Pp
+A shorter invocation to use the default partitioning (as
+.Cm autopart
+would have used) on the same disk:
+.Pp
+bsdinstall scriptedpart ada0
.It Cm mount
Mounts the file systems previously configured by
.Cm autopart ,
@@ -233,6 +233,10 @@ Interactively sets the time, date, and time zone of the new system.
Queries the user for the system daemons to begin at system startup,
writing the result into the new system's
.Pa rc.conf .
+.It Cm entropy
+Reads a small amount of data from
+.Pa /dev/random
+and stores it in a file in the new system's root directory.
.It Cm config
Installs the configuration files destined for the new system (e.g. rc.conf
fragments generated by
@@ -344,14 +348,14 @@ which is passed to the
.Cm scriptedpart
target to control disk setup.
Alternatively,
+to use
+.Cm zfsboot
instead of
-.Ev PARTITIONS ,
+.Cm partedit ,
the preamble can contain the variable
.Ev ZFSBOOT_DATASETS
-which is parsed by the
-.Pq experimental
-.Cm zfsboot
-target to control ZFS datasets/options of the boot pool setup.
+instead of
+.Ev PARTITIONS .
.Ss SETUP SCRIPT
Following the preamble is an optional shell script, beginning with a #!
declaration. This script will be run at the end of the installation process
diff --git a/usr.sbin/bsdinstall/distextract/distextract.c b/usr.sbin/bsdinstall/distextract/distextract.c
index a35dbd6..54e0171 100644
--- a/usr.sbin/bsdinstall/distextract/distextract.c
+++ b/usr.sbin/bsdinstall/distextract/distextract.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011 Nathan Whitehorn
+ * Copyright (c) 2014 Devin Teske <dteske@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -22,114 +23,199 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <sys/param.h>
-#include <stdio.h>
-#include <errno.h>
-#include <limits.h>
#include <archive.h>
+#include <ctype.h>
#include <dialog.h>
-
-static int extract_files(int nfiles, const char **files);
+#include <err.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Data to process */
+static char *distdir = NULL;
+struct file_node {
+ char *path;
+ char *name;
+ int length;
+ struct file_node *next;
+};
+static struct file_node *dists = NULL;
+
+/* Function prototypes */
+static int count_files(const char *file);
+static int extract_files(int nfiles, struct file_node *files);
+
+#if __FreeBSD_version <= 1000008 /* r232154: bump for libarchive update */
+#define archive_read_support_filter_all(x) \
+ archive_read_support_compression_all(x)
+#endif
+
+#define _errx(...) (end_dialog(), errx(__VA_ARGS__))
int
main(void)
{
- char *diststring;
- const char **dists;
- int i, retval, ndists = 0;
-
- if (getenv("DISTRIBUTIONS") == NULL) {
- fprintf(stderr, "DISTRIBUTIONS variable is not set\n");
- return (1);
- }
-
- diststring = strdup(getenv("DISTRIBUTIONS"));
- for (i = 0; diststring[i] != 0; i++)
- if (isspace(diststring[i]) && !isspace(diststring[i+1]))
- ndists++;
- ndists++; /* Last one */
-
- dists = calloc(ndists, sizeof(const char *));
- if (dists == NULL) {
- fprintf(stderr, "Out of memory!\n");
- free(diststring);
- return (1);
- }
-
- for (i = 0; i < ndists; i++)
- dists[i] = strsep(&diststring, " \t");
-
+ char *chrootdir;
+ char *distributions;
+ int ndists = 0;
+ int retval;
+ size_t file_node_size = sizeof(struct file_node);
+ size_t span;
+ struct file_node *dist = dists;
+ char error[PATH_MAX + 512];
+
+ if ((distributions = getenv("DISTRIBUTIONS")) == NULL)
+ errx(EXIT_FAILURE, "DISTRIBUTIONS variable is not set");
+ if ((distdir = getenv("BSDINSTALL_DISTDIR")) == NULL)
+ distdir = __DECONST(char *, "");
+
+ /* Initialize dialog(3) */
init_dialog(stdin, stdout);
dialog_vars.backtitle = __DECONST(char *, "FreeBSD Installer");
dlg_put_backtitle();
- if (chdir(getenv("BSDINSTALL_CHROOT")) != 0) {
- char error[512];
- sprintf(error, "Could could change to directory %s: %s\n",
- getenv("BSDINSTALL_DISTDIR"), strerror(errno));
+ dialog_msgbox("",
+ "Checking distribution archives.\nPlease wait...", 4, 35, FALSE);
+
+ /*
+ * Parse $DISTRIBUTIONS into linked-list
+ */
+ while (*distributions != '\0') {
+ span = strcspn(distributions, "\t\n\v\f\r ");
+ if (span < 1) { /* currently on whitespace */
+ distributions++;
+ continue;
+ }
+ ndists++;
+
+ /* Allocate a new struct for the distribution */
+ if (dist == NULL) {
+ if ((dist = calloc(1, file_node_size)) == NULL)
+ _errx(EXIT_FAILURE, "Out of memory!");
+ dists = dist;
+ } else {
+ dist->next = calloc(1, file_node_size);
+ if (dist->next == NULL)
+ _errx(EXIT_FAILURE, "Out of memory!");
+ dist = dist->next;
+ }
+
+ /* Set path */
+ if ((dist->path = malloc(span + 1)) == NULL)
+ _errx(EXIT_FAILURE, "Out of memory!");
+ snprintf(dist->path, span + 1, "%s", distributions);
+ dist->path[span] = '\0';
+
+ /* Set display name */
+ dist->name = strrchr(dist->path, '/');
+ if (dist->name == NULL)
+ dist->name = dist->path;
+
+ /* Set initial length in files (-1 == error) */
+ dist->length = count_files(dist->path);
+ if (dist->length < 0) {
+ end_dialog();
+ return (EXIT_FAILURE);
+ }
+
+ distributions += span;
+ }
+
+ /* Optionally chdir(2) into $BSDINSTALL_CHROOT */
+ chrootdir = getenv("BSDINSTALL_CHROOT");
+ if (chrootdir != NULL && chdir(chrootdir) != 0) {
+ snprintf(error, sizeof(error),
+ "Could not change to directory %s: %s\n",
+ chrootdir, strerror(errno));
dialog_msgbox("Error", error, 0, 0, TRUE);
end_dialog();
- return (1);
+ return (EXIT_FAILURE);
}
retval = extract_files(ndists, dists);
end_dialog();
- free(diststring);
- free(dists);
+ while ((dist = dists) != NULL) {
+ dists = dist->next;
+ if (dist->path != NULL)
+ free(dist->path);
+ free(dist);
+ }
return (retval);
}
+/*
+ * Returns number of files in archive file. Parses $BSDINSTALL_DISTDIR/MANIFEST
+ * if it exists, otherwise uses archive(3) to read the archive file.
+ */
static int
count_files(const char *file)
{
+ static FILE *manifest = NULL;
+ char *p;
+ int file_count;
+ int retval;
+ size_t span;
struct archive *archive;
struct archive_entry *entry;
- static FILE *manifest = NULL;
- char path[MAXPATHLEN];
- char errormsg[512];
- int file_count, err;
+ char line[512];
+ char path[PATH_MAX];
+ char errormsg[PATH_MAX + 512];
if (manifest == NULL) {
- sprintf(path, "%s/MANIFEST", getenv("BSDINSTALL_DISTDIR"));
+ snprintf(path, sizeof(path), "%s/MANIFEST", distdir);
manifest = fopen(path, "r");
}
if (manifest != NULL) {
- char line[512];
- char *tok1, *tok2;
-
rewind(manifest);
while (fgets(line, sizeof(line), manifest) != NULL) {
- tok2 = line;
- tok1 = strsep(&tok2, "\t");
- if (tok1 == NULL || strcmp(tok1, file) != 0)
+ p = &line[0];
+ span = strcspn(p, "\t") ;
+ if (span < 1 || strncmp(p, file, span) != 0)
continue;
/*
* We're at the right manifest line. The file count is
* in the third element
*/
- tok1 = strsep(&tok2, "\t");
- tok1 = strsep(&tok2, "\t");
- if (tok1 != NULL)
- return atoi(tok1);
+ span = strcspn(p += span + (*p != '\0' ? 1 : 0), "\t");
+ span = strcspn(p += span + (*p != '\0' ? 1 : 0), "\t");
+ if (span > 0) {
+ file_count = (int)strtol(p, (char **)NULL, 10);
+ if (file_count == 0 && errno == EINVAL)
+ continue;
+ return (file_count);
+ }
}
}
- /* Either we didn't have a manifest, or this archive wasn't there */
- archive = archive_read_new();
+ /*
+ * Either no manifest, or manifest didn't mention this archive.
+ * Use archive(3) to read the archive, counting files within.
+ */
+ if ((archive = archive_read_new()) == NULL) {
+ snprintf(errormsg, sizeof(errormsg),
+ "Error: %s\n", archive_error_string(NULL));
+ dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE);
+ return (-1);
+ }
archive_read_support_format_all(archive);
archive_read_support_filter_all(archive);
- sprintf(path, "%s/%s", getenv("BSDINSTALL_DISTDIR"), file);
- err = archive_read_open_filename(archive, path, 4096);
- if (err != ARCHIVE_OK) {
+ snprintf(path, sizeof(path), "%s/%s", distdir, file);
+ retval = archive_read_open_filename(archive, path, 4096);
+ if (retval != ARCHIVE_OK) {
snprintf(errormsg, sizeof(errormsg),
"Error while extracting %s: %s\n", file,
archive_error_string(archive));
@@ -146,76 +232,83 @@ count_files(const char *file)
}
static int
-extract_files(int nfiles, const char **files)
+extract_files(int nfiles, struct file_node *files)
{
- const char *items[nfiles*2];
- char path[PATH_MAX];
+ int archive_file;
int archive_files[nfiles];
- int total_files, current_files, archive_file;
+ int current_files = 0;
+ int i;
+ int last_progress;
+ int progress = 0;
+ int retval;
+ int total_files = 0;
struct archive *archive;
struct archive_entry *entry;
- char errormsg[512];
+ struct file_node *file;
char status[8];
- int i, err, progress, last_progress;
+ static char title[] = "Archive Extraction";
+ static char pprompt[] = "Extracting distribution files...\n";
+ char path[PATH_MAX];
+ char errormsg[PATH_MAX + 512];
+ const char *items[nfiles*2];
- err = 0;
- progress = 0;
-
/* Make the transfer list for dialog */
- for (i = 0; i < nfiles; i++) {
- items[i*2] = strrchr(files[i], '/');
- if (items[i*2] != NULL)
- items[i*2]++;
- else
- items[i*2] = files[i];
+ i = 0;
+ for (file = files; file != NULL; file = file->next) {
+ items[i*2] = file->name;
items[i*2 + 1] = "Pending";
- }
+ archive_files[i] = file->length;
- dialog_msgbox("",
- "Checking distribution archives.\nPlease wait...", 0, 0, FALSE);
-
- /* Count all the files */
- total_files = 0;
- for (i = 0; i < nfiles; i++) {
- archive_files[i] = count_files(files[i]);
- if (archive_files[i] < 0)
- return (-1);
- total_files += archive_files[i];
+ total_files += file->length;
+ i++;
}
- current_files = 0;
-
- for (i = 0; i < nfiles; i++) {
- archive = archive_read_new();
+ i = 0;
+ for (file = files; file != NULL; file = file->next) {
+ if ((archive = archive_read_new()) == NULL) {
+ snprintf(errormsg, sizeof(errormsg),
+ "Error: %s\n", archive_error_string(NULL));
+ dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE);
+ return (EXIT_FAILURE);
+ }
archive_read_support_format_all(archive);
archive_read_support_filter_all(archive);
- sprintf(path, "%s/%s", getenv("BSDINSTALL_DISTDIR"), files[i]);
- err = archive_read_open_filename(archive, path, 4096);
+ snprintf(path, sizeof(path), "%s/%s", distdir, file->path);
+ retval = archive_read_open_filename(archive, path, 4096);
+ if (retval != 0) {
+ snprintf(errormsg, sizeof(errormsg),
+ "Error opening %s: %s\n", file->name,
+ archive_error_string(archive));
+ dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE);
+ return (EXIT_FAILURE);
+ }
items[i*2 + 1] = "In Progress";
archive_file = 0;
- while ((err = archive_read_next_header(archive, &entry)) ==
+ dialog_mixedgauge(title, pprompt, 0, 0, progress, nfiles,
+ __DECONST(char **, items));
+
+ while ((retval = archive_read_next_header(archive, &entry)) ==
ARCHIVE_OK) {
last_progress = progress;
progress = (current_files*100)/total_files;
- sprintf(status, "-%d",
+ snprintf(status, sizeof(status), "-%d",
(archive_file*100)/archive_files[i]);
items[i*2 + 1] = status;
if (progress > last_progress)
- dialog_mixedgauge("Archive Extraction",
- "Extracting distribution files...", 0, 0,
+ dialog_mixedgauge(title, pprompt, 0, 0,
progress, nfiles,
__DECONST(char **, items));
- err = archive_read_extract(archive, entry,
+ retval = archive_read_extract(archive, entry,
ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_OWNER |
ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL |
ARCHIVE_EXTRACT_XATTR | ARCHIVE_EXTRACT_FFLAGS);
- if (err != ARCHIVE_OK)
+ if (retval != ARCHIVE_OK)
break;
archive_file++;
@@ -224,18 +317,22 @@ extract_files(int nfiles, const char **files)
items[i*2 + 1] = "Done";
- if (err != ARCHIVE_EOF) {
+ if (retval != ARCHIVE_EOF) {
snprintf(errormsg, sizeof(errormsg),
"Error while extracting %s: %s\n", items[i*2],
archive_error_string(archive));
items[i*2 + 1] = "Failed";
- dialog_msgbox("Extract Error", errormsg, 0, 0,
- TRUE);
- return (err);
+ dialog_msgbox("Extract Error", errormsg, 0, 0, TRUE);
+ return (retval);
}
+ progress = (current_files*100)/total_files;
+ dialog_mixedgauge(title, pprompt, 0, 0, progress, nfiles,
+ __DECONST(char **, items));
+
archive_read_free(archive);
+ i++;
}
- return (0);
+ return (EXIT_SUCCESS);
}
diff --git a/usr.sbin/bsdinstall/distfetch/distfetch.c b/usr.sbin/bsdinstall/distfetch/distfetch.c
index ae5766c..4e870c8 100644
--- a/usr.sbin/bsdinstall/distfetch/distfetch.c
+++ b/usr.sbin/bsdinstall/distfetch/distfetch.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2011 Nathan Whitehorn
+ * Copyright (c) 2014 Devin Teske <dteske@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -22,15 +23,21 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * $FreeBSD$
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <sys/param.h>
-#include <stdio.h>
+#include <ctype.h>
+#include <err.h>
+#include <dialog.h>
#include <errno.h>
#include <fetch.h>
-#include <dialog.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
static int fetch_files(int nfiles, char **urls);
@@ -39,12 +46,13 @@ main(void)
{
char *diststring;
char **urls;
- int i, nfetched, ndists = 0;
+ int i;
+ int ndists = 0;
+ int nfetched;
+ char error[PATH_MAX + 512];
- if (getenv("DISTRIBUTIONS") == NULL) {
- fprintf(stderr, "DISTRIBUTIONS variable is not set\n");
- return (1);
- }
+ if (getenv("DISTRIBUTIONS") == NULL)
+ errx(EXIT_FAILURE, "DISTRIBUTIONS variable is not set");
diststring = strdup(getenv("DISTRIBUTIONS"));
for (i = 0; diststring[i] != 0; i++)
@@ -54,9 +62,8 @@ main(void)
urls = calloc(ndists, sizeof(const char *));
if (urls == NULL) {
- fprintf(stderr, "Out of memory!\n");
free(diststring);
- return (1);
+ errx(EXIT_FAILURE, "Out of memory!");
}
init_dialog(stdin, stdout);
@@ -65,17 +72,17 @@ main(void)
for (i = 0; i < ndists; i++) {
urls[i] = malloc(PATH_MAX);
- sprintf(urls[i], "%s/%s", getenv("BSDINSTALL_DISTSITE"),
- strsep(&diststring, " \t"));
+ snprintf(urls[i], PATH_MAX, "%s/%s",
+ getenv("BSDINSTALL_DISTSITE"), strsep(&diststring, " \t"));
}
if (chdir(getenv("BSDINSTALL_DISTDIR")) != 0) {
- char error[512];
- sprintf(error, "Could could change to directory %s: %s\n",
+ snprintf(error, sizeof(error),
+ "Could could change to directory %s: %s\n",
getenv("BSDINSTALL_DISTDIR"), strerror(errno));
dialog_msgbox("Error", error, 0, 0, TRUE);
end_dialog();
- return (1);
+ return (EXIT_FAILURE);
}
nfetched = fetch_files(ndists, urls);
@@ -87,31 +94,32 @@ main(void)
free(urls[i]);
free(urls);
- return ((nfetched == ndists) ? 0 : 1);
+ return ((nfetched == ndists) ? EXIT_SUCCESS : EXIT_FAILURE);
}
static int
fetch_files(int nfiles, char **urls)
{
+ FILE *fetch_out;
+ FILE *file_out;
const char **items;
- FILE *fetch_out, *file_out;
- struct url_stat ustat;
- off_t total_bytes, current_bytes, fsize;
+ int i;
+ int last_progress;
+ int nsuccess = 0; /* Number of files successfully downloaded */
+ int progress = 0;
+ size_t chunk;
+ off_t current_bytes;
+ off_t fsize;
+ off_t total_bytes;
char status[8];
- char errormsg[512];
+ struct url_stat ustat;
+ char errormsg[PATH_MAX + 512];
uint8_t block[4096];
- size_t chunk;
- int i, progress, last_progress;
- int nsuccess = 0; /* Number of files successfully downloaded */
- progress = 0;
-
/* Make the transfer list for dialog */
items = calloc(sizeof(char *), nfiles * 2);
- if (items == NULL) {
- fprintf(stderr, "Out of memory!\n");
- return (-1);
- }
+ if (items == NULL)
+ errx(EXIT_FAILURE, "Out of memory!");
for (i = 0; i < nfiles; i++) {
items[i*2] = strrchr(urls[i], '/');
@@ -177,7 +185,8 @@ fetch_files(int nfiles, char **urls)
}
if (ustat.size > 0) {
- sprintf(status, "-%jd", (fsize*100)/ustat.size);
+ snprintf(status, sizeof(status), "-%jd",
+ (fsize*100)/ustat.size);
items[i*2 + 1] = status;
}
@@ -212,4 +221,3 @@ fetch_files(int nfiles, char **urls)
free(items);
return (nsuccess);
}
-
diff --git a/usr.sbin/bsdinstall/partedit/gpart_ops.c b/usr.sbin/bsdinstall/partedit/gpart_ops.c
index 27feb57..37b172e 100644
--- a/usr.sbin/bsdinstall/partedit/gpart_ops.c
+++ b/usr.sbin/bsdinstall/partedit/gpart_ops.c
@@ -27,6 +27,7 @@
*/
#include <sys/param.h>
+#include <sys/stat.h>
#include <errno.h>
#include <libutil.h>
#include <inttypes.h>
@@ -119,6 +120,53 @@ newfs_command(const char *fstype, char *command, int use_default)
else if (strcmp(items[i].name, "TRIM") == 0)
strcat(command, "-t ");
}
+ } else if (strcmp(fstype, "freebsd-zfs") == 0) {
+ int i;
+ DIALOG_LISTITEM items[] = {
+ {"fletcher4", "checksum algorithm: fletcher4",
+ "Use fletcher4 for data integrity checking. "
+ "(default)", 1 },
+ {"fletcher2", "checksum algorithm: fletcher2",
+ "Use fletcher2 for data integrity checking. "
+ "(not recommended)", 0 },
+ {"sha256", "checksum algorithm: sha256",
+ "Use sha256 for data integrity checking. "
+ "(not recommended)", 0 },
+ {"atime", "Update atimes for files",
+ "Disable atime update", 0 },
+ };
+
+ if (!use_default) {
+ int choice;
+ choice = dlg_checklist("ZFS Options", "", 0, 0, 0,
+ sizeof(items)/sizeof(items[0]), items, NULL,
+ FLAG_CHECK, &i);
+ if (choice == 1) /* Cancel */
+ return;
+ }
+
+ strcpy(command, "zpool create -f -m none ");
+ if (getenv("BSDINSTALL_TMPBOOT") != NULL) {
+ char zfsboot_path[MAXPATHLEN];
+ sprintf(zfsboot_path, "%s/zfs",
+ getenv("BSDINSTALL_TMPBOOT"));
+ mkdir(zfsboot_path, S_IRWXU | S_IRGRP | S_IXGRP |
+ S_IROTH | S_IXOTH);
+ sprintf(command, "%s -o cachefile=%s/zpool.cache ",
+ command, zfsboot_path);
+ }
+ for (i = 0; i < (int)(sizeof(items)/sizeof(items[0])); i++) {
+ if (items[i].state == 0)
+ continue;
+ if (strcmp(items[i].name, "fletcher4") == 0)
+ strcat(command, "-O checksum=fletcher4 ");
+ else if (strcmp(items[i].name, "fletcher2") == 0)
+ strcat(command, "-O checksum=fletcher2 ");
+ else if (strcmp(items[i].name, "sha256") == 0)
+ strcat(command, "-O checksum=sha256 ");
+ else if (strcmp(items[i].name, "atime") == 0)
+ strcat(command, "-O atime=off ");
+ }
} else if (strcmp(fstype, "fat32") == 0 || strcmp(fstype, "efi") == 0) {
int i;
DIALOG_LISTITEM items[] = {
@@ -329,7 +377,7 @@ gpart_bootcode(struct ggeom *gp)
}
static void
-gpart_partcode(struct gprovider *pp)
+gpart_partcode(struct gprovider *pp, const char *fstype)
{
struct gconfig *gc;
const char *scheme;
@@ -344,7 +392,7 @@ gpart_partcode(struct gprovider *pp)
}
/* Make sure this partition scheme needs partcode on this platform */
- if (partcode_path(scheme) == NULL)
+ if (partcode_path(scheme, fstype) == NULL)
return;
LIST_FOREACH(gc, &pp->lg_config, lg_config) {
@@ -356,7 +404,7 @@ gpart_partcode(struct gprovider *pp)
/* Shell out to gpart for partcode for now */
sprintf(command, "gpart bootcode -p %s -i %s %s",
- partcode_path(scheme), indexstr, pp->lg_geom->lg_name);
+ partcode_path(scheme, fstype), indexstr, pp->lg_geom->lg_name);
if (system(command) != 0) {
sprintf(message, "Error installing partcode on partition %s",
pp->lg_name);
@@ -416,15 +464,15 @@ gpart_edit(struct gprovider *pp)
const char *errstr, *oldtype, *scheme;
struct partition_metadata *md;
char sizestr[32];
- char newfs[64];
+ char newfs[255];
intmax_t idx;
int hadlabel, choice, junk, nitems;
unsigned i;
DIALOG_FORMITEM items[] = {
{0, "Type:", 5, 0, 0, FALSE, "", 11, 0, 12, 15, 0,
- FALSE, "Filesystem type (e.g. freebsd-ufs, freebsd-swap)",
- FALSE},
+ FALSE, "Filesystem type (e.g. freebsd-ufs, freebsd-zfs, "
+ "freebsd-swap)", FALSE},
{0, "Size:", 5, 1, 0, FALSE, "", 11, 1, 12, 0, 0,
FALSE, "Partition size. Append K, M, G for kilobytes, "
"megabytes or gigabytes.", FALSE},
@@ -565,6 +613,8 @@ set_default_part_metadata(const char *name, const char *scheme,
const char *type, const char *mountpoint, const char *newfs)
{
struct partition_metadata *md;
+ char *zpool_name = NULL;
+ int i;
/* Set part metadata */
md = get_part_metadata(name, 1);
@@ -577,8 +627,18 @@ set_default_part_metadata(const char *name, const char *scheme,
if (newfs != NULL && newfs[0] != '\0') {
md->newfs = malloc(strlen(newfs) + strlen(" /dev/") +
- strlen(name) + 1);
- sprintf(md->newfs, "%s /dev/%s", newfs, name);
+ strlen(mountpoint) + 5 + strlen(name) + 1);
+ if (strcmp("freebsd-zfs", type) == 0) {
+ zpool_name = strdup((strlen(mountpoint) == 1) ?
+ "root" : &mountpoint[1]);
+ for (i = 0; zpool_name[i] != 0; i++)
+ if (!isalnum(zpool_name[i]))
+ zpool_name[i] = '_';
+ sprintf(md->newfs, "%s %s /dev/%s", newfs,
+ zpool_name, name);
+ } else {
+ sprintf(md->newfs, "%s /dev/%s", newfs, name);
+ }
}
}
@@ -587,8 +647,9 @@ set_default_part_metadata(const char *name, const char *scheme,
if (strcmp(type, bootpart_type(scheme)) == 0)
md->bootcode = 1;
- /* VTOC8 needs partcode in UFS partitions */
- if (strcmp(scheme, "VTOC8") == 0 && strcmp(type, "freebsd-ufs") == 0)
+ /* VTOC8 needs partcode at the start of partitions */
+ if (strcmp(scheme, "VTOC8") == 0 && (strcmp(type, "freebsd-ufs") == 0
+ || strcmp(type, "freebsd-zfs") == 0))
md->bootcode = 1;
if (mountpoint == NULL || mountpoint[0] == '\0') {
@@ -611,8 +672,13 @@ set_default_part_metadata(const char *name, const char *scheme,
free(md->fstab->fs_mntops);
free(md->fstab->fs_type);
}
- md->fstab->fs_spec = malloc(strlen(name) + 6);
- sprintf(md->fstab->fs_spec, "/dev/%s", name);
+ if (strcmp("freebsd-zfs", type) == 0) {
+ md->fstab->fs_spec = strdup(zpool_name);
+ } else {
+ md->fstab->fs_spec = malloc(strlen(name) +
+ strlen("/dev/") + 1);
+ sprintf(md->fstab->fs_spec, "/dev/%s", name);
+ }
md->fstab->fs_file = strdup(mountpoint);
/* Get VFS from text after freebsd-, if possible */
if (strncmp("freebsd-", type, 8) == 0)
@@ -625,6 +691,10 @@ set_default_part_metadata(const char *name, const char *scheme,
md->fstab->fs_type = strdup(FSTAB_SW);
md->fstab->fs_freq = 0;
md->fstab->fs_passno = 0;
+ } else if (strcmp(type, "freebsd-zfs") == 0) {
+ md->fstab->fs_type = strdup(FSTAB_RW);
+ md->fstab->fs_freq = 0;
+ md->fstab->fs_passno = 0;
} else {
md->fstab->fs_type = strdup(FSTAB_RW);
if (strcmp(mountpoint, "/") == 0) {
@@ -637,6 +707,9 @@ set_default_part_metadata(const char *name, const char *scheme,
}
md->fstab->fs_mntops = strdup(md->fstab->fs_type);
}
+
+ if (zpool_name != NULL)
+ free(zpool_name);
}
static
@@ -748,7 +821,7 @@ gpart_create(struct gprovider *pp, char *default_type, char *default_size,
struct ggeom *geom;
const char *errstr, *scheme;
char sizestr[32], startstr[32], output[64], *newpartname;
- char newfs[64], options_fstype[64];
+ char newfs[255], options_fstype[64];
intmax_t maxsize, size, sector, firstfree, stripe;
uint64_t bytes;
int nitems, choice, junk;
@@ -756,8 +829,8 @@ gpart_create(struct gprovider *pp, char *default_type, char *default_size,
DIALOG_FORMITEM items[] = {
{0, "Type:", 5, 0, 0, FALSE, "freebsd-ufs", 11, 0, 12, 15, 0,
- FALSE, "Filesystem type (e.g. freebsd-ufs, freebsd-swap)",
- FALSE},
+ FALSE, "Filesystem type (e.g. freebsd-ufs, freebsd-zfs, "
+ "freebsd-swap)", FALSE},
{0, "Size:", 5, 1, 0, FALSE, "", 11, 1, 12, 15, 0,
FALSE, "Partition size. Append K, M, G for kilobytes, "
"megabytes or gigabytes.", FALSE},
@@ -935,6 +1008,20 @@ addpartform:
goto addpartform;
}
+ /* If this is the root partition, check that this fs is bootable */
+ if (strcmp(items[2].text, "/") == 0 && !is_fs_bootable(scheme,
+ items[0].text)) {
+ char message[512];
+ sprintf(message, "This file system (%s) is not bootable "
+ "on this system. Are you sure you want to proceed?",
+ items[0].text);
+ dialog_vars.defaultno = TRUE;
+ choice = dialog_yesno("Warning", message, 0, 0);
+ dialog_vars.defaultno = FALSE;
+ if (choice == 1) /* cancel */
+ goto addpartform;
+ }
+
/*
* If this is the root partition, and we need a boot partition, ask
* the user to add one.
@@ -1177,12 +1264,22 @@ gpart_commit(struct gmesh *mesh)
struct gctl_req *r;
const char *errstr;
const char *modified;
+ const char *rootfs;
LIST_FOREACH(classp, &mesh->lg_class, lg_class) {
if (strcmp(classp->lg_name, "PART") == 0)
break;
}
+ /* Figure out what filesystem / uses */
+ rootfs = "ufs"; /* Assume ufs if nothing else present */
+ TAILQ_FOREACH(md, &part_metadata, metadata) {
+ if (md->fstab != NULL && strcmp(md->fstab->fs_file, "/") == 0) {
+ rootfs = md->fstab->fs_vfstype;
+ break;
+ }
+ }
+
if (strcmp(classp->lg_name, "PART") != 0) {
dialog_msgbox("Error", "gpart not found!", 0, 0, TRUE);
return;
@@ -1222,7 +1319,7 @@ gpart_commit(struct gmesh *mesh)
break;
if (cp == NULL) /* No sub-partitions */
- gpart_partcode(pp);
+ gpart_partcode(pp, rootfs);
}
r = gctl_get_handle();
diff --git a/usr.sbin/bsdinstall/partedit/part_wizard.c b/usr.sbin/bsdinstall/partedit/part_wizard.c
index a304fb8..3f7ccd5 100644
--- a/usr.sbin/bsdinstall/partedit/part_wizard.c
+++ b/usr.sbin/bsdinstall/partedit/part_wizard.c
@@ -31,6 +31,9 @@
#include <libutil.h>
#include <inttypes.h>
+#include <sys/sysctl.h>
+#include <string.h>
+
#include <libgeom.h>
#include <dialog.h>
#include <dlg_keys.h>
@@ -44,10 +47,16 @@ static char *boot_disk(struct gmesh *mesh);
static char *wizard_partition(struct gmesh *mesh, const char *disk);
int
-part_wizard(void) {
+part_wizard(const char *fsreq) {
int error;
struct gmesh mesh;
char *disk, *schemeroot;
+ const char *fstype;
+
+ if (fsreq != NULL)
+ fstype = fsreq;
+ else
+ fstype = "ufs";
startwizard:
error = geom_gettree(&mesh);
@@ -70,11 +79,11 @@ startwizard:
dlg_put_backtitle();
error = geom_gettree(&mesh);
- error = wizard_makeparts(&mesh, schemeroot, 1);
+ error = wizard_makeparts(&mesh, schemeroot, fstype, 1);
if (error)
goto startwizard;
free(schemeroot);
-
+
geom_deletetree(&mesh);
return (0);
@@ -106,9 +115,9 @@ boot_disk(struct gmesh *mesh)
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
desc = type = NULL;
LIST_FOREACH(gc, &pp->lg_config, lg_config) {
- if (strcmp(gc->lg_name, "type") == 0)
+ if (strcmp(gc->lg_name, "type") == 0)
type = gc->lg_val;
- if (strcmp(gc->lg_name, "descr") == 0)
+ if (strcmp(gc->lg_name, "descr") == 0)
desc = gc->lg_val;
}
@@ -200,7 +209,7 @@ wizard_partition(struct gmesh *mesh, const char *disk)
break;
if (classp != NULL) {
- LIST_FOREACH(gpart, &classp->lg_geom, lg_geom)
+ LIST_FOREACH(gpart, &classp->lg_geom, lg_geom)
if (strcmp(gpart->lg_name, disk) == 0)
break;
}
@@ -282,21 +291,29 @@ query:
}
int
-wizard_makeparts(struct gmesh *mesh, const char *disk, int interactive)
+wizard_makeparts(struct gmesh *mesh, const char *disk, const char *fstype, int interactive)
{
struct gmesh submesh;
struct gclass *classp;
struct ggeom *gp;
struct gprovider *pp;
intmax_t swapsize, available;
- char swapsizestr[10], rootsizestr[10];
+ char swapsizestr[10], rootsizestr[10], *fsname;
+ char *fsnames[] = {"freebsd-ufs", "freebsd-zfs"};
int retval;
+ if (strcmp(fstype, "zfs") == 0) {
+ fsname = fsnames[1];
+ } else {
+ /* default to UFS */
+ fsname = fsnames[0];
+ }
+
LIST_FOREACH(classp, &mesh->lg_class, lg_class)
if (strcmp(classp->lg_name, "PART") == 0)
break;
- LIST_FOREACH(gp, &classp->lg_geom, lg_geom)
+ LIST_FOREACH(gp, &classp->lg_geom, lg_geom)
if (strcmp(gp->lg_name, disk) == 0)
break;
@@ -331,7 +348,7 @@ wizard_makeparts(struct gmesh *mesh, const char *disk, int interactive)
geom_gettree(&submesh);
pp = provider_for_name(&submesh, disk);
- gpart_create(pp, "freebsd-ufs", rootsizestr, "/", NULL, 0);
+ gpart_create(pp, fsname, rootsizestr, "/", NULL, 0);
geom_deletetree(&submesh);
geom_gettree(&submesh);
diff --git a/usr.sbin/bsdinstall/partedit/partedit.c b/usr.sbin/bsdinstall/partedit/partedit.c
index eff87fe..ac3cd8a 100644
--- a/usr.sbin/bsdinstall/partedit/partedit.c
+++ b/usr.sbin/bsdinstall/partedit/partedit.c
@@ -95,7 +95,12 @@ main(int argc, const char **argv)
if (strcmp(basename(argv[0]), "autopart") == 0) { /* Guided */
prompt = "Please review the disk setup. When complete, press "
"the Finish button.";
- part_wizard();
+ /* Experimental ZFS autopartition support */
+ if (argc > 1 && strcmp(argv[1], "zfs") == 0) {
+ part_wizard("zfs");
+ } else {
+ part_wizard("ufs");
+ }
} else if (strcmp(basename(argv[0]), "scriptedpart") == 0) {
error = scripted_editor(argc, argv);
prompt = NULL;
@@ -162,7 +167,7 @@ main(int argc, const char **argv)
init_fstab_metadata();
break;
case 4: /* Auto */
- part_wizard();
+ part_wizard("ufs");
break;
}
diff --git a/usr.sbin/bsdinstall/partedit/partedit.h b/usr.sbin/bsdinstall/partedit/partedit.h
index 32e3a36..b6f7258 100644
--- a/usr.sbin/bsdinstall/partedit/partedit.h
+++ b/usr.sbin/bsdinstall/partedit/partedit.h
@@ -54,9 +54,10 @@ struct partition_metadata {
struct partition_metadata *get_part_metadata(const char *name, int create);
void delete_part_metadata(const char *name);
-int part_wizard(void);
+int part_wizard(const char *fstype);
int scripted_editor(int argc, const char **argv);
-int wizard_makeparts(struct gmesh *mesh, const char *disk, int interactive);
+int wizard_makeparts(struct gmesh *mesh, const char *disk, const char *fstype,
+ int interactive);
/* gpart operations */
void gpart_delete(struct gprovider *pp);
@@ -75,9 +76,10 @@ void set_default_part_metadata(const char *name, const char *scheme,
/* machine-dependent bootability checks */
const char *default_scheme(void);
int is_scheme_bootable(const char *scheme);
+int is_fs_bootable(const char *scheme, const char *fs);
size_t bootpart_size(const char *scheme);
const char *bootpart_type(const char *scheme);
const char *bootcode_path(const char *scheme);
-const char *partcode_path(const char *scheme);
+const char *partcode_path(const char *scheme, const char *fs_type);
#endif
diff --git a/usr.sbin/bsdinstall/partedit/partedit_generic.c b/usr.sbin/bsdinstall/partedit/partedit_generic.c
index 8498a78..ceee95a 100644
--- a/usr.sbin/bsdinstall/partedit/partedit_generic.c
+++ b/usr.sbin/bsdinstall/partedit/partedit_generic.c
@@ -50,6 +50,11 @@ is_scheme_bootable(const char *part_type) {
return (1);
}
+int
+is_fs_bootable(const char *part_type, const char *fs) {
+ return (1);
+}
+
/* No clue => no boot partition, bootcode, or partcode */
size_t
@@ -68,7 +73,7 @@ bootcode_path(const char *part_type) {
}
const char *
-partcode_path(const char *part_type) {
+partcode_path(const char *part_type, const char *fs_type) {
return (NULL);
}
diff --git a/usr.sbin/bsdinstall/partedit/partedit_pc98.c b/usr.sbin/bsdinstall/partedit/partedit_pc98.c
index dd075a1..8e914ea 100644
--- a/usr.sbin/bsdinstall/partedit/partedit_pc98.c
+++ b/usr.sbin/bsdinstall/partedit/partedit_pc98.c
@@ -45,6 +45,15 @@ is_scheme_bootable(const char *part_type) {
return (0);
}
+int
+is_fs_bootable(const char *part_type, const char *fs)
+{
+ if (strcmp(fs, "freebsd-ufs") == 0)
+ return (1);
+
+ return (0);
+}
+
size_t
bootpart_size(const char *part_type) {
/* No boot partition */
@@ -67,7 +76,7 @@ bootcode_path(const char *part_type) {
}
const char *
-partcode_path(const char *part_type) {
+partcode_path(const char *part_type, const char *fs_type) {
/* No partcode */
return (NULL);
}
diff --git a/usr.sbin/bsdinstall/partedit/partedit_powerpc.c b/usr.sbin/bsdinstall/partedit/partedit_powerpc.c
index 77c682a..6a5dbb2 100644
--- a/usr.sbin/bsdinstall/partedit/partedit_powerpc.c
+++ b/usr.sbin/bsdinstall/partedit/partedit_powerpc.c
@@ -67,6 +67,15 @@ is_scheme_bootable(const char *part_type) {
return (0);
}
+int
+is_fs_bootable(const char *part_type, const char *fs)
+{
+ if (strcmp(fs, "freebsd-ufs") == 0)
+ return (1);
+
+ return (0);
+}
+
size_t
bootpart_size(const char *part_type) {
size_t platlen = sizeof(platform);
@@ -100,7 +109,7 @@ bootcode_path(const char *part_type) {
}
const char *
-partcode_path(const char *part_type) {
+partcode_path(const char *part_type, const char *fs_type) {
size_t platlen = sizeof(platform);
if (strlen(platform) == 0)
sysctlbyname("hw.platform", platform, &platlen, NULL, -1);
diff --git a/usr.sbin/bsdinstall/partedit/partedit_sparc64.c b/usr.sbin/bsdinstall/partedit/partedit_sparc64.c
index 8232c55..c420f6a 100644
--- a/usr.sbin/bsdinstall/partedit/partedit_sparc64.c
+++ b/usr.sbin/bsdinstall/partedit/partedit_sparc64.c
@@ -42,6 +42,15 @@ is_scheme_bootable(const char *part_type) {
return (0);
}
+int
+is_fs_bootable(const char *part_type, const char *fs)
+{
+ if (strcmp(fs, "freebsd-ufs") == 0 || strcmp(fs, "freebsd-zfs") == 0)
+ return (1);
+ return (0);
+}
+
+
size_t
bootpart_size(const char *part_type) {
/* No standalone boot partition */
@@ -58,11 +67,16 @@ const char *
bootcode_path(const char *part_type) {
return (NULL);
}
-
+
const char *
-partcode_path(const char *part_type) {
- if (strcmp(part_type, "VTOC8") == 0)
- return ("/boot/boot1");
+partcode_path(const char *part_type, const char *fs_type) {
+ if (strcmp(part_type, "VTOC8") == 0) {
+ if (strcmp(fs_type, "ufs") == 0) {
+ return ("/boot/boot1");
+ } else if (strcmp(fs_type, "zfs") == 0) {
+ return ("/boot/zfsboot");
+ }
+ }
return (NULL);
}
diff --git a/usr.sbin/bsdinstall/partedit/partedit_x86.c b/usr.sbin/bsdinstall/partedit/partedit_x86.c
index b458475..cc6a571 100644
--- a/usr.sbin/bsdinstall/partedit/partedit_x86.c
+++ b/usr.sbin/bsdinstall/partedit/partedit_x86.c
@@ -32,23 +32,35 @@
#include "partedit.h"
-static char platform[255] = "";
-static const char *platform_sysctl = "machdep.bootmethod";
+static const char *
+x86_bootmethod(void)
+{
+ static char fw[255] = "";
+ size_t len = sizeof(fw);
+ int error;
+
+ if (strlen(fw) == 0) {
+ error = sysctlbyname("machdep.bootmethod", fw, &len, NULL, -1);
+ if (error != 0)
+ return ("BIOS");
+ }
+
+ return (fw);
+}
const char *
-default_scheme(void) {
+default_scheme(void)
+{
return ("GPT");
}
int
-is_scheme_bootable(const char *part_type) {
- size_t platlen = sizeof(platform);
- if (strlen(platform) == 0)
- sysctlbyname(platform_sysctl, platform, &platlen, NULL, -1);
+is_scheme_bootable(const char *part_type)
+{
if (strcmp(part_type, "GPT") == 0)
return (1);
- if (strcmp(platform, "BIOS") == 0) {
+ if (strcmp(x86_bootmethod(), "BIOS") == 0) {
if (strcmp(part_type, "BSD") == 0)
return (1);
if (strcmp(part_type, "MBR") == 0)
@@ -58,17 +70,30 @@ is_scheme_bootable(const char *part_type) {
return (0);
}
+int
+is_fs_bootable(const char *part_type, const char *fs)
+{
+
+ if (strcmp(fs, "freebsd-ufs") == 0)
+ return (1);
+
+ if (strcmp(fs, "freebsd-zfs") == 0 &&
+ strcmp(part_type, "GPT") == 0 &&
+ strcmp(x86_bootmethod(), "BIOS") == 0)
+ return (1);
+
+ return (0);
+}
+
size_t
-bootpart_size(const char *scheme) {
- size_t platlen = sizeof(platform);
- if (strlen(platform) == 0)
- sysctlbyname(platform_sysctl, platform, &platlen, NULL, -1);
+bootpart_size(const char *scheme)
+{
/* No partcode except for GPT */
if (strcmp(scheme, "GPT") != 0)
return (0);
- if (strcmp(platform, "BIOS") == 0)
+ if (strcmp(x86_bootmethod(), "BIOS") == 0)
return (512*1024);
else
return (800*1024);
@@ -77,23 +102,20 @@ bootpart_size(const char *scheme) {
}
const char *
-bootpart_type(const char *scheme) {
- size_t platlen = sizeof(platform);
- if (strlen(platform) == 0)
- sysctlbyname(platform_sysctl, platform, &platlen, NULL, -1);
+bootpart_type(const char *scheme)
+{
- if (strcmp(platform, "UEFI") == 0)
+ if (strcmp(x86_bootmethod(), "UEFI") == 0)
return ("efi");
return ("freebsd-boot");
}
const char *
-bootcode_path(const char *part_type) {
- size_t platlen = sizeof(platform);
- if (strlen(platform) == 0)
- sysctlbyname(platform_sysctl, platform, &platlen, NULL, -1);
- if (strcmp(platform, "UEFI") == 0)
+bootcode_path(const char *part_type)
+{
+
+ if (strcmp(x86_bootmethod(), "UEFI") == 0)
return (NULL);
if (strcmp(part_type, "GPT") == 0)
@@ -107,14 +129,14 @@ bootcode_path(const char *part_type) {
}
const char *
-partcode_path(const char *part_type) {
- size_t platlen = sizeof(platform);
- if (strlen(platform) == 0)
- sysctlbyname(platform_sysctl, platform, &platlen, NULL, -1);
+partcode_path(const char *part_type, const char *fs_type)
+{
if (strcmp(part_type, "GPT") == 0) {
- if (strcmp(platform, "UEFI") == 0)
+ if (strcmp(x86_bootmethod(), "UEFI") == 0)
return ("/boot/boot1.efifat");
+ else if (strcmp(fs_type, "zfs") == 0)
+ return ("/boot/gptzfsboot");
else
return ("/boot/gptboot");
}
diff --git a/usr.sbin/bsdinstall/partedit/sade.8 b/usr.sbin/bsdinstall/partedit/sade.8
index 79df079..3bb1c65 100644
--- a/usr.sbin/bsdinstall/partedit/sade.8
+++ b/usr.sbin/bsdinstall/partedit/sade.8
@@ -68,7 +68,5 @@ with the equivalent part of
.Sh BUGS
The utility misses a lot of nice features, such as tools for
manipulating
-.Xr gmirror 8
-or
-.Xr zfs 8 .
+.Xr gmirror 8 .
These will be added later.
diff --git a/usr.sbin/bsdinstall/partedit/scripted.c b/usr.sbin/bsdinstall/partedit/scripted.c
index 4ac3482..876df54 100644
--- a/usr.sbin/bsdinstall/partedit/scripted.c
+++ b/usr.sbin/bsdinstall/partedit/scripted.c
@@ -109,7 +109,7 @@ part_config(char *disk, const char *scheme, char *config)
/* Create partitions */
if (config == NULL) {
- wizard_makeparts(&mesh, disk, 0);
+ wizard_makeparts(&mesh, disk, "ufs", 0);
goto finished;
}
diff --git a/usr.sbin/bsdinstall/scripts/auto b/usr.sbin/bsdinstall/scripts/auto
index c2d8fc0..433744e 100755
--- a/usr.sbin/bsdinstall/scripts/auto
+++ b/usr.sbin/bsdinstall/scripts/auto
@@ -35,11 +35,15 @@ BSDCFG_SHARE="/usr/share/bsdconfig"
############################################################ FUNCTIONS
error() {
+ local msg
+ if [ -n "$1" ]; then
+ msg="$1\n\n"
+ fi
test -n "$DISTDIR_IS_UNIONFS" && umount -f $BSDINSTALL_DISTDIR
test -f $PATH_FSTAB && bsdinstall umount
dialog --backtitle "FreeBSD Installer" --title "Abort" \
--no-label "Exit" --yes-label "Restart" --yesno \
- "An installation step has been aborted. Would you like to restart the installation or exit the installer?" 0 0
+ "${msg}An installation step has been aborted. Would you like to restart the installation or exit the installer?" 0 0
if [ $? -ne 0 ]; then
exit 1
else
@@ -58,7 +62,7 @@ trap true SIGINT # This section is optional
bsdinstall keymap
trap error SIGINT # Catch cntrl-C here
-bsdinstall hostname || error
+bsdinstall hostname || error "Set hostname failed"
export DISTRIBUTIONS="base.txz kernel.txz"
if [ -f $BSDINSTALL_DISTDIR/MANIFEST ]; then
@@ -95,7 +99,7 @@ if [ -n "$FETCH_DISTRIBUTIONS" ]; then
BSDINSTALL_DISTSITE=$(`dirname $0`/mirrorselect 2>&1 1>&3)
MIRROR_BUTTON=$?
exec 3>&-
- test $MIRROR_BUTTON -eq 0 || error
+ test $MIRROR_BUTTON -eq 0 || error "No mirror selected"
export BSDINSTALL_DISTSITE
fi
@@ -103,14 +107,14 @@ rm -f $PATH_FSTAB
touch $PATH_FSTAB
PMODES="\
-Guided \"Partitioning Tool (Recommended for Beginners)\" \
-Manual \"Manually Configure Partitions (Expert)\" \
+\"Auto (UFS)\" \"Guided Disk Setup\" \
+Manual \"Manual Disk Setup (experts)\" \
Shell \"Open a shell and partition by hand\""
CURARCH=$( uname -m )
case $CURARCH in
amd64|i386) # Booting ZFS Supported
- PMODES="$PMODES ZFS \"Automatic Root-on-ZFS (Experimental)\""
+ PMODES="$PMODES \"Auto (ZFS)\" \"Guided Root-on-ZFS\""
;;
*) # Booting ZFS Unspported
;;
@@ -124,9 +128,9 @@ PARTMODE=`echo $PMODES | xargs dialog --backtitle "FreeBSD Installer" \
exec 3>&-
case "$PARTMODE" in
-"Guided") # Guided
- bsdinstall autopart || error
- bsdinstall mount || error
+"Auto (UFS)") # Guided
+ bsdinstall autopart || error "Partitioning error"
+ bsdinstall mount || error "Failed to mount filesystem"
;;
"Shell") # Shell
clear
@@ -136,18 +140,18 @@ case "$PARTMODE" in
"Manual") # Manual
if f_isset debugFile; then
# Give partedit the path to our logfile so it can append
- BSDINSTALL_LOG="${debugFile#+}" bsdinstall partedit || error
+ BSDINSTALL_LOG="${debugFile#+}" bsdinstall partedit || error "Partitioning error"
else
- bsdinstall partedit || error
+ bsdinstall partedit || error "Partitioning error"
fi
- bsdinstall mount || error
+ bsdinstall mount || error "Failed to mount filesystem"
;;
-"ZFS") # ZFS
- bsdinstall zfsboot || error
- bsdinstall mount || error
+"Auto (ZFS)") # ZFS
+ bsdinstall zfsboot || error "ZFS setup failed"
+ bsdinstall mount || error "Failed to mount filesystem"
;;
*)
- error
+ error "Unknown partitioning mode"
;;
esac
@@ -156,7 +160,7 @@ if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then
# Download to a directory in the new system as scratch space
BSDINSTALL_FETCHDEST="$BSDINSTALL_CHROOT/usr/freebsd-dist"
- mkdir -p "$BSDINSTALL_FETCHDEST" || error
+ mkdir -p "$BSDINSTALL_FETCHDEST" || error "Could not create directory $BSDINSTALL_FETCHDEST"
export DISTRIBUTIONS="$FETCH_DISTRIBUTIONS"
# Try to use any existing distfiles
@@ -169,13 +173,13 @@ if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then
fi
export FTP_PASSIVE_MODE=YES
- bsdinstall distfetch || error
+ bsdinstall distfetch || error "Failed to fetch distribution"
export DISTRIBUTIONS="$ALL_DISTRIBUTIONS"
fi
-bsdinstall checksum || error
-bsdinstall distextract || error
-bsdinstall rootpass || error
+bsdinstall checksum || error "Distribution checksum failed"
+bsdinstall distextract || error "Distribution extract failed"
+bsdinstall rootpass || error "Could not set root password"
trap true SIGINT # This section is optional
if [ "$NETCONFIG_DONE" != yes ]; then
@@ -239,7 +243,7 @@ finalconfig() {
finalconfig
trap error SIGINT # SIGINT is bad again
-bsdinstall config || error
+bsdinstall config || error "Failed to save config"
if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then
[ "$BSDINSTALL_FETCHDEST" != "$BSDINSTALL_DISTDIR" ] && \
@@ -248,7 +252,8 @@ if [ ! -z "$BSDINSTALL_FETCHDEST" ]; then
fi
dialog --backtitle "FreeBSD Installer" --title "Manual Configuration" \
- --yesno "The installation is now finished. Before exiting the installer, would you like to open a shell in the new system to make any final manual modifications?" 0 0
+ --default-button no --yesno \
+ "The installation is now finished. Before exiting the installer, would you like to open a shell in the new system to make any final manual modifications?" 0 0
if [ $? -eq 0 ]; then
clear
mount -t devfs devfs "$BSDINSTALL_CHROOT/dev"
diff --git a/usr.sbin/bsdinstall/scripts/config b/usr.sbin/bsdinstall/scripts/config
index 98baade..bc3d723 100755
--- a/usr.sbin/bsdinstall/scripts/config
+++ b/usr.sbin/bsdinstall/scripts/config
@@ -36,6 +36,7 @@ cp $BSDINSTALL_TMPETC/* $BSDINSTALL_CHROOT/etc
cat $BSDINSTALL_TMPBOOT/loader.conf.* >> $BSDINSTALL_TMPBOOT/loader.conf
rm $BSDINSTALL_TMPBOOT/loader.conf.*
+df -t zfs $BSDINSTALL_CHROOT > /dev/null && echo "zfs_load=\"YES\"" >> $BSDINSTALL_TMPBOOT/loader.conf
cp $BSDINSTALL_TMPBOOT/* $BSDINSTALL_CHROOT/boot
diff --git a/usr.sbin/bsdinstall/scripts/jail b/usr.sbin/bsdinstall/scripts/jail
index e709145..cb86060 100755
--- a/usr.sbin/bsdinstall/scripts/jail
+++ b/usr.sbin/bsdinstall/scripts/jail
@@ -38,9 +38,13 @@ f_dprintf "Began Installation at %s" "$( date )"
export BSDINSTALL_CHROOT=$1
error() {
+ local msg
+ if [ -n "$1" ]; then
+ msg="$1\n\n"
+ fi
dialog --backtitle "FreeBSD Installer" --title "Abort" \
--no-label "Exit" --yes-label "Restart" --yesno \
- "An installation step has been aborted. Would you like to restart the installation or exit the installer?" 0 0
+ "${msg}An installation step has been aborted. Would you like to restart the installation or exit the installer?" 0 0
if [ $? -ne 0 ]; then
exit
else
@@ -51,7 +55,7 @@ error() {
rm -rf $BSDINSTALL_TMPETC
mkdir $BSDINSTALL_TMPETC
-mkdir -p $1 || error
+mkdir -p $1 || error "mkdir failed for $1"
test ! -d $BSDINSTALL_DISTDIR && mkdir -p $BSDINSTALL_DISTDIR
@@ -60,9 +64,9 @@ if [ ! -f $BSDINSTALL_DISTDIR/MANIFEST -a -z "$BSDINSTALL_DISTSITE" ]; then
BSDINSTALL_DISTSITE=$(`dirname $0`/mirrorselect 2>&1 1>&3)
MIRROR_BUTTON=$?
exec 3>&-
- test $MIRROR_BUTTON -eq 0 || error
+ test $MIRROR_BUTTON -eq 0 || error "No mirror selected"
export BSDINSTALL_DISTSITE
- fetch -o $BSDINSTALL_DISTDIR/MANIFEST $BSDINSTALL_DISTSITE/MANIFEST || error
+ fetch -o $BSDINSTALL_DISTDIR/MANIFEST $BSDINSTALL_DISTSITE/MANIFEST || error "Could not download $BSDINSTALL_DISTSITE/MANIFEST"
fi
export DISTRIBUTIONS="base.txz"
@@ -94,17 +98,17 @@ if [ -n "$FETCH_DISTRIBUTIONS" -a -z "$BSDINSTALL_DISTSITE" ]; then
BSDINSTALL_DISTSITE=`bsdinstall mirrorselect 2>&1 1>&3`
MIRROR_BUTTON=$?
exec 3>&-
- test $MIRROR_BUTTON -eq 0 || error
+ test $MIRROR_BUTTON -eq 0 || error "No mirror selected"
export BSDINSTALL_DISTSITE
fi
if [ ! -z "$FETCH_DISTRIBUTIONS" ]; then
- bsdinstall distfetch || error
+ bsdinstall distfetch || error "Failed to fetch distribution"
fi
-bsdinstall checksum || error
-bsdinstall distextract || error
-bsdinstall rootpass || error
+bsdinstall checksum || error "Distribution checksum failed"
+bsdinstall distextract || error "Distribution extract failed"
+bsdinstall rootpass || error "Could not set root password"
trap true SIGINT # This section is optional
bsdinstall services
@@ -114,7 +118,7 @@ dialog --backtitle "FreeBSD Installer" --title "Add User Accounts" --yesno \
bsdinstall adduser
trap error SIGINT # SIGINT is bad again
-bsdinstall config || error
+bsdinstall config || error "Failed to save config"
cp /etc/resolv.conf $1/etc
cp /etc/localtime $1/etc
diff --git a/usr.sbin/bsdinstall/scripts/services b/usr.sbin/bsdinstall/scripts/services
index 54c5018..83786c2 100755
--- a/usr.sbin/bsdinstall/scripts/services
+++ b/usr.sbin/bsdinstall/scripts/services
@@ -43,6 +43,7 @@ DAEMONS=$( dialog --backtitle "FreeBSD Installer" \
--title "System Configuration" --nocancel --separate-output \
--checklist "Choose the services you would like to be started at boot:" \
0 0 0 \
+ local_unbound "Local caching validating resolver" ${local_unbound:-off} \
sshd "Secure shell daemon" ${sshd_enable:-off} \
moused "PS/2 mouse pointer on console" ${moused_enable:-off} \
ntpd "Synchronize system and network time" ${ntpd_enable:-off} \
diff --git a/usr.sbin/bsdinstall/scripts/zfsboot b/usr.sbin/bsdinstall/scripts/zfsboot
index 9f1abb8..2b01dea 100755
--- a/usr.sbin/bsdinstall/scripts/zfsboot
+++ b/usr.sbin/bsdinstall/scripts/zfsboot
@@ -156,7 +156,7 @@ f_isset ZFSBOOT_DATASETS || ZFSBOOT_DATASETS="
/usr/src
# Create /var and friends
- /var mountpoint=/var
+ /var mountpoint=/var,canmount=off
/var/crash exec=off,setuid=off
/var/log exec=off,setuid=off
/var/mail atime=on
@@ -293,6 +293,7 @@ msg_swap_mirror_help="Mirror swap partitions for redundancy, breaks crash dumps"
msg_swap_size="Swap Size"
msg_swap_size_help="Customize how much swap space is allocated to each selected disk"
msg_these_disks_are_too_small="These disks are too small given the amount of requested\nswap (%s) and/or geli(8) (%s) partitions, which would\ntake 50%% or more of each of the following selected disk\ndevices (not recommended):\n\n %s\n\nRecommend changing partition size(s) and/or selecting a\ndifferent set of devices."
+msg_uefi_not_supported="The FreeBSD UEFI loader does not currently support booting root-on-ZFS. Your system will need to boot in legacy (CSM) mode.\nDo you want to continue?"
msg_unable_to_get_disk_capacity="Unable to get disk capacity of \`%s'"
msg_unsupported_partition_scheme="%s is an unsupported partition scheme"
msg_user_cancelled="User Cancelled."
@@ -687,6 +688,48 @@ dialog_menu_layout()
return $DIALOG_OK
}
+# dialog_uefi_prompt
+#
+# Confirm that the user wants to continue with the installation on a BIOS
+# system when they have booted with UEFI
+#
+dialog_uefi_prompt()
+{
+ local title="$DIALOG_TITLE"
+ local btitle="$DIALOG_BACKTITLE"
+ local prompt # Calculated below
+ local hline="$hline_arrows_tab_enter"
+
+ local height=8 width=50 prefix=" "
+ local plen=${#prefix} list= line=
+ local max_width=$(( $width - 3 - $plen ))
+
+ local yes no defaultno extra_args format
+ if [ "$USE_XDIALOG" ]; then
+ yes=ok no=cancel defaultno=default-no
+ extra_args="--wrap --left"
+ format="$msg_uefi_not_supported"
+ else
+ yes=yes no=no defaultno=defaultno
+ extra_args="--cr-wrap"
+ format="$msg_uefi_not_supported"
+ fi
+
+ # Add height for Xdialog(1)
+ [ "$USE_XDIALOG" ] && height=$(( $height + $height / 5 + 3 ))
+
+ prompt=$( printf "$format" )
+ f_dprintf "%s: UEFI prompt" "$0"
+ $DIALOG \
+ --title "$title" \
+ --backtitle "$btitle" \
+ --hline "$hline" \
+ --$yes-label "$msg_yes" \
+ --$no-label "$msg_no" \
+ $extra_args \
+ --yesno "$prompt" $height $width
+}
+
# zfs_create_diskpart $disk $index
#
# For each block device to be used in the zpool, rather than just create the
@@ -1272,8 +1315,6 @@ zfs_create_boot()
"$funcname"
f_eval_catch $funcname echo "$ECHO_APPEND" 'zfs_enable=\"YES\"' \
$BSDINSTALL_TMPETC/rc.conf.zfs || return $FAILURE
- f_eval_catch $funcname echo "$ECHO_APPEND" 'zfs_load=\"YES\"' \
- $BSDINSTALL_TMPBOOT/loader.conf.zfs || return $FAILURE
f_eval_catch $funcname echo "$ECHO_APPEND" \
'kern.geom.label.disk_ident.enable=\"0\"' \
$BSDINSTALL_TMPBOOT/loader.conf.zfs || return $FAILURE
@@ -1386,6 +1427,21 @@ f_dprintf "BSDINSTALL_TMPETC=[%s]" "$BSDINSTALL_TMPETC"
f_dprintf "FSTAB_FMT=[%s]" "$FSTAB_FMT"
#
+# If the system was booted with UEFI, warn the user that FreeBSD can't do
+# ZFS with UEFI yet
+#
+if f_interactive; then
+ bootmethod=$(sysctl -n machdep.bootmethod)
+ f_dprintf "machdep.bootmethod=[%s]" "$bootmethod"
+ if [ "$bootmethod" != "BIOS" ]; then
+ dialog_uefi_prompt
+ retval=$?
+ f_dprintf "uefi_prompt=[%s]" "$retval"
+ [ $retval -eq $DIALOG_OK ] || f_die
+ fi
+fi
+
+#
# Loop over the main menu until we've accomplished what we came here to do
#
while :; do
OpenPOWER on IntegriCloud