1 #
   2 # CDDL HEADER START
   3 #
   4 # The contents of this file are subject to the terms of the
   5 # Common Development and Distribution License (the "License").
   6 # You may not use this file except in compliance with the License.
   7 #
   8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9 # or http://www.opensolaris.org/os/licensing.
  10 # See the License for the specific language governing permissions
  11 # and limitations under the License.
  12 #
  13 # When distributing Covered Code, include this CDDL HEADER in each
  14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15 # If applicable, add the following below this CDDL HEADER, with the
  16 # fields enclosed by brackets "[]" replaced with your own identifying
  17 # information: Portions Copyright [yyyy] [name of copyright owner]
  18 #
  19 # CDDL HEADER END
  20 #
  21 
  22 #
  23 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24 # Use is subject to license terms.
  25 #
  26 
  27 . $STF_SUITE/include/nfsgen.kshlib
  28 
  29 # TX doesn't allow a regular user to access zone path
  30 # we need to enter mount point first, then access other
  31 # directories or files with relative path
  32 cd $MNTDIR
  33 
  34 #
  35 # Get the given file/directory access mode
  36 #
  37 # $1 object -- file or directroy
  38 #
  39 function get_mode #<obj>
  40 {
  41         FNAME=get_mode
  42         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
  43                 && set -x
  44 
  45         typeset obj=$1
  46         if (( ${#obj} == 0 )); then
  47                 return 1
  48         fi
  49 
  50         $LS -ld $obj | $AWK '{print $1}'
  51         return $?
  52 }
  53 
  54 #
  55 # Get the given file/directory ACL
  56 #
  57 # $1 object -- file or directroy
  58 #
  59 function get_acl #<obj>
  60 {
  61         FNAME=get_acl
  62         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
  63                 && set -x
  64 
  65         typeset obj=$1
  66         if (( ${#obj} == 0 )); then
  67                 return 1
  68         fi
  69 
  70         $LS -vd $obj | $NAWK '(NR != 1) {print $0}'
  71         return $?
  72 }
  73 
  74 #
  75 # Get the given file/directory ACL
  76 #
  77 # $1 object -- file or directroy
  78 #
  79 function get_compact_acl #<obj>
  80 {
  81         FNAME=get_compact_acl
  82         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
  83                 && set -x
  84 
  85         typeset obj=$1
  86         if (( ${#obj} == 0 )); then
  87                 return 1
  88         fi
  89 
  90         $LS -Vd $obj | $NAWK '(NR != 1) {print $0}' 
  91         return $?
  92 }
  93 
  94 #
  95 # Check the given two files/directories have the same ACLs
  96 #
  97 # Return 0, if source object acl is equal to target object acl.
  98 # 
  99 # $1 source object
 100 # $2 target object
 101 #
 102 function compare_acls #<src> <tgt>
 103 {
 104         FNAME=compare_acls
 105         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 106                 && set -x
 107 
 108         typeset src=$1
 109         typeset tgt=$2
 110 
 111         (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
 112         [[ $src == $tgt ]] && return 0
 113 
 114         typeset tmpsrc=/tmp/compare_acls.src.$$
 115         typeset tmptgt=/tmp/compare_acls.tgt.$$
 116 
 117         get_acl $src > $tmpsrc
 118         get_acl $tgt > $tmptgt
 119         typeset -i ret=0
 120         $DIFF $tmpsrc $tmptgt > /dev/null 2>&1
 121         ret=$?  
 122         $RM -f $tmpsrc $tmptgt
 123 
 124         if (( ret != 0 )); then
 125                 return $ret
 126         fi
 127 
 128         RUN_CHECK get_compact_acl $src > $tmpsrc || return 1
 129         RUN_CHECK get_compact_acl $tgt > $tmptgt || return 1
 130         $DIFF $tmpsrc $tmptgt > /dev/null 2>&1
 131         ret=$?  
 132         $RM -f $tmpsrc $tmptgt
 133 
 134         return $ret
 135 }
 136 
 137 #
 138 # Check that the given two objects have the same modes.
 139 # Return 0, if their modes are equal with each other. Otherwise, return 1.
 140 #
 141 # $1 source object
 142 # $2 target object
 143 #
 144 function compare_modes #<src> <tgt>
 145 {
 146         FNAME=compare_modes
 147         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 148                 && set -x
 149 
 150         typeset src=$1
 151         typeset tgt=$2
 152         typeset -i i=0
 153         set -A mode
 154 
 155         (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
 156         [[ $src == $tgt ]] && return 0
 157 
 158         typeset obj
 159         for obj in $src $tgt
 160         do
 161                 mode[i]=$(get_mode $obj)
 162 
 163                 (( i = i + 1 ))
 164         done
 165 
 166         [[ ${mode[0]} != ${mode[1]} ]] && return 1
 167 
 168         return 0
 169 }
 170 
 171 #
 172 # Check that the given two objects have the same xattrs.
 173 # Return 0, if their xattrs are equal with each other. Otherwise, return 1.
 174 #
 175 # $1 source object
 176 # $2 target object
 177 #
 178 function compare_xattrs #<src> <tgt>
 179 {
 180         FNAME=compare_xattrs
 181         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 182                 && set -x
 183 
 184         typeset src=$1
 185         typeset tgt=$2
 186 
 187         (( ${#src} == 0 || ${#tgt} == 0 )) && return 1
 188         [[ $src == $tgt ]] && return 0
 189 
 190         typeset tmpsrc=/tmp/compare_xattrs.src.$$
 191         typeset tmptgt=/tmp/compare_xattrs.tgt.$$
 192 
 193         RUN_CHECK get_xattr $src > $tmpsrc || return 1
 194         RUN_CHECK get_xattr $tgt > $tmptgt || return 1
 195         typeset -i ret=0
 196         $DIFF $tmpsrc $tmptgt > /dev/null 2>&1
 197         ret=$?  
 198         $RM -f $tmpsrc $tmptgt
 199 
 200         return $ret
 201 }
 202 
 203 #
 204 # Check '+' is set for a given file/directory with 'ls [-l]' command
 205 #
 206 # $1 object -- file or directory.
 207 #
 208 function plus_sign_check_l #<obj>
 209 {
 210         FNAME=plus_sign_check_l
 211         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 212                 && set -x
 213 
 214         typeset obj=$1
 215         if (( ${#obj} == 0 )); then
 216                 return 1
 217         fi
 218 
 219         $LS -ld $obj | $AWK '{print $1}' | $GREP "+\>" > /dev/null
 220         return $?
 221 }
 222 
 223 #
 224 # Check '+' is set for a given file/directory with 'ls [-v]' command
 225 #
 226 # $1 object -- file or directory.
 227 #
 228 function plus_sign_check_v #<obj>
 229 {
 230         FNAME=plus_sign_check_v
 231         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 232                 && set -x
 233 
 234         typeset obj=$1
 235         if (( ${#obj} == 0 )); then
 236                 return 1
 237         fi
 238 
 239         $LS -vd $obj | $NAWK '(NR == 1) {print $1}' | $GREP "+\>" > /dev/null
 240         return $?
 241 }
 242 
 243 #
 244 # Export the current user for the following usr_exec operating.
 245 #
 246 # $1 legal login name
 247 #
 248 function set_cur_usr #<login_name>
 249 {
 250         FNAME=set_cur_usr
 251         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 252                 && set -x
 253 
 254         export ACL_CUR_USER=$1
 255 }
 256 
 257 #
 258 # Run commands by $ACL_CUR_USER
 259 #
 260 # $1-n commands and options
 261 #
 262 function usr_exec #<commands> [...]
 263 {
 264         FNAME=usr_exec
 265         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 266                 && set -x
 267         
 268         [[ $IS_KRB5 == 1 && $ACL_CUR_USER != root ]] \
 269                 && chg_usr_exec -k $KPASSWORD "$ACL_CUR_USER" $@   \
 270                 || chg_usr_exec "$ACL_CUR_USER" $@
 271 
 272         return $?
 273 }
 274 
 275 #
 276 # Count how many ACEs for the speficied file or directory.
 277 #
 278 # $1 file or directroy name
 279 #
 280 function count_ACE #<file or dir name>
 281 {
 282         FNAME=count_ACE
 283         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 284                 && set -x
 285 
 286         if [[ ! -e $1 ]]; then
 287                 echo "Need input file or directroy name."
 288                 return 1
 289         fi
 290 
 291         $LS -vd $1 | $NAWK 'BEGIN {count=0}
 292                         (NR != 1)&&(/[0-9]:/) {count++}
 293                         END {print count}'
 294 
 295         return 0
 296 }
 297 
 298 #
 299 # Get specified number ACE content of specified file or directory.
 300 #
 301 # $1 file or directory name
 302 # $2 specified number
 303 #
 304 function get_ACE #<file or dir name> <specified number> <verbose|compact>
 305 {
 306         FNAME=get_ACE
 307         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 308                 && set -x
 309 
 310         if [[ ! -e $1 || $2 -ge $(count_ACE $1) ]]; then
 311                 return 1
 312         fi
 313 
 314         typeset file=$1
 315         typeset -i num=$2
 316         typeset format=${3:-verbose}
 317         typeset -i next_num=-1
 318 
 319         typeset tmpfile=/tmp/tmp_get_ACE.$$
 320         typeset line=""
 321         typeset args
 322 
 323         case $format in
 324                 verbose) args="-vd"
 325                         ;;
 326                 compact) args="-Vd"
 327                         ;;
 328                 *) echo "Invalid parameter as ($format), " \
 329                         "only verbose|compact is supported."
 330                         exit $STF_FAIL
 331                         ;;
 332         esac
 333 
 334         $LS $args $file > $tmpfile
 335         if (( $? != 0 )) then
 336                 echo "FAIL: $LS $args $file > $tmpfile"
 337                 exit $STF_FAIL
 338         fi
 339         while read line; do
 340                 [[ -z $line ]] && continue
 341                 if [[ $args == -vd ]]; then
 342                         if [[ $line == "$num":* ]]; then
 343                                 (( next_num = num + 1 ))
 344                         fi
 345                         if [[ $line == "$next_num":* ]]; then
 346                                 break
 347                         fi
 348                         if (( next_num != -1 )); then
 349                                 print -n $line
 350                         fi
 351                 else
 352                         if (( next_num == num )); then
 353                                 print -n $line
 354                         fi
 355                         (( next_num += 1 ))
 356                 fi
 357         done < $tmpfile
 358 
 359         $RM -f $tmpfile
 360         if (( $? != 0 )); then
 361                 echo "FAIL: $RM -f $tmpfile"
 362                 exit $STF_FAIL
 363         fi
 364 }
 365 
 366 #
 367 # Cleanup exist user/group.
 368 #
 369 function cleanup_user_group
 370 {
 371         FNAME=cleanup_user_group
 372         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 373                 && set -x
 374 
 375         del_user $ACL_ADMIN
 376 
 377         del_user $ACL_STAFF1
 378         del_user $ACL_STAFF2
 379         del_group $ACL_STAFF_GROUP
 380 
 381         del_user $ACL_OTHER1
 382         del_user $ACL_OTHER2
 383         del_group $ACL_OTHER_GROUP
 384 
 385         return 0
 386 }
 387 
 388 #
 389 # According to specified access or acl_spec, do relevant operating by using the
 390 # specified user.
 391 #
 392 # $1 specified user
 393 # $2 node
 394 # $3 acl_spec or access
 395 #
 396 function rwx_node #user node acl_spec|access
 397 {
 398         FNAME=rwx_node
 399         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 400                 && set -x
 401 
 402         typeset user=$1
 403         typeset node=$2
 404         typeset acl_spec=$3
 405 
 406         if [[ $user == "" || $node == "" || $acl_spec == "" ]]; then
 407                 echo "node or acl_spec are not defined."
 408                 return 1
 409         fi
 410 
 411         if [[ -d $node ]]; then
 412                 case $acl_spec in
 413                 *:read_data:*|read_data)
 414                         RUN_CHECK chgusr_exec $user $LS -l $node
 415                         return $? ;;
 416                 *:write_data:*|write_data)
 417                         if [[ -f ${node}/tmpfile ]]; then
 418                                 RUN_CHECK $RM -f ${node}/tmpfile \
 419                                         || exit $STF_FAIL
 420                         fi
 421                         RUN_CHECK chgusr_exec $user $TOUCH ${node}/tmpfile 
 422                         return $? ;;
 423                 *"execute:"*|execute)
 424                         RUN_CHECK chgusr_exec $user $FIND $node
 425                         return $? ;;
 426                 esac
 427         else
 428                 case $acl_spec in
 429                 *:read_data:*|read_data)
 430                         RUN_CHECK chgusr_exec $user $CAT $node
 431                         return $? ;;
 432                 *:write_data:*|write_data)
 433                         RUN_CHECK chgusr_exec $user $DD if=/usr/bin/ls of=$node
 434                         return $? ;;
 435                 *"execute:"*|execute)
 436                         ACL_ERR_STR=$(chgusr_exec $user $node 2>&1) 
 437                         return $? ;;
 438                 esac
 439         fi
 440 }
 441 
 442 #
 443 # Get the given file/directory xattr
 444 #
 445 # $1 object -- file or directroy
 446 #
 447 function get_xattr #<obj>
 448 {
 449         FNAME=get_xattr
 450         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 451                 && set -x
 452 
 453         typeset obj=$1
 454         typeset xattr
 455         if (( ${#obj} == 0 )); then
 456                 return 1
 457         fi
 458 
 459         for xattr in `$RUNAT $obj $LS | \
 460                 /usr/xpg4/bin/egrep -v -e SUNWattr_ro -e SUNWattr_rw` ; do
 461                 $RUNAT $obj $SUM $xattr || return 1
 462         done
 463 }
 464 
 465 #
 466 # Get the owner of a file/directory
 467 #
 468 function get_owner #node
 469 {
 470         FNAME=get_owner
 471         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 472                 && set -x
 473 
 474         typeset node=$1
 475         typeset value
 476 
 477         if [[ -z $node ]]; then
 478                 echo "node are not defined."
 479                 exit $STF_FAIL
 480         fi
 481 
 482         if [[ -d $node ]]; then
 483                 value=$($LS -dl $node | $AWK '{print $3}')
 484         elif [[ -e $node ]]; then
 485                 value=$($LS -l $node | $AWK '{print $3}')
 486         fi
 487 
 488         $ECHO $value
 489 }
 490 
 491 #
 492 # Get the group of a file/directory
 493 #
 494 function get_group #node
 495 {
 496         FNAME=get_group
 497         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 498                 && set -x
 499 
 500         typeset node=$1
 501         typeset value
 502 
 503         if [[ -z $node ]]; then
 504                 echo "node are not defined."
 505                 exit $STF_FAIL
 506         fi
 507 
 508         if [[ -d $node ]]; then
 509                 value=$($LS -dl $node | $AWK '{print $4}')
 510         elif [[ -e $node ]]; then
 511                 value=$($LS -l $node | $AWK '{print $4}')
 512         fi
 513 
 514         $ECHO $value
 515 }
 516 
 517 
 518 #
 519 # Get the group name that a UID belongs to
 520 #
 521 function get_user_group #uid
 522 {
 523         FNAME=get_user_group
 524         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 525                 && set -x
 526 
 527         typeset uid=$1
 528         typeset value
 529 
 530         if [[ -z $uid ]]; then
 531                 echo "UID not defined."
 532                 exit $STF_FAIL
 533         fi
 534 
 535         value=$(id $uid)
 536 
 537         if [[ $? -eq 0 ]]; then
 538                 value=${value##*\(}
 539                 value=${value%%\)*}
 540                 $ECHO $value
 541         else
 542                 echo "Invalid UID (uid)."
 543                 exit $STF_FAIL
 544         fi
 545 }
 546 
 547 #
 548 # Get the specified item of the specified string
 549 #
 550 # $1:   Item number, count from 0.
 551 # $2-n: strings
 552 #
 553 function getitem
 554 {
 555         FNAME=getitem
 556         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 557                 && set -x
 558 
 559         typeset -i n=$1
 560         shift
 561 
 562         (( n += 1 ))
 563         eval echo \${$n}
 564 }
 565 
 566 #
 567 # This function calculate the specified directory files checksum and write
 568 # to the specified array.
 569 #
 570 # $1 directory in which the files will be cksum.
 571 # $2 file array name which was used to store file cksum information.
 572 # $3 attribute array name which was used to store attribute information.
 573 #
 574 function cksum_files #<dir> <file_array_name> <attribute_array_name>
 575 {
 576         FNAME=cksum_files
 577         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 578                 && set -x
 579 
 580         typeset dir=$1
 581         typeset farr_name=$2
 582         typeset aarr_name=$3
 583 
 584         [[ ! -d $dir ]] && return
 585         typeset files=$($LS $dir/file*)
 586 
 587         typeset -i i=0
 588         typeset -i n=0
 589         while (( i < NUM_FILE )); do
 590                 typeset f=$(getitem $i $files)
 591                 RUN_CHECK eval $farr_name[$i]=\$\(\$CKSUM $f\) \
 592                         || cleanup $STF_FAIL
 593 
 594                 typeset -i j=0
 595                 while (( j < NUM_ATTR )); do
 596                         RUN_CHECK eval $aarr_name[$n]=\$\(\$RUNAT \$f \$CKSUM \
 597                                 attribute.$j\) || cleanup $STF_FAIL
 598 
 599                         (( j += 1 ))
 600                         (( n += 1 ))
 601                 done
 602 
 603                 (( i += 1 ))
 604         done
 605 }
 606 
 607 #
 608 # This function compare two cksum results array.
 609 #
 610 # $1 The array name which stored the cksum before operation.
 611 # $2 The array name which stored the cksum after operation.
 612 #
 613 function compare_cksum #<array1> <array2>
 614 {
 615         FNAME=compare_cksum
 616         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 617                 && set -x
 618 
 619         typeset before=$1
 620         typeset after=$2
 621         eval typeset -i count=\${#$before[@]}
 622 
 623         typeset -i i=0
 624         while (( i < count )); do
 625                 eval typeset var1=\${$before[$i]}
 626                 eval typeset var2=\${$after[$i]}
 627 
 628                 if [[ $var1 != $var2 ]]; then
 629                         return 1
 630                 fi
 631 
 632                 (( i += 1 ))
 633         done
 634 
 635         return 0
 636 }
 637 
 638 #
 639 # This function calculate all the files cksum information in current directory 
 640 # and output them to the specified file.
 641 #
 642 # $1 directory from which the files will be cksum.
 643 # $2 cksum output file
 644 #
 645 function record_cksum #<outfile>
 646 {
 647         FNAME=record_cksum
 648         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 649                 && set -x
 650 
 651         typeset dir=$1
 652         typeset outfile=$2
 653 
 654         [[ ! -d ${outfile%/*} ]] && usr_exec $MKDIR -p ${outfile%/*}
 655 
 656         usr_exec $FIND $dir -depth -type f -exec cksum {} \\\; \
 657                 > $STF_TMPDIR/cksum.$$ || return 1
 658         $SORT $STF_TMPDIR/cksum.$$ > $outfile
 659         usr_exec $FIND $dir -depth -type f -xattr -exec runat {} \
 660                 cksum attribute* \\\; > $STF_TMPDIR/cksum.$$ \
 661                 || return 1
 662         $SORT $STF_TMPDIR/cksum.$$ >> $outfile
 663         return 0
 664 }
 665 
 666 #
 667 # The function create_files creates the directories and files that the script 
 668 # will operate on to test extended attribute functionality.
 669 #
 670 # $1 The base directory in which to create directories and files.
 671 #
 672 function create_files #<directory>
 673 {
 674         FNAME=create_files
 675         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 676                 && set -x
 677 
 678         typeset basedir=$1
 679 
 680         [[ ! -d $basedir ]] && RUN_CHECK usr_exec $MKDIR -m 777 $basedir
 681         [[ ! -d $RES_DIR  ]] && RUN_CHECK usr_exec $MKDIR -m 777 $RES_DIR
 682         [[ ! -d $INI_DIR ]] && RUN_CHECK usr_exec $MKDIR -m 777 $INI_DIR
 683         [[ ! -d $TST_DIR ]] && RUN_CHECK usr_exec $MKDIR -m 777 $TST_DIR
 684         [[ ! -d $TMP_DIR  ]] && RUN_CHECK usr_exec $MKDIR -m 777 $TMP_DIR
 685 
 686         #
 687         # Create the original file and its attribute files.
 688         #
 689         if [[ ! -a $RES_DIR/file ]]; then 
 690                 RUN_CHECK "usr_exec \"$FILE_WRITE -W -c -o 4 -B \\\"1024 1 -1\\\" $RES_DIR/file\"" \
 691                         || cleanup $STF_FAIL
 692         fi
 693         if [[ ! -a $RES_DIR/attribute ]]; then
 694                 RUN_CHECK usr_exec $CP $RES_DIR/file $RES_DIR/attribute \
 695                         || cleanup $STF_FAIL
 696         fi
 697 
 698         typeset -i i=0
 699         while (( i < NUM_FILE )); do
 700                 typeset dstfile=$INI_DIR/file.$$.$i
 701                 RUN_CHECK usr_exec $CP $RES_DIR/file $dstfile \
 702                         || cleanup $STF_FAIL
 703 
 704                 typeset -i j=0
 705                 while (( j < NUM_ATTR )); do
 706                         RUN_CHECK usr_exec $RUNAT $dstfile \
 707                                 $CP $STF_SUITE/STF.INFO ./attribute.$j \
 708                                 || cleanup $STF_FAIL
 709                         (( j += 1 ))
 710                 done
 711 
 712                 (( i += 1 ))
 713         done
 714 }
 715 
 716 
 717 #
 718 # The function remount the server's fs with appended option, which can be 
 719 # used to disable the attribute cache with "noac" option for some tests 
 720 #
 721 # $1 the option which is appended.
 722 #
 723 function do_remount #<option>
 724 {
 725         FNAME=do_remount
 726         [[ :$NFSGEN_DEBUG: = *:${FNAME}:* || :${NFSGEN_DEBUG}: = *:all:* ]] \
 727                 && set -x
 728         
 729         typeset opt=$1
 730         typeset mntdir
 731 
 732         [[ $opt != "" ]] && opt=",$opt"
 733         [[ $SETUP == none ]] && mntdir=$realMNT || mntdir=$MNTDIR
 734         [[ $MNTOPT == "" ]] && MNTOPT="rw"
 735 
 736         RUN_CHECK $UMOUNT $mntdir || return 1
 737         RUN_CHECK $MOUNT -o $MNTOPT$opt $SERVER:$SHRDIR $mntdir \
 738                 || return 1
 739 
 740         return 0
 741 }