+test_252() {
+ local f=$DIR/$tdir/$tfile
+ local fid=$(create_empty_file "$f")
+
+ # to have a short test
+ stack_trap "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
+ set_hsm_param loop_period 1
+
+ copytool setup
+
+ # Prevent archive from completing
+ copytool_suspend
+ $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
+ wait_request_state $fid ARCHIVE STARTED
+ rm -f "$f"
+
+ stack_trap "set_hsm_param active_request_timeout \
+ $(get_hsm_param active_request_timeout)" EXIT
+ set_hsm_param active_request_timeout 1
+
+ wait_request_state $fid ARCHIVE CANCELED
+ copytool_continue
+}
+run_test 252 "Timeout'ed running archive of a removed file should be canceled"
+
+test_253() {
+ local rc
+ # test needs a running copytool
+ copytool setup
+
+ mkdir -p $DIR/$tdir
+ local f=$DIR/$tdir/$tfile
+
+ dd if=/dev/zero of=$f bs=1MB count=10
+ local fid=$(path2fid $f)
+
+ $LFS hsm_archive $f || error "could not archive file"
+ wait_request_state $fid ARCHIVE SUCCEED
+
+ # clear locks to discard inode data
+ cancel_lru_locks osc
+
+ #define OBD_FAIL_MDC_MERGE 0x807
+ $LCTL set_param fail_loc=0x807
+
+ #expect error here, instead of release with wrong size
+ $LFS hsm_release $f
+ rc=$?
+ if ((rc == 0)); then
+ file_size=$(stat -c '%s' $f)
+ if ((file_size != 10485760)); then
+ error "Wrong file size after hsm_release"
+ fi
+ else
+ echo "could not release file"
+ fi
+}
+run_test 253 "Check for wrong file size after release"
+
+test_254a()
+{
+ [ $MDS1_VERSION -lt $(version_code 2.10.56) ] &&
+ skip "need MDS version at least 2.10.56"
+
+ # Check that the counters are initialized to 0
+ local count
+ for request_type in archive restore remove; do
+ count="$(get_hsm_param ${request_type}_count)" ||
+ error "Reading ${request_type}_count failed with $?"
+
+ [ "$count" -eq 0 ] ||
+ error "Expected ${request_type}_count to be " \
+ "0 != '$count'"
+ done
+}
+run_test 254a "Request counters are initialized to zero"
+
+test_254b()
+{
+ [ $MDS1_VERSION -lt $(version_code 2.10.56) ] &&
+ skip "need MDS version at least 2.10.56"
+
+ # The number of request to launch (at least 32)
+ local request_count=$((RANDOM % 32 + 32))
+ printf "Will launch %i requests of each type\n" "$request_count"
+
+ # Launch a copytool to process requests
+ copytool setup
+
+ # Set hsm.max_requests to allow starting all requests at the same time
+ stack_trap \
+ "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
+ set_hsm_param max_requests "$request_count"
+
+ local timeout
+ local count
+ for request_type in archive restore remove; do
+ printf "Checking %s requests\n" "${request_type}"
+ # Suspend the copytool to give us time to read the proc files
+ copytool_suspend
+
+ for ((i = 0; i < $request_count; i++)); do
+ case $request_type in
+ archive)
+ create_empty_file "$DIR/$tdir/$tfile-$i" \
+ >/dev/null 2>&1
+ ;;
+ restore)
+ lfs hsm_release "$DIR/$tdir/$tfile-$i"
+ ;;
+ esac
+ $LFS hsm_${request_type} "$DIR/$tdir/$tfile-$i"
+ done
+
+ # Give the coordinator 10 seconds to start every request
+ timeout=10
+ while get_hsm_param actions | grep -q WAITING; do
+ sleep 1
+ let timeout-=1
+ [ $timeout -gt 0 ] ||
+ error "${request_type^} requests took too " \
+ "long to start"
+ done
+
+ count="$(get_hsm_param ${request_type}_count)"
+ [ "$count" -eq "$request_count" ] ||
+ error "Expected '$request_count' (!= '$count') " \
+ "active $request_type requests"
+
+ # Let the copytool process the requests
+ copytool_continue
+ # Give it 10 seconds maximum
+ timeout=10
+ while get_hsm_param actions | grep -q STARTED; do
+ sleep 1
+ let timeout-=1
+ [ $timeout -gt 0 ] ||
+ error "${request_type^} requests took too " \
+ "long to complete"
+ done
+
+ count="$(get_hsm_param ${request_type}_count)"
+ [ "$count" -eq 0 ] ||
+ error "Expected 0 (!= '$count') " \
+ "active $request_type requests"
+ done
+}
+run_test 254b "Request counters are correctly incremented and decremented"
+
+test_255()
+{
+ [ $MDS1_VERSION -lt $(version_code 2.12.0) ] &&
+ skip "Need MDS version at least 2.12.0"
+
+ local file="$DIR/$tdir/$tfile"
+ local fid=$(create_empty_file "$file")
+
+ # How do you make sure the coordinator has consumed any outstanding
+ # event, without triggering an event yourself?
+ #
+ # You wait for a request to disappear from the coordinator's llog.
+
+ # Warning: the setup represents 90% of this test
+
+ # Create and process an HSM request
+ copytool setup
+ "$LFS" hsm_archive "$file"
+ wait_request_state $fid ARCHIVE SUCCEED
+
+ kill_copytools
+ wait_copytools || error "failed to stop copytools"
+
+ # Launch a new HSM request
+ rm "$file"
+ create_empty_file "$file"
+ "$LFS" hsm_archive "$file"
+
+ cdt_shutdown
+
+ # Have the completed request be removed as soon as the cdt wakes up
+ stack_trap "set_hsm_param grace_delay $(get_hsm_param grace_delay)" EXIT
+ set_hsm_param grace_delay 1
+ # (Hopefully, time on the MDS will behave nicely)
+ do_facet $SINGLEMDS sleep 2 &
+
+ # Increase `loop_period' as a mean to prevent the coordinator from
+ # waking itself up to do some housekeeping.
+ stack_trap "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
+ set_hsm_param loop_period 1000
+
+ wait $! || error "waiting failed"
+ cdt_enable
+ wait_request_state $fid ARCHIVE ""
+ # The coordinator will not wake up on its own for ~`loop_period' secs...
+
+ # ... Unless a copytool registers. Now the real test begins
+ copytool setup
+ wait_request_state $(path2fid "$file") ARCHIVE SUCCEED
+}
+run_test 255 "Copytool registration wakes the coordinator up"
+
+# tests 260[a-c] rely on the parsing of the copytool's log file, they might
+# break in the future because of that.
+test_260a()
+{
+ [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
+ skip "need MDS version 2.11.56 or later"
+
+ local -a files=("$DIR/$tdir/$tfile".{0..15})
+ local file
+
+ for file in "${files[@]}"; do
+ create_small_file "$file"
+ done
+
+ # Set a few hsm parameters
+ stack_trap \
+ "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
+ set_hsm_param loop_period 1
+ stack_trap \
+ "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
+ set_hsm_param max_requests 3
+
+ # Release one file
+ copytool setup
+ "$LFS" hsm_archive "${files[0]}"
+ wait_request_state "$(path2fid "${files[0]}")" ARCHIVE SUCCEED
+ "$LFS" hsm_release "${files[0]}"
+
+ # Stop the copytool
+ kill_copytools
+ wait_copytools || error "copytools failed to stop"
+
+ # Send several archive requests
+ for file in "${files[@]:1}"; do
+ "$LFS" hsm_archive "$file"
+ done
+
+ # Send one restore request
+ "$LFS" hsm_restore "${files[0]}"
+
+ # Launch a copytool
+ copytool setup
+
+ # Wait for all the requests to complete
+ wait_request_state "$(path2fid "${files[0]}")" RESTORE SUCCEED
+ for file in "${files[@]:1}"; do
+ wait_request_state "$(path2fid "$file")" ARCHIVE SUCCEED
+ done
+
+ # Collect the actions in the order in which the copytool processed them
+ local -a actions=(
+ $(do_facet "$SINGLEAGT" grep -o '\"RESTORE\\|ARCHIVE\"' \
+ "$(copytool_logfile "$SINGLEAGT")")
+ )
+
+ printf '%s\n' "${actions[@]}"
+
+ local action
+ for action in "${actions[@]:0:3}"; do
+ [ "$action" == RESTORE ] && return
+ done
+
+ error "Too many ARCHIVE requests were run before the RESTORE request"
+}
+run_test 260a "Restore request have priority over other requests"
+
+# This test is very much tied to the implementation of the current priorisation
+# mechanism in the coordinator. It might not make sense to keep it in the future
+test_260b()
+{
+ [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
+ skip "need MDS version 2.11.56 or later"
+
+ local -a files=("$DIR/$tdir/$tfile".{0..15})
+ local file
+
+ for file in "${files[@]}"; do
+ create_small_file "$file"
+ done
+
+ # Set a few hsm parameters
+ stack_trap \
+ "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
+ set_hsm_param loop_period 1
+ stack_trap \
+ "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
+ set_hsm_param max_requests 3
+
+ # Release one file
+ copytool setup --archive-id 2
+ "$LFS" hsm_archive --archive 2 "${files[0]}"
+ wait_request_state "$(path2fid "${files[0]}")" ARCHIVE SUCCEED
+ "$LFS" hsm_release "${files[0]}"
+
+ # Stop the copytool
+ kill_copytools
+ wait_copytools || error "copytools failed to stop"
+
+ # Send several archive requests
+ for file in "${files[@]:1}"; do
+ "$LFS" hsm_archive "$file"
+ done
+
+ # Send one restore request
+ "$LFS" hsm_restore "${files[0]}"
+
+ # Launch a copytool
+ copytool setup
+ copytool setup --archive-id 2
+
+ # Wait for all the requests to complete
+ wait_request_state "$(path2fid "${files[0]}")" RESTORE SUCCEED
+ for file in "${files[@]:1}"; do
+ wait_request_state "$(path2fid "$file")" ARCHIVE SUCCEED
+ done
+
+ # Collect the actions in the order in which the copytool processed them
+ local -a actions=(
+ $(do_facet "$SINGLEAGT" grep -o '\"RESTORE\\|ARCHIVE\"' \
+ "$(copytool_logfile "$SINGLEAGT")")
+ )
+
+ printf '%s\n' "${actions[@]}"
+
+ local action
+ for action in "${actions[@]:0:3}"; do
+ [ "$action" == RESTORE ] && return
+ done
+
+ error "Too many ARCHIVE requests were run before the RESTORE request"
+}
+run_test 260b "Restore request have priority over other requests"
+
+# This test is very much tied to the implementation of the current priorisation
+# mechanism in the coordinator. It might not make sense to keep it in the future
+test_260c()
+{
+ [ $MDS1_VERSION -lt $(version_code 2.12.0) ] &&
+ skip "Need MDS version at least 2.12.0"
+
+ local -a files=("$DIR/$tdir/$tfile".{0..15})
+ local file
+
+ for file in "${files[@]}"; do
+ create_small_file "$file"
+ done
+
+ # Set a few hsm parameters
+ stack_trap \
+ "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
+ set_hsm_param loop_period 1000
+ stack_trap \
+ "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
+ set_hsm_param max_requests 3
+
+ # Release one file
+ copytool setup --archive-id 2
+ "$LFS" hsm_archive --archive 2 "${files[0]}"
+ wait_request_state "$(path2fid "${files[0]}")" ARCHIVE SUCCEED
+ "$LFS" hsm_release "${files[0]}"
+
+ # Stop the copytool
+ kill_copytools
+ wait_copytools || error "copytools failed to stop"
+
+ # Force the next coordinator run to do housekeeping
+ cdt_shutdown
+ cdt_enable
+
+ "$LFS" hsm_archive "${files[1]}"
+
+ # Launch a copytool
+ copytool setup
+ copytool setup --archive-id 2
+
+ wait_request_state "$(path2fid "${files[1]}")" ARCHIVE SUCCEED
+ # The coordinator just did a housekeeping run it won't do another one
+ # for around `loop_period' seconds => requests will not be reordered
+ # if it costs too much (ie. when the coordinator has to discard a whole
+ # hal)
+
+ # Send several archive requests
+ for file in "${files[@]:2}"; do
+ "$LFS" hsm_archive "$file"
+ done
+
+ # Send one restore request
+ "$LFS" hsm_restore "${files[0]}"
+
+ # Wait for all the requests to complete
+ wait_request_state "$(path2fid "${files[0]}")" RESTORE SUCCEED
+ for file in "${files[@]:2}"; do
+ wait_request_state "$(path2fid "$file")" ARCHIVE SUCCEED
+ done
+
+ # Collect the actions in the order in which the copytool processed them
+ local -a actions=(
+ $(do_facet "$SINGLEAGT" grep -o '\"RESTORE\\|ARCHIVE\"' \
+ "$(copytool_logfile "$SINGLEAGT")")
+ )
+
+ printf '%s\n' "${actions[@]}"
+
+ local action
+ for action in "${actions[@]:0:3}"; do
+ [ "$action" == RESTORE ] &&
+ error "Restore requests should not be prioritised" \
+ "unless the coordinator is doing housekeeping"
+ done
+ return 0
+}
+run_test 260c "Requests are not reordered on the 'hot' path of the coordinator"
+