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