Whamcloud - gitweb
9018c3f4bdd86b170115774ff0fa9f51a618cb13
[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:
11 ALWAYS_EXCEPT="              $SANITY_SEC_EXCEPT"
12 if $SHARED_KEY; then
13 # bug number for skipped test: 9145 9145 9671 9145 9145 9145 9145 9245
14         ALWAYS_EXCEPT="        17   18   19   20   21   22   23   27 $ALWAYS_EXCEPT"
15 fi
16 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
17
18 SRCDIR=$(dirname $0)
19 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
20 export NAME=${NAME:-local}
21
22 LUSTRE=${LUSTRE:-$(dirname $0)/..}
23 . $LUSTRE/tests/test-framework.sh
24 init_test_env $@
25 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
26 init_logging
27
28 NODEMAP_TESTS=$(seq 7 26)
29
30 if ! check_versions; then
31         echo "It is NOT necessary to test nodemap under interoperation mode"
32         EXCEPT="$EXCEPT $NODEMAP_TESTS"
33 fi
34
35 [ "$SLOW" = "no" ] && EXCEPT_SLOW="26"
36
37 [ "$ALWAYS_EXCEPT$EXCEPT$EXCEPT_SLOW" ] &&
38         echo "Skipping tests: $ALWAYS_EXCEPT $EXCEPT $EXCEPT_SLOW"
39
40 RUNAS_CMD=${RUNAS_CMD:-runas}
41
42 WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
43
44 CONFDIR=/etc/lustre
45 PERM_CONF=$CONFDIR/perm.conf
46 FAIL_ON_ERROR=false
47 HOSTNAME_CHECKSUM=$(hostname | sum | awk '{ print $1 }')
48 SUBNET_CHECKSUM=$(expr $HOSTNAME_CHECKSUM % 250 + 1)
49
50 require_dsh_mds || exit 0
51 require_dsh_ost || exit 0
52
53 clients=${CLIENTS//,/ }
54 num_clients=$(get_node_count ${clients})
55 clients_arr=($clients)
56
57 ID0=${ID0:-500}
58 ID1=${ID1:-501}
59 USER0=$(getent passwd | grep :$ID0:$ID0: | cut -d: -f1)
60 USER1=$(getent passwd | grep :$ID1:$ID1: | cut -d: -f1)
61
62 NODEMAP_COUNT=16
63 NODEMAP_RANGE_COUNT=3
64 NODEMAP_IPADDR_LIST="1 10 64 128 200 250"
65 NODEMAP_ID_COUNT=10
66 NODEMAP_MAX_ID=$((ID0 + NODEMAP_ID_COUNT))
67
68 [ -z "$USER0" ] &&
69         skip "need to add user0 ($ID0:$ID0)" && exit 0
70
71 [ -z "$USER1" ] &&
72         skip "need to add user1 ($ID1:$ID1)" && exit 0
73
74 IDBASE=${IDBASE:-60000}
75
76 # changes to mappings must be reflected in test 23
77 FOPS_IDMAPS=(
78         [0]="$((IDBASE+3)):$((IDBASE+0)) $((IDBASE+4)):$((IDBASE+2))"
79         [1]="$((IDBASE+5)):$((IDBASE+1)) $((IDBASE+6)):$((IDBASE+2))"
80         )
81
82 check_and_setup_lustre
83
84 assert_DIR
85
86 # for GSS_SUP
87 GSS_REF=$(lsmod | grep ^ptlrpc_gss | awk '{print $3}')
88 if [ ! -z "$GSS_REF" -a "$GSS_REF" != "0" ]; then
89         GSS_SUP=1
90         echo "with GSS support"
91 else
92         GSS_SUP=0
93         echo "without GSS support"
94 fi
95
96 MDT=$(do_facet $SINGLEMDS lctl get_param -N "mdt.\*MDT0000" |
97         cut -d. -f2 || true)
98 [ -z "$MDT" ] && error "fail to get MDT device" && exit 1
99 do_facet $SINGLEMDS "mkdir -p $CONFDIR"
100 IDENTITY_FLUSH=mdt.$MDT.identity_flush
101 IDENTITY_UPCALL=mdt.$MDT.identity_upcall
102
103 SAVE_PWD=$PWD
104
105 build_test_filter
106
107 sec_login() {
108         local user=$1
109         local group=$2
110
111         $GSS_KRB5 || return
112         if ! $RUNAS_CMD -u $user krb5_login.sh; then
113                 error "$user login kerberos failed."
114                 exit 1
115         fi
116
117         if ! $RUNAS_CMD -u $user -g $group ls $DIR > /dev/null 2>&1; then
118                 $RUNAS_CMD -u $user lfs flushctx -k
119                 $RUNAS_CMD -u $user krb5_login.sh
120                 if ! $RUNAS_CMD -u$user -g$group ls $DIR > /dev/null 2>&1; then
121                         error "init $user $group failed."
122                         exit 2
123                 fi
124         fi
125 }
126
127 declare -a identity_old
128
129 sec_setup() {
130         for num in $(seq $MDSCOUNT); do
131                 switch_identity $num true || identity_old[$num]=$?
132         done
133
134         if ! $RUNAS_CMD -u $ID0 ls $DIR > /dev/null 2>&1; then
135                 sec_login $USER0 $USER0
136         fi
137
138         if ! $RUNAS_CMD -u $ID1 ls $DIR > /dev/null 2>&1; then
139                 sec_login $USER1 $USER1
140         fi
141 }
142 sec_setup
143
144 # run as different user
145 test_0() {
146         umask 0022
147
148         chmod 0755 $DIR || error "chmod (1)"
149         rm -rf $DIR/$tdir || error "rm (1)"
150         mkdir -p $DIR/$tdir || error "mkdir (1)"
151         chown $USER0 $DIR/$tdir || error "chown (2)"
152         $RUNAS_CMD -u $ID0 ls $DIR || error "ls (1)"
153         rm -f $DIR/f0 || error "rm (2)"
154         $RUNAS_CMD -u $ID0 touch $DIR/f0 && error "touch (1)"
155         $RUNAS_CMD -u $ID0 touch $DIR/$tdir/f1 || error "touch (2)"
156         $RUNAS_CMD -u $ID1 touch $DIR/$tdir/f2 && error "touch (3)"
157         touch $DIR/$tdir/f3 || error "touch (4)"
158         chown root $DIR/$tdir || error "chown (3)"
159         chgrp $USER0 $DIR/$tdir || error "chgrp (1)"
160         chmod 0775 $DIR/$tdir || error "chmod (2)"
161         $RUNAS_CMD -u $ID0 touch $DIR/$tdir/f4 || error "touch (5)"
162         $RUNAS_CMD -u $ID1 touch $DIR/$tdir/f5 && error "touch (6)"
163         touch $DIR/$tdir/f6 || error "touch (7)"
164         rm -rf $DIR/$tdir || error "rm (3)"
165 }
166 run_test 0 "uid permission ============================="
167
168 # setuid/gid
169 test_1() {
170         [ $GSS_SUP = 0 ] && skip "without GSS support." && return
171
172         rm -rf $DIR/$tdir
173         mkdir -p $DIR/$tdir
174
175         chown $USER0 $DIR/$tdir || error "chown (1)"
176         $RUNAS_CMD -u $ID1 -v $ID0 touch $DIR/$tdir/f0 && error "touch (2)"
177         echo "enable uid $ID1 setuid"
178         do_facet $SINGLEMDS "echo '* $ID1 setuid' >> $PERM_CONF"
179         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
180         $RUNAS_CMD -u $ID1 -v $ID0 touch $DIR/$tdir/f1 || error "touch (3)"
181
182         chown root $DIR/$tdir || error "chown (4)"
183         chgrp $USER0 $DIR/$tdir || error "chgrp (5)"
184         chmod 0770 $DIR/$tdir || error "chmod (6)"
185         $RUNAS_CMD -u $ID1 -g $ID1 touch $DIR/$tdir/f2 && error "touch (7)"
186         $RUNAS_CMD -u$ID1 -g$ID1 -j$ID0 touch $DIR/$tdir/f3 && error "touch (8)"
187         echo "enable uid $ID1 setuid,setgid"
188         do_facet $SINGLEMDS "echo '* $ID1 setuid,setgid' > $PERM_CONF"
189         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
190         $RUNAS_CMD -u $ID1 -g $ID1 -j $ID0 touch $DIR/$tdir/f4 ||
191                 error "touch (9)"
192         $RUNAS_CMD -u $ID1 -v $ID0 -g $ID1 -j $ID0 touch $DIR/$tdir/f5 ||
193                 error "touch (10)"
194
195         rm -rf $DIR/$tdir
196
197         do_facet $SINGLEMDS "rm -f $PERM_CONF"
198         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
199 }
200 run_test 1 "setuid/gid ============================="
201
202 # bug 3285 - supplementary group should always succeed.
203 # NB: the supplementary groups are set for local client only,
204 # as for remote client, the groups of the specified uid on MDT
205 # will be obtained by upcall /sbin/l_getidentity and used.
206 test_4() {
207         local server_version=$(lustre_version_code $SINGLEMDS)
208
209         [[ $server_version -ge $(version_code 2.6.93) ]] ||
210         [[ $server_version -ge $(version_code 2.5.35) &&
211            $server_version -lt $(version_code 2.5.50) ]] ||
212                 { skip "Need MDS version at least 2.6.93 or 2.5.35"; return; }
213
214         rm -rf $DIR/$tdir
215         mkdir -p $DIR/$tdir
216         chmod 0771 $DIR/$tdir
217         chgrp $ID0 $DIR/$tdir
218         $RUNAS_CMD -u $ID0 ls $DIR/$tdir || error "setgroups (1)"
219         do_facet $SINGLEMDS "echo '* $ID1 setgrp' > $PERM_CONF"
220         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
221         $RUNAS_CMD -u $ID1 -G1,2,$ID0 ls $DIR/$tdir ||
222                 error "setgroups (2)"
223         $RUNAS_CMD -u $ID1 -G1,2 ls $DIR/$tdir && error "setgroups (3)"
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 4 "set supplementary group ==============="
230
231 create_nodemaps() {
232         local i
233         local out
234         local rc
235
236         squash_id default 99 0
237         squash_id default 99 1
238         for (( i = 0; i < NODEMAP_COUNT; i++ )); do
239                 local csum=${HOSTNAME_CHECKSUM}_${i}
240
241                 if ! do_facet mgs $LCTL nodemap_add $csum; then
242                         return 1
243                 fi
244
245                 out=$(do_facet mgs $LCTL get_param nodemap.$csum.id)
246                 ## This needs to return zero if the following statement is 1
247                 [[ $(echo $out | grep -c $csum) == 0 ]] && return 1
248         done
249         return 0
250 }
251
252 delete_nodemaps() {
253         local i
254         local out
255
256         for ((i = 0; i < NODEMAP_COUNT; i++)); do
257                 local csum=${HOSTNAME_CHECKSUM}_${i}
258
259                 if ! do_facet mgs $LCTL nodemap_del $csum; then
260                         error "nodemap_del $csum failed with $?"
261                         return 3
262                 fi
263
264                 out=$(do_facet mgs $LCTL get_param nodemap.$csum.id 2>/dev/null)
265                 [[ $(echo $out | grep -c $csum) != 0 ]] && return 1
266         done
267         return 0
268 }
269
270 add_range() {
271         local j
272         local cmd="$LCTL nodemap_add_range"
273         local range
274         local rc=0
275
276         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
277                 range="$SUBNET_CHECKSUM.${2}.${j}.[1-253]@tcp"
278                 if ! do_facet mgs $cmd --name $1 --range $range; then
279                         rc=$((rc + 1))
280                 fi
281         done
282         return $rc
283 }
284
285 delete_range() {
286         local j
287         local cmd="$LCTL nodemap_del_range"
288         local range
289         local rc=0
290
291         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
292                 range="$SUBNET_CHECKSUM.${2}.${j}.[1-253]@tcp"
293                 if ! do_facet mgs $cmd --name $1 --range $range; then
294                         rc=$((rc + 1))
295                 fi
296         done
297
298         return $rc
299 }
300
301 add_idmaps() {
302         local i
303         local cmd="$LCTL nodemap_add_idmap"
304         local rc=0
305
306         echo "Start to add idmaps ..."
307         for ((i = 0; i < NODEMAP_COUNT; i++)); do
308                 local j
309
310                 for ((j = $ID0; j < NODEMAP_MAX_ID; j++)); do
311                         local csum=${HOSTNAME_CHECKSUM}_${i}
312                         local client_id=$j
313                         local fs_id=$((j + 1))
314
315                         if ! do_facet mgs $cmd --name $csum --idtype uid \
316                              --idmap $client_id:$fs_id; then
317                                 rc=$((rc + 1))
318                         fi
319                         if ! do_facet mgs $cmd --name $csum --idtype gid \
320                              --idmap $client_id:$fs_id; then
321                                 rc=$((rc + 1))
322                         fi
323                 done
324         done
325
326         return $rc
327 }
328
329 update_idmaps() { #LU-10040
330         [ $(lustre_version_code mgs) -lt $(version_code 2.10.55) ] &&
331                 skip "Need MGS >= 2.10.55" &&
332                 return
333         local csum=${HOSTNAME_CHECKSUM}_0
334         local old_id_client=$ID0
335         local old_id_fs=$((ID0 + 1))
336         local new_id=$((ID0 + 100))
337         local tmp_id
338         local cmd
339         local run
340         local idtype
341         local rc=0
342
343         echo "Start to update idmaps ..."
344
345         #Inserting an existed idmap should return error
346         cmd="$LCTL nodemap_add_idmap --name $csum --idtype uid"
347         if do_facet mgs \
348                 $cmd --idmap $old_id_client:$old_id_fs 2>/dev/null; then
349                 error "insert idmap {$old_id_client:$old_id_fs} " \
350                         "should return error"
351                 rc=$((rc + 1))
352                 return rc
353         fi
354
355         #Update id_fs and check it
356         if ! do_facet mgs $cmd --idmap $old_id_client:$new_id; then
357                 error "$cmd --idmap $old_id_client:$new_id failed"
358                 rc=$((rc + 1))
359                 return $rc
360         fi
361         tmp_id=$(do_facet mgs $LCTL get_param -n nodemap.$csum.idmap |
362                 awk '{ print $7 }' | sed -n '2p')
363         [ $tmp_id != $new_id ] && { error "new id_fs $tmp_id != $new_id"; \
364                 rc=$((rc + 1)); return $rc; }
365
366         #Update id_client and check it
367         if ! do_facet mgs $cmd --idmap $new_id:$new_id; then
368                 error "$cmd --idmap $new_id:$new_id failed"
369                 rc=$((rc + 1))
370                 return $rc
371         fi
372         tmp_id=$(do_facet mgs $LCTL get_param -n nodemap.$csum.idmap |
373                 awk '{ print $5 }' | sed -n "$((NODEMAP_ID_COUNT + 1)) p")
374         tmp_id=$(echo ${tmp_id%,*}) #e.g. "501,"->"501"
375         [ $tmp_id != $new_id ] && { error "new id_client $tmp_id != $new_id"; \
376                 rc=$((rc + 1)); return $rc; }
377
378         #Delete above updated idmap
379         cmd="$LCTL nodemap_del_idmap --name $csum --idtype uid"
380         if ! do_facet mgs $cmd --idmap $new_id:$new_id; then
381                 error "$cmd --idmap $new_id:$new_id failed"
382                 rc=$((rc + 1))
383                 return $rc
384         fi
385
386         #restore the idmaps to make delete_idmaps work well
387         cmd="$LCTL nodemap_add_idmap --name $csum --idtype uid"
388         if ! do_facet mgs $cmd --idmap $old_id_client:$old_id_fs; then
389                 error "$cmd --idmap $old_id_client:$old_id_fs failed"
390                 rc=$((rc + 1))
391                 return $rc
392         fi
393
394         return $rc
395 }
396
397 delete_idmaps() {
398         local i
399         local cmd="$LCTL nodemap_del_idmap"
400         local rc=0
401
402         echo "Start to delete idmaps ..."
403         for ((i = 0; i < NODEMAP_COUNT; i++)); do
404                 local j
405
406                 for ((j = $ID0; j < NODEMAP_MAX_ID; j++)); do
407                         local csum=${HOSTNAME_CHECKSUM}_${i}
408                         local client_id=$j
409                         local fs_id=$((j + 1))
410
411                         if ! do_facet mgs $cmd --name $csum --idtype uid \
412                              --idmap $client_id:$fs_id; then
413                                 rc=$((rc + 1))
414                         fi
415                         if ! do_facet mgs $cmd --name $csum --idtype gid \
416                              --idmap $client_id:$fs_id; then
417                                 rc=$((rc + 1))
418                         fi
419                 done
420         done
421
422         return $rc
423 }
424
425 modify_flags() {
426         local i
427         local proc
428         local option
429         local cmd="$LCTL nodemap_modify"
430         local rc=0
431
432         proc[0]="admin_nodemap"
433         proc[1]="trusted_nodemap"
434         option[0]="admin"
435         option[1]="trusted"
436
437         for ((idx = 0; idx < 2; idx++)); do
438                 if ! do_facet mgs $cmd --name $1 --property ${option[$idx]} \
439                      --value 1; then
440                         rc=$((rc + 1))
441                 fi
442
443                 if ! do_facet mgs $cmd --name $1 --property ${option[$idx]} \
444                      --value 0; then
445                         rc=$((rc + 1))
446                 fi
447         done
448
449         return $rc
450 }
451
452 squash_id() {
453         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
454                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
455                 return
456         local cmd
457
458         cmd[0]="$LCTL nodemap_modify --property squash_uid"
459         cmd[1]="$LCTL nodemap_modify --property squash_gid"
460
461         if ! do_facet mgs ${cmd[$3]} --name $1 --value $2; then
462                 return 1
463         fi
464 }
465
466 # ensure that the squash defaults are the expected defaults
467 squash_id default 99 0
468 squash_id default 99 1
469
470 test_nid() {
471         local cmd
472
473         cmd="$LCTL nodemap_test_nid"
474
475         nid=$(do_facet mgs $cmd $1)
476
477         if [ $nid == $2 ]; then
478                 return 0
479         fi
480
481         return 1
482 }
483
484 test_idmap() {
485         local i
486         local cmd="$LCTL nodemap_test_id"
487         local rc=0
488
489         echo "Start to test idmaps ..."
490         ## nodemap deactivated
491         if ! do_facet mgs $LCTL nodemap_activate 0; then
492                 return 1
493         fi
494         for ((id = $ID0; id < NODEMAP_MAX_ID; id++)); do
495                 local j
496
497                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
498                         local nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
499                         local fs_id=$(do_facet mgs $cmd --nid $nid      \
500                                       --idtype uid --id $id)
501                         if [ $fs_id != $id ]; then
502                                 echo "expected $id, got $fs_id"
503                                 rc=$((rc + 1))
504                         fi
505                 done
506         done
507
508         ## nodemap activated
509         if ! do_facet mgs $LCTL nodemap_activate 1; then
510                 return 2
511         fi
512
513         for ((id = $ID0; id < NODEMAP_MAX_ID; id++)); do
514                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
515                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
516                         fs_id=$(do_facet mgs $cmd --nid $nid    \
517                                 --idtype uid --id $id)
518                         expected_id=$((id + 1))
519                         if [ $fs_id != $expected_id ]; then
520                                 echo "expected $expected_id, got $fs_id"
521                                 rc=$((rc + 1))
522                         fi
523                 done
524         done
525
526         ## trust client ids
527         for ((i = 0; i < NODEMAP_COUNT; i++)); do
528                 local csum=${HOSTNAME_CHECKSUM}_${i}
529
530                 if ! do_facet mgs $LCTL nodemap_modify --name $csum \
531                      --property trusted --value 1; then
532                         error "nodemap_modify $csum failed with $?"
533                         return 3
534                 fi
535         done
536
537         for ((id = $ID0; id < NODEMAP_MAX_ID; id++)); do
538                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
539                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
540                         fs_id=$(do_facet mgs $cmd --nid $nid    \
541                                 --idtype uid --id $id)
542                         if [ $fs_id != $id ]; then
543                                 echo "expected $id, got $fs_id"
544                                 rc=$((rc + 1))
545                         fi
546                 done
547         done
548
549         ## ensure allow_root_access is enabled
550         for ((i = 0; i < NODEMAP_COUNT; i++)); do
551                 local csum=${HOSTNAME_CHECKSUM}_${i}
552
553                 if ! do_facet mgs $LCTL nodemap_modify --name $csum     \
554                      --property admin --value 1; then
555                         error "nodemap_modify $csum failed with $?"
556                         return 3
557                 fi
558         done
559
560         ## check that root allowed
561         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
562                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
563                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
564                 if [ $fs_id != 0 ]; then
565                         echo "root allowed expected 0, got $fs_id"
566                         rc=$((rc + 1))
567                 fi
568         done
569
570         ## ensure allow_root_access is disabled
571         for ((i = 0; i < NODEMAP_COUNT; i++)); do
572                 local csum=${HOSTNAME_CHECKSUM}_${i}
573
574                 if ! do_facet mgs $LCTL nodemap_modify --name $csum     \
575                                 --property admin --value 0; then
576                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
577                                 "failed with $rc"
578                         return 3
579                 fi
580         done
581
582         ## check that root is mapped to 99
583         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
584                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
585                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
586                 if [ $fs_id != 99 ]; then
587                         error "root squash expected 99, got $fs_id"
588                         rc=$((rc + 1))
589                 fi
590         done
591
592         ## reset client trust to 0
593         for ((i = 0; i < NODEMAP_COUNT; i++)); do
594                 if ! do_facet mgs $LCTL nodemap_modify          \
595                         --name ${HOSTNAME_CHECKSUM}_${i}        \
596                         --property trusted --value 0; then
597                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
598                                 "failed with $rc"
599                         return 3
600                 fi
601         done
602
603         return $rc
604 }
605
606 test_7() {
607         local rc
608
609         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
610         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
611                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
612                 return
613
614         create_nodemaps
615         rc=$?
616         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
617
618         delete_nodemaps
619         rc=$?
620         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 2
621
622         return 0
623 }
624 run_test 7 "nodemap create and delete"
625
626 test_8() {
627         local rc
628
629         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
630         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
631                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
632                 return
633
634         # Set up nodemaps
635
636         create_nodemaps
637         rc=$?
638         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
639
640         # Try duplicates
641
642         create_nodemaps
643         rc=$?
644         [[ $rc == 0 ]] && error "duplicate nodemap_add allowed with $rc" &&
645         return 2
646
647         # Clean up
648         delete_nodemaps
649         rc=$?
650         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 3
651
652         return 0
653 }
654 run_test 8 "nodemap reject duplicates"
655
656 test_9() {
657         local i
658         local rc
659
660         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
661         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
662                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
663                 return
664
665         rc=0
666         create_nodemaps
667         rc=$?
668         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
669
670         rc=0
671         for ((i = 0; i < NODEMAP_COUNT; i++)); do
672                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
673                         rc=$((rc + 1))
674                 fi
675         done
676         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
677
678         rc=0
679         for ((i = 0; i < NODEMAP_COUNT; i++)); do
680                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
681                         rc=$((rc + 1))
682                 fi
683         done
684         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
685
686         rc=0
687         delete_nodemaps
688         rc=$?
689         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
690
691         return 0
692 }
693 run_test 9 "nodemap range add"
694
695 test_10a() {
696         local rc
697
698         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
699         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
700                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
701                 return
702
703         rc=0
704         create_nodemaps
705         rc=$?
706         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
707
708         rc=0
709         for ((i = 0; i < NODEMAP_COUNT; i++)); do
710                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
711                         rc=$((rc + 1))
712                 fi
713         done
714         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
715
716         rc=0
717         for ((i = 0; i < NODEMAP_COUNT; i++)); do
718                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
719                         rc=$((rc + 1))
720                 fi
721         done
722         [[ $rc == 0 ]] && error "nodemap_add_range duplicate add with $rc" &&
723                 return 2
724
725
726         rc=0
727         for ((i = 0; i < NODEMAP_COUNT; i++)); do
728                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
729                         rc=$((rc + 1))
730                 fi
731         done
732         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
733
734         delete_nodemaps
735         rc=$?
736         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 5
737
738         return 0
739 }
740 run_test 10a "nodemap reject duplicate ranges"
741
742 test_10b() {
743         [ $(lustre_version_code mgs) -lt $(version_code 2.10.53) ] &&
744                 skip "Need MGS >= 2.10.53" && return
745
746         local nm1="nodemap1"
747         local nm2="nodemap2"
748         local nids="192.168.19.[0-255]@o2ib20"
749
750         do_facet mgs $LCTL nodemap_del $nm1 2>/dev/null
751         do_facet mgs $LCTL nodemap_del $nm2 2>/dev/null
752
753         do_facet mgs $LCTL nodemap_add $nm1 || error "Add $nm1 failed"
754         do_facet mgs $LCTL nodemap_add $nm2 || error "Add $nm2 failed"
755         do_facet mgs $LCTL nodemap_add_range --name $nm1 --range $nids ||
756                 error "Add range $nids to $nm1 failed"
757         [ -n "$(do_facet mgs $LCTL get_param nodemap.$nm1.* |
758                 grep start_nid)" ] || error "No range was found"
759         do_facet mgs $LCTL nodemap_del_range --name $nm2 --range $nids &&
760                 error "Deleting range $nids from $nm2 should fail"
761         [ -n "$(do_facet mgs $LCTL get_param nodemap.$nm1.* |
762                 grep start_nid)" ] || error "Range $nids should be there"
763
764         do_facet mgs $LCTL nodemap_del $nm1 || error "Delete $nm1 failed"
765         do_facet mgs $LCTL nodemap_del $nm2 || error "Delete $nm2 failed"
766         return 0
767 }
768 run_test 10b "delete range from the correct nodemap"
769
770 test_10c() { #LU-8912
771         [ $(lustre_version_code mgs) -lt $(version_code 2.10.57) ] &&
772                 skip "Need MGS >= 2.10.57" && return
773
774         local nm="nodemap_lu8912"
775         local nid_range="10.210.[32-47].[0-255]@o2ib3"
776         local start_nid="10.210.32.0@o2ib3"
777         local end_nid="10.210.47.255@o2ib3"
778         local start_nid_found
779         local end_nid_found
780
781         do_facet mgs $LCTL nodemap_del $nm 2>/dev/null
782         do_facet mgs $LCTL nodemap_add $nm || error "Add $nm failed"
783         do_facet mgs $LCTL nodemap_add_range --name $nm --range $nid_range ||
784                 error "Add range $nid_range to $nm failed"
785
786         start_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
787                 awk -F '[,: ]' /start_nid/'{ print $9 }')
788         [ "$start_nid" == "$start_nid_found" ] ||
789                 error "start_nid: $start_nid_found != $start_nid"
790         end_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
791                 awk -F '[,: ]' /end_nid/'{ print $13 }')
792         [ "$end_nid" == "$end_nid_found" ] ||
793                 error "end_nid: $end_nid_found != $end_nid"
794
795         do_facet mgs $LCTL nodemap_del $nm || error "Delete $nm failed"
796         return 0
797 }
798 run_test 10c "verfify contiguous range support"
799
800 test_10d() { #LU-8913
801         [ $(lustre_version_code mgs) -lt $(version_code 2.10.59) ] &&
802                 skip "Need MGS >= 2.10.59" && return
803
804         local nm="nodemap_lu8913"
805         local nid_range="*@o2ib3"
806         local start_nid="0.0.0.0@o2ib3"
807         local end_nid="255.255.255.255@o2ib3"
808         local start_nid_found
809         local end_nid_found
810
811         do_facet mgs $LCTL nodemap_del $nm 2>/dev/null
812         do_facet mgs $LCTL nodemap_add $nm || error "Add $nm failed"
813         do_facet mgs $LCTL nodemap_add_range --name $nm --range $nid_range ||
814                 error "Add range $nid_range to $nm failed"
815
816         start_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
817                 awk -F '[,: ]' /start_nid/'{ print $9 }')
818         [ "$start_nid" == "$start_nid_found" ] ||
819                 error "start_nid: $start_nid_found != $start_nid"
820         end_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
821                 awk -F '[,: ]' /end_nid/'{ print $13 }')
822         [ "$end_nid" == "$end_nid_found" ] ||
823                 error "end_nid: $end_nid_found != $end_nid"
824
825         do_facet mgs $LCTL nodemap_del $nm || error "Delete $nm failed"
826         return 0
827 }
828 run_test 10d "verfify nodemap range format '*@<net>' support"
829
830 test_11() {
831         local rc
832
833         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
834         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
835                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
836                 return
837
838         rc=0
839         create_nodemaps
840         rc=$?
841         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
842
843         rc=0
844         for ((i = 0; i < NODEMAP_COUNT; i++)); do
845                 if ! modify_flags ${HOSTNAME_CHECKSUM}_${i}; then
846                         rc=$((rc + 1))
847                 fi
848         done
849         [[ $rc != 0 ]] && error "nodemap_modify with $rc" && return 2
850
851         rc=0
852         delete_nodemaps
853         rc=$?
854         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 3
855
856         return 0
857 }
858 run_test 11 "nodemap modify"
859
860 test_12() {
861         local rc
862
863         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
864         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
865                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
866                 return
867
868         rc=0
869         create_nodemaps
870         rc=$?
871         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
872
873         rc=0
874         for ((i = 0; i < NODEMAP_COUNT; i++)); do
875                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 0; then
876                         rc=$((rc + 1))
877                 fi
878         done
879         [[ $rc != 0 ]] && error "nodemap squash_uid with $rc" && return 2
880
881         rc=0
882         for ((i = 0; i < NODEMAP_COUNT; i++)); do
883                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 1; then
884                         rc=$((rc + 1))
885                 fi
886         done
887         [[ $rc != 0 ]] && error "nodemap squash_gid with $rc" && return 3
888
889         rc=0
890         delete_nodemaps
891         rc=$?
892         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
893
894         return 0
895 }
896 run_test 12 "nodemap set squash ids"
897
898 test_13() {
899         local rc
900
901         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
902         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
903                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
904                 return
905
906         rc=0
907         create_nodemaps
908         rc=$?
909         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
910
911         rc=0
912         for ((i = 0; i < NODEMAP_COUNT; i++)); do
913                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
914                         rc=$((rc + 1))
915                 fi
916         done
917         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
918
919         rc=0
920         for ((i = 0; i < NODEMAP_COUNT; i++)); do
921                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
922                         for k in $NODEMAP_IPADDR_LIST; do
923                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
924                                        ${HOSTNAME_CHECKSUM}_${i}; then
925                                         rc=$((rc + 1))
926                                 fi
927                         done
928                 done
929         done
930         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
931
932         rc=0
933         delete_nodemaps
934         rc=$?
935         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
936
937         return 0
938 }
939 run_test 13 "test nids"
940
941 test_14() {
942         local rc
943
944         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
945         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
946                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
947                 return
948
949         rc=0
950         create_nodemaps
951         rc=$?
952         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
953
954         rc=0
955         for ((i = 0; i < NODEMAP_COUNT; i++)); do
956                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
957                         for k in $NODEMAP_IPADDR_LIST; do
958                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
959                                         default; then
960                                         rc=$((rc + 1))
961                                 fi
962                         done
963                 done
964         done
965         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
966
967         rc=0
968         delete_nodemaps
969         rc=$?
970         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
971
972         return 0
973 }
974 run_test 14 "test default nodemap nid lookup"
975
976 test_15() {
977         local rc
978
979         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
980         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
981                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
982                 return
983
984         rc=0
985         create_nodemaps
986         rc=$?
987         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
988
989         rc=0
990         for ((i = 0; i < NODEMAP_COUNT; i++)); do
991                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
992                         rc=$((rc + 1))
993                 fi
994         done
995         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
996
997         rc=0
998         add_idmaps
999         rc=$?
1000         [[ $rc != 0 ]] && error "nodemap_add_idmap failed with $rc" && return 3
1001
1002         rc=0
1003         test_idmap
1004         rc=$?
1005         [[ $rc != 0 ]] && error "nodemap_test_id failed with $rc" && return 4
1006
1007         rc=0
1008         update_idmaps
1009         rc=$?
1010         [[ $rc != 0 ]] && error "update_idmaps failed with $rc" && return 5
1011
1012         rc=0
1013         delete_idmaps
1014         rc=$?
1015         [[ $rc != 0 ]] && error "nodemap_del_idmap failed with $rc" && return 6
1016
1017         rc=0
1018         delete_nodemaps
1019         rc=$?
1020         [[ $rc != 0 ]] && error "nodemap_delete failed with $rc" && return 7
1021
1022         return 0
1023 }
1024 run_test 15 "test id mapping"
1025
1026 wait_nm_sync() {
1027         local nodemap_name=$1
1028         local key=$2
1029         local value=$3
1030         local opt=$4
1031         local proc_param
1032         local is_active=$(do_facet mgs $LCTL get_param -n nodemap.active)
1033         local max_retries=20
1034         local is_sync
1035         local out1=""
1036         local out2
1037         local mgs_ip=$(host_nids_address $mgs_HOST $NETTYPE | cut -d' ' -f1)
1038         local i
1039
1040         if [ "$nodemap_name" == "active" ]; then
1041                 proc_param="active"
1042         elif [ -z "$key" ]; then
1043                 proc_param=${nodemap_name}
1044         else
1045                 proc_param="${nodemap_name}.${key}"
1046         fi
1047         (( is_active == 0 )) && [ "$proc_param" != "active" ] && return
1048
1049         if [ -z "$value" ]; then
1050                 out1=$(do_facet mgs $LCTL get_param $opt nodemap.${proc_param})
1051                 echo "On MGS ${mgs_ip}, ${proc_param} = $out1"
1052         else
1053                 out1=$value;
1054         fi
1055
1056         # wait up to 10 seconds for other servers to sync with mgs
1057         for i in $(seq 1 10); do
1058                 for node in $(all_server_nodes); do
1059                     local node_ip=$(host_nids_address $node $NETTYPE |
1060                                     cut -d' ' -f1)
1061
1062                     is_sync=true
1063                     if [ -z "$value" ]; then
1064                         [ $node_ip == $mgs_ip ] && continue
1065                     fi
1066
1067                     out2=$(do_node $node_ip $LCTL get_param $opt \
1068                                    nodemap.$proc_param 2>/dev/null)
1069                     echo "On $node ${node_ip}, ${proc_param} = $out2"
1070                     [ "$out1" != "$out2" ] && is_sync=false && break
1071                 done
1072                 $is_sync && break
1073                 sleep 1
1074         done
1075         if ! $is_sync; then
1076                 echo MGS
1077                 echo $out1
1078                 echo OTHER - IP: $node_ip
1079                 echo $out2
1080                 error "mgs and $nodemap_name ${key} mismatch, $i attempts"
1081         fi
1082         echo "waited $((i - 1)) seconds for sync"
1083 }
1084
1085 create_fops_nodemaps() {
1086         local i=0
1087         local client
1088         for client in $clients; do
1089                 local client_ip=$(host_nids_address $client $NETTYPE)
1090                 local client_nid=$(h2nettype $client_ip)
1091                 do_facet mgs $LCTL nodemap_add c${i} || return 1
1092                 do_facet mgs $LCTL nodemap_add_range    \
1093                         --name c${i} --range $client_nid || return 1
1094                 for map in ${FOPS_IDMAPS[i]}; do
1095                         do_facet mgs $LCTL nodemap_add_idmap --name c${i} \
1096                                 --idtype uid --idmap ${map} || return 1
1097                         do_facet mgs $LCTL nodemap_add_idmap --name c${i} \
1098                                 --idtype gid --idmap ${map} || return 1
1099                 done
1100
1101                 wait_nm_sync c$i idmap
1102
1103                 i=$((i + 1))
1104         done
1105         return 0
1106 }
1107
1108 delete_fops_nodemaps() {
1109         local i=0
1110         local client
1111         for client in $clients; do
1112                 do_facet mgs $LCTL nodemap_del c${i} || return 1
1113                 i=$((i + 1))
1114         done
1115         return 0
1116 }
1117
1118 fops_mds_index=0
1119 nm_test_mkdir() {
1120         if [ $MDSCOUNT -le 1 ]; then
1121                 do_node ${clients_arr[0]} mkdir -p $DIR/$tdir
1122         else
1123                 # round-robin MDTs to test DNE nodemap support
1124                 [ ! -d $DIR ] && do_node ${clients_arr[0]} mkdir -p $DIR
1125                 do_node ${clients_arr[0]} $LFS setdirstripe -c 1 -i \
1126                         $((fops_mds_index % MDSCOUNT)) $DIR/$tdir
1127                 ((fops_mds_index++))
1128         fi
1129 }
1130
1131 # acl test directory needs to be initialized on a privileged client
1132 fops_test_setup() {
1133         local admin=$(do_facet mgs $LCTL get_param -n nodemap.c0.admin_nodemap)
1134         local trust=$(do_facet mgs $LCTL get_param -n \
1135                 nodemap.c0.trusted_nodemap)
1136
1137         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1138         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1139
1140         wait_nm_sync c0 admin_nodemap
1141         wait_nm_sync c0 trusted_nodemap
1142
1143         do_node ${clients_arr[0]} rm -rf $DIR/$tdir
1144         nm_test_mkdir
1145         do_node ${clients_arr[0]} chown $user $DIR/$tdir
1146
1147         do_facet mgs $LCTL nodemap_modify --name c0 \
1148                 --property admin --value $admin
1149         do_facet mgs $LCTL nodemap_modify --name c0 \
1150                 --property trusted --value $trust
1151
1152         # flush MDT locks to make sure they are reacquired before test
1153         do_node ${clients_arr[0]} $LCTL set_param \
1154                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
1155
1156         wait_nm_sync c0 admin_nodemap
1157         wait_nm_sync c0 trusted_nodemap
1158 }
1159
1160 # fileset test directory needs to be initialized on a privileged client
1161 fileset_test_setup() {
1162         local nm=$1
1163         local admin=$(do_facet mgs $LCTL get_param -n \
1164                 nodemap.${nm}.admin_nodemap)
1165         local trust=$(do_facet mgs $LCTL get_param -n \
1166                 nodemap.${nm}.trusted_nodemap)
1167
1168         do_facet mgs $LCTL nodemap_modify --name $nm --property admin --value 1
1169         do_facet mgs $LCTL nodemap_modify --name $nm --property trusted \
1170                 --value 1
1171
1172         wait_nm_sync $nm admin_nodemap
1173         wait_nm_sync $nm trusted_nodemap
1174
1175         # create directory and populate it for subdir mount
1176         do_node ${clients_arr[0]} mkdir $MOUNT/$subdir ||
1177                 error "unable to create dir $MOUNT/$subdir"
1178         do_node ${clients_arr[0]} touch $MOUNT/$subdir/this_is_$subdir ||
1179                 error "unable to create file $MOUNT/$subdir/this_is_$subdir"
1180         do_node ${clients_arr[0]} mkdir $MOUNT/$subdir/$subsubdir ||
1181                 error "unable to create dir $MOUNT/$subdir/$subsubdir"
1182         do_node ${clients_arr[0]} touch \
1183                         $MOUNT/$subdir/$subsubdir/this_is_$subsubdir ||
1184                 error "unable to create file \
1185                         $MOUNT/$subdir/$subsubdir/this_is_$subsubdir"
1186
1187         do_facet mgs $LCTL nodemap_modify --name $nm \
1188                 --property admin --value $admin
1189         do_facet mgs $LCTL nodemap_modify --name $nm \
1190                 --property trusted --value $trust
1191
1192         # flush MDT locks to make sure they are reacquired before test
1193         do_node ${clients_arr[0]} $LCTL set_param \
1194                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
1195
1196         wait_nm_sync $nm admin_nodemap
1197         wait_nm_sync $nm trusted_nodemap
1198 }
1199
1200 # fileset test directory needs to be initialized on a privileged client
1201 fileset_test_cleanup() {
1202         local nm=$1
1203         local admin=$(do_facet mgs $LCTL get_param -n \
1204                 nodemap.${nm}.admin_nodemap)
1205         local trust=$(do_facet mgs $LCTL get_param -n \
1206                 nodemap.${nm}.trusted_nodemap)
1207
1208         do_facet mgs $LCTL nodemap_modify --name $nm --property admin --value 1
1209         do_facet mgs $LCTL nodemap_modify --name $nm --property trusted \
1210                 --value 1
1211
1212         wait_nm_sync $nm admin_nodemap
1213         wait_nm_sync $nm trusted_nodemap
1214
1215         # cleanup directory created for subdir mount
1216         do_node ${clients_arr[0]} rm -rf $MOUNT/$subdir ||
1217                 error "unable to remove dir $MOUNT/$subdir"
1218
1219         do_facet mgs $LCTL nodemap_modify --name $nm \
1220                 --property admin --value $admin
1221         do_facet mgs $LCTL nodemap_modify --name $nm \
1222                 --property trusted --value $trust
1223
1224         # flush MDT locks to make sure they are reacquired before test
1225         do_node ${clients_arr[0]} $LCTL set_param \
1226                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
1227
1228         wait_nm_sync $nm admin_nodemap
1229         wait_nm_sync $nm trusted_nodemap
1230 }
1231
1232 do_create_delete() {
1233         local run_u=$1
1234         local key=$2
1235         local testfile=$DIR/$tdir/$tfile
1236         local rc=0
1237         local c=0 d=0
1238         local qused_new
1239         if $run_u touch $testfile >& /dev/null; then
1240                 c=1
1241                 $run_u rm $testfile && d=1
1242         fi >& /dev/null
1243
1244         local res="$c $d"
1245         local expected=$(get_cr_del_expected $key)
1246         [ "$res" != "$expected" ] &&
1247                 error "test $key, wanted $expected, got $res" && rc=$((rc + 1))
1248         return $rc
1249 }
1250
1251 nodemap_check_quota() {
1252         local run_u="$1"
1253         $run_u lfs quota -q $DIR | awk '{ print $2; exit; }'
1254 }
1255
1256 do_fops_quota_test() {
1257         local run_u=$1
1258         # fuzz quota used to account for possible indirect blocks, etc
1259         local quota_fuzz=$(fs_log_size)
1260         local qused_orig=$(nodemap_check_quota "$run_u")
1261         local qused_high=$((qused_orig + quota_fuzz))
1262         local qused_low=$((qused_orig - quota_fuzz))
1263         local testfile=$DIR/$tdir/$tfile
1264         $run_u dd if=/dev/zero of=$testfile oflag=sync bs=1M count=1 \
1265                 >& /dev/null || error "unable to write quota test file"
1266         sync; sync_all_data || true
1267
1268         local qused_new=$(nodemap_check_quota "$run_u")
1269         [ $((qused_new)) -lt $((qused_low + 1024)) -o \
1270           $((qused_new)) -gt $((qused_high + 1024)) ] &&
1271                 error "$qused_new != $qused_orig + 1M after write, " \
1272                       "fuzz is $quota_fuzz"
1273         $run_u rm $testfile || error "unable to remove quota test file"
1274         wait_delete_completed_mds
1275
1276         qused_new=$(nodemap_check_quota "$run_u")
1277         [ $((qused_new)) -lt $((qused_low)) \
1278                 -o $((qused_new)) -gt $((qused_high)) ] &&
1279                 error "quota not reclaimed, expect $qused_orig, " \
1280                       "got $qused_new, fuzz $quota_fuzz"
1281 }
1282
1283 get_fops_mapped_user() {
1284         local cli_user=$1
1285
1286         for ((i=0; i < ${#FOPS_IDMAPS[@]}; i++)); do
1287                 for map in ${FOPS_IDMAPS[i]}; do
1288                         if [ $(cut -d: -f1 <<< "$map") == $cli_user ]; then
1289                                 cut -d: -f2 <<< "$map"
1290                                 return
1291                         fi
1292                 done
1293         done
1294         echo -1
1295 }
1296
1297 get_cr_del_expected() {
1298         local -a key
1299         IFS=":" read -a key <<< "$1"
1300         local mapmode="${key[0]}"
1301         local mds_user="${key[1]}"
1302         local cluster="${key[2]}"
1303         local cli_user="${key[3]}"
1304         local mode="0${key[4]}"
1305         local SUCCESS="1 1"
1306         local FAILURE="0 0"
1307         local noadmin=0
1308         local mapped=0
1309         local other=0
1310
1311         [[ $mapmode == *mapped* ]] && mapped=1
1312         # only c1 is mapped in these test cases
1313         [[ $mapmode == mapped_trusted* ]] && [ "$cluster" == "c0" ] && mapped=0
1314         [[ $mapmode == *noadmin* ]] && noadmin=1
1315
1316         # o+wx works as long as the user isn't mapped
1317         if [ $((mode & 3)) -eq 3 ]; then
1318                 other=1
1319         fi
1320
1321         # if client user is root, check if root is squashed
1322         if [ "$cli_user" == "0" ]; then
1323                 # squash root succeed, if other bit is on
1324                 case $noadmin in
1325                         0) echo $SUCCESS;;
1326                         1) [ "$other" == "1" ] && echo $SUCCESS
1327                            [ "$other" == "0" ] && echo $FAILURE;;
1328                 esac
1329                 return
1330         fi
1331         if [ "$mapped" == "0" ]; then
1332                 [ "$other" == "1" ] && echo $SUCCESS
1333                 [ "$other" == "0" ] && echo $FAILURE
1334                 return
1335         fi
1336
1337         # if mapped user is mds user, check for u+wx
1338         mapped_user=$(get_fops_mapped_user $cli_user)
1339         [ "$mapped_user" == "-1" ] &&
1340                 error "unable to find mapping for client user $cli_user"
1341
1342         if [ "$mapped_user" == "$mds_user" -a \
1343              $(((mode & 0300) == 0300)) -eq 1 ]; then
1344                 echo $SUCCESS
1345                 return
1346         fi
1347         if [ "$mapped_user" != "$mds_user" -a "$other" == "1" ]; then
1348                 echo $SUCCESS
1349                 return
1350         fi
1351         echo $FAILURE
1352 }
1353
1354 test_fops_admin_cli_i=""
1355 test_fops_chmod_dir() {
1356         local current_cli_i=$1
1357         local perm_bits=$2
1358         local dir_to_chmod=$3
1359         local new_admin_cli_i=""
1360
1361         # do we need to set up a new admin client?
1362         [ "$current_cli_i" == "0" ] && [ "$test_fops_admin_cli_i" != "1" ] &&
1363                 new_admin_cli_i=1
1364         [ "$current_cli_i" != "0" ] && [ "$test_fops_admin_cli_i" != "0" ] &&
1365                 new_admin_cli_i=0
1366
1367         # if only one client, and non-admin, need to flip admin everytime
1368         if [ "$num_clients" == "1" ]; then
1369                 test_fops_admin_client=$clients
1370                 test_fops_admin_val=$(do_facet mgs $LCTL get_param -n \
1371                         nodemap.c0.admin_nodemap)
1372                 if [ "$test_fops_admin_val" != "1" ]; then
1373                         do_facet mgs $LCTL nodemap_modify \
1374                                 --name c0 \
1375                                 --property admin \
1376                                 --value 1
1377                         wait_nm_sync c0 admin_nodemap
1378                 fi
1379         elif [ "$new_admin_cli_i" != "" ]; then
1380                 # restore admin val to old admin client
1381                 if [ "$test_fops_admin_cli_i" != "" ] &&
1382                                 [ "$test_fops_admin_val" != "1" ]; then
1383                         do_facet mgs $LCTL nodemap_modify \
1384                                 --name c${test_fops_admin_cli_i} \
1385                                 --property admin \
1386                                 --value $test_fops_admin_val
1387                         wait_nm_sync c${test_fops_admin_cli_i} admin_nodemap
1388                 fi
1389
1390                 test_fops_admin_cli_i=$new_admin_cli_i
1391                 test_fops_admin_client=${clients_arr[$new_admin_cli_i]}
1392                 test_fops_admin_val=$(do_facet mgs $LCTL get_param -n \
1393                         nodemap.c${new_admin_cli_i}.admin_nodemap)
1394
1395                 if [ "$test_fops_admin_val" != "1" ]; then
1396                         do_facet mgs $LCTL nodemap_modify \
1397                                 --name c${new_admin_cli_i} \
1398                                 --property admin \
1399                                 --value 1
1400                         wait_nm_sync c${new_admin_cli_i} admin_nodemap
1401                 fi
1402         fi
1403
1404         do_node $test_fops_admin_client chmod $perm_bits $DIR/$tdir || return 1
1405
1406         # remove admin for single client if originally non-admin
1407         if [ "$num_clients" == "1" ] && [ "$test_fops_admin_val" != "1" ]; then
1408                 do_facet mgs $LCTL nodemap_modify --name c0 --property admin \
1409                         --value 0
1410                 wait_nm_sync c0 admin_nodemap
1411         fi
1412
1413         return 0
1414 }
1415
1416 test_fops() {
1417         local mapmode="$1"
1418         local single_client="$2"
1419         local client_user_list=([0]="0 $((IDBASE+3)) $((IDBASE+4))"
1420                                 [1]="0 $((IDBASE+5)) $((IDBASE+6))")
1421         local mds_i
1422         local rc=0
1423         local perm_bit_list="0 3 $((0300)) $((0303))"
1424         # SLOW tests 000-007, 010-070, 100-700 (octal modes)
1425         [ "$SLOW" == "yes" ] &&
1426                 perm_bit_list="0 $(seq 1 7) $(seq 8 8 63) $(seq 64 64 511) \
1427                                $((0303))"
1428
1429         # step through mds users. -1 means root
1430         for mds_i in -1 0 1 2; do
1431                 local user=$((mds_i + IDBASE))
1432                 local client
1433                 local x
1434
1435                 [ "$mds_i" == "-1" ] && user=0
1436
1437                 echo mkdir -p $DIR/$tdir
1438                 fops_test_setup
1439                 local cli_i=0
1440                 for client in $clients; do
1441                         local u
1442                         for u in ${client_user_list[$cli_i]}; do
1443                                 local run_u="do_node $client \
1444                                              $RUNAS_CMD -u$u -g$u -G$u"
1445                                 for perm_bits in $perm_bit_list; do
1446                                         local mode=$(printf %03o $perm_bits)
1447                                         local key
1448                                         key="$mapmode:$user:c$cli_i:$u:$mode"
1449                                         test_fops_chmod_dir $cli_i $mode \
1450                                                 $DIR/$tdir ||
1451                                                         error cannot chmod $key
1452                                         do_create_delete "$run_u" "$key"
1453                                 done
1454
1455                                 # check quota
1456                                 test_fops_chmod_dir $cli_i 777 $DIR/$tdir ||
1457                                         error cannot chmod $key
1458                                 do_fops_quota_test "$run_u"
1459                         done
1460
1461                         cli_i=$((cli_i + 1))
1462                         [ "$single_client" == "1" ] && break
1463                 done
1464                 rm -rf $DIR/$tdir
1465         done
1466         return $rc
1467 }
1468
1469 nodemap_version_check () {
1470         remote_mgs_nodsh && skip "remote MGS with nodsh" && return 1
1471         [ $(lustre_version_code mgs) -lt $(version_code 2.5.53) ] &&
1472                 skip "No nodemap on $(lustre_build_version mgs) MGS < 2.5.53" &&
1473                 return 1
1474         return 0
1475 }
1476
1477 nodemap_test_setup() {
1478         local rc
1479         local active_nodemap=1
1480
1481         [ "$1" == "0" ] && active_nodemap=0
1482
1483         do_nodes $(comma_list $(all_mdts_nodes)) \
1484                 $LCTL set_param mdt.*.identity_upcall=NONE
1485
1486         rc=0
1487         create_fops_nodemaps
1488         rc=$?
1489         [[ $rc != 0 ]] && error "adding fops nodemaps failed $rc"
1490
1491         do_facet mgs $LCTL nodemap_activate $active_nodemap
1492         wait_nm_sync active
1493
1494         do_facet mgs $LCTL nodemap_modify --name default \
1495                 --property admin --value 1
1496         wait_nm_sync default admin_nodemap
1497         do_facet mgs $LCTL nodemap_modify --name default \
1498                 --property trusted --value 1
1499         wait_nm_sync default trusted_nodemap
1500 }
1501
1502 nodemap_test_cleanup() {
1503         trap 0
1504         delete_fops_nodemaps
1505         rc=$?
1506         [[ $rc != 0 ]] && error "removing fops nodemaps failed $rc"
1507
1508         do_facet mgs $LCTL nodemap_modify --name default \
1509                  --property admin --value 0
1510         wait_nm_sync default admin_nodemap
1511         do_facet mgs $LCTL nodemap_modify --name default \
1512                  --property trusted --value 0
1513         wait_nm_sync default trusted_nodemap
1514
1515         do_facet mgs $LCTL nodemap_activate 0
1516         wait_nm_sync active 0
1517
1518         export SK_UNIQUE_NM=false
1519         return 0
1520 }
1521
1522 nodemap_clients_admin_trusted() {
1523         local admin=$1
1524         local tr=$2
1525         local i=0
1526         for client in $clients; do
1527                 do_facet mgs $LCTL nodemap_modify --name c0 \
1528                         --property admin --value $admin
1529                 do_facet mgs $LCTL nodemap_modify --name c0 \
1530                         --property trusted --value $tr
1531                 i=$((i + 1))
1532         done
1533         wait_nm_sync c$((i - 1)) admin_nodemap
1534         wait_nm_sync c$((i - 1)) trusted_nodemap
1535 }
1536
1537 test_16() {
1538         nodemap_version_check || return 0
1539         nodemap_test_setup 0
1540
1541         trap nodemap_test_cleanup EXIT
1542         test_fops all_off
1543         nodemap_test_cleanup
1544 }
1545 run_test 16 "test nodemap all_off fileops"
1546
1547 test_17() {
1548         nodemap_version_check || return 0
1549         nodemap_test_setup
1550
1551         trap nodemap_test_cleanup EXIT
1552         nodemap_clients_admin_trusted 0 1
1553         test_fops trusted_noadmin 1
1554         nodemap_test_cleanup
1555 }
1556 run_test 17 "test nodemap trusted_noadmin fileops"
1557
1558 test_18() {
1559         nodemap_version_check || return 0
1560         nodemap_test_setup
1561
1562         trap nodemap_test_cleanup EXIT
1563         nodemap_clients_admin_trusted 0 0
1564         test_fops mapped_noadmin 1
1565         nodemap_test_cleanup
1566 }
1567 run_test 18 "test nodemap mapped_noadmin fileops"
1568
1569 test_19() {
1570         nodemap_version_check || return 0
1571         nodemap_test_setup
1572
1573         trap nodemap_test_cleanup EXIT
1574         nodemap_clients_admin_trusted 1 1
1575         test_fops trusted_admin 1
1576         nodemap_test_cleanup
1577 }
1578 run_test 19 "test nodemap trusted_admin fileops"
1579
1580 test_20() {
1581         nodemap_version_check || return 0
1582         nodemap_test_setup
1583
1584         trap nodemap_test_cleanup EXIT
1585         nodemap_clients_admin_trusted 1 0
1586         test_fops mapped_admin 1
1587         nodemap_test_cleanup
1588 }
1589 run_test 20 "test nodemap mapped_admin fileops"
1590
1591 test_21() {
1592         nodemap_version_check || return 0
1593         nodemap_test_setup
1594
1595         trap nodemap_test_cleanup EXIT
1596         local x=1
1597         local i=0
1598         for client in $clients; do
1599                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1600                         --property admin --value 0
1601                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1602                         --property trusted --value $x
1603                 x=0
1604                 i=$((i + 1))
1605         done
1606         wait_nm_sync c$((i - 1)) trusted_nodemap
1607
1608         test_fops mapped_trusted_noadmin
1609         nodemap_test_cleanup
1610 }
1611 run_test 21 "test nodemap mapped_trusted_noadmin fileops"
1612
1613 test_22() {
1614         nodemap_version_check || return 0
1615         nodemap_test_setup
1616
1617         trap nodemap_test_cleanup EXIT
1618         local x=1
1619         local i=0
1620         for client in $clients; do
1621                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1622                         --property admin --value 1
1623                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1624                         --property trusted --value $x
1625                 x=0
1626                 i=$((i + 1))
1627         done
1628         wait_nm_sync c$((i - 1)) trusted_nodemap
1629
1630         test_fops mapped_trusted_admin
1631         nodemap_test_cleanup
1632 }
1633 run_test 22 "test nodemap mapped_trusted_admin fileops"
1634
1635 # acl test directory needs to be initialized on a privileged client
1636 nodemap_acl_test_setup() {
1637         local admin=$(do_facet mgs $LCTL get_param -n \
1638                       nodemap.c0.admin_nodemap)
1639         local trust=$(do_facet mgs $LCTL get_param -n \
1640                       nodemap.c0.trusted_nodemap)
1641
1642         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1643         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1644
1645         wait_nm_sync c0 admin_nodemap
1646         wait_nm_sync c0 trusted_nodemap
1647
1648         do_node ${clients_arr[0]} rm -rf $DIR/$tdir
1649         nm_test_mkdir
1650         do_node ${clients_arr[0]} chmod a+rwx $DIR/$tdir ||
1651                 error unable to chmod a+rwx test dir $DIR/$tdir
1652
1653         do_facet mgs $LCTL nodemap_modify --name c0 \
1654                 --property admin --value $admin
1655         do_facet mgs $LCTL nodemap_modify --name c0 \
1656                 --property trusted --value $trust
1657
1658         wait_nm_sync c0 trusted_nodemap
1659 }
1660
1661 # returns 0 if the number of ACLs does not change on the second (mapped) client
1662 # after being set on the first client
1663 nodemap_acl_test() {
1664         local user="$1"
1665         local set_client="$2"
1666         local get_client="$3"
1667         local check_setfacl="$4"
1668         local setfacl_error=0
1669         local testfile=$DIR/$tdir/$tfile
1670         local RUNAS_USER="$RUNAS_CMD -u $user"
1671         local acl_count=0
1672         local acl_count_post=0
1673
1674         nodemap_acl_test_setup
1675         sleep 5
1676
1677         do_node $set_client $RUNAS_USER touch $testfile
1678
1679         # ACL masks aren't filtered by nodemap code, so we ignore them
1680         acl_count=$(do_node $get_client getfacl $testfile | grep -v mask |
1681                 wc -l)
1682         do_node $set_client $RUNAS_USER setfacl -m $user:rwx $testfile ||
1683                 setfacl_error=1
1684
1685         # if check setfacl is set to 1, then it's supposed to error
1686         if [ "$check_setfacl" == "1" ]; then
1687                 [ "$setfacl_error" != "1" ] && return 1
1688                 return 0
1689         fi
1690         [ "$setfacl_error" == "1" ] && echo "WARNING: unable to setfacl"
1691
1692         acl_count_post=$(do_node $get_client getfacl $testfile | grep -v mask |
1693                 wc -l)
1694         [ $acl_count -eq $acl_count_post ] && return 0
1695         return 1
1696 }
1697
1698 test_23a() {
1699         [ $num_clients -lt 2 ] && skip "Need 2 clients at least" && return
1700         nodemap_version_check || return 0
1701         nodemap_test_setup
1702
1703         trap nodemap_test_cleanup EXIT
1704         # 1 trusted cluster, 1 mapped cluster
1705         local unmapped_fs=$((IDBASE+0))
1706         local unmapped_c1=$((IDBASE+5))
1707         local mapped_fs=$((IDBASE+2))
1708         local mapped_c0=$((IDBASE+4))
1709         local mapped_c1=$((IDBASE+6))
1710
1711         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1712         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1713
1714         do_facet mgs $LCTL nodemap_modify --name c1 --property admin --value 0
1715         do_facet mgs $LCTL nodemap_modify --name c1 --property trusted --value 0
1716
1717         wait_nm_sync c1 trusted_nodemap
1718
1719         # setfacl on trusted cluster to unmapped user, verify it's not seen
1720         nodemap_acl_test $unmapped_fs ${clients_arr[0]} ${clients_arr[1]} ||
1721                 error "acl count (1)"
1722
1723         # setfacl on trusted cluster to mapped user, verify it's seen
1724         nodemap_acl_test $mapped_fs ${clients_arr[0]} ${clients_arr[1]} &&
1725                 error "acl count (2)"
1726
1727         # setfacl on mapped cluster to mapped user, verify it's seen
1728         nodemap_acl_test $mapped_c1 ${clients_arr[1]} ${clients_arr[0]} &&
1729                 error "acl count (3)"
1730
1731         # setfacl on mapped cluster to unmapped user, verify error
1732         nodemap_acl_test $unmapped_fs ${clients_arr[1]} ${clients_arr[0]} 1 ||
1733                 error "acl count (4)"
1734
1735         # 2 mapped clusters
1736         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 0
1737         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 0
1738
1739         wait_nm_sync c0 trusted_nodemap
1740
1741         # setfacl to mapped user on c1, also mapped to c0, verify it's seen
1742         nodemap_acl_test $mapped_c1 ${clients_arr[1]} ${clients_arr[0]} &&
1743                 error "acl count (5)"
1744
1745         # setfacl to mapped user on c1, not mapped to c0, verify not seen
1746         nodemap_acl_test $unmapped_c1 ${clients_arr[1]} ${clients_arr[0]} ||
1747                 error "acl count (6)"
1748
1749         nodemap_test_cleanup
1750 }
1751 run_test 23a "test mapped regular ACLs"
1752
1753 test_23b() { #LU-9929
1754         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
1755         [ $(lustre_version_code mgs) -lt $(version_code 2.10.53) ] &&
1756                 skip "Need MGS >= 2.10.53" && return
1757
1758         nodemap_test_setup
1759         trap nodemap_test_cleanup EXIT
1760
1761         local testdir=$DIR/$tdir
1762         local fs_id=$((IDBASE+10))
1763         local unmapped_id
1764         local mapped_id
1765         local fs_user
1766
1767         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1768         wait_nm_sync c0 admin_nodemap
1769
1770         # Add idmap $ID0:$fs_id (500:60010)
1771         do_facet mgs $LCTL nodemap_add_idmap --name c0 --idtype gid \
1772                 --idmap $ID0:$fs_id ||
1773                 error "add idmap $ID0:$fs_id to nodemap c0 failed"
1774
1775         # set/getfacl default acl on client0 (unmapped gid=500)
1776         rm -rf $testdir
1777         mkdir -p $testdir
1778         # Here, USER0=$(getent passwd | grep :$ID0:$ID0: | cut -d: -f1)
1779         setfacl -R -d -m group:$USER0:rwx $testdir ||
1780                 error "setfacl $testdir on ${clients_arr[0]} failed"
1781         unmapped_id=$(getfacl $testdir | grep -E "default:group:.*:rwx" |
1782                         awk -F: '{print $3}')
1783         [ "$unmapped_id" = "$USER0" ] ||
1784                 error "gid=$ID0 was not unmapped correctly on ${clients_arr[0]}"
1785
1786         # getfacl default acl on MGS (mapped gid=60010)
1787         zconf_mount $mgs_HOST $MOUNT
1788         do_rpc_nodes $mgs_HOST is_mounted $MOUNT ||
1789                 error "mount lustre on MGS failed"
1790         mapped_id=$(do_node $mgs_HOST getfacl $testdir |
1791                         grep -E "default:group:.*:rwx" | awk -F: '{print $3}')
1792         fs_user=$(do_facet mgs getent passwd |
1793                         grep :$fs_id:$fs_id: | cut -d: -f1)
1794         [ $mapped_id -eq $fs_id -o "$mapped_id" = "$fs_user" ] ||
1795                 error "Should return gid=$fs_id or $fs_user on MGS"
1796
1797         rm -rf $testdir
1798         do_facet mgs umount $MOUNT
1799         nodemap_test_cleanup
1800 }
1801 run_test 23b "test mapped default ACLs"
1802
1803 test_24() {
1804         nodemap_test_setup
1805
1806         trap nodemap_test_cleanup EXIT
1807         do_nodes $(comma_list $(all_server_nodes)) $LCTL get_param -R nodemap
1808
1809         nodemap_test_cleanup
1810 }
1811 run_test 24 "check nodemap proc files for LBUGs and Oopses"
1812
1813 test_25() {
1814         local tmpfile=$(mktemp)
1815         local tmpfile2=$(mktemp)
1816         local tmpfile3=$(mktemp)
1817         local tmpfile4=$(mktemp)
1818         local subdir=c0dir
1819         local client
1820
1821         nodemap_version_check || return 0
1822
1823         # stop clients for this test
1824         zconf_umount_clients $CLIENTS $MOUNT ||
1825             error "unable to umount clients $CLIENTS"
1826
1827         export SK_UNIQUE_NM=true
1828         nodemap_test_setup
1829
1830         # enable trusted/admin for setquota call in cleanup_and_setup_lustre()
1831         i=0
1832         for client in $clients; do
1833                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1834                         --property admin --value 1
1835                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1836                         --property trusted --value 1
1837                 ((i++))
1838         done
1839         wait_nm_sync c$((i - 1)) trusted_nodemap
1840
1841         trap nodemap_test_cleanup EXIT
1842
1843         # create a new, empty nodemap, and add fileset info to it
1844         do_facet mgs $LCTL nodemap_add test25 ||
1845                 error "unable to create nodemap $testname"
1846         do_facet mgs $LCTL set_param -P nodemap.$testname.fileset=/$subdir ||
1847                 error "unable to add fileset info to nodemap test25"
1848
1849         wait_nm_sync test25 id
1850
1851         do_facet mgs $LCTL nodemap_info > $tmpfile
1852         do_facet mds $LCTL nodemap_info > $tmpfile2
1853
1854         if ! $SHARED_KEY; then
1855                 # will conflict with SK's nodemaps
1856                 cleanup_and_setup_lustre
1857         fi
1858         # stop clients for this test
1859         zconf_umount_clients $CLIENTS $MOUNT ||
1860             error "unable to umount clients $CLIENTS"
1861
1862         do_facet mgs $LCTL nodemap_info > $tmpfile3
1863         diff -q $tmpfile3 $tmpfile >& /dev/null ||
1864                 error "nodemap_info diff on MGS after remount"
1865
1866         do_facet mds $LCTL nodemap_info > $tmpfile4
1867         diff -q $tmpfile4 $tmpfile2 >& /dev/null ||
1868                 error "nodemap_info diff on MDS after remount"
1869
1870         # cleanup nodemap
1871         do_facet mgs $LCTL nodemap_del test25 ||
1872             error "cannot delete nodemap test25 from config"
1873         nodemap_test_cleanup
1874         # restart clients previously stopped
1875         zconf_mount_clients $CLIENTS $MOUNT ||
1876             error "unable to mount clients $CLIENTS"
1877
1878         rm -f $tmpfile $tmpfile2
1879         export SK_UNIQUE_NM=false
1880 }
1881 run_test 25 "test save and reload nodemap config"
1882
1883 test_26() {
1884         nodemap_version_check || return 0
1885
1886         local large_i=32000
1887
1888         do_facet mgs "seq -f 'c%g' $large_i | xargs -n1 $LCTL nodemap_add"
1889         wait_nm_sync c$large_i admin_nodemap
1890
1891         do_facet mgs "seq -f 'c%g' $large_i | xargs -n1 $LCTL nodemap_del"
1892         wait_nm_sync c$large_i admin_nodemap
1893 }
1894 run_test 26 "test transferring very large nodemap"
1895
1896 nodemap_exercise_fileset() {
1897         local nm="$1"
1898         local loop=0
1899
1900         # setup
1901         if [ "$nm" == "default" ]; then
1902                 do_facet mgs $LCTL nodemap_activate 1
1903                 wait_nm_sync active
1904         else
1905                 nodemap_test_setup
1906         fi
1907         if $SHARED_KEY; then
1908                 export SK_UNIQUE_NM=true
1909         else
1910                 # will conflict with SK's nodemaps
1911                 trap "fileset_test_cleanup $nm" EXIT
1912         fi
1913         fileset_test_setup "$nm"
1914
1915         # add fileset info to $nm nodemap
1916         if ! combined_mgs_mds; then
1917             do_facet mgs $LCTL set_param nodemap.${nm}.fileset=/$subdir ||
1918                 error "unable to add fileset info to $nm nodemap on MGS"
1919         fi
1920         do_facet mgs $LCTL set_param -P nodemap.${nm}.fileset=/$subdir ||
1921                error "unable to add fileset info to $nm nodemap for servers"
1922         wait_nm_sync $nm fileset "nodemap.${nm}.fileset=/$subdir"
1923
1924         # re-mount client
1925         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
1926                 error "unable to umount client ${clients_arr[0]}"
1927         # set some generic fileset to trigger SSK code
1928         export FILESET=/
1929         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
1930                 error "unable to remount client ${clients_arr[0]}"
1931         unset FILESET
1932
1933         # test mount point content
1934         do_node ${clients_arr[0]} test -f $MOUNT/this_is_$subdir ||
1935                 error "fileset not taken into account"
1936
1937         # re-mount client with sub-subdir
1938         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
1939                 error "unable to umount client ${clients_arr[0]}"
1940         export FILESET=/$subsubdir
1941         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
1942                 error "unable to remount client ${clients_arr[0]}"
1943         unset FILESET
1944
1945         # test mount point content
1946         do_node ${clients_arr[0]} test -f $MOUNT/this_is_$subsubdir ||
1947                 error "subdir of fileset not taken into account"
1948
1949         # remove fileset info from nodemap
1950         do_facet mgs $LCTL nodemap_set_fileset --name $nm --fileset clear ||
1951                 error "unable to delete fileset info on $nm nodemap"
1952         wait_update_facet mgs "$LCTL get_param nodemap.${nm}.fileset" \
1953                           "nodemap.${nm}.fileset=" ||
1954                 error "fileset info still not cleared on $nm nodemap"
1955         do_facet mgs $LCTL set_param -P nodemap.${nm}.fileset=clear ||
1956                 error "unable to reset fileset info on $nm nodemap"
1957         wait_nm_sync $nm fileset "nodemap.${nm}.fileset="
1958
1959         # re-mount client
1960         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
1961                 error "unable to umount client ${clients_arr[0]}"
1962         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
1963                 error "unable to remount client ${clients_arr[0]}"
1964
1965         # test mount point content
1966         if ! $(do_node ${clients_arr[0]} test -d $MOUNT/$subdir); then
1967                 ls $MOUNT
1968                 error "fileset not cleared on $nm nodemap"
1969         fi
1970
1971         # back to non-nodemap setup
1972         if $SHARED_KEY; then
1973                 export SK_UNIQUE_NM=false
1974                 zconf_umount_clients ${clients_arr[0]} $MOUNT ||
1975                         error "unable to umount client ${clients_arr[0]}"
1976         fi
1977         fileset_test_cleanup "$nm"
1978         if [ "$nm" == "default" ]; then
1979                 do_facet mgs $LCTL nodemap_activate 0
1980                 wait_nm_sync active 0
1981                 trap 0
1982                 export SK_UNIQUE_NM=false
1983         else
1984                 nodemap_test_cleanup
1985         fi
1986         if $SHARED_KEY; then
1987                 zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
1988                         error "unable to remount client ${clients_arr[0]}"
1989         fi
1990 }
1991
1992 test_27a() {
1993         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.50) ] &&
1994                 skip "Need MDS >= 2.11.50" && return
1995
1996         for nm in "default" "c0"; do
1997                 local subdir="subdir_${nm}"
1998                 local subsubdir="subsubdir_${nm}"
1999
2000                 echo "Exercising fileset for nodemap $nm"
2001                 nodemap_exercise_fileset "$nm"
2002         done
2003 }
2004 run_test 27a "test fileset in various nodemaps"
2005
2006 test_27b() { #LU-10703
2007         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.50) ] &&
2008                 skip "Need MDS >= 2.11.50" && return
2009         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs" && return
2010
2011         nodemap_test_setup
2012         trap nodemap_test_cleanup EXIT
2013
2014         # Add the nodemaps and set their filesets
2015         for i in $(seq 1 $MDSCOUNT); do
2016                 do_facet mgs $LCTL nodemap_del nm$i 2>/dev/null
2017                 do_facet mgs $LCTL nodemap_add nm$i ||
2018                         error "add nodemap nm$i failed"
2019                 wait_nm_sync nm$i "" "" "-N"
2020
2021                 if ! combined_mgs_mds; then
2022                         do_facet mgs \
2023                                 $LCTL set_param nodemap.nm$i.fileset=/dir$i ||
2024                                 error "set nm$i.fileset=/dir$i failed on MGS"
2025                 fi
2026                 do_facet mgs $LCTL set_param -P nodemap.nm$i.fileset=/dir$i ||
2027                         error "set nm$i.fileset=/dir$i failed on servers"
2028                 wait_nm_sync nm$i fileset "nodemap.nm$i.fileset=/dir$i"
2029         done
2030
2031         # Check if all the filesets are correct
2032         for i in $(seq 1 $MDSCOUNT); do
2033                 fileset=$(do_facet mds$i \
2034                           $LCTL get_param -n nodemap.nm$i.fileset)
2035                 [ "$fileset" = "/dir$i" ] ||
2036                         error "nm$i.fileset $fileset != /dir$i on mds$i"
2037                 do_facet mgs $LCTL nodemap_del nm$i ||
2038                         error "delete nodemap nm$i failed"
2039         done
2040
2041         nodemap_test_cleanup
2042 }
2043 run_test 27b "The new nodemap won't clear the old nodemap's fileset"
2044
2045 test_28() {
2046         if ! $SHARED_KEY; then
2047                 skip "need shared key feature for this test" && return
2048         fi
2049         mkdir -p $DIR/$tdir || error "mkdir failed"
2050         touch $DIR/$tdir/$tdir.out || error "touch failed"
2051         if [ ! -f $DIR/$tdir/$tdir.out ]; then
2052                 error "read before rotation failed"
2053         fi
2054         # store top key identity to ensure rotation has occurred
2055         SK_IDENTITY_OLD=$(lctl get_param *.*.*srpc* | grep "expire" |
2056                 head -1 | awk '{print $15}' | cut -c1-8)
2057         do_facet $SINGLEMDS lfs flushctx ||
2058                  error "could not run flushctx on $SINGLEMDS"
2059         sleep 5
2060         lfs flushctx || error "could not run flushctx on client"
2061         sleep 5
2062         # verify new key is in place
2063         SK_IDENTITY_NEW=$(lctl get_param *.*.*srpc* | grep "expire" |
2064                 head -1 | awk '{print $15}' | cut -c1-8)
2065         if [ $SK_IDENTITY_OLD == $SK_IDENTITY_NEW ]; then
2066                 error "key did not rotate correctly"
2067         fi
2068         if [ ! -f $DIR/$tdir/$tdir.out ]; then
2069                 error "read after rotation failed"
2070         fi
2071 }
2072 run_test 28 "check shared key rotation method"
2073
2074 test_29() {
2075         if ! $SHARED_KEY; then
2076                 skip "need shared key feature for this test" && return
2077         fi
2078         if [ $SK_FLAVOR != "ski" ] && [ $SK_FLAVOR != "skpi" ]; then
2079                 skip "test only valid if integrity is active"
2080         fi
2081         rm -r $DIR/$tdir
2082         mkdir $DIR/$tdir || error "mkdir"
2083         touch $DIR/$tdir/$tfile || error "touch"
2084         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2085                 error "unable to umount clients"
2086         keyctl show | awk '/lustre/ { print $1 }' |
2087                 xargs -IX keyctl unlink X
2088         OLD_SK_PATH=$SK_PATH
2089         export SK_PATH=/dev/null
2090         if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
2091                 export SK_PATH=$OLD_SK_PATH
2092                 if [ -e $DIR/$tdir/$tfile ]; then
2093                         error "able to mount and read without key"
2094                 else
2095                         error "able to mount without key"
2096                 fi
2097         else
2098                 export SK_PATH=$OLD_SK_PATH
2099                 keyctl show | awk '/lustre/ { print $1 }' |
2100                         xargs -IX keyctl unlink X
2101         fi
2102 }
2103 run_test 29 "check for missing shared key"
2104
2105 test_30() {
2106         if ! $SHARED_KEY; then
2107                 skip "need shared key feature for this test" && return
2108         fi
2109         if [ $SK_FLAVOR != "ski" ] && [ $SK_FLAVOR != "skpi" ]; then
2110                 skip "test only valid if integrity is active"
2111         fi
2112         mkdir -p $DIR/$tdir || error "mkdir failed"
2113         touch $DIR/$tdir/$tdir.out || error "touch failed"
2114         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2115                 error "unable to umount clients"
2116         # unload keys from ring
2117         keyctl show | awk '/lustre/ { print $1 }' |
2118                 xargs -IX keyctl unlink X
2119         # invalidate the key with bogus filesystem name
2120         lgss_sk -w $SK_PATH/$FSNAME-bogus.key -f $FSNAME.bogus \
2121                 -t client -d /dev/urandom || error "lgss_sk failed (1)"
2122         do_facet $SINGLEMDS lfs flushctx || error "could not run flushctx"
2123         OLD_SK_PATH=$SK_PATH
2124         export SK_PATH=$SK_PATH/$FSNAME-bogus.key
2125         if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
2126                 SK_PATH=$OLD_SK_PATH
2127                 if [ -a $DIR/$tdir/$tdir.out ]; then
2128                         error "mount and read file with invalid key"
2129                 else
2130                         error "mount with invalid key"
2131                 fi
2132         fi
2133         SK_PATH=$OLD_SK_PATH
2134         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2135                 error "unable to umount clients"
2136 }
2137 run_test 30 "check for invalid shared key"
2138
2139 cleanup_31() {
2140         # unmount client
2141         zconf_umount $HOSTNAME $MOUNT || error "unable to umount client"
2142
2143         # remove ${NETTYPE}999 network on all nodes
2144         do_nodes $(comma_list $(all_nodes)) \
2145                  "$LNETCTL net del --net ${NETTYPE}999 && \
2146                   $LNETCTL lnet unconfigure 2>/dev/null || true"
2147
2148         # necessary to do writeconf in order to de-register
2149         # @${NETTYPE}999 nid for targets
2150         KZPOOL=$KEEP_ZPOOL
2151         export KEEP_ZPOOL="true"
2152         stopall
2153         export SK_MOUNTED=false
2154         writeconf_all
2155         setupall || echo 1
2156         export KEEP_ZPOOL="$KZPOOL"
2157 }
2158
2159 test_31() {
2160         local nid=$(lctl list_nids | grep ${NETTYPE} | head -n1)
2161         local addr=${nid%@*}
2162         local net=${nid#*@}
2163
2164         export LNETCTL=$(which lnetctl 2> /dev/null)
2165
2166         [ -z "$LNETCTL" ] && skip "without lnetctl support." && return
2167         local_mode && skip "in local mode."
2168
2169         stack_trap cleanup_31 EXIT
2170
2171         # umount client
2172         if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
2173                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
2174         fi
2175         if $(grep -q $MOUNT' ' /proc/mounts); then
2176                 umount_client $MOUNT || error "umount $MOUNT failed"
2177         fi
2178
2179         # check exports on servers are empty for client
2180         do_facet mgs "lctl get_param -n *.MGS*.exports.'$nid'.uuid 2>/dev/null |
2181                       grep -q -" && error "export on MGS should be empty"
2182         do_nodes $(comma_list $(mdts_nodes) $(osts_nodes)) \
2183                  "lctl get_param -n *.${FSNAME}*.exports.'$nid'.uuid \
2184                   2>/dev/null | grep -q -" &&
2185                 error "export on servers should be empty"
2186
2187         # add network ${NETTYPE}999 on all nodes
2188         do_nodes $(comma_list $(all_nodes)) \
2189                  "$LNETCTL lnet configure && $LNETCTL net add --if \
2190                   $($LNETCTL net show --net $net | awk 'BEGIN{inf=0} \
2191                   {if (inf==1) print $2; fi; inf=0} /interfaces/{inf=1}') \
2192                   --net ${NETTYPE}999" ||
2193                 error "unable to configure NID ${NETTYPE}999"
2194
2195         # necessary to do writeconf in order to register
2196         # new @${NETTYPE}999 nid for targets
2197         KZPOOL=$KEEP_ZPOOL
2198         export KEEP_ZPOOL="true"
2199         stopall
2200         export SK_MOUNTED=false
2201         writeconf_all
2202         setupall server_only || echo 1
2203         export KEEP_ZPOOL="$KZPOOL"
2204
2205         # backup MGSNID
2206         local mgsnid_orig=$MGSNID
2207         # compute new MGSNID
2208         MGSNID=$(do_facet mgs "$LCTL list_nids | grep ${NETTYPE}999")
2209
2210         # on client, turn LNet Dynamic Discovery on
2211         lnetctl set discovery 1
2212
2213         # mount client with -o network=${NETTYPE}999 option:
2214         # should fail because of LNet Dynamic Discovery
2215         mount_client $MOUNT ${MOUNT_OPTS},network=${NETTYPE}999 &&
2216                 error "client mount with '-o network' option should be refused"
2217
2218         # on client, reconfigure LNet and turn LNet Dynamic Discovery off
2219         $LNETCTL net del --net ${NETTYPE}999 && lnetctl lnet unconfigure
2220         lustre_rmmod
2221         modprobe lnet
2222         lnetctl set discovery 0
2223         modprobe ptlrpc
2224         $LNETCTL lnet configure && $LNETCTL net add --if \
2225           $($LNETCTL net show --net $net | awk 'BEGIN{inf=0} \
2226           {if (inf==1) print $2; fi; inf=0} /interfaces/{inf=1}') \
2227           --net ${NETTYPE}999 ||
2228         error "unable to configure NID ${NETTYPE}999 on client"
2229
2230         # mount client with -o network=${NETTYPE}999 option
2231         mount_client $MOUNT ${MOUNT_OPTS},network=${NETTYPE}999 ||
2232                 error "unable to remount client"
2233
2234         # restore MGSNID
2235         MGSNID=$mgsnid_orig
2236
2237         # check export on MGS
2238         do_facet mgs "lctl get_param -n *.MGS*.exports.'$nid'.uuid 2>/dev/null |
2239                       grep -q -"
2240         [ $? -ne 0 ] || error "export for $nid on MGS should not exist"
2241
2242         do_facet mgs \
2243                 "lctl get_param -n *.MGS*.exports.'${addr}@${NETTYPE}999'.uuid \
2244                  2>/dev/null | grep -q -"
2245         [ $? -eq 0 ] ||
2246                 error "export for ${addr}@${NETTYPE}999 on MGS should exist"
2247
2248         # check {mdc,osc} imports
2249         lctl get_param mdc.${FSNAME}-*.import | grep current_connection |
2250             grep -q ${NETTYPE}999
2251         [ $? -eq 0 ] ||
2252                 error "import for mdc should use ${addr}@${NETTYPE}999"
2253         lctl get_param osc.${FSNAME}-*.import | grep current_connection |
2254             grep -q ${NETTYPE}999
2255         [ $? -eq 0 ] ||
2256                 error "import for osc should use ${addr}@${NETTYPE}999"
2257 }
2258 run_test 31 "client mount option '-o network'"
2259
2260 log "cleanup: ======================================================"
2261
2262 sec_unsetup() {
2263         ## nodemap deactivated
2264         do_facet mgs $LCTL nodemap_activate 0
2265
2266         for num in $(seq $MDSCOUNT); do
2267                 if [ "${identity_old[$num]}" = 1 ]; then
2268                         switch_identity $num false || identity_old[$num]=$?
2269                 fi
2270         done
2271
2272         $RUNAS_CMD -u $ID0 ls $DIR
2273         $RUNAS_CMD -u $ID1 ls $DIR
2274 }
2275 sec_unsetup
2276
2277 complete $SECONDS
2278 check_and_cleanup_lustre
2279 exit_status