ia64/xen-unstable

changeset 8110:880b02c04656

The device sharing check races when more than one file backed vbd is
configured. Both of the files pick the same free loop device in the for
loop, and then one fails to losetup. This patch will now retry if
losetup fails until it succeeds or no more devices are available.

Signed-off-by: Robert Read <robert@xensource.com>
author rread@ubuntu.eng.hq.xensource.com
date Mon Nov 28 15:34:00 2005 -0700 (2005-11-28)
parents 444b968a3e09
children ec370b3d2df3
files tools/examples/block
line diff
     1.1 --- a/tools/examples/block	Mon Nov 28 12:16:27 2005 -0700
     1.2 +++ b/tools/examples/block	Mon Nov 28 15:34:00 2005 -0700
     1.3 @@ -202,59 +202,61 @@ case "$command" in
     1.4  mount it read-write in a guest domain."
     1.5          fi
     1.6  
     1.7 -        loopdev=''
     1.8  
     1.9 -	for dev in /dev/loop*
    1.10 -        do
    1.11 -          if [ ! -b "$dev" ]
    1.12 -          then
    1.13 -            continue
    1.14 -          fi
    1.15 -
    1.16 -          f=$(losetup "$dev" 2>/dev/null) || f='()'
    1.17 -          f=$(echo "$f" | sed -e 's/.*(\(.*\)).*/\1/g')
    1.18 -
    1.19 -          log err "$file $f $dev"
    1.20 -
    1.21 -          if [ "$f" ]
    1.22 -          then
    1.23 -            # $dev is in use.  Check sharing.
    1.24 -
    1.25 -            if [ "$mode" == 'no' ]
    1.26 +	while true
    1.27 +        do 
    1.28 +          loopdev=''
    1.29 +          for dev in /dev/loop*
    1.30 +          do
    1.31 +            if [ ! -b "$dev" ]
    1.32              then
    1.33                continue
    1.34              fi
    1.35  
    1.36 -            f=$(readlink -f "$f")
    1.37 +            f=$(losetup "$dev" 2>/dev/null) || f='()'
    1.38 +            f=$(echo "$f" | sed -e 's/.*(\(.*\)).*/\1/g')
    1.39 +
    1.40 +            log err "$file $f $dev"
    1.41 +
    1.42 +            if [ "$f" ]
    1.43 +            then
    1.44 +              # $dev is in use.  Check sharing.
    1.45 +              if [ "$mode" == 'no' ]
    1.46 +              then
    1.47 +                continue
    1.48 +              fi
    1.49  
    1.50 -            if [ "$f" == "$file" ]
    1.51 -            then
    1.52 -              check_file_sharing "$file" "$dev" "$mode"
    1.53 +              f=$(readlink -f "$f")
    1.54 +
    1.55 +              if [ "$f" == "$file" ]
    1.56 +              then
    1.57 +                check_file_sharing "$file" "$dev" "$mode"
    1.58 +              fi
    1.59 +            else
    1.60 +              # $dev is not in use, so we'll remember it for use later; we want
    1.61 +              # to finish the sharing check first.
    1.62 +              
    1.63 +              if [ "$loopdev" == '' ]
    1.64 +              then
    1.65 +                loopdev="$dev"
    1.66 +              fi
    1.67              fi
    1.68 -          else
    1.69 -            # $dev is not in use, so we'll remember it for use later; we want
    1.70 -            # to finish the sharing check first.
    1.71 -            
    1.72 -            if [ "$loopdev" == '' ]
    1.73 -            then
    1.74 -              loopdev="$dev"
    1.75 -            fi
    1.76 +          done
    1.77 +
    1.78 +          if [ "$loopdev" == '' ]
    1.79 +          then
    1.80 +            fatal 'Failed to find an unused loop device'
    1.81            fi
    1.82 -        done
    1.83 -
    1.84 -        if [ "$loopdev" == '' ]
    1.85 -        then
    1.86 -          fatal 'Failed to find an unused loop device'
    1.87 -        fi
    1.88 -
    1.89 -        if losetup "$loopdev" "$file"
    1.90 -        then
    1.91 -          xenstore_write "$XENBUS_PATH/node" "$loopdev"
    1.92 -          write_dev "$loopdev"
    1.93 -          exit 0
    1.94 -        else
    1.95 -          fatal "losetup $loopdev $file failed"
    1.96 -        fi
    1.97 +          if losetup "$loopdev" "$file"
    1.98 +          then
    1.99 +	    log err "mapped $file using $loopdev"
   1.100 +            xenstore_write "$XENBUS_PATH/node" "$loopdev"
   1.101 +            write_dev "$loopdev"
   1.102 +            exit 0
   1.103 +          else
   1.104 +            log err "losetup $loopdev $file failed, retry"
   1.105 +          fi
   1.106 +	done
   1.107  	;;
   1.108      esac
   1.109      ;;