Created
January 15, 2017 14:10
-
-
Save ferdinandkeil/a929b50b36b7cc106b6c0853ba91700d to your computer and use it in GitHub Desktop.
/usr/share/initramfs-tools/scripts/overlay for read-only fs on Raspbian
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I just finished writing something similar, and then stumbled across this. Wish I saw it a little sooner, you did it better than I. ;)