From owner-freebsd-current@FreeBSD.ORG Mon Jul 8 19:02:05 2013 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id F1758E66 for ; Mon, 8 Jul 2013 19:02:05 +0000 (UTC) (envelope-from lidl@pix.net) Received: from hydra.pix.net (hydra.pix.net [IPv6:2001:470:e254::3c]) by mx1.freebsd.org (Postfix) with ESMTP id 3182112A3 for ; Mon, 8 Jul 2013 19:02:05 +0000 (UTC) Received: from torb.pix.net (torb.pix.net [IPv6:2001:470:e254:10:12dd:b1ff:febf:eca9]) (authenticated bits=0) by hydra.pix.net (8.14.5/8.14.5) with ESMTP id r68J24HL082177 for ; Mon, 8 Jul 2013 15:02:04 -0400 (EDT) (envelope-from lidl@pix.net) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.97.8 at mail.pix.net Message-ID: <51DB0CAC.4040004@pix.net> Date: Mon, 08 Jul 2013 15:02:04 -0400 From: Kurt Lidl User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20130620 Thunderbird/17.0.7 MIME-Version: 1.0 To: freebsd-current@freebsd.org Subject: Re: [CFT] sysutils/bsdconfg (0.9.0) and sysutils/sysrc (5.2) References: <13CA24D6AB415D428143D44749F57D7201FB267E@ltcfiswmsgmb21> In-Reply-To: <13CA24D6AB415D428143D44749F57D7201FB267E@ltcfiswmsgmb21> Content-Type: multipart/mixed; boundary="------------040700080200020107080705" X-Mailman-Approved-At: Mon, 08 Jul 2013 19:27:16 +0000 X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Jul 2013 19:02:06 -0000 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--