# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-set -eE -o pipefail
-trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
-
[[ $EUID == 0 ]] || exec sudo "$BASH_SOURCE" "$@"
+
+x="$(readlink -f "$BASH_SOURCE")"
+f="${x%/*}/bash-trace"
+if [[ -e $f ]]; then
+ source $f
+else
+ source ${x%/*}/../bash-trace/DEFAULT
+fi
+
+
usage() {
- cat <<EOF
+ cat <<EOF
Usage: ${0##*/} [OPTIONS] DISTRO_NAME
Set grub to boot into a different distro, and reboot unless -r
With no argument, print available distros
DISTRO_NAME is based on the partition names in /boot.
-For example debianjessie for the partitionn boot_debianjessie.
+For example, boot_debianjessie.
For a system without libreboot, which is failing completely to
boot on one distro, here is how I did a chboot for it:
# arch-pxe had been run previously
-pxe-server treetowl arch
-# reboot treetowl into arch live env
+pxe-server some_hostname arch
+# reboot some_hostname into arch live env
pxe-server # disable pxe server
-ssh root@treetowl
+ssh root@some_hostname
lsblk # identify boot dev. if boot dev is a raid, this could be repeated on all boot devs.
mount /dev/sdd3 /mnt
-mount_point=/mnt/boot_debiantesting # the subvol i want to chboot to
+mp=/mnt/boot_debiantesting # the subvol i want to chboot to
boot_disk=/dev/sdd
-grub-bios-setup -d $mount_point/grub/i386-pc -s -m $mount_point/grub/device.map $boot_disk
+grub-bios-setup -d $mp/grub/i386-pc -s -m $mp/grub/device.map $boot_disk
reboot
todo: figure out if it's possible to make a multi-distro grub like I have with libreboot
Note: Uses GNU getopt options parsing style
EOF
- exit $1
+ exit $1
}
-grub_extn=4
###### begin command line parsing #####
reboot=true
temp=$(getopt -l help hdr "$@") || usage 1
eval set -- "$temp"
while true; do
- case $1 in
- -d) set -x; shift ;;
- -r) reboot=false; shift ;;
- -h|--help) usage ;;
- --) shift; break ;;
- *) echo "$0: Internal error!" ; exit 1 ;;
- esac
+ case $1 in
+ -d) set -x; shift ;;
+ -r) reboot=false; shift ;;
+ -h|--help) usage ;;
+ --) shift; break ;;
+ *) echo "$0: Internal error!" ; exit 1 ;;
+ esac
done
distro=$1
+mnt=/boot
+if ! mountpoint $mnt &>/dev/null; then
+ mnt=/
+fi
+
if [[ ! $distro ]]; then
- echo "available distros:"
- cur=$(btrfs subvol show /boot| sed -rn 's/^.*Name:\s*(\S*).*/\1/p')
- btrfs subvolume list /boot | awk '{print $9}' | sed "s/$cur/$cur (current)/"
- exit 0
+ echo "available distros:"
+ cur=$(btrfs subvol show $mnt| sed -rn 's/^.*Name:\s*(\S*).*/\1/p')
+ btrfs subvolume list $mnt | awk '{print $9}' | sed "s/$cur/$cur (current)/"
+ exit 0
fi
###### end command line parsing #####
#### begin initial error checking #####
-if ! btrfs subvolume list /boot | grep "_$distro$" &>/dev/null; then
- echo "$0: error: _$distro$ not found in btrfs subvolume list /boot:"
- btrfs subvolume list /boot
- exit 1
+if ! btrfs subvolume list $mnt | grep "$distro$" &>/dev/null; then
+ echo "$0: error: $distro not found in btrfs subvolume list $mnt:"
+ btrfs subvolume list $mnt
+ exit 1
fi
#### end initial error checking #####
e() { echo "$@"; "$@"; }
-boot_dev=$(mount | sed -rn "s#^(\S+) on /boot .*#\1#p")
+for boot_dev in $(btrfs fil show $mnt | sed -nr 's#.*path\s+(\S+)$#\1#p'); do
-mount_point=$(mktemp -d)
+ mount_point=$(mktemp -d)
-e mount -o subvol=boot_$distro $boot_dev $mount_point
+ e mount -o subvol=$distro $boot_dev $mount_point
-boot_disk=${boot_dev%%[0-9]*}
+ boot_disk=${boot_dev%%[0-9]*}
-# arch doesn't have $mount_point/grub/device.map, accoring to the grub manual,
-# it just generates one if the file doesn't exist.
-# https://www.gnu.org/software/grub/manual/html_node/Device-map.html
-e grub-bios-setup -d $mount_point/grub/i386-pc -s -m $mount_point/grub/device.map $boot_disk
+ # arch doesn't have $mount_point/grub/device.map, accoring to the grub manual,
+ # it just generates one if the file doesn't exist.
+ # https://www.gnu.org/software/grub/manual/html_node/Device-map.html
+ e grub-bios-setup -d $mount_point/grub/i386-pc -s -m $mount_point/grub/device.map $boot_disk
+ e umount $mount_point
+done
-e umount $mount_point
+if [[ $(blockdev --getsize64 ${boot_disk}4) == 8388608 ]]; then
+ # old partition scheme
+ grub_dev=${boot_disk}4
+elif [[ $(blockdev --getsize64 ${boot_disk}5) == 8388608 ]]; then
+ grub_dev=${boot_disk}5
+else
+ grub_dev=${boot_disk}7
+fi
-e mount $boot_disk$grub_extn $mount_point
-e grub-editenv $mount_point/grubenv set last_boot=/boot_$distro
+e mount $grub_dev $mount_point
+e grub-editenv $mount_point/grubenv set last_boot=/$distro
e grub-editenv $mount_point/grubenv set did_fai_check=true
e umount $mount_point
-e rmdir $mount_point
-
if $reboot; then
- touch /tmp/keyscript-off
- reboot now
+ touch /tmp/keyscript-off
+ reboot now
fi