Skip site navigation (1)Skip section navigation (2)
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

--LZvS9be/3tNcYl/X
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

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


--LZvS9be/3tNcYl/X
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="partedit.diff"

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)

--LZvS9be/3tNcYl/X--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140423230210.GA20429>