From: Thomas De Schampheleire <thomas.de_schamphele...@nokia.com>

Hello,

When loop devices are mounted in parallel, the mount can fail but busybox
ignores it silently (a message is printed but the return code is still 0).

At the bottom of this mail is a (manual) test case that can show the issue quite
easily in case /dev/loop-control is available. Next mail is a patch that will
fix the error handling so that the initial mount actually fails.

However, it feels to me as if the mount shouldn't fail: the scenario is that
/dev/loop-control gives a 'free' number which later turns out to be not free
anymore because another mount used it too. This is an error that mount itself
could resolve by retrying, possibly with a maximum amount of attempts.

When /dev/loop-control is not used, the problem does not seem to show, even
though we have seen sporadic (but less frequent) failures with a similar
description using busybox 1.29.x (before /dev/loop-control was used).

Best regards,
Thomas


Philippe Belet (1):
  loop device: report mount failure in case of set_loop failure

 libbb/loop.c       | 2 +-
 util-linux/mount.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)


--- test case; just run the script in an environment where 'busybox' is in path,
--- or pass it as first argument ---


#!/bin/sh

busybox=${1:-busybox}

# create ext2 image
dd if=/dev/zero of=/tmp/test.ext2 bs=1M count=1
mkfs.ext2 -F /tmp/test.ext2

# create a file inside ext2 image
mkdir  -p /tmp/mountpoint
$busybox mount -t ext2 -o loop /tmp/test.ext2 /tmp/mountpoint
echo foobar > /tmp/mountpoint/file
$busybox umount /tmp/mountpoint

# mount in loop
cnt=0
innercnt=10
stop=0

# Cleanup old mounts
for i in $(seq "$innercnt"); do
        umount /tmp/mountpoint$i >/dev/null 2>&1
done


while true; do

        echo "Mounting"
        for i in $(seq "$innercnt"); do
                (
                mkdir -p /tmp/mountpoint$i
                if ! $busybox mount -t ext2 -o loop /tmp/test.ext2 
/tmp/mountpoint$i; then
                        echo "Error: mount failed (cnt=$cnt, i=$i)!"
                        stop=1
                        break
                fi
                ) &
        done
        if [ "$stop" -eq 1 ]; then
                break
        fi

        sleep 2
        echo "Check if mount completed after 2 seconds"
        for i in $(seq "$innercnt"); do
                if ! $busybox mount | grep "/tmp/mountpoint$i" ; then
                        echo "Mount of /tmp/mountpoint$i seems to have failed 
(but was silently ignored). Checking once again after timeout..."
                        sleep 2
                        if ! $busybox mount | grep "/tmp/mountpoint$i"; then
                                echo "Mount of /tmp/mountpoint$i definitely 
failed."
                                stop=1
                                break
                        fi
                fi
        done
        if [ "$stop" -eq 1 ]; then
                break
        fi

        echo "Checking contents"
        for i in $(seq "$innercnt"); do
                contents=$(cat /tmp/mountpoint$i/file)
                if [ "$contents" != "foobar" ]; then
                        echo "Error: expected file contents differ (cnt=$cnt, 
i=$i)"
                        echo "actual contents: $contents"
                        echo "expected contents: foobar"
                        stop=1
                        break
                fi
        done
        if [ "$stop" -eq 1 ]; then
                break
        fi

        echo "Unmounting"
        for i in $(seq "$innercnt"); do
                $busybox umount /tmp/mountpoint$i
        done
        if [ "$stop" -eq 1 ]; then
                break
        fi

        echo "Increase cnt"
        let 'cnt+=1'

done



-- 
2.26.2

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to