qubes-linux-utils/dracut/full-dmroot/qubes_cow_setup.sh
Marek Marczykowski-Górecki d0fe5e6f9a
initramfs: add support for root.img with partition table
Installing grub on root.img require some space before the filesystem.
Create it by adding partition table to root.img. This commit take care
of assembling dmroot device when such partition table is present, while
preserving compatibility with partition-less images.

QubesOS/qubes-issues#2577
2017-04-08 13:58:33 +02:00

116 lines
3.2 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!"
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
if [ "$ROOT_DEV" = "xvda1" ]; then
# grub2-probe for some reason can't parse dm-linear pointing at
# partition device directly, but can when it points at it indirectly
# through base device and offset; lets make life easier for users of
# grub2-install
DM_ROOT="/dev/xvda $(cat /sys/class/block/$ROOT_DEV/start)"
else
DM_ROOT="/dev/$ROOT_DEV 0"
fi
echo "0 `cat /sys/class/block/$ROOT_DEV/size` linear $DM_ROOT" | \
dmsetup create dmroot || { echo "Qubes: FATAL: cannot create dmroot!"; exit 1; }
log_end
fi
dmsetup mknodes dmroot