Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 08 Jul 2013 15:02:04 -0400
From:      Kurt Lidl <lidl@pix.net>
To:        freebsd-current@freebsd.org
Subject:   Re: [CFT] sysutils/bsdconfg (0.9.0) and sysutils/sysrc (5.2)
Message-ID:  <51DB0CAC.4040004@pix.net>
In-Reply-To: <13CA24D6AB415D428143D44749F57D7201FB267E@ltcfiswmsgmb21>
References:  <13CA24D6AB415D428143D44749F57D7201FB267E@ltcfiswmsgmb21>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------040700080200020107080705
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

In light of Devin's CFT, I offer the following, related code...

Greetings -

I've been asked to look at inserting ZFS support into the guided setup
for FreeBSD.

I've got a mostly working set of patches, but they are still a bit
ugly -- hard wired to use ZFS now, rather than UFS, but I'm to the point
where some external input is needed.

On of the issues that I've run into is the partedit command "knows"
that pretty much a partition equates to a filesystem.  While that
is true for UFS, it's not that way for ZFS.  A partition is more likely
a zpool, and that zpool can have as many filesystems as the user
wants.

Also, the bsdinstall framework (nice piece of work!) would need to
be extended to query for zfs vs ufs and also have some hook for
setting up the different zfs filesystems.  Right now, I just kludged
in a static list of filesystems to create in the "mount" script.
I suppose there should be "filesystems" script before "mount" that
lets a user muck about in terms of creating filesystems...

Anyway, attached should be a patch against a recent snapshot of
a -current source tree to add in this code.  It's not ready for
primetime, buy I would like some feedback about the approach I've
taken so far.

Thanks.

-Kurt


--------------040700080200020107080705
Content-Type: text/plain; charset=UTF-8; x-mac-type="0"; x-mac-creator="0";
 name="zfs.diffs"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="zfs.diffs"

diff --git a/usr.sbin/bsdinstall/partedit/Makefile b/usr.sbin/bsdinstall/partedit/Makefile
--- a/usr.sbin/bsdinstall/partedit/Makefile
+++ b/usr.sbin/bsdinstall/partedit/Makefile
@@ -1,9 +1,11 @@
 # $FreeBSD$
+STRIP=
+CFLAGS+=-g
 
 BINDIR= /usr/libexec/bsdinstall
 PROG=	partedit
 LINKS= ${BINDIR}/partedit ${BINDIR}/autopart \
        ${BINDIR}/partedit ${BINDIR}/scriptedpart
 SYMLINKS= ${BINDIR}/partedit /usr/sbin/sade
 DPADD=	${LIBGEOM} ${LIBNCURSESW} ${LIBUTIL} ${LIBDIALOG} ${LIBM}
 LDADD=	-lgeom -lncursesw -lutil -ldialog -lm
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
@@ -114,16 +114,56 @@ 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 -o cachefile=/tmp/zpool.cache"
+			" -O canmount=off -O mountpoint=none ");
+		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, "zroot "); /* XXX */
 	} 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 +379,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)
@@ -586,16 +630,26 @@ set_default_part_metadata(const char *na
 		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,17 +660,17 @@ 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
@@ -743,25 +797,25 @@ 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 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)",
+		{0, "Type:", 5, 0, 0, FALSE, "freebsd-zfs", 11, 0, 12, 15, 0,
+		    FALSE, "Filesystem type (e.g. 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},
 		{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,
@@ -890,18 +944,19 @@ addpartform:
 	/* Check if the label has a / in it */
 	if (strchr(items[3].text, '/') != NULL) {
 		dialog_msgbox("Error", "Label contains a /, which is not an "
 		    "allowed character.", 0, 0, TRUE);
 		goto addpartform;
 	}
 
 	/* Warn if no mountpoint set */
-	if (strcmp(items[0].text, "freebsd-ufs") == 0 &&
-	    items[2].text[0] != '/') {
+	if ((strcmp(items[0].text, "freebsd-ufs") == 0 &&
+	    items[2].text[0] != '/') ||
+	    strcmp(items[0].text, "freebsd-zfs") == 0) {
 		dialog_vars.defaultno = TRUE;
 		choice = dialog_yesno("Warning",
 		    "This partition does not have a valid mountpoint "
 		    "(for the partition from which you intend to boot the "
 		    "operating system, the mountpoint should be /). Are you "
 		    "sure you want to continue?"
 		, 0, 0);
 		dialog_vars.defaultno = FALSE;
@@ -1040,17 +1095,17 @@ addpartform:
 
 	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
@@ -39,20 +39,26 @@
 
 #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);
 
 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"};
+
+	fstype = fstypes[0];
+	if (fsreq != NULL && strcmp(fsreq, "zfs") == 0) {
+		fstype = fstypes[1];
+	}
 
 startwizard:
 	error = geom_gettree(&mesh);
 
 	dlg_put_backtitle();
 	error = geom_gettree(&mesh);
 	disk = boot_disk(&mesh);
 	if (disk == NULL)
@@ -65,17 +71,17 @@ 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);
 }
@@ -277,26 +283,33 @@ query:
 	} else {
 		retval = strdup(disk);
 	}
 
 	return (retval);
 }
 
 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-zfs", "freebsd-ufs"};
 	int retval;
 
+	if (strcmp(fstype, "zfs") == 0) {
+		fsname = fsnames[0];
+	} else {
+		fsname = fsnames[1];
+	}
+
 	LIST_FOREACH(classp, &mesh->lg_class, lg_class)
 		if (strcmp(classp->lg_name, "PART") == 0)
 			break;
 
 	LIST_FOREACH(gp, &classp->lg_geom, lg_geom) 
 		if (strcmp(gp->lg_name, disk) == 0)
 			break;
 
@@ -326,17 +339,17 @@ wizard_makeparts(struct gmesh *mesh, con
 	swapsize = SWAP_SIZE(available);
 	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,17 @@ 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();
+		part_wizard("zfs");
 	} else if (strcmp(basename(argv[0]), "scriptedpart") == 0) {
 		error = scripted_editor(argc, argv);
 		prompt = NULL;
 		if (error != 0) {
 			end_dialog();
 			return (error);
 		}
 	} else {
@@ -157,17 +157,17 @@ main(int argc, const char **argv)
 				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");
@@ -489,16 +489,17 @@ init_fstab_metadata(void)
 		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->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
@@ -40,28 +40,30 @@ 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 *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);
@@ -72,11 +74,12 @@ int gpart_partition(const char *lg_name,
 void set_default_part_metadata(const char *name, const char *scheme,
     const char *type, const char *mountpoint, 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)
diff --git a/usr.sbin/bsdinstall/scripts/mount b/usr.sbin/bsdinstall/scripts/mount
--- a/usr.sbin/bsdinstall/scripts/mount
+++ b/usr.sbin/bsdinstall/scripts/mount
@@ -28,28 +28,67 @@
 
 TMP_FSTAB=/tmp/bsdinstall-tmp-fstab
 
 cat $PATH_FSTAB | awk -v BSDINSTALL_CHROOT=$BSDINSTALL_CHROOT '{
 	if ($2 ~ "^/.*") {
 		fsname = $2;
 		if (fsname == "/")
 			fsname = ""
-		printf("%s\t%s%s\t%s\t%s\t%s\t%s\n", $1, BSDINSTALL_CHROOT, 
+		dev = $1;
+		if ($3 == "zfs")
+			dev = "zroot"
+		printf("%s\t%s%s\t%s\t%s\t%s\t%s\n", dev, BSDINSTALL_CHROOT,
 		    fsname, $3, $4, $5, $6);
 	}
 }' > $TMP_FSTAB
 
-FILESYSTEMS=`cat $TMP_FSTAB | awk '/^[^#].*/ {if ($2 ~ "^/.*") printf("%s\n", $2);}' | sort -t /`
+FILESYSTEMS=`cat $TMP_FSTAB | awk '/^[^#].*/ {if ($2 ~ "^/.*") printf("%s:%s\n", $2,$3);}' | sort -t /`
 
-for i in $FILESYSTEMS; do
-	mkdir -p $i 2>/dev/null
-	MNTERROR=`mount -F $TMP_FSTAB $i 2>&1`
-	if [ $? -ne 0 ]; then
-		dialog --backtitle "FreeBSD Installer" --title "Error" \
-		    --msgbox "Error mounting partition $i:\n$MNTERROR" 0 0
-		exit 1
+for f in $FILESYSTEMS; do
+	mnt=${f%:*}
+	fstype=${f##*:}
+	pool=zroot
+	mkdir -p $mnt 2>/dev/null
+	if [ $fstype != "zfs" ]; then
+		MNTERROR=`mount -F $TMP_FSTAB $mnt 2>&1`
+		if [ $? -ne 0 ]; then
+			dialog --backtitle "FreeBSD Installer" --title "Error" \
+			    --msgbox "Error mounting partition $mnt:\n$MNTERROR" 0 0
+			exit 1
+		fi
+	else
+		zfs set canmount=on $pool
+		zpool export $pool
+		zpool import -R $mnt -o cachefile=/tmp/zpool.cache $pool 
+		zpool set bootfs=$pool $pool
+
+		# tricky - the import of the pool forces it under /mnt!
+		zfs set mountpoint=/ $pool
+		zfs create -o exec=on -o setuid=off ${pool}/tmp
+		zfs create $pool/usr
+		zfs create -o setuid=off ${pool}/usr/ports
+		zfs create -o exec=off -o setuid=off ${pool}/usr/src
+		zfs create -o exec=on  -o setuid=off ${pool}/usr/obj
+		zfs create $pool/var
+		zfs create -o exec=off -o setuid=off ${pool}/var/crash
+		zfs create -o exec=off -o setuid=off ${pool}/var/empty
+		zfs create -o exec=on -o setuid=off ${pool}/var/tmp
+		zfs create ${pool}/home
+		zfs mount -a
+
+		mkdir -p $mnt/boot/zfs
+		echo 'zfs_load="YES"' > $mnt/boot/loader.conf
+		echo 'vfs.root.mountfrom="zfs:'$pool'"' >> $mnt/boot/loader.conf
+		if [ -f /tmp/zpool.cache ]; then
+			cp /tmp/zpool.cache $mnt/boot/zfs/zpool.cache
+		fi
+		echo 'zfs_enable="YES"' > $BSDINSTALL_TMPETC/rc.conf.zsh
+		chmod 1777 ${mnt}/tmp ${mnt}/var/tmp
 	fi
 done
 
 # User might want a shell and require devfs, so mount it
 mkdir $BSDINSTALL_CHROOT/dev 2>/dev/null
 mount -t devfs devfs $BSDINSTALL_CHROOT/dev
+
+df > /tmp/log
+ls -l /tmp >> /tmp/log
diff --git a/usr.sbin/bsdinstall/scripts/umount b/usr.sbin/bsdinstall/scripts/umount
--- a/usr.sbin/bsdinstall/scripts/umount
+++ b/usr.sbin/bsdinstall/scripts/umount
@@ -34,9 +34,12 @@ cat $PATH_FSTAB | awk -v BSDINSTALL_CHRO
 		if (fsname == "/")
 			fsname = ""
 		printf("%s\t%s%s\t%s\t%s\t%s\t%s\n", $1, BSDINSTALL_CHROOT, 
 		    fsname, $3, $4, $5, $6);
 	}
 }' > $TMP_FSTAB
 
 umount $BSDINSTALL_CHROOT/dev 2>/dev/null
+if [ -f $BSDINSTALL_TMPETC/rc.conf.zsh ]; then
+	zfs set readonly=on zroot/var/empty
+fi
 umount -F $TMP_FSTAB -a 2>/dev/null

--------------040700080200020107080705--



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