mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
image-ddi: Mount persistent storage from internal/rw LVM LV
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
tmpfs /tmp tmpfs mode=0755,nosuid,nodev 0 0
|
||||
tmpfs /run tmpfs mode=0755,nosuid,nodev 0 0
|
||||
tmpfs /media tmpfs mode=1755,nosuid,nodev 0 0
|
||||
tmpfs /mnt/tmp tmpfs defaults 0 0
|
||||
|
||||
# Locate and mount /cfg, /home, /root and /var from the internal
|
||||
# volume, wherever that is located - or, as a last resort, setup tmpfs
|
||||
# mounts at these points. Setup an ephemeral writable overlay on /etc.
|
||||
/usr/libexec/infix/mnt# /mnt/rw helper none 0 0
|
||||
|
||||
# Optional, nice-to-have mounts
|
||||
debugfs /sys/kernel/debug debugfs nofail 0 0
|
||||
tracefs /sys/kernel/tracing tracefs nofail 0 0
|
||||
cfgfs /config configfs nofail,noauto 0 0
|
||||
host /mnt/host 9p nofail,noauto,cache=none,msize=16384 0 0
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
#!/bin/sh
|
||||
# Called from /etc/fstab to ensure we have something writable mounted
|
||||
# at /cfg, /home, /root, and /var.
|
||||
#
|
||||
# In the normal case, the "rw" LV from the "internal" LVM VG is used
|
||||
# to back all persistant storage. In the event that "internal" is
|
||||
# present, but the "rw" LV is missing, one will be provisioned, along
|
||||
# with the required BTRFS subvolumes.
|
||||
#
|
||||
# In all other scenarios where the subvolumes are not available, the
|
||||
# system will fall back to temporary storage for all mount points.
|
||||
#
|
||||
# For /etc, a writable, tmpfs backed, layer is always overlayed on top
|
||||
# of the read-only contents from the OS image.
|
||||
|
||||
set -e
|
||||
|
||||
nm=$(basename "$0")
|
||||
need_restore=
|
||||
code=0
|
||||
|
||||
logmsg()
|
||||
{
|
||||
logger -k -t "$nm" -p user.crit "$@"
|
||||
}
|
||||
|
||||
status()
|
||||
{
|
||||
GREEN="$(printf '\033[1;32m')"
|
||||
RED="$(printf '\033[1;31m')"
|
||||
YELLOW="$(printf '\033[1;33m')"
|
||||
BOLD="$(printf '\033[1m')"
|
||||
RESET="$(printf '\033[0m')"
|
||||
|
||||
case $1 in
|
||||
0) color=$GREEN; text=' OK ' ;;
|
||||
1) color=$RED; text='FAIL' ;;
|
||||
2) color=$YELLOW;text='WARN' ;;
|
||||
*) color=$YELLOW;text=' ⋯ ' ;;
|
||||
esac
|
||||
|
||||
printf '%s[%s%s%s%s]%s ' "$BOLD" "$color" "$text" "$RESET" "$BOLD" "$RESET"
|
||||
}
|
||||
|
||||
print_start()
|
||||
{
|
||||
printf '\r\033[K%s%s' "$(status 3)" "$*" > /dev/console
|
||||
need_restore=YES
|
||||
}
|
||||
|
||||
print_end()
|
||||
{
|
||||
rc=$1; shift
|
||||
if [ $# -gt 0 ]; then
|
||||
printf '\r\033[K%s%s\n' "$(status "$rc")" "$*" > /dev/console
|
||||
else
|
||||
printf '\r%s\n' "$(status "$rc")" > /dev/console
|
||||
fi
|
||||
}
|
||||
|
||||
# Restore Finit's original progress message so its [ OK ] appears correctly
|
||||
print_restore()
|
||||
{
|
||||
[ "$need_restore" ] || return 0
|
||||
print_start "Mounting filesystems from /etc/fstab"
|
||||
}
|
||||
|
||||
# # External button or bootloader changed kernel command line
|
||||
# check_factory()
|
||||
# {
|
||||
# if [ -f /mnt/cfg/infix/.reset ]; then
|
||||
# return 0;
|
||||
# fi
|
||||
|
||||
# if grep -q 'finit.cond=factory-reset' /proc/cmdline; then
|
||||
# return 0;
|
||||
# fi
|
||||
|
||||
# # Add to your br2-external to extend factory-reset check
|
||||
# if [ ! -x /usr/libexec/infix/check-factory ]; then
|
||||
# return 1;
|
||||
# fi
|
||||
|
||||
# /usr/libexec/infix/check-factory
|
||||
# }
|
||||
|
||||
# factory_reset()
|
||||
# {
|
||||
# find /sys/class/leds/ -type l -exec sh -c 'echo 100 > $0/brightness' {} \;
|
||||
# print_start "Resetting to factory defaults."
|
||||
# logger $opt -p user.notice -t "$nm" "Resetting to factory defaults."
|
||||
|
||||
# rm -rf /mnt/cfg/* /mnt/var/*
|
||||
# sync
|
||||
|
||||
# logger $opt -p user.notice -t "$nm" "Factory reset complete."
|
||||
# print_end 0 "Factory reset complete."
|
||||
# print_restore
|
||||
# }
|
||||
|
||||
subvols="cfg var root home"
|
||||
|
||||
internal_rw_provision()
|
||||
{
|
||||
print_start "Provisioning persistent storage on internal volume"
|
||||
|
||||
lvm lvcreate --name rw --extents 50%FREE internal || {
|
||||
logmsg "No rw LV available, nor could it be created"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
mkfs.btrfs -L rw /dev/internal/rw || {
|
||||
logmsg "Could not create BTRFS on rw LV"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
mount -t btrfs /dev/internal/rw /mnt/rw || {
|
||||
logmsg "Failed to mount rw"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
for subvol in $subvols; do
|
||||
btrfs subvolume create /mnt/rw/@"$subvol" || {
|
||||
logmsg "Failed to create @$subvol on rw"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
done
|
||||
|
||||
umount /mnt/rw || {
|
||||
logmsg "Failed to unmount rw"
|
||||
print_end 1
|
||||
return 1
|
||||
}
|
||||
|
||||
print_end 0
|
||||
}
|
||||
|
||||
internal_rw_activate()
|
||||
{
|
||||
lvm vgs internal || {
|
||||
logmsg "No internal volume available"
|
||||
return 1
|
||||
}
|
||||
|
||||
lvm vgchange -ay internal || {
|
||||
logmsg "Unable to bring internal volume online"
|
||||
return 1
|
||||
}
|
||||
|
||||
# The only condition under which we do BTRFS provisioning is when
|
||||
# the LV is absent. In all other failure scenarios: fall back to
|
||||
# tmpfs and let the user sort it out. This way we do not risk any
|
||||
# loss of data.
|
||||
[ -b /dev/internal/rw ] && return 0
|
||||
|
||||
internal_rw_provision
|
||||
}
|
||||
|
||||
internal_rw_mount()
|
||||
{
|
||||
internal_rw_activate || return 1
|
||||
|
||||
for subvol in $subvols; do
|
||||
mount -t btrfs /dev/internal/rw /"$subvol" -o subvol=@"$subvol" || {
|
||||
logmsg "Failed to mount /$subvol"
|
||||
return 1
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
tmpfs_rw_mount()
|
||||
{
|
||||
for subvol in $subvols; do
|
||||
mkdir -p -m 0755 /mnt/tmp/"$subvol"
|
||||
mount /mnt/tmp/"$subvol" /"$subvol" -o bind || {
|
||||
logmsg "Failed to mount temporary /$subvol"
|
||||
return 1
|
||||
}
|
||||
done
|
||||
}
|
||||
|
||||
tmpfs_etc_mount()
|
||||
{
|
||||
mkdir -p -m 0755 /mnt/tmp/etc/
|
||||
tar c -C /etc . | tar x -C /mnt/tmp/etc
|
||||
mount /mnt/tmp/etc /etc -o bind
|
||||
}
|
||||
|
||||
exec >/mnt/tmp/mnt.log 2>&1
|
||||
|
||||
tmpfs_etc_mount || {
|
||||
code=1
|
||||
logmsg "Failed to make /etc writable"
|
||||
}
|
||||
|
||||
if ! internal_rw_mount; then
|
||||
code=1
|
||||
print_end 1 "Mounting persistent storage from internal volume"
|
||||
logmsg "Internal volume not found, falling back to tmpfs"
|
||||
|
||||
print_start "Falling back to ephemeral tmpfs storage!"
|
||||
tmpfs_rw_mount
|
||||
print_end $?
|
||||
fi
|
||||
|
||||
print_restore
|
||||
exit $code
|
||||
Reference in New Issue
Block a user