[Midnightbsd-cvs] src [11302] trunk/usr.sbin/bsdinstall/partedit/gpart_ops.c: add zfs hash checksum algorithms

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Wed Jul 4 09:56:15 EDT 2018


Revision: 11302
          http://svnweb.midnightbsd.org/src/?rev=11302
Author:   laffer1
Date:     2018-07-04 09:56:15 -0400 (Wed, 04 Jul 2018)
Log Message:
-----------
add zfs hash checksum algorithms

Modified Paths:
--------------
    trunk/usr.sbin/bsdinstall/partedit/gpart_ops.c

Modified: trunk/usr.sbin/bsdinstall/partedit/gpart_ops.c
===================================================================
--- trunk/usr.sbin/bsdinstall/partedit/gpart_ops.c	2018-07-04 13:47:52 UTC (rev 11301)
+++ trunk/usr.sbin/bsdinstall/partedit/gpart_ops.c	2018-07-04 13:56:15 UTC (rev 11302)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2011 Nathan Whitehorn
  * All rights reserved.
@@ -23,11 +24,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
- * $FreeBSD: src/usr.sbin/bsdinstall/partedit/gpart_ops.c,v 1.10 2011/10/23 16:57:10 nwhitehorn Exp $
+ * $FreeBSD: stable/10/usr.sbin/bsdinstall/partedit/gpart_ops.c 329870 2018-02-23 16:46:49Z rpokala $
  */
 
 #include <sys/param.h>
+#include <sys/stat.h>
 #include <errno.h>
 #include <libutil.h>
 #include <inttypes.h>
@@ -73,6 +74,8 @@
 		return (1);
 	if (strcmp(scheme, "GPT") == 0)
 		return (1);
+	if (strcmp(scheme, "PC98") == 0)
+		return (1);
 
 	return (0);
 }
@@ -118,6 +121,53 @@
 			else if (strcmp(items[i].name, "TRIM") == 0)
 				strcat(command, "-t ");
 		}
+	} else if (strcmp(fstype, "mnbsd-zfs") == 0) {
+		int i;
+		DIALOG_LISTITEM items[] = {
+			{"fletcher4", "checksum algorithm: fletcher4",
+			    "Use fletcher4 for data integrity checking. "
+			    "(default)", 1 },
+			{"fletcher2", "checksum algorithm: fletcher2",
+			    "Use fletcher2 for data integrity checking. "
+			    "(not recommended)", 0 },
+			{"sha256", "checksum algorithm: sha256",
+			    "Use sha256 for data integrity checking. "
+			    "(not recommended)", 0 },
+			{"atime", "Update atimes for files",
+			    "Disable atime update", 0 },
+		};
+
+		if (!use_default) {
+			int choice;
+			choice = dlg_checklist("ZFS Options", "", 0, 0, 0,
+			    sizeof(items)/sizeof(items[0]), items, NULL,
+			    FLAG_CHECK, &i);
+			if (choice == 1) /* Cancel */
+				return;
+		}
+
+		strcpy(command, "zpool create -f -m none ");
+		if (getenv("BSDINSTALL_TMPBOOT") != NULL) {
+			char zfsboot_path[MAXPATHLEN];
+			sprintf(zfsboot_path, "%s/zfs",
+			    getenv("BSDINSTALL_TMPBOOT"));
+			mkdir(zfsboot_path, S_IRWXU | S_IRGRP | S_IXGRP |
+			    S_IROTH | S_IXOTH);
+			sprintf(command, "%s -o cachefile=%s/zpool.cache ",
+			    command, zfsboot_path);
+		}
+		for (i = 0; i < (int)(sizeof(items)/sizeof(items[0])); i++) {
+			if (items[i].state == 0)
+				continue;
+			if (strcmp(items[i].name, "fletcher4") == 0)
+				strcat(command, "-O checksum=fletcher4 ");
+			else if (strcmp(items[i].name, "fletcher2") == 0)
+				strcat(command, "-O checksum=fletcher2 ");
+			else if (strcmp(items[i].name, "sha256") == 0)
+				strcat(command, "-O checksum=sha256 ");
+			else if (strcmp(items[i].name, "atime") == 0)
+				strcat(command, "-O atime=off ");
+		}
 	} else if (strcmp(fstype, "fat32") == 0 || strcmp(fstype, "efi") == 0) {
 		int i;
 		DIALOG_LISTITEM items[] = {
@@ -157,14 +207,15 @@
 	}
 }
 
-int
-gpart_partition(const char *lg_name, const char *scheme)
+const char *
+choose_part_type(const char *def_scheme)
 {
 	int cancel, choice;
-	struct gctl_req *r;
-	const char *errstr;
+	const char *scheme = NULL;
 
 	DIALOG_LISTITEM items[] = {
+		{"APM", "Apple Partition Map",
+		    "Bootable on PowerPC Apple Hardware", 0 },
 		{"BSD", "BSD Labels",
 		    "Bootable on most x86 systems", 0 },
 		{"GPT", "GUID Partition Table",
@@ -171,34 +222,67 @@
 		    "Bootable on most x86 systems", 0 },
 		{"MBR", "DOS Partitions",
 		    "Bootable on most x86 systems", 0 },
+		{"PC98", "NEC PC9801 Partition Table",
+		    "Bootable on NEC PC9801 systems", 0 },
 		{"VTOC8", "Sun VTOC8 Partition Table",
 		    "Bootable on Sun SPARC systems", 0 },
 	};
 
+parttypemenu:
+	dialog_vars.default_item = __DECONST(char *, def_scheme);
+	cancel = dlg_menu("Partition Scheme",
+	    "Select a partition scheme for this volume:", 0, 0, 0,
+	    sizeof(items) / sizeof(items[0]), items, &choice, NULL);
+	dialog_vars.default_item = NULL;
+
+	if (cancel)
+		return NULL;
+
+	if (!is_scheme_bootable(items[choice].name)) {
+		char message[512];
+		sprintf(message, "This partition scheme (%s) is not "
+		    "bootable on this platform. Are you sure you want "
+		    "to proceed?", items[choice].name);
+		dialog_vars.defaultno = TRUE;
+		cancel = dialog_yesno("Warning", message, 0, 0);
+		dialog_vars.defaultno = FALSE;
+		if (cancel) /* cancel */
+			goto parttypemenu;
+	}
+
+	scheme = items[choice].name;
+
+	return scheme;
+}
+
+int
+gpart_partition(const char *lg_name, const char *scheme)
+{
+	int cancel;
+	struct gctl_req *r;
+	const char *errstr;
+
 schememenu:
 	if (scheme == NULL) {
-		dialog_vars.default_item = __DECONST(char *, default_scheme());
-		cancel = dlg_menu("Partition Scheme",
-		    "Select a partition scheme for this volume:", 0, 0, 0,
-		    sizeof(items) / sizeof(items[0]), items, &choice, NULL);
-		dialog_vars.default_item = NULL;
+		scheme = choose_part_type(default_scheme());
 
-		if (cancel)
+		if (scheme == NULL)
 			return (-1);
 
-		if (!is_scheme_bootable(items[choice].name)) {
+		if (!is_scheme_bootable(scheme)) {
 			char message[512];
 			sprintf(message, "This partition scheme (%s) is not "
 			    "bootable on this platform. Are you sure you want "
-			    "to proceed?", items[choice].name);
+			    "to proceed?", scheme);
 			dialog_vars.defaultno = TRUE;
 			cancel = dialog_yesno("Warning", message, 0, 0);
 			dialog_vars.defaultno = FALSE;
-			if (cancel) /* cancel */
+			if (cancel) { /* cancel */
+				/* Reset scheme so user can choose another */
+				scheme = NULL;
 				goto schememenu;
+			}
 		}
-
-		scheme = items[choice].name;
 	}
 
 	r = gctl_get_handle();
@@ -242,7 +326,8 @@
 		}
 	}
 
-	if (strcmp(scheme, "MBR") == 0 || strcmp(scheme, "EBR") == 0)
+	if (strcmp(scheme, "MBR") == 0 || strcmp(scheme, "EBR") == 0 ||
+	    strcmp(scheme, "PC98") == 0)
 		attribute = "active";
 	else
 		return;
@@ -268,6 +353,26 @@
 	gctl_free(r);
 }
 
+void
+gpart_set_root(const char *lg_name, const char *attribute)
+{
+	struct gctl_req *r;
+	const char *errstr;
+
+	r = gctl_get_handle();
+	gctl_ro_param(r, "class", -1, "PART");
+	gctl_ro_param(r, "arg0", -1, lg_name);
+	gctl_ro_param(r, "flags", -1, "C");
+	gctl_ro_param(r, "verb", -1, "set");
+	gctl_ro_param(r, "attrib", -1, attribute);
+
+	errstr = gctl_issue(r);
+	if (errstr != NULL && errstr[0] != '\0') 
+		gpart_show_error("Error", "Error setting parameter on disk:",
+		    errstr);
+	gctl_free(r);
+}
+
 static void
 gpart_bootcode(struct ggeom *gp)
 {
@@ -323,7 +428,7 @@
 }
 
 static void
-gpart_partcode(struct gprovider *pp)
+gpart_partcode(struct gprovider *pp, const char *fstype)
 {
 	struct gconfig *gc;
 	const char *scheme;
@@ -338,7 +443,7 @@
 	}
 
 	/* Make sure this partition scheme needs partcode on this platform */
-	if (partcode_path(scheme) == NULL)
+	if (partcode_path(scheme, fstype) == NULL)
 		return;
 
 	LIST_FOREACH(gc, &pp->lg_config, lg_config) {
@@ -350,7 +455,7 @@
 
 	/* Shell out to gpart for partcode for now */
 	sprintf(command, "gpart bootcode -p %s -i %s %s",
-	    partcode_path(scheme), indexstr, pp->lg_geom->lg_name);
+	    partcode_path(scheme, fstype), indexstr, pp->lg_geom->lg_name);
 	if (system(command) != 0) {
 		sprintf(message, "Error installing partcode on partition %s",
 		    pp->lg_name);
@@ -410,7 +515,7 @@
 	const char *errstr, *oldtype, *scheme;
 	struct partition_metadata *md;
 	char sizestr[32];
-	char newfs[64];
+	char newfs[255];
 	intmax_t idx;
 	int hadlabel, choice, junk, nitems;
 	unsigned i;
@@ -417,8 +522,8 @@
 
 	DIALOG_FORMITEM items[] = {
 		{0, "Type:", 5, 0, 0, FALSE, "", 11, 0, 12, 15, 0,
-		    FALSE, "Filesystem type (e.g. mnbsd-ufs, mnbsd-swap)",
-		    FALSE},
+		    FALSE, "Filesystem type (e.g. mnbsd-ufs, mnbsd-zfs, "
+		    "mnbsd-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},
@@ -559,6 +664,8 @@
     const char *type, const char *mountpoint, const char *newfs)
 {
 	struct partition_metadata *md;
+	char *zpool_name = NULL;
+	int i;
 
 	/* Set part metadata */
 	md = get_part_metadata(name, 1);
@@ -571,18 +678,29 @@
 
 		if (newfs != NULL && newfs[0] != '\0') {
 			md->newfs = malloc(strlen(newfs) + strlen(" /dev/") +
-			    strlen(name) + 1);
-			sprintf(md->newfs, "%s /dev/%s", newfs, name);
+			    strlen(mountpoint) + 5 + strlen(name) + 1);
+			if (strcmp("mnbsd-zfs", type) == 0) {
+				zpool_name = strdup((strlen(mountpoint) == 1) ?
+				    "root" : &mountpoint[1]);
+				for (i = 0; zpool_name[i] != 0; i++)
+					if (!isalnum(zpool_name[i]))
+						zpool_name[i] = '_';
+				sprintf(md->newfs, "%s %s /dev/%s", newfs,
+				    zpool_name, name);
+			} else {
+				sprintf(md->newfs, "%s /dev/%s", newfs, name);
+			}
 		}
 	}
 
 	if (strcmp(type, "mnbsd-swap") == 0)
 		mountpoint = "none";
-	if (strcmp(type, "mnbsd-boot") == 0)
+	if (strcmp(type, bootpart_type(scheme)) == 0)
 		md->bootcode = 1;
 
-	/* VTOC8 needs partcode in UFS partitions */
-	if (strcmp(scheme, "VTOC8") == 0 && strcmp(type, "mnbsd-ufs") == 0)
+	/* VTOC8 needs partcode at the start of partitions */
+	if (strcmp(scheme, "VTOC8") == 0 && (strcmp(type, "mnbsd-ufs") == 0
+	    || strcmp(type, "mnbsd-zfs") == 0))
 		md->bootcode = 1;
 
 	if (mountpoint == NULL || mountpoint[0] == '\0') {
@@ -605,12 +723,17 @@
 			free(md->fstab->fs_mntops);
 			free(md->fstab->fs_type);
 		}
-		md->fstab->fs_spec = malloc(strlen(name) + 6);
-		sprintf(md->fstab->fs_spec, "/dev/%s", name);
+		if (strcmp("mnbsd-zfs", type) == 0) {
+			md->fstab->fs_spec = strdup(zpool_name);
+		} else {
+			md->fstab->fs_spec = malloc(strlen(name) +
+			    strlen("/dev/") + 1);
+			sprintf(md->fstab->fs_spec, "/dev/%s", name);
+		}
 		md->fstab->fs_file = strdup(mountpoint);
 		/* Get VFS from text after mnbsd-, if possible */
-		if (strncmp("mnbsd-", type, 6) == 0)
-			md->fstab->fs_vfstype = strdup(&type[6]);
+		if (strncmp("mnbsd-", 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
@@ -619,6 +742,10 @@
 			md->fstab->fs_type = strdup(FSTAB_SW);
 			md->fstab->fs_freq = 0;
 			md->fstab->fs_passno = 0;
+		} else if (strcmp(type, "mnbsd-zfs") == 0) {
+			md->fstab->fs_type = strdup(FSTAB_RW);
+			md->fstab->fs_freq = 0;
+			md->fstab->fs_passno = 0;
 		} else {
 			md->fstab->fs_type = strdup(FSTAB_RW);
 			if (strcmp(mountpoint, "/") == 0) {
@@ -631,6 +758,9 @@
 		}
 		md->fstab->fs_mntops = strdup(md->fstab->fs_type);
 	}
+
+	if (zpool_name != NULL)
+		free(zpool_name);
 }
 
 static
@@ -666,6 +796,7 @@
 {
 	struct gconfig *gc;
 	struct gprovider *pp, **providers;
+	intmax_t sectorsize, stripesize, offset;
 	intmax_t lastend;
 	intmax_t start, end;
 	intmax_t maxsize, maxstart;
@@ -716,12 +847,25 @@
 
 	pp = LIST_FIRST(&geom->lg_consumer)->lg_provider;
 
-	/* Compute beginning of new partition and maximum available space */
-	if (pp->lg_stripesize > 0 &&
-	    (maxstart*pp->lg_sectorsize % pp->lg_stripesize) != 0) {
-		intmax_t offset = (pp->lg_stripesize -
-		    ((maxstart*pp->lg_sectorsize) % pp->lg_stripesize)) /
-		    pp->lg_sectorsize;
+	/*
+	 * Round the start and size of the largest available space up to
+	 * the nearest multiple of the adjusted stripe size.
+	 *
+	 * The adjusted stripe size is the least common multiple of the
+	 * actual stripe size, or the sector size if no stripe size was
+	 * reported, and 4096.  The reason for this is that contemporary
+	 * disks often have 4096-byte physical sectors but report 512
+	 * bytes instead for compatibility with older / broken operating
+	 * systems and BIOSes.  For the same reasons, virtualized storage
+	 * may also report a 512-byte stripe size, or none at all.
+	 */
+	sectorsize = pp->lg_sectorsize;
+	if ((stripesize = pp->lg_stripesize) == 0)
+		stripesize = sectorsize;
+	while (stripesize % 4096 != 0)
+		stripesize *= 2;
+	if ((offset = maxstart * sectorsize % stripesize) != 0) {
+		offset = (stripesize - offset) / sectorsize;
 		maxstart += offset;
 		maxsize -= offset;
 	}
@@ -742,7 +886,7 @@
 	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;
@@ -750,8 +894,8 @@
 
 	DIALOG_FORMITEM items[] = {
 		{0, "Type:", 5, 0, 0, FALSE, "mnbsd-ufs", 11, 0, 12, 15, 0,
-		    FALSE, "Filesystem type (e.g. mnbsd-ufs, mnbsd-swap)",
-		    FALSE},
+		    FALSE, "Filesystem type (e.g. mnbsd-ufs, mnbsd-zfs, "
+		    "mnbsd-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},
@@ -822,8 +966,8 @@
 	items[1].text = sizestr;
 
 	/* Special-case the MBR default type for nested partitions */
-	if (strcmp(scheme, "MBR") == 0) {
-		items[0].text = "midnightbsd";
+	if (strcmp(scheme, "MBR") == 0 || strcmp(scheme, "PC98") == 0) {
+		items[0].text = "midightbsd";
 		items[0].help = "Filesystem type (e.g. midnightbsd, fat32)";
 	}
 
@@ -891,14 +1035,17 @@
 	/* Warn if no mountpoint set */
 	if (strcmp(items[0].text, "mnbsd-ufs") == 0 &&
 	    items[2].text[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;
+		choice = 0;
+		if (interactive) {
+			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;
+		}
 		if (choice == 1) /* cancel */
 			goto addpartform;
 	}
@@ -929,12 +1076,26 @@
 			goto addpartform;
 	}
 
+	/* If this is the root partition, check that this fs is bootable */
+	if (strcmp(items[2].text, "/") == 0 && !is_fs_bootable(scheme,
+	    items[0].text)) {
+		char message[512];
+		sprintf(message, "This file system (%s) is not bootable "
+		    "on this system. Are you sure you want to proceed?",
+		    items[0].text);
+		dialog_vars.defaultno = TRUE;
+		choice = dialog_yesno("Warning", message, 0, 0);
+		dialog_vars.defaultno = FALSE;
+		if (choice == 1) /* cancel */
+			goto addpartform;
+	}
+
 	/*
 	 * If this is the root partition, and we need a boot partition, ask
 	 * the user to add one.
 	 */
 
-	/* Check for existing midnightbsd-boot partition */
+	/* Check for existing mnbsd-boot partition */
 	LIST_FOREACH(pp, &geom->lg_provider, lg_provider) {
 		struct partition_metadata *md;
 		md = get_part_metadata(pp->lg_name, 0);
@@ -943,12 +1104,14 @@
 		LIST_FOREACH(gc, &pp->lg_config, lg_config)
 			if (strcmp(gc->lg_name, "type") == 0)
 				break;
-		if (gc != NULL && strcmp(gc->lg_val, "mnbsd-boot") == 0)
+		if (gc != NULL && strcmp(gc->lg_val,
+		    bootpart_type(scheme)) == 0)
 			break;
 	}
 
 	/* If there isn't one, and we need one, ask */
-	if (strcmp(items[2].text, "/") == 0 && bootpart_size(scheme) > 0 &&
+	if ((strcmp(items[0].text, "midnightbsd") == 0 ||
+	    strcmp(items[2].text, "/") == 0) && bootpart_size(scheme) > 0 &&
 	    pp == NULL) {
 		if (interactive)
 			choice = dialog_yesno("Boot Partition",
@@ -964,7 +1127,7 @@
 			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, "mnbsd-boot");
+			gctl_ro_param(r, "type", -1, bootpart_type(scheme));
 			snprintf(sizestr, sizeof(sizestr), "%jd",
 			    bootpart_size(scheme) / sector);
 			gctl_ro_param(r, "size", -1, sizestr);
@@ -1024,7 +1187,7 @@
 	gctl_issue(r); /* Error usually expected and non-fatal */
 	gctl_free(r);
 
-	if (strcmp(items[0].text, "mnbsd-boot") == 0)
+	if (strcmp(items[0].text, bootpart_type(scheme)) == 0)
 		get_part_metadata(newpartname, 1)->bootcode = 1;
 	else if (strcmp(items[0].text, "midnightbsd") == 0)
 		gpart_partition(newpartname, "BSD");
@@ -1169,6 +1332,7 @@
 	struct gctl_req *r;
 	const char *errstr;
 	const char *modified;
+	const char *rootfs;
 
 	LIST_FOREACH(classp, &mesh->lg_class, lg_class) {
 		if (strcmp(classp->lg_name, "PART") == 0)
@@ -1175,6 +1339,15 @@
 			break;
 	}
 
+	/* Figure out what filesystem / uses */
+	rootfs = "ufs"; /* Assume ufs if nothing else present */
+	TAILQ_FOREACH(md, &part_metadata, metadata) {
+		if (md->fstab != NULL && strcmp(md->fstab->fs_file, "/") == 0) {
+			rootfs = md->fstab->fs_vfstype;
+			break;
+		}
+	}
+
 	if (strcmp(classp->lg_name, "PART") != 0) {
 		dialog_msgbox("Error", "gpart not found!", 0, 0, TRUE);
 		return;
@@ -1214,7 +1387,7 @@
 					break;
 
 			if (cp == NULL) /* No sub-partitions */
-				gpart_partcode(pp);
+				gpart_partcode(pp, rootfs);
 		}
 
 		r = gctl_get_handle();



More information about the Midnightbsd-cvs mailing list