Whamcloud - gitweb
LU-3527 nodemap: idmap management functions
[fs/lustre-release.git] / lustre / tests / sanity-sec.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10 # bug number for skipped test: 19430 19967 19967
11 ALWAYS_EXCEPT="                2     5     6    $SANITY_SEC_EXCEPT"
12 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
13
14 [ "$ALWAYS_EXCEPT$EXCEPT" ] && \
15     echo "Skipping tests: $ALWAYS_EXCEPT $EXCEPT"
16
17 SRCDIR=`dirname $0`
18 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin
19 export NAME=${NAME:-local}
20
21 LUSTRE=${LUSTRE:-`dirname $0`/..} 
22 . $LUSTRE/tests/test-framework.sh
23 init_test_env $@
24 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
25 init_logging
26
27 RUNAS="runas"
28
29 WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
30
31 CONFDIR=/etc/lustre
32 PERM_CONF=$CONFDIR/perm.conf
33 FAIL_ON_ERROR=false
34
35 HOSTNAME_CHECKSUM=$(hostname | sum | awk '{ print $1 }')
36 SUBNET_CHECKSUM=$(expr $HOSTNAME_CHECKSUM % 250 + 1)
37 NODEMAP_COUNT=10
38 NODEMAP_RANGE_COUNT=3
39 NODEMAP_IPADDR_COUNT=30
40 NODEMAP_MAX_ID=600
41
42 require_dsh_mds || exit 0
43 require_dsh_ost || exit 0
44
45 ID0=${ID0:-500}
46 ID1=${ID1:-501}
47 USER0=`cat /etc/passwd|grep :$ID0:$ID0:|cut -d: -f1`
48 USER1=`cat /etc/passwd|grep :$ID1:$ID1:|cut -d: -f1`
49
50 [ -z "$USER0" ] && \
51         echo "Please add user0 (uid=$ID0 gid=$ID0)! Skip sanity-sec" && exit 0
52
53 [ -z "$USER1" ] && \
54         echo "Please add user1 (uid=$ID1 gid=$ID1)! Skip sanity-sec" && exit 0
55
56 check_and_setup_lustre
57
58 sec_cleanup() {
59         if [ "$I_MOUNTED" = "yes" ]; then
60                 cleanupall -f || error "sec_cleanup"
61         fi
62 }
63
64 DIR=${DIR:-$MOUNT}
65 [ -z "`echo $DIR | grep $MOUNT`" ] && \
66         error "$DIR not in $MOUNT" && sec_cleanup && exit 1
67
68 [ `echo $MOUNT | wc -w` -gt 1 ] && \
69         echo "NAME=$MOUNT mounted more than once" && sec_cleanup && exit 0
70
71 [ $MDSCOUNT -gt 1 ] && \
72         echo "skip multi-MDS test" && sec_cleanup && exit 0
73
74 # for GSS_SUP
75 GSS_REF=$(lsmod | grep ^ptlrpc_gss | awk '{print $3}')
76 if [ ! -z "$GSS_REF" -a "$GSS_REF" != "0" ]; then
77         GSS_SUP=1
78         echo "with GSS support"
79 else
80         GSS_SUP=0
81         echo "without GSS support"
82 fi
83
84 MDT=$(do_facet $SINGLEMDS lctl get_param -N "mdt.\*MDT0000" |
85         cut -d. -f2 || true)
86 [ -z "$MDT" ] && error "fail to get MDT device" && exit 1
87 do_facet $SINGLEMDS "mkdir -p $CONFDIR"
88 IDENTITY_FLUSH=mdt.$MDT.identity_flush
89 MDSCAPA=mdt.$MDT.capa
90 CAPA_TIMEOUT=mdt.$MDT.capa_timeout
91 MDSSECLEVEL=mdt.$MDT.sec_level
92
93 # for CLIENT_TYPE
94 if [ -z "$(lctl get_param -n llite.*.client_type | grep remote 2>/dev/null)" ]; then
95         CLIENT_TYPE="local"
96         echo "local client"
97 else
98         CLIENT_TYPE="remote"
99         echo "remote client"
100 fi
101
102 SAVE_PWD=$PWD
103
104 build_test_filter
105
106 sec_login() {
107         local user=$1
108         local group=$2
109
110         if ! $RUNAS -u $user krb5_login.sh; then
111                 error "$user login kerberos failed."
112                 exit 1
113         fi
114
115         if ! $RUNAS -u $user -g $group ls $DIR > /dev/null 2>&1; then
116                 $RUNAS -u $user lfs flushctx -k
117                 $RUNAS -u $user krb5_login.sh
118                 if ! $RUNAS -u $user -g $group ls $DIR > /dev/null 2>&1; then
119                         error "init $user $group failed."
120                         exit 2
121                 fi
122         fi
123 }
124
125 declare -a identity_old
126
127 sec_setup() {
128         for num in `seq $MDSCOUNT`; do
129                 switch_identity $num true || identity_old[$num]=$?
130         done
131
132         if ! $RUNAS -u $ID0 ls $DIR > /dev/null 2>&1; then
133                 sec_login $USER0 $USER0
134         fi
135
136         if ! $RUNAS -u $ID1 ls $DIR > /dev/null 2>&1; then
137                 sec_login $USER1 $USER1
138         fi
139 }
140 sec_setup
141
142 # run as different user
143 test_0() {
144         umask 0022
145
146         chmod 0755 $DIR || error "chmod (1)"
147         rm -rf $DIR/$tdir || error "rm (1)"
148         mkdir -p $DIR/$tdir || error "mkdir (1)"
149
150         if [ "$CLIENT_TYPE" = "remote" ]; then
151                 do_facet $SINGLEMDS "echo '* 0 normtown' > $PERM_CONF"
152                 do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
153                 chown $USER0 $DIR/$tdir && error "chown (1)"
154                 do_facet $SINGLEMDS "echo '* 0 rmtown' > $PERM_CONF"
155                 do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
156         else
157                 chown $USER0 $DIR/$tdir || error "chown (2)"
158         fi
159
160         $RUNAS -u $ID0 ls $DIR || error "ls (1)"
161         rm -f $DIR/f0 || error "rm (2)"
162         $RUNAS -u $ID0 touch $DIR/f0 && error "touch (1)"
163         $RUNAS -u $ID0 touch $DIR/$tdir/f1 || error "touch (2)"
164         $RUNAS -u $ID1 touch $DIR/$tdir/f2 && error "touch (3)"
165         touch $DIR/$tdir/f3 || error "touch (4)"
166         chown root $DIR/$tdir || error "chown (3)"
167         chgrp $USER0 $DIR/$tdir || error "chgrp (1)"
168         chmod 0775 $DIR/$tdir || error "chmod (2)"
169         $RUNAS -u $ID0 touch $DIR/$tdir/f4 || error "touch (5)"
170         $RUNAS -u $ID1 touch $DIR/$tdir/f5 && error "touch (6)"
171         touch $DIR/$tdir/f6 || error "touch (7)"
172         rm -rf $DIR/$tdir || error "rm (3)"
173
174         if [ "$CLIENT_TYPE" = "remote" ]; then
175                 do_facet $SINGLEMDS "rm -f $PERM_CONF"
176                 do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
177         fi
178 }
179 run_test 0 "uid permission ============================="
180
181 # setuid/gid
182 test_1() {
183         [ $GSS_SUP = 0 ] && skip "without GSS support." && return
184
185         if [ "$CLIENT_TYPE" = "remote" ]; then
186                 do_facet $SINGLEMDS "echo '* 0 rmtown' > $PERM_CONF"
187                 do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
188         fi
189
190         rm -rf $DIR/$tdir
191         mkdir -p $DIR/$tdir
192
193         chown $USER0 $DIR/$tdir || error "chown (1)"
194         $RUNAS -u $ID1 -v $ID0 touch $DIR/$tdir/f0 && error "touch (2)"
195         echo "enable uid $ID1 setuid"
196         do_facet $SINGLEMDS "echo '* $ID1 setuid' >> $PERM_CONF"
197         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
198         $RUNAS -u $ID1 -v $ID0 touch $DIR/$tdir/f1 || error "touch (3)"
199
200         chown root $DIR/$tdir || error "chown (4)"
201         chgrp $USER0 $DIR/$tdir || error "chgrp (5)"
202         chmod 0770 $DIR/$tdir || error "chmod (6)"
203         $RUNAS -u $ID1 -g $ID1 touch $DIR/$tdir/f2 && error "touch (7)"
204         $RUNAS -u $ID1 -g $ID1 -j $ID0 touch $DIR/$tdir/f3 && error "touch (8)"
205         echo "enable uid $ID1 setuid,setgid"
206         do_facet $SINGLEMDS "echo '* $ID1 setuid,setgid' > $PERM_CONF"
207         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
208         $RUNAS -u $ID1 -g $ID1 -j $ID0 touch $DIR/$tdir/f4 || error "touch (9)"
209         $RUNAS -u $ID1 -v $ID0 -g $ID1 -j $ID0 touch $DIR/$tdir/f5 || error "touch (10)"
210
211         rm -rf $DIR/$tdir
212
213         do_facet $SINGLEMDS "rm -f $PERM_CONF"
214         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
215 }
216 run_test 1 "setuid/gid ============================="
217
218 run_rmtacl_subtest() {
219     $SAVE_PWD/rmtacl/run $SAVE_PWD/rmtacl/$1.test
220     return $?
221 }
222
223 # remote_acl
224 # for remote client only
225 test_2 () {
226         [ "$CLIENT_TYPE" = "local" ] && \
227                 skip "remote_acl for remote client only" && return
228         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep ^acl)" ] && \
229                 skip "must have acl enabled" && return
230         [ -z "$(which setfacl 2>/dev/null)" ] && \
231                 skip "could not find setfacl" && return
232         [ "$UID" != 0 ] && skip "must run as root" && return
233
234         do_facet $SINGLEMDS "echo '* 0 rmtacl,rmtown' > $PERM_CONF"
235         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
236
237         sec_login root root
238         sec_login bin bin
239         sec_login daemon daemon
240         sec_login games users
241
242         SAVE_UMASK=`umask`
243         umask 0022
244         cd $DIR
245
246         echo "performing cp ..."
247         run_rmtacl_subtest cp || error "cp"
248         echo "performing getfacl-noacl..."
249         run_rmtacl_subtest getfacl-noacl || error "getfacl-noacl"
250         echo "performing misc..."
251         run_rmtacl_subtest misc || error "misc"
252         echo "performing permissions..."
253         run_rmtacl_subtest permissions || error "permissions"
254         echo "performing setfacl..."
255         run_rmtacl_subtest setfacl || error "setfacl"
256
257         # inheritance test got from HP
258         echo "performing inheritance..."
259         cp $SAVE_PWD/rmtacl/make-tree .
260         chmod +x make-tree
261         run_rmtacl_subtest inheritance || error "inheritance"
262         rm -f make-tree
263
264         cd $SAVE_PWD
265         umask $SAVE_UMASK
266
267         do_facet $SINGLEMDS "rm -f $PERM_CONF"
268         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
269 }
270 run_test 2 "rmtacl ============================="
271
272 # rootsquash
273 # root_squash will be redesigned in Lustre 1.7
274 test_3() {
275         skip "root_squash will be redesigned in Lustre 1.7" && return
276 }
277 run_test 3 "rootsquash ============================="
278
279 # bug 3285 - supplementary group should always succeed.
280 # NB: the supplementary groups are set for local client only,
281 # as for remote client, the groups of the specified uid on MDT
282 # will be obtained by upcall /sbin/l_getidentity and used.
283 test_4() {
284         if [ "$CLIENT_TYPE" = "remote" ]; then
285                 do_facet $SINGLEMDS "echo '* 0 rmtown' > $PERM_CONF"
286                 do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
287         fi
288
289         rm -rf $DIR/$tdir
290         mkdir -p $DIR/$tdir
291         chmod 0771 $DIR/$tdir
292         chgrp $ID0 $DIR/$tdir
293         $RUNAS -u $ID0 ls $DIR/$tdir || error "setgroups (1)"
294         if [ "$CLIENT_TYPE" = "local" ]; then
295                 do_facet $SINGLEMDS "echo '* $ID1 setgrp' > $PERM_CONF"
296                 do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
297                 $RUNAS -u $ID1 -G1,2,$ID0 ls $DIR/$tdir || error "setgroups (2)"
298         fi
299         $RUNAS -u $ID1 -G1,2 ls $DIR/$tdir && error "setgroups (3)"
300         rm -rf $DIR/$tdir
301
302         do_facet $SINGLEMDS "rm -f $PERM_CONF"
303         do_facet $SINGLEMDS "lctl set_param -n $IDENTITY_FLUSH=-1"
304 }
305 run_test 4 "set supplementary group ==============="
306
307 mds_capability_timeout() {
308         [ $# -lt 1 ] && echo "Miss mds capability timeout value" && return 1
309
310         echo "Set mds capability timeout as $1 seconds"
311         do_facet $SINGLEMDS "lctl set_param -n $CAPA_TIMEOUT=$1"
312         return 0
313 }
314
315 mds_sec_level_switch() {
316         [ $# -lt 1 ] && echo "Miss mds sec level switch value" && return 1
317
318         case $1 in
319                 0) echo "Disable capa for all clients";;
320                 1) echo "Enable capa for remote client";;
321                 3) echo "Enable capa for all clients";;
322                 *) echo "Invalid mds sec level switch value" && return 2;;
323         esac
324
325         do_facet $SINGLEMDS "lctl set_param -n $MDSSECLEVEL=$1"
326         return 0
327 }
328
329 oss_sec_level_switch() {
330         [ $# -lt 1 ] && echo "Miss oss sec level switch value" && return 1
331
332         case $1 in
333                 0) echo "Disable capa for all clients";;
334                 1) echo "Enable capa for remote client";;
335                 3) echo "Enable capa for all clients";;
336                 *) echo "Invalid oss sec level switch value" && return 2;;
337         esac
338
339         for i in `seq $OSTCOUNT`; do
340                 local j=`expr $i - 1`
341                 local OST="`do_facet ost$i "lctl get_param -N obdfilter.\*OST\*$j/stats 2>/dev/null | cut -d"." -f2" || true`"
342                 [ -z "$OST" ] && return 3
343                 do_facet ost$i "lctl set_param -n obdfilter.$OST.sec_level=$1"
344         done
345         return 0
346 }
347
348 mds_capability_switch() {
349         [ $# -lt 1 ] && echo "Miss mds capability switch value" && return 1
350
351         case $1 in
352                 0) echo "Turn off mds capability";;
353                 3) echo "Turn on mds capability";;
354                 *) echo "Invalid mds capability switch value" && return 2;;
355         esac
356
357         do_facet $SINGLEMDS "lctl set_param -n $MDSCAPA=$1"
358         return 0
359 }
360
361 oss_capability_switch() {
362         [ $# -lt 1 ] && echo "Miss oss capability switch value" && return 1
363
364         case $1 in
365                 0) echo "Turn off oss capability";;
366                 1) echo "Turn on oss capability";;
367                 *) echo "Invalid oss capability switch value" && return 2;;
368         esac
369
370         for i in `seq $OSTCOUNT`; do
371                 local j=`expr $i - 1`
372                 local OST="`do_facet ost$i "lctl get_param -N obdfilter.\*OST\*$j/stats 2>/dev/null | cut -d"." -f2" || true`"
373                 [ -z "$OST" ] && return 3
374                 do_facet ost$i "lctl set_param -n obdfilter.$OST.capa=$1"
375         done
376         return 0
377 }
378
379 turn_mds_capa_on() {
380         mds_capability_switch 3 || return 1
381         mds_sec_level_switch 3  || return 2
382         return 0
383 }
384
385 turn_oss_capa_on() {
386         oss_capability_switch 1 || return 1
387         oss_sec_level_switch 3  || return 2
388         return 0
389 }
390
391 turn_capability_on() {
392         local capa_timeout=${1:-"1800"}
393
394         # To turn on fid capability for the system,
395         # there is a requirement that fid capability
396         # is turned on on all MDS/OSS servers before
397         # client mount.
398
399         turn_mds_capa_on || return 1
400         turn_oss_capa_on || return 2
401         mds_capability_timeout $capa_timeout || return 3
402         remount_client $MOUNT || return 4
403         return 0
404 }
405
406 turn_mds_capa_off() {
407         mds_sec_level_switch 0  || return 1
408         mds_capability_switch 0 || return 2
409         return 0
410 }
411
412 turn_oss_capa_off() {
413         oss_sec_level_switch 0  || return 1
414         oss_capability_switch 0 || return 2
415         return 0
416 }
417
418 turn_capability_off() {
419         # to turn off fid capability, you can just do
420         # it in a live system. But, please turn off
421         # capability of all OSS servers before MDS servers.
422
423         turn_oss_capa_off || return 1
424         turn_mds_capa_off || return 2
425         return 0
426 }
427
428 # We demonstrate that access to the objects in the filesystem are not
429 # accessible without supplying secrets from the MDS by disabling a
430 # proc variable on the mds so that it does not supply secrets. We then
431 # try and access objects which result in failure.
432 test_5() {
433         local file=$DIR/f5
434
435         [ $GSS_SUP = 0 ] && skip "without GSS support." && return
436         if ! remote_mds; then
437                 skip "client should be separated from server."
438                 return
439         fi
440
441         rm -f $file
442
443         turn_capability_off
444         if [ $? != 0 ]; then
445                 error "turn_capability_off"
446                 return 1
447         fi
448
449         turn_oss_capa_on
450         if [ $? != 0 ]; then
451                 error "turn_oss_capa_on"
452                 return 2
453         fi
454
455         if [ "$CLIENT_TYPE" = "remote" ]; then
456                 remount_client $MOUNT && return 3
457                 turn_oss_capa_off
458                 return 0
459         else
460                 remount_client $MOUNT || return 4
461         fi
462
463         # proc variable disabled -- access to the objects in the filesystem
464         # is not allowed 
465         echo "Should get Write error here : (proc variable are disabled "\
466              "-- access to the objects in the filesystem is denied."
467         $WTL $file 30
468         if [ $? == 0 ]; then
469                 error "Write worked well even though secrets not supplied."
470                 return 5
471         fi
472
473         turn_capability_on
474         if [ $? != 0 ]; then
475                 error "turn_capability_on"
476                 return 6
477         fi
478
479         sleep 5
480
481         # proc variable enabled, secrets supplied -- write should work now
482         echo "Should not fail here : (proc variable enabled, secrets supplied "\
483              "-- write should work now)."
484         $WTL $file 30
485         if [ $? != 0 ]; then
486                 error "Write failed even though secrets supplied."
487                 return 7
488         fi
489
490         turn_capability_off
491         if [ $? != 0 ]; then
492                 error "turn_capability_off"
493                 return 8
494         fi
495         rm -f $file
496 }
497 run_test 5 "capa secrets ========================="
498
499 # Expiry: A test program is performing I/O on a file. It has credential
500 # with an expiry half a minute later. While the program is running the
501 # credentials expire and no automatic extensions or renewals are
502 # enabled. The program will demonstrate an I/O failure.
503 test_6() {
504         local file=$DIR/f6
505
506         [ $GSS_SUP = 0 ] && skip "without GSS support." && return
507         if ! remote_mds; then
508                 skip "client should be separated from server."
509                 return
510         fi
511
512         turn_capability_off
513         if [ $? != 0 ]; then
514                 error "turn_capability_off"
515                 return 1
516         fi
517
518         rm -f $file
519
520         turn_capability_on 30
521         if [ $? != 0 ]; then
522                 error "turn_capability_on 30"
523                 return 2
524         fi
525
526         # Token expiry
527         $WTL $file 60
528         if [ $? != 0 ]; then
529                 error "$WTL $file 60"
530                 return 3
531         fi
532
533         # Reset MDS capability timeout
534         mds_capability_timeout 30
535         if [ $? != 0 ]; then
536                 error "mds_capability_timeout 30"
537                 return 4
538         fi
539
540         $WTL $file 60 &
541         local PID=$!
542         sleep 5
543
544         # To disable automatic renew, only need turn capa off on MDS.
545         turn_mds_capa_off
546         if [ $? != 0 ]; then
547                 error "turn_mds_capa_off"
548                 return 5
549         fi
550
551         echo "We expect I/O failure."
552         wait $PID
553         if [ $? == 0 ]; then
554                 echo "no I/O failure got."
555                 return 6
556         fi
557
558         turn_capability_off
559         if [ $? != 0 ]; then
560                 error "turn_capability_off"
561                 return 7
562         fi
563         rm -f $file
564 }
565 run_test 6 "capa expiry ========================="
566
567 create_nodemaps() {
568         local i
569         local out
570         local rc
571
572         for (( i = 0; i < NODEMAP_COUNT; i++ )); do
573                 if ! do_facet mgs $LCTL nodemap_add                     \
574                         ${HOSTNAME_CHECKSUM}_${i}; then
575                         return 1
576                 fi
577                 out=$(do_facet mgs $LCTL get_param                      \
578                         nodemap.${HOSTNAME_CHECKSUM}_${i}.id)
579                 ## This needs to return zero if the following statement is 1
580                 rc=$(echo $out | grep -c ${HOSTNAME_CHECKSUM}_${i})
581                 [[ $rc == 0 ]] && return 1
582         done
583         return 0
584 }
585
586 delete_nodemaps() {
587         local i
588         local out
589         local rc
590
591         for ((i = 0; i < NODEMAP_COUNT; i++)); do
592                 if ! do_facet mgs $LCTL nodemap_del                     \
593                         ${HOSTNAME_CHECKSUM}_${i}; then
594                         error "nodemap_del ${HOSTNAME_CHECKSUM}_${i}    \
595                                 failed with $rc"
596                         return 3
597                 fi
598                 out=$(do_facet mgs $LCTL get_param                      \
599                         nodemap.${HOSTNAME_CHECKSUM}_${i}.id)
600                 rc=$(echo $out | grep -c ${HOSTNAME_CHECKSUM}_${i})
601                 [[ $rc != 0 ]] && return 1
602         done
603         return 0
604 }
605
606 add_range() {
607         local j
608         local cmd="$LCTL nodemap_add_range"
609         local range
610         local rc=0
611
612         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
613                 range="$SUBNET_CHECKSUM.${2}.${j}.[1-253]@tcp"
614                 if ! do_facet mgs $cmd --name $1        \
615                         --range $range; then
616                         rc=$(($rc + 1))
617                 fi
618         done
619         return $rc
620 }
621
622 delete_range() {
623         local j
624         local cmd="$LCTL nodemap_del_range"
625         local range
626         local rc=0
627
628         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
629                 range="$SUBNET_CHECKSUM.${2}.${j}.[1-253]@tcp"
630                 if ! do_facet mgs $cmd --name $1        \
631                         --range $range; then
632                         rc=$(($rc + 1))
633                 fi
634         done
635
636         return $rc
637 }
638
639 add_idmaps() {
640         local i
641         local j
642         local client_id
643         local fs_id
644         local cmd="$LCTL nodemap_add_idmap"
645         local rc=0
646
647         for ((i = 0; i < NODEMAP_COUNT; i++)); do
648                 for ((j = 500; j < NODEMAP_MAX_ID; j++)); do
649                         client_id=$j
650                         fs_id=$(($j + 1))
651                         if ! do_facet mgs $cmd                          \
652                         --name ${HOSTNAME_CHECKSUM}_${i}                \
653                         --idtype uid --idmap $client_id:$fs_id; then
654                                 rc=$(($rc + 1))
655                         fi
656                         if ! do_facet mgs $cmd                          \
657                         --name ${HOSTNAME_CHECKSUM}_${i}                \
658                         --idtype gid --idmap $client_id:$fs_id; then
659                                 rc=$(($rc + 1))
660                         fi
661                 done
662         done
663
664         return $rc
665 }
666
667 delete_idmaps() {
668         local i
669         local j
670         local client_id
671         local fs_id
672         local cmd="$LCTL nodemap_del_idmap"
673         local rc=0
674
675         for ((i = 0; i < NODEMAP_COUNT; i++)); do
676                 for ((j = 500; j < NODEMAP_MAX_ID; j++)); do
677                         client_id=$j
678                         fs_id=$(($j + 1))
679                         if ! do_facet mgs $cmd                          \
680                         --name ${HOSTNAME_CHECKSUM}_${i}                \
681                         --idtype uid --idmap $client_id:$fs_id; then
682                                 rc=$(($rc + 1))
683                         fi
684                         if ! do_facet mgs $cmd                          \
685                         --name ${HOSTNAME_CHECKSUM}_${i}                \
686                         --idtype gid --idmap $client_id:$fs_id; then
687                                 rc=$(($rc + 1))
688                         fi
689                 done
690         done
691
692         return $rc
693 }
694
695 modify_flags() {
696         local i
697         local proc
698         local option
699         local cmd="$LCTL nodemap_modify"
700         local rc=0
701
702         proc[0]="admin_nodemap"
703         proc[1]="trusted_nodemap"
704         option[0]="admin"
705         option[1]="trusted"
706
707         for ((idx = 0; idx < 2; idx++)); do
708                 if ! do_facet mgs $cmd --name $1        \
709                         --property ${option[$idx]}      \
710                         --value 1; then
711                         rc=$((rc + 1))
712                 fi
713
714                 if ! do_facet mgs $cmd --name $1        \
715                         --property ${option[$idx]}      \
716                         --value 0; then
717                         rc=$((rc + 1))
718                 fi
719         done
720
721         return $rc
722 }
723
724 squash_id() {
725         local cmd
726
727         cmd[0]="$LCTL nodemap_modify --property squash_uid"
728         cmd[1]="$LCTL nodemap_modify --property squash_gid"
729
730         if ! do_facet mgs ${cmd[$3]} --name $1 --value $2; then
731                 return 1
732         fi
733 }
734
735 test_nid() {
736         local cmd
737
738         cmd="$LCTL nodemap_test_nid"
739
740         nid=$(do_facet mgs $cmd $1)
741
742         if [ $nid == $2 ]; then
743                 return 0
744         fi
745
746         return 1
747 }
748
749 test_idmap() {
750         local i
751         local j
752         local fs_id
753         local cmd="$LCTL nodemap_test_id"
754         local rc=0
755
756         ## nodemap deactivated
757         if ! do_facet mgs lctl nodemap_activate 0; then
758                 return 1
759         fi
760         for ((id = 500; id < NODEMAP_MAX_ID; id++)); do
761                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
762                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
763                         fs_id=$(do_facet mgs $cmd --nid $nid    \
764                                 --idtype uid --id $id)
765                         if [ $fs_id != $id ]; then
766                                 rc=$((rc + 1))
767                         fi
768                 done
769         done
770
771         ## nodemap activated
772         if ! do_facet mgs lctl nodemap_activate 1; then
773                 return 2
774         fi
775
776         for ((id = 500; id < NODEMAP_MAX_ID; id++)); do
777                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
778                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
779                         fs_id=$(do_facet mgs $cmd --nid $nid    \
780                                 --idtype uid --id $id)
781                         expected_id=$((id + 1))
782                         if [ $fs_id != $expected_id ]; then
783                                 rc=$((rc + 1))
784                         fi
785                 done
786         done
787
788         ## trust client ids
789         for ((i = 0; i < NODEMAP_COUNT; i++)); do
790                 if ! do_facet mgs $LCTL nodemap_modify                  \
791                                 --name ${HOSTNAME_CHECKSUM}_${i}        \
792                                 --property trusted --value 1; then
793                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
794                                 "failed with $rc"
795                         return 3
796                 fi
797         done
798
799         for ((id = 500; id < NODEMAP_MAX_ID; id++)); do
800                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
801                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
802                         fs_id=$(do_facet mgs $cmd --nid $nid    \
803                                 --idtype uid --id $id)
804                         expected_id=$((id + 1))
805                         if [ $fs_id != $id ]; then
806                                 rc=$((rc + 1))
807                         fi
808                 done
809         done
810
811         ## ensure allow_root_access is enabled
812         for ((i = 0; i < NODEMAP_COUNT; i++)); do
813                 if ! do_facet mgs $LCTL nodemap_modify          \
814                         --name ${HOSTNAME_CHECKSUM}_${i}        \
815                         --property admin --value 1; then
816                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
817                                 "failed with $rc"
818                         return 3
819                 fi
820         done
821
822         ## check that root is mapped to 99
823         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
824                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
825                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
826                 expected_id=$((id + 1))
827                 if [ $fs_id != 0 ]; then
828                         rc=$((rc + 1))
829                 fi
830         done
831
832         ## ensure allow_root_access is disabled
833         for ((i = 0; i < NODEMAP_COUNT; i++)); do
834                 if ! do_facet mgs $LCTL nodemap_modify          \
835                                 --name ${HOSTNAME_CHECKSUM}_${i}        \
836                                 --property admin --value 0; then
837                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
838                                 "failed with $rc"
839                         return 3
840                 fi
841         done
842
843         ## check that root allowed
844         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
845                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
846                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
847                 expected_id=$((id + 1))
848                 if [ $fs_id != 99 ]; then
849                         rc=$((rc + 1))
850                 fi
851         done
852
853         ## reset client trust to 0
854         for ((i = 0; i < NODEMAP_COUNT; i++)); do
855                 if ! do_facet mgs $LCTL nodemap_modify          \
856                         --name ${HOSTNAME_CHECKSUM}_${i}        \
857                         --property trusted --value 0; then
858                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
859                                 "failed with $rc"
860                         return 3
861                 fi
862         done
863
864         return $rc
865 }
866
867 test_7() {
868         local rc
869
870         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
871         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
872                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
873                 return
874
875         create_nodemaps
876         rc=$?
877         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
878
879         delete_nodemaps
880         rc=$?
881         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 2
882
883         return 0
884 }
885 run_test 7 "nodemap create and delete"
886
887 test_8() {
888         local rc
889
890         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
891         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
892                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
893                 return
894
895         # Set up nodemaps
896
897         create_nodemaps
898         rc=$?
899         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
900
901         # Try duplicates
902
903         create_nodemaps
904         rc=$?
905         [[ $rc == 0 ]] && error "duplicate nodemap_add allowed with $rc" &&
906         return 2
907
908         # Clean up
909         delete_nodemaps
910         rc=$?
911         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 3
912
913         return 0
914 }
915 run_test 8 "nodemap reject duplicates"
916
917 test_9() {
918         local i
919         local rc
920
921         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
922         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
923                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
924                 return
925
926         rc=0
927         create_nodemaps
928         rc=$?
929         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
930
931         rc=0
932         for ((i = 0; i < NODEMAP_COUNT; i++)); do
933                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
934                         rc=$((rc + 1))
935                 fi
936         done
937         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
938
939         rc=0
940         for ((i = 0; i < NODEMAP_COUNT; i++)); do
941                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
942                         rc=$((rc + 1))
943                 fi
944         done
945         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
946
947         rc=0
948         delete_nodemaps
949         rc=$?
950         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 4
951
952         return 0
953 }
954 run_test 9 "nodemap range add"
955
956 test_10() {
957         local rc
958
959         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
960         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
961                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
962                 return
963
964         rc=0
965         create_nodemaps
966         rc=$?
967         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
968
969         rc=0
970         for ((i = 0; i < NODEMAP_COUNT; i++)); do
971                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
972                         rc=$((rc + 1))
973                 fi
974         done
975         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
976
977         rc=0
978         for ((i = 0; i < NODEMAP_COUNT; i++)); do
979                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
980                         rc=$((rc + 1))
981                 fi
982         done
983         [[ $rc == 0 ]] && error "nodemap_add_range duplicate add with $rc" &&
984                 return 2
985
986
987         rc=0
988         for ((i = 0; i < NODEMAP_COUNT; i++)); do
989                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
990                         rc=$((rc + 1))
991                 fi
992         done
993         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
994
995         delete_nodemaps
996         rc=$?
997         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 5
998
999         return 0
1000 }
1001 run_test 10 "nodemap reject duplicate ranges"
1002
1003 test_11() {
1004         local rc
1005
1006         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
1007         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
1008                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
1009                 return
1010
1011         rc=0
1012         create_nodemaps
1013         rc=$?
1014         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1015
1016         rc=0
1017         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1018                 if ! modify_flags ${HOSTNAME_CHECKSUM}_${i}; then
1019                         rc=$((rc + 1))
1020                 fi
1021         done
1022         [[ $rc != 0 ]] && error "nodemap_modify with $rc" && return 2
1023
1024         rc=0
1025         delete_nodemaps
1026         rc=$?
1027         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 3
1028
1029         return 0
1030 }
1031 run_test 11 "nodemap modify"
1032
1033 test_12() {
1034         local rc
1035
1036         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
1037         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
1038                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
1039                 return
1040
1041         rc=0
1042         create_nodemaps
1043         rc=$?
1044         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1045
1046         rc=0
1047         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1048                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 0; then
1049                         rc=$((rc + 1))
1050                 fi
1051         done
1052         [[ $rc != 0 ]] && error "nodemap squash_uid with $rc" && return 2
1053
1054         rc=0
1055         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1056                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 1; then
1057                         rc=$((rc + 1))
1058                 fi
1059         done
1060         [[ $rc != 0 ]] && error "nodemap squash_gid with $rc" && return 3
1061
1062         rc=0
1063         delete_nodemaps
1064         rc=$?
1065         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
1066
1067         return 0
1068 }
1069 run_test 12 "nodemap set squash ids"
1070
1071 test_13() {
1072         local rc
1073
1074         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
1075         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
1076                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
1077                 return
1078
1079         rc=0
1080         create_nodemaps
1081         rc=$?
1082         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1083
1084         rc=0
1085         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1086                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
1087                         rc=$((rc + 1))
1088                 fi
1089         done
1090         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
1091
1092         rc=0
1093         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1094                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
1095                         for ((k = 1; k < 253; k++)); do
1096                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
1097                                        ${HOSTNAME_CHECKSUM}_${i}; then
1098                                         rc=$((rc + 1))
1099                                 fi
1100                         done
1101                 done
1102         done
1103         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
1104
1105         rc=0
1106         delete_nodemaps
1107         rc=$?
1108         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
1109
1110         return 0
1111 }
1112 run_test 13 "test nids"
1113
1114 test_14() {
1115         local rc
1116
1117         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
1118         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
1119                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
1120                 return
1121
1122         rc=0
1123         create_nodemaps
1124         rc=$?
1125         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1126
1127         rc=0
1128         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1129                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
1130                         for ((k = 1; k < 253; k++)); do
1131                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
1132                                         default; then
1133                                         rc=$((rc + 1))
1134                                 fi
1135                         done
1136                 done
1137         done
1138         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
1139
1140         rc=0
1141         delete_nodemaps
1142         rc=$?
1143         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
1144
1145         return 0
1146 }
1147 run_test 14 "test default nodemap nid lookup"
1148
1149 test_15() {
1150         local rc
1151
1152         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
1153         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
1154                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
1155                 return
1156
1157         rc=0
1158         create_nodemaps
1159         rc=$?
1160         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1161
1162         rc=0
1163         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1164                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
1165                         rc=$((rc + 1))
1166                 fi
1167         done
1168         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
1169
1170         rc=0
1171         add_idmaps
1172         rc=$?
1173         [[ $rc != 0 ]] && error "nodemap_add_idmap failed with $rc" && return 3
1174
1175         rc=0
1176         test_idmap
1177         rc=$?
1178         [[ $rc != 0 ]] && error "nodemap_test_id failed with $rc" && return 4
1179
1180         rc=0
1181         delete_idmaps
1182         rc=$?
1183         [[ $rc != 0 ]] && error "nodemap_del_idmap failed with $rc" && return 5
1184
1185         rc=0
1186         delete_nodemaps
1187         rc=$?
1188         [[ $rc != 0 ]] && error "nodemap_delete failed with $rc" && return 6
1189
1190         return 0
1191 }
1192 run_test 15 "test id mapping"
1193
1194 log "cleanup: ======================================================"
1195
1196 sec_unsetup() {
1197         for num in `seq $MDSCOUNT`; do
1198                 if [ "${identity_old[$num]}" = 1 ]; then
1199                         switch_identity $num false || identity_old[$num]=$?
1200                 fi
1201         done
1202
1203         $RUNAS -u $ID0 ls $DIR
1204         $RUNAS -u $ID1 ls $DIR
1205 }
1206 sec_unsetup
1207
1208 sec_cleanup
1209
1210 complete $SECONDS
1211 exit_status