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 2006 Sun Microsystems, Inc.  All rights reserved.
  24 # Use is subject to license terms.
  25 #
  26 # NFSv4 READDIR operation test - positive tests
  27 
  28 # include all test enironment
  29 source READDIR.env
  30 
  31 Connect
  32 
  33 # setting local variables
  34 set TNAME $argv0
  35 set bfh [get_fh "$BASEDIRS"]
  36 
  37 
  38 # Start testing
  39 # --------------------------------------------------------------
  40 # a: Readdir of a small dir w/simple attrs, expect OK
  41 set expcode "OK"
  42 set ASSERTION "Readdir of a small dir w/simple attrs, expect $expcode"
  43 set tag "$TNAME{a}"
  44 putmsg stdout 0 "$tag: $ASSERTION"
  45 set attrs "type mode"
  46 set res [compound {Putfh $bfh; Lookup $env(DIR0777); Getfh;
  47         Readdir 0 0 2048 2048 $attrs; Getfh}]
  48 set cont [ckres "Readdir" $status $expcode $res $FAIL]
  49 # verify the readdir results
  50   if {! [string equal $cont "false"]} {
  51     # check of eof, should be true for small directory
  52     set eof [lindex [lindex $res 3] 4]
  53     if {! [string equal $eof "true"]} {
  54         putmsg stderr 0 "\t Test FAIL: eof flag is not true."
  55         putmsg stderr 1 "\t   res=($res)"
  56         putmsg stderr 1 "\t   eof=($eof)"
  57         set cont false
  58     } else {
  59       # verify the attributes returned
  60       set rdres [lindex [lindex $res 3] 3]
  61       foreach d $rdres {
  62         set al [lindex $d 2]
  63         foreach a $al {
  64           set an [lindex $a 0]
  65           if {! [string equal $an "type"] && ! [string equal $an "mode"]} {
  66             putmsg stderr 0 "\t Test FAIL: attr(type|mode) was not returned."
  67             putmsg stderr 1 "\t   an=($an)"
  68             putmsg stderr 1 "\t   dir-entry=($d)"
  69             putmsg stderr 1 "\t   res=($res)"
  70             putmsg stderr 1 "  "
  71             set cont false
  72             break
  73           }
  74         }
  75       }
  76     }
  77   }
  78 # verify FH is not changed after successful Readdir op
  79   set fh1 [lindex [lindex $res 2] 2]
  80   set fh2 [lindex [lindex $res 4] 2]
  81   fh_equal $fh1 $fh2 $cont $PASS
  82 
  83 
  84 # b: Readdir of a dir w/r-x access, expect OK
  85 set expcode "OK"
  86 set ASSERTION "Readdir of a dir w/r-x access, expect $expcode"
  87 set tag "$TNAME{b}"
  88 putmsg stdout 0 "$tag: $ASSERTION"
  89 set attrs "fh_expire_type"
  90 set res [compound {Putfh $bfh; Lookup $env(DIR0755); Getfh;
  91         Readdir 0 0 512 512 $attrs; Getfh}]
  92 set cont [ckres "Readdir" $status $expcode $res $FAIL]
  93 # verify the readdir results
  94   if {! [string equal $cont "false"]} {
  95       # verify the attributes returned
  96       set rdres [lindex [lindex $res 3] 3]
  97       foreach d $rdres {
  98         set al [lindex $d 2]
  99         foreach a $al {
 100           set an [lindex $a 0]
 101           if {! [string equal $an "fh_expire_type"]} {
 102             putmsg stderr 0 \
 103                 "\t Test FAIL: attr(fh_expire_type) was not returned."
 104             putmsg stderr 1 "\t   an=($an)"
 105             putmsg stderr 1 "\t   dir-entry=($d)"
 106             putmsg stderr 1 "\t   res=($res)"
 107             putmsg stderr 1 "  "
 108             set cont false
 109             break
 110           }
 111         }
 112       }
 113   }
 114 # verify FH is not changed after successful Readdir op
 115   set fh1 [lindex [lindex $res 2] 2]
 116   set fh2 [lindex [lindex $res 4] 2]
 117   fh_equal $fh1 $fh2 $cont $PASS
 118 
 119 
 120 # c: Readdir w/largedir can continue reading, expect OK
 121 set expcode "OK"
 122 set ASSERTION "Readdir w/largedir can continue reading, expect $expcode"
 123 set tag "$TNAME{c}"
 124 putmsg stdout 0 "$tag: $ASSERTION"
 125 set dfh [get_fh "$BASEDIRS $env(LARGEDIR)"]
 126 set cookie 0
 127 set verf 0
 128 set eof false
 129 set count_ent 0
 130 while {$eof != "true"} {
 131     set res [compound {Putfh $dfh; 
 132         Readdir $cookie $verf 1024 1024 {size time_modify}; Getfh}]
 133     set cont [ckres "Readdir" $status $expcode $res $FAIL]
 134 
 135     # verify eof is set correctly for continue reading
 136     set eof [lindex [lindex $res 1] 4]
 137     set verf [lindex [lindex $res 1] 2]
 138     # verify the attributes returned
 139     set rdres [lindex [lindex $res 1] 3]
 140     foreach d $rdres {
 141         incr count_ent
 142         if {$count_ent >= 20000} {
 143                 # got too many entries, something is wrong
 144                 # to quit the while
 145                 set eof "true"
 146                 set count_ent -1
 147                 set errormsg "Too many directory entries"
 148                 break
 149         }
 150         set al [lindex $d 2]
 151         foreach a $al {
 152           set an [lindex $a 0]
 153           if {! [string equal $an "size"] && 
 154                 ! [string equal $an "time_modify"]} {
 155             putmsg stderr 0 \
 156                 "\t Test FAIL: attr(size|time_modify) was not returned."
 157             putmsg stderr 1 "\t   an=($an)"
 158             putmsg stderr 1 "\t   dir-entry=($d)"
 159             putmsg stderr 1 "\t   res=($res)"
 160             putmsg stderr 1 "  "
 161             set cont false
 162             # to quit the while
 163             set eof "true"
 164             break
 165           }
 166         }
 167     }
 168     set cookie [lindex [lindex $rdres end] 0]
 169 }
 170 # check problem was not attributes related (message already printed).
 171 if {$count_ent == -1} {
 172         putmsg stderr 0 "\t Test FAIL: $errormsg"
 173 } else {
 174         # verify FH is not changed after successful Readdir op
 175         set fh1 [lindex [lindex $res 2] 2]
 176         fh_equal $fh1 $dfh $cont $PASS
 177 }
 178 
 179 
 180 # d: Readdir down a long path based on FH attr, expect OK
 181 set expcode "OK"
 182 set ASSERTION "Readdir down a long path based on FH attr, expect $expcode"
 183 set tag "$TNAME{d}"
 184 putmsg stdout 0 "$tag: $ASSERTION"
 185 set dlist [path2comp $env(LONGDIR) $DELM]
 186 set first [lindex $dlist 0]
 187 set dlast [lindex $dlist end]
 188 set nfh [get_fh "$BASEDIRS $first"]
 189 foreach d [lrange $dlist 1 end ] {
 190     set res [compound {Putfh $nfh; 
 191         Readdir 0 0 513 1024 filehandle; Getfh}]
 192     putmsg stdout 1 "d=<$d> res=<$res>"
 193     set cont [ckres "Readdir/$d" $status $expcode $res $FAIL] 
 194     if {$cont == "true"} {
 195         set gfh [lindex [lindex $res 2] 2]
 196         set rdres [lindex [lindex $res 1] 3]
 197         foreach en $rdres {
 198             # find the entry of next nodes and get its FH
 199             if {[lindex $en 1] == "$d"} {
 200                 set nfh [lindex [lindex [lindex $en 2] 0] 1]
 201                 break
 202             }
 203         }
 204         # if not the last node, the path is broken
 205         if {($nfh == $gfh) && ($d != $dlast)} {
 206             putmsg stderr 0 "\t Test UNRESOLVED: can't find next node."
 207             putmsg stderr 0 "\t   d=<$d>, dlast=<$dlast>"
 208             putmsg stderr 0 "\t   nfh=<$nfh>"
 209             putmsg stderr 0 "\t   gfh=<$gfh>"
 210             putmsg stderr 1 "\t res=<$res>"
 211             set cont "false"
 212             break
 213         } else {
 214             set gfh $nfh
 215         }
 216     } else {
 217         break
 218     }
 219 }
 220 # finally verify the FH of last node
 221 if {$cont == "true"} {
 222     set efh [get_fh "$BASEDIRS [path2comp $env(LONGDIR) $DELM]"]
 223     if {$gfh != $efh} {
 224         putmsg stderr 0 "\t Test FAIL: incorrect FH of last node."
 225         putmsg stderr 1 "\t     expected=($efh)"
 226         putmsg stderr 1 "\t     gottheFH=($gfh)"
 227     } else {
 228         logres PASS
 229     }
 230 }
 231 
 232 
 233 # i: Readdir w/dircount=0, expect OK
 234 # XXX spec says: p164 "Since it is a hint, it may be possible that
 235 #     a dircount value is zero".
 236 set expcode "OK"
 237 set ASSERTION "Readdir w/dircount=0, expect $expcode"
 238 set tag "$TNAME{i}"
 239 putmsg stdout 0 "$tag: $ASSERTION"
 240 set attrs "named_attr"
 241 set dircount 0
 242 set res [compound {Putfh $bfh; Lookup $env(DIR0777); Getfh;
 243         Readdir 0 0 $dircount 512 $attrs; Getfh}]
 244 set cont [ckres "Readdir" $status $expcode $res $FAIL]
 245 # verify the readdir results
 246   if {! [string equal $cont "false"]} {
 247     # check of eof, should be true for small directory
 248     set eof [lindex [lindex $res 3] 4]
 249     if {! [string equal $eof "true"]} {
 250         putmsg stderr 0 "\t Test FAIL: eof flag is not true."
 251         putmsg stderr 1 "\t   res=($res)"
 252         putmsg stderr 1 "\t   eof=($eof)"
 253         set cont false
 254     } else {
 255       # verify the attributes returned
 256       set rdres [lindex [lindex $res 3] 3]
 257       foreach d $rdres {
 258         set al [lindex $d 2]
 259         foreach a $al {
 260           set an [lindex $a 0]
 261           if {! [string equal $an "named_attr"]} {
 262             putmsg stderr 0 "\t Test FAIL: attr(named_attr) was not returned."
 263             putmsg stderr 1 "\t   an=($an)"
 264             putmsg stderr 1 "\t   dir-entry=($d)"
 265             putmsg stderr 1 "\t   res=($res)"
 266             putmsg stderr 1 "  "
 267             set cont false
 268             break
 269           }
 270         }
 271       }
 272     }
 273   }
 274 # verify FH is not changed after successful Readdir op
 275   set fh1 [lindex [lindex $res 2] 2]
 276   set fh2 [lindex [lindex $res 4] 2]
 277   fh_equal $fh1 $fh2 $cont $PASS
 278 
 279 
 280 # m: Readdir w/rdattr_error set, expect OK
 281 # XXX Even getattr may fail, but Readdir should return OK.
 282 set expcode "OK"
 283 set ASSERTION "Readdir w/rdattr_error set, expect $expcode"
 284 set tag "$TNAME{m}"
 285 putmsg stdout 0 "$tag: $ASSERTION"
 286 set attrs "acl named_attr hidden fs_locations rdattr_error"
 287 set res [compound {Putfh $bfh; Getfh;
 288         Readdir 0 0 2048 2048 $attrs; Getfh}]
 289 set cont [ckres "Readdir" $status $expcode $res $FAIL]
 290 # verify FH is not changed after successful Readdir op
 291   set fh1 [lindex [lindex $res 1] 2]
 292   set fh2 [lindex [lindex $res 3] 2]
 293   fh_equal $fh1 $fh2 $cont $PASS
 294 
 295 
 296 # n: Readdir with maxcount>32K, expect OK
 297 set expcode "OK"
 298 set ASSERTION "Readdir with maxcount > 32K, $expcode"
 299 set tag "$TNAME{n}"
 300 putmsg stdout 0 "$tag: $ASSERTION"
 301 set maxcount 66688
 302 set res [compound {Putfh $bfh; Getfh;
 303         Readdir 0 0 2048 $maxcount {type size mode}; Getfh}]
 304 set cont [ckres "Readdir" $status $expcode $res $FAIL]
 305 # verify FH is not changed after successful Readdir op
 306   set fh1 [lindex [lindex $res 1] 2]
 307   set fh2 [lindex [lindex $res 3] 2]
 308   fh_equal $fh1 $fh2 $cont $PASS
 309 
 310 
 311 # o: Readdir without any attr request for regular dir, expect OK
 312 set expcode "OK"
 313 set ASSERTION "Readdir regular dir w/no attribute request, expect $expcode"
 314 set tag "$TNAME{o}"
 315 putmsg stdout 0 "$tag: $ASSERTION"
 316 set dfh [get_fh "$BASEDIRS $env(LARGEDIR)"]
 317 set cookie 0
 318 set verf 0
 319 # first get some subdir names
 320 set res [compound {Putfh $dfh; Readdir $cookie $verf 1024 4097 {type}}]
 321 putmsg stderr 1 "First Readdir w/type attr, res=$res"
 322 set cont [ckres "Readdir" $status $expcode $res $FAIL]
 323 if {! [string equal $cont "false"]} {
 324     # then Readdir of the subdirs without attr
 325     set rdres [lindex [lindex $res 1] 3]
 326     foreach en $rdres {
 327         set dname [lindex $en 1]
 328         set dtype [lindex [lindex [lindex $en 2] 0] 1]
 329         putmsg stderr 1 "dname=$dname, dtype=$dtype"
 330         # only interested in type=dir
 331         if { "$dtype" == "dir"} {
 332             set res2 [compound {Putfh $dfh; Lookup $dname; Getfh;
 333                 Readdir $cookie $verf 1024 1023 {}; Getfh}]
 334             putmsg stderr 1 "  res=$res2"
 335             set cont [ckres "Readdir-$dname" $status $expcode $res $FAIL]
 336             # only need to print one FAIL message
 337             if {[string equal $cont "false"]} {
 338                 break
 339             }
 340             set rdres2 [lindex [lindex $res 3] 3]
 341             foreach en $rdres2 {
 342                 set dname [lindex $en 1]
 343                 set en_attr [lindex [lindex $en 2] 0]
 344                 putmsg stderr 1 "entry=$en, en_attr=<$en_attr>"
 345                 if { "x$en_attr" != "x"} {
 346                     putmsg stderr 0 \
 347                         "\t Test FAIL: server unexpectedly returned attr:"
 348                     putmsg stderr 0 \
 349                         "\t\t for entry($dname) with attr($en_attr)."
 350                     set cont "false"
 351                     break
 352                 }
 353             }
 354             if {[string equal $cont "false"]} {
 355                 break
 356             }
 357             set fh1 [lindex [lindex $res 2] 2]
 358             set fh2 [lindex [lindex $res 4] 2]
 359             set cont [fh_equal $fh1 $fh2 $cont $FAIL]
 360         }
 361     }
 362     if {! [string equal $cont "false"]} {
 363         ckres "Readdir2" $status $expcode $res $PASS
 364     }
 365 }
 366 
 367 
 368 # p: Readdir Named-attr dir without any attr request, expect OK
 369 set expcode "OK"
 370 set ASSERTION "Readdir named-attr dir w/no attribute request, expect $expcode"
 371 set tag "$TNAME{p}"
 372 putmsg stdout 0 "$tag: $ASSERTION"
 373 set res [compound {Putfh $bfh; Lookup $env(ATTRFILE); Openattr f; 
 374         Getfh; Readdir 0 0 1023 1025 {}; Getfh }]
 375 putmsg stderr 1 "Readdir($env(ATTRFILE)), res=$res"
 376 set cont [ckres "Readdir" $status $expcode $res $FAIL]
 377 # Now verify server returned no attribute
 378 if {! [string equal $cont "false"]} {
 379     set rdres [lindex [lindex $res 4] 3]
 380     foreach en $rdres {
 381         set dname [lindex $en 1]
 382         set en_attr [lindex [lindex $en 2] 0]
 383         putmsg stderr 1 "entry=$en, en_attr=<$en_attr>"
 384         if { "x$en_attr" != "x"} {
 385             putmsg stderr 0 "\t Test FAIL: server unexpectedly returned attr:"
 386             putmsg stderr 0 "\t\t for entry($dname) with attr($en_attr)."
 387             set cont "false"
 388             break
 389         }
 390     }
 391     if {! [string equal $cont "false"]} {
 392         # verify FH is not changed after successful Readdir op
 393         set fh1 [lindex [lindex $res 3] 2]
 394         set fh2 [lindex [lindex $res 5] 2]
 395         fh_equal $fh1 $fh2 $cont $PASS
 396     }
 397 }
 398 
 399 
 400 # --------------------------------------------------------------
 401 # disconnect and exit
 402 Disconnect
 403 exit $PASS