Page MenuHomeFreeBSD

D3167.id7211.diff
No OneTemporary

D3167.id7211.diff

Index: sys/boot/forth/menu.rc
===================================================================
--- sys/boot/forth/menu.rc
+++ sys/boot/forth/menu.rc
@@ -65,6 +65,11 @@
set mainmenu_keycode[6]=111
set mainansi_caption[6]="Configure Boot ^[1mO^[mptions..."
+set mainmenu_caption[7]="Select Boot [E]nvironment..."
+set mainmenu_command[7]="3 goto_menu"
+set mainmenu_keycode[7]=101
+set mainansi_caption[7]="Select Boot ^[1mE^[37mnvironment..."
+
\
\ BOOT OPTIONS MENU
\
@@ -116,6 +121,53 @@
set optionsansi_caption[6]="^[1mV^[merbose..... ^[34;1mOff^[m"
set optionstoggled_ansi[6]="^[1mV^[merbose..... ^[32;7mOn^[m"
+\
+\ BOOT ENVIRONMENT MENU
+\
+
+set menuset_name3="bootenv"
+
+set bootenvmenu_caption[1]="Back to Main Menu [Backspace]"
+set bootenvmenu_command[1]="1 goto_menu"
+set bootenvmenu_keycode[1]=8
+set bootenvansi_caption[1]="Back to Main Menu ^[1m[Backspace]^[37m"
+
+set bootenvmenu_caption[2]="Choice: "
+set bootenvmenu_command[2]="true"
+set bootenvmenu_keycode[2]=27
+set bootenvansi_caption[2]="^[1m${bootenvmenu_caption[2]}^[37m"
+
+set bemenu_current="Choice: "
+set beansi_current="^[1m${bemenu_current}^[37m"
+: init_bootenv ( -- )
+ s" set menu_caption[2]=${bemenu_current}${vfs.root.mountfrom}" evaluate
+ s" set ansi_caption[2]=${beansi_current}${vfs.root.mountfrom}" evaluate
+;
+
+set bootenvmenu_init="init_bootenv"
+unset bootenvmenu_caption[2]
+unset bootenvansi_caption[2]
+
+: set_bootenv ( N -- N TRUE )
+ dup s" set vfs.root.mountfrom=${bootenv_root[E]}" 38 +c! evaluate
+ s" set currdev=${vfs.root.mountfrom}:" evaluate
+ s" read-conf /boot/defaults/loader.conf" evaluate
+ s" read-conf /boot/loader.conf" evaluate
+ s" unload" evaluate
+ init_bootenv
+ menu-redraw
+ TRUE
+;
+
+set bootenvmenu_caption[3]="[A]ctive: ${vfs.root.mountfrom}"
+set bootenvansi_caption[3]="^[1mA^[37mctive: ${vfs.root.mountfrom}"
+set bootenvmenu_keycode[3]=97
+set bootenvmenu_command[3]="set_bootenv"
+set bootenv_root[3]="${zfs_be_active}"
+
+set bootenvmenu_options=4
+set bootenvmenu_optionstext="Boot Environments:"
+
\ Enable automatic booting (add ``autoboot_delay=N'' to loader.conf(5) to
\ customize the timeout; default is 10-seconds)
\
Index: sys/boot/i386/loader/main.c
===================================================================
--- sys/boot/i386/loader/main.c
+++ sys/boot/i386/loader/main.c
@@ -69,6 +69,7 @@
static void isa_outb(int port, int value);
void exit(int code);
#ifdef LOADER_ZFS_SUPPORT
+static void list_zfs_bootenv(char *currdev);
static void i386_zfs_probe(void);
#endif
@@ -299,12 +300,41 @@
new_currdev.d_unit = 0;
}
+#ifdef LOADER_ZFS_SUPPORT
+ list_zfs_bootenv(zfs_fmtdev(&new_currdev));
+#endif
+
env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev),
i386_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset,
env_nounset);
}
+#ifdef LOADER_ZFS_SUPPORT
+static void
+list_zfs_bootenv(char *currdev)
+{
+ char *beroot;
+
+ /* Remove the trailing : */
+ currdev[strlen(currdev) - 1] = '\0';
+ setenv("zfs_be_active", currdev, 1);
+ /* Do not overwrite if already set */
+ setenv("vfs.root.mountfrom", currdev, 0);
+ /* Forward past zfs: */
+ currdev = strchr(currdev, ':');
+ currdev++;
+ /* Remove the last element (current bootenv) */
+ beroot = strrchr(currdev, '/');
+ beroot[0] = '\0';
+
+ beroot = currdev;
+
+ if (beroot && beroot[0] != '\0')
+ zfs_bootenv(beroot);
+}
+#endif
+
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
static int
@@ -360,6 +390,27 @@
}
return (CMD_OK);
}
+
+COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments",
+ command_reloadbe);
+
+static int
+command_reloadbe(int argc, char *argv[])
+{
+ int err;
+
+ if (argc != 2) {
+ command_errmsg = "wrong number of arguments";
+ return (CMD_ERROR);
+ }
+
+ err = zfs_bootenv(argv[1]);
+ if (err != 0) {
+ command_errmsg = strerror(err);
+ return (CMD_ERROR);
+ }
+ return (CMD_OK);
+}
#endif
/* ISA bus access functions for PnP. */
Index: sys/boot/zfs/libzfs.h
===================================================================
--- sys/boot/zfs/libzfs.h
+++ sys/boot/zfs/libzfs.h
@@ -62,6 +62,8 @@
char *zfs_fmtdev(void *vdev);
int zfs_probe_dev(const char *devname, uint64_t *pool_guid);
int zfs_list(const char *name);
+int zfs_bootenv(const char *name);
+int zfs_set_env(const char *name);
extern struct devsw zfs_dev;
extern struct fs_ops zfs_fsops;
Index: sys/boot/zfs/zfs.c
===================================================================
--- sys/boot/zfs/zfs.c
+++ sys/boot/zfs/zfs.c
@@ -80,6 +80,8 @@
zap_leaf_phys_t *f_zap_leaf; /* zap leaf buffer */
};
+static int zfs_env_index = 0;
+
/*
* Open a file.
*/
@@ -694,3 +696,93 @@
rv = zfs_list_dataset(spa, objid);
return (rv);
}
+
+int
+zfs_bootenv(const char *name)
+{
+ static char poolname[ZFS_MAXNAMELEN];
+ uint64_t objid;
+ spa_t *spa;
+ const char *dsname;
+ char *index_str;
+ int len;
+ int rv;
+
+ setenv("zfs_beroot", name, 1);
+
+ zfs_env_index = 4;
+ len = strlen(name);
+ dsname = strchr(name, '/');
+ if (dsname != NULL) {
+ len = dsname - name;
+ dsname++;
+ } else
+ dsname = "";
+ memcpy(poolname, name, len);
+ poolname[len] = '\0';
+
+ spa = spa_find_by_name(poolname);
+ if (!spa)
+ return (ENXIO);
+ rv = zfs_lookup_dataset(spa, dsname, &objid);
+ if (rv != 0)
+ return (rv);
+ rv = zfs_callback_dataset(spa, objid, zfs_set_env);
+ if (rv != 0)
+ return (rv);
+ index_str = malloc(20);
+ snprintf(index_str, 20, "%d", zfs_env_index - 1);
+ rv = setenv("bootenv_count", index_str, 1);
+ return (rv);
+}
+
+int
+zfs_set_env(const char *name)
+{
+ char *envname = NULL, *envval = NULL, *beroot;
+ int rv, i;
+
+ beroot = getenv("zfs_beroot");
+ if (beroot == NULL)
+ return (1);
+
+ envname = malloc(32);
+ envval = malloc(256);
+ /* Don't overflow the menu, shuffle entries down to show the newest */
+ if (zfs_env_index == 9) {
+ for (i = 4; i < 8; i++) {
+ snprintf(envname, 32, "bootenvmenu_caption[%d]", i);
+ snprintf(envval, 32, "bootenvmenu_caption[%d]", i + 1);
+ setenv(envname, getenv(envval), 1);
+
+ snprintf(envname, 32, "bootenvansi_caption[%d]", i);
+ snprintf(envval, 32, "bootenvansi_caption[%d]", i + 1);
+ setenv(envname, getenv(envval), 1);
+
+ snprintf(envname, 32, "bootenv_root[%d]", i);
+ snprintf(envval, 32, "bootenv_root[%d]", i + 1);
+ setenv(envname, getenv(envval), 1);
+ }
+ zfs_env_index = 8;
+ }
+
+ snprintf(envname, 32, "bootenvmenu_caption[%d]", zfs_env_index);
+ snprintf(envval, 256, "%s", name);
+ rv = setenv(envname, envval, 1);
+
+ snprintf(envname, 32, "bootenvansi_caption[%d]", zfs_env_index);
+ rv = setenv(envname, envval, 1);
+
+ snprintf(envname, 32, "bootenvmenu_command[%d]", zfs_env_index);
+ rv = setenv(envname, "set_bootenv", 1);
+
+ snprintf(envname, 32, "bootenv_root[%d]", zfs_env_index);
+ snprintf(envval, 256, "zfs:%s/%s", beroot, name);
+ rv = setenv(envname, envval, 1);
+
+ if (zfs_env_index <= 8)
+ zfs_env_index++;
+ free(envname);
+ free(envval);
+ return (rv);
+}
\ No newline at end of file
Index: sys/boot/zfs/zfsimpl.c
===================================================================
--- sys/boot/zfs/zfsimpl.c
+++ sys/boot/zfs/zfsimpl.c
@@ -1473,7 +1473,7 @@
* the directory contents.
*/
static int
-mzap_list(const dnode_phys_t *dnode)
+mzap_list(const dnode_phys_t *dnode, int (*callback)(const char *))
{
const mzap_phys_t *mz;
const mzap_ent_phys_t *mze;
@@ -1492,7 +1492,7 @@
mze = &mz->mz_chunk[i];
if (mze->mze_name[0])
//printf("%-32s 0x%jx\n", mze->mze_name, (uintmax_t)mze->mze_value);
- printf("%s\n", mze->mze_name);
+ callback(mze->mze_name);
}
return (0);
@@ -1503,7 +1503,7 @@
* the directory header.
*/
static int
-fzap_list(const spa_t *spa, const dnode_phys_t *dnode)
+fzap_list(const spa_t *spa, const dnode_phys_t *dnode, int (*callback)(const char *))
{
int bsize = dnode->dn_datablkszsec << SPA_MINBLOCKSHIFT;
zap_phys_t zh = *(zap_phys_t *) zap_scratch;
@@ -1566,13 +1566,19 @@
value = fzap_leaf_value(&zl, zc);
//printf("%s 0x%jx\n", name, (uintmax_t)value);
- printf("%s\n", name);
+ callback((const char *)name);
}
}
return (0);
}
+static int zfs_printf(const char *name)
+{
+ printf("%s\n", name);
+ return (0);
+}
+
/*
* List a zap directory.
*/
@@ -1587,9 +1593,9 @@
zap_type = *(uint64_t *) zap_scratch;
if (zap_type == ZBT_MICRO)
- return mzap_list(dnode);
+ return mzap_list(dnode, zfs_printf);
else
- return fzap_list(spa, dnode);
+ return fzap_list(spa, dnode, zfs_printf);
}
static int
@@ -1858,6 +1864,43 @@
return (zap_list(spa, &child_dir_zap) != 0);
}
+
+int
+zfs_callback_dataset(const spa_t *spa, uint64_t objnum, int (*callback)(const char *name))
+{
+ uint64_t dir_obj, child_dir_zapobj, zap_type;
+ dnode_phys_t child_dir_zap, dir, dataset;
+ dsl_dataset_phys_t *ds;
+ dsl_dir_phys_t *dd;
+
+ if (objset_get_dnode(spa, &spa->spa_mos, objnum, &dataset)) {
+ printf("ZFS: can't find dataset %ju\n", (uintmax_t)objnum);
+ return (EIO);
+ }
+ ds = (dsl_dataset_phys_t *) &dataset.dn_bonus;
+ dir_obj = ds->ds_dir_obj;
+
+ if (objset_get_dnode(spa, &spa->spa_mos, dir_obj, &dir)) {
+ printf("ZFS: can't find dirobj %ju\n", (uintmax_t)dir_obj);
+ return (EIO);
+ }
+ dd = (dsl_dir_phys_t *)&dir.dn_bonus;
+
+ child_dir_zapobj = dd->dd_child_dir_zapobj;
+ if (objset_get_dnode(spa, &spa->spa_mos, child_dir_zapobj, &child_dir_zap) != 0) {
+ printf("ZFS: can't find child zap %ju\n", (uintmax_t)dir_obj);
+ return (EIO);
+ }
+
+ if (dnode_read(spa, &child_dir_zap, 0, zap_scratch, child_dir_zap.dn_datablkszsec * 512))
+ return (EIO);
+
+ zap_type = *(uint64_t *) zap_scratch;
+ if (zap_type == ZBT_MICRO)
+ return mzap_list(&child_dir_zap, callback);
+ else
+ return fzap_list(spa, &child_dir_zap, callback);
+}
#endif
/*
Index: usr.sbin/bsdinstall/partedit/gpart_ops.c
===================================================================
--- usr.sbin/bsdinstall/partedit/gpart_ops.c
+++ usr.sbin/bsdinstall/partedit/gpart_ops.c
@@ -206,12 +206,11 @@
}
}
-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",
@@ -228,16 +227,16 @@
"Bootable on Sun SPARC systems", 0 },
};
-schememenu:
+parttypemenu:
if (scheme == NULL) {
- dialog_vars.default_item = __DECONST(char *, default_scheme());
+ 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 (-1);
+ return NULL;
if (!is_scheme_bootable(items[choice].name)) {
char message[512];
@@ -248,12 +247,42 @@
cancel = dialog_yesno("Warning", message, 0, 0);
dialog_vars.defaultno = FALSE;
if (cancel) /* cancel */
- goto schememenu;
+ 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) {
+ scheme = choose_part_type(default_scheme());
+
+ if (scheme == NULL)
+ return (-1);
+
+ 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?", scheme);
+ dialog_vars.defaultno = TRUE;
+ cancel = dialog_yesno("Warning", message, 0, 0);
+ dialog_vars.defaultno = FALSE;
+ if (cancel) /* cancel */
+ goto schememenu;
+ }
+ }
+
r = gctl_get_handle();
gctl_ro_param(r, "class", -1, "PART");
gctl_ro_param(r, "arg0", -1, lg_name);
@@ -322,6 +351,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)
{
Index: usr.sbin/bsdinstall/partedit/part_wizard.c
===================================================================
--- usr.sbin/bsdinstall/partedit/part_wizard.c
+++ usr.sbin/bsdinstall/partedit/part_wizard.c
@@ -257,8 +257,8 @@
goto query;
gpart_destroy(gpart);
- gpart_partition(disk, default_scheme());
- scheme = default_scheme();
+ scheme = choose_part_type(default_scheme());
+ gpart_partition(disk, scheme);
}
if (scheme == NULL || choice == 0) {
@@ -272,8 +272,8 @@
gpart_destroy(gpart);
}
- gpart_partition(disk, default_scheme());
- scheme = default_scheme();
+ scheme = choose_part_type(default_scheme());
+ gpart_partition(disk, scheme);
}
if (strcmp(scheme, "PC98") == 0 || strcmp(scheme, "MBR") == 0) {
Index: usr.sbin/bsdinstall/partedit/partedit.h
===================================================================
--- usr.sbin/bsdinstall/partedit/partedit.h
+++ usr.sbin/bsdinstall/partedit/partedit.h
@@ -72,6 +72,8 @@
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);
+void gpart_set_root(const char *lg_name, const char *attribute);
+const char *choose_part_type(const char *def_scheme);
/* machine-dependent bootability checks */
const char *default_scheme(void);
Index: usr.sbin/bsdinstall/partedit/partedit.c
===================================================================
--- usr.sbin/bsdinstall/partedit/partedit.c
+++ usr.sbin/bsdinstall/partedit/partedit.c
@@ -44,6 +44,7 @@
static int sade_mode = 0;
static int apply_changes(struct gmesh *mesh);
+static void apply_workaround(struct gmesh *mesh);
static struct partedit_item *read_geom_mesh(struct gmesh *mesh, int *nitems);
static void add_geom_children(struct ggeom *gp, int recurse,
struct partedit_item **items, int *nitems);
@@ -189,6 +190,7 @@
if (op == 0 && validate_setup()) { /* Save */
error = apply_changes(&mesh);
+ apply_workaround(&mesh);
break;
} else if (op == 3) { /* Quit */
gpart_revert_all(&mesh);
@@ -390,6 +392,43 @@
return (0);
}
+static void
+apply_workaround(struct gmesh *mesh)
+{
+ struct gclass *classp;
+ struct ggeom *gp;
+ struct gconfig *gc;
+ const char *scheme = NULL, *modified = NULL;
+
+ LIST_FOREACH(classp, &mesh->lg_class, lg_class) {
+ if (strcmp(classp->lg_name, "PART") == 0)
+ break;
+ }
+
+ if (strcmp(classp->lg_name, "PART") != 0) {
+ dialog_msgbox("Error", "gpart not found!", 0, 0, TRUE);
+ return;
+ }
+
+ LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
+ LIST_FOREACH(gc, &gp->lg_config, lg_config) {
+ if (strcmp(gc->lg_name, "scheme") == 0) {
+ scheme = gc->lg_val;
+ } else if (strcmp(gc->lg_name, "modified") == 0) {
+ modified = gc->lg_val;
+ }
+ }
+
+ if (scheme && strcmp(scheme, "GPT") == 0 &&
+ modified && strcmp(modified, "true") == 0) {
+ if (getenv("WORKAROUND_LENOVO"))
+ gpart_set_root(gp->lg_name, "lenovofix");
+ if (getenv("WORKAROUND_GPTACTIVE"))
+ gpart_set_root(gp->lg_name, "active");
+ }
+ }
+}
+
static struct partedit_item *
read_geom_mesh(struct gmesh *mesh, int *nitems)
{
Index: usr.sbin/bsdinstall/scripts/auto
===================================================================
--- usr.sbin/bsdinstall/scripts/auto
+++ usr.sbin/bsdinstall/scripts/auto
@@ -31,6 +31,7 @@
BSDCFG_SHARE="/usr/share/bsdconfig"
. $BSDCFG_SHARE/common.subr || exit 1
+f_include $BSDCFG_SHARE/dialog.subr
############################################################ FUNCTIONS
@@ -51,6 +52,54 @@
fi
}
+hline_arrows_tab_enter="Press arrows, TAB or ENTER"
+msg_gpt_active_fix="Your hardware is known to have issues booting in BIOS mode from GPT partitions that are not set active. Would you like the installer to apply this workaround for you?"
+msg_lenovo_fix="Your model of Lenovo is known to have a BIOS bug that prevents it booting from GPT partitions without UEFI. Would you like the installer to apply a workaround for you?"
+msg_no="NO"
+msg_yes="YES"
+
+# dialog_workaround
+#
+# Ask the user if they wish to apply a workaround
+#
+dialog_workaround()
+{
+ local passed_msg="$1"
+ local title="$DIALOG_TITLE"
+ local btitle="$DIALOG_BACKTITLE"
+ local prompt # Calculated below
+ local hline="$hline_arrows_tab_enter"
+
+ local height=8 width=50 prefix=" "
+ local plen=${#prefix} list= line=
+ local max_width=$(( $width - 3 - $plen ))
+
+ local yes no defaultno extra_args format
+ if [ "$USE_XDIALOG" ]; then
+ yes=ok no=cancel defaultno=default-no
+ extra_args="--wrap --left"
+ format="$passed_msg"
+ else
+ yes=yes no=no defaultno=defaultno
+ extra_args="--cr-wrap"
+ format="$passed_msg"
+ fi
+
+ # Add height for Xdialog(1)
+ [ "$USE_XDIALOG" ] && height=$(( $height + $height / 5 + 3 ))
+
+ prompt=$( printf "$format" )
+ f_dprintf "%s: Workaround prompt" "$0"
+ $DIALOG \
+ --title "$title" \
+ --backtitle "$btitle" \
+ --hline "$hline" \
+ --$yes-label "$msg_yes" \
+ --$no-label "$msg_no" \
+ $extra_args \
+ --yesno "$prompt" $height $width
+}
+
############################################################ MAIN
f_dprintf "Began Installation at %s" "$( date )"
@@ -106,6 +155,47 @@
rm -f $PATH_FSTAB
touch $PATH_FSTAB
+#
+# Try to detect known broken platforms and apply their workarounds
+#
+
+if f_interactive; then
+ sys_maker=$( kenv -q smbios.system.maker )
+ f_dprintf "smbios.system.maker=[%s]" "$sys_maker"
+ sys_model=$( kenv -q smbios.system.product )
+ f_dprintf "smbios.system.product=[%s]" "$sys_model"
+ sys_version=$( kenv -q smbios.system.version )
+ f_dprintf "smbios.system.version=[%s]" "$sys_version"
+ case "$sys_maker" in
+ "LENOVO")
+ case "$sys_version" in
+ "ThinkPad X220"|"ThinkPad T420"|"ThinkPad T520")
+ dialog_workaround "$msg_lenovo_fix"
+ retval=$?
+ f_dprintf "lenovofix_prompt=[%s]" "$retval"
+ if [ $retval -eq $DIALOG_OK ]; then
+ export ZFSBOOT_PARTITION_SCHEME="GPT + Lenovo Fix"
+ export WORKAROUND_LENOVO=1
+ fi
+ ;;
+ esac
+ ;;
+ "Dell Inc.")
+ case "$sys_model" in
+ "Latitude E7440")
+ dialog_workaround "$msg_gpt_active_fix"
+ retval=$?
+ f_dprintf "gpt_active_fix_prompt=[%s]" "$retval"
+ if [ $retval -eq $DIALOG_OK ]; then
+ export ZFSBOOT_PARTITION_SCHEME="GPT + Active"
+ export WORKAROUND_GPTACTIVE=1
+ fi
+ ;;
+ esac
+ ;;
+ esac
+fi
+
PMODES="\
\"Auto (UFS)\" \"Guided Disk Setup\" \
Manual \"Manual Disk Setup (experts)\" \
Index: usr.sbin/bsdinstall/scripts/zfsboot
===================================================================
--- usr.sbin/bsdinstall/scripts/zfsboot
+++ usr.sbin/bsdinstall/scripts/zfsboot
@@ -196,6 +196,8 @@
GPART_CREATE='gpart create -s %s "%s"'
GPART_DESTROY_F='gpart destroy -F "%s"'
GPART_SET_ACTIVE='gpart set -a active -i %s "%s"'
+GPART_SET_LENOVOFIX='gpart set -a lenovofix "%s"'
+GPART_SET_PMBR_ACTIVE='gpart set -a active "%s"'
GRAID_DELETE='graid delete "%s"'
LN_SF='ln -sf "%s" "%s"'
MKDIR_P='mkdir -p "%s"'
@@ -263,7 +265,7 @@
msg_null_poolname="NULL poolname"
msg_ok="OK"
msg_partition_scheme="Partition Scheme"
-msg_partition_scheme_help="Toggle between GPT and MBR partitioning schemes"
+msg_partition_scheme_help="Select partitioning scheme. GPT is recommended."
msg_please_enter_a_name_for_your_zpool="Please enter a name for your zpool:"
msg_please_enter_amount_of_swap_space="Please enter amount of swap space (SI-Unit suffixes\nrecommended; e.g., \`2g' for 2 Gigabytes):"
msg_please_select_one_or_more_disks="Please select one or more disks to create a zpool:"
@@ -779,7 +781,7 @@
# Check for unknown partition scheme before proceeding further
case "$ZFSBOOT_PARTITION_SCHEME" in
- ""|MBR|GPT) : known good ;;
+ ""|MBR|GPT*) : known good ;;
*)
f_dprintf "$funcname: %s is an unsupported partition scheme" \
"$ZFSBOOT_PARTITION_SCHEME"
@@ -826,7 +828,7 @@
fi
case "$ZFSBOOT_PARTITION_SCHEME" in
- ""|GPT) f_dprintf "$funcname: Creating GPT layout..."
+ ""|GPT*) f_dprintf "$funcname: Creating GPT layout..."
#
# 1. Create GPT layout using labels
#
@@ -834,6 +836,17 @@
return $FAILURE
#
+ # Apply workarounds if requested by the user
+ #
+ if [ "$ZFSBOOT_PARTITION_SCHEME" = "GPT + Lenovo Fix" ]; then
+ f_eval_catch $funcname gpart "$GPART_SET_LENOVOFIX" \
+ $disk || return $FAILURE
+ elif [ "$ZFSBOOT_PARTITION_SCHEME" = "GPT + Active" ]; then
+ f_eval_catch $funcname gpart "$GPART_SET_PMBR_ACTIVE" \
+ $disk || return $FAILURE
+ fi
+
+ #
# 2. Add small freebsd-boot partition labeled `boot#'
#
f_eval_catch $funcname gpart "$GPART_ADD_ALIGN_LABEL_WITH_SIZE" \
@@ -1584,6 +1597,10 @@
# Toggle between GPT and MBR
if [ "$ZFSBOOT_PARTITION_SCHEME" = GPT ]; then
ZFSBOOT_PARTITION_SCHEME=MBR
+ elif [ "$ZFSBOOT_PARTITION_SCHEME" = MBR ]; then
+ ZFSBOOT_PARTITION_SCHEME="GPT + Active"
+ elif [ "$ZFSBOOT_PARTITION_SCHEME" = "GPT + Active" ]; then
+ ZFSBOOT_PARTITION_SCHEME="GPT + Lenovo Fix"
else
ZFSBOOT_PARTITION_SCHEME=GPT
fi

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 6, 3:21 PM (5 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30980303
Default Alt Text
D3167.id7211.diff (21 KB)

Event Timeline