From cab88e2f4457c80340c8d9266fa82bb96fc1c50f Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Sun, 25 Jun 2023 02:47:45 -0400 Subject: [PATCH 01/27] Allow for nested mount by using mergerfs --- try | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/try b/try index ca9125f8..18f2ffe2 100755 --- a/try +++ b/try @@ -36,6 +36,11 @@ try() { fi done + for top_dir in $(findmnt --real -r -o target -n | grep -v "^/$") + do + mkdir -p "$SANDBOX_DIR"/upperdir/"$top_dir" "$SANDBOX_DIR"/workdir"/$top_dir" "$SANDBOX_DIR"/temproot/"$top_dir" + done + mount_and_execute=$(mktemp) export chroot_executable=$(mktemp) export try_mount_log=$(mktemp) @@ -61,8 +66,11 @@ done # then we want to exclude the root partition "/" for mount_dir in $(findmnt --real -r -o target -n | grep -v "^/$") do - mount -t overlay overlay -o lowerdir="$mount_dir",upperdir="$SANDBOX_DIR"/upperdir"$mount_dir",workdir="$SANDBOX_DIR"/workdir"$mount_dir" "$SANDBOX_DIR"/temproot"$mount_dir" 2>> "$try_mount_log" || echo "Warning: Failed mounting $mount_dir as an overlay, see "$try_mount_log"" 1>&2 + merger_dir=$(mktemp -d) + mergerfs $mount_dir $merger_dir + echo mount -t overlay overlay -o lowerdir="$merger_dir",upperdir="$SANDBOX_DIR"/upperdir"$mount_dir",workdir="$SANDBOX_DIR"/workdir"$mount_dir" "$SANDBOX_DIR"/temproot"$mount_dir" 2>> "$try_mount_log" || echo "Warning: Failed mounting $mount_dir as an overlay, see "$try_mount_log"" 1>&2 done +bash ## Bind the udev mount so that the containerized process has access to /dev ## KK 2023-05-06 Are there any security/safety implications by binding the whole /dev? From 4e2a1131f2d981857b0ccfde60c9cb82f7f7d730 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Sun, 25 Jun 2023 02:52:55 -0400 Subject: [PATCH 02/27] Remove debug bash --- try | 1 - 1 file changed, 1 deletion(-) diff --git a/try b/try index 18f2ffe2..13e87da7 100755 --- a/try +++ b/try @@ -70,7 +70,6 @@ do mergerfs $mount_dir $merger_dir echo mount -t overlay overlay -o lowerdir="$merger_dir",upperdir="$SANDBOX_DIR"/upperdir"$mount_dir",workdir="$SANDBOX_DIR"/workdir"$mount_dir" "$SANDBOX_DIR"/temproot"$mount_dir" 2>> "$try_mount_log" || echo "Warning: Failed mounting $mount_dir as an overlay, see "$try_mount_log"" 1>&2 done -bash ## Bind the udev mount so that the containerized process has access to /dev ## KK 2023-05-06 Are there any security/safety implications by binding the whole /dev? From 73b9b511d2b78c25ad5a77e1998206ed434644cd Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Sun, 25 Jun 2023 03:10:13 -0400 Subject: [PATCH 03/27] Remove debug echo --- try | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/try b/try index 13e87da7..d8ae2b12 100755 --- a/try +++ b/try @@ -68,7 +68,7 @@ for mount_dir in $(findmnt --real -r -o target -n | grep -v "^/$") do merger_dir=$(mktemp -d) mergerfs $mount_dir $merger_dir - echo mount -t overlay overlay -o lowerdir="$merger_dir",upperdir="$SANDBOX_DIR"/upperdir"$mount_dir",workdir="$SANDBOX_DIR"/workdir"$mount_dir" "$SANDBOX_DIR"/temproot"$mount_dir" 2>> "$try_mount_log" || echo "Warning: Failed mounting $mount_dir as an overlay, see "$try_mount_log"" 1>&2 + mount -t overlay overlay -o lowerdir="$merger_dir",upperdir="$SANDBOX_DIR"/upperdir"$mount_dir",workdir="$SANDBOX_DIR"/workdir"$mount_dir" "$SANDBOX_DIR"/temproot"$mount_dir" 2>> "$try_mount_log" || echo "Warning: Failed mounting $mount_dir as an overlay, see "$try_mount_log"" 1>&2 done ## Bind the udev mount so that the containerized process has access to /dev From 092a46003f41bc69e8958a3f3cdf8148eba926af Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Sun, 25 Jun 2023 03:20:44 -0400 Subject: [PATCH 04/27] mount /run with merger aswell --- try | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/try b/try index d8ae2b12..d6b0d083 100755 --- a/try +++ b/try @@ -75,9 +75,13 @@ done ## KK 2023-05-06 Are there any security/safety implications by binding the whole /dev? ## Maybe we just want to bind a few files in it like /dev/null, /dev/zero? mount --rbind /dev "$SANDBOX_DIR/temproot/dev" + ## KK 2023-06-20 Redirecting to /dev/null to suppress a yet uninvestigated but ## seemingly not impactful warning. -mount --rbind --read-only /run "$SANDBOX_DIR/temproot/run" 2> /dev/null + +run_merger_dir=$(mktemp -d) +mergerfs /run $run_merger_dir +mount -t overlay overlay -o lowerdir="$run_merger_dir",upperdir="$SANDBOX_DIR"/upperdir/run,workdir="$SANDBOX_DIR"/workdir/run "$SANDBOX_DIR"/temproot/run 2>> "$try_mount_log" || echo "Warning: Failed mounting /run as an overlay, see "$try_mount_log"" 1>&2 ## Check if chroot_executable exists, #29 if ! [ -f "$SANDBOX_DIR/temproot/$chroot_executable" ]; then From b95f2e4ba138176277274869889523882499957e Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Sun, 25 Jun 2023 20:41:41 -0400 Subject: [PATCH 05/27] refactor and use overlayfs via mergerfs if regular overlayfs fails --- try | 57 +++++++++++++++++++++++---------------------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/try b/try index d6b0d083..d852316c 100755 --- a/try +++ b/try @@ -28,19 +28,21 @@ try() { # we will overlay-mount each root directory separately (instead of all at once) because some directories cannot be overlayed # so we set up the mount points now - for top_dir in /* + # + # findmnt + # --real: only list real filesystems + # -n: no header + # -r: raw output + # -o target: only print the mount target + # then we want to exclude the root partition "/" + for top_dir in /* $(findmnt --real -r -o target -n | grep -v "^/$") do ## Only make the directory if the original is a directory too if [ -d "$top_dir" ]; then - mkdir "$SANDBOX_DIR"/upperdir/"$top_dir" "$SANDBOX_DIR"/workdir"/$top_dir" "$SANDBOX_DIR"/temproot/"$top_dir" + mkdir -p "$SANDBOX_DIR"/upperdir/"$top_dir" "$SANDBOX_DIR"/workdir"/$top_dir" "$SANDBOX_DIR"/temproot/"$top_dir" fi done - for top_dir in $(findmnt --real -r -o target -n | grep -v "^/$") - do - mkdir -p "$SANDBOX_DIR"/upperdir/"$top_dir" "$SANDBOX_DIR"/workdir"/$top_dir" "$SANDBOX_DIR"/temproot/"$top_dir" - done - mount_and_execute=$(mktemp) export chroot_executable=$(mktemp) export try_mount_log=$(mktemp) @@ -48,53 +50,40 @@ try() { #!/bin/sh # actually mount the overlays -for top_dir in /* +for top_dir in /* $(findmnt --real -r -o target -n | grep -v "^/$") do ## If the directory is not a mountpoint - if [ -d "$top_dir" ] && ! mountpoint -q "$top_dir"; then - ## TODO: The - mount -t overlay overlay -o lowerdir=/"$top_dir",upperdir="$SANDBOX_DIR"/upperdir/"$top_dir",workdir="$SANDBOX_DIR"/workdir/"$top_dir" "$SANDBOX_DIR"/temproot/"$top_dir" 2>> "$try_mount_log" || echo "Warning: Failed mounting $top_dir as an overlay, see "$try_mount_log"" 1>&2 + if [ -d "$top_dir" ]; then + # skip if it is /dev or /proc + if [ "$top_dir" = "/dev" ] || [ "$top_dir" = "/proc" ]; then + continue + fi + mount -t overlay overlay -o lowerdir=/"$top_dir",upperdir="$SANDBOX_DIR"/upperdir/"$top_dir",workdir="$SANDBOX_DIR"/workdir/"$top_dir" "$SANDBOX_DIR"/temproot/"$top_dir" 2>> "$try_mount_log" + if [ $? -ne 0 ]; then + merger_dir=$(mktemp -d) + mergerfs $top_dir $merger_dir 2>> "$try_mount_log" || echo "Warning: Failed to mount $top_dir via mergerfs" 1>&2 && + mount -t overlay overlay -o lowerdir="$merger_dir",upperdir="$SANDBOX_DIR"/upperdir"$top_dir",workdir="$SANDBOX_DIR"/workdir"$top_dir" "$SANDBOX_DIR"/temproot"$top_dir" 2>> "$try_mount_log" || + echo "Warning: Failed mounting $top_dir as an overlay via mergerfs, see "$try_mount_log"" 1>&2 + fi fi done -# Now we will handle custom mounts, e.g., mounts on /home -# findmnt -# --real: only list real filesystems -# -n: no header -# -r: raw output -# -o target: only print the mount target -# then we want to exclude the root partition "/" -for mount_dir in $(findmnt --real -r -o target -n | grep -v "^/$") -do - merger_dir=$(mktemp -d) - mergerfs $mount_dir $merger_dir - mount -t overlay overlay -o lowerdir="$merger_dir",upperdir="$SANDBOX_DIR"/upperdir"$mount_dir",workdir="$SANDBOX_DIR"/workdir"$mount_dir" "$SANDBOX_DIR"/temproot"$mount_dir" 2>> "$try_mount_log" || echo "Warning: Failed mounting $mount_dir as an overlay, see "$try_mount_log"" 1>&2 -done - ## Bind the udev mount so that the containerized process has access to /dev ## KK 2023-05-06 Are there any security/safety implications by binding the whole /dev? ## Maybe we just want to bind a few files in it like /dev/null, /dev/zero? mount --rbind /dev "$SANDBOX_DIR/temproot/dev" -## KK 2023-06-20 Redirecting to /dev/null to suppress a yet uninvestigated but -## seemingly not impactful warning. - -run_merger_dir=$(mktemp -d) -mergerfs /run $run_merger_dir -mount -t overlay overlay -o lowerdir="$run_merger_dir",upperdir="$SANDBOX_DIR"/upperdir/run,workdir="$SANDBOX_DIR"/workdir/run "$SANDBOX_DIR"/temproot/run 2>> "$try_mount_log" || echo "Warning: Failed mounting /run as an overlay, see "$try_mount_log"" 1>&2 - ## Check if chroot_executable exists, #29 if ! [ -f "$SANDBOX_DIR/temproot/$chroot_executable" ]; then cp $chroot_executable "$SANDBOX_DIR/temproot/$chroot_executable" fi - unshare --root="$SANDBOX_DIR/temproot" /bin/bash "$chroot_executable" EOF cat >"$chroot_executable" < Date: Sun, 25 Jun 2023 20:42:28 -0400 Subject: [PATCH 06/27] Only mount /dev/{tty null zero full random urandom} --- try | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/try b/try index d852316c..f5a060ce 100755 --- a/try +++ b/try @@ -68,10 +68,11 @@ do fi done -## Bind the udev mount so that the containerized process has access to /dev -## KK 2023-05-06 Are there any security/safety implications by binding the whole /dev? -## Maybe we just want to bind a few files in it like /dev/null, /dev/zero? -mount --rbind /dev "$SANDBOX_DIR/temproot/dev" +for dev in tty null zero full random urandom +do + touch "$SANDBOX_DIR/temproot/dev/$dev" + mount -o bind /dev/$dev "$SANDBOX_DIR/temproot/dev/$dev" +done ## Check if chroot_executable exists, #29 if ! [ -f "$SANDBOX_DIR/temproot/$chroot_executable" ]; then From 83f8e5da85ee0e1576ba90e3d8d6729ff6c7e18a Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Sun, 25 Jun 2023 20:49:15 -0400 Subject: [PATCH 07/27] improve docs, refactor from top_dir to mountpoint --- try | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/try b/try index f5a060ce..52dea76d 100755 --- a/try +++ b/try @@ -35,11 +35,11 @@ try() { # -r: raw output # -o target: only print the mount target # then we want to exclude the root partition "/" - for top_dir in /* $(findmnt --real -r -o target -n | grep -v "^/$") + for mointpoint in /* $(findmnt --real -r -o target -n | grep -v "^/$") do ## Only make the directory if the original is a directory too - if [ -d "$top_dir" ]; then - mkdir -p "$SANDBOX_DIR"/upperdir/"$top_dir" "$SANDBOX_DIR"/workdir"/$top_dir" "$SANDBOX_DIR"/temproot/"$top_dir" + if [ -d "$mointpoint" ]; then + mkdir -p "$SANDBOX_DIR"/upperdir/"$mointpoint" "$SANDBOX_DIR"/workdir"/$mointpoint" "$SANDBOX_DIR"/temproot/"$mointpoint" fi done @@ -50,20 +50,21 @@ try() { #!/bin/sh # actually mount the overlays -for top_dir in /* $(findmnt --real -r -o target -n | grep -v "^/$") +for mointpoint in /* $(findmnt --real -r -o target -n | grep -v "^/$") do ## If the directory is not a mountpoint - if [ -d "$top_dir" ]; then - # skip if it is /dev or /proc - if [ "$top_dir" = "/dev" ] || [ "$top_dir" = "/proc" ]; then + if [ -d "$mointpoint" ]; then + # skip if it is /dev or /proc, we will mount it later + if [ "$mointpoint" = "/dev" ] || [ "$mointpoint" = "/proc" ]; then continue fi - mount -t overlay overlay -o lowerdir=/"$top_dir",upperdir="$SANDBOX_DIR"/upperdir/"$top_dir",workdir="$SANDBOX_DIR"/workdir/"$top_dir" "$SANDBOX_DIR"/temproot/"$top_dir" 2>> "$try_mount_log" + mount -t overlay overlay -o lowerdir=/"$mointpoint",upperdir="$SANDBOX_DIR"/upperdir/"$mointpoint",workdir="$SANDBOX_DIR"/workdir/"$mointpoint" "$SANDBOX_DIR"/temproot/"$mointpoint" 2>> "$try_mount_log" if [ $? -ne 0 ]; then + # Here we use mergerfs/unionfs to be mounted into a single file system. Used to fix nested mounts #19 merger_dir=$(mktemp -d) - mergerfs $top_dir $merger_dir 2>> "$try_mount_log" || echo "Warning: Failed to mount $top_dir via mergerfs" 1>&2 && - mount -t overlay overlay -o lowerdir="$merger_dir",upperdir="$SANDBOX_DIR"/upperdir"$top_dir",workdir="$SANDBOX_DIR"/workdir"$top_dir" "$SANDBOX_DIR"/temproot"$top_dir" 2>> "$try_mount_log" || - echo "Warning: Failed mounting $top_dir as an overlay via mergerfs, see "$try_mount_log"" 1>&2 + mergerfs $mointpoint $merger_dir 2>> "$try_mount_log" || echo "Warning: Failed to mount $mointpoint via mergerfs" 1>&2 && + mount -t overlay overlay -o lowerdir="$merger_dir",upperdir="$SANDBOX_DIR"/upperdir"$mointpoint",workdir="$SANDBOX_DIR"/workdir"$mointpoint" "$SANDBOX_DIR"/temproot"$mointpoint" 2>> "$try_mount_log" || + echo "Warning: Failed mounting $mointpoint as an overlay via mergerfs, see "$try_mount_log"" 1>&2 fi fi done From 6b469672f8600e70be5eeb609aba7505e36f07ee Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Tue, 27 Jun 2023 12:32:46 -0400 Subject: [PATCH 08/27] Fix mergerfs failing not showing mount log path --- try | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/try b/try index 52dea76d..cb917c2d 100755 --- a/try +++ b/try @@ -62,7 +62,7 @@ do if [ $? -ne 0 ]; then # Here we use mergerfs/unionfs to be mounted into a single file system. Used to fix nested mounts #19 merger_dir=$(mktemp -d) - mergerfs $mointpoint $merger_dir 2>> "$try_mount_log" || echo "Warning: Failed to mount $mointpoint via mergerfs" 1>&2 && + mergerfs $mointpoint $merger_dir 2>> "$try_mount_log" || echo "Warning: Failed to mount $mointpoint via mergerfs, see $try_mount_log" 1>&2 && mount -t overlay overlay -o lowerdir="$merger_dir",upperdir="$SANDBOX_DIR"/upperdir"$mointpoint",workdir="$SANDBOX_DIR"/workdir"$mointpoint" "$SANDBOX_DIR"/temproot"$mointpoint" 2>> "$try_mount_log" || echo "Warning: Failed mounting $mointpoint as an overlay via mergerfs, see "$try_mount_log"" 1>&2 fi From 9c929fe62ba952940672fe56059cd41ad0f10b40 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Tue, 27 Jun 2023 13:53:19 -0400 Subject: [PATCH 09/27] Add support for unionfs, allow user to specify unionfs helper path --- try | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/try b/try index cb917c2d..e48271c8 100755 --- a/try +++ b/try @@ -58,13 +58,27 @@ do if [ "$mointpoint" = "/dev" ] || [ "$mointpoint" = "/proc" ]; then continue fi + # Try mounting everything normally mount -t overlay overlay -o lowerdir=/"$mointpoint",upperdir="$SANDBOX_DIR"/upperdir/"$mointpoint",workdir="$SANDBOX_DIR"/workdir/"$mointpoint" "$SANDBOX_DIR"/temproot/"$mointpoint" 2>> "$try_mount_log" + # If mounting everything normally fails, we try using either using mergerfs or unionfs to mount them. if [ $? -ne 0 ]; then + # Detect if union_helper is set, if not, we try to autodetect them + if [ -z ${union_helper+x} ]; then + if command -v mergerfs > /dev/null; then + union_helper=mergerfs + elif command -v unionfs > /dev/null; then + union_helper=unionfs + else + echo "Error: Failed to mount overlayfs normally, mergerfs or unionfs not found, see "$try_mount_log"" 1>&2 + exit 1 + fi + fi + # Here we use mergerfs/unionfs to be mounted into a single file system. Used to fix nested mounts #19 merger_dir=$(mktemp -d) - mergerfs $mointpoint $merger_dir 2>> "$try_mount_log" || echo "Warning: Failed to mount $mointpoint via mergerfs, see $try_mount_log" 1>&2 && + "$union_helper" $mointpoint $merger_dir 2>> "$try_mount_log" || echo "Warning: Failed to mount $mointpoint via $union_helper, see $try_mount_log" 1>&2 && mount -t overlay overlay -o lowerdir="$merger_dir",upperdir="$SANDBOX_DIR"/upperdir"$mointpoint",workdir="$SANDBOX_DIR"/workdir"$mointpoint" "$SANDBOX_DIR"/temproot"$mointpoint" 2>> "$try_mount_log" || - echo "Warning: Failed mounting $mointpoint as an overlay via mergerfs, see "$try_mount_log"" 1>&2 + echo "Warning: Failed mounting $mointpoint as an overlay via $union_helper, see "$try_mount_log"" 1>&2 fi fi done @@ -222,11 +236,12 @@ ignore_changes() { usage() { cmd="$(basename $0)" cat >&2 <&2; exit 0;; + (U) if ! [ -x "$OPTARG" ] + then + printf "%s: no such executable $OPTARG\n" "$(basename $0)" >&2 + exit 2 + fi + union_helper="$OPTARG" + ;; (h|*) usage; exit 0;; esac done From 74d0894414675743e779f5e6c7b62d7b8664d7d5 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Tue, 27 Jun 2023 13:56:36 -0400 Subject: [PATCH 10/27] Write mountpoint on unionhelper not found message --- try | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/try b/try index e48271c8..6da6b5d2 100755 --- a/try +++ b/try @@ -69,7 +69,7 @@ do elif command -v unionfs > /dev/null; then union_helper=unionfs else - echo "Error: Failed to mount overlayfs normally, mergerfs or unionfs not found, see "$try_mount_log"" 1>&2 + echo "Error: Failed to mount overlayfs normally, mergerfs or unionfs not found for $mointpoint, see $try_mount_log" 1>&2 exit 1 fi fi From f2cb09244dd21790455fd46581ec9c0edcd355d5 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Tue, 27 Jun 2023 14:24:36 -0400 Subject: [PATCH 11/27] exit if findmnt not installed --- try | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/try b/try index fd5d1e81..80753633 100755 --- a/try +++ b/try @@ -22,6 +22,11 @@ TRY_VERSION="0.1.0" try() { START_DIR="$PWD" + if ! command -v findmnt > /dev/null; then + echo "findmnt not found, please install util-linux" 1>&2 + exit 1 + fi + [ "$SANDBOX_DIR" ] || SANDBOX_DIR=$(mktemp -d) export SANDBOX_DIR mkdir -p "$SANDBOX_DIR/upperdir" "$SANDBOX_DIR/workdir" "$SANDBOX_DIR/temproot" From 4f3b766afa41deacc2fc38cf60ed86ac13f29680 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Tue, 27 Jun 2023 14:24:46 -0400 Subject: [PATCH 12/27] nested mount docs --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 7110ce8a..fe41333e 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,11 @@ disks. ### Dependencies +Try relies on the following dependencies +`util-linux` +In cases where overlayfs doesn't work on nested mounts, you will need either +[mergerfs](https://github.com/trapexit/mergerfs) or [unionfs](https://github.com/rpodgorny/unionfs-fuse). Try should be able to autodetect them, but you can specify the path to mergerfs or unionfs via `try -U ~/.local/bin/unionfs` + Has been tested on the following distributions: * `Ubuntu 20.04 LTS` or later * `Debian 12` From ed98863e57760e1e3eb42008e74a41da2175e583 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Tue, 27 Jun 2023 14:26:34 -0400 Subject: [PATCH 13/27] add newlines to readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fe41333e..23301152 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,9 @@ disks. ### Dependencies Try relies on the following dependencies + `util-linux` + In cases where overlayfs doesn't work on nested mounts, you will need either [mergerfs](https://github.com/trapexit/mergerfs) or [unionfs](https://github.com/rpodgorny/unionfs-fuse). Try should be able to autodetect them, but you can specify the path to mergerfs or unionfs via `try -U ~/.local/bin/unionfs` From a8427e2bf24989dc040ff03e4f2d05f93f2e5cbf Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Tue, 27 Jun 2023 14:27:25 -0400 Subject: [PATCH 14/27] grammar fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 23301152..ea40758d 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Try relies on the following dependencies `util-linux` In cases where overlayfs doesn't work on nested mounts, you will need either -[mergerfs](https://github.com/trapexit/mergerfs) or [unionfs](https://github.com/rpodgorny/unionfs-fuse). Try should be able to autodetect them, but you can specify the path to mergerfs or unionfs via `try -U ~/.local/bin/unionfs` +[mergerfs](https://github.com/trapexit/mergerfs) or [unionfs](https://github.com/rpodgorny/unionfs-fuse). Try should be able to autodetect them, but you can specify the path to mergerfs or unionfs with -U (e.g. `try -U ~/.local/bin/unionfs`) Has been tested on the following distributions: * `Ubuntu 20.04 LTS` or later From 38a34b5fa06663fec2a6784f6134396efd0c3b86 Mon Sep 17 00:00:00 2001 From: gliargovas Date: Wed, 28 Jun 2023 06:57:28 -0400 Subject: [PATCH 15/27] Add -U option description to manpages --- docs/try.1.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/try.1.md b/docs/try.1.md index fd679557..6368870e 100644 --- a/docs/try.1.md +++ b/docs/try.1.md @@ -43,9 +43,13 @@ While using *try* you can choose to commit the result to the filesystem or compl : Specifies DIR as the overlay directory (implies -n). The use of -D also implies that *DIR* already exists. +-U *PATH* + +: Use the unionfs helper implementation defined in the *PATH* (e.g., mergerfs, unionfs-fuse) instead of the default. +This option is recommended in case OverlayFS fails. ## Subcommands -try summary *DIR* +try summary *DIR* : Show the summary for the overlay in DIR From 1a29602c35c35c778d9f2e470b6746f4d14ce953 Mon Sep 17 00:00:00 2001 From: gliargovas Date: Wed, 28 Jun 2023 09:08:09 -0400 Subject: [PATCH 16/27] Add shell completion for -U option --- completions/try.bash | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/completions/try.bash b/completions/try.bash index 30832408..d3576112 100755 --- a/completions/try.bash +++ b/completions/try.bash @@ -20,7 +20,7 @@ _try() { case "${cmd}" in try) - opts="-n -y -v -h -D summary commit" + opts="-n -y -v -h -D -U summary commit" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -31,7 +31,10 @@ _try() { COMPREPLY=($(compgen -d "${cur}")) return 0 ;; - + -U) + COMPREPLY=($(compgen -W "$(findmnt --all -l | awk 'NR>1 {print $3}' | sort -u)" -- "${cur}")) + return 0 + ;; commit) COMPREPLY=($(compgen -d "${cur}")) return 0 From 29d47f3f98c5c1c5809cf159a2ee292dbd6c90c0 Mon Sep 17 00:00:00 2001 From: gliargovas Date: Wed, 28 Jun 2023 10:29:55 -0400 Subject: [PATCH 17/27] Change -U flag autocompletion to only suggest executables --- completions/try.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/completions/try.bash b/completions/try.bash index d3576112..d4186b89 100755 --- a/completions/try.bash +++ b/completions/try.bash @@ -32,7 +32,7 @@ _try() { return 0 ;; -U) - COMPREPLY=($(compgen -W "$(findmnt --all -l | awk 'NR>1 {print $3}' | sort -u)" -- "${cur}")) + COMPREPLY=($(compgen -c "${cur}")) return 0 ;; commit) From c216d0e65ace7c5088a0ed2b78224f7601ccbd67 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Wed, 28 Jun 2023 14:31:14 -0400 Subject: [PATCH 18/27] Install mergerfs in ci --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 2f417a33..2441c655 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -19,7 +19,7 @@ jobs: run: | uname -a sudo apt-get update - sudo apt-get install strace + sudo apt-get install mergerfs - name: Checkout uses: actions/checkout@v2 From 68e59650dbfbc1666842023df6dc086180cc5fdf Mon Sep 17 00:00:00 2001 From: gliargovas Date: Thu, 29 Jun 2023 05:09:05 -0600 Subject: [PATCH 19/27] Try reading from /run directory before testing --- test/run_tests.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/test/run_tests.sh b/test/run_tests.sh index 2cad54e7..be73af08 100755 --- a/test/run_tests.sh +++ b/test/run_tests.sh @@ -34,15 +34,27 @@ cleanup() mkdir "$try_workspace" } +test_read_from_run_dir() +{ + ls /run/systemd > /dev/null + if [ $? -ne 0 ]; then + echo "Cannot read from /run/systemd." + return 1 + fi +} + run_test() { cleanup local test=$1 - + if [ "$(type -t $test)" != "function" ]; then echo "$test is not a function! FAIL" return 1 fi + + # Check if we can read from /run dir + test_read_from_run_dir echo -n "Running $test..." From 7d661e997bf9f38ced1f3c3a0608b5066bd74202 Mon Sep 17 00:00:00 2001 From: Konstantinos Kallas Date: Thu, 29 Jun 2023 10:57:52 -0400 Subject: [PATCH 20/27] refactor --- try | 74 ++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/try b/try index 145f6590..779d49fb 100755 --- a/try +++ b/try @@ -57,11 +57,11 @@ try() { # -r: raw output # -o target: only print the mount target # then we want to exclude the root partition "/" - for mointpoint in /* $(findmnt --real -r -o target -n | grep -v "^/$") + for mountpoint in /* $(findmnt --real -r -o target -n | grep -v "^/$") do ## Only make the directory if the original is a directory too - if [ -d "$mointpoint" ]; then - mkdir -p "$SANDBOX_DIR"/upperdir/"$mointpoint" "$SANDBOX_DIR"/workdir"/$mointpoint" "$SANDBOX_DIR"/temproot/"$mointpoint" + if [ -d "$mountpoint" ]; then + mkdir -p "$SANDBOX_DIR"/upperdir/"$mountpoint" "$SANDBOX_DIR"/workdir"/$mountpoint" "$SANDBOX_DIR"/temproot/"$mountpoint" fi done @@ -72,37 +72,50 @@ try() { cat >"$mount_and_execute" <<"EOF" #!/bin/sh +## A wrapper of `mount -t overlay` to have cleaner looking code +make_overlay() { + sandbox_dir="$1" + lowerdir="$2" + mountpoint="$3" + mount -t overlay overlay -o "lowerdir=$lowerdir,upperdir=$SANDBOX_DIR/upperdir/$mountpoint,workdir=$SANDBOX_DIR/workdir/$mountpoint" "$SANDBOX_DIR/temproot/$mountpoint" +} + # actually mount the overlays -for mointpoint in /* $(findmnt --real -r -o target -n | grep -v "^/$") +for mountpoint in /* $(findmnt --real -r -o target -n | grep -v "^/$") do - ## If the directory is not a mountpoint - if [ -d "$mointpoint" ]; then - # skip if it is /dev or /proc, we will mount it later - if [ "$mointpoint" = "/dev" ] || [ "$mointpoint" = "/proc" ]; then - continue - fi - # Try mounting everything normally - mount -t overlay overlay -o lowerdir=/"$mointpoint",upperdir="$SANDBOX_DIR"/upperdir/"$mointpoint",workdir="$SANDBOX_DIR"/workdir/"$mointpoint" "$SANDBOX_DIR"/temproot/"$mointpoint" 2>> "$try_mount_log" - # If mounting everything normally fails, we try using either using mergerfs or unionfs to mount them. - if [ $? -ne 0 ]; then - # Detect if union_helper is set, if not, we try to autodetect them - if [ -z ${union_helper+x} ]; then - if command -v mergerfs > /dev/null; then - union_helper=mergerfs - elif command -v unionfs > /dev/null; then - union_helper=unionfs - else - echo "Error: Failed to mount overlayfs normally, mergerfs or unionfs not found for $mointpoint, see $try_mount_log" 1>&2 - exit 1 - fi - fi + ## We are not interested in mounts that are not directories + if [ ! -d "$mountpoint" ] + then + continue + fi - # Here we use mergerfs/unionfs to be mounted into a single file system. Used to fix nested mounts #19 - merger_dir=$(mktemp -d) - "$union_helper" $mointpoint $merger_dir 2>> "$try_mount_log" || echo "Warning: Failed to mount $mointpoint via $union_helper, see $try_mount_log" 1>&2 && - mount -t overlay overlay -o lowerdir="$merger_dir",upperdir="$SANDBOX_DIR"/upperdir"$mointpoint",workdir="$SANDBOX_DIR"/workdir"$mointpoint" "$SANDBOX_DIR"/temproot"$mointpoint" 2>> "$try_mount_log" || - echo "Warning: Failed mounting $mointpoint as an overlay via $union_helper, see "$try_mount_log"" 1>&2 + # skip if it is /dev or /proc, we will mount it later + if [ "$mountpoint" = "/dev" ] || [ "$mountpoint" = "/proc" ]; then + continue + fi + + # Try mounting everything normally + make_overlay "$SANDBOX_DIR" "/$mountpoint" "$mountpoint" 2>> "$try_mount_log" + # If mounting everything normally fails, we try using either using mergerfs or unionfs to mount them. + if [ "$?" -ne 0 ] + then + # Detect if union_helper is set, if not, we try to autodetect them + if [ -z ${union_helper+x} ]; then + if command -v mergerfs > /dev/null; then + union_helper=mergerfs + elif command -v unionfs > /dev/null; then + union_helper=unionfs + else + echo "Error: Failed to mount overlayfs normally, mergerfs or unionfs not found for $mountpoint, see $try_mount_log" 1>&2 + exit 1 + fi fi + + # Here we use mergerfs/unionfs to be mounted into a single file system. Used to fix nested mounts #19 + merger_dir=$(mktemp -d) + "$union_helper" $mountpoint $merger_dir 2>> "$try_mount_log" || echo "Warning: Failed to mount $mountpoint via $union_helper, see $try_mount_log" 1>&2 && + make_overlay "$SANDBOX_DIR" "$merger_dir" "$mountpoint" 2>> "$try_mount_log" || + echo "Warning: Failed mounting $mountpoint as an overlay via $union_helper, see "$try_mount_log"" 1>&2 fi done @@ -269,6 +282,7 @@ find_upperdir_changes() { find "$sandbox_dir/upperdir/" -type f -o \( -type c -size 0 \) -o -type d | ignore_changes } + ## Processes upperdir changes to an internal format that can be processed by summary and commit ## Format: ## XX PATH From 45f8e0b7c56a374dc06f249351e5c4034985f27e Mon Sep 17 00:00:00 2001 From: Konstantinos Kallas Date: Thu, 29 Jun 2023 11:14:09 -0400 Subject: [PATCH 21/27] Refactor --- try | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/try b/try index 779d49fb..adefd83f 100755 --- a/try +++ b/try @@ -77,7 +77,27 @@ make_overlay() { sandbox_dir="$1" lowerdir="$2" mountpoint="$3" - mount -t overlay overlay -o "lowerdir=$lowerdir,upperdir=$SANDBOX_DIR/upperdir/$mountpoint,workdir=$SANDBOX_DIR/workdir/$mountpoint" "$SANDBOX_DIR/temproot/$mountpoint" + mount -t overlay overlay -o "lowerdir=$lowerdir,upperdir=$sandbox_dir/upperdir/$mountpoint,workdir=$sandbox_dir/workdir/$mountpoint" "$sandbox_dir/temproot/$mountpoint" +} + +## Mounts a few select devices instead of the whole `/dev` +mount_devices() { + sandbox_dir="$1" + for dev in tty null zero full random urandom + do + touch "$sandbox_dir/temproot/dev/$dev" + mount -o bind /dev/$dev "$sandbox_dir/temproot/dev/$dev" + done +} + +## Try to autodetect union helper: {mergerfs | unionfs} +## Returns an empty string if no union helper is found +autodetect_union_helper() { + if command -v mergerfs > /dev/null; then + echo mergerfs + elif command -v unionfs > /dev/null; then + echo unionfs + fi } # actually mount the overlays @@ -100,30 +120,27 @@ do if [ "$?" -ne 0 ] then # Detect if union_helper is set, if not, we try to autodetect them - if [ -z ${union_helper+x} ]; then - if command -v mergerfs > /dev/null; then - union_helper=mergerfs - elif command -v unionfs > /dev/null; then - union_helper=unionfs - else - echo "Error: Failed to mount overlayfs normally, mergerfs or unionfs not found for $mountpoint, see $try_mount_log" 1>&2 + if [ -z ${union_helper+x} ] + then + union_helper="$(autodetect_union_helper)" + if [ -z "$union_helper" ] + then + printf "%s: Failed to mount overlayfs normally, mergerfs or unionfs not found for $mountpoint, see $try_mount_log\n" "$(basename $0)" >&2 exit 1 fi fi # Here we use mergerfs/unionfs to be mounted into a single file system. Used to fix nested mounts #19 merger_dir=$(mktemp -d) - "$union_helper" $mountpoint $merger_dir 2>> "$try_mount_log" || echo "Warning: Failed to mount $mountpoint via $union_helper, see $try_mount_log" 1>&2 && + "$union_helper" $mountpoint $merger_dir 2>> "$try_mount_log" || + printf "%s: Warning: Failed to mount $mountpoint via $union_helper, see \"$try_mount_log\"\n" "$(basename $0)" >&2 + make_overlay "$SANDBOX_DIR" "$merger_dir" "$mountpoint" 2>> "$try_mount_log" || - echo "Warning: Failed mounting $mountpoint as an overlay via $union_helper, see "$try_mount_log"" 1>&2 + printf "%s: Warning: Failed mounting $mountpoint as an overlay via $union_helper, see \"$try_mount_log\"\n" "$(basename $0)" >&2 fi done -for dev in tty null zero full random urandom -do - touch "$SANDBOX_DIR/temproot/dev/$dev" - mount -o bind /dev/$dev "$SANDBOX_DIR/temproot/dev/$dev" -done +mount_devices "$SANDBOX_DIR" ## Check if chroot_executable exists, #29 if ! [ -f "$SANDBOX_DIR/temproot/$chroot_executable" ]; then From a71f715cc63029aa9d32d5b0e4dd5a83ca90e031 Mon Sep 17 00:00:00 2001 From: Konstantinos Kallas Date: Thu, 29 Jun 2023 11:15:27 -0400 Subject: [PATCH 22/27] more refactoring --- try | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/try b/try index adefd83f..6248b354 100755 --- a/try +++ b/try @@ -22,7 +22,8 @@ TRY_VERSION="0.1.0" try() { START_DIR="$PWD" - if ! command -v findmnt > /dev/null; then + if ! command -v findmnt > /dev/null + then printf "%s: findmnt not found, please install util-linux\n" "$(basename $0)" >&2 exit 1 fi @@ -110,7 +111,8 @@ do fi # skip if it is /dev or /proc, we will mount it later - if [ "$mountpoint" = "/dev" ] || [ "$mountpoint" = "/proc" ]; then + if [ "$mountpoint" = "/dev" ] || [ "$mountpoint" = "/proc" ] + then continue fi @@ -143,7 +145,8 @@ done mount_devices "$SANDBOX_DIR" ## Check if chroot_executable exists, #29 -if ! [ -f "$SANDBOX_DIR/temproot/$chroot_executable" ]; then +if ! [ -f "$SANDBOX_DIR/temproot/$chroot_executable" ] +then cp $chroot_executable "$SANDBOX_DIR/temproot/$chroot_executable" fi @@ -216,7 +219,7 @@ summary() { changed_files=$(find_upperdir_changes "$SANDBOX_DIR") summary_output=$(process_changes "$SANDBOX_DIR" "$changed_files") - if [ -z "$summary_output" ]; + if [ -z "$summary_output" ] then return 1 fi From 2f5d40f36e7844560853cfe793731be955422a80 Mon Sep 17 00:00:00 2001 From: Konstantinos Kallas Date: Thu, 29 Jun 2023 11:30:58 -0400 Subject: [PATCH 23/27] Refactor some more and unmount devices for tests to pass --- try | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/try b/try index 6248b354..e7f42d78 100755 --- a/try +++ b/try @@ -81,16 +81,27 @@ make_overlay() { mount -t overlay overlay -o "lowerdir=$lowerdir,upperdir=$sandbox_dir/upperdir/$mountpoint,workdir=$sandbox_dir/workdir/$mountpoint" "$sandbox_dir/temproot/$mountpoint" } -## Mounts a few select devices instead of the whole `/dev` +devices_to_mount="tty null zero full random urandom" + +## Mounts and unmounts a few select devices instead of the whole `/dev` mount_devices() { sandbox_dir="$1" - for dev in tty null zero full random urandom + for dev in $devices_to_mount do touch "$sandbox_dir/temproot/dev/$dev" mount -o bind /dev/$dev "$sandbox_dir/temproot/dev/$dev" done } +unmount_devices() { + sandbox_dir="$1" + for dev in $devices_to_mount + do + umount "$sandbox_dir/temproot/dev/$dev" 2>>"$try_mount_log" + rm -f "$sandbox_dir/temproot/dev/$dev" + done +} + ## Try to autodetect union helper: {mergerfs | unionfs} ## Returns an empty string if no union helper is found autodetect_union_helper() { @@ -102,7 +113,7 @@ autodetect_union_helper() { } # actually mount the overlays -for mountpoint in /* $(findmnt --real -r -o target -n | grep -v "^/$") +for mountpoint in /* $(findmnt --real -r -o target -n) do ## We are not interested in mounts that are not directories if [ ! -d "$mountpoint" ] @@ -110,11 +121,13 @@ do continue fi - # skip if it is /dev or /proc, we will mount it later - if [ "$mountpoint" = "/dev" ] || [ "$mountpoint" = "/proc" ] + ## Don't do anything for the root + ## and skip if it is /dev or /proc, we will mount it later + if [ "$mountpoint" = "/" ] || + [ "$mountpoint" = "/dev" ] || [ "$mountpoint" = "/proc" ] then continue - fi + fi # Try mounting everything normally make_overlay "$SANDBOX_DIR" "/$mountpoint" "$mountpoint" 2>> "$try_mount_log" @@ -142,6 +155,7 @@ do fi done +## Mount a few select devices in /dev mount_devices "$SANDBOX_DIR" ## Check if chroot_executable exists, #29 @@ -151,6 +165,13 @@ then fi unshare --root="$SANDBOX_DIR/temproot" /bin/bash "$chroot_executable" +exitcode="$?" + +# unmount the devices +sync +unmount_devices "$SANDBOX_DIR" + +exit $exitcode EOF cat >"$chroot_executable" < Date: Thu, 29 Jun 2023 11:40:15 -0400 Subject: [PATCH 24/27] Add a device test --- test/run_tests.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/run_tests.sh b/test/run_tests.sh index cdac390c..c6a3bb87 100755 --- a/test/run_tests.sh +++ b/test/run_tests.sh @@ -317,6 +317,16 @@ test_mkdir_on_file() diff -qr expected target } +test_dev() +{ + local try_workspace=$1 + cp $RESOURCE_DIR/file.txt.gz "$try_workspace/" + cd "$try_workspace/" + + "$try" -y "head -c 5 /dev/urandom > target" + [ -s target ] +} + # a test that deliberately fails (for testing CI changes) test_fail() { @@ -343,6 +353,7 @@ if [ "$#" -eq 0 ]; then run_test test_explore run_test test_empty_summary run_test test_mkdir_on_file + run_test test_dev # uncomment this to force a failure # run_test test_fail From 2fcfb172334de0ac742d384f369feea595174ed3 Mon Sep 17 00:00:00 2001 From: Michael Greenberg Date: Thu, 29 Jun 2023 11:50:26 -0400 Subject: [PATCH 25/27] copyedit --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b49b77d4..3b2088e2 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,12 @@ disks. ### Dependencies -Try relies on the following dependencies +`try` relies on the following dependencies -`util-linux` +* `util-linux` In cases where overlayfs doesn't work on nested mounts, you will need either -[mergerfs](https://github.com/trapexit/mergerfs) or [unionfs](https://github.com/rpodgorny/unionfs-fuse). Try should be able to autodetect them, but you can specify the path to mergerfs or unionfs with -U (e.g. `try -U ~/.local/bin/unionfs`) +[mergerfs](https://github.com/trapexit/mergerfs) or [unionfs](https://github.com/rpodgorny/unionfs-fuse). `try` should be able to autodetect them, but you can specify the path to mergerfs or unionfs with -U (e.g. `try -U ~/.local/bin/unionfs`) Has been tested on the following distributions: * `Ubuntu 20.04 LTS` or later @@ -51,7 +51,7 @@ $ git clone https://github.com/binpash/try.git #### Arch Linux -`Try` is present in [AUR](https://aur.archlinux.org/packages/try), you can install it with your preferred AUR helper: +`try` is present in [AUR](https://aur.archlinux.org/packages/try), you can install it with your preferred AUR helper: ```shellsession yay -S try From 57b9b8cff02fbd685c009feb0d1811652a26ea75 Mon Sep 17 00:00:00 2001 From: Michael Greenberg Date: Thu, 29 Jun 2023 11:51:00 -0400 Subject: [PATCH 26/27] copyedit --- docs/try.1.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/try.1.md b/docs/try.1.md index d8439134..7dcf906c 100644 --- a/docs/try.1.md +++ b/docs/try.1.md @@ -48,6 +48,7 @@ While using *try* you can choose to commit the result to the filesystem or compl : Use the unionfs helper implementation defined in the *PATH* (e.g., mergerfs, unionfs-fuse) instead of the default. This option is recommended in case OverlayFS fails. + ## Subcommands try summary *DIR* From 36a7b6c0ecbe5c950ecc2f23498f303eee465405 Mon Sep 17 00:00:00 2001 From: Konstantinos Kallas Date: Thu, 29 Jun 2023 12:59:58 -0400 Subject: [PATCH 27/27] Some comments and redirect a test to /dev/null --- test/run_tests.sh | 2 +- try | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/test/run_tests.sh b/test/run_tests.sh index c6a3bb87..94c7f55f 100755 --- a/test/run_tests.sh +++ b/test/run_tests.sh @@ -177,7 +177,7 @@ test_reuse_problematic_sandbox() ## but it doesn't seem to both overlayfs at all. ## TODO: Extend this with more problematic overlayfs modifications. touch "$try_example_dir/temproot/bin/foo" - ! "$try" -D $try_example_dir "rm file_1.txt; echo test2 >> file_2.txt; touch file.txt.gz" + ! "$try" -D $try_example_dir "rm file_1.txt; echo test2 >> file_2.txt; touch file.txt.gz" 2> /dev/null } test_non_existent_sandbox() diff --git a/try b/try index e7f42d78..f4cce711 100755 --- a/try +++ b/try @@ -52,6 +52,9 @@ try() { # we will overlay-mount each root directory separately (instead of all at once) because some directories cannot be overlayed # so we set up the mount points now # + # KK 2023-06-29 This approach (of mounting each root directory separately) was necessary because we could not mount `/` in an overlay. + # However, this might be solveable using mergerfs/unionfs, allowing us to mount an overlay on a unionfs of the `/` once. + # # findmnt # --real: only list real filesystems # -n: no header @@ -145,11 +148,24 @@ do fi fi - # Here we use mergerfs/unionfs to be mounted into a single file system. Used to fix nested mounts #19 + + ## If the overlay failed, it means that there is a nested mount inside the target mount, e.g., both `/home` and `/home/user/mnt` are mounts. + ## To address this, we use unionfs/mergerfs (they support the same functionality) to show all mounts under the target mount as normal directories. + ## Then we can normally make the overlay on the new union directory. + ## + ## KK 2023-06-29 Since this uses findmnt, it performs the union+overlay for both the outside and the inside mount. + ## In the best case scenario this is only causing extra work (the internal mount is already shown through the unionfs), + ## but in the worst case this could lead to bugs due to the extra complexity (e.g., because we are doing mounts on top of each other). + ## We should try to investigate either: + ## 1. Not doing another overlay if we have done it for a parent directory (we can keep around a list of overlays and skip if we are in a child) + ## 2. Do one unionfs+overlay at the root `/` once and be done with it! merger_dir=$(mktemp -d) + + ## Create a union directory "$union_helper" $mountpoint $merger_dir 2>> "$try_mount_log" || printf "%s: Warning: Failed to mount $mountpoint via $union_helper, see \"$try_mount_log\"\n" "$(basename $0)" >&2 + ## Make the overlay on the union directory which works as a lowerdir for overlay make_overlay "$SANDBOX_DIR" "$merger_dir" "$mountpoint" 2>> "$try_mount_log" || printf "%s: Warning: Failed mounting $mountpoint as an overlay via $union_helper, see \"$try_mount_log\"\n" "$(basename $0)" >&2 fi