Whamcloud - gitweb
New tag 2.14.52
[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
11 LUSTRE=${LUSTRE:-$(dirname $0)/..}
12 . $LUSTRE/tests/test-framework.sh
13 init_test_env $@
14
15 init_logging
16
17 ALWAYS_EXCEPT="$SANITY_SEC_EXCEPT "
18 # bug number for skipped test:
19 ALWAYS_EXCEPT+=" "
20 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
21
22 [ "$SLOW" = "no" ] && EXCEPT_SLOW="26"
23
24 NODEMAP_TESTS=$(seq 7 26)
25
26 if ! check_versions; then
27         echo "It is NOT necessary to test nodemap under interoperation mode"
28         EXCEPT="$EXCEPT $NODEMAP_TESTS"
29 fi
30
31 build_test_filter
32
33 RUNAS_CMD=${RUNAS_CMD:-runas}
34
35 WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
36
37 CONFDIR=/etc/lustre
38 PERM_CONF=$CONFDIR/perm.conf
39 FAIL_ON_ERROR=false
40 HOSTNAME_CHECKSUM=$(hostname | sum | awk '{ print $1 }')
41 SUBNET_CHECKSUM=$(expr $HOSTNAME_CHECKSUM % 250 + 1)
42
43 require_dsh_mds || exit 0
44 require_dsh_ost || exit 0
45
46 clients=${CLIENTS//,/ }
47 num_clients=$(get_node_count ${clients})
48 clients_arr=($clients)
49
50 ID0=${ID0:-500}
51 ID1=${ID1:-501}
52 USER0=$(getent passwd | grep :$ID0:$ID0: | cut -d: -f1)
53 USER1=$(getent passwd | grep :$ID1:$ID1: | cut -d: -f1)
54
55 if [ "$SLOW" == "yes" ]; then
56         NODEMAP_COUNT=16
57         NODEMAP_RANGE_COUNT=3
58         NODEMAP_IPADDR_LIST="1 10 64 128 200 250"
59         NODEMAP_ID_COUNT=10
60 else
61         NODEMAP_COUNT=3
62         NODEMAP_RANGE_COUNT=2
63         NODEMAP_IPADDR_LIST="1 250"
64         NODEMAP_ID_COUNT=3
65 fi
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 sec_login() {
106         local user=$1
107         local group=$2
108
109         $GSS_KRB5 || return
110         if ! $RUNAS_CMD -u $user krb5_login.sh; then
111                 error "$user login kerberos failed."
112                 exit 1
113         fi
114
115         if ! $RUNAS_CMD -u $user -g $group ls $DIR > /dev/null 2>&1; then
116                 $RUNAS_CMD -u $user lfs flushctx -k
117                 $RUNAS_CMD -u $user krb5_login.sh
118                 if ! $RUNAS_CMD -u$user -g$group ls $DIR > /dev/null 2>&1; then
119                         error "init $user $group failed."
120                         exit 2
121                 fi
122         fi
123 }
124
125 declare -a identity_old
126
127 sec_setup() {
128         for num in $(seq $MDSCOUNT); do
129                 switch_identity $num true || identity_old[$num]=$?
130         done
131
132         if ! $RUNAS_CMD -u $ID0 ls $DIR > /dev/null 2>&1; then
133                 sec_login $USER0 $USER0
134         fi
135
136         if ! $RUNAS_CMD -u $ID1 ls $DIR > /dev/null 2>&1; then
137                 sec_login $USER1 $USER1
138         fi
139 }
140 sec_setup
141
142 # run as different user
143 test_0() {
144         umask 0022
145
146         chmod 0755 $DIR || error "chmod (1)"
147         rm -rf $DIR/$tdir || error "rm (1)"
148         mkdir -p $DIR/$tdir || error "mkdir (1)"
149         chown $USER0 $DIR/$tdir || error "chown (2)"
150         $RUNAS_CMD -u $ID0 ls $DIR || error "ls (1)"
151         rm -f $DIR/f0 || error "rm (2)"
152         $RUNAS_CMD -u $ID0 touch $DIR/f0 && error "touch (1)"
153         $RUNAS_CMD -u $ID0 touch $DIR/$tdir/f1 || error "touch (2)"
154         $RUNAS_CMD -u $ID1 touch $DIR/$tdir/f2 && error "touch (3)"
155         touch $DIR/$tdir/f3 || error "touch (4)"
156         chown root $DIR/$tdir || error "chown (3)"
157         chgrp $USER0 $DIR/$tdir || error "chgrp (1)"
158         chmod 0775 $DIR/$tdir || error "chmod (2)"
159         $RUNAS_CMD -u $ID0 touch $DIR/$tdir/f4 || error "touch (5)"
160         $RUNAS_CMD -u $ID1 touch $DIR/$tdir/f5 && error "touch (6)"
161         touch $DIR/$tdir/f6 || error "touch (7)"
162         rm -rf $DIR/$tdir || error "rm (3)"
163 }
164 run_test 0 "uid permission ============================="
165
166 # setuid/gid
167 test_1() {
168         [ $GSS_SUP = 0 ] && skip "without GSS support." && return
169
170         rm -rf $DIR/$tdir
171         mkdir -p $DIR/$tdir
172
173         chown $USER0 $DIR/$tdir || error "chown (1)"
174         $RUNAS_CMD -u $ID1 -v $ID0 touch $DIR/$tdir/f0 && error "touch (2)"
175         echo "enable uid $ID1 setuid"
176         do_facet $SINGLEMDS "echo '* $ID1 setuid' >> $PERM_CONF"
177         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
178         $RUNAS_CMD -u $ID1 -v $ID0 touch $DIR/$tdir/f1 || error "touch (3)"
179
180         chown root $DIR/$tdir || error "chown (4)"
181         chgrp $USER0 $DIR/$tdir || error "chgrp (5)"
182         chmod 0770 $DIR/$tdir || error "chmod (6)"
183         $RUNAS_CMD -u $ID1 -g $ID1 touch $DIR/$tdir/f2 && error "touch (7)"
184         $RUNAS_CMD -u$ID1 -g$ID1 -j$ID0 touch $DIR/$tdir/f3 && error "touch (8)"
185         echo "enable uid $ID1 setuid,setgid"
186         do_facet $SINGLEMDS "echo '* $ID1 setuid,setgid' > $PERM_CONF"
187         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
188         $RUNAS_CMD -u $ID1 -g $ID1 -j $ID0 touch $DIR/$tdir/f4 ||
189                 error "touch (9)"
190         $RUNAS_CMD -u $ID1 -v $ID0 -g $ID1 -j $ID0 touch $DIR/$tdir/f5 ||
191                 error "touch (10)"
192
193         rm -rf $DIR/$tdir
194
195         do_facet $SINGLEMDS "rm -f $PERM_CONF"
196         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
197 }
198 run_test 1 "setuid/gid ============================="
199
200 # bug 3285 - supplementary group should always succeed.
201 # NB: the supplementary groups are set for local client only,
202 # as for remote client, the groups of the specified uid on MDT
203 # will be obtained by upcall /sbin/l_getidentity and used.
204 test_4() {
205         [[ "$MDS1_VERSION" -ge $(version_code 2.6.93) ]] ||
206         [[ "$MDS1_VERSION" -ge $(version_code 2.5.35) &&
207            "$MDS1_VERSION" -lt $(version_code 2.5.50) ]] ||
208                 skip "Need MDS version at least 2.6.93 or 2.5.35"
209
210         rm -rf $DIR/$tdir
211         mkdir -p $DIR/$tdir
212         chmod 0771 $DIR/$tdir
213         chgrp $ID0 $DIR/$tdir
214         $RUNAS_CMD -u $ID0 ls $DIR/$tdir || error "setgroups (1)"
215         do_facet $SINGLEMDS "echo '* $ID1 setgrp' > $PERM_CONF"
216         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
217         $RUNAS_CMD -u $ID1 -G1,2,$ID0 ls $DIR/$tdir ||
218                 error "setgroups (2)"
219         $RUNAS_CMD -u $ID1 -G1,2 ls $DIR/$tdir && error "setgroups (3)"
220         rm -rf $DIR/$tdir
221
222         do_facet $SINGLEMDS "rm -f $PERM_CONF"
223         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
224 }
225 run_test 4 "set supplementary group ==============="
226
227 create_nodemaps() {
228         local i
229         local rc
230
231         squash_id default 99 0
232         wait_nm_sync default squash_uid '' inactive
233         squash_id default 99 1
234         wait_nm_sync default squash_gid '' inactive
235         for (( i = 0; i < NODEMAP_COUNT; i++ )); do
236                 local csum=${HOSTNAME_CHECKSUM}_${i}
237
238                 do_facet mgs $LCTL nodemap_add $csum
239                 rc=$?
240                 if [ $rc -ne 0 ]; then
241                         echo "nodemap_add $csum failed with $rc"
242                         return $rc
243                 fi
244
245                 wait_update_facet --verbose mgs \
246                         "$LCTL get_param nodemap.$csum.id 2>/dev/null | \
247                         grep -c $csum || true" 1 30 ||
248                     return 1
249         done
250         for (( i = 0; i < NODEMAP_COUNT; i++ )); do
251                 local csum=${HOSTNAME_CHECKSUM}_${i}
252
253                 wait_nm_sync $csum id '' inactive
254         done
255         return 0
256 }
257
258 delete_nodemaps() {
259         local i
260
261         for ((i = 0; i < NODEMAP_COUNT; i++)); do
262                 local csum=${HOSTNAME_CHECKSUM}_${i}
263
264                 if ! do_facet mgs $LCTL nodemap_del $csum; then
265                         error "nodemap_del $csum failed with $?"
266                         return 3
267                 fi
268
269                 wait_update_facet --verbose mgs \
270                         "$LCTL get_param nodemap.$csum.id 2>/dev/null | \
271                         grep -c $csum || true" 0 30 ||
272                     return 1
273         done
274         for (( i = 0; i < NODEMAP_COUNT; i++ )); do
275                 local csum=${HOSTNAME_CHECKSUM}_${i}
276
277                 wait_nm_sync $csum id '' inactive
278         done
279         return 0
280 }
281
282 add_range() {
283         local j
284         local cmd="$LCTL nodemap_add_range"
285         local range
286         local rc=0
287
288         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
289                 range="$SUBNET_CHECKSUM.${2}.${j}.[1-253]@tcp"
290                 if ! do_facet mgs $cmd --name $1 --range $range; then
291                         rc=$((rc + 1))
292                 fi
293         done
294         return $rc
295 }
296
297 delete_range() {
298         local j
299         local cmd="$LCTL nodemap_del_range"
300         local range
301         local rc=0
302
303         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
304                 range="$SUBNET_CHECKSUM.${2}.${j}.[1-253]@tcp"
305                 if ! do_facet mgs $cmd --name $1 --range $range; then
306                         rc=$((rc + 1))
307                 fi
308         done
309
310         return $rc
311 }
312
313 add_idmaps() {
314         local i
315         local cmd="$LCTL nodemap_add_idmap"
316         local rc=0
317
318         echo "Start to add idmaps ..."
319         for ((i = 0; i < NODEMAP_COUNT; i++)); do
320                 local j
321
322                 for ((j = $ID0; j < NODEMAP_MAX_ID; j++)); do
323                         local csum=${HOSTNAME_CHECKSUM}_${i}
324                         local client_id=$j
325                         local fs_id=$((j + 1))
326
327                         if ! do_facet mgs $cmd --name $csum --idtype uid \
328                              --idmap $client_id:$fs_id; then
329                                 rc=$((rc + 1))
330                         fi
331                         if ! do_facet mgs $cmd --name $csum --idtype gid \
332                              --idmap $client_id:$fs_id; then
333                                 rc=$((rc + 1))
334                         fi
335                 done
336         done
337
338         return $rc
339 }
340
341 update_idmaps() { #LU-10040
342         [ "$MGS_VERSION" -lt $(version_code 2.10.55) ] &&
343                 skip "Need MGS >= 2.10.55"
344
345         local csum=${HOSTNAME_CHECKSUM}_0
346         local old_id_client=$ID0
347         local old_id_fs=$((ID0 + 1))
348         local new_id=$((ID0 + 100))
349         local tmp_id
350         local cmd
351         local run
352         local idtype
353         local rc=0
354
355         echo "Start to update idmaps ..."
356
357         #Inserting an existed idmap should return error
358         cmd="$LCTL nodemap_add_idmap --name $csum --idtype uid"
359         if do_facet mgs \
360                 $cmd --idmap $old_id_client:$old_id_fs 2>/dev/null; then
361                 error "insert idmap {$old_id_client:$old_id_fs} " \
362                         "should return error"
363                 rc=$((rc + 1))
364                 return rc
365         fi
366
367         #Update id_fs and check it
368         if ! do_facet mgs $cmd --idmap $old_id_client:$new_id; then
369                 error "$cmd --idmap $old_id_client:$new_id failed"
370                 rc=$((rc + 1))
371                 return $rc
372         fi
373         tmp_id=$(do_facet mgs $LCTL get_param -n nodemap.$csum.idmap |
374                 awk '{ print $7 }' | sed -n '2p')
375         [ $tmp_id != $new_id ] && { error "new id_fs $tmp_id != $new_id"; \
376                 rc=$((rc + 1)); return $rc; }
377
378         #Update id_client and check it
379         if ! do_facet mgs $cmd --idmap $new_id:$new_id; then
380                 error "$cmd --idmap $new_id:$new_id failed"
381                 rc=$((rc + 1))
382                 return $rc
383         fi
384         tmp_id=$(do_facet mgs $LCTL get_param -n nodemap.$csum.idmap |
385                 awk '{ print $5 }' | sed -n "$((NODEMAP_ID_COUNT + 1)) p")
386         tmp_id=$(echo ${tmp_id%,*}) #e.g. "501,"->"501"
387         [ $tmp_id != $new_id ] && { error "new id_client $tmp_id != $new_id"; \
388                 rc=$((rc + 1)); return $rc; }
389
390         #Delete above updated idmap
391         cmd="$LCTL nodemap_del_idmap --name $csum --idtype uid"
392         if ! do_facet mgs $cmd --idmap $new_id:$new_id; then
393                 error "$cmd --idmap $new_id:$new_id failed"
394                 rc=$((rc + 1))
395                 return $rc
396         fi
397
398         #restore the idmaps to make delete_idmaps work well
399         cmd="$LCTL nodemap_add_idmap --name $csum --idtype uid"
400         if ! do_facet mgs $cmd --idmap $old_id_client:$old_id_fs; then
401                 error "$cmd --idmap $old_id_client:$old_id_fs failed"
402                 rc=$((rc + 1))
403                 return $rc
404         fi
405
406         return $rc
407 }
408
409 delete_idmaps() {
410         local i
411         local cmd="$LCTL nodemap_del_idmap"
412         local rc=0
413
414         echo "Start to delete idmaps ..."
415         for ((i = 0; i < NODEMAP_COUNT; i++)); do
416                 local j
417
418                 for ((j = $ID0; j < NODEMAP_MAX_ID; j++)); do
419                         local csum=${HOSTNAME_CHECKSUM}_${i}
420                         local client_id=$j
421                         local fs_id=$((j + 1))
422
423                         if ! do_facet mgs $cmd --name $csum --idtype uid \
424                              --idmap $client_id:$fs_id; then
425                                 rc=$((rc + 1))
426                         fi
427                         if ! do_facet mgs $cmd --name $csum --idtype gid \
428                              --idmap $client_id:$fs_id; then
429                                 rc=$((rc + 1))
430                         fi
431                 done
432         done
433
434         return $rc
435 }
436
437 modify_flags() {
438         local i
439         local proc
440         local option
441         local cmd="$LCTL nodemap_modify"
442         local rc=0
443
444         proc[0]="admin_nodemap"
445         proc[1]="trusted_nodemap"
446         option[0]="admin"
447         option[1]="trusted"
448
449         for ((idx = 0; idx < 2; idx++)); do
450                 if ! do_facet mgs $cmd --name $1 --property ${option[$idx]} \
451                      --value 1; then
452                         rc=$((rc + 1))
453                 fi
454
455                 if ! do_facet mgs $cmd --name $1 --property ${option[$idx]} \
456                      --value 0; then
457                         rc=$((rc + 1))
458                 fi
459         done
460
461         return $rc
462 }
463
464 squash_id() {
465         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
466                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
467
468         local cmd
469
470         cmd[0]="$LCTL nodemap_modify --property squash_uid"
471         cmd[1]="$LCTL nodemap_modify --property squash_gid"
472
473         if ! do_facet mgs ${cmd[$3]} --name $1 --value $2; then
474                 return 1
475         fi
476 }
477
478 wait_nm_sync() {
479         local nodemap_name=$1
480         local key=$2
481         local value=$3
482         local opt=$4
483         local proc_param
484         local is_active=$(do_facet mgs $LCTL get_param -n nodemap.active)
485         local max_retries=20
486         local is_sync
487         local out1=""
488         local out2
489         local mgs_ip=$(host_nids_address $mgs_HOST $NETTYPE | cut -d' ' -f1)
490         local i
491
492         if [ "$nodemap_name" == "active" ]; then
493                 proc_param="active"
494         elif [ -z "$key" ]; then
495                 proc_param=${nodemap_name}
496         else
497                 proc_param="${nodemap_name}.${key}"
498         fi
499         if [ "$opt" == "inactive" ]; then
500                 # check nm sync even if nodemap is not activated
501                 is_active=1
502                 opt=""
503         fi
504         (( is_active == 0 )) && [ "$proc_param" != "active" ] && return
505
506         if [ -z "$value" ]; then
507                 out1=$(do_facet mgs $LCTL get_param $opt \
508                         nodemap.${proc_param} 2>/dev/null)
509                 echo "On MGS ${mgs_ip}, ${proc_param} = $out1"
510         else
511                 out1=$value;
512         fi
513
514         # wait up to 10 seconds for other servers to sync with mgs
515         for i in $(seq 1 10); do
516                 for node in $(all_server_nodes); do
517                     local node_ip=$(host_nids_address $node $NETTYPE |
518                                     cut -d' ' -f1)
519
520                     is_sync=true
521                     if [ -z "$value" ]; then
522                         [ $node_ip == $mgs_ip ] && continue
523                     fi
524
525                     out2=$(do_node $node_ip $LCTL get_param $opt \
526                                    nodemap.$proc_param 2>/dev/null)
527                     echo "On $node ${node_ip}, ${proc_param} = $out2"
528                     [ "$out1" != "$out2" ] && is_sync=false && break
529                 done
530                 $is_sync && break
531                 sleep 1
532         done
533         if ! $is_sync; then
534                 echo MGS
535                 echo $out1
536                 echo OTHER - IP: $node_ip
537                 echo $out2
538                 error "mgs and $nodemap_name ${key} mismatch, $i attempts"
539         fi
540         echo "waited $((i - 1)) seconds for sync"
541 }
542
543 # ensure that the squash defaults are the expected defaults
544 squash_id default 99 0
545 wait_nm_sync default squash_uid '' inactive
546 squash_id default 99 1
547 wait_nm_sync default squash_gid '' inactive
548
549 test_nid() {
550         local cmd
551
552         cmd="$LCTL nodemap_test_nid"
553
554         nid=$(do_facet mgs $cmd $1)
555
556         if [ $nid == $2 ]; then
557                 return 0
558         fi
559
560         return 1
561 }
562
563 cleanup_active() {
564         # restore activation state
565         do_facet mgs $LCTL nodemap_activate 0
566         wait_nm_sync active
567 }
568
569 test_idmap() {
570         local i
571         local cmd="$LCTL nodemap_test_id"
572         local rc=0
573
574         echo "Start to test idmaps ..."
575         ## nodemap deactivated
576         if ! do_facet mgs $LCTL nodemap_activate 0; then
577                 return 1
578         fi
579         for ((id = $ID0; id < NODEMAP_MAX_ID; id++)); do
580                 local j
581
582                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
583                         local nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
584                         local fs_id=$(do_facet mgs $cmd --nid $nid      \
585                                       --idtype uid --id $id)
586                         if [ $fs_id != $id ]; then
587                                 echo "expected $id, got $fs_id"
588                                 rc=$((rc + 1))
589                         fi
590                 done
591         done
592
593         ## nodemap activated
594         if ! do_facet mgs $LCTL nodemap_activate 1; then
595                 return 2
596         fi
597
598         for ((id = $ID0; id < NODEMAP_MAX_ID; id++)); do
599                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
600                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
601                         fs_id=$(do_facet mgs $cmd --nid $nid    \
602                                 --idtype uid --id $id)
603                         expected_id=$((id + 1))
604                         if [ $fs_id != $expected_id ]; then
605                                 echo "expected $expected_id, got $fs_id"
606                                 rc=$((rc + 1))
607                         fi
608                 done
609         done
610
611         ## trust client ids
612         for ((i = 0; i < NODEMAP_COUNT; i++)); do
613                 local csum=${HOSTNAME_CHECKSUM}_${i}
614
615                 if ! do_facet mgs $LCTL nodemap_modify --name $csum \
616                      --property trusted --value 1; then
617                         error "nodemap_modify $csum failed with $?"
618                         return 3
619                 fi
620         done
621
622         for ((id = $ID0; id < NODEMAP_MAX_ID; id++)); do
623                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
624                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
625                         fs_id=$(do_facet mgs $cmd --nid $nid    \
626                                 --idtype uid --id $id)
627                         if [ $fs_id != $id ]; then
628                                 echo "expected $id, got $fs_id"
629                                 rc=$((rc + 1))
630                         fi
631                 done
632         done
633
634         ## ensure allow_root_access is enabled
635         for ((i = 0; i < NODEMAP_COUNT; i++)); do
636                 local csum=${HOSTNAME_CHECKSUM}_${i}
637
638                 if ! do_facet mgs $LCTL nodemap_modify --name $csum     \
639                      --property admin --value 1; then
640                         error "nodemap_modify $csum failed with $?"
641                         return 3
642                 fi
643         done
644
645         ## check that root allowed
646         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
647                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
648                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
649                 if [ $fs_id != 0 ]; then
650                         echo "root allowed expected 0, got $fs_id"
651                         rc=$((rc + 1))
652                 fi
653         done
654
655         ## ensure allow_root_access is disabled
656         for ((i = 0; i < NODEMAP_COUNT; i++)); do
657                 local csum=${HOSTNAME_CHECKSUM}_${i}
658
659                 if ! do_facet mgs $LCTL nodemap_modify --name $csum     \
660                                 --property admin --value 0; then
661                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
662                                 "failed with $rc"
663                         return 3
664                 fi
665         done
666
667         ## check that root is mapped to 99
668         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
669                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
670                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
671                 if [ $fs_id != 99 ]; then
672                         error "root squash expected 99, got $fs_id"
673                         rc=$((rc + 1))
674                 fi
675         done
676
677         ## reset client trust to 0
678         for ((i = 0; i < NODEMAP_COUNT; i++)); do
679                 if ! do_facet mgs $LCTL nodemap_modify          \
680                         --name ${HOSTNAME_CHECKSUM}_${i}        \
681                         --property trusted --value 0; then
682                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
683                                 "failed with $rc"
684                         return 3
685                 fi
686         done
687
688         return $rc
689 }
690
691 test_7() {
692         local rc
693
694         remote_mgs_nodsh && skip "remote MGS with nodsh"
695         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
696                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
697
698         create_nodemaps
699         rc=$?
700         [[ $rc != 0 ]] && error "nodemap_add failed with $rc"
701
702         delete_nodemaps
703         rc=$?
704         [[ $rc != 0 ]] && error "nodemap_del failed with $rc"
705
706         return 0
707 }
708 run_test 7 "nodemap create and delete"
709
710 test_8() {
711         local rc
712
713         remote_mgs_nodsh && skip "remote MGS with nodsh"
714         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
715                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
716
717         # Set up nodemaps
718
719         create_nodemaps
720         rc=$?
721         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
722
723         # Try duplicates
724
725         create_nodemaps
726         rc=$?
727         [[ $rc == 0 ]] && error "duplicate nodemap_add allowed with $rc" &&
728         return 2
729
730         # Clean up
731         delete_nodemaps
732         rc=$?
733         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 3
734
735         return 0
736 }
737 run_test 8 "nodemap reject duplicates"
738
739 test_9() {
740         local i
741         local rc
742
743         remote_mgs_nodsh && skip "remote MGS with nodsh"
744         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
745                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
746
747         rc=0
748         create_nodemaps
749         rc=$?
750         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
751
752         rc=0
753         for ((i = 0; i < NODEMAP_COUNT; i++)); do
754                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
755                         rc=$((rc + 1))
756                 fi
757         done
758         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
759
760         rc=0
761         for ((i = 0; i < NODEMAP_COUNT; i++)); do
762                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
763                         rc=$((rc + 1))
764                 fi
765         done
766         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
767
768         rc=0
769         delete_nodemaps
770         rc=$?
771         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
772
773         return 0
774 }
775 run_test 9 "nodemap range add"
776
777 test_10a() {
778         local rc
779
780         remote_mgs_nodsh && skip "remote MGS with nodsh"
781         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
782                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
783
784         rc=0
785         create_nodemaps
786         rc=$?
787         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
788
789         rc=0
790         for ((i = 0; i < NODEMAP_COUNT; i++)); do
791                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
792                         rc=$((rc + 1))
793                 fi
794         done
795         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
796
797         rc=0
798         for ((i = 0; i < NODEMAP_COUNT; i++)); do
799                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
800                         rc=$((rc + 1))
801                 fi
802         done
803         [[ $rc == 0 ]] && error "nodemap_add_range duplicate add with $rc" &&
804                 return 2
805
806
807         rc=0
808         for ((i = 0; i < NODEMAP_COUNT; i++)); do
809                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
810                         rc=$((rc + 1))
811                 fi
812         done
813         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
814
815         delete_nodemaps
816         rc=$?
817         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 5
818
819         return 0
820 }
821 run_test 10a "nodemap reject duplicate ranges"
822
823 test_10b() {
824         [ "$MGS_VERSION" -lt $(version_code 2.10.53) ] &&
825                 skip "Need MGS >= 2.10.53"
826
827         local nm1="nodemap1"
828         local nm2="nodemap2"
829         local nids="192.168.19.[0-255]@o2ib20"
830
831         do_facet mgs $LCTL nodemap_del $nm1 2>/dev/null
832         do_facet mgs $LCTL nodemap_del $nm2 2>/dev/null
833
834         do_facet mgs $LCTL nodemap_add $nm1 || error "Add $nm1 failed"
835         do_facet mgs $LCTL nodemap_add $nm2 || error "Add $nm2 failed"
836         do_facet mgs $LCTL nodemap_add_range --name $nm1 --range $nids ||
837                 error "Add range $nids to $nm1 failed"
838         [ -n "$(do_facet mgs $LCTL get_param nodemap.$nm1.* |
839                 grep start_nid)" ] || error "No range was found"
840         do_facet mgs $LCTL nodemap_del_range --name $nm2 --range $nids &&
841                 error "Deleting range $nids from $nm2 should fail"
842         [ -n "$(do_facet mgs $LCTL get_param nodemap.$nm1.* |
843                 grep start_nid)" ] || error "Range $nids should be there"
844
845         do_facet mgs $LCTL nodemap_del $nm1 || error "Delete $nm1 failed"
846         do_facet mgs $LCTL nodemap_del $nm2 || error "Delete $nm2 failed"
847         return 0
848 }
849 run_test 10b "delete range from the correct nodemap"
850
851 test_10c() { #LU-8912
852         [ "$MGS_VERSION" -lt $(version_code 2.10.57) ] &&
853                 skip "Need MGS >= 2.10.57"
854
855         local nm="nodemap_lu8912"
856         local nid_range="10.210.[32-47].[0-255]@o2ib3"
857         local start_nid="10.210.32.0@o2ib3"
858         local end_nid="10.210.47.255@o2ib3"
859         local start_nid_found
860         local end_nid_found
861
862         do_facet mgs $LCTL nodemap_del $nm 2>/dev/null
863         do_facet mgs $LCTL nodemap_add $nm || error "Add $nm failed"
864         do_facet mgs $LCTL nodemap_add_range --name $nm --range $nid_range ||
865                 error "Add range $nid_range to $nm failed"
866
867         start_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
868                 awk -F '[,: ]' /start_nid/'{ print $9 }')
869         [ "$start_nid" == "$start_nid_found" ] ||
870                 error "start_nid: $start_nid_found != $start_nid"
871         end_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
872                 awk -F '[,: ]' /end_nid/'{ print $13 }')
873         [ "$end_nid" == "$end_nid_found" ] ||
874                 error "end_nid: $end_nid_found != $end_nid"
875
876         do_facet mgs $LCTL nodemap_del $nm || error "Delete $nm failed"
877         return 0
878 }
879 run_test 10c "verfify contiguous range support"
880
881 test_10d() { #LU-8913
882         [ "$MGS_VERSION" -lt $(version_code 2.10.59) ] &&
883                 skip "Need MGS >= 2.10.59"
884
885         local nm="nodemap_lu8913"
886         local nid_range="*@o2ib3"
887         local start_nid="0.0.0.0@o2ib3"
888         local end_nid="255.255.255.255@o2ib3"
889         local start_nid_found
890         local end_nid_found
891
892         do_facet mgs $LCTL nodemap_del $nm 2>/dev/null
893         do_facet mgs $LCTL nodemap_add $nm || error "Add $nm failed"
894         do_facet mgs $LCTL nodemap_add_range --name $nm --range $nid_range ||
895                 error "Add range $nid_range to $nm failed"
896
897         start_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
898                 awk -F '[,: ]' /start_nid/'{ print $9 }')
899         [ "$start_nid" == "$start_nid_found" ] ||
900                 error "start_nid: $start_nid_found != $start_nid"
901         end_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
902                 awk -F '[,: ]' /end_nid/'{ print $13 }')
903         [ "$end_nid" == "$end_nid_found" ] ||
904                 error "end_nid: $end_nid_found != $end_nid"
905
906         do_facet mgs $LCTL nodemap_del $nm || error "Delete $nm failed"
907         return 0
908 }
909 run_test 10d "verfify nodemap range format '*@<net>' support"
910
911 test_11() {
912         local rc
913
914         remote_mgs_nodsh && skip "remote MGS with nodsh"
915         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
916                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
917
918         rc=0
919         create_nodemaps
920         rc=$?
921         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
922
923         rc=0
924         for ((i = 0; i < NODEMAP_COUNT; i++)); do
925                 if ! modify_flags ${HOSTNAME_CHECKSUM}_${i}; then
926                         rc=$((rc + 1))
927                 fi
928         done
929         [[ $rc != 0 ]] && error "nodemap_modify with $rc" && return 2
930
931         rc=0
932         delete_nodemaps
933         rc=$?
934         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 3
935
936         return 0
937 }
938 run_test 11 "nodemap modify"
939
940 test_12() {
941         local rc
942
943         remote_mgs_nodsh && skip "remote MGS with nodsh"
944         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
945                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
946
947         rc=0
948         create_nodemaps
949         rc=$?
950         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
951
952         rc=0
953         for ((i = 0; i < NODEMAP_COUNT; i++)); do
954                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 0; then
955                         rc=$((rc + 1))
956                 fi
957         done
958         [[ $rc != 0 ]] && error "nodemap squash_uid with $rc" && return 2
959
960         rc=0
961         for ((i = 0; i < NODEMAP_COUNT; i++)); do
962                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 1; then
963                         rc=$((rc + 1))
964                 fi
965         done
966         [[ $rc != 0 ]] && error "nodemap squash_gid with $rc" && return 3
967
968         rc=0
969         delete_nodemaps
970         rc=$?
971         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
972
973         return 0
974 }
975 run_test 12 "nodemap set squash ids"
976
977 test_13() {
978         local rc
979
980         remote_mgs_nodsh && skip "remote MGS with nodsh"
981         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
982                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
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         for ((i = 0; i < NODEMAP_COUNT; i++)); do
999                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
1000                         for k in $NODEMAP_IPADDR_LIST; do
1001                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
1002                                        ${HOSTNAME_CHECKSUM}_${i}; then
1003                                         rc=$((rc + 1))
1004                                 fi
1005                         done
1006                 done
1007         done
1008         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
1009
1010         rc=0
1011         delete_nodemaps
1012         rc=$?
1013         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
1014
1015         return 0
1016 }
1017 run_test 13 "test nids"
1018
1019 test_14() {
1020         local rc
1021
1022         remote_mgs_nodsh && skip "remote MGS with nodsh"
1023         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
1024                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
1025
1026         rc=0
1027         create_nodemaps
1028         rc=$?
1029         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1030
1031         rc=0
1032         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1033                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
1034                         for k in $NODEMAP_IPADDR_LIST; do
1035                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
1036                                         default; then
1037                                         rc=$((rc + 1))
1038                                 fi
1039                         done
1040                 done
1041         done
1042         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
1043
1044         rc=0
1045         delete_nodemaps
1046         rc=$?
1047         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
1048
1049         return 0
1050 }
1051 run_test 14 "test default nodemap nid lookup"
1052
1053 test_15() {
1054         local rc
1055
1056         remote_mgs_nodsh && skip "remote MGS with nodsh"
1057         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
1058                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
1059
1060         rc=0
1061         create_nodemaps
1062         rc=$?
1063         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1064
1065         rc=0
1066         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1067                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
1068                         rc=$((rc + 1))
1069                 fi
1070         done
1071         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
1072
1073         rc=0
1074         add_idmaps
1075         rc=$?
1076         [[ $rc != 0 ]] && error "nodemap_add_idmap failed with $rc" && return 3
1077
1078         activedefault=$(do_facet mgs $LCTL get_param -n nodemap.active)
1079         if [[ "$activedefault" != "1" ]]; then
1080                 stack_trap cleanup_active EXIT
1081         fi
1082
1083         rc=0
1084         test_idmap
1085         rc=$?
1086         [[ $rc != 0 ]] && error "nodemap_test_id failed with $rc" && return 4
1087
1088         rc=0
1089         update_idmaps
1090         rc=$?
1091         [[ $rc != 0 ]] && error "update_idmaps failed with $rc" && return 5
1092
1093         rc=0
1094         delete_idmaps
1095         rc=$?
1096         [[ $rc != 0 ]] && error "nodemap_del_idmap failed with $rc" && return 6
1097
1098         rc=0
1099         delete_nodemaps
1100         rc=$?
1101         [[ $rc != 0 ]] && error "nodemap_delete failed with $rc" && return 7
1102
1103         return 0
1104 }
1105 run_test 15 "test id mapping"
1106
1107 create_fops_nodemaps() {
1108         local i=0
1109         local client
1110         for client in $clients; do
1111                 local client_ip=$(host_nids_address $client $NETTYPE)
1112                 local client_nid=$(h2nettype $client_ip)
1113                 do_facet mgs $LCTL nodemap_add c${i} || return 1
1114                 do_facet mgs $LCTL nodemap_add_range    \
1115                         --name c${i} --range $client_nid || return 1
1116                 for map in ${FOPS_IDMAPS[i]}; do
1117                         do_facet mgs $LCTL nodemap_add_idmap --name c${i} \
1118                                 --idtype uid --idmap ${map} || return 1
1119                         do_facet mgs $LCTL nodemap_add_idmap --name c${i} \
1120                                 --idtype gid --idmap ${map} || return 1
1121                 done
1122
1123                 wait_nm_sync c$i idmap
1124
1125                 i=$((i + 1))
1126         done
1127         return 0
1128 }
1129
1130 delete_fops_nodemaps() {
1131         local i=0
1132         local client
1133         for client in $clients; do
1134                 do_facet mgs $LCTL nodemap_del c${i} || return 1
1135                 i=$((i + 1))
1136         done
1137         return 0
1138 }
1139
1140 fops_mds_index=0
1141 nm_test_mkdir() {
1142         if [ $MDSCOUNT -le 1 ]; then
1143                 do_node ${clients_arr[0]} mkdir -p $DIR/$tdir
1144         else
1145                 # round-robin MDTs to test DNE nodemap support
1146                 [ ! -d $DIR ] && do_node ${clients_arr[0]} mkdir -p $DIR
1147                 do_node ${clients_arr[0]} $LFS setdirstripe -c 1 -i \
1148                         $((fops_mds_index % MDSCOUNT)) $DIR/$tdir
1149                 ((fops_mds_index++))
1150         fi
1151 }
1152
1153 # acl test directory needs to be initialized on a privileged client
1154 fops_test_setup() {
1155         local admin=$(do_facet mgs $LCTL get_param -n nodemap.c0.admin_nodemap)
1156         local trust=$(do_facet mgs $LCTL get_param -n \
1157                 nodemap.c0.trusted_nodemap)
1158
1159         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1160         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1161
1162         wait_nm_sync c0 admin_nodemap
1163         wait_nm_sync c0 trusted_nodemap
1164
1165         do_node ${clients_arr[0]} rm -rf $DIR/$tdir
1166         nm_test_mkdir
1167         do_node ${clients_arr[0]} chown $user $DIR/$tdir
1168
1169         do_facet mgs $LCTL nodemap_modify --name c0 \
1170                 --property admin --value $admin
1171         do_facet mgs $LCTL nodemap_modify --name c0 \
1172                 --property trusted --value $trust
1173
1174         # flush MDT locks to make sure they are reacquired before test
1175         do_node ${clients_arr[0]} $LCTL set_param \
1176                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
1177
1178         wait_nm_sync c0 admin_nodemap
1179         wait_nm_sync c0 trusted_nodemap
1180 }
1181
1182 # fileset test directory needs to be initialized on a privileged client
1183 fileset_test_setup() {
1184         local nm=$1
1185
1186         if [ -n "$FILESET" -a -z "$SKIP_FILESET" ]; then
1187                 cleanup_mount $MOUNT
1188                 FILESET="" zconf_mount_clients $CLIENTS $MOUNT
1189         fi
1190
1191         local admin=$(do_facet mgs $LCTL get_param -n \
1192                 nodemap.${nm}.admin_nodemap)
1193         local trust=$(do_facet mgs $LCTL get_param -n \
1194                 nodemap.${nm}.trusted_nodemap)
1195
1196         do_facet mgs $LCTL nodemap_modify --name $nm --property admin --value 1
1197         do_facet mgs $LCTL nodemap_modify --name $nm --property trusted \
1198                 --value 1
1199
1200         wait_nm_sync $nm admin_nodemap
1201         wait_nm_sync $nm trusted_nodemap
1202
1203         # create directory and populate it for subdir mount
1204         do_node ${clients_arr[0]} mkdir $MOUNT/$subdir ||
1205                 error "unable to create dir $MOUNT/$subdir"
1206         do_node ${clients_arr[0]} touch $MOUNT/$subdir/this_is_$subdir ||
1207                 error "unable to create file $MOUNT/$subdir/this_is_$subdir"
1208         do_node ${clients_arr[0]} mkdir $MOUNT/$subdir/$subsubdir ||
1209                 error "unable to create dir $MOUNT/$subdir/$subsubdir"
1210         do_node ${clients_arr[0]} touch \
1211                         $MOUNT/$subdir/$subsubdir/this_is_$subsubdir ||
1212                 error "unable to create file \
1213                         $MOUNT/$subdir/$subsubdir/this_is_$subsubdir"
1214
1215         do_facet mgs $LCTL nodemap_modify --name $nm \
1216                 --property admin --value $admin
1217         do_facet mgs $LCTL nodemap_modify --name $nm \
1218                 --property trusted --value $trust
1219
1220         # flush MDT locks to make sure they are reacquired before test
1221         do_node ${clients_arr[0]} $LCTL set_param \
1222                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
1223
1224         wait_nm_sync $nm admin_nodemap
1225         wait_nm_sync $nm trusted_nodemap
1226 }
1227
1228 # fileset test directory needs to be initialized on a privileged client
1229 fileset_test_cleanup() {
1230         local nm=$1
1231         local admin=$(do_facet mgs $LCTL get_param -n \
1232                 nodemap.${nm}.admin_nodemap)
1233         local trust=$(do_facet mgs $LCTL get_param -n \
1234                 nodemap.${nm}.trusted_nodemap)
1235
1236         do_facet mgs $LCTL nodemap_modify --name $nm --property admin --value 1
1237         do_facet mgs $LCTL nodemap_modify --name $nm --property trusted \
1238                 --value 1
1239
1240         wait_nm_sync $nm admin_nodemap
1241         wait_nm_sync $nm trusted_nodemap
1242
1243         # cleanup directory created for subdir mount
1244         do_node ${clients_arr[0]} rm -rf $MOUNT/$subdir ||
1245                 error "unable to remove dir $MOUNT/$subdir"
1246
1247         do_facet mgs $LCTL nodemap_modify --name $nm \
1248                 --property admin --value $admin
1249         do_facet mgs $LCTL nodemap_modify --name $nm \
1250                 --property trusted --value $trust
1251
1252         # flush MDT locks to make sure they are reacquired before test
1253         do_node ${clients_arr[0]} $LCTL set_param \
1254                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
1255
1256         wait_nm_sync $nm admin_nodemap
1257         wait_nm_sync $nm trusted_nodemap
1258         if [ -n "$FILESET" -a -z "$SKIP_FILESET" ]; then
1259                 cleanup_mount $MOUNT
1260                 zconf_mount_clients $CLIENTS $MOUNT
1261         fi
1262 }
1263
1264 do_create_delete() {
1265         local run_u=$1
1266         local key=$2
1267         local testfile=$DIR/$tdir/$tfile
1268         local rc=0
1269         local c=0 d=0
1270         local qused_new
1271         if $run_u touch $testfile >& /dev/null; then
1272                 c=1
1273                 $run_u rm $testfile && d=1
1274         fi >& /dev/null
1275
1276         local res="$c $d"
1277         local expected=$(get_cr_del_expected $key)
1278         [ "$res" != "$expected" ] &&
1279                 error "test $key, wanted $expected, got $res" && rc=$((rc + 1))
1280         return $rc
1281 }
1282
1283 nodemap_check_quota() {
1284         local run_u="$1"
1285         $run_u lfs quota -q $DIR | awk '{ print $2; exit; }'
1286 }
1287
1288 do_fops_quota_test() {
1289         local run_u=$1
1290         # fuzz quota used to account for possible indirect blocks, etc
1291         local quota_fuzz=$(fs_log_size)
1292         local qused_orig=$(nodemap_check_quota "$run_u")
1293         local qused_high=$((qused_orig + quota_fuzz))
1294         local qused_low=$((qused_orig - quota_fuzz))
1295         local testfile=$DIR/$tdir/$tfile
1296         $run_u dd if=/dev/zero of=$testfile oflag=sync bs=1M count=1 \
1297                 >& /dev/null || error "unable to write quota test file"
1298         sync; sync_all_data || true
1299
1300         local qused_new=$(nodemap_check_quota "$run_u")
1301         [ $((qused_new)) -lt $((qused_low + 1024)) -o \
1302           $((qused_new)) -gt $((qused_high + 1024)) ] &&
1303                 error "$qused_new != $qused_orig + 1M after write, " \
1304                       "fuzz is $quota_fuzz"
1305         $run_u rm $testfile || error "unable to remove quota test file"
1306         wait_delete_completed_mds
1307
1308         qused_new=$(nodemap_check_quota "$run_u")
1309         [ $((qused_new)) -lt $((qused_low)) \
1310                 -o $((qused_new)) -gt $((qused_high)) ] &&
1311                 error "quota not reclaimed, expect $qused_orig, " \
1312                       "got $qused_new, fuzz $quota_fuzz"
1313 }
1314
1315 get_fops_mapped_user() {
1316         local cli_user=$1
1317
1318         for ((i=0; i < ${#FOPS_IDMAPS[@]}; i++)); do
1319                 for map in ${FOPS_IDMAPS[i]}; do
1320                         if [ $(cut -d: -f1 <<< "$map") == $cli_user ]; then
1321                                 cut -d: -f2 <<< "$map"
1322                                 return
1323                         fi
1324                 done
1325         done
1326         echo -1
1327 }
1328
1329 get_cr_del_expected() {
1330         local -a key
1331         IFS=":" read -a key <<< "$1"
1332         local mapmode="${key[0]}"
1333         local mds_user="${key[1]}"
1334         local cluster="${key[2]}"
1335         local cli_user="${key[3]}"
1336         local mode="0${key[4]}"
1337         local SUCCESS="1 1"
1338         local FAILURE="0 0"
1339         local noadmin=0
1340         local mapped=0
1341         local other=0
1342
1343         [[ $mapmode == *mapped* ]] && mapped=1
1344         # only c1 is mapped in these test cases
1345         [[ $mapmode == mapped_trusted* ]] && [ "$cluster" == "c0" ] && mapped=0
1346         [[ $mapmode == *noadmin* ]] && noadmin=1
1347
1348         # o+wx works as long as the user isn't mapped
1349         if [ $((mode & 3)) -eq 3 ]; then
1350                 other=1
1351         fi
1352
1353         # if client user is root, check if root is squashed
1354         if [ "$cli_user" == "0" ]; then
1355                 # squash root succeed, if other bit is on
1356                 case $noadmin in
1357                         0) echo $SUCCESS;;
1358                         1) [ "$other" == "1" ] && echo $SUCCESS
1359                            [ "$other" == "0" ] && echo $FAILURE;;
1360                 esac
1361                 return
1362         fi
1363         if [ "$mapped" == "0" ]; then
1364                 [ "$other" == "1" ] && echo $SUCCESS
1365                 [ "$other" == "0" ] && echo $FAILURE
1366                 return
1367         fi
1368
1369         # if mapped user is mds user, check for u+wx
1370         mapped_user=$(get_fops_mapped_user $cli_user)
1371         [ "$mapped_user" == "-1" ] &&
1372                 error "unable to find mapping for client user $cli_user"
1373
1374         if [ "$mapped_user" == "$mds_user" -a \
1375              $(((mode & 0300) == 0300)) -eq 1 ]; then
1376                 echo $SUCCESS
1377                 return
1378         fi
1379         if [ "$mapped_user" != "$mds_user" -a "$other" == "1" ]; then
1380                 echo $SUCCESS
1381                 return
1382         fi
1383         echo $FAILURE
1384 }
1385
1386 test_fops_admin_cli_i=""
1387 test_fops_chmod_dir() {
1388         local current_cli_i=$1
1389         local perm_bits=$2
1390         local dir_to_chmod=$3
1391         local new_admin_cli_i=""
1392
1393         # do we need to set up a new admin client?
1394         [ "$current_cli_i" == "0" ] && [ "$test_fops_admin_cli_i" != "1" ] &&
1395                 new_admin_cli_i=1
1396         [ "$current_cli_i" != "0" ] && [ "$test_fops_admin_cli_i" != "0" ] &&
1397                 new_admin_cli_i=0
1398
1399         # if only one client, and non-admin, need to flip admin everytime
1400         if [ "$num_clients" == "1" ]; then
1401                 test_fops_admin_client=$clients
1402                 test_fops_admin_val=$(do_facet mgs $LCTL get_param -n \
1403                         nodemap.c0.admin_nodemap)
1404                 if [ "$test_fops_admin_val" != "1" ]; then
1405                         do_facet mgs $LCTL nodemap_modify \
1406                                 --name c0 \
1407                                 --property admin \
1408                                 --value 1
1409                         wait_nm_sync c0 admin_nodemap
1410                 fi
1411         elif [ "$new_admin_cli_i" != "" ]; then
1412                 # restore admin val to old admin client
1413                 if [ "$test_fops_admin_cli_i" != "" ] &&
1414                                 [ "$test_fops_admin_val" != "1" ]; then
1415                         do_facet mgs $LCTL nodemap_modify \
1416                                 --name c${test_fops_admin_cli_i} \
1417                                 --property admin \
1418                                 --value $test_fops_admin_val
1419                         wait_nm_sync c${test_fops_admin_cli_i} admin_nodemap
1420                 fi
1421
1422                 test_fops_admin_cli_i=$new_admin_cli_i
1423                 test_fops_admin_client=${clients_arr[$new_admin_cli_i]}
1424                 test_fops_admin_val=$(do_facet mgs $LCTL get_param -n \
1425                         nodemap.c${new_admin_cli_i}.admin_nodemap)
1426
1427                 if [ "$test_fops_admin_val" != "1" ]; then
1428                         do_facet mgs $LCTL nodemap_modify \
1429                                 --name c${new_admin_cli_i} \
1430                                 --property admin \
1431                                 --value 1
1432                         wait_nm_sync c${new_admin_cli_i} admin_nodemap
1433                 fi
1434         fi
1435
1436         do_node $test_fops_admin_client chmod $perm_bits $DIR/$tdir || return 1
1437
1438         # remove admin for single client if originally non-admin
1439         if [ "$num_clients" == "1" ] && [ "$test_fops_admin_val" != "1" ]; then
1440                 do_facet mgs $LCTL nodemap_modify --name c0 --property admin \
1441                         --value 0
1442                 wait_nm_sync c0 admin_nodemap
1443         fi
1444
1445         return 0
1446 }
1447
1448 test_fops() {
1449         local mapmode="$1"
1450         local single_client="$2"
1451         local client_user_list=([0]="0 $((IDBASE+3))"
1452                                 [1]="0 $((IDBASE+5))")
1453         local mds_users="-1 0"
1454         local mds_i
1455         local rc=0
1456         local perm_bit_list="3 $((0300))"
1457         # SLOW tests 000-007, 010-070, 100-700 (octal modes)
1458         if [ "$SLOW" == "yes" ]; then
1459                 perm_bit_list="0 $(seq 1 7) $(seq 8 8 63) $(seq 64 64 511) \
1460                                $((0303))"
1461                 client_user_list=([0]="0 $((IDBASE+3)) $((IDBASE+4))"
1462                                   [1]="0 $((IDBASE+5)) $((IDBASE+6))")
1463                 mds_users="-1 0 1 2"
1464         fi
1465
1466         # force single_client to speed up test
1467         [ "$SLOW" == "yes" ] ||
1468                 single_client=1
1469         # step through mds users. -1 means root
1470         for mds_i in $mds_users; do
1471                 local user=$((mds_i + IDBASE))
1472                 local client
1473                 local x
1474
1475                 [ "$mds_i" == "-1" ] && user=0
1476
1477                 echo mkdir -p $DIR/$tdir
1478                 fops_test_setup
1479                 local cli_i=0
1480                 for client in $clients; do
1481                         local u
1482                         for u in ${client_user_list[$cli_i]}; do
1483                                 local run_u="do_node $client \
1484                                              $RUNAS_CMD -u$u -g$u -G$u"
1485                                 for perm_bits in $perm_bit_list; do
1486                                         local mode=$(printf %03o $perm_bits)
1487                                         local key
1488                                         key="$mapmode:$user:c$cli_i:$u:$mode"
1489                                         test_fops_chmod_dir $cli_i $mode \
1490                                                 $DIR/$tdir ||
1491                                                         error cannot chmod $key
1492                                         do_create_delete "$run_u" "$key"
1493                                 done
1494
1495                                 # check quota
1496                                 test_fops_chmod_dir $cli_i 777 $DIR/$tdir ||
1497                                         error cannot chmod $key
1498                                 do_fops_quota_test "$run_u"
1499                         done
1500
1501                         cli_i=$((cli_i + 1))
1502                         [ "$single_client" == "1" ] && break
1503                 done
1504                 rm -rf $DIR/$tdir
1505         done
1506         return $rc
1507 }
1508
1509 nodemap_version_check () {
1510         remote_mgs_nodsh && skip "remote MGS with nodsh" && return 1
1511         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
1512                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53" &&
1513                 return 1
1514         return 0
1515 }
1516
1517 nodemap_test_setup() {
1518         local rc
1519         local active_nodemap=1
1520
1521         [ "$1" == "0" ] && active_nodemap=0
1522
1523         do_nodes $(comma_list $(all_mdts_nodes)) \
1524                 $LCTL set_param mdt.*.identity_upcall=NONE
1525
1526         rc=0
1527         create_fops_nodemaps
1528         rc=$?
1529         [[ $rc != 0 ]] && error "adding fops nodemaps failed $rc"
1530
1531         do_facet mgs $LCTL nodemap_activate $active_nodemap
1532         wait_nm_sync active
1533
1534         do_facet mgs $LCTL nodemap_modify --name default \
1535                 --property admin --value 1
1536         wait_nm_sync default admin_nodemap
1537         do_facet mgs $LCTL nodemap_modify --name default \
1538                 --property trusted --value 1
1539         wait_nm_sync default trusted_nodemap
1540 }
1541
1542 nodemap_test_cleanup() {
1543         trap 0
1544         delete_fops_nodemaps
1545         rc=$?
1546         [[ $rc != 0 ]] && error "removing fops nodemaps failed $rc"
1547
1548         do_facet mgs $LCTL nodemap_modify --name default \
1549                  --property admin --value 0
1550         wait_nm_sync default admin_nodemap
1551         do_facet mgs $LCTL nodemap_modify --name default \
1552                  --property trusted --value 0
1553         wait_nm_sync default trusted_nodemap
1554
1555         do_facet mgs $LCTL nodemap_activate 0
1556         wait_nm_sync active 0
1557
1558         export SK_UNIQUE_NM=false
1559         return 0
1560 }
1561
1562 nodemap_clients_admin_trusted() {
1563         local admin=$1
1564         local tr=$2
1565         local i=0
1566         for client in $clients; do
1567                 do_facet mgs $LCTL nodemap_modify --name c0 \
1568                         --property admin --value $admin
1569                 do_facet mgs $LCTL nodemap_modify --name c0 \
1570                         --property trusted --value $tr
1571                 i=$((i + 1))
1572         done
1573         wait_nm_sync c$((i - 1)) admin_nodemap
1574         wait_nm_sync c$((i - 1)) trusted_nodemap
1575 }
1576
1577 test_16() {
1578         nodemap_version_check || return 0
1579         nodemap_test_setup 0
1580
1581         trap nodemap_test_cleanup EXIT
1582         test_fops all_off
1583         nodemap_test_cleanup
1584 }
1585 run_test 16 "test nodemap all_off fileops"
1586
1587 test_17() {
1588         if $SHARED_KEY &&
1589         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1590                 skip "Need MDS >= 2.11.55"
1591         fi
1592
1593         nodemap_version_check || return 0
1594         nodemap_test_setup
1595
1596         trap nodemap_test_cleanup EXIT
1597         nodemap_clients_admin_trusted 0 1
1598         test_fops trusted_noadmin 1
1599         nodemap_test_cleanup
1600 }
1601 run_test 17 "test nodemap trusted_noadmin fileops"
1602
1603 test_18() {
1604         if $SHARED_KEY &&
1605         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1606                 skip "Need MDS >= 2.11.55"
1607         fi
1608
1609         nodemap_version_check || return 0
1610         nodemap_test_setup
1611
1612         trap nodemap_test_cleanup EXIT
1613         nodemap_clients_admin_trusted 0 0
1614         test_fops mapped_noadmin 1
1615         nodemap_test_cleanup
1616 }
1617 run_test 18 "test nodemap mapped_noadmin fileops"
1618
1619 test_19() {
1620         if $SHARED_KEY &&
1621         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1622                 skip "Need MDS >= 2.11.55"
1623         fi
1624
1625         nodemap_version_check || return 0
1626         nodemap_test_setup
1627
1628         trap nodemap_test_cleanup EXIT
1629         nodemap_clients_admin_trusted 1 1
1630         test_fops trusted_admin 1
1631         nodemap_test_cleanup
1632 }
1633 run_test 19 "test nodemap trusted_admin fileops"
1634
1635 test_20() {
1636         if $SHARED_KEY &&
1637         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1638                 skip "Need MDS >= 2.11.55"
1639         fi
1640
1641         nodemap_version_check || return 0
1642         nodemap_test_setup
1643
1644         trap nodemap_test_cleanup EXIT
1645         nodemap_clients_admin_trusted 1 0
1646         test_fops mapped_admin 1
1647         nodemap_test_cleanup
1648 }
1649 run_test 20 "test nodemap mapped_admin fileops"
1650
1651 test_21() {
1652         if $SHARED_KEY &&
1653         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1654                 skip "Need MDS >= 2.11.55"
1655         fi
1656
1657         nodemap_version_check || return 0
1658         nodemap_test_setup
1659
1660         trap nodemap_test_cleanup EXIT
1661         local x=1
1662         local i=0
1663         for client in $clients; do
1664                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1665                         --property admin --value 0
1666                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1667                         --property trusted --value $x
1668                 x=0
1669                 i=$((i + 1))
1670         done
1671         wait_nm_sync c$((i - 1)) trusted_nodemap
1672
1673         test_fops mapped_trusted_noadmin
1674         nodemap_test_cleanup
1675 }
1676 run_test 21 "test nodemap mapped_trusted_noadmin fileops"
1677
1678 test_22() {
1679         if $SHARED_KEY &&
1680         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1681                 skip "Need MDS >= 2.11.55"
1682         fi
1683
1684         nodemap_version_check || return 0
1685         nodemap_test_setup
1686
1687         trap nodemap_test_cleanup EXIT
1688         local x=1
1689         local i=0
1690         for client in $clients; do
1691                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1692                         --property admin --value 1
1693                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1694                         --property trusted --value $x
1695                 x=0
1696                 i=$((i + 1))
1697         done
1698         wait_nm_sync c$((i - 1)) trusted_nodemap
1699
1700         test_fops mapped_trusted_admin
1701         nodemap_test_cleanup
1702 }
1703 run_test 22 "test nodemap mapped_trusted_admin fileops"
1704
1705 # acl test directory needs to be initialized on a privileged client
1706 nodemap_acl_test_setup() {
1707         local admin=$(do_facet mgs $LCTL get_param -n \
1708                       nodemap.c0.admin_nodemap)
1709         local trust=$(do_facet mgs $LCTL get_param -n \
1710                       nodemap.c0.trusted_nodemap)
1711
1712         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1713         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1714
1715         wait_nm_sync c0 admin_nodemap
1716         wait_nm_sync c0 trusted_nodemap
1717
1718         do_node ${clients_arr[0]} rm -rf $DIR/$tdir
1719         nm_test_mkdir
1720         do_node ${clients_arr[0]} chmod a+rwx $DIR/$tdir ||
1721                 error unable to chmod a+rwx test dir $DIR/$tdir
1722
1723         do_facet mgs $LCTL nodemap_modify --name c0 \
1724                 --property admin --value $admin
1725         do_facet mgs $LCTL nodemap_modify --name c0 \
1726                 --property trusted --value $trust
1727
1728         wait_nm_sync c0 trusted_nodemap
1729 }
1730
1731 # returns 0 if the number of ACLs does not change on the second (mapped) client
1732 # after being set on the first client
1733 nodemap_acl_test() {
1734         local user="$1"
1735         local set_client="$2"
1736         local get_client="$3"
1737         local check_setfacl="$4"
1738         local setfacl_error=0
1739         local testfile=$DIR/$tdir/$tfile
1740         local RUNAS_USER="$RUNAS_CMD -u $user"
1741         local acl_count=0
1742         local acl_count_post=0
1743
1744         nodemap_acl_test_setup
1745         sleep 5
1746
1747         do_node $set_client $RUNAS_USER touch $testfile
1748
1749         # ACL masks aren't filtered by nodemap code, so we ignore them
1750         acl_count=$(do_node $get_client getfacl $testfile | grep -v mask |
1751                 wc -l)
1752         do_node $set_client $RUNAS_USER setfacl -m $user:rwx $testfile ||
1753                 setfacl_error=1
1754
1755         # if check setfacl is set to 1, then it's supposed to error
1756         if [ "$check_setfacl" == "1" ]; then
1757                 [ "$setfacl_error" != "1" ] && return 1
1758                 return 0
1759         fi
1760         [ "$setfacl_error" == "1" ] && echo "WARNING: unable to setfacl"
1761
1762         acl_count_post=$(do_node $get_client getfacl $testfile | grep -v mask |
1763                 wc -l)
1764         [ $acl_count -eq $acl_count_post ] && return 0
1765         return 1
1766 }
1767
1768 test_23a() {
1769         [ $num_clients -lt 2 ] && skip "Need 2 clients at least" && return
1770         nodemap_version_check || return 0
1771         nodemap_test_setup
1772
1773         trap nodemap_test_cleanup EXIT
1774         # 1 trusted cluster, 1 mapped cluster
1775         local unmapped_fs=$((IDBASE+0))
1776         local unmapped_c1=$((IDBASE+5))
1777         local mapped_fs=$((IDBASE+2))
1778         local mapped_c0=$((IDBASE+4))
1779         local mapped_c1=$((IDBASE+6))
1780
1781         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1782         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1783
1784         do_facet mgs $LCTL nodemap_modify --name c1 --property admin --value 0
1785         do_facet mgs $LCTL nodemap_modify --name c1 --property trusted --value 0
1786
1787         wait_nm_sync c1 trusted_nodemap
1788
1789         # setfacl on trusted cluster to unmapped user, verify it's not seen
1790         nodemap_acl_test $unmapped_fs ${clients_arr[0]} ${clients_arr[1]} ||
1791                 error "acl count (1)"
1792
1793         # setfacl on trusted cluster to mapped user, verify it's seen
1794         nodemap_acl_test $mapped_fs ${clients_arr[0]} ${clients_arr[1]} &&
1795                 error "acl count (2)"
1796
1797         # setfacl on mapped cluster to mapped user, verify it's seen
1798         nodemap_acl_test $mapped_c1 ${clients_arr[1]} ${clients_arr[0]} &&
1799                 error "acl count (3)"
1800
1801         # setfacl on mapped cluster to unmapped user, verify error
1802         nodemap_acl_test $unmapped_fs ${clients_arr[1]} ${clients_arr[0]} 1 ||
1803                 error "acl count (4)"
1804
1805         # 2 mapped clusters
1806         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 0
1807         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 0
1808
1809         wait_nm_sync c0 trusted_nodemap
1810
1811         # setfacl to mapped user on c1, also mapped to c0, verify it's seen
1812         nodemap_acl_test $mapped_c1 ${clients_arr[1]} ${clients_arr[0]} &&
1813                 error "acl count (5)"
1814
1815         # setfacl to mapped user on c1, not mapped to c0, verify not seen
1816         nodemap_acl_test $unmapped_c1 ${clients_arr[1]} ${clients_arr[0]} ||
1817                 error "acl count (6)"
1818
1819         nodemap_test_cleanup
1820 }
1821 run_test 23a "test mapped regular ACLs"
1822
1823 test_23b() { #LU-9929
1824         [ $num_clients -lt 2 ] && skip "Need 2 clients at least"
1825         [ "$MGS_VERSION" -lt $(version_code 2.10.53) ] &&
1826                 skip "Need MGS >= 2.10.53"
1827
1828         export SK_UNIQUE_NM=true
1829         nodemap_test_setup
1830         trap nodemap_test_cleanup EXIT
1831
1832         local testdir=$DIR/$tdir
1833         local fs_id=$((IDBASE+10))
1834         local unmapped_id
1835         local mapped_id
1836         local fs_user
1837
1838         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1839         wait_nm_sync c0 admin_nodemap
1840         do_facet mgs $LCTL nodemap_modify --name c1 --property admin --value 1
1841         wait_nm_sync c1 admin_nodemap
1842         do_facet mgs $LCTL nodemap_modify --name c1 --property trusted --value 1
1843         wait_nm_sync c1 trusted_nodemap
1844
1845         # Add idmap $ID0:$fs_id (500:60010)
1846         do_facet mgs $LCTL nodemap_add_idmap --name c0 --idtype gid \
1847                 --idmap $ID0:$fs_id ||
1848                 error "add idmap $ID0:$fs_id to nodemap c0 failed"
1849         wait_nm_sync c0 idmap
1850
1851         # set/getfacl default acl on client 1 (unmapped gid=500)
1852         do_node ${clients_arr[0]} rm -rf $testdir
1853         do_node ${clients_arr[0]} mkdir -p $testdir
1854         # Here, USER0=$(getent passwd | grep :$ID0:$ID0: | cut -d: -f1)
1855         do_node ${clients_arr[0]} setfacl -R -d -m group:$USER0:rwx $testdir ||
1856                 error "setfacl $testdir on ${clients_arr[0]} failed"
1857         unmapped_id=$(do_node ${clients_arr[0]} getfacl $testdir |
1858                         grep -E "default:group:.*:rwx" | awk -F: '{print $3}')
1859         [ "$unmapped_id" = "$USER0" ] ||
1860                 error "gid=$ID0 was not unmapped correctly on ${clients_arr[0]}"
1861
1862         # getfacl default acl on client 2 (mapped gid=60010)
1863         mapped_id=$(do_node ${clients_arr[1]} getfacl $testdir |
1864                         grep -E "default:group:.*:rwx" | awk -F: '{print $3}')
1865         fs_user=$(do_node ${clients_arr[1]} getent passwd |
1866                         grep :$fs_id:$fs_id: | cut -d: -f1)
1867         [ -z "$fs_user" ] && fs_user=$fs_id
1868         [ $mapped_id -eq $fs_id -o "$mapped_id" = "$fs_user" ] ||
1869                 error "Should return gid=$fs_id or $fs_user on client2"
1870
1871         rm -rf $testdir
1872         nodemap_test_cleanup
1873         export SK_UNIQUE_NM=false
1874 }
1875 run_test 23b "test mapped default ACLs"
1876
1877 test_24() {
1878         nodemap_test_setup
1879
1880         trap nodemap_test_cleanup EXIT
1881         do_nodes $(comma_list $(all_server_nodes)) $LCTL get_param -R nodemap
1882
1883         nodemap_test_cleanup
1884 }
1885 run_test 24 "check nodemap proc files for LBUGs and Oopses"
1886
1887 test_25() {
1888         local tmpfile=$(mktemp)
1889         local tmpfile2=$(mktemp)
1890         local tmpfile3=$(mktemp)
1891         local tmpfile4=$(mktemp)
1892         local subdir=c0dir
1893         local client
1894
1895         nodemap_version_check || return 0
1896
1897         # stop clients for this test
1898         zconf_umount_clients $CLIENTS $MOUNT ||
1899             error "unable to umount clients $CLIENTS"
1900
1901         export SK_UNIQUE_NM=true
1902         nodemap_test_setup
1903
1904         # enable trusted/admin for setquota call in cleanup_and_setup_lustre()
1905         i=0
1906         for client in $clients; do
1907                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1908                         --property admin --value 1
1909                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1910                         --property trusted --value 1
1911                 ((i++))
1912         done
1913         wait_nm_sync c$((i - 1)) trusted_nodemap
1914
1915         trap nodemap_test_cleanup EXIT
1916
1917         # create a new, empty nodemap, and add fileset info to it
1918         do_facet mgs $LCTL nodemap_add test25 ||
1919                 error "unable to create nodemap $testname"
1920         do_facet mgs $LCTL set_param -P nodemap.$testname.fileset=/$subdir ||
1921                 error "unable to add fileset info to nodemap test25"
1922
1923         wait_nm_sync test25 id
1924
1925         do_facet mgs $LCTL nodemap_info > $tmpfile
1926         do_facet mds $LCTL nodemap_info > $tmpfile2
1927
1928         if ! $SHARED_KEY; then
1929                 # will conflict with SK's nodemaps
1930                 cleanup_and_setup_lustre
1931         fi
1932         # stop clients for this test
1933         zconf_umount_clients $CLIENTS $MOUNT ||
1934             error "unable to umount clients $CLIENTS"
1935
1936         do_facet mgs $LCTL nodemap_info > $tmpfile3
1937         diff -q $tmpfile3 $tmpfile >& /dev/null ||
1938                 error "nodemap_info diff on MGS after remount"
1939
1940         do_facet mds $LCTL nodemap_info > $tmpfile4
1941         diff -q $tmpfile4 $tmpfile2 >& /dev/null ||
1942                 error "nodemap_info diff on MDS after remount"
1943
1944         # cleanup nodemap
1945         do_facet mgs $LCTL nodemap_del test25 ||
1946             error "cannot delete nodemap test25 from config"
1947         nodemap_test_cleanup
1948         # restart clients previously stopped
1949         zconf_mount_clients $CLIENTS $MOUNT ||
1950             error "unable to mount clients $CLIENTS"
1951
1952         rm -f $tmpfile $tmpfile2
1953         export SK_UNIQUE_NM=false
1954 }
1955 run_test 25 "test save and reload nodemap config"
1956
1957 test_26() {
1958         nodemap_version_check || return 0
1959
1960         local large_i=32000
1961
1962         do_facet mgs "seq -f 'c%g' $large_i | xargs -n1 $LCTL nodemap_add"
1963         wait_nm_sync c$large_i admin_nodemap
1964
1965         do_facet mgs "seq -f 'c%g' $large_i | xargs -n1 $LCTL nodemap_del"
1966         wait_nm_sync c$large_i admin_nodemap
1967 }
1968 run_test 26 "test transferring very large nodemap"
1969
1970 nodemap_exercise_fileset() {
1971         local nm="$1"
1972         local loop=0
1973
1974         # setup
1975         if [ "$nm" == "default" ]; then
1976                 do_facet mgs $LCTL nodemap_activate 1
1977                 wait_nm_sync active
1978         else
1979                 nodemap_test_setup
1980         fi
1981         if $SHARED_KEY; then
1982                 export SK_UNIQUE_NM=true
1983         else
1984                 # will conflict with SK's nodemaps
1985                 trap "fileset_test_cleanup $nm" EXIT
1986         fi
1987         fileset_test_setup "$nm"
1988
1989         # add fileset info to $nm nodemap
1990         if ! combined_mgs_mds; then
1991             do_facet mgs $LCTL set_param nodemap.${nm}.fileset=/$subdir ||
1992                 error "unable to add fileset info to $nm nodemap on MGS"
1993         fi
1994         do_facet mgs $LCTL set_param -P nodemap.${nm}.fileset=/$subdir ||
1995                error "unable to add fileset info to $nm nodemap for servers"
1996         wait_nm_sync $nm fileset "nodemap.${nm}.fileset=/$subdir"
1997
1998         # re-mount client
1999         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2000                 error "unable to umount client ${clients_arr[0]}"
2001         # set some generic fileset to trigger SSK code
2002         export FILESET=/
2003         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2004                 error "unable to remount client ${clients_arr[0]}"
2005         unset FILESET
2006
2007         # test mount point content
2008         do_node ${clients_arr[0]} test -f $MOUNT/this_is_$subdir ||
2009                 error "fileset not taken into account"
2010
2011         # re-mount client with sub-subdir
2012         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2013                 error "unable to umount client ${clients_arr[0]}"
2014         export FILESET=/$subsubdir
2015         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2016                 error "unable to remount client ${clients_arr[0]}"
2017         unset FILESET
2018
2019         # test mount point content
2020         do_node ${clients_arr[0]} test -f $MOUNT/this_is_$subsubdir ||
2021                 error "subdir of fileset not taken into account"
2022
2023         # remove fileset info from nodemap
2024         do_facet mgs $LCTL nodemap_set_fileset --name $nm --fileset clear ||
2025                 error "unable to delete fileset info on $nm nodemap"
2026         wait_update_facet mgs "$LCTL get_param nodemap.${nm}.fileset" \
2027                           "nodemap.${nm}.fileset=" ||
2028                 error "fileset info still not cleared on $nm nodemap"
2029         do_facet mgs $LCTL set_param -P nodemap.${nm}.fileset=clear ||
2030                 error "unable to reset fileset info on $nm nodemap"
2031         wait_nm_sync $nm fileset "nodemap.${nm}.fileset="
2032
2033         # re-mount client
2034         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2035                 error "unable to umount client ${clients_arr[0]}"
2036         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2037                 error "unable to remount client ${clients_arr[0]}"
2038
2039         # test mount point content
2040         if ! $(do_node ${clients_arr[0]} test -d $MOUNT/$subdir); then
2041                 ls $MOUNT
2042                 error "fileset not cleared on $nm nodemap"
2043         fi
2044
2045         # back to non-nodemap setup
2046         if $SHARED_KEY; then
2047                 export SK_UNIQUE_NM=false
2048                 zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2049                         error "unable to umount client ${clients_arr[0]}"
2050         fi
2051         fileset_test_cleanup "$nm"
2052         if [ "$nm" == "default" ]; then
2053                 do_facet mgs $LCTL nodemap_activate 0
2054                 wait_nm_sync active 0
2055                 trap 0
2056                 export SK_UNIQUE_NM=false
2057         else
2058                 nodemap_test_cleanup
2059         fi
2060         if $SHARED_KEY; then
2061                 zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2062                         error "unable to remount client ${clients_arr[0]}"
2063         fi
2064 }
2065
2066 test_27a() {
2067         [ "$MDS1_VERSION" -lt $(version_code 2.11.50) ] &&
2068                 skip "Need MDS >= 2.11.50"
2069
2070         for nm in "default" "c0"; do
2071                 local subdir="subdir_${nm}"
2072                 local subsubdir="subsubdir_${nm}"
2073
2074                 if [ "$nm" == "default" ] && [ "$SHARED_KEY" == "true" ]; then
2075                         echo "Skipping nodemap $nm with SHARED_KEY";
2076                         continue;
2077                 fi
2078
2079                 echo "Exercising fileset for nodemap $nm"
2080                 nodemap_exercise_fileset "$nm"
2081         done
2082 }
2083 run_test 27a "test fileset in various nodemaps"
2084
2085 test_27b() { #LU-10703
2086         [ "$MDS1_VERSION" -lt $(version_code 2.11.50) ] &&
2087                 skip "Need MDS >= 2.11.50"
2088         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs"
2089
2090         nodemap_test_setup
2091         trap nodemap_test_cleanup EXIT
2092
2093         # Add the nodemaps and set their filesets
2094         for i in $(seq 1 $MDSCOUNT); do
2095                 do_facet mgs $LCTL nodemap_del nm$i 2>/dev/null
2096                 do_facet mgs $LCTL nodemap_add nm$i ||
2097                         error "add nodemap nm$i failed"
2098                 wait_nm_sync nm$i "" "" "-N"
2099
2100                 if ! combined_mgs_mds; then
2101                         do_facet mgs \
2102                                 $LCTL set_param nodemap.nm$i.fileset=/dir$i ||
2103                                 error "set nm$i.fileset=/dir$i failed on MGS"
2104                 fi
2105                 do_facet mgs $LCTL set_param -P nodemap.nm$i.fileset=/dir$i ||
2106                         error "set nm$i.fileset=/dir$i failed on servers"
2107                 wait_nm_sync nm$i fileset "nodemap.nm$i.fileset=/dir$i"
2108         done
2109
2110         # Check if all the filesets are correct
2111         for i in $(seq 1 $MDSCOUNT); do
2112                 fileset=$(do_facet mds$i \
2113                           $LCTL get_param -n nodemap.nm$i.fileset)
2114                 [ "$fileset" = "/dir$i" ] ||
2115                         error "nm$i.fileset $fileset != /dir$i on mds$i"
2116                 do_facet mgs $LCTL nodemap_del nm$i ||
2117                         error "delete nodemap nm$i failed"
2118         done
2119
2120         nodemap_test_cleanup
2121 }
2122 run_test 27b "The new nodemap won't clear the old nodemap's fileset"
2123
2124 test_28() {
2125         if ! $SHARED_KEY; then
2126                 skip "need shared key feature for this test" && return
2127         fi
2128         mkdir -p $DIR/$tdir || error "mkdir failed"
2129         touch $DIR/$tdir/$tdir.out || error "touch failed"
2130         if [ ! -f $DIR/$tdir/$tdir.out ]; then
2131                 error "read before rotation failed"
2132         fi
2133         # store top key identity to ensure rotation has occurred
2134         SK_IDENTITY_OLD=$(lctl get_param *.*.*srpc* | grep "expire" |
2135                 head -1 | awk '{print $15}' | cut -c1-8)
2136         do_facet $SINGLEMDS lfs flushctx ||
2137                  error "could not run flushctx on $SINGLEMDS"
2138         sleep 5
2139         lfs flushctx || error "could not run flushctx on client"
2140         sleep 5
2141         # verify new key is in place
2142         SK_IDENTITY_NEW=$(lctl get_param *.*.*srpc* | grep "expire" |
2143                 head -1 | awk '{print $15}' | cut -c1-8)
2144         if [ $SK_IDENTITY_OLD == $SK_IDENTITY_NEW ]; then
2145                 error "key did not rotate correctly"
2146         fi
2147         if [ ! -f $DIR/$tdir/$tdir.out ]; then
2148                 error "read after rotation failed"
2149         fi
2150 }
2151 run_test 28 "check shared key rotation method"
2152
2153 test_29() {
2154         if ! $SHARED_KEY; then
2155                 skip "need shared key feature for this test" && return
2156         fi
2157         if [ $SK_FLAVOR != "ski" ] && [ $SK_FLAVOR != "skpi" ]; then
2158                 skip "test only valid if integrity is active"
2159         fi
2160         rm -r $DIR/$tdir
2161         mkdir $DIR/$tdir || error "mkdir"
2162         touch $DIR/$tdir/$tfile || error "touch"
2163         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2164                 error "unable to umount clients"
2165         do_node ${clients_arr[0]} "keyctl show |
2166                 awk '/lustre/ { print \\\$1 }' | xargs -IX keyctl unlink X"
2167         OLD_SK_PATH=$SK_PATH
2168         export SK_PATH=/dev/null
2169         if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
2170                 export SK_PATH=$OLD_SK_PATH
2171                 do_node ${clients_arr[0]} "ls $DIR/$tdir/$tfile"
2172                 if [ $? -eq 0 ]; then
2173                         error "able to mount and read without key"
2174                 else
2175                         error "able to mount without key"
2176                 fi
2177         else
2178                 export SK_PATH=$OLD_SK_PATH
2179                 do_node ${clients_arr[0]} "keyctl show |
2180                         awk '/lustre/ { print \\\$1 }' |
2181                         xargs -IX keyctl unlink X"
2182         fi
2183         zconf_mount_clients ${clients_arr[0]} $MOUNT ||
2184                 error "unable to mount clients"
2185 }
2186 run_test 29 "check for missing shared key"
2187
2188 test_30() {
2189         if ! $SHARED_KEY; then
2190                 skip "need shared key feature for this test" && return
2191         fi
2192         if [ $SK_FLAVOR != "ski" ] && [ $SK_FLAVOR != "skpi" ]; then
2193                 skip "test only valid if integrity is active"
2194         fi
2195         mkdir -p $DIR/$tdir || error "mkdir failed"
2196         touch $DIR/$tdir/$tdir.out || error "touch failed"
2197         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2198                 error "unable to umount clients"
2199         # unload keys from ring
2200         do_node ${clients_arr[0]} "keyctl show |
2201                 awk '/lustre/ { print \\\$1 }' | xargs -IX keyctl unlink X"
2202         # generate key with bogus filesystem name
2203         do_node ${clients_arr[0]} "lgss_sk -w $SK_PATH/$FSNAME-bogus.key \
2204                 -f $FSNAME.bogus -t client -d /dev/urandom" ||
2205                 error "lgss_sk failed (1)"
2206         do_facet $SINGLEMDS lfs flushctx || error "could not run flushctx"
2207         OLD_SK_PATH=$SK_PATH
2208         export SK_PATH=$SK_PATH/$FSNAME-bogus.key
2209         if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
2210                 SK_PATH=$OLD_SK_PATH
2211                 do_node ${clients_arr[0]} "ls $DIR/$tdir/$tdir.out"
2212                 if [ $? -eq 0 ]; then
2213                         error "mount and read file with invalid key"
2214                 else
2215                         error "mount with invalid key"
2216                 fi
2217         fi
2218         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2219                 error "unable to umount clients"
2220         # unload keys from ring
2221         do_node ${clients_arr[0]} "keyctl show |
2222                 awk '/lustre/ { print \\\$1 }' | xargs -IX keyctl unlink X"
2223         rm -f $SK_PATH
2224         SK_PATH=$OLD_SK_PATH
2225         zconf_mount_clients ${clients_arr[0]} $MOUNT ||
2226                 error "unable to mount clients"
2227 }
2228 run_test 30 "check for invalid shared key"
2229
2230 basic_ios() {
2231         local flvr=$1
2232
2233         mkdir -p $DIR/$tdir || error "mkdir $flvr"
2234         touch $DIR/$tdir/f0 || error "touch $flvr"
2235         ls $DIR/$tdir || error "ls $flvr"
2236         dd if=/dev/zero of=$DIR/$tdir/f0 conv=fsync bs=1M count=10 \
2237                 >& /dev/null || error "dd $flvr"
2238         rm -f $DIR/$tdir/f0 || error "rm $flvr"
2239         rmdir $DIR/$tdir || error "rmdir $flvr"
2240
2241         sync ; sync
2242         echo 3 > /proc/sys/vm/drop_caches
2243 }
2244
2245 test_30b() {
2246         local save_flvr=$SK_FLAVOR
2247
2248         if ! $SHARED_KEY; then
2249                 skip "need shared key feature for this test"
2250         fi
2251
2252         stack_trap restore_to_default_flavor EXIT
2253
2254         for flvr in skn ska ski skpi; do
2255                 # set flavor
2256                 SK_FLAVOR=$flvr
2257                 restore_to_default_flavor || error "cannot set $flvr flavor"
2258                 SK_FLAVOR=$save_flvr
2259
2260                 basic_ios $flvr
2261         done
2262 }
2263 run_test 30b "basic test of all different SSK flavors"
2264
2265 cleanup_31() {
2266         # unmount client
2267         zconf_umount $HOSTNAME $MOUNT || error "unable to umount client"
2268
2269         # remove ${NETTYPE}999 network on all nodes
2270         do_nodes $(comma_list $(all_nodes)) \
2271                  "$LNETCTL net del --net ${NETTYPE}999 && \
2272                   $LNETCTL lnet unconfigure 2>/dev/null || true"
2273
2274         # necessary to do writeconf in order to de-register
2275         # @${NETTYPE}999 nid for targets
2276         KZPOOL=$KEEP_ZPOOL
2277         export KEEP_ZPOOL="true"
2278         stopall
2279         export SK_MOUNTED=false
2280         writeconf_all
2281         setupall || echo 1
2282         export KEEP_ZPOOL="$KZPOOL"
2283 }
2284
2285 test_31() {
2286         local nid=$(lctl list_nids | grep ${NETTYPE} | head -n1)
2287         local addr=${nid%@*}
2288         local net=${nid#*@}
2289
2290         export LNETCTL=$(which lnetctl 2> /dev/null)
2291
2292         [ -z "$LNETCTL" ] && skip "without lnetctl support." && return
2293         local_mode && skip "in local mode."
2294
2295         stack_trap cleanup_31 EXIT
2296
2297         # umount client
2298         if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
2299                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
2300         fi
2301         if $(grep -q $MOUNT' ' /proc/mounts); then
2302                 umount_client $MOUNT || error "umount $MOUNT failed"
2303         fi
2304
2305         # check exports on servers are empty for client
2306         do_facet mgs "lctl get_param -n *.MGS*.exports.'$nid'.uuid 2>/dev/null |
2307                       grep -q -" && error "export on MGS should be empty"
2308         do_nodes $(comma_list $(mdts_nodes) $(osts_nodes)) \
2309                  "lctl get_param -n *.${FSNAME}*.exports.'$nid'.uuid \
2310                   2>/dev/null | grep -q -" &&
2311                 error "export on servers should be empty"
2312
2313         # add network ${NETTYPE}999 on all nodes
2314         do_nodes $(comma_list $(all_nodes)) \
2315                  "$LNETCTL lnet configure && $LNETCTL net add --if \
2316                   \$($LNETCTL net show --net $net | awk 'BEGIN{inf=0} \
2317                   {if (inf==1) print \$2; fi; inf=0} /interfaces/{inf=1}') \
2318                   --net ${NETTYPE}999" ||
2319                 error "unable to configure NID ${NETTYPE}999"
2320
2321         # necessary to do writeconf in order to register
2322         # new @${NETTYPE}999 nid for targets
2323         KZPOOL=$KEEP_ZPOOL
2324         export KEEP_ZPOOL="true"
2325         stopall
2326         export SK_MOUNTED=false
2327         writeconf_all
2328         setupall server_only || echo 1
2329         export KEEP_ZPOOL="$KZPOOL"
2330
2331         # backup MGSNID
2332         local mgsnid_orig=$MGSNID
2333         # compute new MGSNID
2334         MGSNID=$(do_facet mgs "$LCTL list_nids | grep ${NETTYPE}999")
2335
2336         # on client, turn LNet Dynamic Discovery on
2337         lnetctl set discovery 1
2338
2339         # mount client with -o network=${NETTYPE}999 option:
2340         # should fail because of LNet Dynamic Discovery
2341         mount_client $MOUNT ${MOUNT_OPTS},network=${NETTYPE}999 &&
2342                 error "client mount with '-o network' option should be refused"
2343
2344         # on client, reconfigure LNet and turn LNet Dynamic Discovery off
2345         $LNETCTL net del --net ${NETTYPE}999 && lnetctl lnet unconfigure
2346         lustre_rmmod
2347         modprobe lnet
2348         lnetctl set discovery 0
2349         modprobe ptlrpc
2350         $LNETCTL lnet configure && $LNETCTL net add --if \
2351           $($LNETCTL net show --net $net | awk 'BEGIN{inf=0} \
2352           {if (inf==1) print $2; fi; inf=0} /interfaces/{inf=1}') \
2353           --net ${NETTYPE}999 ||
2354         error "unable to configure NID ${NETTYPE}999 on client"
2355
2356         # mount client with -o network=${NETTYPE}999 option
2357         mount_client $MOUNT ${MOUNT_OPTS},network=${NETTYPE}999 ||
2358                 error "unable to remount client"
2359
2360         # restore MGSNID
2361         MGSNID=$mgsnid_orig
2362
2363         # check export on MGS
2364         do_facet mgs "lctl get_param -n *.MGS*.exports.'$nid'.uuid 2>/dev/null |
2365                       grep -q -"
2366         [ $? -ne 0 ] || error "export for $nid on MGS should not exist"
2367
2368         do_facet mgs \
2369                 "lctl get_param -n *.MGS*.exports.'${addr}@${NETTYPE}999'.uuid \
2370                  2>/dev/null | grep -q -"
2371         [ $? -eq 0 ] ||
2372                 error "export for ${addr}@${NETTYPE}999 on MGS should exist"
2373
2374         # check {mdc,osc} imports
2375         lctl get_param mdc.${FSNAME}-*.import | grep current_connection |
2376             grep -q ${NETTYPE}999
2377         [ $? -eq 0 ] ||
2378                 error "import for mdc should use ${addr}@${NETTYPE}999"
2379         lctl get_param osc.${FSNAME}-*.import | grep current_connection |
2380             grep -q ${NETTYPE}999
2381         [ $? -eq 0 ] ||
2382                 error "import for osc should use ${addr}@${NETTYPE}999"
2383 }
2384 run_test 31 "client mount option '-o network'"
2385
2386 cleanup_32() {
2387         # umount client
2388         zconf_umount_clients ${clients_arr[0]} $MOUNT
2389
2390         # disable sk flavor enforcement on MGS
2391         set_rule _mgs any any null
2392
2393         # stop gss daemon on MGS
2394         if ! combined_mgs_mds ; then
2395                 send_sigint $mgs_HOST lsvcgssd
2396         fi
2397
2398         # re-mount client
2399         MOUNT_OPTS=$(add_sk_mntflag $MOUNT_OPTS)
2400         mountcli
2401
2402         restore_to_default_flavor
2403 }
2404
2405 test_32() {
2406         if ! $SHARED_KEY; then
2407                 skip "need shared key feature for this test"
2408         fi
2409
2410         stack_trap cleanup_32 EXIT
2411
2412         # restore to default null flavor
2413         save_flvr=$SK_FLAVOR
2414         SK_FLAVOR=null
2415         restore_to_default_flavor || error "cannot set null flavor"
2416         SK_FLAVOR=$save_flvr
2417
2418         # umount client
2419         if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
2420                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
2421         fi
2422         if $(grep -q $MOUNT' ' /proc/mounts); then
2423         umount_client $MOUNT || error "umount $MOUNT failed"
2424         fi
2425
2426         # start gss daemon on MGS
2427         if combined_mgs_mds ; then
2428                 send_sigint $mds_HOST lsvcgssd
2429         fi
2430         start_gss_daemons $mgs_HOST "$LSVCGSSD -vvv -s -g"
2431
2432         # add mgs key type and MGS NIDs in key on MGS
2433         do_nodes $mgs_HOST "lgss_sk -t mgs,server -g $MGSNID -m \
2434                                 $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2435                 error "could not modify keyfile on MGS"
2436
2437         # load modified key file on MGS
2438         do_nodes $mgs_HOST "lgss_sk -l $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2439                 error "could not load keyfile on MGS"
2440
2441         # add MGS NIDs in key on client
2442         do_nodes ${clients_arr[0]} "lgss_sk -g $MGSNID -m \
2443                                 $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2444                 error "could not modify keyfile on MGS"
2445
2446         # set perms for per-nodemap keys else permission denied
2447         do_nodes $(comma_list $(all_nodes)) \
2448                  "keyctl show | grep lustre | cut -c1-11 |
2449                                 sed -e 's/ //g;' |
2450                                 xargs -IX keyctl setperm X 0x3f3f3f3f"
2451
2452         # re-mount client with mgssec=skn
2453         save_opts=$MOUNT_OPTS
2454         if [ -z "$MOUNT_OPTS" ]; then
2455                 MOUNT_OPTS="-o mgssec=skn"
2456         else
2457                 MOUNT_OPTS="$MOUNT_OPTS,mgssec=skn"
2458         fi
2459         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2460                 error "mount ${clients_arr[0]} with mgssec=skn failed"
2461         MOUNT_OPTS=$save_opts
2462
2463         # umount client
2464         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2465                 error "umount ${clients_arr[0]} failed"
2466
2467         # enforce ska flavor on MGS
2468         set_rule _mgs any any ska
2469
2470         # re-mount client without mgssec
2471         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS &&
2472                 error "mount ${clients_arr[0]} without mgssec should fail"
2473
2474         # re-mount client with mgssec=skn
2475         save_opts=$MOUNT_OPTS
2476         if [ -z "$MOUNT_OPTS" ]; then
2477                 MOUNT_OPTS="-o mgssec=skn"
2478         else
2479                 MOUNT_OPTS="$MOUNT_OPTS,mgssec=skn"
2480         fi
2481         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS &&
2482                 error "mount ${clients_arr[0]} with mgssec=skn should fail"
2483         MOUNT_OPTS=$save_opts
2484
2485         # re-mount client with mgssec=ska
2486         save_opts=$MOUNT_OPTS
2487         if [ -z "$MOUNT_OPTS" ]; then
2488                 MOUNT_OPTS="-o mgssec=ska"
2489         else
2490                 MOUNT_OPTS="$MOUNT_OPTS,mgssec=ska"
2491         fi
2492         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2493                 error "mount ${clients_arr[0]} with mgssec=ska failed"
2494         MOUNT_OPTS=$save_opts
2495
2496         exit 0
2497 }
2498 run_test 32 "check for mgssec"
2499
2500 cleanup_33() {
2501         # disable sk flavor enforcement
2502         set_rule $FSNAME any cli2mdt null
2503         wait_flavor cli2mdt null
2504
2505         # umount client
2506         zconf_umount_clients ${clients_arr[0]} $MOUNT
2507
2508         # stop gss daemon on MGS
2509         if ! combined_mgs_mds ; then
2510                 send_sigint $mgs_HOST lsvcgssd
2511         fi
2512
2513         # re-mount client
2514         MOUNT_OPTS=$(add_sk_mntflag $MOUNT_OPTS)
2515         mountcli
2516
2517         restore_to_default_flavor
2518 }
2519
2520 test_33() {
2521         if ! $SHARED_KEY; then
2522                 skip "need shared key feature for this test"
2523         fi
2524
2525         stack_trap cleanup_33 EXIT
2526
2527         # restore to default null flavor
2528         save_flvr=$SK_FLAVOR
2529         SK_FLAVOR=null
2530         restore_to_default_flavor || error "cannot set null flavor"
2531         SK_FLAVOR=$save_flvr
2532
2533         # umount client
2534         if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
2535                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
2536         fi
2537         if $(grep -q $MOUNT' ' /proc/mounts); then
2538         umount_client $MOUNT || error "umount $MOUNT failed"
2539         fi
2540
2541         # start gss daemon on MGS
2542         if combined_mgs_mds ; then
2543                 send_sigint $mds_HOST lsvcgssd
2544         fi
2545         start_gss_daemons $mgs_HOST "$LSVCGSSD -vvv -s -g"
2546
2547         # add mgs key type and MGS NIDs in key on MGS
2548         do_nodes $mgs_HOST "lgss_sk -t mgs,server -g $MGSNID -m \
2549                                 $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2550                 error "could not modify keyfile on MGS"
2551
2552         # load modified key file on MGS
2553         do_nodes $mgs_HOST "lgss_sk -l $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2554                 error "could not load keyfile on MGS"
2555
2556         # add MGS NIDs in key on client
2557         do_nodes ${clients_arr[0]} "lgss_sk -g $MGSNID -m \
2558                                 $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2559                 error "could not modify keyfile on MGS"
2560
2561         # set perms for per-nodemap keys else permission denied
2562         do_nodes $(comma_list $(all_nodes)) \
2563                  "keyctl show | grep lustre | cut -c1-11 |
2564                                 sed -e 's/ //g;' |
2565                                 xargs -IX keyctl setperm X 0x3f3f3f3f"
2566
2567         # re-mount client with mgssec=skn
2568         save_opts=$MOUNT_OPTS
2569         if [ -z "$MOUNT_OPTS" ]; then
2570                 MOUNT_OPTS="-o mgssec=skn"
2571         else
2572                 MOUNT_OPTS="$MOUNT_OPTS,mgssec=skn"
2573         fi
2574         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2575                 error "mount ${clients_arr[0]} with mgssec=skn failed"
2576         MOUNT_OPTS=$save_opts
2577
2578         # enforce ska flavor for cli2mdt
2579         set_rule $FSNAME any cli2mdt ska
2580         wait_flavor cli2mdt ska
2581
2582         # check error message
2583         $LCTL dk | grep "faked source" &&
2584                 error "MGS connection srpc flags incorrect"
2585
2586         exit 0
2587 }
2588 run_test 33 "correct srpc flags for MGS connection"
2589
2590 cleanup_34_deny() {
2591         # restore deny_unknown
2592         do_facet mgs $LCTL nodemap_modify --name default \
2593                            --property deny_unknown --value $denydefault
2594         if [ $? -ne 0 ]; then
2595                 error_noexit "cannot reset deny_unknown on default nodemap"
2596                 return
2597         fi
2598
2599         wait_nm_sync default deny_unknown
2600 }
2601
2602 test_34() {
2603         local denynew
2604         local activedefault
2605
2606         [ $MGS_VERSION -lt $(version_code 2.12.51) ] &&
2607                 skip "deny_unknown on default nm not supported before 2.12.51"
2608
2609         activedefault=$(do_facet mgs $LCTL get_param -n nodemap.active)
2610
2611         if [[ "$activedefault" != "1" ]]; then
2612                 do_facet mgs $LCTL nodemap_activate 1
2613                 wait_nm_sync active
2614                 stack_trap cleanup_active EXIT
2615         fi
2616
2617         denydefault=$(do_facet mgs $LCTL get_param -n \
2618                       nodemap.default.deny_unknown)
2619         [ -z "$denydefault" ] &&
2620                 error "cannot get deny_unknown on default nodemap"
2621         if [ "$denydefault" -eq 0 ]; then
2622                 denynew=1;
2623         else
2624                 denynew=0;
2625         fi
2626
2627         do_facet mgs $LCTL nodemap_modify --name default \
2628                         --property deny_unknown --value $denynew ||
2629                 error "cannot set deny_unknown on default nodemap"
2630
2631         [ "$(do_facet mgs $LCTL get_param -n nodemap.default.deny_unknown)" \
2632                         -eq $denynew ] ||
2633                 error "setting deny_unknown on default nodemap did not work"
2634
2635         stack_trap cleanup_34_deny EXIT
2636
2637         wait_nm_sync default deny_unknown
2638 }
2639 run_test 34 "deny_unknown on default nodemap"
2640
2641 test_35() {
2642         [ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.13.50) ] ||
2643                 skip "Need MDS >= 2.13.50"
2644
2645         # activate changelogs
2646         changelog_register || error "changelog_register failed"
2647         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
2648         changelog_users $SINGLEMDS | grep -q $cl_user ||
2649                 error "User $cl_user not found in changelog_users"
2650         changelog_chmask ALL
2651
2652         # do some IOs
2653         mkdir $DIR/$tdir || error "failed to mkdir $tdir"
2654         touch $DIR/$tdir/$tfile || error "failed to touch $tfile"
2655
2656         # access changelogs with root
2657         changelog_dump || error "failed to dump changelogs"
2658         changelog_clear 0 || error "failed to clear changelogs"
2659
2660         # put clients in non-admin nodemap
2661         nodemap_test_setup
2662         stack_trap nodemap_test_cleanup EXIT
2663         for i in $(seq 0 $((num_clients-1))); do
2664                 do_facet mgs $LCTL nodemap_modify --name c${i} \
2665                          --property admin --value 0
2666         done
2667         for i in $(seq 0 $((num_clients-1))); do
2668                 wait_nm_sync c${i} admin_nodemap
2669         done
2670
2671         # access with mapped root
2672         changelog_dump && error "dump changelogs should have failed"
2673         changelog_clear 0 && error "clear changelogs should have failed"
2674
2675         exit 0
2676 }
2677 run_test 35 "Check permissions when accessing changelogs"
2678
2679 setup_for_enc_tests() {
2680         # remount client with test_dummy_encryption option
2681         if is_mounted $MOUNT; then
2682                 umount_client $MOUNT || error "umount $MOUNT failed"
2683         fi
2684         mount_client $MOUNT ${MOUNT_OPTS},test_dummy_encryption ||
2685                 error "mount with '-o test_dummy_encryption' failed"
2686
2687         # this directory will be encrypted, because of dummy mode
2688         mkdir $DIR/$tdir
2689 }
2690
2691 cleanup_for_enc_tests() {
2692         # remount client normally
2693         if is_mounted $MOUNT; then
2694                 umount_client $MOUNT || error "umount $MOUNT failed"
2695         fi
2696         mount_client $MOUNT ${MOUNT_OPTS} ||
2697                 error "remount failed"
2698
2699         if is_mounted $MOUNT2; then
2700                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
2701         fi
2702         if [ "$MOUNT_2" ]; then
2703                 mount_client $MOUNT2 ${MOUNT_OPTS} ||
2704                         error "remount failed"
2705         fi
2706 }
2707
2708 cleanup_nodemap_after_enc_tests() {
2709         do_facet mgs $LCTL nodemap_modify --name default \
2710                 --property forbid_encryption --value 0
2711         wait_nm_sync default forbid_encryption
2712         do_facet mgs $LCTL nodemap_activate 0
2713         wait_nm_sync active
2714 }
2715
2716 test_36() {
2717         $LCTL get_param mdc.*.import | grep -q client_encryption ||
2718                 skip "client encryption not supported"
2719
2720         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
2721                 skip "need dummy encryption support"
2722
2723         stack_trap cleanup_for_enc_tests EXIT
2724
2725         # first make sure it is possible to enable encryption
2726         # when nodemap is not active
2727         setup_for_enc_tests
2728         rmdir $DIR/$tdir
2729         umount_client $MOUNT || error "umount $MOUNT failed (1)"
2730
2731         # then activate nodemap, and retry
2732         # should succeed as encryption is not forbidden on default nodemap
2733         # by default
2734         stack_trap cleanup_nodemap_after_enc_tests EXIT
2735         do_facet mgs $LCTL nodemap_activate 1
2736         wait_nm_sync active
2737         forbid=$(do_facet mgs lctl get_param -n nodemap.default.forbid_encryption)
2738         [ $forbid -eq 0 ] || error "wrong default value for forbid_encryption"
2739         mount_client $MOUNT ${MOUNT_OPTS},test_dummy_encryption ||
2740                 error "mount '-o test_dummy_encryption' failed with default"
2741         umount_client $MOUNT || error "umount $MOUNT failed (2)"
2742
2743         # then forbid encryption, and retry
2744         do_facet mgs $LCTL nodemap_modify --name default \
2745                 --property forbid_encryption --value 1
2746         wait_nm_sync default forbid_encryption
2747         mount_client $MOUNT ${MOUNT_OPTS},test_dummy_encryption &&
2748                 error "mount '-o test_dummy_encryption' should have failed"
2749         return 0
2750 }
2751 run_test 36 "control if clients can use encryption"
2752
2753 test_37() {
2754         local testfile=$DIR/$tdir/$tfile
2755         local tmpfile=$TMP/abc
2756         local objdump=$TMP/objdump
2757         local objid
2758
2759         $LCTL get_param mdc.*.import | grep -q client_encryption ||
2760                 skip "client encryption not supported"
2761
2762         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
2763                 skip "need dummy encryption support"
2764
2765         [ "$ost1_FSTYPE" = ldiskfs ] || skip "ldiskfs only test (using debugfs)"
2766
2767         stack_trap cleanup_for_enc_tests EXIT
2768         setup_for_enc_tests
2769
2770         # write a few bytes in file
2771         echo "abc" > $tmpfile
2772         $LFS setstripe -c1 -i0 $testfile
2773         dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync
2774         do_facet ost1 "sync; sync"
2775
2776         # check that content on ost is encrypted
2777         objid=$($LFS getstripe $testfile | awk '/obdidx/{getline; print $2}')
2778         do_facet ost1 "$DEBUGFS -c -R 'cat O/0/d$(($objid % 32))/$objid' \
2779                  $(ostdevname 1)" > $objdump
2780         cmp -s $objdump $tmpfile &&
2781                 error "file $testfile is not encrypted on ost"
2782
2783         # check that in-memory representation of file is correct
2784         cmp -bl ${tmpfile} ${testfile} ||
2785                 error "file $testfile is corrupted in memory"
2786
2787         cancel_lru_locks osc ; cancel_lru_locks mdc
2788
2789         # check that file read from server is correct
2790         cmp -bl ${tmpfile} ${testfile} ||
2791                 error "file $testfile is corrupted on server"
2792
2793         rm -f $tmpfile $objdump
2794 }
2795 run_test 37 "simple encrypted file"
2796
2797 test_38() {
2798         local testfile=$DIR/$tdir/$tfile
2799         local tmpfile=$TMP/abc
2800         local objid
2801         local blksz
2802         local srvsz=0
2803         local filesz
2804         local bsize
2805         local pagesz=$(getconf PAGE_SIZE)
2806
2807         $LCTL get_param mdc.*.import | grep -q client_encryption ||
2808                 skip "client encryption not supported"
2809
2810         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
2811                 skip "need dummy encryption support"
2812
2813         stack_trap cleanup_for_enc_tests EXIT
2814         setup_for_enc_tests
2815
2816         # get block size on ost
2817         blksz=$($LCTL get_param osc.$FSNAME*.import |
2818                 awk '/grant_block_size:/ { print $2; exit; }')
2819         # write a few bytes in file at offset $blksz
2820         echo "abc" > $tmpfile
2821         $LFS setstripe -c1 -i0 $testfile
2822         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$blksz \
2823                 oflag=seek_bytes conv=fsync
2824
2825         blksz=$(($blksz > $pagesz ? $blksz : $pagesz))
2826         # check that in-memory representation of file is correct
2827         bsize=$(stat --format=%B $testfile)
2828         filesz=$(stat --format=%b $testfile)
2829         filesz=$((filesz*bsize))
2830         [ $filesz -le $blksz ] ||
2831                 error "file $testfile is $filesz long in memory"
2832
2833         cancel_lru_locks osc ; cancel_lru_locks mdc
2834
2835         # check that file read from server is correct
2836         bsize=$(stat --format=%B $testfile)
2837         filesz=$(stat --format=%b $testfile)
2838         filesz=$((filesz*bsize))
2839         [ $filesz -le $blksz ] ||
2840                 error "file $testfile is $filesz long on server"
2841
2842         rm -f $tmpfile
2843 }
2844 run_test 38 "encrypted file with hole"
2845
2846 test_39() {
2847         local testfile=$DIR/$tdir/$tfile
2848         local tmpfile=$TMP/abc
2849
2850         $LCTL get_param mdc.*.import | grep -q client_encryption ||
2851                 skip "client encryption not supported"
2852
2853         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
2854                 skip "need dummy encryption support"
2855
2856         stack_trap cleanup_for_enc_tests EXIT
2857         setup_for_enc_tests
2858
2859         # write a few bytes in file
2860         echo "abc" > $tmpfile
2861         $LFS setstripe -c1 -i0 $testfile
2862         dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync
2863
2864         # write a few more bytes in the same page
2865         dd if=$tmpfile of=$testfile bs=4 count=1 seek=1024 oflag=seek_bytes \
2866                 conv=fsync,notrunc
2867
2868         dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=1024 oflag=seek_bytes \
2869                 conv=fsync,notrunc
2870
2871         # check that in-memory representation of file is correct
2872         cmp -bl $tmpfile $testfile ||
2873                 error "file $testfile is corrupted in memory"
2874
2875         cancel_lru_locks osc ; cancel_lru_locks mdc
2876
2877         # check that file read from server is correct
2878         cmp -bl $tmpfile $testfile ||
2879                 error "file $testfile is corrupted on server"
2880
2881         rm -f $tmpfile
2882 }
2883 run_test 39 "rewrite data in already encrypted page"
2884
2885 test_40() {
2886         local testfile=$DIR/$tdir/$tfile
2887         local tmpfile=$TMP/abc
2888         local tmpfile2=$TMP/abc2
2889         local seek
2890
2891         $LCTL get_param mdc.*.import | grep -q client_encryption ||
2892                 skip "client encryption not supported"
2893
2894         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
2895                 skip "need dummy encryption support"
2896
2897         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2898
2899         stack_trap cleanup_for_enc_tests EXIT
2900         setup_for_enc_tests
2901
2902         # write a few bytes in file
2903         echo "abc" > $tmpfile
2904         $LFS setstripe -c1 -i0 $testfile
2905         dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync
2906
2907         # check that in-memory representation of file is correct
2908         cmp -bl $tmpfile $testfile ||
2909                 error "file $testfile is corrupted in memory (1)"
2910
2911         cancel_lru_locks osc ; cancel_lru_locks mdc
2912
2913         # check that file read from server is correct
2914         cmp -bl $tmpfile $testfile ||
2915                 error "file $testfile is corrupted on server (1)"
2916
2917         # write a few other bytes in same page
2918         dd if=$tmpfile of=$testfile bs=4 count=1 seek=256 oflag=seek_bytes \
2919                 conv=fsync,notrunc
2920
2921         dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=256 oflag=seek_bytes \
2922                 conv=fsync,notrunc
2923
2924         # check that in-memory representation of file is correct
2925         cmp -bl $tmpfile $testfile ||
2926                 error "file $testfile is corrupted in memory (2)"
2927
2928         cancel_lru_locks osc ; cancel_lru_locks mdc
2929
2930         # check that file read from server is correct
2931         cmp -bl $tmpfile $testfile ||
2932                 error "file $testfile is corrupted on server (2)"
2933
2934         rm -f $testfile $tmpfile
2935         cancel_lru_locks osc ; cancel_lru_locks mdc
2936
2937         # write a few bytes in file, at end of first page
2938         echo "abc" > $tmpfile
2939         $LFS setstripe -c1 -i0 $testfile
2940         seek=$(getconf PAGESIZE)
2941         seek=$((seek - 4))
2942         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
2943                 conv=fsync,notrunc
2944
2945         # write a few other bytes at beginning of first page
2946         dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync,notrunc
2947
2948         dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=$seek oflag=seek_bytes \
2949                 conv=fsync,notrunc
2950
2951         # check that in-memory representation of file is correct
2952         cmp -bl $tmpfile $testfile ||
2953                 error "file $testfile is corrupted in memory (3)"
2954
2955         cancel_lru_locks osc ; cancel_lru_locks mdc
2956
2957         # check that file read from server is correct
2958         cmp -bl $tmpfile $testfile ||
2959                 error "file $testfile is corrupted on server (3)"
2960
2961         rm -f $testfile $tmpfile
2962         cancel_lru_locks osc ; cancel_lru_locks mdc
2963
2964         # write a few bytes in file, at beginning of second page
2965         echo "abc" > $tmpfile
2966         $LFS setstripe -c1 -i0 $testfile
2967         seek=$(getconf PAGESIZE)
2968         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
2969                 conv=fsync,notrunc
2970         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
2971                 conv=fsync,notrunc
2972
2973         # write a few other bytes at end of first page
2974         seek=$((seek - 4))
2975         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
2976                 conv=fsync,notrunc
2977         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
2978                 conv=fsync,notrunc
2979
2980         # check that in-memory representation of file is correct
2981         cmp -bl $tmpfile2 $testfile ||
2982                 error "file $testfile is corrupted in memory (4)"
2983
2984         cancel_lru_locks osc ; cancel_lru_locks mdc
2985
2986         # check that file read from server is correct
2987         cmp -bl $tmpfile2 $testfile ||
2988                 error "file $testfile is corrupted on server (4)"
2989
2990         rm -f $testfile $tmpfile $tmpfile2
2991         cancel_lru_locks osc ; cancel_lru_locks mdc
2992
2993         # write a few bytes in file, at beginning of first stripe
2994         echo "abc" > $tmpfile
2995         $LFS setstripe -S 256k -c2 $testfile
2996         dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync,notrunc
2997
2998         # write a few other bytes, at beginning of second stripe
2999         dd if=$tmpfile of=$testfile bs=4 count=1 seek=262144 oflag=seek_bytes \
3000                 conv=fsync,notrunc
3001         dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=262144 oflag=seek_bytes \
3002                 conv=fsync,notrunc
3003
3004         # check that in-memory representation of file is correct
3005         cmp -bl $tmpfile $testfile ||
3006                 error "file $testfile is corrupted in memory (5)"
3007
3008         cancel_lru_locks osc ; cancel_lru_locks mdc
3009
3010         # check that file read from server is correct
3011         cmp -bl $tmpfile $testfile ||
3012                 error "file $testfile is corrupted on server (5)"
3013
3014         rm -f $tmpfile
3015 }
3016 run_test 40 "exercise size of encrypted file"
3017
3018 test_41() {
3019         local testfile=$DIR/$tdir/$tfile
3020         local tmpfile=$TMP/abc
3021         local tmpfile2=$TMP/abc2
3022         local seek
3023
3024         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3025                 skip "client encryption not supported"
3026
3027         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3028                 skip "need dummy encryption support"
3029
3030         stack_trap cleanup_for_enc_tests EXIT
3031         setup_for_enc_tests
3032
3033         echo "abc" > $tmpfile
3034         seek=$(getconf PAGESIZE)
3035         seek=$((seek - 204))
3036         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3037                 conv=fsync
3038         seek=$(getconf PAGESIZE)
3039         seek=$((seek + 1092))
3040         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3041                 conv=fsync,notrunc
3042
3043         # write a few bytes in file
3044         $LFS setstripe -c1 -i0 -S 256k $testfile
3045         seek=$(getconf PAGESIZE)
3046         seek=$((seek - 204))
3047         #define OBD_FAIL_OST_WR_ATTR_DELAY       0x250
3048         do_facet ost1 "$LCTL set_param fail_loc=0x250 fail_val=15"
3049         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3050                 conv=fsync &
3051
3052         sleep 5
3053         # write a few other bytes, at a different offset
3054         seek=$(getconf PAGESIZE)
3055         seek=$((seek + 1092))
3056         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3057                 conv=fsync,notrunc &
3058         wait
3059         do_facet ost1 "$LCTL set_param fail_loc=0x0"
3060
3061         # check that in-memory representation of file is correct
3062         cmp -bl $tmpfile2 $testfile ||
3063                 error "file $testfile is corrupted in memory (1)"
3064
3065         cancel_lru_locks osc ; cancel_lru_locks mdc
3066
3067         # check that file read from server is correct
3068         cmp -bl $tmpfile2 $testfile ||
3069                 error "file $testfile is corrupted on server (1)"
3070
3071         rm -f $tmpfile $tmpfile2
3072 }
3073 run_test 41 "test race on encrypted file size (1)"
3074
3075 test_42() {
3076         local testfile=$DIR/$tdir/$tfile
3077         local testfile2=$DIR2/$tdir/$tfile
3078         local tmpfile=$TMP/abc
3079         local tmpfile2=$TMP/abc2
3080         local pagesz=$(getconf PAGESIZE)
3081         local seek
3082
3083         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3084                 skip "client encryption not supported"
3085
3086         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3087                 skip "need dummy encryption support"
3088
3089         stack_trap cleanup_for_enc_tests EXIT
3090         setup_for_enc_tests
3091
3092         if is_mounted $MOUNT2; then
3093                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
3094         fi
3095         mount_client $MOUNT2 ${MOUNT_OPTS},test_dummy_encryption ||
3096                 error "mount2 with '-o test_dummy_encryption' failed"
3097
3098         # create file by writting one whole page
3099         $LFS setstripe -c1 -i0 -S 256k $testfile
3100         dd if=/dev/zero of=$testfile bs=$pagesz count=1 conv=fsync
3101
3102         # read file from 2nd mount point
3103         cat $testfile2 > /dev/null
3104
3105         echo "abc" > $tmpfile
3106         dd if=/dev/zero of=$tmpfile2 bs=$pagesz count=1 conv=fsync
3107         seek=$((2*pagesz - 204))
3108         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3109                 conv=fsync,notrunc
3110         seek=$((2*pagesz + 1092))
3111         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3112                 conv=fsync,notrunc
3113
3114         # write a few bytes in file from 1st mount point
3115         seek=$((2*pagesz - 204))
3116         #define OBD_FAIL_OST_WR_ATTR_DELAY       0x250
3117         do_facet ost1 "$LCTL set_param fail_loc=0x250 fail_val=15"
3118         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3119                 conv=fsync,notrunc &
3120
3121         sleep 5
3122         # write a few other bytes, at a different offset from 2nd mount point
3123         seek=$((2*pagesz + 1092))
3124         dd if=$tmpfile of=$testfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3125                 conv=fsync,notrunc &
3126         wait
3127         do_facet ost1 "$LCTL set_param fail_loc=0x0"
3128
3129         # check that in-memory representation of file is correct
3130         cmp -bl $tmpfile2 $testfile ||
3131                 error "file $testfile is corrupted in memory (1)"
3132
3133         # check that in-memory representation of file is correct
3134         cmp -bl $tmpfile2 $testfile2 ||
3135                 error "file $testfile is corrupted in memory (2)"
3136
3137         cancel_lru_locks osc ; cancel_lru_locks mdc
3138
3139         # check that file read from server is correct
3140         cmp -bl $tmpfile2 $testfile ||
3141                 error "file $testfile is corrupted on server (1)"
3142
3143         rm -f $tmpfile $tmpfile2
3144 }
3145 run_test 42 "test race on encrypted file size (2)"
3146
3147 test_43() {
3148         local testfile=$DIR/$tdir/$tfile
3149         local testfile2=$DIR2/$tdir/$tfile
3150         local tmpfile=$TMP/abc
3151         local tmpfile2=$TMP/abc2
3152         local resfile=$TMP/res
3153         local pagesz=$(getconf PAGESIZE)
3154         local seek
3155
3156         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3157                 skip "client encryption not supported"
3158
3159         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3160                 skip "need dummy encryption support"
3161
3162         stack_trap cleanup_for_enc_tests EXIT
3163         setup_for_enc_tests
3164
3165         if is_mounted $MOUNT2; then
3166                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
3167         fi
3168         mount_client $MOUNT2 ${MOUNT_OPTS},test_dummy_encryption ||
3169                 error "mount2 with '-o test_dummy_encryption' failed"
3170
3171         # create file
3172         tr '\0' '1' < /dev/zero |
3173                 dd of=$tmpfile bs=1 count=$pagesz conv=fsync
3174         $LFS setstripe -c1 -i0 -S 256k $testfile
3175         cp $tmpfile $testfile
3176
3177         # read file from 2nd mount point
3178         cat $testfile2 > /dev/null
3179
3180         # write a few bytes in file from 1st mount point
3181         echo "abc" > $tmpfile2
3182         seek=$((2*pagesz - 204))
3183         #define OBD_FAIL_OST_WR_ATTR_DELAY       0x250
3184         do_facet ost1 "$LCTL set_param fail_loc=0x250 fail_val=15"
3185         dd if=$tmpfile2 of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3186                 conv=fsync,notrunc &
3187
3188         sleep 5
3189         # read file from 2nd mount point
3190         dd if=$testfile2 of=$resfile bs=$pagesz count=1 conv=fsync,notrunc
3191         cmp -bl $tmpfile $resfile ||
3192                 error "file $testfile is corrupted in memory (1)"
3193
3194         wait
3195         do_facet ost1 "$LCTL set_param fail_loc=0x0"
3196
3197         # check that in-memory representation of file is correct
3198         dd if=$tmpfile2 of=$tmpfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3199                 conv=fsync,notrunc
3200         cmp -bl $tmpfile $testfile2 ||
3201                 error "file $testfile is corrupted in memory (2)"
3202
3203         cancel_lru_locks osc ; cancel_lru_locks mdc
3204
3205         # check that file read from server is correct
3206         cmp -bl $tmpfile $testfile ||
3207                 error "file $testfile is corrupted on server (1)"
3208
3209         rm -f $tmpfile $tmpfile2
3210 }
3211 run_test 43 "test race on encrypted file size (3)"
3212
3213 test_44() {
3214         local testfile=$DIR/$tdir/$tfile
3215         local tmpfile=$TMP/abc
3216         local resfile=$TMP/resfile
3217         local pagesz=$(getconf PAGESIZE)
3218         local respage
3219
3220         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3221                 skip "client encryption not supported"
3222
3223         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3224                 skip "need dummy encryption support"
3225
3226         which vmtouch || skip "This test needs vmtouch utility"
3227
3228         # Direct I/O is now supported on encrypted files.
3229
3230         stack_trap cleanup_for_enc_tests EXIT
3231         setup_for_enc_tests
3232
3233         $LFS setstripe -c1 -i0 $testfile
3234         dd if=/dev/urandom of=$tmpfile bs=$pagesz count=2 conv=fsync
3235         dd if=$tmpfile of=$testfile bs=$pagesz count=2 oflag=direct ||
3236                 error "could not write to file with O_DIRECT (1)"
3237
3238         respage=$(vmtouch $testfile | awk '/Resident Pages:/ {print $3}')
3239         [ "$respage" == "0/2" ] ||
3240                 error "write to enc file fell back to buffered IO"
3241
3242         cancel_lru_locks
3243
3244         dd if=$testfile of=$resfile bs=$pagesz count=2 iflag=direct ||
3245                 error "could not read from file with O_DIRECT (1)"
3246
3247         respage=$(vmtouch $testfile | awk '/Resident Pages:/ {print $3}')
3248         [ "$respage" == "0/2" ] ||
3249                 error "read from enc file fell back to buffered IO"
3250
3251         cmp -bl $tmpfile $resfile ||
3252                 error "file $testfile is corrupted (1)"
3253
3254         rm -f $resfile
3255
3256         $TRUNCATE $tmpfile $pagesz
3257         dd if=$tmpfile of=$testfile bs=$pagesz count=1 seek=13 oflag=direct ||
3258                 error "could not write to file with O_DIRECT (2)"
3259
3260         cancel_lru_locks
3261
3262         dd if=$testfile of=$resfile bs=$pagesz count=1 skip=13 iflag=direct ||
3263                 error "could not read from file with O_DIRECT (2)"
3264         cmp -bl $tmpfile $resfile ||
3265                 error "file $testfile is corrupted (2)"
3266
3267         rm -f $testfile $resfile
3268         $LFS setstripe -c1 -i0 $testfile
3269
3270         $TRUNCATE $tmpfile $((pagesz/2 - 5))
3271         cp $tmpfile $testfile
3272
3273         cancel_lru_locks
3274
3275         dd if=$testfile of=$resfile bs=$pagesz count=1 iflag=direct ||
3276                 error "could not read from file with O_DIRECT (3)"
3277         cmp -bl $tmpfile $resfile ||
3278                 error "file $testfile is corrupted (3)"
3279
3280         rm -f $tmpfile $resfile
3281 }
3282 run_test 44 "encrypted file access semantics: direct IO"
3283
3284 test_45() {
3285         local testfile=$DIR/$tdir/$tfile
3286         local tmpfile=$TMP/junk
3287
3288         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3289                 skip "client encryption not supported"
3290
3291         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3292                 skip "need dummy encryption support"
3293
3294         stack_trap cleanup_for_enc_tests EXIT
3295         setup_for_enc_tests
3296
3297         $LFS setstripe -c1 -i0 $testfile
3298         dd if=/dev/zero of=$testfile bs=512K count=1
3299         $MULTIOP $testfile OSMRUc || error "$MULTIOP $testfile failed (1)"
3300         $MULTIOP $testfile OSMWUc || error "$MULTIOP $testfile failed (2)"
3301
3302         dd if=/dev/zero of=$tmpfile bs=512K count=1
3303         $MULTIOP $tmpfile OSMWUc || error "$MULTIOP $tmpfile failed"
3304         $MMAP_CAT $tmpfile > ${tmpfile}2
3305
3306         cancel_lru_locks
3307
3308         $MULTIOP $testfile OSMRUc
3309         $MMAP_CAT $testfile > ${testfile}2
3310         cmp -bl ${tmpfile}2 ${testfile}2 ||
3311                 error "file $testfile is corrupted"
3312
3313         rm -f $tmpfile ${tmpfile}2
3314 }
3315 run_test 45 "encrypted file access semantics: MMAP"
3316
3317 test_46() {
3318         local testdir=$DIR/$tdir/mydir
3319         local testfile=$testdir/myfile
3320         local lsfile=$TMP/lsfile
3321         local scrambleddir
3322         local scrambledfile
3323
3324         local testfile2=$DIR/$tdir/${tfile}.2
3325         local tmpfile=$DIR/junk
3326
3327         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3328                 skip "client encryption not supported"
3329
3330         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3331                 skip "need dummy encryption support"
3332
3333         stack_trap cleanup_for_enc_tests EXIT
3334         setup_for_enc_tests
3335
3336         touch $DIR/onefile
3337         touch $DIR/$tdir/$tfile
3338         mkdir $testdir
3339         echo test > $testfile
3340         sync ; echo 3 > /proc/sys/vm/drop_caches
3341
3342         # remove fscrypt key from keyring
3343         keyctl revoke $(keyctl show | awk '$7 ~ "^fscrypt:" {print $1}')
3344         keyctl reap
3345
3346         scrambleddir=$(find $DIR/$tdir/ -maxdepth 1 -mindepth 1 -type d)
3347         ls -1 $scrambleddir > $lsfile || error "ls $testdir failed"
3348
3349         scrambledfile=$scrambleddir/$(head -n 1 $lsfile)
3350         stat $scrambledfile || error "stat $scrambledfile failed"
3351         rm -f $lsfile
3352
3353         cat $scrambledfile && error "cat $scrambledfile should have failed"
3354
3355         touch $scrambleddir/otherfile &&
3356                 error "touch otherfile should have failed"
3357         ls $scrambleddir/otherfile && error "otherfile should not exist"
3358         mkdir $scrambleddir/otherdir &&
3359                 error "mkdir otherdir should have failed"
3360         ls -d $scrambleddir/otherdir && error "otherdir should not exist"
3361
3362         rm -f $scrambledfile || error "rm $scrambledfile failed"
3363         rmdir $scrambleddir || error "rmdir $scrambleddir failed"
3364
3365         rm -f $DIR/onefile
3366 }
3367 run_test 46 "encrypted file access semantics without key"
3368
3369 test_47() {
3370         local testfile=$DIR/$tdir/$tfile
3371         local testfile2=$DIR/$tdir/${tfile}.2
3372         local tmpfile=$DIR/junk
3373         local scrambleddir
3374         local scrambledfile
3375
3376         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3377                 skip "client encryption not supported"
3378
3379         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3380                 skip "need dummy encryption support"
3381
3382         stack_trap cleanup_for_enc_tests EXIT
3383         setup_for_enc_tests
3384
3385         dd if=/dev/zero of=$tmpfile bs=512K count=1
3386         mrename $tmpfile $testfile &&
3387                 error "rename from unencrypted to encrypted dir should fail"
3388
3389         ln $tmpfile $testfile &&
3390                 error "link from unencrypted to encrypted dir should fail"
3391
3392         cp $tmpfile $testfile ||
3393                 error "cp from unencrypted to encrypted dir should succeed"
3394         rm -f $tmpfile
3395
3396         mrename $testfile $testfile2 ||
3397                 error "rename from within encrypted dir should succeed"
3398
3399         ln $testfile2 $testfile ||
3400                 error "link from within encrypted dir should succeed"
3401         rm -f $testfile
3402
3403         ln $testfile2 $tmpfile ||
3404                 error "link from encrypted to unencrypted dir should succeed"
3405         rm -f $tmpfile
3406
3407         # check we are limited in the number of hard links
3408         # we can create for encrypted files, to what can fit into LinkEA
3409         for i in $(seq 1 160); do
3410                 ln $testfile2 ${testfile}_$i || break
3411         done
3412         [ $i -lt 160 ] || error "hard link $i should fail"
3413
3414         mrename $testfile2 $tmpfile &&
3415                 error "rename from encrypted to unencrypted dir should fail"
3416         touch $tmpfile
3417
3418         dd if=/dev/zero of=$testfile bs=512K count=1
3419         mkdir $DIR/$tdir/mydir
3420         sync ; echo 3 > /proc/sys/vm/drop_caches
3421
3422         # remove fscrypt key from keyring
3423         keyctl revoke $(keyctl show | awk '$7 ~ "^fscrypt:" {print $1}')
3424         keyctl reap
3425
3426         scrambleddir=$(find $DIR/$tdir/ -maxdepth 1 -mindepth 1 -type d)
3427         scrambledfile=$(find $DIR/$tdir/ -maxdepth 1 -type f)
3428         ln $scrambledfile $scrambleddir/linkfile &&
3429                 error "ln linkfile should have failed"
3430         mrename $scrambledfile $DIR/onefile2 &&
3431                 error "mrename from $scrambledfile should have failed"
3432         touch $DIR/onefile
3433         mrename $DIR/onefile $scrambleddir/otherfile &&
3434                 error "mrename to $scrambleddir should have failed"
3435
3436         rm -f $tmpfile $DIR/onefile
3437 }
3438 run_test 47 "encrypted file access semantics: rename/link"
3439
3440 test_48a() {
3441         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
3442         local testfile=$DIR/$tdir/$tfile
3443         local tmpfile=$TMP/111
3444         local tmpfile2=$TMP/abc
3445         local pagesz=$(getconf PAGESIZE)
3446         local sz
3447         local seek
3448         local scrambledfile
3449
3450         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3451                 skip "client encryption not supported"
3452
3453         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3454                 skip "need dummy encryption support"
3455
3456         stack_trap cleanup_for_enc_tests EXIT
3457         setup_for_enc_tests
3458
3459         # create file, 4 x PAGE_SIZE long
3460         tr '\0' '1' < /dev/zero |
3461                 dd of=$tmpfile bs=1 count=4x$pagesz conv=fsync
3462         $LFS setstripe -c1 -i0 $testfile
3463         cp $tmpfile $testfile
3464         echo "abc" > $tmpfile2
3465
3466         # decrease size: truncate to PAGE_SIZE
3467         $TRUNCATE $tmpfile $pagesz
3468         $TRUNCATE $testfile $pagesz
3469         cancel_lru_locks osc ; cancel_lru_locks mdc
3470         cmp -bl $tmpfile $testfile ||
3471                 error "file $testfile is corrupted (1)"
3472
3473         # increase size: truncate to 2 x PAGE_SIZE
3474         sz=$((pagesz*2))
3475         $TRUNCATE $tmpfile $sz
3476         $TRUNCATE $testfile $sz
3477         cancel_lru_locks osc ; cancel_lru_locks mdc
3478         cmp -bl $tmpfile $testfile ||
3479                 error "file $testfile is corrupted (2)"
3480
3481         # write in 2nd page
3482         seek=$((pagesz+100))
3483         dd if=$tmpfile2 of=$tmpfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3484                 conv=fsync,notrunc
3485         dd if=$tmpfile2 of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3486                 conv=fsync,notrunc
3487         cancel_lru_locks osc ; cancel_lru_locks mdc
3488         cmp -bl $tmpfile $testfile ||
3489                 error "file $testfile is corrupted (3)"
3490
3491         # truncate to PAGE_SIZE / 2
3492         sz=$((pagesz/2))
3493         $TRUNCATE $tmpfile $sz
3494         $TRUNCATE $testfile $sz
3495         cancel_lru_locks osc ; cancel_lru_locks mdc
3496         cmp -bl $tmpfile $testfile ||
3497                 error "file $testfile is corrupted (4)"
3498
3499         # lockless truncate should be turned into regular truncate for enc file
3500         save_lustre_params client "osc.*.lockless_truncate" > $save
3501         # restore lockless_truncate default values on exit
3502         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
3503         cancel_lru_locks osc ; cancel_lru_locks mdc
3504         lctl set_param -n osc.*.lockless_truncate 1
3505         cancel_lru_locks osc
3506         clear_stats osc.*.osc_stats
3507         $TRUNCATE $testfile 8000000 || error "truncate failed (1)"
3508         [ $(calc_stats osc.*.osc_stats lockless_truncate) -eq 0 ] ||
3509                 error "lockless truncate should be turned into regular truncate"
3510         lctl set_param -n osc.*.lockless_truncate 0
3511
3512         # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16
3513         sz=$((sz-7))
3514         $TRUNCATE $tmpfile $sz
3515         $TRUNCATE $testfile $sz
3516         cancel_lru_locks osc ; cancel_lru_locks mdc
3517         cmp -bl $tmpfile $testfile ||
3518                 error "file $testfile is corrupted (5)"
3519
3520         # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16
3521         sz=$((sz+18))
3522         $TRUNCATE $tmpfile $sz
3523         $TRUNCATE $testfile $sz
3524         cancel_lru_locks osc ; cancel_lru_locks mdc
3525         cmp -bl $tmpfile $testfile ||
3526                 error "file $testfile is corrupted (6)"
3527
3528         # truncate to a larger, non-multiple of PAGE_SIZE, in a different page
3529         sz=$((sz+pagesz+30))
3530         $TRUNCATE $tmpfile $sz
3531         $TRUNCATE $testfile $sz
3532         cancel_lru_locks osc ; cancel_lru_locks mdc
3533         cmp -bl $tmpfile $testfile ||
3534                 error "file $testfile is corrupted (7)"
3535
3536         sync ; echo 3 > /proc/sys/vm/drop_caches
3537
3538         # remove fscrypt key from keyring
3539         keyctl revoke $(keyctl show | awk '$7 ~ "^fscrypt:" {print $1}')
3540         keyctl reap
3541
3542         scrambledfile=$(find $DIR/$tdir/ -maxdepth 1 -type f)
3543         $TRUNCATE $scrambledfile 0 &&
3544                 error "truncate $scrambledfile should have failed without key"
3545
3546         rm -f $tmpfile $tmpfile2
3547 }
3548 run_test 48a "encrypted file access semantics: truncate"
3549
3550 cleanup_for_enc_tests_othercli() {
3551         local othercli=$1
3552
3553         # remount othercli normally
3554         zconf_umount $othercli $MOUNT ||
3555                 error "umount $othercli $MOUNT failed"
3556         zconf_mount $othercli $MOUNT ||
3557                 error "remount $othercli $MOUNT failed"
3558 }
3559
3560 test_48b() {
3561         local othercli
3562
3563         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3564                 skip "client encryption not supported"
3565
3566         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3567                 skip "need dummy encryption support"
3568
3569         [ "$num_clients" -ge 2 ] || skip "Need at least 2 clients"
3570
3571         if [ "$HOSTNAME" == ${clients_arr[0]} ]; then
3572                 othercli=${clients_arr[1]}
3573         else
3574                 othercli=${clients_arr[0]}
3575         fi
3576
3577         stack_trap cleanup_for_enc_tests EXIT
3578         stack_trap "cleanup_for_enc_tests_othercli $othercli" EXIT
3579         setup_for_enc_tests
3580         zconf_umount $othercli $MOUNT ||
3581                 error "umount $othercli $MOUNT failed"
3582
3583         cp /bin/sleep $DIR/$tdir/
3584         cancel_lru_locks osc ; cancel_lru_locks mdc
3585         $DIR/$tdir/sleep 30 &
3586         # mount and IOs must be done in the same shell session, otherwise
3587         # encryption key in session keyring is missing
3588         do_node $othercli "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
3589                            $MGSNID:/$FSNAME $MOUNT && \
3590                            $TRUNCATE $DIR/$tdir/sleep 7"
3591         wait || error "wait error"
3592         cmp --silent /bin/sleep $DIR/$tdir/sleep ||
3593                 error "/bin/sleep and $DIR/$tdir/sleep differ"
3594 }
3595 run_test 48b "encrypted file: concurrent truncate"
3596
3597 trace_cmd() {
3598         local cmd="$@"
3599         local xattr_name="security.c"
3600
3601         cancel_lru_locks
3602         $LCTL set_param debug=+info
3603         $LCTL clear
3604
3605         echo $cmd
3606         eval $cmd
3607         [ $? -eq 0 ] || error "$cmd failed"
3608
3609         $LCTL dk | grep -E "get xattr '${xattr_name}'|get xattrs"
3610         [ $? -ne 0 ] || error "get xattr event was triggered"
3611 }
3612
3613 test_49() {
3614         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3615                 skip "client encryption not supported"
3616
3617         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3618                 skip "need dummy encryption support"
3619
3620         stack_trap cleanup_for_enc_tests EXIT
3621         setup_for_enc_tests
3622
3623         local dirname=$DIR/$tdir/subdir
3624
3625         mkdir $dirname
3626
3627         trace_cmd stat $dirname
3628         trace_cmd touch $dirname/f1
3629         trace_cmd stat $dirname/f1
3630         trace_cmd cat $dirname/f1
3631         dd if=/dev/zero of=$dirname/f1 bs=1M count=10 conv=fsync
3632         trace_cmd $TRUNCATE $dirname/f1 10240
3633         trace_cmd $LFS setstripe -E -1 -S 4M $dirname/f2
3634         trace_cmd $LFS migrate -E -1 -S 256K $dirname/f2
3635
3636         if [[ $MDSCOUNT -gt 1 ]]; then
3637                 trace_cmd $LFS setdirstripe -i 1 $dirname/d2
3638                 trace_cmd $LFS migrate -m 0 $dirname/d2
3639                 touch $dirname/d2/subf
3640                 # migrate a non-empty encrypted dir
3641                 trace_cmd $LFS migrate -m 1 $dirname/d2
3642
3643                 $LFS setdirstripe -i 1 -c 1 $dirname/d3
3644                 dirname=$dirname/d3/subdir
3645                 mkdir $dirname
3646
3647                 trace_cmd stat $dirname
3648                 trace_cmd touch $dirname/f1
3649                 trace_cmd stat $dirname/f1
3650                 trace_cmd cat $dirname/f1
3651                 dd if=/dev/zero of=$dirname/f1 bs=1M count=10 conv=fsync
3652                 trace_cmd $TRUNCATE $dirname/f1 10240
3653                 trace_cmd $LFS setstripe -E -1 -S 4M $dirname/f2
3654                 trace_cmd $LFS migrate -E -1 -S 256K $dirname/f2
3655         else
3656                 skip_noexit "2nd part needs >= 2 MDTs"
3657         fi
3658 }
3659 run_test 49 "Avoid getxattr for encryption context"
3660
3661 test_50() {
3662         local testfile=$DIR/$tdir/$tfile
3663         local tmpfile=$TMP/abc
3664         local pagesz=$(getconf PAGESIZE)
3665         local sz
3666
3667         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3668                 skip "client encryption not supported"
3669
3670         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3671                 skip "need dummy encryption support"
3672
3673         stack_trap cleanup_for_enc_tests EXIT
3674         setup_for_enc_tests
3675
3676         # write small file, data on MDT only
3677         tr '\0' '1' < /dev/zero |
3678             dd of=$tmpfile bs=1 count=5000 conv=fsync
3679         $LFS setstripe -E 1M -L mdt -E EOF $testfile
3680         cp $tmpfile $testfile
3681
3682         # check that in-memory representation of file is correct
3683         cmp -bl $tmpfile $testfile ||
3684                 error "file $testfile is corrupted in memory"
3685
3686         cancel_lru_locks osc ; cancel_lru_locks mdc
3687
3688         # check that file read from server is correct
3689         cmp -bl $tmpfile $testfile ||
3690                 error "file $testfile is corrupted on server"
3691
3692         # decrease size: truncate to PAGE_SIZE
3693         $TRUNCATE $tmpfile $pagesz
3694         $TRUNCATE $testfile $pagesz
3695         cancel_lru_locks osc ; cancel_lru_locks mdc
3696         cmp -bl $tmpfile $testfile ||
3697                 error "file $testfile is corrupted (1)"
3698
3699         # increase size: truncate to 2 x PAGE_SIZE
3700         sz=$((pagesz*2))
3701         $TRUNCATE $tmpfile $sz
3702         $TRUNCATE $testfile $sz
3703         cancel_lru_locks osc ; cancel_lru_locks mdc
3704         cmp -bl $tmpfile $testfile ||
3705                 error "file $testfile is corrupted (2)"
3706
3707         # truncate to PAGE_SIZE / 2
3708         sz=$((pagesz/2))
3709         $TRUNCATE $tmpfile $sz
3710         $TRUNCATE $testfile $sz
3711         cancel_lru_locks osc ; cancel_lru_locks mdc
3712         cmp -bl $tmpfile $testfile ||
3713                 error "file $testfile is corrupted (3)"
3714
3715         # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16
3716         sz=$((sz-7))
3717         $TRUNCATE $tmpfile $sz
3718         $TRUNCATE $testfile $sz
3719         cancel_lru_locks osc ; cancel_lru_locks mdc
3720         cmp -bl $tmpfile $testfile ||
3721                 error "file $testfile is corrupted (4)"
3722
3723         # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16
3724         sz=$((sz+18))
3725         $TRUNCATE $tmpfile $sz
3726         $TRUNCATE $testfile $sz
3727         cancel_lru_locks osc ; cancel_lru_locks mdc
3728         cmp -bl $tmpfile $testfile ||
3729                 error "file $testfile is corrupted (5)"
3730
3731         # truncate to a larger, non-multiple of PAGE_SIZE, in a different page
3732         sz=$((sz+pagesz+30))
3733         $TRUNCATE $tmpfile $sz
3734         $TRUNCATE $testfile $sz
3735         cancel_lru_locks osc ; cancel_lru_locks mdc
3736         cmp -bl $tmpfile $testfile ||
3737                 error "file $testfile is corrupted (6)"
3738
3739         rm -f $testfile
3740         cancel_lru_locks osc ; cancel_lru_locks mdc
3741
3742         # write hole in file, data spread on MDT and OST
3743         tr '\0' '2' < /dev/zero |
3744             dd of=$tmpfile bs=1 count=1539 seek=1539074 conv=fsync,notrunc
3745         $LFS setstripe -E 1M -L mdt -E EOF $testfile
3746         cp --sparse=always $tmpfile $testfile
3747
3748         # check that in-memory representation of file is correct
3749         cmp -bl $tmpfile $testfile ||
3750                 error "file $testfile is corrupted in memory"
3751
3752         cancel_lru_locks osc ; cancel_lru_locks mdc
3753
3754         # check that file read from server is correct
3755         cmp -bl $tmpfile $testfile ||
3756                 error "file $testfile is corrupted on server"
3757
3758         # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16,
3759         # inside OST part of data
3760         sz=$((1024*1024+13))
3761         $TRUNCATE $tmpfile $sz
3762         $TRUNCATE $testfile $sz
3763         cancel_lru_locks osc ; cancel_lru_locks mdc
3764         cmp -bl $tmpfile $testfile ||
3765                 error "file $testfile is corrupted (7)"
3766
3767         # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16,
3768         # inside MDT part of data
3769         sz=7
3770         $TRUNCATE $tmpfile $sz
3771         $TRUNCATE $testfile $sz
3772         cancel_lru_locks osc ; cancel_lru_locks mdc
3773         cmp -bl $tmpfile $testfile ||
3774                 error "file $testfile is corrupted (8)"
3775
3776         # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16,
3777         # inside MDT part of data
3778         sz=$((1024*1024-13))
3779         $TRUNCATE $tmpfile $sz
3780         $TRUNCATE $testfile $sz
3781         cancel_lru_locks osc ; cancel_lru_locks mdc
3782         cmp -bl $tmpfile $testfile ||
3783                 error "file $testfile is corrupted (9)"
3784
3785         # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16,
3786         # inside OST part of data
3787         sz=$((1024*1024+7))
3788         $TRUNCATE $tmpfile $sz
3789         $TRUNCATE $testfile $sz
3790         cancel_lru_locks osc ; cancel_lru_locks mdc
3791         cmp -bl $tmpfile $testfile ||
3792                 error "file $testfile is corrupted (10)"
3793
3794         rm -f $tmpfile
3795 }
3796 run_test 50 "DoM encrypted file"
3797
3798 test_51() {
3799         [ "$MDS1_VERSION" -gt $(version_code 2.13.53) ] ||
3800                 skip "Need MDS version at least 2.13.53"
3801
3802         mkdir $DIR/$tdir || error "mkdir $tdir"
3803
3804         touch $DIR/$tdir/$tfile || error "touch $tfile"
3805         cp $(which chown) $DIR/$tdir || error "cp chown"
3806         $RUNAS_CMD -u $ID0 $DIR/$tdir/chown $ID0 $DIR/$tdir/$tfile &&
3807                 error "chown $tfile should fail"
3808         setcap 'CAP_CHOWN=ep' $DIR/$tdir/chown || error "setcap CAP_CHOWN"
3809         $RUNAS_CMD -u $ID0 $DIR/$tdir/chown $ID0 $DIR/$tdir/$tfile ||
3810                 error "chown $tfile"
3811         rm $DIR/$tdir/$tfile || error "rm $tfile"
3812
3813         touch $DIR/$tdir/$tfile || error "touch $tfile"
3814         cp $(which touch) $DIR/$tdir || error "cp touch"
3815         $RUNAS_CMD -u $ID0 $DIR/$tdir/touch $DIR/$tdir/$tfile &&
3816                 error "touch should fail"
3817         setcap 'CAP_FOWNER=ep' $DIR/$tdir/touch || error "setcap CAP_FOWNER"
3818         $RUNAS_CMD -u $ID0 $DIR/$tdir/touch $DIR/$tdir/$tfile ||
3819                 error "touch $tfile"
3820         rm $DIR/$tdir/$tfile || error "rm $tfile"
3821
3822         local cap
3823         for cap in "CAP_DAC_OVERRIDE" "CAP_DAC_READ_SEARCH"; do
3824                 touch $DIR/$tdir/$tfile || error "touch $tfile"
3825                 chmod 600 $DIR/$tdir/$tfile || error "chmod $tfile"
3826                 cp $(which cat) $DIR/$tdir || error "cp cat"
3827                 $RUNAS_CMD -u $ID0 $DIR/$tdir/cat $DIR/$tdir/$tfile &&
3828                         error "cat should fail"
3829                 setcap $cap=ep $DIR/$tdir/cat || error "setcap $cap"
3830                 $RUNAS_CMD -u $ID0 $DIR/$tdir/cat $DIR/$tdir/$tfile ||
3831                         error "cat $tfile"
3832                 rm $DIR/$tdir/$tfile || error "rm $tfile"
3833         done
3834 }
3835 run_test 51 "FS capabilities ==============="
3836
3837 test_52() {
3838         local testfile=$DIR/$tdir/$tfile
3839         local tmpfile=$TMP/$tfile
3840         local mirror1=$TMP/$tfile.mirror1
3841         local mirror2=$TMP/$tfile.mirror2
3842
3843         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3844                 skip "client encryption not supported"
3845
3846         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3847                 skip "need dummy encryption support"
3848
3849         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
3850
3851         stack_trap cleanup_for_enc_tests EXIT
3852         setup_for_enc_tests
3853
3854         dd if=/dev/urandom of=$tmpfile bs=5000 count=1 conv=fsync
3855
3856         $LFS mirror create -N -i0 -N -i1 $testfile ||
3857                 error "could not create mirror"
3858
3859         dd if=$tmpfile of=$testfile bs=5000 count=1 conv=fsync ||
3860                 error "could not write to $testfile"
3861
3862         $LFS mirror resync $testfile ||
3863                 error "could not resync mirror"
3864
3865         $LFS mirror verify -v $testfile ||
3866                 error "verify mirror failed"
3867
3868         $LFS mirror read -N 1 -o $mirror1 $testfile ||
3869                 error "could not read from mirror 1"
3870
3871         cmp -bl $tmpfile $mirror1 ||
3872                 error "mirror 1 is corrupted"
3873
3874         $LFS mirror read -N 2 -o $mirror2 $testfile ||
3875                 error "could not read from mirror 2"
3876
3877         cmp -bl $tmpfile $mirror2 ||
3878                 error "mirror 2 is corrupted"
3879
3880         tr '\0' '2' < /dev/zero |
3881             dd of=$tmpfile bs=1 count=9000 conv=fsync
3882
3883         $LFS mirror write -N 1 -i $tmpfile $testfile ||
3884                 error "could not write to mirror 1"
3885
3886         $LFS mirror verify -v $testfile &&
3887                 error "mirrors should be different"
3888
3889         rm -f $tmpfile $mirror1 $mirror2
3890 }
3891 run_test 52 "Mirrored encrypted file"
3892
3893 test_53() {
3894         local testfile=$DIR/$tdir/$tfile
3895         local testfile2=$DIR2/$tdir/$tfile
3896         local tmpfile=$TMP/$tfile.tmp
3897         local resfile=$TMP/$tfile.res
3898         local pagesz
3899         local filemd5
3900
3901         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3902                 skip "client encryption not supported"
3903
3904         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3905                 skip "need dummy encryption support"
3906
3907         pagesz=$(getconf PAGESIZE)
3908         [[ $pagesz == 65536 ]] || skip "Need 64K PAGE_SIZE client"
3909
3910         do_node $mds1_HOST \
3911                 "mount.lustre --help |& grep -q 'test_dummy_encryption:'" ||
3912                         skip "need dummy encryption support on MDS client mount"
3913
3914         # this test is probably useless now, but may turn out to be useful when
3915         # Lustre supports servers with PAGE_SIZE != 4KB
3916         pagesz=$(do_node $mds1_HOST getconf PAGESIZE)
3917         [[ $pagesz == 4096 ]] || skip "Need 4K PAGE_SIZE MDS client"
3918
3919         stack_trap cleanup_for_enc_tests EXIT
3920         stack_trap "zconf_umount $mds1_HOST $MOUNT2" EXIT
3921         setup_for_enc_tests
3922
3923         $LFS setstripe -c1 -i0 $testfile
3924
3925         # write from 1st client
3926         cat /dev/urandom | tr -dc 'a-zA-Z0-9' |
3927                 dd of=$tmpfile bs=$((pagesz+3)) count=2 conv=fsync
3928         dd if=$tmpfile of=$testfile bs=$((pagesz+3)) count=2 conv=fsync ||
3929                 error "could not write to $testfile (1)"
3930
3931         # read from 2nd client
3932         # mount and IOs must be done in the same shell session, otherwise
3933         # encryption key in session keyring is missing
3934         do_node $mds1_HOST "mkdir -p $MOUNT2"
3935         do_node $mds1_HOST \
3936                 "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
3937                  $MGSNID:/$FSNAME $MOUNT2 && \
3938                  dd if=$testfile2 of=$resfile bs=$((pagesz+3)) count=2" ||
3939                 error "could not read from $testfile2 (1)"
3940
3941         # compare
3942         filemd5=$(do_node $mds1_HOST md5sum $resfile | awk '{print $1}')
3943         [ $filemd5 = $(md5sum $tmpfile | awk '{print $1}') ] ||
3944                 error "file is corrupted (1)"
3945         do_node $mds1_HOST rm -f $resfile
3946         cancel_lru_locks
3947
3948         # truncate from 2nd client
3949         $TRUNCATE $tmpfile $((pagesz+3))
3950         zconf_umount $mds1_HOST $MOUNT2 ||
3951                 error "umount $mds1_HOST $MOUNT2 failed (1)"
3952         do_node $mds1_HOST "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
3953                            $MGSNID:/$FSNAME $MOUNT2 && \
3954                            $TRUNCATE $testfile2 $((pagesz+3))" ||
3955                 error "could not truncate $testfile2 (1)"
3956
3957         # compare
3958         cmp -bl $tmpfile $testfile ||
3959                 error "file is corrupted (2)"
3960         rm -f $tmpfile $testfile
3961         cancel_lru_locks
3962         zconf_umount $mds1_HOST $MOUNT2 ||
3963                 error "umount $mds1_HOST $MOUNT2 failed (2)"
3964
3965         # do conversly
3966         do_node $mds1_HOST \
3967               dd if=/dev/urandom of=$tmpfile bs=$((pagesz+3)) count=2 conv=fsync
3968         # write from 2nd client
3969         do_node $mds1_HOST \
3970            "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
3971             $MGSNID:/$FSNAME $MOUNT2 && \
3972             dd if=$tmpfile of=$testfile2 bs=$((pagesz+3)) count=2 conv=fsync" ||
3973                 error "could not write to $testfile2 (2)"
3974
3975         # read from 1st client
3976         dd if=$testfile of=$resfile bs=$((pagesz+3)) count=2 ||
3977                 error "could not read from $testfile (2)"
3978
3979         # compare
3980         filemd5=$(do_node $mds1_HOST md5sum -b $tmpfile | awk '{print $1}')
3981         [ $filemd5 = $(md5sum -b $resfile | awk '{print $1}') ] ||
3982                 error "file is corrupted (3)"
3983         rm -f $resfile
3984         cancel_lru_locks
3985
3986         # truncate from 1st client
3987         do_node $mds1_HOST "$TRUNCATE $tmpfile $((pagesz+3))"
3988         $TRUNCATE $testfile $((pagesz+3)) ||
3989                 error "could not truncate $testfile (2)"
3990
3991         # compare
3992         zconf_umount $mds1_HOST $MOUNT2 ||
3993                 error "umount $mds1_HOST $MOUNT2 failed (3)"
3994         do_node $mds1_HOST "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
3995                            $MGSNID:/$FSNAME $MOUNT2 && \
3996                            cmp -bl $tmpfile $testfile2" ||
3997                 error "file is corrupted (4)"
3998
3999         do_node $mds1_HOST rm -f $tmpfile
4000         rm -f $tmpfile
4001 }
4002 run_test 53 "Mixed PAGE_SIZE clients"
4003
4004 test_54() {
4005         local testdir=$DIR/$tdir/$ID0
4006         local testfile=$testdir/$tfile
4007         local testfile2=$testdir/${tfile}2
4008         local tmpfile=$TMP/${tfile}.tmp
4009         local resfile=$TMP/${tfile}.res
4010
4011         $LCTL get_param mdc.*.import | grep -q client_encryption ||
4012                 skip "client encryption not supported"
4013
4014         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
4015                 skip "need dummy encryption support"
4016
4017         which fscrypt || skip "This test needs fscrypt userspace tool"
4018
4019         fscrypt setup --force --verbose || error "fscrypt global setup failed"
4020         sed -i 's/\(.*\)policy_version\(.*\):\(.*\)\"[0-9]*\"\(.*\)/\1policy_version\2:\3"2"\4/' \
4021                 /etc/fscrypt.conf
4022         fscrypt setup --verbose $MOUNT || error "fscrypt setup $MOUNT failed"
4023         mkdir -p $testdir
4024         chown -R $ID0:$ID0 $testdir
4025
4026         echo -e 'mypass\nmypass' | su - $USER0 -c "fscrypt encrypt --verbose \
4027                 --source=custom_passphrase --name=protector $testdir" ||
4028                 error "fscrypt encrypt failed"
4029
4030         echo -e 'mypass\nmypass' | su - $USER0 -c "fscrypt encrypt --verbose \
4031                 --source=custom_passphrase --name=protector2 $testdir" &&
4032                 error "second fscrypt encrypt should have failed"
4033
4034         mkdir -p ${testdir}2 || error "mkdir ${testdir}2 failed"
4035         touch ${testdir}2/f || error "mkdir ${testdir}2/f failed"
4036         cancel_lru_locks
4037
4038         echo -e 'mypass\nmypass' | fscrypt encrypt --verbose \
4039                 --source=custom_passphrase --name=protector3 ${testdir}2 &&
4040                 error "fscrypt encrypt on non-empty dir should have failed"
4041
4042         $RUNAS dd if=/dev/urandom of=$testfile bs=127 count=1 conv=fsync ||
4043                 error "write to encrypted file $testfile failed"
4044         cp $testfile $tmpfile
4045         $RUNAS dd if=/dev/urandom of=$testfile2 bs=127 count=1 conv=fsync ||
4046                 error "write to encrypted file $testfile2 failed"
4047         $RUNAS mkdir $testdir/subdir || error "mkdir subdir failed"
4048         $RUNAS touch $testdir/subdir/subfile || error "mkdir subdir failed"
4049
4050         $RUNAS fscrypt lock --verbose $testdir ||
4051                 error "fscrypt lock $testdir failed (1)"
4052
4053         $RUNAS ls -R $testdir || error "ls -R $testdir failed"
4054         local filecount=$($RUNAS find $testdir -type f | wc -l)
4055         [ $filecount -eq 3 ] || error "found $filecount files"
4056
4057         $RUNAS hexdump -C $testfile &&
4058                 error "reading $testfile should have failed without key"
4059
4060         $RUNAS touch ${testfile}.nokey &&
4061                 error "touch ${testfile}.nokey should have failed without key"
4062
4063         echo mypass | $RUNAS fscrypt unlock --verbose $testdir ||
4064                 error "fscrypt unlock $testdir failed (1)"
4065
4066         $RUNAS cat $testfile > $resfile ||
4067                 error "reading $testfile failed"
4068
4069         cmp -bl $tmpfile $resfile || error "file read differs from file written"
4070
4071         $RUNAS fscrypt lock --verbose $testdir ||
4072                 error "fscrypt lock $testdir failed (2)"
4073
4074         $RUNAS hexdump -C $testfile2 &&
4075                 error "reading $testfile2 should have failed without key"
4076
4077         echo mypass | $RUNAS fscrypt unlock --verbose $testdir ||
4078                 error "fscrypt unlock $testdir failed (2)"
4079
4080         rm -rf $testdir/*
4081         $RUNAS fscrypt lock --verbose $testdir ||
4082                 error "fscrypt lock $testdir failed (3)"
4083
4084         rm -f $tmpfile $resfile
4085 }
4086 run_test 54 "Encryption policies with fscrypt"
4087
4088 cleanup_55() {
4089         # unmount client
4090         if is_mounted $MOUNT; then
4091                 umount_client $MOUNT || error "umount $MOUNT failed"
4092         fi
4093
4094         do_facet mgs $LCTL nodemap_del c0
4095         do_facet mgs $LCTL nodemap_modify --name default \
4096                  --property admin --value 0
4097         do_facet mgs $LCTL nodemap_modify --name default \
4098                  --property trusted --value 0
4099         wait_nm_sync default admin_nodemap
4100         wait_nm_sync default trusted_nodemap
4101
4102         do_facet mgs $LCTL nodemap_activate 0
4103         wait_nm_sync active 0
4104
4105         if $SHARED_KEY; then
4106                 export SK_UNIQUE_NM=false
4107         fi
4108
4109         # remount client
4110         mount_client $MOUNT ${MOUNT_OPTS} || error "remount failed"
4111         if [ "$MOUNT_2" ]; then
4112                 mount_client $MOUNT2 ${MOUNT_OPTS} || error "remount failed"
4113         fi
4114 }
4115
4116 test_55() {
4117         local client_ip
4118         local client_nid
4119
4120         mkdir -p $DIR/$tdir/$USER0/testdir_groups
4121         chown root:$ID0 $DIR/$tdir/$USER0
4122         chmod 770 $DIR/$tdir/$USER0
4123         chmod g+s $DIR/$tdir/$USER0
4124         chown $ID0:$ID0 $DIR/$tdir/$USER0/testdir_groups
4125         chmod 770 $DIR/$tdir/$USER0/testdir_groups
4126         chmod g+s $DIR/$tdir/$USER0/testdir_groups
4127
4128         # unmount client completely
4129         umount_client $MOUNT || error "umount $MOUNT failed"
4130         if is_mounted $MOUNT2; then
4131                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
4132         fi
4133
4134         do_nodes $(comma_list $(all_mdts_nodes)) \
4135                 $LCTL set_param mdt.*.identity_upcall=NONE
4136
4137         stack_trap cleanup_55 EXIT
4138
4139         do_facet mgs $LCTL nodemap_activate 1
4140         wait_nm_sync active
4141
4142         do_facet mgs $LCTL nodemap_del c0 || true
4143         wait_nm_sync c0 id ''
4144
4145         do_facet mgs $LCTL nodemap_modify --name default \
4146                 --property admin --value 1
4147         do_facet mgs $LCTL nodemap_modify --name default \
4148                 --property trusted --value 1
4149         wait_nm_sync default admin_nodemap
4150         wait_nm_sync default trusted_nodemap
4151
4152         client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
4153         client_nid=$(h2nettype $client_ip)
4154         do_facet mgs $LCTL nodemap_add c0
4155         do_facet mgs $LCTL nodemap_add_range \
4156                  --name c0 --range $client_nid
4157         do_facet mgs $LCTL nodemap_modify --name c0 \
4158                  --property admin --value 0
4159         do_facet mgs $LCTL nodemap_modify --name c0 \
4160                  --property trusted --value 1
4161         wait_nm_sync c0 admin_nodemap
4162         wait_nm_sync c0 trusted_nodemap
4163
4164         if $SHARED_KEY; then
4165                 export SK_UNIQUE_NM=true
4166                 # set some generic fileset to trigger SSK code
4167                 export FILESET=/
4168         fi
4169
4170         # remount client to take nodemap into account
4171         zconf_mount_clients $HOSTNAME $MOUNT $MOUNT_OPTS ||
4172                 error "remount failed"
4173         unset FILESET
4174
4175         euid_access $USER0 $DIR/$tdir/$USER0/testdir_groups/file
4176 }
4177 run_test 55 "access with seteuid"
4178
4179 test_56() {
4180         local testfile=$DIR/$tdir/$tfile
4181
4182         [[ $(facet_fstype ost1) == zfs ]] && skip "skip ZFS backend"
4183
4184         $LCTL get_param mdc.*.import | grep -q client_encryption ||
4185                 skip "client encryption not supported"
4186
4187         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
4188                 skip "need dummy encryption support"
4189
4190         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4191
4192         stack_trap cleanup_for_enc_tests EXIT
4193         setup_for_enc_tests
4194
4195         $LFS setstripe -c1 $testfile
4196         dd if=/dev/urandom of=$testfile bs=1M count=3 conv=fsync
4197         filefrag -v $testfile || error "filefrag $testfile failed"
4198         (( $(filefrag -v $testfile | grep -c encrypted) >= 1 )) ||
4199                 error "filefrag $testfile does not show encrypted flag"
4200         (( $(filefrag -v $testfile | grep -c encoded) >= 1 )) ||
4201                 error "filefrag $testfile does not show encoded flag"
4202 }
4203 run_test 56 "FIEMAP on encrypted file"
4204
4205 test_57() {
4206         local testdir=$DIR/$tdir/mytestdir
4207         local testfile=$DIR/$tdir/$tfile
4208
4209         [[ $(facet_fstype ost1) == zfs ]] && skip "skip ZFS backend"
4210
4211         $LCTL get_param mdc.*.import | grep -q client_encryption ||
4212                 skip "client encryption not supported"
4213
4214         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
4215                 skip "need dummy encryption support"
4216
4217         mkdir $DIR/$tdir
4218         mkdir $testdir
4219         setfattr -n security.c -v myval $testdir &&
4220                 error "setting xattr on $testdir should have failed (1)"
4221         touch $testfile
4222         setfattr -n security.c -v myval $testfile &&
4223                 error "setting xattr on $testfile should have failed (1)"
4224
4225         rm -rf $DIR/$tdir
4226
4227         stack_trap cleanup_for_enc_tests EXIT
4228         setup_for_enc_tests
4229
4230         mkdir $testdir
4231         setfattr -n security.c -v myval $testdir &&
4232                 error "setting xattr on $testdir should have failed (2)"
4233         touch $testfile
4234         setfattr -n security.c -v myval $testfile &&
4235                 error "setting xattr on $testfile should have failed (2)"
4236         return 0
4237 }
4238 run_test 57 "security.c xattr protection"
4239
4240 log "cleanup: ======================================================"
4241
4242 sec_unsetup() {
4243         for num in $(seq $MDSCOUNT); do
4244                 if [ "${identity_old[$num]}" = 1 ]; then
4245                         switch_identity $num false || identity_old[$num]=$?
4246                 fi
4247         done
4248
4249         $RUNAS_CMD -u $ID0 ls $DIR
4250         $RUNAS_CMD -u $ID1 ls $DIR
4251 }
4252 sec_unsetup
4253
4254 complete $SECONDS
4255 check_and_cleanup_lustre
4256 exit_status