[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    [PATCH 0/1] loop mount: propagate errors correctly
From:       Thomas De Schampheleire <patrickdepinguin () gmail ! com>
Date:       2020-05-18 12:03:10
Message-ID: 20200518120311.30060-1-patrickdepinguin () gmail ! com
[Download RAW message or body]

From: Thomas De Schampheleire <thomas.de_schampheleire@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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic