Whamcloud - gitweb
LU-7931 tests: setup/cleanup after every test script
[fs/lustre-release.git] / lustre / tests / sanity-sec.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10 # bug number for skipped test: 19430 19967 19967
11 ALWAYS_EXCEPT="                2     5     6    $SANITY_SEC_EXCEPT"
12 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
13
14 SRCDIR=$(dirname $0)
15 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
16 export NAME=${NAME:-local}
17
18 LUSTRE=${LUSTRE:-$(dirname $0)/..}
19 . $LUSTRE/tests/test-framework.sh
20 init_test_env $@
21 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
22 init_logging
23
24 NODEMAP_TESTS=$(seq 7 26)
25
26 if ! check_versions; then
27         echo "It is NOT necessary to test nodemap under interoperation mode"
28         EXCEPT="$EXCEPT $NODEMAP_TESTS"
29 fi
30
31 [ "$SLOW" = "no" ] && EXCEPT_SLOW="26"
32
33 [ "$ALWAYS_EXCEPT$EXCEPT$EXCEPT_SLOW" ] &&
34         echo "Skipping tests: $ALWAYS_EXCEPT $EXCEPT $EXCEPT_SLOW"
35
36 RUNAS_CMD=${RUNAS_CMD:-runas}
37
38 WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
39
40 CONFDIR=/etc/lustre
41 PERM_CONF=$CONFDIR/perm.conf
42 FAIL_ON_ERROR=false
43
44 HOSTNAME_CHECKSUM=$(hostname | sum | awk '{ print $1 }')
45 SUBNET_CHECKSUM=$(expr $HOSTNAME_CHECKSUM % 250 + 1)
46 NODEMAP_COUNT=16
47 NODEMAP_RANGE_COUNT=3
48 NODEMAP_IPADDR_LIST="1 10 64 128 200 250"
49 NODEMAP_MAX_ID=128
50
51 require_dsh_mds || exit 0
52 require_dsh_ost || exit 0
53
54 clients=${CLIENTS//,/ }
55 num_clients=$(get_node_count ${clients})
56 clients_arr=($clients)
57
58 ID0=${ID0:-500}
59 ID1=${ID1:-501}
60 USER0=$(getent passwd | grep :$ID0:$ID0: | cut -d: -f1)
61 USER1=$(getent passwd | grep :$ID1:$ID1: | cut -d: -f1)
62
63 [ -z "$USER0" ] &&
64         skip "need to add user0 ($ID0:$ID0)" && exit 0
65
66 [ -z "$USER1" ] &&
67         skip "need to add user1 ($ID1:$ID1)" && exit 0
68
69 IDBASE=${IDBASE:-60000}
70
71 # changes to mappings must be reflected in test 23
72 FOPS_IDMAPS=(
73         [0]="$((IDBASE+3)):$((IDBASE+0)) $((IDBASE+4)):$((IDBASE+2))"
74         [1]="$((IDBASE+5)):$((IDBASE+1)) $((IDBASE+6)):$((IDBASE+2))"
75         )
76
77 check_and_setup_lustre
78
79 sec_cleanup() {
80         if [ "$I_MOUNTED" = "yes" ]; then
81                 cleanupall -f || error "sec_cleanup"
82         fi
83 }
84
85 DIR=${DIR:-$MOUNT}
86 [ -z "$(echo $DIR | grep $MOUNT)" ] &&
87         error "$DIR not in $MOUNT" && sec_cleanup && exit 1
88
89 [ $(echo $MOUNT | wc -w) -gt 1 ] &&
90         echo "NAME=$MOUNT mounted more than once" && sec_cleanup && exit 0
91
92 # for GSS_SUP
93 GSS_REF=$(lsmod | grep ^ptlrpc_gss | awk '{print $3}')
94 if [ ! -z "$GSS_REF" -a "$GSS_REF" != "0" ]; then
95         GSS_SUP=1
96         echo "with GSS support"
97 else
98         GSS_SUP=0
99         echo "without GSS support"
100 fi
101
102 MDT=$(do_facet $SINGLEMDS lctl get_param -N "mdt.\*MDT0000" |
103         cut -d. -f2 || true)
104 [ -z "$MDT" ] && error "fail to get MDT device" && exit 1
105 do_facet $SINGLEMDS "mkdir -p $CONFDIR"
106 IDENTITY_FLUSH=mdt.$MDT.identity_flush
107 IDENTITY_UPCALL=mdt.$MDT.identity_upcall
108 MDSSECLEVEL=mdt.$MDT.sec_level
109
110 SAVE_PWD=$PWD
111
112 build_test_filter
113
114 sec_login() {
115         local user=$1
116         local group=$2
117
118         if ! $RUNAS_CMD -u $user krb5_login.sh; then
119                 error "$user login kerberos failed."
120                 exit 1
121         fi
122
123         if ! $RUNAS_CMD -u $user -g $group ls $DIR > /dev/null 2>&1; then
124                 $RUNAS_CMD -u $user lfs flushctx -k
125                 $RUNAS_CMD -u $user krb5_login.sh
126                 if ! $RUNAS_CMD -u$user -g$group ls $DIR > /dev/null 2>&1; then
127                         error "init $user $group failed."
128                         exit 2
129                 fi
130         fi
131 }
132
133 declare -a identity_old
134
135 sec_setup() {
136         for num in $(seq $MDSCOUNT); do
137                 switch_identity $num true || identity_old[$num]=$?
138         done
139
140         if ! $RUNAS_CMD -u $ID0 ls $DIR > /dev/null 2>&1; then
141                 sec_login $USER0 $USER0
142         fi
143
144         if ! $RUNAS_CMD -u $ID1 ls $DIR > /dev/null 2>&1; then
145                 sec_login $USER1 $USER1
146         fi
147 }
148 sec_setup
149
150 # run as different user
151 test_0() {
152         umask 0022
153
154         chmod 0755 $DIR || error "chmod (1)"
155         rm -rf $DIR/$tdir || error "rm (1)"
156         mkdir -p $DIR/$tdir || error "mkdir (1)"
157         chown $USER0 $DIR/$tdir || error "chown (2)"
158         $RUNAS_CMD -u $ID0 ls $DIR || error "ls (1)"
159         rm -f $DIR/f0 || error "rm (2)"
160         $RUNAS_CMD -u $ID0 touch $DIR/f0 && error "touch (1)"
161         $RUNAS_CMD -u $ID0 touch $DIR/$tdir/f1 || error "touch (2)"
162         $RUNAS_CMD -u $ID1 touch $DIR/$tdir/f2 && error "touch (3)"
163         touch $DIR/$tdir/f3 || error "touch (4)"
164         chown root $DIR/$tdir || error "chown (3)"
165         chgrp $USER0 $DIR/$tdir || error "chgrp (1)"
166         chmod 0775 $DIR/$tdir || error "chmod (2)"
167         $RUNAS_CMD -u $ID0 touch $DIR/$tdir/f4 || error "touch (5)"
168         $RUNAS_CMD -u $ID1 touch $DIR/$tdir/f5 && error "touch (6)"
169         touch $DIR/$tdir/f6 || error "touch (7)"
170         rm -rf $DIR/$tdir || error "rm (3)"
171 }
172 run_test 0 "uid permission ============================="
173
174 # setuid/gid
175 test_1() {
176         [ $GSS_SUP = 0 ] && skip "without GSS support." && return
177
178         rm -rf $DIR/$tdir
179         mkdir -p $DIR/$tdir
180
181         chown $USER0 $DIR/$tdir || error "chown (1)"
182         $RUNAS_CMD -u $ID1 -v $ID0 touch $DIR/$tdir/f0 && error "touch (2)"
183         echo "enable uid $ID1 setuid"
184         do_facet $SINGLEMDS "echo '* $ID1 setuid' >> $PERM_CONF"
185         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
186         $RUNAS_CMD -u $ID1 -v $ID0 touch $DIR/$tdir/f1 || error "touch (3)"
187
188         chown root $DIR/$tdir || error "chown (4)"
189         chgrp $USER0 $DIR/$tdir || error "chgrp (5)"
190         chmod 0770 $DIR/$tdir || error "chmod (6)"
191         $RUNAS_CMD -u $ID1 -g $ID1 touch $DIR/$tdir/f2 && error "touch (7)"
192         $RUNAS_CMD -u$ID1 -g$ID1 -j$ID0 touch $DIR/$tdir/f3 && error "touch (8)"
193         echo "enable uid $ID1 setuid,setgid"
194         do_facet $SINGLEMDS "echo '* $ID1 setuid,setgid' > $PERM_CONF"
195         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
196         $RUNAS_CMD -u $ID1 -g $ID1 -j $ID0 touch $DIR/$tdir/f4 ||
197                 error "touch (9)"
198         $RUNAS_CMD -u $ID1 -v $ID0 -g $ID1 -j $ID0 touch $DIR/$tdir/f5 ||
199                 error "touch (10)"
200
201         rm -rf $DIR/$tdir
202
203         do_facet $SINGLEMDS "rm -f $PERM_CONF"
204         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
205 }
206 run_test 1 "setuid/gid ============================="
207
208 # bug 3285 - supplementary group should always succeed.
209 # NB: the supplementary groups are set for local client only,
210 # as for remote client, the groups of the specified uid on MDT
211 # will be obtained by upcall /sbin/l_getidentity and used.
212 test_4() {
213         local server_version=$(lustre_version_code $SINGLEMDS)
214
215         [[ $server_version -ge $(version_code 2.6.93) ]] ||
216         [[ $server_version -ge $(version_code 2.5.35) &&
217            $server_version -lt $(version_code 2.5.50) ]] ||
218                 { skip "Need MDS version at least 2.6.93 or 2.5.35"; return; }
219
220         rm -rf $DIR/$tdir
221         mkdir -p $DIR/$tdir
222         chmod 0771 $DIR/$tdir
223         chgrp $ID0 $DIR/$tdir
224         $RUNAS_CMD -u $ID0 ls $DIR/$tdir || error "setgroups (1)"
225         do_facet $SINGLEMDS "echo '* $ID1 setgrp' > $PERM_CONF"
226         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
227         $RUNAS_CMD -u $ID1 -G1,2,$ID0 ls $DIR/$tdir ||
228                 error "setgroups (2)"
229         $RUNAS_CMD -u $ID1 -G1,2 ls $DIR/$tdir && error "setgroups (3)"
230         rm -rf $DIR/$tdir
231
232         do_facet $SINGLEMDS "rm -f $PERM_CONF"
233         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
234 }
235 run_test 4 "set supplementary group ==============="
236
237 create_nodemaps() {
238         local i
239         local out
240         local rc
241
242         squash_id default 99 0
243         squash_id default 99 1
244         for (( i = 0; i < NODEMAP_COUNT; i++ )); do
245                 local csum=${HOSTNAME_CHECKSUM}_${i}
246
247                 if ! do_facet mgs $LCTL nodemap_add $csum; then
248                         return 1
249                 fi
250
251                 out=$(do_facet mgs $LCTL get_param nodemap.$csum.id)
252                 ## This needs to return zero if the following statement is 1
253                 [[ $(echo $out | grep -c $csum) == 0 ]] && return 1
254         done
255         return 0
256 }
257
258 delete_nodemaps() {
259         local i
260         local out
261
262         for ((i = 0; i < NODEMAP_COUNT; i++)); do
263                 local csum=${HOSTNAME_CHECKSUM}_${i}
264
265                 if ! do_facet mgs $LCTL nodemap_del $csum; then
266                         error "nodemap_del $csum failed with $?"
267                         return 3
268                 fi
269
270                 out=$(do_facet mgs $LCTL get_param nodemap.$csum.id)
271                 [[ $(echo $out | grep -c $csum) != 0 ]] && return 1
272         done
273         return 0
274 }
275
276 add_range() {
277         local j
278         local cmd="$LCTL nodemap_add_range"
279         local range
280         local rc=0
281
282         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
283                 range="$SUBNET_CHECKSUM.${2}.${j}.[1-253]@tcp"
284                 if ! do_facet mgs $cmd --name $1 --range $range; then
285                         rc=$((rc + 1))
286                 fi
287         done
288         return $rc
289 }
290
291 delete_range() {
292         local j
293         local cmd="$LCTL nodemap_del_range"
294         local range
295         local rc=0
296
297         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
298                 range="$SUBNET_CHECKSUM.${2}.${j}.[1-253]@tcp"
299                 if ! do_facet mgs $cmd --name $1 --range $range; then
300                         rc=$((rc + 1))
301                 fi
302         done
303
304         return $rc
305 }
306
307 add_idmaps() {
308         local i
309         local cmd="$LCTL nodemap_add_idmap"
310         local rc=0
311
312         for ((i = 0; i < NODEMAP_COUNT; i++)); do
313                 local j
314
315                 for ((j = 500; j < NODEMAP_MAX_ID; j++)); do
316                         local csum=${HOSTNAME_CHECKSUM}_${i}
317                         local client_id=$j
318                         local fs_id=$((j + 1))
319
320                         if ! do_facet mgs $cmd --name $csum --idtype uid \
321                              --idmap $client_id:$fs_id; then
322                                 rc=$((rc + 1))
323                         fi
324                         if ! do_facet mgs $cmd --name $csum --idtype gid \
325                              --idmap $client_id:$fs_id; then
326                                 rc=$((rc + 1))
327                         fi
328                 done
329         done
330
331         return $rc
332 }
333
334 delete_idmaps() {
335         local i
336         local cmd="$LCTL nodemap_del_idmap"
337         local rc=0
338
339         for ((i = 0; i < NODEMAP_COUNT; i++)); do
340                 local j
341
342                 for ((j = 500; j < NODEMAP_MAX_ID; j++)); do
343                         local csum=${HOSTNAME_CHECKSUM}_${i}
344                         local client_id=$j
345                         local fs_id=$((j + 1))
346
347                         if ! do_facet mgs $cmd --name $csum --idtype uid \
348                              --idmap $client_id:$fs_id; then
349                                 rc=$((rc + 1))
350                         fi
351                         if ! do_facet mgs $cmd --name $csum --idtype gid \
352                              --idmap $client_id:$fs_id; then
353                                 rc=$((rc + 1))
354                         fi
355                 done
356         done
357
358         return $rc
359 }
360
361 modify_flags() {
362         local i
363         local proc
364         local option
365         local cmd="$LCTL nodemap_modify"
366         local rc=0
367
368         proc[0]="admin_nodemap"
369         proc[1]="trusted_nodemap"
370         option[0]="admin"
371         option[1]="trusted"
372
373         for ((idx = 0; idx < 2; idx++)); do
374                 if ! do_facet mgs $cmd --name $1 --property ${option[$idx]} \
375                      --value 1; then
376                         rc=$((rc + 1))
377                 fi
378
379                 if ! do_facet mgs $cmd --name $1 --property ${option[$idx]} \
380                      --value 0; then
381                         rc=$((rc + 1))
382                 fi
383         done
384
385         return $rc
386 }
387
388 squash_id() {
389         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
390                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
391                 return
392         local cmd
393
394         cmd[0]="$LCTL nodemap_modify --property squash_uid"
395         cmd[1]="$LCTL nodemap_modify --property squash_gid"
396
397         if ! do_facet mgs ${cmd[$3]} --name $1 --value $2; then
398                 return 1
399         fi
400 }
401
402 # ensure that the squash defaults are the expected defaults
403 squash_id default 99 0
404 squash_id default 99 1
405
406 test_nid() {
407         local cmd
408
409         cmd="$LCTL nodemap_test_nid"
410
411         nid=$(do_facet mgs $cmd $1)
412
413         if [ $nid == $2 ]; then
414                 return 0
415         fi
416
417         return 1
418 }
419
420 test_idmap() {
421         local i
422         local cmd="$LCTL nodemap_test_id"
423         local rc=0
424
425         ## nodemap deactivated
426         if ! do_facet mgs $LCTL nodemap_activate 0; then
427                 return 1
428         fi
429         for ((id = 500; id < NODEMAP_MAX_ID; id++)); do
430                 local j
431
432                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
433                         local nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
434                         local fs_id=$(do_facet mgs $cmd --nid $nid      \
435                                       --idtype uid --id $id)
436                         if [ $fs_id != $id ]; then
437                                 echo "expected $id, got $fs_id"
438                                 rc=$((rc + 1))
439                         fi
440                 done
441         done
442
443         ## nodemap activated
444         if ! do_facet mgs $LCTL nodemap_activate 1; then
445                 return 2
446         fi
447
448         for ((id = 500; id < NODEMAP_MAX_ID; id++)); do
449                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
450                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
451                         fs_id=$(do_facet mgs $cmd --nid $nid    \
452                                 --idtype uid --id $id)
453                         expected_id=$((id + 1))
454                         if [ $fs_id != $expected_id ]; then
455                                 echo "expected $expected_id, got $fs_id"
456                                 rc=$((rc + 1))
457                         fi
458                 done
459         done
460
461         ## trust client ids
462         for ((i = 0; i < NODEMAP_COUNT; i++)); do
463                 local csum=${HOSTNAME_CHECKSUM}_${i}
464
465                 if ! do_facet mgs $LCTL nodemap_modify --name $csum \
466                      --property trusted --value 1; then
467                         error "nodemap_modify $csum failed with $?"
468                         return 3
469                 fi
470         done
471
472         for ((id = 500; id < NODEMAP_MAX_ID; id++)); do
473                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
474                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
475                         fs_id=$(do_facet mgs $cmd --nid $nid    \
476                                 --idtype uid --id $id)
477                         if [ $fs_id != $id ]; then
478                                 echo "expected $id, got $fs_id"
479                                 rc=$((rc + 1))
480                         fi
481                 done
482         done
483
484         ## ensure allow_root_access is enabled
485         for ((i = 0; i < NODEMAP_COUNT; i++)); do
486                 local csum=${HOSTNAME_CHECKSUM}_${i}
487
488                 if ! do_facet mgs $LCTL nodemap_modify --name $csum     \
489                      --property admin --value 1; then
490                         error "nodemap_modify $csum failed with $?"
491                         return 3
492                 fi
493         done
494
495         ## check that root allowed
496         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
497                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
498                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
499                 if [ $fs_id != 0 ]; then
500                         echo "root allowed expected 0, got $fs_id"
501                         rc=$((rc + 1))
502                 fi
503         done
504
505         ## ensure allow_root_access is disabled
506         for ((i = 0; i < NODEMAP_COUNT; i++)); do
507                 local csum=${HOSTNAME_CHECKSUM}_${i}
508
509                 if ! do_facet mgs $LCTL nodemap_modify --name $csum     \
510                                 --property admin --value 0; then
511                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
512                                 "failed with $rc"
513                         return 3
514                 fi
515         done
516
517         ## check that root is mapped to 99
518         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
519                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
520                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
521                 if [ $fs_id != 99 ]; then
522                         error "root squash expected 99, got $fs_id"
523                         rc=$((rc + 1))
524                 fi
525         done
526
527         ## reset client trust to 0
528         for ((i = 0; i < NODEMAP_COUNT; i++)); do
529                 if ! do_facet mgs $LCTL nodemap_modify          \
530                         --name ${HOSTNAME_CHECKSUM}_${i}        \
531                         --property trusted --value 0; then
532                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
533                                 "failed with $rc"
534                         return 3
535                 fi
536         done
537
538         return $rc
539 }
540
541 test_7() {
542         local rc
543
544         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
545         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
546                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
547                 return
548
549         create_nodemaps
550         rc=$?
551         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
552
553         delete_nodemaps
554         rc=$?
555         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 2
556
557         return 0
558 }
559 run_test 7 "nodemap create and delete"
560
561 test_8() {
562         local rc
563
564         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
565         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
566                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
567                 return
568
569         # Set up nodemaps
570
571         create_nodemaps
572         rc=$?
573         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
574
575         # Try duplicates
576
577         create_nodemaps
578         rc=$?
579         [[ $rc == 0 ]] && error "duplicate nodemap_add allowed with $rc" &&
580         return 2
581
582         # Clean up
583         delete_nodemaps
584         rc=$?
585         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 3
586
587         return 0
588 }
589 run_test 8 "nodemap reject duplicates"
590
591 test_9() {
592         local i
593         local rc
594
595         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
596         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
597                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
598                 return
599
600         rc=0
601         create_nodemaps
602         rc=$?
603         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
604
605         rc=0
606         for ((i = 0; i < NODEMAP_COUNT; i++)); do
607                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
608                         rc=$((rc + 1))
609                 fi
610         done
611         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
612
613         rc=0
614         for ((i = 0; i < NODEMAP_COUNT; i++)); do
615                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
616                         rc=$((rc + 1))
617                 fi
618         done
619         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
620
621         rc=0
622         delete_nodemaps
623         rc=$?
624         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 4
625
626         return 0
627 }
628 run_test 9 "nodemap range add"
629
630 test_10() {
631         local rc
632
633         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
634         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
635                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
636                 return
637
638         rc=0
639         create_nodemaps
640         rc=$?
641         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
642
643         rc=0
644         for ((i = 0; i < NODEMAP_COUNT; i++)); do
645                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
646                         rc=$((rc + 1))
647                 fi
648         done
649         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
650
651         rc=0
652         for ((i = 0; i < NODEMAP_COUNT; i++)); do
653                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
654                         rc=$((rc + 1))
655                 fi
656         done
657         [[ $rc == 0 ]] && error "nodemap_add_range duplicate add with $rc" &&
658                 return 2
659
660
661         rc=0
662         for ((i = 0; i < NODEMAP_COUNT; i++)); do
663                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
664                         rc=$((rc + 1))
665                 fi
666         done
667         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
668
669         delete_nodemaps
670         rc=$?
671         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 5
672
673         return 0
674 }
675 run_test 10 "nodemap reject duplicate ranges"
676
677 test_11() {
678         local rc
679
680         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
681         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
682                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
683                 return
684
685         rc=0
686         create_nodemaps
687         rc=$?
688         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
689
690         rc=0
691         for ((i = 0; i < NODEMAP_COUNT; i++)); do
692                 if ! modify_flags ${HOSTNAME_CHECKSUM}_${i}; then
693                         rc=$((rc + 1))
694                 fi
695         done
696         [[ $rc != 0 ]] && error "nodemap_modify with $rc" && return 2
697
698         rc=0
699         delete_nodemaps
700         rc=$?
701         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 3
702
703         return 0
704 }
705 run_test 11 "nodemap modify"
706
707 test_12() {
708         local rc
709
710         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
711         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
712                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
713                 return
714
715         rc=0
716         create_nodemaps
717         rc=$?
718         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
719
720         rc=0
721         for ((i = 0; i < NODEMAP_COUNT; i++)); do
722                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 0; then
723                         rc=$((rc + 1))
724                 fi
725         done
726         [[ $rc != 0 ]] && error "nodemap squash_uid with $rc" && return 2
727
728         rc=0
729         for ((i = 0; i < NODEMAP_COUNT; i++)); do
730                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 1; then
731                         rc=$((rc + 1))
732                 fi
733         done
734         [[ $rc != 0 ]] && error "nodemap squash_gid with $rc" && return 3
735
736         rc=0
737         delete_nodemaps
738         rc=$?
739         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
740
741         return 0
742 }
743 run_test 12 "nodemap set squash ids"
744
745 test_13() {
746         local rc
747
748         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
749         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
750                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
751                 return
752
753         rc=0
754         create_nodemaps
755         rc=$?
756         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
757
758         rc=0
759         for ((i = 0; i < NODEMAP_COUNT; i++)); do
760                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
761                         rc=$((rc + 1))
762                 fi
763         done
764         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
765
766         rc=0
767         for ((i = 0; i < NODEMAP_COUNT; i++)); do
768                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
769                         for k in $NODEMAP_IPADDR_LIST; do
770                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
771                                        ${HOSTNAME_CHECKSUM}_${i}; then
772                                         rc=$((rc + 1))
773                                 fi
774                         done
775                 done
776         done
777         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
778
779         rc=0
780         delete_nodemaps
781         rc=$?
782         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
783
784         return 0
785 }
786 run_test 13 "test nids"
787
788 test_14() {
789         local rc
790
791         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
792         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
793                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
794                 return
795
796         rc=0
797         create_nodemaps
798         rc=$?
799         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
800
801         rc=0
802         for ((i = 0; i < NODEMAP_COUNT; i++)); do
803                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
804                         for k in $NODEMAP_IPADDR_LIST; do
805                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
806                                         default; then
807                                         rc=$((rc + 1))
808                                 fi
809                         done
810                 done
811         done
812         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
813
814         rc=0
815         delete_nodemaps
816         rc=$?
817         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
818
819         return 0
820 }
821 run_test 14 "test default nodemap nid lookup"
822
823 test_15() {
824         local rc
825
826         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
827         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
828                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
829                 return
830
831         rc=0
832         create_nodemaps
833         rc=$?
834         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
835
836         rc=0
837         for ((i = 0; i < NODEMAP_COUNT; i++)); do
838                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
839                         rc=$((rc + 1))
840                 fi
841         done
842         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
843
844         rc=0
845         add_idmaps
846         rc=$?
847         [[ $rc != 0 ]] && error "nodemap_add_idmap failed with $rc" && return 3
848
849         rc=0
850         test_idmap
851         rc=$?
852         [[ $rc != 0 ]] && error "nodemap_test_id failed with $rc" && return 4
853
854         rc=0
855         delete_idmaps
856         rc=$?
857         [[ $rc != 0 ]] && error "nodemap_del_idmap failed with $rc" && return 5
858
859         rc=0
860         delete_nodemaps
861         rc=$?
862         [[ $rc != 0 ]] && error "nodemap_delete failed with $rc" && return 6
863
864         return 0
865 }
866 run_test 15 "test id mapping"
867
868 wait_nm_sync() {
869         local nodemap_name=$1
870         local key=$2
871         local proc_param="${nodemap_name}.${key}"
872         [ "$nodemap_name" == "active" ] && proc_param="active"
873
874         local is_active=$(do_facet mgs $LCTL get_param -n nodemap.active)
875         (( is_active == 0 )) && [ "$proc_param" != "active" ] && return
876
877         local max_retries=20
878         local is_sync
879         local out1=$(do_facet mgs $LCTL get_param nodemap.${proc_param})
880         local out2
881         local mgs_ip=$(host_nids_address $mgs_HOST $NETTYPE | cut -d' ' -f1)
882         local i
883
884         # wait up to 10 seconds for other servers to sync with mgs
885         for i in $(seq 1 10); do
886                 for node in $(all_server_nodes); do
887                     local node_ip=$(host_nids_address $node $NETTYPE |
888                                     cut -d' ' -f1)
889
890                     is_sync=true
891                     [ $node_ip == $mgs_ip ] && continue
892
893                     out2=$(do_node $node_ip $LCTL get_param \
894                                    nodemap.$proc_param 2>/dev/null)
895                     [ "$out1" != "$out2" ] && is_sync=false && break
896                 done
897                 $is_sync && break
898                 sleep 1
899         done
900         if ! $is_sync; then
901                 echo MGS
902                 echo $out1
903                 echo OTHER - IP: $node_ip
904                 echo $out2
905                 error "mgs and $nodemap_name ${key} mismatch, $i attempts"
906         fi
907         echo "waited $((i - 1)) seconds for sync"
908 }
909
910 create_fops_nodemaps() {
911         local i=0
912         local client
913         for client in $clients; do
914                 local client_ip=$(host_nids_address $client $NETTYPE)
915                 local client_nid=$(h2$NETTYPE $client_ip)
916                 do_facet mgs $LCTL nodemap_add c${i} || return 1
917                 do_facet mgs $LCTL nodemap_add_range    \
918                         --name c${i} --range $client_nid || return 1
919                 for map in ${FOPS_IDMAPS[i]}; do
920                         do_facet mgs $LCTL nodemap_add_idmap --name c${i} \
921                                 --idtype uid --idmap ${map} || return 1
922                         do_facet mgs $LCTL nodemap_add_idmap --name c${i} \
923                                 --idtype gid --idmap ${map} || return 1
924                 done
925
926                 wait_nm_sync c$i idmap
927
928                 i=$((i + 1))
929         done
930         return 0
931 }
932
933 delete_fops_nodemaps() {
934         local i=0
935         local client
936         for client in $clients; do
937                 do_facet mgs $LCTL nodemap_del c${i} || return 1
938                 i=$((i + 1))
939         done
940         return 0
941 }
942
943 fops_mds_index=0
944 nm_test_mkdir() {
945         if [ $MDSCOUNT -le 1 ]; then
946                 do_node ${clients_arr[0]} mkdir -p $DIR/$tdir
947         else
948                 # round-robin MDTs to test DNE nodemap support
949                 [ ! -d $DIR ] && do_node ${clients_arr[0]} mkdir -p $DIR
950                 do_node ${clients_arr[0]} $LFS setdirstripe -c 1 -i \
951                         $((fops_mds_index % MDSCOUNT)) $DIR/$tdir
952                 ((fops_mds_index++))
953         fi
954 }
955
956 # acl test directory needs to be initialized on a privileged client
957 fops_test_setup() {
958         local admin=$(do_facet mgs $LCTL get_param -n nodemap.c0.admin_nodemap)
959         local trust=$(do_facet mgs $LCTL get_param -n \
960                 nodemap.c0.trusted_nodemap)
961
962         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
963         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
964
965         wait_nm_sync c0 admin_nodemap
966         wait_nm_sync c0 trusted_nodemap
967
968         do_node ${clients_arr[0]} rm -rf $DIR/$tdir
969         nm_test_mkdir
970         do_node ${clients_arr[0]} chown $user $DIR/$tdir
971
972         do_facet mgs $LCTL nodemap_modify --name c0 \
973                 --property admin --value $admin
974         do_facet mgs $LCTL nodemap_modify --name c0 \
975                 --property trusted --value $trust
976
977         # flush MDT locks to make sure they are reacquired before test
978         do_node ${clients_arr[0]} $LCTL set_param \
979                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
980
981         wait_nm_sync c0 admin_nodemap
982         wait_nm_sync c0 trusted_nodemap
983 }
984
985 # fileset test directory needs to be initialized on a privileged client
986 fileset_test_setup() {
987         local admin=$(do_facet mgs $LCTL get_param -n nodemap.c0.admin_nodemap)
988         local trust=$(do_facet mgs $LCTL get_param -n \
989                 nodemap.c0.trusted_nodemap)
990
991         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
992         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
993
994         wait_nm_sync c0 admin_nodemap
995         wait_nm_sync c0 trusted_nodemap
996
997         # create directory and populate it for subdir mount
998         do_node ${clients_arr[0]} mkdir $MOUNT/$subdir ||
999                 error "unable to create dir $MOUNT/$subdir"
1000         do_node ${clients_arr[0]} touch $MOUNT/$subdir/this_is_$subdir ||
1001                 error "unable to create file $MOUNT/$subdir/this_is_$subdir"
1002         do_node ${clients_arr[0]} mkdir $MOUNT/$subdir/$subsubdir ||
1003                 error "unable to create dir $MOUNT/$subdir/$subsubdir"
1004         do_node ${clients_arr[0]} touch \
1005                         $MOUNT/$subdir/$subsubdir/this_is_$subsubdir ||
1006                 error "unable to create file \
1007                         $MOUNT/$subdir/$subsubdir/this_is_$subsubdir"
1008
1009         do_facet mgs $LCTL nodemap_modify --name c0 \
1010                 --property admin --value $admin
1011         do_facet mgs $LCTL nodemap_modify --name c0 \
1012                 --property trusted --value $trust
1013
1014         # flush MDT locks to make sure they are reacquired before test
1015         do_node ${clients_arr[0]} $LCTL set_param \
1016                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
1017
1018         wait_nm_sync c0 admin_nodemap
1019         wait_nm_sync c0 trusted_nodemap
1020 }
1021
1022 # fileset test directory needs to be initialized on a privileged client
1023 fileset_test_cleanup() {
1024         local admin=$(do_facet mgs $LCTL get_param -n nodemap.c0.admin_nodemap)
1025         local trust=$(do_facet mgs $LCTL get_param -n \
1026                 nodemap.c0.trusted_nodemap)
1027
1028         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1029         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1030
1031         wait_nm_sync c0 admin_nodemap
1032         wait_nm_sync c0 trusted_nodemap
1033
1034         # cleanup directory created for subdir mount
1035         do_node ${clients_arr[0]} rm -rf $MOUNT/$subdir ||
1036                 error "unable to remove dir $MOUNT/$subdir"
1037
1038         do_facet mgs $LCTL nodemap_modify --name c0 \
1039                 --property admin --value $admin
1040         do_facet mgs $LCTL nodemap_modify --name c0 \
1041                 --property trusted --value $trust
1042
1043         # flush MDT locks to make sure they are reacquired before test
1044         do_node ${clients_arr[0]} $LCTL set_param \
1045                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
1046
1047         wait_nm_sync c0 admin_nodemap
1048         wait_nm_sync c0 trusted_nodemap
1049 }
1050
1051 do_create_delete() {
1052         local run_u=$1
1053         local key=$2
1054         local testfile=$DIR/$tdir/$tfile
1055         local rc=0
1056         local c=0 d=0
1057         local qused_new
1058         if $run_u touch $testfile >& /dev/null; then
1059                 c=1
1060                 $run_u rm $testfile && d=1
1061         fi >& /dev/null
1062
1063         local res="$c $d"
1064         local expected=$(get_cr_del_expected $key)
1065         [ "$res" != "$expected" ] &&
1066                 error "test $key, wanted $expected, got $res" && rc=$((rc + 1))
1067         return $rc
1068 }
1069
1070 nodemap_check_quota() {
1071         local run_u="$1"
1072         $run_u lfs quota -q $DIR | awk '{ print $2; exit; }'
1073 }
1074
1075 do_fops_quota_test() {
1076         local run_u=$1
1077         # fuzz quota used to account for possible indirect blocks, etc
1078         local quota_fuzz=$(fs_log_size)
1079         local qused_orig=$(nodemap_check_quota "$run_u")
1080         local qused_high=$((qused_orig + quota_fuzz))
1081         local qused_low=$((qused_orig - quota_fuzz))
1082         local testfile=$DIR/$tdir/$tfile
1083         $run_u dd if=/dev/zero of=$testfile bs=1M count=1 >& /dev/null ||
1084                 error "unable to write quota test file"
1085         sync; sync_all_data || true
1086
1087         local qused_new=$(nodemap_check_quota "$run_u")
1088         [ $((qused_new)) -lt $((qused_low + 1024)) -o \
1089           $((qused_new)) -gt $((qused_high + 1024)) ] &&
1090                 error "$qused_new != $qused_orig + 1M after write, " \
1091                       "fuzz is $quota_fuzz"
1092         $run_u rm $testfile || error "unable to remove quota test file"
1093         wait_delete_completed_mds
1094
1095         qused_new=$(nodemap_check_quota "$run_u")
1096         [ $((qused_new)) -lt $((qused_low)) \
1097                 -o $((qused_new)) -gt $((qused_high)) ] &&
1098                 error "quota not reclaimed, expect $qused_orig, " \
1099                       "got $qused_new, fuzz $quota_fuzz"
1100 }
1101
1102 get_fops_mapped_user() {
1103         local cli_user=$1
1104
1105         for ((i=0; i < ${#FOPS_IDMAPS[@]}; i++)); do
1106                 for map in ${FOPS_IDMAPS[i]}; do
1107                         if [ $(cut -d: -f1 <<< "$map") == $cli_user ]; then
1108                                 cut -d: -f2 <<< "$map"
1109                                 return
1110                         fi
1111                 done
1112         done
1113         echo -1
1114 }
1115
1116 get_cr_del_expected() {
1117         local -a key
1118         IFS=":" read -a key <<< "$1"
1119         local mapmode="${key[0]}"
1120         local mds_user="${key[1]}"
1121         local cluster="${key[2]}"
1122         local cli_user="${key[3]}"
1123         local mode="0${key[4]}"
1124         local SUCCESS="1 1"
1125         local FAILURE="0 0"
1126         local noadmin=0
1127         local mapped=0
1128         local other=0
1129
1130         [[ $mapmode == *mapped* ]] && mapped=1
1131         # only c1 is mapped in these test cases
1132         [[ $mapmode == mapped_trusted* ]] && [ "$cluster" == "c0" ] && mapped=0
1133         [[ $mapmode == *noadmin* ]] && noadmin=1
1134
1135         # o+wx works as long as the user isn't mapped
1136         if [ $((mode & 3)) -eq 3 ]; then
1137                 other=1
1138         fi
1139
1140         # if client user is root, check if root is squashed
1141         if [ "$cli_user" == "0" ]; then
1142                 # squash root succeed, if other bit is on
1143                 case $noadmin in
1144                         0) echo $SUCCESS;;
1145                         1) [ "$other" == "1" ] && echo $SUCCESS
1146                            [ "$other" == "0" ] && echo $FAILURE;;
1147                 esac
1148                 return
1149         fi
1150         if [ "$mapped" == "0" ]; then
1151                 [ "$other" == "1" ] && echo $SUCCESS
1152                 [ "$other" == "0" ] && echo $FAILURE
1153                 return
1154         fi
1155
1156         # if mapped user is mds user, check for u+wx
1157         mapped_user=$(get_fops_mapped_user $cli_user)
1158         [ "$mapped_user" == "-1" ] &&
1159                 error "unable to find mapping for client user $cli_user"
1160
1161         if [ "$mapped_user" == "$mds_user" -a \
1162              $(((mode & 0300) == 0300)) -eq 1 ]; then
1163                 echo $SUCCESS
1164                 return
1165         fi
1166         if [ "$mapped_user" != "$mds_user" -a "$other" == "1" ]; then
1167                 echo $SUCCESS
1168                 return
1169         fi
1170         echo $FAILURE
1171 }
1172
1173 test_fops_admin_cli_i=""
1174 test_fops_chmod_dir() {
1175         local current_cli_i=$1
1176         local perm_bits=$2
1177         local dir_to_chmod=$3
1178         local new_admin_cli_i=""
1179
1180         # do we need to set up a new admin client?
1181         [ "$current_cli_i" == "0" ] && [ "$test_fops_admin_cli_i" != "1" ] &&
1182                 new_admin_cli_i=1
1183         [ "$current_cli_i" != "0" ] && [ "$test_fops_admin_cli_i" != "0" ] &&
1184                 new_admin_cli_i=0
1185
1186         # if only one client, and non-admin, need to flip admin everytime
1187         if [ "$num_clients" == "1" ]; then
1188                 test_fops_admin_client=$clients
1189                 test_fops_admin_val=$(do_facet mgs $LCTL get_param -n \
1190                         nodemap.c0.admin_nodemap)
1191                 if [ "$test_fops_admin_val" != "1" ]; then
1192                         do_facet mgs $LCTL nodemap_modify \
1193                                 --name c0 \
1194                                 --property admin \
1195                                 --value 1
1196                         wait_nm_sync c0 admin_nodemap
1197                 fi
1198         elif [ "$new_admin_cli_i" != "" ]; then
1199                 # restore admin val to old admin client
1200                 if [ "$test_fops_admin_cli_i" != "" ] &&
1201                                 [ "$test_fops_admin_val" != "1" ]; then
1202                         do_facet mgs $LCTL nodemap_modify \
1203                                 --name c${test_fops_admin_cli_i} \
1204                                 --property admin \
1205                                 --value $test_fops_admin_val
1206                         wait_nm_sync c${test_fops_admin_cli_i} admin_nodemap
1207                 fi
1208
1209                 test_fops_admin_cli_i=$new_admin_cli_i
1210                 test_fops_admin_client=${clients_arr[$new_admin_cli_i]}
1211                 test_fops_admin_val=$(do_facet mgs $LCTL get_param -n \
1212                         nodemap.c${new_admin_cli_i}.admin_nodemap)
1213
1214                 if [ "$test_fops_admin_val" != "1" ]; then
1215                         do_facet mgs $LCTL nodemap_modify \
1216                                 --name c${new_admin_cli_i} \
1217                                 --property admin \
1218                                 --value 1
1219                         wait_nm_sync c${new_admin_cli_i} admin_nodemap
1220                 fi
1221         fi
1222
1223         do_node $test_fops_admin_client chmod $perm_bits $DIR/$tdir || return 1
1224
1225         # remove admin for single client if originally non-admin
1226         if [ "$num_clients" == "1" ] && [ "$test_fops_admin_val" != "1" ]; then
1227                 do_facet mgs $LCTL nodemap_modify --name c0 --property admin \
1228                         --value 0
1229                 wait_nm_sync c0 admin_nodemap
1230         fi
1231
1232         return 0
1233 }
1234
1235 test_fops() {
1236         local mapmode="$1"
1237         local single_client="$2"
1238         local client_user_list=([0]="0 $((IDBASE+3)) $((IDBASE+4))"
1239                                 [1]="0 $((IDBASE+5)) $((IDBASE+6))")
1240         local mds_i
1241         local rc=0
1242         local perm_bit_list="0 3 $((0300)) $((0303))"
1243         # SLOW tests 000-007, 010-070, 100-700 (octal modes)
1244         [ "$SLOW" == "yes" ] &&
1245                 perm_bit_list="0 $(seq 1 7) $(seq 8 8 63) $(seq 64 64 511) \
1246                                $((0303))"
1247
1248         # step through mds users. -1 means root
1249         for mds_i in -1 0 1 2; do
1250                 local user=$((mds_i + IDBASE))
1251                 local client
1252                 local x
1253
1254                 [ "$mds_i" == "-1" ] && user=0
1255
1256                 echo mkdir -p $DIR/$tdir
1257                 fops_test_setup
1258                 local cli_i=0
1259                 for client in $clients; do
1260                         local u
1261                         for u in ${client_user_list[$cli_i]}; do
1262                                 local run_u="do_node $client \
1263                                              $RUNAS_CMD -u$u -g$u -G$u"
1264                                 for perm_bits in $perm_bit_list; do
1265                                         local mode=$(printf %03o $perm_bits)
1266                                         local key
1267                                         key="$mapmode:$user:c$cli_i:$u:$mode"
1268                                         test_fops_chmod_dir $cli_i $mode \
1269                                                 $DIR/$tdir ||
1270                                                         error cannot chmod $key
1271                                         do_create_delete "$run_u" "$key"
1272                                 done
1273
1274                                 # check quota
1275                                 test_fops_chmod_dir $cli_i 777 $DIR/$tdir ||
1276                                         error cannot chmod $key
1277                                 do_fops_quota_test "$run_u"
1278                         done
1279
1280                         cli_i=$((cli_i + 1))
1281                         [ "$single_client" == "1" ] && break
1282                 done
1283                 rm -rf $DIR/$tdir
1284         done
1285         return $rc
1286 }
1287
1288 nodemap_version_check () {
1289         remote_mgs_nodsh && skip "remote MGS with nodsh" && return 1
1290         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
1291                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
1292                 return 1
1293         return 0
1294 }
1295
1296 nodemap_test_setup() {
1297         local rc
1298         local active_nodemap=1
1299
1300         [ "$1" == "0" ] && active_nodemap=0
1301
1302         do_nodes $(comma_list $(all_mdts_nodes)) \
1303                 $LCTL set_param mdt.*.identity_upcall=NONE
1304
1305         rc=0
1306         create_fops_nodemaps
1307         rc=$?
1308         [[ $rc != 0 ]] && error "adding fops nodemaps failed $rc"
1309
1310         do_facet mgs $LCTL nodemap_activate $active_nodemap
1311         wait_nm_sync active
1312
1313         do_facet mgs $LCTL nodemap_modify --name default \
1314                 --property admin --value 1
1315         do_facet mgs $LCTL nodemap_modify --name default \
1316                 --property trusted --value 1
1317         wait_nm_sync default trusted_nodemap
1318 }
1319
1320 nodemap_test_cleanup() {
1321         trap 0
1322         delete_fops_nodemaps
1323         rc=$?
1324         [[ $rc != 0 ]] && error "removing fops nodemaps failed $rc"
1325
1326         do_facet mgs $LCTL nodemap_modify --name default \
1327                  --property admin --value 0
1328         do_facet mgs $LCTL nodemap_modify --name default \
1329                  --property trusted --value 0
1330         wait_nm_sync default trusted_nodemap
1331
1332         do_facet mgs $LCTL nodemap_activate 0
1333         wait_nm_sync active 0
1334
1335         return 0
1336 }
1337
1338 nodemap_clients_admin_trusted() {
1339         local admin=$1
1340         local tr=$2
1341         local i=0
1342         for client in $clients; do
1343                 do_facet mgs $LCTL nodemap_modify --name c0 \
1344                         --property admin --value $admin
1345                 do_facet mgs $LCTL nodemap_modify --name c0 \
1346                         --property trusted --value $tr
1347                 i=$((i + 1))
1348         done
1349         wait_nm_sync c$((i - 1)) admin_nodemap
1350         wait_nm_sync c$((i - 1)) trusted_nodemap
1351 }
1352
1353 test_16() {
1354         nodemap_version_check || return 0
1355         nodemap_test_setup 0
1356
1357         trap nodemap_test_cleanup EXIT
1358         test_fops all_off
1359         nodemap_test_cleanup
1360 }
1361 run_test 16 "test nodemap all_off fileops"
1362
1363 test_17() {
1364         nodemap_version_check || return 0
1365         nodemap_test_setup
1366
1367         trap nodemap_test_cleanup EXIT
1368         nodemap_clients_admin_trusted 0 1
1369         test_fops trusted_noadmin 1
1370         nodemap_test_cleanup
1371 }
1372 run_test 17 "test nodemap trusted_noadmin fileops"
1373
1374 test_18() {
1375         nodemap_version_check || return 0
1376         nodemap_test_setup
1377
1378         trap nodemap_test_cleanup EXIT
1379         nodemap_clients_admin_trusted 0 0
1380         test_fops mapped_noadmin 1
1381         nodemap_test_cleanup
1382 }
1383 run_test 18 "test nodemap mapped_noadmin fileops"
1384
1385 test_19() {
1386         nodemap_version_check || return 0
1387         nodemap_test_setup
1388
1389         trap nodemap_test_cleanup EXIT
1390         nodemap_clients_admin_trusted 1 1
1391         test_fops trusted_admin 1
1392         nodemap_test_cleanup
1393 }
1394 run_test 19 "test nodemap trusted_admin fileops"
1395
1396 test_20() {
1397         nodemap_version_check || return 0
1398         nodemap_test_setup
1399
1400         trap nodemap_test_cleanup EXIT
1401         nodemap_clients_admin_trusted 1 0
1402         test_fops mapped_admin 1
1403         nodemap_test_cleanup
1404 }
1405 run_test 20 "test nodemap mapped_admin fileops"
1406
1407 test_21() {
1408         nodemap_version_check || return 0
1409         nodemap_test_setup
1410
1411         trap nodemap_test_cleanup EXIT
1412         local x=1
1413         local i=0
1414         for client in $clients; do
1415                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1416                         --property admin --value 0
1417                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1418                         --property trusted --value $x
1419                 x=0
1420                 i=$((i + 1))
1421         done
1422         wait_nm_sync c$((i - 1)) trusted_nodemap
1423
1424         test_fops mapped_trusted_noadmin
1425         nodemap_test_cleanup
1426 }
1427 run_test 21 "test nodemap mapped_trusted_noadmin fileops"
1428
1429 test_22() {
1430         nodemap_version_check || return 0
1431         nodemap_test_setup
1432
1433         trap nodemap_test_cleanup EXIT
1434         local x=1
1435         local i=0
1436         for client in $clients; do
1437                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1438                         --property admin --value 1
1439                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1440                         --property trusted --value $x
1441                 x=0
1442                 i=$((i + 1))
1443         done
1444         wait_nm_sync c$((i - 1)) trusted_nodemap
1445
1446         test_fops mapped_trusted_admin
1447         nodemap_test_cleanup
1448 }
1449 run_test 22 "test nodemap mapped_trusted_admin fileops"
1450
1451 # acl test directory needs to be initialized on a privileged client
1452 nodemap_acl_test_setup() {
1453         local admin=$(do_facet mgs $LCTL get_param -n nodemap.c0.admin_nodemap)
1454         local trust=$(do_facet mgs $LCTL get_param -n \
1455                       nodemap.c0.trusted_nodemap)
1456
1457         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1458         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1459
1460         wait_nm_sync c0 admin_nodemap
1461         wait_nm_sync c0 trusted_nodemap
1462
1463         do_node ${clients_arr[0]} rm -rf $DIR/$tdir
1464         nm_test_mkdir
1465         do_node ${clients_arr[0]} chmod a+rwx $DIR/$tdir ||
1466                 error unable to chmod a+rwx test dir $DIR/$tdir
1467
1468         do_facet mgs $LCTL nodemap_modify --name c0 \
1469                 --property admin --value $admin
1470         do_facet mgs $LCTL nodemap_modify --name c0 \
1471                 --property trusted --value $trust
1472
1473         wait_nm_sync c0 trusted_nodemap
1474 }
1475
1476 # returns 0 if the number of ACLs does not change on the second (mapped) client
1477 # after being set on the first client
1478 nodemap_acl_test() {
1479         local user="$1"
1480         local set_client="$2"
1481         local get_client="$3"
1482         local check_setfacl="$4"
1483         local setfacl_error=0
1484         local testfile=$DIR/$tdir/$tfile
1485         local RUNAS_USER="$RUNAS_CMD -u $user"
1486         local acl_count=0
1487         local acl_count_post=0
1488
1489         nodemap_acl_test_setup
1490         sleep 5
1491
1492         do_node $set_client $RUNAS_USER touch $testfile
1493
1494         # ACL masks aren't filtered by nodemap code, so we ignore them
1495         acl_count=$(do_node $get_client getfacl $testfile | grep -v mask |
1496                 wc -l)
1497         do_node $set_client $RUNAS_USER setfacl -m $user:rwx $testfile ||
1498                 setfacl_error=1
1499
1500         # if check setfacl is set to 1, then it's supposed to error
1501         if [ "$check_setfacl" == "1" ]; then
1502                 [ "$setfacl_error" != "1" ] && return 1
1503                 return 0
1504         fi
1505         [ "$setfacl_error" == "1" ] && echo "WARNING: unable to setfacl"
1506
1507         acl_count_post=$(do_node $get_client getfacl $testfile | grep -v mask |
1508                 wc -l)
1509         [ $acl_count -eq $acl_count_post ] && return 0
1510         return 1
1511 }
1512
1513 test_23() {
1514         nodemap_version_check || return 0
1515         nodemap_test_setup
1516
1517         trap nodemap_test_cleanup EXIT
1518         # 1 trusted cluster, 1 mapped cluster
1519         local unmapped_fs=$((IDBASE+0))
1520         local unmapped_c1=$((IDBASE+5))
1521         local mapped_fs=$((IDBASE+2))
1522         local mapped_c0=$((IDBASE+4))
1523         local mapped_c1=$((IDBASE+6))
1524
1525         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1526         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1527
1528         do_facet mgs $LCTL nodemap_modify --name c1 --property admin --value 0
1529         do_facet mgs $LCTL nodemap_modify --name c1 --property trusted --value 0
1530
1531         wait_nm_sync c1 trusted_nodemap
1532
1533         # setfacl on trusted cluster to unmapped user, verify it's not seen
1534         nodemap_acl_test $unmapped_fs ${clients_arr[0]} ${clients_arr[1]} ||
1535                 error "acl count (1)"
1536
1537         # setfacl on trusted cluster to mapped user, verify it's seen
1538         nodemap_acl_test $mapped_fs ${clients_arr[0]} ${clients_arr[1]} &&
1539                 error "acl count (2)"
1540
1541         # setfacl on mapped cluster to mapped user, verify it's seen
1542         nodemap_acl_test $mapped_c1 ${clients_arr[1]} ${clients_arr[0]} &&
1543                 error "acl count (3)"
1544
1545         # setfacl on mapped cluster to unmapped user, verify error
1546         nodemap_acl_test $unmapped_fs ${clients_arr[1]} ${clients_arr[0]} 1 ||
1547                 error "acl count (4)"
1548
1549         # 2 mapped clusters
1550         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 0
1551         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 0
1552
1553         wait_nm_sync c0 trusted_nodemap
1554
1555         # setfacl to mapped user on c1, also mapped to c0, verify it's seen
1556         nodemap_acl_test $mapped_c1 ${clients_arr[1]} ${clients_arr[0]} &&
1557                 error "acl count (5)"
1558
1559         # setfacl to mapped user on c1, not mapped to c0, verify not seen
1560         nodemap_acl_test $unmapped_c1 ${clients_arr[1]} ${clients_arr[0]} ||
1561                 error "acl count (6)"
1562
1563         nodemap_test_cleanup
1564 }
1565 run_test 23 "test mapped ACLs"
1566
1567 test_24() {
1568         nodemap_test_setup
1569
1570         trap nodemap_test_cleanup EXIT
1571         do_nodes $(comma_list $(all_server_nodes)) $LCTL get_param -R nodemap ||
1572                 error "proc readable file read failed"
1573
1574         nodemap_test_cleanup
1575 }
1576 run_test 24 "check nodemap proc files for LBUGs and Oopses"
1577
1578 test_25() {
1579         local tmpfile=$(mktemp)
1580         local tmpfile2=$(mktemp)
1581         local subdir=c0dir
1582
1583         nodemap_version_check || return 0
1584
1585         # stop clients for this test
1586         zconf_umount_clients $CLIENTS $MOUNT ||
1587             error "unable to umount clients $CLIENTS"
1588
1589         nodemap_test_setup
1590
1591         trap nodemap_test_cleanup EXIT
1592
1593         # create a new, empty nodemap, and add fileset info to it
1594         do_facet mgs $LCTL nodemap_add test26 ||
1595                 error "unable to create nodemap test26"
1596         do_facet mgs $LCTL set_param -P nodemap.test26.fileset=/$subdir ||
1597                 error "unable to add fileset info to nodemap test26"
1598
1599         wait_nm_sync test26 id
1600
1601         do_facet mgs $LCTL nodemap_info > $tmpfile
1602         do_facet mds $LCTL nodemap_info > $tmpfile2
1603
1604         cleanup_and_setup_lustre
1605         # stop clients for this test
1606         zconf_umount_clients $CLIENTS $MOUNT ||
1607             error "unable to umount clients $CLIENTS"
1608
1609         diff -q <(do_facet mgs $LCTL nodemap_info) $tmpfile >& /dev/null ||
1610                 error "nodemap_info diff on MGS after remount"
1611
1612         diff -q <(do_facet mds $LCTL nodemap_info) $tmpfile2 >& /dev/null ||
1613                 error "nodemap_info diff on MDS after remount"
1614
1615         # cleanup nodemap
1616         do_facet mgs $LCTL nodemap_del test26 ||
1617             error "cannot delete nodemap test26 from config"
1618         nodemap_test_cleanup
1619         # restart clients previously stopped
1620         zconf_mount_clients $CLIENTS $MOUNT ||
1621             error "unable to mount clients $CLIENTS"
1622
1623         rm -f $tmpfile $tmpfile2
1624 }
1625 run_test 25 "test save and reload nodemap config"
1626
1627 test_26() {
1628         nodemap_version_check || return 0
1629
1630         local large_i=32000
1631
1632         do_facet mgs "seq -f 'c%g' $large_i | xargs -n1 $LCTL nodemap_add"
1633         wait_nm_sync c$large_i admin_nodemap
1634
1635         do_facet mgs "seq -f 'c%g' $large_i | xargs -n1 $LCTL nodemap_del"
1636         wait_nm_sync c$large_i admin_nodemap
1637 }
1638 run_test 26 "test transferring very large nodemap"
1639
1640 test_27() {
1641         local subdir=c0dir
1642         local subsubdir=c0subdir
1643
1644         nodemap_test_setup
1645         trap nodemap_test_cleanup EXIT
1646
1647         fileset_test_setup
1648
1649         # add fileset info to nodemap
1650         do_facet mgs $LCTL set_param nodemap.c0.fileset=/$subdir ||
1651                 error "unable to set fileset info on nodemap c0"
1652         do_facet mgs $LCTL set_param -P nodemap.c0.fileset=/$subdir ||
1653                 error "unable to add fileset info to nodemap c0"
1654         wait_nm_sync c0 fileset
1655
1656         # re-mount client
1657         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
1658                 error "unable to umount client ${clients_arr[0]}"
1659         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
1660                 error "unable to remount client ${clients_arr[0]}"
1661
1662         # test mount point content
1663         do_node ${clients_arr[0]} test -f $MOUNT/this_is_$subdir ||
1664                 error "fileset not taken into account"
1665
1666         # re-mount client with sub-subdir
1667         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
1668                 error "unable to umount client ${clients_arr[0]}"
1669         export FILESET=/$subsubdir
1670         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
1671                 error "unable to remount client ${clients_arr[0]}"
1672         unset FILESET
1673
1674         # test mount point content
1675         do_node ${clients_arr[0]} test -f $MOUNT/this_is_$subsubdir ||
1676                 error "subdir of fileset not taken into account"
1677
1678         # remove fileset info from nodemap
1679         do_facet mgs $LCTL nodemap_set_fileset --name c0 --fileset \'\' ||
1680                 error "unable to delete fileset info on nodemap c0"
1681         do_facet mgs $LCTL set_param -P nodemap.c0.fileset=\'\' ||
1682                 error "unable to reset fileset info on nodemap c0"
1683         wait_nm_sync c0 fileset
1684
1685         # re-mount client
1686         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
1687                 error "unable to umount client ${clients_arr[0]}"
1688         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
1689                 error "unable to remount client ${clients_arr[0]}"
1690
1691         # test mount point content
1692         do_node ${clients_arr[0]} test -d $MOUNT/$subdir ||
1693                 error "fileset not cleared on nodemap c0"
1694
1695         fileset_test_cleanup
1696         nodemap_test_cleanup
1697 }
1698 run_test 27 "test fileset in nodemap"
1699
1700 log "cleanup: ======================================================"
1701
1702 sec_unsetup() {
1703         ## nodemap deactivated
1704         do_facet mgs $LCTL nodemap_activate 0
1705
1706         for num in $(seq $MDSCOUNT); do
1707                 if [ "${identity_old[$num]}" = 1 ]; then
1708                         switch_identity $num false || identity_old[$num]=$?
1709                 fi
1710         done
1711
1712         $RUNAS_CMD -u $ID0 ls $DIR
1713         $RUNAS_CMD -u $ID1 ls $DIR
1714 }
1715 sec_unsetup
1716
1717 sec_cleanup
1718
1719 complete $SECONDS
1720 exit_status