diff --git a/board/aarch64/espressobin/genimage.cfg b/board/aarch64/espressobin/genimage.cfg index ef3490c3..7da1c2cd 100644 --- a/board/aarch64/espressobin/genimage.cfg +++ b/board/aarch64/espressobin/genimage.cfg @@ -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" } } diff --git a/board/amd64/genimage.cfg b/board/amd64/genimage.cfg index 52c471ab..50a1e3e5 100644 --- a/board/amd64/genimage.cfg +++ b/board/amd64/genimage.cfg @@ -1,6 +1,6 @@ -image rw.ext4 { +image cfg.ext4 { ext4 { - label = "infix-rw" + label = "cfg" } empty = true size = 16M diff --git a/board/common/mkgns3a.sh b/board/common/mkgns3a.sh index 5cdf230b..14334d42 100755 --- a/board/common/mkgns3a.sh +++ b/board/common/mkgns3a.sh @@ -33,9 +33,9 @@ cat <"$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 <"$BINARIES_DIR/infix.gns3a" "name": "0.0", "images": { "cdrom_image": "rootfs.iso9660", - "hda_disk_image": "rw.ext4" + "hda_disk_image": "cfg.ext4" } } ] diff --git a/board/common/rootfs/rw/.empty b/board/common/rootfs/cfg/.empty similarity index 100% rename from board/common/rootfs/rw/.empty rename to board/common/rootfs/cfg/.empty diff --git a/board/common/rootfs/etc/fstab b/board/common/rootfs/etc/fstab index 7c7239e7..d1d24a5a 100644 --- a/board/common/rootfs/etc/fstab +++ b/board/common/rootfs/etc/fstab @@ -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 diff --git a/board/common/rootfs/etc/profile.d/factory.sh b/board/common/rootfs/etc/profile.d/factory.sh index e4f586a5..90bf3a2d 100755 --- a/board/common/rootfs/etc/profile.d/factory.sh +++ b/board/common/rootfs/etc/profile.d/factory.sh @@ -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' diff --git a/board/common/rootfs/lib/infix/mnt b/board/common/rootfs/lib/infix/mnt new file mode 100755 index 00000000..95cf2f1f --- /dev/null +++ b/board/common/rootfs/lib/infix/mnt @@ -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 diff --git a/board/common/rootfs/lib/infix/mount-rw b/board/common/rootfs/lib/infix/mount-rw deleted file mode 100755 index 9aaba710..00000000 --- a/board/common/rootfs/lib/infix/mount-rw +++ /dev/null @@ -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 diff --git a/board/common/rootfs/mnt/cfg/.empty b/board/common/rootfs/mnt/cfg/.empty new file mode 100644 index 00000000..e69de29b diff --git a/board/common/rootfs/mnt/tmp/.empty b/board/common/rootfs/mnt/tmp/.empty new file mode 100644 index 00000000..e69de29b diff --git a/board/common/rootfs/mnt/var/.empty b/board/common/rootfs/mnt/var/.empty new file mode 100644 index 00000000..e69de29b diff --git a/qemu/Config.in b/qemu/Config.in index e5ba5a8b..d9f348fd 100644 --- a/qemu/Config.in +++ b/qemu/Config.in @@ -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 diff --git a/qemu/qemu.sh b/qemu/qemu.sh index 74be3aa5..db82ed6d 100755 --- a/qemu/qemu.sh +++ b/qemu/qemu.sh @@ -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 "