umorpha-boxes/pkg/umorpha-disk/umorpha-mount

114 lines
3.9 KiB
Plaintext
Raw Permalink Normal View History

#!/bin/sh
# Copyright (C) 2023 Umorpha Systems
# SPDX-License-Identifier: AGPL-3.0-or-later
# This script is intended to work both in an initramfs and as a
# developer-friendly tool on a real OS. Therefore, it has very few
# dependencies and must be tolerant of different implementations:
#
# - sh (bash or busybox)
# - getopt (busybox or util-linux)
# - mkdir (busybox or coreutils)
# - mount (util-linux)
set -eu
usage() {
echo "Usage: $0 OPTIONS"
2023-12-07 20:49:39 +00:00
echo "Mount devices using the Umorpha overlay-partition scheme."
echo
echo "OPTIONS:"
echo " -h, --help Show this help text"
echo " --root SPEC (required) The read-only root device ant its mount arguments"
echo " --overlay SPEC (required) The writable overlay device ant its mount arguments"
echo " --boot SPEC (optional) The device to mount at /boot"
echo " --basedir DIR (required) Scratch directory to mount the root device and the overlay device"
echo " --final-mountpoint DIR (optional) Where to mount the overlayfs (default: \${basedir}/mnt"
echo
echo "A SPEC is of the form"
echo " DEVICE[:[FSTYPE][:OPTS]]"
echo "If FSTYPE value isn't present, or is empty, then \`auto\` is used."
}
main() {
mode=run
if O=$(getopt -n "${0##*/}" -l help,root:,overlay:,boot:,basedir:,final-mountpoint: -o h -- "$@"); then
eval "set -- $O"
while true; do
case "$1" in
--help|-h) usage; exit 0;;
--root) root_all=$2; shift 2;;
--overlay) overlay_all=$2; shift 2;;
--boot) boot_all=$2; shift 2;;
--basedir) basedir=$2; shift 2;;
--final-mountpoint) union_mnt=$2; shift 2;;
--) shift; break;;
esac
done
if [[ "$#" -gt 0 ]]; then
echo >&2 "${0##*/}: unexpected positional arguments: $*"
mode=error
fi
if [[ -z "${root_all:-}" ]]; then
echo >&2 "${0##*/}: missing required --root flag"
mode=error
fi
if [[ -z "${overlay_all:-}" ]]; then
echo >&2 "${0##*/}: missing required --overlay flag"
mode=error
fi
if [[ -z "${basedir:-}" ]]; then
echo >&2 "${0##*/}: missing required --basedir flag"
mode=error
fi
else
mode=error
fi
if [[ $mode == error ]]; then
echo "Try '${0##*/} --help' for more information."
exit 2
fi
IFS=: read -r root_dev root_typ root_opt < <(echo "$root_all")
root_mnt=$basedir/root
IFS=: read -r overlay_dev overlay_typ overlay_opt < <(echo "$overlay_all")
2023-12-06 23:46:11 +00:00
overlay_mnt=$basedir/overlay
union_dev=umorpha-rootfs
union_typ=overlay
# BusyBox ash supports weird Bash-isms like "<(process
# substitution)" and the special "[[" syntax, but supporting
# "+=" to append to a variable is too much bloat!??
union_opt=''
union_opt="${union_opt:+${union_opt},}lowerdir=${root_mnt}"
union_opt="${union_opt:+${union_opt},}upperdir=${overlay_mnt}/upperdir"
union_opt="${union_opt:+${union_opt},}workdir=${overlay_mnt}/workdir"
# > Offline changes to the lower tree are only allowed if the
# > "metadata only copy up", "inode index", "xino" and
# > "redirect_dir" features have not been used.
#
# -- https://www.kernel.org/doc/html/v6.6/filesystems/overlayfs.html#changes-to-underlying-filesystems
union_opt="${union_opt:+${union_opt},}metacopy=off"
union_opt="${union_opt:+${union_opt},}index=off"
union_opt="${union_opt:+${union_opt},}xino=off"
union_opt="${union_opt:+${union_opt},}redirect_dir=off"
union_mnt=${union_mnt:-${basedir:-}/mnt}
if [[ -n "${boot_all:-}" ]]; then
IFS=: read -r boot_dev boot_typ boot_opt < <(echo "$boot_all")
2023-12-07 05:06:07 +00:00
boot_mnt=$union_mnt/boot
fi
set -x
mount --mkdir -t "${root_typ:-auto}" -o "$root_opt" "$root_dev" "$root_mnt"
mount --mkdir -t "${overlay_typ:-auto}" -o "$overlay_opt" "$overlay_dev" "$overlay_mnt"
2023-12-07 05:06:07 +00:00
mkdir -p -- "$overlay_mnt/upperdir" "$overlay_mnt/workdir"
mount --mkdir -t "${union_typ:-auto}" -o "$union_opt" "$union_dev" "$union_mnt"
if [[ -n "${boot_all:-}" ]]; then
mount --mkdir -t "${boot_typ:-auto}" -o "$boot_opt" "$boot_dev" "$boot_mnt"
fi
}
main "$@"