Whamcloud - gitweb
LU-19098 hsm: don't print progname twice with lhsmtool
[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         local huge_num=$((2**60))
2985
2986         stack_trap "set_hsm_param max_requests $max_requests" EXIT
2987         # Increase the number of HSM request that can be performed in
2988         # parallel. With the coordinator running once per second, this
2989         # also limits the number of requests per seconds that can be
2990         # performed, so we pick a decent number. But we also need to keep
2991         # that number low because the copytool has no rate limit and will
2992         # fail some requests if it gets too many at once.
2993         if (( $MDS1_VERSION >= $(version_code v2_16_56-40) )); then
2994                 set_hsm_param max_requests $huge_num &&
2995                         error "set max_requests=$huge_num should failed" ||
2996                         echo "set max_requests=$huge_num failed with $?"
2997
2998                 tmp_reqs=$(get_hsm_param max_requests)
2999                 (( $tmp_reqs < $huge_num && $tmp_reqs > $max_requests )) ||
3000                         error "Should set max_requests to be a reasonable value"
3001                 do_facet mds1 "dmesg | tail -n 5 | grep 'to set HSM max_requests='" ||
3002                         true
3003         fi
3004         set_hsm_param max_requests 300
3005
3006         for i in $(seq 1 $file_count); do
3007                 for p in $(seq 1 $stream_count); do
3008                         fid=$(copy_file /etc/hosts $f.$p.$i)
3009                 done
3010         done
3011
3012         copytool setup
3013
3014         # to be sure wait_all_done will not be mislead by previous tests
3015         cdt_purge
3016         wait_for_grace_delay
3017         typeset -a pids
3018         # start archive streams in background (archive files in parallel)
3019         for p in $(seq 1 $stream_count); do
3020                 multi_archive $f.$p $file_count &
3021                 pids[$p]=$!
3022         done
3023         echo -n  "Wait for all requests being enqueued..."
3024         wait ${pids[*]}
3025         echo OK
3026         wait_all_done 100
3027 }
3028 run_test 40 "Parallel archive requests"
3029
3030 hsm_archive_batch() {
3031         local files_num=$1
3032         local batch_max=$2
3033         local filebase=$3
3034         local batch_num=0
3035         local fileset=""
3036         local i=0
3037
3038         while [ $i -lt $files_num ]; do
3039                 if [ $batch_num -eq $batch_max ]; then
3040                         $LFS hsm_archive $fileset || error "HSM archive failed"
3041                         # Reset the batch container.
3042                         fileset=""
3043                         batch_num=0
3044                 fi
3045
3046                 fileset+="${filebase}$i "
3047                 batch_num=$(( batch_num + 1 ))
3048                 i=$(( i + 1 ))
3049         done
3050
3051         if [ $batch_num -ne 0 ]; then
3052                 $LFS hsm_archive $fileset || error "HSM archive failed"
3053                 fileset=""
3054                 batch_num=0
3055         fi
3056 }
3057
3058 test_50() {
3059         local dir=$DIR/$tdir
3060         local batch_max=50
3061
3062         stack_trap "set_hsm_param max_requests $(get_hsm_param max_requests)"
3063         set_hsm_param max_requests 1000000
3064         mkdir $dir || error "mkdir $dir failed"
3065         df -i $MOUNT
3066
3067         local start
3068         local elapsed
3069         local files_num
3070         local filebase
3071
3072         files_num=10000
3073         filebase="$dir/$tfile.start."
3074         createmany -m $filebase $files_num ||
3075                 error "createmany -m $filebase failed: $?"
3076
3077         start=$SECONDS
3078         hsm_archive_batch $files_num $batch_max "$filebase"
3079         elapsed=$((SECONDS - start))
3080         do_facet $SINGLEMDS "$LCTL get_param -n \
3081                  $HSM_PARAM.actions | grep WAITING | wc -l"
3082         unlinkmany $filebase $files_num || error "unlinkmany $filabase failed"
3083         echo "Start Phase files_num: $files_num time: $elapsed"
3084
3085         files_num=20000
3086         filebase="$dir/$tfile.in."
3087         createmany -m $filebase $files_num ||
3088                 error "createmany -m $filebase failed: $?"
3089         start=$SECONDS
3090         hsm_archive_batch  $files_num $batch_max "$filebase"
3091         elapsed=$((SECONDS - start))
3092         unlinkmany $filebase $files_num || error "unlinkmany $filabase failed"
3093         echo "Middle Phase files_num: $files_num time: $elapsed"
3094
3095         files_num=10000
3096         filebase="$dir/$tfile.end."
3097         createmany -m $filebase $files_num ||
3098                 error "createmany -m $filebase failed: $?"
3099
3100         start=$SECONDS
3101         hsm_archive_batch $files_num $batch_max "$filebase"
3102         elapsed=$((SECONDS - start))
3103         do_facet $SINGLEMDS "$LCTL get_param -n \
3104                  $HSM_PARAM.actions | grep WAITING | wc -l"
3105
3106         unlinkmany $filebase $files_num || error "unlinkmany $filebase failed"
3107         echo "End Phase files_num: $files_num time: $elapsed"
3108
3109         do_facet $SINGLEMDS "$LCTL get_param -n \
3110                  $HSM_PARAM.actions | grep WAITING | wc -l"
3111
3112         cdt_purge
3113 }
3114 run_test 50 "Archive with large number of pending HSM actions"
3115
3116 test_52() {
3117         # test needs a running copytool
3118         copytool setup
3119
3120         mkdir_on_mdt0 $DIR/$tdir
3121         local f=$DIR/$tdir/$tfile
3122         local fid=$(create_small_file $f)
3123
3124         $LFS hsm_archive $f || error "could not archive file"
3125         wait_request_state $fid ARCHIVE SUCCEED
3126         check_hsm_flags $f "0x00000009"
3127
3128         multiop_bg_pause $f O_c || error "multiop failed"
3129         local MULTIPID=$!
3130
3131         mds_evict_client
3132         client_up || client_up || true
3133
3134         kill -USR1 $MULTIPID
3135         wait $MULTIPID || error "multiop close failed"
3136
3137         check_hsm_flags $f "0x0000000b"
3138 }
3139 run_test 52 "Opened for write file on an evicted client should be set dirty"
3140
3141 test_53() {
3142         # test needs a running copytool
3143         copytool setup
3144
3145         mkdir_on_mdt0 $DIR/$tdir
3146         local f=$DIR/$tdir/$tfile
3147         local fid=$(create_small_file $f)
3148
3149         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3150                 error "could not archive file"
3151         wait_request_state $fid ARCHIVE SUCCEED
3152         check_hsm_flags $f "0x00000009"
3153
3154         multiop_bg_pause $f o_c || error "multiop failed"
3155         MULTIPID=$!
3156
3157         mds_evict_client
3158         client_up || client_up || true
3159
3160         kill -USR1 $MULTIPID
3161         wait $MULTIPID || error "multiop close failed"
3162
3163         check_hsm_flags $f "0x00000009"
3164 }
3165 run_test 53 "Opened for read file on an evicted client should not be set dirty"
3166
3167 test_54() {
3168         mkdir_on_mdt0 $DIR/$tdir
3169
3170         local f=$DIR/$tdir/$tfile
3171         local fid=$(create_file "$f" 1MB 39)
3172
3173         copytool setup -b 1
3174
3175         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3176                 error "could not archive file"
3177         wait_request_state $fid ARCHIVE STARTED
3178
3179         check_hsm_flags $f "0x00000001"
3180
3181         stack_trap "cdt_clear_no_retry" EXIT
3182         # Avoid coordinator resending this request as soon it has failed.
3183         cdt_set_no_retry
3184
3185         echo "foo" >> $f
3186         sync
3187         wait_request_state $fid ARCHIVE FAILED
3188
3189         check_hsm_flags $f "0x00000003"
3190 }
3191 run_test 54 "Write during an archive cancels it"
3192
3193 test_55() {
3194         mkdir_on_mdt0 $DIR/$tdir
3195
3196         local f=$DIR/$tdir/$tfile
3197         local fid=$(create_file "$f" 1MB 39)
3198
3199         copytool setup -b 1
3200
3201         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3202                 error "could not archive file"
3203         wait_request_state $fid ARCHIVE STARTED
3204
3205         check_hsm_flags $f "0x00000001"
3206
3207         stack_trap "cdt_clear_no_retry" EXIT
3208         # Avoid coordinator resending this request as soon it has failed.
3209         cdt_set_no_retry
3210
3211         $TRUNCATE $f 1024 || error "truncate failed"
3212         sync
3213         wait_request_state $fid ARCHIVE FAILED
3214
3215         check_hsm_flags $f "0x00000003"
3216 }
3217 run_test 55 "Truncate during an archive cancels it"
3218
3219 test_56() {
3220         mkdir_on_mdt0 $DIR/$tdir
3221
3222         local f=$DIR/$tdir/$tfile
3223         local fid=$(create_file "$f" 1MB 39)
3224
3225         copytool setup -b 1
3226
3227         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3228                 error "could not archive file"
3229         wait_request_state $fid ARCHIVE STARTED
3230
3231         check_hsm_flags $f "0x00000001"
3232
3233         # Change metadata and sync to be sure we are not changing only
3234         # in memory.
3235         chmod 644 $f
3236         chgrp sys $f
3237         sync
3238         wait_request_state $fid ARCHIVE SUCCEED
3239
3240         check_hsm_flags $f "0x00000009"
3241 }
3242 run_test 56 "Setattr during an archive is ok"
3243
3244 test_57() {
3245         # Need one client for I/O, one for request
3246         needclients 2 || return 0
3247
3248         # test needs a running copytool
3249         copytool setup
3250
3251         mkdir_on_mdt0 $DIR/$tdir
3252         local f=$DIR/$tdir/test_archive_remote
3253         # Create a file on a remote node
3254         do_node $CLIENT2 "dd if=/dev/urandom of=$f bs=1M "\
3255                 "count=2 conv=fsync"
3256
3257         # And archive it
3258         do_node $CLIENT2 "$LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $f" ||
3259                 error "hsm_archive failed"
3260         local fid=$(path2fid $f)
3261         wait_request_state $fid ARCHIVE SUCCEED
3262
3263         # Release and implicit restore it
3264         do_node $CLIENT2 "$LFS hsm_release $f" ||
3265                 error "hsm_release failed"
3266         do_node $CLIENT2 "md5sum $f" ||
3267                 error "hsm_restore failed"
3268
3269         wait_request_state $fid RESTORE SUCCEED
3270 }
3271 run_test 57 "Archive a file with dirty cache on another node"
3272
3273 truncate_released_file() {
3274         local src_file=$1
3275         local trunc_to=$2
3276
3277         local sz=$(stat -c %s $src_file)
3278         local f=$DIR/$tdir/$tfile
3279         local fid=$(copy_file $1 $f)
3280         local ref=$f-ref
3281         cp $f $f-ref
3282
3283         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3284                 error "could not archive file"
3285         wait_request_state $fid ARCHIVE SUCCEED
3286
3287         $LFS hsm_release $f || error "could not release file"
3288
3289         $TRUNCATE $f $trunc_to || error "truncate failed"
3290         sync
3291
3292         local sz1=$(stat -c %s $f)
3293         [[ $sz1 == $trunc_to ]] ||
3294                 error "size after trunc: $sz1 expect $trunc_to, original $sz"
3295
3296         $LFS hsm_state $f
3297         check_hsm_flags $f "0x0000000b"
3298
3299         local state=$(get_request_state $fid RESTORE)
3300         [[ "$state" == "SUCCEED" ]] ||
3301                 error "truncate $sz does not trig restore, state = $state"
3302
3303         $TRUNCATE $ref $trunc_to
3304         cmp $ref $f || error "file data wrong after truncate"
3305
3306         rm -f $f $f-ref
3307 }
3308
3309 test_58() {
3310         # test needs a running copytool
3311         copytool setup
3312
3313         mkdir_on_mdt0 $DIR/$tdir
3314
3315         local sz=$(stat -c %s /etc/passwd)
3316
3317         echo "truncate up from $sz to $((sz*2))"
3318         truncate_released_file /etc/passwd $((sz*2))
3319
3320         echo "truncate down from $sz to $((sz/2))"
3321         truncate_released_file /etc/passwd $((sz/2))
3322
3323         echo "truncate to 0"
3324         truncate_released_file /etc/passwd 0
3325 }
3326 run_test 58 "Truncate a released file will trigger restore"
3327
3328 test_59() {
3329         local fid
3330         [[ $MDS1_VERSION -lt $(version_code 2.7.63) ]] &&
3331                 skip "Need MDS version at least 2.7.63"
3332
3333         copytool setup
3334         $MCREATE $DIR/$tfile || error "mcreate failed"
3335         $TRUNCATE $DIR/$tfile 42 || error "truncate failed"
3336         $LFS hsm_archive $DIR/$tfile || error "archive request failed"
3337         fid=$(path2fid $DIR/$tfile)
3338         wait_request_state $fid ARCHIVE SUCCEED
3339         $LFS hsm_release $DIR/$tfile || error "release failed"
3340 }
3341 run_test 59 "Release stripeless file with non-zero size"
3342
3343 test_60() {
3344         # This test validates the fix for LU-4512. Ensure that the -u
3345         # option changes the progress reporting interval from the
3346         # default (30 seconds) to the user-specified interval.
3347         mkdir_on_mdt0 $DIR/$tdir
3348
3349         local f=$DIR/$tdir/$tfile
3350         local fid=$(create_file "$f" 1M 10)
3351
3352         local interval=5
3353         local progress_timeout=$((interval * 4))
3354         copytool setup -b 1 --update-interval $interval
3355
3356         local mdtidx=0
3357         local mdt=${MDT_PREFIX}${mdtidx}
3358         local mds=mds$((mdtidx + 1))
3359
3360         # Wait for copytool to register
3361         wait_update_facet $mds \
3362                 "$LCTL get_param -n ${mdt}.hsm.agents | grep -o ^uuid" \
3363                 uuid 100 || error "coyptool failed to register with $mdt"
3364
3365         local start_at=$(date +%s)
3366         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3367                 error "could not archive file"
3368
3369         local agent=$(facet_active_host $SINGLEAGT)
3370         local logfile=$(copytool_logfile $SINGLEAGT)
3371
3372         wait_update $agent \
3373             "grep -o start.copy \"$logfile\"" "start copy" 100 ||
3374                 error "copytool failed to start"
3375
3376         local cmd="$LCTL get_param -n ${mdt}.hsm.active_requests"
3377         cmd+=" | awk '/'$fid'.*action=ARCHIVE/ {print \\\$12}' | cut -f2 -d="
3378
3379         local RESULT
3380         local WAIT=0
3381         local sleep=1
3382
3383         echo -n "Expecting a progress update within $progress_timeout seconds... "
3384         while true; do
3385                 RESULT=$(do_node $(facet_active_host $mds) "$cmd")
3386                 if [ -n "$RESULT" ] && [ "$RESULT" -gt 0 ]; then
3387                         echo "$RESULT bytes copied in $WAIT seconds."
3388                         break
3389                 elif [ $WAIT -ge $progress_timeout ]; then
3390                         error "Timed out waiting for progress update!"
3391                         break
3392                 fi
3393                 WAIT=$((WAIT + sleep))
3394                 sleep $sleep
3395         done
3396
3397         local finish_at=$(date +%s)
3398         local elapsed=$((finish_at - start_at))
3399
3400         # Ensure that the progress update occurred within the expected window.
3401         if [ $elapsed -lt $((interval - 1)) ]; then
3402                 error "Expected progress update after at least $interval seconds"
3403         fi
3404
3405         echo "Wait for on going archive hsm action to complete"
3406         wait_update $agent "grep -o copied \"$logfile\"" "copied" 10 ||
3407                 echo "File archiving not completed even after 10 secs"
3408 }
3409 run_test 60 "Changing progress update interval from default"
3410
3411 test_61() {
3412         # test needs a running copytool
3413         copytool setup
3414
3415         mkdir_on_mdt0 $DIR/$tdir
3416         local f=$DIR/$tdir/$tfile
3417         local fid=$(copy_file /etc/passwd $f)
3418         cdt_disable
3419         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3420         rm -f $f
3421         cdt_enable
3422         wait_request_state $fid ARCHIVE FAILED
3423 }
3424 run_test 61 "Waiting archive of a removed file should fail"
3425
3426 test_70() {
3427         # test needs a new running copytool
3428         stack_trap copytool_monitor_cleanup EXIT
3429         copytool_monitor_setup
3430         copytool setup --event-fifo "$HSMTOOL_MONITOR_DIR/fifo"
3431
3432         # Wait for the copytool to register.
3433         wait_update --verbose $(facet_active_host mds1) \
3434                 "$LCTL get_param -n ${MDT_PREFIX}0.hsm.agents | grep -o ^uuid" \
3435                 uuid 100 ||
3436                 error "copytool failed to register with MDT0000"
3437
3438         kill_copytools
3439         wait_copytools || error "Copytools failed to stop"
3440
3441         local REGISTER_EVENT
3442         local UNREGISTER_EVENT
3443         while read event; do
3444                 local parsed=$(parse_json_event "$event")
3445                 if [ -z "$parsed" ]; then
3446                         error "Copytool sent malformed event: $event"
3447                 fi
3448                 eval $parsed
3449
3450                 if [ $event_type == "REGISTER" ]; then
3451                         REGISTER_EVENT=$event
3452                 elif [ $event_type == "UNREGISTER" ]; then
3453                         UNREGISTER_EVENT=$event
3454                 fi
3455         done < <(echo $"$(get_copytool_event_log)")
3456
3457         if [ -z "$REGISTER_EVENT" ]; then
3458                 error "Copytool failed to send register event to FIFO"
3459         fi
3460
3461         if [ -z "$UNREGISTER_EVENT" ]; then
3462                 error "Copytool failed to send unregister event to FIFO"
3463         fi
3464
3465         echo "Register/Unregister events look OK."
3466 }
3467 run_test 70 "Copytool logs JSON register/unregister events to FIFO"
3468
3469 test_71() {
3470         # Bump progress interval for livelier events.
3471         local interval=5
3472
3473         # test needs a new running copytool
3474         stack_trap copytool_monitor_cleanup EXIT
3475         copytool_monitor_setup
3476         copytool setup --update-interval $interval --event-fifo \
3477                 "$HSMTOOL_MONITOR_DIR/fifo"
3478
3479         stack_trap "cdt_clear_no_retry" EXIT
3480         # Just start and stop the copytool to generate events.
3481         cdt_clear_no_retry
3482
3483         mkdir_on_mdt0 $DIR/$tdir
3484
3485         local f=$DIR/$tdir/$tfile
3486         local fid=$(create_small_file "$f")
3487
3488         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3489                 error "could not archive file"
3490         wait_request_state $fid ARCHIVE SUCCEED
3491
3492         local expected_fields="event_time data_fid source_fid"
3493         expected_fields+=" total_bytes current_bytes"
3494
3495         local -A events=(
3496                 [ARCHIVE_START]=false
3497                 [ARCHIVE_FINISH]=false
3498                 [ARCHIVE_RUNNING]=false
3499                 )
3500         while read event; do
3501                 # Make sure we're not getting anything from previous events.
3502                 for field in $expected_fields; do
3503                         unset $field
3504                 done
3505
3506                 local parsed=$(parse_json_event "$event")
3507                 if [ -z "$parsed" ]; then
3508                         error "Copytool sent malformed event: $event"
3509                 fi
3510                 eval $parsed
3511
3512                 events["$event_type"]=true
3513
3514                 [ "$event_type" != ARCHIVE_RUNNING ] && continue
3515
3516                 # Do some simple checking of the progress update events.
3517                 for expected_field in $expected_fields; do
3518                         if [ -z ${!expected_field+x} ]; then
3519                                 error "Missing $expected_field field in event"
3520                         fi
3521                 done
3522
3523                 [ $total_bytes -gt 0 ] || error "Expected total_bytes to be > 0"
3524
3525                 # These should be identical throughout an archive operation
3526                 [ $source_fid == $data_fid ] ||
3527                         error "Expected source_fid to equal data_fid"
3528         done < <(echo $"$(get_copytool_event_log)")
3529
3530         # Check we received every type of events we were expecting
3531         for event in "${!events[@]}"; do
3532                 ${events["$event"]} ||
3533                         error "Copytool failed to send '$event' event to FIFO"
3534         done
3535
3536         echo "Archive events look OK."
3537 }
3538 run_test 71 "Copytool logs JSON archive events to FIFO"
3539
3540 test_72() {
3541         # Bump progress interval for livelier events.
3542         local interval=5
3543
3544         # test needs a new running copytool
3545         stack_trap copytool_monitor_cleanup EXIT
3546         copytool_monitor_setup
3547         copytool setup --update-interval $interval --event-fifo \
3548                 "$HSMTOOL_MONITOR_DIR/fifo"
3549         local test_file=$HSMTOOL_MONITOR_DIR/file
3550
3551         local cmd="dd if=/dev/urandom of=$test_file count=16 bs=1000000 "
3552         cmd+="conv=fsync"
3553         do_facet $SINGLEAGT "$cmd" ||
3554                 error "cannot create $test_file on $SINGLEAGT"
3555         copy2archive $test_file $tdir/$tfile
3556
3557         mkdir_on_mdt0 $DIR/$tdir
3558         local f=$DIR/$tdir/$tfile
3559         copytool import $tdir/$tfile $f
3560         f=$DIR2/$tdir/$tfile
3561         echo "Verifying released state: "
3562         check_hsm_flags $f "0x0000000d"
3563
3564         local fid=$(path2fid $f)
3565         $LFS hsm_restore $f
3566         wait_request_state $fid RESTORE SUCCEED
3567
3568         local expected_fields="event_time data_fid source_fid"
3569         expected_fields+=" total_bytes current_bytes"
3570
3571         local START_EVENT
3572         local FINISH_EVENT
3573         while read event; do
3574                 # Make sure we're not getting anything from previous events.
3575                 for field in $expected_fields; do
3576                         unset $field
3577                 done
3578
3579                 local parsed=$(parse_json_event "$event")
3580                 if [ -z "$parsed" ]; then
3581                         error "Copytool sent malformed event: $event"
3582                 fi
3583                 eval $parsed
3584
3585                 if [ $event_type == "RESTORE_START" ]; then
3586                         START_EVENT=$event
3587                         if [ $source_fid != $data_fid ]; then
3588                                 error "source_fid should == data_fid at start"
3589                         fi
3590                         continue
3591                 elif [ $event_type == "RESTORE_FINISH" ]; then
3592                         FINISH_EVENT=$event
3593                         if [ $source_fid != $data_fid ]; then
3594                                 error "source_fid should == data_fid at finish"
3595                         fi
3596                         continue
3597                 elif [ $event_type != "RESTORE_RUNNING" ]; then
3598                         continue
3599                 fi
3600
3601                 # Do some simple checking of the progress update events.
3602                 for expected_field in $expected_fields; do
3603                         if [ -z ${!expected_field+x} ]; then
3604                                 error "Missing $expected_field field in event"
3605                         fi
3606                 done
3607
3608                 if [ $total_bytes -eq 0 ]; then
3609                         error "Expected total_bytes to be > 0"
3610                 fi
3611
3612                 # When a restore starts out, the data fid is the same as the
3613                 # source fid. After the restore has gotten going, we learn
3614                 # the new data fid. Once the restore has finished, the source
3615                 # fid is set to the new data fid.
3616                 #
3617                 # We test this because some monitoring software may depend on
3618                 # this behavior. If it changes, then the consumers of these
3619                 # events may need to be modified.
3620                 if [ $source_fid == $data_fid ]; then
3621                         error "source_fid should != data_fid during restore"
3622                 fi
3623         done < <(echo $"$(get_copytool_event_log)")
3624
3625         if [ -z "$START_EVENT" ]; then
3626                 error "Copytool failed to send restore start event to FIFO"
3627         fi
3628
3629         if [ -z "$FINISH_EVENT" ]; then
3630                 error "Copytool failed to send restore finish event to FIFO"
3631         fi
3632
3633         echo "Restore events look OK."
3634 }
3635 run_test 72 "Copytool logs JSON restore events to FIFO"
3636
3637 test_90() {
3638         file_count=51 # Max number of files constrained by LNET message size
3639         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
3640         local f=$DIR/$tdir/$tfile
3641         local FILELIST=/tmp/filelist.txt
3642         local i=""
3643
3644         rm -f $FILELIST
3645         for i in $(seq 1 $file_count); do
3646                 fid=$(copy_file /etc/hosts $f.$i)
3647                 echo $f.$i >> $FILELIST
3648         done
3649
3650         copytool setup
3651         # to be sure wait_all_done will not be mislead by previous tests
3652         cdt_purge
3653         wait_for_grace_delay
3654         $LFS hsm_archive --filelist $FILELIST ||
3655                 error "cannot archive a file list"
3656         wait_all_done 200
3657         $LFS hsm_release --filelist $FILELIST ||
3658                 error "cannot release a file list"
3659         $LFS hsm_restore --filelist $FILELIST ||
3660                 error "cannot restore a file list"
3661         wait_all_done 200
3662 }
3663 run_test 90 "Archive/restore a file list"
3664
3665 double_verify_reset_hsm_param() {
3666         local p=$1
3667         echo "Testing $HSM_PARAM.$p"
3668         local val=$(get_hsm_param $p)
3669         local save=$val
3670         local val2=$(($val * 2))
3671
3672         stack_trap "set_hsm_param $p $save"
3673         set_hsm_param $p $val2
3674         val=$(get_hsm_param $p)
3675         [[ $val == $val2 ]] ||
3676                 error "$HSM_PARAM.$p: $val != $val2 should be (2 * $save)"
3677         echo "Set $p to 0 must failed"
3678         set_hsm_param $p 0
3679         local rc=$?
3680         # restore value
3681         set_hsm_param $p $save
3682
3683         if [[ $rc == 0 ]]; then
3684                 error "we must not be able to set $HSM_PARAM.$p to 0"
3685         fi
3686 }
3687
3688 test_100() {
3689         double_verify_reset_hsm_param loop_period
3690         double_verify_reset_hsm_param grace_delay
3691         double_verify_reset_hsm_param active_request_timeout
3692         double_verify_reset_hsm_param max_requests
3693         double_verify_reset_hsm_param default_archive_id
3694 }
3695 run_test 100 "Set coordinator /proc tunables"
3696
3697 test_102() {
3698         cdt_disable
3699         cdt_enable
3700         cdt_restart
3701 }
3702 run_test 102 "Verify coordinator control"
3703
3704 test_103() {
3705         # test needs a running copytool
3706         copytool setup
3707
3708         local i=""
3709         local fid=""
3710
3711         mkdir -p $DIR/$tdir
3712         for i in $(seq 1 20); do
3713                 fid=$(copy_file /etc/passwd $DIR/$tdir/$i)
3714         done
3715         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/*
3716
3717         cdt_purge
3718
3719         echo "Current requests"
3720         local res=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3721                         $HSM_PARAM.actions |\
3722                         grep -v CANCELED | grep -v SUCCEED | grep -v FAILED")
3723
3724         [[ -z "$res" ]] || error "Some request have not been canceled"
3725 }
3726 run_test 103 "Purge all requests"
3727
3728 test_103a() {
3729         (( MDS1_VERSION >= $(version_code 2.14.56) )) ||
3730                 skip "Need MDS version at least 2.14.56"
3731
3732         cdt_clear_non_blocking_restore
3733
3734         # test needs a running copytool
3735         copytool setup
3736
3737         local -a fids=()
3738         local i
3739         local rpcs_inflight=$($LCTL get_param -n \
3740                 "mdc.$(facet_svc mds1)*.max_rpcs_in_flight" |
3741                 head -n1)
3742
3743         mkdir_on_mdt0 $DIR/$tdir
3744         for ((i=0; i < rpcs_inflight; i++)); do
3745                 fids+=( $(copy_file /etc/passwd $DIR/$tdir/${tfile}_$i) )
3746         done
3747         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/*
3748
3749         local time=0
3750         local cnt=0
3751         local grep_regex="($(tr ' ' '|' <<< "${fids[*]}")).*action=ARCHIVE.*status=SUCCEED"
3752         echo $grep_regex
3753         while [[ $time -lt 5 ]] && [[ $cnt -ne ${#fids[@]} ]]; do
3754                 cnt=$(do_facet mds1 "$LCTL get_param -n $HSM_PARAM.actions |
3755                         grep -c -E '$grep_regex'")
3756                 sleep 1
3757                 ((++time))
3758         done
3759         [[ $cnt -eq ${#fids[@]} ]] || error "Fail to archive files $cnt/${#fids[@]}"
3760
3761         $LFS hsm_release $DIR/$tdir/*
3762
3763         kill_copytools
3764         wait_copytools || error "Copytool failed to stop"
3765
3766         local -a pids=()
3767         for i in "${fids[@]}"; do
3768                 cat $DIR/.lustre/fid/$i > /dev/null & pids+=($!)
3769         done
3770
3771         cdt_purge
3772         grep_regex="($(tr ' ' '|' <<< "${fids[*]}")).*action=RESTORE.*status=CANCELED"
3773         cnt=$(do_facet mds1 "$LCTL get_param -n $HSM_PARAM.actions |
3774                 grep -cE '$grep_regex'")
3775
3776         [[ "$cnt" -eq ${#fids[@]} ]] ||
3777                 error "Some request have not been canceled ($cnt/${#fids[@]} canceled)"
3778
3779         # cat cmds should not hang and should fail
3780         for i in "${!pids[@]}"; do
3781                 wait ${pids[$i]} &&
3782                         error "Restore for ${tfile}_$i (${pids[$i]}) should fail" ||
3783                         true
3784         done
3785 }
3786 run_test 103a "Purge pending restore requests"
3787
3788 DATA=CEA
3789 DATAHEX='[434541]'
3790 test_104() {
3791         mkdir_on_mdt0 $DIR/$tdir
3792
3793         local f=$DIR/$tdir/$tfile
3794         local fid=$(create_empty_file "$f")
3795
3796         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER --data $DATA $f
3797         local data1=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3798                         $HSM_PARAM.actions |\
3799                         grep $fid | cut -f16 -d=")
3800
3801         [[ "$data1" == "$DATAHEX" ]] ||
3802                 error "Data field in records is ($data1) and not ($DATAHEX)"
3803
3804         cdt_purge
3805 }
3806 run_test 104 "Copy tool data field"
3807
3808 test_105() {
3809         local max_requests=$(get_hsm_param max_requests)
3810         mkdir_on_mdt0 $DIR/$tdir
3811         local i=""
3812
3813         stack_trap "set_hsm_param max_requests $max_requests" EXIT
3814         set_hsm_param max_requests 300
3815
3816         cdt_disable
3817         for i in $(seq -w 1 10); do
3818                 cp /etc/passwd $DIR/$tdir/$i
3819                 $LFS hsm_archive $DIR/$tdir/$i
3820         done
3821         local reqcnt1=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3822                         $HSM_PARAM.actions |\
3823                         grep WAITING | wc -l")
3824         cdt_restart
3825
3826         cdt_disable
3827         local reqcnt2=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3828                         $HSM_PARAM.actions |\
3829                         grep WAITING | wc -l")
3830         cdt_enable
3831         cdt_purge
3832         [[ "$reqcnt1" == "$reqcnt2" ]] ||
3833                 error "Requests count after shutdown $reqcnt2 != "\
3834                       "before shutdown $reqcnt1"
3835 }
3836 run_test 105 "Restart of coordinator"
3837
3838 test_106() {
3839         # test needs a running copytool
3840         copytool setup
3841
3842         local uuid=$(get_agent_uuid $(facet_active_host $SINGLEAGT))
3843
3844         check_agent_registered $uuid
3845
3846         search_copytools || error "No copytool found"
3847
3848         kill_copytools
3849         wait_copytools || error "Copytool failed to stop"
3850
3851         check_agent_unregistered $uuid
3852
3853         copytool setup
3854         uuid=$(get_agent_uuid $(facet_active_host $SINGLEAGT))
3855         check_agent_registered $uuid
3856 }
3857 run_test 106 "Copytool register/unregister"
3858
3859 test_107() {
3860         [ "$CLIENTONLY" ] && skip "CLIENTONLY mode" && return
3861
3862         # test needs a running copytool
3863         copytool setup
3864         # create and archive file
3865         mkdir_on_mdt0 $DIR/$tdir
3866         local f1=$DIR/$tdir/$tfile
3867         local fid=$(copy_file /etc/passwd $f1)
3868         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1
3869         wait_request_state $fid ARCHIVE SUCCEED
3870         # shutdown and restart MDS
3871         fail $SINGLEMDS
3872         # check the copytool still gets messages from MDT
3873         local f2=$DIR/$tdir/2
3874         local fid=$(copy_file /etc/passwd $f2)
3875         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f2
3876         # main check of this sanity: this request MUST succeed
3877         wait_request_state $fid ARCHIVE SUCCEED
3878 }
3879 run_test 107 "Copytool re-register after MDS restart"
3880
3881 policy_set_and_test()
3882 {
3883         local change="$1"
3884         local target="$2"
3885         do_facet $SINGLEMDS $LCTL set_param "$HSM_PARAM.policy=\\\"$change\\\""
3886         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
3887         [[ "$policy" == "$target" ]] ||
3888                 error "Wrong policy after '$change': '$policy' != '$target'"
3889 }
3890
3891 test_109() {
3892         # to force default policy setting if error
3893         CDT_POLICY_HAD_CHANGED=true
3894
3895         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
3896         local default="NonBlockingRestore [NoRetryAction]"
3897         [[ "$policy" == "$default" ]] ||
3898                 error "default policy has changed,"\
3899                       " '$policy' != '$default' update the test"
3900         policy_set_and_test "+NBR" "[NonBlockingRestore] [NoRetryAction]"
3901         policy_set_and_test "+NRA" "[NonBlockingRestore] [NoRetryAction]"
3902         policy_set_and_test "-NBR" "NonBlockingRestore [NoRetryAction]"
3903         policy_set_and_test "-NRA" "NonBlockingRestore NoRetryAction"
3904         policy_set_and_test "NRA NBR" "[NonBlockingRestore] [NoRetryAction]"
3905         # useless bacause we know but safer for futur changes to use real value
3906         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
3907         echo "Next set_param must failed"
3908         policy_set_and_test "wrong" "$policy"
3909
3910         # return to default
3911         echo "Back to default policy"
3912         cdt_set_sanity_policy
3913 }
3914 run_test 109 "Policy display/change"
3915
3916 test_110a() {
3917         # test needs a running copytool
3918         copytool setup
3919
3920         mkdir_on_mdt0 $DIR/$tdir
3921
3922         copy2archive /etc/passwd $tdir/$tfile
3923
3924         local f=$DIR/$tdir/$tfile
3925         copytool import $tdir/$tfile $f
3926         local fid=$(path2fid $f)
3927
3928         cdt_set_non_blocking_restore
3929         md5sum $f
3930         local st=$?
3931
3932         # cleanup
3933         wait_request_state $fid RESTORE SUCCEED
3934         cdt_clear_non_blocking_restore
3935
3936         # Test result
3937         [[ $st == 1 ]] ||
3938                 error "md5sum returns $st != 1, "\
3939                         "should also perror ENODATA (No data available)"
3940 }
3941 run_test 110a "Non blocking restore policy (import case)"
3942
3943 test_110b() {
3944         # test needs a running copytool
3945         copytool setup
3946
3947         mkdir_on_mdt0 $DIR/$tdir
3948         local f=$DIR/$tdir/$tfile
3949         local fid=$(copy_file /etc/passwd $f)
3950         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3951         wait_request_state $fid ARCHIVE SUCCEED
3952         $LFS hsm_release $f
3953
3954         cdt_set_non_blocking_restore
3955         md5sum $f
3956         local st=$?
3957
3958         # cleanup
3959         wait_request_state $fid RESTORE SUCCEED
3960         cdt_clear_non_blocking_restore
3961
3962         # Test result
3963         [[ $st == 1 ]] ||
3964                 error "md5sum returns $st != 1, "\
3965                         "should also perror ENODATA (No data available)"
3966 }
3967 run_test 110b "Non blocking restore policy (release case)"
3968
3969 test_111a() {
3970         # test needs a running copytool
3971         copytool setup
3972
3973         mkdir_on_mdt0 $DIR/$tdir
3974         copy2archive /etc/passwd $tdir/$tfile
3975
3976         local f=$DIR/$tdir/$tfile
3977
3978         copytool import $tdir/$tfile $f
3979         local fid=$(path2fid $f)
3980
3981         cdt_set_no_retry
3982
3983         copytool_remove_backend $fid
3984
3985         $LFS hsm_restore $f
3986         wait_request_state $fid RESTORE FAILED
3987         local st=$?
3988
3989         # cleanup
3990         cdt_clear_no_retry
3991
3992         # Test result
3993         [[ $st == 0 ]] || error "Restore does not failed"
3994 }
3995 run_test 111a "No retry policy (import case), restore will error"\
3996               " (No such file or directory)"
3997
3998 test_111b() {
3999         # test needs a running copytool
4000         copytool setup
4001
4002         mkdir_on_mdt0 $DIR/$tdir
4003         local f=$DIR/$tdir/$tfile
4004         local fid=$(copy_file /etc/passwd $f)
4005         stack_trap cdt_clear_no_retry EXIT
4006         cdt_set_no_retry
4007         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4008         wait_request_state $fid ARCHIVE SUCCEED
4009         $LFS hsm_release $f
4010
4011         copytool_remove_backend $fid
4012
4013         $LFS hsm_restore $f
4014         wait_request_state $fid RESTORE FAILED
4015         local st=$?
4016
4017         # Test result
4018         [[ $st == 0 ]] || error "Restore does not failed"
4019 }
4020 run_test 111b "No retry policy (release case), restore will error"\
4021               " (No such file or directory)"
4022
4023 test_112() {
4024         # test needs a running copytool
4025         copytool setup
4026
4027         mkdir_on_mdt0 $DIR/$tdir
4028         local f=$DIR/$tdir/$tfile
4029         local fid=$(copy_file /etc/passwd $f)
4030         cdt_disable
4031         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4032         local l=$($LFS hsm_action $f)
4033         echo $l
4034         local res=$(echo $l | cut -f 2- -d" " | grep ARCHIVE)
4035
4036         cdt_enable
4037         wait_request_state $fid ARCHIVE SUCCEED
4038
4039         # Test result
4040         [[ ! -z "$res" ]] || error "action is $l which is not an ARCHIVE"
4041 }
4042 run_test 112 "State of recorded request"
4043
4044 test_113() {
4045         mkdir_on_mdt0 $DIR/$tdir
4046
4047         local file1=$DIR/$tdir/$tfile
4048         local file2=$DIR2/$tdir/$tfile
4049
4050         local fid=$(create_small_sync_file $file1)
4051
4052         stack_trap "zconf_umount \"$(facet_host $SINGLEAGT)\" \"$MOUNT3\"" EXIT
4053         zconf_mount "$(facet_host $SINGLEAGT)" "$MOUNT3" ||
4054                 error "cannot mount '$MOUNT3' on '$SINGLEAGT'"
4055
4056         copytool setup -m  "$MOUNT3"
4057
4058         do_nodes $(comma_list $(nodes_list)) $LCTL clear
4059
4060         $LFS hsm_archive $file1 || error "Fail to archive $file1"
4061         wait_request_state $fid ARCHIVE SUCCEED
4062
4063         $LFS hsm_release $file1
4064         echo "Verifying released state: "
4065         check_hsm_flags $file1 "0x0000000d"
4066
4067         multiop_bg_pause $file1 oO_WRONLY:O_APPEND:_w4c || error "multiop failed"
4068         MULTIPID=$!
4069         stat $file2 &
4070         kill -USR1 $MULTIPID
4071
4072         wait
4073         sync
4074
4075         local size1=$(stat -c "%s" $file1)
4076         local size2=$(stat -c "%s" $file2)
4077
4078         [ $size1 -eq $size2 ] || error "sizes are different $size1 $size2"
4079 }
4080 run_test 113 "wrong stat after restore"
4081
4082 test_114() {
4083         (( MDS1_VERSION >= $(version_code 2.15.54) )) ||
4084                 skip "need MDS version at least 2.15.54"
4085
4086         mkdir_on_mdt0 $DIR/$tdir
4087
4088         local f1=$DIR/$tdir/${tfile}1
4089         local f2=$DIR/$tdir/${tfile}2
4090         local fid1=$(create_empty_file "$f1")
4091         local fid2=$(create_empty_file "$f2")
4092
4093         copytool setup
4094
4095         # Prevent archive from completing
4096         cdt_disable
4097
4098         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1 $f2
4099         # wait archive to register at CDT
4100         wait_request_state "$fid1" ARCHIVE WAITING
4101
4102         # Set f2 in an incompatible state
4103         $LFS hsm_set --noarchive $f2
4104
4105         cdt_enable
4106
4107         wait_request_state "$fid1" ARCHIVE SUCCEED
4108         wait_request_state "$fid2" ARCHIVE FAILED
4109 }
4110 run_test 114 "Incompatible request does not set other requests as STARTED"
4111
4112 test_200() {
4113         mkdir_on_mdt0 $DIR/$tdir
4114
4115         local f=$DIR/$tdir/$tfile
4116         local fid=$(create_empty_file "$f")
4117
4118         copytool setup
4119
4120         # Prevent archive from completing
4121         copytool_suspend
4122
4123         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4124         # wait archive to register at CDT
4125         wait_request_state $fid ARCHIVE STARTED
4126
4127         # Cancel the archive
4128         $LFS hsm_cancel "$f"
4129
4130         wait_request_state $fid ARCHIVE CANCELED
4131
4132         copytool_continue
4133         wait_request_state $fid CANCEL SUCCEED
4134 }
4135 run_test 200 "Register/Cancel archive"
4136
4137 test_201() {
4138         # test needs a running copytool
4139         copytool setup
4140         mkdir_on_mdt0 $DIR/$tdir
4141
4142         local f=$DIR/$tdir/$tfile
4143         create_archive_file $tdir/$tfile
4144         copytool import $tdir/$tfile $f
4145         local fid=$(path2fid $f)
4146
4147         # test with cdt on is made in test_222
4148         cdt_disable
4149         $LFS hsm_restore $f
4150         # wait restore to register at CDT
4151         wait_request_state $fid RESTORE WAITING
4152         $LFS hsm_cancel $f
4153         cdt_enable
4154         wait_request_state $fid RESTORE CANCELED
4155         wait_request_state $fid CANCEL SUCCEED
4156 }
4157 run_test 201 "Register/Cancel restore"
4158
4159 test_202() {
4160         mkdir_on_mdt0 $DIR/$tdir
4161
4162         local f=$DIR/$tdir/$tfile
4163         local fid=$(create_empty_file "$f")
4164
4165         # test needs a running copytool
4166         copytool setup
4167
4168         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4169         wait_request_state $fid ARCHIVE SUCCEED
4170
4171         copytool_suspend
4172         $LFS hsm_remove $f
4173         # wait remove to register at CDT
4174         wait_request_state $fid REMOVE STARTED
4175         $LFS hsm_cancel $f
4176
4177         wait_request_state $fid REMOVE CANCELED
4178 }
4179 run_test 202 "Register/Cancel remove"
4180
4181 test_220A() { # was test_220
4182         # test needs a running copytool
4183         copytool setup
4184
4185         mkdir_on_mdt0 $DIR/$tdir
4186
4187         local f=$DIR/$tdir/$tfile
4188         local fid=$(copy_file /etc/passwd $f)
4189
4190         changelog_register
4191
4192         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4193         wait_request_state $fid ARCHIVE SUCCEED
4194
4195         changelog_find -type HSM -target-fid $fid -flags 0x0 ||
4196                 error "The expected changelog was not emitted"
4197 }
4198 run_test 220A "Changelog for archive"
4199
4200 test_220a() {
4201         # test needs a running copytool
4202         copytool setup
4203
4204         mkdir_on_mdt0 $DIR/$tdir
4205
4206         local f=$DIR/$tdir/$tfile
4207         local fid=$(copy_file /etc/passwd $f)
4208
4209         changelog_register
4210
4211         # block copytool operations to allow for HSM request to be
4212         # submitted and file be unlinked (CDT will find object removed)
4213         copytool_suspend
4214
4215         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4216
4217         # wait request to reach CT
4218         wait_request_state $fid ARCHIVE STARTED
4219
4220         rm -f $f
4221
4222         copytool_continue
4223
4224         wait_request_state $fid ARCHIVE FAILED
4225
4226         # HE_ARCHIVE|ENOENT
4227         changelog_find -type HSM -target-fid $fid -flags 0x2 ||
4228                 error "The expected changelog was not emitted"
4229 }
4230 run_test 220a "Changelog for failed archive"
4231
4232 test_221() {
4233         mkdir_on_mdt0 $DIR/$tdir
4234
4235         local f=$DIR/$tdir/$tfile
4236         local fid=$(create_empty_file "$f")
4237
4238         copytool setup -b 1
4239         changelog_register
4240
4241         # Prevent archive from completing
4242         copytool_suspend
4243         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4244         wait_request_state $fid ARCHIVE STARTED
4245
4246         $LFS hsm_cancel $f
4247         wait_request_state $fid ARCHIVE CANCELED
4248
4249         copytool_continue
4250         wait_request_state $fid CANCEL SUCCEED
4251
4252         changelog_find -type HSM -target-fid $fid -flags 0x7d ||
4253                 error "The expected changelog was not emitted"
4254 }
4255 run_test 221 "Changelog for archive canceled"
4256
4257 test_222a() {
4258         # test needs a running copytool
4259         copytool setup
4260
4261         mkdir_on_mdt0 $DIR/$tdir
4262         copy2archive /etc/passwd $tdir/$tfile
4263
4264         local f=$DIR/$tdir/$tfile
4265         copytool import $tdir/$tfile $f
4266         local fid=$(path2fid $f)
4267
4268         changelog_register
4269
4270         $LFS hsm_restore $f
4271         wait_request_state $fid RESTORE SUCCEED
4272
4273         changelog_find -type HSM -target-fid $fid -flags 0x80 ||
4274                 error "The expected changelog was not emitted"
4275 }
4276 run_test 222a "Changelog for explicit restore"
4277
4278 test_222b() {
4279         # test needs a running copytool
4280         copytool setup
4281
4282         mkdir_on_mdt0 $DIR/$tdir
4283         local f=$DIR/$tdir/$tfile
4284         local fid=$(copy_file /etc/passwd $f)
4285
4286         changelog_register
4287         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4288         wait_request_state $fid ARCHIVE SUCCEED
4289         $LFS hsm_release $f
4290
4291         md5sum $f
4292
4293         wait_request_state $fid RESTORE SUCCEED
4294
4295         changelog_find -type HSM -target-fid $fid -flags 0x80 ||
4296                 error "The expected changelog was not emitted"
4297 }
4298 run_test 222b "Changelog for implicit restore"
4299
4300 test_222c() {
4301         # test needs a running copytool
4302         copytool setup
4303
4304         mkdir_on_mdt0 $DIR/$tdir
4305         copy2archive /etc/passwd $tdir/$tfile
4306
4307         local f=$DIR/$tdir/$tfile
4308         copytool import $tdir/$tfile $f
4309         local fid=$(path2fid $f)
4310
4311         changelog_register
4312
4313         # block copytool operations to allow for HSM request to be
4314         # submitted and file be unlinked (CDT will find object removed)
4315         copytool_suspend
4316
4317         $LFS hsm_restore $f
4318
4319         # wait request to reach CT
4320         wait_request_state $fid RESTORE STARTED
4321
4322         rm -f $f
4323
4324         copytool_continue
4325
4326         wait_request_state $fid RESTORE FAILED
4327
4328         # HE_RESTORE|ENOENT
4329         changelog_find -type HSM -target-fid $fid -flags 0x82 ||
4330                 error "The expected changelog was not emitted"
4331 }
4332 run_test 222c "Changelog for failed explicit restore"
4333
4334 test_222d() {
4335         # test needs a running copytool
4336         copytool setup
4337
4338         mkdir_on_mdt0 $DIR/$tdir
4339         local f=$DIR/$tdir/$tfile
4340         local fid=$(copy_file /etc/passwd $f)
4341
4342         changelog_register
4343         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4344         wait_request_state $fid ARCHIVE SUCCEED
4345         $LFS hsm_release $f
4346
4347         copytool_remove_backend $fid
4348         md5sum $f
4349
4350         wait_request_state $fid RESTORE FAILED
4351
4352         # HE_RESTORE|ENOENT
4353         changelog_find -type HSM -target-fid $fid -flags 0x82 ||
4354                 error "The expected changelog was not emitted"
4355 }
4356 run_test 222d "Changelog for failed implicit restore"
4357
4358 test_223a() {
4359         # test needs a running copytool
4360         copytool setup -b 1
4361         mkdir_on_mdt0 $DIR/$tdir
4362
4363         local f=$DIR/$tdir/$tfile
4364         create_archive_file $tdir/$tfile
4365
4366         changelog_register
4367
4368         copytool import $tdir/$tfile $f
4369         local fid=$(path2fid $f)
4370
4371         $LFS hsm_restore $f
4372         wait_request_state $fid RESTORE STARTED
4373         $LFS hsm_cancel $f
4374         wait_request_state $fid RESTORE CANCELED
4375         wait_request_state $fid CANCEL SUCCEED
4376
4377         changelog_find -type HSM -target-fid $fid -flags 0xfd ||
4378                 error "The expected changelog was not emitted"
4379 }
4380 run_test 223a "Changelog for restore canceled (import case)"
4381
4382 test_223b() {
4383         mkdir_on_mdt0 $DIR/$tdir
4384
4385         local f=$DIR/$tdir/$tfile
4386         local fid=$(create_empty_file "$f")
4387
4388         copytool setup -b 1
4389         changelog_register
4390
4391         $LFS hsm archive --archive $HSM_ARCHIVE_NUMBER $f
4392         wait_request_state $fid ARCHIVE SUCCEED
4393         $LFS hsm release $f
4394
4395         # Prevent restore from completing
4396         copytool_suspend
4397         $LFS hsm restore $f
4398         wait_request_state $fid RESTORE STARTED
4399
4400         $LFS hsm cancel $f
4401         wait_request_state $fid RESTORE CANCELED
4402
4403         copytool_continue
4404         wait_request_state $fid CANCEL SUCCEED
4405
4406         changelog_find -type HSM -target-fid $fid -flags 0xfd ||
4407                 error "The expected changelog was not emitted"
4408 }
4409 run_test 223b "Changelog for restore canceled (release case)"
4410
4411 test_224A() { # was test_224
4412         # test needs a running copytool
4413         copytool setup
4414
4415         mkdir_on_mdt0 $DIR/$tdir
4416
4417         local f=$DIR/$tdir/$tfile
4418         local fid=$(copy_file /etc/passwd $f)
4419
4420         changelog_register
4421         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4422         wait_request_state $fid ARCHIVE SUCCEED
4423
4424         $LFS hsm_remove $f
4425         wait_request_state $fid REMOVE SUCCEED
4426
4427         changelog_find -type HSM -target-fid $fid -flags 0x200 ||
4428                 error "The expected changelog was not emitted"
4429 }
4430 run_test 224A "Changelog for remove"
4431
4432 test_224a() {
4433         # test needs a running copytool
4434         copytool setup
4435
4436         mkdir_on_mdt0 $DIR/$tdir
4437
4438         local f=$DIR/$tdir/$tfile
4439         local fid=$(copy_file /etc/passwd $f)
4440
4441         changelog_register
4442         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4443         wait_request_state $fid ARCHIVE SUCCEED
4444
4445         copytool_remove_backend $fid
4446
4447         # block copytool operations to allow for HSM request to be
4448         # submitted and file be unlinked (CDT will find object removed)
4449         copytool_suspend
4450
4451         $LFS hsm_remove $f
4452
4453         # wait for request to reach CT
4454         wait_request_state $fid REMOVE STARTED
4455
4456         rm -f $f
4457
4458         copytool_continue
4459
4460         wait_request_state $fid REMOVE FAILED
4461
4462         # HE_REMOVE|ENOENT=0x202
4463         changelog_find -type HSM -target-fid $fid -flags 0x202 ||
4464                 error "The expected changelog was not emitted"
4465 }
4466 run_test 224a "Changelog for failed remove"
4467
4468 test_225() {
4469         # test is not usable because remove request is too fast
4470         # so it is always finished before cancel can be done ...
4471         echo "Test disabled"
4472         return 0
4473
4474         # test needs a running copytool
4475         copytool setup
4476         mkdir_on_mdt0 $DIR/$tdir
4477
4478         local f=$DIR/$tdir/$tfile
4479         local fid=$(create_empty_file "$f")
4480
4481         changelog_register
4482         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4483         wait_request_state $fid ARCHIVE SUCCEED
4484
4485         # Prevent restore from completing
4486         copytool_suspend
4487         $LFS hsm_remove $f
4488
4489         $LFS hsm_cancel $f
4490         wait_request_state $fid REMOVE CANCELED
4491
4492         copytool_continue
4493         wait_request_state $fid CANCEL SUCCEED
4494
4495         changelog_find -type HSM -target-fid $fid -flags 0x27d
4496                 error "The expected changelog was not emitted"
4497 }
4498 run_test 225 "Changelog for remove canceled"
4499
4500 test_226() {
4501         # test needs a running copytool
4502         copytool setup
4503
4504         mkdir_on_mdt0 $DIR/$tdir
4505
4506         local f1=$DIR/$tdir/$tfile-1
4507         local f2=$DIR/$tdir/$tfile-2
4508         local f3=$DIR/$tdir/$tfile-3
4509         local fid1=$(copy_file /etc/passwd $f1)
4510         local fid2=$(copy_file /etc/passwd $f2)
4511         copy_file /etc/passwd $f3
4512
4513         changelog_register
4514         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1
4515         wait_request_state $fid1 ARCHIVE SUCCEED
4516
4517         $LFS hsm_archive $f2
4518         wait_request_state $fid2 ARCHIVE SUCCEED
4519
4520         rm $f1 || error "rm $f1 failed"
4521
4522         changelog_dump
4523         changelog_find -type UNLNK -target-fid $fid1 -flags 0x3 ||
4524                 error "The expected changelog was not emitted"
4525
4526         mv $f3 $f2 || error "mv $f3 $f2 failed"
4527
4528         changelog_find -type RENME -target-fid $fid2 -flags 0x3 ||
4529                 error "The expected changelog was not emitted"
4530 }
4531 run_test 226 "changelog for last rm/mv with exiting archive"
4532
4533 # This is just a utility function to clarify what test_227 does
4534 __test_227()
4535 {
4536         local target=0x280
4537
4538         "$LFS" "$action" --$flag "$file" ||
4539                 error "Cannot ${action#hsm_} $flag on '$file'"
4540
4541         # Only one changelog should be produced
4542         local entries="$(changelog_find -type HSM -target-fid $fid)"
4543         [ $(wc -l <<< "$entries") -eq $((++count)) ] ||
4544                 error "lfs $action --$flag '$file' produced more than one" \
4545                       "changelog record"
4546
4547         # Parse the last changelog record
4548         local entry="$(tail -n 1 <<< "$entries")"
4549         eval local -A changelog=$(changelog2array $entry)
4550
4551         # Also check the flags match what is expected
4552         [[ ${changelog[flags]} == $target ]] ||
4553                 error "Changelog flag is '${changelog[flags]}', not $target"
4554 }
4555
4556 test_227() {
4557         local file="$DIR/$tdir/$tfile"
4558         local fid=$(create_empty_file "$file")
4559         local count=0
4560
4561         changelog_register
4562
4563         for flag in norelease noarchive exists archived lost; do
4564                 if [ "$flag" == lost ]; then
4565                         # The flag "lost" only works on an archived file
4566                         "$LFS" hsm_set --archived "$file"
4567                         ((count++))
4568                 fi
4569
4570                 action="hsm_set" __test_227
4571                 action="hsm_clear" __test_227
4572         done
4573 }
4574 run_test 227 "changelog when explicit setting of HSM flags"
4575
4576 test_228() {
4577         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
4578         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
4579
4580         # test needs a running copytool
4581         copytool setup
4582         mkdir_on_mdt0 $DIR/$tdir
4583
4584         local fid=$(create_small_sync_file $DIR/$tfile)
4585         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tfile
4586         wait_request_state $fid ARCHIVE SUCCEED
4587
4588         $LFS hsm_release $DIR/$tfile
4589         check_hsm_flags $DIR/$tfile "0x0000000d"
4590
4591         filefrag $DIR/$tfile | grep " 1 extent found" ||
4592                 error "filefrag on released file must return only one extent"
4593
4594         # only newer versions of cp detect sparse files by stat/FIEMAP
4595         # (LU-2580)
4596         cp --sparse=auto $DIR/$tfile $DIR/$tfile.2 ||
4597                 error "copying $DIR/$tfile"
4598         cmp $DIR/$tfile $DIR/$tfile.2 || error "comparing copied $DIR/$tfile"
4599
4600         $LFS hsm_release $DIR/$tfile
4601         check_hsm_flags $DIR/$tfile "0x0000000d"
4602
4603         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
4604
4605         tar cf - --sparse $DIR/$tfile | tar xvf - -C $DIR/$tdir ||
4606                 error "tar failed"
4607         cmp $DIR/$tfile $DIR/$tdir/$DIR/$tfile ||
4608                 error "comparing untarred $DIR/$tfile"
4609
4610         rm -f $DIR/$tfile $DIR/$tfile.2 ||
4611                 error "rm $DIR/$tfile or $DIR/$tfile.2 failed"
4612 }
4613 run_test 228 "On released file, return extend to FIEMAP. For [cp,tar] --sparse"
4614
4615 test_250() {
4616         local file="$DIR/$tdir/$tfile"
4617
4618         # set max_requests to allow one request of each type to be started (3)
4619         stack_trap \
4620                 "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
4621         set_hsm_param max_requests 3
4622         # speed up test
4623         stack_trap \
4624                 "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
4625         set_hsm_param loop_period 1
4626
4627         # send 1 requests of each kind twice
4628         copytool setup
4629
4630         mkdir_on_mdt0 $DIR/$tdir
4631
4632         # setup the files
4633         for action in archive restore remove; do
4634                 local filepath="$file"-to-$action
4635                 local fid=$(create_empty_file "$filepath")
4636                 local fid2=$(create_empty_file "$filepath".bis)
4637
4638                 if [ "$action" != archive ]; then
4639                         "$LFS" hsm_archive "$filepath"
4640                         wait_request_state $fid ARCHIVE SUCCEED
4641                         "$LFS" hsm_archive "$filepath".bis
4642                         wait_request_state $fid2 ARCHIVE SUCCEED
4643                 fi
4644                 if [ "$action" == restore ]; then
4645                         "$LFS" hsm_release "$filepath"
4646                         "$LFS" hsm_release "$filepath".bis
4647                 fi
4648         done
4649
4650         # suspend the copytool to prevent requests from completing
4651         stack_trap "copytool_continue" EXIT
4652         copytool_suspend
4653
4654         # send `max_requests' requests (one of each kind)
4655         for action in archive restore remove; do
4656                 filepath="$file"-to-$action
4657                 "$LFS" hsm_${action} "$filepath"
4658                 wait_request_state $(path2fid "$filepath") "${action^^}" STARTED
4659         done
4660
4661         # send another batch of requests
4662         for action in archive restore remove; do
4663                 "$LFS" hsm_${action} "$file-to-$action".bis
4664         done
4665         # wait for `loop_period' seconds to make sure the coordinator has time
4666         # to register those, even though it should not
4667         sleep 1
4668
4669         # only the first batch of request should be started
4670         local -i count
4671         count=$(do_facet $SINGLEMDS "$LCTL" get_param -n $HSM_PARAM.actions |
4672                 grep -c STARTED)
4673
4674         ((count == 3)) ||
4675                 error "expected 3 STARTED requests, found $count"
4676 }
4677 run_test 250 "Coordinator max request"
4678
4679 test_251() {
4680         mkdir_on_mdt0 $DIR/$tdir
4681
4682         local f=$DIR/$tdir/$tfile
4683         local fid=$(create_empty_file "$f")
4684
4685         cdt_disable
4686         # to have a short test
4687         local old_to=$(get_hsm_param active_request_timeout)
4688         set_hsm_param active_request_timeout 1
4689         # to be sure the cdt will wake up frequently so
4690         # it will be able to cancel the "old" request
4691         local old_loop=$(get_hsm_param loop_period)
4692         set_hsm_param loop_period 1
4693         cdt_enable
4694
4695         copytool setup
4696
4697         # Prevent archive from completing
4698         copytool_suspend
4699         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4700         wait_request_state $fid ARCHIVE STARTED
4701
4702         # Let the request timeout
4703         wait_request_state $fid ARCHIVE CANCELED
4704
4705         set_hsm_param active_request_timeout $old_to
4706         set_hsm_param loop_period $old_loop
4707 }
4708 run_test 251 "Coordinator request timeout"
4709
4710 test_252() {
4711         mkdir_on_mdt0 $DIR/$tdir
4712
4713         local f=$DIR/$tdir/$tfile
4714         local fid=$(create_empty_file "$f")
4715
4716         # to have a short test
4717         stack_trap "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
4718         set_hsm_param loop_period 1
4719
4720         copytool setup
4721
4722         # Prevent archive from completing
4723         copytool_suspend
4724         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4725         wait_request_state $fid ARCHIVE STARTED
4726         rm -f "$f"
4727
4728         stack_trap "set_hsm_param active_request_timeout \
4729                     $(get_hsm_param active_request_timeout)" EXIT
4730         set_hsm_param active_request_timeout 1
4731
4732         wait_request_state $fid ARCHIVE CANCELED
4733         copytool_continue
4734 }
4735 run_test 252 "Timeout'ed running archive of a removed file should be canceled"
4736
4737 test_253() {
4738         local rc
4739         # test needs a running copytool
4740         copytool setup
4741
4742         mkdir_on_mdt0 $DIR/$tdir
4743         local f=$DIR/$tdir/$tfile
4744
4745         dd if=/dev/zero of=$f bs=1MB count=10
4746         local fid=$(path2fid $f)
4747
4748         $LFS hsm_archive $f || error "could not archive file"
4749         wait_request_state $fid ARCHIVE SUCCEED
4750
4751         # clear locks to discard inode data
4752         cancel_lru_locks osc
4753
4754         #define OBD_FAIL_MDC_MERGE              0x807
4755         $LCTL set_param fail_loc=0x807
4756
4757         #expect error here, instead of release with wrong size
4758         $LFS hsm_release $f
4759         rc=$?
4760         if ((rc == 0)); then
4761                 file_size=$(stat -c '%s' $f)
4762                 if ((file_size != 10485760)); then
4763                         error "Wrong file size after hsm_release"
4764                 fi
4765         else
4766                 echo "could not release file"
4767         fi
4768 }
4769 run_test 253 "Check for wrong file size after release"
4770
4771 test_254a()
4772 {
4773         [ $MDS1_VERSION -lt $(version_code 2.10.56) ] &&
4774                 skip "need MDS version at least 2.10.56"
4775
4776         # Check that the counters are initialized to 0
4777         local count
4778         for request_type in archive restore remove; do
4779                 count="$(get_hsm_param ${request_type}_count)" ||
4780                         error "Reading ${request_type}_count failed with $?"
4781
4782                 [ "$count" -eq 0 ] ||
4783                         error "Expected ${request_type}_count to be " \
4784                               "0 != '$count'"
4785         done
4786 }
4787 run_test 254a "Request counters are initialized to zero"
4788
4789 test_254b()
4790 {
4791         [ $MDS1_VERSION -lt $(version_code 2.10.56) ] &&
4792                 skip "need MDS version at least 2.10.56"
4793
4794         # The number of request to launch (at least 32)
4795         local request_count=$((RANDOM % 32 + 32))
4796         printf "Will launch %i requests of each type\n" "$request_count"
4797
4798         # Launch a copytool to process requests
4799         copytool setup
4800
4801         # Set hsm.max_requests to allow starting all requests at the same time
4802         stack_trap \
4803                 "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
4804         set_hsm_param max_requests "$request_count"
4805
4806         mkdir_on_mdt0 $DIR/$tdir
4807
4808         local timeout
4809         local count
4810         for request_type in archive restore remove; do
4811                 printf "Checking %s requests\n" "${request_type}"
4812                 # Suspend the copytool to give us time to read the proc files
4813                 copytool_suspend
4814
4815                 for ((i = 0; i < $request_count; i++)); do
4816                         case $request_type in
4817                         archive)
4818                                 create_empty_file "$DIR/$tdir/$tfile-$i" \
4819                                         >/dev/null 2>&1
4820                                 ;;
4821                         restore)
4822                                 lfs hsm_release "$DIR/$tdir/$tfile-$i"
4823                                 ;;
4824                         esac
4825                         $LFS hsm_${request_type} "$DIR/$tdir/$tfile-$i"
4826                 done
4827
4828                 # Give the coordinator 10 seconds to start every request
4829                 timeout=10
4830                 while get_hsm_param actions | grep -q WAITING; do
4831                         sleep 1
4832                         let timeout-=1
4833                         [ $timeout -gt 0 ] ||
4834                                 error "${request_type^} requests took too " \
4835                                       "long to start"
4836                 done
4837
4838                 count="$(get_hsm_param ${request_type}_count)"
4839                 [ "$count" -eq "$request_count" ] ||
4840                         error "Expected '$request_count' (!= '$count') " \
4841                               "active $request_type requests"
4842
4843                 # Let the copytool process the requests
4844                 copytool_continue
4845                 # Give it 10 seconds maximum
4846                 timeout=10
4847                 while get_hsm_param actions | grep -q STARTED; do
4848                         sleep 1
4849                         let timeout-=1
4850                         [ $timeout -gt 0 ] ||
4851                                 error "${request_type^} requests took too " \
4852                                       "long to complete"
4853                 done
4854
4855                 count="$(get_hsm_param ${request_type}_count)"
4856                 [ "$count" -eq 0 ] ||
4857                         error "Expected 0 (!= '$count') " \
4858                               "active $request_type requests"
4859         done
4860 }
4861 run_test 254b "Request counters are correctly incremented and decremented"
4862
4863 test_255()
4864 {
4865         [ $MDS1_VERSION -lt $(version_code 2.12.0) ] &&
4866                 skip "Need MDS version at least 2.12.0"
4867
4868         mkdir_on_mdt0 $DIR/$tdir
4869
4870         local file="$DIR/$tdir/$tfile"
4871         local fid=$(create_empty_file "$file")
4872
4873         # How do you make sure the coordinator has consumed any outstanding
4874         # event, without triggering an event yourself?
4875         #
4876         # You wait for a request to disappear from the coordinator's llog.
4877
4878         # Warning: the setup represents 90% of this test
4879
4880         # Create and process an HSM request
4881         copytool setup
4882         "$LFS" hsm_archive "$file"
4883         wait_request_state $fid ARCHIVE SUCCEED
4884
4885         kill_copytools
4886         wait_copytools || error "failed to stop copytools"
4887
4888         # Launch a new HSM request
4889         rm "$file"
4890         create_empty_file "$file"
4891         "$LFS" hsm_archive "$file"
4892
4893         cdt_shutdown
4894
4895         # Have the completed request be removed as soon as the cdt wakes up
4896         stack_trap "set_hsm_param grace_delay $(get_hsm_param grace_delay)" EXIT
4897         set_hsm_param grace_delay 1
4898         # (Hopefully, time on the MDS will behave nicely)
4899         do_facet $SINGLEMDS sleep 2 &
4900
4901         # Increase `loop_period' as a mean to prevent the coordinator from
4902         # waking itself up to do some housekeeping.
4903         stack_trap "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
4904         set_hsm_param loop_period 1000
4905
4906         wait $! || error "waiting failed"
4907         cdt_enable
4908         wait_request_state $fid ARCHIVE ""
4909         # The coordinator will not wake up on its own for ~`loop_period' secs...
4910
4911         # ... Unless a copytool registers. Now the real test begins
4912         copytool setup
4913         wait_request_state $(path2fid "$file") ARCHIVE SUCCEED
4914 }
4915 run_test 255 "Copytool registration wakes the coordinator up"
4916
4917 # tests 260[a-c] rely on the parsing of the copytool's log file, they might
4918 # break in the future because of that.
4919 test_260a()
4920 {
4921         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
4922                 skip "need MDS version 2.11.56 or later"
4923
4924         local -a files=("$DIR/$tdir/$tfile".{0..15})
4925         local file
4926
4927         mkdir_on_mdt0 $DIR/$tdir
4928
4929         for file in "${files[@]}"; do
4930                 create_small_file "$file"
4931         done
4932
4933         # Set a few hsm parameters
4934         stack_trap \
4935                 "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
4936         set_hsm_param loop_period 1
4937         stack_trap \
4938                 "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
4939         set_hsm_param max_requests 3
4940
4941         # Release one file
4942         copytool setup
4943         "$LFS" hsm_archive "${files[0]}"
4944         wait_request_state "$(path2fid "${files[0]}")" ARCHIVE SUCCEED
4945         "$LFS" hsm_release "${files[0]}"
4946
4947         # Stop the copytool
4948         kill_copytools
4949         wait_copytools || error "copytools failed to stop"
4950
4951         # Send several archive requests
4952         for file in "${files[@]:1}"; do
4953                 "$LFS" hsm_archive "$file"
4954         done
4955
4956         # Send one restore request
4957         "$LFS" hsm_restore "${files[0]}"
4958
4959         # Launch a copytool
4960         copytool setup
4961
4962         # Wait for all the requests to complete
4963         wait_request_state "$(path2fid "${files[0]}")" RESTORE SUCCEED
4964         for file in "${files[@]:1}"; do
4965                 wait_request_state "$(path2fid "$file")" ARCHIVE SUCCEED
4966         done
4967
4968         # Collect the actions in the order in which the copytool processed them
4969         local -a actions=(
4970                 $(do_facet "$SINGLEAGT" grep -o '\"RESTORE\\|ARCHIVE\"' \
4971                         "$(copytool_logfile "$SINGLEAGT")")
4972                 )
4973
4974         printf '%s\n' "${actions[@]}"
4975
4976         local action
4977         for action in "${actions[@]:0:3}"; do
4978                 [ "$action" == RESTORE ] && return
4979         done
4980
4981         error "Too many ARCHIVE requests were run before the RESTORE request"
4982 }
4983 run_test 260a "Restore request have priority over other requests"
4984
4985 # This test is very much tied to the implementation of the current priorisation
4986 # mechanism in the coordinator. It might not make sense to keep it in the future
4987 test_260b()
4988 {
4989         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
4990                 skip "need MDS version 2.11.56 or later"
4991
4992         local -a files=("$DIR/$tdir/$tfile".{0..15})
4993         local file
4994
4995         mkdir_on_mdt0 $DIR/$tdir
4996
4997         for file in "${files[@]}"; do
4998                 create_small_file "$file"
4999         done
5000
5001         # Set a few hsm parameters
5002         stack_trap \
5003                 "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
5004         set_hsm_param loop_period 1
5005         stack_trap \
5006                 "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
5007         set_hsm_param max_requests 3
5008
5009         # Release one file
5010         copytool setup --archive-id 2
5011         "$LFS" hsm_archive --archive 2 "${files[0]}"
5012         wait_request_state "$(path2fid "${files[0]}")" ARCHIVE SUCCEED
5013         "$LFS" hsm_release "${files[0]}"
5014
5015         # Stop the copytool
5016         kill_copytools
5017         wait_copytools || error "copytools failed to stop"
5018
5019         # Send several archive requests
5020         for file in "${files[@]:1}"; do
5021                 "$LFS" hsm_archive "$file"
5022         done
5023
5024         # Send one restore request
5025         "$LFS" hsm_restore "${files[0]}"
5026
5027         # Launch a copytool
5028         copytool setup
5029         copytool setup --archive-id 2
5030
5031         # Wait for all the requests to complete
5032         wait_request_state "$(path2fid "${files[0]}")" RESTORE SUCCEED
5033         for file in "${files[@]:1}"; do
5034                 wait_request_state "$(path2fid "$file")" ARCHIVE SUCCEED
5035         done
5036
5037         # Collect the actions in the order in which the copytool processed them
5038         local -a actions=(
5039                 $(do_facet "$SINGLEAGT" grep -o '\"RESTORE\\|ARCHIVE\"' \
5040                         "$(copytool_logfile "$SINGLEAGT")")
5041                 )
5042
5043         printf '%s\n' "${actions[@]}"
5044
5045         local action
5046         for action in "${actions[@]:0:3}"; do
5047                 [ "$action" == RESTORE ] && return
5048         done
5049
5050         error "Too many ARCHIVE requests were run before the RESTORE request"
5051 }
5052 run_test 260b "Restore request have priority over other requests"
5053
5054 # This test is very much tied to the implementation of the current priorisation
5055 # mechanism in the coordinator. It might not make sense to keep it in the future
5056 test_260c()
5057 {
5058         [ $MDS1_VERSION -lt $(version_code 2.12.0) ] &&
5059                 skip "Need MDS version at least 2.12.0"
5060
5061         local -a files=("$DIR/$tdir/$tfile".{0..15})
5062         local file
5063
5064         mkdir_on_mdt0 $DIR/$tdir
5065
5066         for file in "${files[@]}"; do
5067                 create_small_file "$file"
5068         done
5069
5070         # Set a few hsm parameters
5071         stack_trap \
5072                 "set_hsm_param loop_period $(get_hsm_param loop_period)" EXIT
5073         set_hsm_param loop_period 1000
5074         stack_trap \
5075                 "set_hsm_param max_requests $(get_hsm_param max_requests)" EXIT
5076         set_hsm_param max_requests 3
5077
5078         # Release one file
5079         copytool setup --archive-id 2
5080         "$LFS" hsm_archive --archive 2 "${files[0]}"
5081         wait_request_state "$(path2fid "${files[0]}")" ARCHIVE SUCCEED
5082         "$LFS" hsm_release "${files[0]}"
5083
5084         # Stop the copytool
5085         kill_copytools
5086         wait_copytools || error "copytools failed to stop"
5087
5088         # Force the next coordinator run to do housekeeping
5089         cdt_shutdown
5090         cdt_enable
5091
5092         "$LFS" hsm_archive "${files[1]}"
5093
5094         # Launch a copytool
5095         copytool setup
5096         copytool setup --archive-id 2
5097
5098         wait_request_state "$(path2fid "${files[1]}")" ARCHIVE SUCCEED
5099         # The coordinator just did a housekeeping run it won't do another one
5100         # for around `loop_period' seconds => requests will not be reordered
5101         # if it costs too much (ie. when the coordinator has to discard a whole
5102         # hal)
5103
5104         # Send several archive requests
5105         for file in "${files[@]:2}"; do
5106                 "$LFS" hsm_archive "$file"
5107         done
5108
5109         # Send one restore request
5110         "$LFS" hsm_restore "${files[0]}"
5111
5112         # Wait for all the requests to complete
5113         wait_request_state "$(path2fid "${files[0]}")" RESTORE SUCCEED
5114         for file in "${files[@]:2}"; do
5115                 wait_request_state "$(path2fid "$file")" ARCHIVE SUCCEED
5116         done
5117
5118         # Collect the actions in the order in which the copytool processed them
5119         local -a actions=(
5120                 $(do_facet "$SINGLEAGT" grep -o '\"RESTORE\\|ARCHIVE\"' \
5121                         "$(copytool_logfile "$SINGLEAGT")")
5122                 )
5123
5124         printf '%s\n' "${actions[@]}"
5125
5126         local action
5127         for action in "${actions[@]:0:3}"; do
5128                 [ "$action" == RESTORE ] &&
5129                         error "Restore requests should not be prioritised" \
5130                               "unless the coordinator is doing housekeeping"
5131         done
5132         return 0
5133 }
5134 run_test 260c "Requests are not reordered on the 'hot' path of the coordinator"
5135
5136 test_261() {
5137         local file=$DIR/$tdir/$tfile
5138         local size
5139         local fid
5140
5141         copytool setup
5142         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5143
5144         dd if=/dev/zero of=$file bs=4k count=2 || error "Write $file failed"
5145         fid=$(path2fid $file)
5146         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $file
5147         wait_request_state $fid ARCHIVE SUCCEED
5148
5149         $LFS hsm_state $file
5150         $LFS hsm_release $file
5151         $LFS hsm_restore $file
5152         wait_request_state $fid RESTORE SUCCEED
5153         $LFS hsm_release $file
5154         size=$(stat -c %s $file)
5155         [[ $size == 8192 ]] || error "Size after HSM release: $size"
5156
5157         $LFS hsm_release $file
5158         $LFS hsm_restore $file
5159         $LFS hsm_release $file
5160         size=$(stat -c %s $file)
5161         [[ $size == 8192 ]] || error "Size after HSM release: $size"
5162         $LFS hsm_state $file
5163 }
5164 run_test 261 "Report 0 bytes size after HSM release"
5165
5166 test_262() {
5167         (( MDS1_VERSION >= $(version_code v2_15_61-204-g5ee13823a4) )) ||
5168                 skip "Need MDS version at least 2.15.61"
5169
5170         local file=$DIR/$tdir/$tfile
5171         local blocks
5172         local fid
5173
5174         copytool setup
5175         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5176
5177         dd if=/dev/zero of=$file bs=4k count=2 || error "Write $file failed"
5178         fid=$(path2fid $file)
5179         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $file
5180         wait_request_state $fid ARCHIVE SUCCEED
5181
5182         $LFS hsm_release $file || error "HSM release $file failed"
5183         $LFS hsm_restore $file || error "HSM restore $file failed"
5184         $LFS hsm_release $file || error "HSM release $file failed"
5185         $LFS hsm_release $file || error "HSM release $file failed"
5186         blocks=$(stat -c "%b" $file)
5187         [ $blocks -eq "1" ] || error "wrong block number is $blocks, not 1"
5188 }
5189 run_test 262 "The client should return 1 block for HSM released files"
5190
5191 test_300() {
5192         [ "$CLIENTONLY" ] && skip "CLIENTONLY mode" && return
5193
5194         # the only way to test ondisk conf is to restart MDS ...
5195         echo "Stop coordinator and remove coordinator state at mount"
5196         # stop coordinator
5197         cdt_shutdown
5198         # clean on disk conf set by default
5199         cdt_clear_mount_state
5200         cdt_check_state stopped
5201
5202         # check cdt still off after umount/remount
5203         fail $SINGLEMDS
5204         cdt_check_state stopped
5205
5206         echo "Set coordinator start at mount, and start coordinator"
5207         cdt_set_mount_state enabled
5208
5209         # check cdt is on
5210         cdt_check_state enabled
5211
5212         # check cdt still on after umount/remount
5213         fail $SINGLEMDS
5214         cdt_check_state enabled
5215
5216         # we are back to original state (cdt started at mount)
5217 }
5218 run_test 300 "On disk coordinator state kept between MDT umount/mount"
5219
5220 test_301() {
5221         [ "$CLIENTONLY" ] && skip "CLIENTONLY mode" && return
5222
5223         local ai=$(get_hsm_param default_archive_id)
5224         local new=$((ai + 1))
5225
5226         set_hsm_param default_archive_id $new -P
5227         fail $SINGLEMDS
5228         local res=$(get_hsm_param default_archive_id)
5229
5230         # clear value
5231         set_hsm_param default_archive_id "" "-P -d"
5232
5233         [[ $new == $res ]] || error "Value after MDS restart is $res != $new"
5234 }
5235 run_test 301 "HSM tunnable are persistent"
5236
5237 test_302() {
5238         [ "$CLIENTONLY" ] && skip "CLIENTONLY mode" && return
5239
5240         local ai=$(get_hsm_param default_archive_id)
5241         local new=$((ai + 1))
5242
5243         # stop coordinator
5244         cdt_shutdown
5245
5246         set_hsm_param default_archive_id $new -P
5247
5248         local mdtno
5249         for mdtno in $(seq 1 $MDSCOUNT); do
5250                 fail mds${mdtno}
5251         done
5252
5253         # check cdt is on
5254         cdt_check_state enabled
5255
5256         local res=$(get_hsm_param default_archive_id)
5257
5258         # clear value
5259         set_hsm_param default_archive_id "" "-P -d"
5260
5261         [[ $new == $res ]] || error "Value after MDS restart is $res != $new"
5262 }
5263 run_test 302 "HSM tunnable are persistent when CDT is off"
5264
5265 test_400() {
5266         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5267
5268         copytool setup
5269
5270         mkdir_on_mdt0 $DIR/$tdir
5271
5272         local dir_mdt0=$DIR/$tdir/mdt0
5273         local dir_mdt1=$DIR/$tdir/mdt1
5274
5275         # create 1 dir per MDT
5276         stack_trap "rm -rf $dir_mdt0" EXIT
5277         $LFS mkdir -i 0 $dir_mdt0 || error "lfs mkdir"
5278         stack_trap "rm -rf $dir_mdt1" EXIT
5279         $LFS mkdir -i 1 $dir_mdt1 || error "lfs mkdir"
5280
5281         # create 1 file in each MDT
5282         local fid1=$(create_small_file $dir_mdt0/$tfile)
5283         local fid2=$(create_small_file $dir_mdt1/$tfile)
5284
5285         # check that hsm request on mdt0 is sent to the right MDS
5286         $LFS hsm_archive $dir_mdt0/$tfile || error "lfs hsm_archive"
5287         wait_request_state $fid1 ARCHIVE SUCCEED 0 &&
5288                 echo "archive successful on mdt0"
5289
5290         # check that hsm request on mdt1 is sent to the right MDS
5291         $LFS hsm_archive $dir_mdt1/$tfile || error "lfs hsm_archive"
5292         wait_request_state $fid2 ARCHIVE SUCCEED 1 &&
5293                 echo "archive successful on mdt1"
5294 }
5295 run_test 400 "Single request is sent to the right MDT"
5296
5297 test_401() {
5298         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5299
5300         copytool setup
5301
5302         mkdir_on_mdt0 $DIR/$tdir
5303
5304         local dir_mdt0=$DIR/$tdir/mdt0
5305         local dir_mdt1=$DIR/$tdir/mdt1
5306
5307         # create 1 dir per MDT
5308         stack_trap "rm -rf $dir_mdt0" EXIT
5309         $LFS mkdir -i 0 $dir_mdt0 || error "lfs mkdir"
5310         stack_trap "rm -rf $dir_mdt1" EXIT
5311         $LFS mkdir -i 1 $dir_mdt1 || error "lfs mkdir"
5312
5313         # create 1 file in each MDT
5314         local fid1=$(create_small_file $dir_mdt0/$tfile)
5315         local fid2=$(create_small_file $dir_mdt1/$tfile)
5316
5317         # check that compound requests are shunt to the rights MDTs
5318         $LFS hsm_archive $dir_mdt0/$tfile $dir_mdt1/$tfile ||
5319                 error "lfs hsm_archive"
5320         wait_request_state $fid1 ARCHIVE SUCCEED 0 &&
5321                 echo "archive successful on mdt0"
5322         wait_request_state $fid2 ARCHIVE SUCCEED 1 &&
5323                 echo "archive successful on mdt1"
5324 }
5325 run_test 401 "Compound requests split and sent to their respective MDTs"
5326
5327 mdc_change_state() # facet, MDT_pattern, activate|deactivate
5328 {
5329         local facet=$1
5330         local pattern="$2"
5331         local state=$3
5332         local node=$(facet_active_host $facet)
5333         local mdc
5334         for mdc in $(do_facet $facet "$LCTL dl | grep -E ${pattern}-mdc" |
5335                         awk '{print $4}'); do
5336                 echo "$3 $mdc on $node"
5337                 do_facet $facet "$LCTL --device $mdc $state" || return 1
5338         done
5339 }
5340
5341 test_402a() {
5342         # deactivate all mdc on agent1
5343         mdc_change_state $SINGLEAGT "$FSNAME-MDT000." "deactivate"
5344
5345         copytool setup --no-fail
5346
5347         check_agent_unregistered "uuid" # match any agent
5348
5349         # no expected running copytool
5350         search_copytools $agent && error "Copytool start should have failed"
5351
5352         # reactivate MDCs
5353         mdc_change_state $SINGLEAGT "$FSNAME-MDT000." "activate"
5354 }
5355 run_test 402a "Copytool start fails if all MDTs are inactive"
5356
5357 test_402b() {
5358         copytool setup
5359
5360         mkdir_on_mdt0 $DIR/$tdir
5361
5362         local f=$DIR/$tdir/$tfile
5363         touch $f || error "touch $f failed"
5364         local fid=$(path2fid $f)
5365
5366 #define OBD_FAIL_MDS_HSM_CT_REGISTER_NET        0x14d
5367         do_facet $SINGLEAGT lctl set_param fail_loc=0x14d
5368         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
5369
5370         # give time for CDT to send request and to keep it for retry
5371         wait_for_loop_period
5372
5373         wait_request_state $fid ARCHIVE WAITING
5374
5375         do_facet $SINGLEAGT lctl set_param fail_loc=0
5376
5377         # request should succeed now
5378         wait_request_state $fid ARCHIVE SUCCEED
5379 }
5380 run_test 402b "CDT must retry request upon slow start of CT"
5381
5382 test_403() {
5383         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5384
5385         local agent=$(facet_active_host $SINGLEAGT)
5386
5387         # deactivate all mdc for MDT0001
5388         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "deactivate"
5389
5390         copytool setup
5391         local uuid=$(get_agent_uuid $agent)
5392         # check the agent is registered on MDT0000, and not on MDT0001
5393         check_agent_registered_by_mdt $uuid 0
5394         check_agent_unregistered_by_mdt $uuid 1
5395
5396         # check running copytool process
5397         search_copytools $agent || error "No running copytools on $agent"
5398
5399         # reactivate all mdc for MDT0001
5400         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "activate"
5401
5402         # make sure the copytool is now registered to all MDTs
5403         check_agent_registered $uuid
5404 }
5405 run_test 403 "Copytool starts with inactive MDT and register on reconnect"
5406
5407 test_404() {
5408         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5409
5410         copytool setup
5411
5412         # create files on both MDT0000 and MDT0001
5413         mkdir_on_mdt0 $DIR/$tdir
5414
5415         local dir_mdt0=$DIR/$tdir/mdt0
5416         stack_trap "rm -rf $dir_mdt0" EXIT
5417         $LFS mkdir -i 0 $dir_mdt0 || error "lfs mkdir"
5418
5419         # create 1 file on mdt0
5420         local fid1=$(create_small_file $dir_mdt0/$tfile)
5421
5422         # deactivate all mdc for MDT0001
5423         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "deactivate"
5424
5425         # send an HSM request for files in MDT0000
5426         $LFS hsm_archive $dir_mdt0/$tfile || error "lfs hsm_archive"
5427
5428         # check for completion of files in MDT0000
5429         wait_request_state $fid1 ARCHIVE SUCCEED 0 &&
5430                 echo "archive successful on mdt0"
5431
5432         # reactivate all mdc for MDT0001
5433         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "activate"
5434 }
5435 run_test 404 "Inactive MDT does not block requests for active MDTs"
5436
5437 test_405() {
5438         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5439
5440         copytool setup
5441
5442         mkdir_on_mdt0 $DIR/$tdir
5443
5444         local striped_dir=$DIR/$tdir/striped_dir
5445
5446         # create striped dir on all of MDTs
5447         $LFS mkdir -i 0 -c $MDSCOUNT $striped_dir || error "lfs mkdir"
5448
5449         local fid1=$(create_small_sync_file $striped_dir/${tfile}_0)
5450         local fid2=$(create_small_sync_file $striped_dir/${tfile}_1)
5451         local fid3=$(create_small_sync_file $striped_dir/${tfile}_2)
5452         local fid4=$(create_small_sync_file $striped_dir/${tfile}_3)
5453
5454         local idx1=$($LFS getstripe -m $striped_dir/${tfile}_0)
5455         local idx2=$($LFS getstripe -m $striped_dir/${tfile}_1)
5456         local idx3=$($LFS getstripe -m $striped_dir/${tfile}_2)
5457         local idx4=$($LFS getstripe -m $striped_dir/${tfile}_3)
5458
5459         # check that compound requests are shunt to the rights MDTs
5460         $LFS hsm_archive $striped_dir/${tfile}_0 $striped_dir/${tfile}_1  \
5461                          $striped_dir/${tfile}_2 $striped_dir/${tfile}_3 ||
5462                 error "lfs hsm_archive"
5463
5464         wait_request_state $fid1 ARCHIVE SUCCEED $idx1 &&
5465                 echo "archive successful on $fid1"
5466         wait_request_state $fid2 ARCHIVE SUCCEED $idx2 &&
5467                 echo "archive successful on $fid2"
5468         wait_request_state $fid3 ARCHIVE SUCCEED $idx3 &&
5469                 echo "archive successful on $fid3"
5470         wait_request_state $fid4 ARCHIVE SUCCEED $idx4 &&
5471                 echo "archive successful on $fid4"
5472
5473         $LFS hsm_release $striped_dir/${tfile}_0 || error "lfs hsm_release 1"
5474         $LFS hsm_release $striped_dir/${tfile}_1 || error "lfs hsm_release 2"
5475         $LFS hsm_release $striped_dir/${tfile}_2 || error "lfs hsm_release 3"
5476         $LFS hsm_release $striped_dir/${tfile}_3 || error "lfs hsm_release 4"
5477
5478         cat $striped_dir/${tfile}_0 > /dev/null || error "cat ${tfile}_0 failed"
5479         cat $striped_dir/${tfile}_1 > /dev/null || error "cat ${tfile}_1 failed"
5480         cat $striped_dir/${tfile}_2 > /dev/null || error "cat ${tfile}_2 failed"
5481         cat $striped_dir/${tfile}_3 > /dev/null || error "cat ${tfile}_3 failed"
5482 }
5483 run_test 405 "archive and release under striped directory"
5484
5485 test_406() {
5486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
5487
5488         [ $MDS1_VERSION -lt $(version_code 2.7.64) ] &&
5489                 skip "need MDS version at least 2.7.64"
5490
5491         local fid
5492         local mdt_index
5493
5494         mkdir_on_mdt0 $DIR/$tdir
5495
5496         fid=$(create_small_file $DIR/$tdir/$tfile)
5497         echo "old fid $fid"
5498
5499         copytool setup
5500
5501         $LFS hsm_archive $DIR/$tdir/$tfile
5502         wait_request_state "$fid" ARCHIVE SUCCEED
5503         $LFS hsm_release $DIR/$tdir/$tfile
5504
5505         # Should migrate $tdir but not $tfile.
5506         $LFS migrate -m1 $DIR/$tdir &&
5507                 error "migrating HSM an archived file should fail"
5508
5509         $LFS hsm_restore $DIR/$tdir/$tfile
5510         wait_request_state "$fid" RESTORE SUCCEED
5511
5512         $LFS hsm_remove $DIR/$tdir/$tfile
5513         wait_request_state "$fid" REMOVE SUCCEED
5514
5515         cat $DIR/$tdir/$tfile > /dev/null ||
5516                 error "cannot read $DIR/$tdir/$tfile"
5517
5518         $LFS migrate -m1 $DIR/$tdir ||
5519                 error "cannot complete migration after HSM remove"
5520
5521         mdt_index=$($LFS getstripe -m $DIR/$tdir)
5522         if ((mdt_index != 1)); then
5523                 error "expected MDT index 1, got $mdt_index"
5524         fi
5525
5526         # Refresh fid after migration.
5527         fid=$(path2fid $DIR/$tdir/$tfile)
5528         echo "new fid $fid"
5529
5530         $LFS hsm_archive $DIR/$tdir/$tfile
5531         wait_request_state "$fid" ARCHIVE SUCCEED 1
5532
5533         lctl set_param debug=+trace
5534         $LFS hsm_release $DIR/$tdir/$tfile ||
5535                 error "cannot release $DIR/$tdir/$tfile"
5536
5537         $LFS hsm_restore $DIR/$tdir/$tfile
5538         wait_request_state "$fid" RESTORE SUCCEED 1
5539
5540         cat $DIR/$tdir/$tfile > /dev/null ||
5541                 error "cannot read $DIR/$tdir/$tfile"
5542 }
5543 run_test 406 "attempting to migrate HSM archived files is safe"
5544
5545 test_407() {
5546         mkdir_on_mdt0 $DIR/$tdir
5547
5548         local f=$DIR/$tdir/$tfile
5549         local f2=$DIR2/$tdir/$tfile
5550         local fid=$(create_empty_file "$f")
5551
5552         copytool setup
5553
5554         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
5555         wait_request_state $fid ARCHIVE SUCCEED
5556         $LFS hsm_release $f
5557
5558 #define OBD_FAIL_MDS_HSM_CDT_DELAY      0x164
5559         do_facet $SINGLEMDS $LCTL set_param fail_val=5 fail_loc=0x164
5560
5561         # Prevent restore from completing
5562         copytool_suspend
5563
5564         md5sum $f &
5565         # 1st request holds layout lock while appropriate
5566         # RESTORE record is still not added to llog
5567         md5sum $f2 &
5568         sleep 2
5569
5570         do_facet $SINGLEMDS "$LCTL get_param $HSM_PARAM.actions"
5571         # after umount hsm_actions->O/x/x log shouldn't have
5572         # double RESTORE records like below
5573         #[0x200000401:0x1:0x0]...0x58d03a0d/0x58d03a0c action=RESTORE...WAITING
5574         #[0x200000401:0x1:0x0]...0x58d03a0c/0x58d03a0d action=RESTORE...WAITING
5575         sleep 30 &&
5576                 do_facet $SINGLEMDS "$LCTL get_param $HSM_PARAM.actions"&
5577         fail $SINGLEMDS
5578         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
5579
5580         do_facet $SINGLEMDS "$LCTL get_param $HSM_PARAM.actions"
5581
5582         copytool_continue
5583         wait_all_done 100 $fid
5584 }
5585 run_test 407 "Check for double RESTORE records in llog"
5586
5587 test_408 () { #LU-17110
5588         checkfiemap --test ||
5589                 skip "checkfiemap not runnable: $?"
5590
5591         local f=$DIR/$tfile
5592         local fid
5593         local out;
5594
5595         copytool setup
5596
5597         # write data this way: hole - data - hole - data
5598         dd if=/dev/urandom of=$f bs=64K count=1 conv=fsync
5599         [[ "$(facet_fstype ost$(($($LFS getstripe -i $f) + 1)))" != "zfs" ]] ||
5600                 skip "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
5601         dd if=/dev/urandom of=$f bs=64K seek=3 count=1 conv=fsync
5602         stat $DIR/$tfile
5603         echo "disk usage: $(du -B1 $f)"
5604         echo "file size: $(du -b $f)"
5605
5606         fid=$(path2fid $f)
5607         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
5608         wait_request_state $fid ARCHIVE SUCCEED
5609         $LFS hsm_release $f
5610
5611         out=$(checkfiemap --corruption_test $f $((4 * 64 * 1024))) ||
5612                 error "checkfiemap failed"
5613
5614         echo "$out"
5615         grep -q "flags (0x3):" <<< "$out" ||
5616                 error "the extent flags of a relase file should be: LAST UNKNOWN"
5617
5618 }
5619 run_test 408 "Verify fiemap on release file"
5620
5621 test_409a() {
5622         (( MDS1_VERSION >= $(version_code 2.15.59) )) ||
5623                 skip "need MDS version at least 2.15.59"
5624
5625         mkdir_on_mdt0 $DIR/$tdir
5626
5627         local restore_pid shutdown_pid
5628         local mdt0_hsm_state
5629         local f=$DIR/$tdir/$tfile
5630         local fid=$(create_empty_file "$f")
5631
5632         copytool setup
5633
5634         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
5635                 error "could not archive file $f"
5636         wait_request_state $fid ARCHIVE SUCCEED
5637         $LFS hsm_release $f || error "could not release file $f"
5638
5639 #define OBD_FAIL_MDS_HSM_CDT_DELAY      0x164
5640         do_facet $SINGLEMDS $LCTL set_param fail_val=5 fail_loc=0x164
5641
5642         # send a restore request
5643         cat $f > /dev/null & restore_pid=$!
5644
5645         # stop the coordinator while it handle the request
5646         cdt_shutdown & shutdown_pid=$!
5647         stack_trap "cdt_enable" EXIT
5648
5649         sleep 1;
5650         mdt0_hsm_state=$(do_facet mds1 "$LCTL get_param -n mdt.*MDT0000.hsm_control")
5651         [[ "$mdt0_hsm_state" == "stopping" ]] ||
5652                 error "HSM state of MDT0000 is not 'stopping' (hsm_control=$mdt0_hsm_state)"
5653
5654         wait $shutdown_pid
5655         cdt_check_state stopped
5656         wait_request_state $fid RESTORE WAITING
5657
5658         cdt_enable
5659
5660         # copytool must re-register
5661         kill_copytools
5662         wait_copytools || error "copytool failed to stop"
5663         copytool setup
5664
5665         wait $restore_pid || true
5666         wait_request_state $fid RESTORE SUCCEED
5667         cat $f > /dev/null || error "fail to read $f"
5668 }
5669 run_test 409a "Coordinator should not stop when in use"
5670
5671 test_409b()
5672 {
5673         mkdir_on_mdt0 $DIR/$tdir
5674
5675         local f=$DIR/$tdir/$tfile
5676         local fid=$(create_empty_file "$f")
5677
5678         copytool setup
5679
5680         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
5681         wait_request_state $fid ARCHIVE SUCCEED
5682
5683         $LFS hsm_release $f || error "cannot release $f"
5684         check_hsm_flags $f "0x0000000d"
5685
5686         kill_copytools
5687         wait_copytools || error "copytools failed to stop"
5688
5689         # Remount fs to clear cached file attributes and free restore hash
5690         stack_trap "cdt_check_state enabled" EXIT
5691         stack_trap "cdt_set_mount_state enabled" EXIT
5692         cdt_set_mount_state shutdown
5693         cdt_check_state stopped
5694
5695         fail mds1
5696
5697         # getattr should work even if CDT is stopped
5698         stat $f || error "cannot stat file"
5699 }
5700 run_test 409b "getattr released file with CDT stopped after remount"
5701
5702 test_410()
5703 {
5704         (( MDS1_VERSION >= $(version_code 2.15.90.10) )) ||
5705                 skip "need MDS >= v2_15_90-10-g80a961261a23 for HSM fix"
5706
5707         mkdir_on_mdt0 $DIR/$tdir
5708
5709         local f=$DIR/$tdir/$tfile
5710         local fid=$(create_small_file $f)
5711
5712         copytool setup
5713
5714         $LFS hsm_set --exists --archived $f ||
5715                 error "could not change hsm flags"
5716         $LFS hsm_release $f 2>&1 > /dev/null && error "HSM release should fail"
5717
5718         $LFS data_version -ws $f 2>&1 > /dev/null
5719         $LFS hsm_release $f || error "could not release file"
5720 }
5721 run_test 410 "lfs data_version -s allows release of force-archived file"
5722
5723 cleanup_411() {
5724         local nm=$1
5725
5726         do_facet mgs $LCTL nodemap_del $nm || true
5727         do_facet mgs $LCTL nodemap_activate 0
5728         wait_nm_sync active
5729 }
5730
5731 test_411()
5732 {
5733         local client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
5734         local client_nid=$(h2nettype $client_ip)
5735         local tf1=$DIR/$tdir/fileA
5736         local tf2=$DIR/$tdir/fileB
5737         local nm=test_411
5738         local roles
5739         local fid
5740
5741         do_facet mgs $LCTL nodemap_modify --name default \
5742                 --property admin --value 1
5743         do_facet mgs $LCTL nodemap_modify --name default \
5744                 --property trusted --value 1
5745         do_facet mgs $LCTL nodemap_add $nm
5746         do_facet mgs $LCTL nodemap_add_range    \
5747                 --name $nm --range $client_nid
5748         do_facet mgs $LCTL nodemap_modify --name $nm \
5749                 --property admin --value 1
5750         do_facet mgs $LCTL nodemap_modify --name $nm \
5751                 --property trusted --value 1
5752         do_facet mgs $LCTL nodemap_activate 1
5753         stack_trap "cleanup_411 $nm" EXIT
5754         wait_nm_sync active
5755         wait_nm_sync $nm trusted_nodemap
5756
5757         roles=$(do_facet mds $LCTL get_param -n nodemap.$nm.rbac)
5758         [[ "$roles" =~ "hsm_ops" ]] ||
5759                 skip "role 'hsm_ops' not supported by server"
5760
5761         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
5762         echo hi > $tf1 || error "create $tf1 failed"
5763         echo hi > $tf2 || error "create $tf2 failed"
5764
5765         copytool setup
5766
5767         # with hsm_ops role, all ops should pass
5768         fid=$(path2fid $tf1)
5769         $LFS hsm_state $tf1 || error "hsm_state $tf1 failed"
5770         $LFS hsm_archive $tf1 || error "hsm_archive $tf1 failed"
5771         wait_request_state $fid ARCHIVE SUCCEED
5772         $LFS hsm_release $tf1 || error "hsm_release $tf1 failed"
5773         check_hsm_flags $tf1 "0x0000000d"
5774         $LFS hsm_restore $tf1 || error "hsm_restore $tf1 failed"
5775         wait_request_state $fid RESTORE SUCCEED
5776         $LFS hsm_remove $tf1 || error "hsm_remove $tf1 failed"
5777         wait_request_state $fid REMOVE SUCCEED
5778         check_hsm_flags $tf1 "0x00000000"
5779         $LFS hsm_set --exists $tf1 || error "hsm_set $tf1 failed"
5780         check_hsm_flags $tf1 "0x00000001"
5781         $LFS hsm_clear --exists $tf1 || error "hsm_clear $tf1 failed"
5782         check_hsm_flags $tf1 "0x00000000"
5783
5784         # check copytool cleanup works with the hsm_ops rbac role present
5785         # and nodemap activated
5786         kill_copytools
5787         wait_copytools || error "copytool failed to stop"
5788
5789         copytool setup
5790         # Re-add cleanup_411 to the stack to make sure it is always called
5791         # before the copytool is cleaned up.
5792         stack_trap "cleanup_411 $nm" EXIT
5793
5794         # remove hsm_ops from rbac roles
5795         roles=$(echo "$roles" | sed 's/hsm_ops,//;s/,hsm_ops//;s/^hsm_ops,//')
5796         do_facet mgs $LCTL nodemap_modify --name $nm \
5797                 --property rbac --value $roles
5798         wait_nm_sync $nm rbac
5799
5800         # without hsm_ops role, all ops should fail
5801         fid=$(path2fid $tf2)
5802         $LFS hsm_state $tf2 || error "hsm_state $tf2 failed"
5803         $LFS hsm_archive $tf2 && error "hsm_archive $tf2 succeeded"
5804         $LFS hsm_release $tf2 && error "hsm_release $tf2 succeeded"
5805         check_hsm_flags $tf2 "0x00000000"
5806         $LFS hsm_restore $tf2 && error "hsm_restore $tf2 succeeded"
5807         $LFS hsm_remove $tf2 && error "hsm_remove $tf2 succeeded"
5808         check_hsm_flags $tf2 "0x00000000"
5809         $LFS hsm_set --exists $tf2 && error "hsm_set $tf2 succeeded"
5810         check_hsm_flags $tf2 "0x00000000"
5811         $LFS hsm_clear --exists $tf2 && error "hsm_clear $tf2 succeeded"
5812         check_hsm_flags $tf2 "0x00000000"
5813 }
5814 run_test 411 "hsm_ops rbac role"
5815
5816 test_500()
5817 {
5818         local bitmap_opt=""
5819
5820         (( $MDS1_VERSION >= $(version_code 2.6.92-47-g1fe3ae8dab) )) ||
5821                 skip "need MDS >= 2.6.92.47 for HSM migrate support"
5822
5823         test_mkdir -p $DIR/$tdir
5824
5825         (( $CLIENT_VERSION >= $(version_code 2.11.56-179-g3bfb6107ba) &&
5826            $MDS1_VERSION >= $(version_code 2.11.56-179-g3bfb6107ba) )) ||
5827                 bitmap_opt="-b"
5828
5829         (( $MDS1_VERSION >= $(version_code 2.14.50-142-gf684172237) )) ||
5830                 SKIP500+=" -s 113"
5831
5832         llapi_hsm_test -d $DIR/$tdir $bitmap_opt $SKIP500 ||
5833                 error "llapi HSM testing failed"
5834 }
5835 run_test 500 "various LLAPI HSM tests"
5836
5837 test_600() {
5838         [ "$MDS1_VERSION" -lt $(version_code 2.10.58) ] &&
5839                 skip "need MDS version at least 2.10.58"
5840
5841         mkdir -p $DIR/$tdir
5842
5843         local f=$DIR/$tdir/$tfile
5844
5845         changelog_register
5846         # set changelog_mask to ALL
5847         changelog_chmask "ALL"
5848
5849         chmod 777 $DIR/$tdir
5850         $RUNAS touch $f || error "touch $f failed as $RUNAS_ID"
5851         local fid=$(path2fid $f)
5852
5853         local entry
5854         entry=$(changelog_find -type CREAT -target-fid $fid -uid "$RUNAS_ID" \
5855                                -gid "$RUNAS_GID") ||
5856                 error "No matching CREAT entry"
5857
5858         # Parse the changelog
5859         eval local -A changelog=$(changelog2array $entry)
5860         local nid="${changelog[nid]}"
5861
5862         # Check its NID
5863         echo "Got NID '$nid'"
5864         [ -n "$nid" ] && [[ "${CLIENT_NIDS[*]}" =~ $nid ]] ||
5865                 error "nid '$nid' does not match any client NID:" \
5866                       "${CLIENT_NIDS[@]}"
5867 }
5868 run_test 600 "Changelog fields 'u=' and 'nid='"
5869
5870 test_601() {
5871         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
5872                 skip "need MDS version at least 2.10.58"
5873
5874         mkdir -p $DIR/$tdir
5875
5876         local f=$DIR/$tdir/$tfile
5877
5878         changelog_register
5879         # set changelog_mask to ALL
5880         changelog_chmask "ALL"
5881
5882         touch $f || error "touch $f failed"
5883         local fid=$(path2fid $f)
5884
5885         changelog_clear
5886         cat $f || error "cat $f failed"
5887
5888         changelog_find -type OPEN -target-fid $fid -mode "r--" ||
5889                 error "No matching OPEN entry"
5890 }
5891 run_test 601 "OPEN Changelog entry"
5892
5893 test_602() {
5894         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
5895                 skip "need MDS version at least 2.10.58"
5896
5897         stack_trap "restore_opencache" EXIT
5898         disable_opencache
5899
5900         mkdir -p $DIR/$tdir
5901
5902         local f=$DIR/$tdir/$tfile
5903
5904         changelog_register
5905         # set changelog_mask to ALL
5906         changelog_chmask "ALL"
5907
5908         touch $f || error "touch $f failed"
5909         local fid=$(path2fid $f)
5910
5911         changelog_clear
5912         cat $f || error "cat $f failed"
5913
5914         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
5915
5916         changelog_clear
5917         changelog_dump
5918         echo f > $f || error "write $f failed"
5919         changelog_dump
5920
5921         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
5922
5923         # remove OPEN from changelog_mask
5924         changelog_chmask "-OPEN"
5925
5926         changelog_clear
5927         changelog_dump
5928         cat $f || error "cat $f failed"
5929         changelog_dump
5930
5931         changelog_find -type CLOSE -target-fid $fid &&
5932                 error "There should be no CLOSE entry"
5933
5934         changelog_clear
5935         changelog_dump
5936         echo f > $f || error "write $f failed"
5937         changelog_dump
5938
5939         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
5940 }
5941 run_test 602 "Changelog record CLOSE only if open+write or OPEN recorded"
5942
5943 test_603() {
5944         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
5945                 skip "need MDS version at least 2.10.58"
5946
5947         mkdir -p $DIR/$tdir
5948
5949         local f=$DIR/$tdir/$tfile
5950
5951         changelog_register
5952         # set changelog_mask to ALL
5953         changelog_chmask "ALL"
5954
5955         touch $f || error "touch $f failed"
5956         local fid=$(path2fid $f)
5957
5958         setfattr -n user.xattr1 -v "value1" $f || error "setfattr $f failed"
5959
5960         changelog_clear
5961         getfattr -n user.xattr1 $f || error "getfattr $f failed"
5962
5963         changelog_find -type GXATR -target-fid $fid -xattr "user.xattr1" ||
5964                 error "No matching GXATR entry"
5965 }
5966 run_test 603 "GETXATTR Changelog entry"
5967
5968 test_604() {
5969         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
5970                 skip "need MDS version at least 2.10.58"
5971
5972         mkdir_on_mdt0 $DIR/$tdir
5973
5974         local f=$DIR/$tdir/$tfile
5975         local f2=$DIR2/$tdir/$tfile
5976         local procname="mdd.$FSNAME-MDT0000.changelog_deniednext"
5977         local timeout
5978         timeout="$(do_facet mds1 "$LCTL" get_param -n "$procname")"
5979         stack_trap "do_facet mds1 '$LCTL' set_param '$procname=$timeout'" EXIT
5980         do_facet mds1 lctl set_param "$procname=20"
5981
5982
5983         changelog_register
5984         # set changelog_mask to ALL
5985         changelog_chmask "ALL"
5986
5987         touch $f || error "touch $f failed"
5988         local fid=$(path2fid $f)
5989
5990         chmod 600 $f
5991
5992         changelog_clear
5993         changelog_dump
5994         $RUNAS cat $f2 && error "cat $f2 by user $RUNAS_ID should have failed"
5995         changelog_dump
5996
5997         local entry
5998         entry=$(changelog_find -type NOPEN -target-fid $fid -uid "$RUNAS_ID" \
5999                                -gid "$RUNAS_GID" -mode "r--") ||
6000                 error "No matching NOPEN entry"
6001
6002         # Parse the changelog
6003         eval local -A changelog=$(changelog2array $entry)
6004         local nid="${changelog[nid]}"
6005
6006         # Check its NID
6007         echo "Got NID '$nid'"
6008         [ -n "$nid" ] && [[ "${CLIENT_NIDS[*]}" =~ $nid ]] ||
6009                 error "nid '$nid' does not match any client NID:" \
6010                       "${CLIENT_NIDS[@]}"
6011
6012         changelog_clear
6013         changelog_dump
6014         $RUNAS cat $f2 && error "cat $f2 by user $RUNAS_ID should have failed"
6015         changelog_dump
6016
6017         changelog_find -type NOPEN -target-fid $fid &&
6018                 error "There should be no NOPEN entry"
6019
6020         # Sleep for `changelog_deniednext` seconds
6021         sleep 20
6022
6023         changelog_clear
6024         changelog_dump
6025         $RUNAS cat $f2 && error "cat $f by user $RUNAS_ID should have failed"
6026         changelog_dump
6027
6028         entry=$(changelog_find -type NOPEN -target-fid $fid -uid "$RUNAS_ID" \
6029                                -gid "$RUNAS_GID" -mode "r--") ||
6030                 error "No matching NOPEN entry"
6031
6032         # Parse the changelog
6033         eval local -A changelog=$(changelog2array $entry)
6034         local nid="${changelog[nid]}"
6035
6036         # Check the NID
6037         echo "Got NID '$nid'"
6038         [ -n "$nid" ] && [[ "${CLIENT_NIDS[*]}" =~ $nid ]] ||
6039                 error "nid '$nid' does not match any client NID:" \
6040                       "${CLIENT_NIDS[@]}"
6041 }
6042 run_test 604 "NOPEN Changelog entry"
6043
6044 test_605() {
6045         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
6046                 skip "need MDS version at least 2.10.58"
6047
6048         stack_trap "restore_opencache" EXIT
6049         disable_opencache
6050
6051         mkdir -p $DIR/$tdir
6052
6053         local f=$DIR/$tdir/$tfile
6054         local f2=$DIR2/$tdir/$tfile
6055
6056         changelog_register
6057         # set changelog_mask to ALL
6058         changelog_chmask "ALL"
6059
6060         touch $f || error "touch $f failed"
6061         local fid=$(path2fid $f)
6062
6063         changelog_clear
6064         changelog_dump
6065         exec 3<> $f || error "open $f failed"
6066         changelog_dump
6067
6068         local entry
6069         changelog_find -type OPEN -target-fid $fid || error "No OPEN entry"
6070
6071         changelog_clear
6072         changelog_dump
6073         exec 4<> $f || error "open $f failed"
6074         changelog_dump
6075
6076         changelog_find -type OPEN -target-fid $fid &&
6077                 error "There should be no OPEN entry"
6078
6079         exec 4>&- || error "close $f failed"
6080         changelog_dump
6081
6082         changelog_find -type CLOSE -target-fid $fid &&
6083                 error "There should be no CLOSE entry"
6084
6085         changelog_clear
6086         changelog_dump
6087         # access in rw, so different access mode should generate entries
6088         cat $f || error "cat $f failed"
6089         changelog_dump
6090
6091         changelog_find -type OPEN -target-fid $fid || error "No OPEN entry"
6092
6093         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
6094
6095         changelog_clear
6096         changelog_dump
6097         # same access as first one, should not generate new entries
6098         exec 4<> $f || error "open $f failed"
6099         changelog_dump
6100
6101         changelog_find -type OPEN -target-fid $fid &&
6102                 error "There should be no OPEN entry"
6103
6104         exec 4>&- || error "close $f failed"
6105         changelog_dump
6106
6107         changelog_find -type CLOSE -target-fid $fid &&
6108                 error "There should be no CLOSE entry"
6109
6110         changelog_clear
6111         changelog_dump
6112         # access by different user should generate new entries
6113         $RUNAS cat $f || error "cat $f by user $RUNAS_ID failed"
6114         changelog_dump
6115
6116         changelog_find -type OPEN -target-fid $fid || error "No OPEN entry"
6117
6118         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
6119
6120         changelog_clear
6121         changelog_dump
6122         exec 3>&- || error "close $f failed"
6123         changelog_dump
6124
6125         changelog_find -type CLOSE -target-fid $fid || error "No CLOSE entry"
6126 }
6127 run_test 605 "Test OPEN and CLOSE rate limit in Changelogs"
6128
6129 test_606() {
6130         [ $MDS1_VERSION -lt $(version_code 2.10.58) ] &&
6131                 skip "need MDS version at least 2.10.58"
6132
6133         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6134         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6135         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6136                         skip_env "missing llog_reader"
6137
6138         mkdir_on_mdt0 $DIR/$tdir
6139
6140         local f=$DIR/$tdir/$tfile
6141
6142         changelog_register
6143         # set changelog_mask to ALL
6144         changelog_chmask "ALL"
6145
6146         chmod 777 $DIR/$tdir
6147         $RUNAS touch $f || error "touch $f failed as $RUNAS_ID"
6148         local fid=$(path2fid $f)
6149         rm $f || error "rm $f failed"
6150
6151         local mntpt=$(facet_mntpt mds1)
6152         local pass=true
6153         local entry
6154
6155         #remount mds1 as ldiskfs or zfs type
6156         stop mds1 || error "stop mds1 failed"
6157         stack_trap "unmount_fstype mds1; start mds1 $(mdsdevname 1)\
6158                 $MDS_MOUNT_OPTS" EXIT
6159         mount_fstype mds1 || error "remount mds1 failed"
6160
6161         for ((i = 0; i < 1; i++)); do
6162                 do_facet mds1 $llog_reader $mntpt/changelog_catalog
6163                 local cat_file=$(do_facet mds1 $llog_reader \
6164                                 $mntpt/changelog_catalog | awk \
6165                                 '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
6166                 [ -n "$cat_file" ] || error "no catalog file"
6167
6168                 entry=$(do_facet mds1 $llog_reader $mntpt/$cat_file |
6169                         awk "/CREAT/ && /target:\[$fid\]/ {print}")
6170                 [ -n "$entry" ] || error "no CREAT entry"
6171         done
6172
6173         local uidgid=$(echo $entry |
6174                 sed 's+.*\ user:\([0-9][0-9]*:[0-9][0-9]*\)\ .*+\1+')
6175         [ -n "$uidgid" ] || error "uidgid is empty"
6176         echo "Got UID/GID $uidgid"
6177         [ "$uidgid" = "$RUNAS_ID:$RUNAS_GID" ] ||
6178                 error "uidgid '$uidgid' != '$RUNAS_ID:$RUNAS_GID'"
6179         local nid=$(echo $entry |
6180                 sed 's+.*\ nid:\(\S\S*@\S\S*\)\ .*+\1+')
6181         [ -n "$nid" ] || error "nid is empty"
6182         echo "Got NID $nid"
6183         [ -n "$nid" ] && [[ "${CLIENT_NIDS[*]}" =~ $nid ]] ||
6184                 error "nid '$nid' does not match any NID ${CLIENT_NIDS[*]}"
6185 }
6186 run_test 606 "llog_reader groks changelog fields"
6187
6188 get_hsm_xattr_sha()
6189 {
6190         getfattr -e text -n trusted.hsm "$1" 2>/dev/null |
6191                 sha1sum | awk '{ print $1 }'
6192 }
6193
6194 test_hsm_migrate_init()
6195 {
6196         local d=$1
6197         local f=$2
6198         local fid
6199
6200         mkdir_on_mdt0 "$d"
6201         fid=$(create_small_file "$f")
6202
6203         echo "$fid"
6204 }
6205
6206 test_607a()
6207 {
6208         local d="$DIR/$tdir"
6209         local f="$d/$tfile"
6210         local fid
6211
6212         (( MDS1_VERSION >= $(version_code 2.15.60) )) ||
6213                 skip "need MDS version at least 2.15.60"
6214
6215         (( OSTCOUNT >= 2 )) || skip_env "needs >= 2 OSTs"
6216
6217         fid=$(test_hsm_migrate_init "$d" "$f" | tail -1)
6218
6219         copytool setup
6220
6221         $LFS hsm_archive "$f" || error "could not archive file"
6222         wait_request_state $fid ARCHIVE SUCCEED
6223
6224         $LFS migrate -n -i 1 "$f" ||
6225                 error "could not migrate file to OST 1"
6226
6227         $LFS hsm_release "$f" ||
6228                 error "could not release file after non blocking migrate"
6229         $LFS hsm_restore "$f" ||
6230                 error "could not restore file after non blocking migrate"
6231         wait_request_state $fid RESTORE SUCCEED
6232 }
6233 run_test 607a "release a file that was migrated after being archived"
6234
6235 test_607b()
6236 {
6237         local d="$DIR/$tdir"
6238         local f="$DIR/$tdir/$tfile"
6239         local saved_params
6240         local old_hsm
6241         local new_hsm
6242         local fid
6243
6244         (( MDS1_VERSION >= $(version_code 2.15.60) )) ||
6245                 skip "need MDS version at least 2.15.60"
6246
6247         (( OSTCOUNT >= 2 )) || skip_env "needs >= 2 OSTs"
6248
6249         fid=$(test_hsm_migrate_init "$d" "$f" | tail -1)
6250
6251         copytool setup
6252
6253         $LFS hsm_archive "$f" || error "could not archive file"
6254         wait_request_state $fid ARCHIVE SUCCEED
6255
6256         saved_params=$($LCTL get_param llite.*.xattr_cache | tr '\n' ' ')
6257         $LCTL set_param llite.*.xattr_cache=0
6258         stack_trap "$LCTL set_param $saved_params" EXIT
6259
6260         # make sure that migrate won't change archive version
6261         echo 10 >> "$f"
6262
6263         old_hsm=$(get_hsm_xattr_sha "$f")
6264         $LFS migrate -n -i 1 "$f" ||
6265                 error "could not migrate file to OST 1"
6266
6267         $LFS hsm_state "$f" | grep dirty || error "dirty flag not found"
6268
6269         new_hsm=$(get_hsm_xattr_sha "$f")
6270         [ "$old_hsm" != "$new_hsm" ] &&
6271                  error "migrate should not modify data version of dirty files"
6272
6273         return 0
6274 }
6275 run_test 607b "Migrate should not change the HSM attribute of dirty files"
6276
6277 test_607c()
6278 {
6279         local d="$DIR/$tdir"
6280         local f="$DIR/$tdir/$tfile"
6281         local fid1 fid2 fid3
6282         local nbr_dirty
6283
6284         (( MDS1_VERSION >= $(version_code 2.15.60) )) ||
6285                 skip "need MDS version at least 2.15.60"
6286
6287         mkdir_on_mdt0 $d
6288         fid1=$(create_small_file "$f-1")
6289         fid2=$(create_small_file "$f-2")
6290         fid3=$(create_small_file "$f-3")
6291
6292         copytool setup
6293
6294         $LFS hsm_archive "$f-1" || error "could not archive file"
6295         wait_request_state $fid1 ARCHIVE SUCCEED
6296
6297         $LFS hsm_archive "$f-3" || error "could not archive file"
6298         wait_request_state $fid3 ARCHIVE SUCCEED
6299
6300         $LFS swap_layouts "$f-1" "$f-3" |& grep "Operation not permitted" ||
6301                 error "swap_layouts should fail with EPERM on 2 archived file"
6302
6303         $LFS swap_layouts "$f-1" "$f-2" ||
6304                 error "swap_layout failed on $f-1 and $f-2"
6305
6306         $LFS swap_layouts "$f-2" "$f-3" ||
6307                 error "swap_layout failed on $f-2 and $f-3"
6308
6309         nbr_dirty=$($LFS hsm_state "$f-1" "$f-3" | grep -c 'dirty')
6310         ((nbr_dirty == 2)) || error "dirty flag should be set on $f-1 and $f-3"
6311
6312 }
6313 run_test 607c "'lfs swap_layouts' should set dirty flag on HSM file"
6314
6315 complete_test $SECONDS
6316 check_and_cleanup_lustre
6317 exit_status