Whamcloud - gitweb
LU-80 tests: large xattr support
authorYu Jian <yujian@whamcloud.com>
Fri, 30 Dec 2011 06:28:44 +0000 (14:28 +0800)
committerOleg Drokin <green@whamcloud.com>
Fri, 6 Jan 2012 03:18:20 +0000 (22:18 -0500)
This patch adds and updates some test cases to verify the
large xattr feature. To enable this feature, the "-O large_xattr"
option needs to be set on the filesystem either with --mkfsoptions
at format time or via tune2fs.

Signed-off-by: Yu Jian <yujian@whamcloud.com>
Change-Id: Ie62e6e2194fdaa7239ec4e1451a4e696888dca8c
Reviewed-on: http://review.whamcloud.com/1880
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: James Simmons <uja.ornl@gmail.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/tests/conf-sanity.sh
lustre/tests/lustre-rsync-test.sh
lustre/tests/replay-single.sh
lustre/tests/sanity.sh
lustre/tests/test-framework.sh

index be76532..6b3b646 100644 (file)
@@ -2758,6 +2758,65 @@ test_60() { # LU-471
 }
 run_test 60 "check mkfs.lustre --mkfsoptions -E -O options setting"
 
+test_61() { # LU-80
+    local reformat=false
+
+    if ! large_xattr_enabled; then
+        reformat=true
+        local mds_dev=$(mdsdevname ${SINGLEMDS//mds/})
+        add $SINGLEMDS $MDS_MKFS_OPTS --mkfsoptions='\"-O large_xattr\"' \
+            --reformat $mds_dev || error "reformatting $mds_dev failed"
+    fi
+
+    setup_noconfig || error "setting up the filesystem failed"
+    client_up || error "starting client failed"
+
+    local file=$DIR/$tfile
+    touch $file
+
+    local large_value="$(generate_string $(max_xattr_size))"
+    local small_value="bar"
+
+    local name="trusted.big"
+    log "save large xattr $name on $file"
+    setfattr -n $name -v $large_value $file ||
+        error "saving $name on $file failed"
+
+    local new_value=$(get_xattr_value $name $file)
+    [[ "$new_value" != "$large_value" ]] &&
+        error "$name different after saving"
+
+    log "shrink value of $name on $file"
+    setfattr -n $name -v $small_value $file ||
+        error "shrinking value of $name on $file failed"
+
+    new_value=$(get_xattr_value $name $file)
+    [[ "$new_value" != "$small_value" ]] &&
+        error "$name different after shrinking"
+
+    log "grow value of $name on $file"
+    setfattr -n $name -v $large_value $file ||
+        error "growing value of $name on $file failed"
+
+    new_value=$(get_xattr_value $name $file)
+    [[ "$new_value" != "$large_value" ]] &&
+        error "$name different after growing"
+
+    log "check value of $name on $file after remounting MDS"
+    fail $SINGLEMDS
+    new_value=$(get_xattr_value $name $file)
+    [[ "$new_value" != "$large_value" ]] &&
+        error "$name different after remounting MDS"
+
+    log "remove large xattr $name from $file"
+    setfattr -x $name $file || error "removing $name from $file failed"
+
+    rm -f $file
+    stopall
+    $reformat && reformat
+}
+run_test 61 "large xattr"
+
 if ! combined_mgs_mds ; then
        stop mgs
 fi
index 3064507..1cfeaff 100644 (file)
@@ -82,14 +82,25 @@ fini_changelog() {
     do_facet $SINGLEMDS lctl --device $MDT0 changelog_deregister $CL_USER
 }
 
+# Check whether the filesystem supports xattr or not.
+# Return value:
+# "large" - large xattr is supported
+# "small" - large xattr is unsupported but small xattr is supported
+# "no"    - xattr is unsupported
 check_xattr() {
     local tgt=$1
-    local xattr="yes"
+    local xattr="no"
+
     touch $tgt
-    setfattr -n user.foo -v 'bar' $tgt 2> /dev/null
-    if [ $? -ne 0 ]; then
-       xattr="no"
+
+    local val="$(generate_string $(max_xattr_size))"
+    if large_xattr_enabled &&
+       setfattr -n user.foo -v $val $tgt 2>/dev/null; then
+            xattr="large"
+    else
+        setfattr -n user.foo -v bar $tgt 2>/dev/null && xattr="small"
     fi
+
     rm -f $tgt
     echo $xattr
 }
@@ -108,7 +119,7 @@ check_diff() {
 test_1() {
     init_src
     init_changelog
-    local xattr=`check_xattr $TGT/foo`
+    local xattr=$(check_xattr $TGT/foo)
 
     # Directory create
     mkdir $DIR/$tdir/d1
@@ -148,32 +159,33 @@ test_1() {
     chown nobody:nobody $DIR/$tdir/d2/file3
 
     # Set xattrs
-    if [ "$xattr" == "yes" ]; then
-       touch $DIR/$tdir/file5
-       setfattr -n user.foo -v 'bar' $DIR/$tdir/file5
+    if [[ "$xattr" != "no" ]]; then
+        local value
+        touch $DIR/$tdir/file5
+        [[ "$xattr" = "large" ]] &&
+            value="$(generate_string $(max_xattr_size))" || value="bar"
+        setfattr -n user.foo -v $value $DIR/$tdir/file5
     fi
 
     echo "Replication #2"
     $LRSYNC -l $LREPL_LOG
 
-    if [ "$xattr" == "yes" ]; then
-       local xval1=$(getfattr -n user.foo --absolute-names --only-values \
-           $TGT/$tdir/file5)
-       local xval2=$(getfattr -n user.foo --absolute-names --only-values \
-           $TGT2/$tdir/file5)
+    if [[ "$xattr" != "no" ]]; then
+        local xval1=$(get_xattr_value user.foo $TGT/$tdir/file5)
+        local xval2=$(get_xattr_value user.foo $TGT2/$tdir/file5)
     fi
 
     RC=0
 
     # fid2path and path2fid aren't implemented for block devices
     #if [[ ! -b $TGT/$tdir/dev1 ]] || [[ ! -b $TGT2/$tdir/dev1 ]]; then
-    #  ls -l $DIR/$tdir/dev1 $TGT/$tdir/dev1 $TGT2/$tdir/dev1
+    #   ls -l $DIR/$tdir/dev1 $TGT/$tdir/dev1 $TGT2/$tdir/dev1
     #   error "Error replicating block devices"
     #   RC=1
 
-    if [[ "$xattr" == "yes" ]] &&
-       [[ "$xval1" != "bar" || "$xval2" != "bar" ]]; then
-        error "Error in replicating xattrs. $xval1, $xval2"
+    if [[ "$xattr" != "no" ]] &&
+       [[ "$xval1" != "$value" || "$xval2" != "$value" ]]; then
+        error "Error in replicating xattrs."
         RC=1
     fi
 
@@ -503,7 +515,7 @@ test_7() {
     init_changelog
 
     local NUMFILES=100
-    lfs setstripe -c 2 ${DIR}/$tdir
+    lfs setstripe -c $OSTCOUNT $DIR/$tdir
     createmany -o $DIR/$tdir/$tfile $NUMFILES
 
     # To simulate replication to another lustre filesystem, replicate
@@ -518,7 +530,7 @@ test_7() {
     while [ $i -lt $NUMFILES ];
     do
       local count=$(lfs getstripe $DIR/tgt/$tdir/${tfile}$i | awk '/stripe_count/ {print $2}')
-      if [ $count -ne 2 ]; then
+      if [ $count -ne $OSTCOUNT ]; then
          error "Stripe size not replicated" 
       fi
       i=$(expr $i + 1)
index b0d5a60..596e7a4 100755 (executable)
@@ -1369,14 +1369,20 @@ test_58a() {
 run_test 58a "test recovery from llog for setattr op (test llog_gen_rec)"
 
 test_58b() {
+    local orig
+    local new
+
+    large_xattr_enabled &&
+        orig="$(generate_string $(max_xattr_size))" || orig="bar"
+
     mount_client $MOUNT2
     mkdir -p $DIR/$tdir
     touch $DIR/$tdir/$tfile
     replay_barrier $SINGLEMDS
-    setfattr -n trusted.foo -v bar $DIR/$tdir/$tfile
+    setfattr -n trusted.foo -v $orig $DIR/$tdir/$tfile
     fail $SINGLEMDS
-    VAL=`getfattr --absolute-names --only-value -n trusted.foo $MOUNT2/$tdir/$tfile`
-    [ x$VAL = x"bar" ] || return 1
+    new=$(get_xattr_value trusted.foo $MOUNT2/$tdir/$tfile)
+    [[ "$new" = "$orig" ]] || return 1
     rm -f $DIR/$tdir/$tfile
     rmdir $DIR/$tdir
     zconf_umount `hostname` $MOUNT2
@@ -1384,20 +1390,33 @@ test_58b() {
 run_test 58b "test replay of setxattr op"
 
 test_58c() { # bug 16570
-        mount_client $MOUNT2
-        mkdir -p $DIR/$tdir
-        touch $DIR/$tdir/$tfile
-        drop_request "setfattr -n trusted.foo -v bar $DIR/$tdir/$tfile" || \
-                return 1
-        VAL=`getfattr --absolute-names --only-value -n trusted.foo $MOUNT2/$tdir/$tfile`
-        [ x$VAL = x"bar" ] || return 2
-        drop_reint_reply "setfattr -n trusted.foo1 -v bar1 $DIR/$tdir/$tfile" || \
-                return 3
-        VAL=`getfattr --absolute-names --only-value -n trusted.foo1 $MOUNT2/$tdir/$tfile`
-        [ x$VAL = x"bar1" ] || return 4
-        rm -f $DIR/$tdir/$tfile
-        rmdir $DIR/$tdir
-        zconf_umount `hostname` $MOUNT2
+    local orig
+    local orig1
+    local new
+
+    if large_xattr_enabled; then
+        local xattr_size=$(max_xattr_size)
+        orig="$(generate_string $((xattr_size / 2)))"
+        orig1="$(generate_string $xattr_size)"
+    else
+        orig="bar"
+        orig1="bar1"
+    fi
+
+    mount_client $MOUNT2
+    mkdir -p $DIR/$tdir
+    touch $DIR/$tdir/$tfile
+    drop_request "setfattr -n trusted.foo -v $orig $DIR/$tdir/$tfile" ||
+        return 1
+    new=$(get_xattr_value trusted.foo $MOUNT2/$tdir/$tfile)
+    [[ "$new" = "$orig" ]] || return 2
+    drop_reint_reply "setfattr -n trusted.foo1 -v $orig1 $DIR/$tdir/$tfile" ||
+        return 3
+    new=$(get_xattr_value trusted.foo1 $MOUNT2/$tdir/$tfile)
+    [[ "$new" = "$orig1" ]] || return 4
+    rm -f $DIR/$tdir/$tfile
+    rmdir $DIR/$tdir
+    zconf_umount $HOSTNAME $MOUNT2
 }
 run_test 58c "resend/reconstruct setxattr op"
 
index b397284..ffa3e79 100644 (file)
@@ -1382,11 +1382,11 @@ test_27z() {
         remote_ost_nodsh && skip "remote OST with nodsh" && return
         mkdir -p $DIR/$tdir
         $SETSTRIPE $DIR/$tdir/$tfile-1 -c 1 -o 0 -s 1m ||
-                { error "setstripe -c -1 failed"; return 1; }
+                { error "setstripe -c 1 failed"; return 1; }
         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
                 { error "dd 1 mb failed"; return 2; }
         $SETSTRIPE $DIR/$tdir/$tfile-2 -c -1 -o $(($OSTCOUNT - 1)) -s 1m ||
-                { error "setstripe -c 1 failed"; return 3; }
+                { error "setstripe -c -1 failed"; return 3; }
         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
                 { error "dd $OSTCOUNT mb failed"; return 4; }
         sync
@@ -3760,9 +3760,9 @@ test_65d() {
        mkdir -p $DIR/d65
        if [ $STRIPECOUNT -le 0 ]; then
                sc=1
-       elif [ $STRIPECOUNT -gt 160 ]; then
-#LOV_MAX_STRIPE_COUNT is 160
-               [ $OSTCOUNT -gt 160 ] && sc=160 || sc=$(($OSTCOUNT - 1))
+       elif [ $STRIPECOUNT -gt 2000 ]; then
+#LOV_MAX_STRIPE_COUNT is 2000
+               [ $OSTCOUNT -gt 2000 ] && sc=2000 || sc=$(($OSTCOUNT - 1))
        else
                sc=$(($STRIPECOUNT - 1))
        fi
@@ -4829,7 +4829,10 @@ test_102b() {
        echo "get/set/list trusted.lov xattr ..."
        [ "$OSTCOUNT" -lt "2" ] && skip_env "skipping 2-stripe test" && return
        local testfile=$DIR/$tfile
-       $SETSTRIPE -s 65536 -i 1 -c 2 $testfile || error "setstripe failed"
+       $SETSTRIPE -s 65536 -i 1 -c $OSTCOUNT $testfile ||
+               error "setstripe failed"
+       local STRIPECOUNT=$(lfs getstripe -c $testfile) ||
+               error "getstripe failed"
        getfattr -d -m "^trusted" $testfile 2> /dev/null | \
        grep "trusted.lov" || error "can't get trusted.lov from $testfile"
 
@@ -4844,7 +4847,8 @@ test_102b() {
        local stripe_size=`grep "size"  $tmp_file| awk '{print $2}'`
        local stripe_count=`grep "count"  $tmp_file| awk '{print $2}'`
        [ "$stripe_size" -eq 65536 ] || error "stripe size $stripe_size != 65536"
-       [ "$stripe_count" -eq 2 ] || error "stripe count $stripe_count != 2"
+       [ "$stripe_count" -eq $STRIPECOUNT ] ||
+               error "stripe count $stripe_count != $STRIPECOUNT"
        rm -f $DIR/$tfile
 }
 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
@@ -4856,7 +4860,10 @@ test_102c() {
        mkdir -p $DIR/$tdir
        chown $RUNAS_ID $DIR/$tdir
        local testfile=$DIR/$tdir/$tfile
-       $RUNAS $SETSTRIPE -s 65536 -i 1 -c 2 $testfile||error "setstripe failed"
+       $RUNAS $SETSTRIPE -s 65536 -i 1 -c $OSTCOUNT $testfile ||
+               error "setstripe failed"
+       local STRIPECOUNT=$($RUNAS lfs getstripe -c $testfile) ||
+               error "getstripe failed"
        $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
        grep "lustre.lov" || error "can't get lustre.lov from $testfile"
 
@@ -4871,7 +4878,8 @@ test_102c() {
        local stripe_size=`grep "size"  $tmp_file| awk '{print $2}'`
        local stripe_count=`grep "count"  $tmp_file| awk '{print $2}'`
        [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
-       [ $stripe_count -eq 2 ] || error "stripe count $stripe_count != 2"
+       [ $stripe_count -eq $STRIPECOUNT ] ||
+               error "stripe count $stripe_count != $STRIPECOUNT"
 }
 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
 
@@ -4958,51 +4966,58 @@ test_102f() {
 }
 run_test 102f "tar copy files, not keep osts ==========="
 
-test_102h() { # bug 15777
+grow_xattr() {
+       local xsize=${1:-1024}  # in bytes
+       local file=$DIR/$tfile
+
        [ -z $(lctl get_param -n mdc.*.connect_flags | grep xattr) ] &&
-               skip "must have user_xattr" && return
+               skip "must have user_xattr" && return 0
        [ -z "$(which setfattr 2>/dev/null)" ] &&
-               skip_env "could not find setfattr" && return
+               skip_env "could not find setfattr" && return 0
+       [ -z "$(which getfattr 2>/dev/null)" ] &&
+               skip_env "could not find getfattr" && return 0
 
-       XBIG=trusted.big
-       XSIZE=1024
-       touch $DIR/$tfile
-       VALUE=datadatadatadatadatadatadatadata
-       while [ $(echo $VALUE | wc -c) -lt $XSIZE ]; do
-               VALUE="$VALUE$VALUE"
-       done
-       log "save $XBIG on $DIR/$tfile"
-        setfattr -n $XBIG -v "$VALUE" $DIR/$tfile ||
-               error "saving $XBIG on $DIR/$tfile failed"
-        ORIG=$(getfattr -n $XBIG $DIR/$tfile 2> /dev/null | grep $XBIG)
-       OSIZE=$(echo $ORIG | wc -c)
-       [ $OSIZE -lt $XSIZE ] && error "set $XBIG too small ($OSIZE < $XSIZE)"
-
-       XSML=trusted.sml
-       log "save $XSML on $DIR/$tfile"
-        setfattr -n $XSML -v val $DIR/$tfile ||
-               error "saving $XSML on $DIR/$tfile failed"
-        NEW=$(getfattr -n $XBIG $DIR/$tfile 2> /dev/null | grep $XBIG)
-       if [ "$NEW" != "$ORIG" ]; then
-               log "orig: $ORIG"
-               log "new: $NEW"
-               error "$XBIG different after saving $XSML"
-       fi
+       touch $file
+
+       local value="$(generate_string $xsize)"
+
+       local xbig=trusted.big
+       log "save $xbig on $file"
+       setfattr -n $xbig -v $value $file ||
+               error "saving $xbig on $file failed"
+
+       local orig=$(get_xattr_value $xbig $file)
+       [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
+
+       local xsml=trusted.sml
+       log "save $xsml on $file"
+       setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
+
+       local new=$(get_xattr_value $xbig $file)
+       [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
+
+       log "grow $xsml on $file"
+       setfattr -n $xsml -v "$value" $file ||
+               error "growing $xsml on $file failed"
+
+       new=$(get_xattr_value $xbig $file)
+       [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
+       log "$xbig still valid after growing $xsml"
 
-       log "grow $XSML on $DIR/$tfile"
-        setfattr -n $XSML -v "$VALUE" $DIR/$tfile ||
-               error "growing $XSML on $DIR/$tfile failed"
-        NEW=$(getfattr -n $XBIG $DIR/$tfile 2> /dev/null | grep $XBIG)
-       if [ "$NEW" != "$ORIG" ]; then
-               log "orig: $ORIG"
-               log "new: $NEW"
-               error "$XBIG different after growing $XSML"
-       fi
-       log "$XBIG still valid after growing $XSML"
        rm -f $file
 }
+
+test_102h() { # bug 15777
+       grow_xattr 1024
+}
 run_test 102h "grow xattr from inside inode to external block"
 
+test_102ha() {
+       large_xattr_enabled || { skip "large_xattr disabled" && return; }
+       grow_xattr $(max_xattr_size)
+}
+run_test 102ha "grow xattr from inside inode to external inode"
+
 test_102i() { # bug 17038
         touch $DIR/$tfile
         ln -s $DIR/$tfile $DIR/${tfile}link
index 95c89d8..4b2cd84 100644 (file)
@@ -4785,3 +4785,56 @@ is_sanity_benchmark() {
 min_ost_size () {
     $LCTL get_param -n osc.*.kbytesavail | sort -n | head -n1
 }
+
+# Get the block size of the filesystem.
+get_block_size() {
+    local facet=$1
+    local device=$2
+    local size
+
+    size=$(do_facet $facet "$DUMPE2FS -h $device 2>&1" |
+           awk '/^Block size:/ {print $3}')
+    echo $size
+}
+
+# Check whether the "large_xattr" feature is enabled or not.
+large_xattr_enabled() {
+    local mds_dev=$(mdsdevname ${SINGLEMDS//mds/})
+
+    do_facet $SINGLEMDS "$DUMPE2FS -h $mds_dev 2>&1 | grep -q large_xattr"
+    return ${PIPESTATUS[0]}
+}
+
+# Get the maximum xattr size supported by the filesystem.
+max_xattr_size() {
+    local size
+
+    if large_xattr_enabled; then
+        # include/linux/limits.h: #define XATTR_SIZE_MAX 65536
+        size=65536
+    else
+        local mds_dev=$(mdsdevname ${SINGLEMDS//mds/})
+        local block_size=$(get_block_size $SINGLEMDS $mds_dev)
+
+        # maximum xattr size = size of block - size of header -
+        #                      size of 1 entry - 4 null bytes
+        size=$((block_size - 32 - 32 - 4))
+    fi
+
+    echo $size
+}
+
+# Dump the value of the named xattr from a file.
+get_xattr_value() {
+    local xattr_name=$1
+    local file=$2
+
+    echo "$(getfattr -n $xattr_name --absolute-names --only-values $file)"
+}
+
+# Generate a string with size of $size bytes.
+generate_string() {
+    local size=${1:-1024} # in bytes
+
+    echo "$(head -c $size < /dev/zero | tr '\0' y)"
+}