Whamcloud - gitweb
LU-9682 nodemap: delete nids range from nodemap correctly
[fs/lustre-release.git] / lustre / tests / sanity-sec.sh
index 30bfeb2..5c517b1 100755 (executable)
@@ -7,8 +7,12 @@
 set -e
 
 ONLY=${ONLY:-"$*"}
-# bug number for skipped test: 19430 19967 19967
-ALWAYS_EXCEPT="                2     5     6    $SANITY_SEC_EXCEPT"
+# bug number for skipped test:
+ALWAYS_EXCEPT="              $SANITY_SEC_EXCEPT"
+if $SHARED_KEY; then
+# bug number for skipped test: 9145 9145 9671 9145 9145 9145 9145 9245
+       ALWAYS_EXCEPT="        17   18   19   20   21   22   23   27 $ALWAYS_EXCEPT"
+fi
 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
 
 SRCDIR=$(dirname $0)
@@ -114,6 +118,7 @@ sec_login() {
        local user=$1
        local group=$2
 
+       $GSS_KRB5 || return
        if ! $RUNAS_CMD -u $user krb5_login.sh; then
                error "$user login kerberos failed."
                exit 1
@@ -551,7 +556,7 @@ test_7() {
 
        delete_nodemaps
        rc=$?
-       [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 2
+       [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 2
 
        return 0
 }
@@ -581,7 +586,7 @@ test_8() {
        # Clean up
        delete_nodemaps
        rc=$?
-       [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 3
+       [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 3
 
        return 0
 }
@@ -620,13 +625,13 @@ test_9() {
        rc=0
        delete_nodemaps
        rc=$?
-       [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 4
+       [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 4
 
        return 0
 }
 run_test 9 "nodemap range add"
 
-test_10() {
+test_10a() {
        local rc
 
        remote_mgs_nodsh && skip "remote MGS with nodsh" && return
@@ -667,11 +672,39 @@ test_10() {
 
        delete_nodemaps
        rc=$?
-       [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 5
+       [[ $rc != 0 ]] && error "nodemap_del failed with $rc" && return 5
 
        return 0
 }
-run_test 10 "nodemap reject duplicate ranges"
+run_test 10a "nodemap reject duplicate ranges"
+
+test_10b() {
+       [ $(lustre_version_code mgs) -lt $(version_code 2.10.53) ] &&
+               skip "Need MGS >= 2.10.53" && return
+
+       local nm1="nodemap1"
+       local nm2="nodemap2"
+       local nids="192.168.19.[0-255]@o2ib20"
+
+       do_facet mgs $LCTL nodemap_del $nm1 2>/dev/null
+       do_facet mgs $LCTL nodemap_del $nm2 2>/dev/null
+
+       do_facet mgs $LCTL nodemap_add $nm1 || error "Add $nm1 failed"
+       do_facet mgs $LCTL nodemap_add $nm2 || error "Add $nm2 failed"
+       do_facet mgs $LCTL nodemap_add_range --name $nm1 --range $nids ||
+               error "Add range $nids to $nm1 failed"
+       [ -n "$(do_facet mgs $LCTL get_param nodemap.$nm1.* |
+               grep start_nid)" ] || error "No range was found"
+       do_facet mgs $LCTL nodemap_del_range --name $nm2 --range $nids &&
+               error "Deleting range $nids from $nm2 should fail"
+       [ -n "$(do_facet mgs $LCTL get_param nodemap.$nm1.* |
+               grep start_nid)" ] || error "Range $nids should be there"
+
+       do_facet mgs $LCTL nodemap_del $nm1 || error "Delete $nm1 failed"
+       do_facet mgs $LCTL nodemap_del $nm2 || error "Delete $nm2 failed"
+       return 0
+}
+run_test 10b "delete range from the correct nodemap"
 
 test_11() {
        local rc
@@ -867,6 +900,7 @@ run_test 15 "test id mapping"
 wait_nm_sync() {
        local nodemap_name=$1
        local key=$2
+       local value=$3
        local proc_param="${nodemap_name}.${key}"
        [ "$nodemap_name" == "active" ] && proc_param="active"
 
@@ -875,11 +909,18 @@ wait_nm_sync() {
 
        local max_retries=20
        local is_sync
-       local out1=$(do_facet mgs $LCTL get_param nodemap.${proc_param})
+       local out1=""
        local out2
        local mgs_ip=$(host_nids_address $mgs_HOST $NETTYPE | cut -d' ' -f1)
        local i
 
+       if [ -z "$value" ]; then
+               out1=$(do_facet mgs $LCTL get_param nodemap.${proc_param})
+               echo "On MGS ${mgs_ip}, ${proc_param} = $out1"
+       else
+               out1=$value;
+       fi
+
        # wait up to 10 seconds for other servers to sync with mgs
        for i in $(seq 1 10); do
                for node in $(all_server_nodes); do
@@ -887,10 +928,13 @@ wait_nm_sync() {
                                    cut -d' ' -f1)
 
                    is_sync=true
-                   [ $node_ip == $mgs_ip ] && continue
+                   if [ -z "$value" ]; then
+                       [ $node_ip == $mgs_ip ] && continue
+                   fi
 
                    out2=$(do_node $node_ip $LCTL get_param \
                                   nodemap.$proc_param 2>/dev/null)
+                   echo "On $node ${node_ip}, ${proc_param} = $out2"
                    [ "$out1" != "$out2" ] && is_sync=false && break
                done
                $is_sync && break
@@ -911,7 +955,7 @@ create_fops_nodemaps() {
        local client
        for client in $clients; do
                local client_ip=$(host_nids_address $client $NETTYPE)
-               local client_nid=$(h2$NETTYPE $client_ip)
+               local client_nid=$(h2nettype $client_ip)
                do_facet mgs $LCTL nodemap_add c${i} || return 1
                do_facet mgs $LCTL nodemap_add_range    \
                        --name c${i} --range $client_nid || return 1
@@ -1079,8 +1123,8 @@ do_fops_quota_test() {
        local qused_high=$((qused_orig + quota_fuzz))
        local qused_low=$((qused_orig - quota_fuzz))
        local testfile=$DIR/$tdir/$tfile
-       $run_u dd if=/dev/zero of=$testfile bs=1M count=1 >& /dev/null ||
-               error "unable to write quota test file"
+       $run_u dd if=/dev/zero of=$testfile oflag=sync bs=1M count=1 \
+               >& /dev/null || error "unable to write quota test file"
        sync; sync_all_data || true
 
        local qused_new=$(nodemap_check_quota "$run_u")
@@ -1331,6 +1375,7 @@ nodemap_test_cleanup() {
        do_facet mgs $LCTL nodemap_activate 0
        wait_nm_sync active 0
 
+       export SK_UNIQUE_NM=false
        return 0
 }
 
@@ -1577,7 +1622,10 @@ run_test 24 "check nodemap proc files for LBUGs and Oopses"
 test_25() {
        local tmpfile=$(mktemp)
        local tmpfile2=$(mktemp)
+       local tmpfile3=$(mktemp)
+       local tmpfile4=$(mktemp)
        local subdir=c0dir
+       local client
 
        nodemap_version_check || return 0
 
@@ -1585,41 +1633,59 @@ test_25() {
        zconf_umount_clients $CLIENTS $MOUNT ||
            error "unable to umount clients $CLIENTS"
 
+       export SK_UNIQUE_NM=true
        nodemap_test_setup
 
+       # enable trusted/admin for setquota call in cleanup_and_setup_lustre()
+       i=0
+       for client in $clients; do
+               do_facet mgs $LCTL nodemap_modify --name c${i} \
+                       --property admin --value 1
+               do_facet mgs $LCTL nodemap_modify --name c${i} \
+                       --property trusted --value 1
+               ((i++))
+       done
+       wait_nm_sync c$((i - 1)) trusted_nodemap
+
        trap nodemap_test_cleanup EXIT
 
        # create a new, empty nodemap, and add fileset info to it
-       do_facet mgs $LCTL nodemap_add test26 ||
-               error "unable to create nodemap test26"
-       do_facet mgs $LCTL set_param -P nodemap.test26.fileset=/$subdir ||
-               error "unable to add fileset info to nodemap test26"
+       do_facet mgs $LCTL nodemap_add test25 ||
+               error "unable to create nodemap $testname"
+       do_facet mgs $LCTL set_param -P nodemap.$testname.fileset=/$subdir ||
+               error "unable to add fileset info to nodemap test25"
 
-       wait_nm_sync test26 id
+       wait_nm_sync test25 id
 
        do_facet mgs $LCTL nodemap_info > $tmpfile
        do_facet mds $LCTL nodemap_info > $tmpfile2
 
-       cleanup_and_setup_lustre
+       if ! $SHARED_KEY; then
+               # will conflict with SK's nodemaps
+               cleanup_and_setup_lustre
+       fi
        # stop clients for this test
        zconf_umount_clients $CLIENTS $MOUNT ||
            error "unable to umount clients $CLIENTS"
 
-       diff -q <(do_facet mgs $LCTL nodemap_info) $tmpfile >& /dev/null ||
+       do_facet mgs $LCTL nodemap_info > $tmpfile3
+       diff -q $tmpfile3 $tmpfile >& /dev/null ||
                error "nodemap_info diff on MGS after remount"
 
-       diff -q <(do_facet mds $LCTL nodemap_info) $tmpfile2 >& /dev/null ||
+       do_facet mds $LCTL nodemap_info > $tmpfile4
+       diff -q $tmpfile4 $tmpfile2 >& /dev/null ||
                error "nodemap_info diff on MDS after remount"
 
        # cleanup nodemap
-       do_facet mgs $LCTL nodemap_del test26 ||
-           error "cannot delete nodemap test26 from config"
+       do_facet mgs $LCTL nodemap_del test25 ||
+           error "cannot delete nodemap test25 from config"
        nodemap_test_cleanup
        # restart clients previously stopped
        zconf_mount_clients $CLIENTS $MOUNT ||
            error "unable to mount clients $CLIENTS"
 
        rm -f $tmpfile $tmpfile2
+       export SK_UNIQUE_NM=false
 }
 run_test 25 "test save and reload nodemap config"
 
@@ -1639,24 +1705,32 @@ run_test 26 "test transferring very large nodemap"
 test_27() {
        local subdir=c0dir
        local subsubdir=c0subdir
+       local fileset_on_mgs=""
+       local loop=0
 
        nodemap_test_setup
-       trap nodemap_test_cleanup EXIT
+       if $SHARED_KEY; then
+               export SK_UNIQUE_NM=true
+       else
+               # will conflict with SK's nodemaps
+               trap nodemap_test_cleanup EXIT
+       fi
 
        fileset_test_setup
 
        # add fileset info to nodemap
-       do_facet mgs $LCTL set_param nodemap.c0.fileset=/$subdir ||
-               error "unable to set fileset info on nodemap c0"
        do_facet mgs $LCTL set_param -P nodemap.c0.fileset=/$subdir ||
                error "unable to add fileset info to nodemap c0"
-       wait_nm_sync c0 fileset
+       wait_nm_sync c0 fileset "nodemap.c0.fileset=/$subdir"
 
        # re-mount client
        zconf_umount_clients ${clients_arr[0]} $MOUNT ||
                error "unable to umount client ${clients_arr[0]}"
+       # set some generic fileset to trigger SSK code
+       export FILESET=/
        zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
                error "unable to remount client ${clients_arr[0]}"
+       unset FILESET
 
        # test mount point content
        do_node ${clients_arr[0]} test -f $MOUNT/this_is_$subdir ||
@@ -1677,6 +1751,18 @@ test_27() {
        # remove fileset info from nodemap
        do_facet mgs $LCTL nodemap_set_fileset --name c0 --fileset \'\' ||
                error "unable to delete fileset info on nodemap c0"
+       fileset_on_mgs=$(do_facet mgs $LCTL get_param nodemap.c0.fileset)
+       while [ "${fileset_on_mgs}" != "nodemap.c0.fileset=" ]; do
+           if [ $loop -eq 10 ]; then
+               error "On MGS, fileset cannnot be cleared"
+               break;
+           else
+               loop=$((loop+1))
+               echo "On MGS, fileset is still ${fileset_on_mgs}, waiting..."
+               sleep 20;
+           fi
+           fileset_on_mgs=$(do_facet mgs $LCTL get_param nodemap.c0.fileset)
+       done
        do_facet mgs $LCTL set_param -P nodemap.c0.fileset=\'\' ||
                error "unable to reset fileset info on nodemap c0"
        wait_nm_sync c0 fileset
@@ -1689,13 +1775,117 @@ test_27() {
 
        # test mount point content
        do_node ${clients_arr[0]} test -d $MOUNT/$subdir ||
-               error "fileset not cleared on nodemap c0"
+               (ls $MOUNT ; error "fileset not cleared on nodemap c0")
 
+       # back to non-nodemap setup
+       if $SHARED_KEY; then
+               export SK_UNIQUE_NM=false
+               zconf_umount_clients ${clients_arr[0]} $MOUNT ||
+                       error "unable to umount client ${clients_arr[0]}"
+       fi
        fileset_test_cleanup
        nodemap_test_cleanup
+       if $SHARED_KEY; then
+               zconf_mount_clients ${clients_arr[0]} $MOUNT $MOUNT_OPTS ||
+                       error "unable to remount client ${clients_arr[0]}"
+       fi
 }
 run_test 27 "test fileset in nodemap"
 
+test_28() {
+       if ! $SHARED_KEY; then
+               skip "need shared key feature for this test" && return
+       fi
+       mkdir -p $DIR/$tdir || error "mkdir failed"
+       touch $DIR/$tdir/$tdir.out || error "touch failed"
+       if [ ! -f $DIR/$tdir/$tdir.out ]; then
+               error "read before rotation failed"
+       fi
+       # store top key identity to ensure rotation has occurred
+       SK_IDENTITY_OLD=$(lctl get_param *.*.*srpc* | grep "expire" |
+               head -1 | awk '{print $15}' | cut -c1-8)
+       do_facet $SINGLEMDS lfs flushctx ||
+                error "could not run flushctx on $SINGLEMDS"
+       sleep 5
+       lfs flushctx || error "could not run flushctx on client"
+       sleep 5
+       # verify new key is in place
+       SK_IDENTITY_NEW=$(lctl get_param *.*.*srpc* | grep "expire" |
+               head -1 | awk '{print $15}' | cut -c1-8)
+       if [ $SK_IDENTITY_OLD == $SK_IDENTITY_NEW ]; then
+               error "key did not rotate correctly"
+       fi
+       if [ ! -f $DIR/$tdir/$tdir.out ]; then
+               error "read after rotation failed"
+       fi
+}
+run_test 28 "check shared key rotation method"
+
+test_29() {
+       if ! $SHARED_KEY; then
+               skip "need shared key feature for this test" && return
+       fi
+       if [ $SK_FLAVOR != "ski" ] && [ $SK_FLAVOR != "skpi" ]; then
+               skip "test only valid if integrity is active"
+       fi
+       rm -r $DIR/$tdir
+       mkdir $DIR/$tdir || error "mkdir"
+       touch $DIR/$tdir/$tfile || error "touch"
+       zconf_umount_clients ${clients_arr[0]} $MOUNT ||
+               error "unable to umount clients"
+       keyctl show | awk '/lustre/ { print $1 }' |
+               xargs -IX keyctl unlink X
+       OLD_SK_PATH=$SK_PATH
+       export SK_PATH=/dev/null
+       if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
+               export SK_PATH=$OLD_SK_PATH
+               if [ -e $DIR/$tdir/$tfile ]; then
+                       error "able to mount and read without key"
+               else
+                       error "able to mount without key"
+               fi
+       else
+               export SK_PATH=$OLD_SK_PATH
+               keyctl show | awk '/lustre/ { print $1 }' |
+                       xargs -IX keyctl unlink X
+       fi
+}
+run_test 29 "check for missing shared key"
+
+test_30() {
+       if ! $SHARED_KEY; then
+               skip "need shared key feature for this test" && return
+       fi
+       if [ $SK_FLAVOR != "ski" ] && [ $SK_FLAVOR != "skpi" ]; then
+               skip "test only valid if integrity is active"
+       fi
+       mkdir -p $DIR/$tdir || error "mkdir failed"
+       touch $DIR/$tdir/$tdir.out || error "touch failed"
+       zconf_umount_clients ${clients_arr[0]} $MOUNT ||
+               error "unable to umount clients"
+       # unload keys from ring
+       keyctl show | awk '/lustre/ { print $1 }' |
+               xargs -IX keyctl unlink X
+       # invalidate the key with bogus filesystem name
+       lgss_sk -w $SK_PATH/$FSNAME-bogus.key -f $FSNAME.bogus \
+               -t client -d /dev/urandom || error "lgss_sk failed (1)"
+       do_facet $SINGLEMDS lfs flushctx || error "could not run flushctx"
+       OLD_SK_PATH=$SK_PATH
+       export SK_PATH=$SK_PATH/$FSNAME-bogus.key
+       if zconf_mount_clients ${clients_arr[0]} $MOUNT; then
+               SK_PATH=$OLD_SK_PATH
+               if [ -a $DIR/$tdir/$tdir.out ]; then
+                       error "mount and read file with invalid key"
+               else
+                       error "mount with invalid key"
+               fi
+       fi
+       SK_PATH=$OLD_SK_PATH
+       zconf_umount_clients ${clients_arr[0]} $MOUNT ||
+               error "unable to umount clients"
+}
+run_test 30 "check for invalid shared key"
+
 log "cleanup: ======================================================"
 
 sec_unsetup() {