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