Whamcloud - gitweb
LU-17814 utils: implement real pfind
[fs/lustre-release.git] / lustre / tests / sanity-hsm.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 # exit on error
7 set -e
8 set +o monitor
9
10 ONLY=${ONLY:-"$*"}
11
12 LUSTRE=${LUSTRE:-$(dirname $0)/..}
13 . $LUSTRE/tests/test-framework.sh
14 init_test_env "$@"
15 init_logging
16
17 ALWAYS_EXCEPT="$SANITY_HSM_EXCEPT "
18 if $SHARED_KEY; then
19 # bug number for skipped tests: LU-9795
20         ALWAYS_EXCEPT+="        402b "
21 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
22 fi
23
24 # Skip tests for PPC that fail frequently
25 if [[ $(uname -m) = ppc64 ]]; then
26         # bug number:    LU-12251 LU-12251 LU-12251 LU-12251 LU-12251 LU-12251
27         ALWAYS_EXCEPT+=" 1a       1b       1d       1e       12c      12f "
28         # bug number:    LU-12251 LU-12251 LU-12251 LU-12251 LU-12251 LU-12251
29         ALWAYS_EXCEPT+=" 12g      12h      12m      12n      12o      12p "
30         # bug number:    LU-12251 LU-12251 LU-12251 LU-12251 LU-12251 LU-12251
31         ALWAYS_EXCEPT+=" 12q      21       22       23       24a      24b "
32         # bug number:    LU-12251 LU-12251 LU-12251 LU-12251 LU-12251 LU-12251
33         ALWAYS_EXCEPT+=" 24d      24e      24f      25b      30c      37 "
34         # bug number:    LU-12251 LU-12251 LU-12251 LU-12251 LU-12251 LU-12251
35         ALWAYS_EXCEPT+=" 57       58       90       110b     111b     113 "
36         # bug number:    LU-12251 LU-12251 LU-12251 LU-12251 LU-12251 LU-12251
37         ALWAYS_EXCEPT+=" 222b     222d     228      260a     260b     260c "
38         # bug number:    LU-12252 LU-12252 LU-12252 LU-12252 LU-12252 LU-12252
39         ALWAYS_EXCEPT+=" 220A     220a     221      222a     222c     223a "
40         # bug number:    LU-12252 LU-12252 LU-12252 LU-12252 LU-12252 LU-12252
41         ALWAYS_EXCEPT+=" 223b     224A     224a     226      227      600"
42         # bug number:    LU-12252 LU-12252 LU-12252 LU-12252 LU-12252 LU-12252
43         ALWAYS_EXCEPT+=" 601      602      603      604      605 "
44 fi
45
46 build_test_filter
47
48 [ -n "$FILESET" ] && skip "Not functional for FILESET set"
49
50 OPENFILE=${OPENFILE:-openfile}
51 MOUNT_2=${MOUNT_2:-"yes"}
52 FAIL_ON_ERROR=false
53
54 # script only handles up to 10 MDTs (because of MDT_PREFIX)
55 [ $MDSCOUNT -gt 9 ] &&
56         error "script cannot handle more than 9 MDTs, please fix"
57
58 check_and_setup_lustre
59
60 if [[ $MDS1_VERSION -lt $(version_code 2.4.53) ]]; then
61         skip_env "Need MDS version at least 2.4.53"
62 fi
63
64 # $RUNAS_ID may get set incorrectly somewhere else
65 if [[ $UID -eq 0 && $RUNAS_ID -eq 0 ]]; then
66         skip_env "\$RUNAS_ID set to 0, but \$UID is also 0!"
67 fi
68 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
69 if getent group nobody; then
70         GROUP=nobody
71 elif getent group nogroup; then
72         GROUP=nogroup
73 else
74         error "No generic nobody group"
75 fi
76
77 # if there is no CLIENT1 defined, some tests can be ran on localhost
78 CLIENT1=${CLIENT1:-$HOSTNAME}
79 # if CLIENT2 doesn't exist then use CLIENT1 instead
80 # All tests should use CLIENT2 with MOUNT2 only therefore it will work if
81 # $CLIENT2 == CLIENT1
82 # Exception is the test which need two separate nodes
83 CLIENT2=${CLIENT2:-$CLIENT1}
84
85 search_copytools() {
86         local hosts=${1:-$(facet_active_host $SINGLEAGT)}
87         do_nodesv $hosts "pgrep --pidfile=$HSMTOOL_PID_FILE hsmtool"
88 }
89
90 wait_copytools() {
91         local hosts=${1:-$(facet_active_host $SINGLEAGT)}
92         local wait_timeout=200
93         local wait_start=$SECONDS
94         local wait_end=$((wait_start + wait_timeout))
95         local sleep_time=1
96
97         while ((SECONDS < wait_end)); do
98                 if ! search_copytools $hosts; then
99                         echo "copytools stopped in $((SECONDS - wait_start))s"
100                         return 0
101                 fi
102
103                 echo "copytools still running on $hosts"
104                 sleep $sleep_time
105                 [ $sleep_time -lt 5 ] && sleep_time=$((sleep_time + 1))
106         done
107
108         # try to dump Copytool's stack
109         do_nodesv $hosts "echo 1 >/proc/sys/kernel/sysrq ; " \
110                          "echo t >/proc/sysrq-trigger"
111
112         echo "copytools failed to stop in ${wait_timeout}s"
113
114         return 1
115 }
116
117 copytool_monitor_setup() {
118         local facet=${1:-$SINGLEAGT}
119         local agent=$(facet_active_host $facet)
120
121         local cmd="mktemp --tmpdir=/tmp -d ${TESTSUITE}.${TESTNAME}.XXXX"
122         local test_dir=$(do_node $agent "$cmd") ||
123                 error "Failed to create tempdir on $agent"
124         export HSMTOOL_MONITOR_DIR=$test_dir
125
126         # Create the fifo and a monitor (cat dies when copytool dies)
127         do_node $agent "mkfifo -m 0644 $test_dir/fifo" ||
128                 error "failed to create copytool fifo on $agent"
129         cmd="cat $test_dir/fifo > $test_dir/events &"
130         cmd+=" echo \\\$! > $test_dir/monitor_pid"
131
132         # This background subshell nonsense is required when pdsh/ssh decides
133         # to wait for the cat process to exit on the remote client
134         (do_node $agent "$cmd") &
135         export HSMTOOL_MONITOR_PDSH=$!
136
137         # Slightly racy, but just making a best-effort to catch obvious
138         # problems.
139         sleep 1
140         do_node $agent "stat $HSMTOOL_MONITOR_DIR/monitor_pid 2>&1 > /dev/null"
141         if [ $? != 0 ]; then
142                 error "Failed to start copytool monitor on $agent"
143         fi
144 }
145
146 fid2archive()
147 {
148         local fid="$1"
149
150         case "$HSMTOOL_ARCHIVE_FORMAT" in
151                 v1)
152                         printf "%s" "$(hsm_root)/*/*/*/*/*/*/$fid"
153                         ;;
154                 v2)
155                         printf "%s" "$(hsm_root)/*/$fid"
156                         ;;
157         esac
158 }
159
160 get_copytool_event_log() {
161         local facet=${1:-$SINGLEAGT}
162         local agent=$(facet_active_host $facet)
163
164         [ -z "$HSMTOOL_MONITOR_DIR" ] &&
165                 error "Can't get event log: No monitor directory!"
166
167         do_node $agent "cat $HSMTOOL_MONITOR_DIR/events" ||
168                 error "Could not collect event log from $agent"
169 }
170
171 copytool_suspend() {
172         local agents=${1:-$(facet_active_host $SINGLEAGT)}
173
174         stack_trap "pkill_copytools $agents CONT || true" EXIT
175         pkill_copytools $agents STOP || return 0
176         echo "Copytool is suspended on $agents"
177 }
178
179 copytool_remove_backend() {
180         local fid=$1
181         local be=$(do_facet $SINGLEAGT find "$(hsm_root)" -name $fid)
182         echo "Remove from backend: $fid = $be"
183         do_facet $SINGLEAGT rm -f $be
184 }
185
186 file_creation_failure() {
187         local cmd=$1
188         local file=$2
189         local err=$3
190
191         case $err in
192         28)
193                 df $MOUNT $MOUNT2 >&2
194                 error "Not enough space to create $file with $cmd"
195                 ;;
196         *)
197                 error "cannot create $file with $cmd, status=$err"
198                 ;;
199         esac
200 }
201
202 # Creates a file using dd
203 create_file() {
204         local file=$1
205         local bs=$2
206         local count=$3
207         local conv=$4
208         local source=${5:-/dev/zero}
209         local args=""
210         local err
211
212         if [ -n "$conv" ]; then
213                 args+=" conv=$conv"
214         fi
215
216         # Create the directory in case it does not exist
217         mkdir -p "$(dirname "$file")"
218         # Delete the file in case it already exist
219         rm -f "$file"
220
221         if dd if="$source" of="$file" count="$count" bs="$bs" $args; then
222                 path2fid "$file" || error "cannot get FID of '$file'"
223         else
224                 err=$?
225                 echo "cannot create file '$file'" >&2;
226                 # Let the caller decide what to do on error
227                 return $err;
228         fi
229 }
230
231 create_empty_file() {
232         create_file "${1/$DIR/$DIR2}" 1M 0 ||
233                 file_creation_failure dd "${1/$DIR/$DIR2}" $?
234 }
235
236 create_small_file() {
237         local source_file=/dev/urandom
238         local count=1
239         local bs=1M
240         local conv=${2:-fsync}
241
242         create_file "${1/$DIR/$DIR2}" $bs $count $conv $source_file ||
243                 file_creation_failure dd "${1/$DIR/$DIR2}" $?
244 }
245
246 create_small_sync_file() {
247         create_small_file "$1" sync
248 }
249
250 create_archive_file() {
251         local file="$(hsm_root)/$1"
252         local count=${2:-39}
253         local source=/dev/urandom
254
255         # Create the counterpart directory of the archive
256         do_facet "$SINGLEAGT" mkdir -p "$(dirname "$file")" ||
257                 error "cannot create archive directory '$(dirname "$file")'"
258
259         do_facet "$SINGLEAGT" dd if=$source of="$file" bs=1M count=$count ||
260                 error "cannot create archive file '$file'"
261 }
262
263 copy2archive() {
264         local hsm_root="$(hsm_root)"
265         local file="$hsm_root/$2"
266
267         stack_trap "do_facet $SINGLEAGT rm -rf '$hsm_root'" EXIT
268         do_facet $SINGLEAGT mkdir -p "$(dirname "$file")" ||
269             error "mkdir '$(dirname "$file")' failed"
270         do_facet $SINGLEAGT cp -p "$1" "$file" ||
271                 error "cannot copy '$1' to '$file'"
272 }
273
274 get_hsm_param() {
275         local param=$1
276         local val=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.$param)
277         echo $val
278 }
279
280 set_test_state() {
281         local cmd=$1
282         local target=$2
283         mdts_set_param "" hsm_control "$cmd"
284         mdts_check_param hsm_control "$target" 10
285 }
286
287
288 cdt_set_no_retry() {
289         mdts_set_param "" hsm.policy "+NRA"
290         CDT_POLICY_HAD_CHANGED=true
291 }
292
293 cdt_clear_no_retry() {
294         mdts_set_param "" hsm.policy "-NRA"
295         CDT_POLICY_HAD_CHANGED=true
296 }
297
298 cdt_set_non_blocking_restore() {
299         mdts_set_param "" hsm.policy "+NBR"
300         CDT_POLICY_HAD_CHANGED=true
301 }
302
303 cdt_clear_non_blocking_restore() {
304         mdts_set_param "" hsm.policy "-NBR"
305         CDT_POLICY_HAD_CHANGED=true
306 }
307
308 cdt_clear_mount_state() {
309         mdts_set_param "-P -d" hsm_control ""
310 }
311
312 cdt_disable() {
313         set_test_state disabled disabled
314 }
315
316 cdt_enable() {
317         set_test_state enabled enabled
318 }
319
320 cdt_shutdown() {
321         set_test_state shutdown stopped
322 }
323
324 cdt_purge() {
325         set_test_state purge enabled
326 }
327
328 cdt_restart() {
329         cdt_shutdown
330         cdt_enable
331         cdt_set_sanity_policy
332 }
333
334
335 get_hsm_archive_id() {
336         local f=$1
337         local st
338         st=$($LFS hsm_state $f)
339         [[ $? == 0 ]] || error "$LFS hsm_state $f failed"
340
341         local ar=$(echo $st | grep -oP '(?<=archive_id:).*')
342         echo $ar
343 }
344
345 check_hsm_flags_user() {
346         local f=$1
347         local fl=$2
348
349         local st=$(get_hsm_flags $f user)
350         [[ $st == $fl ]] || error "hsm flags on $f are $st != $fl"
351 }
352
353 copy_file() {
354         local f=
355
356         if [[ -d $2 ]]; then
357                 f=$2/$(basename $1)
358         else
359                 f=$2
360         fi
361
362         if [[ "$3" != 1 ]]; then
363                 f=${f/$DIR/$DIR2}
364         fi
365         rm -f $f
366         cp $1 $f || file_creation_failure cp $f $?
367
368         path2fid $f || error "cannot get fid on $f"
369 }
370
371 # Delete any file bigger than 10M under $MOUNT and wait for deletes to complete
372 #
373 # Note that this might lead to surprising behaviours such as deleting an
374 # important file for the currently running test
375 delete_large_files() {
376         printf "Deleting large files...\n" >&2
377         find $MOUNT -size +10M -delete
378         wait_delete_completed
379 }
380
381 get_request_state() {
382         local fid=$1
383         local request=$2
384
385         do_facet $SINGLEMDS "$LCTL get_param -n $HSM_PARAM.actions |"\
386                 "awk '/'$fid'.*action='$request'/ {print \\\$13}' | cut -f2 -d="
387 }
388
389 get_request_count() {
390         local fid=$1
391         local request=$2
392
393         do_facet $SINGLEMDS "$LCTL get_param -n $HSM_PARAM.actions |"\
394                 "awk -vn=0 '/'$fid'.*action='$request'/ {n++}; END {print n}'"
395 }
396
397 get_request_cookie() {
398         local fid=$1
399         local request=$2
400
401         do_facet $SINGLEMDS "$LCTL get_param -n $HSM_PARAM.actions |"\
402                 "awk '/'$fid'.*action='$request'/ {print \\\$6}' | cut -f3 -d/"
403 }
404
405 # Ensure the number of HSM request for a given FID is correct
406 # assert_request_count FID REQUEST_TYPE COUNT [ERROR_MSG]
407 assert_request_count() {
408         local request_count=$(get_request_count $1 $2)
409         local default_error_msg=("expected $3 '$2' request(s) for '$1', found "
410                                 "'$request_count'")
411         [ $request_count -eq $3 ] || error "${4:-"${default_error_msg[@]}"}"
412 }
413
414 wait_all_done() {
415         local timeout=$1
416         local fid=$2
417
418         local cmd="$LCTL get_param -n $HSM_PARAM.actions"
419         [[ -n $fid ]] && cmd+=" | grep '$fid'"
420         cmd+=" | egrep 'WAITING|STARTED'"
421
422         wait_update_facet --verbose mds1 "$cmd" "" $timeout ||
423                 error "requests did not complete"
424 }
425
426 wait_for_grace_delay() {
427         local val=$(get_hsm_param grace_delay)
428         sleep $val
429 }
430
431 wait_for_loop_period() {
432         local val=$(get_hsm_param loop_period)
433         sleep $val
434 }
435
436 parse_json_event() {
437         local raw_event=$1
438
439         # python2.6 in EL6 includes an internal json module
440         local PYTHON='python'
441         local json_parser='import json; import fileinput;'
442         json_parser+=' print("\n".join(["local %s=\"%s\"" % tuple for tuple in '
443         json_parser+='json.loads([line for line in '
444         json_parser+='fileinput.input()][0]).items()]))'
445
446         # check if python/python2/python3 is available
447         if ! which $PYTHON > /dev/null 2>&1 ; then
448                 PYTHON='python2'
449                 if ! which $PYTHON > /dev/null 2>&1 ; then
450                         PYTHON='python3'
451                 fi
452         fi
453         echo $raw_event | $PYTHON -c "$json_parser"
454 }
455
456 get_agent_by_uuid_mdt() {
457         local uuid=$1
458         local mdtidx=$2
459         local mds=mds$(($mdtidx + 1))
460         do_facet $mds "$LCTL get_param -n ${MDT_PREFIX}${mdtidx}.hsm.agents |\
461                  grep $uuid"
462 }
463
464 check_agent_registered_by_mdt() {
465         local uuid=$1
466         local mdtidx=$2
467         local mds=mds$(($mdtidx + 1))
468         local agent=$(get_agent_by_uuid_mdt $uuid $mdtidx)
469         if [[ ! -z "$agent" ]]; then
470                 echo "found agent $agent on $mds"
471         else
472                 error "uuid $uuid not found in agent list on $mds"
473         fi
474 }
475
476 check_agent_unregistered_by_mdt() {
477         local uuid=$1
478         local mdtidx=$2
479         local mds=mds$(($mdtidx + 1))
480         local agent=$(get_agent_by_uuid_mdt $uuid $mdtidx)
481         if [[ -z "$agent" ]]; then
482                 echo "uuid not found in agent list on $mds"
483         else
484                 error "uuid found in agent list on $mds: $agent"
485         fi
486 }
487
488 check_agent_registered() {
489         local uuid=$1
490         local mdsno
491         for mdsno in $(seq 1 $MDSCOUNT); do
492                 check_agent_registered_by_mdt $uuid $((mdsno - 1))
493         done
494 }
495
496 check_agent_unregistered() {
497         local uuid=$1
498         local mdsno
499         for mdsno in $(seq 1 $MDSCOUNT); do
500                 check_agent_unregistered_by_mdt $uuid $((mdsno - 1))
501         done
502 }
503
504 get_agent_uuid() {
505         local agent=${1:-$(facet_active_host $SINGLEAGT)}
506
507         # Lustre mount-point is mandatory and last parameter on
508         # copytool cmd-line.
509         local mntpnt=$(do_rpc_nodes $agent \
510                         pgrep --pidfile=$HSMTOOL_PID_FILE --list-full hsmtool |
511                        awk '{print $NF}')
512         [ -n "$mntpnt" ] || error "Found no Agent or with no mount-point "\
513                                   "parameter"
514         do_rpc_nodes $agent get_client_uuid $mntpnt | cut -d' ' -f2
515 }
516
517 # initiate variables
518 init_agt_vars
519
520 # populate MDT device array
521 get_mdt_devices
522
523 # cleanup from previous bad setup
524 kill_copytools
525
526 # for recovery tests, coordinator needs to be started at mount
527 # so force it
528 # the lustre conf must be without hsm on (like for sanity.sh)
529 echo "Set HSM on and start"
530 cdt_set_mount_state enabled
531 cdt_check_state enabled
532
533 echo "Set sanity-hsm HSM policy"
534 cdt_set_sanity_policy
535
536 # finished requests are quickly removed from list
537 set_hsm_param grace_delay 10
538
539 CLIENT_NIDS=( $($LCTL list_nids all) )
540
541 test_1A() { # was test_1
542         mkdir -p $DIR/$tdir
543         chmod 777 $DIR/$tdir
544
545         local f=$DIR/$tdir/$tfile
546         $RUNAS touch $f
547
548         # User flags
549         check_hsm_flags_user $f "0x00000000"
550
551         $RUNAS $LFS hsm_set --norelease $f ||
552                 error "user could not change hsm flags"
553         check_hsm_flags_user $f "0x00000010"
554
555         $RUNAS $LFS hsm_clear --norelease $f ||
556                 error "user could not clear hsm flags"
557         check_hsm_flags_user $f "0x00000000"
558
559         # User could not change those flags...
560         $RUNAS $LFS hsm_set --exists $f &&
561                 error "user should not set this flag"
562         check_hsm_flags_user $f "0x00000000"
563
564         # ...but root can
565         $LFS hsm_set --exists $f ||
566                 error "root could not change hsm flags"
567         check_hsm_flags_user $f "0x00000001"
568
569         $LFS hsm_clear --exists $f ||
570                 error "root could not clear hsm state"
571         check_hsm_flags_user $f "0x00000000"
572
573 }
574 run_test 1A "lfs hsm flags root/non-root access"
575
576 test_1a() {
577         mkdir_on_mdt0 $DIR/$tdir
578
579         local f=$DIR/$tdir/$tfile
580         local fid=$(create_small_file $f)
581
582         copytool setup
583
584         $LFS hsm_archive $f || error "could not archive file"
585         wait_request_state $fid ARCHIVE SUCCEED
586
587         # Release and check states
588         $LFS hsm_release $f || error "could not release file"
589         echo -n "Verifying released state: "
590         check_hsm_flags $f "0x0000000d"
591
592         $MMAP_CAT $f > /dev/null || error "failed mmap & cat release file"
593 }
594 run_test 1a "mmap & cat a HSM released file"
595
596 test_1bde_base() {
597         local f=$1
598         rm -f $f
599
600         dd if=/dev/urandom of=$f bs=1M count=1 conv=sync ||
601                 error "failed to create file"
602         local fid=$(path2fid $f)
603
604         copytool setup
605
606         echo "archive $f"
607         $LFS hsm_archive $f || error "could not archive file"
608         wait_request_state $fid ARCHIVE SUCCEED
609
610         echo "release $f"
611         $LFS hsm_release $f || error "could not release file"
612         echo "verify released state: "
613         check_hsm_flags $f "0x0000000d" && echo "pass"
614
615         echo "restore $f"
616         $LFS hsm_restore $f || error "could not restore file"
617         wait_request_state $fid RESTORE SUCCEED
618         echo "verify restored state: "
619         check_hsm_flags $f "0x00000009" && echo "pass"
620 }
621
622 test_1b() {
623         mkdir_on_mdt0 $DIR/$tdir
624         $LFS setstripe -E 1M -S 1M -E 64M -c 2 -E -1 -c 4 $DIR/$tdir ||
625                 error "failed to set default stripe"
626         local f=$DIR/$tdir/$tfile
627
628         test_1bde_base $f
629 }
630 run_test 1b "Archive, Release and Restore composite file"
631
632 test_1c() {
633         mkdir -p $DIR/$tdir
634         chmod 777 $DIR/$tdir
635
636         local f=$DIR/$tdir/$tfile
637         $RUNAS touch $f
638
639         # Test whether we can set the maximum archive number.
640         local LOCAL_HSM_ARCHIVE_NUMBER=32
641         $LFS hsm_set --exists --archive-id $LOCAL_HSM_ARCHIVE_NUMBER $f ||
642                 error "root could not change hsm flags"
643         check_hsm_flags_user $f "0x00000001"
644         echo "verifying archive number is $LOCAL_HSM_ARCHIVE_NUMBER"
645         local st=$(get_hsm_archive_id $f)
646         [[ $st == $LOCAL_HSM_ARCHIVE_NUMBER ]] ||
647                 error "wrong archive number, $st != $LOCAL_HSM_ARCHIVE_NUMBER"
648
649         # Test whether setting archive number 0 results in no change.
650         $LFS hsm_set --exists --archive-id 0 $f ||
651                 error "root could not change hsm flags"
652         check_hsm_flags_user $f "0x00000001"
653         echo "verifying archive number is still $LOCAL_HSM_ARCHIVE_NUMBER"
654         st=$(get_hsm_archive_id $f)
655         [[ $st == $LOCAL_HSM_ARCHIVE_NUMBER ]] ||
656                 error "wrong archive number, $st != $LOCAL_HSM_ARCHIVE_NUMBER"
657
658         LOCAL_HSM_ARCHIVE_NUMBER=33
659         if [ "$CLIENT_VERSION" -ge $(version_code 2.11.56) ] &&
660            [ "$MDS1_VERSION" -ge $(version_code 2.11.56) ]; then
661                 # lustre in the new version supports unlimited archiveID.
662                 # Test whether setting archive number > 32 is supported
663                 $LFS hsm_set --exists --archive-id $LOCAL_HSM_ARCHIVE_NUMBER $f ||
664                         error "archive ID $LOCAL_HSM_ARCHIVE_NUMBER too large?"
665                 check_hsm_flags_user $f "0x00000001"
666
667                 echo "verifying archive number is $LOCAL_HSM_ARCHIVE_NUMBER"
668                 st=$(get_hsm_archive_id $f)
669                 [[ $st == $LOCAL_HSM_ARCHIVE_NUMBER ]] ||
670                         error "wrong archive number, $st != $LOCAL_HSM_ARCHIVE_NUMBER"
671         else
672                 # old client or old mds can only support at most 32 archiveID
673                 # test whether setting archive number > 32 results in error.
674                 $LFS hsm_set --exists --archive-id $LOCAL_HSM_ARCHIVE_NUMBER $f &&
675                         error "bitmap archive number is larger than 32"
676                 check_hsm_flags_user $f "0x00000001"
677         fi
678
679         # Test whether setting archive number 16 and archived flag.
680         LOCAL_HSM_ARCHIVE_NUMBER=16
681         $LFS hsm_set --exists --archived \
682              --archive-id $LOCAL_HSM_ARCHIVE_NUMBER $f ||
683             error "root could not change hsm flags"
684         check_hsm_flags_user $f "0x00000009"
685         echo "verifying archive number is $LOCAL_HSM_ARCHIVE_NUMBER"
686         st=$(get_hsm_archive_id $f)
687         [[ $st == $LOCAL_HSM_ARCHIVE_NUMBER ]] ||
688                 error "wrong archive number, $st != $LOCAL_HSM_ARCHIVE_NUMBER"
689 }
690 run_test 1c "Check setting archive-id in lfs hsm_set"
691
692 test_1d() {
693         [ $MDS1_VERSION -lt $(version_code 2.10.59) ] &&
694                 skip "need MDS version at least 2.10.59"
695
696         mkdir_on_mdt0 $DIR/$tdir
697         $LFS setstripe -E 1M -L mdt -E -1 -c 2 $DIR/$tdir ||
698                 error "failed to set default stripe"
699         local f=$DIR/$tdir/$tfile
700
701         test_1bde_base $f
702 }
703 run_test 1d "Archive, Release and Restore DoM file"
704
705 test_1e() {
706         [ "$MDS1_VERSION" -lt $(version_code $SEL_VER) ] &&
707                 skip "skipped for lustre < $SEL_VER"
708
709         mkdir_on_mdt0 $DIR/$tdir
710         $LFS setstripe -E 1G -z 64M -E 10G -z 512M -E -1 -z 1G $DIR/$tdir ||
711                 error "failed to set default stripe"
712         local comp_file=$DIR/$tdir/$tfile
713
714         test_1bde_base $comp_file
715
716         local flg_opts="--comp-start 0 -E 64M --comp-flags init"
717         local found=$($LFS find $flg_opts $comp_file | wc -l)
718         [ $found -eq 1 ] || error "1st component not found"
719
720         flg_opts="--comp-start 64M -E 1G --comp-flags extension"
721         found=$($LFS find $flg_opts $comp_file | wc -l)
722         [ $found -eq 1 ] || error "2nd component not found"
723
724         flg_opts="--comp-start 1G -E 1G --comp-flags ^init"
725         found=$($LFS find $flg_opts $comp_file | wc -l)
726         [ $found -eq 1 ] || error "3rd component not found"
727
728         flg_opts="--comp-start 1G -E 10G --comp-flags extension"
729         found=$($LFS find $flg_opts $comp_file | wc -l)
730         [ $found -eq 1 ] || error "4th component not found"
731
732         flg_opts="--comp-start 10G -E 10G --comp-flags ^init"
733         found=$($LFS find $flg_opts $comp_file | wc -l)
734         [ $found -eq 1 ] || error "5th component not found"
735
736         flg_opts="--comp-start 10G -E EOF --comp-flags extension"
737         found=$($LFS find $flg_opts $comp_file | wc -l)
738         [ $found -eq 1 ] || error "6th component not found"
739
740         sel_layout_sanity $comp_file 6
741 }
742 run_test 1e "Archive, Release and Restore SEL file"
743
744 test_1f() {
745         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
746                 skip "need MDS version at least 2.15.55.203"
747         local dom=$DIR/$tdir/$tfile
748
749         mkdir_on_mdt0 $DIR/$tdir
750         $LFS setstripe -E 512K -L mdt -E -1 -c 2 $DIR/$tdir ||
751                 error "failed to set default stripe"
752
753         test_1bde_base $dom
754
755         [[ $($LFS getstripe --component-start=0 -L $dom) == 'mdt' ]] ||
756                 error "MDT stripe isn't set"
757
758         # check that metadata change doesn't prevent second release
759         chmod 600 $dom  || error "chmod failed"
760
761         echo "release again $dom"
762         $LFS hsm_release $dom || error "second release failed"
763         $LFS hsm_state $dom
764         echo "verify released state: "
765         check_hsm_flags $dom "0x0000000d" && echo "pass"
766 }
767 run_test 1f "DoM file release after restore"
768
769 test_2() {
770         local f=$DIR/$tdir/$tfile
771
772         mkdir_on_mdt0 $DIR/$tdir
773         create_empty_file "$f"
774         # New files are not dirty
775         check_hsm_flags $f "0x00000000"
776
777         # For test, we simulate an archived file.
778         $LFS hsm_set --exists $f || error "user could not change hsm flags"
779         check_hsm_flags $f "0x00000001"
780
781         # chmod do not put the file dirty
782         chmod 600 $f || error "could not chmod test file"
783         check_hsm_flags $f "0x00000001"
784
785         # chown do not put the file dirty
786         chown $RUNAS_ID $f || error "could not chown test file"
787         check_hsm_flags $f "0x00000001"
788
789         # truncate put the file dirty
790         $TRUNCATE $f 1 || error "could not truncate test file"
791         check_hsm_flags $f "0x00000003"
792
793         $LFS hsm_clear --dirty $f || error "could not clear hsm flags"
794         check_hsm_flags $f "0x00000001"
795 }
796 run_test 2 "Check file dirtyness when doing setattr"
797
798 test_3() {
799         mkdir_on_mdt0 $DIR/$tdir
800         f=$DIR/$tdir/$tfile
801
802         # New files are not dirty
803         cp -p /etc/passwd $f
804         check_hsm_flags $f "0x00000000"
805
806         # For test, we simulate an archived file.
807         $LFS hsm_set --exists $f ||
808                 error "user could not change hsm flags"
809         check_hsm_flags $f "0x00000001"
810
811         # Reading a file, does not set dirty
812         cat $f > /dev/null || error "could not read file"
813         check_hsm_flags $f "0x00000001"
814
815         # Open for write without modifying data, does not set dirty
816         openfile -f O_WRONLY $f || error "could not open test file"
817         check_hsm_flags $f "0x00000001"
818
819         # Append to a file sets it dirty
820         cp -p /etc/passwd $f.append || error "could not create file"
821         $LFS hsm_set --exists $f.append ||
822                 error "user could not change hsm flags"
823         dd if=/etc/passwd of=$f.append bs=1 count=3\
824            conv=notrunc oflag=append status=noxfer ||
825                 file_creation_failure dd $f.append $?
826         check_hsm_flags $f.append "0x00000003"
827
828         # Modify a file sets it dirty
829         cp -p /etc/passwd $f.modify || error "could not create file"
830         $LFS hsm_set --exists $f.modify ||
831                 error "user could not change hsm flags"
832         dd if=/dev/zero of=$f.modify bs=1 count=3\
833            conv=notrunc status=noxfer ||
834                 file_creation_failure dd $f.modify $?
835         check_hsm_flags $f.modify "0x00000003"
836
837         # Open O_TRUNC sets dirty
838         cp -p /etc/passwd $f.trunc || error "could not create file"
839         $LFS hsm_set --exists $f.trunc ||
840                 error "user could not change hsm flags"
841         cp /etc/group $f.trunc || error "could not override a file"
842         check_hsm_flags $f.trunc "0x00000003"
843
844         # Mmapped a file sets dirty
845         cp -p /etc/passwd $f.mmap || error "could not create file"
846         $LFS hsm_set --exists $f.mmap ||
847                 error "user could not change hsm flags"
848         multiop $f.mmap OSMWUc || error "could not mmap a file"
849         check_hsm_flags $f.mmap "0x00000003"
850 }
851 run_test 3 "Check file dirtyness when opening for write"
852
853 test_4() {
854         local f=$DIR/$tdir/$tfile
855         local fid=$(create_small_file $f)
856
857         $LFS hsm_cancel $f
858         local st=$(get_request_state $fid CANCEL)
859         [[ -z "$st" ]] || error "hsm_cancel must not be registered (state=$st)"
860 }
861 run_test 4 "Useless cancel must not be registered"
862
863 test_8() {
864         # test needs a running copytool
865         copytool setup
866
867         mkdir_on_mdt0 $DIR/$tdir
868         local f=$DIR/$tdir/$tfile
869         local fid=$(copy_file /etc/passwd $f)
870         $LFS hsm_archive $f
871         wait_request_state $fid ARCHIVE SUCCEED
872
873         check_hsm_flags $f "0x00000009"
874 }
875 run_test 8 "Test default archive number"
876
877 test_9A() { # was test_9
878         # we do not use the default one to be sure
879         local archive_id=$((HSM_ARCHIVE_NUMBER + 1))
880         copytool setup --archive-id $archive_id
881
882         # give time for CT to register with MDTs
883         sleep $(($MDSCOUNT*2))
884         local uuid=$(get_agent_uuid $(facet_active_host $SINGLEAGT))
885         check_agent_registered $uuid
886
887         mkdir_on_mdt0 $DIR/$tdir
888
889         local f=$DIR/$tdir/$tfile
890         local fid=$(copy_file /etc/passwd $f)
891         $LFS hsm_archive --archive $archive_id $f
892         wait_request_state $fid ARCHIVE SUCCEED
893
894         check_hsm_flags $f "0x00000009"
895 }
896 run_test 9A "Use of explicit archive number, with dedicated copytool"
897
898 test_9a() {
899         needclients 3 || return 0
900
901         local n
902         local file
903         local fid
904
905         # start all of the copytools
906         for n in $(seq $AGTCOUNT); do
907                 copytool setup --facet agt$n
908         done
909
910         mkdir_on_mdt0 $DIR/$tdir
911
912         # archive files
913         for n in $(seq $AGTCOUNT); do
914                 file=$DIR/$tdir/$tfile.$n
915                 fid=$(create_small_file $file)
916
917                 $LFS hsm_archive $file || error "could not archive file $file"
918                 wait_request_state $fid ARCHIVE SUCCEED
919                 check_hsm_flags $file "0x00000009"
920         done
921 }
922 run_test 9a "Multiple remote agents"
923
924 test_10a() {
925         # test needs a running copytool
926         copytool setup
927
928         mkdir_on_mdt0 $DIR/$tdir
929         mkdir -p $DIR/$tdir/d1
930         local f=$DIR/$tdir/$tfile
931         local fid=$(copy_file /etc/hosts $f)
932         $LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $f ||
933                 error "hsm_archive failed"
934         wait_request_state $fid ARCHIVE SUCCEED
935
936         local hsm_root="$(copytool_device $SINGLEAGT)"
937         local archive="$(do_facet $SINGLEAGT \
938                          find "$hsm_root" -name "$fid" -print0)"
939         [ -n "$archive" ] || error "fid '$fid' not in archive '$hsm_root'"
940
941         echo "Verifying content"
942         do_facet $SINGLEAGT diff $f $archive || error "archived file differs"
943         echo "Verifying hsm state "
944         check_hsm_flags $f "0x00000009"
945
946         echo "Verifying archive number is $HSM_ARCHIVE_NUMBER"
947         local st=$(get_hsm_archive_id $f)
948         [[ $st == $HSM_ARCHIVE_NUMBER ]] ||
949                 error "Wrong archive number, $st != $HSM_ARCHIVE_NUMBER"
950 }
951 run_test 10a "Archive a file"
952
953 test_10b() {
954         # test needs a running copytool
955         copytool setup
956
957         mkdir_on_mdt0 $DIR/$tdir
958         local f=$DIR/$tdir/$tfile
959         local fid=$(copy_file /etc/hosts $f)
960         $LFS hsm_archive $f || error "archive request failed"
961         wait_request_state $fid ARCHIVE SUCCEED
962
963         $LFS hsm_archive $f || error "archive of non dirty file failed"
964         local cnt=$(get_request_count $fid ARCHIVE)
965         [[ "$cnt" == "1" ]] ||
966                 error "archive of non dirty file must not make a request"
967 }
968 run_test 10b "Archive of non dirty file must work without doing request"
969
970 test_10c() {
971         # test needs a running copytool
972         copytool setup
973
974         mkdir -p $DIR/$tdir
975         local f=$DIR/$tdir/$tfile
976         local fid=$(copy_file /etc/hosts $f)
977         $LFS hsm_set --noarchive $f
978         $LFS hsm_archive $f && error "archive a noarchive file must fail"
979         return 0
980 }
981 run_test 10c "Check forbidden archive"
982
983 test_10d() {
984         # test needs a running copytool
985         copytool setup
986
987         mkdir_on_mdt0 $DIR/$tdir
988         local f=$DIR/$tdir/$tfile
989         local fid=$(copy_file /etc/hosts $f)
990         $LFS hsm_archive $f || error "cannot archive $f"
991         wait_request_state $fid ARCHIVE SUCCEED
992
993         local ar=$(get_hsm_archive_id $f)
994         local dflt=$(get_hsm_param default_archive_id)
995         [[ $ar == $dflt ]] ||
996                 error "archived file is not on default archive: $ar != $dflt"
997 }
998 run_test 10d "Archive a file on the default archive id"
999
1000 test_11a() {
1001         mkdir_on_mdt0 $DIR/$tdir
1002         copy2archive /etc/hosts $tdir/$tfile
1003         local f=$DIR/$tdir/$tfile
1004
1005         copytool import $tdir/$tfile $f
1006         echo -n "Verifying released state: "
1007         check_hsm_flags $f "0x0000000d"
1008
1009         local LSZ=$(stat -c "%s" $f)
1010         local ASZ=$(do_facet $SINGLEAGT stat -c "%s" "$(hsm_root)/$tdir/$tfile")
1011
1012         echo "Verifying imported size $LSZ=$ASZ"
1013         [[ $LSZ -eq $ASZ ]] || error "Incorrect size $LSZ != $ASZ"
1014         echo -n "Verifying released pattern: "
1015         local PTRN=$($LFS getstripe -L $f)
1016         echo $PTRN
1017         [[ $PTRN == released ]] || error "Is not released"
1018         local fid=$(path2fid $f)
1019         echo "Verifying new fid $fid in archive"
1020
1021         do_facet $SINGLEAGT "[ -f \"$(fid2archive "$fid")\" ]" ||
1022                 error "No archive for fid $fid"
1023 }
1024 run_test 11a "Import a file"
1025
1026 test_11b() {
1027         # test needs a running copytool
1028         copytool setup
1029
1030         mkdir_on_mdt0 $DIR/$tdir
1031         local f=$DIR/$tdir/$tfile
1032         local fid=$(copy_file /etc/hosts $f)
1033         $LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $f ||
1034                 error "hsm_archive failed"
1035         wait_request_state $fid ARCHIVE SUCCEED
1036
1037         local FILE_HASH=$(md5sum $f)
1038         rm -f $f
1039
1040         copytool import $fid $f
1041
1042         echo "$FILE_HASH" | md5sum -c
1043
1044         [[ $? -eq 0 ]] || error "Restored file differs"
1045 }
1046 run_test 11b "Import a deleted file using its FID"
1047
1048 test_11c() {
1049         pool_add $TESTNAME || error "Pool creation failed"
1050         pool_add_targets $TESTNAME 1 1 || error "pool_add_targets failed"
1051
1052         mkdir -p $DIR/$tdir
1053         $LFS setstripe -p "$TESTNAME" $DIR/$tdir
1054
1055         copy2archive /etc/hosts $tdir/$tfile
1056         copytool import $tdir/$tfile $DIR/$tdir/$tfile
1057 }
1058 run_test 11c "Import a file to a directory with a pool"
1059
1060 test_12a() {
1061         # test needs a running copytool
1062         copytool setup
1063
1064         mkdir_on_mdt0 $DIR/$tdir
1065         copy2archive /etc/hosts $tdir/$tfile
1066
1067         local f=$DIR/$tdir/$tfile
1068         copytool import $tdir/$tfile $f
1069         local f2=$DIR2/$tdir/$tfile
1070         echo "Verifying released state: "
1071         check_hsm_flags $f2 "0x0000000d"
1072
1073         local fid=$(path2fid $f2)
1074         $LFS hsm_restore $f2
1075         wait_request_state $fid RESTORE SUCCEED
1076
1077         echo "Verifying file state: "
1078         check_hsm_flags $f2 "0x00000009"
1079
1080         do_facet $SINGLEAGT diff -q $(hsm_root)/$tdir/$tfile $f
1081
1082         [[ $? -eq 0 ]] || error "Restored file differs"
1083 }
1084 run_test 12a "Restore an imported file explicitly"
1085
1086 test_12b() {
1087         # test needs a running copytool
1088         copytool setup
1089
1090         mkdir_on_mdt0 $DIR/$tdir
1091         copy2archive /etc/hosts $tdir/$tfile
1092
1093         local f=$DIR/$tdir/$tfile
1094         copytool import $tdir/$tfile $f
1095         echo "Verifying released state: "
1096         check_hsm_flags $f "0x0000000d"
1097
1098         cat $f > /dev/null || error "File read failed"
1099
1100         echo "Verifying file state after restore: "
1101         check_hsm_flags $f "0x00000009"
1102
1103         do_facet $SINGLEAGT diff -q $(hsm_root)/$tdir/$tfile $f
1104
1105         [[ $? -eq 0 ]] || error "Restored file differs"
1106 }
1107 run_test 12b "Restore an imported file implicitly"
1108
1109 test_12c() {
1110         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs" && return
1111
1112         # test needs a running copytool
1113         copytool setup
1114
1115         local f=$DIR/$tdir/$tfile
1116         mkdir_on_mdt0 $DIR/$tdir
1117         $LFS setstripe -c 2 "$f"
1118         local fid=$(create_file "$f" 1M 5)
1119
1120         local FILE_CRC=$(md5sum $f)
1121
1122         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1123         wait_request_state $fid ARCHIVE SUCCEED
1124         $LFS hsm_release $f || error "release $f failed"
1125
1126         echo "$FILE_CRC" | md5sum -c
1127
1128         [[ $? -eq 0 ]] || error "Restored file differs"
1129 }
1130 run_test 12c "Restore a file with stripe of 2"
1131
1132 test_12d() {
1133         # test needs a running copytool
1134         copytool setup
1135
1136         mkdir_on_mdt0 $DIR/$tdir
1137
1138         local f=$DIR/$tdir/$tfile
1139         local fid=$(copy_file /etc/hosts $f)
1140         $LFS hsm_restore $f || error "restore of non archived file failed"
1141         local cnt=$(get_request_count $fid RESTORE)
1142         [[ "$cnt" == "0" ]] ||
1143                 error "restore non archived must not make a request"
1144         $LFS hsm_archive $f ||
1145                 error "archive request failed"
1146         wait_request_state $fid ARCHIVE SUCCEED
1147         $LFS hsm_restore $f ||
1148                 error "restore of non released file failed"
1149         local cnt=$(get_request_count $fid RESTORE)
1150         [[ "$cnt" == "0" ]] ||
1151                 error "restore a non dirty file must not make a request"
1152 }
1153 run_test 12d "Restore of a non archived, non released file must work"\
1154                 " without doing request"
1155
1156 test_12e() {
1157         # test needs a running copytool
1158         copytool setup
1159
1160         mkdir_on_mdt0 $DIR/$tdir
1161         local f=$DIR/$tdir/$tfile
1162         local fid=$(copy_file /etc/hosts $f)
1163         $LFS hsm_archive $f || error "archive request failed"
1164         wait_request_state $fid ARCHIVE SUCCEED
1165
1166         # make file dirty
1167         cat /etc/hosts >> $f
1168         sync
1169         $LFS hsm_state $f
1170
1171         $LFS hsm_restore $f && error "restore a dirty file must fail"
1172         return 0
1173 }
1174 run_test 12e "Check forbidden restore"
1175
1176 test_12f() {
1177         # test needs a running copytool
1178         copytool setup
1179
1180         mkdir_on_mdt0 $DIR/$tdir
1181         local f=$DIR/$tdir/$tfile
1182         local fid=$(copy_file /etc/hosts $f)
1183
1184         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1185         wait_request_state $fid ARCHIVE SUCCEED
1186         $LFS hsm_release $f || error "release of $f failed"
1187         $LFS hsm_restore $f
1188         wait_request_state $fid RESTORE SUCCEED
1189
1190         echo -n "Verifying file state: "
1191         check_hsm_flags $f "0x00000009"
1192
1193         diff -q /etc/hosts $f
1194
1195         [[ $? -eq 0 ]] || error "Restored file differs"
1196 }
1197 run_test 12f "Restore a released file explicitly"
1198
1199 test_12g() {
1200         # test needs a running copytool
1201         copytool setup
1202
1203         mkdir_on_mdt0 $DIR/$tdir
1204         local f=$DIR/$tdir/$tfile
1205         local fid=$(copy_file /etc/hosts $f)
1206
1207         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1208         wait_request_state $fid ARCHIVE SUCCEED
1209         $LFS hsm_release $f || error "release of $f failed"
1210
1211         diff -q /etc/hosts $f
1212         local st=$?
1213
1214         # we check we had a restore done
1215         wait_request_state $fid RESTORE SUCCEED
1216
1217         [[ $st -eq 0 ]] || error "Restored file differs"
1218 }
1219 run_test 12g "Restore a released file implicitly"
1220
1221 test_12h() {
1222         needclients 2 || return 0
1223
1224         # test needs a running copytool
1225         copytool setup
1226
1227         mkdir_on_mdt0 $DIR/$tdir
1228         local f=$DIR/$tdir/$tfile
1229         local fid=$(copy_file /etc/hosts $f)
1230
1231         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1232         wait_request_state $fid ARCHIVE SUCCEED
1233         $LFS hsm_release $f || error "release of $f failed"
1234
1235         do_node $CLIENT2 diff -q /etc/hosts $f
1236         local st=$?
1237
1238         # we check we had a restore done
1239         wait_request_state $fid RESTORE SUCCEED
1240
1241         [[ $st -eq 0 ]] || error "Restored file differs"
1242 }
1243 run_test 12h "Restore a released file implicitly from a second node"
1244
1245 test_12m() {
1246         # test needs a running copytool
1247         copytool setup
1248
1249         mkdir_on_mdt0 $DIR/$tdir
1250         local f=$DIR/$tdir/$tfile
1251         local fid=$(copy_file /etc/passwd $f)
1252         $LFS hsm_archive $f || error "archive of $f failed"
1253         wait_request_state $fid ARCHIVE SUCCEED
1254
1255         $LFS hsm_release $f || error "release of $f failed"
1256
1257         cmp /etc/passwd $f
1258
1259         [[ $? -eq 0 ]] || error "Restored file differs"
1260 }
1261 run_test 12m "Archive/release/implicit restore"
1262
1263 test_12n() {
1264         # test needs a running copytool
1265         copytool setup
1266
1267         mkdir -p $DIR/$tdir
1268         copy2archive /etc/hosts $tdir/$tfile
1269
1270         local f=$DIR/$tdir/$tfile
1271         copytool import $tdir/$tfile $f
1272
1273         do_facet $SINGLEAGT cmp /etc/hosts $f ||
1274                 error "Restored file differs"
1275
1276         $LFS hsm_release $f || error "release of $f failed"
1277 }
1278 run_test 12n "Import/implicit restore/release"
1279
1280 test_12o() {
1281         # test needs a running copytool
1282         copytool setup
1283
1284         mkdir_on_mdt0 $DIR/$tdir
1285         local f=$DIR/$tdir/$tfile
1286         local fid=$(copy_file /etc/hosts $f)
1287
1288         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1289         wait_request_state $fid ARCHIVE SUCCEED
1290         $LFS hsm_release $f || error "release of $f failed"
1291
1292 #define OBD_FAIL_MDS_HSM_SWAP_LAYOUTS           0x152
1293         do_facet $SINGLEMDS lctl set_param fail_loc=0x152
1294
1295         # set no retry action mode
1296         cdt_set_no_retry
1297
1298         diff -q /etc/hosts $f
1299         local st=$?
1300
1301         # we check we had a restore failure
1302         wait_request_state $fid RESTORE FAILED
1303
1304         [[ $st -eq 0 ]] && error "Restore must fail"
1305
1306         # remove no retry action mode
1307         cdt_clear_no_retry
1308
1309         # check file is still released
1310         check_hsm_flags $f "0x0000000d"
1311
1312         # retry w/o failure injection
1313         do_facet $SINGLEMDS lctl set_param fail_loc=0
1314
1315         # to be sure previous RESTORE result is gone
1316         cdt_purge
1317         wait_for_grace_delay
1318
1319         diff -q /etc/hosts $f
1320         st=$?
1321
1322         # we check we had a restore done
1323         wait_request_state $fid RESTORE SUCCEED
1324
1325         [[ $st -eq 0 ]] || error "Restored file differs"
1326 }
1327 run_test 12o "Layout-swap failure during Restore leaves file released"
1328
1329 test_12p() {
1330         # test needs a running copytool
1331         copytool setup
1332
1333         mkdir_on_mdt0 $DIR/$tdir
1334         local f=$DIR/$tdir/$tfile
1335         local fid=$(copy_file /etc/hosts $f)
1336
1337         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1338         wait_request_state $fid ARCHIVE SUCCEED
1339         do_facet $SINGLEAGT cat $f > /dev/null || error "cannot cat $f"
1340         $LFS hsm_release $f || error "cannot release $f"
1341         do_facet $SINGLEAGT cat $f > /dev/null || error "cannot cat $f"
1342         $LFS hsm_release $f || error "cannot release $f"
1343         do_facet $SINGLEAGT cat $f > /dev/null || error "cannot cat $f"
1344 }
1345 run_test 12p "implicit restore of a file on copytool mount point"
1346
1347 test_12q() {
1348         [ $MDS1_VERSION -lt $(version_code 2.7.58) ] &&
1349                 skip "need MDS version at least 2.7.58"
1350
1351         stack_trap "zconf_umount \"$(facet_host $SINGLEAGT)\" \"$MOUNT3\"" EXIT
1352         zconf_mount $(facet_host $SINGLEAGT) $MOUNT3 ||
1353                 error "cannot mount $MOUNT3 on $SINGLEAGT"
1354
1355         # test needs a running copytool
1356         copytool setup -m "$MOUNT3"
1357
1358         mkdir_on_mdt0 $DIR/$tdir
1359
1360         local f=$DIR/$tdir/$tfile
1361         local f2=$DIR2/$tdir/$tfile
1362         local fid=$(create_small_file $f)
1363         local orig_size=$(stat -c "%s" $f)
1364
1365         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1366         wait_request_state $fid ARCHIVE SUCCEED
1367
1368         $LFS hsm_release $f || error "could not release file"
1369         check_hsm_flags $f "0x0000000d"
1370
1371         kill_copytools
1372         wait_copytools || error "copytool failed to stop"
1373
1374         cat $f > /dev/null &
1375
1376         # wait a bit to allow implicit restore request to be handled.
1377         # if not, next stat would also block on layout-lock.
1378         sleep 5
1379
1380         local size=$(stat -c "%s" $f2)
1381         [ $size -eq $orig_size ] ||
1382                 error "$f2: wrong size after archive: $size != $orig_size"
1383
1384         copytool setup -m "$MOUNT3"
1385
1386         wait
1387
1388         size=$(stat -c "%s" $f)
1389         [ $size -eq $orig_size ] ||
1390                 error "$f: wrong size after restore: $size != $orig_size"
1391
1392         size=$(stat -c "%s" $f2)
1393         [ $size -eq $orig_size ] ||
1394                 error "$f2: wrong size after restore: $size != $orig_size"
1395
1396         :>$f
1397
1398         size=$(stat -c "%s" $f)
1399         [ $size -eq 0 ] ||
1400                 error "$f: wrong size after overwrite: $size != 0"
1401
1402         size=$(stat -c "%s" $f2)
1403         [ $size -eq 0 ] ||
1404                 error "$f2: wrong size after overwrite: $size != 0"
1405 }
1406 run_test 12q "file attributes are refreshed after restore"
1407
1408 test_12r() {
1409         # test needs a running copytool
1410         copytool setup
1411
1412         mkdir_on_mdt0 $DIR/$tdir
1413         local f=$DIR/$tdir/$tfile
1414         local fid=$(copy_file /etc/hosts $f)
1415
1416         $LFS hsm_archive $f || error "archive of $f failed"
1417         wait_request_state $fid ARCHIVE SUCCEED
1418         $LFS hsm_release $f || error "release of $f failed"
1419
1420         offset=$(lseek_test -d 7 $f)
1421
1422         # we check we had a restore done
1423         wait_request_state $fid RESTORE SUCCEED
1424         [[ $offset == 7 ]] || error "offset $offset != 7"
1425 }
1426 run_test 12r "lseek restores released file"
1427
1428 test_12s() {
1429         local f=$DIR/$tdir/$tfile
1430         local fid
1431         local pid1 pid2
1432
1433         (( MDS1_VERSION >= $(version_code 2.15.50) )) ||
1434                 skip "Need MDS version newer than 2.15.50"
1435
1436         # test needs a running copytool
1437         copytool setup
1438
1439         mkdir_on_mdt0 $DIR/$tdir
1440         fid=$(copy_file /etc/hosts $f)
1441
1442         $LFS hsm_archive $f || error "archive of $f failed"
1443         wait_request_state $fid ARCHIVE SUCCEED
1444         $LFS hsm_release $f || error "release of $f failed"
1445
1446 #define CFS_FAIL_ONCE|OBD_FAIL_MDS_HSM_RESTORE_RACE 0x8000018b
1447         do_facet mds1 $LCTL set_param fail_loc=0x8000018b
1448         cat $f > /dev/null & pid1=$!
1449         cat $f > /dev/null & pid2=$!
1450
1451         wait $pid1 || error "cat process 1 fail (pid: $pid1)"
1452         wait $pid2 || error "cat process 2 fail (pid: $pid2)"
1453
1454         # Race exists if more than 1 restore requests is registered
1455         assert_request_count $fid RESTORE 1
1456 }
1457 run_test 12s "race between restore requests"
1458
1459 test_12t() {
1460         copytool setup
1461
1462         mkdir_on_mdt0 $DIR/$tdir
1463
1464         local file=$DIR/$tdir/$tfile
1465         local fid=$(copy_file /etc/hosts $file)
1466         local n=32
1467
1468         $LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $file ||
1469                 error "failed to HSM archive $file"
1470         wait_request_state $fid ARCHIVE SUCCEED
1471         rm -f $file || error "failed to rm $file"
1472
1473         copytool import $fid $file
1474         check_hsm_flags $file "0x0000000d"
1475
1476         local -a pids
1477
1478         for ((i=0; i < $n; i++)); do
1479                 cat $file > /dev/null &
1480                 pids[$i]=$!
1481         done
1482
1483         for ((i=0; i < $n; i++));do
1484                 wait ${pids[$i]} || error "$?: failed to read pid=${pids[$i]}"
1485         done
1486 }
1487 run_test 12t "Multiple parallel reads for a HSM imported file"
1488
1489 test_12u() {
1490         local dir=$DIR/$tdir
1491         local n=10
1492         local t=32
1493
1494         copytool setup
1495         mkdir_on_mdt0 $dir || error "failed to mkdir $dir"
1496
1497         local -a pids
1498         local -a fids
1499
1500         for ((i=0; i<$n; i++)); do
1501                 fids[$i]=$(copy_file /etc/hosts $dir/$tfile.$i)
1502                 $LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $dir/$tfile.$i ||
1503                         error "failed to HSM archive $dir/$tfile.$i"
1504         done
1505
1506         for ((i=0; i<$n; i++)); do
1507                 wait_request_state ${fids[$i]} ARCHIVE SUCCEED
1508                 rm $dir/$tfile.$i || error "failed to rm $dir/$tfile.$i"
1509         done
1510
1511         for ((i=0; i<$n; i++)); do
1512                 copytool import ${fids[$i]} $dir/$tfile.$i
1513                 check_hsm_flags $dir/$tfile.$i "0x0000000d"
1514         done
1515
1516         for ((i=0; i<$n; i++)); do
1517                 for ((j=0; j<$t; j++)); do
1518                         cat $dir/$tfile.$i > /dev/null &
1519                         pids[$((i * t + j))]=$!
1520                 done
1521         done
1522
1523         local pid
1524
1525         for pid in "${pids[@]}"; do
1526                 wait $pid || error "$pid: failed to cat file: $?"
1527         done
1528 }
1529 run_test 12u "Multiple reads on multiple HSM imported files in parallel"
1530
1531 test_13() {
1532         local -i i j k=0
1533         for i in {1..10}; do
1534                 local archive_dir="$(hsm_root)"/subdir/dir.$i
1535
1536                 do_facet $SINGLEAGT mkdir -p "$archive_dir"
1537                 for j in {1..10}; do
1538                         local archive_file="$archive_dir"/file.$j
1539
1540                         do_facet $SINGLEAGT "echo $k > \"$archive_dir\"/file.$j"
1541                         k+=1
1542                 done
1543         done
1544
1545         # import to Lustre
1546         copytool import "subdir" "$DIR/$tdir"
1547
1548         # To check the import, the test uses diff with the -r flag
1549         # This is nice, but diff only checks files one by one, and triggering
1550         # an implicit restore for one file at a time will consume as many
1551         # seconds as there are files to compare. To speed this up, a restore
1552         # operation is triggered manually first.
1553         copytool setup
1554         find "$DIR/$tdir"/subdir -type f -exec $LFS hsm_restore {} \;
1555
1556         # Compare the imported data
1557         do_facet $SINGLEAGT \
1558                 diff -r "$(hsm_root)"/subdir "$DIR/$tdir"/subdir ||
1559                 error "imported files differ from archived data"
1560 }
1561 run_test 13 "Recursively import and restore a directory"
1562
1563 test_14() {
1564         # test needs a running copytool
1565         copytool setup
1566
1567         mkdir_on_mdt0 $DIR/$tdir
1568
1569         # archive a file
1570         local f=$DIR/$tdir/$tfile
1571         local fid=$(create_small_file $f)
1572         local sum=$(md5sum $f | awk '{print $1}')
1573         $LFS hsm_archive $f || error "could not archive file"
1574         wait_request_state $fid ARCHIVE SUCCEED
1575
1576         # create released file (simulate llapi_hsm_import call)
1577         local fid2=$(create_empty_file "$f")
1578         $LFS hsm_set --archived --exists $f || error "could not force hsm flags"
1579         $LFS hsm_release $f || error "could not release file"
1580
1581         # rebind the archive to the newly created file
1582         echo "rebind $fid to $fid2"
1583
1584         copytool rebind $fid $fid2
1585
1586         # restore file and compare md5sum
1587         local sum2=$(md5sum $f | awk '{print $1}')
1588
1589         [[ $sum == $sum2 ]] || error "md5sum mismatch after restore"
1590 }
1591 run_test 14 "Rebind archived file to a new fid"
1592
1593 test_15() {
1594         # test needs a running copytool
1595         copytool setup
1596
1597         mkdir_on_mdt0 $DIR/$tdir
1598
1599         # archive files
1600         local f=$DIR/$tdir/$tfile
1601         local count=5
1602         local tmpfile=$SHARED_DIRECTORY/tmp.$$
1603
1604         local fids=()
1605         local sums=()
1606         for i in $(seq 1 $count); do
1607                 fids[$i]=$(create_small_file $f.$i)
1608                 sums[$i]=$(md5sum $f.$i | awk '{print $1}')
1609                 $LFS hsm_archive $f.$i || error "could not archive file"
1610         done
1611         wait_all_done $(($count*60))
1612
1613         stack_trap "rm -f $tmpfile" EXIT
1614         :>$tmpfile
1615         # delete the files
1616         for i in $(seq 1 $count); do
1617                 local fid2=$(create_empty_file "${f}.${i}")
1618                 # add the rebind operation to the list
1619                 echo ${fids[$i]} $fid2 >> $tmpfile
1620
1621                 # set it released (simulate llapi_hsm_import call)
1622                 $LFS hsm_set --archived --exists $f.$i ||
1623                         error "could not force hsm flags"
1624                 $LFS hsm_release $f.$i || error "could not release file"
1625         done
1626         nl=$(wc -l < $tmpfile)
1627         [[ $nl == $count ]] || error "$nl files in list, $count expected"
1628
1629         echo "rebind list of files"
1630         copytool rebind "$tmpfile"
1631
1632         # restore files and compare md5sum
1633         for i in $(seq 1 $count); do
1634                 local sum2=$(md5sum $f.$i | awk '{print $1}')
1635                 [[ $sum2 == ${sums[$i]} ]] ||
1636                     error "md5sum mismatch after restore ($sum2 != ${sums[$i]})"
1637         done
1638 }
1639 run_test 15 "Rebind a list of files"
1640
1641 test_16() {
1642         # test needs a running copytool
1643         copytool setup -b 1
1644
1645         local ref=/tmp/ref
1646         # create a known size file so we can verify transfer speed
1647         # 20 MB <-> 20s
1648         local goal=20
1649         dd if=/dev/zero of=$ref bs=1M count=20
1650
1651         mkdir_on_mdt0 $DIR/$tdir
1652         local f=$DIR/$tdir/$tfile
1653         local fid=$(copy_file $ref $f)
1654         rm $ref
1655         local start=$(date +%s)
1656         $LFS hsm_archive $f
1657         wait_request_state $fid ARCHIVE SUCCEED
1658         local end=$(date +%s)
1659         # Add 1 to account for rounding errors between start and end (LU-8155)
1660         local duration=$((end - start + 1))
1661
1662         [[ $duration -ge $((goal - 1)) ]] ||
1663                 error "Transfer is too fast $duration < $goal"
1664 }
1665 run_test 16 "Test CT bandwith control option"
1666
1667 test_20() {
1668         local f=$DIR/$tdir/$tfile
1669         create_empty_file "$f"
1670
1671         # Could not release a non-archived file
1672         $LFS hsm_release $f && error "release should not succeed"
1673
1674         # For following tests, we must test them with HS_ARCHIVED set
1675         $LFS hsm_set --exists --archived $f || error "could not add flag"
1676
1677         # Could not release a file if no-release is set
1678         $LFS hsm_set --norelease $f || error "could not add flag"
1679         $LFS hsm_release $f && error "release should not succeed"
1680         $LFS hsm_clear --norelease $f || error "could not remove flag"
1681
1682         # Could not release a file if lost
1683         $LFS hsm_set --lost $f || error "could not add flag"
1684         $LFS hsm_release $f && error "release should not succeed"
1685         $LFS hsm_clear --lost $f || error "could not remove flag"
1686
1687         # Could not release a file if dirty
1688         $LFS hsm_set --dirty $f || error "could not add flag"
1689         $LFS hsm_release $f && error "release should not succeed"
1690         $LFS hsm_clear --dirty $f || error "could not remove flag"
1691 }
1692 run_test 20 "Release is not permitted"
1693
1694 test_21() {
1695         # test needs a running copytool
1696         copytool setup
1697         mkdir_on_mdt0 $DIR/$tdir
1698
1699         local f=$DIR/$tdir/test_release
1700
1701         # Create a file and check its states
1702         local fid=$(create_small_file $f)
1703         check_hsm_flags $f "0x00000000"
1704
1705         # LU-4388/LU-4389 - ZFS does not report full number of blocks
1706         # used until file is flushed to disk
1707         if [ "$ost1_FSTYPE" == "zfs" ]; then
1708             # this causes an OST_SYNC rpc to be sent
1709             dd if=/dev/zero of=$f bs=512 count=1 oflag=sync conv=notrunc,fsync
1710             # clear locks to reread file data
1711             cancel_lru_locks osc
1712         fi
1713
1714         local orig_size=$(stat -c "%s" $f)
1715         local orig_blocks=$(stat -c "%b" $f)
1716
1717 #       start_full_debug_logging
1718
1719         $LFS hsm_archive $f || error "could not archive file"
1720         wait_request_state $fid ARCHIVE SUCCEED
1721
1722         local blocks=$(stat -c "%b" $f)
1723         [ $blocks -eq $orig_blocks ] ||
1724                 error "$f: wrong block number after archive: " \
1725                       "$blocks != $orig_blocks"
1726         local size=$(stat -c "%s" $f)
1727         [ $size -eq $orig_size ] ||
1728                 error "$f: wrong size after archive: $size != $orig_size"
1729
1730         # Release and check states
1731         $LFS hsm_release $f || error "could not release file"
1732         check_hsm_flags $f "0x0000000d"
1733
1734         blocks=$(stat -c "%b" $f)
1735         [ $blocks -gt 5 ] &&
1736                 error "$f: too many blocks after release: $blocks > 5"
1737         size=$(stat -c "%s" $f)
1738         [ $size -ne $orig_size ] &&
1739                 error "$f: wrong size after release: $size != $orig_size"
1740
1741         # Check we can release an file without stripe info
1742         f=$f.nolov
1743         $MCREATE $f
1744         fid=$(path2fid $f)
1745         check_hsm_flags $f "0x00000000"
1746         $LFS hsm_archive $f || error "could not archive file"
1747         wait_request_state $fid ARCHIVE SUCCEED
1748
1749         # Release and check states
1750         $LFS hsm_release $f || error "could not release file"
1751         check_hsm_flags $f "0x0000000d"
1752
1753         # Release again a file that is already released is OK
1754         $LFS hsm_release $f || fail "second release should succeed"
1755         check_hsm_flags $f "0x0000000d"
1756
1757 #       stop_full_debug_logging
1758 }
1759 run_test 21 "Simple release tests"
1760
1761 test_22() {
1762         # test needs a running copytool
1763         copytool setup
1764         mkdir_on_mdt0 $DIR/$tdir
1765
1766         local f=$DIR/$tdir/test_release
1767         local swap=$DIR/$tdir/test_swap
1768
1769         # Create a file and check its states
1770         local fid=$(create_small_file $f)
1771         check_hsm_flags $f "0x00000000"
1772
1773         $LFS hsm_archive $f || error "could not archive file"
1774         wait_request_state $fid ARCHIVE SUCCEED
1775
1776         # Release and check states
1777         $LFS hsm_release $f || error "could not release file"
1778         check_hsm_flags $f "0x0000000d"
1779
1780         create_small_file $swap
1781         $LFS swap_layouts $swap $f && error "swap_layouts should failed"
1782
1783         return 0
1784 }
1785 run_test 22 "Could not swap a release file"
1786
1787 test_23() {
1788         # test needs a running copytool
1789         copytool setup
1790         mkdir_on_mdt0 $DIR/$tdir
1791
1792         local f=$DIR/$tdir/test_mtime
1793
1794         # Create a file and check its states
1795         local fid=$(create_small_file $f)
1796         check_hsm_flags $f "0x00000000"
1797
1798         $LFS hsm_archive $f || error "could not archive file"
1799         wait_request_state $fid ARCHIVE SUCCEED
1800
1801         # Set modification time in the past
1802         touch -m -a -d @978261179 $f
1803
1804         # Release and check states
1805         $LFS hsm_release $f || error "could not release file"
1806         check_hsm_flags $f "0x0000000d"
1807
1808         local MTIME=$(stat -c "%Y" $f)
1809         local ATIME=$(stat -c "%X" $f)
1810         [ $MTIME -eq "978261179" ] || fail "bad mtime: $MTIME"
1811         [ $ATIME -eq "978261179" ] || fail "bad atime: $ATIME"
1812 }
1813 run_test 23 "Release does not change a/mtime (utime)"
1814
1815 test_24a() {
1816         local file=$DIR/$tdir/$tfile
1817         local fid
1818         local atime0
1819         local atime1
1820         local mtime0
1821         local mtime1
1822         local ctime0
1823         local ctime1
1824
1825         # test needs a running copytool
1826         copytool setup
1827         mkdir_on_mdt0 $DIR/$tdir
1828
1829         fid=$(create_small_file $file)
1830
1831         # Create a file and check its states
1832         check_hsm_flags $file "0x00000000"
1833
1834         # Ensure atime is less than mtime and ctime.
1835         sleep 1
1836         echo >> $file
1837
1838         atime0=$(stat -c "%X" $file)
1839         mtime0=$(stat -c "%Y" $file)
1840         ctime0=$(stat -c "%Z" $file)
1841
1842         [ $atime0 -lt $mtime0 ] ||
1843                 error "atime $atime0 is not less than mtime $mtime0"
1844
1845         [ $atime0 -lt $ctime0 ] ||
1846                 error "atime $atime0 is not less than ctime $ctime0"
1847
1848         # Archive should not change any timestamps.
1849         $LFS hsm_archive $file || error "cannot archive '$file'"
1850         wait_request_state $fid ARCHIVE SUCCEED
1851
1852         atime1=$(stat -c "%X" $file)
1853         mtime1=$(stat -c "%Y" $file)
1854         ctime1=$(stat -c "%Z" $file)
1855
1856         [ $atime0 -eq $atime1 ] ||
1857                 error "archive changed atime from $atime0 to $atime1"
1858
1859         [ $mtime0 -eq $mtime1 ] ||
1860                 error "archive changed mtime from $mtime0 to $mtime1"
1861
1862         [ $ctime0 -eq $ctime1 ] ||
1863                 error "archive changed ctime from $ctime0 to $ctime1"
1864
1865         # Release should not change any timestamps.
1866         $LFS hsm_release $file || error "cannot release '$file'"
1867         check_hsm_flags $file "0x0000000d"
1868
1869         atime1=$(stat -c "%X" $file)
1870         mtime1=$(stat -c "%Y" $file)
1871         ctime1=$(stat -c "%Z" $file)
1872
1873         [ $atime0 -eq $atime1 ] ||
1874                 error "release changed atime from $atime0 to $atime1"
1875
1876         [ $mtime0 -eq $mtime1 ] ||
1877                 error "release changed mtime from $mtime0 to $mtime1"
1878
1879         [ $ctime0 -eq $ctime1 ] ||
1880                 error "release changed ctime from $ctime0 to $ctime1"
1881
1882         # Restore should not change any timestamps.
1883         $LFS hsm_restore $file
1884         wait_request_state $fid RESTORE SUCCEED
1885
1886         atime1=$(stat -c "%X" $file)
1887         mtime1=$(stat -c "%Y" $file)
1888         ctime1=$(stat -c "%Z" $file)
1889
1890         [ $atime0 -eq $atime1 ] ||
1891                 error "restore changed atime from $atime0 to $atime1"
1892
1893         [ $mtime0 -eq $mtime1 ] ||
1894                 error "restore changed mtime from $mtime0 to $mtime1"
1895
1896         [ $ctime0 -eq $ctime1 ] ||
1897                 error "restore changed ctime from $ctime0 to $ctime1"
1898
1899         kill_copytools
1900         wait_copytools || error "Copytools failed to stop"
1901
1902         # Once more, after unmount and mount.
1903         umount_client $MOUNT || error "cannot unmount '$MOUNT'"
1904         mount_client $MOUNT || error "cannot mount '$MOUNT'"
1905
1906         atime1=$(stat -c "%X" $file)
1907         mtime1=$(stat -c "%Y" $file)
1908         ctime1=$(stat -c "%Z" $file)
1909
1910         [ $atime0 -eq $atime1 ] ||
1911                 error "remount changed atime from $atime0 to $atime1"
1912
1913         [ $mtime0 -eq $mtime1 ] ||
1914                 error "remount changed mtime from $mtime0 to $mtime1"
1915
1916         [ $ctime0 -eq $ctime1 ] ||
1917                 error "remount changed ctime from $ctime0 to $ctime1"
1918 }
1919 run_test 24a "Archive, release, and restore does not change a/mtime (i/o)"
1920
1921 test_24b() {
1922         local file=$DIR/$tdir/$tfile
1923         local fid
1924         local sum0
1925         local sum1
1926         # LU-3811
1927
1928         # Test needs a running copytool.
1929         copytool setup
1930         mkdir_on_mdt0 $DIR/$tdir
1931
1932         # Check that root can do HSM actions on a regular user's file.
1933         fid=$(create_small_file $file)
1934         sum0=$(md5sum $file)
1935
1936         chown $RUNAS_ID:$RUNAS_GID $file ||
1937                 error "cannot chown '$file' to '$RUNAS_ID'"
1938
1939         chmod ugo-w $DIR/$tdir ||
1940                 error "cannot chmod '$DIR/$tdir'"
1941
1942         $LFS hsm_archive $file
1943         wait_request_state $fid ARCHIVE SUCCEED
1944
1945         $LFS hsm_release $file
1946         check_hsm_flags $file "0x0000000d"
1947
1948         $LFS hsm_restore $file
1949         wait_request_state $fid RESTORE SUCCEED
1950
1951         # Check that ordinary user can get HSM state.
1952         $RUNAS $LFS hsm_state $file ||
1953                 error "user '$RUNAS_ID' cannot get HSM state of '$file'"
1954
1955         $LFS hsm_release $file
1956         check_hsm_flags $file "0x0000000d"
1957
1958         # Check that ordinary user can accessed released file.
1959         sum1=$($RUNAS md5sum $file) ||
1960                 error "user '$RUNAS_ID' cannot read '$file'"
1961
1962         [ "$sum0" == "$sum1" ] ||
1963                 error "md5sum mismatch for '$file'"
1964 }
1965 run_test 24b "root can archive, release, and restore user files"
1966
1967 test_24c() {
1968         local file=$DIR/$tdir/$tfile
1969         local action=archive
1970         local user_save
1971         local group_save
1972         local other_save
1973
1974         # test needs a running copytool
1975         copytool setup
1976         mkdir_on_mdt0 $DIR/$tdir
1977
1978         # Save the default masks and check that cleanup_24c will
1979         # restore the request masks correctly.
1980         user_save=$(get_hsm_param user_request_mask)
1981         stack_trap "set_hsm_param user_request_mask '$user_save'" EXIT
1982         group_save=$(get_hsm_param group_request_mask)
1983         stack_trap "set_hsm_param group_request_mask '$group_save'" EXIT
1984         other_save=$(get_hsm_param other_request_mask)
1985         stack_trap "set_hsm_param other_request_mask '$other_save'" EXIT
1986
1987         [ "$user_save" == RESTORE ] ||
1988                 error "user_request_mask is '$user_save' expected 'RESTORE'"
1989         [ "$group_save" == RESTORE ] ||
1990                 error "group_request_mask is '$group_save' expected 'RESTORE'"
1991         [ "$other_save" == RESTORE ] ||
1992                 error "other_request_mask is '$other_save' expected 'RESTORE'"
1993
1994         # User.
1995         create_small_file $file
1996         chown $RUNAS_ID:$GROUP $file ||
1997                 error "cannot chown '$file' to '$RUNAS_ID:$GROUP'"
1998
1999         $RUNAS $LFS hsm_$action $file &&
2000                 error "$action by user should fail"
2001
2002         set_hsm_param user_request_mask $action
2003         $RUNAS $LFS hsm_$action $file ||
2004                 error "$action by user should succeed"
2005
2006         # Group.
2007         create_small_file $file
2008         chown nobody:$RUNAS_GID $file ||
2009                 error "cannot chown '$file' to 'nobody:$RUNAS_GID'"
2010
2011         $RUNAS $LFS hsm_$action $file &&
2012                 error "$action by group should fail"
2013
2014         set_hsm_param group_request_mask $action
2015         $RUNAS $LFS hsm_$action $file ||
2016                 error "$action by group should succeed"
2017
2018         # Other.
2019         create_small_file $file
2020         chown nobody:$GROUP $file ||
2021                 error "cannot chown '$file' to 'nobody:$GROUP'"
2022
2023         $RUNAS $LFS hsm_$action $file &&
2024                 error "$action by other should fail"
2025
2026         set_hsm_param other_request_mask $action
2027         $RUNAS $LFS hsm_$action $file ||
2028                 error "$action by other should succeed"
2029 }
2030 run_test 24c "check that user,group,other request masks work"
2031
2032 test_24d() {
2033         local file1=$DIR/$tdir/$tfile
2034         local file2=$DIR2/$tdir/$tfile
2035         local fid1
2036         local fid2
2037
2038         mkdir_on_mdt0 $DIR/$tdir
2039
2040         fid1=$(create_small_file $file1)
2041
2042         echo $fid1
2043         $LFS getstripe $file1
2044
2045         stack_trap "zconf_umount \"$(facet_host $SINGLEAGT)\" \"$MOUNT3\"" EXIT
2046         zconf_mount "$(facet_host $SINGLEAGT)" "$MOUNT3" ||
2047                 error "cannot mount '$MOUNT3' on '$SINGLEAGT'"
2048
2049         copytool setup -m  "$MOUNT3"
2050
2051         stack_trap "mount -o remount,rw \"$MOUNT2\"" EXIT
2052         mount -o remount,ro $MOUNT2
2053
2054         do_nodes $(comma_list $(nodes_list)) $LCTL clear
2055
2056         fid2=$(path2fid $file2)
2057         [ "$fid1" == "$fid2" ] ||
2058                 error "FID mismatch '$fid1' != '$fid2'"
2059
2060         $LFS hsm_archive $file2 &&
2061                 error "archive should fail on read-only mount"
2062         check_hsm_flags $file1 "0x00000000"
2063
2064         $LFS hsm_archive $file1 || error "Fail to archive $file1"
2065         wait_request_state $fid1 ARCHIVE SUCCEED
2066
2067         $LFS hsm_release $file1
2068         $LFS hsm_restore $file2
2069         wait_request_state $fid1 RESTORE SUCCEED
2070
2071         $LFS hsm_release $file1 || error "cannot release '$file1'"
2072         dd if=$file2 of=/dev/null bs=1M || error "cannot read '$file2'"
2073
2074         $LFS hsm_release $file2 &&
2075                 error "release should fail on read-only mount"
2076
2077         return 0
2078 }
2079 run_test 24d "check that read-only mounts are respected"
2080
2081 test_24e() {
2082         copytool setup
2083         mkdir_on_mdt0 $DIR/$tdir
2084
2085         local f=$DIR/$tdir/$tfile
2086         local fid
2087
2088         fid=$(create_small_file $f) || error "cannot create $f"
2089         $LFS hsm_archive $f || error "cannot archive $f"
2090         wait_request_state $fid ARCHIVE SUCCEED
2091         $LFS hsm_release $f || error "cannot release $f"
2092         while ! $LFS hsm_state $f | grep released; do
2093                 sleep 1
2094         done
2095
2096         tar -cf $TMP/$tfile.tar $DIR/$tdir || error "cannot tar $DIR/$tdir"
2097 }
2098 run_test 24e "tar succeeds on HSM released files" # LU-6213
2099
2100 test_24f() {
2101         # test needs a running copytool
2102         copytool setup
2103         mkdir_on_mdt0 $DIR/$tdir
2104
2105         mkdir -p $DIR/$tdir/d1
2106         local f=$DIR/$tdir/$tfile
2107         local fid=$(copy_file /etc/hosts $f)
2108         sum0=$(md5sum $f)
2109         echo $sum0
2110         $LFS hsm_archive $f ||
2111                 error "hsm_archive failed"
2112         wait_request_state $fid ARCHIVE SUCCEED
2113         $LFS hsm_release $f || error "cannot release $f"
2114         tar --xattrs -cvf $f.tar -C $DIR/$tdir $tfile
2115         rm -f $f
2116         sync
2117         tar --xattrs -xvf $f.tar -C $DIR/$tdir ||
2118                 error "Can not recover the tar contents"
2119         sum1=$(md5sum $f)
2120         echo "Sum0 = $sum0, sum1 = $sum1"
2121         [ "$sum0" == "$sum1" ] || error "md5sum mismatch for '$tfile'"
2122 }
2123 run_test 24f "root can archive, release, and restore tar files"
2124
2125 test_24g() {
2126         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
2127                 skip "need MDS version 2.11.56 or later"
2128
2129         local file=$DIR/$tdir/$tfile
2130         local fid
2131
2132         echo "RUNAS = '$RUNAS'"
2133
2134         copytool setup
2135
2136         mkdir_on_mdt0 $DIR/$tdir
2137         chmod ugo+rwx $DIR/$tdir
2138
2139         echo "Please listen carefully as our options have changed." | tee $file
2140         fid=$(path2fid $file)
2141         chmod ugo+rw $file
2142
2143         $LFS hsm_archive $file
2144         wait_request_state $fid ARCHIVE SUCCEED
2145         check_hsm_flags $file 0x00000009 # exists archived
2146
2147         echo "To be electrocuted by your telephone, press #." | $RUNAS tee $file
2148         check_hsm_flags $file 0x0000000b # exists dirty archived
2149 }
2150 run_test 24g "write by non-owner still sets dirty" # LU-11369
2151
2152 test_25a() {
2153         # test needs a running copytool
2154         copytool setup
2155
2156         mkdir -p $DIR/$tdir
2157         copy2archive /etc/hosts $tdir/$tfile
2158
2159         local f=$DIR/$tdir/$tfile
2160
2161         copytool import $tdir/$tfile $f
2162
2163         $LFS hsm_set --lost $f
2164
2165         md5sum $f
2166         local st=$?
2167
2168         [[ $st == 1 ]] || error "lost file access should failed (returns $st)"
2169 }
2170 run_test 25a "Restore lost file (HS_LOST flag) from import"\
2171              " (Operation not permitted)"
2172
2173 test_25b() {
2174         # test needs a running copytool
2175         copytool setup
2176
2177         mkdir_on_mdt0 $DIR/$tdir
2178
2179         local f=$DIR/$tdir/$tfile
2180         local fid=$(copy_file /etc/passwd $f)
2181
2182         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2183         wait_request_state $fid ARCHIVE SUCCEED
2184
2185         $LFS hsm_release $f
2186         $LFS hsm_set --lost $f
2187         md5sum $f
2188         st=$?
2189
2190         [[ $st == 1 ]] || error "lost file access should failed (returns $st)"
2191 }
2192 run_test 25b "Restore lost file (HS_LOST flag) after release"\
2193              " (Operation not permitted)"
2194
2195 test_26A() { # was test_26
2196         # test needs a running copytool
2197         copytool setup
2198         mkdir_on_mdt0 $DIR/$tdir
2199
2200         local f=$DIR/$tdir/$tfile
2201         local fid=$(create_empty_file "$f")
2202
2203         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2204         wait_request_state $fid ARCHIVE SUCCEED
2205
2206         $LFS hsm_remove $f
2207         wait_request_state $fid REMOVE SUCCEED
2208
2209         check_hsm_flags $f "0x00000000"
2210 }
2211 run_test 26A "Remove the archive of a valid file"
2212
2213 test_26a() {
2214         local raolu=$(get_hsm_param remove_archive_on_last_unlink)
2215         [[ $raolu -eq 0 ]] || error "RAoLU policy should be off"
2216
2217         # test needs a running copytool
2218         copytool setup
2219         mkdir_on_mdt0 $DIR/$tdir
2220
2221         local f=$DIR/$tdir/$tfile
2222         local fid=$(copy_file /etc/passwd $f)
2223
2224         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2225         wait_request_state $fid ARCHIVE SUCCEED
2226
2227         local f2=$DIR/$tdir/${tfile}_2
2228         local fid2=$(copy_file /etc/passwd $f2)
2229
2230         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f2
2231         wait_request_state $fid2 ARCHIVE SUCCEED
2232
2233         local f3=$DIR/$tdir/${tfile}_3
2234         local fid3=$(copy_file /etc/passwd $f3)
2235
2236         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f3
2237         wait_request_state $fid3 ARCHIVE SUCCEED
2238
2239         # set a long grace_delay vs short loop_period
2240         local orig_loop_period=$(get_hsm_param loop_period)
2241         local orig_grace_delay=$(get_hsm_param grace_delay)
2242         stack_trap "set_hsm_param loop_period $orig_loop_period" EXIT
2243         set_hsm_param loop_period 10
2244         stack_trap "set_hsm_param grace_delay $orig_grace_delay" EXIT
2245         set_hsm_param grace_delay 100
2246
2247         rm -f $f
2248
2249         stack_trap "set_hsm_param remove_archive_on_last_unlink 0" EXIT
2250         set_hsm_param remove_archive_on_last_unlink 1
2251
2252         ln "$f3" "$f3"_bis || error "Unable to create hard-link"
2253         rm -f $f3
2254
2255         rm -f $f2
2256
2257         wait_request_state $fid2 REMOVE SUCCEED
2258
2259         assert_request_count $fid REMOVE 0 \
2260                 "Unexpected archived data remove request for $f"
2261         assert_request_count $fid3 REMOVE 0 \
2262                 "Unexpected archived data remove request for $f3"
2263 }
2264 run_test 26a "Remove Archive On Last Unlink (RAoLU) policy"
2265
2266 test_26b() {
2267         # test needs a running copytool
2268         copytool setup
2269         mkdir_on_mdt0 $DIR/$tdir
2270
2271         local f=$DIR/$tdir/$tfile
2272         local fid=$(copy_file /etc/passwd $f)
2273
2274         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2275         wait_request_state $fid ARCHIVE SUCCEED
2276
2277         stack_trap "set_hsm_param remove_archive_on_last_unlink 0" EXIT
2278         set_hsm_param remove_archive_on_last_unlink 1
2279
2280         cdt_shutdown
2281         cdt_check_state stopped
2282
2283         rm -f $f
2284
2285         wait_request_state $fid REMOVE WAITING
2286
2287         cdt_enable
2288
2289         # copytool must re-register
2290         kill_copytools
2291         wait_copytools || error "copytool failed to stop"
2292         copytool setup
2293
2294         wait_request_state $fid REMOVE SUCCEED
2295 }
2296 run_test 26b "RAoLU policy when CDT off"
2297
2298 test_26c() {
2299         # test needs a running copytool
2300         copytool setup
2301         mkdir_on_mdt0 $DIR/$tdir
2302
2303         local f=$DIR/$tdir/$tfile
2304         local fid=$(copy_file /etc/passwd $f)
2305
2306         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2307         wait_request_state $fid ARCHIVE SUCCEED
2308
2309         local f2=$DIR/$tdir/${tfile}_2
2310         local fid2=$(copy_file /etc/passwd $f2)
2311
2312         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f2
2313         wait_request_state $fid2 ARCHIVE SUCCEED
2314
2315         # set a long grace_delay vs short loop_period
2316         local orig_loop_period=$(get_hsm_param loop_period)
2317         local orig_grace_delay=$(get_hsm_param grace_delay)
2318         stack_trap "set_hsm_param loop_period $orig_loop_period" EXIT
2319         set_hsm_param loop_period 10
2320         stack_trap "set_hsm_param grace_delay $orig_grace_delay" EXIT
2321         set_hsm_param grace_delay 100
2322
2323         stack_trap "set_hsm_param remove_archive_on_last_unlink 0" EXIT
2324         set_hsm_param remove_archive_on_last_unlink 1
2325
2326         multiop_bg_pause $f O_c || error "open $f failed"
2327         local pid=$!
2328
2329         rm -f $f
2330         rm -f $f2
2331
2332         wait_request_state $fid2 REMOVE SUCCEED
2333         assert_request_count $fid REMOVE 0 \
2334                 "Unexpected archived data remove request for $f"
2335
2336         kill -USR1 $pid || error "multiop early exit"
2337         # should reach autotest timeout if multiop fails to trap
2338         # signal, close file, and exit ...
2339         wait $pid || error "wait PID $PID failed"
2340
2341         wait_request_state $fid REMOVE SUCCEED
2342 }
2343 run_test 26c "RAoLU effective when file closed"
2344
2345 test_26d() {
2346         # test needs a running copytool
2347         copytool setup
2348         mkdir_on_mdt0 $DIR/$tdir
2349
2350         local f=$DIR/$tdir/$tfile
2351         local fid=$(create_small_file $f)
2352
2353         $LFS hsm_archive $f || error "could not archive file"
2354         wait_request_state $fid ARCHIVE SUCCEED
2355
2356         # set a long grace_delay vs short loop_period
2357         local orig_loop_period=$(get_hsm_param loop_period)
2358         local orig_grace_delay=$(get_hsm_param grace_delay)
2359         stack_trap "set_hsm_param loop_period $orig_loop_period" EXIT
2360         set_hsm_param loop_period 10
2361         stack_trap "set_hsm_param grace_delay $orig_grace_delay" EXIT
2362         set_hsm_param grace_delay 100
2363
2364         stack_trap "set_hsm_param remove_archive_on_last_unlink 0" EXIT
2365         set_hsm_param remove_archive_on_last_unlink 1
2366
2367         multiop_bg_pause $f O_c || error "multiop failed"
2368         local MULTIPID=$!
2369
2370         rm -f $f
2371
2372         mds_evict_client
2373
2374         wait_request_state $fid REMOVE SUCCEED
2375
2376         client_up || client_up || true
2377
2378         kill -USR1 $MULTIPID
2379         wait $MULTIPID || error "multiop close failed"
2380 }
2381 run_test 26d "RAoLU when Client eviction"
2382
2383 test_26e() {
2384         (( MDS1_VERSION >= $(version_code 2.16.51) )) ||
2385                 skip "need MDS version at least 2.16.51"
2386
2387         # test needs a running copytool
2388         copytool setup
2389         mkdir_on_mdt0 $DIR/$tdir
2390
2391         local f=$DIR/$tdir/$tfile
2392         local fid=$(create_small_file $f)
2393         local f2=$DIR/$tdir/$tfile-2
2394         local fid2=$(create_small_file $f2)
2395
2396         $LFS hsm_archive $f || error "could not archive file"
2397         wait_request_state $fid ARCHIVE SUCCEED
2398
2399         kill_copytools
2400         wait_copytools || error "copytool failed to stop"
2401
2402         $LFS hsm_archive $f2 || error "could not archive file"
2403         wait_request_state $fid2 ARCHIVE WAITING
2404
2405         local last_cookie=$(( $(get_request_cookie $fid2 ARCHIVE) ))
2406
2407         stack_trap "cdt_set_mount_state enabled"
2408         cdt_set_mount_state shutdown
2409
2410         fail mds1
2411         cdt_check_state stopped
2412
2413         stack_trap "set_hsm_param remove_archive_on_last_unlink 0"
2414         set_hsm_param remove_archive_on_last_unlink 1
2415
2416         rm -f $f
2417
2418         wait_request_state $fid REMOVE WAITING
2419
2420         local new_cookie=$(( $(get_request_cookie $fid REMOVE) ))
2421         echo "Check cookie from RAoLU request (last: $last_cookie, remove: $new_cookie)"
2422         (( new_cookie == last_cookie + 1 )) ||
2423                 error "RAoLU fail to setup a valid cookie ($new_cookie != $last_cookie + 1)"
2424
2425         cdt_enable
2426         copytool setup
2427
2428         wait_request_state $fid2 ARCHIVE SUCCEED
2429         wait_request_state $fid REMOVE SUCCEED
2430 }
2431 run_test 26e "RAoLU with a non-started coordinator"
2432
2433 test_27a() {
2434         # test needs a running copytool
2435         copytool setup
2436
2437         create_archive_file $tdir/$tfile
2438         local f=$DIR/$tdir/$tfile
2439         copytool import $tdir/$tfile $f
2440         local fid=$(path2fid $f)
2441
2442         $LFS hsm_remove $f
2443
2444         [[ $? != 0 ]] || error "Remove of a released file should fail"
2445 }
2446 run_test 27a "Remove the archive of an imported file (Operation not permitted)"
2447
2448 test_27b() {
2449         # test needs a running copytool
2450         copytool setup
2451         mkdir_on_mdt0 $DIR/$tdir
2452
2453         local f=$DIR/$tdir/$tfile
2454         local fid=$(create_empty_file "$f")
2455
2456         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2457         wait_request_state $fid ARCHIVE SUCCEED
2458         $LFS hsm_release $f
2459
2460         $LFS hsm_remove $f
2461
2462         [[ $? != 0 ]] || error "Remove of a released file should fail"
2463 }
2464 run_test 27b "Remove the archive of a relased file (Operation not permitted)"
2465
2466 test_28() {
2467         # test needs a running copytool
2468         copytool setup
2469         mkdir_on_mdt0 $DIR/$tdir
2470
2471         local f=$DIR/$tdir/$tfile
2472         local fid=$(create_empty_file "$f")
2473
2474         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2475         wait_request_state $fid ARCHIVE SUCCEED
2476
2477         cdt_disable
2478         $LFS hsm_remove $f
2479
2480         rm -f $f
2481
2482         cdt_enable
2483
2484         wait_request_state $fid REMOVE SUCCEED
2485 }
2486 run_test 28 "Concurrent archive/file remove"
2487
2488 test_29a() {
2489         # Tests --mntpath and --archive options
2490
2491         local archive_id=7
2492         copytool setup -m "$MOUNT" -a $archive_id
2493
2494         # Bad archive number
2495         $LFS hsm_remove -m "$MOUNT" -a 33 0x857765760:0x8:0x2 2>&1 |
2496                 grep "Invalid argument" ||
2497                 error "unexpected hsm_remove failure (1)"
2498
2499         # mntpath is present but file is given
2500         $LFS hsm_remove --mntpath "$MOUNT" --archive 30 /qwerty/uyt 2>&1 |
2501                 grep "hsm: '/qwerty/uyt' is not a valid FID" ||
2502                 error "unexpected hsm_remove failure (2)"
2503 }
2504 run_test 29a "Tests --mntpath and --archive options"
2505
2506 test_29b() {
2507         # test needs a running copytool
2508         copytool setup
2509         mkdir_on_mdt0 $DIR/$tdir
2510
2511         local f=$DIR/$tdir/$tfile
2512         local fid=$(create_small_file $f)
2513
2514         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2515         wait_request_state $fid ARCHIVE SUCCEED
2516
2517         rm -f $f
2518
2519         $LFS hsm_remove -m $MOUNT -a $HSM_ARCHIVE_NUMBER $fid
2520         wait_request_state $fid REMOVE SUCCEED
2521 }
2522 run_test 29b "Archive/delete/remove by FID from the archive."
2523
2524 test_29c() {
2525         # test needs a running copytool
2526         copytool setup
2527         mkdir_on_mdt0 $DIR/$tdir
2528
2529         local fid1=$(create_small_file $DIR/$tdir/$tfile-1)
2530         local fid2=$(create_small_file $DIR/$tdir/$tfile-2)
2531         local fid3=$(create_small_file $DIR/$tdir/$tfile-3)
2532
2533         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/$tfile-[1-3]
2534         wait_request_state $fid1 ARCHIVE SUCCEED
2535         wait_request_state $fid2 ARCHIVE SUCCEED
2536         wait_request_state $fid3 ARCHIVE SUCCEED
2537
2538         rm -f $DIR/$tdir/$tfile-[1-3]
2539
2540         echo $fid1 > $DIR/$tdir/list
2541         echo $fid2 >> $DIR/$tdir/list
2542         echo $fid3 >> $DIR/$tdir/list
2543
2544         $LFS hsm_remove -m $MOUNT -a $HSM_ARCHIVE_NUMBER \
2545                 --filelist $DIR/$tdir/list
2546         wait_request_state $fid1 REMOVE SUCCEED
2547         wait_request_state $fid2 REMOVE SUCCEED
2548         wait_request_state $fid3 REMOVE SUCCEED
2549 }
2550 run_test 29c "Archive/delete/remove by FID, using a file list."
2551
2552 test_29d() {
2553         # test needs more than one CT
2554         needclients 3 || return 0
2555
2556         local n
2557         local file
2558         local fid
2559
2560         # start all of the copytools
2561         for n in $(seq $AGTCOUNT); do
2562                 copytool setup -f agt$n -a $n
2563         done
2564
2565         mkdir_on_mdt0 $DIR/$tdir
2566
2567         # archive files
2568         file=$DIR/$tdir/$tfile
2569         fid=$(create_small_file $file)
2570
2571         $LFS hsm_archive $file
2572         wait_request_state $fid ARCHIVE SUCCEED
2573         check_hsm_flags $file "0x00000009"
2574
2575         rm -f $file
2576
2577         $LFS hsm_remove --mntpath "$MOUNT" -a 0 $fid ||
2578                 error "cannot hsm_remove '$fid'"
2579
2580         # give time for CDT to handle remove request and create broadcasted
2581         sleep 2
2582
2583         # remove request has been broadcasted ?
2584         local cnt=$(get_request_count $fid REMOVE)
2585         # broadcasted requests + original
2586         [[ $cnt -eq $((AGTCOUNT + 1)) ]] ||
2587                 error "remove not broadcasted to all CTs"
2588
2589         # give time for CDT and CTs to handle broadcasted
2590         wait_for_loop_period
2591
2592         # each agent serves one different archive_id, so broadcasted
2593         # hsm_remove request should only succeed once and fail at all others
2594         local res
2595         local scnt=0
2596         local fcnt=0
2597         for n in $(seq $AGTCOUNT); do
2598                 res=$(do_facet $SINGLEMDS "$LCTL get_param -n \
2599                                $HSM_PARAM.actions | awk \
2600                                '/'$fid'.*action=REMOVE archive#='$n'/ \
2601                                {print \\\$13}' | cut -f2 -d=")
2602                 if [[ "$res" == "SUCCEED" ]]; then
2603                         scnt=$((scnt + 1))
2604                 elif [[ "$res" == "FAILED" ]]; then
2605                         fcnt=$((fcnt + 1))
2606                 fi
2607         done
2608
2609         [[ $scnt -eq 1 ]] ||
2610                 error "one and only CT should have removed successfully"
2611
2612         [[ $AGTCOUNT -eq $((scnt + fcnt)) ]] ||
2613                 error "all but one CT should have failed to remove"
2614 }
2615 run_test 29d "hsm_remove by FID with archive_id 0 for unlinked file cause "\
2616              "request to be sent once for each registered archive_id"
2617
2618 test_30a() {
2619         # restore at exec cannot work on agent node (because of Linux kernel
2620         # protection of executables)
2621         needclients 2 || return 0
2622
2623         # test needs a running copytool
2624         copytool setup
2625
2626         mkdir -p $DIR/$tdir
2627         copy2archive /bin/true $tdir/$tfile
2628
2629         local f=$DIR/$tdir/true
2630         copytool import $tdir/$tfile $f
2631
2632         local fid=$(path2fid $f)
2633
2634         stack_trap "cdt_clear_no_retry" EXIT
2635         # set no retry action mode
2636         cdt_set_no_retry
2637         do_node $CLIENT2 $f
2638         local st=$?
2639
2640         $LFS hsm_state $f
2641
2642         [[ $st == 0 ]] || error "Failed to exec a released file"
2643 }
2644 run_test 30a "Restore at exec (import case)"
2645
2646 test_30b() {
2647         # restore at exec cannot work on agent node (because of Linux kernel
2648         # protection of executables)
2649         needclients 2 || return 0
2650
2651         # test needs a running copytool
2652         copytool setup
2653
2654         mkdir_on_mdt0 $DIR/$tdir
2655         local f=$DIR/$tdir/true
2656         local fid=$(copy_file /bin/true $f)
2657         chmod 755 $f
2658         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2659         wait_request_state $fid ARCHIVE SUCCEED
2660         $LFS hsm_release $f
2661         $LFS hsm_state $f
2662
2663         stack_trap cdt_clear_no_retry EXIT
2664         # set no retry action mode
2665         cdt_set_no_retry
2666
2667         do_node $CLIENT2 $f
2668         local st=$?
2669
2670         $LFS hsm_state $f
2671
2672         [[ $st == 0 ]] || error "Failed to exec a released file"
2673 }
2674 run_test 30b "Restore at exec (release case)"
2675
2676 test_30c() {
2677         needclients 2 || return 0
2678
2679         # test needs a running copytool
2680         copytool setup
2681
2682         mkdir_on_mdt0 $DIR/$tdir
2683         local f=$DIR/$tdir/SLEEP
2684         local slp_sum1=$(md5sum /bin/sleep)
2685         local fid=$(copy_file /bin/sleep $f)
2686         chmod 755 $f
2687         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2688         wait_request_state $fid ARCHIVE SUCCEED
2689         $LFS hsm_release $f
2690         check_hsm_flags $f "0x0000000d"
2691
2692         stack_trap cdt_clear_no_retry EXIT
2693         # set no retry action mode
2694         cdt_set_no_retry
2695
2696         do_node $CLIENT2 "$f 10" &
2697         local pid=$!
2698         sleep 3
2699         echo 'Hi!' > $f
2700         [[ $? == 0 ]] && error "Update during exec of released file must fail"
2701         wait $pid
2702         [[ $? == 0 ]] || error "Execution failed during run"
2703         cmp /bin/sleep $f
2704         if [[ $? != 0 ]]; then
2705                 local slp_sum2=$(md5sum /bin/sleep)
2706                 # in case sleep file is modified during the test
2707                 [[ $slp_sum1 == $slp_sum2 ]] &&
2708                         error "Binary overwritten during exec"
2709         fi
2710
2711         check_hsm_flags $f "0x00000009"
2712 }
2713 run_test 30c "Update during exec of released file must fail"
2714
2715 restore_and_check_size() {
2716         local f=$1
2717         local fid=$2
2718         local s=$(stat -c "%s" $f)
2719         local n=$s
2720         local st=$(get_hsm_flags $f)
2721         local err=0
2722         local cpt=0
2723         $LFS hsm_restore $f
2724         while [[ "$st" != "0x00000009" && $cpt -le 10 ]]
2725         do
2726                 n=$(stat -c "%s" $f)
2727                 # we echo in both cases to show stat is not hang
2728                 if [[ $n != $s ]]; then
2729                         echo "size seen is $n != $s"
2730                         err=1
2731                 else
2732                         echo "size seen is right: $n == $s"
2733                 fi
2734                 sleep 10
2735                 cpt=$((cpt + 1))
2736                 st=$(get_hsm_flags $f)
2737         done
2738         if [[ "$st" = "0x00000009" ]]; then
2739                 echo " "done
2740         else
2741                 echo " restore is too long"
2742                 wait_request_state $fid RESTORE SUCCEED
2743         fi
2744         return $err
2745 }
2746
2747 test_31a() {
2748         # test needs a running copytool
2749         copytool setup
2750         mkdir_on_mdt0 $DIR/$tdir
2751
2752         create_archive_file $tdir/$tfile
2753         local f=$DIR/$tdir/$tfile
2754         copytool import $tdir/$tfile $f
2755         local fid=$($LFS path2fid $f)
2756         copytool setup
2757
2758         restore_and_check_size $f $fid
2759         local err=$?
2760
2761         [[ $err -eq 0 ]] || error "File size changed during restore"
2762 }
2763 run_test 31a "Import a large file and check size during restore"
2764
2765
2766 test_31b() {
2767         # test needs a running copytool
2768         copytool setup
2769         mkdir_on_mdt0 $DIR/$tdir
2770
2771         local f=$DIR/$tdir/$tfile
2772         local fid=$(create_file "$f" 1MB 39)
2773
2774         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2775         wait_request_state $fid ARCHIVE SUCCEED
2776         $LFS hsm_release $f
2777
2778         restore_and_check_size $f $fid
2779         local err=$?
2780
2781         [[ $err -eq 0 ]] || error "File size changed during restore"
2782 }
2783 run_test 31b "Restore a large unaligned file and check size during restore"
2784
2785 test_31c() {
2786         # test needs a running copytool
2787         copytool setup
2788         mkdir_on_mdt0 $DIR/$tdir
2789
2790         local f=$DIR/$tdir/$tfile
2791         local fid=$(create_file "$f" 1M 39)
2792
2793         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2794         wait_request_state $fid ARCHIVE SUCCEED
2795         $LFS hsm_release $f
2796
2797         restore_and_check_size $f $fid
2798         local err=$?
2799
2800         [[ $err -eq 0 ]] || error "File size changed during restore"
2801 }
2802 run_test 31c "Restore a large aligned file and check size during restore"
2803
2804 test_33() {
2805         local f=$DIR/$tdir/$tfile
2806
2807         mkdir_on_mdt0 $DIR/$tdir
2808         local fid=$(create_empty_file "$f")
2809
2810         copytool setup
2811
2812         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2813         wait_request_state $fid ARCHIVE SUCCEED
2814         $LFS hsm_release $f
2815
2816         # Prevent restore from completing
2817         copytool_suspend
2818
2819         # Implicit restore
2820         md5sum $f >/dev/null &
2821         local pid=$!
2822
2823         wait_request_state $fid RESTORE STARTED
2824         kill -15 $pid
2825
2826         copytool_continue
2827
2828         # Check restore trigger process was killed
2829         wait $pid
2830         [ $? -eq 143 ] || error "md5sum was not 'Terminated'"
2831 }
2832 run_test 33 "Kill a restore waiting process"
2833
2834 test_34() {
2835         # test needs a running copytool
2836         copytool setup -b 1
2837         mkdir_on_mdt0 $DIR/$tdir
2838
2839         local f=$DIR/$tdir/$tfile
2840         local fid=$(create_empty_file "$f")
2841
2842         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2843         wait_request_state $fid ARCHIVE SUCCEED
2844         $LFS hsm_release $f
2845
2846         # Prevent restore from completing
2847         copytool_suspend
2848
2849         md5sum $f >/dev/null &
2850         local pid=$!
2851
2852         wait_request_state $fid RESTORE STARTED
2853
2854         # rm must not block during restore
2855         timeout --signal=KILL 1 rm "$f" || error "rm $f failed"
2856
2857         copytool_continue
2858         wait_request_state $fid RESTORE SUCCEED
2859
2860         # Check md5sum pgm finished
2861         kill -0 $pid && error "Restore initiatior still running"
2862         wait $pid || error "Restore initiator failed with $?"
2863
2864         # Check the file was actually deleted
2865         [ ! -f "$f" ] || error "$f was not deleted"
2866 }
2867 run_test 34 "Remove file during restore"
2868
2869 test_35() {
2870         # test needs a running copytool
2871         copytool setup -b 1
2872         mkdir_on_mdt0 $DIR/$tdir
2873
2874         local f=$DIR/$tdir/$tfile
2875         local f1=$DIR/$tdir/$tfile-1
2876         local fid=$(create_empty_file "$f")
2877         local fid1=$(copy_file /etc/passwd $f1)
2878
2879         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2880         wait_request_state $fid ARCHIVE SUCCEED
2881         $LFS hsm_release $f
2882
2883         # Prevent restore from completing
2884         copytool_suspend
2885
2886         md5sum $f >/dev/null &
2887         local pid=$!
2888
2889         wait_request_state $fid RESTORE STARTED
2890
2891         # mv must not block during restore
2892         timeout --signal=KILL 2 mv "$f1" "$f" || error "mv $f1 $f failed"
2893
2894         copytool_continue
2895         wait_request_state $fid RESTORE SUCCEED
2896
2897         # Check md5sum pgm finished
2898         kill -0 $pid && error "Restore initiatior still running"
2899         wait $pid || error "Restore initiator failed with $?"
2900
2901         local fid2=$(path2fid $f)
2902         [[ $fid2 == $fid1 ]] || error "Wrong fid after mv $fid2 != $fid1"
2903 }
2904 run_test 35 "Overwrite file during restore"
2905
2906 test_36() {
2907         # test needs a running copytool
2908         copytool setup -b 1
2909         mkdir_on_mdt0 $DIR/$tdir
2910
2911         local f=$DIR/$tdir/$tfile
2912         local fid=$(create_empty_file "$f")
2913
2914         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2915         wait_request_state $fid ARCHIVE SUCCEED
2916         $LFS hsm_release $f
2917
2918         # Prevent restore from completing
2919         copytool_suspend
2920
2921         md5sum $f >/dev/null &
2922         local pid=$!
2923
2924         wait_request_state $fid RESTORE STARTED
2925
2926         # mv must not block during restore
2927         timeout --signal=KILL 10 mv "$f" "$f.new" ||
2928                 error "mv '$f' '$f.new' failed with rc=$?"
2929
2930         copytool_continue
2931         wait_request_state $fid RESTORE SUCCEED
2932
2933         # Check md5sum pgm finished
2934         kill -0 $pid && error "Restore initiator is still running"
2935         wait $pid || error "Restore initiator failed with $?"
2936 }
2937 run_test 36 "Move file during restore"
2938
2939 test_37() {
2940         # LU-5683: check that an archived dirty file can be rearchived.
2941         copytool setup
2942         mkdir_on_mdt0 $DIR/$tdir
2943
2944         local f=$DIR/$tdir/$tfile
2945         local fid
2946
2947         fid=$(create_small_file $f) || error "cannot create small file"
2948
2949         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2950         wait_request_state $fid ARCHIVE SUCCEED
2951         $LFS hsm_release $f || error "cannot release $f"
2952
2953         # Allow previous archive request to expire from the actions log.
2954         wait_for_grace_delay
2955
2956         # Dirty file.
2957         dd if=/dev/urandom of=$f bs=1M count=1 || error "cannot dirty file"
2958
2959         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2960         wait_request_state $fid ARCHIVE SUCCEED
2961 }
2962 run_test 37 "re-archive a dirty file"
2963
2964 multi_archive() {
2965         local prefix=$1
2966         local count=$2
2967         local n=""
2968
2969         for n in $(seq 1 $count); do
2970                 $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $prefix.$n
2971         done
2972         echo "$count archive requests submitted"
2973 }
2974
2975 test_40() {
2976         local stream_count=4
2977         local file_count=100
2978         mkdir -p $DIR/$tdir
2979         local f=$DIR/$tdir/$tfile
2980         local i=""
2981         local p=""
2982         local fid=""
2983         local max_requests=$(get_hsm_param max_requests)
2984
2985         stack_trap "set_hsm_param max_requests $max_requests" EXIT
2986         # Increase the number of HSM request that can be performed in
2987         # parallel. With the coordinator running once per second, this
2988         # also limits the number of requests per seconds that can be
2989         # performed, so we pick a decent number. But we also need to keep
2990         # that number low because the copytool has no rate limit and will
2991         # fail some requests if if gets too many at once.
2992         set_hsm_param max_requests 300
2993
2994         for i in $(seq 1 $file_count); do
2995                 for p in $(seq 1 $stream_count); do
2996                         fid=$(copy_file /etc/hosts $f.$p.$i)
2997                 done
2998         done
2999
3000         copytool setup
3001
3002         # to be sure wait_all_done will not be mislead by previous tests
3003         cdt_purge
3004         wait_for_grace_delay
3005         typeset -a pids
3006         # start archive streams in background (archive files in parallel)
3007         for p in $(seq 1 $stream_count); do
3008                 multi_archive $f.$p $file_count &
3009                 pids[$p]=$!
3010         done
3011         echo -n  "Wait for all requests being enqueued..."
3012         wait ${pids[*]}
3013         echo OK
3014         wait_all_done 100
3015 }
3016 run_test 40 "Parallel archive requests"
3017
3018 hsm_archive_batch() {
3019         local files_num=$1
3020         local batch_max=$2
3021         local filebase=$3
3022         local batch_num=0
3023         local fileset=""
3024         local i=0
3025
3026         while [ $i -lt $files_num ]; do
3027                 if [ $batch_num -eq $batch_max ]; then
3028                         $LFS hsm_archive $fileset || error "HSM archive failed"
3029                         # Reset the batch container.
3030                         fileset=""
3031                         batch_num=0
3032                 fi
3033
3034                 fileset+="${filebase}$i "
3035                 batch_num=$(( batch_num + 1 ))
3036                 i=$(( i + 1 ))
3037         done
3038
3039         if [ $batch_num -ne 0 ]; then
3040                 $LFS hsm_archive $fileset || error "HSM archive failed"
3041                 fileset=""
3042                 batch_num=0
3043         fi
3044 }
3045
3046 test_50() {
3047         local dir=$DIR/$tdir
3048         local batch_max=50
3049
3050         set_hsm_param max_requests 1000000
3051         mkdir $dir || error "mkdir $dir failed"
3052         df -i $MOUNT
3053
3054         local start
3055         local elapsed
3056         local files_num
3057         local filebase
3058
3059         files_num=10000
3060         filebase="$dir/$tfile.start."
3061         createmany -m $filebase $files_num ||
3062                 error "createmany -m $filebase failed: $?"
3063
3064         start=$SECONDS
3065         hsm_archive_batch $files_num $batch_max "$filebase"
3066         elapsed=$((SECONDS - start))
3067         do_facet $SINGLEMDS "$LCTL get_param -n \
3068                  $HSM_PARAM.actions | grep WAITING | wc -l"
3069         unlinkmany $filebase $files_num || error "unlinkmany $filabase failed"
3070         echo "Start Phase files_num: $files_num time: $elapsed"
3071
3072         files_num=20000
3073         filebase="$dir/$tfile.in."
3074         createmany -m $filebase $files_num ||
3075                 error "createmany -m $filebase failed: $?"
3076         start=$SECONDS
3077         hsm_archive_batch  $files_num $batch_max "$filebase"
3078         elapsed=$((SECONDS - start))
3079         unlinkmany $filebase $files_num || error "unlinkmany $filabase failed"
3080         echo "Middle Phase files_num: $files_num time: $elapsed"
3081
3082         files_num=10000
3083         filebase="$dir/$tfile.end."
3084         createmany -m $filebase $files_num ||
3085                 error "createmany -m $filebase failed: $?"
3086
3087         start=$SECONDS
3088         hsm_archive_batch $files_num $batch_max "$filebase"
3089         elapsed=$((SECONDS - start))
3090         do_facet $SINGLEMDS "$LCTL get_param -n \
3091                  $HSM_PARAM.actions | grep WAITING | wc -l"
3092
3093         unlinkmany $filebase $files_num || error "unlinkmany $filebase failed"
3094         echo "End Phase files_num: $files_num time: $elapsed"
3095
3096         do_facet $SINGLEMDS "$LCTL get_param -n \
3097                  $HSM_PARAM.actions | grep WAITING | wc -l"
3098
3099         cdt_purge
3100 }
3101 run_test 50 "Archive with large number of pending HSM actions"
3102
3103 test_52() {
3104         # test needs a running copytool
3105         copytool setup
3106
3107         mkdir_on_mdt0 $DIR/$tdir
3108         local f=$DIR/$tdir/$tfile
3109         local fid=$(create_small_file $f)
3110
3111         $LFS hsm_archive $f || error "could not archive file"
3112         wait_request_state $fid ARCHIVE SUCCEED
3113         check_hsm_flags $f "0x00000009"
3114
3115         multiop_bg_pause $f O_c || error "multiop failed"
3116         local MULTIPID=$!
3117
3118         mds_evict_client
3119         client_up || client_up || true
3120
3121         kill -USR1 $MULTIPID
3122         wait $MULTIPID || error "multiop close failed"
3123
3124         check_hsm_flags $f "0x0000000b"
3125 }
3126 run_test 52 "Opened for write file on an evicted client should be set dirty"
3127
3128 test_53() {
3129         # test needs a running copytool
3130         copytool setup
3131
3132         mkdir_on_mdt0 $DIR/$tdir
3133         local f=$DIR/$tdir/$tfile
3134         local fid=$(create_small_file $f)
3135
3136         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3137                 error "could not archive file"
3138         wait_request_state $fid ARCHIVE SUCCEED
3139         check_hsm_flags $f "0x00000009"
3140
3141         multiop_bg_pause $f o_c || error "multiop failed"
3142         MULTIPID=$!
3143
3144         mds_evict_client
3145         client_up || client_up || true
3146
3147         kill -USR1 $MULTIPID
3148         wait $MULTIPID || error "multiop close failed"
3149
3150         check_hsm_flags $f "0x00000009"
3151 }
3152 run_test 53 "Opened for read file on an evicted client should not be set dirty"
3153
3154 test_54() {
3155         mkdir_on_mdt0 $DIR/$tdir
3156
3157         local f=$DIR/$tdir/$tfile
3158         local fid=$(create_file "$f" 1MB 39)
3159
3160         copytool setup -b 1
3161
3162         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3163                 error "could not archive file"
3164         wait_request_state $fid ARCHIVE STARTED
3165
3166         check_hsm_flags $f "0x00000001"
3167
3168         stack_trap "cdt_clear_no_retry" EXIT
3169         # Avoid coordinator resending this request as soon it has failed.
3170         cdt_set_no_retry
3171
3172         echo "foo" >> $f
3173         sync
3174         wait_request_state $fid ARCHIVE FAILED
3175
3176         check_hsm_flags $f "0x00000003"
3177 }
3178 run_test 54 "Write during an archive cancels it"
3179
3180 test_55() {
3181         mkdir_on_mdt0 $DIR/$tdir
3182
3183         local f=$DIR/$tdir/$tfile
3184         local fid=$(create_file "$f" 1MB 39)
3185
3186         copytool setup -b 1
3187
3188         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3189                 error "could not archive file"
3190         wait_request_state $fid ARCHIVE STARTED
3191
3192         check_hsm_flags $f "0x00000001"
3193
3194         stack_trap "cdt_clear_no_retry" EXIT
3195         # Avoid coordinator resending this request as soon it has failed.
3196         cdt_set_no_retry
3197
3198         $TRUNCATE $f 1024 || error "truncate failed"
3199         sync
3200         wait_request_state $fid ARCHIVE FAILED
3201
3202         check_hsm_flags $f "0x00000003"
3203 }
3204 run_test 55 "Truncate during an archive cancels it"
3205
3206 test_56() {
3207         mkdir_on_mdt0 $DIR/$tdir
3208
3209         local f=$DIR/$tdir/$tfile
3210         local fid=$(create_file "$f" 1MB 39)
3211
3212         copytool setup -b 1
3213
3214         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3215                 error "could not archive file"
3216         wait_request_state $fid ARCHIVE STARTED
3217
3218         check_hsm_flags $f "0x00000001"
3219
3220         # Change metadata and sync to be sure we are not changing only
3221         # in memory.
3222         chmod 644 $f
3223         chgrp sys $f
3224         sync
3225         wait_request_state $fid ARCHIVE SUCCEED
3226
3227         check_hsm_flags $f "0x00000009"
3228 }
3229 run_test 56 "Setattr during an archive is ok"
3230
3231 test_57() {
3232         # Need one client for I/O, one for request
3233         needclients 2 || return 0
3234
3235         # test needs a running copytool
3236         copytool setup
3237
3238         mkdir_on_mdt0 $DIR/$tdir
3239         local f=$DIR/$tdir/test_archive_remote
3240         # Create a file on a remote node
3241         do_node $CLIENT2 "dd if=/dev/urandom of=$f bs=1M "\
3242                 "count=2 conv=fsync"
3243
3244         # And archive it
3245         do_node $CLIENT2 "$LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $f" ||
3246                 error "hsm_archive failed"
3247         local fid=$(path2fid $f)
3248         wait_request_state $fid ARCHIVE SUCCEED
3249
3250         # Release and implicit restore it
3251         do_node $CLIENT2 "$LFS hsm_release $f" ||
3252                 error "hsm_release failed"
3253         do_node $CLIENT2 "md5sum $f" ||
3254                 error "hsm_restore failed"
3255
3256         wait_request_state $fid RESTORE SUCCEED
3257 }
3258 run_test 57 "Archive a file with dirty cache on another node"
3259
3260 truncate_released_file() {
3261         local src_file=$1
3262         local trunc_to=$2
3263
3264         local sz=$(stat -c %s $src_file)
3265         local f=$DIR/$tdir/$tfile
3266         local fid=$(copy_file $1 $f)
3267         local ref=$f-ref
3268         cp $f $f-ref
3269
3270         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3271                 error "could not archive file"
3272         wait_request_state $fid ARCHIVE SUCCEED
3273
3274         $LFS hsm_release $f || error "could not release file"
3275
3276         $TRUNCATE $f $trunc_to || error "truncate failed"
3277         sync
3278
3279         local sz1=$(stat -c %s $f)
3280         [[ $sz1 == $trunc_to ]] ||
3281                 error "size after trunc: $sz1 expect $trunc_to, original $sz"
3282
3283         $LFS hsm_state $f
3284         check_hsm_flags $f "0x0000000b"
3285
3286         local state=$(get_request_state $fid RESTORE)
3287         [[ "$state" == "SUCCEED" ]] ||
3288                 error "truncate $sz does not trig restore, state = $state"
3289
3290         $TRUNCATE $ref $trunc_to
3291         cmp $ref $f || error "file data wrong after truncate"
3292
3293         rm -f $f $f-ref
3294 }
3295
3296 test_58() {
3297         # test needs a running copytool
3298         copytool setup
3299
3300         mkdir_on_mdt0 $DIR/$tdir
3301
3302         local sz=$(stat -c %s /etc/passwd)
3303
3304         echo "truncate up from $sz to $((sz*2))"
3305         truncate_released_file /etc/passwd $((sz*2))
3306
3307         echo "truncate down from $sz to $((sz/2))"
3308         truncate_released_file /etc/passwd $((sz/2))
3309
3310         echo "truncate to 0"
3311         truncate_released_file /etc/passwd 0
3312 }
3313 run_test 58 "Truncate a released file will trigger restore"
3314
3315 test_59() {
3316         local fid
3317         [[ $MDS1_VERSION -lt $(version_code 2.7.63) ]] &&
3318                 skip "Need MDS version at least 2.7.63"
3319
3320         copytool setup
3321         $MCREATE $DIR/$tfile || error "mcreate failed"
3322         $TRUNCATE $DIR/$tfile 42 || error "truncate failed"
3323         $LFS hsm_archive $DIR/$tfile || error "archive request failed"
3324         fid=$(path2fid $DIR/$tfile)
3325         wait_request_state $fid ARCHIVE SUCCEED
3326         $LFS hsm_release $DIR/$tfile || error "release failed"
3327 }
3328 run_test 59 "Release stripeless file with non-zero size"
3329
3330 test_60() {
3331         # This test validates the fix for LU-4512. Ensure that the -u
3332         # option changes the progress reporting interval from the
3333         # default (30 seconds) to the user-specified interval.
3334         mkdir_on_mdt0 $DIR/$tdir
3335
3336         local f=$DIR/$tdir/$tfile
3337         local fid=$(create_file "$f" 1M 10)
3338
3339         local interval=5
3340         local progress_timeout=$((interval * 4))
3341         copytool setup -b 1 --update-interval $interval
3342
3343         local mdtidx=0
3344         local mdt=${MDT_PREFIX}${mdtidx}
3345         local mds=mds$((mdtidx + 1))
3346
3347         # Wait for copytool to register
3348         wait_update_facet $mds \
3349                 "$LCTL get_param -n ${mdt}.hsm.agents | grep -o ^uuid" \
3350                 uuid 100 || error "coyptool failed to register with $mdt"
3351
3352         local start_at=$(date +%s)
3353         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3354                 error "could not archive file"
3355
3356         local agent=$(facet_active_host $SINGLEAGT)
3357         local logfile=$(copytool_logfile $SINGLEAGT)
3358
3359         wait_update $agent \
3360             "grep -o start.copy \"$logfile\"" "start copy" 100 ||
3361                 error "copytool failed to start"
3362
3363         local cmd="$LCTL get_param -n ${mdt}.hsm.active_requests"
3364         cmd+=" | awk '/'$fid'.*action=ARCHIVE/ {print \\\$12}' | cut -f2 -d="
3365
3366         local RESULT
3367         local WAIT=0
3368         local sleep=1
3369
3370         echo -n "Expecting a progress update within $progress_timeout seconds... "
3371         while true; do
3372                 RESULT=$(do_node $(facet_active_host $mds) "$cmd")
3373                 if [ -n "$RESULT" ] && [ "$RESULT" -gt 0 ]; then
3374                         echo "$RESULT bytes copied in $WAIT seconds."
3375                         break
3376                 elif [ $WAIT -ge $progress_timeout ]; then
3377                         error "Timed out waiting for progress update!"
3378                         break
3379                 fi
3380                 WAIT=$((WAIT + sleep))
3381                 sleep $sleep
3382         done
3383
3384         local finish_at=$(date +%s)
3385         local elapsed=$((finish_at - start_at))
3386
3387         # Ensure that the progress update occurred within the expected window.
3388         if [ $elapsed -lt $((interval - 1)) ]; then
3389                 error "Expected progress update after at least $interval seconds"
3390         fi
3391
3392         echo "Wait for on going archive hsm action to complete"
3393         wait_update $agent "grep -o copied \"$logfile\"" "copied" 10 ||
3394                 echo "File archiving not completed even after 10 secs"
3395 }
3396 run_test 60 "Changing progress update interval from default"
3397
3398 test_61() {
3399         # test needs a running copytool
3400         copytool setup
3401
3402         mkdir_on_mdt0 $DIR/$tdir
3403         local f=$DIR/$tdir/$tfile
3404         local fid=$(copy_file /etc/passwd $f)
3405         cdt_disable
3406         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3407         rm -f $f
3408         cdt_enable
3409         wait_request_state $fid ARCHIVE FAILED
3410 }
3411 run_test 61 "Waiting archive of a removed file should fail"
3412
3413 test_70() {
3414         # test needs a new running copytool
3415         stack_trap copytool_monitor_cleanup EXIT
3416         copytool_monitor_setup
3417         copytool setup --event-fifo "$HSMTOOL_MONITOR_DIR/fifo"
3418
3419         # Wait for the copytool to register.
3420         wait_update --verbose $(facet_active_host mds1) \
3421                 "$LCTL get_param -n ${MDT_PREFIX}0.hsm.agents | grep -o ^uuid" \
3422                 uuid 100 ||
3423                 error "copytool failed to register with MDT0000"
3424
3425         kill_copytools
3426         wait_copytools || error "Copytools failed to stop"
3427
3428         local REGISTER_EVENT
3429         local UNREGISTER_EVENT
3430         while read event; do
3431                 local parsed=$(parse_json_event "$event")
3432                 if [ -z "$parsed" ]; then
3433                         error "Copytool sent malformed event: $event"
3434                 fi
3435                 eval $parsed
3436
3437                 if [ $event_type == "REGISTER" ]; then
3438                         REGISTER_EVENT=$event
3439                 elif [ $event_type == "UNREGISTER" ]; then
3440                         UNREGISTER_EVENT=$event
3441                 fi
3442         done < <(echo $"$(get_copytool_event_log)")
3443
3444         if [ -z "$REGISTER_EVENT" ]; then
3445                 error "Copytool failed to send register event to FIFO"
3446         fi
3447
3448         if [ -z "$UNREGISTER_EVENT" ]; then
3449                 error "Copytool failed to send unregister event to FIFO"
3450         fi
3451
3452         echo "Register/Unregister events look OK."
3453 }
3454 run_test 70 "Copytool logs JSON register/unregister events to FIFO"
3455
3456 test_71() {
3457         # Bump progress interval for livelier events.
3458         local interval=5
3459
3460         # test needs a new running copytool
3461         stack_trap copytool_monitor_cleanup EXIT
3462         copytool_monitor_setup
3463         copytool setup --update-interval $interval --event-fifo \
3464                 "$HSMTOOL_MONITOR_DIR/fifo"
3465
3466         stack_trap "cdt_clear_no_retry" EXIT
3467         # Just start and stop the copytool to generate events.
3468         cdt_clear_no_retry
3469
3470         mkdir_on_mdt0 $DIR/$tdir
3471
3472         local f=$DIR/$tdir/$tfile
3473         local fid=$(create_small_file "$f")
3474
3475         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3476                 error "could not archive file"
3477         wait_request_state $fid ARCHIVE SUCCEED
3478
3479         local expected_fields="event_time data_fid source_fid"
3480         expected_fields+=" total_bytes current_bytes"
3481
3482         local -A events=(
3483                 [ARCHIVE_START]=false
3484                 [ARCHIVE_FINISH]=false
3485                 [ARCHIVE_RUNNING]=false
3486                 )
3487         while read event; do
3488                 # Make sure we're not getting anything from previous events.
3489                 for field in $expected_fields; do
3490                         unset $field
3491                 done
3492
3493                 local parsed=$(parse_json_event "$event")
3494                 if [ -z "$parsed" ]; then
3495                         error "Copytool sent malformed event: $event"
3496                 fi
3497                 eval $parsed
3498
3499                 events["$event_type"]=true
3500
3501                 [ "$event_type" != ARCHIVE_RUNNING ] && continue
3502
3503                 # Do some simple checking of the progress update events.
3504                 for expected_field in $expected_fields; do
3505                         if [ -z ${!expected_field+x} ]; then
3506                                 error "Missing $expected_field field in event"
3507                         fi
3508                 done
3509
3510                 [ $total_bytes -gt 0 ] || error "Expected total_bytes to be > 0"
3511
3512                 # These should be identical throughout an archive operation
3513                 [ $source_fid == $data_fid ] ||
3514                         error "Expected source_fid to equal data_fid"
3515         done < <(echo $"$(get_copytool_event_log)")
3516
3517         # Check we received every type of events we were expecting
3518         for event in "${!events[@]}"; do
3519                 ${events["$event"]} ||
3520                         error "Copytool failed to send '$event' event to FIFO"
3521         done
3522
3523         echo "Archive events look OK."
3524 }
3525 run_test 71 "Copytool logs JSON archive events to FIFO"
3526
3527 test_72() {
3528         # Bump progress interval for livelier events.
3529         local interval=5
3530
3531         # test needs a new running copytool
3532         stack_trap copytool_monitor_cleanup EXIT
3533         copytool_monitor_setup
3534         copytool setup --update-interval $interval --event-fifo \
3535                 "$HSMTOOL_MONITOR_DIR/fifo"
3536         local test_file=$HSMTOOL_MONITOR_DIR/file
3537
3538         local cmd="dd if=/dev/urandom of=$test_file count=16 bs=1000000 "
3539         cmd+="conv=fsync"
3540         do_facet $SINGLEAGT "$cmd" ||
3541                 error "cannot create $test_file on $SINGLEAGT"
3542         copy2archive $test_file $tdir/$tfile
3543
3544         mkdir_on_mdt0 $DIR/$tdir
3545         local f=$DIR/$tdir/$tfile
3546         copytool import $tdir/$tfile $f
3547         f=$DIR2/$tdir/$tfile
3548         echo "Verifying released state: "
3549         check_hsm_flags $f "0x0000000d"
3550
3551         local fid=$(path2fid $f)
3552         $LFS hsm_restore $f
3553         wait_request_state $fid RESTORE SUCCEED
3554
3555         local expected_fields="event_time data_fid source_fid"
3556         expected_fields+=" total_bytes current_bytes"
3557
3558         local START_EVENT
3559         local FINISH_EVENT
3560         while read event; do
3561                 # Make sure we're not getting anything from previous events.
3562                 for field in $expected_fields; do
3563                         unset $field
3564                 done
3565
3566                 local parsed=$(parse_json_event "$event")
3567                 if [ -z "$parsed" ]; then
3568                         error "Copytool sent malformed event: $event"
3569                 fi
3570                 eval $parsed
3571
3572                 if [ $event_type == "RESTORE_START" ]; then
3573                         START_EVENT=$event
3574                         if [ $source_fid != $data_fid ]; then
3575                                 error "source_fid should == data_fid at start"
3576                         fi
3577                         continue
3578                 elif [ $event_type == "RESTORE_FINISH" ]; then
3579                         FINISH_EVENT=$event
3580                         if [ $source_fid != $data_fid ]; then
3581                                 error "source_fid should == data_fid at finish"
3582                         fi
3583                         continue
3584                 elif [ $event_type != "RESTORE_RUNNING" ]; then
3585                         continue
3586                 fi
3587
3588                 # Do some simple checking of the progress update events.
3589                 for expected_field in $expected_fields; do
3590                         if [ -z ${!expected_field+x} ]; then
3591                                 error "Missing $expected_field field in event"
3592                         fi
3593                 done
3594
3595                 if [ $total_bytes -eq 0 ]; then
3596                         error "Expected total_bytes to be > 0"
3597                 fi
3598
3599                 # When a restore starts out, the data fid is the same as the
3600                 # source fid. After the restore has gotten going, we learn
3601                 # the new data fid. Once the restore has finished, the source
3602                 # fid is set to the new data fid.
3603                 #
3604                 # We test this because some monitoring software may depend on
3605                 # this behavior. If it changes, then the consumers of these
3606                 # events may need to be modified.
3607                 if [ $source_fid == $data_fid ]; then
3608                         error "source_fid should != data_fid during restore"
3609                 fi
3610         done < <(echo $"$(get_copytool_event_log)")
3611
3612         if [ -z "$START_EVENT" ]; then
3613                 error "Copytool failed to send restore start event to FIFO"
3614         fi
3615
3616         if [ -z "$FINISH_EVENT" ]; then
3617                 error "Copytool failed to send restore finish event to FIFO"
3618         fi
3619
3620         echo "Restore events look OK."
3621 }
3622 run_test 72 "Copytool logs JSON restore events to FIFO"
3623
3624 test_90() {
3625         file_count=51 # Max number of files constrained by LNET message size
3626         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
3627         local f=$DIR/$tdir/$tfile
3628         local FILELIST=/tmp/filelist.txt
3629         local i=""
3630
3631         rm -f $FILELIST
3632         for i in $(seq 1 $file_count); do
3633                 fid=$(copy_file /etc/hosts $f.$i)
3634                 echo $f.$i >> $FILELIST
3635         done
3636
3637         copytool setup
3638         # to be sure wait_all_done will not be mislead by previous tests
3639         cdt_purge
3640         wait_for_grace_delay
3641         $LFS hsm_archive --filelist $FILELIST ||
3642                 error "cannot archive a file list"
3643         wait_all_done 200
3644         $LFS hsm_release --filelist $FILELIST ||
3645                 error "cannot release a file list"
3646         $LFS hsm_restore --filelist $FILELIST ||
3647                 error "cannot restore a file list"
3648         wait_all_done 200
3649 }
3650 run_test 90 "Archive/restore a file list"
3651
3652 double_verify_reset_hsm_param() {
3653         local p=$1
3654         echo "Testing $HSM_PARAM.$p"
3655         local val=$(get_hsm_param $p)
3656         local save=$val
3657         local val2=$(($val * 2))
3658         set_hsm_param $p $val2
3659         val=$(get_hsm_param $p)
3660         [[ $val == $val2 ]] ||
3661                 error "$HSM_PARAM.$p: $val != $val2 should be (2 * $save)"
3662         echo "Set $p to 0 must failed"
3663         set_hsm_param $p 0
3664         local rc=$?
3665         # restore value
3666         set_hsm_param $p $save
3667
3668         if [[ $rc == 0 ]]; then
3669                 error "we must not be able to set $HSM_PARAM.$p to 0"
3670         fi
3671 }
3672
3673 test_100() {
3674         double_verify_reset_hsm_param loop_period
3675         double_verify_reset_hsm_param grace_delay
3676         double_verify_reset_hsm_param active_request_timeout
3677         double_verify_reset_hsm_param max_requests
3678         double_verify_reset_hsm_param default_archive_id
3679 }
3680 run_test 100 "Set coordinator /proc tunables"
3681
3682 test_102() {
3683         cdt_disable
3684         cdt_enable
3685         cdt_restart
3686 }
3687 run_test 102 "Verify coordinator control"
3688
3689 test_103() {
3690         # test needs a running copytool
3691         copytool setup
3692
3693         local i=""
3694         local fid=""
3695
3696         mkdir -p $DIR/$tdir
3697         for i in $(seq 1 20); do
3698                 fid=$(copy_file /etc/passwd $DIR/$tdir/$i)
3699         done
3700         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/*
3701
3702         cdt_purge
3703
3704         echo "Current requests"
3705         local res=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3706                         $HSM_PARAM.actions |\
3707                         grep -v CANCELED | grep -v SUCCEED | grep -v FAILED")
3708
3709         [[ -z "$res" ]] || error "Some request have not been canceled"
3710 }
3711 run_test 103 "Purge all requests"
3712
3713 test_103a() {
3714         (( MDS1_VERSION >= $(version_code 2.14.56) )) ||
3715                 skip "Need MDS version at least 2.14.56"
3716
3717         cdt_clear_non_blocking_restore
3718
3719         # test needs a running copytool
3720         copytool setup
3721
3722         local -a fids=()
3723         local i
3724         local rpcs_inflight=$($LCTL get_param -n \
3725                 "mdc.$(facet_svc mds1)*.max_rpcs_in_flight" |
3726                 head -n1)
3727
3728         mkdir_on_mdt0 $DIR/$tdir
3729         for ((i=0; i < rpcs_inflight; i++)); do
3730                 fids+=( $(copy_file /etc/passwd $DIR/$tdir/${tfile}_$i) )
3731         done
3732         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/*
3733
3734         local time=0
3735         local cnt=0
3736         local grep_regex="($(tr ' ' '|' <<< "${fids[*]}")).*action=ARCHIVE.*status=SUCCEED"
3737         echo $grep_regex
3738         while [[ $time -lt 5 ]] && [[ $cnt -ne ${#fids[@]} ]]; do
3739                 cnt=$(do_facet mds1 "$LCTL get_param -n $HSM_PARAM.actions |
3740                         grep -c -E '$grep_regex'")
3741                 sleep 1
3742                 ((++time))
3743         done
3744         [[ $cnt -eq ${#fids[@]} ]] || error "Fail to archive files $cnt/${#fids[@]}"
3745
3746         $LFS hsm_release $DIR/$tdir/*
3747
3748         kill_copytools
3749         wait_copytools || error "Copytool failed to stop"
3750
3751         local -a pids=()
3752         for i in "${fids[@]}"; do
3753                 cat $DIR/.lustre/fid/$i > /dev/null & pids+=($!)
3754         done
3755
3756         cdt_purge
3757         grep_regex="($(tr ' ' '|' <<< "${fids[*]}")).*action=RESTORE.*status=CANCELED"
3758         cnt=$(do_facet mds1 "$LCTL get_param -n $HSM_PARAM.actions |
3759                 grep -cE '$grep_regex'")
3760
3761         [[ "$cnt" -eq ${#fids[@]} ]] ||
3762                 error "Some request have not been canceled ($cnt/${#fids[@]} canceled)"
3763
3764         # cat cmds should not hang and should fail
3765         for i in "${!pids[@]}"; do
3766                 wait ${pids[$i]} &&
3767                         error "Restore for ${tfile}_$i (${pids[$i]}) should fail" ||
3768                         true
3769         done
3770 }
3771 run_test 103a "Purge pending restore requests"
3772
3773 DATA=CEA
3774 DATAHEX='[434541]'
3775 test_104() {
3776         mkdir_on_mdt0 $DIR/$tdir
3777
3778         local f=$DIR/$tdir/$tfile
3779         local fid=$(create_empty_file "$f")
3780
3781         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER --data $DATA $f
3782         local data1=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3783                         $HSM_PARAM.actions |\
3784                         grep $fid | cut -f16 -d=")
3785
3786         [[ "$data1" == "$DATAHEX" ]] ||
3787                 error "Data field in records is ($data1) and not ($DATAHEX)"
3788
3789         cdt_purge
3790 }
3791 run_test 104 "Copy tool data field"
3792
3793 test_105() {
3794         local max_requests=$(get_hsm_param max_requests)
3795         mkdir_on_mdt0 $DIR/$tdir
3796         local i=""
3797
3798         stack_trap "set_hsm_param max_requests $max_requests" EXIT
3799         set_hsm_param max_requests 300
3800
3801         cdt_disable
3802         for i in $(seq -w 1 10); do
3803                 cp /etc/passwd $DIR/$tdir/$i
3804                 $LFS hsm_archive $DIR/$tdir/$i
3805         done
3806         local reqcnt1=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3807                         $HSM_PARAM.actions |\
3808                         grep WAITING | wc -l")
3809         cdt_restart
3810
3811         cdt_disable
3812         local reqcnt2=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3813                         $HSM_PARAM.actions |\
3814                         grep WAITING | wc -l")
3815         cdt_enable
3816         cdt_purge
3817         [[ "$reqcnt1" == "$reqcnt2" ]] ||
3818                 error "Requests count after shutdown $reqcnt2 != "\
3819                       "before shutdown $reqcnt1"
3820 }
3821 run_test 105 "Restart of coordinator"
3822
3823 test_106() {
3824         # test needs a running copytool
3825         copytool setup
3826
3827         local uuid=$(get_agent_uuid $(facet_active_host $SINGLEAGT))
3828
3829         check_agent_registered $uuid
3830
3831         search_copytools || error "No copytool found"
3832
3833         kill_copytools
3834         wait_copytools || error "Copytool failed to stop"
3835
3836         check_agent_unregistered $uuid
3837
3838         copytool setup
3839         uuid=$(get_agent_uuid $(facet_active_host $SINGLEAGT))
3840         check_agent_registered $uuid
3841 }
3842 run_test 106 "Copytool register/unregister"
3843
3844 test_107() {
3845         [ "$CLIENTONLY" ] && skip "CLIENTONLY mode" && return
3846
3847         # test needs a running copytool
3848         copytool setup
3849         # create and archive file
3850         mkdir_on_mdt0 $DIR/$tdir
3851         local f1=$DIR/$tdir/$tfile
3852         local fid=$(copy_file /etc/passwd $f1)
3853         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1
3854         wait_request_state $fid ARCHIVE SUCCEED
3855         # shutdown and restart MDS
3856         fail $SINGLEMDS
3857         # check the copytool still gets messages from MDT
3858         local f2=$DIR/$tdir/2
3859         local fid=$(copy_file /etc/passwd $f2)
3860         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f2
3861         # main check of this sanity: this request MUST succeed
3862         wait_request_state $fid ARCHIVE SUCCEED
3863 }
3864 run_test 107 "Copytool re-register after MDS restart"
3865
3866 policy_set_and_test()
3867 {
3868         local change="$1"
3869         local target="$2"
3870         do_facet $SINGLEMDS $LCTL set_param "$HSM_PARAM.policy=\\\"$change\\\""
3871         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
3872         [[ "$policy" == "$target" ]] ||
3873                 error "Wrong policy after '$change': '$policy' != '$target'"
3874 }
3875
3876 test_109() {
3877         # to force default policy setting if error
3878         CDT_POLICY_HAD_CHANGED=true
3879
3880         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
3881         local default="NonBlockingRestore [NoRetryAction]"
3882         [[ "$policy" == "$default" ]] ||
3883                 error "default policy has changed,"\
3884                       " '$policy' != '$default' update the test"
3885         policy_set_and_test "+NBR" "[NonBlockingRestore] [NoRetryAction]"
3886         policy_set_and_test "+NRA" "[NonBlockingRestore] [NoRetryAction]"
3887         policy_set_and_test "-NBR" "NonBlockingRestore [NoRetryAction]"
3888         policy_set_and_test "-NRA" "NonBlockingRestore NoRetryAction"
3889         policy_set_and_test "NRA NBR" "[NonBlockingRestore] [NoRetryAction]"
3890         # useless bacause we know but safer for futur changes to use real value
3891         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
3892         echo "Next set_param must failed"
3893         policy_set_and_test "wrong" "$policy"
3894
3895         # return to default
3896         echo "Back to default policy"
3897         cdt_set_sanity_policy
3898 }
3899 run_test 109 "Policy display/change"
3900
3901 test_110a() {
3902         # test needs a running copytool
3903         copytool setup
3904
3905         mkdir_on_mdt0 $DIR/$tdir
3906
3907         copy2archive /etc/passwd $tdir/$tfile
3908
3909         local f=$DIR/$tdir/$tfile
3910         copytool import $tdir/$tfile $f
3911         local fid=$(path2fid $f)
3912
3913         cdt_set_non_blocking_restore
3914         md5sum $f
3915         local st=$?
3916
3917         # cleanup
3918         wait_request_state $fid RESTORE SUCCEED
3919         cdt_clear_non_blocking_restore
3920
3921         # Test result
3922         [[ $st == 1 ]] ||
3923                 error "md5sum returns $st != 1, "\
3924                         "should also perror ENODATA (No data available)"
3925 }
3926 run_test 110a "Non blocking restore policy (import case)"
3927
3928 test_110b() {
3929         # test needs a running copytool
3930         copytool setup
3931
3932         mkdir_on_mdt0 $DIR/$tdir
3933         local f=$DIR/$tdir/$tfile
3934         local fid=$(copy_file /etc/passwd $f)
3935         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3936         wait_request_state $fid ARCHIVE SUCCEED
3937         $LFS hsm_release $f
3938
3939         cdt_set_non_blocking_restore
3940         md5sum $f
3941         local st=$?
3942
3943         # cleanup
3944         wait_request_state $fid RESTORE SUCCEED
3945         cdt_clear_non_blocking_restore
3946
3947         # Test result
3948         [[ $st == 1 ]] ||
3949                 error "md5sum returns $st != 1, "\
3950                         "should also perror ENODATA (No data available)"
3951 }
3952 run_test 110b "Non blocking restore policy (release case)"
3953
3954 test_111a() {
3955         # test needs a running copytool
3956         copytool setup
3957
3958         mkdir_on_mdt0 $DIR/$tdir
3959         copy2archive /etc/passwd $tdir/$tfile
3960
3961         local f=$DIR/$tdir/$tfile
3962
3963         copytool import $tdir/$tfile $f
3964         local fid=$(path2fid $f)
3965
3966         cdt_set_no_retry
3967
3968         copytool_remove_backend $fid
3969
3970         $LFS hsm_restore $f
3971         wait_request_state $fid RESTORE FAILED
3972         local st=$?
3973
3974         # cleanup
3975         cdt_clear_no_retry
3976
3977         # Test result
3978         [[ $st == 0 ]] || error "Restore does not failed"
3979 }
3980 run_test 111a "No retry policy (import case), restore will error"\
3981               " (No such file or directory)"
3982
3983 test_111b() {
3984         # test needs a running copytool
3985         copytool setup
3986
3987         mkdir_on_mdt0 $DIR/$tdir
3988         local f=$DIR/$tdir/$tfile
3989         local fid=$(copy_file /etc/passwd $f)
3990         stack_trap cdt_clear_no_retry EXIT
3991         cdt_set_no_retry
3992         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3993         wait_request_state $fid ARCHIVE SUCCEED
3994         $LFS hsm_release $f
3995
3996         copytool_remove_backend $fid
3997
3998         $LFS hsm_restore $f
3999         wait_request_state $fid RESTORE FAILED
4000         local st=$?
4001
4002         # Test result
4003         [[ $st == 0 ]] || error "Restore does not failed"
4004 }
4005 run_test 111b "No retry policy (release case), restore will error"\
4006               " (No such file or directory)"
4007
4008 test_112() {
4009         # test needs a running copytool
4010         copytool setup
4011
4012         mkdir_on_mdt0 $DIR/$tdir
4013         local f=$DIR/$tdir/$tfile
4014         local fid=$(copy_file /etc/passwd $f)
4015         cdt_disable
4016         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4017         local l=$($LFS hsm_action $f)
4018         echo $l
4019         local res=$(echo $l | cut -f 2- -d" " | grep ARCHIVE)
4020
4021         cdt_enable
4022         wait_request_state $fid ARCHIVE SUCCEED
4023
4024         # Test result
4025         [[ ! -z "$res" ]] || error "action is $l which is not an ARCHIVE"
4026 }
4027 run_test 112 "State of recorded request"
4028
4029 test_113() {
4030         mkdir_on_mdt0 $DIR/$tdir
4031
4032         local file1=$DIR/$tdir/$tfile
4033         local file2=$DIR2/$tdir/$tfile
4034
4035         local fid=$(create_small_sync_file $file1)
4036
4037         stack_trap "zconf_umount \"$(facet_host $SINGLEAGT)\" \"$MOUNT3\"" EXIT
4038         zconf_mount "$(facet_host $SINGLEAGT)" "$MOUNT3" ||
4039                 error "cannot mount '$MOUNT3' on '$SINGLEAGT'"
4040
4041         copytool setup -m  "$MOUNT3"
4042
4043         do_nodes $(comma_list $(nodes_list)) $LCTL clear
4044
4045         $LFS hsm_archive $file1 || error "Fail to archive $file1"
4046         wait_request_state $fid ARCHIVE SUCCEED
4047
4048         $LFS hsm_release $file1
4049         echo "Verifying released state: "
4050         check_hsm_flags $file1 "0x0000000d"
4051
4052         multiop_bg_pause $file1 oO_WRONLY:O_APPEND:_w4c || error "multiop failed"
4053         MULTIPID=$!
4054         stat $file2 &
4055         kill -USR1 $MULTIPID
4056
4057         wait
4058         sync
4059
4060         local size1=$(stat -c "%s" $file1)
4061         local size2=$(stat -c "%s" $file2)
4062
4063         [ $size1 -eq $size2 ] || error "sizes are different $size1 $size2"
4064 }
4065 run_test 113 "wrong stat after restore"
4066
4067 test_114() {
4068         (( MDS1_VERSION >= $(version_code 2.15.54) )) ||
4069                 skip "need MDS version at least 2.15.54"
4070
4071         mkdir_on_mdt0 $DIR/$tdir
4072
4073         local f1=$DIR/$tdir/${tfile}1
4074         local f2=$DIR/$tdir/${tfile}2
4075         local fid1=$(create_empty_file "$f1")
4076         local fid2=$(create_empty_file "$f2")
4077
4078         copytool setup
4079
4080         # Prevent archive from completing
4081         cdt_disable
4082
4083         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1 $f2
4084         # wait archive to register at CDT
4085         wait_request_state "$fid1" ARCHIVE WAITING
4086
4087         # Set f2 in an incompatible state
4088         $LFS hsm_set --noarchive $f2
4089
4090         cdt_enable
4091
4092         wait_request_state "$fid1" ARCHIVE SUCCEED
4093         wait_request_state "$fid2" ARCHIVE FAILED
4094 }
4095 run_test 114 "Incompatible request does not set other requests as STARTED"
4096
4097 test_200() {
4098         mkdir_on_mdt0 $DIR/$tdir
4099
4100         local f=$DIR/$tdir/$tfile
4101         local fid=$(create_empty_file "$f")
4102
4103         copytool setup
4104
4105         # Prevent archive from completing
4106         copytool_suspend
4107
4108         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4109         # wait archive to register at CDT
4110         wait_request_state $fid ARCHIVE STARTED
4111
4112         # Cancel the archive
4113         $LFS hsm_cancel "$f"
4114
4115         wait_request_state $fid ARCHIVE CANCELED
4116
4117         copytool_continue
4118         wait_request_state $fid CANCEL SUCCEED
4119 }
4120 run_test 200 "Register/Cancel archive"
4121
4122 test_201() {
4123         # test needs a running copytool
4124         copytool setup
4125         mkdir_on_mdt0 $DIR/$tdir
4126
4127         local f=$DIR/$tdir/$tfile
4128         create_archive_file $tdir/$tfile
4129         copytool import $tdir/$tfile $f
4130         local fid=$(path2fid $f)
4131
4132         # test with cdt on is made in test_222
4133         cdt_disable
4134         $LFS hsm_restore $f
4135         # wait restore to register at CDT
4136         wait_request_state $fid RESTORE WAITING
4137         $LFS hsm_cancel $f
4138         cdt_enable
4139         wait_request_state $fid RESTORE CANCELED
4140         wait_request_state $fid CANCEL SUCCEED
4141 }
4142 run_test 201 "Register/Cancel restore"
4143
4144 test_202() {
4145         mkdir_on_mdt0 $DIR/$tdir
4146
4147         local f=$DIR/$tdir/$tfile
4148         local fid=$(create_empty_file "$f")
4149
4150         # test needs a running copytool
4151         copytool setup
4152
4153         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4154         wait_request_state $fid ARCHIVE SUCCEED
4155
4156         copytool_suspend
4157         $LFS hsm_remove $f
4158         # wait remove to register at CDT
4159         wait_request_state $fid REMOVE STARTED
4160         $LFS hsm_cancel $f
4161
4162         wait_request_state $fid REMOVE CANCELED
4163 }
4164 run_test 202 "Register/Cancel remove"
4165
4166 test_220A() { # was test_220
4167         # test needs a running copytool
4168         copytool setup
4169
4170         mkdir_on_mdt0 $DIR/$tdir
4171
4172         local f=$DIR/$tdir/$tfile
4173         local fid=$(copy_file /etc/passwd $f)
4174
4175         changelog_register
4176
4177         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4178         wait_request_state $fid ARCHIVE SUCCEED
4179
4180         changelog_find -type HSM -target-fid $fid -flags 0x0 ||
4181                 error "The expected changelog was not emitted"
4182 }
4183 run_test 220A "Changelog for archive"
4184
4185 test_220a() {
4186         # test needs a running copytool
4187         copytool setup
4188
4189         mkdir_on_mdt0 $DIR/$tdir
4190
4191         local f=$DIR/$tdir/$tfile
4192         local fid=$(copy_file /etc/passwd $f)
4193
4194         changelog_register
4195
4196         # block copytool operations to allow for HSM request to be
4197         # submitted and file be unlinked (CDT will find object removed)
4198         copytool_suspend
4199
4200         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4201
4202         # wait request to reach CT
4203         wait_request_state $fid ARCHIVE STARTED
4204
4205         rm -f $f
4206
4207         copytool_continue
4208
4209         wait_request_state $fid ARCHIVE FAILED
4210
4211         # HE_ARCHIVE|ENOENT
4212         changelog_find -type HSM -target-fid $fid -flags 0x2 ||
4213                 error "The expected changelog was not emitted"
4214 }
4215 run_test 220a "Changelog for failed archive"
4216
4217 test_221() {
4218         mkdir_on_mdt0 $DIR/$tdir
4219
4220         local f=$DIR/$tdir/$tfile
4221         local fid=$(create_empty_file "$f")
4222
4223         copytool setup -b 1
4224         changelog_register
4225
4226         # Prevent archive from completing
4227         copytool_suspend
4228         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4229         wait_request_state $fid ARCHIVE STARTED
4230
4231         $LFS hsm_cancel $f
4232         wait_request_state $fid ARCHIVE CANCELED
4233
4234         copytool_continue
4235         wait_request_state $fid CANCEL SUCCEED
4236
4237         changelog_find -type HSM -target-fid $fid -flags 0x7d ||
4238                 error "The expected changelog was not emitted"
4239 }
4240 run_test 221 "Changelog for archive canceled"
4241
4242 test_222a() {
4243         # test needs a running copytool
4244         copytool setup
4245
4246         mkdir_on_mdt0 $DIR/$tdir
4247         copy2archive /etc/passwd $tdir/$tfile
4248
4249         local f=$DIR/$tdir/$tfile
4250         copytool import $tdir/$tfile $f
4251         local fid=$(path2fid $f)
4252
4253         changelog_register
4254
4255         $LFS hsm_restore $f
4256         wait_request_state $fid RESTORE SUCCEED
4257
4258         changelog_find -type HSM -target-fid $fid -flags 0x80 ||
4259                 error "The expected changelog was not emitted"
4260 }
4261 run_test 222a "Changelog for explicit restore"
4262
4263 test_222b() {
4264         # test needs a running copytool
4265         copytool setup
4266
4267         mkdir_on_mdt0 $DIR/$tdir
4268         local f=$DIR/$tdir/$tfile
4269         local fid=$(copy_file /etc/passwd $f)
4270
4271         changelog_register
4272         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4273         wait_request_state $fid ARCHIVE SUCCEED
4274         $LFS hsm_release $f
4275
4276         md5sum $f
4277
4278         wait_request_state $fid RESTORE SUCCEED
4279
4280         changelog_find -type HSM -target-fid $fid -flags 0x80 ||
4281                 error "The expected changelog was not emitted"
4282 }
4283 run_test 222b "Changelog for implicit restore"
4284
4285 test_222c() {
4286         # test needs a running copytool
4287         copytool setup
4288
4289         mkdir_on_mdt0 $DIR/$tdir
4290         copy2archive /etc/passwd $tdir/$tfile
4291
4292         local f=$DIR/$tdir/$tfile
4293         copytool import $tdir/$tfile $f
4294         local fid=$(path2fid $f)
4295
4296         changelog_register
4297
4298         # block copytool operations to allow for HSM request to be
4299         # submitted and file be unlinked (CDT will find object removed)
4300         copytool_suspend
4301
4302         $LFS hsm_restore $f
4303
4304         # wait request to reach CT
4305         wait_request_state $fid RESTORE STARTED
4306
4307         rm -f $f
4308
4309         copytool_continue
4310
4311         wait_request_state $fid RESTORE FAILED
4312
4313         # HE_RESTORE|ENOENT
4314         changelog_find -type HSM -target-fid $fid -flags 0x82 ||
4315                 error "The expected changelog was not emitted"
4316 }
4317 run_test 222c "Changelog for failed explicit restore"
4318
4319 test_222d() {
4320         # test needs a running copytool
4321         copytool setup
4322
4323         mkdir_on_mdt0 $DIR/$tdir
4324         local f=$DIR/$tdir/$tfile
4325         local fid=$(copy_file /etc/passwd $f)
4326
4327         changelog_register
4328         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4329         wait_request_state $fid ARCHIVE SUCCEED
4330         $LFS hsm_release $f
4331
4332         copytool_remove_backend $fid
4333         md5sum $f
4334
4335         wait_request_state $fid RESTORE FAILED
4336
4337         # HE_RESTORE|ENOENT
4338         changelog_find -type HSM -target-fid $fid -flags 0x82 ||
4339                 error "The expected changelog was not emitted"
4340 }
4341 run_test 222d "Changelog for failed implicit restore"
4342
4343 test_223a() {
4344         # test needs a running copytool
4345         copytool setup -b 1
4346         mkdir_on_mdt0 $DIR/$tdir
4347
4348         local f=$DIR/$tdir/$tfile
4349         create_archive_file $tdir/$tfile
4350
4351         changelog_register
4352
4353         copytool import $tdir/$tfile $f
4354         local fid=$(path2fid $f)
4355
4356         $LFS hsm_restore $f
4357         wait_request_state $fid RESTORE STARTED
4358         $LFS hsm_cancel $f
4359         wait_request_state $fid RESTORE CANCELED
4360         wait_request_state $fid CANCEL SUCCEED
4361
4362         changelog_find -type HSM -target-fid $fid -flags 0xfd ||
4363                 error "The expected changelog was not emitted"
4364 }
4365 run_test 223a "Changelog for restore canceled (import case)"
4366
4367 test_223b() {
4368         mkdir_on_mdt0 $DIR/$tdir
4369
4370         local f=$DIR/$tdir/$tfile
4371         local fid=$(create_empty_file "$f")
4372
4373         copytool setup -b 1
4374         changelog_register
4375
4376         $LFS hsm archive --archive $HSM_ARCHIVE_NUMBER $f
4377         wait_request_state $fid ARCHIVE SUCCEED
4378         $LFS hsm release $f
4379
4380         # Prevent restore from completing
4381         copytool_suspend
4382         $LFS hsm restore $f
4383         wait_request_state $fid RESTORE STARTED
4384
4385         $LFS hsm cancel $f
4386         wait_request_state $fid RESTORE CANCELED
4387
4388         copytool_continue
4389         wait_request_state $fid CANCEL SUCCEED
4390
4391         changelog_find -type HSM -target-fid $fid -flags 0xfd ||
4392                 error "The expected changelog was not emitted"
4393 }
4394 run_test 223b "Changelog for restore canceled (release case)"
4395
4396 test_224A() { # was test_224
4397         # test needs a running copytool
4398         copytool setup
4399
4400         mkdir_on_mdt0 $DIR/$tdir
4401
4402         local f=$DIR/$tdir/$tfile
4403         local fid=$(copy_file /etc/passwd $f)
4404
4405         changelog_register
4406         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4407         wait_request_state $fid ARCHIVE SUCCEED
4408
4409         $LFS hsm_remove $f
4410         wait_request_state $fid REMOVE SUCCEED
4411
4412         changelog_find -type HSM -target-fid $fid -flags 0x200 ||
4413                 error "The expected changelog was not emitted"
4414 }
4415 run_test 224A "Changelog for remove"
4416
4417 test_224a() {
4418         # test needs a running copytool
4419         copytool setup
4420
4421         mkdir_on_mdt0 $DIR/$tdir
4422
4423         local f=$DIR/$tdir/$tfile
4424         local fid=$(copy_file /etc/passwd $f)
4425
4426         changelog_register
4427         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4428         wait_request_state $fid ARCHIVE SUCCEED
4429
4430         copytool_remove_backend $fid
4431
4432         # block copytool operations to allow for HSM request to be
4433         # submitted and file be unlinked (CDT will find object removed)
4434         copytool_suspend
4435
4436         $LFS hsm_remove $f
4437
4438         # wait for request to reach CT
4439         wait_request_state $fid REMOVE STARTED
4440
4441         rm -f $f
4442
4443         copytool_continue
4444
4445         wait_request_state $fid REMOVE FAILED
4446
4447         # HE_REMOVE|ENOENT=0x202
4448         changelog_find -type HSM -target-fid $fid -flags 0x202 ||
4449                 error "The expected changelog was not emitted"
4450 }
4451 run_test 224a "Changelog for failed remove"
4452
4453 test_225() {
4454         # test is not usable because remove request is too fast
4455         # so it is always finished before cancel can be done ...
4456         echo "Test disabled"
4457         return 0
4458
4459         # test needs a running copytool
4460         copytool setup
4461         mkdir_on_mdt0 $DIR/$tdir
4462
4463         local f=$DIR/$tdir/$tfile
4464         local fid=$(create_empty_file "$f")
4465
4466         changelog_register
4467         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4468         wait_request_state $fid ARCHIVE SUCCEED
4469
4470         # Prevent restore from completing
4471         copytool_suspend
4472         $LFS hsm_remove $f
4473
4474         $LFS hsm_cancel $f
4475         wait_request_state $fid REMOVE CANCELED
4476
4477         copytool_continue
4478         wait_request_state $fid CANCEL SUCCEED
4479
4480         changelog_find -type HSM -target-fid $fid -flags 0x27d
4481                 error "The expected changelog was not emitted"
4482 }
4483 run_test 225 "Changelog for remove canceled"
4484
4485 test_226() {
4486         # test needs a running copytool
4487         copytool setup
4488
4489         mkdir_on_mdt0 $DIR/$tdir
4490
4491         local f1=$DIR/$tdir/$tfile-1
4492         local f2=$DIR/$tdir/$tfile-2
4493         local f3=$DIR/$tdir/$tfile-3
4494         local fid1=$(copy_file /etc/passwd $f1)
4495         local fid2=$(copy_file /etc/passwd $f2)
4496         copy_file /etc/passwd $f3
4497
4498         changelog_register
4499         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1
4500         wait_request_state $fid1 ARCHIVE SUCCEED
4501
4502         $LFS hsm_archive $f2
4503         wait_request_state $fid2 ARCHIVE SUCCEED
4504
4505         rm $f1 || error "rm $f1 failed"
4506
4507         changelog_dump
4508         changelog_find -type UNLNK -target-fid $fid1 -flags 0x3 ||
4509                 error "The expected changelog was not emitted"
4510
4511         mv $f3 $f2 || error "mv $f3 $f2 failed"
4512
4513         changelog_find -type RENME -target-fid $fid2 -flags 0x3 ||
4514                 error "The expected changelog was not emitted"
4515 }
4516 run_test 226 "changelog for last rm/mv with exiting archive"
4517
4518 # This is just a utility function to clarify what test_227 does
4519 __test_227()
4520 {
4521         local target=0x280
4522
4523         "$LFS" "$action" --$flag "$file" ||
4524                 error "Cannot ${action#hsm_} $flag on '$file'"
4525
4526         # Only one changelog should be produced
4527         local entries="$(changelog_find -type HSM -target-fid $fid)"
4528         [ $(wc -l <<< "$entries") -eq $((++count)) ] ||
4529                 error "lfs $action --$flag '$file' produced more than one" \
4530                       "changelog record"
4531
4532         # Parse the last changelog record
4533         local entry="$(tail -n 1 <<< "$entries")"
4534         eval local -A changelog=$(changelog2array $entry)
4535
4536         # Also check the flags match what is expected
4537         [[ ${changelog[flags]} == $target ]] ||
4538                 error "Changelog flag is '${changelog[flags]}', not $target"
4539 }
4540
4541 test_227() {
4542         local file="$DIR/$tdir/$tfile"
4543         local fid=$(create_empty_file "$file")
4544         local count=0
4545
4546         changelog_register
4547
4548         for flag in norelease noarchive exists archived lost; do
4549                 if [ "$flag" == lost ]; then
4550                         # The flag "lost" only works on an archived file
4551                         "$LFS" hsm_set --archived "$file"
4552                         ((count++))
4553                 fi
4554
4555                 action="hsm_set" __test_227
4556                 action="hsm_clear" __test_227
4557         done
4558 }
4559 run_test 227 "changelog when explicit setting of HSM flags"
4560
4561 test_228() {
4562         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
4563         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
4564
4565         # test needs a running copytool
4566         copytool setup
4567         mkdir_on_mdt0 $DIR/$tdir
4568
4569         local fid=$(create_small_sync_file $DIR/$tfile)
4570         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tfile
4571         wait_request_state $fid ARCHIVE SUCCEED
4572
4573         $LFS hsm_release $DIR/$tfile
4574         check_hsm_flags $DIR/$tfile "0x0000000d"
4575
4576         filefrag $DIR/$tfile | grep " 1 extent found" ||
4577                 error "filefrag on released file must return only one extent"
4578
4579         # only newer versions of cp detect sparse files by stat/FIEMAP
4580         # (LU-2580)
4581         cp --sparse=auto $DIR/$tfile $DIR/$tfile.2 ||
4582                 error "copying $DIR/$tfile"
4583         cmp $DIR/$tfile $DIR/$tfile.2 || error "comparing copied $DIR/$tfile"
4584
4585         $LFS hsm_release $DIR/$tfile
4586         check_hsm_flags $DIR/$tfile "0x0000000d"
4587
4588         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
4589
4590         tar cf - --sparse $DIR/$tfile | tar xvf - -C $DIR/$tdir ||
4591                 error "tar failed"
4592         cmp $DIR/$tfile $DIR/$tdir/$DIR/$tfile ||
4593                 error "comparing untarred $DIR/$tfile"
4594
4595         rm -f $DIR/$tfile $DIR/$tfile.2 ||
4596                 error "rm $DIR/$tfile or $DIR/$tfile.2 failed"
4597 }
4598 run_test 228 "On released file, return extend to FIEMAP. For [cp,tar] --sparse"
4599
4600 test_250() {
4601         local file="$DIR/$tdir/$tfile"
4602
4603         # set max_requests to allow one request of each type to be started (3)
4604         stack_trap \
4605                 "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
4606         set_hsm_param max_requests 3
4607         # speed up test
4608         stack_trap \
4609                 "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
4610         set_hsm_param loop_period 1
4611
4612         # send 1 requests of each kind twice
4613         copytool setup
4614
4615         mkdir_on_mdt0 $DIR/$tdir
4616
4617         # setup the files
4618         for action in archive restore remove; do
4619                 local filepath="$file"-to-$action
4620                 local fid=$(create_empty_file "$filepath")
4621                 local fid2=$(create_empty_file "$filepath".bis)
4622
4623                 if [ "$action" != archive ]; then
4624                         "$LFS" hsm_archive "$filepath"
4625                         wait_request_state $fid ARCHIVE SUCCEED
4626                         "$LFS" hsm_archive "$filepath".bis
4627                         wait_request_state $fid2 ARCHIVE SUCCEED
4628                 fi
4629                 if [ "$action" == restore ]; then
4630                         "$LFS" hsm_release "$filepath"
4631                         "$LFS" hsm_release "$filepath".bis
4632                 fi
4633         done
4634
4635         # suspend the copytool to prevent requests from completing
4636         stack_trap "copytool_continue" EXIT
4637         copytool_suspend
4638
4639         # send `max_requests' requests (one of each kind)
4640         for action in archive restore remove; do
4641                 filepath="$file"-to-$action
4642                 "$LFS" hsm_${action} "$filepath"
4643                 wait_request_state $(path2fid "$filepath") "${action^^}" STARTED
4644         done
4645
4646         # send another batch of requests
4647         for action in archive restore remove; do
4648                 "$LFS" hsm_${action} "$file-to-$action".bis
4649         done
4650         # wait for `loop_period' seconds to make sure the coordinator has time
4651         # to register those, even though it should not
4652         sleep 1
4653
4654         # only the first batch of request should be started
4655         local -i count
4656         count=$(do_facet $SINGLEMDS "$LCTL" get_param -n $HSM_PARAM.actions |
4657                 grep -c STARTED)
4658
4659         ((count == 3)) ||
4660                 error "expected 3 STARTED requests, found $count"
4661 }
4662 run_test 250 "Coordinator max request"
4663
4664 test_251() {
4665         mkdir_on_mdt0 $DIR/$tdir
4666
4667         local f=$DIR/$tdir/$tfile
4668         local fid=$(create_empty_file "$f")
4669
4670         cdt_disable
4671         # to have a short test
4672         local old_to=$(get_hsm_param active_request_timeout)
4673         set_hsm_param active_request_timeout 1
4674         # to be sure the cdt will wake up frequently so
4675         # it will be able to cancel the "old" request
4676         local old_loop=$(get_hsm_param loop_period)
4677         set_hsm_param loop_period 1
4678         cdt_enable
4679
4680         copytool setup
4681
4682         # Prevent archive from completing
4683         copytool_suspend
4684         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4685         wait_request_state $fid ARCHIVE STARTED
4686
4687         # Let the request timeout
4688         wait_request_state $fid ARCHIVE CANCELED
4689
4690         set_hsm_param active_request_timeout $old_to
4691         set_hsm_param loop_period $old_loop
4692 }
4693 run_test 251 "Coordinator request timeout"
4694
4695 test_252() {
4696         mkdir_on_mdt0 $DIR/$tdir
4697
4698         local f=$DIR/$tdir/$tfile
4699         local fid=$(create_empty_file "$f")
4700
4701         # to have a short test
4702         stack_trap "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
4703         set_hsm_param loop_period 1
4704
4705         copytool setup
4706
4707         # Prevent archive from completing
4708         copytool_suspend
4709         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4710         wait_request_state $fid ARCHIVE STARTED
4711         rm -f "$f"
4712
4713         stack_trap "set_hsm_param active_request_timeout \
4714                     $(get_hsm_param active_request_timeout)" EXIT
4715         set_hsm_param active_request_timeout 1
4716
4717         wait_request_state $fid ARCHIVE CANCELED
4718         copytool_continue
4719 }
4720 run_test 252 "Timeout'ed running archive of a removed file should be canceled"
4721
4722 test_253() {
4723         local rc
4724         # test needs a running copytool
4725         copytool setup
4726
4727         mkdir_on_mdt0 $DIR/$tdir
4728         local f=$DIR/$tdir/$tfile
4729
4730         dd if=/dev/zero of=$f bs=1MB count=10
4731         local fid=$(path2fid $f)
4732
4733         $LFS hsm_archive $f || error "could not archive file"
4734         wait_request_state $fid ARCHIVE SUCCEED
4735
4736         # clear locks to discard inode data
4737         cancel_lru_locks osc
4738
4739         #define OBD_FAIL_MDC_MERGE              0x807
4740         $LCTL set_param fail_loc=0x807
4741
4742         #expect error here, instead of release with wrong size
4743         $LFS hsm_release $f
4744         rc=$?
4745         if ((rc == 0)); then
4746                 file_size=$(stat -c '%s' $f)
4747                 if ((file_size != 10485760)); then
4748                         error "Wrong file size after hsm_release"
4749                 fi
4750         else
4751                 echo "could not release file"
4752         fi
4753 }
4754 run_test 253 "Check for wrong file size after release"
4755
4756 test_254a()
4757 {
4758         [ $MDS1_VERSION -lt $(version_code 2.10.56) ] &&
4759                 skip "need MDS version at least 2.10.56"
4760
4761         # Check that the counters are initialized to 0
4762         local count
4763         for request_type in archive restore remove; do
4764                 count="$(get_hsm_param ${request_type}_count)" ||
4765                         error "Reading ${request_type}_count failed with $?"
4766
4767                 [ "$count" -eq 0 ] ||
4768                         error "Expected ${request_type}_count to be " \
4769                               "0 != '$count'"
4770         done
4771 }
4772 run_test 254a "Request counters are initialized to zero"
4773
4774 test_254b()
4775 {
4776         [ $MDS1_VERSION -lt $(version_code 2.10.56) ] &&
4777                 skip "need MDS version at least 2.10.56"
4778
4779         # The number of request to launch (at least 32)
4780         local request_count=$((RANDOM % 32 + 32))
4781         printf "Will launch %i requests of each type\n" "$request_count"
4782
4783         # Launch a copytool to process requests
4784         copytool setup
4785
4786         # Set hsm.max_requests to allow starting all requests at the same time
4787         stack_trap \
4788                 "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
4789         set_hsm_param max_requests "$request_count"
4790
4791         mkdir_on_mdt0 $DIR/$tdir
4792
4793         local timeout
4794         local count
4795         for request_type in archive restore remove; do
4796                 printf "Checking %s requests\n" "${request_type}"
4797                 # Suspend the copytool to give us time to read the proc files
4798                 copytool_suspend
4799
4800                 for ((i = 0; i < $request_count; i++)); do
4801                         case $request_type in
4802                         archive)
4803                                 create_empty_file "$DIR/$tdir/$tfile-$i" \
4804                                         >/dev/null 2>&1
4805                                 ;;
4806                         restore)
4807                                 lfs hsm_release "$DIR/$tdir/$tfile-$i"
4808                                 ;;
4809                         esac
4810                         $LFS hsm_${request_type} "$DIR/$tdir/$tfile-$i"
4811                 done
4812
4813                 # Give the coordinator 10 seconds to start every request
4814                 timeout=10
4815                 while get_hsm_param actions | grep -q WAITING; do
4816                         sleep 1
4817                         let timeout-=1
4818                         [ $timeout -gt 0 ] ||
4819                                 error "${request_type^} requests took too " \
4820                                       "long to start"
4821                 done
4822
4823                 count="$(get_hsm_param ${request_type}_count)"
4824                 [ "$count" -eq "$request_count" ] ||
4825                         error "Expected '$request_count' (!= '$count') " \
4826                               "active $request_type requests"
4827
4828                 # Let the copytool process the requests
4829                 copytool_continue
4830                 # Give it 10 seconds maximum
4831                 timeout=10
4832                 while get_hsm_param actions | grep -q STARTED; do
4833                         sleep 1
4834                         let timeout-=1
4835                         [ $timeout -gt 0 ] ||
4836                                 error "${request_type^} requests took too " \
4837                                       "long to complete"
4838                 done
4839
4840                 count="$(get_hsm_param ${request_type}_count)"
4841                 [ "$count" -eq 0 ] ||
4842                         error "Expected 0 (!= '$count') " \
4843                               "active $request_type requests"
4844         done
4845 }
4846 run_test 254b "Request counters are correctly incremented and decremented"
4847
4848 test_255()
4849 {
4850         [ $MDS1_VERSION -lt $(version_code 2.12.0) ] &&
4851                 skip "Need MDS version at least 2.12.0"
4852
4853         mkdir_on_mdt0 $DIR/$tdir
4854
4855         local file="$DIR/$tdir/$tfile"
4856         local fid=$(create_empty_file "$file")
4857
4858         # How do you make sure the coordinator has consumed any outstanding
4859         # event, without triggering an event yourself?
4860         #
4861         # You wait for a request to disappear from the coordinator's llog.
4862
4863         # Warning: the setup represents 90% of this test
4864
4865         # Create and process an HSM request
4866         copytool setup
4867         "$LFS" hsm_archive "$file"
4868         wait_request_state $fid ARCHIVE SUCCEED
4869
4870         kill_copytools
4871         wait_copytools || error "failed to stop copytools"
4872
4873         # Launch a new HSM request
4874         rm "$file"
4875         create_empty_file "$file"
4876         "$LFS" hsm_archive "$file"
4877
4878         cdt_shutdown
4879
4880         # Have the completed request be removed as soon as the cdt wakes up
4881         stack_trap "set_hsm_param grace_delay $(get_hsm_param grace_delay)" EXIT
4882         set_hsm_param grace_delay 1
4883         # (Hopefully, time on the MDS will behave nicely)
4884         do_facet $SINGLEMDS sleep 2 &
4885
4886         # Increase `loop_period' as a mean to prevent the coordinator from
4887         # waking itself up to do some housekeeping.
4888         stack_trap "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
4889         set_hsm_param loop_period 1000
4890
4891         wait $! || error "waiting failed"
4892         cdt_enable
4893         wait_request_state $fid ARCHIVE ""
4894         # The coordinator will not wake up on its own for ~`loop_period' secs...
4895
4896         # ... Unless a copytool registers. Now the real test begins
4897         copytool setup
4898         wait_request_state $(path2fid "$file") ARCHIVE SUCCEED
4899 }
4900 run_test 255 "Copytool registration wakes the coordinator up"
4901
4902 # tests 260[a-c] rely on the parsing of the copytool's log file, they might
4903 # break in the future because of that.
4904 test_260a()
4905 {
4906         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
4907                 skip "need MDS version 2.11.56 or later"
4908
4909         local -a files=("$DIR/$tdir/$tfile".{0..15})
4910         local file
4911
4912         mkdir_on_mdt0 $DIR/$tdir
4913
4914         for file in "${files[@]}"; do
4915                 create_small_file "$file"
4916         done
4917
4918         # Set a few hsm parameters
4919         stack_trap \
4920                 "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
4921         set_hsm_param loop_period 1
4922         stack_trap \
4923                 "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
4924         set_hsm_param max_requests 3
4925
4926         # Release one file
4927         copytool setup
4928         "$LFS" hsm_archive "${files[0]}"
4929         wait_request_state "$(path2fid "${files[0]}")" ARCHIVE SUCCEED
4930         "$LFS" hsm_release "${files[0]}"
4931
4932         # Stop the copytool
4933         kill_copytools
4934         wait_copytools || error "copytools failed to stop"
4935
4936         # Send several archive requests
4937         for file in "${files[@]:1}"; do
4938                 "$LFS" hsm_archive "$file"
4939         done
4940
4941         # Send one restore request
4942         "$LFS" hsm_restore "${files[0]}"
4943
4944         # Launch a copytool
4945         copytool setup
4946
4947         # Wait for all the requests to complete
4948         wait_request_state "$(path2fid "${files[0]}")" RESTORE SUCCEED
4949         for file in "${files[@]:1}"; do
4950                 wait_request_state "$(path2fid "$file")" ARCHIVE SUCCEED
4951         done
4952
4953         # Collect the actions in the order in which the copytool processed them
4954         local -a actions=(
4955                 $(do_facet "$SINGLEAGT" grep -o '\"RESTORE\\|ARCHIVE\"' \
4956                         "$(copytool_logfile "$SINGLEAGT")")
4957                 )
4958
4959         printf '%s\n' "${actions[@]}"
4960
4961         local action
4962         for action in "${actions[@]:0:3}"; do
4963                 [ "$action" == RESTORE ] && return
4964         done
4965
4966         error "Too many ARCHIVE requests were run before the RESTORE request"
4967 }
4968 run_test 260a "Restore request have priority over other requests"
4969
4970 # This test is very much tied to the implementation of the current priorisation
4971 # mechanism in the coordinator. It might not make sense to keep it in the future
4972 test_260b()
4973 {
4974         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
4975                 skip "need MDS version 2.11.56 or later"
4976
4977         local -a files=("$DIR/$tdir/$tfile".{0..15})
4978         local file
4979
4980         mkdir_on_mdt0 $DIR/$tdir
4981
4982         for file in "${files[@]}"; do
4983                 create_small_file "$file"
4984         done
4985
4986         # Set a few hsm parameters
4987         stack_trap \
4988                 "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
4989         set_hsm_param loop_period 1
4990         stack_trap \
4991                 "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
4992         set_hsm_param max_requests 3
4993
4994         # Release one file
4995         copytool setup --archive-id 2
4996         "$LFS" hsm_archive --archive 2 "${files[0]}"
4997         wait_request_state "$(path2fid "${files[0]}")" ARCHIVE SUCCEED
4998         "$LFS" hsm_release "${files[0]}"
4999
5000         # Stop the copytool
5001         kill_copytools
5002         wait_copytools || error "copytools failed to stop"
5003
5004         # Send several archive requests
5005         for file in "${files[@]:1}"; do
5006                 "$LFS" hsm_archive "$file"
5007         done
5008
5009         # Send one restore request
5010         "$LFS" hsm_restore "${files[0]}"
5011
5012         # Launch a copytool
5013         copytool setup
5014         copytool setup --archive-id 2
5015
5016         # Wait for all the requests to complete
5017         wait_request_state "$(path2fid "${files[0]}")" RESTORE SUCCEED
5018         for file in "${files[@]:1}"; do
5019                 wait_request_state "$(path2fid "$file")" ARCHIVE SUCCEED
5020         done
5021
5022         # Collect the actions in the order in which the copytool processed them
5023         local -a actions=(
5024                 $(do_facet "$SINGLEAGT" grep -o '\"RESTORE\\|ARCHIVE\"' \
5025                         "$(copytool_logfile "$SINGLEAGT")")
5026                 )
5027
5028         printf '%s\n' "${actions[@]}"
5029
5030         local action
5031         for action in "${actions[@]:0:3}"; do
5032                 [ "$action" == RESTORE ] && return
5033         done
5034
5035         error "Too many ARCHIVE requests were run before the RESTORE request"
5036 }
5037 run_test 260b "Restore request have priority over other requests"
5038
5039 # This test is very much tied to the implementation of the current priorisation
5040 # mechanism in the coordinator. It might not make sense to keep it in the future
5041 test_260c()
5042 {
5043         [ $MDS1_VERSION -lt $(version_code 2.12.0) ] &&
5044                 skip "Need MDS version at least 2.12.0"
5045
5046         local -a files=("$DIR/$tdir/$tfile".{0..15})
5047         local file
5048
5049         mkdir_on_mdt0 $DIR/$tdir
5050
5051         for file in "${files[@]}"; do
5052                 create_small_file "$file"
5053         done
5054
5055         # Set a few hsm parameters
5056         stack_trap \
5057                 "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
5058         set_hsm_param loop_period 1000
5059         stack_trap \
5060                 "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
5061         set_hsm_param max_requests 3
5062
5063         # Release one file
5064         copytool setup --archive-id 2
5065         "$LFS" hsm_archive --archive 2 "${files[0]}"
5066         wait_request_state "$(path2fid "${files[0]}")" ARCHIVE SUCCEED
5067         "$LFS" hsm_release "${files[0]}"
5068
5069         # Stop the copytool
5070         kill_copytools
5071         wait_copytools || error "copytools failed to stop"
5072
5073         # Force the next coordinator run to do housekeeping
5074         cdt_shutdown
5075         cdt_enable
5076
5077         "$LFS" hsm_archive "${files[1]}"
5078
5079         # Launch a copytool
5080         copytool setup
5081         copytool setup --archive-id 2
5082
5083         wait_request_state "$(path2fid "${files[1]}")" ARCHIVE SUCCEED
5084         # The coordinator just did a housekeeping run it won't do another one
5085         # for around `loop_period' seconds => requests will not be reordered
5086         # if it costs too much (ie. when the coordinator has to discard a whole
5087         # hal)
5088
5089         # Send several archive requests
5090         for file in "${files[@]:2}"; do
5091                 "$LFS" hsm_archive "$file"
5092         done
5093
5094         # Send one restore request
5095         "$LFS" hsm_restore "${files[0]}"
5096
5097         # Wait for all the requests to complete
5098         wait_request_state "$(path2fid "${files[0]}")" RESTORE SUCCEED
5099         for file in "${files[@]:2}"; do
5100                 wait_request_state "$(path2fid "$file")" ARCHIVE SUCCEED
5101         done
5102
5103         # Collect the actions in the order in which the copytool processed them
5104         local -a actions=(
5105                 $(do_facet "$SINGLEAGT" grep -o '\"RESTORE\\|ARCHIVE\"' \
5106                         "$(copytool_logfile "$SINGLEAGT")")
5107                 )
5108
5109         printf '%s\n' "${actions[@]}"
5110
5111         local action
5112         for action in "${actions[@]:0:3}"; do
5113                 [ "$action" == RESTORE ] &&
5114                         error "Restore requests should not be prioritised" \
5115                               "unless the coordinator is doing housekeeping"
5116         done
5117         return 0
5118 }
5119 run_test 260c "Requests are not reordered on the 'hot' path of the coordinator"
5120
5121 test_261() {
5122         local file=$DIR/$tdir/$tfile
5123         local size
5124         local fid
5125
5126         copytool setup
5127         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5128
5129         dd if=/dev/zero of=$file bs=4k count=2 || error "Write $file failed"
5130         fid=$(path2fid $file)
5131         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $file
5132         wait_request_state $fid ARCHIVE SUCCEED
5133
5134         $LFS hsm_state $file
5135         $LFS hsm_release $file
5136         $LFS hsm_restore $file
5137         wait_request_state $fid RESTORE SUCCEED
5138         $LFS hsm_release $file
5139         size=$(stat -c %s $file)
5140         [[ $size == 8192 ]] || error "Size after HSM release: $size"
5141
5142         $LFS hsm_release $file
5143         $LFS hsm_restore $file
5144         $LFS hsm_release $file
5145         size=$(stat -c %s $file)
5146         [[ $size == 8192 ]] || error "Size after HSM release: $size"
5147         $LFS hsm_state $file
5148 }
5149 run_test 261 "Report 0 bytes size after HSM release"
5150
5151 test_262() {
5152         (( MDS1_VERSION >= $(version_code v2_15_61-204-g5ee13823a4) )) ||
5153                 skip "Need MDS version at least 2.15.61"
5154
5155         local file=$DIR/$tdir/$tfile
5156         local blocks
5157         local fid
5158
5159         copytool setup
5160         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5161
5162         dd if=/dev/zero of=$file bs=4k count=2 || error "Write $file failed"
5163         fid=$(path2fid $file)
5164         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $file
5165         wait_request_state $fid ARCHIVE SUCCEED
5166
5167         $LFS hsm_release $file || error "HSM release $file failed"
5168         $LFS hsm_restore $file || error "HSM restore $file failed"
5169         $LFS hsm_release $file || error "HSM release $file failed"
5170         $LFS hsm_release $file || error "HSM release $file failed"
5171         blocks=$(stat -c "%b" $file)
5172         [ $blocks -eq "1" ] || error "wrong block number is $blocks, not 1"
5173 }
5174 run_test 262 "The client should return 1 block for HSM released files"
5175
5176 test_300() {
5177         [ "$CLIENTONLY" ] && skip "CLIENTONLY mode" && return
5178
5179         # the only way to test ondisk conf is to restart MDS ...
5180         echo "Stop coordinator and remove coordinator state at mount"
5181         # stop coordinator
5182         cdt_shutdown
5183         # clean on disk conf set by default
5184         cdt_clear_mount_state
5185         cdt_check_state stopped
5186
5187         # check cdt still off after umount/remount
5188         fail $SINGLEMDS
5189         cdt_check_state stopped
5190
5191         echo "Set coordinator start at mount, and start coordinator"
5192         cdt_set_mount_state enabled
5193
5194         # check cdt is on
5195         cdt_check_state enabled
5196
5197         # check cdt still on after umount/remount
5198         fail $SINGLEMDS
5199         cdt_check_state enabled
5200
5201         # we are back to original state (cdt started at mount)
5202 }
5203 run_test 300 "On disk coordinator state kept between MDT umount/mount"
5204
5205 test_301() {
5206         [ "$CLIENTONLY" ] && skip "CLIENTONLY mode" && return
5207
5208         local ai=$(get_hsm_param default_archive_id)
5209         local new=$((ai + 1))
5210
5211         set_hsm_param default_archive_id $new -P
5212         fail $SINGLEMDS
5213         local res=$(get_hsm_param default_archive_id)
5214
5215         # clear value
5216         set_hsm_param default_archive_id "" "-P -d"
5217
5218         [[ $new == $res ]] || error "Value after MDS restart is $res != $new"
5219 }
5220 run_test 301 "HSM tunnable are persistent"
5221
5222 test_302() {
5223         [ "$CLIENTONLY" ] && skip "CLIENTONLY mode" && return
5224
5225         local ai=$(get_hsm_param default_archive_id)
5226         local new=$((ai + 1))
5227
5228         # stop coordinator
5229         cdt_shutdown
5230
5231         set_hsm_param default_archive_id $new -P
5232
5233         local mdtno
5234         for mdtno in $(seq 1 $MDSCOUNT); do
5235                 fail mds${mdtno}
5236         done
5237
5238         # check cdt is on
5239         cdt_check_state enabled
5240
5241         local res=$(get_hsm_param default_archive_id)
5242
5243         # clear value
5244         set_hsm_param default_archive_id "" "-P -d"
5245
5246         [[ $new == $res ]] || error "Value after MDS restart is $res != $new"
5247 }
5248 run_test 302 "HSM tunnable are persistent when CDT is off"
5249
5250 test_400() {
5251         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5252
5253         copytool setup
5254
5255         mkdir_on_mdt0 $DIR/$tdir
5256
5257         local dir_mdt0=$DIR/$tdir/mdt0
5258         local dir_mdt1=$DIR/$tdir/mdt1
5259
5260         # create 1 dir per MDT
5261         stack_trap "rm -rf $dir_mdt0" EXIT
5262         $LFS mkdir -i 0 $dir_mdt0 || error "lfs mkdir"
5263         stack_trap "rm -rf $dir_mdt1" EXIT
5264         $LFS mkdir -i 1 $dir_mdt1 || error "lfs mkdir"
5265
5266         # create 1 file in each MDT
5267         local fid1=$(create_small_file $dir_mdt0/$tfile)
5268         local fid2=$(create_small_file $dir_mdt1/$tfile)
5269
5270         # check that hsm request on mdt0 is sent to the right MDS
5271         $LFS hsm_archive $dir_mdt0/$tfile || error "lfs hsm_archive"
5272         wait_request_state $fid1 ARCHIVE SUCCEED 0 &&
5273                 echo "archive successful on mdt0"
5274
5275         # check that hsm request on mdt1 is sent to the right MDS
5276         $LFS hsm_archive $dir_mdt1/$tfile || error "lfs hsm_archive"
5277         wait_request_state $fid2 ARCHIVE SUCCEED 1 &&
5278                 echo "archive successful on mdt1"
5279 }
5280 run_test 400 "Single request is sent to the right MDT"
5281
5282 test_401() {
5283         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5284
5285         copytool setup
5286
5287         mkdir_on_mdt0 $DIR/$tdir
5288
5289         local dir_mdt0=$DIR/$tdir/mdt0
5290         local dir_mdt1=$DIR/$tdir/mdt1
5291
5292         # create 1 dir per MDT
5293         stack_trap "rm -rf $dir_mdt0" EXIT
5294         $LFS mkdir -i 0 $dir_mdt0 || error "lfs mkdir"
5295         stack_trap "rm -rf $dir_mdt1" EXIT
5296         $LFS mkdir -i 1 $dir_mdt1 || error "lfs mkdir"
5297
5298         # create 1 file in each MDT
5299         local fid1=$(create_small_file $dir_mdt0/$tfile)
5300         local fid2=$(create_small_file $dir_mdt1/$tfile)
5301
5302         # check that compound requests are shunt to the rights MDTs
5303         $LFS hsm_archive $dir_mdt0/$tfile $dir_mdt1/$tfile ||
5304                 error "lfs hsm_archive"
5305         wait_request_state $fid1 ARCHIVE SUCCEED 0 &&
5306                 echo "archive successful on mdt0"
5307         wait_request_state $fid2 ARCHIVE SUCCEED 1 &&
5308                 echo "archive successful on mdt1"
5309 }
5310 run_test 401 "Compound requests split and sent to their respective MDTs"
5311
5312 mdc_change_state() # facet, MDT_pattern, activate|deactivate
5313 {
5314         local facet=$1
5315         local pattern="$2"
5316         local state=$3
5317         local node=$(facet_active_host $facet)
5318         local mdc
5319         for mdc in $(do_facet $facet "$LCTL dl | grep -E ${pattern}-mdc" |
5320                         awk '{print $4}'); do
5321                 echo "$3 $mdc on $node"
5322                 do_facet $facet "$LCTL --device $mdc $state" || return 1
5323         done
5324 }
5325
5326 test_402a() {
5327         # deactivate all mdc on agent1
5328         mdc_change_state $SINGLEAGT "$FSNAME-MDT000." "deactivate"
5329
5330         copytool setup --no-fail
5331
5332         check_agent_unregistered "uuid" # match any agent
5333
5334         # no expected running copytool
5335         search_copytools $agent && error "Copytool start should have failed"
5336
5337         # reactivate MDCs
5338         mdc_change_state $SINGLEAGT "$FSNAME-MDT000." "activate"
5339 }
5340 run_test 402a "Copytool start fails if all MDTs are inactive"
5341
5342 test_402b() {
5343         copytool setup
5344
5345         mkdir_on_mdt0 $DIR/$tdir
5346
5347         local f=$DIR/$tdir/$tfile
5348         touch $f || error "touch $f failed"
5349         local fid=$(path2fid $f)
5350
5351 #define OBD_FAIL_MDS_HSM_CT_REGISTER_NET        0x14d
5352         do_facet $SINGLEAGT lctl set_param fail_loc=0x14d
5353         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
5354
5355         # give time for CDT to send request and to keep it for retry
5356         wait_for_loop_period
5357
5358         wait_request_state $fid ARCHIVE WAITING
5359
5360         do_facet $SINGLEAGT lctl set_param fail_loc=0
5361
5362         # request should succeed now
5363         wait_request_state $fid ARCHIVE SUCCEED
5364 }
5365 run_test 402b "CDT must retry request upon slow start of CT"
5366
5367 test_403() {
5368         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5369
5370         local agent=$(facet_active_host $SINGLEAGT)
5371
5372         # deactivate all mdc for MDT0001
5373         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "deactivate"
5374
5375         copytool setup
5376         local uuid=$(get_agent_uuid $agent)
5377         # check the agent is registered on MDT0000, and not on MDT0001
5378         check_agent_registered_by_mdt $uuid 0
5379         check_agent_unregistered_by_mdt $uuid 1
5380
5381         # check running copytool process
5382         search_copytools $agent || error "No running copytools on $agent"
5383
5384         # reactivate all mdc for MDT0001
5385         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "activate"
5386
5387         # make sure the copytool is now registered to all MDTs
5388         check_agent_registered $uuid
5389 }
5390 run_test 403 "Copytool starts with inactive MDT and register on reconnect"
5391
5392 test_404() {
5393         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5394
5395         copytool setup
5396
5397         # create files on both MDT0000 and MDT0001
5398         mkdir_on_mdt0 $DIR/$tdir
5399
5400         local dir_mdt0=$DIR/$tdir/mdt0
5401         stack_trap "rm -rf $dir_mdt0" EXIT
5402         $LFS mkdir -i 0 $dir_mdt0 || error "lfs mkdir"
5403
5404         # create 1 file on mdt0
5405         local fid1=$(create_small_file $dir_mdt0/$tfile)
5406
5407         # deactivate all mdc for MDT0001
5408         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "deactivate"
5409
5410         # send an HSM request for files in MDT0000
5411         $LFS hsm_archive $dir_mdt0/$tfile || error "lfs hsm_archive"
5412
5413         # check for completion of files in MDT0000
5414         wait_request_state $fid1 ARCHIVE SUCCEED 0 &&
5415                 echo "archive successful on mdt0"
5416
5417         # reactivate all mdc for MDT0001
5418         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "activate"
5419 }
5420 run_test 404 "Inactive MDT does not block requests for active MDTs"
5421
5422 test_405() {
5423         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5424
5425         copytool setup
5426
5427         mkdir_on_mdt0 $DIR/$tdir
5428
5429         local striped_dir=$DIR/$tdir/striped_dir
5430
5431         # create striped dir on all of MDTs
5432         $LFS mkdir -i 0 -c $MDSCOUNT $striped_dir || error "lfs mkdir"
5433
5434         local fid1=$(create_small_sync_file $striped_dir/${tfile}_0)
5435         local fid2=$(create_small_sync_file $striped_dir/${tfile}_1)
5436         local fid3=$(create_small_sync_file $striped_dir/${tfile}_2)
5437         local fid4=$(create_small_sync_file $striped_dir/${tfile}_3)
5438
5439         local idx1=$($LFS getstripe -m $striped_dir/${tfile}_0)
5440         local idx2=$($LFS getstripe -m $striped_dir/${tfile}_1)
5441         local idx3=$($LFS getstripe -m $striped_dir/${tfile}_2)
5442         local idx4=$($LFS getstripe -m $striped_dir/${tfile}_3)
5443
5444         # check that compound requests are shunt to the rights MDTs
5445         $LFS hsm_archive $striped_dir/${tfile}_0 $striped_dir/${tfile}_1  \
5446                          $striped_dir/${tfile}_2 $striped_dir/${tfile}_3 ||
5447                 error "lfs hsm_archive"
5448
5449         wait_request_state $fid1 ARCHIVE SUCCEED $idx1 &&
5450                 echo "archive successful on $fid1"
5451         wait_request_state $fid2 ARCHIVE SUCCEED $idx2 &&
5452                 echo "archive successful on $fid2"
5453         wait_request_state $fid3 ARCHIVE SUCCEED $idx3 &&
5454                 echo "archive successful on $fid3"
5455         wait_request_state $fid4 ARCHIVE SUCCEED $idx4 &&
5456                 echo "archive successful on $fid4"
5457
5458         $LFS hsm_release $striped_dir/${tfile}_0 || error "lfs hsm_release 1"
5459         $LFS hsm_release $striped_dir/${tfile}_1 || error "lfs hsm_release 2"
5460         $LFS hsm_release $striped_dir/${tfile}_2 || error "lfs hsm_release 3"
5461         $LFS hsm_release $striped_dir/${tfile}_3 || error "lfs hsm_release 4"
5462
5463         cat $striped_dir/${tfile}_0 > /dev/null || error "cat ${tfile}_0 failed"
5464         cat $striped_dir/${tfile}_1 > /dev/null || error "cat ${tfile}_1 failed"
5465         cat $striped_dir/${tfile}_2 > /dev/null || error "cat ${tfile}_2 failed"
5466         cat $striped_dir/${tfile}_3 > /dev/null || error "cat ${tfile}_3 failed"
5467 }
5468 run_test 405 "archive and release under striped directory"
5469
5470 test_406() {
5471         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
5472
5473         [ $MDS1_VERSION -lt $(version_code 2.7.64) ] &&
5474                 skip "need MDS version at least 2.7.64"
5475
5476         local fid
5477         local mdt_index
5478
5479         mkdir_on_mdt0 $DIR/$tdir
5480
5481         fid=$(create_small_file $DIR/$tdir/$tfile)
5482         echo "old fid $fid"
5483
5484         copytool setup
5485
5486         $LFS hsm_archive $DIR/$tdir/$tfile
5487         wait_request_state "$fid" ARCHIVE SUCCEED
5488         $LFS hsm_release $DIR/$tdir/$tfile
5489
5490         # Should migrate $tdir but not $tfile.
5491         $LFS migrate -m1 $DIR/$tdir &&
5492                 error "migrating HSM an archived file should fail"
5493
5494         $LFS hsm_restore $DIR/$tdir/$tfile
5495         wait_request_state "$fid" RESTORE SUCCEED
5496
5497         $LFS hsm_remove $DIR/$tdir/$tfile
5498         wait_request_state "$fid" REMOVE SUCCEED
5499
5500         cat $DIR/$tdir/$tfile > /dev/null ||
5501                 error "cannot read $DIR/$tdir/$tfile"
5502
5503         $LFS migrate -m1 $DIR/$tdir ||
5504                 error "cannot complete migration after HSM remove"
5505
5506         mdt_index=$($LFS getstripe -m $DIR/$tdir)
5507         if ((mdt_index != 1)); then
5508                 error "expected MDT index 1, got $mdt_index"
5509         fi
5510
5511         # Refresh fid after migration.
5512         fid=$(path2fid $DIR/$tdir/$tfile)
5513         echo "new fid $fid"
5514
5515         $LFS hsm_archive $DIR/$tdir/$tfile
5516         wait_request_state "$fid" ARCHIVE SUCCEED 1
5517
5518         lctl set_param debug=+trace
5519         $LFS hsm_release $DIR/$tdir/$tfile ||
5520                 error "cannot release $DIR/$tdir/$tfile"
5521
5522         $LFS hsm_restore $DIR/$tdir/$tfile
5523         wait_request_state "$fid" RESTORE SUCCEED 1
5524
5525         cat $DIR/$tdir/$tfile > /dev/null ||
5526                 error "cannot read $DIR/$tdir/$tfile"
5527 }
5528 run_test 406 "attempting to migrate HSM archived files is safe"
5529
5530 test_407() {
5531         mkdir_on_mdt0 $DIR/$tdir
5532
5533         local f=$DIR/$tdir/$tfile
5534         local f2=$DIR2/$tdir/$tfile
5535         local fid=$(create_empty_file "$f")
5536
5537         copytool setup
5538
5539         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
5540         wait_request_state $fid ARCHIVE SUCCEED
5541         $LFS hsm_release $f
5542
5543 #define OBD_FAIL_MDS_HSM_CDT_DELAY      0x164
5544         do_facet $SINGLEMDS $LCTL set_param fail_val=5 fail_loc=0x164
5545
5546         # Prevent restore from completing
5547         copytool_suspend
5548
5549         md5sum $f &
5550         # 1st request holds layout lock while appropriate
5551         # RESTORE record is still not added to llog
5552         md5sum $f2 &
5553         sleep 2
5554
5555         do_facet $SINGLEMDS "$LCTL get_param $HSM_PARAM.actions"
5556         # after umount hsm_actions->O/x/x log shouldn't have
5557         # double RESTORE records like below
5558         #[0x200000401:0x1:0x0]...0x58d03a0d/0x58d03a0c action=RESTORE...WAITING
5559         #[0x200000401:0x1:0x0]...0x58d03a0c/0x58d03a0d action=RESTORE...WAITING
5560         sleep 30 &&
5561                 do_facet $SINGLEMDS "$LCTL get_param $HSM_PARAM.actions"&
5562         fail $SINGLEMDS
5563         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
5564
5565         do_facet $SINGLEMDS "$LCTL get_param $HSM_PARAM.actions"
5566
5567         copytool_continue
5568         wait_all_done 100 $fid
5569 }
5570 run_test 407 "Check for double RESTORE records in llog"
5571
5572 test_408 () { #LU-17110
5573         checkfiemap --test ||
5574                 skip "checkfiemap not runnable: $?"
5575
5576         local f=$DIR/$tfile
5577         local fid
5578         local out;
5579
5580         copytool setup
5581
5582         # write data this way: hole - data - hole - data
5583         dd if=/dev/urandom of=$f bs=64K count=1 conv=fsync
5584         [[ "$(facet_fstype ost$(($($LFS getstripe -i $f) + 1)))" != "zfs" ]] ||
5585                 skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
5586         dd if=/dev/urandom of=$f bs=64K seek=3 count=1 conv=fsync
5587         stat $DIR/$tfile
5588         echo "disk usage: $(du -B1 $f)"
5589         echo "file size: $(du -b $f)"
5590
5591         fid=$(path2fid $f)
5592         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
5593         wait_request_state $fid ARCHIVE SUCCEED
5594         $LFS hsm_release $f
5595
5596         out=$(checkfiemap --corruption_test $f $((4 * 64 * 1024))) ||
5597                 error "checkfiemap failed"
5598
5599         echo "$out"
5600         grep -q "flags (0x3):" <<< "$out" ||
5601                 error "the extent flags of a relase file should be: LAST UNKNOWN"
5602
5603 }
5604 run_test 408 "Verify fiemap on release file"
5605
5606 test_409a() {
5607         (( MDS1_VERSION >= $(version_code 2.15.59) )) ||
5608                 skip "need MDS version at least 2.15.59"
5609
5610         mkdir_on_mdt0 $DIR/$tdir
5611
5612         local restore_pid shutdown_pid
5613         local mdt0_hsm_state
5614         local f=$DIR/$tdir/$tfile
5615         local fid=$(create_empty_file "$f")
5616
5617         copytool setup
5618
5619         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
5620                 error "could not archive file $f"
5621         wait_request_state $fid ARCHIVE SUCCEED
5622         $LFS hsm_release $f || error "could not release file $f"
5623
5624 #define OBD_FAIL_MDS_HSM_CDT_DELAY      0x164
5625         do_facet $SINGLEMDS $LCTL set_param fail_val=5 fail_loc=0x164
5626
5627         # send a restore request
5628         cat $f > /dev/null & restore_pid=$!
5629
5630         # stop the coordinator while it handle the request
5631         cdt_shutdown & shutdown_pid=$!
5632         stack_trap "cdt_enable" EXIT
5633
5634         sleep 1;
5635         mdt0_hsm_state=$(do_facet mds1 "$LCTL get_param -n mdt.*MDT0000.hsm_control")
5636         [[ "$mdt0_hsm_state" == "stopping" ]] ||
5637                 error "HSM state of MDT0000 is not 'stopping' (hsm_control=$mdt0_hsm_state)"
5638
5639         wait $shutdown_pid
5640         cdt_check_state stopped
5641         wait_request_state $fid RESTORE WAITING
5642
5643         cdt_enable
5644
5645         # copytool must re-register
5646         kill_copytools
5647         wait_copytools || error "copytool failed to stop"
5648         copytool setup
5649
5650         wait $restore_pid || true
5651         wait_request_state $fid RESTORE SUCCEED
5652         cat $f > /dev/null || error "fail to read $f"
5653 }
5654 run_test 409a "Coordinator should not stop when in use"
5655
5656 test_409b()
5657 {
5658         mkdir_on_mdt0 $DIR/$tdir
5659
5660         local f=$DIR/$tdir/$tfile
5661         local fid=$(create_empty_file "$f")
5662
5663         copytool setup
5664
5665         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
5666         wait_request_state $fid ARCHIVE SUCCEED
5667
5668         $LFS hsm_release $f || error "cannot release $f"
5669         check_hsm_flags $f "0x0000000d"
5670
5671         kill_copytools
5672         wait_copytools || error "copytools failed to stop"
5673
5674         # Remount fs to clear cached file attributes and free restore hash
5675         stack_trap "cdt_check_state enabled" EXIT
5676         stack_trap "cdt_set_mount_state enabled" EXIT
5677         cdt_set_mount_state shutdown
5678         cdt_check_state stopped
5679
5680         fail mds1
5681
5682         # getattr should work even if CDT is stopped
5683         stat $f || error "cannot stat file"
5684 }
5685 run_test 409b "getattr released file with CDT stopped after remount"
5686
5687 test_410()
5688 {
5689         (( MDS1_VERSION >= $(version_code 2.15.90.10) )) ||
5690                 skip "need MDS >= v2_15_90-10-g80a961261a23 for HSM fix"
5691
5692         mkdir_on_mdt0 $DIR/$tdir
5693
5694         local f=$DIR/$tdir/$tfile
5695         local fid=$(create_small_file $f)
5696
5697         copytool setup
5698
5699         $LFS hsm_set --exists --archived $f ||
5700                 error "could not change hsm flags"
5701         $LFS hsm_release $f 2>&1 > /dev/null && error "HSM release should fail"
5702
5703         $LFS data_version -ws $f 2>&1 > /dev/null
5704         $LFS hsm_release $f || error "could not release file"
5705 }
5706 run_test 410 "lfs data_version -s allows release of force-archived file"
5707
5708 cleanup_411() {
5709         local nm=$1
5710
5711         do_facet mgs $LCTL nodemap_del $nm || true
5712         do_facet mgs $LCTL nodemap_activate 0
5713         wait_nm_sync active
5714 }
5715
5716 test_411()
5717 {
5718         local client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
5719         local client_nid=$(h2nettype $client_ip)
5720         local tf1=$DIR/$tdir/fileA
5721         local tf2=$DIR/$tdir/fileB
5722         local nm=test_411
5723         local roles
5724         local fid
5725
5726         do_facet mgs $LCTL nodemap_modify --name default \
5727                 --property admin --value 1
5728         do_facet mgs $LCTL nodemap_modify --name default \
5729                 --property trusted --value 1
5730         do_facet mgs $LCTL nodemap_add $nm
5731         do_facet mgs $LCTL nodemap_add_range    \
5732                 --name $nm --range $client_nid
5733         do_facet mgs $LCTL nodemap_modify --name $nm \
5734                 --property admin --value 1
5735         do_facet mgs $LCTL nodemap_modify --name $nm \
5736                 --property trusted --value 1
5737         do_facet mgs $LCTL nodemap_activate 1
5738         stack_trap "cleanup_411 $nm" EXIT
5739         wait_nm_sync active
5740         wait_nm_sync $nm trusted_nodemap
5741
5742         roles=$(do_facet mds $LCTL get_param -n nodemap.$nm.rbac)
5743         [[ "$roles" =~ "hsm_ops" ]] ||
5744                 skip "role 'hsm_ops' not supported by server"
5745
5746         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5747         echo hi > $tf1 || error "create $tf1 failed"
5748         echo hi > $tf2 || error "create $tf2 failed"
5749
5750         copytool setup
5751
5752         # with hsm_ops role, all ops should pass
5753         fid=$(path2fid $tf1)
5754         $LFS hsm_state $tf1 || error "hsm_state $tf1 failed"
5755         $LFS hsm_archive $tf1 || error "hsm_archive $tf1 failed"
5756         wait_request_state $fid ARCHIVE SUCCEED
5757         $LFS hsm_release $tf1 || error "hsm_release $tf1 failed"
5758         check_hsm_flags $tf1 "0x0000000d"
5759         $LFS hsm_restore $tf1 || error "hsm_restore $tf1 failed"
5760         wait_request_state $fid RESTORE SUCCEED
5761         $LFS hsm_remove $tf1 || error "hsm_remove $tf1 failed"
5762         wait_request_state $fid REMOVE SUCCEED
5763         check_hsm_flags $tf1 "0x00000000"
5764         $LFS hsm_set --exists $tf1 || error "hsm_set $tf1 failed"
5765         check_hsm_flags $tf1 "0x00000001"
5766         $LFS hsm_clear --exists $tf1 || error "hsm_clear $tf1 failed"
5767         check_hsm_flags $tf1 "0x00000000"
5768
5769         # check copytool cleanup works with the hsm_ops rbac role present
5770         # and nodemap activated
5771         kill_copytools
5772         wait_copytools || error "copytool failed to stop"
5773
5774         copytool setup
5775         # Re-add cleanup_411 to the stack to make sure it is always called
5776         # before the copytool is cleaned up.
5777         stack_trap "cleanup_411 $nm" EXIT
5778
5779         # remove hsm_ops from rbac roles
5780         roles=$(echo "$roles" | sed 's/hsm_ops,//;s/,hsm_ops//;s/^hsm_ops,//')
5781         do_facet mgs $LCTL nodemap_modify --name $nm \
5782                 --property rbac --value $roles
5783         wait_nm_sync $nm rbac
5784
5785         # without hsm_ops role, all ops should fail
5786         fid=$(path2fid $tf2)
5787         $LFS hsm_state $tf2 || error "hsm_state $tf2 failed"
5788         $LFS hsm_archive $tf2 && error "hsm_archive $tf2 succeeded"
5789         $LFS hsm_release $tf2 && error "hsm_release $tf2 succeeded"
5790         check_hsm_flags $tf2 "0x00000000"
5791         $LFS hsm_restore $tf2 && error "hsm_restore $tf2 succeeded"
5792         $LFS hsm_remove $tf2 && error "hsm_remove $tf2 succeeded"
5793         check_hsm_flags $tf2 "0x00000000"
5794         $LFS hsm_set --exists $tf2 && error "hsm_set $tf2 succeeded"
5795         check_hsm_flags $tf2 "0x00000000"
5796         $LFS hsm_clear --exists $tf2 && error "hsm_clear $tf2 succeeded"
5797         check_hsm_flags $tf2 "0x00000000"
5798 }
5799 run_test 411 "hsm_ops rbac role"
5800
5801 test_500()
5802 {
5803         local bitmap_opt=""
5804
5805         (( $MDS1_VERSION >= $(version_code 2.6.92-47-g1fe3ae8dab) )) ||
5806                 skip "need MDS >= 2.6.92.47 for HSM migrate support"
5807
5808         test_mkdir -p $DIR/$tdir
5809
5810         (( $CLIENT_VERSION >= $(version_code 2.11.56-179-g3bfb6107ba) &&
5811            $MDS1_VERSION >= $(version_code 2.11.56-179-g3bfb6107ba) )) ||
5812                 bitmap_opt="-b"
5813
5814         (( $MDS1_VERSION >= $(version_code 2.14.50-142-gf684172237) )) ||
5815                 SKIP500+=" -s 113"
5816
5817         llapi_hsm_test -d $DIR/$tdir $bitmap_opt $SKIP500 ||
5818                 error "llapi HSM testing failed"
5819 }
5820 run_test 500 "various LLAPI HSM tests"
5821
5822 test_600() {
5823         [ "$MDS1_VERSION" -lt $(version_code 2.10.58) ] &&
5824                 skip "need MDS version at least 2.10.58"
5825
5826         mkdir -p $DIR/$tdir
5827
5828         local f=$DIR/$tdir/$tfile
5829
5830         changelog_register
5831         # set changelog_mask to ALL
5832         changelog_chmask "ALL"
5833
5834         chmod 777 $DIR/$tdir
5835         $RUNAS touch $f || error "touch $f failed as $RUNAS_ID"
5836         local fid=$(path2fid $f)
5837
5838         local entry
5839         entry=$(changelog_find -type CREAT -target-fid $fid -uid "$RUNAS_ID" \
5840                                -gid "$RUNAS_GID") ||
5841                 error "No matching CREAT entry"
5842
5843         # Parse the changelog
5844         eval local -A changelog=$(changelog2array $entry)
5845         local nid="${changelog[nid]}"
5846
5847         # Check its NID
5848         echo "Got NID '$nid'"
5849         [ -n "$nid" ] && [[ "${CLIENT_NIDS[*]}" =~ $nid ]] ||
5850                 error "nid '$nid' does not match any client NID:" \
5851                       "${CLIENT_NIDS[@]}"
5852 }
5853 run_test 600 "Changelog fields 'u=' and 'nid='"
5854
5855 test_601() {
5856         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
5857                 skip "need MDS version at least 2.10.58"
5858
5859         mkdir -p $DIR/$tdir
5860
5861         local f=$DIR/$tdir/$tfile
5862
5863         changelog_register
5864         # set changelog_mask to ALL
5865         changelog_chmask "ALL"
5866
5867         touch $f || error "touch $f failed"
5868         local fid=$(path2fid $f)
5869
5870         changelog_clear
5871         cat $f || error "cat $f failed"
5872
5873         changelog_find -type OPEN -target-fid $fid -mode "r--" ||
5874                 error "No matching OPEN entry"
5875 }
5876 run_test 601 "OPEN Changelog entry"
5877
5878 test_602() {
5879         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
5880                 skip "need MDS version at least 2.10.58"
5881
5882         stack_trap "restore_opencache" EXIT
5883         disable_opencache
5884
5885         mkdir -p $DIR/$tdir
5886
5887         local f=$DIR/$tdir/$tfile
5888
5889         changelog_register
5890         # set changelog_mask to ALL
5891         changelog_chmask "ALL"
5892
5893         touch $f || error "touch $f failed"
5894         local fid=$(path2fid $f)
5895
5896         changelog_clear
5897         cat $f || error "cat $f failed"
5898
5899         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
5900
5901         changelog_clear
5902         changelog_dump
5903         echo f > $f || error "write $f failed"
5904         changelog_dump
5905
5906         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
5907
5908         # remove OPEN from changelog_mask
5909         changelog_chmask "-OPEN"
5910
5911         changelog_clear
5912         changelog_dump
5913         cat $f || error "cat $f failed"
5914         changelog_dump
5915
5916         changelog_find -type CLOSE -target-fid $fid &&
5917                 error "There should be no CLOSE entry"
5918
5919         changelog_clear
5920         changelog_dump
5921         echo f > $f || error "write $f failed"
5922         changelog_dump
5923
5924         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
5925 }
5926 run_test 602 "Changelog record CLOSE only if open+write or OPEN recorded"
5927
5928 test_603() {
5929         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
5930                 skip "need MDS version at least 2.10.58"
5931
5932         mkdir -p $DIR/$tdir
5933
5934         local f=$DIR/$tdir/$tfile
5935
5936         changelog_register
5937         # set changelog_mask to ALL
5938         changelog_chmask "ALL"
5939
5940         touch $f || error "touch $f failed"
5941         local fid=$(path2fid $f)
5942
5943         setfattr -n user.xattr1 -v "value1" $f || error "setfattr $f failed"
5944
5945         changelog_clear
5946         getfattr -n user.xattr1 $f || error "getfattr $f failed"
5947
5948         changelog_find -type GXATR -target-fid $fid -xattr "user.xattr1" ||
5949                 error "No matching GXATR entry"
5950 }
5951 run_test 603 "GETXATTR Changelog entry"
5952
5953 test_604() {
5954         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
5955                 skip "need MDS version at least 2.10.58"
5956
5957         mkdir_on_mdt0 $DIR/$tdir
5958
5959         local f=$DIR/$tdir/$tfile
5960         local f2=$DIR2/$tdir/$tfile
5961         local procname="mdd.$FSNAME-MDT0000.changelog_deniednext"
5962         local timeout
5963         timeout="$(do_facet mds1 "$LCTL" get_param -n "$procname")"
5964         stack_trap "do_facet mds1 '$LCTL' set_param '$procname=$timeout'" EXIT
5965         do_facet mds1 lctl set_param "$procname=20"
5966
5967
5968         changelog_register
5969         # set changelog_mask to ALL
5970         changelog_chmask "ALL"
5971
5972         touch $f || error "touch $f failed"
5973         local fid=$(path2fid $f)
5974
5975         chmod 600 $f
5976
5977         changelog_clear
5978         changelog_dump
5979         $RUNAS cat $f2 && error "cat $f2 by user $RUNAS_ID should have failed"
5980         changelog_dump
5981
5982         local entry
5983         entry=$(changelog_find -type NOPEN -target-fid $fid -uid "$RUNAS_ID" \
5984                                -gid "$RUNAS_GID" -mode "r--") ||
5985                 error "No matching NOPEN entry"
5986
5987         # Parse the changelog
5988         eval local -A changelog=$(changelog2array $entry)
5989         local nid="${changelog[nid]}"
5990
5991         # Check its NID
5992         echo "Got NID '$nid'"
5993         [ -n "$nid" ] && [[ "${CLIENT_NIDS[*]}" =~ $nid ]] ||
5994                 error "nid '$nid' does not match any client NID:" \
5995                       "${CLIENT_NIDS[@]}"
5996
5997         changelog_clear
5998         changelog_dump
5999         $RUNAS cat $f2 && error "cat $f2 by user $RUNAS_ID should have failed"
6000         changelog_dump
6001
6002         changelog_find -type NOPEN -target-fid $fid &&
6003                 error "There should be no NOPEN entry"
6004
6005         # Sleep for `changelog_deniednext` seconds
6006         sleep 20
6007
6008         changelog_clear
6009         changelog_dump
6010         $RUNAS cat $f2 && error "cat $f by user $RUNAS_ID should have failed"
6011         changelog_dump
6012
6013         entry=$(changelog_find -type NOPEN -target-fid $fid -uid "$RUNAS_ID" \
6014                                -gid "$RUNAS_GID" -mode "r--") ||
6015                 error "No matching NOPEN entry"
6016
6017         # Parse the changelog
6018         eval local -A changelog=$(changelog2array $entry)
6019         local nid="${changelog[nid]}"
6020
6021         # Check the NID
6022         echo "Got NID '$nid'"
6023         [ -n "$nid" ] && [[ "${CLIENT_NIDS[*]}" =~ $nid ]] ||
6024                 error "nid '$nid' does not match any client NID:" \
6025                       "${CLIENT_NIDS[@]}"
6026 }
6027 run_test 604 "NOPEN Changelog entry"
6028
6029 test_605() {
6030         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
6031                 skip "need MDS version at least 2.10.58"
6032
6033         stack_trap "restore_opencache" EXIT
6034         disable_opencache
6035
6036         mkdir -p $DIR/$tdir
6037
6038         local f=$DIR/$tdir/$tfile
6039         local f2=$DIR2/$tdir/$tfile
6040
6041         changelog_register
6042         # set changelog_mask to ALL
6043         changelog_chmask "ALL"
6044
6045         touch $f || error "touch $f failed"
6046         local fid=$(path2fid $f)
6047
6048         changelog_clear
6049         changelog_dump
6050         exec 3<> $f || error "open $f failed"
6051         changelog_dump
6052
6053         local entry
6054         changelog_find -type OPEN -target-fid $fid || error "No OPEN entry"
6055
6056         changelog_clear
6057         changelog_dump
6058         exec 4<> $f || error "open $f failed"
6059         changelog_dump
6060
6061         changelog_find -type OPEN -target-fid $fid &&
6062                 error "There should be no OPEN entry"
6063
6064         exec 4>&- || error "close $f failed"
6065         changelog_dump
6066
6067         changelog_find -type CLOSE -target-fid $fid &&
6068                 error "There should be no CLOSE entry"
6069
6070         changelog_clear
6071         changelog_dump
6072         # access in rw, so different access mode should generate entries
6073         cat $f || error "cat $f failed"
6074         changelog_dump
6075
6076         changelog_find -type OPEN -target-fid $fid || error "No OPEN entry"
6077
6078         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
6079
6080         changelog_clear
6081         changelog_dump
6082         # same access as first one, should not generate new entries
6083         exec 4<> $f || error "open $f failed"
6084         changelog_dump
6085
6086         changelog_find -type OPEN -target-fid $fid &&
6087                 error "There should be no OPEN entry"
6088
6089         exec 4>&- || error "close $f failed"
6090         changelog_dump
6091
6092         changelog_find -type CLOSE -target-fid $fid &&
6093                 error "There should be no CLOSE entry"
6094
6095         changelog_clear
6096         changelog_dump
6097         # access by different user should generate new entries
6098         $RUNAS cat $f || error "cat $f by user $RUNAS_ID failed"
6099         changelog_dump
6100
6101         changelog_find -type OPEN -target-fid $fid || error "No OPEN entry"
6102
6103         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
6104
6105         changelog_clear
6106         changelog_dump
6107         exec 3>&- || error "close $f failed"
6108         changelog_dump
6109
6110         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
6111 }
6112 run_test 605 "Test OPEN and CLOSE rate limit in Changelogs"
6113
6114 test_606() {
6115         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
6116                 skip "need MDS version at least 2.10.58"
6117
6118         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6119         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6120         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6121                         skip_env "missing llog_reader"
6122
6123         mkdir_on_mdt0 $DIR/$tdir
6124
6125         local f=$DIR/$tdir/$tfile
6126
6127         changelog_register
6128         # set changelog_mask to ALL
6129         changelog_chmask "ALL"
6130
6131         chmod 777 $DIR/$tdir
6132         $RUNAS touch $f || error "touch $f failed as $RUNAS_ID"
6133         local fid=$(path2fid $f)
6134         rm $f || error "rm $f failed"
6135
6136         local mntpt=$(facet_mntpt mds1)
6137         local pass=true
6138         local entry
6139
6140         #remount mds1 as ldiskfs or zfs type
6141         stop mds1 || error "stop mds1 failed"
6142         stack_trap "unmount_fstype mds1; start mds1 $(mdsdevname 1)\
6143                 $MDS_MOUNT_OPTS" EXIT
6144         mount_fstype mds1 || error "remount mds1 failed"
6145
6146         for ((i = 0; i < 1; i++)); do
6147                 do_facet mds1 $llog_reader $mntpt/changelog_catalog
6148                 local cat_file=$(do_facet mds1 $llog_reader \
6149                                 $mntpt/changelog_catalog | awk \
6150                                 '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
6151                 [ -n "$cat_file" ] || error "no catalog file"
6152
6153                 entry=$(do_facet mds1 $llog_reader $mntpt/$cat_file |
6154                         awk "/CREAT/ && /target:\[$fid\]/ {print}")
6155                 [ -n "$entry" ] || error "no CREAT entry"
6156         done
6157
6158         local uidgid=$(echo $entry |
6159                 sed 's+.*\ user:\([0-9][0-9]*:[0-9][0-9]*\)\ .*+\1+')
6160         [ -n "$uidgid" ] || error "uidgid is empty"
6161         echo "Got UID/GID $uidgid"
6162         [ "$uidgid" = "$RUNAS_ID:$RUNAS_GID" ] ||
6163                 error "uidgid '$uidgid' != '$RUNAS_ID:$RUNAS_GID'"
6164         local nid=$(echo $entry |
6165                 sed 's+.*\ nid:\(\S\S*@\S\S*\)\ .*+\1+')
6166         [ -n "$nid" ] || error "nid is empty"
6167         echo "Got NID $nid"
6168         [ -n "$nid" ] && [[ "${CLIENT_NIDS[*]}" =~ $nid ]] ||
6169                 error "nid '$nid' does not match any NID ${CLIENT_NIDS[*]}"
6170 }
6171 run_test 606 "llog_reader groks changelog fields"
6172
6173 get_hsm_xattr_sha()
6174 {
6175         getfattr -e text -n trusted.hsm "$1" 2>/dev/null |
6176                 sha1sum | awk '{ print $1 }'
6177 }
6178
6179 test_hsm_migrate_init()
6180 {
6181         local d=$1
6182         local f=$2
6183         local fid
6184
6185         mkdir_on_mdt0 "$d"
6186         fid=$(create_small_file "$f")
6187
6188         echo "$fid"
6189 }
6190
6191 test_607a()
6192 {
6193         local d="$DIR/$tdir"
6194         local f="$d/$tfile"
6195         local fid
6196
6197         (( MDS1_VERSION >= $(version_code 2.15.60) )) ||
6198                 skip "need MDS version at least 2.15.60"
6199
6200         (( OSTCOUNT >= 2 )) || skip_env "needs >= 2 OSTs"
6201
6202         fid=$(test_hsm_migrate_init "$d" "$f" | tail -1)
6203
6204         copytool setup
6205
6206         $LFS hsm_archive "$f" || error "could not archive file"
6207         wait_request_state $fid ARCHIVE SUCCEED
6208
6209         $LFS migrate -n -i 1 "$f" ||
6210                 error "could not migrate file to OST 1"
6211
6212         $LFS hsm_release "$f" ||
6213                 error "could not release file after non blocking migrate"
6214         $LFS hsm_restore "$f" ||
6215                 error "could not restore file after non blocking migrate"
6216         wait_request_state $fid RESTORE SUCCEED
6217 }
6218 run_test 607a "release a file that was migrated after being archived"
6219
6220 test_607b()
6221 {
6222         local d="$DIR/$tdir"
6223         local f="$DIR/$tdir/$tfile"
6224         local saved_params
6225         local old_hsm
6226         local new_hsm
6227         local fid
6228
6229         (( MDS1_VERSION >= $(version_code 2.15.60) )) ||
6230                 skip "need MDS version at least 2.15.60"
6231
6232         (( OSTCOUNT >= 2 )) || skip_env "needs >= 2 OSTs"
6233
6234         fid=$(test_hsm_migrate_init "$d" "$f" | tail -1)
6235
6236         copytool setup
6237
6238         $LFS hsm_archive "$f" || error "could not archive file"
6239         wait_request_state $fid ARCHIVE SUCCEED
6240
6241         saved_params=$($LCTL get_param llite.*.xattr_cache | tr '\n' ' ')
6242         $LCTL set_param llite.*.xattr_cache=0
6243         stack_trap "$LCTL set_param $saved_params" EXIT
6244
6245         # make sure that migrate won't change archive version
6246         echo 10 >> "$f"
6247
6248         old_hsm=$(get_hsm_xattr_sha "$f")
6249         $LFS migrate -n -i 1 "$f" ||
6250                 error "could not migrate file to OST 1"
6251
6252         $LFS hsm_state "$f" | grep dirty || error "dirty flag not found"
6253
6254         new_hsm=$(get_hsm_xattr_sha "$f")
6255         [ "$old_hsm" != "$new_hsm" ] &&
6256                  error "migrate should not modify data version of dirty files"
6257
6258         return 0
6259 }
6260 run_test 607b "Migrate should not change the HSM attribute of dirty files"
6261
6262 test_607c()
6263 {
6264         local d="$DIR/$tdir"
6265         local f="$DIR/$tdir/$tfile"
6266         local fid1 fid2 fid3
6267         local nbr_dirty
6268
6269         (( MDS1_VERSION >= $(version_code 2.15.60) )) ||
6270                 skip "need MDS version at least 2.15.60"
6271
6272         mkdir_on_mdt0 $d
6273         fid1=$(create_small_file "$f-1")
6274         fid2=$(create_small_file "$f-2")
6275         fid3=$(create_small_file "$f-3")
6276
6277         copytool setup
6278
6279         $LFS hsm_archive "$f-1" || error "could not archive file"
6280         wait_request_state $fid1 ARCHIVE SUCCEED
6281
6282         $LFS hsm_archive "$f-3" || error "could not archive file"
6283         wait_request_state $fid3 ARCHIVE SUCCEED
6284
6285         $LFS swap_layouts "$f-1" "$f-3" |& grep "Operation not permitted" ||
6286                 error "swap_layouts should fail with EPERM on 2 archived file"
6287
6288         $LFS swap_layouts "$f-1" "$f-2" ||
6289                 error "swap_layout failed on $f-1 and $f-2"
6290
6291         $LFS swap_layouts "$f-2" "$f-3" ||
6292                 error "swap_layout failed on $f-2 and $f-3"
6293
6294         nbr_dirty=$($LFS hsm_state "$f-1" "$f-3" | grep -c 'dirty')
6295         ((nbr_dirty == 2)) || error "dirty flag should be set on $f-1 and $f-3"
6296
6297 }
6298 run_test 607c "'lfs swap_layouts' should set dirty flag on HSM file"
6299
6300 complete_test $SECONDS
6301 check_and_cleanup_lustre
6302 exit_status