Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
/usr/share/initramfs-tools/scripts/overlay for read-only fs on Raspbian
# Local filesystem mounting -*- shell-script -*-
local_top()
{
if [ "${local_top_used}" != "yes" ]; then
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-top"
run_scripts /scripts/local-top
[ "$quiet" != "y" ] && log_end_msg
fi
local_top_used=yes
}
local_block()
{
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-block"
run_scripts /scripts/local-block "$@"
[ "$quiet" != "y" ] && log_end_msg
}
local_premount()
{
if [ "${local_premount_used}" != "yes" ]; then
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-premount"
run_scripts /scripts/local-premount
[ "$quiet" != "y" ] && log_end_msg
fi
local_premount_used=yes
}
local_bottom()
{
if [ "${local_premount_used}" = "yes" ] || [ "${local_top_used}" = "yes" ]; then
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/local-bottom"
run_scripts /scripts/local-bottom
[ "$quiet" != "y" ] && log_end_msg
fi
local_premount_used=no
local_top_used=no
}
# $1=device to mount
# $2=optionname (for root and etc)
local_device_setup()
{
wait_for_udev 10
# Load ubi with the correct MTD partition and return since fstype
# doesn't work with a char device like ubi.
if [ -n "$UBIMTD" ]; then
modprobe ubi mtd=$UBIMTD
return
fi
# Don't wait for a root device that doesn't have a corresponding
# device in /dev (ie, mtd0)
if [ "${1#/dev}" = "$1" ]; then
return
fi
# If the root device hasn't shown up yet, give it a little while
# to allow for asynchronous device discovery (e.g. USB). We
# also need to keep invoking the local-block scripts in case
# there are devices stacked on top of those.
if [ ! -e "$1" ] || ! $(get_fstype "$1" >/dev/null); then
log_begin_msg "Waiting for $2 file system"
# Timeout is max(30, rootdelay) seconds (approximately)
slumber=30
if [ ${ROOTDELAY:-0} -gt $slumber ]; then
slumber=$ROOTDELAY
fi
while true; do
sleep 1
local_block "$1"
if [ -e "$1" ] && get_fstype "$1" >/dev/null; then
wait_for_udev 10
log_end_msg 0
break
fi
slumber=$(( ${slumber} - 1 ))
if [ ${slumber} -eq 0 ]; then
log_end_msg 1 || true
break
fi
done
fi
# We've given up, but we'll let the user fix matters if they can
while [ ! -e "$1" ]; do
# give hint about renamed root
case "$1" in
/dev/hd*)
suffix="${1#/dev/hd}"
major="${suffix%[[:digit:]]}"
major="${major%[[:digit:]]}"
if [ -d "/sys/block/sd${major}" ]; then
echo "WARNING bootdevice may be renamed. Try $2=/dev/sd${suffix}"
fi
;;
/dev/sd*)
suffix="${1#/dev/sd}"
major="${suffix%[[:digit:]]}"
major="${major%[[:digit:]]}"
if [ -d "/sys/block/hd${major}" ]; then
echo "WARNING bootdevice may be renamed. Try $2=/dev/hd${suffix}"
fi
;;
esac
echo "Gave up waiting for $2 device. Common problems:"
echo " - Boot args (cat /proc/cmdline)"
echo " - Check rootdelay= (did the system wait long enough?)"
# Only applies to root= and etc=:
if [ "${2#/}" = "$2" ]; then
echo " - Check $2= (did the system wait for the right device?)"
fi
echo " - Missing modules (cat /proc/modules; ls /dev)"
panic "ALERT! $1 does not exist. Dropping to a shell!"
done
}
local_mount_root()
{
local_top
local_device_setup "${ROOT}" root
# Get the root filesystem type if not set
if [ -z "${ROOTFSTYPE}" ]; then
FSTYPE=$(get_fstype "${ROOT}")
else
FSTYPE=${ROOTFSTYPE}
fi
local_premount
ROOT=$(resolve_device "$ROOT")
# if [ "${readonly}" = "y" ]; then
# roflag=-r
# else
# roflag=-w
# fi
# FIXME This has no error checking
modprobe ${FSTYPE}
checkfs ${ROOT} root
# FIXME This has no error checking
# Mount root
# if [ "${FSTYPE}" != "unknown" ]; then
# mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}
# else
# mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt}
# fi
mkdir /upper /lower
if [ "${FSTYPE}" != "unknown" ]; then
mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} /lower
else
mount ${roflag} ${ROOTFLAGS} ${ROOT} /lower
fi
modprobe overlay
mount -t tmpfs tmpfs /upper
mkdir /upper/data /upper/work
mount -t overlay \
-olowerdir=/lower,upperdir=/upper/data,workdir=/upper/work \
overlay ${rootmnt}
}
local_mount_fs()
{
read_fstab_entry "$1"
MNT_FSNAME=$(resolve_device "$MNT_FSNAME")
local_device_setup "$MNT_FSNAME" "$1"
local_premount
MNT_FSNAME=$(resolve_device "$MNT_FSNAME")
if [ "${readonly}" = "y" ]; then
roflag=-r
else
roflag=-w
fi
# FIXME This has no error checking
modprobe "${MNT_TYPE}"
checkfs "$MNT_FSNAME" "$MNT_DIR"
# FIXME This has no error checking
# Mount filesystem
mount ${roflag} -t "${MNT_TYPE}" -o "${MNT_OPTS}" "$MNT_FSNAME" "${rootmnt}${MNT_DIR}"
}
mountroot()
{
local_mount_root
}
mount_top()
{
# Note, also called directly in case it's overridden.
local_top
}
mount_premount()
{
# Note, also called directly in case it's overridden.
local_premount
}
mount_bottom()
{
# Note, also called directly in case it's overridden.
local_bottom
}

Izzette commented Aug 15, 2017

I just finished writing something similar, and then stumbled across this. Wish I saw it a little sooner, you did it better than I. ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment