qubes-linux-utils/dracut/full-dmroot/qubes_cow_setup.sh
Marek Marczykowski-Górecki da3f3cd426
initramfs: use symlink for rw root.img, instead of dm-linear
Do not add 1:1 dm-linear when root.img (/dev/xvda) is read-write. This
was to always have root device at /dev/mapper/dmroot, but unfortunately
grub can't parse it properly (fails at looking for partition number of
/dev/xvda1). There was a hack specifically for this, but it caused other
partitions on xvda unavailable.
On the other hand, symlink is enough to be able to mount always the same
device. Now, grub detect that root fs is on /dev/xvda1, which is
enough to have grub2-install working. Unfortunate effect is that it puts
root=/dev/xvda1 at kernel command line, which breaks AppVMs based on
this TemplateVM. But it's easier to fix kernel command line, than grub
device detection logic.

Fixes "initramfs: add support for root.img with partition table"

QubesOS/qubes-issues#2557
2017-06-12 13:02:31 +02:00

107 lines
2.8 KiB
Bash

#!/bin/sh
#
# This file should be placed in pre-trigger directory in dracut's initramfs, or
# scripts/local-top in case of initramfs-tools
#
# initramfs-tools (Debian) API
PREREQS=""
case "$1" in
prereqs)
# This runs during initramfs creation
echo "$PREREQS"
exit 0
;;
esac
# This runs inside real initramfs
if [ -r /scripts/functions ]; then
# We're running in Debian's initramfs
. /scripts/functions
alias die=panic
alias info=true
alias warn=log_warning_msg
alias log_begin=log_begin_msg
alias log_end=log_end_msg
elif [ -r /lib/dracut-lib.sh ]; then
. /lib/dracut-lib.sh
alias log_begin=info
alias log_end=true
else
die() {
echo "$@"
exit 1
}
alias info=echo
alias warn=echo
alias log_begin=echo
alias log_end=true
fi
info "Qubes initramfs script here:"
if ! grep -q 'root=[^ ]*dmroot' /proc/cmdline; then
warn "dmroot not requested, probably not a Qubes VM"
exit 0
fi
if [ -e /dev/mapper/dmroot ] ; then
die "Qubes: FATAL error: /dev/mapper/dmroot already exists?!"
fi
modprobe xenblk || modprobe xen-blkfront || warn "Qubes: Cannot load Xen Block Frontend..."
log_begin "Waiting for /dev/xvda* devices..."
while ! [ -e /dev/xvda ]; do sleep 0.1; done
log_end
# prefer first partition if exists
if [ -b /dev/xvda1 ]; then
ROOT_DEV=xvda1
else
ROOT_DEV=xvda
fi
SWAP_SIZE=$(( 1024 * 1024 * 2 )) # sectors, 1GB
if [ `cat /sys/class/block/$ROOT_DEV/ro` = 1 ] ; then
log_begin "Qubes: Doing COW setup for AppVM..."
while ! [ -e /dev/xvdc ]; do sleep 0.1; done
VOLATILE_SIZE=$(cat /sys/class/block/xvdc/size) # sectors
ROOT_SIZE=$(cat /sys/class/block/$ROOT_DEV/size) # sectors
if [ $VOLATILE_SIZE -lt $SWAP_SIZE ]; then
die "volatile.img smaller than 1GB, cannot continue"
fi
sfdisk -q --unit S /dev/xvdc >/dev/null <<EOF
1,$SWAP_SIZE,S
,,L
EOF
if [ $? -ne 0 ]; then
die "Qubes: failed to setup partitions on volatile device"
fi
while ! [ -e /dev/xvdc1 ]; do sleep 0.1; done
mkswap /dev/xvdc1
while ! [ -e /dev/xvdc2 ]; do sleep 0.1; done
echo "0 `cat /sys/class/block/$ROOT_DEV/size` snapshot /dev/$ROOT_DEV /dev/xvdc2 N 16" | \
dmsetup --noudevsync create dmroot || die "Qubes: FATAL: cannot create dmroot!"
dmsetup mknodes dmroot
log_end
else
log_begin "Qubes: Doing R/W setup for TemplateVM..."
while ! [ -e /dev/xvdc ]; do sleep 0.1; done
sfdisk -q --unit S /dev/xvdc >/dev/null <<EOF
1,$SWAP_SIZE,S
EOF
if [ $? -ne 0 ]; then
die "Qubes: failed to setup partitions on volatile device"
fi
while ! [ -e /dev/xvdc1 ]; do sleep 0.1; done
mkswap /dev/xvdc1
printf 'KERNEL=="%s", SYMLINK+="mapper/dmroot"' "$ROOT_DEV" >> \
/etc/udev/rules.d/99-root.rules
log_end
fi