Can't boot from a GRUB loop device.

The GRUB bootloader has the ability to boot directly from ISO images. znx exploits that feature to provide a very crucial part of its functionality. When a Manjaro image is deployed (GNOME, Plasma, XFCE), znx fails to boot it. The initramfs scripts will complain because the root device can't be found.

The miso_loop_mnt hook tries to detect the loop device based on its label. However, the GRUB configuration file does not pass the needed parameter; instead, it passes the device UUID. But that UUID is never set.

A solution for that problem is to discover the device from within the initramfs by looking for the loop device (which is a file) in all the connected devices. That is achieved by the find_dev_by_path function below.

find_dev_by_path () {
	local path="$1"
	local tmp_mnt=/tmp_mnt
	local _mnt
	local a d
	local device

	[ "$path" ] ||
		return 1

	mkdir -p "$tmp_mnt"

	for a in 1 2 3; do
		for d in $(awk '{ print "/dev/"$4 }' /proc/partitions); do

			# -- If the device is already mounted, it shouldn't be
			# -- unmounted after the check.

			grep -q "^$d " /proc/mounts && {
				_mnt=$(grep "^$d " /proc/mounts | cut -d ' ' -f 2)
				unmount=
			} || {
				mount -r -t auto "$d" "$tmp_mnt" 2> /dev/null || continue
				_mnt="$tmp_mnt"
				unmount=true
			}

			# -- File exists in $d. Save $d on $device.

			[ -f "$_mnt/$path" ] &&
				device="$d"

			[ "$unmount" ] &&
				umount "$tmp_mnt" 2> /dev/null || true

			[ "$device" ] && {
				echo "$device"
				return
			}

		done
		sleep 1
	done

	return 1
}


run_hook () {

	[ "$img_flags" ] || img_flags="defaults"

	if [ "$img_loop" ]; then
		img_dev=$(find_dev_by_path "$img_loop")
		mount_handler="miso_loop_mount_handler"
	fi
}

miso_loop_mount_handler () {
	newroot="$1"

	local _dev_loop

	msg ":: Setup a loop device from $img_loop located at device $img_dev"
	_mnt_dev "$img_dev" "/run/miso/img_dev" "-r" "$img_flags"

	if _dev_loop=$(losetup --find --show --read-only "/run/miso/img_dev/$img_loop"); then
		misodevice="$_dev_loop"
	else
		echo "ERROR: Setting loopback device for file '/run/miso/img_dev/$img_loop'"
		launch_interactive_shell
	fi

	miso_mount_handler $newroot

	if [ "$copytoram" == "y" ]; then
		losetup -d $_dev_loop 2> /dev/null
		umount /run/miso/img_dev
	else
		echo $(readlink -f $img_dev) >> /run/miso/used_block_devices
	fi
}
Edited by Ghost User