Date: Wed, 23 Apr 2014 19:02:10 -0400 From: Kurt Lidl <lidl@pix.net> To: Nathan Whitehorn <nwhitehorn@freebsd.org> Cc: freebsd-sysinstall@freebsd.org Subject: Re: bin/164281: bsdinstall(8): please allow sysinstall as installer option Message-ID: <20140423230210.GA20429@pix.net> In-Reply-To: <53583DB8.1080905@freebsd.org> References: <201404151630.s3FGU0Zg026166@freefall.freebsd.org> <CAM9wqY8Bn9yQvMbpMdg1wcVhx5AGgK6rP1tkh9qccDhWZaU9Kw@mail.gmail.com> <012501cf5f1f$c5e7c740$51b755c0$@FreeBSD.org> <5358223B.1090408@gmail.com> <535827AC.3040503@allanjude.com> <53582CC4.2080808@freebsd.org> <53583D5C.5020506@pix.net> <53583DB8.1080905@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
On Wed, Apr 23, 2014 at 03:24:56PM -0700, Nathan Whitehorn wrote:
>
> On 04/23/14 15:23, Kurt Lidl wrote:
> > On 4/23/14 5:12 PM, Nathan Whitehorn wrote:
> >>
> >> On 04/23/14 13:50, Allan Jude wrote:
> >>
> >>> I had big ideas for the ZFS part of the installer, to extend it further
> >>> to allow multi-way mirrors and customizing the dataset layout.
> >>
> >> That's nice to hear. Hopefully you can integrate it into the regular
> >> partition editor too. It's about to grow support for setting EFI systems
> >> and duplicating that logic around would be unfortunate.
> >
> > Hmm, I've got some kinda ugly (but functional) support for doing
> > creating zpools from the disk partitioning editor. Anybody interested
> > in the patches?
> >
> > -Kurt
> >
> >
>
> Yes, please! Allan, maybe we could set up a branch for this?
OK, here's a slightly editted diff from fbsd-stable9 to my tree.
I stripped out a little hardware specific code that diddles the
swap space size - it's not really generically useful to people.
Hopefully I didn't mess up the diff when I took that out.
A couple of notes: I unconditionally setup a 4K gnop when
creating the zfs zpool. It's kludgey, but I don't think it is
possible to get that effect through a command line option (yet).
Certainly if you want it to do this on freebsd-9 or freebsd-10
there's no command line way to do it.
The fstab that gets created for a zpool based system has a
commented out entry for / -- I have other mods in some of the
related scripts to key off that and "do the right thing" for
my purposes. This could be improved.
Finally, I took a stab at supporting ZFS booting on sparcs.
There's a comment in there about the actual "dd" command that
needs to be done to make this fly. I didn't do it. I think
a general "installbootcode" command that could be built and
applied (similar to the way I built the gnop command) could
be made to work for doing this. I'd really like this to
"just work" on sparcs too...
I didn't add any copyright to this mods, I don't know if the
changes deserve a mention or not.
-Kurt
[-- Attachment #2 --]
diff --git a/usr.sbin/bsdinstall/partedit/gpart_ops.c b/usr.sbin/bsdinstall/partedit/gpart_ops.c
--- a/usr.sbin/bsdinstall/partedit/gpart_ops.c
+++ b/usr.sbin/bsdinstall/partedit/gpart_ops.c
@@ -33,16 +33,17 @@
#include <libgeom.h>
#include <dialog.h>
#include <dlg_keys.h>
#include "partedit.h"
#define GPART_FLAGS "x" /* Do not commit changes by default */
+#define DEFAULT_ZPOOL_NAME "sys" /* default name for zpool */
static void
gpart_show_error(const char *title, const char *explanation, const char *errstr)
{
char *errmsg;
char message[512];
int error;
@@ -74,16 +75,26 @@ scheme_supports_labels(const char *schem
return (1);
if (strcmp(scheme, "PC98") == 0)
return (1);
return (0);
}
static void
+gnop_command(const char *fstype, char *command, int use_default)
+{
+ if (strcmp(fstype, "freebsd-zfs") == 0) {
+ strcpy(command, "gnop create -S 4096 ");
+ } else {
+ command[0] = '\0';
+ }
+}
+
+static void
newfs_command(const char *fstype, char *command, int use_default)
{
if (strcmp(fstype, "freebsd-ufs") == 0) {
int i;
DIALOG_LISTITEM items[] = {
{"UFS1", "UFS Version 1",
"Use version 1 of the UFS file system instead "
"of version 2 (not recommended)", 0 },
@@ -114,16 +125,57 @@ newfs_command(const char *fstype, char *
strcat(command, "-O1 ");
else if (strcmp(items[i].name, "SU") == 0)
strcat(command, "-U ");
else if (strcmp(items[i].name, "SUJ") == 0)
strcat(command, "-j ");
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 -o cachefile=none"
+ " -m none -R /mnt ");
+ 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 ");
+ }
+ strcat(command, DEFAULT_ZPOOL_NAME);
+ strcat(command, " ");
} else if (strcmp(fstype, "fat32") == 0 || strcmp(fstype, "efi") == 0) {
int i;
DIALOG_LISTITEM items[] = {
{"FAT32", "FAT Type 32",
"Create a FAT32 filesystem (default)", 1 },
{"FAT16", "FAT Type 16",
"Create a FAT16 filesystem", 0 },
{"FAT12", "FAT Type 12",
@@ -339,30 +391,34 @@ gpart_partcode(struct gprovider *pp)
LIST_FOREACH(gc, &pp->lg_geom->lg_config, lg_config) {
if (strcmp(gc->lg_name, "scheme") == 0) {
scheme = gc->lg_val;
break;
}
}
/* Make sure this partition scheme needs partcode on this platform */
- if (partcode_path(scheme) == NULL)
+ if (partcode_required(scheme) == NULL)
return;
LIST_FOREACH(gc, &pp->lg_config, lg_config) {
if (strcmp(gc->lg_name, "index") == 0) {
indexstr = gc->lg_val;
break;
}
}
/* 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);
- if (system(command) != 0) {
+ partcode_path(scheme, "zfs"), indexstr, pp->lg_geom->lg_name);
+ sprintf(message, "(echo %s; %s) >>%s 2>>%s",
+ command, command, getenv("BSDINSTALL_LOG"),
+ getenv("BSDINSTALL_LOG"));
+
+ if (system(message) != 0) {
sprintf(message, "Error installing partcode on partition %s",
pp->lg_name);
dialog_msgbox("Error", message, 0, 0, TRUE);
}
}
void
gpart_destroy(struct ggeom *lg_geom)
@@ -411,25 +467,25 @@ gpart_edit(struct gprovider *pp)
{
struct gctl_req *r;
struct gconfig *gc;
struct gconsumer *cp;
struct ggeom *geom;
const char *errstr, *oldtype, *scheme;
struct partition_metadata *md;
char sizestr[32];
- char newfs[64];
+ char gnop[255], 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-zfs, freebsd-ufs, "
+ "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},
{0, "Mountpoint:", 11, 2, 0, FALSE, "", 11, 2, 12, 15, 0,
FALSE, "Path at which to mount this partition (leave blank "
"for swap, set to / for root filesystem)", FALSE},
{0, "Label:", 7, 3, 0, FALSE, "", 11, 3, 12, 15, 0, FALSE,
"Partition name. Not all partition schemes support this.",
@@ -539,63 +595,91 @@ editpart:
if (errstr != NULL && errstr[0] != '\0') {
gpart_show_error("Error", NULL, errstr);
gctl_free(r);
goto editpart;
}
gctl_free(r);
newfs_command(items[0].text, newfs, 1);
+ gnop_command(items[0].text, gnop, 1);
set_default_part_metadata(pp->lg_name, scheme, items[0].text,
- items[2].text, (strcmp(oldtype, items[0].text) != 0) ?
- newfs : NULL);
+ items[2].text,
+ (strcmp(oldtype, items[0].text) != 0) ? gnop : NULL,
+ (strcmp(oldtype, items[0].text) != 0) ? newfs : NULL);
endedit:
if (strcmp(oldtype, items[0].text) != 0 && cp != NULL)
gpart_destroy(cp->lg_geom);
if (strcmp(oldtype, items[0].text) != 0 && strcmp(items[0].text,
"freebsd") == 0)
gpart_partition(pp->lg_name, "BSD");
for (i = 0; i < (sizeof(items) / sizeof(items[0])); i++)
if (items[i].text_free)
free(items[i].text);
}
void
set_default_part_metadata(const char *name, const char *scheme,
- const char *type, const char *mountpoint, const char *newfs)
+ const char *type, const char *mountpoint,
+ const char *gnop, const char *newfs)
{
struct partition_metadata *md;
/* Set part metadata */
md = get_part_metadata(name, 1);
+ if (gnop) {
+ if (md->gnop != NULL) {
+ free(md->gnop);
+ md->gnop = NULL;
+ }
+
+ if (gnop != NULL && gnop[0] != '\0') {
+ md->gnop = malloc(strlen(gnop) + strlen(" /dev/") +
+ strlen(name) + 1);
+ sprintf(md->gnop, "%s /dev/%s", gnop, name);
+ }
+ }
+
if (newfs) {
if (md->newfs != NULL) {
free(md->newfs);
md->newfs = NULL;
}
if (newfs != NULL && newfs[0] != '\0') {
md->newfs = malloc(strlen(newfs) + strlen(" /dev/") +
- strlen(name) + 1);
+ strlen(name) + strlen(".nop") + 1);
sprintf(md->newfs, "%s /dev/%s", newfs, name);
+ if (gnop != NULL)
+ strcat(md->newfs, ".nop");
}
}
if (strcmp(type, "freebsd-swap") == 0)
mountpoint = "none";
if (strcmp(type, "freebsd-boot") == 0)
md->bootcode = 1;
/* VTOC8 needs partcode in UFS partitions */
if (strcmp(scheme, "VTOC8") == 0 && strcmp(type, "freebsd-ufs") == 0)
md->bootcode = 1;
+ /* VTOC8 needs partcode at start of ZFS zpool */
+ if (strcmp(scheme, "VTOC8") == 0 && strcmp(type, "freebsd-zfs") == 0)
+ md->bootcode = 1;
+ /* XXX
+ * ZFS on sparc64 uses the reserved space at the front of
+ * a zpool to hold the boot code, which is generally
+ * placed there with 'dd'. Just putting the bootcode on
+ * the disk is not enough.
+ */
+
if (mountpoint == NULL || mountpoint[0] == '\0') {
if (md->fstab != NULL) {
free(md->fstab->fs_spec);
free(md->fstab->fs_file);
free(md->fstab->fs_vfstype);
free(md->fstab->fs_mntops);
free(md->fstab->fs_type);
free(md->fstab);
@@ -606,32 +690,39 @@ set_default_part_metadata(const char *na
md->fstab = malloc(sizeof(struct fstab));
} else {
free(md->fstab->fs_spec);
free(md->fstab->fs_file);
free(md->fstab->fs_vfstype);
free(md->fstab->fs_mntops);
free(md->fstab->fs_type);
}
- md->fstab->fs_spec = malloc(strlen(name) + 6);
+ 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)
md->fstab->fs_vfstype = strdup(&type[8]);
else if (strcmp("fat32", type) == 0 || strcmp("efi", type) == 0)
md->fstab->fs_vfstype = strdup("msdosfs");
else
md->fstab->fs_vfstype = strdup(type); /* Guess */
if (strcmp(type, "freebsd-swap") == 0) {
md->fstab->fs_type = strdup(FSTAB_SW);
md->fstab->fs_freq = 0;
md->fstab->fs_passno = 0;
} else {
- md->fstab->fs_type = strdup(FSTAB_RW);
+ if (strcmp("zfs",md->fstab->fs_vfstype) == 0) {
+ md->fstab->fs_type = strdup(FSTAB_XX ",noauto");
+ free(md->fstab->fs_spec);
+ md->fstab->fs_spec = malloc(strlen(name) + strlen("#/dev/") + 1);
+ sprintf(md->fstab->fs_spec, "#/dev/%s", name);
+ } else {
+ md->fstab->fs_type = strdup(FSTAB_RW);
+ }
if (strcmp(mountpoint, "/") == 0) {
md->fstab->fs_freq = 1;
md->fstab->fs_passno = 1;
} else {
md->fstab->fs_freq = 2;
md->fstab->fs_passno = 2;
}
}
@@ -743,26 +834,26 @@ gpart_create(struct gprovider *pp, char
char *default_mountpoint, char **partname, int interactive)
{
struct gctl_req *r;
struct gconfig *gc;
struct gconsumer *cp;
struct ggeom *geom;
const char *errstr, *scheme;
char sizestr[32], startstr[32], output[64], *newpartname;
- char newfs[64], options_fstype[64];
+ char gnop[255], newfs[255], options_fstype[64];
intmax_t maxsize, size, sector, firstfree, stripe;
uint64_t bytes;
int nitems, choice, junk;
unsigned i;
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},
+ {0, "Type:", 5, 0, 0, FALSE, "freebsd-zfs", 11, 0, 12, 15, 0,
+ FALSE, "Filesystem type (e.g. freebsd-zfs, freebsd-ufs, "
+ "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},
{0, "Mountpoint:", 11, 2, 0, FALSE, "", 11, 2, 12, 15, 0,
FALSE, "Path at which to mount partition (blank for "
"swap, / for root filesystem)", FALSE},
{0, "Label:", 7, 3, 0, FALSE, "", 11, 3, 12, 15, 0, FALSE,
"Partition name. Not all partition schemes support this.",
@@ -841,43 +932,46 @@ gpart_create(struct gprovider *pp, char
items[1].text = default_size;
if (default_mountpoint != NULL)
items[2].text = default_mountpoint;
/* Default options */
strncpy(options_fstype, items[0].text,
sizeof(options_fstype));
newfs_command(options_fstype, newfs, 1);
+ gnop_command(options_fstype, gnop, 1);
addpartform:
if (interactive) {
dialog_vars.extra_label = "Options";
dialog_vars.extra_button = TRUE;
choice = dlg_form("Add Partition", "", 0, 0, 0, nitems,
items, &junk);
dialog_vars.extra_button = FALSE;
switch (choice) {
case 0: /* OK */
break;
case 1: /* Cancel */
return;
case 3: /* Options */
strncpy(options_fstype, items[0].text,
sizeof(options_fstype));
newfs_command(options_fstype, newfs, 0);
+ gnop_command(options_fstype, gnop, 0);
goto addpartform;
}
}
/*
* If the user changed the fs type after specifying options, undo
* their choices in favor of the new filesystem's defaults.
*/
if (strcmp(options_fstype, items[0].text) != 0) {
strncpy(options_fstype, items[0].text, sizeof(options_fstype));
newfs_command(options_fstype, newfs, 1);
+ gnop_command(options_fstype, gnop, 1);
}
size = maxsize;
if (strlen(items[1].text) > 0) {
if (expand_number(items[1].text, &bytes) != 0) {
char error[512];
sprintf(error, "Invalid size: %s\n", strerror(errno));
@@ -969,16 +1063,18 @@ addpartform:
gctl_ro_param(r, "class", -1, "PART");
gctl_ro_param(r, "arg0", -1, geom->lg_name);
gctl_ro_param(r, "flags", -1, GPART_FLAGS);
gctl_ro_param(r, "verb", -1, "add");
gctl_ro_param(r, "type", -1, "freebsd-boot");
snprintf(sizestr, sizeof(sizestr), "%jd",
bootpart_size(scheme) / sector);
gctl_ro_param(r, "size", -1, sizestr);
+ if (34 == firstfree)
+ firstfree += 30+64; /* round to 64K boundary */
snprintf(startstr, sizeof(startstr), "%jd", firstfree);
gctl_ro_param(r, "start", -1, startstr);
gctl_rw_param(r, "output", sizeof(output), output);
errstr = gctl_issue(r);
if (errstr != NULL && errstr[0] != '\0')
gpart_show_error("Error", NULL, errstr);
gctl_free(r);
@@ -1031,26 +1127,26 @@ addpartform:
gctl_free(r);
if (strcmp(items[0].text, "freebsd-boot") == 0)
get_part_metadata(newpartname, 1)->bootcode = 1;
else if (strcmp(items[0].text, "freebsd") == 0)
gpart_partition(newpartname, "BSD");
else
set_default_part_metadata(newpartname, scheme,
- items[0].text, items[2].text, newfs);
+ items[0].text, items[2].text, gnop, newfs);
for (i = 0; i < (sizeof(items) / sizeof(items[0])); i++)
if (items[i].text_free)
free(items[i].text);
if (partname != NULL)
*partname = strdup(newpartname);
}
-
+
void
gpart_delete(struct gprovider *pp)
{
struct gconfig *gc;
struct ggeom *geom;
struct gconsumer *cp;
struct gctl_req *r;
const char *errstr;
diff --git a/usr.sbin/bsdinstall/partedit/part_wizard.c b/usr.sbin/bsdinstall/partedit/part_wizard.c
--- a/usr.sbin/bsdinstall/partedit/part_wizard.c
+++ b/usr.sbin/bsdinstall/partedit/part_wizard.c
@@ -26,33 +26,48 @@
* $FreeBSD$
*/
#include <sys/param.h>
#include <errno.h>
#include <libutil.h>
#include <inttypes.h>
+#include <sys/sysctl.h>
+#include <string.h>
+
#include <libgeom.h>
#include <dialog.h>
#include <dlg_keys.h>
#include "partedit.h"
#define MIN_FREE_SPACE (1024*1024*1024) /* 1 GB */
#define SWAP_SIZE(available) MIN(available/20, 4*1024*1024*1024LL)
static char *boot_disk(struct gmesh *mesh);
static char *wizard_partition(struct gmesh *mesh, const char *disk);
+static intmax_t calc_swapsize(void);
int
-part_wizard(void) {
+part_wizard(const char *fsreq) {
int error;
struct gmesh mesh;
- char *disk, *schemeroot;
+ char *disk, *schemeroot, *fstype;
+ char *fstypes[] = {"ufs", "zfs"};
+
+ if (fsreq != NULL && strcmp(fsreq, "zfs") == 0) {
+ fstype = fstypes[1];
+ } else {
+ /* default to UFS */
+ fstype = fstypes[0];
+ }
startwizard:
error = geom_gettree(&mesh);
dlg_put_backtitle();
error = geom_gettree(&mesh);
disk = boot_disk(&mesh);
if (disk == NULL)
@@ -65,21 +80,21 @@ startwizard:
if (schemeroot == NULL)
return (1);
geom_deletetree(&mesh);
dlg_clear();
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);
}
static char *
boot_disk(struct gmesh *mesh)
{
@@ -101,19 +116,19 @@ boot_disk(struct gmesh *mesh)
LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
if (LIST_EMPTY(&gp->lg_provider))
continue;
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;
}
/* Skip swap-backed md and WORM devices */
if (strcmp(classp->lg_name, "MD") == 0 &&
type != NULL && strcmp(type, "swap") == 0)
continue;
if (strncmp(pp->lg_name, "cd", 2) == 0)
@@ -195,17 +210,17 @@ wizard_partition(struct gmesh *mesh, con
char *retval = NULL;
int choice;
LIST_FOREACH(classp, &mesh->lg_class, lg_class)
if (strcmp(classp->lg_name, "PART") == 0)
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;
}
if (gpart != NULL) {
LIST_FOREACH(gc, &gpart->lg_config, lg_config) {
if (strcmp(gc->lg_name, "scheme") == 0) {
scheme = gc->lg_val;
@@ -276,32 +291,93 @@ query:
geom_deletetree(&submesh);
} else {
retval = strdup(disk);
}
return (retval);
}
+intmax_t
+calc_swapsize(void)
+{
+ size_t physmem;
+ size_t physmemlen = sizeof(physmem);
+ intmax_t swapsize;
+
+ sysctlbyname("hw.physmem", &physmem, &physmemlen, NULL, 0);
+ fprintf(stderr, "system physmem = %ld\n", physmem);
+ swapsize = physmem;
+ if (physmem > 1024 * 1024 * 1024) {
+ swapsize += 1024LL * 1024 * 1024 + 1024LL * 1024;
+ fprintf(stderr, "swapsize before rounding = %ld\n", swapsize);
+ swapsize = swapsize & 0xFFFFFFFFC0000000LL; // GB
+ } else {
+ swapsize += 2LL * 1024 * 1024;
+ fprintf(stderr, "swapsize before rounding = %ld\n", swapsize);
+ swapsize = swapsize & 0xFFFFFFFFFFF00000LL; // MB
+ }
+ fprintf(stderr, "rounded swapsize = %ld\n", swapsize);
+
+ return swapsize;
+}
+
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;
pp = provider_for_name(mesh, disk);
available = gpart_max_free(gp, NULL)*pp->lg_sectorsize;
if (interactive && available < MIN_FREE_SPACE) {
char availablestr[10], neededstr[10], message[512];
@@ -318,25 +394,25 @@ wizard_makeparts(struct gmesh *mesh, con
dialog_vars.no_label = "Editor";
retval = dialog_yesno("Warning", message, 0, 0);
dialog_vars.yes_label = NULL;
dialog_vars.no_label = NULL;
return (!retval); /* Editor -> return 0 */
}
- swapsize = SWAP_SIZE(available);
+ swapsize = calc_swapsize();
humanize_number(swapsizestr, 7, swapsize, "B", HN_AUTOSCALE,
HN_NOSPACE | HN_DECIMAL);
humanize_number(rootsizestr, 7, available - swapsize - 1024*1024,
"B", HN_AUTOSCALE, HN_NOSPACE | HN_DECIMAL);
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);
pp = provider_for_name(&submesh, disk);
gpart_create(pp, "freebsd-swap", swapsizestr, NULL, NULL, 0);
geom_deletetree(&submesh);
return (0);
diff --git a/usr.sbin/bsdinstall/partedit/partedit.c b/usr.sbin/bsdinstall/partedit/partedit.c
--- a/usr.sbin/bsdinstall/partedit/partedit.c
+++ b/usr.sbin/bsdinstall/partedit/partedit.c
@@ -90,17 +90,21 @@ main(int argc, const char **argv)
nscroll = i = 0;
/* Revert changes on SIGINT */
signal(SIGINT, sigint_handler);
if (strcmp(basename(argv[0]), "autopart") == 0) { /* Guided */
prompt = "Please review the disk setup. When complete, press "
"the Finish button.";
- part_wizard();
+ if (argc > 1 && strcmp(basename(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;
if (error != 0) {
end_dialog();
return (error);
}
} else {
@@ -147,27 +151,29 @@ main(int argc, const char **argv)
if (md->fstab != NULL) {
free(md->fstab->fs_spec);
free(md->fstab->fs_file);
free(md->fstab->fs_vfstype);
free(md->fstab->fs_mntops);
free(md->fstab->fs_type);
free(md->fstab);
}
+ if (md->gnop != NULL)
+ free(md->gnop);
if (md->newfs != NULL)
free(md->newfs);
free(md->name);
TAILQ_REMOVE(&part_metadata, md, metadata);
free(md);
}
init_fstab_metadata();
break;
case 4: /* Auto */
- part_wizard();
+ part_wizard("zfs");
break;
}
error = 0;
if (op == 5) { /* Finished */
dialog_vars.ok_label = __DECONST(char *, "Commit");
dialog_vars.extra_label =
__DECONST(char *, "Revert & Exit");
@@ -241,16 +247,18 @@ delete_part_metadata(const char *name)
if (md->fstab != NULL) {
free(md->fstab->fs_spec);
free(md->fstab->fs_file);
free(md->fstab->fs_vfstype);
free(md->fstab->fs_mntops);
free(md->fstab->fs_type);
free(md->fstab);
}
+ if (md->gnop != NULL)
+ free(md->gnop);
if (md->newfs != NULL)
free(md->newfs);
free(md->name);
TAILQ_REMOVE(&part_metadata, md, metadata);
free(md);
break;
}
@@ -340,16 +348,23 @@ apply_changes(struct gmesh *mesh)
setenv("BSDINSTALL_LOG", "/dev/null", 1);
TAILQ_FOREACH(md, &part_metadata, metadata) {
if (md->newfs != NULL) {
items[i*2 + 1] = "7"; /* In progress */
dialog_mixedgauge("Initializing",
"Initializing file systems. Please wait.", 0, 0,
i*100/nitems, nitems, __DECONST(char **, items));
+ if (md->gnop != NULL) {
+ sprintf(message, "(echo %s; %s) >>%s 2>>%s",
+ md->gnop, md->gnop,
+ getenv("BSDINSTALL_LOG"),
+ getenv("BSDINSTALL_LOG"));
+ error = system(message);
+ }
sprintf(message, "(echo %s; %s) >>%s 2>>%s",
md->newfs, md->newfs, getenv("BSDINSTALL_LOG"),
getenv("BSDINSTALL_LOG"));
error = system(message);
items[i*2 + 1] = (error == 0) ? "3" : "1";
i++;
}
}
@@ -367,20 +382,20 @@ apply_changes(struct gmesh *mesh)
fstab_path = "/etc/fstab";
fstab = fopen(fstab_path, "w+");
if (fstab == NULL) {
sprintf(message, "Cannot open fstab file %s for writing (%s)\n",
getenv("PATH_FSTAB"), strerror(errno));
dialog_msgbox("Error", message, 0, 0, TRUE);
return (-1);
}
- fprintf(fstab, "# Device\tMountpoint\tFStype\tOptions\tDump\tPass#\n");
+ fprintf(fstab, "# Device\t\tMountpoint\tFStype\tOptions\t\tDump\tPass#\n");
TAILQ_FOREACH(md, &part_metadata, metadata) {
if (md->fstab != NULL)
- fprintf(fstab, "%s\t%s\t\t%s\t%s\t%d\t%d\n",
+ fprintf(fstab, "%s\t\t%s\t\t%s\t%s\t\t%d\t%d\n",
md->fstab->fs_spec, md->fstab->fs_file,
md->fstab->fs_vfstype, md->fstab->fs_mntops,
md->fstab->fs_freq, md->fstab->fs_passno);
}
fclose(fstab);
return (0);
}
@@ -488,17 +503,19 @@ init_fstab_metadata(void)
md->fstab->fs_spec = strdup(fstab->fs_spec);
md->fstab->fs_file = strdup(fstab->fs_file);
md->fstab->fs_vfstype = strdup(fstab->fs_vfstype);
md->fstab->fs_mntops = strdup(fstab->fs_mntops);
md->fstab->fs_type = strdup(fstab->fs_type);
md->fstab->fs_freq = fstab->fs_freq;
md->fstab->fs_passno = fstab->fs_passno;
+ md->gnop = NULL;
md->newfs = NULL;
+ md->poolname = NULL;
TAILQ_INSERT_TAIL(&part_metadata, md, metadata);
}
}
static void
get_mount_points(struct partedit_item *items, int nitems)
{
diff --git a/usr.sbin/bsdinstall/partedit/partedit.h b/usr.sbin/bsdinstall/partedit/partedit.h
--- a/usr.sbin/bsdinstall/partedit/partedit.h
+++ b/usr.sbin/bsdinstall/partedit/partedit.h
@@ -39,44 +39,49 @@ struct ggeom;
TAILQ_HEAD(pmetadata_head, partition_metadata);
extern struct pmetadata_head part_metadata;
struct partition_metadata {
char *name; /* name of this partition, as in GEOM */
struct fstab *fstab; /* fstab data for this partition */
+ char *gnop; /* shell command to initialize gnop */
char *newfs; /* shell command to initialize partition */
+ char *poolname; /* ZFS pool name */
int bootcode;
TAILQ_ENTRY(partition_metadata) 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);
void gpart_destroy(struct ggeom *lg_geom);
void gpart_edit(struct gprovider *pp);
void gpart_create(struct gprovider *pp, char *default_type, char *default_size,
char *default_mountpoint, char **output, int interactive);
intmax_t gpart_max_free(struct ggeom *gp, intmax_t *start);
void gpart_revert(struct gprovider *pp);
void gpart_revert_all(struct gmesh *mesh);
void gpart_commit(struct gmesh *mesh);
int gpart_partition(const char *lg_name, const char *scheme);
void set_default_part_metadata(const char *name, const char *scheme,
- const char *type, const char *mountpoint, const char *newfs);
+ const char *type, const char *mountpoint,
+ const char *gnop, const char *newfs);
/* machine-dependent bootability checks */
const char *default_scheme(void);
int is_scheme_bootable(const char *part_type);
size_t bootpart_size(const char *part_type);
const char *bootcode_path(const char *part_type);
-const char *partcode_path(const char *part_type);
+const char *partcode_required(const char *part_type);
+const char *partcode_path(const char *part_type, const char *fs_type);
#endif
diff --git a/usr.sbin/bsdinstall/partedit/partedit_generic.c b/usr.sbin/bsdinstall/partedit/partedit_generic.c
--- a/usr.sbin/bsdinstall/partedit/partedit_generic.c
+++ b/usr.sbin/bsdinstall/partedit/partedit_generic.c
@@ -56,14 +56,19 @@ size_t
bootpart_size(const char *part_type) {
return (0);
}
const char *
bootcode_path(const char *part_type) {
return (NULL);
}
-
+
const char *
-partcode_path(const char *part_type) {
+partcode_required(const char *part_type) {
return (NULL);
}
+const char *
+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
--- a/usr.sbin/bsdinstall/partedit/partedit_pc98.c
+++ b/usr.sbin/bsdinstall/partedit/partedit_pc98.c
@@ -55,15 +55,21 @@ const char *
bootcode_path(const char *part_type) {
if (strcmp(part_type, "PC98") == 0)
return ("/boot/pc98boot");
if (strcmp(part_type, "BSD") == 0)
return ("/boot/boot");
return (NULL);
}
-
+
const char *
-partcode_path(const char *part_type) {
+partcode_required(const char *part_type) {
/* No partcode */
return (NULL);
}
+const char *
+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
--- a/usr.sbin/bsdinstall/partedit/partedit_powerpc.c
+++ b/usr.sbin/bsdinstall/partedit/partedit_powerpc.c
@@ -71,18 +71,25 @@ bootpart_size(const char *part_type) {
return (800*1024);
return (0);
}
const char *
bootcode_path(const char *part_type) {
return (NULL);
}
-
+
const char *
-partcode_path(const char *part_type) {
+partcode_required(const char *part_type) {
+ if (strcmp(part_type, "APM") == 0 || strcmp(part_type, "MBR") == 0)
+ return ("required");
+ return (NULL);
+}
+
+const char *
+partcode_path(const char *part_type, const char *fs_type) {
if (strcmp(part_type, "APM") == 0)
return ("/boot/boot1.hfs");
if (strcmp(part_type, "MBR") == 0)
return ("/boot/boot1.elf");
return (NULL);
}
diff --git a/usr.sbin/bsdinstall/partedit/partedit_sparc64.c b/usr.sbin/bsdinstall/partedit/partedit_sparc64.c
--- a/usr.sbin/bsdinstall/partedit/partedit_sparc64.c
+++ b/usr.sbin/bsdinstall/partedit/partedit_sparc64.c
@@ -48,16 +48,28 @@ bootpart_size(const char *part_type) {
return (0);
}
const char *
bootcode_path(const char *part_type) {
return (NULL);
}
-
+
const char *
-partcode_path(const char *part_type) {
+partcode_required(const char *part_type) {
if (strcmp(part_type, "VTOC8") == 0)
- return ("/boot/boot1");
+ return ("required");
return (NULL);
}
+const char *
+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
--- a/usr.sbin/bsdinstall/partedit/partedit_x86.c
+++ b/usr.sbin/bsdinstall/partedit/partedit_x86.c
@@ -62,18 +62,31 @@ bootcode_path(const char *part_type) {
return ("/boot/pmbr");
if (strcmp(part_type, "MBR") == 0)
return ("/boot/mbr");
if (strcmp(part_type, "BSD") == 0)
return ("/boot/boot");
return (NULL);
}
-
+
const char *
-partcode_path(const char *part_type) {
+partcode_required(const char *part_type) {
if (strcmp(part_type, "GPT") == 0)
- return ("/boot/gptboot");
+ return ("required");
/* No partcode except for GPT */
return (NULL);
}
+const char *
+partcode_path(const char *part_type, const char *fs_type) {
+ if (strcmp(part_type, "GPT") == 0) {
+ if (strcmp(fs_type, "ufs") == 0) {
+ return ("/boot/gptboot");
+ } else if (strcmp(fs_type, "zfs") == 0) {
+ return ("/boot/gptzfsboot");
+ }
+ }
+
+ return (NULL);
+}
+
diff --git a/usr.sbin/bsdinstall/partedit/scripted.c b/usr.sbin/bsdinstall/partedit/scripted.c
--- a/usr.sbin/bsdinstall/partedit/scripted.c
+++ b/usr.sbin/bsdinstall/partedit/scripted.c
@@ -104,17 +104,17 @@ part_config(char *disk, const char *sche
disk= strdup(disk);
}
geom_deletetree(&mesh);
error = geom_gettree(&mesh);
/* Create partitions */
if (config == NULL) {
- wizard_makeparts(&mesh, disk, 0);
+ wizard_makeparts(&mesh, disk, "zfs", 0);
goto finished;
}
while ((partition = strsep(&config, ",")) != NULL) {
while ((ap = strsep(&partition, " \t\n")) != NULL) {
if (*ap == '\0')
continue;
if (size == NULL)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140423230210.GA20429>
