Whamcloud - gitweb
LU-17452 tests: fix interop sanityn tests with b2_15
[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 echo "was USER0=$(getent passwd | grep :${ID0:-500}:)"
51 echo "was USER1=$(getent passwd | grep :${ID1:-501}:)"
52
53 ID0=$(id -u $USER0)
54 ID1=$(id -u $USER1)
55
56 echo "now USER0=$USER0=$ID0:$(id -g $USER0), USER1=$USER1=$ID1:$(id -g $USER1)"
57
58 if [ "$SLOW" == "yes" ]; then
59         NODEMAP_COUNT=16
60         NODEMAP_RANGE_COUNT=3
61         NODEMAP_IPADDR_LIST="1 10 64 128 200 250"
62         NODEMAP_ID_COUNT=10
63 else
64         NODEMAP_COUNT=3
65         NODEMAP_RANGE_COUNT=2
66         NODEMAP_IPADDR_LIST="1 250"
67         NODEMAP_ID_COUNT=3
68 fi
69 NODEMAP_MAX_ID=$((ID0 + NODEMAP_ID_COUNT))
70
71 [ -z "$USER0" ] &&
72         skip "need to add user0 ($ID0:$ID0)" && exit 0
73
74 [ -z "$USER1" ] &&
75         skip "need to add user1 ($ID1:$ID1)" && exit 0
76
77 IDBASE=${IDBASE:-60000}
78
79 # changes to mappings must be reflected in test 23
80 FOPS_IDMAPS=(
81         [0]="$((IDBASE+3)):$((IDBASE+0)) $((IDBASE+4)):$((IDBASE+2))"
82         [1]="$((IDBASE+5)):$((IDBASE+1)) $((IDBASE+6)):$((IDBASE+2))"
83         )
84
85 check_and_setup_lustre
86
87 assert_DIR
88
89 # for GSS_SUP
90 GSS_REF=$(lsmod | grep ^ptlrpc_gss | awk '{print $3}')
91 if [ ! -z "$GSS_REF" -a "$GSS_REF" != "0" ]; then
92         GSS_SUP=1
93         echo "with GSS support"
94 else
95         GSS_SUP=0
96         echo "without GSS support"
97 fi
98
99 MDT=$(mdtname_from_index 0 $MOUNT)
100 [[ -z "$MDT" ]] && error "fail to get MDT0000 device name" && exit 1
101 do_facet $SINGLEMDS "mkdir -p $CONFDIR"
102 IDENTITY_FLUSH=mdt.$MDT.identity_flush
103
104 SAVE_PWD=$PWD
105
106 sec_login() {
107         local user=$1
108         local group=$2
109
110         $GSS_KRB5 || return
111         if ! $RUNAS_CMD -u $user krb5_login.sh; then
112                 error "$user login kerberos failed."
113                 exit 1
114         fi
115
116         if ! $RUNAS_CMD -u $user -g $group ls $DIR > /dev/null 2>&1; then
117                 $RUNAS_CMD -u $user lfs flushctx -k
118                 $RUNAS_CMD -u $user krb5_login.sh
119                 if ! $RUNAS_CMD -u$user -g$group ls $DIR > /dev/null 2>&1; then
120                         error "init $user $group failed."
121                         exit 2
122                 fi
123         fi
124 }
125
126 declare -a identity_old
127
128 sec_setup() {
129         for ((num = 1; num <= $MDSCOUNT; num++)); do
130                 switch_identity $num true || identity_old[$num]=$?
131         done
132
133         if ! $RUNAS_CMD -u $ID0 ls $DIR > /dev/null 2>&1; then
134                 sec_login $USER0 $USER0
135         fi
136
137         if ! $RUNAS_CMD -u $ID1 ls $DIR > /dev/null 2>&1; then
138                 sec_login $USER1 $USER1
139         fi
140 }
141 sec_setup
142
143 # run as different user
144 test_0() {
145         umask 0022
146
147         chmod 0755 $DIR || error "chmod (1) Failed"
148         rm -rf $DIR/$tdir || error "rm (1) Failed"
149         mkdir -p $DIR/$tdir || error "mkdir (1) Failed"
150
151         # $DIR/$tdir owner changed to USER0(sanityusr)
152         chown $USER0 $DIR/$tdir || error "chown (2) Failed"
153         chmod 0755 $DIR/$tdir || error "chmod (2) Failed"
154
155         # Run as ID0 cmd must pass
156         $RUNAS_CMD -u $ID0 ls -ali $DIR || error "ls (1) Failed"
157         # Remove non-existing file f0
158         rm -f $DIR/f0 || error "rm (2) Failed"
159
160         # It is expected that this cmd should fail
161         # $DIR has only r-x rights for group and other
162         $RUNAS_CMD -u $ID0 touch $DIR/f0
163         (( $? == 0 )) && error "touch (1) should not pass"
164
165         # This must pass. $DIR/$tdir/ is owned by ID0/USER0
166         $RUNAS_CMD -u $ID0 touch $DIR/$tdir/f1 || error "touch (2) Failed"
167
168         # It is expected that this cmd should fail
169         # $tdir has rwxr-xr-x rights for $ID0
170         $RUNAS_CMD -u $ID1 touch $DIR/$tdir/f2
171         (( $? == 0 )) && error "touch (3) should not pass"
172
173         touch $DIR/$tdir/f3 || error "touch (4) Failed"
174         chown root $DIR/$tdir || error "chown (3) Failed"
175         chgrp $USER0 $DIR/$tdir || error "chgrp (1) Failed"
176         chmod 0775 $DIR/$tdir || error "chmod (3) Failed"
177
178         # Owner is root and group is USER0
179         $RUNAS_CMD -u $USER0 -g $USER0 touch $DIR/$tdir/f4 ||
180                 error "touch (5) Failed"
181
182         # It is expected that this cmd should fail
183         # $tdir has rwxrwxr-x rights for group sanityusr/ID0, ID1 will fail
184         $RUNAS_CMD -u $ID1 -g $ID1 touch $DIR/$tdir/f5
185         (( $? == 0 )) && error "touch (6) should not pass"
186
187         touch $DIR/$tdir/f6 || error "touch (7) Failed"
188         rm -rf $DIR/$tdir || error "rm (3) Failed"
189 }
190 run_test 0 "uid permission ============================="
191
192 # setuid/gid
193 test_1() {
194         [ $GSS_SUP = 0 ] && skip "without GSS support." && return
195
196         rm -rf $DIR/$tdir
197         mkdir_on_mdt0 $DIR/$tdir
198
199         chown $USER0 $DIR/$tdir || error "chown (1)"
200         $RUNAS_CMD -u $ID1 -v $ID0 touch $DIR/$tdir/f0 && error "touch (2)"
201         echo "enable uid $ID1 setuid"
202         do_facet $SINGLEMDS "echo '* $ID1 setuid' >> $PERM_CONF"
203         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
204         $RUNAS_CMD -u $ID1 -v $ID0 touch $DIR/$tdir/f1 || error "touch (3)"
205
206         chown root $DIR/$tdir || error "chown (4)"
207         chgrp $USER0 $DIR/$tdir || error "chgrp (5)"
208         chmod 0770 $DIR/$tdir || error "chmod (6)"
209         $RUNAS_CMD -u $ID1 -g $ID1 touch $DIR/$tdir/f2 && error "touch (7)"
210         $RUNAS_CMD -u$ID1 -g$ID1 -j$ID0 touch $DIR/$tdir/f3 && error "touch (8)"
211         echo "enable uid $ID1 setuid,setgid"
212         do_facet $SINGLEMDS "echo '* $ID1 setuid,setgid' > $PERM_CONF"
213         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
214         $RUNAS_CMD -u $ID1 -g $ID1 -j $ID0 touch $DIR/$tdir/f4 ||
215                 error "touch (9)"
216         $RUNAS_CMD -u $ID1 -v $ID0 -g $ID1 -j $ID0 touch $DIR/$tdir/f5 ||
217                 error "touch (10)"
218
219         rm -rf $DIR/$tdir
220
221         do_facet $SINGLEMDS "rm -f $PERM_CONF"
222         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
223 }
224 run_test 1 "setuid/gid ============================="
225
226 # bug 3285 - supplementary group should always succeed.
227 # NB: the supplementary groups are set for local client only,
228 # as for remote client, the groups of the specified uid on MDT
229 # will be obtained by upcall /usr/sbin/l_getidentity and used.
230 test_4() {
231         [[ "$MDS1_VERSION" -ge $(version_code 2.6.93) ]] ||
232         [[ "$MDS1_VERSION" -ge $(version_code 2.5.35) &&
233            "$MDS1_VERSION" -lt $(version_code 2.5.50) ]] ||
234                 skip "Need MDS version at least 2.6.93 or 2.5.35"
235
236         rm -rf $DIR/$tdir
237         mkdir_on_mdt0 -p $DIR/$tdir
238         chmod 0771 $DIR/$tdir
239         chgrp $ID0 $DIR/$tdir
240         $RUNAS_CMD -u $ID0 ls $DIR/$tdir || error "setgroups (1)"
241         do_facet $SINGLEMDS "echo '* $ID1 setgrp' > $PERM_CONF"
242         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
243         $RUNAS_CMD -u $ID1 -G1,2,$ID0 ls $DIR/$tdir ||
244                 error "setgroups (2)"
245         $RUNAS_CMD -u $ID1 -G1,2 ls $DIR/$tdir && error "setgroups (3)"
246         rm -rf $DIR/$tdir
247
248         do_facet $SINGLEMDS "rm -f $PERM_CONF"
249         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
250 }
251 run_test 4 "set supplementary group ==============="
252
253 create_nodemaps() {
254         local i
255         local rc
256
257         squash_id default 99 0
258         wait_nm_sync default squash_uid '' inactive
259         squash_id default 99 1
260         wait_nm_sync default squash_gid '' inactive
261         for (( i = 0; i < NODEMAP_COUNT; i++ )); do
262                 local csum=${HOSTNAME_CHECKSUM}_${i}
263
264                 do_facet mgs $LCTL nodemap_add $csum
265                 rc=$?
266                 if [ $rc -ne 0 ]; then
267                         echo "nodemap_add $csum failed with $rc"
268                         return $rc
269                 fi
270
271                 wait_update_facet --verbose mgs \
272                         "$LCTL get_param nodemap.$csum.id 2>/dev/null | \
273                         grep -c $csum || true" 1 30 ||
274                     return 1
275         done
276         for (( i = 0; i < NODEMAP_COUNT; i++ )); do
277                 local csum=${HOSTNAME_CHECKSUM}_${i}
278
279                 wait_nm_sync $csum id '' inactive
280         done
281         return 0
282 }
283
284 delete_nodemaps() {
285         local i
286
287         for ((i = 0; i < NODEMAP_COUNT; i++)); do
288                 local csum=${HOSTNAME_CHECKSUM}_${i}
289
290                 if ! do_facet mgs $LCTL nodemap_del $csum; then
291                         error "nodemap_del $csum failed with $?"
292                         return 3
293                 fi
294
295                 wait_update_facet --verbose mgs \
296                         "$LCTL get_param nodemap.$csum.id 2>/dev/null | \
297                         grep -c $csum || true" 0 30 ||
298                     return 1
299         done
300         for (( i = 0; i < NODEMAP_COUNT; i++ )); do
301                 local csum=${HOSTNAME_CHECKSUM}_${i}
302
303                 wait_nm_sync $csum id '' inactive
304         done
305         return 0
306 }
307
308 add_range() {
309         local j
310         local cmd="$LCTL nodemap_add_range"
311         local range
312         local rc=0
313
314         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
315                 range="$SUBNET_CHECKSUM.${2}.${j}.[1-253]@tcp"
316                 if ! do_facet mgs $cmd --name $1 --range $range; then
317                         rc=$((rc + 1))
318                 fi
319         done
320         return $rc
321 }
322
323 delete_range() {
324         local j
325         local cmd="$LCTL nodemap_del_range"
326         local range
327         local rc=0
328
329         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
330                 range="$SUBNET_CHECKSUM.${2}.${j}.[1-253]@tcp"
331                 if ! do_facet mgs $cmd --name $1 --range $range; then
332                         rc=$((rc + 1))
333                 fi
334         done
335
336         return $rc
337 }
338
339 add_idmaps() {
340         local i
341         local cmd="$LCTL nodemap_add_idmap"
342         local do_proj=true
343         local rc=0
344
345         (( $MDS1_VERSION >= $(version_code 2.14.52) )) || do_proj=false
346
347         echo "Start to add idmaps ..."
348         for ((i = 0; i < NODEMAP_COUNT; i++)); do
349                 local j
350
351                 for ((j = $ID0; j < NODEMAP_MAX_ID; j++)); do
352                         local csum=${HOSTNAME_CHECKSUM}_${i}
353                         local client_id=$j
354                         local fs_id=$((j + 1))
355
356                         if ! do_facet mgs $cmd --name $csum --idtype uid \
357                              --idmap $client_id:$fs_id; then
358                                 rc=$((rc + 1))
359                         fi
360                         if ! do_facet mgs $cmd --name $csum --idtype gid \
361                              --idmap $client_id:$fs_id; then
362                                 rc=$((rc + 1))
363                         fi
364                         if $do_proj; then
365                                 if ! do_facet mgs $cmd --name $csum \
366                                      --idtype projid --idmap \
367                                      $client_id:$fs_id; then
368                                         rc=$((rc + 1))
369                                 fi
370                         fi
371                 done
372         done
373
374         return $rc
375 }
376
377 update_idmaps() { #LU-10040
378         [ "$MGS_VERSION" -lt $(version_code 2.10.55) ] &&
379                 skip "Need MGS >= 2.10.55"
380
381         local csum=${HOSTNAME_CHECKSUM}_0
382         local old_id_client=$ID0
383         local old_id_fs=$((ID0 + 1))
384         local new_id=$((ID0 + 100))
385         local tmp_id
386         local cmd
387         local rc=0
388
389         echo "Start to update idmaps ..."
390
391         #Inserting an existed idmap should return error
392         cmd="$LCTL nodemap_add_idmap --name $csum --idtype uid"
393         if do_facet mgs \
394                 $cmd --idmap $old_id_client:$old_id_fs 2>/dev/null; then
395                 error "insert idmap {$old_id_client:$old_id_fs} " \
396                         "should return error"
397                 rc=$((rc + 1))
398                 return rc
399         fi
400
401         #Update id_fs and check it
402         if ! do_facet mgs $cmd --idmap $old_id_client:$new_id; then
403                 error "$cmd --idmap $old_id_client:$new_id failed"
404                 rc=$((rc + 1))
405                 return $rc
406         fi
407         tmp_id=$(do_facet mgs $LCTL get_param -n nodemap.$csum.idmap |
408                 awk '{ print $7 }' | sed -n '2p')
409         [ $tmp_id != $new_id ] && { error "new id_fs $tmp_id != $new_id"; \
410                 rc=$((rc + 1)); return $rc; }
411
412         #Update id_client and check it
413         if ! do_facet mgs $cmd --idmap $new_id:$new_id; then
414                 error "$cmd --idmap $new_id:$new_id failed"
415                 rc=$((rc + 1))
416                 return $rc
417         fi
418         tmp_id=$(do_facet mgs $LCTL get_param -n nodemap.$csum.idmap |
419                 awk '{ print $5 }' | sed -n "$((NODEMAP_ID_COUNT + 1)) p")
420         tmp_id=$(echo ${tmp_id%,*}) #e.g. "501,"->"501"
421         [ $tmp_id != $new_id ] && { error "new id_client $tmp_id != $new_id"; \
422                 rc=$((rc + 1)); return $rc; }
423
424         #Delete above updated idmap
425         cmd="$LCTL nodemap_del_idmap --name $csum --idtype uid"
426         if ! do_facet mgs $cmd --idmap $new_id:$new_id; then
427                 error "$cmd --idmap $new_id:$new_id failed"
428                 rc=$((rc + 1))
429                 return $rc
430         fi
431
432         #restore the idmaps to make delete_idmaps work well
433         cmd="$LCTL nodemap_add_idmap --name $csum --idtype uid"
434         if ! do_facet mgs $cmd --idmap $old_id_client:$old_id_fs; then
435                 error "$cmd --idmap $old_id_client:$old_id_fs failed"
436                 rc=$((rc + 1))
437                 return $rc
438         fi
439
440         return $rc
441 }
442
443 delete_idmaps() {
444         local i
445         local cmd="$LCTL nodemap_del_idmap"
446         local do_proj=true
447         local rc=0
448
449         (( $MDS1_VERSION >= $(version_code 2.14.52) )) || do_proj=false
450
451         echo "Start to delete idmaps ..."
452         for ((i = 0; i < NODEMAP_COUNT; i++)); do
453                 local j
454
455                 for ((j = $ID0; j < NODEMAP_MAX_ID; j++)); do
456                         local csum=${HOSTNAME_CHECKSUM}_${i}
457                         local client_id=$j
458                         local fs_id=$((j + 1))
459
460                         if ! do_facet mgs $cmd --name $csum --idtype uid \
461                              --idmap $client_id:$fs_id; then
462                                 rc=$((rc + 1))
463                         fi
464                         if ! do_facet mgs $cmd --name $csum --idtype gid \
465                              --idmap $client_id:$fs_id; then
466                                 rc=$((rc + 1))
467                         fi
468                         if $do_proj; then
469                                 if ! do_facet mgs $cmd --name $csum \
470                                      --idtype projid --idmap \
471                                      $client_id:$fs_id; then
472                                         rc=$((rc + 1))
473                                 fi
474                         fi
475                 done
476         done
477
478         return $rc
479 }
480
481 modify_flags() {
482         local i
483         local proc
484         local option
485         local cmd="$LCTL nodemap_modify"
486         local rc=0
487
488         proc[0]="admin_nodemap"
489         proc[1]="trusted_nodemap"
490         option[0]="admin"
491         option[1]="trusted"
492
493         for ((idx = 0; idx < 2; idx++)); do
494                 if ! do_facet mgs $cmd --name $1 --property ${option[$idx]} \
495                      --value 1; then
496                         rc=$((rc + 1))
497                 fi
498
499                 if ! do_facet mgs $cmd --name $1 --property ${option[$idx]} \
500                      --value 0; then
501                         rc=$((rc + 1))
502                 fi
503         done
504
505         return $rc
506 }
507
508 squash_id() {
509         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
510                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
511
512         local cmd
513
514         cmd[0]="$LCTL nodemap_modify --property squash_uid"
515         cmd[1]="$LCTL nodemap_modify --property squash_gid"
516         cmd[2]="$LCTL nodemap_modify --property squash_projid"
517
518         if ! do_facet mgs ${cmd[$3]} --name $1 --value $2; then
519                 return 1
520         fi
521 }
522
523 # ensure that the squash defaults are the expected defaults
524 squash_id default 99 0
525 wait_nm_sync default squash_uid '' inactive
526 squash_id default 99 1
527 wait_nm_sync default squash_gid '' inactive
528 if [ "$MDS1_VERSION" -ge $(version_code 2.14.50) ]; then
529         squash_id default 99 2
530         wait_nm_sync default squash_projid '' inactive
531 fi
532
533 test_nid() {
534         local cmd
535
536         cmd="$LCTL nodemap_test_nid"
537
538         nid=$(do_facet mgs $cmd $1)
539
540         if [ $nid == $2 ]; then
541                 return 0
542         fi
543
544         return 1
545 }
546
547 cleanup_active() {
548         # restore activation state
549         do_facet mgs $LCTL nodemap_activate 0
550         wait_nm_sync active
551 }
552
553 test_idmap() {
554         local i
555         local cmd="$LCTL nodemap_test_id"
556         local rc=0
557
558         echo "Start to test idmaps ..."
559         ## nodemap deactivated
560         if ! do_facet mgs $LCTL nodemap_activate 0; then
561                 return 1
562         fi
563         for ((id = $ID0; id < NODEMAP_MAX_ID; id++)); do
564                 local j
565
566                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
567                         local nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
568                         local fs_id=$(do_facet mgs $cmd --nid $nid      \
569                                       --idtype uid --id $id)
570                         if [ $fs_id != $id ]; then
571                                 echo "expected $id, got $fs_id"
572                                 rc=$((rc + 1))
573                         fi
574                 done
575         done
576
577         ## nodemap activated
578         if ! do_facet mgs $LCTL nodemap_activate 1; then
579                 return 2
580         fi
581
582         for ((id = $ID0; id < NODEMAP_MAX_ID; id++)); do
583                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
584                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
585                         fs_id=$(do_facet mgs $cmd --nid $nid    \
586                                 --idtype uid --id $id)
587                         expected_id=$((id + 1))
588                         if [ $fs_id != $expected_id ]; then
589                                 echo "expected $expected_id, got $fs_id"
590                                 rc=$((rc + 1))
591                         fi
592                 done
593         done
594
595         ## trust client ids
596         for ((i = 0; i < NODEMAP_COUNT; i++)); do
597                 local csum=${HOSTNAME_CHECKSUM}_${i}
598
599                 if ! do_facet mgs $LCTL nodemap_modify --name $csum \
600                      --property trusted --value 1; then
601                         error "nodemap_modify $csum failed with $?"
602                         return 3
603                 fi
604         done
605
606         for ((id = $ID0; id < NODEMAP_MAX_ID; id++)); do
607                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
608                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
609                         fs_id=$(do_facet mgs $cmd --nid $nid    \
610                                 --idtype uid --id $id)
611                         if [ $fs_id != $id ]; then
612                                 echo "expected $id, got $fs_id"
613                                 rc=$((rc + 1))
614                         fi
615                 done
616         done
617
618         ## ensure allow_root_access is enabled
619         for ((i = 0; i < NODEMAP_COUNT; i++)); do
620                 local csum=${HOSTNAME_CHECKSUM}_${i}
621
622                 if ! do_facet mgs $LCTL nodemap_modify --name $csum     \
623                      --property admin --value 1; then
624                         error "nodemap_modify $csum failed with $?"
625                         return 3
626                 fi
627         done
628
629         ## check that root allowed
630         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
631                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
632                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
633                 if [ $fs_id != 0 ]; then
634                         echo "root allowed expected 0, got $fs_id"
635                         rc=$((rc + 1))
636                 fi
637         done
638
639         ## ensure allow_root_access is disabled
640         for ((i = 0; i < NODEMAP_COUNT; i++)); do
641                 local csum=${HOSTNAME_CHECKSUM}_${i}
642
643                 if ! do_facet mgs $LCTL nodemap_modify --name $csum     \
644                                 --property admin --value 0; then
645                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
646                                 "failed with $rc"
647                         return 3
648                 fi
649         done
650
651         ## check that root is mapped to 99
652         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
653                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
654                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
655                 if [ $fs_id != 99 ]; then
656                         error "root squash expected 99, got $fs_id"
657                         rc=$((rc + 1))
658                 fi
659         done
660
661         ## reset client trust to 0
662         for ((i = 0; i < NODEMAP_COUNT; i++)); do
663                 if ! do_facet mgs $LCTL nodemap_modify          \
664                         --name ${HOSTNAME_CHECKSUM}_${i}        \
665                         --property trusted --value 0; then
666                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
667                                 "failed with $rc"
668                         return 3
669                 fi
670         done
671
672         return $rc
673 }
674
675 test_7() {
676         local rc
677
678         remote_mgs_nodsh && skip "remote MGS with nodsh"
679         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
680                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
681
682         create_nodemaps
683         rc=$?
684         [[ $rc != 0 ]] && error "nodemap_add failed with $rc"
685
686         delete_nodemaps
687         rc=$?
688         [[ $rc != 0 ]] && error "nodemap_del failed with $rc"
689
690         return 0
691 }
692 run_test 7 "nodemap create and delete"
693
694 test_8() {
695         local rc
696
697         remote_mgs_nodsh && skip "remote MGS with nodsh"
698         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
699                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
700
701         # Set up nodemaps
702
703         create_nodemaps
704         rc=$?
705         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
706
707         # Try duplicates
708
709         create_nodemaps
710         rc=$?
711         [[ $rc == 0 ]] && error "duplicate nodemap_add allowed with $rc" &&
712         return 2
713
714         # Clean up
715         delete_nodemaps
716         rc=$?
717         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 3
718
719         return 0
720 }
721 run_test 8 "nodemap reject duplicates"
722
723 test_9() {
724         local i
725         local rc
726
727         remote_mgs_nodsh && skip "remote MGS with nodsh"
728         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
729                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
730
731         rc=0
732         create_nodemaps
733         rc=$?
734         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
735
736         rc=0
737         for ((i = 0; i < NODEMAP_COUNT; i++)); do
738                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
739                         rc=$((rc + 1))
740                 fi
741         done
742         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
743
744         rc=0
745         for ((i = 0; i < NODEMAP_COUNT; i++)); do
746                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
747                         rc=$((rc + 1))
748                 fi
749         done
750         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
751
752         rc=0
753         delete_nodemaps
754         rc=$?
755         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
756
757         return 0
758 }
759 run_test 9 "nodemap range add"
760
761 test_10a() {
762         local rc
763
764         remote_mgs_nodsh && skip "remote MGS with nodsh"
765         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
766                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
767
768         rc=0
769         create_nodemaps
770         rc=$?
771         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
772
773         rc=0
774         for ((i = 0; i < NODEMAP_COUNT; i++)); do
775                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
776                         rc=$((rc + 1))
777                 fi
778         done
779         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
780
781         rc=0
782         for ((i = 0; i < NODEMAP_COUNT; i++)); do
783                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
784                         rc=$((rc + 1))
785                 fi
786         done
787         [[ $rc == 0 ]] && error "nodemap_add_range duplicate add with $rc" &&
788                 return 2
789
790
791         rc=0
792         for ((i = 0; i < NODEMAP_COUNT; i++)); do
793                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
794                         rc=$((rc + 1))
795                 fi
796         done
797         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
798
799         delete_nodemaps
800         rc=$?
801         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 5
802
803         return 0
804 }
805 run_test 10a "nodemap reject duplicate ranges"
806
807 test_10b() {
808         [ "$MGS_VERSION" -lt $(version_code 2.10.53) ] &&
809                 skip "Need MGS >= 2.10.53"
810
811         local nm1="nodemap1"
812         local nm2="nodemap2"
813         local nids="192.168.19.[0-255]@o2ib20"
814
815         do_facet mgs $LCTL nodemap_del $nm1 2>/dev/null
816         do_facet mgs $LCTL nodemap_del $nm2 2>/dev/null
817
818         do_facet mgs $LCTL nodemap_add $nm1 || error "Add $nm1 failed"
819         do_facet mgs $LCTL nodemap_add $nm2 || error "Add $nm2 failed"
820         do_facet mgs $LCTL nodemap_add_range --name $nm1 --range $nids ||
821                 error "Add range $nids to $nm1 failed"
822         [ -n "$(do_facet mgs $LCTL get_param nodemap.$nm1.* |
823                 grep start_nid)" ] || error "No range was found"
824         do_facet mgs $LCTL nodemap_del_range --name $nm2 --range $nids &&
825                 error "Deleting range $nids from $nm2 should fail"
826         [ -n "$(do_facet mgs $LCTL get_param nodemap.$nm1.* |
827                 grep start_nid)" ] || error "Range $nids should be there"
828
829         do_facet mgs $LCTL nodemap_del $nm1 || error "Delete $nm1 failed"
830         do_facet mgs $LCTL nodemap_del $nm2 || error "Delete $nm2 failed"
831         return 0
832 }
833 run_test 10b "delete range from the correct nodemap"
834
835 test_10c() { #LU-8912
836         [ "$MGS_VERSION" -lt $(version_code 2.10.57) ] &&
837                 skip "Need MGS >= 2.10.57"
838
839         local nm="nodemap_lu8912"
840         local nid_range="10.210.[32-47].[0-255]@o2ib3"
841         local start_nid="10.210.32.0@o2ib3"
842         local end_nid="10.210.47.255@o2ib3"
843         local start_nid_found
844         local end_nid_found
845
846         do_facet mgs $LCTL nodemap_del $nm 2>/dev/null
847         do_facet mgs $LCTL nodemap_add $nm || error "Add $nm failed"
848         do_facet mgs $LCTL nodemap_add_range --name $nm --range $nid_range ||
849                 error "Add range $nid_range to $nm failed"
850
851         start_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
852                 awk -F '[,: ]' /start_nid/'{ print $9 }')
853         [ "$start_nid" == "$start_nid_found" ] ||
854                 error "start_nid: $start_nid_found != $start_nid"
855         end_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
856                 awk -F '[,: ]' /end_nid/'{ print $13 }')
857         [ "$end_nid" == "$end_nid_found" ] ||
858                 error "end_nid: $end_nid_found != $end_nid"
859
860         do_facet mgs $LCTL nodemap_del $nm || error "Delete $nm failed"
861         return 0
862 }
863 run_test 10c "verfify contiguous range support"
864
865 test_10d() { #LU-8913
866         [ "$MGS_VERSION" -lt $(version_code 2.10.59) ] &&
867                 skip "Need MGS >= 2.10.59"
868
869         local nm="nodemap_lu8913"
870         local nid_range="*@o2ib3"
871         local start_nid="0.0.0.0@o2ib3"
872         local end_nid="255.255.255.255@o2ib3"
873         local start_nid_found
874         local end_nid_found
875
876         do_facet mgs $LCTL nodemap_del $nm 2>/dev/null
877         do_facet mgs $LCTL nodemap_add $nm || error "Add $nm failed"
878         do_facet mgs $LCTL nodemap_add_range --name $nm --range $nid_range ||
879                 error "Add range $nid_range to $nm failed"
880
881         start_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
882                 awk -F '[,: ]' /start_nid/'{ print $9 }')
883         [ "$start_nid" == "$start_nid_found" ] ||
884                 error "start_nid: $start_nid_found != $start_nid"
885         end_nid_found=$(do_facet mgs $LCTL get_param nodemap.$nm.* |
886                 awk -F '[,: ]' /end_nid/'{ print $13 }')
887         [ "$end_nid" == "$end_nid_found" ] ||
888                 error "end_nid: $end_nid_found != $end_nid"
889
890         do_facet mgs $LCTL nodemap_del $nm || error "Delete $nm failed"
891         return 0
892 }
893 run_test 10d "verfify nodemap range format '*@<net>' support"
894
895 test_11() {
896         local rc
897
898         remote_mgs_nodsh && skip "remote MGS with nodsh"
899         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
900                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
901
902         rc=0
903         create_nodemaps
904         rc=$?
905         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
906
907         rc=0
908         for ((i = 0; i < NODEMAP_COUNT; i++)); do
909                 if ! modify_flags ${HOSTNAME_CHECKSUM}_${i}; then
910                         rc=$((rc + 1))
911                 fi
912         done
913         [[ $rc != 0 ]] && error "nodemap_modify with $rc" && return 2
914
915         rc=0
916         delete_nodemaps
917         rc=$?
918         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 3
919
920         return 0
921 }
922 run_test 11 "nodemap modify"
923
924 test_12() {
925         local rc
926
927         remote_mgs_nodsh && skip "remote MGS with nodsh"
928         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
929                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
930
931         rc=0
932         create_nodemaps
933         rc=$?
934         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
935
936         rc=0
937         for ((i = 0; i < NODEMAP_COUNT; i++)); do
938                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 0; then
939                         rc=$((rc + 1))
940                 fi
941         done
942         [[ $rc != 0 ]] && error "nodemap squash_uid with $rc" && return 2
943
944         rc=0
945         for ((i = 0; i < NODEMAP_COUNT; i++)); do
946                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 1; then
947                         rc=$((rc + 1))
948                 fi
949         done
950         [[ $rc != 0 ]] && error "nodemap squash_gid with $rc" && return 3
951
952         rc=0
953         if (( $MDS1_VERSION >= $(version_code 2.14.52) )); then
954                 for ((i = 0; i < NODEMAP_COUNT; i++)); do
955                         if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 2; then
956                                 rc=$((rc + 1))
957                         fi
958                 done
959         fi
960         [[ $rc != 0 ]] && error "nodemap squash_projid with $rc" && return 5
961
962         rc=0
963         delete_nodemaps
964         rc=$?
965         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
966
967         return 0
968 }
969 run_test 12 "nodemap set squash ids"
970
971 test_13() {
972         local rc
973
974         remote_mgs_nodsh && skip "remote MGS with nodsh"
975         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
976                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
977
978         rc=0
979         create_nodemaps
980         rc=$?
981         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
982
983         rc=0
984         for ((i = 0; i < NODEMAP_COUNT; i++)); do
985                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
986                         rc=$((rc + 1))
987                 fi
988         done
989         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
990
991         rc=0
992         for ((i = 0; i < NODEMAP_COUNT; i++)); do
993                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
994                         for k in $NODEMAP_IPADDR_LIST; do
995                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
996                                        ${HOSTNAME_CHECKSUM}_${i}; then
997                                         rc=$((rc + 1))
998                                 fi
999                         done
1000                 done
1001         done
1002         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
1003
1004         rc=0
1005         delete_nodemaps
1006         rc=$?
1007         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
1008
1009         return 0
1010 }
1011 run_test 13 "test nids"
1012
1013 test_14() {
1014         local rc
1015
1016         remote_mgs_nodsh && skip "remote MGS with nodsh"
1017         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
1018                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
1019
1020         rc=0
1021         create_nodemaps
1022         rc=$?
1023         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1024
1025         rc=0
1026         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1027                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
1028                         for k in $NODEMAP_IPADDR_LIST; do
1029                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
1030                                         default; then
1031                                         rc=$((rc + 1))
1032                                 fi
1033                         done
1034                 done
1035         done
1036         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
1037
1038         rc=0
1039         delete_nodemaps
1040         rc=$?
1041         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
1042
1043         return 0
1044 }
1045 run_test 14 "test default nodemap nid lookup"
1046
1047 test_15() {
1048         local rc
1049
1050         remote_mgs_nodsh && skip "remote MGS with nodsh"
1051         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
1052                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53"
1053
1054         rc=0
1055         create_nodemaps
1056         rc=$?
1057         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1058
1059         for (( i = 0; i < NODEMAP_COUNT; i++ )); do
1060                 local csum=${HOSTNAME_CHECKSUM}_${i}
1061
1062                 if ! do_facet mgs $LCTL nodemap_modify --name $csum \
1063                                 --property admin --value 0; then
1064                         rc=$((rc + 1))
1065                 fi
1066                 if ! do_facet mgs $LCTL nodemap_modify --name $csum \
1067                                 --property trusted --value 0; then
1068                         rc=$((rc + 1))
1069                 fi
1070         done
1071         [[ $rc != 0 ]] && error "nodemap_modify failed with $rc" && return 1
1072
1073         rc=0
1074         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1075                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
1076                         rc=$((rc + 1))
1077                 fi
1078         done
1079         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
1080
1081         rc=0
1082         add_idmaps
1083         rc=$?
1084         [[ $rc != 0 ]] && error "nodemap_add_idmap failed with $rc" && return 3
1085
1086         activedefault=$(do_facet mgs $LCTL get_param -n nodemap.active)
1087         if [[ "$activedefault" != "1" ]]; then
1088                 stack_trap cleanup_active EXIT
1089         fi
1090
1091         rc=0
1092         test_idmap
1093         rc=$?
1094         [[ $rc != 0 ]] && error "nodemap_test_id failed with $rc" && return 4
1095
1096         rc=0
1097         update_idmaps
1098         rc=$?
1099         [[ $rc != 0 ]] && error "update_idmaps failed with $rc" && return 5
1100
1101         rc=0
1102         delete_idmaps
1103         rc=$?
1104         [[ $rc != 0 ]] && error "nodemap_del_idmap failed with $rc" && return 6
1105
1106         rc=0
1107         delete_nodemaps
1108         rc=$?
1109         [[ $rc != 0 ]] && error "nodemap_delete failed with $rc" && return 7
1110
1111         return 0
1112 }
1113 run_test 15 "test id mapping"
1114
1115 create_fops_nodemaps() {
1116         local i=0
1117         local client
1118         for client in $clients; do
1119                 local client_ip=$(host_nids_address $client $NETTYPE)
1120                 local client_nid=$(h2nettype $client_ip)
1121                  [[ "$client_nid" =~ ":" ]] && client_nid+="/128"
1122                 do_facet mgs $LCTL nodemap_add c${i} || return 1
1123                 do_facet mgs $LCTL nodemap_add_range    \
1124                         --name c${i} --range $client_nid || {
1125                         do_facet mgs $LCTL nodemap_del c${i}
1126                         return 1
1127                 }
1128                 for map in ${FOPS_IDMAPS[i]}; do
1129                         do_facet mgs $LCTL nodemap_add_idmap --name c${i} \
1130                                 --idtype uid --idmap ${map} || return 1
1131                         do_facet mgs $LCTL nodemap_add_idmap --name c${i} \
1132                                 --idtype gid --idmap ${map} || return 1
1133                 done
1134
1135                 wait_nm_sync c$i idmap
1136
1137                 i=$((i + 1))
1138         done
1139         return 0
1140 }
1141
1142 delete_fops_nodemaps() {
1143         local i=0
1144         local client
1145         for client in $clients; do
1146                 do_facet mgs $LCTL nodemap_del c${i} || return 1
1147                 i=$((i + 1))
1148         done
1149         return 0
1150 }
1151
1152 fops_mds_index=0
1153 nm_test_mkdir() {
1154         if [ $MDSCOUNT -le 1 ]; then
1155                 do_node ${clients_arr[0]} mkdir -p $DIR/$tdir
1156         else
1157                 # round-robin MDTs to test DNE nodemap support
1158                 [ ! -d $DIR ] && do_node ${clients_arr[0]} mkdir -p $DIR
1159                 do_node ${clients_arr[0]} $LFS setdirstripe -c 1 -i \
1160                         $((fops_mds_index % MDSCOUNT)) $DIR/$tdir
1161                 ((fops_mds_index++))
1162         fi
1163 }
1164
1165 # acl test directory needs to be initialized on a privileged client
1166 fops_test_setup() {
1167         local admin=$(do_facet mgs $LCTL get_param -n nodemap.c0.admin_nodemap)
1168         local trust=$(do_facet mgs $LCTL get_param -n \
1169                 nodemap.c0.trusted_nodemap)
1170
1171         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1172         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1173
1174         wait_nm_sync c0 admin_nodemap
1175         wait_nm_sync c0 trusted_nodemap
1176
1177         do_node ${clients_arr[0]} rm -rf $DIR/$tdir
1178         nm_test_mkdir
1179         do_node ${clients_arr[0]} chown $user $DIR/$tdir
1180
1181         do_facet mgs $LCTL nodemap_modify --name c0 \
1182                 --property admin --value $admin
1183         do_facet mgs $LCTL nodemap_modify --name c0 \
1184                 --property trusted --value $trust
1185
1186         # flush MDT locks to make sure they are reacquired before test
1187         do_node ${clients_arr[0]} $LCTL set_param \
1188                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
1189
1190         wait_nm_sync c0 admin_nodemap
1191         wait_nm_sync c0 trusted_nodemap
1192 }
1193
1194 # fileset test directory needs to be initialized on a privileged client
1195 fileset_test_setup() {
1196         local nm=$1
1197
1198         if [ -n "$FILESET" -a -z "$SKIP_FILESET" ]; then
1199                 cleanup_mount $MOUNT
1200                 FILESET="" zconf_mount_clients $CLIENTS $MOUNT
1201         fi
1202
1203         local admin=$(do_facet mgs $LCTL get_param -n \
1204                 nodemap.${nm}.admin_nodemap)
1205         local trust=$(do_facet mgs $LCTL get_param -n \
1206                 nodemap.${nm}.trusted_nodemap)
1207
1208         do_facet mgs $LCTL nodemap_modify --name $nm --property admin --value 1
1209         do_facet mgs $LCTL nodemap_modify --name $nm --property trusted \
1210                 --value 1
1211
1212         wait_nm_sync $nm admin_nodemap
1213         wait_nm_sync $nm trusted_nodemap
1214
1215         # create directory and populate it for subdir mount
1216         do_node ${clients_arr[0]} mkdir $MOUNT/$subdir ||
1217                 error "unable to create dir $MOUNT/$subdir"
1218         do_node ${clients_arr[0]} touch $MOUNT/$subdir/this_is_$subdir ||
1219                 error "unable to create file $MOUNT/$subdir/this_is_$subdir"
1220         do_node ${clients_arr[0]} mkdir $MOUNT/$subdir/$subsubdir ||
1221                 error "unable to create dir $MOUNT/$subdir/$subsubdir"
1222         do_node ${clients_arr[0]} touch \
1223                         $MOUNT/$subdir/$subsubdir/this_is_$subsubdir ||
1224                 error "unable to create file \
1225                         $MOUNT/$subdir/$subsubdir/this_is_$subsubdir"
1226
1227         do_facet mgs $LCTL nodemap_modify --name $nm \
1228                 --property admin --value $admin
1229         do_facet mgs $LCTL nodemap_modify --name $nm \
1230                 --property trusted --value $trust
1231
1232         # flush MDT locks to make sure they are reacquired before test
1233         do_node ${clients_arr[0]} $LCTL set_param \
1234                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
1235
1236         wait_nm_sync $nm admin_nodemap
1237         wait_nm_sync $nm trusted_nodemap
1238 }
1239
1240 # fileset test directory needs to be initialized on a privileged client
1241 fileset_test_cleanup() {
1242         local nm=$1
1243         local admin=$(do_facet mgs $LCTL get_param -n \
1244                 nodemap.${nm}.admin_nodemap)
1245         local trust=$(do_facet mgs $LCTL get_param -n \
1246                 nodemap.${nm}.trusted_nodemap)
1247
1248         do_facet mgs $LCTL nodemap_modify --name $nm --property admin --value 1
1249         do_facet mgs $LCTL nodemap_modify --name $nm --property trusted \
1250                 --value 1
1251
1252         wait_nm_sync $nm admin_nodemap
1253         wait_nm_sync $nm trusted_nodemap
1254
1255         # cleanup directory created for subdir mount
1256         do_node ${clients_arr[0]} rm -rf $MOUNT/$subdir ||
1257                 error "unable to remove dir $MOUNT/$subdir"
1258
1259         do_facet mgs $LCTL nodemap_modify --name $nm \
1260                 --property admin --value $admin
1261         do_facet mgs $LCTL nodemap_modify --name $nm \
1262                 --property trusted --value $trust
1263
1264         # flush MDT locks to make sure they are reacquired before test
1265         do_node ${clients_arr[0]} $LCTL set_param \
1266                 ldlm.namespaces.$FSNAME-MDT*.lru_size=clear
1267
1268         wait_nm_sync $nm admin_nodemap
1269         wait_nm_sync $nm trusted_nodemap
1270         if [ -n "$FILESET" -a -z "$SKIP_FILESET" ]; then
1271                 cleanup_mount $MOUNT
1272                 zconf_mount_clients $CLIENTS $MOUNT
1273         fi
1274 }
1275
1276 do_create_delete() {
1277         local run_u=$1
1278         local key=$2
1279         local testfile=$DIR/$tdir/$tfile
1280         local rc=0
1281         local c=0 d=0
1282         local qused_new
1283         if $run_u touch $testfile >& /dev/null; then
1284                 c=1
1285                 $run_u rm $testfile && d=1
1286         fi >& /dev/null
1287
1288         local res="$c $d"
1289         local expected=$(get_cr_del_expected $key)
1290         [ "$res" != "$expected" ] &&
1291                 error "test $key, wanted $expected, got $res" && rc=$((rc + 1))
1292         return $rc
1293 }
1294
1295 nodemap_check_quota() {
1296         local run_u="$1"
1297         $run_u lfs quota -q $DIR | awk '{ print $2; exit; }'
1298 }
1299
1300 do_fops_quota_test() {
1301         local run_u=$1
1302         # fuzz quota used to account for possible indirect blocks, etc
1303         local quota_fuzz=$(fs_log_size)
1304         local qused_orig=$(nodemap_check_quota "$run_u")
1305         local qused_high=$((qused_orig + quota_fuzz))
1306         local qused_low=$((qused_orig - quota_fuzz))
1307         local testfile=$DIR/$tdir/$tfile
1308         $run_u dd if=/dev/zero of=$testfile oflag=sync bs=1M count=1 \
1309                 >& /dev/null || error "unable to write quota test file"
1310         sync; sync_all_data || true
1311
1312         local qused_new=$(nodemap_check_quota "$run_u")
1313         [ $((qused_new)) -lt $((qused_low + 1024)) -o \
1314           $((qused_new)) -gt $((qused_high + 1024)) ] &&
1315                 error "$qused_new != $qused_orig + 1M after write, " \
1316                       "fuzz is $quota_fuzz"
1317         $run_u rm $testfile || error "unable to remove quota test file"
1318         wait_delete_completed_mds
1319
1320         qused_new=$(nodemap_check_quota "$run_u")
1321         [ $((qused_new)) -lt $((qused_low)) \
1322                 -o $((qused_new)) -gt $((qused_high)) ] &&
1323                 error "quota not reclaimed, expect $qused_orig, " \
1324                       "got $qused_new, fuzz $quota_fuzz"
1325 }
1326
1327 get_fops_mapped_user() {
1328         local cli_user=$1
1329
1330         for ((i=0; i < ${#FOPS_IDMAPS[@]}; i++)); do
1331                 for map in ${FOPS_IDMAPS[i]}; do
1332                         if [ $(cut -d: -f1 <<< "$map") == $cli_user ]; then
1333                                 cut -d: -f2 <<< "$map"
1334                                 return
1335                         fi
1336                 done
1337         done
1338         echo -1
1339 }
1340
1341 get_cr_del_expected() {
1342         local -a key
1343         IFS=":" read -a key <<< "$1"
1344         local mapmode="${key[0]}"
1345         local mds_user="${key[1]}"
1346         local cluster="${key[2]}"
1347         local cli_user="${key[3]}"
1348         local mode="0${key[4]}"
1349         local SUCCESS="1 1"
1350         local FAILURE="0 0"
1351         local noadmin=0
1352         local mapped=0
1353         local other=0
1354
1355         [[ $mapmode == *mapped* ]] && mapped=1
1356         # only c1 is mapped in these test cases
1357         [[ $mapmode == mapped_trusted* ]] && [ "$cluster" == "c0" ] && mapped=0
1358         [[ $mapmode == *noadmin* ]] && noadmin=1
1359
1360         # o+wx works as long as the user isn't mapped
1361         if [ $((mode & 3)) -eq 3 ]; then
1362                 other=1
1363         fi
1364
1365         # if client user is root, check if root is squashed
1366         if [ "$cli_user" == "0" ]; then
1367                 # squash root succeed, if other bit is on
1368                 case $noadmin in
1369                         0) echo $SUCCESS;;
1370                         1) [ "$other" == "1" ] && echo $SUCCESS
1371                            [ "$other" == "0" ] && echo $FAILURE;;
1372                 esac
1373                 return
1374         fi
1375         if [ "$mapped" == "0" ]; then
1376                 [ "$other" == "1" ] && echo $SUCCESS
1377                 [ "$other" == "0" ] && echo $FAILURE
1378                 return
1379         fi
1380
1381         # if mapped user is mds user, check for u+wx
1382         mapped_user=$(get_fops_mapped_user $cli_user)
1383         [ "$mapped_user" == "-1" ] &&
1384                 error "unable to find mapping for client user $cli_user"
1385
1386         if [ "$mapped_user" == "$mds_user" -a \
1387              $(((mode & 0300) == 0300)) -eq 1 ]; then
1388                 echo $SUCCESS
1389                 return
1390         fi
1391         if [ "$mapped_user" != "$mds_user" -a "$other" == "1" ]; then
1392                 echo $SUCCESS
1393                 return
1394         fi
1395         echo $FAILURE
1396 }
1397
1398 test_fops_admin_cli_i=""
1399 test_fops_chmod_dir() {
1400         local current_cli_i=$1
1401         local perm_bits=$2
1402         local dir_to_chmod=$3
1403         local new_admin_cli_i=""
1404
1405         # do we need to set up a new admin client?
1406         [ "$current_cli_i" == "0" ] && [ "$test_fops_admin_cli_i" != "1" ] &&
1407                 new_admin_cli_i=1
1408         [ "$current_cli_i" != "0" ] && [ "$test_fops_admin_cli_i" != "0" ] &&
1409                 new_admin_cli_i=0
1410
1411         # if only one client, and non-admin, need to flip admin everytime
1412         if [ "$num_clients" == "1" ]; then
1413                 test_fops_admin_client=$clients
1414                 test_fops_admin_val=$(do_facet mgs $LCTL get_param -n \
1415                         nodemap.c0.admin_nodemap)
1416                 if [ "$test_fops_admin_val" != "1" ]; then
1417                         do_facet mgs $LCTL nodemap_modify \
1418                                 --name c0 \
1419                                 --property admin \
1420                                 --value 1
1421                         wait_nm_sync c0 admin_nodemap
1422                 fi
1423         elif [ "$new_admin_cli_i" != "" ]; then
1424                 # restore admin val to old admin client
1425                 if [ "$test_fops_admin_cli_i" != "" ] &&
1426                                 [ "$test_fops_admin_val" != "1" ]; then
1427                         do_facet mgs $LCTL nodemap_modify \
1428                                 --name c${test_fops_admin_cli_i} \
1429                                 --property admin \
1430                                 --value $test_fops_admin_val
1431                         wait_nm_sync c${test_fops_admin_cli_i} admin_nodemap
1432                 fi
1433
1434                 test_fops_admin_cli_i=$new_admin_cli_i
1435                 test_fops_admin_client=${clients_arr[$new_admin_cli_i]}
1436                 test_fops_admin_val=$(do_facet mgs $LCTL get_param -n \
1437                         nodemap.c${new_admin_cli_i}.admin_nodemap)
1438
1439                 if [ "$test_fops_admin_val" != "1" ]; then
1440                         do_facet mgs $LCTL nodemap_modify \
1441                                 --name c${new_admin_cli_i} \
1442                                 --property admin \
1443                                 --value 1
1444                         wait_nm_sync c${new_admin_cli_i} admin_nodemap
1445                 fi
1446         fi
1447
1448         do_node $test_fops_admin_client chmod $perm_bits $DIR/$tdir || return 1
1449
1450         # remove admin for single client if originally non-admin
1451         if [ "$num_clients" == "1" ] && [ "$test_fops_admin_val" != "1" ]; then
1452                 do_facet mgs $LCTL nodemap_modify --name c0 --property admin \
1453                         --value 0
1454                 wait_nm_sync c0 admin_nodemap
1455         fi
1456
1457         return 0
1458 }
1459
1460 test_fops() {
1461         local mapmode="$1"
1462         local single_client="$2"
1463         local client_user_list=([0]="0 $((IDBASE+3))"
1464                                 [1]="0 $((IDBASE+5))")
1465         local mds_users="-1 0"
1466         local mds_i
1467         local rc=0
1468         local perm_bit_list="3 $((0300))"
1469         # SLOW tests 000-007, 010-070, 100-700 (octal modes)
1470         if [ "$SLOW" == "yes" ]; then
1471                 perm_bit_list="0 $(seq 1 7) $(seq 8 8 63) $(seq 64 64 511) \
1472                                $((0303))"
1473                 client_user_list=([0]="0 $((IDBASE+3)) $((IDBASE+4))"
1474                                   [1]="0 $((IDBASE+5)) $((IDBASE+6))")
1475                 mds_users="-1 0 1 2"
1476         fi
1477
1478         # force single_client to speed up test
1479         [ "$SLOW" == "yes" ] ||
1480                 single_client=1
1481         # step through mds users. -1 means root
1482         for mds_i in $mds_users; do
1483                 local user=$((mds_i + IDBASE))
1484                 local client
1485                 local x
1486
1487                 [ "$mds_i" == "-1" ] && user=0
1488
1489                 echo mkdir -p $DIR/$tdir
1490                 fops_test_setup
1491                 local cli_i=0
1492                 for client in $clients; do
1493                         local u
1494                         for u in ${client_user_list[$cli_i]}; do
1495                                 local run_u="do_node $client \
1496                                              $RUNAS_CMD -u$u -g$u -G$u"
1497                                 for perm_bits in $perm_bit_list; do
1498                                         local mode=$(printf %03o $perm_bits)
1499                                         local key
1500                                         key="$mapmode:$user:c$cli_i:$u:$mode"
1501                                         test_fops_chmod_dir $cli_i $mode \
1502                                                 $DIR/$tdir ||
1503                                                         error cannot chmod $key
1504                                         do_create_delete "$run_u" "$key"
1505                                 done
1506
1507                                 # check quota
1508                                 test_fops_chmod_dir $cli_i 777 $DIR/$tdir ||
1509                                         error cannot chmod $key
1510                                 do_fops_quota_test "$run_u"
1511                         done
1512
1513                         cli_i=$((cli_i + 1))
1514                         [ "$single_client" == "1" ] && break
1515                 done
1516                 rm -rf $DIR/$tdir
1517         done
1518         return $rc
1519 }
1520
1521 nodemap_version_check () {
1522         remote_mgs_nodsh && skip "remote MGS with nodsh" && return 1
1523         [ "$MGS_VERSION" -lt $(version_code 2.5.53) ] &&
1524                 skip "No nodemap on $MGS_VERSION MGS < 2.5.53" &&
1525                 return 1
1526         return 0
1527 }
1528
1529 nodemap_test_setup() {
1530         local rc
1531         local active_nodemap=1
1532
1533         [ "$1" == "0" ] && active_nodemap=0
1534
1535         do_nodes $(comma_list $(all_mdts_nodes)) \
1536                 $LCTL set_param mdt.*.identity_upcall=NONE
1537
1538         rc=0
1539         create_fops_nodemaps
1540         rc=$?
1541         [[ $rc != 0 ]] && error "adding fops nodemaps failed $rc"
1542
1543         do_facet mgs $LCTL nodemap_activate $active_nodemap
1544         wait_nm_sync active
1545
1546         do_facet mgs $LCTL nodemap_modify --name default \
1547                 --property admin --value 1
1548         wait_nm_sync default admin_nodemap
1549         do_facet mgs $LCTL nodemap_modify --name default \
1550                 --property trusted --value 1
1551         wait_nm_sync default trusted_nodemap
1552 }
1553
1554 nodemap_test_cleanup() {
1555         trap 0
1556         delete_fops_nodemaps
1557         rc=$?
1558         [[ $rc != 0 ]] && error "removing fops nodemaps failed $rc"
1559
1560         do_facet mgs $LCTL nodemap_modify --name default \
1561                  --property admin --value 0
1562         wait_nm_sync default admin_nodemap
1563         do_facet mgs $LCTL nodemap_modify --name default \
1564                  --property trusted --value 0
1565         wait_nm_sync default trusted_nodemap
1566
1567         do_facet mgs $LCTL nodemap_activate 0
1568         wait_nm_sync active 0
1569
1570         export SK_UNIQUE_NM=false
1571         return 0
1572 }
1573
1574 nodemap_clients_admin_trusted() {
1575         local admin=$1
1576         local tr=$2
1577         local i=0
1578         for client in $clients; do
1579                 do_facet mgs $LCTL nodemap_modify --name c0 \
1580                         --property admin --value $admin
1581                 do_facet mgs $LCTL nodemap_modify --name c0 \
1582                         --property trusted --value $tr
1583                 i=$((i + 1))
1584         done
1585         wait_nm_sync c$((i - 1)) admin_nodemap
1586         wait_nm_sync c$((i - 1)) trusted_nodemap
1587 }
1588
1589 test_16() {
1590         nodemap_version_check || return 0
1591         nodemap_test_setup 0
1592
1593         trap nodemap_test_cleanup EXIT
1594         test_fops all_off
1595         nodemap_test_cleanup
1596 }
1597 run_test 16 "test nodemap all_off fileops"
1598
1599 test_17() {
1600         if $SHARED_KEY &&
1601         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1602                 skip "Need MDS >= 2.11.55"
1603         fi
1604         local check_proj=true
1605
1606         (( $MDS1_VERSION >= $(version_code 2.14.52) )) || check_proj=false
1607
1608         nodemap_version_check || return 0
1609         nodemap_test_setup
1610
1611         trap nodemap_test_cleanup EXIT
1612         nodemap_clients_admin_trusted 0 1
1613         test_fops trusted_noadmin 1
1614         if $check_proj; then
1615                 do_facet mgs $LCTL nodemap_modify --name c0 \
1616                         --property map_mode --value projid
1617                 wait_nm_sync c0 map_mode
1618         fi
1619         test_fops trusted_noadmin 1
1620         nodemap_test_cleanup
1621 }
1622 run_test 17 "test nodemap trusted_noadmin fileops"
1623
1624 test_18() {
1625         if $SHARED_KEY &&
1626         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1627                 skip "Need MDS >= 2.11.55"
1628         fi
1629
1630         nodemap_version_check || return 0
1631         nodemap_test_setup
1632
1633         trap nodemap_test_cleanup EXIT
1634         nodemap_clients_admin_trusted 0 0
1635         test_fops mapped_noadmin 1
1636         nodemap_test_cleanup
1637 }
1638 run_test 18 "test nodemap mapped_noadmin fileops"
1639
1640 test_19() {
1641         if $SHARED_KEY &&
1642         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1643                 skip "Need MDS >= 2.11.55"
1644         fi
1645
1646         nodemap_version_check || return 0
1647         nodemap_test_setup
1648
1649         trap nodemap_test_cleanup EXIT
1650         nodemap_clients_admin_trusted 1 1
1651         test_fops trusted_admin 1
1652         nodemap_test_cleanup
1653 }
1654 run_test 19 "test nodemap trusted_admin fileops"
1655
1656 test_20() {
1657         if $SHARED_KEY &&
1658         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1659                 skip "Need MDS >= 2.11.55"
1660         fi
1661
1662         nodemap_version_check || return 0
1663         nodemap_test_setup
1664
1665         trap nodemap_test_cleanup EXIT
1666         nodemap_clients_admin_trusted 1 0
1667         test_fops mapped_admin 1
1668         nodemap_test_cleanup
1669 }
1670 run_test 20 "test nodemap mapped_admin fileops"
1671
1672 test_21() {
1673         if $SHARED_KEY &&
1674         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1675                 skip "Need MDS >= 2.11.55"
1676         fi
1677
1678         nodemap_version_check || return 0
1679         nodemap_test_setup
1680
1681         trap nodemap_test_cleanup EXIT
1682         local x=1
1683         local i=0
1684         for client in $clients; do
1685                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1686                         --property admin --value 0
1687                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1688                         --property trusted --value $x
1689                 x=0
1690                 i=$((i + 1))
1691         done
1692         wait_nm_sync c$((i - 1)) trusted_nodemap
1693
1694         test_fops mapped_trusted_noadmin
1695         nodemap_test_cleanup
1696 }
1697 run_test 21 "test nodemap mapped_trusted_noadmin fileops"
1698
1699 test_22() {
1700         if $SHARED_KEY &&
1701         [ "$MDS1_VERSION" -lt $(version_code 2.11.55) ]; then
1702                 skip "Need MDS >= 2.11.55"
1703         fi
1704
1705         nodemap_version_check || return 0
1706         nodemap_test_setup
1707
1708         trap nodemap_test_cleanup EXIT
1709         local x=1
1710         local i=0
1711         for client in $clients; do
1712                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1713                         --property admin --value 1
1714                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1715                         --property trusted --value $x
1716                 x=0
1717                 i=$((i + 1))
1718         done
1719         wait_nm_sync c$((i - 1)) trusted_nodemap
1720
1721         test_fops mapped_trusted_admin
1722         nodemap_test_cleanup
1723 }
1724 run_test 22 "test nodemap mapped_trusted_admin fileops"
1725
1726 # acl test directory needs to be initialized on a privileged client
1727 nodemap_acl_test_setup() {
1728         local admin=$(do_facet mgs $LCTL get_param -n \
1729                       nodemap.c0.admin_nodemap)
1730         local trust=$(do_facet mgs $LCTL get_param -n \
1731                       nodemap.c0.trusted_nodemap)
1732
1733         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1734         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1735
1736         wait_nm_sync c0 admin_nodemap
1737         wait_nm_sync c0 trusted_nodemap
1738
1739         do_node ${clients_arr[0]} rm -rf $DIR/$tdir
1740         nm_test_mkdir
1741         do_node ${clients_arr[0]} chmod a+rwx $DIR/$tdir ||
1742                 error unable to chmod a+rwx test dir $DIR/$tdir
1743
1744         do_facet mgs $LCTL nodemap_modify --name c0 \
1745                 --property admin --value $admin
1746         do_facet mgs $LCTL nodemap_modify --name c0 \
1747                 --property trusted --value $trust
1748
1749         wait_nm_sync c0 trusted_nodemap
1750 }
1751
1752 # returns 0 if the number of ACLs does not change on the second (mapped) client
1753 # after being set on the first client
1754 nodemap_acl_test() {
1755         local user="$1"
1756         local set_client="$2"
1757         local get_client="$3"
1758         local check_setfacl="$4"
1759         local setfacl_error=0
1760         local testfile=$DIR/$tdir/$tfile
1761         local RUNAS_USER="$RUNAS_CMD -u $user"
1762         local acl_count=0
1763         local acl_count_post=0
1764
1765         nodemap_acl_test_setup
1766         sleep 5
1767
1768         do_node $set_client $RUNAS_USER touch $testfile
1769         # remove from cache, otherwise ACLs will not be fetched from server
1770         do_rpc_nodes $set_client cancel_lru_locks
1771         do_node $set_client "sync ; echo 3 > /proc/sys/vm/drop_caches"
1772
1773         # ACL masks aren't filtered by nodemap code, so we ignore them
1774         acl_count=$(do_node $get_client getfacl $testfile | grep -v mask |
1775                 wc -l)
1776         # remove from cache, otherwise ACLs will not be fetched from server
1777         do_rpc_nodes $get_client cancel_lru_locks
1778         do_node $get_client "sync ; echo 3 > /proc/sys/vm/drop_caches"
1779         do_node $set_client $RUNAS_USER setfacl -m $user:rwx $testfile ||
1780                 setfacl_error=1
1781         # remove from cache, otherwise ACLs will not be fetched from server
1782         do_rpc_nodes $set_client cancel_lru_locks
1783         do_node $set_client "sync ; echo 3 > /proc/sys/vm/drop_caches"
1784
1785         # if check setfacl is set to 1, then it's supposed to error
1786         if [ "$check_setfacl" == "1" ]; then
1787                 [ "$setfacl_error" != "1" ] && return 1
1788                 return 0
1789         fi
1790         [ "$setfacl_error" == "1" ] && echo "WARNING: unable to setfacl"
1791
1792         acl_count_post=$(do_node $get_client getfacl $testfile | grep -v mask |
1793                 wc -l)
1794         # remove from cache, otherwise ACLs will not be fetched from server
1795         do_rpc_nodes $get_client cancel_lru_locks
1796         do_node $get_client "sync ; echo 3 > /proc/sys/vm/drop_caches"
1797         [ $acl_count -eq $acl_count_post ] && return 0
1798         return 1
1799 }
1800
1801 test_23a() {
1802         [ $num_clients -lt 2 ] && skip "Need 2 clients at least" && return
1803         nodemap_version_check || return 0
1804         nodemap_test_setup
1805
1806         trap nodemap_test_cleanup EXIT
1807         # 1 trusted cluster, 1 mapped cluster
1808         local unmapped_fs=$((IDBASE+0))
1809         local unmapped_c1=$((IDBASE+5))
1810         local mapped_fs=$((IDBASE+2))
1811         local mapped_c0=$((IDBASE+4))
1812         local mapped_c1=$((IDBASE+6))
1813
1814         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1815         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 1
1816
1817         do_facet mgs $LCTL nodemap_modify --name c1 --property admin --value 0
1818         do_facet mgs $LCTL nodemap_modify --name c1 --property trusted --value 0
1819
1820         wait_nm_sync c1 trusted_nodemap
1821
1822         # setfacl on trusted cluster to unmapped user, verify it's not seen
1823         nodemap_acl_test $unmapped_fs ${clients_arr[0]} ${clients_arr[1]} ||
1824                 error "acl count (1)"
1825
1826         # setfacl on trusted cluster to mapped user, verify it's seen
1827         nodemap_acl_test $mapped_fs ${clients_arr[0]} ${clients_arr[1]} &&
1828                 error "acl count (2)"
1829
1830         # setfacl on mapped cluster to mapped user, verify it's seen
1831         nodemap_acl_test $mapped_c1 ${clients_arr[1]} ${clients_arr[0]} &&
1832                 error "acl count (3)"
1833
1834         # setfacl on mapped cluster to unmapped user, verify error
1835         nodemap_acl_test $unmapped_fs ${clients_arr[1]} ${clients_arr[0]} 1 ||
1836                 error "acl count (4)"
1837
1838         # 2 mapped clusters
1839         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 0
1840         do_facet mgs $LCTL nodemap_modify --name c0 --property trusted --value 0
1841
1842         wait_nm_sync c0 trusted_nodemap
1843
1844         # setfacl to mapped user on c1, also mapped to c0, verify it's seen
1845         nodemap_acl_test $mapped_c1 ${clients_arr[1]} ${clients_arr[0]} &&
1846                 error "acl count (5)"
1847
1848         # setfacl to mapped user on c1, not mapped to c0, verify not seen
1849         nodemap_acl_test $unmapped_c1 ${clients_arr[1]} ${clients_arr[0]} ||
1850                 error "acl count (6)"
1851
1852         nodemap_test_cleanup
1853 }
1854 run_test 23a "test mapped regular ACLs"
1855
1856 test_23b() { #LU-9929
1857         [ $num_clients -lt 2 ] && skip "Need 2 clients at least"
1858         [ "$MGS_VERSION" -lt $(version_code 2.10.53) ] &&
1859                 skip "Need MGS >= 2.10.53"
1860
1861         export SK_UNIQUE_NM=true
1862         nodemap_test_setup
1863         trap nodemap_test_cleanup EXIT
1864
1865         local testdir=$DIR/$tdir
1866         local fs_id=$((IDBASE+10))
1867         local unmapped_id
1868         local mapped_id
1869         local fs_user
1870
1871         do_facet mgs $LCTL nodemap_modify --name c0 --property admin --value 1
1872         wait_nm_sync c0 admin_nodemap
1873         do_facet mgs $LCTL nodemap_modify --name c1 --property admin --value 1
1874         wait_nm_sync c1 admin_nodemap
1875         do_facet mgs $LCTL nodemap_modify --name c1 --property trusted --value 1
1876         wait_nm_sync c1 trusted_nodemap
1877
1878         # Add idmap $ID0:$fs_id (500:60010)
1879         do_facet mgs $LCTL nodemap_add_idmap --name c0 --idtype gid \
1880                 --idmap $ID0:$fs_id ||
1881                 error "add idmap $ID0:$fs_id to nodemap c0 failed"
1882         wait_nm_sync c0 idmap
1883
1884         # set/getfacl default acl on client 1 (unmapped gid=500)
1885         do_node ${clients_arr[0]} rm -rf $testdir
1886         do_node ${clients_arr[0]} mkdir -p $testdir
1887         # Here, USER0=$(getent passwd | grep :$ID0:$ID0: | cut -d: -f1)
1888         do_node ${clients_arr[0]} setfacl -R -d -m group:$USER0:rwx $testdir ||
1889                 error "setfacl $testdir on ${clients_arr[0]} failed"
1890         unmapped_id=$(do_node ${clients_arr[0]} getfacl $testdir |
1891                         grep -E "default:group:.*:rwx" | awk -F: '{print $3}')
1892         [ "$unmapped_id" = "$USER0" ] ||
1893                 error "gid=$ID0 was not unmapped correctly on ${clients_arr[0]}"
1894
1895         # getfacl default acl on client 2 (mapped gid=60010)
1896         mapped_id=$(do_node ${clients_arr[1]} getfacl $testdir |
1897                         grep -E "default:group:.*:rwx" | awk -F: '{print $3}')
1898         fs_user=$(do_node ${clients_arr[1]} getent passwd |
1899                         grep :$fs_id:$fs_id: | cut -d: -f1)
1900         [ -z "$fs_user" ] && fs_user=$fs_id
1901         [ $mapped_id -eq $fs_id -o "$mapped_id" = "$fs_user" ] ||
1902                 error "Should return gid=$fs_id or $fs_user on client2"
1903
1904         rm -rf $testdir
1905         nodemap_test_cleanup
1906         export SK_UNIQUE_NM=false
1907 }
1908 run_test 23b "test mapped default ACLs"
1909
1910 test_24() {
1911         nodemap_test_setup
1912
1913         trap nodemap_test_cleanup EXIT
1914         do_nodes $(comma_list $(all_server_nodes)) $LCTL get_param -R nodemap
1915
1916         nodemap_test_cleanup
1917 }
1918 run_test 24 "check nodemap proc files for LBUGs and Oopses"
1919
1920 test_25() {
1921         local tmpfile=$(mktemp)
1922         local tmpfile2=$(mktemp)
1923         local tmpfile3=$(mktemp)
1924         local tmpfile4=$(mktemp)
1925         local subdir=c0dir
1926         local client
1927
1928         nodemap_version_check || return 0
1929
1930         # stop clients for this test
1931         zconf_umount_clients $CLIENTS $MOUNT ||
1932             error "unable to umount clients $CLIENTS"
1933
1934         export SK_UNIQUE_NM=true
1935         nodemap_test_setup
1936
1937         # enable trusted/admin for setquota call in cleanup_and_setup_lustre()
1938         i=0
1939         for client in $clients; do
1940                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1941                         --property admin --value 1
1942                 do_facet mgs $LCTL nodemap_modify --name c${i} \
1943                         --property trusted --value 1
1944                 ((i++))
1945         done
1946         wait_nm_sync c$((i - 1)) trusted_nodemap
1947
1948         trap nodemap_test_cleanup EXIT
1949
1950         # create a new, empty nodemap, and add fileset info to it
1951         do_facet mgs $LCTL nodemap_add test25 ||
1952                 error "unable to create nodemap $testname"
1953         do_facet mgs $LCTL set_param -P nodemap.$testname.fileset=/$subdir ||
1954                 error "unable to add fileset info to nodemap test25"
1955
1956         wait_nm_sync test25 id
1957
1958         do_facet mgs $LCTL nodemap_info > $tmpfile
1959         do_facet mds $LCTL nodemap_info > $tmpfile2
1960
1961         if ! $SHARED_KEY; then
1962                 # will conflict with SK's nodemaps
1963                 cleanup_and_setup_lustre
1964         fi
1965         # stop clients for this test
1966         zconf_umount_clients $CLIENTS $MOUNT ||
1967             error "unable to umount clients $CLIENTS"
1968
1969         do_facet mgs $LCTL nodemap_info > $tmpfile3
1970         diff -q $tmpfile3 $tmpfile >& /dev/null ||
1971                 error "nodemap_info diff on MGS after remount"
1972
1973         do_facet mds $LCTL nodemap_info > $tmpfile4
1974         diff -q $tmpfile4 $tmpfile2 >& /dev/null ||
1975                 error "nodemap_info diff on MDS after remount"
1976
1977         # cleanup nodemap
1978         do_facet mgs $LCTL nodemap_del test25 ||
1979             error "cannot delete nodemap test25 from config"
1980         nodemap_test_cleanup
1981         # restart clients previously stopped
1982         zconf_mount_clients $CLIENTS $MOUNT ||
1983             error "unable to mount clients $CLIENTS"
1984
1985         rm -f $tmpfile $tmpfile2
1986         export SK_UNIQUE_NM=false
1987 }
1988 run_test 25 "test save and reload nodemap config"
1989
1990 test_26() {
1991         nodemap_version_check || return 0
1992
1993         local large_i=32000
1994
1995         do_facet mgs "seq -f 'c%g' $large_i | xargs -n1 $LCTL nodemap_add"
1996         wait_nm_sync c$large_i admin_nodemap
1997
1998         do_facet mgs "seq -f 'c%g' $large_i | xargs -n1 $LCTL nodemap_del"
1999         wait_nm_sync c$large_i admin_nodemap
2000 }
2001 run_test 26 "test transferring very large nodemap"
2002
2003 nodemap_exercise_fileset() {
2004         local nm="$1"
2005         local loop=0
2006         local check_proj=true
2007
2008         (( $MDS1_VERSION >= $(version_code 2.14.52) )) || check_proj=false
2009
2010         # setup
2011         if [ "$nm" == "default" ]; then
2012                 do_facet mgs $LCTL nodemap_activate 1
2013                 wait_nm_sync active
2014                 do_facet mgs $LCTL nodemap_modify --name default \
2015                         --property admin --value 1
2016                 do_facet mgs $LCTL nodemap_modify --name default \
2017                         --property trusted --value 1
2018                 wait_nm_sync default admin_nodemap
2019                 wait_nm_sync default trusted_nodemap
2020                 check_proj=false
2021         else
2022                 nodemap_test_setup
2023         fi
2024         if $SHARED_KEY; then
2025                 export SK_UNIQUE_NM=true
2026         else
2027                 # will conflict with SK's nodemaps
2028                 trap "fileset_test_cleanup $nm" EXIT
2029         fi
2030         fileset_test_setup "$nm"
2031
2032         # add fileset info to $nm nodemap
2033         if ! combined_mgs_mds; then
2034             do_facet mgs $LCTL set_param nodemap.${nm}.fileset=/$subdir ||
2035                 error "unable to add fileset info to $nm nodemap on MGS"
2036         fi
2037         do_facet mgs $LCTL set_param -P nodemap.${nm}.fileset=/$subdir ||
2038                error "unable to add fileset info to $nm nodemap for servers"
2039         wait_nm_sync $nm fileset "nodemap.${nm}.fileset=/$subdir"
2040
2041         if $check_proj; then
2042                 do_facet mgs $LCTL nodemap_modify --name $nm \
2043                          --property admin --value 1
2044                 wait_nm_sync $nm admin_nodemap
2045                 do_facet mgs $LCTL nodemap_modify --name $nm \
2046                          --property trusted --value 0
2047                 wait_nm_sync $nm trusted_nodemap
2048                 do_facet mgs $LCTL nodemap_modify --name $nm \
2049                          --property map_mode --value projid
2050                 wait_nm_sync $nm map_mode
2051                 do_facet mgs $LCTL nodemap_add_idmap --name $nm \
2052                          --idtype projid --idmap 1:1
2053                 do_facet mgs $LCTL nodemap_modify --name $nm \
2054                          --property deny_unknown --value 1
2055                 wait_nm_sync $nm deny_unknown
2056         fi
2057
2058         # re-mount client
2059         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2060                 error "unable to umount client ${clients_arr[0]}"
2061         # set some generic fileset to trigger SSK code
2062         export FILESET=/
2063         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2064                 error "unable to remount client ${clients_arr[0]}"
2065         unset FILESET
2066
2067         # test mount point content
2068         do_node ${clients_arr[0]} test -f $MOUNT/this_is_$subdir ||
2069                 error "fileset not taken into account"
2070
2071         if $check_proj; then
2072                 do_node ${clients_arr[0]} $LFS setquota -p 1 -b 10000 -B 11000 \
2073                         -i 0 -I 0 $MOUNT || error "setquota -p 1 failed"
2074                 do_node ${clients_arr[0]} $LFS setquota -p 2 -b 10000 -B 11000 \
2075                         -i 0 -I 0 $MOUNT && error "setquota -p 2 should fail"
2076         fi
2077
2078         # re-mount client with sub-subdir
2079         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2080                 error "unable to umount client ${clients_arr[0]}"
2081         export FILESET=/$subsubdir
2082         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2083                 error "unable to remount client ${clients_arr[0]}"
2084         unset FILESET
2085
2086         # test mount point content
2087         do_node ${clients_arr[0]} test -f $MOUNT/this_is_$subsubdir ||
2088                 error "subdir of fileset not taken into account"
2089
2090         # remove fileset info from nodemap
2091         do_facet mgs $LCTL nodemap_set_fileset --name $nm --fileset clear ||
2092                 error "unable to delete fileset info on $nm nodemap"
2093         wait_update_facet mgs "$LCTL get_param nodemap.${nm}.fileset" \
2094                           "nodemap.${nm}.fileset=" ||
2095                 error "fileset info still not cleared on $nm nodemap"
2096         do_facet mgs $LCTL set_param -P nodemap.${nm}.fileset=clear ||
2097                 error "unable to reset fileset info on $nm nodemap"
2098         wait_nm_sync $nm fileset "nodemap.${nm}.fileset="
2099         do_facet mgs $LCTL set_param -P -d nodemap.${nm}.fileset ||
2100                 error "unable to remove fileset rule on $nm nodemap"
2101
2102         # re-mount client
2103         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2104                 error "unable to umount client ${clients_arr[0]}"
2105         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2106                 error "unable to remount client ${clients_arr[0]}"
2107
2108         # test mount point content
2109         if ! $(do_node ${clients_arr[0]} test -d $MOUNT/$subdir); then
2110                 ls $MOUNT
2111                 error "fileset not cleared on $nm nodemap"
2112         fi
2113
2114         # back to non-nodemap setup
2115         if $SHARED_KEY; then
2116                 export SK_UNIQUE_NM=false
2117                 zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2118                         error "unable to umount client ${clients_arr[0]}"
2119         fi
2120         fileset_test_cleanup "$nm"
2121         if [ "$nm" == "default" ]; then
2122                 do_facet mgs $LCTL nodemap_modify --name default \
2123                          --property admin --value 0
2124                 do_facet mgs $LCTL nodemap_modify --name default \
2125                          --property trusted --value 0
2126                 wait_nm_sync default admin_nodemap
2127                 wait_nm_sync default trusted_nodemap
2128                 do_facet mgs $LCTL nodemap_activate 0
2129                 wait_nm_sync active 0
2130                 trap 0
2131                 export SK_UNIQUE_NM=false
2132         else
2133                 nodemap_test_cleanup
2134         fi
2135         if $SHARED_KEY; then
2136                 zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2137                         error "unable to remount client ${clients_arr[0]}"
2138         fi
2139 }
2140
2141 test_27a() {
2142         [ "$MDS1_VERSION" -lt $(version_code 2.11.50) ] &&
2143                 skip "Need MDS >= 2.11.50"
2144
2145         # if servers run on the same node, it is impossible to tell if they get
2146         # synced with the mgs, so this test needs to be skipped
2147         if [ $(facet_active_host mgs) == $(facet_active_host mds) ] &&
2148            [ $(facet_active_host mgs) == $(facet_active_host ost1) ]; then
2149                 skip "local mode not supported"
2150         fi
2151
2152         for nm in "default" "c0"; do
2153                 local subdir="subdir_${nm}"
2154                 local subsubdir="subsubdir_${nm}"
2155
2156                 if [ "$nm" == "default" ] && [ "$SHARED_KEY" == "true" ]; then
2157                         echo "Skipping nodemap $nm with SHARED_KEY";
2158                         continue;
2159                 fi
2160
2161                 echo "Exercising fileset for nodemap $nm"
2162                 nodemap_exercise_fileset "$nm"
2163         done
2164 }
2165 run_test 27a "test fileset in various nodemaps"
2166
2167 test_27b() { #LU-10703
2168         [ "$MDS1_VERSION" -lt $(version_code 2.11.50) ] &&
2169                 skip "Need MDS >= 2.11.50"
2170         [[ $MDSCOUNT -lt 2 ]] && skip "needs >= 2 MDTs"
2171
2172         # if servers run on the same node, it is impossible to tell if they get
2173         # synced with the mgs, so this test needs to be skipped
2174         if [ $(facet_active_host mgs) == $(facet_active_host mds) ] &&
2175            [ $(facet_active_host mgs) == $(facet_active_host ost1) ]; then
2176                 skip "local mode not supported"
2177         fi
2178
2179         nodemap_test_setup
2180         trap nodemap_test_cleanup EXIT
2181
2182         # Add the nodemaps and set their filesets
2183         for i in $(seq 1 $MDSCOUNT); do
2184                 do_facet mgs $LCTL nodemap_del nm$i 2>/dev/null
2185                 do_facet mgs $LCTL nodemap_add nm$i ||
2186                         error "add nodemap nm$i failed"
2187                 wait_nm_sync nm$i "" "" "-N"
2188
2189                 if ! combined_mgs_mds; then
2190                         do_facet mgs \
2191                                 $LCTL set_param nodemap.nm$i.fileset=/dir$i ||
2192                                 error "set nm$i.fileset=/dir$i failed on MGS"
2193                 fi
2194                 do_facet mgs $LCTL set_param -P nodemap.nm$i.fileset=/dir$i ||
2195                         error "set nm$i.fileset=/dir$i failed on servers"
2196                 wait_nm_sync nm$i fileset "nodemap.nm$i.fileset=/dir$i"
2197         done
2198
2199         # Check if all the filesets are correct
2200         for i in $(seq 1 $MDSCOUNT); do
2201                 fileset=$(do_facet mds$i \
2202                           $LCTL get_param -n nodemap.nm$i.fileset)
2203                 [ "$fileset" = "/dir$i" ] ||
2204                         error "nm$i.fileset $fileset != /dir$i on mds$i"
2205                 do_facet mgs $LCTL set_param -P -d nodemap.nm$i.fileset ||
2206                         error "unable to remove fileset rule for nm$i nodemap"
2207                 do_facet mgs $LCTL nodemap_del nm$i ||
2208                         error "delete nodemap nm$i failed"
2209         done
2210
2211         nodemap_test_cleanup
2212 }
2213 run_test 27b "The new nodemap won't clear the old nodemap's fileset"
2214
2215 test_28() {
2216         if ! $SHARED_KEY; then
2217                 skip "need shared key feature for this test" && return
2218         fi
2219         mkdir -p $DIR/$tdir || error "mkdir failed"
2220         touch $DIR/$tdir/$tdir.out || error "touch failed"
2221         if [ ! -f $DIR/$tdir/$tdir.out ]; then
2222                 error "read before rotation failed"
2223         fi
2224         # store top key identity to ensure rotation has occurred
2225         SK_IDENTITY_OLD=$(lctl get_param *.*.*srpc* 2>/dev/null | grep "expire"|
2226                 head -1 | awk '{print $15}' | cut -c1-8)
2227         do_facet $SINGLEMDS lfs flushctx ||
2228                  error "could not run flushctx on $SINGLEMDS"
2229         sleep 5
2230         lfs flushctx || error "could not run flushctx on client"
2231         sleep 5
2232         # verify new key is in place
2233         SK_IDENTITY_NEW=$(lctl get_param *.*.*srpc* 2>/dev/null | grep "expire"|
2234                 head -1 | awk '{print $15}' | cut -c1-8)
2235         if [ $SK_IDENTITY_OLD == $SK_IDENTITY_NEW ]; then
2236                 error "key did not rotate correctly"
2237         fi
2238         if [ ! -f $DIR/$tdir/$tdir.out ]; then
2239                 error "read after rotation failed"
2240         fi
2241 }
2242 run_test 28 "check shared key rotation method"
2243
2244 test_29() {
2245         if ! $SHARED_KEY; then
2246                 skip "need shared key feature for this test" && return
2247         fi
2248         if [ $SK_FLAVOR != "ski" ] && [ $SK_FLAVOR != "skpi" ]; then
2249                 skip "test only valid if integrity is active"
2250         fi
2251         rm -r $DIR/$tdir
2252         mkdir $DIR/$tdir || error "mkdir"
2253         touch $DIR/$tdir/$tfile || error "touch"
2254         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2255                 error "unable to umount clients"
2256         do_node ${clients_arr[0]} "keyctl show |
2257                 awk '/lustre/ { print \\\$1 }' | xargs -IX keyctl unlink X"
2258         OLD_SK_PATH=$SK_PATH
2259         export SK_PATH=/dev/null
2260         if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
2261                 export SK_PATH=$OLD_SK_PATH
2262                 do_node ${clients_arr[0]} "ls $DIR/$tdir/$tfile"
2263                 if [ $? -eq 0 ]; then
2264                         error "able to mount and read without key"
2265                 else
2266                         error "able to mount without key"
2267                 fi
2268         else
2269                 export SK_PATH=$OLD_SK_PATH
2270                 do_node ${clients_arr[0]} "keyctl show |
2271                         awk '/lustre/ { print \\\$1 }' |
2272                         xargs -IX keyctl unlink X"
2273         fi
2274         zconf_mount_clients ${clients_arr[0]} $MOUNT ||
2275                 error "unable to mount clients"
2276 }
2277 run_test 29 "check for missing shared key"
2278
2279 test_30() {
2280         if ! $SHARED_KEY; then
2281                 skip "need shared key feature for this test" && return
2282         fi
2283         if [ $SK_FLAVOR != "ski" ] && [ $SK_FLAVOR != "skpi" ]; then
2284                 skip "test only valid if integrity is active"
2285         fi
2286         mkdir -p $DIR/$tdir || error "mkdir failed"
2287         touch $DIR/$tdir/$tdir.out || error "touch failed"
2288         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2289                 error "unable to umount clients"
2290         # unload keys from ring
2291         do_node ${clients_arr[0]} "keyctl show |
2292                 awk '/lustre/ { print \\\$1 }' | xargs -IX keyctl unlink X"
2293         # generate key with bogus filesystem name
2294         do_node ${clients_arr[0]} "$LGSS_SK -w $SK_PATH/$FSNAME-bogus.key \
2295                 -f $FSNAME.bogus -t client -d /dev/urandom" ||
2296                 error "lgss_sk failed (1)"
2297         do_facet $SINGLEMDS lfs flushctx || error "could not run flushctx"
2298         OLD_SK_PATH=$SK_PATH
2299         export SK_PATH=$SK_PATH/$FSNAME-bogus.key
2300         if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
2301                 SK_PATH=$OLD_SK_PATH
2302                 do_node ${clients_arr[0]} "ls $DIR/$tdir/$tdir.out"
2303                 if [ $? -eq 0 ]; then
2304                         error "mount and read file with invalid key"
2305                 else
2306                         error "mount with invalid key"
2307                 fi
2308         fi
2309         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2310                 error "unable to umount clients"
2311         # unload keys from ring
2312         do_node ${clients_arr[0]} "keyctl show |
2313                 awk '/lustre/ { print \\\$1 }' | xargs -IX keyctl unlink X"
2314         rm -f $SK_PATH
2315         SK_PATH=$OLD_SK_PATH
2316         zconf_mount_clients ${clients_arr[0]} $MOUNT ||
2317                 error "unable to mount clients"
2318 }
2319 run_test 30 "check for invalid shared key"
2320
2321 basic_ios() {
2322         local flvr=$1
2323
2324         mkdir -p $DIR/$tdir || error "mkdir $flvr"
2325         touch $DIR/$tdir/f0 || error "touch $flvr"
2326         ls $DIR/$tdir || error "ls $flvr"
2327         dd if=/dev/zero of=$DIR/$tdir/f0 conv=fsync bs=1M count=10 \
2328                 >& /dev/null || error "dd $flvr"
2329         rm -f $DIR/$tdir/f0 || error "rm $flvr"
2330         rmdir $DIR/$tdir || error "rmdir $flvr"
2331
2332         sync ; sync
2333         echo 3 > /proc/sys/vm/drop_caches
2334 }
2335
2336 test_30b() {
2337         local save_flvr=$SK_FLAVOR
2338
2339         if ! $SHARED_KEY; then
2340                 skip "need shared key feature for this test"
2341         fi
2342
2343         stack_trap restore_to_default_flavor EXIT
2344
2345         for flvr in skn ska ski skpi; do
2346                 # set flavor
2347                 SK_FLAVOR=$flvr
2348                 restore_to_default_flavor || error "cannot set $flvr flavor"
2349                 SK_FLAVOR=$save_flvr
2350
2351                 basic_ios $flvr
2352         done
2353 }
2354 run_test 30b "basic test of all different SSK flavors"
2355
2356 cleanup_31() {
2357         local failover_mds1=$1
2358
2359         # unmount client
2360         zconf_umount $HOSTNAME $MOUNT || error "unable to umount client"
2361
2362         # remove ${NETTYPE}999 network on all nodes
2363         do_nodes $(comma_list $(all_nodes)) \
2364                  "$LNETCTL net del --net ${NETTYPE}999 && \
2365                   $LNETCTL lnet unconfigure 2>/dev/null || true"
2366
2367         # necessary to do writeconf in order to de-register
2368         # @${NETTYPE}999 nid for targets
2369         KZPOOL=$KEEP_ZPOOL
2370         export KEEP_ZPOOL="true"
2371         stopall
2372
2373         do_facet mds1 $TUNEFS --erase-param failover.node $(mdsdevname 1)
2374         if [ -n "$failover_mds1" ]; then
2375                 do_facet mds1 $TUNEFS \
2376                         --servicenode=$failover_mds1 $(mdsdevname 1)
2377         else
2378                 # If no service node previously existed, setting one in test_31
2379                 # added the no_primnode flag to the target. To remove everything
2380                 # and clear the flag, add a meaningless failnode and remove it.
2381                 do_facet mds1 $TUNEFS \
2382                         --failnode=$(do_facet mds1 $LCTL list_nids | head -1) \
2383                         $(mdsdevname 1)
2384                 do_facet mds1 $TUNEFS \
2385                         --erase-param failover.node $(mdsdevname 1)
2386         fi
2387
2388         export SK_MOUNTED=false
2389         writeconf_all
2390         setupall || echo 1
2391         export KEEP_ZPOOL="$KZPOOL"
2392 }
2393
2394 test_31() {
2395         local nid=$(lctl list_nids | grep ${NETTYPE} | head -n1)
2396         local addr=${nid%@*}
2397         local net=${nid#*@}
2398         local net2=${NETTYPE}999
2399         local mdsnid=$(do_facet mds1 $LCTL list_nids | head -1)
2400         local addr1=${mdsnid%@*}
2401         local addr2=${addr1%.*}.$(((${addr1##*.} + 11) % 256))
2402         local failover_mds1
2403
2404         export LNETCTL=$(which lnetctl 2> /dev/null)
2405
2406         [ -z "$LNETCTL" ] && skip "without lnetctl support." && return
2407         local_mode && skip "in local mode."
2408
2409         if $SHARED_KEY; then
2410                 skip "Conflicting test with SSK"
2411         fi
2412
2413         # save mds failover nids for restore at cleanup
2414         failover_mds1=$(do_facet mds1 $TUNEFS --dryrun $(mdsdevname 1))
2415         if [ -n "$failover_mds1" ]; then
2416                 failover_mds1=${failover_mds1##*Parameters:}
2417                 failover_mds1=${failover_mds1%%exiting*}
2418                 failover_mds1=$(echo $failover_mds1 | tr ' ' '\n' |
2419                                 grep failover.node | cut -d'=' -f2-)
2420         fi
2421         stack_trap "cleanup_31 $failover_mds1" EXIT
2422
2423         # umount client
2424         if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
2425                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
2426         fi
2427         if $(grep -q $MOUNT' ' /proc/mounts); then
2428                 umount_client $MOUNT || error "umount $MOUNT failed"
2429         fi
2430
2431         # check exports on servers are empty for client
2432         do_facet mgs "lctl get_param -n *.MGS*.exports.'$nid'.uuid 2>/dev/null |
2433                       grep -q -" && error "export on MGS should be empty"
2434         do_nodes $(comma_list $(mdts_nodes) $(osts_nodes)) \
2435                  "lctl get_param -n *.${FSNAME}*.exports.'$nid'.uuid \
2436                   2>/dev/null | grep -q -" &&
2437                 error "export on servers should be empty"
2438
2439         # add network $net2 on all nodes
2440         do_nodes $(comma_list $(all_nodes)) \
2441                  "$LNETCTL lnet configure && $LNETCTL net add --if \
2442                   \$($LNETCTL net show --net $net | awk 'BEGIN{inf=0} \
2443                   {if (inf==1) print \$2; fi; inf=0} /interfaces/{inf=1}') \
2444                   --net $net2" ||
2445                 error "unable to configure NID $net2"
2446
2447         # necessary to do writeconf in order to register
2448         # new @$net2 nid for targets
2449         KZPOOL=$KEEP_ZPOOL
2450         export KEEP_ZPOOL="true"
2451         stopall
2452         export SK_MOUNTED=false
2453         writeconf_all
2454
2455         nids="${addr1}@$net,${addr1}@$net2:${addr2}@$net,${addr2}@$net2"
2456         do_facet mds1 "$TUNEFS --servicenode="$nids" $(mdsdevname 1)" ||
2457                 error "tunefs failed"
2458
2459         setupall server_only || echo 1
2460         export KEEP_ZPOOL="$KZPOOL"
2461
2462         # backup MGSNID
2463         local mgsnid_orig=$MGSNID
2464         # compute new MGSNID
2465         MGSNID=$(do_facet mgs "$LCTL list_nids | grep $net2")
2466
2467         # on client, turn LNet Dynamic Discovery on
2468         lnetctl set discovery 1
2469
2470         # mount client with -o network=$net2 option:
2471         # should fail because of LNet Dynamic Discovery
2472         mount_client $MOUNT ${MOUNT_OPTS},network=$net2 &&
2473                 error "client mount with '-o network' option should be refused"
2474
2475         # on client, reconfigure LNet and turn LNet Dynamic Discovery off
2476         $LNETCTL net del --net $net2 && lnetctl lnet unconfigure
2477         lustre_rmmod
2478         modprobe lnet
2479         lnetctl set discovery 0
2480         modprobe ptlrpc
2481         $LNETCTL lnet configure && $LNETCTL net add --if \
2482           $($LNETCTL net show --net $net | awk 'BEGIN{inf=0} \
2483           {if (inf==1) print $2; fi; inf=0} /interfaces/{inf=1}') \
2484           --net $net2 ||
2485                 error "unable to configure NID $net2 on client"
2486
2487         # mount client with -o network=$net2 option
2488         mount_client $MOUNT ${MOUNT_OPTS},network=$net2 ||
2489                 error "unable to remount client"
2490
2491         # restore MGSNID
2492         MGSNID=$mgsnid_orig
2493
2494         # check export on MGS
2495         do_facet mgs "lctl get_param -n *.MGS*.exports.'$nid'.uuid 2>/dev/null |
2496                       grep -"
2497         [ $? -ne 0 ] || error "export for $nid on MGS should not exist"
2498
2499         do_facet mgs \
2500                 "lctl get_param -n *.MGS*.exports.'${addr}@$net2'.uuid \
2501                  2>/dev/null | grep -"
2502         [ $? -eq 0 ] ||
2503                 error "export for ${addr}@$net2 on MGS should exist"
2504
2505         # check {mdc,osc} imports
2506         lctl get_param mdc.${FSNAME}-*.import | grep current_connection |
2507             grep $net2
2508         [ $? -eq 0 ] ||
2509                 error "import for mdc should use ${addr1}@$net2"
2510         lctl get_param osc.${FSNAME}-*.import | grep current_connection |
2511             grep $net2
2512         [ $? -eq 0 ] ||
2513                 error "import for osc should use ${addr1}@$net2"
2514
2515         # no NIDs on other networks should be listed
2516         lctl get_param mdc.${FSNAME}-*.import | grep failover_nids |
2517             grep -w ".*@$net" &&
2518                 error "MDC import shouldn't have failnids at @$net"
2519
2520         # failover NIDs on net999 should be listed
2521         lctl get_param mdc.${FSNAME}-*.import | grep failover_nids |
2522             grep ${addr2}@$net2 ||
2523                 error "MDC import should have failnid ${addr2}@$net2"
2524 }
2525 run_test 31 "client mount option '-o network'"
2526
2527 cleanup_32() {
2528         # umount client
2529         zconf_umount_clients ${clients_arr[0]} $MOUNT
2530
2531         # disable sk flavor enforcement on MGS
2532         set_rule _mgs any any null
2533
2534         # stop gss daemon on MGS
2535         send_sigint $mgs_HOST lsvcgssd
2536
2537         # re-start gss daemon on MDS if necessary
2538         if combined_mgs_mds ; then
2539                 start_gss_daemons $mds_HOST $LSVCGSSD "-vvv -s -m -o -z"
2540         fi
2541
2542         # re-mount client
2543         MOUNT_OPTS=$(add_sk_mntflag $MOUNT_OPTS)
2544         mountcli
2545
2546         restore_to_default_flavor
2547 }
2548
2549 test_32() {
2550         if ! $SHARED_KEY; then
2551                 skip "need shared key feature for this test"
2552         fi
2553
2554         stack_trap cleanup_32 EXIT
2555
2556         # restore to default null flavor
2557         save_flvr=$SK_FLAVOR
2558         SK_FLAVOR=null
2559         restore_to_default_flavor || error "cannot set null flavor"
2560         SK_FLAVOR=$save_flvr
2561
2562         # umount client
2563         if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
2564                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
2565         fi
2566         if $(grep -q $MOUNT' ' /proc/mounts); then
2567         umount_client $MOUNT || error "umount $MOUNT failed"
2568         fi
2569
2570         # kill daemon on MGS to start afresh
2571         send_sigint $mgs_HOST lsvcgssd
2572
2573         # start gss daemon on MGS
2574         if combined_mgs_mds ; then
2575                 start_gss_daemons $mgs_HOST $LSVCGSSD "-vvv -s -g -m -o -z"
2576         else
2577                 start_gss_daemons $mgs_HOST $LSVCGSSD "-vvv -s -g"
2578         fi
2579
2580         # add mgs key type and MGS NIDs in key on MGS
2581         do_nodes $mgs_HOST "$LGSS_SK -t mgs,server -g $MGSNID -m \
2582                                 $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2583                 error "could not modify keyfile on MGS"
2584
2585         # load modified key file on MGS
2586         do_nodes $mgs_HOST "$LGSS_SK -l $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2587                 error "could not load keyfile on MGS"
2588
2589         # add MGS NIDs in key on client
2590         do_nodes ${clients_arr[0]} "$LGSS_SK -g $MGSNID -m \
2591                                 $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2592                 error "could not modify keyfile on MGS"
2593
2594         # set perms for per-nodemap keys else permission denied
2595         do_nodes $(comma_list $(all_nodes)) \
2596                  "keyctl show | grep lustre | cut -c1-11 |
2597                                 sed -e 's/ //g;' |
2598                                 xargs -IX keyctl setperm X 0x3f3f3f3f"
2599
2600         # re-mount client with mgssec=skn
2601         save_opts=$MOUNT_OPTS
2602         if [ -z "$MOUNT_OPTS" ]; then
2603                 MOUNT_OPTS="-o mgssec=skn"
2604         else
2605                 MOUNT_OPTS="$MOUNT_OPTS,mgssec=skn"
2606         fi
2607         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2608                 error "mount ${clients_arr[0]} with mgssec=skn failed"
2609         MOUNT_OPTS=$save_opts
2610
2611         # umount client
2612         zconf_umount_clients ${clients_arr[0]} $MOUNT ||
2613                 error "umount ${clients_arr[0]} failed"
2614
2615         # enforce ska flavor on MGS
2616         set_rule _mgs any any ska
2617
2618         # re-mount client without mgssec
2619         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS &&
2620                 error "mount ${clients_arr[0]} without mgssec should fail"
2621
2622         # re-mount client with mgssec=skn
2623         save_opts=$MOUNT_OPTS
2624         if [ -z "$MOUNT_OPTS" ]; then
2625                 MOUNT_OPTS="-o mgssec=skn"
2626         else
2627                 MOUNT_OPTS="$MOUNT_OPTS,mgssec=skn"
2628         fi
2629         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS &&
2630                 error "mount ${clients_arr[0]} with mgssec=skn should fail"
2631         MOUNT_OPTS=$save_opts
2632
2633         # re-mount client with mgssec=ska
2634         save_opts=$MOUNT_OPTS
2635         if [ -z "$MOUNT_OPTS" ]; then
2636                 MOUNT_OPTS="-o mgssec=ska"
2637         else
2638                 MOUNT_OPTS="$MOUNT_OPTS,mgssec=ska"
2639         fi
2640         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2641                 error "mount ${clients_arr[0]} with mgssec=ska failed"
2642         MOUNT_OPTS=$save_opts
2643
2644         exit 0
2645 }
2646 run_test 32 "check for mgssec"
2647
2648 cleanup_33() {
2649         # disable sk flavor enforcement
2650         set_rule $FSNAME any cli2mdt null
2651         wait_flavor cli2mdt null
2652
2653         # umount client
2654         zconf_umount_clients ${clients_arr[0]} $MOUNT
2655
2656         # stop gss daemon on MGS
2657         send_sigint $mgs_HOST lsvcgssd
2658
2659         # re-start gss daemon on MDS if necessary
2660         if combined_mgs_mds ; then
2661                 start_gss_daemons $mds_HOST $LSVCGSSD "-vvv -s -m -o -z"
2662         fi
2663
2664         # re-mount client
2665         MOUNT_OPTS=$(add_sk_mntflag $MOUNT_OPTS)
2666         mountcli
2667
2668         restore_to_default_flavor
2669 }
2670
2671 test_33() {
2672         if ! $SHARED_KEY; then
2673                 skip "need shared key feature for this test"
2674         fi
2675
2676         stack_trap cleanup_33 EXIT
2677
2678         # restore to default null flavor
2679         save_flvr=$SK_FLAVOR
2680         SK_FLAVOR=null
2681         restore_to_default_flavor || error "cannot set null flavor"
2682         SK_FLAVOR=$save_flvr
2683
2684         # umount client
2685         if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
2686                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
2687         fi
2688         if $(grep -q $MOUNT' ' /proc/mounts); then
2689         umount_client $MOUNT || error "umount $MOUNT failed"
2690         fi
2691
2692         # kill daemon on MGS to start afresh
2693         send_sigint $mgs_HOST lsvcgssd
2694
2695         # start gss daemon on MGS
2696         if combined_mgs_mds ; then
2697                 start_gss_daemons $mgs_HOST $LSVCGSSD "-vvv -s -g -m -o -z"
2698         else
2699                 start_gss_daemons $mgs_HOST $LSVCGSSD "-vvv -s -g"
2700         fi
2701
2702         # add mgs key type and MGS NIDs in key on MGS
2703         do_nodes $mgs_HOST "$LGSS_SK -t mgs,server -g $MGSNID -m \
2704                                 $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2705                 error "could not modify keyfile on MGS"
2706
2707         # load modified key file on MGS
2708         do_nodes $mgs_HOST "$LGSS_SK -l $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2709                 error "could not load keyfile on MGS"
2710
2711         # add MGS NIDs in key on client
2712         do_nodes ${clients_arr[0]} "$LGSS_SK -g $MGSNID -m \
2713                                 $SK_PATH/$FSNAME.key >/dev/null 2>&1" ||
2714                 error "could not modify keyfile on MGS"
2715
2716         # set perms for per-nodemap keys else permission denied
2717         do_nodes $(comma_list $(all_nodes)) \
2718                  "keyctl show | grep lustre | cut -c1-11 |
2719                                 sed -e 's/ //g;' |
2720                                 xargs -IX keyctl setperm X 0x3f3f3f3f"
2721
2722         # re-mount client with mgssec=skn
2723         save_opts=$MOUNT_OPTS
2724         if [ -z "$MOUNT_OPTS" ]; then
2725                 MOUNT_OPTS="-o mgssec=skn"
2726         else
2727                 MOUNT_OPTS="$MOUNT_OPTS,mgssec=skn"
2728         fi
2729         zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
2730                 error "mount ${clients_arr[0]} with mgssec=skn failed"
2731         MOUNT_OPTS=$save_opts
2732
2733         # enforce ska flavor for cli2mdt
2734         set_rule $FSNAME any cli2mdt ska
2735         wait_flavor cli2mdt ska
2736
2737         # check error message
2738         $LCTL dk | grep "faked source" &&
2739                 error "MGS connection srpc flags incorrect"
2740
2741         exit 0
2742 }
2743 run_test 33 "correct srpc flags for MGS connection"
2744
2745 cleanup_34_deny() {
2746         # restore deny_unknown
2747         do_facet mgs $LCTL nodemap_modify --name default \
2748                            --property deny_unknown --value $denydefault
2749         if [ $? -ne 0 ]; then
2750                 error_noexit "cannot reset deny_unknown on default nodemap"
2751                 return
2752         fi
2753
2754         wait_nm_sync default deny_unknown
2755 }
2756
2757 test_34() {
2758         local denynew
2759         local activedefault
2760
2761         [ $MGS_VERSION -lt $(version_code 2.12.51) ] &&
2762                 skip "deny_unknown on default nm not supported before 2.12.51"
2763
2764         activedefault=$(do_facet mgs $LCTL get_param -n nodemap.active)
2765
2766         if [[ "$activedefault" != "1" ]]; then
2767                 do_facet mgs $LCTL nodemap_activate 1
2768                 wait_nm_sync active
2769                 stack_trap cleanup_active EXIT
2770         fi
2771
2772         denydefault=$(do_facet mgs $LCTL get_param -n \
2773                       nodemap.default.deny_unknown)
2774         [ -z "$denydefault" ] &&
2775                 error "cannot get deny_unknown on default nodemap"
2776         if [ "$denydefault" -eq 0 ]; then
2777                 denynew=1;
2778         else
2779                 denynew=0;
2780         fi
2781
2782         do_facet mgs $LCTL nodemap_modify --name default \
2783                         --property deny_unknown --value $denynew ||
2784                 error "cannot set deny_unknown on default nodemap"
2785
2786         [ "$(do_facet mgs $LCTL get_param -n nodemap.default.deny_unknown)" \
2787                         -eq $denynew ] ||
2788                 error "setting deny_unknown on default nodemap did not work"
2789
2790         stack_trap cleanup_34_deny EXIT
2791
2792         wait_nm_sync default deny_unknown
2793 }
2794 run_test 34 "deny_unknown on default nodemap"
2795
2796 test_35() {
2797         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
2798                 skip "Need MDS >= 2.13.50"
2799
2800         # activate changelogs
2801         changelog_register || error "changelog_register failed"
2802         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
2803         changelog_users $SINGLEMDS | grep -q $cl_user ||
2804                 error "User $cl_user not found in changelog_users"
2805         changelog_chmask ALL
2806
2807         # do some IOs
2808         mkdir $DIR/$tdir || error "failed to mkdir $tdir"
2809         touch $DIR/$tdir/$tfile || error "failed to touch $tfile"
2810
2811         # access changelogs with root
2812         changelog_dump || error "failed to dump changelogs"
2813         changelog_clear 0 || error "failed to clear changelogs"
2814
2815         # put clients in non-admin nodemap
2816         nodemap_test_setup
2817         stack_trap nodemap_test_cleanup EXIT
2818         for i in $(seq 0 $((num_clients-1))); do
2819                 do_facet mgs $LCTL nodemap_modify --name c${i} \
2820                          --property admin --value 0
2821         done
2822         for i in $(seq 0 $((num_clients-1))); do
2823                 wait_nm_sync c${i} admin_nodemap
2824         done
2825
2826         # access with mapped root
2827         changelog_dump && error "dump changelogs should have failed"
2828         changelog_clear 0 && error "clear changelogs should have failed"
2829
2830         exit 0
2831 }
2832 run_test 35 "Check permissions when accessing changelogs"
2833
2834 setup_dummy_key() {
2835         local mode='\x00\x00\x00\x00'
2836         local raw="$(printf ""\\\\x%02x"" {0..63})"
2837         local size
2838         local key
2839
2840         [[ $(lscpu) =~ Byte\ Order.*Little ]] && size='\x40\x00\x00\x00' ||
2841                 size='\x00\x00\x00\x40'
2842         key="${mode}${raw}${size}"
2843         echo -n -e "${key}" | keyctl padd logon fscrypt:4242424242424242 @s
2844 }
2845
2846 insert_enc_key() {
2847         cancel_lru_locks
2848         sync ; echo 3 > /proc/sys/vm/drop_caches
2849         setup_dummy_key
2850 }
2851
2852 remove_enc_key() {
2853         local dummy_key
2854
2855         $LCTL set_param -n ldlm.namespaces.*.lru_size=clear
2856         sync ; echo 3 > /proc/sys/vm/drop_caches
2857         dummy_key=$(keyctl show | awk '$7 ~ "^fscrypt:" {print $1}')
2858         if [ -n "$dummy_key" ]; then
2859                 keyctl revoke $dummy_key
2860                 keyctl reap
2861         fi
2862 }
2863
2864 wait_ssk() {
2865         # wait for SSK flavor to be applied if necessary
2866         if $GSS_SK; then
2867                 if $SK_S2S; then
2868                         wait_flavor all2all $SK_FLAVOR
2869                 else
2870                         wait_flavor cli2mdt $SK_FLAVOR
2871                         wait_flavor cli2ost $SK_FLAVOR
2872                 fi
2873         fi
2874 }
2875
2876 remount_client_normally() {
2877         # remount client without dummy encryption key
2878         if is_mounted $MOUNT; then
2879                 umount_client $MOUNT || error "umount $MOUNT failed"
2880         fi
2881         mount_client $MOUNT ${MOUNT_OPTS} ||
2882                 error "remount failed"
2883
2884         if is_mounted $MOUNT2; then
2885                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
2886         fi
2887         if [ "$MOUNT_2" ]; then
2888                 mount_client $MOUNT2 ${MOUNT_OPTS} ||
2889                         error "remount failed"
2890         fi
2891
2892         remove_enc_key
2893         wait_ssk
2894 }
2895
2896 remount_client_dummykey() {
2897         insert_enc_key
2898
2899         # remount client with dummy encryption key
2900         if is_mounted $MOUNT; then
2901                 umount_client $MOUNT || error "umount $MOUNT failed"
2902         fi
2903         mount_client $MOUNT ${MOUNT_OPTS},test_dummy_encryption ||
2904                 error "remount failed"
2905
2906         wait_ssk
2907 }
2908
2909 setup_for_enc_tests() {
2910         # remount client with test_dummy_encryption option
2911         if is_mounted $MOUNT; then
2912                 umount_client $MOUNT || error "umount $MOUNT failed"
2913         fi
2914         mount_client $MOUNT ${MOUNT_OPTS},test_dummy_encryption ||
2915                 error "mount with '-o test_dummy_encryption' failed"
2916
2917         wait_ssk
2918
2919         # this directory will be encrypted, because of dummy mode
2920         mkdir $DIR/$tdir
2921 }
2922
2923 cleanup_for_enc_tests() {
2924         rm -rf $DIR/$tdir $*
2925
2926         remount_client_normally
2927 }
2928
2929 cleanup_nodemap_after_enc_tests() {
2930         umount_client $MOUNT || true
2931
2932         if (( MGS_VERSION >= $(version_code 2.13.55) )); then
2933                 do_facet mgs $LCTL nodemap_modify --name default \
2934                         --property forbid_encryption --value 0
2935                 if (( MGS_VERSION >= $(version_code 2.15.51) )); then
2936                         do_facet mgs $LCTL nodemap_modify --name default \
2937                                 --property readonly_mount --value 0
2938                 fi
2939         fi
2940         do_facet mgs $LCTL nodemap_modify --name default \
2941                 --property trusted --value 0
2942         do_facet mgs $LCTL nodemap_modify --name default \
2943                 --property admin --value 0
2944         do_facet mgs $LCTL nodemap_activate 0
2945
2946         if (( MGS_VERSION >= $(version_code 2.13.55) )); then
2947                 wait_nm_sync default forbid_encryption '' inactive
2948                 if (( MGS_VERSION >= $(version_code 2.15.51) )); then
2949                         wait_nm_sync default readonly_mount '' inactive
2950                 fi
2951         fi
2952         wait_nm_sync default trusted_nodemap '' inactive
2953         wait_nm_sync default admin_nodemap '' inactive
2954         wait_nm_sync active
2955
2956         mount_client $MOUNT ${MOUNT_OPTS} || error "re-mount failed"
2957         wait_ssk
2958 }
2959
2960 test_36() {
2961         $LCTL get_param mdc.*.import | grep -q client_encryption ||
2962                 skip "client encryption not supported"
2963
2964         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
2965                 skip "need dummy encryption support"
2966
2967         stack_trap cleanup_for_enc_tests EXIT
2968
2969         # first make sure it is possible to enable encryption
2970         # when nodemap is not active
2971         setup_for_enc_tests
2972         rmdir $DIR/$tdir
2973         umount_client $MOUNT || error "umount $MOUNT failed (1)"
2974
2975         # then activate nodemap, and retry
2976         # should succeed as encryption is not forbidden on default nodemap
2977         # by default
2978         stack_trap cleanup_nodemap_after_enc_tests EXIT
2979         do_facet mgs $LCTL nodemap_activate 1
2980         wait_nm_sync active
2981         forbid=$(do_facet mgs lctl get_param -n nodemap.default.forbid_encryption)
2982         [ $forbid -eq 0 ] || error "wrong default value for forbid_encryption"
2983         mount_client $MOUNT ${MOUNT_OPTS},test_dummy_encryption ||
2984                 error "mount '-o test_dummy_encryption' failed with default"
2985         umount_client $MOUNT || error "umount $MOUNT failed (2)"
2986
2987         # then forbid encryption, and retry
2988         do_facet mgs $LCTL nodemap_modify --name default \
2989                 --property forbid_encryption --value 1
2990         wait_nm_sync default forbid_encryption
2991         mount_client $MOUNT ${MOUNT_OPTS},test_dummy_encryption &&
2992                 error "mount '-o test_dummy_encryption' should have failed"
2993         return 0
2994 }
2995 run_test 36 "control if clients can use encryption"
2996
2997 test_37() {
2998         local testfile=$DIR/$tdir/$tfile
2999         local tmpfile=$TMP/abc
3000         local objdump=$TMP/objdump
3001
3002         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3003                 skip "client encryption not supported"
3004
3005         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3006                 skip "need dummy encryption support"
3007
3008         [ "$ost1_FSTYPE" = ldiskfs ] || skip "ldiskfs only test (using debugfs)"
3009
3010         stack_trap cleanup_for_enc_tests EXIT
3011         setup_for_enc_tests
3012
3013         # write a few bytes in file
3014         echo "abc" > $tmpfile
3015         $LFS setstripe -c1 -i0 $testfile
3016         dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync
3017         do_facet ost1 "sync; sync"
3018
3019         # check that content on ost is encrypted
3020         local fid=($($LFS getstripe $testfile | grep 0x))
3021         local seq=${fid[3]#0x}
3022         local oid=${fid[1]}
3023         local oid_hex
3024
3025         if [ $seq == 0 ]; then
3026                 oid_hex=${fid[1]}
3027         else
3028                 oid_hex=${fid[2]#0x}
3029         fi
3030         do_facet ost1 "$DEBUGFS -c -R 'cat O/$seq/d$(($oid % 32))/$oid_hex' \
3031                  $(ostdevname 1)" > $objdump
3032         cmp -s $objdump $tmpfile &&
3033                 error "file $testfile is not encrypted on ost"
3034
3035         # check that in-memory representation of file is correct
3036         cmp -bl ${tmpfile} ${testfile} ||
3037                 error "file $testfile is corrupted in memory"
3038
3039         cancel_lru_locks osc ; cancel_lru_locks mdc
3040
3041         # check that file read from server is correct
3042         cmp -bl ${tmpfile} ${testfile} ||
3043                 error "file $testfile is corrupted on server"
3044
3045         rm -f $tmpfile $objdump
3046 }
3047 run_test 37 "simple encrypted file"
3048
3049 test_38() {
3050         local testfile=$DIR/$tdir/$tfile
3051         local tmpfile=$TMP/abc
3052         local blksz
3053         local filesz
3054         local bsize
3055         local pagesz=$(getconf PAGE_SIZE)
3056
3057         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3058                 skip "client encryption not supported"
3059
3060         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3061                 skip "need dummy encryption support"
3062
3063         stack_trap cleanup_for_enc_tests EXIT
3064         setup_for_enc_tests
3065
3066         # get block size on ost
3067         blksz=$($LCTL get_param osc.$FSNAME*.import |
3068                 awk '/grant_block_size:/ { print $2; exit; }')
3069         # write a few bytes in file at offset $blksz
3070         echo "abc" > $tmpfile
3071         $LFS setstripe -c1 -i0 $testfile
3072         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$blksz \
3073                 oflag=seek_bytes conv=fsync
3074
3075         blksz=$(($blksz > $pagesz ? $blksz : $pagesz))
3076         # check that in-memory representation of file is correct
3077         bsize=$(stat --format=%B $testfile)
3078         filesz=$(stat --format=%b $testfile)
3079         filesz=$((filesz*bsize))
3080         [ $filesz -le $blksz ] ||
3081                 error "file $testfile is $filesz long in memory"
3082
3083         cancel_lru_locks osc ; cancel_lru_locks mdc
3084
3085         # check that file read from server is correct
3086         bsize=$(stat --format=%B $testfile)
3087         filesz=$(stat --format=%b $testfile)
3088         filesz=$((filesz*bsize))
3089         [ $filesz -le $blksz ] ||
3090                 error "file $testfile is $filesz long on server"
3091
3092         rm -f $tmpfile
3093 }
3094 run_test 38 "encrypted file with hole"
3095
3096 test_39() {
3097         local testfile=$DIR/$tdir/$tfile
3098         local tmpfile=$TMP/abc
3099
3100         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3101                 skip "client encryption not supported"
3102
3103         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3104                 skip "need dummy encryption support"
3105
3106         stack_trap cleanup_for_enc_tests EXIT
3107         setup_for_enc_tests
3108
3109         # write a few bytes in file
3110         echo "abc" > $tmpfile
3111         $LFS setstripe -c1 -i0 $testfile
3112         dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync
3113
3114         # write a few more bytes in the same page
3115         dd if=$tmpfile of=$testfile bs=4 count=1 seek=1024 oflag=seek_bytes \
3116                 conv=fsync,notrunc
3117
3118         dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=1024 oflag=seek_bytes \
3119                 conv=fsync,notrunc
3120
3121         # check that in-memory representation of file is correct
3122         cmp -bl $tmpfile $testfile ||
3123                 error "file $testfile is corrupted in memory"
3124
3125         cancel_lru_locks osc ; cancel_lru_locks mdc
3126
3127         # check that file read from server is correct
3128         cmp -bl $tmpfile $testfile ||
3129                 error "file $testfile is corrupted on server"
3130
3131         rm -f $tmpfile
3132 }
3133 run_test 39 "rewrite data in already encrypted page"
3134
3135 test_40() {
3136         local testfile=$DIR/$tdir/$tfile
3137         local tmpfile=$TMP/abc
3138         local tmpfile2=$TMP/abc2
3139         local seek
3140         local filesz
3141         #define LUSTRE_ENCRYPTION_UNIT_SIZE   (1 << 12)
3142         local UNIT_SIZE=$((1 << 12))
3143         local scrambledfile
3144
3145         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3146                 skip "client encryption not supported"
3147
3148         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3149                 skip "need dummy encryption support"
3150
3151         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
3152
3153         stack_trap cleanup_for_enc_tests EXIT
3154         setup_for_enc_tests
3155
3156         # write a few bytes in file
3157         echo "abc" > $tmpfile
3158         $LFS setstripe -c1 -i0 $testfile
3159         dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync
3160
3161         # check that in-memory representation of file is correct
3162         cmp -bl $tmpfile $testfile ||
3163                 error "file $testfile is corrupted in memory (1)"
3164
3165         cancel_lru_locks osc ; cancel_lru_locks mdc
3166
3167         # check that file read from server is correct
3168         cmp -bl $tmpfile $testfile ||
3169                 error "file $testfile is corrupted on server (1)"
3170
3171         # write a few other bytes in same page
3172         dd if=$tmpfile of=$testfile bs=4 count=1 seek=256 oflag=seek_bytes \
3173                 conv=fsync,notrunc
3174
3175         dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=256 oflag=seek_bytes \
3176                 conv=fsync,notrunc
3177
3178         # check that in-memory representation of file is correct
3179         cmp -bl $tmpfile $testfile ||
3180                 error "file $testfile is corrupted in memory (2)"
3181
3182         cancel_lru_locks osc ; cancel_lru_locks mdc
3183
3184         # check that file read from server is correct
3185         cmp -bl $tmpfile $testfile ||
3186                 error "file $testfile is corrupted on server (2)"
3187
3188         rm -f $testfile $tmpfile
3189         cancel_lru_locks osc ; cancel_lru_locks mdc
3190
3191         # write a few bytes in file, at end of first page
3192         echo "abc" > $tmpfile
3193         $LFS setstripe -c1 -i0 $testfile
3194         seek=$(getconf PAGESIZE)
3195         seek=$((seek - 4))
3196         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3197                 conv=fsync,notrunc
3198
3199         # write a few other bytes at beginning of first page
3200         dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync,notrunc
3201
3202         dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3203                 conv=fsync,notrunc
3204
3205         # check that in-memory representation of file is correct
3206         cmp -bl $tmpfile $testfile ||
3207                 error "file $testfile is corrupted in memory (3)"
3208
3209         cancel_lru_locks osc ; cancel_lru_locks mdc
3210
3211         # check that file read from server is correct
3212         cmp -bl $tmpfile $testfile ||
3213                 error "file $testfile is corrupted on server (3)"
3214
3215         rm -f $testfile $tmpfile
3216         cancel_lru_locks osc ; cancel_lru_locks mdc
3217
3218         # write a few bytes in file, at beginning of second page
3219         echo "abc" > $tmpfile
3220         $LFS setstripe -c1 -i0 $testfile
3221         seek=$(getconf PAGESIZE)
3222         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3223                 conv=fsync,notrunc
3224         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3225                 conv=fsync,notrunc
3226
3227         # write a few other bytes at end of first page
3228         seek=$((seek - 4))
3229         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3230                 conv=fsync,notrunc
3231         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3232                 conv=fsync,notrunc
3233
3234         # check that in-memory representation of file is correct
3235         cmp -bl $tmpfile2 $testfile ||
3236                 error "file $testfile is corrupted in memory (4)"
3237
3238         cancel_lru_locks osc ; cancel_lru_locks mdc
3239
3240         # check that file read from server is correct
3241         cmp -bl $tmpfile2 $testfile ||
3242                 error "file $testfile is corrupted on server (4)"
3243
3244         rm -f $testfile $tmpfile $tmpfile2
3245         cancel_lru_locks osc ; cancel_lru_locks mdc
3246
3247         # write a few bytes in file, at beginning of first stripe
3248         echo "abc" > $tmpfile
3249         $LFS setstripe -S 256k -c2 $testfile
3250         dd if=$tmpfile of=$testfile bs=4 count=1 conv=fsync,notrunc
3251
3252         # write a few other bytes, at beginning of second stripe
3253         dd if=$tmpfile of=$testfile bs=4 count=1 seek=262144 oflag=seek_bytes \
3254                 conv=fsync,notrunc
3255         dd if=$tmpfile of=$tmpfile bs=4 count=1 seek=262144 oflag=seek_bytes \
3256                 conv=fsync,notrunc
3257
3258         # check that in-memory representation of file is correct
3259         cmp -bl $tmpfile $testfile ||
3260                 error "file $testfile is corrupted in memory (5)"
3261
3262         cancel_lru_locks osc ; cancel_lru_locks mdc
3263
3264         # check that file read from server is correct
3265         cmp -bl $tmpfile $testfile ||
3266                 error "file $testfile is corrupted on server (5)"
3267
3268         filesz=$(stat --format=%s $testfile)
3269         filesz=$(((filesz+UNIT_SIZE-1)/UNIT_SIZE * UNIT_SIZE))
3270
3271         # remount without dummy encryption key
3272         remount_client_normally
3273
3274         scrambledfile=$(find $DIR/$tdir/ -maxdepth 1 -mindepth 1 -type f)
3275         [ $(stat --format=%s $scrambledfile) -eq $filesz ] ||
3276                 error "file size without key should be rounded up"
3277
3278         rm -f $tmpfile
3279 }
3280 run_test 40 "exercise size of encrypted file"
3281
3282 test_41() {
3283         local testfile=$DIR/$tdir/$tfile
3284         local tmpfile=$TMP/abc
3285         local tmpfile2=$TMP/abc2
3286         local seek
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         echo "abc" > $tmpfile
3298         seek=$(getconf PAGESIZE)
3299         seek=$((seek - 204))
3300         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3301                 conv=fsync
3302         seek=$(getconf PAGESIZE)
3303         seek=$((seek + 1092))
3304         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3305                 conv=fsync,notrunc
3306
3307         # write a few bytes in file
3308         $LFS setstripe -c1 -i0 -S 256k $testfile
3309         seek=$(getconf PAGESIZE)
3310         seek=$((seek - 204))
3311         #define OBD_FAIL_OST_WR_ATTR_DELAY       0x250
3312         do_facet ost1 "$LCTL set_param fail_loc=0x250 fail_val=15"
3313         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3314                 conv=fsync &
3315
3316         sleep 5
3317         # write a few other bytes, at a different offset
3318         seek=$(getconf PAGESIZE)
3319         seek=$((seek + 1092))
3320         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3321                 conv=fsync,notrunc &
3322         wait
3323         do_facet ost1 "$LCTL set_param fail_loc=0x0"
3324
3325         # check that in-memory representation of file is correct
3326         cmp -bl $tmpfile2 $testfile ||
3327                 error "file $testfile is corrupted in memory (1)"
3328
3329         cancel_lru_locks osc ; cancel_lru_locks mdc
3330
3331         # check that file read from server is correct
3332         cmp -bl $tmpfile2 $testfile ||
3333                 error "file $testfile is corrupted on server (1)"
3334
3335         rm -f $tmpfile $tmpfile2
3336 }
3337 run_test 41 "test race on encrypted file size (1)"
3338
3339 test_42() {
3340         local testfile=$DIR/$tdir/$tfile
3341         local testfile2=$DIR2/$tdir/$tfile
3342         local tmpfile=$TMP/abc
3343         local tmpfile2=$TMP/abc2
3344         local pagesz=$(getconf PAGESIZE)
3345         local seek
3346
3347         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3348                 skip "client encryption not supported"
3349
3350         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3351                 skip "need dummy encryption support"
3352
3353         stack_trap cleanup_for_enc_tests EXIT
3354         setup_for_enc_tests
3355
3356         if is_mounted $MOUNT2; then
3357                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
3358         fi
3359         mount_client $MOUNT2 ${MOUNT_OPTS},test_dummy_encryption ||
3360                 error "mount2 with '-o test_dummy_encryption' failed"
3361
3362         # create file by writting one whole page
3363         $LFS setstripe -c1 -i0 -S 256k $testfile
3364         dd if=/dev/zero of=$testfile bs=$pagesz count=1 conv=fsync
3365
3366         # read file from 2nd mount point
3367         cat $testfile2 > /dev/null
3368
3369         echo "abc" > $tmpfile
3370         dd if=/dev/zero of=$tmpfile2 bs=$pagesz count=1 conv=fsync
3371         seek=$((2*pagesz - 204))
3372         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3373                 conv=fsync,notrunc
3374         seek=$((2*pagesz + 1092))
3375         dd if=$tmpfile of=$tmpfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3376                 conv=fsync,notrunc
3377
3378         # write a few bytes in file from 1st mount point
3379         seek=$((2*pagesz - 204))
3380         #define OBD_FAIL_OST_WR_ATTR_DELAY       0x250
3381         do_facet ost1 "$LCTL set_param fail_loc=0x250 fail_val=15"
3382         dd if=$tmpfile of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3383                 conv=fsync,notrunc &
3384
3385         sleep 5
3386         # write a few other bytes, at a different offset from 2nd mount point
3387         seek=$((2*pagesz + 1092))
3388         dd if=$tmpfile of=$testfile2 bs=4 count=1 seek=$seek oflag=seek_bytes \
3389                 conv=fsync,notrunc &
3390         wait
3391         do_facet ost1 "$LCTL set_param fail_loc=0x0"
3392
3393         # check that in-memory representation of file is correct
3394         cmp -bl $tmpfile2 $testfile ||
3395                 error "file $testfile is corrupted in memory (1)"
3396
3397         # check that in-memory representation of file is correct
3398         cmp -bl $tmpfile2 $testfile2 ||
3399                 error "file $testfile is corrupted in memory (2)"
3400
3401         cancel_lru_locks osc ; cancel_lru_locks mdc
3402
3403         # check that file read from server is correct
3404         cmp -bl $tmpfile2 $testfile ||
3405                 error "file $testfile is corrupted on server (1)"
3406
3407         rm -f $tmpfile $tmpfile2
3408 }
3409 run_test 42 "test race on encrypted file size (2)"
3410
3411 test_43() {
3412         local testfile=$DIR/$tdir/$tfile
3413         local testfile2=$DIR2/$tdir/$tfile
3414         local tmpfile=$TMP/abc
3415         local tmpfile2=$TMP/abc2
3416         local resfile=$TMP/res
3417         local pagesz=$(getconf PAGESIZE)
3418         local seek
3419
3420         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3421                 skip "client encryption not supported"
3422
3423         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3424                 skip "need dummy encryption support"
3425
3426         stack_trap cleanup_for_enc_tests EXIT
3427         setup_for_enc_tests
3428
3429         if is_mounted $MOUNT2; then
3430                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
3431         fi
3432         mount_client $MOUNT2 ${MOUNT_OPTS},test_dummy_encryption ||
3433                 error "mount2 with '-o test_dummy_encryption' failed"
3434
3435         # create file
3436         tr '\0' '1' < /dev/zero |
3437                 dd of=$tmpfile bs=1 count=$pagesz conv=fsync
3438         $LFS setstripe -c1 -i0 -S 256k $testfile
3439         cp $tmpfile $testfile
3440
3441         # read file from 2nd mount point
3442         cat $testfile2 > /dev/null
3443
3444         # write a few bytes in file from 1st mount point
3445         echo "abc" > $tmpfile2
3446         seek=$((2*pagesz - 204))
3447         #define OBD_FAIL_OST_WR_ATTR_DELAY       0x250
3448         do_facet ost1 "$LCTL set_param fail_loc=0x250 fail_val=15"
3449         dd if=$tmpfile2 of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3450                 conv=fsync,notrunc &
3451
3452         sleep 5
3453         # read file from 2nd mount point
3454         dd if=$testfile2 of=$resfile bs=$pagesz count=1 conv=fsync,notrunc
3455         cmp -bl $tmpfile $resfile ||
3456                 error "file $testfile is corrupted in memory (1)"
3457
3458         wait
3459         do_facet ost1 "$LCTL set_param fail_loc=0x0"
3460
3461         # check that in-memory representation of file is correct
3462         dd if=$tmpfile2 of=$tmpfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3463                 conv=fsync,notrunc
3464         cmp -bl $tmpfile $testfile2 ||
3465                 error "file $testfile is corrupted in memory (2)"
3466
3467         cancel_lru_locks osc ; cancel_lru_locks mdc
3468
3469         # check that file read from server is correct
3470         cmp -bl $tmpfile $testfile ||
3471                 error "file $testfile is corrupted on server (1)"
3472
3473         rm -f $tmpfile $tmpfile2
3474 }
3475 run_test 43 "test race on encrypted file size (3)"
3476
3477 test_44() {
3478         local testfile=$DIR/$tdir/$tfile
3479         local tmpfile=$TMP/abc
3480         local resfile=$TMP/resfile
3481         local pagesz=$(getconf PAGESIZE)
3482         local respage
3483
3484         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3485                 skip "client encryption not supported"
3486
3487         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3488                 skip "need dummy encryption support"
3489
3490         which vmtouch || skip "This test needs vmtouch utility"
3491
3492         # Direct I/O is now supported on encrypted files.
3493
3494         stack_trap cleanup_for_enc_tests EXIT
3495         setup_for_enc_tests
3496
3497         $LFS setstripe -c1 -i0 $testfile
3498         dd if=/dev/urandom of=$tmpfile bs=$pagesz count=2 conv=fsync
3499         dd if=$tmpfile of=$testfile bs=$pagesz count=2 oflag=direct ||
3500                 error "could not write to file with O_DIRECT (1)"
3501
3502         respage=$(vmtouch $testfile | awk '/Resident Pages:/ {print $3}')
3503         [ "$respage" == "0/2" ] ||
3504                 error "write to enc file fell back to buffered IO"
3505
3506         cancel_lru_locks
3507
3508         dd if=$testfile of=$resfile bs=$pagesz count=2 iflag=direct ||
3509                 error "could not read from file with O_DIRECT (1)"
3510
3511         respage=$(vmtouch $testfile | awk '/Resident Pages:/ {print $3}')
3512         [ "$respage" == "0/2" ] ||
3513                 error "read from enc file fell back to buffered IO"
3514
3515         cmp -bl $tmpfile $resfile ||
3516                 error "file $testfile is corrupted (1)"
3517
3518         rm -f $resfile
3519
3520         $TRUNCATE $tmpfile $pagesz
3521         dd if=$tmpfile of=$testfile bs=$pagesz count=1 seek=13 oflag=direct ||
3522                 error "could not write to file with O_DIRECT (2)"
3523
3524         cancel_lru_locks
3525
3526         dd if=$testfile of=$resfile bs=$pagesz count=1 skip=13 iflag=direct ||
3527                 error "could not read from file with O_DIRECT (2)"
3528         cmp -bl $tmpfile $resfile ||
3529                 error "file $testfile is corrupted (2)"
3530
3531         rm -f $testfile $resfile
3532         $LFS setstripe -c1 -i0 $testfile
3533
3534         $TRUNCATE $tmpfile $((pagesz/2 - 5))
3535         cp $tmpfile $testfile
3536
3537         cancel_lru_locks
3538
3539         dd if=$testfile of=$resfile bs=$pagesz count=1 iflag=direct ||
3540                 error "could not read from file with O_DIRECT (3)"
3541         cmp -bl $tmpfile $resfile ||
3542                 error "file $testfile is corrupted (3)"
3543
3544         rm -f $tmpfile $resfile $testfile
3545
3546         if [ $OSTCOUNT -ge 2 ]; then
3547                 dd if=/dev/urandom of=$tmpfile bs=$pagesz count=1 conv=fsync
3548                 $LFS setstripe -S 256k -c2 $testfile
3549
3550                 # write in file, at beginning of first stripe, buffered IO
3551                 dd if=$tmpfile of=$testfile bs=$pagesz count=1 \
3552                         conv=fsync,notrunc
3553
3554                 # write at beginning of second stripe, direct IO
3555                 dd if=$tmpfile of=$testfile bs=$pagesz count=1 seek=256k \
3556                         oflag=seek_bytes,direct conv=fsync,notrunc
3557
3558                 cancel_lru_locks
3559
3560                 # read at beginning of first stripe, direct IO
3561                 dd if=$testfile of=$resfile bs=$pagesz count=1 \
3562                         iflag=direct conv=fsync
3563
3564                 cmp -bl $tmpfile $resfile ||
3565                         error "file $testfile is corrupted (4)"
3566
3567                 # read at beginning of second stripe, buffered IO
3568                 dd if=$testfile of=$resfile bs=$pagesz count=1 skip=256k \
3569                         iflag=skip_bytes conv=fsync
3570
3571                 cmp -bl $tmpfile $resfile ||
3572                         error "file $testfile is corrupted (5)"
3573
3574                 rm -f $tmpfile $resfile
3575         fi
3576 }
3577 run_test 44 "encrypted file access semantics: direct IO"
3578
3579 test_45() {
3580         local testfile=$DIR/$tdir/$tfile
3581         local tmpfile=$TMP/junk
3582
3583         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3584                 skip "client encryption not supported"
3585
3586         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3587                 skip "need dummy encryption support"
3588
3589         stack_trap cleanup_for_enc_tests EXIT
3590         setup_for_enc_tests
3591
3592         $LFS setstripe -c1 -i0 $testfile
3593         dd if=/dev/zero of=$testfile bs=512K count=1
3594         $MULTIOP $testfile OSMRUc || error "$MULTIOP $testfile failed (1)"
3595         $MULTIOP $testfile OSMWUc || error "$MULTIOP $testfile failed (2)"
3596
3597         dd if=/dev/zero of=$tmpfile bs=512K count=1
3598         $MULTIOP $tmpfile OSMWUc || error "$MULTIOP $tmpfile failed"
3599         $MMAP_CAT $tmpfile > ${tmpfile}2
3600
3601         cancel_lru_locks
3602
3603         $MULTIOP $testfile OSMRUc
3604         $MMAP_CAT $testfile > ${testfile}2
3605         cmp -bl ${tmpfile}2 ${testfile}2 ||
3606                 error "file $testfile is corrupted"
3607
3608         rm -f $tmpfile ${tmpfile}2
3609 }
3610 run_test 45 "encrypted file access semantics: MMAP"
3611
3612 test_46() {
3613         local testdir=$DIR/$tdir/mydir
3614         local testfile=$testdir/myfile
3615         local testdir2=$DIR/$tdir/mydirwithaveryverylongnametotestcodebehaviour0
3616         local testfile2=$testdir/myfilewithaveryverylongnametotestcodebehaviour0
3617         # testdir3, testfile3, testhl3 and testsl3 names are 255 bytes long
3618         local testdir3=$testdir2/dir_abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz012345678
3619         local testfile3=$testdir2/file_abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01234567
3620         local testhl3=$testdir2/hl_abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789
3621         local testsl3=$testdir2/sl_abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789
3622         local lsfile=$TMP/lsfile
3623         local scrambleddir
3624         local scrambledfile
3625         local inum
3626
3627         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3628                 skip "client encryption not supported"
3629
3630         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3631                 skip "need dummy encryption support"
3632
3633         stack_trap cleanup_for_enc_tests EXIT
3634         setup_for_enc_tests
3635
3636         touch $DIR/$tdir/$tfile
3637         mkdir $testdir
3638         echo test > $testfile
3639         echo othertest > $testfile2
3640         if [[ $MDSCOUNT -gt 1 ]]; then
3641                 $LFS setdirstripe -c1 -i1 $testdir2
3642         else
3643                 mkdir $testdir2
3644         fi
3645         inum=$(stat -c %i $testdir2)
3646         if [ "$mds1_FSTYPE" = ldiskfs ]; then
3647                 # For now, restrict this part of the test to ldiskfs backend,
3648                 # as osd-zfs does not support 255 byte-long encrypted names.
3649                 mkdir $testdir3 || error "cannot mkdir $testdir3"
3650                 touch $testfile3 || error "cannot touch $testfile3"
3651                 ln $testfile3 $testhl3 || error "cannot ln $testhl3"
3652                 ln -s $testfile3 $testsl3 || error "cannot ln $testsl3"
3653         fi
3654         sync ; echo 3 > /proc/sys/vm/drop_caches
3655
3656         # remount without dummy encryption key
3657         remount_client_normally
3658
3659         # this is $testdir2
3660         scrambleddir=$(find $DIR/$tdir/ -maxdepth 1 -mindepth 1 -inum $inum)
3661         stat $scrambleddir || error "stat $scrambleddir failed"
3662         if [ "$mds1_FSTYPE" = ldiskfs ]; then
3663                 stat $scrambleddir/* || error "cannot stat in $scrambleddir"
3664                 rm -rf $scrambleddir/* || error "cannot clean in $scrambleddir"
3665         fi
3666         rmdir $scrambleddir || error "rmdir $scrambleddir failed"
3667
3668         scrambleddir=$(find $DIR/$tdir/ -maxdepth 1 -mindepth 1 -type d)
3669         ls -1 $scrambleddir > $lsfile || error "ls $testdir failed (1)"
3670
3671         scrambledfile=$scrambleddir/$(head -n 1 $lsfile)
3672         stat $scrambledfile || error "stat $scrambledfile failed (1)"
3673         rm -f $lsfile
3674
3675         cat $scrambledfile && error "cat $scrambledfile should have failed (1)"
3676         rm -f $scrambledfile || error "rm $scrambledfile failed (1)"
3677
3678         ls -1 $scrambleddir > $lsfile || error "ls $testdir failed (2)"
3679         scrambledfile=$scrambleddir/$(head -n 1 $lsfile)
3680         stat $scrambledfile || error "stat $scrambledfile failed (2)"
3681         rm -f $lsfile
3682         cat $scrambledfile && error "cat $scrambledfile should have failed (2)"
3683
3684         touch $scrambleddir/otherfile &&
3685                 error "touch otherfile should have failed"
3686         ls $scrambleddir/otherfile && error "otherfile should not exist"
3687         mkdir $scrambleddir/otherdir &&
3688                 error "mkdir otherdir should have failed"
3689         ls -d $scrambleddir/otherdir && error "otherdir should not exist"
3690
3691         ls -R $DIR
3692         rm -f $scrambledfile || error "rm $scrambledfile failed (2)"
3693         rmdir $scrambleddir || error "rmdir $scrambleddir failed"
3694         ls -R $DIR
3695 }
3696 run_test 46 "encrypted file access semantics without key"
3697
3698 test_47() {
3699         local testfile=$DIR/$tdir/$tfile
3700         local testfile2=$DIR/$tdir/${tfile}.2
3701         local tmpfile=$DIR/junk
3702         local name_enc=1
3703         local scrambleddir
3704         local scrambledfile
3705
3706         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3707                 skip "client encryption not supported"
3708
3709         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3710                 skip "need dummy encryption support"
3711
3712         $LCTL get_param mdc.*.connect_flags | grep -q name_encryption ||
3713                 name_enc=0
3714
3715         stack_trap cleanup_for_enc_tests EXIT
3716         setup_for_enc_tests
3717
3718         dd if=/dev/urandom of=$tmpfile bs=512K count=1
3719         mrename $tmpfile $testfile &&
3720                 error "rename from unencrypted to encrypted dir should fail"
3721
3722         ln $tmpfile $testfile &&
3723                 error "link from encrypted to unencrypted dir should fail"
3724
3725         cp $tmpfile $testfile ||
3726                 error "cp from unencrypted to encrypted dir should succeed"
3727         rm -f $tmpfile
3728
3729         mrename $testfile $testfile2 ||
3730                 error "rename from within encrypted dir should succeed"
3731
3732         ln $testfile2 $testfile ||
3733                 error "link from within encrypted dir should succeed"
3734         cmp -bl $testfile2 $testfile ||
3735                 error "cannot read from hard link (1.1)"
3736         echo a >> $testfile || error "cannot write to hard link (1)"
3737         cancel_lru_locks
3738         cmp -bl $testfile2 $testfile ||
3739                 error "cannot read from hard link (1.2)"
3740         rm -f $testfile
3741
3742         ln $testfile2 $tmpfile ||
3743                 error "link from unencrypted to encrypted dir should succeed"
3744         cancel_lru_locks
3745         cmp -bl $testfile2 $tmpfile ||
3746                 error "cannot read from hard link (2.1)"
3747         echo a >> $tmpfile || error "cannot write to hard link (2)"
3748         cancel_lru_locks
3749         cmp -bl $testfile2 $tmpfile ||
3750                 error "cannot read from hard link (2.2)"
3751         rm -f $tmpfile
3752
3753         if [ $name_enc -eq 1 ]; then
3754                 # check we are limited in the number of hard links
3755                 # we can create for encrypted files, to what can fit into LinkEA
3756                 for i in $(seq 1 160); do
3757                         ln $testfile2 ${testfile}_$i || break
3758                 done
3759                 [ $i -lt 160 ] || error "hard link $i should fail"
3760                 rm -f ${testfile}_*
3761         fi
3762
3763         mrename $testfile2 $tmpfile &&
3764                 error "rename from encrypted to unencrypted dir should fail"
3765         rm -f $testfile2
3766         dd if=/dev/urandom of=$tmpfile bs=512K count=1
3767
3768         dd if=/dev/urandom of=$testfile bs=512K count=1
3769         mkdir $DIR/$tdir/mydir
3770
3771         ln -s $testfile ${testfile}.sym ||
3772                 error "symlink from within encrypted dir should succeed"
3773         cancel_lru_locks
3774         cmp -bl $testfile ${testfile}.sym ||
3775                 error "cannot read from sym link (1.1)"
3776         echo a >> ${testfile}.sym || error "cannot write to sym link (1)"
3777         cancel_lru_locks
3778         cmp -bl $testfile ${testfile}.sym ||
3779                 error "cannot read from sym link (1.2)"
3780         [ $(stat -c %s ${testfile}.sym) -eq ${#testfile} ] ||
3781                 error "wrong symlink size (1)"
3782
3783         ln -s $tmpfile ${testfile}.sl ||
3784                 error "symlink from encrypted to unencrypted dir should succeed"
3785         cancel_lru_locks
3786         cmp -bl $tmpfile ${testfile}.sl ||
3787                 error "cannot read from sym link (2.1)"
3788         echo a >> ${testfile}.sl || error "cannot write to sym link (2)"
3789         cancel_lru_locks
3790         cmp -bl $tmpfile ${testfile}.sl ||
3791                 error "cannot read from sym link (2.2)"
3792         [ $(stat -c %s ${testfile}.sl) -eq ${#tmpfile} ] ||
3793                 error "wrong symlink size (2)"
3794         rm -f ${testfile}.sl
3795
3796         sync ; echo 3 > /proc/sys/vm/drop_caches
3797
3798         # remount without dummy encryption key
3799         remount_client_normally
3800
3801         scrambleddir=$(find $DIR/$tdir/ -maxdepth 1 -mindepth 1 -type d)
3802         scrambledfile=$(find $DIR/$tdir/ -maxdepth 1 -type f)
3803         scrambledlink=$(find $DIR/$tdir/ -maxdepth 1 -type l)
3804         ln $scrambledfile $scrambleddir/linkfile &&
3805                 error "ln linkfile should have failed"
3806         mrename $scrambledfile $DIR/onefile2 &&
3807                 error "mrename from $scrambledfile should have failed"
3808         touch $DIR/onefile
3809         mrename $DIR/onefile $scrambleddir/otherfile &&
3810                 error "mrename to $scrambleddir should have failed"
3811         readlink $scrambledlink ||
3812                 error "link should be read without key"
3813         [ $(stat -c %s $scrambledlink) -eq \
3814                         $(expr length "$(readlink $scrambledlink)") ] ||
3815                 error "wrong symlink size without key"
3816         if [ $name_enc -eq 1 ]; then
3817                 readlink -e $scrambledlink &&
3818                         error "link should not point to anywhere useful"
3819         fi
3820         ln -s $scrambledfile ${scrambledfile}.sym &&
3821                 error "symlink without key should fail (1)"
3822         ln -s $tmpfile ${scrambledfile}.sl &&
3823                 error "symlink without key should fail (2)"
3824
3825         rm -f $tmpfile $DIR/onefile
3826 }
3827 run_test 47 "encrypted file access semantics: rename/link"
3828
3829 test_48a() {
3830         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
3831         local testfile=$DIR/$tdir/$tfile
3832         local tmpfile=$TMP/111
3833         local tmpfile2=$TMP/abc
3834         local pagesz=$(getconf PAGESIZE)
3835         local sz
3836         local seek
3837         local scrambledfile
3838
3839         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3840                 skip "client encryption not supported"
3841
3842         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3843                 skip "need dummy encryption support"
3844
3845         stack_trap cleanup_for_enc_tests EXIT
3846         setup_for_enc_tests
3847
3848         # create file, 4 x PAGE_SIZE long
3849         tr '\0' '1' < /dev/zero |
3850                 dd of=$tmpfile bs=1 count=4x$pagesz conv=fsync
3851         $LFS setstripe -c1 -i0 $testfile
3852         cp $tmpfile $testfile
3853         echo "abc" > $tmpfile2
3854
3855         # decrease size: truncate to PAGE_SIZE
3856         $TRUNCATE $tmpfile $pagesz
3857         $TRUNCATE $testfile $pagesz
3858         cancel_lru_locks osc ; cancel_lru_locks mdc
3859         cmp -bl $tmpfile $testfile ||
3860                 error "file $testfile is corrupted (1)"
3861
3862         # increase size: truncate to 2 x PAGE_SIZE
3863         sz=$((pagesz*2))
3864         $TRUNCATE $tmpfile $sz
3865         $TRUNCATE $testfile $sz
3866         cancel_lru_locks osc ; cancel_lru_locks mdc
3867         cmp -bl $tmpfile $testfile ||
3868                 error "file $testfile is corrupted (2)"
3869
3870         # write in 2nd page
3871         seek=$((pagesz+100))
3872         dd if=$tmpfile2 of=$tmpfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3873                 conv=fsync,notrunc
3874         dd if=$tmpfile2 of=$testfile bs=4 count=1 seek=$seek oflag=seek_bytes \
3875                 conv=fsync,notrunc
3876         cancel_lru_locks osc ; cancel_lru_locks mdc
3877         cmp -bl $tmpfile $testfile ||
3878                 error "file $testfile is corrupted (3)"
3879
3880         # truncate to PAGE_SIZE / 2
3881         sz=$((pagesz/2))
3882         $TRUNCATE $tmpfile $sz
3883         $TRUNCATE $testfile $sz
3884         cancel_lru_locks osc ; cancel_lru_locks mdc
3885         cmp -bl $tmpfile $testfile ||
3886                 error "file $testfile is corrupted (4)"
3887
3888         # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16
3889         sz=$((sz-7))
3890         $TRUNCATE $tmpfile $sz
3891         $TRUNCATE $testfile $sz
3892         cancel_lru_locks osc ; cancel_lru_locks mdc
3893         cmp -bl $tmpfile $testfile ||
3894                 error "file $testfile is corrupted (5)"
3895
3896         # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16
3897         sz=$((sz+18))
3898         $TRUNCATE $tmpfile $sz
3899         $TRUNCATE $testfile $sz
3900         cancel_lru_locks osc ; cancel_lru_locks mdc
3901         cmp -bl $tmpfile $testfile ||
3902                 error "file $testfile is corrupted (6)"
3903
3904         # truncate to a larger, non-multiple of PAGE_SIZE, in a different page
3905         sz=$((sz+pagesz+30))
3906         $TRUNCATE $tmpfile $sz
3907         $TRUNCATE $testfile $sz
3908         cancel_lru_locks osc ; cancel_lru_locks mdc
3909         cmp -bl $tmpfile $testfile ||
3910                 error "file $testfile is corrupted (7)"
3911
3912         sync ; echo 3 > /proc/sys/vm/drop_caches
3913
3914         # remount without dummy encryption key
3915         remount_client_normally
3916
3917         scrambledfile=$(find $DIR/$tdir/ -maxdepth 1 -type f)
3918         $TRUNCATE $scrambledfile 0 &&
3919                 error "truncate $scrambledfile should have failed without key"
3920
3921         rm -f $tmpfile $tmpfile2
3922 }
3923 run_test 48a "encrypted file access semantics: truncate"
3924
3925 cleanup_for_enc_tests_othercli() {
3926         local othercli=$1
3927
3928         # remount othercli normally
3929         zconf_umount $othercli $MOUNT ||
3930                 error "umount $othercli $MOUNT failed"
3931         zconf_mount $othercli $MOUNT ||
3932                 error "remount $othercli $MOUNT failed"
3933 }
3934
3935 test_48b() {
3936         local othercli
3937
3938         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3939                 skip "client encryption not supported"
3940
3941         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3942                 skip "need dummy encryption support"
3943
3944         [ "$num_clients" -ge 2 ] || skip "Need at least 2 clients"
3945
3946         if [ "$HOSTNAME" == ${clients_arr[0]} ]; then
3947                 othercli=${clients_arr[1]}
3948         else
3949                 othercli=${clients_arr[0]}
3950         fi
3951
3952         stack_trap cleanup_for_enc_tests EXIT
3953         stack_trap "cleanup_for_enc_tests_othercli $othercli" EXIT
3954         setup_for_enc_tests
3955         zconf_umount $othercli $MOUNT ||
3956                 error "umount $othercli $MOUNT failed"
3957
3958         cp /bin/sleep $DIR/$tdir/
3959         cancel_lru_locks osc ; cancel_lru_locks mdc
3960         $DIR/$tdir/sleep 30 &
3961         # mount and IOs must be done in the same shell session, otherwise
3962         # encryption key in session keyring is missing
3963         do_node $othercli "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
3964                            $MGSNID:/$FSNAME $MOUNT && \
3965                            $TRUNCATE $DIR/$tdir/sleep 7"
3966         wait || error "wait error"
3967         cmp --silent /bin/sleep $DIR/$tdir/sleep ||
3968                 error "/bin/sleep and $DIR/$tdir/sleep differ"
3969 }
3970 run_test 48b "encrypted file: concurrent truncate"
3971
3972 trace_cmd() {
3973         local cmd="$@"
3974
3975         cancel_lru_locks
3976         $LCTL set_param debug=+info
3977         $LCTL clear
3978
3979         echo $cmd
3980         eval $cmd
3981         [ $? -eq 0 ] || error "$cmd failed"
3982
3983         if [ -z "$MATCHING_STRING" ]; then
3984                 $LCTL dk | grep -E "get xattr 'encryption.c'|get xattrs"
3985         else
3986                 $LCTL dk | grep -E "$MATCHING_STRING"
3987         fi
3988         [ $? -ne 0 ] || error "get xattr event was triggered"
3989 }
3990
3991 test_49() {
3992         $LCTL get_param mdc.*.import | grep -q client_encryption ||
3993                 skip "client encryption not supported"
3994
3995         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
3996                 skip "need dummy encryption support"
3997
3998         stack_trap cleanup_for_enc_tests EXIT
3999         setup_for_enc_tests
4000
4001         local dirname=$DIR/$tdir/subdir
4002
4003         mkdir $dirname
4004
4005         trace_cmd stat $dirname
4006         trace_cmd echo a > $dirname/f1
4007         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4008         trace_cmd stat $dirname/f1
4009         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4010         trace_cmd cat $dirname/f1
4011         dd if=/dev/zero of=$dirname/f1 bs=1M count=10 conv=fsync
4012         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4013         MATCHING_STRING="get xattr 'encryption.c'" \
4014                 trace_cmd $TRUNCATE $dirname/f1 10240
4015         trace_cmd $LFS setstripe -E -1 -S 4M $dirname/f2
4016         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4017         trace_cmd $LFS migrate -E -1 -S 256K $dirname/f2
4018
4019         if [[ $MDSCOUNT -gt 1 ]]; then
4020                 trace_cmd $LFS setdirstripe -i 1 $dirname/d2
4021                 sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4022                 trace_cmd $LFS migrate -m 0 $dirname/d2
4023                 echo b > $dirname/d2/subf
4024                 sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4025                 if (( "$MDS1_VERSION" > $(version_code 2.14.54.54) )); then
4026                         # migrate a non-empty encrypted dir
4027                         trace_cmd $LFS migrate -m 1 $dirname/d2
4028                         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4029                         [ -f $dirname/d2/subf ] || error "migrate failed (1)"
4030                         [ $(cat $dirname/d2/subf) == "b" ] ||
4031                                 error "migrate failed (2)"
4032                 fi
4033
4034                 $LFS setdirstripe -i 1 -c 1 $dirname/d3
4035                 dirname=$dirname/d3/subdir
4036                 mkdir $dirname
4037                 sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4038                 trace_cmd stat $dirname
4039                 trace_cmd echo c > $dirname/f1
4040                 sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4041                 trace_cmd stat $dirname/f1
4042                 sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4043                 trace_cmd cat $dirname/f1
4044                 dd if=/dev/zero of=$dirname/f1 bs=1M count=10 conv=fsync
4045                 sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4046                 MATCHING_STRING="get xattr 'encryption.c'" \
4047                         trace_cmd $TRUNCATE $dirname/f1 10240
4048                 trace_cmd $LFS setstripe -E -1 -S 4M $dirname/f2
4049                 sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
4050                 trace_cmd $LFS migrate -E -1 -S 256K $dirname/f2
4051         else
4052                 skip_noexit "2nd part needs >= 2 MDTs"
4053         fi
4054 }
4055 run_test 49 "Avoid getxattr for encryption context"
4056
4057 test_50() {
4058         local testfile=$DIR/$tdir/$tfile
4059         local tmpfile=$TMP/abc
4060         local pagesz=$(getconf PAGESIZE)
4061         local sz
4062
4063         $LCTL get_param mdc.*.import | grep -q client_encryption ||
4064                 skip "client encryption not supported"
4065
4066         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
4067                 skip "need dummy encryption support"
4068
4069         stack_trap cleanup_for_enc_tests EXIT
4070         setup_for_enc_tests
4071
4072         # write small file, data on MDT only
4073         tr '\0' '1' < /dev/zero |
4074             dd of=$tmpfile bs=1 count=5000 conv=fsync
4075         $LFS setstripe -E 1M -L mdt -E EOF $testfile
4076         cp $tmpfile $testfile
4077
4078         # check that in-memory representation of file is correct
4079         cmp -bl $tmpfile $testfile ||
4080                 error "file $testfile is corrupted in memory"
4081
4082         remove_enc_key ; insert_enc_key
4083
4084         # check that file read from server is correct
4085         cmp -bl $tmpfile $testfile ||
4086                 error "file $testfile is corrupted on server"
4087
4088         # decrease size: truncate to PAGE_SIZE
4089         $TRUNCATE $tmpfile $pagesz
4090         $TRUNCATE $testfile $pagesz
4091         remove_enc_key ; insert_enc_key
4092         cmp -bl $tmpfile $testfile ||
4093                 error "file $testfile is corrupted (1)"
4094
4095         # increase size: truncate to 2 x PAGE_SIZE
4096         sz=$((pagesz*2))
4097         $TRUNCATE $tmpfile $sz
4098         $TRUNCATE $testfile $sz
4099         remove_enc_key ; insert_enc_key
4100         cmp -bl $tmpfile $testfile ||
4101                 error "file $testfile is corrupted (2)"
4102
4103         # truncate to PAGE_SIZE / 2
4104         sz=$((pagesz/2))
4105         $TRUNCATE $tmpfile $sz
4106         $TRUNCATE $testfile $sz
4107         remove_enc_key ; insert_enc_key
4108         cmp -bl $tmpfile $testfile ||
4109                 error "file $testfile is corrupted (3)"
4110
4111         # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16
4112         sz=$((sz-7))
4113         $TRUNCATE $tmpfile $sz
4114         $TRUNCATE $testfile $sz
4115         remove_enc_key ; insert_enc_key
4116         cmp -bl $tmpfile $testfile ||
4117                 error "file $testfile is corrupted (4)"
4118
4119         # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16
4120         sz=$((sz+18))
4121         $TRUNCATE $tmpfile $sz
4122         $TRUNCATE $testfile $sz
4123         remove_enc_key ; insert_enc_key
4124         cmp -bl $tmpfile $testfile ||
4125                 error "file $testfile is corrupted (5)"
4126
4127         # truncate to a larger, non-multiple of PAGE_SIZE, in a different page
4128         sz=$((sz+pagesz+30))
4129         $TRUNCATE $tmpfile $sz
4130         $TRUNCATE $testfile $sz
4131         remove_enc_key ; insert_enc_key
4132         cmp -bl $tmpfile $testfile ||
4133                 error "file $testfile is corrupted (6)"
4134
4135         rm -f $testfile
4136         remove_enc_key ; insert_enc_key
4137
4138         # write hole in file, data spread on MDT and OST
4139         tr '\0' '2' < /dev/zero |
4140             dd of=$tmpfile bs=1 count=1539 seek=1539074 conv=fsync,notrunc
4141         $LFS setstripe -E 1M -L mdt -E EOF $testfile
4142         cp --sparse=always $tmpfile $testfile
4143
4144         # check that in-memory representation of file is correct
4145         cmp -bl $tmpfile $testfile ||
4146                 error "file $testfile is corrupted in memory"
4147
4148         remove_enc_key ; insert_enc_key
4149
4150         # check that file read from server is correct
4151         cmp -bl $tmpfile $testfile ||
4152                 error "file $testfile is corrupted on server"
4153
4154         # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16,
4155         # inside OST part of data
4156         sz=$((1024*1024+13))
4157         $TRUNCATE $tmpfile $sz
4158         $TRUNCATE $testfile $sz
4159         remove_enc_key ; insert_enc_key
4160         cmp -bl $tmpfile $testfile ||
4161                 error "file $testfile is corrupted (7)"
4162
4163         # truncate to a smaller, non-multiple of PAGE_SIZE, non-multiple of 16,
4164         # inside MDT part of data
4165         sz=7
4166         $TRUNCATE $tmpfile $sz
4167         $TRUNCATE $testfile $sz
4168         remove_enc_key ; insert_enc_key
4169         cmp -bl $tmpfile $testfile ||
4170                 error "file $testfile is corrupted (8)"
4171
4172         # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16,
4173         # inside MDT part of data
4174         sz=$((1024*1024-13))
4175         $TRUNCATE $tmpfile $sz
4176         $TRUNCATE $testfile $sz
4177         remove_enc_key ; insert_enc_key
4178         cmp -bl $tmpfile $testfile ||
4179                 error "file $testfile is corrupted (9)"
4180
4181         # truncate to a larger, non-multiple of PAGE_SIZE, non-multiple of 16,
4182         # inside OST part of data
4183         sz=$((1024*1024+7))
4184         $TRUNCATE $tmpfile $sz
4185         $TRUNCATE $testfile $sz
4186         remove_enc_key ; insert_enc_key
4187         cmp -bl $tmpfile $testfile ||
4188                 error "file $testfile is corrupted (10)"
4189
4190         rm -f $tmpfile
4191 }
4192 run_test 50 "DoM encrypted file"
4193
4194 test_51() {
4195         [ "$MDS1_VERSION" -gt $(version_code 2.13.53) ] ||
4196                 skip "Need MDS version at least 2.13.53"
4197
4198         mkdir $DIR/$tdir || error "mkdir $tdir"
4199         local mdts=$(comma_list $(mdts_nodes))
4200         local cap_param=mdt.*.enable_cap_mask
4201
4202         old_cap=($(do_nodes $mdts $LCTL get_param -n $cap_param 2>/dev/null))
4203         if [[ -n "$old_cap" ]]; then
4204                 do_nodes $mdts $LCTL set_param $cap_param=0xf
4205                 stack_trap "do_nodes $mdts $LCTL set_param $cap_param=$old_cap"
4206         fi
4207
4208         touch $DIR/$tdir/$tfile || error "touch $tfile"
4209         cp $(which chown) $DIR/$tdir || error "cp chown"
4210         $RUNAS_CMD -u $ID0 $DIR/$tdir/chown $ID0 $DIR/$tdir/$tfile &&
4211                 error "chown $tfile should fail"
4212         setcap 'CAP_CHOWN=ep' $DIR/$tdir/chown || error "setcap CAP_CHOWN"
4213         $RUNAS_CMD -u $ID0 $DIR/$tdir/chown $ID0 $DIR/$tdir/$tfile ||
4214                 error "chown $tfile"
4215         rm $DIR/$tdir/$tfile || error "rm $tfile"
4216
4217         touch $DIR/$tdir/$tfile || error "touch $tfile"
4218         cp $(which touch) $DIR/$tdir || error "cp touch"
4219         $RUNAS_CMD -u $ID0 $DIR/$tdir/touch $DIR/$tdir/$tfile &&
4220                 error "touch should fail"
4221         setcap 'CAP_FOWNER=ep' $DIR/$tdir/touch || error "setcap CAP_FOWNER"
4222         $RUNAS_CMD -u $ID0 $DIR/$tdir/touch $DIR/$tdir/$tfile ||
4223                 error "touch $tfile"
4224         rm $DIR/$tdir/$tfile || error "rm $tfile"
4225
4226         local cap
4227         for cap in "CAP_DAC_OVERRIDE" "CAP_DAC_READ_SEARCH"; do
4228                 touch $DIR/$tdir/$tfile || error "touch $tfile"
4229                 chmod 600 $DIR/$tdir/$tfile || error "chmod $tfile"
4230                 cp $(which cat) $DIR/$tdir || error "cp cat"
4231                 $RUNAS_CMD -u $ID0 $DIR/$tdir/cat $DIR/$tdir/$tfile &&
4232                         error "cat should fail"
4233                 setcap $cap=ep $DIR/$tdir/cat || error "setcap $cap"
4234                 $RUNAS_CMD -u $ID0 $DIR/$tdir/cat $DIR/$tdir/$tfile ||
4235                         error "cat $tfile"
4236                 rm $DIR/$tdir/$tfile || error "rm $tfile"
4237         done
4238 }
4239 run_test 51 "FS capabilities ==============="
4240
4241 test_52() {
4242         local testfile=$DIR/$tdir/$tfile
4243         local tmpfile=$TMP/$tfile
4244         local mirror1=$TMP/$tfile.mirror1
4245         local mirror2=$TMP/$tfile.mirror2
4246
4247         $LCTL get_param mdc.*.import | grep -q client_encryption ||
4248                 skip "client encryption not supported"
4249
4250         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
4251                 skip "need dummy encryption support"
4252
4253         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4254
4255         stack_trap "cleanup_for_enc_tests $tmpfile $mirror1 $mirror2" EXIT
4256         setup_for_enc_tests
4257
4258         dd if=/dev/urandom of=$tmpfile bs=5000 count=1 conv=fsync
4259
4260         $LFS mirror create -N -i0 -N -i1 $testfile ||
4261                 error "could not create mirror"
4262
4263         dd if=$tmpfile of=$testfile bs=5000 count=1 conv=fsync ||
4264                 error "could not write to $testfile"
4265
4266         $LFS mirror resync $testfile ||
4267                 error "could not resync mirror"
4268
4269         $LFS mirror verify -v $testfile ||
4270                 error "verify mirror failed"
4271
4272         $LFS mirror read -N 1 -o $mirror1 $testfile ||
4273                 error "could not read from mirror 1"
4274
4275         cmp -bl $tmpfile $mirror1 ||
4276                 error "mirror 1 is corrupted"
4277
4278         $LFS mirror read -N 2 -o $mirror2 $testfile ||
4279                 error "could not read from mirror 2"
4280
4281         cmp -bl $tmpfile $mirror2 ||
4282                 error "mirror 2 is corrupted"
4283
4284         tr '\0' '2' < /dev/zero |
4285             dd of=$tmpfile bs=1 count=9000 conv=fsync
4286
4287         $LFS mirror write -N 1 -i $tmpfile $testfile ||
4288                 error "could not write to mirror 1"
4289
4290         $LFS mirror verify -v $testfile &&
4291                 error "mirrors should be different"
4292
4293         rm -f $testfile $mirror1 $mirror2
4294
4295         $LFS setstripe -c1 -i0 $testfile
4296         dd if=$tmpfile of=$testfile bs=9000 count=1 conv=fsync ||
4297                 error "write to $testfile failed"
4298         $LFS getstripe $testfile
4299         cancel_lru_locks
4300
4301         $LFS migrate -i1 $testfile ||
4302                 error "migrate $testfile failed"
4303         $LFS getstripe $testfile
4304         stripe=$($LFS getstripe -i $testfile)
4305         [ $stripe -eq 1 ] || error "migrate file $testfile failed"
4306
4307         cancel_lru_locks
4308         cmp -bl $tmpfile $testfile ||
4309                 error "migrated file is corrupted"
4310
4311         $LFS mirror extend -N -i0 $testfile ||
4312                 error "mirror extend $testfile failed"
4313         $LFS getstripe $testfile
4314         mirror_count=$($LFS getstripe -N $testfile)
4315         [ $mirror_count -eq 2 ] ||
4316                 error "mirror extend file $testfile failed (1)"
4317         stripe=$($LFS getstripe --mirror-id=1 -i $testfile)
4318         [ $stripe -eq 1 ] || error "mirror extend file $testfile failed (2)"
4319         stripe=$($LFS getstripe --mirror-id=2 -i $testfile)
4320         [ $stripe -eq 0 ] || error "mirror extend file $testfile failed (3)"
4321
4322         cancel_lru_locks
4323         $LFS mirror verify -v $testfile ||
4324                 error "mirror verify failed"
4325         $LFS mirror read -N 1 -o $mirror1 $testfile ||
4326                 error "read from mirror 1 failed"
4327         cmp -bl $tmpfile $mirror1 ||
4328                 error "corruption of mirror 1"
4329         $LFS mirror read -N 2 -o $mirror2 $testfile ||
4330                 error "read from mirror 2 failed"
4331         cmp -bl $tmpfile $mirror2 ||
4332                 error "corruption of mirror 2"
4333
4334         $LFS mirror split --mirror-id 1 -f ${testfile}.mirror $testfile &&
4335                 error "mirror split -f should fail"
4336
4337         $LFS mirror split --mirror-id 1 $testfile &&
4338                 error "mirror split without -d should fail"
4339
4340         $LFS mirror split --mirror-id 1 -d $testfile ||
4341                 error "mirror split failed"
4342         $LFS getstripe $testfile
4343         mirror_count=$($LFS getstripe -N $testfile)
4344         [ $mirror_count -eq 1 ] ||
4345                 error "mirror split file $testfile failed (1)"
4346         stripe=$($LFS getstripe --mirror-id=1 -i $testfile)
4347         [ -z "$stripe" ] || error "mirror extend file $testfile failed (2)"
4348         stripe=$($LFS getstripe --mirror-id=2 -i $testfile)
4349         [ $stripe -eq 0 ] || error "mirror extend file $testfile failed (3)"
4350
4351         cancel_lru_locks
4352         cmp -bl $tmpfile $testfile ||
4353                 error "extended/split file is corrupted"
4354 }
4355 run_test 52 "Mirrored encrypted file"
4356
4357 test_53() {
4358         local testfile=$DIR/$tdir/$tfile
4359         local testfile2=$DIR2/$tdir/$tfile
4360         local tmpfile=$TMP/$tfile.tmp
4361         local resfile=$TMP/$tfile.res
4362         local pagesz
4363         local filemd5
4364
4365         $LCTL get_param mdc.*.import | grep -q client_encryption ||
4366                 skip "client encryption not supported"
4367
4368         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
4369                 skip "need dummy encryption support"
4370
4371         pagesz=$(getconf PAGESIZE)
4372         [[ $pagesz == 65536 ]] || skip "Need 64K PAGE_SIZE client"
4373
4374         do_node $mds1_HOST \
4375                 "mount.lustre --help |& grep -q 'test_dummy_encryption:'" ||
4376                         skip "need dummy encryption support on MDS client mount"
4377
4378         # this test is probably useless now, but may turn out to be useful when
4379         # Lustre supports servers with PAGE_SIZE != 4KB
4380         pagesz=$(do_node $mds1_HOST getconf PAGESIZE)
4381         [[ $pagesz == 4096 ]] || skip "Need 4K PAGE_SIZE MDS client"
4382
4383         stack_trap cleanup_for_enc_tests EXIT
4384         stack_trap "zconf_umount $mds1_HOST $MOUNT2" EXIT
4385         setup_for_enc_tests
4386
4387         $LFS setstripe -c1 -i0 $testfile
4388
4389         # write from 1st client
4390         cat /dev/urandom | tr -dc 'a-zA-Z0-9' |
4391                 dd of=$tmpfile bs=$((pagesz+3)) count=2 conv=fsync
4392         dd if=$tmpfile of=$testfile bs=$((pagesz+3)) count=2 conv=fsync ||
4393                 error "could not write to $testfile (1)"
4394
4395         # read from 2nd client
4396         # mount and IOs must be done in the same shell session, otherwise
4397         # encryption key in session keyring is missing
4398         do_node $mds1_HOST "mkdir -p $MOUNT2"
4399         do_node $mds1_HOST \
4400                 "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
4401                  $MGSNID:/$FSNAME $MOUNT2 && \
4402                  dd if=$testfile2 of=$resfile bs=$((pagesz+3)) count=2" ||
4403                 error "could not read from $testfile2 (1)"
4404
4405         # compare
4406         filemd5=$(do_node $mds1_HOST md5sum $resfile | awk '{print $1}')
4407         [ $filemd5 = $(md5sum $tmpfile | awk '{print $1}') ] ||
4408                 error "file is corrupted (1)"
4409         do_node $mds1_HOST rm -f $resfile
4410         cancel_lru_locks
4411
4412         # truncate from 2nd client
4413         $TRUNCATE $tmpfile $((pagesz+3))
4414         zconf_umount $mds1_HOST $MOUNT2 ||
4415                 error "umount $mds1_HOST $MOUNT2 failed (1)"
4416         do_node $mds1_HOST "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
4417                            $MGSNID:/$FSNAME $MOUNT2 && \
4418                            $TRUNCATE $testfile2 $((pagesz+3))" ||
4419                 error "could not truncate $testfile2 (1)"
4420
4421         # compare
4422         cmp -bl $tmpfile $testfile ||
4423                 error "file is corrupted (2)"
4424         rm -f $tmpfile $testfile
4425         cancel_lru_locks
4426         zconf_umount $mds1_HOST $MOUNT2 ||
4427                 error "umount $mds1_HOST $MOUNT2 failed (2)"
4428
4429         # do conversly
4430         do_node $mds1_HOST \
4431               dd if=/dev/urandom of=$tmpfile bs=$((pagesz+3)) count=2 conv=fsync
4432         # write from 2nd client
4433         do_node $mds1_HOST \
4434            "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
4435             $MGSNID:/$FSNAME $MOUNT2 && \
4436             dd if=$tmpfile of=$testfile2 bs=$((pagesz+3)) count=2 conv=fsync" ||
4437                 error "could not write to $testfile2 (2)"
4438
4439         # read from 1st client
4440         dd if=$testfile of=$resfile bs=$((pagesz+3)) count=2 ||
4441                 error "could not read from $testfile (2)"
4442
4443         # compare
4444         filemd5=$(do_node $mds1_HOST md5sum -b $tmpfile | awk '{print $1}')
4445         [ $filemd5 = $(md5sum -b $resfile | awk '{print $1}') ] ||
4446                 error "file is corrupted (3)"
4447         rm -f $resfile
4448         cancel_lru_locks
4449
4450         # truncate from 1st client
4451         do_node $mds1_HOST "$TRUNCATE $tmpfile $((pagesz+3))"
4452         $TRUNCATE $testfile $((pagesz+3)) ||
4453                 error "could not truncate $testfile (2)"
4454
4455         # compare
4456         zconf_umount $mds1_HOST $MOUNT2 ||
4457                 error "umount $mds1_HOST $MOUNT2 failed (3)"
4458         do_node $mds1_HOST "$MOUNT_CMD -o ${MOUNT_OPTS},test_dummy_encryption \
4459                            $MGSNID:/$FSNAME $MOUNT2 && \
4460                            cmp -bl $tmpfile $testfile2" ||
4461                 error "file is corrupted (4)"
4462
4463         do_node $mds1_HOST rm -f $tmpfile
4464         rm -f $tmpfile
4465 }
4466 run_test 53 "Mixed PAGE_SIZE clients"
4467
4468 test_54() {
4469         local testdir=$DIR/$tdir/$ID0
4470         local testdir2=$DIR2/$tdir/$ID0
4471         local testfile=$testdir/$tfile
4472         local testfile2=$testdir/${tfile}withveryverylongnametoexercisecode
4473         local testfile3=$testdir/_${tfile}
4474         local tmpfile=$TMP/${tfile}.tmp
4475         local resfile=$TMP/${tfile}.res
4476         local nameenc=""
4477         local fid1
4478         local fid2
4479
4480         $LCTL get_param mdc.*.import | grep -q client_encryption ||
4481                 skip "client encryption not supported"
4482
4483         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
4484                 skip "need dummy encryption support"
4485
4486         which fscrypt || skip "This test needs fscrypt userspace tool"
4487
4488         yes | fscrypt setup --force --verbose ||
4489                 error "fscrypt global setup failed"
4490         sed -i 's/\(.*\)policy_version\(.*\):\(.*\)\"[0-9]*\"\(.*\)/\1policy_version\2:\3"2"\4/' \
4491                 /etc/fscrypt.conf
4492         yes | fscrypt setup --verbose $MOUNT ||
4493                 error "fscrypt setup $MOUNT failed"
4494         mkdir -p $testdir
4495         chown -R $ID0:$ID0 $testdir
4496
4497         echo -e 'mypass\nmypass' | su - $USER0 -c "fscrypt encrypt --verbose \
4498                 --source=custom_passphrase --name=protector $testdir" ||
4499                 error "fscrypt encrypt failed"
4500
4501         echo -e 'mypass\nmypass' | su - $USER0 -c "fscrypt encrypt --verbose \
4502                 --source=custom_passphrase --name=protector2 $testdir" &&
4503                 error "second fscrypt encrypt should have failed"
4504
4505         mkdir -p ${testdir}2 || error "mkdir ${testdir}2 failed"
4506         touch ${testdir}2/f || error "mkdir ${testdir}2/f failed"
4507         cancel_lru_locks
4508
4509         echo -e 'mypass\nmypass' | fscrypt encrypt --verbose \
4510                 --source=custom_passphrase --name=protector3 ${testdir}2 &&
4511                 error "fscrypt encrypt on non-empty dir should have failed"
4512
4513         $RUNAS dd if=/dev/urandom of=$testfile bs=127 count=1 conv=fsync ||
4514                 error "write to encrypted file $testfile failed"
4515         cp $testfile $tmpfile
4516         $RUNAS dd if=/dev/urandom of=$testfile2 bs=127 count=1 conv=fsync ||
4517                 error "write to encrypted file $testfile2 failed"
4518         $RUNAS dd if=/dev/urandom of=$testfile3 bs=127 count=1 conv=fsync ||
4519                 error "write to encrypted file $testfile3 failed"
4520         $RUNAS mkdir $testdir/subdir || error "mkdir subdir failed"
4521         $RUNAS touch $testdir/subdir/subfile || error "mkdir subdir failed"
4522
4523         $RUNAS fscrypt lock --verbose $testdir ||
4524                 error "fscrypt lock $testdir failed (1)"
4525
4526         $RUNAS ls -R $testdir || error "ls -R $testdir failed"
4527         local filecount=$($RUNAS find $testdir -type f | wc -l)
4528         [ $filecount -eq 4 ] || error "found $filecount files"
4529
4530         # check enable_filename_encryption default value
4531         # tunable only available for client built against embedded llcrypt
4532         $LCTL get_param mdc.*.connect_flags | grep -q name_encryption &&
4533           nameenc=$(lctl get_param -n llite.*.enable_filename_encryption |
4534                         head -n1)
4535         # If client is built against in-kernel fscrypt, it is not possible
4536         # to decide to encrypt file names or not: they are always encrypted.
4537         if [ -n "$nameenc" ]; then
4538                 [ $nameenc -eq 0 ] ||
4539                        error "enable_filename_encryption should be 0 by default"
4540
4541                 # $testfile, $testfile2 and $testfile3 should exist because
4542                 # names are not encrypted
4543                 [ -f $testfile ] ||
4544                       error "$testfile should exist because name not encrypted"
4545                 [ -f $testfile2 ] ||
4546                       error "$testfile2 should exist because name not encrypted"
4547                 [ -f $testfile3 ] ||
4548                       error "$testfile3 should exist because name not encrypted"
4549                 stat $testfile3
4550                 [ $? -eq 0 ] || error "cannot stat $testfile3 without key"
4551         fi
4552
4553         scrambledfiles=( $(find $testdir/ -maxdepth 1 -type f) )
4554         $RUNAS hexdump -C ${scrambledfiles[0]} &&
4555                 error "reading ${scrambledfiles[0]} should fail without key"
4556
4557         $RUNAS touch ${testfile}.nokey &&
4558                 error "touch ${testfile}.nokey should have failed without key"
4559
4560         echo mypass | $RUNAS fscrypt unlock --verbose $testdir ||
4561                 error "fscrypt unlock $testdir failed (1)"
4562
4563         $RUNAS cat $testfile > $resfile ||
4564                 error "reading $testfile failed"
4565
4566         cmp -bl $tmpfile $resfile || error "file read differs from file written"
4567         stat $testfile3
4568         [ $? -eq 0 ] || error "cannot stat $testfile3 with key"
4569
4570         $RUNAS fscrypt lock --verbose $testdir ||
4571                 error "fscrypt lock $testdir failed (2)"
4572
4573         $RUNAS hexdump -C ${scrambledfiles[1]} &&
4574                 error "reading ${scrambledfiles[1]} should fail without key"
4575
4576         # server local client incompatible with SSK keys installed
4577         if [ "$SHARED_KEY" != true ]; then
4578                 mount_mds_client
4579                 stack_trap umount_mds_client EXIT
4580                 do_facet $SINGLEMDS touch $DIR2/$tdir/newfile
4581                 mdsscrambledfile=$(do_facet $SINGLEMDS find $testdir2/ \
4582                                         -maxdepth 1 -type f | head -n1)
4583                 [ -n "$mdsscrambledfile" ] || error "could not find file"
4584                 do_facet $SINGLEMDS cat "$mdsscrambledfile" &&
4585                         error "reading $mdsscrambledfile should fail on MDS"
4586                 do_facet $SINGLEMDS "echo aaa >> \"$mdsscrambledfile\"" &&
4587                         error "writing $mdsscrambledfile should fail on MDS"
4588                 do_facet $SINGLEMDS $MULTIOP $testdir2/fileA m &&
4589                         error "creating $testdir2/fileA should fail on MDS"
4590                 do_facet $SINGLEMDS mkdir $testdir2/dirA &&
4591                         error "mkdir $testdir2/dirA should fail on MDS"
4592                 do_facet $SINGLEMDS ln -s $DIR2/$tdir/newfile $testdir2/sl1 &&
4593                         error "ln -s $testdir2/sl1 should fail on MDS"
4594                 do_facet $SINGLEMDS ln $DIR2/$tdir/newfile $testdir2/hl1 &&
4595                         error "ln $testdir2/hl1 should fail on MDS"
4596                 do_facet $SINGLEMDS mv "$mdsscrambledfile" $testdir2/fB &&
4597                         error "mv $mdsscrambledfile should fail on MDS"
4598                 do_facet $SINGLEMDS mrename "$mdsscrambledfile" $testdir2/fB &&
4599                         error "mrename $mdsscrambledfile should fail on MDS"
4600                 do_facet $SINGLEMDS rm -f $DIR2/$tdir/newfile
4601         fi
4602
4603         echo mypass | $RUNAS fscrypt unlock --verbose $testdir ||
4604                 error "fscrypt unlock $testdir failed (2)"
4605
4606         rm -rf $testdir/*
4607         $RUNAS fscrypt lock --verbose $testdir ||
4608                 error "fscrypt lock $testdir failed (3)"
4609
4610         rm -rf $tmpfile $resfile $testdir ${testdir}2 $MOUNT/.fscrypt
4611
4612         # remount client with subdirectory mount
4613         umount_client $MOUNT || error "umount $MOUNT failed (1)"
4614         export FILESET=/$tdir
4615         mount_client $MOUNT ${MOUNT_OPTS} || error "remount failed (1)"
4616         export FILESET=""
4617         wait_ssk
4618
4619         # setup encryption from inside this subdir mount
4620         # the .fscrypt directory is going to be created at the real fs root
4621         yes | fscrypt setup --verbose $MOUNT ||
4622                 error "fscrypt setup $MOUNT failed (2)"
4623         testdir=$MOUNT/vault
4624         mkdir $testdir
4625         chown -R $ID0:$ID0 $testdir
4626         fid1=$(path2fid $MOUNT/.fscrypt)
4627         echo "With FILESET $tdir, .fscrypt FID is $fid1"
4628
4629         # enable name encryption, only valid if built against embedded llcrypt
4630         if [ -n "$nameenc" ]; then
4631                 do_facet mgs $LCTL set_param -P \
4632                         llite.*.enable_filename_encryption=1
4633                 [ $? -eq 0 ] ||
4634                         error "set_param -P \
4635                                 llite.*.enable_filename_encryption failed"
4636
4637                 wait_update_facet --verbose client \
4638                         "$LCTL get_param -n llite.*.enable_filename_encryption \
4639                         | head -n1" 1 30 ||
4640                         error "enable_filename_encryption not set on client"
4641         fi
4642
4643         # encrypt 'vault' dir inside the subdir mount
4644         echo -e 'mypass\nmypass' | su - $USER0 -c "fscrypt encrypt --verbose \
4645                 --source=custom_passphrase --name=protector $testdir" ||
4646                 error "fscrypt encrypt failed"
4647
4648         echo abc > $tmpfile
4649         chmod 666 $tmpfile
4650         $RUNAS cp $tmpfile $testdir/encfile
4651
4652         $RUNAS fscrypt lock --verbose $testdir ||
4653                 error "fscrypt lock $testdir failed (4)"
4654
4655         # encfile should actually have its name encrypted
4656         if [ -n "$nameenc" ]; then
4657                 [ -f $testdir/encfile ] &&
4658                         error "encfile name should be encrypted"
4659         fi
4660         filecount=$(find $testdir -type f | wc -l)
4661         [ $filecount -eq 1 ] || error "found $filecount files instead of 1"
4662
4663         # remount client with encrypted dir as subdirectory mount
4664         umount_client $MOUNT || error "umount $MOUNT failed (2)"
4665         export FILESET=/$tdir/vault
4666         mount_client $MOUNT ${MOUNT_OPTS} || error "remount failed (2)"
4667         export FILESET=""
4668         wait_ssk
4669         ls -laR $MOUNT
4670         fid2=$(path2fid $MOUNT/.fscrypt)
4671         echo "With FILESET $tdir/vault, .fscrypt FID is $fid2"
4672         [ "$fid1" == "$fid2" ] || error "fid1 $fid1 != fid2 $fid2 (1)"
4673
4674         # all content seen by this mount is encrypted, but .fscrypt is virtually
4675         # presented, letting us call fscrypt lock/unlock
4676         echo mypass | $RUNAS fscrypt unlock --verbose $MOUNT ||
4677                 error "fscrypt unlock $MOUNT failed (3)"
4678
4679         ls -laR $MOUNT
4680         [ $(cat $MOUNT/encfile) == "abc" ] || error "cat encfile failed"
4681
4682         # remount client without subdir mount
4683         umount_client $MOUNT || error "umount $MOUNT failed (3)"
4684         mount_client $MOUNT ${MOUNT_OPTS} || error "remount failed (3)"
4685         wait_ssk
4686         ls -laR $MOUNT
4687         fid2=$(path2fid $MOUNT/.fscrypt)
4688         echo "Without FILESET, .fscrypt FID is $fid2"
4689         [ "$fid1" == "$fid2" ] || error "fid1 $fid1 != fid2 $fid2 (2)"
4690
4691         # because .fscrypt was actually created at the real root of the fs,
4692         # we can call fscrypt lock/unlock on the encrypted dir
4693         echo mypass | $RUNAS fscrypt unlock --verbose $DIR/$tdir/vault ||
4694                 error "fscrypt unlock $$DIR/$tdir/vault failed (4)"
4695
4696         ls -laR $MOUNT
4697         echo c >> $DIR/$tdir/vault/encfile || error "write to encfile failed"
4698
4699         rm -rf $DIR/$tdir/vault/*
4700         $RUNAS fscrypt lock --verbose $DIR/$tdir/vault ||
4701                 error "fscrypt lock $DIR/$tdir/vault failed (5)"
4702
4703         # disable name encryption, only valid if built against embedded llcrypt
4704         if [ -n "$nameenc" ]; then
4705                 do_facet mgs $LCTL set_param -P \
4706                         llite.*.enable_filename_encryption=0
4707                 [ $? -eq 0 ] ||
4708                         error "set_param -P \
4709                                 llite.*.enable_filename_encryption failed"
4710
4711                 wait_update_facet --verbose client \
4712                         "$LCTL get_param -n llite.*.enable_filename_encryption \
4713                         | head -n1" 0 30 ||
4714                         error "enable_filename_encryption not set back to default"
4715         fi
4716
4717         rm -rf $tmpfile $MOUNT/.fscrypt
4718 }
4719 run_test 54 "Encryption policies with fscrypt"
4720
4721 cleanup_55() {
4722         # unmount client
4723         if is_mounted $MOUNT; then
4724                 umount_client $MOUNT || error "umount $MOUNT failed"
4725         fi
4726
4727         do_facet mgs $LCTL nodemap_del c0
4728         do_facet mgs $LCTL nodemap_modify --name default \
4729                  --property admin --value 0
4730         do_facet mgs $LCTL nodemap_modify --name default \
4731                  --property trusted --value 0
4732         wait_nm_sync default admin_nodemap
4733         wait_nm_sync default trusted_nodemap
4734
4735         do_facet mgs $LCTL nodemap_activate 0
4736         wait_nm_sync active 0
4737
4738         if $SHARED_KEY; then
4739                 export SK_UNIQUE_NM=false
4740         fi
4741
4742         # remount client
4743         mount_client $MOUNT ${MOUNT_OPTS} || error "remount failed"
4744         if [ "$MOUNT_2" ]; then
4745                 mount_client $MOUNT2 ${MOUNT_OPTS} || error "remount failed"
4746         fi
4747         wait_ssk
4748 }
4749
4750 test_55() {
4751         (( $MDS1_VERSION > $(version_code 2.12.6.2) )) ||
4752                 skip "Need MDS version at least 2.12.6.3"
4753
4754         local client_ip
4755         local client_nid
4756
4757         mkdir -p $DIR/$tdir/$USER0/testdir_groups
4758         chown root:$USER0 $DIR/$tdir/$USER0
4759         chmod 770 $DIR/$tdir/$USER0
4760         chmod g+s $DIR/$tdir/$USER0
4761         chown $USER0:$USER0 $DIR/$tdir/$USER0/testdir_groups
4762         chmod 770 $DIR/$tdir/$USER0/testdir_groups
4763         chmod g+s $DIR/$tdir/$USER0/testdir_groups
4764
4765         # unmount client completely
4766         umount_client $MOUNT || error "umount $MOUNT failed"
4767         if is_mounted $MOUNT2; then
4768                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
4769         fi
4770
4771         do_nodes $(comma_list $(all_mdts_nodes)) \
4772                 $LCTL set_param mdt.*.identity_upcall=NONE
4773
4774         stack_trap cleanup_55 EXIT
4775
4776         do_facet mgs $LCTL nodemap_activate 1
4777         wait_nm_sync active
4778
4779         do_facet mgs $LCTL nodemap_del c0 || true
4780         wait_nm_sync c0 id ''
4781
4782         do_facet mgs $LCTL nodemap_modify --name default \
4783                 --property admin --value 1
4784         do_facet mgs $LCTL nodemap_modify --name default \
4785                 --property trusted --value 1
4786         wait_nm_sync default admin_nodemap
4787         wait_nm_sync default trusted_nodemap
4788
4789         client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
4790         client_nid=$(h2nettype $client_ip)
4791         do_facet mgs $LCTL nodemap_add c0
4792         do_facet mgs $LCTL nodemap_add_range \
4793                  --name c0 --range $client_nid
4794         do_facet mgs $LCTL nodemap_modify --name c0 \
4795                  --property admin --value 0
4796         do_facet mgs $LCTL nodemap_modify --name c0 \
4797                  --property trusted --value 1
4798         wait_nm_sync c0 admin_nodemap
4799         wait_nm_sync c0 trusted_nodemap
4800
4801         if $SHARED_KEY; then
4802                 export SK_UNIQUE_NM=true
4803                 # set some generic fileset to trigger SSK code
4804                 export FILESET=/
4805         fi
4806
4807         # remount client to take nodemap into account
4808         zconf_mount_clients $HOSTNAME $MOUNT $MOUNT_OPTS ||
4809                 error "remount failed"
4810         unset FILESET
4811         wait_ssk
4812
4813         euid_access $USER0 $DIR/$tdir/$USER0/testdir_groups/file
4814 }
4815 run_test 55 "access with seteuid"
4816
4817 test_56() {
4818         local testfile=$DIR/$tdir/$tfile
4819
4820         [[ $(facet_fstype ost1) == zfs ]] && skip "skip ZFS backend"
4821
4822         $LCTL get_param mdc.*.import | grep -q client_encryption ||
4823                 skip "client encryption not supported"
4824
4825         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
4826                 skip "need dummy encryption support"
4827
4828         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4829
4830         stack_trap cleanup_for_enc_tests EXIT
4831         setup_for_enc_tests
4832
4833         $LFS setstripe -c1 $testfile
4834         dd if=/dev/urandom of=$testfile bs=1M count=3 conv=fsync
4835         filefrag -v $testfile || error "filefrag $testfile failed"
4836         (( $(filefrag -v $testfile | grep -c encrypted) >= 1 )) ||
4837                 error "filefrag $testfile does not show encrypted flag"
4838         (( $(filefrag -v $testfile | grep -c encoded) >= 1 )) ||
4839                 error "filefrag $testfile does not show encoded flag"
4840 }
4841 run_test 56 "FIEMAP on encrypted file"
4842
4843 test_57() {
4844         local testdir=$DIR/$tdir/mytestdir
4845         local testfile=$DIR/$tdir/$tfile
4846
4847         [[ $(facet_fstype ost1) == zfs ]] && skip "skip ZFS backend"
4848
4849         $LCTL get_param mdc.*.import | grep -q client_encryption ||
4850                 skip "client encryption not supported"
4851
4852         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
4853                 skip "need dummy encryption support"
4854
4855         mkdir $DIR/$tdir
4856         mkdir $testdir
4857         setfattr -n security.c -v myval $testdir &&
4858                 error "setting xattr on $testdir should have failed (1.1)"
4859         setfattr -n encryption.c -v myval $testdir &&
4860                 error "setting xattr on $testdir should have failed (1.2)"
4861         touch $testfile
4862         setfattr -n security.c -v myval $testfile &&
4863                 error "setting xattr on $testfile should have failed (1.1)"
4864         setfattr -n encryption.c -v myval $testfile &&
4865                 error "setting xattr on $testfile should have failed (1.2)"
4866
4867         rm -rf $DIR/$tdir
4868
4869         stack_trap cleanup_for_enc_tests EXIT
4870         setup_for_enc_tests
4871
4872         mkdir $testdir
4873         if [ $(getfattr -n security.c $testdir 2>&1 |
4874                grep -ci "Operation not permitted") -eq 0 ]; then
4875                 error "getting xattr on $testdir should have failed (1.1)"
4876         fi
4877         if [ $(getfattr -n encryption.c $testdir 2>&1 |
4878                grep -ci "Operation not supported") -eq 0 ]; then
4879                 error "getting xattr on $testdir should have failed (1.2)"
4880         fi
4881         getfattr -d -m - $testdir 2>&1 | grep security\.c &&
4882                 error "listing xattrs on $testdir should not expose security.c"
4883         getfattr -d -m - $testdir 2>&1 | grep encryption\.c &&
4884                error "listing xattrs on $testdir should not expose encryption.c"
4885         if [ $(setfattr -n security.c -v myval $testdir 2>&1 |
4886                grep -ci "Operation not permitted") -eq 0 ]; then
4887                 error "setting xattr on $testdir should have failed (2.1)"
4888         fi
4889         if [ $(setfattr -n encryption.c -v myval $testdir 2>&1 |
4890                grep -ci "Operation not supported") -eq 0 ]; then
4891                 error "setting xattr on $testdir should have failed (2.2)"
4892         fi
4893         touch $testfile
4894         if [ $(getfattr -n security.c $testfile 2>&1 |
4895                grep -ci "Operation not permitted") -eq 0 ]; then
4896                 error "getting xattr on $testfile should have failed (1.1)"
4897         fi
4898         if [ $(getfattr -n encryption.c $testfile 2>&1 |
4899                grep -ci "Operation not supported") -eq 0 ]; then
4900                 error "getting xattr on $testfile should have failed (1.2)"
4901         fi
4902         getfattr -d -m - $testfile 2>&1 | grep security\.c &&
4903                 error "listing xattrs on $testfile should not expose security.c"
4904         getfattr -d -m - $testfile 2>&1 | grep encryption\.c &&
4905               error "listing xattrs on $testfile should not expose encryption.c"
4906         if [ $(setfattr -n security.c -v myval $testfile 2>&1 |
4907                grep -ci "Operation not permitted") -eq 0 ]; then
4908                 error "setting xattr on $testfile should have failed (2.1)"
4909         fi
4910         if [ $(setfattr -n encryption.c -v myval $testfile 2>&1 |
4911                grep -ci "Operation not supported") -eq 0 ]; then
4912                 error "setting xattr on $testfile should have failed (2.2)"
4913         fi
4914         return 0
4915 }
4916 run_test 57 "security.c/encryption.c xattr protection"
4917
4918 test_58() {
4919         local testdir=$DIR/$tdir/mytestdir
4920         local testfile=$DIR/$tdir/$tfile
4921
4922         [[ $(facet_fstype ost1) == zfs ]] && skip "skip ZFS backend"
4923
4924         $LCTL get_param mdc.*.import | grep -q client_encryption ||
4925                 skip "client encryption not supported"
4926
4927         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
4928                 skip "need dummy encryption support"
4929
4930         stack_trap cleanup_for_enc_tests EXIT
4931         setup_for_enc_tests
4932
4933         touch $DIR/$tdir/$tfile
4934         mkdir $DIR/$tdir/subdir
4935
4936         cancel_lru_locks
4937         sync ; sync
4938         echo 3 > /proc/sys/vm/drop_caches
4939
4940         ll_decode_linkea $DIR/$tdir/$tfile || error "cannot read $tfile linkea"
4941         ll_decode_linkea $DIR/$tdir/subdir || error "cannot read subdir linkea"
4942
4943         for ((i = 0; i < 1000; i = $((i+1)))); do
4944                 mkdir -p $DIR/$tdir/d${i}
4945                 touch $DIR/$tdir/f${i}
4946                 createmany -m $DIR/$tdir/d${i}/f 5 > /dev/null
4947         done
4948
4949         cancel_lru_locks
4950         sync ; sync
4951         echo 3 > /proc/sys/vm/drop_caches
4952
4953         sleep 10
4954         ls -ailR $DIR/$tdir > /dev/null || error "fail to ls"
4955 }
4956 run_test 58 "access to enc file's xattrs"
4957
4958 verify_mirror() {
4959         local mirror1=$TMP/$tfile.mirror1
4960         local mirror2=$TMP/$tfile.mirror2
4961         local testfile=$1
4962         local reffile=$2
4963
4964         $LFS mirror verify -vvv $testfile ||
4965                 error "verifying mirror failed (1)"
4966         if [ $($LFS mirror verify -v $testfile 2>&1 |
4967                 grep -ci "only valid") -ne 0 ]; then
4968                 error "verifying mirror failed (2)"
4969         fi
4970
4971         $LFS mirror read -N 1 -o $mirror1 $testfile ||
4972                 error "read from mirror 1 failed"
4973         cmp -bl $reffile $mirror1 ||
4974                 error "corruption of mirror 1"
4975         $LFS mirror read -N 2 -o $mirror2 $testfile ||
4976                 error "read from mirror 2 failed"
4977         cmp -bl $reffile $mirror2 ||
4978                 error "corruption of mirror 2"
4979 }
4980
4981 test_59a() {
4982         local testfile=$DIR/$tdir/$tfile
4983         local tmpfile=$TMP/$tfile
4984         local mirror1=$TMP/$tfile.mirror1
4985         local mirror2=$TMP/$tfile.mirror2
4986         local scrambledfile
4987
4988         $LCTL get_param mdc.*.import | grep -q client_encryption ||
4989                 skip "client encryption not supported"
4990
4991         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
4992                 skip "need dummy encryption support"
4993
4994         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4995
4996         stack_trap "cleanup_for_enc_tests $tmpfile $mirror1 $mirror2" EXIT
4997         setup_for_enc_tests
4998
4999         dd if=/dev/urandom of=$tmpfile bs=5000 count=1 conv=fsync
5000
5001         $LFS mirror create -N -i0 -N -i1 $testfile ||
5002                 error "could not create mirror"
5003         dd if=$tmpfile of=$testfile bs=5000 count=1 conv=fsync ||
5004                 error "could not write to $testfile"
5005         $LFS getstripe $testfile
5006
5007         # remount without dummy encryption key
5008         remount_client_normally
5009
5010         scrambledfile=$(find $DIR/$tdir/ -maxdepth 1 -mindepth 1 -type f)
5011         $LFS mirror resync $scrambledfile ||
5012                 error "could not resync mirror"
5013
5014         $LFS mirror verify -vvv $scrambledfile ||
5015                 error "mirror verify failed (1)"
5016         if [ $($LFS mirror verify -v $scrambledfile 2>&1 |
5017                 grep -ci "only valid") -ne 0 ]; then
5018                 error "mirror verify failed (2)"
5019         fi
5020
5021         $LFS mirror read -N 1 -o $mirror1 $scrambledfile &&
5022                 error "read from mirror should fail"
5023
5024         # now, with the key
5025         remount_client_dummykey
5026         verify_mirror $testfile $tmpfile
5027 }
5028 run_test 59a "mirror resync of encrypted files without key"
5029
5030 test_59b() {
5031         local testfile=$DIR/$tdir/$tfile
5032         local tmpfile=$TMP/$tfile
5033         local mirror1=$TMP/$tfile.mirror1
5034         local mirror2=$TMP/$tfile.mirror2
5035         local scrambledfile
5036
5037         $LCTL get_param mdc.*.import | grep -q client_encryption ||
5038                 skip "client encryption not supported"
5039
5040         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
5041                 skip "need dummy encryption support"
5042
5043         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5044
5045         stack_trap "cleanup_for_enc_tests $tmpfile $mirror1 $mirror2" EXIT
5046         setup_for_enc_tests
5047
5048         tr '\0' '2' < /dev/zero |
5049                 dd of=$tmpfile bs=1 count=9000 conv=fsync
5050
5051         $LFS setstripe -c1 -i0 $testfile
5052         dd if=$tmpfile of=$testfile bs=9000 count=1 conv=fsync ||
5053                 error "write to $testfile failed"
5054         $LFS getstripe $testfile
5055
5056         # remount without dummy encryption key
5057         remount_client_normally
5058
5059         scrambledfile=$(find $DIR/$tdir/ -maxdepth 1 -mindepth 1 -type f)
5060         $LFS migrate -i1 $scrambledfile ||
5061                 error "migrate $scrambledfile failed"
5062         $LFS getstripe $scrambledfile
5063         stripe=$($LFS getstripe -i $scrambledfile)
5064         [ $stripe -eq 1 ] || error "migrate file $scrambledfile failed"
5065         cancel_lru_locks
5066
5067         # now, with the key
5068         remount_client_dummykey
5069         cmp -bl $tmpfile $testfile ||
5070                 error "migrated file is corrupted"
5071
5072         # remount without dummy encryption key
5073         remount_client_normally
5074
5075         $LFS mirror extend -N -i0 $scrambledfile ||
5076                 error "mirror extend $scrambledfile failed (1)"
5077         $LFS getstripe $scrambledfile
5078         mirror_count=$($LFS getstripe -N $scrambledfile)
5079         [ $mirror_count -eq 2 ] ||
5080                 error "mirror extend file $scrambledfile failed (2)"
5081         stripe=$($LFS getstripe --mirror-id=1 -i $scrambledfile)
5082         [ $stripe -eq 1 ] ||
5083                 error "mirror extend file $scrambledfile failed (3)"
5084         stripe=$($LFS getstripe --mirror-id=2 -i $scrambledfile)
5085         [ $stripe -eq 0 ] ||
5086                 error "mirror extend file $scrambledfile failed (4)"
5087
5088         $LFS mirror verify -vvv $scrambledfile ||
5089                 error "mirror verify failed (1)"
5090         if [ $($LFS mirror verify -v $scrambledfile 2>&1 |
5091                 grep -ci "only valid") -ne 0 ]; then
5092                 error "mirror verify failed (2)"
5093         fi
5094
5095         # now, with the key
5096         remount_client_dummykey
5097         verify_mirror $testfile $tmpfile
5098
5099         # remount without dummy encryption key
5100         remount_client_normally
5101
5102         $LFS mirror split --mirror-id 1 -d $scrambledfile ||
5103                 error "mirror split file $scrambledfile failed (1)"
5104         $LFS getstripe $scrambledfile
5105         mirror_count=$($LFS getstripe -N $scrambledfile)
5106         [ $mirror_count -eq 1 ] ||
5107                 error "mirror split file $scrambledfile failed (2)"
5108         stripe=$($LFS getstripe --mirror-id=1 -i $scrambledfile)
5109         [ -z "$stripe" ] || error "mirror split file $scrambledfile failed (3)"
5110         stripe=$($LFS getstripe --mirror-id=2 -i $scrambledfile)
5111         [ $stripe -eq 0 ] || error "mirror split file $scrambledfile failed (4)"
5112
5113         # now, with the key
5114         remount_client_dummykey
5115         cancel_lru_locks
5116         cmp -bl $tmpfile $testfile ||
5117                 error "extended/split file is corrupted"
5118 }
5119 run_test 59b "migrate/extend/split of encrypted files without key"
5120
5121 test_59c() {
5122         local dirname=$DIR/$tdir/subdir
5123         local scrambleddir
5124
5125         $LCTL get_param mdc.*.import | grep -q client_encryption ||
5126                 skip "client encryption not supported"
5127
5128         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
5129                 skip "need dummy encryption support"
5130
5131         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
5132
5133         (( "$MDS1_VERSION" > $(version_code 2.14.54.54) )) ||
5134                 skip "MDT migration not supported with older server"
5135
5136         stack_trap cleanup_for_enc_tests EXIT
5137         setup_for_enc_tests
5138
5139         $LFS setdirstripe -i 0 $dirname
5140         echo b > $dirname/subf
5141
5142         # remount without dummy encryption key
5143         remount_client_normally
5144
5145         scrambleddir=$(find $DIR/$tdir/ -maxdepth 1 -mindepth 1 -type d)
5146
5147         # migrate a non-empty encrypted dir
5148         $LFS migrate -m 1 $scrambleddir ||
5149                 error "migrate $scrambleddir between MDTs failed (1)"
5150
5151         stripe=$($LFS getdirstripe -i $scrambleddir)
5152         [ $stripe -eq 1 ] ||
5153                 error "migrate $scrambleddir between MDTs failed (2)"
5154
5155         # now, with the key
5156         insert_enc_key
5157         [ -f $dirname/subf ] ||
5158             error "migrate $scrambleddir between MDTs failed (3)"
5159         [ $(cat $dirname/subf) == "b" ] ||
5160             error "migrate $scrambleddir between MDTs failed (4)"
5161 }
5162 run_test 59c "MDT migrate of encrypted files without key"
5163
5164 test_60() {
5165         local testdir=$DIR/$tdir/mytestdir
5166         local testfile=$DIR/$tdir/$tfile
5167
5168         (( $MDS1_VERSION > $(version_code 2.14.53) )) ||
5169                 skip "Need MDS version at least 2.14.53"
5170
5171         $LCTL get_param mdc.*.import | grep -q client_encryption ||
5172                 skip "client encryption not supported"
5173
5174         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
5175                 skip "need dummy encryption support"
5176
5177         stack_trap cleanup_for_enc_tests EXIT
5178         setup_for_enc_tests
5179
5180         echo a > $DIR/$tdir/file1
5181         mkdir $DIR/$tdir/subdir
5182         echo b > $DIR/$tdir/subdir/subfile1
5183
5184         remove_enc_key
5185         # unmount client completely
5186         umount_client $MOUNT || error "umount $MOUNT failed"
5187         if is_mounted $MOUNT2; then
5188                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
5189         fi
5190
5191         # remount client with subdirectory mount
5192         export FILESET=/$tdir
5193         mount_client $MOUNT ${MOUNT_OPTS} || error "remount failed"
5194         if [ "$MOUNT_2" ]; then
5195                 mount_client $MOUNT2 ${MOUNT_OPTS} || error "remount failed"
5196         fi
5197         wait_ssk
5198
5199         ls -Rl $DIR || error "ls -Rl $DIR failed (1)"
5200
5201         # now, with the key
5202         remount_client_dummykey
5203         export FILESET=""
5204
5205         ls -Rl $DIR || error "ls -Rl $DIR failed (2)"
5206         cat $DIR/file1 || error "cat $DIR/$tdir/file1 failed"
5207         cat $DIR/subdir/subfile1 ||
5208                 error "cat $DIR/$tdir/subdir/subfile1 failed"
5209 }
5210 run_test 60 "Subdirmount of encrypted dir"
5211
5212 setup_61() {
5213         if $SHARED_KEY; then
5214                 export SK_UNIQUE_NM=true
5215                 export FILESET="/"
5216         fi
5217
5218         do_facet mgs $LCTL nodemap_activate 1
5219         wait_nm_sync active
5220
5221         do_facet mgs $LCTL nodemap_del c0 || true
5222         wait_nm_sync c0 id ''
5223
5224         do_facet mgs $LCTL nodemap_modify --name default \
5225                 --property admin --value 1
5226         do_facet mgs $LCTL nodemap_modify --name default \
5227                 --property trusted --value 1
5228         wait_nm_sync default admin_nodemap
5229         wait_nm_sync default trusted_nodemap
5230
5231         client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
5232         client_nid=$(h2nettype $client_ip)
5233         [[ "$client_nid" =~ ":" ]] && client_nid+="/128"
5234         do_facet mgs $LCTL nodemap_add c0
5235         do_facet mgs $LCTL nodemap_add_range \
5236                  --name c0 --range $client_nid || {
5237                 do_facet mgs $LCTL nodemap_del c0
5238                 return 1
5239         }
5240         do_facet mgs $LCTL nodemap_modify --name c0 \
5241                  --property admin --value 1
5242         do_facet mgs $LCTL nodemap_modify --name c0 \
5243                  --property trusted --value 1
5244         wait_nm_sync c0 admin_nodemap
5245         wait_nm_sync c0 trusted_nodemap
5246 }
5247
5248 cleanup_61() {
5249         do_facet mgs $LCTL nodemap_del c0
5250         do_facet mgs $LCTL nodemap_modify --name default \
5251                  --property admin --value 0
5252         do_facet mgs $LCTL nodemap_modify --name default \
5253                  --property trusted --value 0
5254         wait_nm_sync default admin_nodemap
5255         wait_nm_sync default trusted_nodemap
5256
5257         do_facet mgs $LCTL nodemap_activate 0
5258         wait_nm_sync active 0
5259
5260         if $SHARED_KEY; then
5261                 unset FILESET
5262                 export SK_UNIQUE_NM=false
5263         fi
5264
5265         mount_client $MOUNT ${MOUNT_OPTS} || error "re-mount failed"
5266         wait_ssk
5267 }
5268
5269 test_61() {
5270         local testfile=$DIR/$tdir/$tfile
5271         local readonly
5272
5273         readonly=$(do_facet mgs \
5274                         lctl get_param -n nodemap.default.readonly_mount)
5275         [ -n "$readonly" ] ||
5276                 skip "Server does not have readonly_mount nodemap flag"
5277
5278         stack_trap cleanup_61 EXIT
5279         for idx in $(seq 1 $MDSCOUNT); do
5280                 wait_recovery_complete mds$idx
5281         done
5282         umount_client $MOUNT || error "umount $MOUNT failed (1)"
5283
5284         # Activate nodemap, and mount rw.
5285         # Should succeed as rw mount is not forbidden by default.
5286         setup_61
5287         readonly=$(do_facet mgs \
5288                         lctl get_param -n nodemap.default.readonly_mount)
5289         [ $readonly -eq 0 ] ||
5290                 error "wrong default value for readonly_mount on default nodemap"
5291         readonly=$(do_facet mgs \
5292                         lctl get_param -n nodemap.c0.readonly_mount)
5293         [ $readonly -eq 0 ] ||
5294                 error "wrong default value for readonly_mount on nodemap c0"
5295
5296         zconf_mount_clients $HOSTNAME $MOUNT ${MOUNT_OPTS},rw ||
5297                 error "mount '-o rw' failed with default"
5298         wait_ssk
5299         findmnt $MOUNT --output=options -n -f | grep -q "rw," ||
5300                 error "should be rw mount"
5301         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5302         echo a > $testfile || error "write $testfile failed"
5303         umount_client $MOUNT || error "umount $MOUNT failed (2)"
5304
5305         # Now enforce read-only, and retry.
5306         do_facet mgs $LCTL nodemap_modify --name c0 \
5307                 --property readonly_mount --value 1
5308         wait_nm_sync c0 readonly_mount
5309         zconf_mount_clients $HOSTNAME $MOUNT ${MOUNT_OPTS} ||
5310                 error "mount failed"
5311         findmnt $MOUNT --output=options -n -f | grep -q "ro," ||
5312                 error "mount should have been turned into ro"
5313         cat $testfile || error "read $testfile failed (1)"
5314         echo b > $testfile && error "write $testfile should fail (1)"
5315         umount_client $MOUNT || error "umount $MOUNT failed (3)"
5316         zconf_mount_clients $HOSTNAME $MOUNT ${MOUNT_OPTS},rw ||
5317                 error "mount '-o rw' failed"
5318         findmnt $MOUNT --output=options -n -f | grep -q "ro," ||
5319                 error "mount rw should have been turned into ro"
5320         cat $testfile || error "read $testfile failed (2)"
5321         echo b > $testfile && error "write $testfile should fail (2)"
5322         umount_client $MOUNT || error "umount $MOUNT failed (4)"
5323         zconf_mount_clients $HOSTNAME $MOUNT ${MOUNT_OPTS},ro ||
5324                 error "mount '-o ro' failed"
5325         wait_ssk
5326         cat $testfile || error "read $testfile failed (3)"
5327         echo b > $testfile && error "write $testfile should fail (3)"
5328         umount_client $MOUNT || error "umount $MOUNT failed (5)"
5329 }
5330 run_test 61 "Nodemap enforces read-only mount"
5331
5332 test_62() {
5333         local testdir=$DIR/$tdir/mytestdir
5334         local testfile=$DIR/$tdir/$tfile
5335
5336         [[ $(facet_fstype ost1) == zfs ]] && skip "skip ZFS backend"
5337
5338         (( $MDS1_VERSION > $(version_code 2.15.51) )) ||
5339                 skip "Need MDS version at least 2.15.51"
5340
5341         $LCTL get_param mdc.*.import | grep -q client_encryption ||
5342                 skip "client encryption not supported"
5343
5344         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
5345                 skip "need dummy encryption support"
5346
5347         stack_trap cleanup_for_enc_tests EXIT
5348         setup_for_enc_tests
5349
5350         lfs setstripe -c -1 $DIR/$tdir
5351         touch $DIR/$tdir/${tfile}_1 || error "touch ${tfile}_1 failed"
5352         dd if=/dev/zero of=$DIR/$tdir/${tfile}_2 bs=1 count=1 conv=fsync ||
5353                 error "dd ${tfile}_2 failed"
5354
5355         # unmount the Lustre filesystem
5356         stopall || error "stopping for e2fsck run"
5357
5358         # run e2fsck on the MDT and OST devices
5359         local mds_host=$(facet_active_host $SINGLEMDS)
5360         local ost_host=$(facet_active_host ost1)
5361         local mds_dev=$(mdsdevname ${SINGLEMDS//mds/})
5362         local ost_dev=$(ostdevname 1)
5363
5364         run_e2fsck $mds_host $mds_dev "-n"
5365         run_e2fsck $ost_host $ost_dev "-n"
5366
5367         # mount the Lustre filesystem
5368         setupall || error "remounting the filesystem failed"
5369 }
5370 run_test 62 "e2fsck with encrypted files"
5371
5372 create_files() {
5373         local path
5374
5375         for path in "${paths[@]}"; do
5376                 touch $path
5377         done
5378 }
5379
5380 build_fids() {
5381         local path
5382
5383         for path in "${paths[@]}"; do
5384                 fids+=("$(lfs path2fid $path)")
5385         done
5386 }
5387
5388 check_fids() {
5389         for fid in "${fids[@]}"; do
5390                 echo $fid
5391                 respath=$(lfs fid2path $MOUNT $fid)
5392                 echo -e "\t" $respath
5393                 ls -li $respath >/dev/null
5394                 [ $? -eq 0 ] || error "fid2path $fid failed"
5395         done
5396 }
5397
5398 test_63() {
5399         declare -a fids
5400         declare -a paths
5401         local vaultdir1=$DIR/$tdir/vault1==dir
5402         local vaultdir2=$DIR/$tdir/vault2==dir
5403         local longfname1="longfilenamewitha=inthemiddletotestbehaviorregardingthedigestedform"
5404         local longdname="longdirectorynamewitha=inthemiddletotestbehaviorregardingthedigestedform"
5405         local longfname2="$longdname/${longfname1}2"
5406
5407         (( $MDS1_VERSION > $(version_code 2.15.53) )) ||
5408                 skip "Need MDS version at least 2.15.53"
5409
5410         $LCTL get_param mdc.*.import | grep -q client_encryption ||
5411                 skip "client encryption not supported"
5412
5413         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
5414                 skip "need dummy encryption support"
5415
5416         which fscrypt || skip "This test needs fscrypt userspace tool"
5417
5418         yes | fscrypt setup --force --verbose ||
5419                 echo "fscrypt global setup already done"
5420         sed -i 's/\(.*\)policy_version\(.*\):\(.*\)\"[0-9]*\"\(.*\)/\1policy_version\2:\3"2"\4/' \
5421                 /etc/fscrypt.conf
5422         yes | fscrypt setup --verbose $MOUNT ||
5423                 echo "fscrypt setup $MOUNT already done"
5424
5425         # enable_filename_encryption tunable only available for client
5426         # built against embedded llcrypt. If client is built against in-kernel
5427         # fscrypt, file names are always encrypted.
5428         $LCTL get_param mdc.*.connect_flags | grep -q name_encryption &&
5429           nameenc=$(lctl get_param -n llite.*.enable_filename_encryption |
5430                         head -n1)
5431         if [ -n "$nameenc" ]; then
5432                 do_facet mgs $LCTL set_param -P \
5433                         llite.*.enable_filename_encryption=1
5434                 [ $? -eq 0 ] ||
5435                         error "set_param -P \
5436                                 llite.*.enable_filename_encryption=1 failed"
5437
5438                 wait_update_facet --verbose client \
5439                         "$LCTL get_param -n llite.*.enable_filename_encryption \
5440                         | head -n1" 1 30 ||
5441                         error "enable_filename_encryption not set on client"
5442         fi
5443
5444         mkdir -p $vaultdir1
5445         echo -e 'mypass\nmypass' | fscrypt encrypt --verbose \
5446                 --source=custom_passphrase --name=protector_63_1 $vaultdir1 ||
5447                 error "fscrypt encrypt $vaultdir1 failed"
5448
5449         mkdir $vaultdir1/dirA
5450         mkdir $vaultdir1/$longdname
5451         paths=("$vaultdir1/fileA")
5452         paths+=("$vaultdir1/dirA/fileB")
5453         paths+=("$vaultdir1/$longfname1")
5454         paths+=("$vaultdir1/$longfname2")
5455         create_files
5456
5457         paths+=("$vaultdir1/dirA")
5458         paths+=("$vaultdir1/$longdname")
5459
5460         build_fids
5461         check_fids
5462
5463         fscrypt lock --verbose $vaultdir1 ||
5464                 error "fscrypt lock $vaultdir1 failed (1)"
5465
5466         check_fids
5467
5468         if [ -z "$nameenc" ]; then
5469                 echo "Rest of the test requires disabling name encryption"
5470                 exit 0
5471         fi
5472
5473         # disable name encryption
5474         do_facet mgs $LCTL set_param -P llite.*.enable_filename_encryption=0
5475         [ $? -eq 0 ] ||
5476                 error "set_param -P llite.*.enable_filename_encryption=0 failed"
5477
5478         wait_update_facet --verbose client \
5479                 "$LCTL get_param -n llite.*.enable_filename_encryption \
5480                 | head -n1" 0 30 ||
5481                 error "enable_filename_encryption not set back to default"
5482
5483         mkdir -p $vaultdir2
5484         echo -e 'mypass\nmypass' | fscrypt encrypt --verbose \
5485                 --source=custom_passphrase --name=protector_63_2 $vaultdir2 ||
5486                 error "fscrypt encrypt $vaultdir2 failed"
5487
5488         mkdir $vaultdir2/dirA
5489         mkdir $vaultdir2/$longdname
5490         paths=()
5491         fids=()
5492         paths=("$vaultdir2/fileA")
5493         paths+=("$vaultdir2/dirA/fileB")
5494         paths+=("$vaultdir2/$longfname1")
5495         paths+=("$vaultdir2/$longfname2")
5496         create_files
5497
5498         paths+=("$vaultdir2/dirA")
5499         paths+=("$vaultdir2/$longdname")
5500
5501         build_fids
5502         check_fids
5503
5504         fscrypt lock --verbose $vaultdir2 ||
5505                 error "fscrypt lock $vaultdir2 failed (2)"
5506
5507         check_fids
5508
5509         rm -rf $MOUNT/.fscrypt
5510 }
5511 run_test 63 "fid2path with encrypted files"
5512
5513 setup_64() {
5514         do_facet mgs $LCTL nodemap_activate 1
5515         wait_nm_sync active
5516
5517         do_facet mgs $LCTL nodemap_del c0 || true
5518         wait_nm_sync c0 id ''
5519
5520         do_facet mgs $LCTL nodemap_modify --name default \
5521                 --property admin --value 1
5522         do_facet mgs $LCTL nodemap_modify --name default \
5523                 --property trusted --value 1
5524         wait_nm_sync default admin_nodemap
5525         wait_nm_sync default trusted_nodemap
5526
5527         client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
5528         client_nid=$(h2nettype $client_ip)
5529         do_facet mgs $LCTL nodemap_add c0
5530         do_facet mgs $LCTL nodemap_add_range \
5531                  --name c0 --range $client_nid
5532         do_facet mgs $LCTL nodemap_modify --name c0 \
5533                  --property admin --value 1
5534         do_facet mgs $LCTL nodemap_modify --name c0 \
5535                  --property trusted --value 1
5536         wait_nm_sync c0 admin_nodemap
5537         wait_nm_sync c0 trusted_nodemap
5538 }
5539
5540 cleanup_64() {
5541         do_facet mgs $LCTL nodemap_del c0
5542         do_facet mgs $LCTL nodemap_modify --name default \
5543                  --property admin --value 0
5544         do_facet mgs $LCTL nodemap_modify --name default \
5545                  --property trusted --value 0
5546         wait_nm_sync default admin_nodemap
5547         wait_nm_sync default trusted_nodemap
5548
5549         do_facet mgs $LCTL nodemap_activate 0
5550         wait_nm_sync active 0
5551 }
5552
5553 test_64a() {
5554         local testfile=$DIR/$tdir/$tfile
5555         local rbac
5556
5557         (( MDS1_VERSION >= $(version_code 2.15.54) )) ||
5558                 skip "Need MDS >= 2.15.54 for role-based controls"
5559
5560         stack_trap cleanup_64 EXIT
5561         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5562         setup_64
5563
5564         # check default value for rbac is all
5565         rbac=$(do_facet mds $LCTL get_param -n nodemap.c0.rbac)
5566         for role in file_perms \
5567                     dne_ops \
5568                     quota_ops \
5569                     byfid_ops \
5570                     chlg_ops \
5571                     fscrypt_admin \
5572                     ;
5573         do
5574                 [[ "$rbac" =~ "$role" ]] ||
5575                         error "role '$role' not in default '$rbac'"
5576         done
5577
5578         do_facet mgs $LCTL nodemap_modify --name c0 \
5579                  --property rbac --value file_perms
5580         wait_nm_sync c0 rbac
5581         touch $testfile
5582         stack_trap "set +vx"
5583         set -vx
5584         chmod 777 $testfile || error "chmod failed"
5585         chown $TSTUSR:$TSTUSR $testfile || error "chown failed"
5586         chgrp $TSTUSR $testfile || error "chgrp failed"
5587         $LFS project -p 1000 $testfile || error "setting project failed"
5588         set +vx
5589         rm -f $testfile
5590         do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none
5591         wait_nm_sync c0 rbac
5592         touch $testfile
5593         set -vx
5594         chmod 777 $testfile && error "chmod should fail"
5595         chown $TSTUSR:$TSTUSR $testfile && error "chown should fail"
5596         chgrp $TSTUSR $testfile && error "chgrp should fail"
5597         $LFS project -p 1000 $testfile && error "setting project should fail"
5598         set +vx
5599 }
5600 run_test 64a "Nodemap enforces file_perms RBAC roles"
5601
5602 test_64b() {
5603         local testdir=$DIR/$tdir/${tfile}.d
5604         local dir_restripe
5605
5606         (( MDS1_VERSION >= $(version_code 2.15.54) )) ||
5607                 skip "Need MDS >= 2.15.54 for role-based controls"
5608
5609         (( MDSCOUNT >= 2 )) || skip "mdt count $MDSCOUNT, skipping dne_ops role"
5610
5611         stack_trap cleanup_64 EXIT
5612         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5613         setup_64
5614
5615         dir_restripe=$(do_node $mds1_HOST \
5616                 "$LCTL get_param -n mdt.*MDT0000.enable_dir_restripe")
5617         [ -n "$dir_restripe" ] || dir_restripe=0
5618         do_nodes $(comma_list $(all_mdts_nodes)) \
5619                 $LCTL set_param mdt.*.enable_dir_restripe=1 ||
5620                         error "enabling dir_restripe failed"
5621         stack_trap "do_nodes $(comma_list $(all_mdts_nodes)) \
5622               $LCTL set_param mdt.*.enable_dir_restripe=$dir_restripe" EXIT
5623         do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \
5624                  --value dne_ops
5625         wait_nm_sync c0 rbac
5626         $LFS mkdir -i 0 ${testdir}_for_migr ||
5627                 error "$LFS mkdir ${testdir}_for_migr failed (1)"
5628         touch ${testdir}_for_migr/file001 ||
5629                 error "touch ${testdir}_for_migr/file001 failed (1)"
5630         $LFS mkdir -i 0 ${testdir}_mdt0 ||
5631                 error "$LFS mkdir ${testdir}_mdt0 failed (1)"
5632         $LFS mkdir -i 1 ${testdir}_mdt1 ||
5633                 error "$LFS mkdir ${testdir}_mdt1 failed (1)"
5634         set -vx
5635         $LFS mkdir -i 1 $testdir || error "$LFS mkdir failed (1)"
5636         rmdir $testdir
5637         $LFS mkdir -c 2 $testdir || error "$LFS mkdir failed (2)"
5638         rmdir $testdir
5639         mkdir $testdir
5640         $LFS setdirstripe -c 2 $testdir || error "$LFS setdirstripe failed"
5641         rmdir $testdir
5642         $LFS migrate -m 1 ${testdir}_for_migr || error "$LFS migrate failed"
5643         touch ${testdir}_mdt0/fileA || error "touch fileA failed (1)"
5644         mv ${testdir}_mdt0/fileA ${testdir}_mdt1/ || error "mv failed (1)"
5645         set +vx
5646         rm -rf ${testdir}*
5647         $LFS mkdir -i 0 ${testdir}_for_migr ||
5648                 error "$LFS mkdir ${testdir}_for_migr failed (2)"
5649         touch ${testdir}_for_migr/file001 ||
5650                 error "touch ${testdir}_for_migr/file001 failed (2)"
5651         $LFS mkdir -i 0 ${testdir}_mdt0 ||
5652                 error "$LFS mkdir ${testdir}_mdt0 failed (2)"
5653         $LFS mkdir -i 1 ${testdir}_mdt1 ||
5654                 error "$LFS mkdir ${testdir}_mdt1 failed (2)"
5655
5656         do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none
5657         wait_nm_sync c0 rbac
5658         set -vx
5659         $LFS mkdir -i 1 $testdir && error "$LFS mkdir should fail (1)"
5660         $LFS mkdir -c 2 $testdir && error "$LFS mkdir should fail (2)"
5661         mkdir $testdir
5662         $LFS setdirstripe -c 2 $testdir && error "$LFS setdirstripe should fail"
5663         rmdir $testdir
5664         $LFS migrate -m 1 ${testdir}_for_migr &&
5665                 error "$LFS migrate should fail"
5666         touch ${testdir}_mdt0/fileA || error "touch fileA failed (2)"
5667         mv ${testdir}_mdt0/fileA ${testdir}_mdt1/ || error "mv failed (2)"
5668         set +vx
5669 }
5670 run_test 64b "Nodemap enforces dne_ops RBAC roles"
5671
5672 test_64c() {
5673         (( MDS1_VERSION >= $(version_code 2.15.54) )) ||
5674                 skip "Need MDS >= 2.15.54 for role-based controls"
5675
5676         stack_trap cleanup_64 EXIT
5677         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5678         setup_64
5679
5680         do_facet mgs $LCTL nodemap_modify --name c0 \
5681                  --property rbac --value quota_ops
5682         wait_nm_sync c0 rbac
5683         set -vx
5684         $LFS setquota -u $USER0 -b 307200 -B 309200 -i 10000 -I 11000 $MOUNT ||
5685                 error "lfs setquota -u failed"
5686         $LFS setquota -u $USER0 --delete $MOUNT
5687         $LFS setquota -g $USER0 -b 307200 -B 309200 -i 10000 -I 11000 $MOUNT ||
5688                 error "lfs setquota -g failed"
5689         $LFS setquota -g $USER0 --delete $MOUNT
5690         $LFS setquota -p 1000 -b 307200 -B 309200 -i 10000 -I 11000 $MOUNT ||
5691                 error "lfs setquota -p failed"
5692         $LFS setquota -p 1000 --delete $MOUNT
5693
5694         $LFS setquota -U -b 10G -B 11G -i 100K -I 105K $MOUNT ||
5695                 error "lfs setquota -U failed"
5696         $LFS setquota -U -b 0 -B 0 -i 0 -I 0 $MOUNT
5697         $LFS setquota -G -b 10G -B 11G -i 100K -I 105K $MOUNT ||
5698                 error "lfs setquota -G failed"
5699         $LFS setquota -G -b 0 -B 0 -i 0 -I 0 $MOUNT
5700         $LFS setquota -P -b 10G -B 11G -i 100K -I 105K $MOUNT ||
5701                 error "lfs setquota -P failed"
5702         $LFS setquota -P -b 0 -B 0 -i 0 -I 0 $MOUNT
5703         $LFS setquota -u $USER0 -D $MOUNT ||
5704                 error "lfs setquota -u -D failed"
5705         $LFS setquota -u $USER0 --delete $MOUNT
5706         $LFS setquota -g $USER0 -D $MOUNT ||
5707                 error "lfs setquota -g -D failed"
5708         $LFS setquota -g $USER0 --delete $MOUNT
5709         $LFS setquota -p 1000 -D $MOUNT ||
5710                 error "lfs setquota -p -D failed"
5711         $LFS setquota -p 1000 --delete $MOUNT
5712         set +vx
5713
5714         do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none
5715         wait_nm_sync c0 rbac
5716
5717         set -vx
5718         $LFS setquota -u $USER0 -b 307200 -B 309200 -i 10000 -I 11000 $MOUNT &&
5719                 error "lfs setquota -u should fail"
5720         $LFS setquota -u $USER0 --delete $MOUNT
5721         $LFS setquota -g $USER0 -b 307200 -B 309200 -i 10000 -I 11000 $MOUNT &&
5722                 error "lfs setquota -g should fail"
5723         $LFS setquota -g $USER0 --delete $MOUNT
5724         $LFS setquota -p 1000 -b 307200 -B 309200 -i 10000 -I 11000 $MOUNT &&
5725                 error "lfs setquota -p should fail"
5726         $LFS setquota -p 1000 --delete $MOUNT
5727
5728         $LFS setquota -U -b 10G -B 11G -i 100K -I 105K $MOUNT &&
5729                 error "lfs setquota -U should fail"
5730         $LFS setquota -G -b 10G -B 11G -i 100K -I 105K $MOUNT &&
5731                 error "lfs setquota -G should fail"
5732         $LFS setquota -P -b 10G -B 11G -i 100K -I 105K $MOUNT &&
5733                 error "lfs setquota -P should fail"
5734         $LFS setquota -u $USER0 -D $MOUNT &&
5735                 error "lfs setquota -u -D should fail"
5736         $LFS setquota -u $USER0 --delete $MOUNT
5737         $LFS setquota -g $USER0 -D $MOUNT &&
5738                 error "lfs setquota -g -D should fail"
5739         $LFS setquota -g $USER0 --delete $MOUNT
5740         $LFS setquota -p 1000 -D $MOUNT &&
5741                 error "lfs setquota -p -D should fail"
5742         $LFS setquota -p 1000 --delete $MOUNT
5743         set +vx
5744 }
5745 run_test 64c "Nodemap enforces quota_ops RBAC roles"
5746
5747 test_64d() {
5748         local testfile=$DIR/$tdir/$tfile
5749         local fid
5750
5751         (( MDS1_VERSION >= $(version_code 2.15.54) )) ||
5752                 skip "Need MDS >= 2.15.54 for role-based controls"
5753
5754         stack_trap cleanup_64 EXIT
5755         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5756         setup_64
5757
5758         do_facet mgs $LCTL nodemap_modify --name c0 \
5759                  --property rbac --value byfid_ops
5760         wait_nm_sync c0 rbac
5761
5762         touch $testfile
5763         fid=$(lfs path2fid $testfile)
5764         set -vx
5765         $LFS fid2path $MOUNT $fid || error "fid2path $fid failed (1)"
5766         cat $MOUNT/.lustre/fid/$fid || error "cat by fid failed"
5767         lfs rmfid $MOUNT $fid || error "lfs rmfid failed"
5768         set +vx
5769
5770         do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none
5771         wait_nm_sync c0 rbac
5772
5773         touch $testfile
5774         fid=$(lfs path2fid $testfile)
5775         set -vx
5776         $LFS fid2path $MOUNT $fid || error "fid2path $fid failed (2)"
5777         cat $MOUNT/.lustre/fid/$fid && error "cat by fid should fail"
5778         lfs rmfid $MOUNT $fid && error "lfs rmfid should fail"
5779         set +vx
5780         rm -f $testfile
5781 }
5782 run_test 64d "Nodemap enforces byfid_ops RBAC roles"
5783
5784 test_64e() {
5785         local testfile=$DIR/$tdir/$tfile
5786         local testdir=$DIR/$tdir/${tfile}.d
5787
5788         (( MDS1_VERSION >= $(version_code 2.15.54) )) ||
5789                 skip "Need MDS >= 2.15.54 for role-based controls"
5790
5791         stack_trap cleanup_64 EXIT
5792         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5793         setup_64
5794
5795         # activate changelogs
5796         changelog_register || error "changelog_register failed"
5797         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
5798         changelog_users $SINGLEMDS | grep -q $cl_user ||
5799                 error "User $cl_user not found in changelog_users"
5800         changelog_chmask ALL
5801
5802         # do some IOs
5803         mkdir $testdir || error "failed to mkdir $testdir"
5804         touch $testfile || error "failed to touch $testfile"
5805
5806         do_facet mgs $LCTL nodemap_modify --name c0 \
5807                  --property rbac --value chlg_ops
5808         wait_nm_sync c0 rbac
5809
5810         # access changelogs
5811         echo "changelogs dump"
5812         changelog_dump || error "failed to dump changelogs"
5813         echo "changelogs clear"
5814         changelog_clear 0 || error "failed to clear changelogs"
5815
5816         rm -rf $testdir $testfile || error "rm -rf $testdir $testfile failed"
5817
5818         do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none
5819         wait_nm_sync c0 rbac
5820
5821         # do some IOs
5822         mkdir $testdir || error "failed to mkdir $testdir"
5823         touch $testfile || error "failed to touch $testfile"
5824
5825         # access changelogs
5826         echo "changelogs dump"
5827         changelog_dump && error "dump changelogs should fail"
5828         echo "changelogs clear"
5829         changelog_clear 0 && error "clear changelogs should fail"
5830         rm -rf $testdir $testfile
5831
5832         do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value all
5833         wait_nm_sync c0 rbac
5834 }
5835 run_test 64e "Nodemap enforces chlg_ops RBAC roles"
5836
5837 test_64f() {
5838         local vaultdir=$DIR/$tdir/vault
5839         local cli_enc
5840         local policy
5841         local protector
5842
5843         (( MDS1_VERSION >= $(version_code 2.15.54) )) ||
5844                 skip "Need MDS >= 2.15.54 for role-based controls"
5845
5846         cli_enc=$($LCTL get_param mdc.*.import | grep client_encryption)
5847         [ -n "$cli_enc" ] || skip "Need enc support, skip fscrypt_admin role"
5848         which fscrypt || skip "Need fscrypt, skip fscrypt_admin role"
5849
5850         stack_trap cleanup_64 EXIT
5851         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5852         setup_64
5853
5854         yes | fscrypt setup --force --verbose ||
5855                 echo "fscrypt global setup already done"
5856         sed -i 's/\(.*\)policy_version\(.*\):\(.*\)\"[0-9]*\"\(.*\)/\1policy_version\2:\3"2"\4/' \
5857                 /etc/fscrypt.conf
5858         yes | fscrypt setup --verbose $MOUNT ||
5859                 echo "fscrypt setup $MOUNT already done"
5860         stack_trap "rm -rf $MOUNT/.fscrypt"
5861
5862         # file_perms is required because fscrypt uses chmod/chown
5863         do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \
5864                 --value fscrypt_admin,file_perms
5865         wait_nm_sync c0 rbac
5866
5867         mkdir -p $vaultdir
5868         set -vx
5869         echo -e 'mypass\nmypass' | fscrypt encrypt --verbose \
5870              --source=custom_passphrase --name=protector_64 $vaultdir ||
5871                 error "fscrypt encrypt $vaultdir failed"
5872         fscrypt lock $vaultdir || error "fscrypt lock $vaultdir failed (1)"
5873         policy=$(fscrypt status $vaultdir | awk '$1 == "Policy:"{print $2}')
5874         [ -n "$policy" ] || error "could not get enc policy"
5875         protector=$(fscrypt status $vaultdir |
5876                   awk 'BEGIN {found=0} { if (found == 1) { print $1 }} \
5877                         $1 == "PROTECTOR" {found=1}')
5878         [ -n "$protector" ] || error "could not get enc protector"
5879         set +vx
5880
5881         cancel_lru_locks
5882         # file_perms is required because fscrypt uses chmod/chown
5883         do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \
5884                 --value file_perms
5885         wait_nm_sync c0 rbac
5886
5887         set -vx
5888         echo mypass | fscrypt unlock $vaultdir ||
5889                 error "fscrypt unlock $vaultdir failed"
5890         fscrypt lock $vaultdir || error "fscrypt lock $vaultdir failed (2)"
5891         fscrypt metadata destroy --protector=$MOUNT:$protector --force &&
5892                 error "destroy protector should fail"
5893         fscrypt metadata destroy --policy=$MOUNT:$policy --force &&
5894                 error "destroy policy should fail"
5895         mkdir -p ${vaultdir}2
5896         echo -e 'mypass\nmypass' | fscrypt encrypt --verbose \
5897                 --source=custom_passphrase \
5898                 --name=protector_64bis ${vaultdir}2 &&
5899                         error "fscrypt encrypt ${vaultdir}2 should fail"
5900         set +vx
5901
5902         cancel_lru_locks
5903         do_facet mgs $LCTL nodemap_modify --name c0 --property rbac  --value all
5904         wait_nm_sync c0 rbac
5905
5906         set -vx
5907         fscrypt metadata destroy --protector=$MOUNT:$protector --force ||
5908                 error "destroy protector failed"
5909         fscrypt metadata destroy --policy=$MOUNT:$policy --force ||
5910                 error "destroy policy failed"
5911         set +vx
5912
5913         rm -rf ${vaultdir}*
5914 }
5915 run_test 64f "Nodemap enforces fscrypt_admin RBAC roles"
5916
5917 look_for_files() {
5918         local pattern=$1
5919         local neg=$2
5920         local path=$3
5921         local expected=$4
5922         local res
5923
5924         (( neg == 1 )) || neg=""
5925         $LFS find -type f ${neg:+"!"} --attrs $pattern $path > $TMP/res
5926         cat $TMP/res
5927         res=$(cat $TMP/res | wc -l)
5928         (( res == $expected )) ||
5929                 error "Find $pattern $path: found $res, expected $expected"
5930 }
5931
5932 test_65() {
5933         local dirbis=$DIR/${tdir}_bis
5934         local testfile=$DIR/$tdir/$tfile
5935         local res
5936
5937         $LCTL get_param mdc.*.import | grep -q client_encryption ||
5938                 skip "client encryption not supported"
5939
5940         mount.lustre --help |& grep -q "test_dummy_encryption:" ||
5941                 skip "need dummy encryption support"
5942
5943         # $dirbis is not going to be encrypted, as client
5944         # is not mounted with -o test_dummy_encryption yet
5945         mkdir $dirbis
5946         stack_trap "rm -rf $dirbis" EXIT
5947         touch $dirbis/$tfile.1
5948         touch $dirbis/$tfile.2
5949         chattr +i $dirbis/$tfile.2
5950         stack_trap "chattr -i $dirbis/$tfile.2" EXIT
5951
5952         stack_trap cleanup_for_enc_tests EXIT
5953         setup_for_enc_tests
5954
5955         # All files/dirs under $DIR/$tdir are encrypted
5956         touch $testfile.1
5957         touch $testfile.2
5958         chattr +i $testfile.2
5959         stack_trap "chattr -i $testfile.2" EXIT
5960
5961         $LFS find -printf "%p %LA\n" $dirbis/$tfile.1
5962         res=$($LFS find -printf "%LA" $dirbis/$tfile.1)
5963         [ "$res" == "---" ] ||
5964                 error "$dirbis/$tfile.1 should have no attr, showed $res (1)"
5965         $LFS find -printf "%p %La\n" $dirbis/$tfile.1
5966         res=$($LFS find -printf "%La" $dirbis/$tfile.1)
5967         [ "$res" == "---" ] ||
5968                 error "$dirbis/$tfile.1 should have no attr, showed $res (2)"
5969         $LFS find -printf "%p %LA\n" $dirbis/$tfile.2
5970         res=$($LFS find -printf "%LA" $dirbis/$tfile.2)
5971         [ "$res" == "Immutable" ] ||
5972                 error "$dirbis/$tfile.2 should be Immutable, showed $res"
5973         $LFS find -printf "%p %La\n" $dirbis/$tfile.2
5974         res=$($LFS find -printf "%La" $dirbis/$tfile.2)
5975         [ "$res" == "i" ] ||
5976                 error "$dirbis/$tfile.2 should be 'i', showed $res"
5977         $LFS find -printf "%p %LA\n" $testfile.1
5978         res=$($LFS find -printf "%LA" $testfile.1)
5979         [ "$res" == "Encrypted" ] ||
5980                 error "$testfile.1 should be Encrypted, showed $res"
5981         $LFS find -printf "%p %La\n" $testfile.1
5982         res=$($LFS find -printf "%La" $testfile.1)
5983         [ "$res" == "E" ] ||
5984                 error "$testfile.1 should be 'E', showed $res"
5985         $LFS find -printf "%p %LA\n" $testfile.2
5986         res=$($LFS find -printf "%LA" $testfile.2)
5987         [ "$res" == "Immutable,Encrypted" ] ||
5988                 error "$testfile.2 should be Immutable,Encrypted, showed $res"
5989         $LFS find -printf "%p %La\n" $testfile.2
5990         res=$($LFS find -printf "%La" $testfile.2)
5991         [ "$res" == "iE" ] ||
5992                 error "$testfile.2 should be 'iE', showed $res"
5993
5994         echo Expecting to find 2 encrypted files
5995         look_for_files Encrypted 0 "$DIR/${tdir}*" 2
5996         echo Expecting to find 2 encrypted files
5997         look_for_files E 0 "$DIR/${tdir}*" 2
5998
5999         echo Expecting to find 2 non-encrypted files
6000         look_for_files Encrypted 1 "$DIR/${tdir}*" 2
6001         echo Expecting to find 2 non-encrypted files
6002         look_for_files E 1 "$DIR/${tdir}*" 2
6003
6004         echo Expecting to find 1 encrypted+immutable file
6005         look_for_files "Encrypted,Immutable" 0 "$DIR/${tdir}*" 1
6006         echo Expecting to find 1 encrypted+immutable file
6007         look_for_files "Ei" 0 "$DIR/${tdir}*" 1
6008
6009         echo Expecting to find 1 encrypted+^immutable file
6010         look_for_files "Encrypted,^Immutable" 0 "$DIR/${tdir}*" 1
6011         echo Expecting to find 1 encrypted+^immutable file
6012         look_for_files "E^i" 0 "$DIR/${tdir}*" 1
6013
6014         echo Expecting to find 1 ^encrypted+immutable file
6015         look_for_files "^Encrypted,Immutable" 0 "$DIR/${tdir}*" 1
6016         echo Expecting to find 1 ^encrypted+immutable file
6017         look_for_files "^Ei" 0 "$DIR/${tdir}*" 1
6018
6019         echo Expecting to find 1 ^encrypted+^immutable file
6020         look_for_files "^Encrypted,^Immutable" 0 "$DIR/${tdir}*" 1
6021         echo Expecting to find 1 ^encrypted+^immutable file
6022         look_for_files "^E^i" 0 "$DIR/${tdir}*" 1
6023 }
6024 run_test 65 "lfs find -printf %La and --attrs support"
6025
6026 log "cleanup: ======================================================"
6027
6028 sec_unsetup() {
6029         for ((num = 1; num <= $MDSCOUNT; num++)); do
6030                 if [[ "${identity_old[$num]}" == 1 ]]; then
6031                         switch_identity $num false || identity_old[$num]=$?
6032                 fi
6033         done
6034
6035         $RUNAS_CMD -u $ID0 ls $DIR
6036         $RUNAS_CMD -u $ID1 ls $DIR
6037 }
6038 sec_unsetup
6039
6040 complete_test $SECONDS
6041 check_and_cleanup_lustre
6042 exit_status