Whamcloud - gitweb
LU-4647 nodemap: add mapping functionality
[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 LU-5423 19967 19967
11 ALWAYS_EXCEPT="                2     4       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=16
38 NODEMAP_RANGE_COUNT=3
39 NODEMAP_IPADDR_COUNT=30
40 NODEMAP_MAX_ID=128
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 # ensure that the squash defaults are the expected defaults
736 squash_id default 99 0
737 squash_id default 99 1
738
739 test_nid() {
740         local cmd
741
742         cmd="$LCTL nodemap_test_nid"
743
744         nid=$(do_facet mgs $cmd $1)
745
746         if [ $nid == $2 ]; then
747                 return 0
748         fi
749
750         return 1
751 }
752
753 test_idmap() {
754         local i
755         local j
756         local fs_id
757         local cmd="$LCTL nodemap_test_id"
758         local rc=0
759
760         ## nodemap deactivated
761         if ! do_facet mgs lctl nodemap_activate 0; then
762                 return 1
763         fi
764         for ((id = 500; id < NODEMAP_MAX_ID; id++)); do
765                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
766                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
767                         fs_id=$(do_facet mgs $cmd --nid $nid    \
768                                 --idtype uid --id $id)
769                         if [ $fs_id != $id ]; then
770                                 rc=$((rc + 1))
771                         fi
772                 done
773         done
774
775         ## nodemap activated
776         if ! do_facet mgs lctl nodemap_activate 1; then
777                 return 2
778         fi
779
780         for ((id = 500; id < NODEMAP_MAX_ID; id++)); do
781                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
782                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
783                         fs_id=$(do_facet mgs $cmd --nid $nid    \
784                                 --idtype uid --id $id)
785                         expected_id=$((id + 1))
786                         if [ $fs_id != $expected_id ]; then
787                                 rc=$((rc + 1))
788                         fi
789                 done
790         done
791
792         ## trust client ids
793         for ((i = 0; i < NODEMAP_COUNT; i++)); do
794                 if ! do_facet mgs $LCTL nodemap_modify                  \
795                                 --name ${HOSTNAME_CHECKSUM}_${i}        \
796                                 --property trusted --value 1; then
797                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
798                                 "failed with $rc"
799                         return 3
800                 fi
801         done
802
803         for ((id = 500; id < NODEMAP_MAX_ID; id++)); do
804                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
805                         nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
806                         fs_id=$(do_facet mgs $cmd --nid $nid    \
807                                 --idtype uid --id $id)
808                         expected_id=$((id + 1))
809                         if [ $fs_id != $id ]; then
810                                 rc=$((rc + 1))
811                         fi
812                 done
813         done
814
815         ## ensure allow_root_access is enabled
816         for ((i = 0; i < NODEMAP_COUNT; i++)); do
817                 if ! do_facet mgs $LCTL nodemap_modify          \
818                         --name ${HOSTNAME_CHECKSUM}_${i}        \
819                         --property admin --value 1; then
820                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
821                                 "failed with $rc"
822                         return 3
823                 fi
824         done
825
826         ## check that root is mapped to 99
827         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
828                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
829                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
830                 expected_id=$((id + 1))
831                 if [ $fs_id != 0 ]; then
832                         rc=$((rc + 1))
833                 fi
834         done
835
836         ## ensure allow_root_access is disabled
837         for ((i = 0; i < NODEMAP_COUNT; i++)); do
838                 if ! do_facet mgs $LCTL nodemap_modify          \
839                                 --name ${HOSTNAME_CHECKSUM}_${i}        \
840                                 --property admin --value 0; then
841                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
842                                 "failed with $rc"
843                         return 3
844                 fi
845         done
846
847         ## check that root allowed
848         for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
849                 nid="$SUBNET_CHECKSUM.0.${j}.100@tcp"
850                 fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0)
851                 expected_id=$((id + 1))
852                 if [ $fs_id != 99 ]; then
853                         rc=$((rc + 1))
854                 fi
855         done
856
857         ## reset client trust to 0
858         for ((i = 0; i < NODEMAP_COUNT; i++)); do
859                 if ! do_facet mgs $LCTL nodemap_modify          \
860                         --name ${HOSTNAME_CHECKSUM}_${i}        \
861                         --property trusted --value 0; then
862                         error "nodemap_modify ${HOSTNAME_CHECKSUM}_${i} "
863                                 "failed with $rc"
864                         return 3
865                 fi
866         done
867
868         return $rc
869 }
870
871 test_7() {
872         local rc
873
874         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
875         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
876                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
877                 return
878
879         create_nodemaps
880         rc=$?
881         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
882
883         delete_nodemaps
884         rc=$?
885         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 2
886
887         return 0
888 }
889 run_test 7 "nodemap create and delete"
890
891 test_8() {
892         local rc
893
894         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
895         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
896                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
897                 return
898
899         # Set up nodemaps
900
901         create_nodemaps
902         rc=$?
903         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
904
905         # Try duplicates
906
907         create_nodemaps
908         rc=$?
909         [[ $rc == 0 ]] && error "duplicate nodemap_add allowed with $rc" &&
910         return 2
911
912         # Clean up
913         delete_nodemaps
914         rc=$?
915         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 3
916
917         return 0
918 }
919 run_test 8 "nodemap reject duplicates"
920
921 test_9() {
922         local i
923         local rc
924
925         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
926         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
927                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
928                 return
929
930         rc=0
931         create_nodemaps
932         rc=$?
933         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
934
935         rc=0
936         for ((i = 0; i < NODEMAP_COUNT; i++)); do
937                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
938                         rc=$((rc + 1))
939                 fi
940         done
941         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
942
943         rc=0
944         for ((i = 0; i < NODEMAP_COUNT; i++)); do
945                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
946                         rc=$((rc + 1))
947                 fi
948         done
949         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
950
951         rc=0
952         delete_nodemaps
953         rc=$?
954         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 4
955
956         return 0
957 }
958 run_test 9 "nodemap range add"
959
960 test_10() {
961         local rc
962
963         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
964         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
965                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
966                 return
967
968         rc=0
969         create_nodemaps
970         rc=$?
971         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
972
973         rc=0
974         for ((i = 0; i < NODEMAP_COUNT; i++)); do
975                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
976                         rc=$((rc + 1))
977                 fi
978         done
979         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
980
981         rc=0
982         for ((i = 0; i < NODEMAP_COUNT; i++)); do
983                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
984                         rc=$((rc + 1))
985                 fi
986         done
987         [[ $rc == 0 ]] && error "nodemap_add_range duplicate add with $rc" &&
988                 return 2
989
990
991         rc=0
992         for ((i = 0; i < NODEMAP_COUNT; i++)); do
993                 if ! delete_range ${HOSTNAME_CHECKSUM}_${i} $i; then
994                         rc=$((rc + 1))
995                 fi
996         done
997         [[ $rc != 0 ]] && error "nodemap_del_range failed with $rc" && return 4
998
999         delete_nodemaps
1000         rc=$?
1001         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 5
1002
1003         return 0
1004 }
1005 run_test 10 "nodemap reject duplicate ranges"
1006
1007 test_11() {
1008         local rc
1009
1010         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
1011         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
1012                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
1013                 return
1014
1015         rc=0
1016         create_nodemaps
1017         rc=$?
1018         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1019
1020         rc=0
1021         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1022                 if ! modify_flags ${HOSTNAME_CHECKSUM}_${i}; then
1023                         rc=$((rc + 1))
1024                 fi
1025         done
1026         [[ $rc != 0 ]] && error "nodemap_modify with $rc" && return 2
1027
1028         rc=0
1029         delete_nodemaps
1030         rc=$?
1031         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 3
1032
1033         return 0
1034 }
1035 run_test 11 "nodemap modify"
1036
1037 test_12() {
1038         local rc
1039
1040         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
1041         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
1042                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
1043                 return
1044
1045         rc=0
1046         create_nodemaps
1047         rc=$?
1048         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1049
1050         rc=0
1051         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1052                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 0; then
1053                         rc=$((rc + 1))
1054                 fi
1055         done
1056         [[ $rc != 0 ]] && error "nodemap squash_uid with $rc" && return 2
1057
1058         rc=0
1059         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1060                 if ! squash_id ${HOSTNAME_CHECKSUM}_${i} 88 1; then
1061                         rc=$((rc + 1))
1062                 fi
1063         done
1064         [[ $rc != 0 ]] && error "nodemap squash_gid with $rc" && return 3
1065
1066         rc=0
1067         delete_nodemaps
1068         rc=$?
1069         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
1070
1071         return 0
1072 }
1073 run_test 12 "nodemap set squash ids"
1074
1075 test_13() {
1076         local rc
1077
1078         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
1079         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
1080                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
1081                 return
1082
1083         rc=0
1084         create_nodemaps
1085         rc=$?
1086         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1087
1088         rc=0
1089         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1090                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
1091                         rc=$((rc + 1))
1092                 fi
1093         done
1094         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
1095
1096         rc=0
1097         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1098                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
1099                         for ((k = 1; k < 253; k++)); do
1100                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
1101                                        ${HOSTNAME_CHECKSUM}_${i}; then
1102                                         rc=$((rc + 1))
1103                                 fi
1104                         done
1105                 done
1106         done
1107         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
1108
1109         rc=0
1110         delete_nodemaps
1111         rc=$?
1112         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
1113
1114         return 0
1115 }
1116 run_test 13 "test nids"
1117
1118 test_14() {
1119         local rc
1120
1121         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
1122         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
1123                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
1124                 return
1125
1126         rc=0
1127         create_nodemaps
1128         rc=$?
1129         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1130
1131         rc=0
1132         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1133                 for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do
1134                         for ((k = 1; k < 253; k++)); do
1135                                 if ! test_nid $SUBNET_CHECKSUM.$i.$j.$k \
1136                                         default; then
1137                                         rc=$((rc + 1))
1138                                 fi
1139                         done
1140                 done
1141         done
1142         [[ $rc != 0 ]] && error "nodemap_test_nid failed with $rc" && return 3
1143
1144         rc=0
1145         delete_nodemaps
1146         rc=$?
1147         [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
1148
1149         return 0
1150 }
1151 run_test 14 "test default nodemap nid lookup"
1152
1153 test_15() {
1154         local rc
1155
1156         remote_mgs_nodsh && skip "remote MGS with nodsh" && return
1157         [ $(lustre_version_code $SINGLEMGS) -lt $(version_code 2.5.53) ] &&
1158                 skip "No nodemap on $(get_lustre_version) MGS, need 2.5.53+" &&
1159                 return
1160
1161         rc=0
1162         create_nodemaps
1163         rc=$?
1164         [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
1165
1166         rc=0
1167         for ((i = 0; i < NODEMAP_COUNT; i++)); do
1168                 if ! add_range ${HOSTNAME_CHECKSUM}_${i} $i; then
1169                         rc=$((rc + 1))
1170                 fi
1171         done
1172         [[ $rc != 0 ]] && error "nodemap_add_range failed with $rc" && return 2
1173
1174         rc=0
1175         add_idmaps
1176         rc=$?
1177         [[ $rc != 0 ]] && error "nodemap_add_idmap failed with $rc" && return 3
1178
1179         rc=0
1180         test_idmap
1181         rc=$?
1182         [[ $rc != 0 ]] && error "nodemap_test_id failed with $rc" && return 4
1183
1184         rc=0
1185         delete_idmaps
1186         rc=$?
1187         [[ $rc != 0 ]] && error "nodemap_del_idmap failed with $rc" && return 5
1188
1189         rc=0
1190         delete_nodemaps
1191         rc=$?
1192         [[ $rc != 0 ]] && error "nodemap_delete failed with $rc" && return 6
1193
1194         return 0
1195 }
1196 run_test 15 "test id mapping"
1197
1198 log "cleanup: ======================================================"
1199
1200 sec_unsetup() {
1201         ## nodemap deactivated
1202         do_facet mgs lctl nodemap_activate 0
1203
1204         for num in $(seq $MDSCOUNT); do
1205                 if [ "${identity_old[$num]}" = 1 ]; then
1206                         switch_identity $num false || identity_old[$num]=$?
1207                 fi
1208         done
1209
1210         $RUNAS -u $ID0 ls $DIR
1211         $RUNAS -u $ID1 ls $DIR
1212 }
1213 sec_unsetup
1214
1215 sec_cleanup
1216
1217 complete $SECONDS
1218 exit_status