Skip to content

Commit 42cbabc

Browse files
author
Daniel Ruthardt
committed
✨ Add support for multiple overlay devices
Signed-off-by: Daniel Ruthardt <druthardt@linuxfoundation.org>
1 parent 91169ed commit 42cbabc

File tree

2 files changed

+81
-40
lines changed

2 files changed

+81
-40
lines changed

overlayroot/etc/overlayroot.conf

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
# overlayroot=tmpfs
1818
# overlayroot=tmpfs:swap=1
1919
#
20-
# * overlayroot=DEVICE or overlayroot=device:PARAMETERS
21-
# mount DEVICE as overlayfs and write changes there
22-
# device must already have kernel mountalbe filesystem on it.
20+
# * overlayroot=DEVICE[:DEVICE] or overlayroot=device:PARAMETERS
21+
# mount DEVICE(s) as overlayfs and write changes to the first
22+
# device(s) must already have kernel mountalbe filesystem on them.
2323
#
2424
# available parameters are:
2525
# * dev: default: "" [REQUIRED]
26-
# use given device for backing filesystem.
26+
# use given device(s) for backing filesystems.
2727
# Note, 'overlayroot=/dev/vdb' is translated to
2828
# 'overlayrooot=device:dev=/dev/vdb'
2929
# * timeout: default: 0
@@ -34,7 +34,9 @@
3434
# examples:
3535
# overlayroot=/dev/xvdb
3636
# overlayroot=/dev/vdb
37+
# overlayroot=/dev/vdc:/dev/vdb
3738
# overlayroot=device:dev=/dev/sdb,timeout=180
39+
# overlayroot=device:dev=/dev/sdc:/dev/sdb,timeout=180
3840
# overlayroot=device:dev=LABEL=my-flashdrive,timeout=180
3941
#
4042
# * overlayroot=crypt:PARAMETERS

overlayroot/scripts/init-bottom/overlayroot

Lines changed: 75 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Copyright, 2012 Dustin Kirkland <kirkland@ubuntu.com>
33
# Copyright, 2012 Scott Moser <smoser@ubuntu.com>
44
# Copyright, 2012 Axel Heider
5+
# Copyright, 2024 Daniel Ruthardt <druthrdt@linuxfoundation.org>
56
#
67
# Based on scripts from
78
# Sebastian P.
@@ -335,7 +336,7 @@ overlayrootify_fstab() {
335336
local hash="#" oline="" ospec="" upper="" dirs="" copy_opts="" copy_opt=""
336337
local spec file vfstype opts pass freq line ro_line
337338
local workdir="" use_orig="" relfile="" needs_workdir=false noauto=""
338-
339+
339340
[ -f "$input" ] || return 1
340341

341342
cat <<EOF
@@ -671,17 +672,29 @@ case "${overlayroot:-disabled}" in
671672
/dev/*) opts="dev=${overlayroot}";;
672673
*) opts="${overlayroot#device:}";;
673674
esac
674-
dev_setup "${opts}" ||
675-
fail "failed setup overlay for ${overlayroot} [$opts]${cfgmsg}"
675+
676+
devices="$(echo -n "$opts" | grep -Eo 'dev=([^,]*)' | cut -d= -f2 | tr ":" "\n" | tac)"
677+
678+
for device in $devices; do
679+
dopts=$(echo "$opts" | sed "s,dev=[^,]*,dev=${device},")
680+
681+
dev_setup "$dopts" ||
682+
fail "failed setup overlay for ${overlayroot} [${dopts}]${cfgmsg}"
683+
done
676684
mode="device"
677-
device="$_RET_DEVICE"
685+
686+
mountpoints=""
687+
i=1; for device in $(echo "$devices" | sed '$d'); do
688+
mountpoints="${mountpoints:+${mountpoints}
689+
}/media/root-ro-${i}"
690+
i=$((i+1)); done
678691
;;
679692
crypt:*)
680693
mode="crypt"
681694
opts=${overlayroot#crypt:}
682695
crypto_setup "${opts}" ||
683696
fail "failed setup crypt for ${overlayroot}${cfgmsg}"
684-
device="$_RET_DEVICE"
697+
devices="$_RET_DEVICE"
685698
;;
686699
disabled)
687700
debug "overlayroot disabled${cfgmsg}"
@@ -713,46 +726,24 @@ else
713726
fi
714727

715728
debug "swap=$swap recurse=$recurse debug=$OVERLAYROOT_DEBUG dir=$dir_prefix"
716-
debug "device=$device mode=$mode driver=${overlayroot_driver}"
729+
debug "devices=$(echo -n "$devices" | tr "\n" ",") mode=$mode driver=${overlayroot_driver}"
717730

718731
[ "$swap" = "0" -o "$swap" = "1" ] ||
719732
fail "invalid setting for swap: $swap. must be '0' or '1'"
720733
[ "$recurse" = "0" -o "$recurse" = "1" ] ||
721734
fail "invalid setting for recurse: $recurse. must be '0' or '1'"
722735

723-
log_warn "configuring overlayroot with driver=${overlayroot_driver} mode=$mode opts='$opts' per $used_desc"
724-
725-
# settings based on overlayroot_driver
726-
workdir=""
727-
case "${overlayroot_driver}" in
728-
overlayfs|overlay)
729-
mount_type="${overlayroot_driver}"
730-
mount_opts="-o lowerdir=${root_ro},upperdir=${root_rw}/${dir_prefix}"
731-
if needs_workdir; then
732-
get_workdir "$root_rw" "$dir_prefix" "/"
733-
workdir="$_RET"
734-
mount_opts="${mount_opts},workdir=$workdir"
735-
fi
736-
clean_path "${mount_opts} overlayroot ${ROOTMNT}"
737-
mount_opts="$_RET"
738-
;;
739-
aufs)
740-
mount_type="aufs"
741-
mount_opts="-o dirs=${root_rw}/${dir_prefix}:${root_ro}=ro aufs-root ${ROOTMNT}"
742-
;;
743-
*)
744-
log_fail "invalid overlayroot driver: ${overlayroot_driver}"
745-
panic "$MYTAG"
746-
;;
747-
esac
748-
749736
# make the mount point on the init root fs ${root_rw}
750737
mkdir -p "${root_rw}" ||
751738
fail "failed to create ${root_rw}"
752739

753740
# make the mount point on the init root fs ${root_ro}
754741
mkdir -p "${root_ro}" ||
755742
fail "failed to create ${root_ro}"
743+
for mountpoint in $mountpoints; do
744+
mkdir -p "$mountpoint" ||
745+
fail "failed to create ${mountpoint}"
746+
done
756747

757748
# mount the backing device to $root_rw
758749
if [ "$mode" = "tmpfs" ]; then
@@ -761,15 +752,20 @@ if [ "$mode" = "tmpfs" ]; then
761752
fail "failed to create tmpfs"
762753
else
763754
# dev or crypto
764-
mount "$device" "${root_rw}" ||
765-
fail "failed mount backing device $device"
755+
device=$(echo "$devices" | tail -n1)
756+
mount "$device" "$root_rw" ||
757+
fail "failed mount backing device ${device}"
766758
fi
767759

768760
mkdir -p "${root_rw}/${dir_prefix}" ||
769761
fail "failed to create ${dir_prefix} on ${device}"
770762

771-
[ -z "$workdir" ] || mkdir -p "$workdir" ||
772-
fail "failed to create workdir '$workdir' on ${device}"
763+
i=1; for device in $(echo "$devices" | head -n -1); do
764+
mountpoint=$(echo "$mountpoints" | head -n$i | tail -n1)
765+
# mount the backing device
766+
mount "$device" "$mountpoint" ||
767+
fail "failed mount backing device ${device}"
768+
i=$((i+1)); done
773769

774770
# root is mounted on ${ROOTMNT}, move it to ${ROOT_RO}.
775771
mount --move "${ROOTMNT}" "${root_ro}" ||
@@ -780,6 +776,44 @@ mount --move "${ROOTMNT}" "${root_ro}" ||
780776
# "panic". Otherwise the boot process is very likely to fail with even more
781777
# errors and leave the system in a wired state.
782778

779+
log_warn "configuring overlayroot with driver=${overlayroot_driver} mode=$mode opts='$opts' per $used_desc"
780+
781+
# settings based on overlayroot_driver
782+
workdir=""
783+
case "${overlayroot_driver}" in
784+
overlayfs|overlay)
785+
mount_type="${overlayroot_driver}"
786+
lowerdirs="$root_ro"
787+
for mountpoint in $mountpoints; do
788+
if [ -d "${mountpoint}${dir_prefix}" ]; then
789+
lowerdir="${mountpoint}${dir_prefix}"
790+
else
791+
lowerdir="$mountpoint"
792+
fi
793+
lowerdirs="${lowerdir}:${lowerdirs}"
794+
done
795+
mount_opts="-o lowerdir=${lowerdirs},upperdir=${root_rw}/${dir_prefix}"
796+
if needs_workdir; then
797+
get_workdir "$root_rw" "$dir_prefix" "/"
798+
workdir="$_RET"
799+
mount_opts="${mount_opts},workdir=$workdir"
800+
801+
[ -z "$workdir" ] || mkdir -p "$workdir" ||
802+
fail "failed to create workdir '${workdir}' on ${device}"
803+
fi
804+
clean_path "${mount_opts} overlayroot ${ROOTMNT}"
805+
mount_opts="$_RET"
806+
;;
807+
aufs)
808+
mount_type="aufs"
809+
mount_opts="-o dirs=${root_rw}/${dir_prefix}:${root_ro}=ro aufs-root ${ROOTMNT}"
810+
;;
811+
*)
812+
log_fail "invalid overlayroot driver: ${overlayroot_driver}"
813+
panic "$MYTAG"
814+
;;
815+
esac
816+
783817
# mount virtual fs ${ROOTMNT} with rw-fs ${root_rw} on top of ro-fs ${root_ro}.
784818
debug mount -t "$mount_type" $mount_opts
785819
mount -t "$mount_type" $mount_opts
@@ -810,6 +844,11 @@ fi
810844
mkdir -p "${ROOTMNT}/${root_ro}"
811845
mount --move ${root_ro} "${ROOTMNT}${root_ro}" ||
812846
fail "failed to move ${root_ro} to ${ROOTMNT}${root_ro}"
847+
for mountpoint in $mountpoints; do
848+
mkdir -p "${ROOTMNT}${mountpoint}"
849+
mount --move "$mountpoint" "${ROOTMNT}${mountpoint}" ||
850+
fail "failed to move ${mountpoint} to ${ROOTMNT}${mountpoint}"
851+
done
813852

814853
# move mount from ${root_rw} to ${ROOTMNT}${root_rw}
815854
[ -d ${ROOTMNT}${root_rw} ] || mkdir -p ${ROOTMNT}${root_rw}

0 commit comments

Comments
 (0)