common: Refactor persistent storage setup

In the new model, we have three sources of storage:

- /mnt/var: Mountpoint for a disk with the label "var"
- /mnt/cfg: Mountpoint for a disk with the label "cfg"
- /mnt/tmp: Mountpoint for a ramdisk

These sources are used for the following overlays:

- **/cfg, /home, /root**: /mnt/cfg if available, else /mnt/tmp

- **/etc**: /mnt/cfg if available and the boot/etc finit condition is
            set, else /mnt/tmp

- **/var**: /mnt/var if available, else /mnt/tmp

- **/var/lib**: /mnt/var if available, else /mnt/cfg if available,
                else /mnt/tmp

See board/common/rootfs/lib/infix/mnt for more information.
This commit is contained in:
Tobias Waldekranz
2023-02-07 15:42:35 +01:00
parent 5ec019f97a
commit ca1467736f
13 changed files with 138 additions and 90 deletions
+4 -4
View File
@@ -1,6 +1,6 @@
image rw.ext4 {
image cfg.ext4 {
ext4 {
label = "infix-rw"
label = "cfg"
}
empty = true
size = 16M
@@ -15,9 +15,9 @@ image sdcard.img {
image = "rootfs.ext4"
}
partition rw {
partition cfg {
partition-type = 0x83
image = "rw.ext4"
image = "cfg.ext4"
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
image rw.ext4 {
image cfg.ext4 {
ext4 {
label = "infix-rw"
label = "cfg"
}
empty = true
size = 16M
+4 -4
View File
@@ -33,9 +33,9 @@ cat <<EOF >"$BINARIES_DIR/infix.gns3a"
"version": "0.0"
},
{
"filename": "rw.ext4",
"filesize": $(stat --printf='%s' "$BINARIES_DIR/rw.ext4"),
"md5sum": "$(md5sum "$BINARIES_DIR/rw.ext4" | awk '{print $1}')",
"filename": "cfg.ext4",
"filesize": $(stat --printf='%s' "$BINARIES_DIR/cfg.ext4"),
"md5sum": "$(md5sum "$BINARIES_DIR/cfg.ext4" | awk '{print $1}')",
"version": "0.0"
}
],
@@ -44,7 +44,7 @@ cat <<EOF >"$BINARIES_DIR/infix.gns3a"
"name": "0.0",
"images": {
"cdrom_image": "rootfs.iso9660",
"hda_disk_image": "rw.ext4"
"hda_disk_image": "cfg.ext4"
}
}
]
+7 -23
View File
@@ -14,26 +14,10 @@ cfgfs /config configfs nofail,noauto 0 0
# Optional host share when running in Qemu
hostfs /host 9p nofail,cache=none,msize=16384 0 0
# Use persistent storage if available, fallback to ramdisk otherwise
LABEL=infix-rw /rw auto noatime,nodiratime,noauto 0 0
tmpfs-rw /rw tmpfs noatime,nodiratime,noauto 0 0
/lib/infix/mount-rw# /rw helper none 0 0
# Ensure that all overlay directories are available
mkdir#-p#-m0755 /tmp/infix/var.u helper none 0 0
mkdir#-p#-m0755 /tmp/infix/var.w helper none 0 0
mkdir#-p#-m0755 /rw/infix/varlib.u helper none 0 0
mkdir#-p#-m0755 /rw/infix/varlib.w helper none 0 0
mkdir#-p#-m0755 /rw/infix/etc.u helper none 0 0
mkdir#-p#-m0755 /rw/infix/etc.w helper none 0 0
mkdir#-p#-m0700 /rw/infix/root.u helper none 0 0
mkdir#-p#-m0700 /rw/infix/root.w helper none 0 0
mkdir#-p#-m0700 /rw/infix/home.u helper none 0 0
mkdir#-p#-m0700 /rw/infix/home.w helper none 0 0
# Overlay selected parts of the fileinfix with persistent storage
rw-var /var overlay lowerdir=/var,upperdir=/tmp/infix/var.u,workdir=/tmp/infix/var.w 0 0
rw-vlib /var/lib overlay lowerdir=/var/lib,upperdir=/rw/infix/varlib.u,workdir=/rw/infix/varlib.w 0 0
rw-etc /etc overlay lowerdir=/etc,upperdir=/rw/infix/etc.u,workdir=/rw/infix/etc.w 0 0
rw-root /root overlay lowerdir=/root,upperdir=/rw/infix/root.u,workdir=/rw/infix/root.w 0 0
rw-home /home overlay lowerdir=/home,upperdir=/rw/infix/home.u,workdir=/rw/infix/home.w 0 0
# The chosen backing storage for the overlays placed on /cfg, /etc,
# /home, /root, and /var, are determined dynamically by /lib/infix/mnt
# depending on the available devices.
mnttmp /mnt/tmp tmpfs defaults 0 0
LABEL=var /mnt/var auto noatime,nodiratime,noauto 0 0
LABEL=cfg /mnt/cfg auto noatime,nodiratime,noauto 0 0
/lib/infix/mnt# /cfg helper none 0 0
+1 -1
View File
@@ -1 +1 @@
alias factory='read -N 1 -p "Factory reset requires a reboot, continue (y/N)? " yorn; echo; if [ "$yorn" = "y" ]; then touch /rw/infix/.reset; reboot; fi'
alias factory='read -N 1 -p "Factory reset requires a reboot, continue (y/N)? " yorn; echo; if [ "$yorn" = "y" ]; then touch /mnt/cfg/infix/.reset; reboot; fi'
+118
View File
@@ -0,0 +1,118 @@
#!/bin/sh
# Called from /etc/fstab to ensure we have something writable mounted
# at /cfg, /etc, /home, /root, and /var.
#
# /mnt/cfg is used to store device modifications made to /etc, /home,
# /root.
#
# /mnt/var is used as the backins store for /var. If /mnt/var is not
# available, /mnt/cfg will still be be used to persist /var/lib.
#
# If a disk partiion with the corresponding label ("cfg"/"var") is
# available, that is used to persist changes to the aforementioned
# directories. Otherwise fall back to a tmpfs based RAM disk. This
# effectively brings up the system with the default configuration, but
# obviously any subsequent configuration is ephemeral.
set -e
nm=$(basename $0)
err=0
opt="-k"
mount_rw()
{
# If something is already setup, leave it be.
mountpoint -q /$1 && return 0
# TODO: Also look for UBI partitions
mount LABEL=$1 && return 0
return 1
}
mount_overlay()
{
local tag=$1
local src=$2
local dst=$3
local u=$src/infix/$tag.u
local w=$src/infix/$tag.w
mkdir -p -m 0755 $u
mkdir -p -m 0755 $w
mount -t overlay $tag-overlay $dst \
-o lowerdir=$dst,upperdir=$u,workdir=$w
}
use_etc()
{
# Finit's condition system is not yet bootstrapped when /etc/fstab
# is parsed, so we have to manually check for the boot/etc
# condition.
cat /proc/1/cmdline | awk '
$0 == "finit.cond" {
cond=1;
next;
}
cond == 1 {
exit(index($0, "etc") == 0);
}
'
}
# Fall back to console logging if sysklogd is too old
if ! logger -? |grep -q "Log to kernel"; then
opt="-c"
fi
varsrc=/mnt/var
if ! mount_rw var >/dev/null 2>&1; then
logger $opt -p user.warn -t "$nm" \
"No persistent storage found for /var, only /var/lib is persisted."
varsrc=/mnt/tmp
vlibsrc=/mnt/cfg
fi
cfgsrc=/mnt/cfg
etcsrc=/mnt/tmp
if ! mount_rw cfg; then
err=1
logger $opt -p user.crit -t "$nm" \
"No persistent storage found for /cfg, falling back to tmpfs."
cfgsrc=/mnt/tmp
# Even if /mnt/var isn't available, if /mnt/cfg isn't either, then
# there's no point in overlaying one ramdisk on top of another.
vlibsrc=
else
if use_etc; then
etcsrc=/mnt/cfg
fi
# Check for factory reset
if [ -f /mnt/cfg/infix/.reset ]; then
logger $opt -p user.crit -t "$nm" "Resetting to factory defaults."
rm -rf /mnt/cfg/infix /mnt/var/infix
sync
fi
# Ensure that all users in wheel can create the .reset file
mkdir -p /mnt/cfg/infix
chgrp wheel /mnt/cfg/infix
fi
mount_overlay cfg $cfgsrc /cfg
mount_overlay etc $etcsrc /etc
mount_overlay home $cfgsrc /home
mount_overlay root $cfgsrc /root
mount_overlay var $varsrc /var
[ "$vlibsrc" ] && mount_overlay vlib $vlibsrc /var/lib
exit $err
-54
View File
@@ -1,54 +0,0 @@
#!/bin/sh
# Called from /etc/fstab to ensure we have something writable mounted
# at /rw, which is used by Infix to store device modifications made
# to /etc, /home, /root, and /var/lib.
#
# If a disk partiion labeled "infix-rw" is available, that is used to
# persist changes to the aforementioned directories. Otherwise fall
# back to a tmpfs based RAM disk. This effectively brings up the
# system with the default configuration, but obviously any subsequent
# configuration is ephemeral.
set -e
nm=$(basename $0)
err=0
opt="-k"
mount_rw()
{
# If something is already setup, leave it be.
mountpoint -q /rw && return 0
# TODO: Also look for UBI partitions
mount $tab LABEL=infix-rw && return 0
return 1
}
if ! mount_rw; then
err=1
logger $opt -p user.crit -t "$nm" \
"No persistent storage found for /rw, falling back to tmpfs."
mount tmpfs-rw
fi
# fall back to console logging if sysklogd is too old
if ! logger -? |grep -q "Log to kernel"; then
opt="-c"
fi
# Allow users in wheel group to write to /rw
chgrp wheel /rw && chmod g+w /rw
# Check for factory reset
if [ -f /rw/infix/.reset ]; then
logger $opt -p user.crit -t "$nm" "Resetting to factory defaults."
rm -rf /rw/infix/* /rw/infix/.reset
sync
fi
exit $err
View File
View File
View File
+1 -1
View File
@@ -15,7 +15,7 @@ config QEMU_ROOTFS
config QEMU_RW
string "Writable layer"
default "images/rw.ext4"
default "images/cfg.ext4"
config QEMU_CONSOLE
string
+1 -1
View File
@@ -56,7 +56,7 @@ rw_args()
if ! [ -f "$QEMU_RW" ]; then
dd if=/dev/zero of="$QEMU_RW" bs=16M count=1 >/dev/null 2>&1
mkfs.ext4 -L infix-rw "$QEMU_RW" >/dev/null 2>&1
mkfs.ext4 -L cfg "$QEMU_RW" >/dev/null 2>&1
fi
echo -n "-drive file=$QEMU_RW,if=virtio,format=raw,bus=0,unit=1 "