Index: head/sysutils/grub2-pcbsd/Makefile =================================================================== --- head/sysutils/grub2-pcbsd/Makefile (revision 388937) +++ head/sysutils/grub2-pcbsd/Makefile (revision 388938) @@ -1,98 +1,98 @@ # Created by: kmoore@FreeBSD.org # $FreeBSD$ PORTNAME= grub2-pcbsd PORTVERSION= 2.02q -PORTREVISION= 2 +PORTREVISION= 3 CATEGORIES= sysutils MASTER_SITES= http://www.pcbsd.org/~kris/software/ \ ftp://ftp.pcbsd.org/pub/software/ DISTNAME= grub-2.02_7 MAINTAINER= kmoore@FreeBSD.org COMMENT= Multiboot boot loader LICENSE= GPLv3 BUILD_DEPENDS= ${LOCALBASE}/bin/flex:${PORTSDIR}/textproc/flex \ ${LOCALBASE}/bin/bash:${PORTSDIR}/shells/bash \ help2man:${PORTSDIR}/misc/help2man WRKSRC= ${WRKDIR}/grub-2.02 CONFLICTS= grub-0* grub2-2* SSP_UNSAFE= yes USE_GCC= yes ACLOCAL_ARGS= -Im4 GNU_CONFIGURE= yes USES= autoreconf bison cpe gettext gmake makeinfo python tar:xz ONLY_FOR_ARCHS= i386 amd64 INFO= grub grub-dev MAKE_JOBS_UNSAFE= yes CPE_PRODUCT= grub CPE_VENDOR= gnu CONFIGURE_ARGS= --disable-werror --localedir=${PREFIX}/share/locale CONFIGURE_ENV= CPP="${CC} -E" \ LEX=${LOCALBASE}/bin/flex SUB_FILES= 00_header 10_kfreebsd 10_ktrueos 30_os-prober 50_otherbe OPTIONS_DEFINE= MKFONT FUSE OPTIONS_DEFAULT=MKFONT MKFONT_DESC= Build grub-mkfont (require freetype2) FUSE_DESC= Build grub-mount (require FUSE) .include .if ${ARCH} != "amd64" EFIEMU= "@comment " .endif PLIST_SUB+= EFIEMU=${EFIEMU} .if ${PORT_OPTIONS:MMKFONT} LIB_DEPENDS+= libfreetype.so:${PORTSDIR}/print/freetype2 BUILD_DEPENDS+= ${LOCALBASE}/share/fonts/dejavu/DejaVuSans.ttf:${PORTSDIR}/x11-fonts/dejavu \ ${LOCALBASE}/share/fonts/gnu-unifont/unifont.pcf.gz:${PORTSDIR}/x11-fonts/gnu-unifont MAN1+= grub-mkfont.1 CONFIGURE_ARGS+= --enable-grub-mkfont .else CONFIGURE_ARGS+= --disable-grub-mkfont MKFONT= "@comment " .endif PLIST_SUB+= MKFONT=${MKFONT} .if ${PORT_OPTIONS:MFUSE} LIB_DEPENDS+= libfuse.so:${PORTSDIR}/sysutils/fusefs-libs CONFIGURE_ARGS+= --enable-grub-mount .else CONFIGURE_ARGS+= --disable-grub-mount FUSE= "@comment " .endif PLIST_SUB+= FUSE=${FUSE} post-patch: @${TOUCH} -t 200001010000 ${WRKSRC}/Makefile.util.def pre-configure: @${REINPLACE_CMD} -e 's|python|${PYTHON_CMD}|g' ${WRKSRC}/autogen.sh cd ${WRKSRC} && ./autogen.sh post-configure: @${LN} -sfh /usr/include/machine /usr/include/sys /usr/include/x86 ${WRKSRC}/grub-core post-install: ${RM} -rf ${STAGEDIR}${PREFIX}/lib/charset.alias ${INSTALL_SCRIPT} ${WRKDIR}/00_header ${STAGEDIR}${PREFIX}/etc/grub.d/ ${INSTALL_SCRIPT} ${WRKDIR}/10_kfreebsd ${STAGEDIR}${PREFIX}/etc/grub.d/ ${INSTALL_SCRIPT} ${WRKDIR}/10_ktrueos ${STAGEDIR}${PREFIX}/etc/grub.d/ ${INSTALL_SCRIPT} ${WRKDIR}/30_os-prober ${STAGEDIR}${PREFIX}/etc/grub.d/ ${INSTALL_SCRIPT} ${WRKDIR}/50_otherbe ${STAGEDIR}${PREFIX}/etc/grub.d/ ${MV} ${STAGEDIR}${PREFIX}/etc/grub.d/40_custom ${STAGEDIR}/${PREFIX}/etc/grub.d/40_custom.dist RUN_DEPENDS:= ${RUN_DEPENDS:Ngcc*} .include Index: head/sysutils/grub2-pcbsd/files/10_kfreebsd.in =================================================================== --- head/sysutils/grub2-pcbsd/files/10_kfreebsd.in (revision 388937) +++ head/sysutils/grub2-pcbsd/files/10_kfreebsd.in (revision 388938) @@ -1,4 +1,247 @@ #! /bin/sh +set -e -# Exit for now, we can use 10_ktrueos instead -return 0 +# grub-mkconfig helper script. +# Copyright (C) 2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see . + +# Check if we have beadm installed, if not do normal freebsd detection +if [ -e "/usr/local/sbin/beadm" ] ; then exit 0; fi + +prefix="@prefix@" +exec_prefix="@exec_prefix@" +datarootdir="@datarootdir@" +. "$pkgdatadir/grub-mkconfig_lib" + +export TEXTDOMAIN=@PACKAGE@ +export TEXTDOMAINDIR="@localedir@" + +CLASS="--class os" + +case "${GRUB_DISTRIBUTOR}" in + Debian) + OS="${GRUB_DISTRIBUTOR} GNU/kFreeBSD" + CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') --class gnu-kfreebsd --class gnu ${CLASS}" + ;; + *) + OS="FreeBSD" + CLASS="--class freebsd --class bsd ${CLASS}" + ;; +esac + +load_kfreebsd_module () +{ + mod="$1" + allow_fail="$2" + + if ! test -e "${module_dir}/${mod}.ko" ; then + if [ "${allow_fail}" = "true" ] ; then + # Return silently + return + else + # Print an error and fail. + ls "${module_dir}/${mod}.ko" > /dev/null + fi + fi + + if [ -z "${prepare_module_dir_cache}" ]; then + prepare_module_dir_cache="$(prepare_grub_to_access_device $(${grub_probe} -t device "${module_dir}") | grub_add_tab)" + fi + + printf '%s\n' "${prepare_module_dir_cache}" + cat << EOF + kfreebsd_module_elf ${module_dir_rel}/${mod}.ko +EOF +} + +title_correction_code= + +kfreebsd_entry () +{ + os="$1" + version="$2" + type="$3" + args="$4" + if [ -z "$boot_device_id" ]; then + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" + fi + if [ x$type != xsimple ] ; then + if [ x$type = xrecovery ] ; then + title="$(gettext_printf "%s, with kFreeBSD %s (recovery mode)" "${os}" "${version}")" + else + title="$(gettext_printf "%s, with kFreeBSD %s" "${os}" "${version}")" + fi + replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')" + if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then + quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" + title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" + grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "kfreebsd-advanced-$boot_device_id>kfreebsd-$version-$type-$boot_device_id")" + fi + echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'kfreebsd-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" + else + echo "menuentry '$(echo "$OS" | grub_quote)' ${CLASS} \$menuentry_id_option 'kfreebsd-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/" + fi + if [ x$type != xrecovery ] ; then + save_default_entry | grub_add_tab | sed "s/^/$submenu_indentation/" + fi + if [ -z "${prepare_boot_cache}" ]; then + prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)" + fi + + printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" + message="$(gettext_printf "Loading kernel of FreeBSD %s ..." ${version})" + sed "s/^/$submenu_indentation/" << EOF + echo '$(echo "$message" | grub_quote)' + kfreebsd ${rel_dirname}/${basename} ${args} +EOF + + if test -n "${devices}" ; then + sed "s/^/$submenu_indentation/" << EOF + kfreebsd_loadenv ${devices_rel_dirname}/${devices_basename} +EOF + fi + + load_kfreebsd_module acpi true + + for abstraction in dummy $(${grub_probe} -t abstraction --device ${GRUB_DEVICE}) ; do + case $abstraction in + lvm) load_kfreebsd_module geom_linux_lvm false ;; + esac + done + + case "${kfreebsd_fs}" in + zfs) + load_kfreebsd_module opensolaris false + + ls "/boot/zfs/zpool.cache" > /dev/null + printf '%s\n' "${prepare_boot_cache}" + sed "s/^/$submenu_indentation/" << EOF + kfreebsd_module $(make_system_path_relative_to_its_root /boot)/zfs/zpool.cache type=/boot/zfs/zpool.cache +EOF + ;; + esac + + if [ x${kfreebsd_fs} = xufs ]; then + load_kfreebsd_module ${kfreebsd_fs} true | sed "s/^/$submenu_indentation/" + else + load_kfreebsd_module ${kfreebsd_fs} false | sed "s/^/$submenu_indentation/" + fi + + sed "s/^/$submenu_indentation/" << EOF + set kFreeBSD.vfs.root.mountfrom=${kfreebsd_fs}:${kfreebsd_device} + set kFreeBSD.vfs.root.mountfrom.options=rw +} +EOF +} + +list= +for i in /boot/kfreebsd-* /boot/kernel/kernel ; do + if grub_file_is_not_garbage "$i" ; then + list="$list $i" + fi +done +prepare_boot_cache= +boot_device_id= +title_correction_code= + +# Extra indentation to add to menu entries in a submenu. We're not in a submenu +# yet, so it's empty. In a submenu it will be equal to '\t' (one tab). +submenu_indentation="" + +is_top_level=true + +while [ "x$list" != "x" ] ; do + kfreebsd=`version_find_latest $list` + gettext_printf "Found kernel of FreeBSD: %s\n" "$kfreebsd" >&2 + basename=`basename $kfreebsd` + dirname=`dirname $kfreebsd` + rel_dirname=`make_system_path_relative_to_its_root $dirname` + + if [ -f /boot/device.hints ] ; then + devices=/boot/device.hints + devices_basename=`basename $devices` + devices_dirname=`dirname $devices` + devices_rel_dirname=`make_system_path_relative_to_its_root $devices_dirname` + fi + + case ${GRUB_FS} in + ufs1 | ufs2) kfreebsd_fs=ufs ;; + ext2) kfreebsd_fs=ext2fs ;; + *) kfreebsd_fs=${GRUB_FS} ;; + esac + + case ${GRUB_FS} in + zfs) + # zpool name + kfreebsd_device=$(${grub_probe} -t fs_label --device ${GRUB_DEVICE}) + # filesystem name (empty string for the main filesystem) + kfreebsd_device="${kfreebsd_device}$(${grub_mkrelpath} / | sed -e "s,/*@$,,")" + ;; + *) + kfreebsd_device=${kfreebsd_fs}id/${GRUB_DEVICE_UUID} + # Debian GNU/kFreeBSD can't remount root if it's supplied as UUID but + # as an UUID + if [ "x${GRUB_DISTRIBUTOR}" = "xDebian" ] \ + && ! (cat /etc/fstab | awk '!/^[[:space:]]*#/ && $2=="/" { print $1; }' \ + | grep "${kfreebsd_fs}id/${GRUB_DEVICE_UUID}" > /dev/null); then + kfreebsd_device=${GRUB_DEVICE} + fi + ;; + esac + + version=`echo $basename | sed -e "s,^[^0-9]*-,,g;s/\.gz$//g"` + alt_version=`echo $version | sed -e "s,\.old$,,g"` + + module_dir= + for i in "/lib/modules/${version}" "/lib/modules/${alt_version}" \ + "/boot/kernel"; do + if test -e "$i" ; then + module_dir="$i" + break + fi + done + if test -n "${module_dir}" ; then + gettext_printf "Found kernel module directory: %s\n" "${module_dir}" >&2 + module_dir_rel=$(make_system_path_relative_to_its_root $module_dir) + fi + + if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xy ]; then + kfreebsd_entry "${OS}" "${version}" simple + submenu_indentation="$grub_tab" + + if [ -z "$boot_device_id" ]; then + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" + fi + # TRANSLATORS: %s is replaced with an OS name + echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'kfreebsd-advanced-$boot_device_id' {" + is_top_level=false + fi + + kfreebsd_entry "${OS}" "${version}" advanced + if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then + kfreebsd_entry "${OS}" "${version}" recovery "-s" + fi + + list=`echo $list | tr ' ' '\n' | fgrep -vx "$kfreebsd" | tr '\n' ' '` +done + +# If at least one kernel was found, then we need to +# add a closing '}' for the submenu command. +if [ x"$is_top_level" != xtrue ]; then + echo '}' +fi + +echo "$title_correction_code" + Index: head/sysutils/grub2-pcbsd/files/10_ktrueos.in =================================================================== --- head/sysutils/grub2-pcbsd/files/10_ktrueos.in (revision 388937) +++ head/sysutils/grub2-pcbsd/files/10_ktrueos.in (revision 388938) @@ -1,386 +1,389 @@ #!/bin/sh # # Copyright 2015 iXsystems (Kris Moore) # All rights reserved # # Redistribution and use in source and binary forms, with or without # modification, are permitted providing that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # Script to detect TrueOS / PC-BSD disk installations and create grub # entries for them +# Check if we have beadm installed, if not skip this file +if [ ! -e "/usr/local/sbin/beadm" ] ; then exit 0; fi + ROOTFS=`mount | awk '/ \/ / {print $1}'` BEDS="$( echo ${ROOTFS} | awk -F '/' '{print $2}' )" if [ "$BEDS" = "dev" ] ; then BEDS="ROOT"; fi serial=0; console=0; for x in ${GRUB_TERMINAL_OUTPUT}; do if [ xserial = "x$x" ]; then serial=1; fi if [ xgfxterm = "x$x" ]; then console=1; fi if [ xconsole = "x$x" ]; then console=1; fi done if [ "x$serial" = "x1" ]; then if [ "x$console" = "x1" ]; then out="-Dh" else out="-h" fi fi display_loaderopts() { # Optional ARG1, set to a ZFS dataset to mount and read values from if [ -n "$1" ] ; then fMnt="/mnt.$$" mkdir $fMnt mount -t zfs ${1} $fMnt >/dev/null if [ $? -ne 0 ] ; then echo "Failed to mount ${1}" >&2 return fi else fMnt="" fi # Create our placeholder to save _load entries to parse touch /tmp/.lRObjs.$$ touch /tmp/.lSysCtls.$$ # Loader files, in order of which to read them lFiles="${fMnt}/boot/loader.conf.local ${fMnt}/boot/loader.conf ${fMnt}/boot/loader.conf.trueos ${fMnt}/boot/loader.conf.pcbsd" for f in $lFiles do if [ ! -e "$f" ] ; then continue ; fi # Lets parse any of the _load= lines grep "_load=" ${f} | grep -v "^#" >/tmp/.lObjs.$$ while read line do loadVal="`echo $line | cut -d '=' -f 1`" # Is this value already set in a higher priority file? grep -q "^${loadVal}" /tmp/.lRObjs.$$ if [ $? -eq 0 ];then continue; fi # Save this value for later echo "$line" >> /tmp/.lRObjs.$$ haveObjs=1 done < /tmp/.lObjs.$$ rm /tmp/.lObjs.$$ # Lets look for any sysctls to set grep "." ${f} | grep "=" | grep -v "^#" | grep -v "_load" >/tmp/.sObjs.$$ while read line do loadVal="`echo $line | cut -d '=' -f 1`" # Is this value already set in a higher priority file? grep -q "^${loadVal}" /tmp/.lSysCtls.$$ if [ $? -eq 0 ];then continue; fi # Save this value for later echo "$line" >> /tmp/.lSysCtls.$$ haveSysCtls=1 done < /tmp/.sObjs.$$ rm /tmp/.sObjs.$$ done # Using GELI encryption? haveGELI="false" # Now lets echo out the modules to load if [ "$haveObjs" = "1" ] ; then while read line do echo "$line" | grep -q '"YES"' if [ $? -ne 0 ] ; then continue ; fi module="`echo $line | cut -d '=' -f 1 | sed 's|_load||g'`" # Try to locate module now if [ -e "${fMnt}/boot/kernel/${module}.ko" ] ; then mPath="kernel" elif [ -e "${fMnt}/boot/modules/${module}.ko" ] ; then mPath="modules" else # This isn't a module that we can see, lets set it as a variable #echo "No such module $line, setting as a variable" >&2 echo "$line" >> /tmp/.lSysCtls.$$ continue fi # Are we loading GELI module? if [ "$module" = "geom_eli" ] ; then haveGELI="true" ; fi echo " kfreebsd_module_elf ${loadPrefix}/@/boot/${mPath}/${module}.ko" done < /tmp/.lRObjs.$$ fi # Add our compat kenv lines echo " set kFreeBSD.bootfile=\"kernel\"" echo " set kFreeBSD.kernel=\"kernel\"" echo " set kFreeBSD.kernel_options=\"\"" echo " set kFreeBSD.kernelname=\"/boot/kernel/kernel\"" echo " set kFreeBSD.module_path=\"/boot/kernel;/boot/modules\"" # Any kenv to set? if [ "$haveSysCtls" = "1" ] ; then while read line do # Strip out the vfs.root.mountfrom, we set that elsewhere echo "$line" | grep -q "vfs.root.mountfrom" if [ $? -eq 0 ] ; then continue ; fi line="`echo $line | sed 's|"||g'`" key="`echo $line | cut -d '=' -f 1`" val="`echo $line | cut -d '=' -f 2`" if [ -z "$key" -o -z "$val" ] ; then continue ; fi echo " set kFreeBSD.${key}=\"${val}\"" done < /tmp/.lSysCtls.$$ fi rm /tmp/.lRObjs.$$ rm /tmp/.lSysCtls.$$ if [ -n "$1" ] ; then umount /mnt.$$ >/dev/null rmdir /mnt.$$ >/dev/null fi # Set the grub.platform kenv variable echo " set kFreeBSD.grub.platform=\"\$grub_platform\"" # See if we need to do GELI passphrase passthrough if [ "$haveGELI" = "true" ] ; then echo " set kFreeBSD.kern.geom.eli.passphrase=\"\$pass\"" fi } detect_beadm() { /usr/bin/which -s beadm >/dev/null 2>/dev/null if [ $? -ne 0 ] ; then return 0; fi # Check if we are running from the installer and use its beadm if [ -e "/root/beadm.install" ] ; then BEADM="/root/beadm.install" # Check if this is valid testBE=`$BEADM list` if [ -z "$testBE" ] ; then # No BE's, lets switch back to regular mode BEADM="`/usr/bin/which beadm`" fi else BEADM="`/usr/bin/which beadm`" fi ${BEADM} list >/dev/null 2>/dev/null if [ $? -ne 0 ] ; then return 0; fi if [ -e "/etc/defaults/pcbsd" ] ; then NICK="PC-BSD" else NICK="TrueOS" fi # Only list the default BE here $BEADM list -H >/tmp/.grub-beadm.$$ 2>/dev/null while read line do be=`echo $line | awk '{print $1}'` flags=`echo $line | awk '{print $2}'` # Is this BE marked as wanting to be used for next boot? Make it the first one if so if [ "$flags" = "NR" -o "$flags" = "R" ] ; then BE_LIST="$be" break fi done < /tmp/.grub-beadm.$$ rm /tmp/.grub-beadm.$$ # Get list of beadm datasets for b in $BE_LIST do # Got a beadm snapshot, lets get the complete dataset name beLine=`${BEADM} list -a | grep "/$BEDS/${b}"` cdataset=`echo $beLine | awk '{print $1}'` cdatadate=`echo $beLine | awk '{print $5}'` cdatatime=`echo $beLine | awk '{print $6}'` ztank=`echo $cdataset | cut -d '/' -f 1` shortdataset="/`echo $cdataset | cut -d '/' -f 2-5`" # Get the BE nickname if it exists beNickName=`${BEADM} list | grep "^${b} " | tr -s ' ' | cut -d ' ' -f 7-12` if [ -z "$beNickName" ] ; then beNickName="$b" fi # First part of this dataset cat > /tmp/.grubdataset.$$.1 << EOF insmod zfs search --no-floppy -s -l $ztank EOF # Second part of loader to save cat > /tmp/.grubdataset.$$.2 << EOF kfreebsd_module ${shortdataset}/@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache set kFreeBSD.vfs.root.mountfrom=zfs:$cdataset EOF # Now lets look for options in loader.conf to load loadPrefix="${shortdataset}" # If this is the current mounted dataset, we can skip mounting it mount | grep -q -e "$cdataset on / (" -e "$cdataset on /mnt (" if [ $? -eq 0 ] ; then display_loaderopts >>/tmp/.grubdataset.$$.2 else display_loaderopts $cdataset >> /tmp/.grubdataset.$$.2 fi # Lets start a submenu for each BE cat << EOF submenu "${NICK} (${beNickName}) - ${cdatadate} ${cdatatime}" { EOF # Lets do the default entry first ################################# cat << EOF menuentry "Normal Bootup" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out}" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF } EOF # Next lets do single user mode ################################# cat << EOF menuentry "Single User Mode" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out} -s" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF } EOF # Next lets do verbose mode ################################# cat << EOF menuentry "Verbose Mode" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out} -v" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF } EOF if [ -e "/etc/defaults/pcbsd" ] ; then # Next lets do display wizard ################################# cat << EOF menuentry "Run the Display Wizard" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out}" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF set kFreeBSD.runwiz=YES } EOF # Now for vesa mode ################################# cat << EOF menuentry "Run X in vesa mode" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out}" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF set kFreeBSD.xvesa=YES } EOF # Now for non-xorg mode ################################# cat << EOF menuentry "Boot to console (Disable X)" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out}" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF set kFreeBSD.noxorg=YES } EOF fi # Lastly lets close the submenu section cat << EOF } EOF done # Cleanup after ourselves if [ -e "/tmp/.grubdataset.$$.1" ] ; then rm /tmp/.grubdataset.$$.1 rm /tmp/.grubdataset.$$.2 fi } # Detect our types of disk layouts detect_beadm Index: head/sysutils/grub2-pcbsd/files/50_otherbe.in =================================================================== --- head/sysutils/grub2-pcbsd/files/50_otherbe.in (revision 388937) +++ head/sysutils/grub2-pcbsd/files/50_otherbe.in (revision 388938) @@ -1,393 +1,396 @@ #!/bin/sh # # Copyright 2015 iXsystems (Kris Moore) # All rights reserved # # Redistribution and use in source and binary forms, with or without # modification, are permitted providing that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # Script to detect TrueOS / PC-BSD disk installations and create grub # entries for them +# Check if we have beadm installed, if not skip this file +if [ ! -e "/usr/local/sbin/beadm" ] ; then exit 0; fi + ROOTFS=`mount | awk '/ \/ / {print $1}'` BEDS="$( echo ${ROOTFS} | awk -F '/' '{print $2}' )" if [ "$BEDS" = "dev" ] ; then BEDS="ROOT"; fi serial=0; console=0; for x in ${GRUB_TERMINAL_OUTPUT}; do if [ xserial = "x$x" ]; then serial=1; fi if [ xgfxterm = "x$x" ]; then console=1; fi if [ xconsole = "x$x" ]; then console=1; fi done if [ "x$serial" = "x1" ]; then if [ "x$console" = "x1" ]; then out="-Dh" else out="-h" fi fi display_loaderopts() { # Optional ARG1, set to a ZFS dataset to mount and read values from if [ -n "$1" ] ; then fMnt="/mnt.$$" mkdir $fMnt mount -t zfs ${1} $fMnt >/dev/null if [ $? -ne 0 ] ; then echo "Failed to mount ${1}" >&2 return fi else fMnt="" fi # Create our placeholder to save _load entries to parse touch /tmp/.lRObjs.$$ touch /tmp/.lSysCtls.$$ # Loader files, in order of which to read them lFiles="${fMnt}/boot/loader.conf.local ${fMnt}/boot/loader.conf ${fMnt}/boot/loader.conf.trueos ${fMnt}/boot/loader.conf.pcbsd" for f in $lFiles do if [ ! -e "$f" ] ; then continue ; fi # Lets parse any of the _load= lines grep "_load=" ${f} | grep -v "^#" >/tmp/.lObjs.$$ while read line do loadVal="`echo $line | cut -d '=' -f 1`" # Is this value already set in a higher priority file? grep -q "^${loadVal}" /tmp/.lRObjs.$$ if [ $? -eq 0 ];then continue; fi # Save this value for later echo "$line" >> /tmp/.lRObjs.$$ haveObjs=1 done < /tmp/.lObjs.$$ rm /tmp/.lObjs.$$ # Lets look for any sysctls to set grep "." ${f} | grep "=" | grep -v "^#" | grep -v "_load" >/tmp/.sObjs.$$ while read line do loadVal="`echo $line | cut -d '=' -f 1`" # Is this value already set in a higher priority file? grep -q "^${loadVal}" /tmp/.lSysCtls.$$ if [ $? -eq 0 ];then continue; fi # Save this value for later echo "$line" >> /tmp/.lSysCtls.$$ haveSysCtls=1 done < /tmp/.sObjs.$$ rm /tmp/.sObjs.$$ done # Using GELI encryption? haveGELI="false" # Now lets echo out the modules to load if [ "$haveObjs" = "1" ] ; then while read line do echo "$line" | grep -q '"YES"' if [ $? -ne 0 ] ; then continue ; fi module="`echo $line | cut -d '=' -f 1 | sed 's|_load||g'`" # Try to locate module now if [ -e "${fMnt}/boot/kernel/${module}.ko" ] ; then mPath="kernel" elif [ -e "${fMnt}/boot/modules/${module}.ko" ] ; then mPath="modules" else # This isn't a module that we can see, lets set it as a variable #echo "No such module $line, setting as a variable" >&2 echo "$line" >> /tmp/.lSysCtls.$$ continue fi # Are we loading GELI module? if [ "$module" = "geom_eli" ] ; then haveGELI="true" ; fi echo " kfreebsd_module_elf ${loadPrefix}/@/boot/${mPath}/${module}.ko" done < /tmp/.lRObjs.$$ fi # Add our compat kenv lines echo " set kFreeBSD.bootfile=\"kernel\"" echo " set kFreeBSD.kernel=\"kernel\"" echo " set kFreeBSD.kernel_options=\"\"" echo " set kFreeBSD.kernelname=\"/boot/kernel/kernel\"" echo " set kFreeBSD.module_path=\"/boot/kernel;/boot/modules\"" # Any kenv to set? if [ "$haveSysCtls" = "1" ] ; then while read line do # Strip out the vfs.root.mountfrom, we set that elsewhere echo "$line" | grep -q "vfs.root.mountfrom" if [ $? -eq 0 ] ; then continue ; fi line="`echo $line | sed 's|"||g'`" key="`echo $line | cut -d '=' -f 1`" val="`echo $line | cut -d '=' -f 2`" if [ -z "$key" -o -z "$val" ] ; then continue ; fi echo " set kFreeBSD.${key}=\"${val}\"" done < /tmp/.lSysCtls.$$ fi rm /tmp/.lRObjs.$$ rm /tmp/.lSysCtls.$$ if [ -n "$1" ] ; then umount /mnt.$$ >/dev/null rmdir /mnt.$$ >/dev/null fi # Set the grub.platform kenv variable echo " set kFreeBSD.grub.platform=\"\$grub_platform\"" # See if we need to do GELI passphrase passthrough if [ "$haveGELI" = "true" ] ; then echo " set kFreeBSD.kern.geom.eli.passphrase=\"\$pass\"" fi } detect_beadm() { /usr/bin/which -s beadm >/dev/null 2>/dev/null if [ $? -ne 0 ] ; then return 0; fi # Check if we are running from the installer and use its beadm if [ -e "/root/beadm.install" ] ; then BEADM="/root/beadm.install" # Check if this is valid testBE=`$BEADM list` if [ -z "$testBE" ] ; then # No BE's, lets switch back to regular mode BEADM="`/usr/bin/which beadm`" fi else BEADM="`/usr/bin/which beadm`" fi ${BEADM} list >/dev/null 2>/dev/null if [ $? -ne 0 ] ; then return 0; fi if [ -e "/etc/defaults/pcbsd" ] ; then NICK="PC-BSD" else NICK="TrueOS" fi # Now we will list all the non-default BEs $BEADM list -H >/tmp/.grub-beadm.$$ 2>/dev/null while read line do be=`echo $line | awk '{print $1}'` flags=`echo $line | awk '{print $2}'` # Skip the active BE if [ "$flags" = "NR" -o "$flags" = "R" ] ; then continue fi BE_LIST="${be} ${BE_LIST}" done < /tmp/.grub-beadm.$$ rm /tmp/.grub-beadm.$$ if [ -z "$BE_LIST" ] ; then return; fi echo "submenu \"Boot Environment Menu\" {" # Get list of beadm datasets for b in $BE_LIST do # Got a beadm snapshot, lets get the complete dataset name beLine=`${BEADM} list -a | grep "/$BEDS/${b}"` cdataset=`echo $beLine | awk '{print $1}'` cdatadate=`echo $beLine | awk '{print $5}'` cdatatime=`echo $beLine | awk '{print $6}'` ztank=`echo $cdataset | cut -d '/' -f 1` shortdataset="/`echo $cdataset | cut -d '/' -f 2-5`" # Get the BE nickname if it exists beNickName=`${BEADM} list | grep "^${b} " | tr -s ' ' | cut -d ' ' -f 7-12` if [ -z "$beNickName" ] ; then beNickName="$b" fi # First part of this dataset cat > /tmp/.grubdataset.$$.1 << EOF insmod zfs search --no-floppy -s -l $ztank EOF # Second part of loader to save cat > /tmp/.grubdataset.$$.2 << EOF kfreebsd_module ${shortdataset}/@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache set kFreeBSD.vfs.root.mountfrom=zfs:$cdataset EOF # Now lets look for options in loader.conf to load loadPrefix="${shortdataset}" # If this is the current mounted dataset, we can skip mounting it mount | grep -q -e "$cdataset on / (" -e "$cdataset on /mnt (" if [ $? -eq 0 ] ; then display_loaderopts >>/tmp/.grubdataset.$$.2 else display_loaderopts $cdataset >> /tmp/.grubdataset.$$.2 fi # Lets start a submenu for each BE cat << EOF submenu "${NICK} (${beNickName}) - ${cdatadate} ${cdatatime}" { EOF # Lets do the default entry first ################################# cat << EOF menuentry "Normal Bootup" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out}" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF } EOF # Next lets do single user mode ################################# cat << EOF menuentry "Single User Mode" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out} -s" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF } EOF # Next lets do verbose mode ################################# cat << EOF menuentry "Verbose Mode" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out} -v" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF } EOF if [ -e "/etc/defaults/pcbsd" ] ; then # Next lets do display wizard ################################# cat << EOF menuentry "Run the Display Wizard" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out}" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF set kFreeBSD.runwiz=YES } EOF # Now for vesa mode ################################# cat << EOF menuentry "Run X in vesa mode" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out}" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF set kFreeBSD.xvesa=YES } EOF # Now for non-xorg mode ################################# cat << EOF menuentry "Boot to console (Disable X)" { EOF # Get the dataset guts cat /tmp/.grubdataset.$$.1 echo " kfreebsd ${shortdataset}/@/boot/kernel/kernel ${out}" echo " kfreebsd_loadenv ${shortdataset}@/boot/device.hints" cat /tmp/.grubdataset.$$.2 # Set any options cat << EOF set kFreeBSD.noxorg=YES } EOF fi # Lastly lets close the submenu section cat << EOF } EOF done echo "}" echo "" # Cleanup after ourselves if [ -e "/tmp/.grubdataset.$$.1" ] ; then rm /tmp/.grubdataset.$$.1 rm /tmp/.grubdataset.$$.2 fi } # Detect our types of disk layouts detect_beadm Index: head/sysutils/grub2-pcbsd/pkg-message =================================================================== --- head/sysutils/grub2-pcbsd/pkg-message (revision 388937) +++ head/sysutils/grub2-pcbsd/pkg-message (revision 388938) @@ -1,19 +1,34 @@ -This version of GRUB includes support for PC-BSD style boot -environments. For it to properly detect / populate your -BE menus you must have your root zpool setup in the following -manner: +To install GRUB as your boot-loader, use the following command: -/ROOT/ +# grub-install /dev/ada0 (replace ada0 with your disk) +# grub-mkconfig -o /boot/grub/grub.cfg -Where is your zpool, and is your '/' mountpoint. -The "beadm" utility must be installed and working before using -GRUB utilities. +This version of GRUB can be used traditionally or with +PC-BSD style boot environments. Additionally, when using GPT, you must have a created a "bios-boot" partition at install time. This partition is used for GRUB's modules for GELI/ZFS and related bits. -To install GRUB as your boot-loader, use the following command: +Traditional Setup +-- -# grub-install /dev/ada0 (replace ada0 with your disk) -# grub-mkconfig -o /boot/grub/grub.cfg +When the "beadm" utility is not present, grub-mkconfig +will use the standard GRUB detection scripts for setting +up your /boot/grub/grub.cfg file. + + +Boot Environment Setup +-- + +If the "beadm" command is installed on the system, +grub-mkconfig will use it to setup /boot/grub/grub.cfg + +For it to properly detect / populate your BE menus you +must have your root zpool setup in the following manner: + +/ROOT/ + +Where is your zpool, and is your '/' mountpoint. +The "beadm" utility must be installed and working before using +GRUB utilities.