Whamcloud - gitweb
LU-17662 osd-zfs: Support for ZFS 2.2.3
[fs/lustre-release.git] / lustre / tests / sanity-selinux.sh
1 #!/bin/bash
2 #
3 # NOTE
4 # In order to be able to do the runcon commands in test_4,
5 # the SELinux policy must allow transitions from unconfined_t
6 # to user_t and guest_t:
7 # #============= unconfined_r ==============
8 # allow unconfined_r guest_r;
9 # allow unconfined_r user_r;
10 #
11 # Run select tests by setting ONLY, or as arguments to the script.
12 # Skip specific tests by setting EXCEPT.
13 #
14 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
15 set -e
16
17 ONLY=${ONLY:-"$*"}
18
19 LUSTRE=${LUSTRE:-$(dirname $0)/..}
20 . $LUSTRE/tests/test-framework.sh
21 init_test_env "$@"
22 init_logging
23
24 ALWAYS_EXCEPT="$SANITY_SELINUX_EXCEPT"
25
26 [ "$SLOW" = "no" ] && EXCEPT_SLOW="xxx"
27
28 build_test_filter
29
30 require_dsh_mds || exit 0
31
32 RUNAS_CMD=${RUNAS_CMD:-runas}
33 # $RUNAS_ID may get set incorrectly somewhere else
34 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
35         error "RUNAS_ID set to 0, but UID is also 0!"
36
37 #
38 # global variables of this  sanity
39 #
40
41 check_selinux() {
42         echo -n "Checking SELinux environment... "
43         local selinux_status=$(getenforce)
44         if [ "$selinux_status" != "Enforcing" ]; then
45             skip "SELinux is currently in $selinux_status mode," \
46                  "but it must be enforced to run sanity-selinux" && exit 0
47         fi
48         local selinux_policy=$(sestatus |
49                 awk -F':' '$1 == "Loaded policy name" {print $2}' | xargs)
50         if [ -z "$selinux_policy" ]; then
51             selinux_policy=$(sestatus |
52                 awk -F':' '$1 == "Policy from config file" {print $2}' | xargs)
53         fi
54         [ "$selinux_policy" == "targeted" ] ||
55                 error "Accepting only targeted policy"
56         echo "$selinux_status, $selinux_policy"
57 }
58
59 check_selinux
60
61 # we want double mount
62 MOUNT_2=${MOUNT_2:-"yes"}
63 check_and_setup_lustre
64
65 rm -rf $DIR/[df][0-9]*
66
67 check_runas_id $RUNAS_ID $RUNAS_ID $RUNAS
68
69 umask 077
70
71 check_selinux_xattr() {
72         local mds=$1
73         local mds_path=$2
74         local mntpt="/tmp/mdt_"
75
76         do_facet $mds mkdir -p $mntpt || error "mkdir $mntpt failed"
77         mount_fstype $mds $mntpt  || error "mount $mds failed"
78
79         local xattrval=$(do_facet $mds getfattr -n security.selinux \
80                                 ${mntpt}/ROOT/$mds_path |
81                          awk -F"=" '$1=="security.selinux" {print $2}')
82
83         unmount_fstype $mds $mntpt || error "umount $mds failed"
84         do_facet $mds rmdir $mntpt || error "rmdir $mntpt failed"
85
86         echo $xattrval
87 }
88
89 get_sel_ctx() {
90         local file=$1
91
92         [ -n "$file" ] || return;
93         [ -f $file ] || return;
94         stat $file | awk '$1 == "Context:" {print $2}'
95 }
96
97 test_1() {
98         local filename=${DIR}/${tdir}/df1
99         local mds_path=${filename#$MOUNT}
100
101         mds_path=${mds_path#/}
102
103         $LFS setdirstripe -i0 -c1 ${DIR}/$tdir || error "create dir $tdir failed"
104         touch $filename || error "cannot touch $filename"
105
106         local xattrval=$(check_selinux_xattr "mds1" $mds_path)
107
108         [ -n "$xattrval" -a "$xattrval" != '""' ] ||
109                 error "security.selinux xattr is not set"
110 }
111 run_test 1 "create file and check security.selinux xattr is set on MDT"
112
113 test_2a() {
114         local dirname=${DIR}/${tdir}/dir2a
115         local mds_path=${dirname#$MOUNT}
116
117         mds_path=${mds_path#/}
118
119         mkdir_on_mdt0 ${DIR}/$tdir || error "create dir failed"
120         mkdir $dirname || error "cannot mkdir $dirname"
121
122         local xattrval=$(check_selinux_xattr "mds1" $mds_path)
123
124         [ -n "$xattrval" -a "$xattrval" != '""' ] ||
125                 error "security.selinux xattr is not set"
126 }
127 run_test 2a "create dir (mkdir) and check security.selinux xattr is set on MDT"
128
129 test_2b() {
130         local dirname1=${DIR}/$tdir/dir2b1
131         local dirname2=${DIR}/$tdir/dir2b2
132         local mds_path=${dirname1#$MOUNT}
133
134         mds_path=${mds_path#/}
135
136         $LFS setdirstripe -i0 -c1 ${DIR}/$tdir || error "create dir failed"
137         $LFS mkdir -c0 -i0 $dirname1 || error "cannot 'lfs mkdir' $dirname1"
138
139         local xattrval=$(check_selinux_xattr "mds1" $mds_path)
140
141         mds_path=${dirname2#$MOUNT}
142         mds_path=${mds_path#/}
143
144         [ -n "$xattrval" -a "$xattrval" != '""' ] ||
145                 error "security.selinux xattr is not set"
146
147         $LFS setdirstripe -i0 $dirname2 ||
148             error "cannot 'lfs setdirstripe' $dirname2"
149
150         xattrval=$(check_selinux_xattr "mds1" $mds_path)
151
152         [ -n "$xattrval" -a "$xattrval" != '""' ] ||
153                 error "security.selinux xattr is not set"
154 }
155 run_test 2b "create dir with lfs and check security.selinux xattr is set on MDT"
156
157 test_3() {
158         local filename=$DIR/$tdir/df3
159         local level=$(id -Z | cut -d':' -f4-)
160         local unconctx="-u unconfined_u -r unconfined_r -t unconfined_t \
161                         -l $level"
162
163         mkdir -p $DIR/$tdir
164         chmod 777 $DIR/$tdir
165
166         # "access" Lustre
167         echo "As unconfined_u: touch $filename"
168         $RUNAS_CMD -u $RUNAS_ID runcon $unconctx touch $filename ||
169                 error "can't touch $filename"
170         echo "As unconfined_u: rm -f $filename"
171         $RUNAS_CMD -u $RUNAS_ID runcon $unconctx rm -f $filename ||
172                 error "can't remove $filename"
173
174         return 0
175 }
176 run_test 3 "access with unconfined user"
177
178 test_4() {
179         local filename=$DIR/$tdir/df4
180         local guestctx="-u guest_u -r guest_r -t guest_t -l s0"
181         local usrctx="-u user_u -r user_r -t user_t -l s0"
182
183         sesearch --role_allow | grep -q "allow unconfined_r user_r"
184         if [ $? -ne 0 ]; then
185             skip "SELinux policy module must allow transition from \
186                    unconfined_r to user_r for this test." && exit 0
187         fi
188         sesearch --role_allow | grep -q "allow unconfined_r guest_r"
189         if [ $? -ne 0 ]; then
190             skip "SELinux policy module must allow transition from \
191                    unconfined_r to guest_r for this test." && exit 0
192         fi
193
194         mkdir -p $DIR/$tdir
195         chmod 777 $DIR/$tdir
196
197         # "access" Lustre
198         echo "As guest_u: touch $filename"
199         $RUNAS_CMD -u $RUNAS_ID runcon $guestctx touch $filename &&
200                 error "touch $filename should have failed"
201
202         # "access" Lustre
203         echo "As user_u: touch $filename"
204         $RUNAS_CMD -u $RUNAS_ID runcon $usrctx touch $filename ||
205                 error "can't touch $filename"
206         echo "As user_u: rm -f $filename"
207         $RUNAS_CMD -u $RUNAS_ID runcon $usrctx rm -f $filename ||
208                 error "can't remove $filename"
209
210         return 0
211 }
212 run_test 4 "access with specific SELinux user"
213
214 test_5() {
215         local filename=$DIR/df5
216         local newsecctx="nfs_t"
217
218         # create file
219         touch $filename || error "cannot touch $filename"
220
221         # change sec context
222         chcon -t $newsecctx $filename
223         ls -lZ $filename
224
225         # purge client's cache
226         sync ; echo 3 > /proc/sys/vm/drop_caches
227
228         # get sec context
229         ls -lZ $filename
230         local secctxseen=$(get_sel_ctx $filename | cut -d: -f3)
231
232         [ "$newsecctx" == "$secctxseen" ] ||
233                 error "sec context seen from 1st mount point is not correct"
234
235         return 0
236 }
237 run_test 5 "security context retrieval from MDT xattr"
238
239 test_10() {
240         local filename1=$DIR/df10
241         local filename2=$DIR2/df10
242         local newsecctx="nfs_t"
243
244         # create file from 1st mount point
245         touch $filename1 || error "cannot touch $filename1"
246         ls -lZ $filename1
247
248         # change sec context from 2nd mount point
249         chcon -t $newsecctx $filename2
250         ls -lZ $filename2
251
252         # get sec context from 1st mount point
253         ls -lZ $filename1
254         local secctxseen=$(get_sel_ctx $filename1 | cut -d: -f3)
255
256         [ "$newsecctx" == "$secctxseen" ] ||
257                 error_ignore LU-6784 \
258                     "sec context seen from 1st mount point is not correct"
259
260         return 0
261 }
262 run_test 10 "[consistency] concurrent security context change"
263
264 test_20a() {
265         local filename1=$DIR/$tdir/df20a
266         local filename2=$DIR2/$tdir/df20a
267         local req_delay=20
268         local unconctx="-u unconfined_u -r unconfined_r -t unconfined_t -l s0"
269
270         mkdir -p $DIR/$tdir
271         chmod 777 $DIR/$tdir
272
273         # sleep some time in ll_create_nd()
274         #define OBD_FAIL_LLITE_CREATE_FILE_PAUSE   0x1409
275         do_facet client "$LCTL set_param fail_val=$req_delay fail_loc=0x1409"
276
277         # create file on first mount point
278         $RUNAS_CMD -u $RUNAS_ID runcon $unconctx touch $filename1 &
279         local touchpid=$!
280         sleep 5
281
282         if [[ -z "$(ps h -o comm -p $touchpid)" ]]; then
283                 error "touch failed to sleep, pid=$touchpid"
284         fi
285
286         # get sec info on second mount point
287         if [ -e "$filename2" ]; then
288                 secinfo2=$(get_sel_ctx $filename2)
289         fi
290
291         # get sec info on first mount point
292         wait $touchpid
293         secinfo1=$(get_sel_ctx $filename1)
294
295         # compare sec contexts
296         [ -z "$secinfo2" -o "$secinfo1" == "$secinfo2" ] ||
297                 error "sec context seen from 2nd mount point is not correct"
298
299         return 0
300 }
301 run_test 20a "[atomicity] concurrent access from another client (file)"
302
303 test_20b() {
304         local dirname1=$DIR/$tdir/dd20b
305         local dirname2=$DIR2/$tdir/dd20b
306         local req_delay=20
307         local unconctx="-u unconfined_u -r unconfined_r -t unconfined_t -l s0"
308
309         mkdir -p $DIR/$tdir
310         chmod 777 $DIR/$tdir
311
312         # sleep some time in ll_create_nd()
313         #define OBD_FAIL_LLITE_NEWNODE_PAUSE     0x140a
314         do_facet client "$LCTL set_param fail_val=$req_delay fail_loc=0x140a"
315
316         # create file on first mount point
317         $RUNAS_CMD -u $RUNAS_ID runcon $unconctx mkdir $dirname1 &
318         local mkdirpid=$!
319         sleep 5
320
321         if [[ -z "$(ps h -o comm -p $mkdirpid)" ]]; then
322                 error "mkdir failed to sleep, pid=$mkdirpid"
323         fi
324
325         # get sec info on second mount point
326         if [ -e "$dirname2" ]; then
327                 secinfo2=$(ls -ldZ $dirname2 | awk '{print $4}')
328         else
329                 secinfo2=""
330         fi
331
332         # get sec info on first mount point
333         wait $mkdirpid
334         secinfo1=$(ls -ldZ $dirname1 | awk '{print $4}')
335
336         # compare sec contexts
337         [ -z "$secinfo2" -o "$secinfo1" == "$secinfo2" ] ||
338                 error "sec context seen from 2nd mount point is not correct"
339
340         return 0
341 }
342 run_test 20b "[atomicity] concurrent access from another client (dir)"
343
344 test_20c() {
345         local dirname1=$DIR/dd20c
346         local dirname2=$DIR2/dd20c
347         local req_delay=20
348
349         # sleep some time in ll_create_nd()
350         #define OBD_FAIL_LLITE_SETDIRSTRIPE_PAUSE     0x140b
351         do_facet client "$LCTL set_param fail_val=$req_delay fail_loc=0x140b"
352
353         # create file on first mount point
354         $LFS mkdir -c0 -i0 $dirname1 &
355         local mkdirpid=$!
356         sleep 5
357
358         if [[ -z "$(ps h -o comm -p $mkdirpid)" ]]; then
359                 error "lfs mkdir failed to sleep, pid=$mkdirpid"
360         fi
361
362         # get sec info on second mount point
363         if [ -e "$dirname2" ]; then
364                 secinfo2=$(ls -ldZ $dirname2 | awk '{print $4}')
365         else
366                 secinfo2=""
367         fi
368
369         # get sec info on first mount point
370         wait $mkdirpid
371         secinfo1=$(ls -ldZ $dirname1 | awk '{print $4}')
372
373         # compare sec contexts
374         [ -z "$secinfo2" -o "$secinfo1" == "$secinfo2" ] ||
375                 error "sec context seen from 2nd mount point is not correct"
376
377         return 0
378 }
379 run_test 20c "[atomicity] concurrent access from another client (dir via lfs)"
380
381 cleanup_20d() {
382         umount_client $MOUNT || error "umount $MOUNT failed"
383         mountcli
384 }
385
386 trace_cmd() {
387         local cmd="$@"
388         local xattr_prefix=$(grep -E \
389                 "#define[[:space:]]+XATTR_SECURITY_PREFIX[[:space:]]+" \
390                 /usr/include/linux/xattr.h 2>/dev/null |
391                 awk '{print $3}' | sed s+\"++g)
392         local xattr_suffix=$(grep -E \
393                 "#define[[:space:]]+XATTR_SELINUX_SUFFIX[[:space:]]+" \
394                 /usr/include/linux/xattr.h 2>/dev/null |
395                 awk '{print $3}' | sed s+\"++g)
396         local xattr_name=${xattr_prefix}${xattr_suffix}
397
398         [ -z "$xattr_name" ] && xattr_name="security.selinux"
399
400         # umount client
401         if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
402                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
403         fi
404         if $(grep -q $MOUNT' ' /proc/mounts); then
405                 umount_client $MOUNT || error "umount $MOUNT failed"
406         fi
407         lustre_rmmod
408         # remount client
409         mount_client $MOUNT ${MOUNT_OPTS} || error "mount client failed"
410
411         $LCTL set_param debug=+info
412         $LCTL clear
413
414         echo $cmd
415         eval $cmd
416
417         $LCTL dk | grep "get xattr '${xattr_name}'"
418         [ $? -eq 0 ] && error "get xattr event was triggered" || true
419 }
420
421 test_20d() {
422         if [ "$MDS1_VERSION" -lt $(version_code 2.12.50) ] ||
423            [ "$CLIENT_VERSION" -lt $(version_code 2.12.50) ]; then
424                 skip "Need version >= 2.12.50"
425         fi
426         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
427
428         stack_trap cleanup_20d EXIT
429
430         local dirname=$DIR/$tdir/subdir
431
432         mkdir -p $DIR/$tdir
433         mkdir $dirname
434
435         trace_cmd stat $dirname
436         trace_cmd touch $dirname/f1
437         trace_cmd stat $dirname/f1
438         trace_cmd cat $dirname/f1
439         dd if=/dev/zero of=$dirname/f1 bs=1M count=10
440         trace_cmd /usr/bin/truncate -s 10240 $dirname/f1
441         trace_cmd lfs setstripe -E -1 -S 4M $dirname/f2
442         trace_cmd lfs migrate -E -1 -S 256K $dirname/f2
443         trace_cmd lfs setdirstripe -i 1 $dirname/d2
444         trace_cmd lfs migrate -m 0 $dirname/d2
445
446         lfs setdirstripe -i 1 -c 1 $dirname/d3
447         dirname=$dirname/d3/subdir
448         mkdir $dirname
449
450         trace_cmd stat $dirname
451         trace_cmd touch $dirname/f1
452         trace_cmd stat $dirname/f1
453         trace_cmd cat $dirname/f1
454         dd if=/dev/zero of=$dirname/f1 bs=1M count=10
455         trace_cmd /usr/bin/truncate -s 10240 $dirname/f1
456         trace_cmd lfs setstripe -E -1 -S 4M $dirname/f2
457         trace_cmd lfs migrate -E -1 -S 256K $dirname/f2
458 }
459 run_test 20d "[atomicity] avoid getxattr for security context"
460
461 test_20e() {
462         [ "$CLIENT_VERSION" -lt $(version_code 2.13.54) ] &&
463                 skip "Need client version >= 2.13.54"
464         local filename1=$DIR/$tdir/df20e
465         local delay=5
466         local evict
467         local unconctx="-u unconfined_u -r unconfined_r -t unconfined_t -l s0"
468
469         mkdir -p $DIR/$tdir
470         chmod 777 $DIR/$tdir
471         #define OBD_FAIL_LLITE_CREATE_FILE_PAUSE2   0x1416
472         do_facet client "$LCTL set_param fail_val=$delay fail_loc=0x80001416"
473
474         # create file on first mount point
475         $RUNAS_CMD -u $RUNAS_ID runcon $unconctx touch $filename1 &
476         local touchpid=$!
477         sleep 1
478         cancel_lru_locks mdc
479         sysctl -w vm.drop_caches=2
480         $RUNAS_CMD -u $RUNAS_ID runcon $unconctx stat $DIR/$tdir &
481
482         wait $touchpid
483
484         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
485           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
486
487         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
488 }
489 run_test 20e "client deadlock and eviction form MDS"
490
491 check_nodemap() {
492         local nm=$1
493         local key=$2
494         local val=$3
495         local facets=""
496         local i
497
498         if [ "$nm" == "active" ]; then
499                 proc_param="active"
500         else
501                 proc_param="$nm.$key"
502         fi
503         # check all MDS nodes, in reverse order to privilege remote ones first
504         for i in $(seq $MDSCOUNT); do
505                 facets="mds$i $facets"
506         done
507         for facet in $facets; do
508                 is_sync=false
509                 for i in {1..20}; do
510                         out=$(do_facet $facet $LCTL get_param -n \
511                                    nodemap.$proc_param 2>/dev/null)
512                         echo "On $facet, ${proc_param} = $out"
513                         [ "$val" == "$out" ] && is_sync=true && break
514                         sleep 1
515                 done
516                 if ! $is_sync; then
517                         error "$proc_param not updated on $facet after 20 secs"
518                 fi
519         done
520 }
521
522 create_nodemap() {
523         local nm=$1
524         local sepol
525         local client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
526         local client_nid=$(h2nettype $client_ip)
527
528         do_facet mgs $LCTL nodemap_activate 1
529
530         do_facet mgs $LCTL nodemap_add $nm
531         do_facet mgs $LCTL nodemap_add_range \
532                         --name $nm --range $client_nid
533         do_facet mgs $LCTL nodemap_modify --name $nm \
534                         --property admin --value 1
535         do_facet mgs $LCTL nodemap_modify --name $nm \
536                         --property trusted --value 1
537
538         check_nodemap $nm admin_nodemap 1
539         check_nodemap $nm trusted_nodemap 1
540
541         sleep 10
542         l_getsepol || error "cannot get sepol"
543         sepol=$(l_getsepol | cut -d':' -f2- | xargs)
544         [ -n "$sepol" ] || error "sepol is empty"
545         do_facet mgs $LCTL set_param -P nodemap.$nm.sepol="$sepol"
546
547         check_nodemap $nm sepol $sepol
548 }
549
550 remove_nodemap() {
551         local nm=$1
552
553         do_facet mgs $LCTL nodemap_del $nm
554
555         wait_update_facet --verbose mds1 \
556                 "$LCTL get_param nodemap.$nm.id 2>/dev/null | \
557                 grep -c $nm || true" 0 30 ||
558                 error "nodemap $nm could not be removed"
559
560         do_facet mgs $LCTL nodemap_activate 0
561
562         check_nodemap active x  0
563 }
564
565 test_21a() {
566         [ "$MDS1_VERSION" -lt $(version_code 2.11.56) ] &&
567                 skip "Need MDS >= 2.11.56"
568
569         local sepol
570
571         # umount client
572         if [ "$MOUNT_2" ] && $(grep -q $MOUNT2' ' /proc/mounts); then
573                 umount_client $MOUNT2 || error "umount $MOUNT2 failed"
574         fi
575         if $(grep -q $MOUNT' ' /proc/mounts); then
576                 umount_client $MOUNT || error "umount $MOUNT failed"
577         fi
578
579         # create nodemap entry with sepol
580         create_nodemap c0
581
582         if $GSS_SK; then
583                 # update mount option with skpath
584                 MOUNT_OPTS=$(add_sk_mntflag $MOUNT_OPTS)
585                 export SK_UNIQUE_NM=true
586
587                 # load specific key on servers
588                 do_nodes $(comma_list $(all_server_nodes)) "$LGSS_SK -t server \
589                                                     -l $SK_PATH/nodemap/c0.key"
590
591                 # set perms for per-nodemap keys else permission denied
592                 do_nodes $(comma_list $(all_server_nodes)) \
593                  "keyctl show | grep lustre | cut -c1-11 |
594                                 sed -e 's/ //g;' |
595                                 xargs -IX keyctl setperm X 0x3f3f3f3f"
596
597         fi
598
599         # mount client without sending sepol
600         mount_client $MOUNT $MOUNT_OPTS &&
601                 error "client mount without sending sepol should be refused"
602
603         # mount client with sepol
604         echo -1 > /sys/module/ptlrpc/parameters/send_sepol
605         mount_client $MOUNT $MOUNT_OPTS ||
606                 error "client mount with sepol failed"
607
608         # umount client
609         umount_client $MOUNT || error "umount $MOUNT failed"
610
611         # store wrong sepol in nodemap
612         sepol="0:policy:0:0000000000000000000000000000000000000000000000000000000000000000"
613         do_facet mgs $LCTL set_param -P nodemap.c0.sepol="$sepol"
614         check_nodemap c0 sepol $sepol
615
616         # mount client with sepol
617         mount_client $MOUNT $MOUNT_OPTS &&
618                 error "client mount without matching sepol should be refused"
619
620         # remove nodemap
621         remove_nodemap c0
622
623         if $GSS_SK; then
624                 export SK_UNIQUE_NM=false
625         fi
626
627         # remount client normally
628         echo 0 > /sys/module/ptlrpc/parameters/send_sepol
629         mountcli || error "normal client mount failed"
630 }
631 run_test 21a "Send sepol at connect"
632
633 test_21b() {
634         [ "$MDS1_VERSION" -lt $(version_code 2.11.56) ] &&
635                 skip "Need MDS >= 2.11.56"
636
637         stack_trap "restore_opencache" EXIT
638         disable_opencache
639
640         local sepol
641
642         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
643         echo test > $DIR/$tdir/toopen ||
644                 error "failed to write to $DIR/$tdir/toopen"
645         touch $DIR/$tdir/ftoremove ||
646                 error "failed to create $DIR/$tdir/ftoremove"
647         touch $DIR/$tdir/ftoremove2 ||
648                 error "failed to create $DIR/$tdir/ftoremove2"
649         touch $DIR/$tdir/ftoremove3 ||
650                 error "failed to create $DIR/$tdir/ftoremove3"
651         touch $DIR/$tdir/ftoremove4 ||
652                 error "failed to create $DIR/$tdir/ftoremove4"
653         mkdir $DIR/$tdir/dtoremove ||
654                 error "failed to create $DIR/$tdir/dtoremove"
655         mkdir $DIR/$tdir/dtoremove2 ||
656                 error "failed to create $DIR/$tdir/dtoremove2"
657         mkdir $DIR/$tdir/dtoremove3 ||
658                 error "failed to create $DIR/$tdir/dtoremove3"
659         mkdir $DIR/$tdir/dtoremove4 ||
660                 error "failed to create $DIR/$tdir/dtoremove4"
661         touch $DIR/$tdir/ftorename ||
662                 error "failed to create $DIR/$tdir/ftorename"
663         mkdir $DIR/$tdir/dtorename ||
664                 error "failed to create $DIR/$tdir/dtorename"
665         setfattr -n user.myattr -v myval $DIR/$tdir/toopen ||
666                 error "failed to set xattr on $DIR/$tdir/toopen"
667         echo 3 > /proc/sys/vm/drop_caches
668
669         # create nodemap entry with sepol
670         create_nodemap c0
671
672         if $GSS_SK; then
673                 export SK_UNIQUE_NM=true
674
675                 # load specific key on servers
676                 do_nodes $(comma_list $(all_server_nodes)) "$LGSS_SK -t server \
677                                                     -l $SK_PATH/nodemap/c0.key"
678
679                 # set perms for per-nodemap keys else permission denied
680                 do_nodes $(comma_list $(all_server_nodes)) \
681                  "keyctl show | grep lustre | cut -c1-11 |
682                                 sed -e 's/ //g;' |
683                                 xargs -IX keyctl setperm X 0x3f3f3f3f"
684
685         fi
686
687         # metadata ops without sending sepol
688         touch $DIR/$tdir/f0 && error "touch (1)"
689         lfs setstripe -c1 $DIR/$tdir/f1 && error "lfs setstripe (1)"
690         mkdir $DIR/$tdir/d0 && error "mkdir (1)"
691         lfs setdirstripe -i0 -c1 $DIR/$tdir/d1 && error "lfs setdirstripe (1)"
692         cat $DIR/$tdir/toopen && error "cat (1)"
693         rm -f $DIR/$tdir/ftoremove && error "rm (1)"
694         rmdir $DIR/$tdir/dtoremove && error "rmdir (1)"
695         mv $DIR/$tdir/ftorename $DIR/$tdir/ftorename2 && error "mv (1)"
696         mv $DIR/$tdir/dtorename $DIR/$tdir/dtorename2 && error "mv (2)"
697         getfattr -n user.myattr $DIR/$tdir/toopen && error "getfattr (1)"
698         setfattr -n user.myattr -v myval2 $DIR/$tdir/toopen &&
699                 error "setfattr (1)"
700         chattr +i $DIR/$tdir/toopen && error "chattr (1)"
701         lsattr $DIR/$tdir/toopen && error "lsattr (1)"
702         chattr -i $DIR/$tdir/toopen && error "chattr (1)"
703         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl1 && error "symlink (1)"
704         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl1 && error "hardlink (1)"
705
706         # metadata ops with sepol
707         echo -1 > /sys/module/ptlrpc/parameters/send_sepol
708         touch $DIR/$tdir/f2 || error "touch (2)"
709         lfs setstripe -c1 $DIR/$tdir/f3 || error "lfs setstripe (2)"
710         mkdir $DIR/$tdir/d2 || error "mkdir (2)"
711         lfs setdirstripe -i0 -c1 $DIR/$tdir/d3 || error "lfs setdirstripe (2)"
712         cat $DIR/$tdir/toopen || error "cat (2)"
713         rm -f $DIR/$tdir/ftoremove || error "rm (2)"
714         rmdir $DIR/$tdir/dtoremove || error "rmdir (2)"
715         mv $DIR/$tdir/ftorename $DIR/$tdir/ftorename2 || error "mv (3)"
716         mv $DIR/$tdir/dtorename $DIR/$tdir/dtorename2 || error "mv (4)"
717         getfattr -n user.myattr $DIR/$tdir/toopen || error "getfattr (2)"
718         setfattr -n user.myattr -v myval2 $DIR/$tdir/toopen ||
719                 error "setfattr (2)"
720         chattr +i $DIR/$tdir/toopen || error "chattr (2)"
721         lsattr $DIR/$tdir/toopen || error "lsattr (2)"
722         chattr -i $DIR/$tdir/toopen || error "chattr (2)"
723         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl2 || error "symlink (2)"
724         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl2 || error "hardlink (2)"
725         echo 3 > /proc/sys/vm/drop_caches
726
727         # store wrong sepol in nodemap
728         sepol="0:policy:0:0000000000000000000000000000000000000000000000000000000000000000"
729         do_facet mgs $LCTL set_param -P nodemap.c0.sepol="$sepol"
730         check_nodemap c0 sepol $sepol
731
732         # metadata ops with sepol
733         touch $DIR/$tdir/f4 && error "touch (3)"
734         lfs setstripe -c1 $DIR/$tdir/f5 && error "lfs setstripe (3)"
735         mkdir $DIR/$tdir/d4 && error "mkdir (3)"
736         lfs setdirstripe -i0 -c1 $DIR/$tdir/d5 && error "lfs setdirstripe (3)"
737         cat $DIR/$tdir/toopen && error "cat (3)"
738         rm -f $DIR/$tdir/ftoremove2 && error "rm (3)"
739         rmdir $DIR/$tdir/dtoremove2 && error "rmdir (3)"
740         mv $DIR/$tdir/ftorename2 $DIR/$tdir/ftorename && error "mv (5)"
741         mv $DIR/$tdir/dtorename2 $DIR/$tdir/dtorename && error "mv (6)"
742         getfattr -n user.myattr $DIR/$tdir/toopen && error "getfattr (3)"
743         setfattr -n user.myattr -v myval3 $DIR/$tdir/toopen &&
744                 error "setfattr (3)"
745         chattr +i $DIR/$tdir/toopen && error "chattr (3)"
746         lsattr $DIR/$tdir/toopen && error "lsattr (3)"
747         chattr -i $DIR/$tdir/toopen && error "chattr (3)"
748         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl3 && error "symlink (3)"
749         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl3 && error "hardlink (3)"
750
751         # reset correct sepol
752         l_getsepol || error "cannot get sepol"
753         sepol=$(l_getsepol | cut -d':' -f2- | xargs)
754         [ -n "$sepol" ] || error "sepol is empty"
755         do_facet mgs $LCTL set_param -P nodemap.c0.sepol="$sepol"
756         check_nodemap c0 sepol $sepol
757
758         # metadata ops with sepol every 1000 seconds only
759         echo 1000 > /sys/module/ptlrpc/parameters/send_sepol
760         local before=$(date +%s)
761         touch $DIR/$tdir/f6 || error "touch (4)"
762         lfs setstripe -c1 $DIR/$tdir/f7 || error "lfs setstripe (4)"
763         mkdir $DIR/$tdir/d6 || error "mkdir (4)"
764         lfs setdirstripe -i0 -c1 $DIR/$tdir/d7 || error "lfs setdirstripe (4)"
765         cat $DIR/$tdir/toopen || error "cat (4)"
766         rm -f $DIR/$tdir/ftoremove2 || error "rm (4)"
767         rmdir $DIR/$tdir/dtoremove2 || error "rmdir (4)"
768         mv $DIR/$tdir/ftorename2 $DIR/$tdir/ftorename || error "mv (7)"
769         mv $DIR/$tdir/dtorename2 $DIR/$tdir/dtorename || error "mv (8)"
770         getfattr -n user.myattr $DIR/$tdir/toopen || error "getfattr (4)"
771         setfattr -n user.myattr -v myval3 $DIR/$tdir/toopen ||
772                 error "setfattr (4)"
773         chattr +i $DIR/$tdir/toopen || error "chattr (4)"
774         lsattr $DIR/$tdir/toopen || error "lsattr (4)"
775         chattr -i $DIR/$tdir/toopen || error "chattr (4)"
776         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl4 || error "symlink (4)"
777         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl4 || error "hardlink (4)"
778         echo 3 > /proc/sys/vm/drop_caches
779
780         # change one SELinux boolean value
781         sebool=$(getsebool deny_ptrace | awk '{print $3}')
782         if [ "$sebool" == "off" ]; then
783                 setsebool -P deny_ptrace on
784         else
785                 setsebool -P deny_ptrace off
786         fi
787
788         # sepol should not be checked yet, so metadata ops without matching
789         # sepol should succeed
790         touch $DIR/$tdir/f8 || error "touch (5)"
791         lfs setstripe -c1 $DIR/$tdir/f9 || error "lfs setstripe (5)"
792         mkdir $DIR/$tdir/d8 || error "mkdir (5)"
793         lfs setdirstripe -i0 -c1 $DIR/$tdir/d9 || error "lfs setdirstripe (5)"
794         cat $DIR/$tdir/toopen || error "cat (5)"
795         rm -f $DIR/$tdir/ftoremove3 || error "rm (5)"
796         rmdir $DIR/$tdir/dtoremove3 || error "rmdir (5)"
797         mv $DIR/$tdir/ftorename $DIR/$tdir/ftorename2 || error "mv (9)"
798         mv $DIR/$tdir/dtorename $DIR/$tdir/dtorename2 || error "mv (10)"
799         getfattr -n user.myattr $DIR/$tdir/toopen || error "getfattr (5)"
800         setfattr -n user.myattr -v myval4 $DIR/$tdir/toopen ||
801                 error "setfattr (5)"
802         chattr +i $DIR/$tdir/toopen || error "chattr (5)"
803         lsattr $DIR/$tdir/toopen || error "lsattr (5)"
804         chattr -i $DIR/$tdir/toopen || error "chattr (5)"
805         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl5 || error "symlink (5)"
806         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl5 || error "hardlink (5)"
807         echo 3 > /proc/sys/vm/drop_caches
808
809         local after=$(date +%s)
810         # change send_sepol to a smaller, already expired, value
811         echo $((after-before-1)) > /sys/module/ptlrpc/parameters/send_sepol
812         # metadata ops without matching sepol: should fail now
813         touch $DIR/$tdir/f10 && error "touch (6)"
814         lfs setstripe -c1 $DIR/$tdir/f11 && error "lfs setstripe (6)"
815         mkdir $DIR/$tdir/d10 && error "mkdir (6)"
816         lfs setdirstripe -i0 -c1 $DIR/$tdir/d11 && error "lfs setdirstripe (6)"
817         cat $DIR/$tdir/toopen && error "cat (6)"
818         rm -f $DIR/$tdir/ftoremove4 && error "rm (6)"
819         rmdir $DIR/$tdir/dtoremove4 && error "rmdir (6)"
820         mv $DIR/$tdir/ftorename2 $DIR/$tdir/ftorename && error "mv (11)"
821         mv $DIR/$tdir/dtorename2 $DIR/$tdir/dtorename && error "mv (12)"
822         getfattr -n user.myattr $DIR/$tdir/toopen && error "getfattr (6)"
823         setfattr -n user.myattr -v myval5 $DIR/$tdir/toopen &&
824                 error "setfattr (6)"
825         chattr +i $DIR/$tdir/toopen && error "chattr (6)"
826         lsattr $DIR/$tdir/toopen && error "lsattr (6)"
827         chattr -i $DIR/$tdir/toopen && error "chattr (6)"
828         ln -s $DIR/$tdir/toopen $DIR/$tdir/toopen_sl6 && error "symlink (6)"
829         ln $DIR/$tdir/toopen $DIR/$tdir/toopen_hl6 && error "hardlink (6)"
830
831         # restore SELinux boolean value
832         if [ "$sebool" == "off" ]; then
833                 setsebool -P deny_ptrace off
834         else
835                 setsebool -P deny_ptrace on
836         fi
837
838         # remove nodemap
839         remove_nodemap c0
840         echo 0 > /sys/module/ptlrpc/parameters/send_sepol
841
842         if $GSS_SK; then
843                 export SK_UNIQUE_NM=false
844         fi
845 }
846 run_test 21b "Send sepol for metadata ops"
847
848 complete_test $SECONDS
849 check_and_cleanup_lustre
850 exit_status