Whamcloud - gitweb
LU-9474 tests: rewrite copytool_setup to use stack_trap
[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 SRCDIR=$(dirname $0)
11 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/utils:$PATH:/sbin:/usr/sbin
12
13 ONLY=${ONLY:-"$*"}
14 # bug number for skipped test:
15 ALWAYS_EXCEPT="$SANITY_HSM_EXCEPT"
16 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
17
18 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
19
20 . $LUSTRE/tests/test-framework.sh
21 init_test_env $@
22 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
23 init_logging
24
25 MULTIOP=${MULTIOP:-multiop}
26 OPENFILE=${OPENFILE:-openfile}
27 MMAP_CAT=${MMAP_CAT:-mmap_cat}
28 MOUNT_2=${MOUNT_2:-"yes"}
29 FAIL_ON_ERROR=false
30
31 # script only handles up to 10 MDTs (because of MDT_PREFIX)
32 [ $MDSCOUNT -gt 9 ] &&
33         error "script cannot handle more than 9 MDTs, please fix" && exit
34
35 check_and_setup_lustre
36
37 if [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.53) ]]; then
38         skip_env "Need MDS version at least 2.4.53" && exit
39 fi
40
41 # $RUNAS_ID may get set incorrectly somewhere else
42 if [[ $UID -eq 0 && $RUNAS_ID -eq 0 ]]; then
43         skip_env "\$RUNAS_ID set to 0, but \$UID is also 0!" && exit
44 fi
45 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
46
47 build_test_filter
48
49 # if there is no CLIENT1 defined, some tests can be ran on localhost
50 CLIENT1=${CLIENT1:-$HOSTNAME}
51 # if CLIENT2 doesn't exist then use CLIENT1 instead
52 # All tests should use CLIENT2 with MOUNT2 only therefore it will work if
53 # $CLIENT2 == CLIENT1
54 # Exception is the test which need two separate nodes
55 CLIENT2=${CLIENT2:-$CLIENT1}
56
57 #
58 # In order to test multiple remote HSM agents, a new facet type named "AGT" and
59 # the following associated variables are added:
60 #
61 # AGTCOUNT: number of agents
62 # AGTDEV{N}: target HSM mount point (root path of the backend)
63 # agt{N}_HOST: hostname of the agent agt{N}
64 # SINGLEAGT: facet of the single agent
65 #
66 # The number of agents is initialized as the number of remote client nodes.
67 # By default, only single copytool is started on a remote client/agent. If there
68 # was no remote client, then the copytool will be started on the local client.
69 #
70 init_agt_vars() {
71         local n
72         local agent
73
74         export AGTCOUNT=${AGTCOUNT:-$((CLIENTCOUNT - 1))}
75         [[ $AGTCOUNT -gt 0 ]] || AGTCOUNT=1
76
77         export SHARED_DIRECTORY=${SHARED_DIRECTORY:-$TMP}
78         if [[ $CLIENTCOUNT -gt 1 ]] &&
79                 ! check_shared_dir $SHARED_DIRECTORY $CLIENTS; then
80                 skip_env "SHARED_DIRECTORY should be accessible"\
81                          "on all client nodes"
82                 exit 0
83         fi
84
85         # We used to put the HSM archive in $SHARED_DIRECTORY but that
86         # meant NFS issues could hose sanity-hsm sessions. So now we
87         # use $TMP instead.
88         for n in $(seq $AGTCOUNT); do
89                 eval export AGTDEV$n=\$\{AGTDEV$n:-"$TMP/arc$n"\}
90                 agent=CLIENT$((n + 1))
91                 if [[ -z "${!agent}" ]]; then
92                         [[ $CLIENTCOUNT -eq 1 ]] && agent=CLIENT1 ||
93                                 agent=CLIENT2
94                 fi
95                 eval export agt${n}_HOST=\$\{agt${n}_HOST:-${!agent}\}
96         done
97
98         export SINGLEAGT=${SINGLEAGT:-agt1}
99
100         export HSMTOOL=${HSMTOOL:-"lhsmtool_posix"}
101         export HSMTOOL_VERBOSE=${HSMTOOL_VERBOSE:-""}
102         export HSMTOOL_UPDATE_INTERVAL=${HSMTOOL_UPDATE_INTERVAL:=""}
103         export HSMTOOL_EVENT_FIFO=${HSMTOOL_EVENT_FIFO:=""}
104         export HSMTOOL_TESTDIR
105         export HSMTOOL_BASE=$(basename "$HSMTOOL" | cut -f1 -d" ")
106         # $hsm_root/$HSMTMP Makes $hsm_root dir path less generic to ensure
107         # rm -rf $hsm_root/* is safe even if $hsm_root becomes unset to avoid
108         # deleting everything in filesystem, independent of any copytool.
109         export HSMTMP=${HSMTMP:-"shsm"}
110
111         HSM_ARCHIVE=$(copytool_device $SINGLEAGT)
112
113         [ -z "${HSM_ARCHIVE// /}" ] && error "HSM_ARCHIVE is empty!"
114         HSM_ARCHIVE=$HSM_ARCHIVE/$HSMTMP
115
116         HSM_ARCHIVE_NUMBER=2
117
118         # The test only support up to 10 MDTs
119         MDT_PREFIX="mdt.$FSNAME-MDT000"
120         HSM_PARAM="${MDT_PREFIX}0.hsm"
121
122         # archive is purged at copytool setup
123         HSM_ARCHIVE_PURGE=true
124
125         # Don't allow copytool error upon start/setup
126         HSMTOOL_NOERROR=false
127 }
128
129 # Get the backend root path for the given agent facet.
130 copytool_device() {
131         local facet=$1
132         local dev=AGTDEV$(facet_number $facet)
133
134         echo -n ${!dev}
135 }
136
137 # Stop copytool and unregister an existing changelog user.
138 cleanup() {
139         copytool_monitor_cleanup
140         copytool_cleanup
141         changelog_cleanup
142         cdt_set_sanity_policy
143 }
144
145 get_mdt_devices() {
146         local mdtno
147         # get MDT device for each mdc
148         for mdtno in $(seq 1 $MDSCOUNT); do
149                 local idx=$(($mdtno - 1))
150                 MDT[$idx]=$($LCTL get_param -n \
151                         mdc.$FSNAME-MDT000${idx}-mdc-*.mds_server_uuid |
152                         awk '{gsub(/_UUID/,""); print $1}' | head -n1)
153         done
154 }
155
156 search_copytools() {
157         local hosts=${1:-$(facet_active_host $SINGLEAGT)}
158         do_nodesv $hosts "pgrep -x $HSMTOOL_BASE"
159 }
160
161 kill_copytools() {
162         local hosts=${1:-$(facet_active_host $SINGLEAGT)}
163
164         echo "Killing existing copytools on $hosts"
165         do_nodesv $hosts "killall -q $HSMTOOL_BASE" || true
166 }
167
168 wait_copytools() {
169         local hosts=${1:-$(facet_active_host $SINGLEAGT)}
170         local wait_timeout=200
171         local wait_start=$SECONDS
172         local wait_end=$((wait_start + wait_timeout))
173         local sleep_time=100000 # 0.1 second
174
175         while ((SECONDS < wait_end)); do
176                 if ! search_copytools $hosts; then
177                         echo "copytools stopped in $((SECONDS - wait_start))s"
178                         return 0
179                 fi
180
181                 echo "copytools still running on $hosts"
182                 usleep $sleep_time
183                 [ $sleep_time -lt 32000000 ] && # 3.2 seconds
184                         sleep_time=$(bc <<< "$sleep_time * 2")
185         done
186
187         # try to dump Copytool's stack
188         do_nodesv $hosts "echo 1 >/proc/sys/kernel/sysrq ; " \
189                          "echo t >/proc/sysrq-trigger"
190
191         echo "copytools failed to stop in ${wait_timeout}s"
192
193         return 1
194 }
195
196 copytool_monitor_setup() {
197         local facet=${1:-$SINGLEAGT}
198         local agent=$(facet_active_host $facet)
199
200         local cmd="mktemp --tmpdir=/tmp -d ${TESTSUITE}.${TESTNAME}.XXXX"
201         local test_dir=$(do_node $agent "$cmd") ||
202                 error "Failed to create tempdir on $agent"
203         export HSMTOOL_MONITOR_DIR=$test_dir
204
205         # Create the fifo and a monitor (cat dies when copytool dies)
206         do_node $agent "mkfifo -m 0644 $test_dir/fifo" ||
207                 error "failed to create copytool fifo on $agent"
208         cmd="cat $test_dir/fifo > $test_dir/events &"
209         cmd+=" echo \\\$! > $test_dir/monitor_pid"
210
211         if [[ $PDSH == *Rmrsh* ]]; then
212                 # This is required for pdsh -Rmrsh and its handling of remote
213                 # shells.
214                 # Regular ssh and pdsh -Rssh work fine without this
215                 # backgrounded subshell nonsense.
216                 (do_node $agent "$cmd") &
217                 export HSMTOOL_MONITOR_PDSH=$!
218
219                 # Slightly racy, but just making a best-effort to catch obvious
220                 # problems.
221                 sleep 1
222                 ps -p $HSMTOOL_MONITOR_PDSH > /dev/null ||
223                         error "Failed to start copytool monitor on $agent"
224         else
225                 do_node $agent "$cmd"
226                 if [ $? != 0 ]; then
227                         error "Failed to start copytool monitor on $agent"
228                 fi
229         fi
230 }
231
232 copytool_monitor_cleanup() {
233         local facet=${1:-$SINGLEAGT}
234         local agent=$(facet_active_host $facet)
235
236         if [ -n "$HSMTOOL_MONITOR_DIR" ]; then
237                 # Should die when the copytool dies, but just in case.
238                 local cmd="kill \\\$(cat $HSMTOOL_MONITOR_DIR/monitor_pid)"
239                 cmd+=" 2>/dev/null || true"
240                 do_node $agent "$cmd"
241                 do_node $agent "rm -fr $HSMTOOL_MONITOR_DIR"
242                 export HSMTOOL_MONITOR_DIR=
243         fi
244
245         # The pdsh should die on its own when the monitor dies. Just
246         # in case, though, try to clean up to avoid any cruft.
247         if [ -n "$HSMTOOL_MONITOR_PDSH" ]; then
248                 kill $HSMTOOL_MONITOR_PDSH 2>/dev/null || true
249                 export HSMTOOL_MONITOR_PDSH=
250         fi
251 }
252
253 copytool_logfile()
254 {
255         local host="$(facet_host "$1")"
256         local prefix=$TESTLOG_PREFIX
257         [ -n "$TESTNAME" ] && prefix+=.$TESTNAME
258
259         printf "${prefix}.copytool${archive_id}_log.${host}.log"
260 }
261
262 __lhsmtool_setup()
263 {
264         local cmd="$HSMTOOL $HSMTOOL_VERBOSE --daemon --hsm-root \"$hsm_root\""
265         [ -n "$bandwidth" ] && cmd+=" --bandwidth $bandwidth"
266         [ -n "$archive_id" ] && cmd+=" --archive $archive_id"
267         [ ${#misc_options[@]} -gt 0 ] &&
268                 cmd+=" $(IFS=" " echo "$@")"
269         cmd+=" \"$mountpoint\""
270
271         echo "Starting copytool $facet on $(facet_host $facet)"
272         stack_trap "do_facet $facet \"pkill -x $HSMTOOL_BASE\" || true" EXIT
273         do_facet $facet "$cmd < /dev/null > \"$(copytool_logfile $facet)\" 2>&1"
274 }
275
276 hsm_root() {
277         local facet="${1:-$SINGLEAGT}"
278
279         printf "$(copytool_device "$facet")/${TESTSUITE}.${TESTNAME}/"
280 }
281
282 copytool()
283 {
284         local action=$1
285         shift
286
287         # Parse arguments
288         local fail_on_error=true
289         local -a misc_options
290         while [ $# -gt 0 ]; do
291                 case "$1" in
292                 -f|--facet)
293                         shift
294                         local facet="$1"
295                         ;;
296                 -m|--mountpoint)
297                         shift
298                         local mountpoint="$1"
299                         ;;
300                 -a|--archive-id)
301                         shift
302                         local archive_id="$1"
303                         ;;
304                 -b|--bwlimit)
305                         shift
306                         local bandwidth="$1" # in MB/s
307                         ;;
308                 -n|--no-fail)
309                         local fail_on_error=false
310                         ;;
311                 *)
312                         # Uncommon(/copytool dependent) option
313                         misc_options+=("$1")
314                         ;;
315                 esac
316                 shift
317         done
318
319         # Use default values if needed
320         local facet=${facet:-$SINGLEAGT}
321         local mountpoint="${mountpoint:-${MOUNT2:-$MOUNT}}"
322         local hsm_root="$(hsm_root "$facet")"
323
324         stack_trap "do_facet $facet \"rm -rf \\\"$hsm_root\\\"\"" EXIT
325         do_facet $facet "mkdir -p \"$hsm_root\"" ||
326                 error "mkdir \"$hsm_root\" failed"
327
328         case "$HSMTOOL" in
329         lhsmtool_posix)
330                 local copytool=lhsmtool
331                 ;;
332         esac
333
334         __${copytool}_${action} "${misc_options[@]}"
335         if [ $? -ne 0 ]; then
336                 local error_msg
337
338                 case $action in
339                 setup)
340                         local host="$(facet_host $facet)"
341                         error_msg="Failed to start copytool $facet on '$host'"
342                         ;;
343                 esac
344
345                 $fail_on_error && error "$error_msg" || echo "$error_msg"
346         fi
347 }
348
349 copytool_setup() {
350         local facet=${1:-$SINGLEAGT}
351         # Use MOUNT2 by default if defined
352         local lustre_mntpnt=${2:-${MOUNT2:-$MOUNT}}
353         local arc_id=$3
354         local hsm_root=${4:-$(copytool_device $facet)}
355
356         [ -z "${hsm_root// /}" ] && error "copytool_setup: hsm_root empty!"
357
358         local agent=$(facet_active_host $facet)
359
360         if $HSM_ARCHIVE_PURGE; then
361                 echo "Purging archive on $agent"
362                 do_facet $facet "rm -rf $hsm_root/$HSMTMP/*"
363         fi
364
365         echo "Starting copytool $facet on $agent"
366         do_facet $facet "mkdir -p $hsm_root/$HSMTMP/" ||
367                         error "mkdir '$hsm_root/$HSMTMP' failed"
368         # bandwidth is limited to 1MB/s so the copy time is known and
369         # independent of hardware
370         local cmd="$HSMTOOL $HSMTOOL_VERBOSE --daemon"
371         cmd+=" --hsm-root $hsm_root/$HSMTMP"
372         [[ -z "$arc_id" ]] || cmd+=" --archive $arc_id"
373         [[ -z "$HSMTOOL_UPDATE_INTERVAL" ]] ||
374                 cmd+=" --update-interval $HSMTOOL_UPDATE_INTERVAL"
375         [[ -z "$HSMTOOL_EVENT_FIFO" ]] ||
376                 cmd+=" --event-fifo $HSMTOOL_EVENT_FIFO"
377         cmd+=" --bandwidth 1 $lustre_mntpnt"
378
379         # Redirect the standard output and error to a log file which
380         # can be uploaded to Maloo.
381         local prefix=$TESTLOG_PREFIX
382         [[ -z "$TESTNAME" ]] || prefix=$prefix.$TESTNAME
383         local copytool_log=$prefix.copytool${arc_id}_log.$agent.log
384
385         stack_trap cleanup EXIT
386         do_facet $facet "$cmd < /dev/null > $copytool_log 2>&1"
387         if [[ $? !=  0 ]]; then
388                 [[ $HSMTOOL_NOERROR == true ]] ||
389                         error "start copytool $facet on $agent failed"
390                 echo "start copytool $facet on $agent failed"
391         fi
392 }
393
394 get_copytool_event_log() {
395         local facet=${1:-$SINGLEAGT}
396         local agent=$(facet_active_host $facet)
397
398         [ -z "$HSMTOOL_MONITOR_DIR" ] &&
399                 error "Can't get event log: No monitor directory!"
400
401         do_node $agent "cat $HSMTOOL_MONITOR_DIR/events" ||
402                 error "Could not collect event log from $agent"
403 }
404
405 copytool_cleanup() {
406         trap - EXIT
407         local agt_facet=$SINGLEAGT
408         local agt_hosts=${1:-$(facet_active_host $agt_facet)}
409         local hsm_root=$(copytool_device $agt_facet)
410
411         [ -z "${hsm_root// /}" ] && error "copytool_cleanup: hsm_root empty!"
412
413         local i
414         local facet
415         local param
416         local -a state
417
418         kill_copytools $agt_hosts
419         wait_copytools $agt_hosts || error "copytools failed to stop"
420
421         # Clean all CDTs orphans requests from previous tests that
422         # would otherwise need to timeout to clear.
423         for ((i = 0; i < MDSCOUNT; i++)); do
424                 facet=mds$((i + 1))
425                 param=$(printf 'mdt.%s-MDT%04x.hsm_control' $FSNAME $i)
426                 state[$i]=$(do_facet $facet "$LCTL get_param -n $param")
427
428                 # Skip already stopping or stopped CDTs.
429                 [[ "${state[$i]}" =~ ^stop ]] && continue
430
431                 do_facet $facet "$LCTL set_param $param=shutdown"
432         done
433
434         for ((i = 0; i < MDSCOUNT; i++)); do
435                 # Only check and restore CDTs that we stopped in the first loop.
436                 [[ "${state[$i]}" =~ ^stop ]] && continue
437
438                 facet=mds$((i + 1))
439                 param=$(printf 'mdt.%s-MDT%04x.hsm_control' $FSNAME $i)
440
441                 wait_result $facet "$LCTL get_param -n $param" stopped 20 ||
442                         error "$facet CDT state is not stopped"
443
444                 # Restore old CDT state.
445                 do_facet $facet "$LCTL set_param $param=${state[$i]}"
446         done
447
448         for ((i = 0; i < MDSCOUNT; i++)); do
449                 # Only check CDTs that we stopped in the first loop.
450                 [[ "${state[$i]}" =~ ^stop ]] && continue
451
452                 facet=mds$((i + 1))
453                 param=$(printf 'mdt.%s-MDT%04x.hsm_control' $FSNAME $i)
454
455                 # Check that the old CDT state was restored.
456                 wait_result $facet "$LCTL get_param -n $param" "${state[$i]}" \
457                         20 || error "$facet CDT state is not '${state[$i]}'"
458         done
459
460         if do_facet $agt_facet "df $hsm_root" >/dev/null 2>&1 ; then
461                 do_facet $agt_facet "rm -rf $hsm_root/$HSMTMP/*"
462         fi
463 }
464
465 copytool_suspend() {
466         local agents=${1:-$(facet_active_host $SINGLEAGT)}
467
468         do_nodesv $agents "pkill -STOP -x $HSMTOOL_BASE" || return 0
469         echo "Copytool is suspended on $agents"
470 }
471
472 copytool_continue() {
473         local agents=${1:-$(facet_active_host $SINGLEAGT)}
474
475         do_nodesv $agents "pkill -CONT -x $HSMTOOL_BASE" || return 0
476         echo "Copytool is continued on $agents"
477 }
478
479 copytool_remove_backend() {
480         local fid=$1
481         local be=$(do_facet $SINGLEAGT find $HSM_ARCHIVE -name $fid)
482         echo "Remove from backend: $fid = $be"
483         do_facet $SINGLEAGT rm -f $be
484 }
485
486 import_file() {
487         mkdir -p "$(dirname "$2")" ||
488                 error "cannot create directory '$(dirname "$2")'"
489
490         do_facet $SINGLEAGT \
491                 "$HSMTOOL --archive $HSM_ARCHIVE_NUMBER --hsm-root $HSM_ARCHIVE\
492                 --import $1 $2 $MOUNT" ||
493                 error "import of $1 to $2 failed"
494 }
495
496 file_creation_failure() {
497         local cmd=$1
498         local file=$2
499         local err=$3
500
501         case $err in
502         28)
503                 df $MOUNT $MOUNT2 >&2
504                 error "Not enough space to create $file with $cmd"
505                 ;;
506         *)
507                 error "cannot create $file with $cmd, status=$err"
508                 ;;
509         esac
510 }
511
512 # Creates a file using dd
513 create_file() {
514         local file=$1
515         local bs=$2
516         local count=$3
517         local conv=$4
518         local source=${5:-/dev/zero}
519         local args=""
520         local err
521
522         if [ -n "$conv" ]; then
523                 args+=" conv=$conv"
524         fi
525
526         # Create the directory in case it does not exist
527         mkdir -p "$(dirname "$file")"
528         # Delete the file in case it already exist
529         rm -f "$file"
530
531         if dd if="$source" of="$file" count="$count" bs="$bs" $args; then
532                 path2fid "$file" || error "cannot get FID of '$file'"
533         else
534                 err=$?
535                 echo "cannot create file '$file'" >&2;
536                 # Let the caller decide what to do on error
537                 return $err;
538         fi
539 }
540
541 create_empty_file() {
542         create_file "${1/$DIR/$DIR2}" 1M 0 ||
543                 file_creation_failure dd "${1/$DIR/$DIR2}" $?
544 }
545
546 create_small_file() {
547         local source_file=/dev/urandom
548         local count=1
549         local bs=1M
550         local conv=${2:-fsync}
551
552         create_file "${1/$DIR/$DIR2}" $bs $count $conv $source_file ||
553                 file_creation_failure dd "${1/$DIR/$DIR2}" $?
554 }
555
556 create_small_sync_file() {
557         create_small_file "$1" sync
558 }
559
560 create_archive_file() {
561         local file="$HSM_ARCHIVE/$1"
562         local count=${2:-39}
563         local source=/dev/urandom
564
565         # Create the counterpart directory of the archive
566         do_facet "$SINGLEAGT" mkdir -p "$(dirname "$file")" ||
567                 error "cannot create archive directory '$(dirname "$file")'"
568
569         do_facet "$SINGLEAGT" dd if=$source of="$file" bs=1M count=$count ||
570                 error "cannot create archive file '$file'"
571 }
572
573 copy2archive() {
574         local file=$HSM_ARCHIVE/$2
575         do_facet $SINGLEAGT mkdir -p $(dirname $file)
576         do_facet $SINGLEAGT cp -p $1 $file || error "cannot copy $1 to $file"
577 }
578
579 mdts_set_param() {
580         local arg=$1
581         local key=$2
582         local value=$3
583         local mdtno
584         local rc=0
585         if [[ "$value" != "" ]]; then
586                 value="=$value"
587         fi
588         for mdtno in $(seq 1 $MDSCOUNT); do
589                 local idx=$(($mdtno - 1))
590                 local facet=mds${mdtno}
591                 # if $arg include -P option, run 1 set_param per MDT on the MGS
592                 # else, run set_param on each MDT
593                 [[ $arg = *"-P"* ]] && facet=mgs
594                 do_facet $facet $LCTL set_param $arg mdt.${MDT[$idx]}.$key$value
595                 [[ $? != 0 ]] && rc=1
596         done
597         return $rc
598 }
599
600 mdts_check_param() {
601         local key="$1"
602         local target="$2"
603         local timeout="$3"
604         local mdtno
605         for mdtno in $(seq 1 $MDSCOUNT); do
606                 local idx=$(($mdtno - 1))
607                 wait_result mds${mdtno} \
608                         "$LCTL get_param -n $MDT_PREFIX${idx}.$key" "$target" \
609                         $timeout ||
610                         error "$key state is not '$target' on mds${mdtno}"
611         done
612 }
613
614 changelog_setup() {
615         CL_USERS=()
616         local mdtno
617         for mdtno in $(seq 1 $MDSCOUNT); do
618                 local idx=$(($mdtno - 1))
619                 local cl_user=$(do_facet mds${mdtno} $LCTL \
620                              --device ${MDT[$idx]} \
621                              changelog_register -n)
622                 CL_USERS+=($cl_user)
623                 do_facet mds${mdtno} lctl set_param \
624                         mdd.${MDT[$idx]}.changelog_mask="+hsm"
625                 $LFS changelog_clear ${MDT[$idx]} $cl_user 0
626         done
627 }
628
629 changelog_cleanup() {
630         local mdtno
631         for mdtno in $(seq 1 $MDSCOUNT); do
632                 local idx=$(($mdtno - 1))
633                 [[ -z  ${CL_USERS[$idx]} ]] && continue
634                 $LFS changelog_clear ${MDT[$idx]} ${CL_USERS[$idx]} 0
635                 do_facet mds${mdtno} lctl --device ${MDT[$idx]} \
636                         changelog_deregister ${CL_USERS[$idx]}
637         done
638         CL_USERS=()
639 }
640
641 changelog_get_flags() {
642         local mdt=$1
643         local cltype=$2
644         local fid=$3
645
646         $LFS changelog $mdt | awk "/$cltype/ && /t=\[$fid\]/ {print \$5}"
647 }
648
649 get_hsm_param() {
650         local param=$1
651         local val=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.$param)
652         echo $val
653 }
654
655 set_hsm_param() {
656         local param=$1
657         local value=$2
658         local opt=$3
659         mdts_set_param "$opt -n" "hsm.$param" "$value"
660         return $?
661 }
662
663 set_test_state() {
664         local cmd=$1
665         local target=$2
666         mdts_set_param "" hsm_control "$cmd"
667         mdts_check_param hsm_control "$target" 10
668 }
669
670 cdt_set_sanity_policy() {
671         if [[ "$CDT_POLICY_HAD_CHANGED" ]]
672         then
673                 # clear all
674                 mdts_set_param "" hsm.policy "+NRA"
675                 mdts_set_param "" hsm.policy "-NBR"
676                 CDT_POLICY_HAD_CHANGED=
677         fi
678 }
679
680 cdt_set_no_retry() {
681         mdts_set_param "" hsm.policy "+NRA"
682         CDT_POLICY_HAD_CHANGED=true
683 }
684
685 cdt_clear_no_retry() {
686         mdts_set_param "" hsm.policy "-NRA"
687         CDT_POLICY_HAD_CHANGED=true
688 }
689
690 cdt_set_non_blocking_restore() {
691         mdts_set_param "" hsm.policy "+NBR"
692         CDT_POLICY_HAD_CHANGED=true
693 }
694
695 cdt_clear_non_blocking_restore() {
696         mdts_set_param "" hsm.policy "-NBR"
697         CDT_POLICY_HAD_CHANGED=true
698 }
699
700 cdt_clear_mount_state() {
701         mdts_set_param "-P -d" hsm_control ""
702 }
703
704 cdt_set_mount_state() {
705         mdts_set_param "-P" hsm_control "$1"
706         # set_param -P is asynchronous operation and could race with set_param.
707         # In such case configs could be retrieved and applied at mgc after
708         # set_param -P completion. Sleep here to avoid race with set_param.
709         # We need at least 20 seconds. 10 for mgc_requeue_thread to wake up
710         # MGC_TIMEOUT_MIN_SECONDS + MGC_TIMEOUT_RAND_CENTISEC(5 + 5)
711         # and 10 seconds to retrieve config from server.
712         sleep 20
713 }
714
715 cdt_check_state() {
716         mdts_check_param hsm_control "$1" 20
717 }
718
719 cdt_disable() {
720         set_test_state disabled disabled
721 }
722
723 cdt_enable() {
724         set_test_state enabled enabled
725 }
726
727 cdt_shutdown() {
728         set_test_state shutdown stopped
729 }
730
731 cdt_purge() {
732         set_test_state purge enabled
733 }
734
735 cdt_restart() {
736         cdt_shutdown
737         cdt_enable
738         cdt_set_sanity_policy
739 }
740
741 needclients() {
742         local client_count=$1
743         if [[ $CLIENTCOUNT -lt $client_count ]]; then
744                 skip "Need $client_count or more clients, have $CLIENTCOUNT"
745                 return 1
746         fi
747         return 0
748 }
749
750 path2fid() {
751         $LFS path2fid $1 | tr -d '[]'
752         return ${PIPESTATUS[0]}
753 }
754
755 get_hsm_flags() {
756         local f=$1
757         local u=$2
758         local st
759
760         if [[ $u == "user" ]]; then
761                 st=$($RUNAS $LFS hsm_state $f)
762         else
763                 u=root
764                 st=$($LFS hsm_state $f)
765         fi
766
767         [[ $? == 0 ]] || error "$LFS hsm_state $f failed (run as $u)"
768
769         st=$(echo $st | cut -f 2 -d" " | tr -d "()," )
770         echo $st
771 }
772
773 get_hsm_archive_id() {
774         local f=$1
775         local st
776         st=$($LFS hsm_state $f)
777         [[ $? == 0 ]] || error "$LFS hsm_state $f failed"
778
779         local ar=$(echo $st | grep -oP '(?<=archive_id:).*')
780         echo $ar
781 }
782
783 check_hsm_flags() {
784         local f=$1
785         local fl=$2
786
787         local st=$(get_hsm_flags $f)
788         [[ $st == $fl ]] || error "hsm flags on $f are $st != $fl"
789 }
790
791 check_hsm_flags_user() {
792         local f=$1
793         local fl=$2
794
795         local st=$(get_hsm_flags $f user)
796         [[ $st == $fl ]] || error "hsm flags on $f are $st != $fl"
797 }
798
799 copy_file() {
800         local f=
801
802         if [[ -d $2 ]]; then
803                 f=$2/$(basename $1)
804         else
805                 f=$2
806         fi
807
808         if [[ "$3" != 1 ]]; then
809                 f=${f/$DIR/$DIR2}
810         fi
811         rm -f $f
812         cp $1 $f || file_creation_failure cp $f $?
813
814         path2fid $f || error "cannot get fid on $f"
815 }
816
817 # Delete any file bigger than 10M under $MOUNT and wait for deletes to complete
818 #
819 # Note that this might lead to surprising behaviours such as deleting an
820 # important file for the currently running test
821 delete_large_files() {
822         printf "Deleting large files...\n" >&2
823         find $MOUNT -size +10M -delete
824         wait_delete_completed
825 }
826
827 make_custom_file_for_progress() {
828         local count=${2:-"39"}
829         local bs=$($LCTL get_param -n lov.*-clilov-*.stripesize | head -n1)
830         bs=${3:-$bs}
831
832         [[ $count -gt  0 ]] || error "Invalid file size"
833         [[ $bs -gt 0 ]] || error "Invalid stripe size"
834
835         if ! create_file "${1/$DIR/$DIR2}" $bs $count fsync; then
836                 echo "The creation of '${1/$DIR/$DIR2}' failed" >&2
837                 echo "It might be due to a lack of space in the filesystem" >&2
838                 delete_large_files >&2
839                 create_file "${1/$DIR/$DIR2}" $bs $count fsync ||
840                         file_creation_failure dd "${1/$DIR/$DIR2}" $?
841         fi
842 }
843
844 wait_result() {
845         local facet=$1
846         shift
847         wait_update --verbose $(facet_active_host $facet) "$@"
848 }
849
850 wait_request_state() {
851         local fid=$1
852         local request=$2
853         local state=$3
854         # 4th arg (mdt index) is optional
855         local mdtidx=${4:-0}
856         local mds=mds$(($mdtidx + 1))
857
858         local cmd="$LCTL get_param -n ${MDT_PREFIX}${mdtidx}.hsm.actions"
859         cmd+=" | awk '/'$fid'.*action='$request'/ {print \\\$13}' | cut -f2 -d="
860
861         wait_result $mds "$cmd" $state 200 ||
862                 error "request on $fid is not $state on $mds"
863 }
864
865 get_request_state() {
866         local fid=$1
867         local request=$2
868
869         do_facet $SINGLEMDS "$LCTL get_param -n $HSM_PARAM.actions |"\
870                 "awk '/'$fid'.*action='$request'/ {print \\\$13}' | cut -f2 -d="
871 }
872
873 get_request_count() {
874         local fid=$1
875         local request=$2
876
877         do_facet $SINGLEMDS "$LCTL get_param -n $HSM_PARAM.actions |"\
878                 "awk -vn=0 '/'$fid'.*action='$request'/ {n++}; END {print n}'"
879 }
880
881 # Ensure the number of HSM request for a given FID is correct
882 # assert_request_count FID REQUEST_TYPE COUNT [ERROR_MSG]
883 assert_request_count() {
884         local request_count=$(get_request_count $1 $2)
885         local default_error_msg=("expected $3 '$2' request(s) for '$1', found "
886                                 "'$request_count'")
887         [ $request_count -eq $3 ] || error "${4:-"${default_error_msg[@]}"}"
888 }
889
890 wait_all_done() {
891         local timeout=$1
892         local fid=$2
893
894         local cmd="$LCTL get_param -n $HSM_PARAM.actions"
895         [[ -n $fid ]] && cmd+=" | grep '$fid'"
896         cmd+=" | egrep 'WAITING|STARTED'"
897
898         wait_result $SINGLEMDS "$cmd" "" $timeout ||
899                 error "requests did not complete"
900 }
901
902 wait_for_grace_delay() {
903         local val=$(get_hsm_param grace_delay)
904         sleep $val
905 }
906
907 wait_for_loop_period() {
908         local val=$(get_hsm_param loop_period)
909         sleep $val
910 }
911
912 parse_json_event() {
913         local raw_event=$1
914
915         # python2.6 in EL6 includes an internal json module
916         local json_parser='import json; import fileinput;'
917         json_parser+=' print "\n".join(["local %s=\"%s\"" % tuple for tuple in '
918         json_parser+='json.loads([line for line in '
919         json_parser+='fileinput.input()][0]).items()])'
920
921         echo $raw_event | python -c "$json_parser"
922 }
923
924 get_agent_by_uuid_mdt() {
925         local uuid=$1
926         local mdtidx=$2
927         local mds=mds$(($mdtidx + 1))
928         do_facet $mds "$LCTL get_param -n ${MDT_PREFIX}${mdtidx}.hsm.agents |\
929                  grep $uuid"
930 }
931
932 check_agent_registered_by_mdt() {
933         local uuid=$1
934         local mdtidx=$2
935         local mds=mds$(($mdtidx + 1))
936         local agent=$(get_agent_by_uuid_mdt $uuid $mdtidx)
937         if [[ ! -z "$agent" ]]; then
938                 echo "found agent $agent on $mds"
939         else
940                 error "uuid $uuid not found in agent list on $mds"
941         fi
942 }
943
944 check_agent_unregistered_by_mdt() {
945         local uuid=$1
946         local mdtidx=$2
947         local mds=mds$(($mdtidx + 1))
948         local agent=$(get_agent_by_uuid_mdt $uuid $mdtidx)
949         if [[ -z "$agent" ]]; then
950                 echo "uuid not found in agent list on $mds"
951         else
952                 error "uuid found in agent list on $mds: $agent"
953         fi
954 }
955
956 check_agent_registered() {
957         local uuid=$1
958         local mdsno
959         for mdsno in $(seq 1 $MDSCOUNT); do
960                 check_agent_registered_by_mdt $uuid $((mdsno - 1))
961         done
962 }
963
964 check_agent_unregistered() {
965         local uuid=$1
966         local mdsno
967         for mdsno in $(seq 1 $MDSCOUNT); do
968                 check_agent_unregistered_by_mdt $uuid $((mdsno - 1))
969         done
970 }
971
972 get_agent_uuid() {
973         local agent=${1:-$(facet_active_host $SINGLEAGT)}
974
975         # Lustre mount-point is mandatory and last parameter on
976         # copytool cmd-line.
977         local mntpnt=$(do_rpc_nodes $agent ps -C $HSMTOOL_BASE -o args= |
978                        awk '{print $NF}')
979         [ -n "$mntpnt" ] || error "Found no Agent or with no mount-point "\
980                                   "parameter"
981         do_rpc_nodes $agent get_client_uuid $mntpnt | cut -d' ' -f2
982 }
983
984 # initiate variables
985 init_agt_vars
986
987 # populate MDT device array
988 get_mdt_devices
989
990 # cleanup from previous bad setup
991 kill_copytools
992
993 # for recovery tests, coordinator needs to be started at mount
994 # so force it
995 # the lustre conf must be without hsm on (like for sanity.sh)
996 echo "Set HSM on and start"
997 cdt_set_mount_state enabled
998 cdt_check_state enabled
999
1000 echo "Set sanity-hsm HSM policy"
1001 cdt_set_sanity_policy
1002
1003 # finished requests are quickly removed from list
1004 set_hsm_param grace_delay 10
1005
1006 test_1() {
1007         mkdir -p $DIR/$tdir
1008         chmod 777 $DIR/$tdir
1009
1010         local f=$DIR/$tdir/$tfile
1011         $RUNAS touch $f
1012
1013         # User flags
1014         check_hsm_flags_user $f "0x00000000"
1015
1016         $RUNAS $LFS hsm_set --norelease $f ||
1017                 error "user could not change hsm flags"
1018         check_hsm_flags_user $f "0x00000010"
1019
1020         $RUNAS $LFS hsm_clear --norelease $f ||
1021                 error "user could not clear hsm flags"
1022         check_hsm_flags_user $f "0x00000000"
1023
1024         # User could not change those flags...
1025         $RUNAS $LFS hsm_set --exists $f &&
1026                 error "user should not set this flag"
1027         check_hsm_flags_user $f "0x00000000"
1028
1029         # ...but root can
1030         $LFS hsm_set --exists $f ||
1031                 error "root could not change hsm flags"
1032         check_hsm_flags_user $f "0x00000001"
1033
1034         $LFS hsm_clear --exists $f ||
1035                 error "root could not clear hsm state"
1036         check_hsm_flags_user $f "0x00000000"
1037
1038 }
1039 run_test 1 "lfs hsm flags root/non-root access"
1040
1041 test_1a() {
1042         local f=$DIR/$tdir/$tfile
1043         local fid=$(create_small_file $f)
1044
1045         copytool setup
1046
1047         $LFS hsm_archive $f || error "could not archive file"
1048         wait_request_state $fid ARCHIVE SUCCEED
1049
1050         # Release and check states
1051         $LFS hsm_release $f || error "could not release file"
1052         echo -n "Verifying released state: "
1053         check_hsm_flags $f "0x0000000d"
1054
1055         $MMAP_CAT $f > /dev/null || error "failed mmap & cat release file"
1056 }
1057 run_test 1a "mmap & cat a HSM released file"
1058
1059 test_1b() {
1060         mkdir -p $DIR/$tdir
1061         $LFS setstripe -E 1M -E 64M -c 2 -E -1 -c 4 $DIR/$tdir ||
1062                 error "failed to set default stripe"
1063         local f=$DIR/$tdir/$tfile
1064         rm -f $f
1065
1066         dd if=/dev/random of=$f bs=1M count=1 conv=sync ||
1067                 error "failed to create file"
1068         local fid=$(path2fid $f)
1069
1070         copytool setup
1071
1072         echo "archive $f"
1073         $LFS hsm_archive $f || error "could not archive file"
1074         wait_request_state $fid ARCHIVE SUCCEED
1075
1076         echo "release $f"
1077         $LFS hsm_release $f || error "could not release file"
1078         echo "verify released state: "
1079         check_hsm_flags $f "0x0000000d" && echo "pass"
1080
1081         echo "restore $f"
1082         $LFS hsm_restore $f || error "could not restore file"
1083         wait_request_state $fid RESTORE SUCCEED
1084         echo "verify restored state: "
1085         check_hsm_flags $f "0x00000009" && echo "pass"
1086 }
1087 run_test 1b "Archive, Release & Restore composite file"
1088
1089 test_1c() {
1090         mkdir -p $DIR/$tdir
1091         chmod 777 $DIR/$tdir
1092
1093         local f=$DIR/$tdir/$tfile
1094         $RUNAS touch $f
1095
1096         # Test whether we can set the maximum archive number.
1097         local LOCAL_HSM_ARCHIVE_NUMBER=32
1098         $LFS hsm_set --exists --archive-id $LOCAL_HSM_ARCHIVE_NUMBER $f ||
1099                 error "root could not change hsm flags"
1100         check_hsm_flags_user $f "0x00000001"
1101         echo "verifying archive number is $LOCAL_HSM_ARCHIVE_NUMBER"
1102         local st=$(get_hsm_archive_id $f)
1103         [[ $st == $LOCAL_HSM_ARCHIVE_NUMBER ]] ||
1104                 error "wrong archive number, $st != $LOCAL_HSM_ARCHIVE_NUMBER"
1105
1106         # Test whether setting archive number 0 results in no change.
1107         $LFS hsm_set --exists --archive-id 0 $f ||
1108                 error "root could not change hsm flags"
1109         check_hsm_flags_user $f "0x00000001"
1110         echo "verifying archive number is still $LOCAL_HSM_ARCHIVE_NUMBER"
1111         st=$(get_hsm_archive_id $f)
1112         [[ $st == $LOCAL_HSM_ARCHIVE_NUMBER ]] ||
1113                 error "wrong archive number, $st != $LOCAL_HSM_ARCHIVE_NUMBER"
1114
1115         # Test whether setting archive number > 32 results in error.
1116         $LFS hsm_set --exists --archive-id 33 $f &&
1117                 error "archive number is larger than 32"
1118         check_hsm_flags_user $f "0x00000001"
1119
1120         # Test whether setting archive number 16 and archived flag.
1121         LOCAL_HSM_ARCHIVE_NUMBER=16
1122         $LFS hsm_set --exists --archived \
1123              --archive-id $LOCAL_HSM_ARCHIVE_NUMBER $f ||
1124             error "root could not change hsm flags"
1125         check_hsm_flags_user $f "0x00000009"
1126         echo "verifying archive number is $LOCAL_HSM_ARCHIVE_NUMBER"
1127         st=$(get_hsm_archive_id $f)
1128         [[ $st == $LOCAL_HSM_ARCHIVE_NUMBER ]] ||
1129                 error "wrong archive number, $st != $LOCAL_HSM_ARCHIVE_NUMBER"
1130 }
1131 run_test 1c "Check setting archive-id in lfs hsm_set"
1132
1133 test_2() {
1134         local f=$DIR/$tdir/$tfile
1135
1136         create_empty_file "$f"
1137         # New files are not dirty
1138         check_hsm_flags $f "0x00000000"
1139
1140         # For test, we simulate an archived file.
1141         $LFS hsm_set --exists $f || error "user could not change hsm flags"
1142         check_hsm_flags $f "0x00000001"
1143
1144         # chmod do not put the file dirty
1145         chmod 600 $f || error "could not chmod test file"
1146         check_hsm_flags $f "0x00000001"
1147
1148         # chown do not put the file dirty
1149         chown $RUNAS_ID $f || error "could not chown test file"
1150         check_hsm_flags $f "0x00000001"
1151
1152         # truncate put the file dirty
1153         $TRUNCATE $f 1 || error "could not truncate test file"
1154         check_hsm_flags $f "0x00000003"
1155
1156         $LFS hsm_clear --dirty $f || error "could not clear hsm flags"
1157         check_hsm_flags $f "0x00000001"
1158 }
1159 run_test 2 "Check file dirtyness when doing setattr"
1160
1161 test_3() {
1162         mkdir -p $DIR/$tdir
1163         f=$DIR/$tdir/$tfile
1164
1165         # New files are not dirty
1166         cp -p /etc/passwd $f
1167         check_hsm_flags $f "0x00000000"
1168
1169         # For test, we simulate an archived file.
1170         $LFS hsm_set --exists $f ||
1171                 error "user could not change hsm flags"
1172         check_hsm_flags $f "0x00000001"
1173
1174         # Reading a file, does not set dirty
1175         cat $f > /dev/null || error "could not read file"
1176         check_hsm_flags $f "0x00000001"
1177
1178         # Open for write without modifying data, does not set dirty
1179         openfile -f O_WRONLY $f || error "could not open test file"
1180         check_hsm_flags $f "0x00000001"
1181
1182         # Append to a file sets it dirty
1183         cp -p /etc/passwd $f.append || error "could not create file"
1184         $LFS hsm_set --exists $f.append ||
1185                 error "user could not change hsm flags"
1186         dd if=/etc/passwd of=$f.append bs=1 count=3\
1187            conv=notrunc oflag=append status=noxfer ||
1188                 file_creation_failure dd $f.append $?
1189         check_hsm_flags $f.append "0x00000003"
1190
1191         # Modify a file sets it dirty
1192         cp -p /etc/passwd $f.modify || error "could not create file"
1193         $LFS hsm_set --exists $f.modify ||
1194                 error "user could not change hsm flags"
1195         dd if=/dev/zero of=$f.modify bs=1 count=3\
1196            conv=notrunc status=noxfer ||
1197                 file_creation_failure dd $f.modify $?
1198         check_hsm_flags $f.modify "0x00000003"
1199
1200         # Open O_TRUNC sets dirty
1201         cp -p /etc/passwd $f.trunc || error "could not create file"
1202         $LFS hsm_set --exists $f.trunc ||
1203                 error "user could not change hsm flags"
1204         cp /etc/group $f.trunc || error "could not override a file"
1205         check_hsm_flags $f.trunc "0x00000003"
1206
1207         # Mmapped a file sets dirty
1208         cp -p /etc/passwd $f.mmap || error "could not create file"
1209         $LFS hsm_set --exists $f.mmap ||
1210                 error "user could not change hsm flags"
1211         multiop $f.mmap OSMWUc || error "could not mmap a file"
1212         check_hsm_flags $f.mmap "0x00000003"
1213 }
1214 run_test 3 "Check file dirtyness when opening for write"
1215
1216 test_4() {
1217         local f=$DIR/$tdir/$tfile
1218         local fid=$(create_small_file $f)
1219
1220         $LFS hsm_cancel $f
1221         local st=$(get_request_state $fid CANCEL)
1222         [[ -z "$st" ]] || error "hsm_cancel must not be registered (state=$st)"
1223 }
1224 run_test 4 "Useless cancel must not be registered"
1225
1226 test_8() {
1227         # test needs a running copytool
1228         copytool setup
1229
1230         mkdir -p $DIR/$tdir
1231         local f=$DIR/$tdir/$tfile
1232         local fid=$(copy_file /etc/passwd $f)
1233         $LFS hsm_archive $f
1234         wait_request_state $fid ARCHIVE SUCCEED
1235
1236         check_hsm_flags $f "0x00000009"
1237 }
1238 run_test 8 "Test default archive number"
1239
1240 test_9() {
1241         # we do not use the default one to be sure
1242         local archive_id=$((HSM_ARCHIVE_NUMBER + 1))
1243         copytool setup --archive-id $archive_id
1244
1245         # give time for CT to register with MDTs
1246         sleep $(($MDSCOUNT*2))
1247         local uuid=$(get_agent_uuid $(facet_active_host $SINGLEAGT))
1248         check_agent_registered $uuid
1249
1250         mkdir -p $DIR/$tdir
1251         local f=$DIR/$tdir/$tfile
1252         local fid=$(copy_file /etc/passwd $f)
1253         $LFS hsm_archive --archive $archive_id $f
1254         wait_request_state $fid ARCHIVE SUCCEED
1255
1256         check_hsm_flags $f "0x00000009"
1257 }
1258 run_test 9 "Use of explicit archive number, with dedicated copytool"
1259
1260 test_9a() {
1261         needclients 3 || return 0
1262
1263         local n
1264         local file
1265         local fid
1266
1267         # start all of the copytools
1268         for n in $(seq $AGTCOUNT); do
1269                 copytool setup --facet agt$n
1270         done
1271
1272         # archive files
1273         for n in $(seq $AGTCOUNT); do
1274                 file=$DIR/$tdir/$tfile.$n
1275                 fid=$(create_small_file $file)
1276
1277                 $LFS hsm_archive $file || error "could not archive file $file"
1278                 wait_request_state $fid ARCHIVE SUCCEED
1279                 check_hsm_flags $file "0x00000009"
1280         done
1281 }
1282 run_test 9a "Multiple remote agents"
1283
1284 test_10a() {
1285         # test needs a running copytool
1286         copytool_setup
1287
1288         mkdir -p $DIR/$tdir/d1
1289         local f=$DIR/$tdir/$tfile
1290         local fid=$(copy_file /etc/hosts $f)
1291         $LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $f ||
1292                 error "hsm_archive failed"
1293         wait_request_state $fid ARCHIVE SUCCEED
1294
1295         local AFILE=$(do_facet $SINGLEAGT ls $HSM_ARCHIVE'/*/*/*/*/*/*/'$fid) ||
1296                 error "fid $fid not in archive $HSM_ARCHIVE"
1297         echo "Verifying content"
1298         do_facet $SINGLEAGT diff $f $AFILE || error "archived file differs"
1299         echo "Verifying hsm state "
1300         check_hsm_flags $f "0x00000009"
1301
1302         echo "Verifying archive number is $HSM_ARCHIVE_NUMBER"
1303         local st=$(get_hsm_archive_id $f)
1304         [[ $st == $HSM_ARCHIVE_NUMBER ]] ||
1305                 error "Wrong archive number, $st != $HSM_ARCHIVE_NUMBER"
1306
1307         copytool_cleanup
1308 }
1309 run_test 10a "Archive a file"
1310
1311 test_10b() {
1312         # test needs a running copytool
1313         copytool setup
1314
1315         mkdir -p $DIR/$tdir
1316         local f=$DIR/$tdir/$tfile
1317         local fid=$(copy_file /etc/hosts $f)
1318         $LFS hsm_archive $f || error "archive request failed"
1319         wait_request_state $fid ARCHIVE SUCCEED
1320
1321         $LFS hsm_archive $f || error "archive of non dirty file failed"
1322         local cnt=$(get_request_count $fid ARCHIVE)
1323         [[ "$cnt" == "1" ]] ||
1324                 error "archive of non dirty file must not make a request"
1325 }
1326 run_test 10b "Archive of non dirty file must work without doing request"
1327
1328 test_10c() {
1329         # test needs a running copytool
1330         copytool setup
1331
1332         mkdir -p $DIR/$tdir
1333         local f=$DIR/$tdir/$tfile
1334         local fid=$(copy_file /etc/hosts $f)
1335         $LFS hsm_set --noarchive $f
1336         $LFS hsm_archive $f && error "archive a noarchive file must fail"
1337         return 0
1338 }
1339 run_test 10c "Check forbidden archive"
1340
1341 test_10d() {
1342         # test needs a running copytool
1343         copytool setup
1344
1345         mkdir -p $DIR/$tdir
1346         local f=$DIR/$tdir/$tfile
1347         local fid=$(copy_file /etc/hosts $f)
1348         $LFS hsm_archive $f || error "cannot archive $f"
1349         wait_request_state $fid ARCHIVE SUCCEED
1350
1351         local ar=$(get_hsm_archive_id $f)
1352         local dflt=$(get_hsm_param default_archive_id)
1353         [[ $ar == $dflt ]] ||
1354                 error "archived file is not on default archive: $ar != $dflt"
1355 }
1356 run_test 10d "Archive a file on the default archive id"
1357
1358 test_11a() {
1359         mkdir -p $DIR/$tdir
1360         copy2archive /etc/hosts $tdir/$tfile
1361         local f=$DIR/$tdir/$tfile
1362
1363         import_file $tdir/$tfile $f
1364         echo -n "Verifying released state: "
1365         check_hsm_flags $f "0x0000000d"
1366
1367         local LSZ=$(stat -c "%s" $f)
1368         local ASZ=$(do_facet $SINGLEAGT stat -c "%s" $HSM_ARCHIVE/$tdir/$tfile)
1369
1370         echo "Verifying imported size $LSZ=$ASZ"
1371         [[ $LSZ -eq $ASZ ]] || error "Incorrect size $LSZ != $ASZ"
1372         echo -n "Verifying released pattern: "
1373         local PTRN=$($GETSTRIPE -L $f)
1374         echo $PTRN
1375         [[ $PTRN == released ]] || error "Is not released"
1376         local fid=$(path2fid $f)
1377         echo "Verifying new fid $fid in archive"
1378
1379         local AFILE=$(do_facet $SINGLEAGT ls $HSM_ARCHIVE'/*/*/*/*/*/*/'$fid) ||
1380                 error "fid $fid not in archive $HSM_ARCHIVE"
1381 }
1382 run_test 11a "Import a file"
1383
1384 test_11b() {
1385         # test needs a running copytool
1386         copytool_setup
1387
1388         mkdir -p $DIR/$tdir
1389         local f=$DIR/$tdir/$tfile
1390         local fid=$(copy_file /etc/hosts $f)
1391         $LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $f ||
1392                 error "hsm_archive failed"
1393         wait_request_state $fid ARCHIVE SUCCEED
1394
1395         local FILE_HASH=$(md5sum $f)
1396         rm -f $f
1397
1398         import_file $fid $f
1399
1400         echo "$FILE_HASH" | md5sum -c
1401
1402         [[ $? -eq 0 ]] || error "Restored file differs"
1403
1404         copytool_cleanup
1405 }
1406 run_test 11b "Import a deleted file using its FID"
1407
1408 test_12a() {
1409         # test needs a running copytool
1410         copytool_setup
1411
1412         mkdir -p $DIR/$tdir
1413         copy2archive /etc/hosts $tdir/$tfile
1414
1415         local f=$DIR/$tdir/$tfile
1416         import_file $tdir/$tfile $f
1417         local f2=$DIR2/$tdir/$tfile
1418         echo "Verifying released state: "
1419         check_hsm_flags $f2 "0x0000000d"
1420
1421         local fid=$(path2fid $f2)
1422         $LFS hsm_restore $f2
1423         wait_request_state $fid RESTORE SUCCEED
1424
1425         echo "Verifying file state: "
1426         check_hsm_flags $f2 "0x00000009"
1427
1428         do_facet $SINGLEAGT diff -q $HSM_ARCHIVE/$tdir/$tfile $f
1429
1430         [[ $? -eq 0 ]] || error "Restored file differs"
1431
1432         copytool_cleanup
1433 }
1434 run_test 12a "Restore an imported file explicitly"
1435
1436 test_12b() {
1437         # test needs a running copytool
1438         copytool_setup
1439
1440         mkdir -p $DIR/$tdir
1441         copy2archive /etc/hosts $tdir/$tfile
1442
1443         local f=$DIR/$tdir/$tfile
1444         import_file $tdir/$tfile $f
1445         echo "Verifying released state: "
1446         check_hsm_flags $f "0x0000000d"
1447
1448         cat $f > /dev/null || error "File read failed"
1449
1450         echo "Verifying file state after restore: "
1451         check_hsm_flags $f "0x00000009"
1452
1453         do_facet $SINGLEAGT diff -q $HSM_ARCHIVE/$tdir/$tfile $f
1454
1455         [[ $? -eq 0 ]] || error "Restored file differs"
1456
1457         copytool_cleanup
1458 }
1459 run_test 12b "Restore an imported file implicitly"
1460
1461 test_12c() {
1462         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs" && return
1463
1464         # test needs a running copytool
1465         copytool setup
1466
1467         local f=$DIR/$tdir/$tfile
1468         mkdir -p $DIR/$tdir
1469         $LFS setstripe -c 2 "$f"
1470         local fid
1471         fid=$(make_custom_file_for_progress $f 5)
1472         [ $? != 0 ] && skip "not enough free space" && return
1473
1474         local FILE_CRC=$(md5sum $f)
1475
1476         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1477         wait_request_state $fid ARCHIVE SUCCEED
1478         $LFS hsm_release $f || error "release $f failed"
1479
1480         echo "$FILE_CRC" | md5sum -c
1481
1482         [[ $? -eq 0 ]] || error "Restored file differs"
1483 }
1484 run_test 12c "Restore a file with stripe of 2"
1485
1486 test_12d() {
1487         # test needs a running copytool
1488         copytool setup
1489
1490         mkdir -p $DIR/$tdir
1491
1492         local f=$DIR/$tdir/$tfile
1493         local fid=$(copy_file /etc/hosts $f)
1494         $LFS hsm_restore $f || error "restore of non archived file failed"
1495         local cnt=$(get_request_count $fid RESTORE)
1496         [[ "$cnt" == "0" ]] ||
1497                 error "restore non archived must not make a request"
1498         $LFS hsm_archive $f ||
1499                 error "archive request failed"
1500         wait_request_state $fid ARCHIVE SUCCEED
1501         $LFS hsm_restore $f ||
1502                 error "restore of non released file failed"
1503         local cnt=$(get_request_count $fid RESTORE)
1504         [[ "$cnt" == "0" ]] ||
1505                 error "restore a non dirty file must not make a request"
1506 }
1507 run_test 12d "Restore of a non archived, non released file must work"\
1508                 " without doing request"
1509
1510 test_12e() {
1511         # test needs a running copytool
1512         copytool setup
1513
1514         mkdir -p $DIR/$tdir $HSM_ARCHIVE/$tdir
1515         local f=$DIR/$tdir/$tfile
1516         local fid=$(copy_file /etc/hosts $f)
1517         $LFS hsm_archive $f || error "archive request failed"
1518         wait_request_state $fid ARCHIVE SUCCEED
1519
1520         # make file dirty
1521         cat /etc/hosts >> $f
1522         sync
1523         $LFS hsm_state $f
1524
1525         $LFS hsm_restore $f && error "restore a dirty file must fail"
1526         return 0
1527 }
1528 run_test 12e "Check forbidden restore"
1529
1530 test_12f() {
1531         # test needs a running copytool
1532         copytool setup
1533
1534         mkdir -p $DIR/$tdir
1535         local f=$DIR/$tdir/$tfile
1536         local fid=$(copy_file /etc/hosts $f)
1537
1538         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1539         wait_request_state $fid ARCHIVE SUCCEED
1540         $LFS hsm_release $f || error "release of $f failed"
1541         $LFS hsm_restore $f
1542         wait_request_state $fid RESTORE SUCCEED
1543
1544         echo -n "Verifying file state: "
1545         check_hsm_flags $f "0x00000009"
1546
1547         diff -q /etc/hosts $f
1548
1549         [[ $? -eq 0 ]] || error "Restored file differs"
1550 }
1551 run_test 12f "Restore a released file explicitly"
1552
1553 test_12g() {
1554         # test needs a running copytool
1555         copytool setup
1556
1557         mkdir -p $DIR/$tdir
1558         local f=$DIR/$tdir/$tfile
1559         local fid=$(copy_file /etc/hosts $f)
1560
1561         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1562         wait_request_state $fid ARCHIVE SUCCEED
1563         $LFS hsm_release $f || error "release of $f failed"
1564
1565         diff -q /etc/hosts $f
1566         local st=$?
1567
1568         # we check we had a restore done
1569         wait_request_state $fid RESTORE SUCCEED
1570
1571         [[ $st -eq 0 ]] || error "Restored file differs"
1572 }
1573 run_test 12g "Restore a released file implicitly"
1574
1575 test_12h() {
1576         needclients 2 || return 0
1577
1578         # test needs a running copytool
1579         copytool setup
1580
1581         mkdir -p $DIR/$tdir
1582         local f=$DIR/$tdir/$tfile
1583         local fid=$(copy_file /etc/hosts $f)
1584
1585         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1586         wait_request_state $fid ARCHIVE SUCCEED
1587         $LFS hsm_release $f || error "release of $f failed"
1588
1589         do_node $CLIENT2 diff -q /etc/hosts $f
1590         local st=$?
1591
1592         # we check we had a restore done
1593         wait_request_state $fid RESTORE SUCCEED
1594
1595         [[ $st -eq 0 ]] || error "Restored file differs"
1596 }
1597 run_test 12h "Restore a released file implicitly from a second node"
1598
1599 test_12m() {
1600         # test needs a running copytool
1601         copytool setup
1602
1603         mkdir -p $DIR/$tdir
1604         local f=$DIR/$tdir/$tfile
1605         local fid=$(copy_file /etc/passwd $f)
1606         $LFS hsm_archive $f || error "archive of $f failed"
1607         wait_request_state $fid ARCHIVE SUCCEED
1608
1609         $LFS hsm_release $f || error "release of $f failed"
1610
1611         cmp /etc/passwd $f
1612
1613         [[ $? -eq 0 ]] || error "Restored file differs"
1614 }
1615 run_test 12m "Archive/release/implicit restore"
1616
1617 test_12n() {
1618         # test needs a running copytool
1619         copytool_setup
1620
1621         mkdir -p $DIR/$tdir
1622         copy2archive /etc/hosts $tdir/$tfile
1623
1624         local f=$DIR/$tdir/$tfile
1625         import_file $tdir/$tfile $f
1626
1627         do_facet $SINGLEAGT cmp /etc/hosts $f ||
1628                 error "Restored file differs"
1629
1630         $LFS hsm_release $f || error "release of $f failed"
1631
1632         copytool_cleanup
1633 }
1634 run_test 12n "Import/implicit restore/release"
1635
1636 test_12o() {
1637         # test needs a running copytool
1638         copytool setup
1639
1640         mkdir -p $DIR/$tdir
1641         local f=$DIR/$tdir/$tfile
1642         local fid=$(copy_file /etc/hosts $f)
1643
1644         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1645         wait_request_state $fid ARCHIVE SUCCEED
1646         $LFS hsm_release $f || error "release of $f failed"
1647
1648 #define OBD_FAIL_MDS_HSM_SWAP_LAYOUTS           0x152
1649         do_facet $SINGLEMDS lctl set_param fail_loc=0x152
1650
1651         # set no retry action mode
1652         cdt_set_no_retry
1653
1654         diff -q /etc/hosts $f
1655         local st=$?
1656
1657         # we check we had a restore failure
1658         wait_request_state $fid RESTORE FAILED
1659
1660         [[ $st -eq 0 ]] && error "Restore must fail"
1661
1662         # remove no retry action mode
1663         cdt_clear_no_retry
1664
1665         # check file is still released
1666         check_hsm_flags $f "0x0000000d"
1667
1668         # retry w/o failure injection
1669         do_facet $SINGLEMDS lctl set_param fail_loc=0
1670
1671         # to be sure previous RESTORE result is gone
1672         cdt_purge
1673         wait_for_grace_delay
1674
1675         diff -q /etc/hosts $f
1676         st=$?
1677
1678         # we check we had a restore done
1679         wait_request_state $fid RESTORE SUCCEED
1680
1681         [[ $st -eq 0 ]] || error "Restored file differs"
1682 }
1683 run_test 12o "Layout-swap failure during Restore leaves file released"
1684
1685 test_12p() {
1686         # test needs a running copytool
1687         copytool setup
1688
1689         mkdir $DIR/$tdir
1690         local f=$DIR/$tdir/$tfile
1691         local fid=$(copy_file /etc/hosts $f)
1692
1693         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1694         wait_request_state $fid ARCHIVE SUCCEED
1695         do_facet $SINGLEAGT cat $f > /dev/null || error "cannot cat $f"
1696         $LFS hsm_release $f || error "cannot release $f"
1697         do_facet $SINGLEAGT cat $f > /dev/null || error "cannot cat $f"
1698         $LFS hsm_release $f || error "cannot release $f"
1699         do_facet $SINGLEAGT cat $f > /dev/null || error "cannot cat $f"
1700 }
1701 run_test 12p "implicit restore of a file on copytool mount point"
1702
1703 cleanup_test_12q() {
1704                 error "cannot umount $MOUNT3 on $SINGLEAGT"
1705 }
1706
1707 test_12q() {
1708         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.58) ] &&
1709                 skip "need MDS version at least 2.7.58" && return 0
1710
1711         stack_trap "zconf_umount \"$(facet_host $SINGLEAGT)\" \"$MOUNT3\"" EXIT
1712         zconf_mount $(facet_host $SINGLEAGT) $MOUNT3 ||
1713                 error "cannot mount $MOUNT3 on $SINGLEAGT"
1714
1715         # test needs a running copytool
1716         copytool setup -m "$MOUNT3"
1717
1718         local f=$DIR/$tdir/$tfile
1719         local f2=$DIR2/$tdir/$tfile
1720         local fid=$(create_small_file $f)
1721         local orig_size=$(stat -c "%s" $f)
1722
1723         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1724         wait_request_state $fid ARCHIVE SUCCEED
1725
1726         $LFS hsm_release $f || error "could not release file"
1727         check_hsm_flags $f "0x0000000d"
1728
1729         kill_copytools
1730         wait_copytools || error "copytool failed to stop"
1731
1732         cat $f > /dev/null &
1733
1734         # wait a bit to allow implicit restore request to be handled.
1735         # if not, next stat would also block on layout-lock.
1736         sleep 5
1737
1738         local size=$(stat -c "%s" $f2)
1739         [ $size -eq $orig_size ] ||
1740                 error "$f2: wrong size after archive: $size != $orig_size"
1741
1742         copytool setup -m "$MOUNT3"
1743
1744         wait
1745
1746         size=$(stat -c "%s" $f)
1747         [ $size -eq $orig_size ] ||
1748                 error "$f: wrong size after restore: $size != $orig_size"
1749
1750         size=$(stat -c "%s" $f2)
1751         [ $size -eq $orig_size ] ||
1752                 error "$f2: wrong size after restore: $size != $orig_size"
1753
1754         :>$f
1755
1756         size=$(stat -c "%s" $f)
1757         [ $size -eq 0 ] ||
1758                 error "$f: wrong size after overwrite: $size != 0"
1759
1760         size=$(stat -c "%s" $f2)
1761         [ $size -eq 0 ] ||
1762                 error "$f2: wrong size after overwrite: $size != 0"
1763 }
1764 run_test 12q "file attributes are refreshed after restore"
1765
1766 test_13() {
1767         # test needs a running copytool
1768         copytool_setup
1769
1770         local ARC_SUBDIR="import.orig"
1771         local d=""
1772         local f=""
1773
1774         # populate directory to be imported
1775         for d in $(seq 1 10); do
1776                 local CURR_DIR="$HSM_ARCHIVE/$ARC_SUBDIR/dir.$d"
1777                 do_facet $SINGLEAGT mkdir -p "$CURR_DIR"
1778                 for f in $(seq 1 10); do
1779                         CURR_FILE="$CURR_DIR/$tfile.$f"
1780                         # write file-specific data
1781                         do_facet $SINGLEAGT \
1782                                 "echo d=$d, f=$f, dir=$CURR_DIR, "\
1783                                         "file=$CURR_FILE > $CURR_FILE"
1784                 done
1785         done
1786         # import to Lustre
1787         import_file "$ARC_SUBDIR" $DIR/$tdir
1788         # diff lustre content and origin (triggers file restoration)
1789         # there must be 10x10 identical files, and no difference
1790         local cnt_ok=$(do_facet $SINGLEAGT diff -rs $HSM_ARCHIVE/$ARC_SUBDIR \
1791                        $DIR/$tdir/$ARC_SUBDIR | grep identical | wc -l)
1792         local cnt_diff=$(do_facet $SINGLEAGT diff -r $HSM_ARCHIVE/$ARC_SUBDIR \
1793                          $DIR/$tdir/$ARC_SUBDIR | wc -l)
1794
1795         [ $cnt_diff -eq 0 ] ||
1796                 error "$cnt_diff imported files differ from read data"
1797         [ $cnt_ok -eq 100 ] ||
1798                 error "not enough identical files ($cnt_ok != 100)"
1799
1800         copytool_cleanup
1801 }
1802 run_test 13 "Recursively import and restore a directory"
1803
1804 test_14() {
1805         # test needs a running copytool
1806         copytool_setup
1807
1808         # archive a file
1809         local f=$DIR/$tdir/$tfile
1810         local fid=$(create_small_file $f)
1811         local sum=$(md5sum $f | awk '{print $1}')
1812         $LFS hsm_archive $f || error "could not archive file"
1813         wait_request_state $fid ARCHIVE SUCCEED
1814
1815         # create released file (simulate llapi_hsm_import call)
1816         local fid2=$(create_empty_file "$f")
1817         $LFS hsm_set --archived --exists $f || error "could not force hsm flags"
1818         $LFS hsm_release $f || error "could not release file"
1819
1820         # rebind the archive to the newly created file
1821         echo "rebind $fid to $fid2"
1822
1823         do_facet $SINGLEAGT \
1824                 "$HSMTOOL --archive $HSM_ARCHIVE_NUMBER --hsm-root $HSM_ARCHIVE\
1825                  --rebind $fid $fid2 $DIR" || error "could not rebind file"
1826
1827         # restore file and compare md5sum
1828         local sum2=$(md5sum $f | awk '{print $1}')
1829
1830         [[ $sum == $sum2 ]] || error "md5sum mismatch after restore"
1831
1832         copytool_cleanup
1833 }
1834 run_test 14 "Rebind archived file to a new fid"
1835
1836 test_15() {
1837         # test needs a running copytool
1838         copytool_setup
1839
1840         # archive files
1841         local f=$DIR/$tdir/$tfile
1842         local count=5
1843         local tmpfile=$SHARED_DIRECTORY/tmp.$$
1844
1845         local fids=()
1846         local sums=()
1847         for i in $(seq 1 $count); do
1848                 fids[$i]=$(create_small_file $f.$i)
1849                 sums[$i]=$(md5sum $f.$i | awk '{print $1}')
1850                 $LFS hsm_archive $f.$i || error "could not archive file"
1851         done
1852         wait_all_done $(($count*60))
1853
1854         :>$tmpfile
1855         # delete the files
1856         for i in $(seq 1 $count); do
1857                 local fid2=$(create_empty_file "${f}.${i}")
1858                 # add the rebind operation to the list
1859                 echo ${fids[$i]} $fid2 >> $tmpfile
1860
1861                 # set it released (simulate llapi_hsm_import call)
1862                 $LFS hsm_set --archived --exists $f.$i ||
1863                         error "could not force hsm flags"
1864                 $LFS hsm_release $f.$i || error "could not release file"
1865         done
1866         nl=$(wc -l < $tmpfile)
1867         [[ $nl == $count ]] || error "$nl files in list, $count expected"
1868
1869         echo "rebind list of files"
1870         do_facet $SINGLEAGT \
1871                 "$HSMTOOL --archive $HSM_ARCHIVE_NUMBER --hsm-root $HSM_ARCHIVE\
1872                  --rebind $tmpfile $DIR" || error "could not rebind file list"
1873
1874         # restore files and compare md5sum
1875         for i in $(seq 1 $count); do
1876                 local sum2=$(md5sum $f.$i | awk '{print $1}')
1877                 [[ $sum2 == ${sums[$i]} ]] ||
1878                     error "md5sum mismatch after restore ($sum2 != ${sums[$i]})"
1879         done
1880
1881         rm -f $tmpfile
1882         copytool_cleanup
1883 }
1884 run_test 15 "Rebind a list of files"
1885
1886 test_16() {
1887         # test needs a running copytool
1888         copytool setup -b 1
1889
1890         local ref=/tmp/ref
1891         # create a known size file so we can verify transfer speed
1892         # 20 MB <-> 20s
1893         local goal=20
1894         dd if=/dev/zero of=$ref bs=1M count=20
1895
1896         mkdir -p $DIR/$tdir
1897         local f=$DIR/$tdir/$tfile
1898         local fid=$(copy_file $ref $f)
1899         rm $ref
1900         local start=$(date +%s)
1901         $LFS hsm_archive $f
1902         wait_request_state $fid ARCHIVE SUCCEED
1903         local end=$(date +%s)
1904         # Add 1 to account for rounding errors between start and end (LU-8155)
1905         local duration=$((end - start + 1))
1906
1907         [[ $duration -ge $((goal - 1)) ]] ||
1908                 error "Transfer is too fast $duration < $goal"
1909 }
1910 run_test 16 "Test CT bandwith control option"
1911
1912 test_20() {
1913         local f=$DIR/$tdir/$tfile
1914         create_empty_file "$f"
1915
1916         # Could not release a non-archived file
1917         $LFS hsm_release $f && error "release should not succeed"
1918
1919         # For following tests, we must test them with HS_ARCHIVED set
1920         $LFS hsm_set --exists --archived $f || error "could not add flag"
1921
1922         # Could not release a file if no-release is set
1923         $LFS hsm_set --norelease $f || error "could not add flag"
1924         $LFS hsm_release $f && error "release should not succeed"
1925         $LFS hsm_clear --norelease $f || error "could not remove flag"
1926
1927         # Could not release a file if lost
1928         $LFS hsm_set --lost $f || error "could not add flag"
1929         $LFS hsm_release $f && error "release should not succeed"
1930         $LFS hsm_clear --lost $f || error "could not remove flag"
1931
1932         # Could not release a file if dirty
1933         $LFS hsm_set --dirty $f || error "could not add flag"
1934         $LFS hsm_release $f && error "release should not succeed"
1935         $LFS hsm_clear --dirty $f || error "could not remove flag"
1936 }
1937 run_test 20 "Release is not permitted"
1938
1939 test_21() {
1940         # test needs a running copytool
1941         copytool setup
1942
1943         local f=$DIR/$tdir/test_release
1944
1945         # Create a file and check its states
1946         local fid=$(create_small_file $f)
1947         check_hsm_flags $f "0x00000000"
1948
1949         # LU-4388/LU-4389 - ZFS does not report full number of blocks
1950         # used until file is flushed to disk
1951         if [  $(facet_fstype ost1) == "zfs" ]; then
1952             # this causes an OST_SYNC rpc to be sent
1953             dd if=/dev/zero of=$f bs=512 count=1 oflag=sync conv=notrunc,fsync
1954             # clear locks to reread file data
1955             cancel_lru_locks osc
1956         fi
1957
1958         local orig_size=$(stat -c "%s" $f)
1959         local orig_blocks=$(stat -c "%b" $f)
1960
1961         start_full_debug_logging
1962
1963         $LFS hsm_archive $f || error "could not archive file"
1964         wait_request_state $fid ARCHIVE SUCCEED
1965
1966         local blocks=$(stat -c "%b" $f)
1967         [ $blocks -eq $orig_blocks ] ||
1968                 error "$f: wrong block number after archive: " \
1969                       "$blocks != $orig_blocks"
1970         local size=$(stat -c "%s" $f)
1971         [ $size -eq $orig_size ] ||
1972                 error "$f: wrong size after archive: $size != $orig_size"
1973
1974         # Release and check states
1975         $LFS hsm_release $f || error "could not release file"
1976         check_hsm_flags $f "0x0000000d"
1977
1978         blocks=$(stat -c "%b" $f)
1979         [ $blocks -gt 5 ] &&
1980                 error "$f: too many blocks after release: $blocks > 5"
1981         size=$(stat -c "%s" $f)
1982         [ $size -ne $orig_size ] &&
1983                 error "$f: wrong size after release: $size != $orig_size"
1984
1985         # Check we can release an file without stripe info
1986         f=$f.nolov
1987         $MCREATE $f
1988         fid=$(path2fid $f)
1989         check_hsm_flags $f "0x00000000"
1990         $LFS hsm_archive $f || error "could not archive file"
1991         wait_request_state $fid ARCHIVE SUCCEED
1992
1993         # Release and check states
1994         $LFS hsm_release $f || error "could not release file"
1995         check_hsm_flags $f "0x0000000d"
1996
1997         # Release again a file that is already released is OK
1998         $LFS hsm_release $f || fail "second release should succeed"
1999         check_hsm_flags $f "0x0000000d"
2000
2001         stop_full_debug_logging
2002 }
2003 run_test 21 "Simple release tests"
2004
2005 test_22() {
2006         # test needs a running copytool
2007         copytool setup
2008
2009         local f=$DIR/$tdir/test_release
2010         local swap=$DIR/$tdir/test_swap
2011
2012         # Create a file and check its states
2013         local fid=$(create_small_file $f)
2014         check_hsm_flags $f "0x00000000"
2015
2016         $LFS hsm_archive $f || error "could not archive file"
2017         wait_request_state $fid ARCHIVE SUCCEED
2018
2019         # Release and check states
2020         $LFS hsm_release $f || error "could not release file"
2021         check_hsm_flags $f "0x0000000d"
2022
2023         create_small_file $swap
2024         $LFS swap_layouts $swap $f && error "swap_layouts should failed"
2025
2026         return 0
2027 }
2028 run_test 22 "Could not swap a release file"
2029
2030 test_23() {
2031         # test needs a running copytool
2032         copytool setup
2033
2034         local f=$DIR/$tdir/test_mtime
2035
2036         # Create a file and check its states
2037         local fid=$(create_small_file $f)
2038         check_hsm_flags $f "0x00000000"
2039
2040         $LFS hsm_archive $f || error "could not archive file"
2041         wait_request_state $fid ARCHIVE SUCCEED
2042
2043         # Set modification time in the past
2044         touch -m -a -d @978261179 $f
2045
2046         # Release and check states
2047         $LFS hsm_release $f || error "could not release file"
2048         check_hsm_flags $f "0x0000000d"
2049
2050         local MTIME=$(stat -c "%Y" $f)
2051         local ATIME=$(stat -c "%X" $f)
2052         [ $MTIME -eq "978261179" ] || fail "bad mtime: $MTIME"
2053         [ $ATIME -eq "978261179" ] || fail "bad atime: $ATIME"
2054 }
2055 run_test 23 "Release does not change a/mtime (utime)"
2056
2057 test_24a() {
2058         local file=$DIR/$tdir/$tfile
2059         local fid
2060         local atime0
2061         local atime1
2062         local mtime0
2063         local mtime1
2064         local ctime0
2065         local ctime1
2066
2067         # test needs a running copytool
2068         copytool setup
2069
2070         fid=$(create_small_file $file)
2071
2072         # Create a file and check its states
2073         check_hsm_flags $file "0x00000000"
2074
2075         # Ensure atime is less than mtime and ctime.
2076         sleep 1
2077         echo >> $file
2078
2079         atime0=$(stat -c "%X" $file)
2080         mtime0=$(stat -c "%Y" $file)
2081         ctime0=$(stat -c "%Z" $file)
2082
2083         [ $atime0 -lt $mtime0 ] ||
2084                 error "atime $atime0 is not less than mtime $mtime0"
2085
2086         [ $atime0 -lt $ctime0 ] ||
2087                 error "atime $atime0 is not less than ctime $ctime0"
2088
2089         # Archive should not change any timestamps.
2090         $LFS hsm_archive $file || error "cannot archive '$file'"
2091         wait_request_state $fid ARCHIVE SUCCEED
2092
2093         atime1=$(stat -c "%X" $file)
2094         mtime1=$(stat -c "%Y" $file)
2095         ctime1=$(stat -c "%Z" $file)
2096
2097         [ $atime0 -eq $atime1 ] ||
2098                 error "archive changed atime from $atime0 to $atime1"
2099
2100         [ $mtime0 -eq $mtime1 ] ||
2101                 error "archive changed mtime from $mtime0 to $mtime1"
2102
2103         [ $ctime0 -eq $ctime1 ] ||
2104                 error "archive changed ctime from $ctime0 to $ctime1"
2105
2106         # Release should not change any timestamps.
2107         $LFS hsm_release $file || error "cannot release '$file'"
2108         check_hsm_flags $file "0x0000000d"
2109
2110         atime1=$(stat -c "%X" $file)
2111         mtime1=$(stat -c "%Y" $file)
2112         ctime1=$(stat -c "%Z" $file)
2113
2114         [ $atime0 -eq $atime1 ] ||
2115                 error "release changed atime from $atime0 to $atime1"
2116
2117         [ $mtime0 -eq $mtime1 ] ||
2118                 error "release changed mtime from $mtime0 to $mtime1"
2119
2120         [ $ctime0 -eq $ctime1 ] ||
2121                 error "release changed ctime from $ctime0 to $ctime1"
2122
2123         # Restore should not change any timestamps.
2124         $LFS hsm_restore $file
2125         wait_request_state $fid RESTORE SUCCEED
2126
2127         atime1=$(stat -c "%X" $file)
2128         mtime1=$(stat -c "%Y" $file)
2129         ctime1=$(stat -c "%Z" $file)
2130
2131         [ $atime0 -eq $atime1 ] ||
2132                 error "restore changed atime from $atime0 to $atime1"
2133
2134         [ $mtime0 -eq $mtime1 ] ||
2135                 error "restore changed mtime from $mtime0 to $mtime1"
2136
2137         [ $ctime0 -eq $ctime1 ] ||
2138                 error "restore changed ctime from $ctime0 to $ctime1"
2139
2140         kill_copytools
2141         wait_copytools || error "Copytools failed to stop"
2142
2143         # Once more, after unmount and mount.
2144         umount_client $MOUNT || error "cannot unmount '$MOUNT'"
2145         mount_client $MOUNT || error "cannot mount '$MOUNT'"
2146
2147         atime1=$(stat -c "%X" $file)
2148         mtime1=$(stat -c "%Y" $file)
2149         ctime1=$(stat -c "%Z" $file)
2150
2151         [ $atime0 -eq $atime1 ] ||
2152                 error "remount changed atime from $atime0 to $atime1"
2153
2154         [ $mtime0 -eq $mtime1 ] ||
2155                 error "remount changed mtime from $mtime0 to $mtime1"
2156
2157         [ $ctime0 -eq $ctime1 ] ||
2158                 error "remount changed ctime from $ctime0 to $ctime1"
2159 }
2160 run_test 24a "Archive, release, and restore does not change a/mtime (i/o)"
2161
2162 test_24b() {
2163         local file=$DIR/$tdir/$tfile
2164         local fid
2165         local sum0
2166         local sum1
2167         # LU-3811
2168
2169         # Test needs a running copytool.
2170         copytool setup
2171
2172         # Check that root can do HSM actions on a regular user's file.
2173         fid=$(create_small_file $file)
2174         sum0=$(md5sum $file)
2175
2176         chown $RUNAS_ID:$RUNAS_GID $file ||
2177                 error "cannot chown '$file' to '$RUNAS_ID'"
2178
2179         chmod ugo-w $DIR/$tdir ||
2180                 error "cannot chmod '$DIR/$tdir'"
2181
2182         $LFS hsm_archive $file
2183         wait_request_state $fid ARCHIVE SUCCEED
2184
2185         $LFS hsm_release $file
2186         check_hsm_flags $file "0x0000000d"
2187
2188         $LFS hsm_restore $file
2189         wait_request_state $fid RESTORE SUCCEED
2190
2191         # Check that ordinary user can get HSM state.
2192         $RUNAS $LFS hsm_state $file ||
2193                 error "user '$RUNAS_ID' cannot get HSM state of '$file'"
2194
2195         $LFS hsm_release $file
2196         check_hsm_flags $file "0x0000000d"
2197
2198         # Check that ordinary user can accessed released file.
2199         sum1=$($RUNAS md5sum $file) ||
2200                 error "user '$RUNAS_ID' cannot read '$file'"
2201
2202         [ "$sum0" == "$sum1" ] ||
2203                 error "md5sum mismatch for '$file'"
2204 }
2205 run_test 24b "root can archive, release, and restore user files"
2206
2207 test_24c() {
2208         local file=$DIR/$tdir/$tfile
2209         local action=archive
2210         local user_save
2211         local group_save
2212         local other_save
2213
2214         # test needs a running copytool
2215         copytool setup
2216
2217         mkdir -p $DIR/$tdir
2218
2219         # Save the default masks and check that cleanup_24c will
2220         # restore the request masks correctly.
2221         user_save=$(get_hsm_param user_request_mask)
2222         stack_trap "set_hsm_param user_request_mask $user_save" EXIT
2223         group_save=$(get_hsm_param group_request_mask)
2224         stack_trap "set_hsm_param user_request_mask $group_save" EXIT
2225         other_save=$(get_hsm_param other_request_mask)
2226         stack_trap "set_hsm_param user_request_mask $other_save" EXIT
2227
2228         [ "$user_save" == RESTORE ] ||
2229                 error "user_request_mask is '$user_save' expected 'RESTORE'"
2230         [ "$group_save" == RESTORE ] ||
2231                 error "group_request_mask is '$group_save' expected 'RESTORE'"
2232         [ "$other_save" == RESTORE ] ||
2233                 error "other_request_mask is '$other_save' expected 'RESTORE'"
2234
2235         # User.
2236         create_small_file $file
2237         chown $RUNAS_ID:nobody $file ||
2238                 error "cannot chown '$file' to '$RUNAS_ID:nobody'"
2239
2240         $RUNAS $LFS hsm_$action $file &&
2241                 error "$action by user should fail"
2242
2243         set_hsm_param user_request_mask $action
2244         $RUNAS $LFS hsm_$action $file ||
2245                 error "$action by user should succeed"
2246
2247         # Group.
2248         create_small_file $file
2249         chown nobody:$RUNAS_GID $file ||
2250                 error "cannot chown '$file' to 'nobody:$RUNAS_GID'"
2251
2252         $RUNAS $LFS hsm_$action $file &&
2253                 error "$action by group should fail"
2254
2255         set_hsm_param group_request_mask $action
2256         $RUNAS $LFS hsm_$action $file ||
2257                 error "$action by group should succeed"
2258
2259         # Other.
2260         create_small_file $file
2261         chown nobody:nobody $file ||
2262                 error "cannot chown '$file' to 'nobody:nobody'"
2263
2264         $RUNAS $LFS hsm_$action $file &&
2265                 error "$action by other should fail"
2266
2267         set_hsm_param other_request_mask $action
2268         $RUNAS $LFS hsm_$action $file ||
2269                 error "$action by other should succeed"
2270 }
2271 run_test 24c "check that user,group,other request masks work"
2272
2273 test_24d() {
2274         local file1=$DIR/$tdir/$tfile
2275         local file2=$DIR2/$tdir/$tfile
2276         local fid1
2277         local fid2
2278
2279         fid1=$(create_small_file $file1)
2280
2281         echo $fid1
2282         $LFS getstripe $file1
2283
2284         stack_trap "zconf_umount \"$(facet_host $SINGLEAGT)\" \"$MOUNT3\"" EXIT
2285         zconf_mount "$(facet_host $SINGLEAGT)" "$MOUNT3" ||
2286                 error "cannot mount '$MOUNT3' on '$SINGLEAGT'"
2287
2288         copytool setup -m  "$MOUNT3"
2289
2290         stack_trap "mount -o remount,rw \"$MOUNT2\"" EXIT
2291         mount -o remount,ro $MOUNT2
2292
2293         do_nodes $(comma_list $(nodes_list)) $LCTL clear
2294
2295         fid2=$(path2fid $file2)
2296         [ "$fid1" == "$fid2" ] ||
2297                 error "FID mismatch '$fid1' != '$fid2'"
2298
2299         $LFS hsm_archive $file2 &&
2300                 error "archive should fail on read-only mount"
2301         check_hsm_flags $file1 "0x00000000"
2302
2303         $LFS hsm_archive $file1 || error "Fail to archive $file1"
2304         wait_request_state $fid1 ARCHIVE SUCCEED
2305
2306         $LFS hsm_release $file1
2307         $LFS hsm_restore $file2
2308         wait_request_state $fid1 RESTORE SUCCEED
2309
2310         $LFS hsm_release $file1 || error "cannot release '$file1'"
2311         dd if=$file2 of=/dev/null bs=1M || error "cannot read '$file2'"
2312
2313         $LFS hsm_release $file2 &&
2314                 error "release should fail on read-only mount"
2315
2316         return 0
2317 }
2318 run_test 24d "check that read-only mounts are respected"
2319
2320 test_24e() {
2321         copytool setup
2322
2323         local f=$DIR/$tdir/$tfile
2324         local fid
2325
2326         fid=$(create_small_file $f) || error "cannot create $f"
2327         $LFS hsm_archive $f || error "cannot archive $f"
2328         wait_request_state $fid ARCHIVE SUCCEED
2329         $LFS hsm_release $f || error "cannot release $f"
2330         while ! $LFS hsm_state $f | grep released; do
2331                 sleep 1
2332         done
2333
2334         tar -cf $TMP/$tfile.tar $DIR/$tdir || error "cannot tar $DIR/$tdir"
2335 }
2336 run_test 24e "tar succeeds on HSM released files" # LU-6213
2337
2338 test_24f() {
2339         # test needs a running copytool
2340         copytool setup
2341
2342         mkdir -p $DIR/$tdir/d1
2343         local f=$DIR/$tdir/$tfile
2344         local fid=$(copy_file /etc/hosts $f)
2345         sum0=$(md5sum $f)
2346         echo $sum0
2347         $LFS hsm_archive $f ||
2348                 error "hsm_archive failed"
2349         wait_request_state $fid ARCHIVE SUCCEED
2350         $LFS hsm_release $f || error "cannot release $f"
2351         tar --xattrs -cvf $f.tar -C $DIR/$tdir $tfile
2352         rm -f $f
2353         sync
2354         tar --xattrs -xvf $f.tar -C $DIR/$tdir ||
2355                 error "Can not recover the tar contents"
2356         sum1=$(md5sum $f)
2357         echo "Sum0 = $sum0, sum1 = $sum1"
2358         [ "$sum0" == "$sum1" ] || error "md5sum mismatch for '$tfile'"
2359 }
2360 run_test 24f "root can archive, release, and restore tar files"
2361
2362 test_25a() {
2363         # test needs a running copytool
2364         copytool_setup
2365
2366         mkdir -p $DIR/$tdir
2367         copy2archive /etc/hosts $tdir/$tfile
2368
2369         local f=$DIR/$tdir/$tfile
2370
2371         import_file $tdir/$tfile $f
2372
2373         $LFS hsm_set --lost $f
2374
2375         md5sum $f
2376         local st=$?
2377
2378         [[ $st == 1 ]] || error "lost file access should failed (returns $st)"
2379
2380         copytool_cleanup
2381 }
2382 run_test 25a "Restore lost file (HS_LOST flag) from import"\
2383              " (Operation not permitted)"
2384
2385 test_25b() {
2386         # test needs a running copytool
2387         copytool setup
2388
2389         mkdir -p $DIR/$tdir
2390
2391         local f=$DIR/$tdir/$tfile
2392         local fid=$(copy_file /etc/passwd $f)
2393
2394         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2395         wait_request_state $fid ARCHIVE SUCCEED
2396
2397         $LFS hsm_release $f
2398         $LFS hsm_set --lost $f
2399         md5sum $f
2400         st=$?
2401
2402         [[ $st == 1 ]] || error "lost file access should failed (returns $st)"
2403 }
2404 run_test 25b "Restore lost file (HS_LOST flag) after release"\
2405              " (Operation not permitted)"
2406
2407 test_26() {
2408         # test needs a running copytool
2409         copytool setup
2410
2411         local f=$DIR/$tdir/$tfile
2412         local fid
2413         fid=$(make_custom_file_for_progress $f 39 1000000)
2414         [ $? != 0 ] && skip "not enough free space" && return
2415
2416         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2417         wait_request_state $fid ARCHIVE SUCCEED
2418
2419         $LFS hsm_remove $f
2420         wait_request_state $fid REMOVE SUCCEED
2421
2422         check_hsm_flags $f "0x00000000"
2423 }
2424 run_test 26 "Remove the archive of a valid file"
2425
2426 test_26a() {
2427         local raolu=$(get_hsm_param remove_archive_on_last_unlink)
2428         [[ $raolu -eq 0 ]] || error "RAoLU policy should be off"
2429
2430         # test needs a running copytool
2431         copytool setup
2432
2433         mkdir -p $DIR/$tdir
2434         local f=$DIR/$tdir/$tfile
2435         local fid=$(copy_file /etc/passwd $f)
2436
2437         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2438         wait_request_state $fid ARCHIVE SUCCEED
2439
2440         local f2=$DIR/$tdir/${tfile}_2
2441         local fid2=$(copy_file /etc/passwd $f2)
2442
2443         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f2
2444         wait_request_state $fid2 ARCHIVE SUCCEED
2445
2446         local f3=$DIR/$tdir/${tfile}_3
2447         local fid3=$(copy_file /etc/passwd $f3)
2448
2449         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f3
2450         wait_request_state $fid3 ARCHIVE SUCCEED
2451
2452         # set a long grace_delay vs short loop_period
2453         local orig_loop_period=$(get_hsm_param loop_period)
2454         local orig_grace_delay=$(get_hsm_param grace_delay)
2455         stack_trap "set_hsm_param loop_period $orig_loop_period" EXIT
2456         set_hsm_param loop_period 10
2457         stack_trap "set_hsm_param grace_delay $orig_grace_delay" EXIT
2458         set_hsm_param grace_delay 100
2459
2460         rm -f $f
2461
2462         stack_trap "set_hsm_param remove_archive_on_last_unlink 0" EXIT
2463         set_hsm_param remove_archive_on_last_unlink 1
2464
2465         ln "$f3" "$f3"_bis || error "Unable to create hard-link"
2466         rm -f $f3
2467
2468         rm -f $f2
2469
2470         set_hsm_param remove_archive_on_last_unlink 0
2471
2472         wait_request_state $fid2 REMOVE SUCCEED
2473
2474         assert_request_count $fid REMOVE 0 \
2475                 "Unexpected archived data remove request for $f"
2476         assert_request_count $fid3 REMOVE 0 \
2477                 "Unexpected archived data remove request for $f3"
2478 }
2479 run_test 26a "Remove Archive On Last Unlink (RAoLU) policy"
2480
2481 test_26b() {
2482         # test needs a running copytool
2483         copytool setup
2484
2485         mkdir -p $DIR/$tdir
2486         local f=$DIR/$tdir/$tfile
2487         local fid=$(copy_file /etc/passwd $f)
2488
2489         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2490         wait_request_state $fid ARCHIVE SUCCEED
2491
2492         stack_trap "set_hsm_param remove_archive_on_last_unlink 0" EXIT
2493         set_hsm_param remove_archive_on_last_unlink 1
2494
2495         cdt_shutdown
2496         cdt_check_state stopped
2497
2498         rm -f $f
2499
2500         set_hsm_param remove_archive_on_last_unlink 0
2501
2502         wait_request_state $fid REMOVE WAITING
2503
2504         cdt_enable
2505
2506         # copytool must re-register
2507         kill_copytools
2508         wait_copytools || error "copytool failed to stop"
2509         copytool setup
2510
2511         wait_request_state $fid REMOVE SUCCEED
2512 }
2513 run_test 26b "RAoLU policy when CDT off"
2514
2515 test_26c() {
2516         # test needs a running copytool
2517         copytool setup
2518
2519         mkdir -p $DIR/$tdir
2520         local f=$DIR/$tdir/$tfile
2521         local fid=$(copy_file /etc/passwd $f)
2522
2523         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2524         wait_request_state $fid ARCHIVE SUCCEED
2525
2526         local f2=$DIR/$tdir/${tfile}_2
2527         local fid2=$(copy_file /etc/passwd $f2)
2528
2529         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f2
2530         wait_request_state $fid2 ARCHIVE SUCCEED
2531
2532         # set a long grace_delay vs short loop_period
2533         local orig_loop_period=$(get_hsm_param loop_period)
2534         local orig_grace_delay=$(get_hsm_param grace_delay)
2535         stack_trap "set_hsm_param loop_period $orig_loop_period" EXIT
2536         set_hsm_param loop_period 10
2537         stack_trap "set_hsm_param grace_delay $orig_grace_delay" EXIT
2538         set_hsm_param grace_delay 100
2539
2540         stack_trap "set_hsm_param remove_archive_on_last_unlink 0" EXIT
2541         set_hsm_param remove_archive_on_last_unlink 1
2542
2543         multiop_bg_pause $f O_c || error "open $f failed"
2544         local pid=$!
2545
2546         rm -f $f
2547         rm -f $f2
2548
2549         wait_request_state $fid2 REMOVE SUCCEED
2550         assert_request_count $fid REMOVE 0 \
2551                 "Unexpected archived data remove request for $f"
2552
2553         kill -USR1 $pid || error "multiop early exit"
2554         # should reach autotest timeout if multiop fails to trap
2555         # signal, close file, and exit ...
2556         wait $pid || error
2557
2558         set_hsm_param remove_archive_on_last_unlink 0
2559
2560         wait_request_state $fid REMOVE SUCCEED
2561 }
2562 run_test 26c "RAoLU effective when file closed"
2563
2564 test_26d() {
2565         # test needs a running copytool
2566         copytool setup
2567
2568         mkdir -p $DIR/$tdir
2569         local f=$DIR/$tdir/$tfile
2570         local fid=$(copy_file /etc/motd $f 1)
2571
2572         $LFS hsm_archive $f || error "could not archive file"
2573         wait_request_state $fid ARCHIVE SUCCEED
2574
2575         # set a long grace_delay vs short loop_period
2576         local orig_loop_period=$(get_hsm_param loop_period)
2577         local orig_grace_delay=$(get_hsm_param grace_delay)
2578         stack_trap "set_hsm_param loop_period $orig_loop_period" EXIT
2579         set_hsm_param loop_period 10
2580         stack_trap "set_hsm_param grace_delay $orig_grace_delay" EXIT
2581         set_hsm_param grace_delay 100
2582
2583         stack_trap "set_hsm_param remove_archive_on_last_unlink 0" EXIT
2584         set_hsm_param remove_archive_on_last_unlink 1
2585
2586         multiop_bg_pause $f O_c || error "multiop failed"
2587         local MULTIPID=$!
2588
2589         rm -f $f
2590
2591         mds_evict_client
2592
2593         set_hsm_param remove_archive_on_last_unlink 0
2594
2595         wait_request_state $fid REMOVE SUCCEED
2596
2597         client_up || client_up || true
2598
2599         kill -USR1 $MULTIPID
2600         wait $MULTIPID || error "multiop close failed"
2601 }
2602 run_test 26d "RAoLU when Client eviction"
2603
2604 test_27a() {
2605         # test needs a running copytool
2606         copytool_setup
2607
2608         create_archive_file $tdir/$tfile
2609         local f=$DIR/$tdir/$tfile
2610         import_file $tdir/$tfile $f
2611         local fid=$(path2fid $f)
2612
2613         $LFS hsm_remove $f
2614
2615         [[ $? != 0 ]] || error "Remove of a released file should fail"
2616
2617         copytool_cleanup
2618 }
2619 run_test 27a "Remove the archive of an imported file (Operation not permitted)"
2620
2621 test_27b() {
2622         # test needs a running copytool
2623         copytool setup
2624
2625         local f=$DIR/$tdir/$tfile
2626         local fid
2627         fid=$(make_custom_file_for_progress $f 39 1000000)
2628         [ $? != 0 ] && skip "not enough free space" && return
2629
2630         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2631         wait_request_state $fid ARCHIVE SUCCEED
2632         $LFS hsm_release $f
2633
2634         $LFS hsm_remove $f
2635
2636         [[ $? != 0 ]] || error "Remove of a released file should fail"
2637 }
2638 run_test 27b "Remove the archive of a relased file (Operation not permitted)"
2639
2640 test_28() {
2641         # test needs a running copytool
2642         copytool setup
2643
2644         local f=$DIR/$tdir/$tfile
2645         local fid
2646         fid=$(make_custom_file_for_progress $f 39 1000000)
2647         [ $? != 0 ] && skip "not enough free space" && return
2648
2649         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2650         wait_request_state $fid ARCHIVE SUCCEED
2651
2652         cdt_disable
2653         $LFS hsm_remove $f
2654
2655         rm -f $f
2656
2657         cdt_enable
2658
2659         wait_request_state $fid REMOVE SUCCEED
2660 }
2661 run_test 28 "Concurrent archive/file remove"
2662
2663 test_29a() {
2664         # Tests --mntpath and --archive options
2665
2666         local archive_id=7
2667         copytool setup -m "$MOUNT" -a $archive_id
2668
2669         # Bad archive number
2670         $LFS hsm_remove -m "$MOUNT" -a 33 0x857765760:0x8:0x2 2>&1 |
2671                 grep "Invalid argument" ||
2672                 error "unexpected hsm_remove failure (1)"
2673
2674         # mntpath is present but file is given
2675         $LFS hsm_remove --mntpath "$MOUNT" --archive 30 /qwerty/uyt 2>&1 |
2676                 grep "hsm: '/qwerty/uyt' is not a valid FID" ||
2677                 error "unexpected hsm_remove failure (2)"
2678 }
2679 run_test 29a "Tests --mntpath and --archive options"
2680
2681 test_29b() {
2682         # test needs a running copytool
2683         copytool setup
2684
2685         local f=$DIR/$tdir/$tfile
2686         local fid=$(create_small_file $f)
2687
2688         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2689         wait_request_state $fid ARCHIVE SUCCEED
2690
2691         rm -f $f
2692
2693         $LFS hsm_remove -m $MOUNT -a $HSM_ARCHIVE_NUMBER $fid
2694         wait_request_state $fid REMOVE SUCCEED
2695 }
2696 run_test 29b "Archive/delete/remove by FID from the archive."
2697
2698 test_29c() {
2699         # test needs a running copytool
2700         copytool setup
2701
2702         local fid1=$(create_small_file $DIR/$tdir/$tfile-1)
2703         local fid2=$(create_small_file $DIR/$tdir/$tfile-2)
2704         local fid3=$(create_small_file $DIR/$tdir/$tfile-3)
2705
2706         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/$tfile-[1-3]
2707         wait_request_state $fid1 ARCHIVE SUCCEED
2708         wait_request_state $fid2 ARCHIVE SUCCEED
2709         wait_request_state $fid3 ARCHIVE SUCCEED
2710
2711         rm -f $DIR/$tdir/$tfile-[1-3]
2712
2713         echo $fid1 > $DIR/$tdir/list
2714         echo $fid2 >> $DIR/$tdir/list
2715         echo $fid3 >> $DIR/$tdir/list
2716
2717         $LFS hsm_remove -m $MOUNT -a $HSM_ARCHIVE_NUMBER \
2718                 --filelist $DIR/$tdir/list
2719         wait_request_state $fid1 REMOVE SUCCEED
2720         wait_request_state $fid2 REMOVE SUCCEED
2721         wait_request_state $fid3 REMOVE SUCCEED
2722 }
2723 run_test 29c "Archive/delete/remove by FID, using a file list."
2724
2725 test_29d() {
2726         # test needs more than one CT
2727         needclients 3 || return 0
2728
2729         local n
2730         local file
2731         local fid
2732
2733         # start all of the copytools
2734         for n in $(seq $AGTCOUNT); do
2735                 copytool setup -f agt$n -a $n
2736         done
2737
2738         # archive files
2739         file=$DIR/$tdir/$tfile
2740         fid=$(create_small_file $file)
2741
2742         $LFS hsm_archive $file
2743         wait_request_state $fid ARCHIVE SUCCEED
2744         check_hsm_flags $file "0x00000009"
2745
2746         rm -f $file
2747
2748         $LFS hsm_remove --mntpath "$MOUNT" -a 0 $fid ||
2749                 error "cannot hsm_remove '$fid'"
2750
2751         # give time for CDT to handle remove request and create broadcasted
2752         sleep 2
2753
2754         # remove request has been broadcasted ?
2755         local cnt=$(get_request_count $fid REMOVE)
2756         # broadcasted requests + original
2757         [[ $cnt -eq $((AGTCOUNT + 1)) ]] ||
2758                 error "remove not broadcasted to all CTs"
2759
2760         # give time for CDT and CTs to handle broadcasted
2761         wait_for_loop_period
2762
2763         # each agent serves one different archive_id, so broadcasted
2764         # hsm_remove request should only succeed once and fail at all others
2765         local res
2766         local scnt=0
2767         local fcnt=0
2768         for n in $(seq $AGTCOUNT); do
2769                 res=$(do_facet $SINGLEMDS "$LCTL get_param -n \
2770                                $HSM_PARAM.actions | awk \
2771                                '/'$fid'.*action=REMOVE archive#='$n'/ \
2772                                {print \\\$13}' | cut -f2 -d=")
2773                 if [[ "$res" == "SUCCEED" ]]; then
2774                         scnt=$((scnt + 1))
2775                 elif [[ "$res" == "FAILED" ]]; then
2776                         fcnt=$((fcnt + 1))
2777                 fi
2778         done
2779
2780         [[ $scnt -eq 1 ]] ||
2781                 error "one and only CT should have removed successfully"
2782
2783         [[ $AGTCOUNT -eq $((scnt + fcnt)) ]] ||
2784                 error "all but one CT should have failed to remove"
2785 }
2786 run_test 29d "hsm_remove by FID with archive_id 0 for unlinked file cause "\
2787              "request to be sent once for each registered archive_id"
2788
2789 test_30a() {
2790         # restore at exec cannot work on agent node (because of Linux kernel
2791         # protection of executables)
2792         needclients 2 || return 0
2793
2794         # test needs a running copytool
2795         copytool_setup
2796
2797         mkdir -p $DIR/$tdir
2798         copy2archive /bin/true $tdir/$tfile
2799
2800         local f=$DIR/$tdir/true
2801         import_file $tdir/$tfile $f
2802
2803         local fid=$(path2fid $f)
2804
2805         # set no retry action mode
2806         cdt_set_no_retry
2807         do_node $CLIENT2 $f
2808         local st=$?
2809
2810         # cleanup
2811         # remove no try action mode
2812         cdt_clear_no_retry
2813         $LFS hsm_state $f
2814
2815         [[ $st == 0 ]] || error "Failed to exec a released file"
2816
2817         copytool_cleanup
2818 }
2819 run_test 30a "Restore at exec (import case)"
2820
2821 test_30b() {
2822         # restore at exec cannot work on agent node (because of Linux kernel
2823         # protection of executables)
2824         needclients 2 || return 0
2825
2826         # test needs a running copytool
2827         copytool setup
2828
2829         mkdir -p $DIR/$tdir
2830         local f=$DIR/$tdir/true
2831         local fid=$(copy_file /bin/true $f)
2832         chmod 755 $f
2833         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2834         wait_request_state $fid ARCHIVE SUCCEED
2835         $LFS hsm_release $f
2836         $LFS hsm_state $f
2837
2838         stack_trap cdt_clear_no_retry EXIT
2839         # set no retry action mode
2840         cdt_set_no_retry
2841
2842         do_node $CLIENT2 $f
2843         local st=$?
2844
2845         $LFS hsm_state $f
2846
2847         [[ $st == 0 ]] || error "Failed to exec a released file"
2848 }
2849 run_test 30b "Restore at exec (release case)"
2850
2851 test_30c() {
2852         needclients 2 || return 0
2853
2854         # test needs a running copytool
2855         copytool setup
2856
2857         mkdir -p $DIR/$tdir
2858         local f=$DIR/$tdir/SLEEP
2859         local slp_sum1=$(md5sum /bin/sleep)
2860         local fid=$(copy_file /bin/sleep $f)
2861         chmod 755 $f
2862         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2863         wait_request_state $fid ARCHIVE SUCCEED
2864         $LFS hsm_release $f
2865         check_hsm_flags $f "0x0000000d"
2866
2867         stack_trap cdt_clear_no_retry EXIT
2868         # set no retry action mode
2869         cdt_set_no_retry
2870
2871         do_node $CLIENT2 "$f 10" &
2872         local pid=$!
2873         sleep 3
2874         echo 'Hi!' > $f
2875         [[ $? == 0 ]] && error "Update during exec of released file must fail"
2876         wait $pid
2877         [[ $? == 0 ]] || error "Execution failed during run"
2878         cmp /bin/sleep $f
2879         if [[ $? != 0 ]]; then
2880                 local slp_sum2=$(md5sum /bin/sleep)
2881                 # in case sleep file is modified during the test
2882                 [[ $slp_sum1 == $slp_sum2 ]] &&
2883                         error "Binary overwritten during exec"
2884         fi
2885
2886         check_hsm_flags $f "0x00000009"
2887 }
2888 run_test 30c "Update during exec of released file must fail"
2889
2890 restore_and_check_size() {
2891         local f=$1
2892         local fid=$2
2893         local s=$(stat -c "%s" $f)
2894         local n=$s
2895         local st=$(get_hsm_flags $f)
2896         local err=0
2897         local cpt=0
2898         $LFS hsm_restore $f
2899         while [[ "$st" != "0x00000009" && $cpt -le 10 ]]
2900         do
2901                 n=$(stat -c "%s" $f)
2902                 # we echo in both cases to show stat is not hang
2903                 if [[ $n != $s ]]; then
2904                         echo "size seen is $n != $s"
2905                         err=1
2906                 else
2907                         echo "size seen is right: $n == $s"
2908                 fi
2909                 sleep 10
2910                 cpt=$((cpt + 1))
2911                 st=$(get_hsm_flags $f)
2912         done
2913         if [[ "$st" = "0x00000009" ]]; then
2914                 echo " "done
2915         else
2916                 echo " restore is too long"
2917                 wait_request_state $fid RESTORE SUCCEED
2918         fi
2919         return $err
2920 }
2921
2922 test_31a() {
2923         # test needs a running copytool
2924         copytool_setup
2925
2926         create_archive_file $tdir/$tfile
2927         local f=$DIR/$tdir/$tfile
2928         import_file $tdir/$tfile $f
2929         local fid=$($LFS path2fid $f)
2930         HSM_ARCHIVE_PURGE=false copytool_setup
2931
2932         restore_and_check_size $f $fid
2933         local err=$?
2934
2935         [[ $err -eq 0 ]] || error "File size changed during restore"
2936
2937         copytool_cleanup
2938 }
2939 run_test 31a "Import a large file and check size during restore"
2940
2941
2942 test_31b() {
2943         # test needs a running copytool
2944         copytool setup
2945
2946         local f=$DIR/$tdir/$tfile
2947         local fid
2948         fid=$(make_custom_file_for_progress $f 39 1000000)
2949         [ $? != 0 ] && skip "not enough free space" && return
2950
2951         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2952         wait_request_state $fid ARCHIVE SUCCEED
2953         $LFS hsm_release $f
2954
2955         restore_and_check_size $f $fid
2956         local err=$?
2957
2958         [[ $err -eq 0 ]] || error "File size changed during restore"
2959 }
2960 run_test 31b "Restore a large unaligned file and check size during restore"
2961
2962 test_31c() {
2963         # test needs a running copytool
2964         copytool setup
2965
2966         local f=$DIR/$tdir/$tfile
2967         local fid
2968         fid=$(make_custom_file_for_progress $f 33 1048576)
2969         [ $? != 0 ] && skip "not enough free space" && return
2970
2971         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2972         wait_request_state $fid ARCHIVE SUCCEED
2973         $LFS hsm_release $f
2974
2975         restore_and_check_size $f $fid
2976         local err=$?
2977
2978         [[ $err -eq 0 ]] || error "File size changed during restore"
2979 }
2980 run_test 31c "Restore a large aligned file and check size during restore"
2981
2982 test_33() {
2983         # test needs a running copytool
2984         copytool setup -b 1
2985
2986         local f=$DIR/$tdir/$tfile
2987         local fid
2988         fid=$(make_custom_file_for_progress $f 39 1000000)
2989         [ $? != 0 ] && skip "not enough free space" && return
2990
2991         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2992         wait_request_state $fid ARCHIVE SUCCEED
2993         $LFS hsm_release $f
2994
2995         # to be sure wait_all_done will not be mislead by previous tests
2996         # and ops.
2997         cdt_purge
2998         wait_for_grace_delay
2999         # Also raise grace_delay significantly so the Canceled
3000         # Restore action will stay enough long avail.
3001         local old_grace=$(get_hsm_param grace_delay)
3002         stack_trap "set_hsm_param grace_delay $old_grace" EXIT
3003         set_hsm_param grace_delay 100
3004
3005         md5sum $f >/dev/null &
3006         local pid=$!
3007         wait_request_state $fid RESTORE STARTED
3008
3009         kill -15 $pid
3010         sleep 1
3011
3012         # Check restore trigger process was killed
3013         local killed=$(ps -o pid,comm hp $pid >/dev/null)
3014
3015         $LFS hsm_cancel $f
3016
3017         # instead of waiting+checking both Restore and Cancel ops
3018         # sequentially, wait for both to be finished and then check
3019         # each results.
3020         wait_all_done 100 $fid
3021         local rstate=$(get_request_state $fid RESTORE)
3022         local cstate=$(get_request_state $fid CANCEL)
3023
3024         if [[ "$rstate" == "CANCELED" ]] ; then
3025                 [[ "$cstate" == "SUCCEED" ]] ||
3026                         error "Restore state is CANCELED and Cancel state " \
3027                                "is not SUCCEED but $cstate"
3028                 echo "Restore state is CANCELED, Cancel state is SUCCEED"
3029         elif [[ "$rstate" == "SUCCEED" ]] ; then
3030                 [[ "$cstate" == "FAILED" ]] ||
3031                         error "Restore state is SUCCEED and Cancel state " \
3032                                 "is not FAILED but $cstate"
3033                 echo "Restore state is SUCCEED, Cancel state is FAILED"
3034         else
3035                 error "Restore state is $rstate and Cancel state is $cstate"
3036         fi
3037
3038         [ -z $killed ] ||
3039                 error "Cannot kill process waiting for restore ($killed)"
3040 }
3041 run_test 33 "Kill a restore waiting process"
3042
3043 test_34() {
3044         # test needs a running copytool
3045         copytool setup -b 1
3046
3047         local f=$DIR/$tdir/$tfile
3048         local fid
3049         fid=$(make_custom_file_for_progress $f 39 1000000)
3050         [ $? != 0 ] && skip "not enough free space" && return
3051
3052         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3053         wait_request_state $fid ARCHIVE SUCCEED
3054         $LFS hsm_release $f
3055
3056         md5sum $f >/dev/null &
3057         local pid=$!
3058         wait_request_state $fid RESTORE STARTED
3059
3060         rm $f || error "rm $f failed"
3061         # rm must not block during restore
3062         wait_request_state $fid RESTORE STARTED
3063
3064         wait_request_state $fid RESTORE SUCCEED
3065         # check md5sum pgm finished
3066         local there=$(ps -o pid,comm hp $pid >/dev/null)
3067         [[ -z $there ]] || error "Restore initiator does not exit"
3068
3069         wait $pid || error "Restore initiator failed with $?"
3070 }
3071 run_test 34 "Remove file during restore"
3072
3073 test_35() {
3074         # test needs a running copytool
3075         copytool setup -b 1
3076
3077         local f=$DIR/$tdir/$tfile
3078         local f1=$DIR/$tdir/$tfile-1
3079         local fid
3080         fid=$(make_custom_file_for_progress $f 39 1000000)
3081         [ $? != 0 ] && skip "not enough free space" && return
3082
3083         local fid1=$(copy_file /etc/passwd $f1)
3084         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3085         wait_request_state $fid ARCHIVE SUCCEED
3086         $LFS hsm_release $f
3087
3088         md5sum $f >/dev/null &
3089         local pid=$!
3090         wait_request_state $fid RESTORE STARTED
3091
3092         mv $f1 $f || error "mv $f1 $f failed"
3093         # mv must not block during restore
3094         wait_request_state $fid RESTORE STARTED
3095
3096         wait_request_state $fid RESTORE SUCCEED
3097         # check md5sum pgm finished
3098         local there=$(ps -o pid,comm hp $pid >/dev/null)
3099         [[ -z $there ]] || error "Restore initiator does not exit"
3100
3101         wait $pid || error "Restore initiator failed with $?"
3102
3103         fid2=$(path2fid $f)
3104         [[ $fid2 == $fid1 ]] || error "Wrong fid after mv $fid2 != $fid1"
3105 }
3106 run_test 35 "Overwrite file during restore"
3107
3108 test_36() {
3109         # test needs a running copytool
3110         copytool setup -b 1
3111
3112         local f=$DIR/$tdir/$tfile
3113         local fid
3114         fid=$(make_custom_file_for_progress $f 39 1000000)
3115         [ $? != 0 ] && skip "not enough free space" && return
3116
3117         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3118         wait_request_state $fid ARCHIVE SUCCEED
3119         $LFS hsm_release $f
3120
3121         md5sum $f >/dev/null &
3122         local pid=$!
3123         wait_request_state $fid RESTORE STARTED
3124
3125         mv $f $f.new
3126         # rm must not block during restore
3127         wait_request_state $fid RESTORE STARTED
3128
3129         wait_request_state $fid RESTORE SUCCEED
3130         # check md5sum pgm finished
3131         local there=$(ps -o pid,comm hp $pid >/dev/null)
3132         [[ -z $there ]] ||
3133                 error "Restore initiator does not exit"
3134
3135         wait $pid || error "Restore initiator failed with $?"
3136 }
3137 run_test 36 "Move file during restore"
3138
3139 test_37() {
3140         # LU-5683: check that an archived dirty file can be rearchived.
3141         copytool setup
3142
3143         local f=$DIR/$tdir/$tfile
3144         local fid
3145
3146         fid=$(create_small_file $f) || error "cannot create small file"
3147
3148         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3149         wait_request_state $fid ARCHIVE SUCCEED
3150         $LFS hsm_release $f || error "cannot release $f"
3151
3152         # Allow previous archive request to expire from the actions log.
3153         wait_for_grace_delay
3154
3155         # Dirty file.
3156         dd if=/dev/urandom of=$f bs=1M count=1 || error "cannot dirty file"
3157
3158         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3159         wait_request_state $fid ARCHIVE SUCCEED
3160 }
3161 run_test 37 "re-archive a dirty file"
3162
3163 multi_archive() {
3164         local prefix=$1
3165         local count=$2
3166         local n=""
3167
3168         for n in $(seq 1 $count); do
3169                 $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $prefix.$n
3170         done
3171         echo "$count archive requests submitted"
3172 }
3173
3174 test_40() {
3175         local stream_count=4
3176         local file_count=100
3177         mkdir -p $DIR/$tdir
3178         local f=$DIR/$tdir/$tfile
3179         local i=""
3180         local p=""
3181         local fid=""
3182         local max_requests=$(get_hsm_param max_requests)
3183
3184         stack_trap "set_hsm_param max_requests $max_requests" EXIT
3185         # Increase the number of HSM request that can be performed in
3186         # parallel. With the coordinator running once per second, this
3187         # also limits the number of requests per seconds that can be
3188         # performed, so we pick a decent number. But we also need to keep
3189         # that number low because the copytool has no rate limit and will
3190         # fail some requests if if gets too many at once.
3191         set_hsm_param max_requests 300
3192
3193         for i in $(seq 1 $file_count); do
3194                 for p in $(seq 1 $stream_count); do
3195                         fid=$(copy_file /etc/hosts $f.$p.$i)
3196                 done
3197         done
3198
3199         copytool setup
3200
3201         # to be sure wait_all_done will not be mislead by previous tests
3202         cdt_purge
3203         wait_for_grace_delay
3204         typeset -a pids
3205         # start archive streams in background (archive files in parallel)
3206         for p in $(seq 1 $stream_count); do
3207                 multi_archive $f.$p $file_count &
3208                 pids[$p]=$!
3209         done
3210         echo -n  "Wait for all requests being enqueued..."
3211         wait ${pids[*]}
3212         echo OK
3213         wait_all_done 100
3214 }
3215 run_test 40 "Parallel archive requests"
3216
3217 test_52() {
3218         # test needs a running copytool
3219         copytool setup
3220
3221         mkdir -p $DIR/$tdir
3222         local f=$DIR/$tdir/$tfile
3223         local fid=$(copy_file /etc/motd $f 1)
3224
3225         $LFS hsm_archive $f || error "could not archive file"
3226         wait_request_state $fid ARCHIVE SUCCEED
3227         check_hsm_flags $f "0x00000009"
3228
3229         multiop_bg_pause $f O_c || error "multiop failed"
3230         local MULTIPID=$!
3231
3232         mds_evict_client
3233         client_up || client_up || true
3234
3235         kill -USR1 $MULTIPID
3236         wait $MULTIPID || error "multiop close failed"
3237
3238         check_hsm_flags $f "0x0000000b"
3239 }
3240 run_test 52 "Opened for write file on an evicted client should be set dirty"
3241
3242 test_53() {
3243         # test needs a running copytool
3244         copytool setup
3245
3246         mkdir -p $DIR/$tdir
3247         local f=$DIR/$tdir/$tfile
3248         local fid=$(copy_file /etc/motd $f 1)
3249
3250         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3251                 error "could not archive file"
3252         wait_request_state $fid ARCHIVE SUCCEED
3253         check_hsm_flags $f "0x00000009"
3254
3255         multiop_bg_pause $f o_c || error "multiop failed"
3256         MULTIPID=$!
3257
3258         mds_evict_client
3259         client_up || client_up || true
3260
3261         kill -USR1 $MULTIPID
3262         wait $MULTIPID || error "multiop close failed"
3263
3264         check_hsm_flags $f "0x00000009"
3265 }
3266 run_test 53 "Opened for read file on an evicted client should not be set dirty"
3267
3268 test_54() {
3269         # test needs a running copytool
3270         copytool setup -b 1
3271
3272         local f=$DIR/$tdir/$tfile
3273         local fid=$(make_custom_file_for_progress $f 39 1000000)
3274
3275         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3276                 error "could not archive file"
3277         wait_request_state $fid ARCHIVE STARTED
3278
3279         check_hsm_flags $f "0x00000001"
3280
3281         stack_trap "cdt_clear_no_retry" EXIT
3282         # Avoid coordinator resending this request as soon it has failed.
3283         cdt_set_no_retry
3284
3285         echo "foo" >> $f
3286         sync
3287         wait_request_state $fid ARCHIVE FAILED
3288
3289         check_hsm_flags $f "0x00000003"
3290 }
3291 run_test 54 "Write during an archive cancels it"
3292
3293 test_55() {
3294         # test needs a running copytool
3295         copytool setup -b 1
3296
3297         local f=$DIR/$tdir/$tfile
3298         local fid=$(make_custom_file_for_progress $f 39 1000000)
3299
3300         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3301                 error "could not archive file"
3302         wait_request_state $fid ARCHIVE STARTED
3303
3304         check_hsm_flags $f "0x00000001"
3305
3306         stack_trap "cdt_clear_no_retry" EXIT
3307         # Avoid coordinator resending this request as soon it has failed.
3308         cdt_set_no_retry
3309
3310         $TRUNCATE $f 1024 || error "truncate failed"
3311         sync
3312         wait_request_state $fid ARCHIVE FAILED
3313
3314         check_hsm_flags $f "0x00000003"
3315 }
3316 run_test 55 "Truncate during an archive cancels it"
3317
3318 test_56() {
3319         # test needs a running copytool
3320         copytool setup -b 1
3321
3322         local f=$DIR/$tdir/$tfile
3323         local fid
3324         fid=$(make_custom_file_for_progress $f 39 1000000)
3325         [ $? != 0 ] && skip "not enough free space" && return
3326
3327         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3328                 error "could not archive file"
3329         wait_request_state $fid ARCHIVE STARTED
3330
3331         check_hsm_flags $f "0x00000001"
3332
3333         # Change metadata and sync to be sure we are not changing only
3334         # in memory.
3335         chmod 644 $f
3336         chgrp sys $f
3337         sync
3338         wait_request_state $fid ARCHIVE SUCCEED
3339
3340         check_hsm_flags $f "0x00000009"
3341 }
3342 run_test 56 "Setattr during an archive is ok"
3343
3344 test_57() {
3345         # Need one client for I/O, one for request
3346         needclients 2 || return 0
3347
3348         # test needs a running copytool
3349         copytool setup
3350
3351         mkdir -p $DIR/$tdir
3352         local f=$DIR/$tdir/test_archive_remote
3353         # Create a file on a remote node
3354         do_node $CLIENT2 "dd if=/dev/urandom of=$f bs=1M "\
3355                 "count=2 conv=fsync"
3356
3357         # And archive it
3358         do_node $CLIENT2 "$LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $f" ||
3359                 error "hsm_archive failed"
3360         local fid=$(path2fid $f)
3361         wait_request_state $fid ARCHIVE SUCCEED
3362
3363         # Release and implicit restore it
3364         do_node $CLIENT2 "$LFS hsm_release $f" ||
3365                 error "hsm_release failed"
3366         do_node $CLIENT2 "md5sum $f" ||
3367                 error "hsm_restore failed"
3368
3369         wait_request_state $fid RESTORE SUCCEED
3370 }
3371 run_test 57 "Archive a file with dirty cache on another node"
3372
3373 truncate_released_file() {
3374         local src_file=$1
3375         local trunc_to=$2
3376
3377         local sz=$(stat -c %s $src_file)
3378         local f=$DIR/$tdir/$tfile
3379         local fid=$(copy_file $1 $f)
3380         local ref=$f-ref
3381         cp $f $f-ref
3382
3383         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3384                 error "could not archive file"
3385         wait_request_state $fid ARCHIVE SUCCEED
3386
3387         $LFS hsm_release $f || error "could not release file"
3388
3389         $TRUNCATE $f $trunc_to || error "truncate failed"
3390         sync
3391
3392         local sz1=$(stat -c %s $f)
3393         [[ $sz1 == $trunc_to ]] ||
3394                 error "size after trunc: $sz1 expect $trunc_to, original $sz"
3395
3396         $LFS hsm_state $f
3397         check_hsm_flags $f "0x0000000b"
3398
3399         local state=$(get_request_state $fid RESTORE)
3400         [[ "$state" == "SUCCEED" ]] ||
3401                 error "truncate $sz does not trig restore, state = $state"
3402
3403         $TRUNCATE $ref $trunc_to
3404         cmp $ref $f || error "file data wrong after truncate"
3405
3406         rm -f $f $f-ref
3407 }
3408
3409 test_58() {
3410         # test needs a running copytool
3411         copytool setup
3412
3413         mkdir -p $DIR/$tdir
3414
3415         local sz=$(stat -c %s /etc/passwd)
3416
3417         echo "truncate up from $sz to $((sz*2))"
3418         truncate_released_file /etc/passwd $((sz*2))
3419
3420         echo "truncate down from $sz to $((sz/2))"
3421         truncate_released_file /etc/passwd $((sz/2))
3422
3423         echo "truncate to 0"
3424         truncate_released_file /etc/passwd 0
3425 }
3426 run_test 58 "Truncate a released file will trigger restore"
3427
3428 test_59() {
3429         local fid
3430         local server_version=$(lustre_version_code $SINGLEMDS)
3431         [[ $server_version -lt $(version_code 2.7.63) ]] &&
3432                 skip "Need MDS version at least 2.7.63" && return
3433
3434         copytool setup
3435         $MCREATE $DIR/$tfile || error "mcreate failed"
3436         $TRUNCATE $DIR/$tfile 42 || error "truncate failed"
3437         $LFS hsm_archive $DIR/$tfile || error "archive request failed"
3438         fid=$(path2fid $DIR/$tfile)
3439         wait_request_state $fid ARCHIVE SUCCEED
3440         $LFS hsm_release $DIR/$tfile || error "release failed"
3441 }
3442 run_test 59 "Release stripeless file with non-zero size"
3443
3444 test_60() {
3445         # This test validates the fix for LU-4512. Ensure that the -u
3446         # option changes the progress reporting interval from the
3447         # default (30 seconds) to the user-specified interval.
3448         local interval=5
3449         local progress_timeout=$((interval * 4))
3450
3451         copytool setup -b 1 --update-interval $interval
3452
3453         local f=$DIR/$tdir/$tfile
3454         local fid
3455         fid=$(make_custom_file_for_progress $f 10)
3456         [ $? != 0 ] && skip "not enough free space" && return
3457
3458         local mdtidx=0
3459         local mdt=${MDT_PREFIX}${mdtidx}
3460         local mds=mds$((mdtidx + 1))
3461
3462         # Wait for copytool to register
3463         wait_update_facet $mds \
3464                 "$LCTL get_param -n ${mdt}.hsm.agents | grep -o ^uuid" \
3465                 uuid 100 || error "coyptool failed to register with $mdt"
3466
3467         local start_at=$(date +%s)
3468         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3469                 error "could not archive file"
3470
3471         local agent=$(facet_active_host $SINGLEAGT)
3472         local logfile=$(copytool_logfile $SINGLEAGT)
3473
3474         wait_update $agent \
3475             "grep -o start.copy \"$logfile\"" "start copy" 100 ||
3476                 error "copytool failed to start"
3477
3478         local cmd="$LCTL get_param -n ${mdt}.hsm.active_requests"
3479         cmd+=" | awk '/'$fid'.*action=ARCHIVE/ {print \\\$12}' | cut -f2 -d="
3480
3481         local RESULT
3482         local WAIT=0
3483         local sleep=1
3484
3485         echo -n "Expecting a progress update within $progress_timeout seconds... "
3486         while [ true ]; do
3487                 RESULT=$(do_node $(facet_active_host $mds) "$cmd")
3488                 if [ -n "$RESULT" ] && [ "$RESULT" -gt 0 ]; then
3489                         echo "$RESULT bytes copied in $WAIT seconds."
3490                         break
3491                 elif [ $WAIT -ge $progress_timeout ]; then
3492                         error "Timed out waiting for progress update!"
3493                         break
3494                 fi
3495                 WAIT=$((WAIT + sleep))
3496                 sleep $sleep
3497         done
3498
3499         local finish_at=$(date +%s)
3500         local elapsed=$((finish_at - start_at))
3501
3502         # Ensure that the progress update occurred within the expected window.
3503         if [ $elapsed -lt $((interval - 1)) ]; then
3504                 error "Expected progress update after at least $interval seconds"
3505         fi
3506
3507         echo "Wait for on going archive hsm action to complete"
3508         wait_update $agent "grep -o copied \"$logfile\"" "copied" 10 ||
3509                 echo "File archiving not completed even after 10 secs"
3510 }
3511 run_test 60 "Changing progress update interval from default"
3512
3513 test_61() {
3514         # test needs a running copytool
3515         copytool setup
3516
3517         mkdir -p $DIR/$tdir
3518         local f=$DIR/$tdir/$tfile
3519         local fid=$(copy_file /etc/passwd $f)
3520         cdt_disable
3521         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3522         rm -f $f
3523         cdt_enable
3524         wait_request_state $fid ARCHIVE FAILED
3525 }
3526 run_test 61 "Waiting archive of a removed file should fail"
3527
3528 test_62() {
3529         local agent=$(facet_active_host $SINGLEAGT)
3530
3531         copytool_setup
3532
3533         mkdir -p $DIR/$tdir
3534         local f=$DIR/$tdir/$tfile
3535         local fid
3536         fid=$(make_custom_file_for_progress $f 20)
3537         [ $? != 0 ] && skip "not enough free space" && return
3538
3539         local file_hash_before_archive=$(md5sum $f)
3540         $LFS hsm_archive $f
3541         wait_request_state $fid ARCHIVE SUCCEED
3542         $LFS hsm_release $f
3543
3544         # Run md5sum in the back ground
3545         md5sum $f &
3546         wait_request_state $fid RESTORE STARTED
3547
3548         # Kill copytool while md5sum is running
3549         kill_copytools $agent
3550         wait_copytools $agent || error "copytools failed to stop"
3551
3552         echo "Copytool is stopped on $agent"
3553
3554         wait_request_state $fid RESTORE CANCELED
3555
3556         HSM_ARCHIVE_PURGE=false copytool_setup
3557         # md5sum triggers hsm_restore action
3558         local file_hash_after_archive=$(md5sum $f)
3559         wait_request_state $fid RESTORE SUCCEED
3560
3561         [ "$file_hash_before_archive" = \
3562                 "$file_hash_after_archive" ] ||
3563                         error "Restore incomplete"
3564
3565         copytool_cleanup
3566 }
3567 run_test 62 "Stopping a copytool should cancel its requests"
3568
3569 test_70() {
3570         # test needs a new running copytool
3571         stack_trap copytool_monitor_cleanup EXIT
3572         copytool_monitor_setup
3573         copytool setup --event-fifo "$HSMTOOL_MONITOR_DIR/fifo"
3574
3575         # Wait for the copytool to register.
3576         wait_update --verbose $(facet_active_host mds1) \
3577                 "$LCTL get_param -n ${MDT_PREFIX}0.hsm.agents | grep -o ^uuid" \
3578                 uuid 100 ||
3579                 error "copytool failed to register with MDT0000"
3580
3581         kill_copytools
3582         wait_copytools || error "Copytools failed to stop"
3583
3584         local REGISTER_EVENT
3585         local UNREGISTER_EVENT
3586         while read event; do
3587                 local parsed=$(parse_json_event "$event")
3588                 if [ -z "$parsed" ]; then
3589                         error "Copytool sent malformed event: $event"
3590                 fi
3591                 eval $parsed
3592
3593                 if [ $event_type == "REGISTER" ]; then
3594                         REGISTER_EVENT=$event
3595                 elif [ $event_type == "UNREGISTER" ]; then
3596                         UNREGISTER_EVENT=$event
3597                 fi
3598         done < <(echo $"$(get_copytool_event_log)")
3599
3600         if [ -z "$REGISTER_EVENT" ]; then
3601                 error "Copytool failed to send register event to FIFO"
3602         fi
3603
3604         if [ -z "$UNREGISTER_EVENT" ]; then
3605                 error "Copytool failed to send unregister event to FIFO"
3606         fi
3607
3608         echo "Register/Unregister events look OK."
3609 }
3610 run_test 70 "Copytool logs JSON register/unregister events to FIFO"
3611
3612 test_71() {
3613         # Bump progress interval for livelier events.
3614         local interval=5
3615
3616         # test needs a new running copytool
3617         stack_trap copytool_monitor_cleanup EXIT
3618         copytool_monitor_setup
3619         copytool setup --update-interval $interval --event-fifo \
3620                 "$HSMTOOL_MONITOR_DIR/fifo"
3621
3622         stack_trap "cdt_clear_no_retry" EXIT
3623         # Just start and stop the copytool to generate events.
3624         cdt_clear_no_retry
3625
3626         local f=$DIR/$tdir/$tfile
3627         local fid
3628         fid=$(make_custom_file_for_progress $f 39 1000000)
3629         [ $? != 0 ] && skip "not enough free space" && return
3630
3631         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
3632                 error "could not archive file"
3633         wait_request_state $fid ARCHIVE SUCCEED
3634
3635         local expected_fields="event_time data_fid source_fid"
3636         expected_fields+=" total_bytes current_bytes"
3637
3638         local START_EVENT
3639         local FINISH_EVENT
3640         while read event; do
3641                 # Make sure we're not getting anything from previous events.
3642                 for field in $expected_fields; do
3643                         unset $field
3644                 done
3645
3646                 local parsed=$(parse_json_event "$event")
3647                 if [ -z "$parsed" ]; then
3648                         error "Copytool sent malformed event: $event"
3649                 fi
3650                 eval $parsed
3651
3652                 if [ $event_type == "ARCHIVE_START" ]; then
3653                         START_EVENT=$event
3654                         continue
3655                 elif [ $event_type == "ARCHIVE_FINISH" ]; then
3656                         FINISH_EVENT=$event
3657                         continue
3658                 elif [ $event_type != "ARCHIVE_RUNNING" ]; then
3659                         continue
3660                 fi
3661
3662                 # Do some simple checking of the progress update events.
3663                 for expected_field in $expected_fields; do
3664                         if [ -z ${!expected_field+x} ]; then
3665                                 error "Missing $expected_field field in event"
3666                         fi
3667                 done
3668
3669                 if [ $total_bytes -eq 0 ]; then
3670                         error "Expected total_bytes to be > 0"
3671                 fi
3672
3673                 # These should be identical throughout an archive
3674                 # operation.
3675                 if [ $source_fid != $data_fid ]; then
3676                         error "Expected source_fid to equal data_fid"
3677                 fi
3678         done < <(echo $"$(get_copytool_event_log)")
3679
3680         if [ -z "$START_EVENT" ]; then
3681                 error "Copytool failed to send archive start event to FIFO"
3682         fi
3683
3684         if [ -z "$FINISH_EVENT" ]; then
3685                 error "Copytool failed to send archive finish event to FIFO"
3686         fi
3687
3688         echo "Archive events look OK."
3689 }
3690 run_test 71 "Copytool logs JSON archive events to FIFO"
3691
3692 test_72() {
3693         # Bump progress interval for livelier events.
3694         local interval=5
3695
3696         # test needs a new running copytool
3697         copytool_cleanup
3698         copytool_monitor_setup
3699         HSMTOOL_UPDATE_INTERVAL=$interval \
3700         HSMTOOL_EVENT_FIFO=$HSMTOOL_MONITOR_DIR/fifo copytool_setup
3701         local test_file=$HSMTOOL_MONITOR_DIR/file
3702
3703         local cmd="dd if=/dev/urandom of=$test_file count=16 bs=1000000 "
3704         cmd+="conv=fsync"
3705         do_facet $SINGLEAGT "$cmd" ||
3706                 error "cannot create $test_file on $SINGLEAGT"
3707         copy2archive $test_file $tdir/$tfile
3708
3709         mkdir -p $DIR/$tdir
3710         local f=$DIR/$tdir/$tfile
3711         import_file $tdir/$tfile $f
3712         f=$DIR2/$tdir/$tfile
3713         echo "Verifying released state: "
3714         check_hsm_flags $f "0x0000000d"
3715
3716         local fid=$(path2fid $f)
3717         $LFS hsm_restore $f
3718         wait_request_state $fid RESTORE SUCCEED
3719
3720         local expected_fields="event_time data_fid source_fid"
3721         expected_fields+=" total_bytes current_bytes"
3722
3723         local START_EVENT
3724         local FINISH_EVENT
3725         while read event; do
3726                 # Make sure we're not getting anything from previous events.
3727                 for field in $expected_fields; do
3728                         unset $field
3729                 done
3730
3731                 local parsed=$(parse_json_event "$event")
3732                 if [ -z "$parsed" ]; then
3733                         error "Copytool sent malformed event: $event"
3734                 fi
3735                 eval $parsed
3736
3737                 if [ $event_type == "RESTORE_START" ]; then
3738                         START_EVENT=$event
3739                         if [ $source_fid != $data_fid ]; then
3740                                 error "source_fid should == data_fid at start"
3741                         fi
3742                         continue
3743                 elif [ $event_type == "RESTORE_FINISH" ]; then
3744                         FINISH_EVENT=$event
3745                         if [ $source_fid != $data_fid ]; then
3746                                 error "source_fid should == data_fid at finish"
3747                         fi
3748                         continue
3749                 elif [ $event_type != "RESTORE_RUNNING" ]; then
3750                         continue
3751                 fi
3752
3753                 # Do some simple checking of the progress update events.
3754                 for expected_field in $expected_fields; do
3755                         if [ -z ${!expected_field+x} ]; then
3756                                 error "Missing $expected_field field in event"
3757                         fi
3758                 done
3759
3760                 if [ $total_bytes -eq 0 ]; then
3761                         error "Expected total_bytes to be > 0"
3762                 fi
3763
3764                 # When a restore starts out, the data fid is the same as the
3765                 # source fid. After the restore has gotten going, we learn
3766                 # the new data fid. Once the restore has finished, the source
3767                 # fid is set to the new data fid.
3768                 #
3769                 # We test this because some monitoring software may depend on
3770                 # this behavior. If it changes, then the consumers of these
3771                 # events may need to be modified.
3772                 if [ $source_fid == $data_fid ]; then
3773                         error "source_fid should != data_fid during restore"
3774                 fi
3775         done < <(echo $"$(get_copytool_event_log)")
3776
3777         if [ -z "$START_EVENT" ]; then
3778                 error "Copytool failed to send restore start event to FIFO"
3779         fi
3780
3781         if [ -z "$FINISH_EVENT" ]; then
3782                 error "Copytool failed to send restore finish event to FIFO"
3783         fi
3784
3785         echo "Restore events look OK."
3786
3787         cdt_clear_no_retry
3788         copytool_cleanup
3789         copytool_monitor_cleanup
3790
3791         rm -rf $test_dir
3792 }
3793 run_test 72 "Copytool logs JSON restore events to FIFO"
3794
3795 test_90() {
3796         file_count=51 # Max number of files constrained by LNET message size
3797         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
3798         local f=$DIR/$tdir/$tfile
3799         local FILELIST=/tmp/filelist.txt
3800         local i=""
3801
3802         rm -f $FILELIST
3803         for i in $(seq 1 $file_count); do
3804                 fid=$(copy_file /etc/hosts $f.$i)
3805                 echo $f.$i >> $FILELIST
3806         done
3807
3808         copytool setup
3809         # to be sure wait_all_done will not be mislead by previous tests
3810         cdt_purge
3811         wait_for_grace_delay
3812         $LFS hsm_archive --filelist $FILELIST ||
3813                 error "cannot archive a file list"
3814         wait_all_done 100
3815         $LFS hsm_release --filelist $FILELIST ||
3816                 error "cannot release a file list"
3817         $LFS hsm_restore --filelist $FILELIST ||
3818                 error "cannot restore a file list"
3819         wait_all_done 100
3820 }
3821 run_test 90 "Archive/restore a file list"
3822
3823 double_verify_reset_hsm_param() {
3824         local p=$1
3825         echo "Testing $HSM_PARAM.$p"
3826         local val=$(get_hsm_param $p)
3827         local save=$val
3828         local val2=$(($val * 2))
3829         set_hsm_param $p $val2
3830         val=$(get_hsm_param $p)
3831         [[ $val == $val2 ]] ||
3832                 error "$HSM_PARAM.$p: $val != $val2 should be (2 * $save)"
3833         echo "Set $p to 0 must failed"
3834         set_hsm_param $p 0
3835         local rc=$?
3836         # restore value
3837         set_hsm_param $p $save
3838
3839         if [[ $rc == 0 ]]; then
3840                 error "we must not be able to set $HSM_PARAM.$p to 0"
3841         fi
3842 }
3843
3844 test_100() {
3845         double_verify_reset_hsm_param loop_period
3846         double_verify_reset_hsm_param grace_delay
3847         double_verify_reset_hsm_param active_request_timeout
3848         double_verify_reset_hsm_param max_requests
3849         double_verify_reset_hsm_param default_archive_id
3850 }
3851 run_test 100 "Set coordinator /proc tunables"
3852
3853 test_102() {
3854         cdt_disable
3855         cdt_enable
3856         cdt_restart
3857 }
3858 run_test 102 "Verify coordinator control"
3859
3860 test_103() {
3861         # test needs a running copytool
3862         copytool setup
3863
3864         local i=""
3865         local fid=""
3866
3867         mkdir -p $DIR/$tdir
3868         for i in $(seq 1 20); do
3869                 fid=$(copy_file /etc/passwd $DIR/$tdir/$i)
3870         done
3871         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/*
3872
3873         cdt_purge
3874
3875         echo "Current requests"
3876         local res=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3877                         $HSM_PARAM.actions |\
3878                         grep -v CANCELED | grep -v SUCCEED | grep -v FAILED")
3879
3880         [[ -z "$res" ]] || error "Some request have not been canceled"
3881 }
3882 run_test 103 "Purge all requests"
3883
3884 DATA=CEA
3885 DATAHEX='[434541]'
3886 test_104() {
3887         local f=$DIR/$tdir/$tfile
3888         local fid
3889         fid=$(make_custom_file_for_progress $f 39 1000000)
3890         [ $? != 0 ] && skip "not enough free space" && return
3891
3892         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER --data $DATA $f
3893         local data1=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3894                         $HSM_PARAM.actions |\
3895                         grep $fid | cut -f16 -d=")
3896
3897         [[ "$data1" == "$DATAHEX" ]] ||
3898                 error "Data field in records is ($data1) and not ($DATAHEX)"
3899
3900         # archive the file
3901         copytool setup
3902
3903         wait_request_state $fid ARCHIVE SUCCEED
3904 }
3905 run_test 104 "Copy tool data field"
3906
3907 test_105() {
3908         local max_requests=$(get_hsm_param max_requests)
3909         mkdir -p $DIR/$tdir
3910         local i=""
3911
3912         stack_trap "set_hsm_param max_requests $max_requests" EXIT
3913         set_hsm_param max_requests 300
3914
3915         cdt_disable
3916         for i in $(seq -w 1 10); do
3917                 cp /etc/passwd $DIR/$tdir/$i
3918                 $LFS hsm_archive $DIR/$tdir/$i
3919         done
3920         local reqcnt1=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3921                         $HSM_PARAM.actions |\
3922                         grep WAITING | wc -l")
3923         cdt_restart
3924
3925         cdt_disable
3926         local reqcnt2=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3927                         $HSM_PARAM.actions |\
3928                         grep WAITING | wc -l")
3929         cdt_enable
3930         cdt_purge
3931         [[ "$reqcnt1" == "$reqcnt2" ]] ||
3932                 error "Requests count after shutdown $reqcnt2 != "\
3933                       "before shutdown $reqcnt1"
3934 }
3935 run_test 105 "Restart of coordinator"
3936
3937 test_106() {
3938         # test needs a running copytool
3939         copytool setup
3940
3941         local uuid=$(get_agent_uuid $(facet_active_host $SINGLEAGT))
3942
3943         check_agent_registered $uuid
3944
3945         search_copytools || error "No copytool found"
3946
3947         kill_copytools
3948         wait_copytools || error "Copytool failed to stop"
3949
3950         check_agent_unregistered $uuid
3951
3952         copytool setup
3953         uuid=$(get_agent_uuid $(facet_active_host $SINGLEAGT))
3954         check_agent_registered $uuid
3955 }
3956 run_test 106 "Copytool register/unregister"
3957
3958 test_107() {
3959         # test needs a running copytool
3960         copytool setup
3961         # create and archive file
3962         mkdir -p $DIR/$tdir
3963         local f1=$DIR/$tdir/$tfile
3964         local fid=$(copy_file /etc/passwd $f1)
3965         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1
3966         wait_request_state $fid ARCHIVE SUCCEED
3967         # shutdown and restart MDS
3968         fail $SINGLEMDS
3969         # check the copytool still gets messages from MDT
3970         local f2=$DIR/$tdir/2
3971         local fid=$(copy_file /etc/passwd $f2)
3972         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f2
3973         # main check of this sanity: this request MUST succeed
3974         wait_request_state $fid ARCHIVE SUCCEED
3975 }
3976 run_test 107 "Copytool re-register after MDS restart"
3977
3978 policy_set_and_test()
3979 {
3980         local change="$1"
3981         local target="$2"
3982         do_facet $SINGLEMDS $LCTL set_param "$HSM_PARAM.policy=\\\"$change\\\""
3983         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
3984         [[ "$policy" == "$target" ]] ||
3985                 error "Wrong policy after '$change': '$policy' != '$target'"
3986 }
3987
3988 test_109() {
3989         # to force default policy setting if error
3990         CDT_POLICY_HAD_CHANGED=true
3991
3992         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
3993         local default="NonBlockingRestore [NoRetryAction]"
3994         [[ "$policy" == "$default" ]] ||
3995                 error "default policy has changed,"\
3996                       " '$policy' != '$default' update the test"
3997         policy_set_and_test "+NBR" "[NonBlockingRestore] [NoRetryAction]"
3998         policy_set_and_test "+NRA" "[NonBlockingRestore] [NoRetryAction]"
3999         policy_set_and_test "-NBR" "NonBlockingRestore [NoRetryAction]"
4000         policy_set_and_test "-NRA" "NonBlockingRestore NoRetryAction"
4001         policy_set_and_test "NRA NBR" "[NonBlockingRestore] [NoRetryAction]"
4002         # useless bacause we know but safer for futur changes to use real value
4003         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
4004         echo "Next set_param must failed"
4005         policy_set_and_test "wrong" "$policy"
4006
4007         # return to default
4008         echo "Back to default policy"
4009         cdt_set_sanity_policy
4010 }
4011 run_test 109 "Policy display/change"
4012
4013 test_110a() {
4014         # test needs a running copytool
4015         copytool_setup
4016
4017         mkdir -p $DIR/$tdir
4018
4019         copy2archive /etc/passwd $tdir/$tfile
4020
4021         local f=$DIR/$tdir/$tfile
4022         import_file $tdir/$tfile $f
4023         local fid=$(path2fid $f)
4024
4025         cdt_set_non_blocking_restore
4026         md5sum $f
4027         local st=$?
4028
4029         # cleanup
4030         wait_request_state $fid RESTORE SUCCEED
4031         cdt_clear_non_blocking_restore
4032
4033         # Test result
4034         [[ $st == 1 ]] ||
4035                 error "md5sum returns $st != 1, "\
4036                         "should also perror ENODATA (No data available)"
4037 }
4038 run_test 110a "Non blocking restore policy (import case)"
4039
4040 test_110b() {
4041         # test needs a running copytool
4042         copytool setup
4043
4044         mkdir -p $DIR/$tdir
4045         local f=$DIR/$tdir/$tfile
4046         local fid=$(copy_file /etc/passwd $f)
4047         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4048         wait_request_state $fid ARCHIVE SUCCEED
4049         $LFS hsm_release $f
4050
4051         cdt_set_non_blocking_restore
4052         md5sum $f
4053         local st=$?
4054
4055         # cleanup
4056         wait_request_state $fid RESTORE SUCCEED
4057         cdt_clear_non_blocking_restore
4058
4059         # Test result
4060         [[ $st == 1 ]] ||
4061                 error "md5sum returns $st != 1, "\
4062                         "should also perror ENODATA (No data available)"
4063 }
4064 run_test 110b "Non blocking restore policy (release case)"
4065
4066 test_111a() {
4067         # test needs a running copytool
4068         copytool_setup
4069
4070         mkdir -p $DIR/$tdir
4071         copy2archive /etc/passwd $tdir/$tfile
4072
4073         local f=$DIR/$tdir/$tfile
4074
4075         import_file $tdir/$tfile $f
4076         local fid=$(path2fid $f)
4077
4078         cdt_set_no_retry
4079
4080         copytool_remove_backend $fid
4081
4082         $LFS hsm_restore $f
4083         wait_request_state $fid RESTORE FAILED
4084         local st=$?
4085
4086         # cleanup
4087         cdt_clear_no_retry
4088
4089         # Test result
4090         [[ $st == 0 ]] || error "Restore does not failed"
4091
4092         copytool_cleanup
4093 }
4094 run_test 111a "No retry policy (import case), restore will error"\
4095               " (No such file or directory)"
4096
4097 test_111b() {
4098         # test needs a running copytool
4099         copytool_setup
4100
4101         mkdir -p $DIR/$tdir
4102         local f=$DIR/$tdir/$tfile
4103         local fid=$(copy_file /etc/passwd $f)
4104         cdt_set_no_retry
4105         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4106         wait_request_state $fid ARCHIVE SUCCEED
4107         $LFS hsm_release $f
4108
4109         copytool_remove_backend $fid
4110
4111         $LFS hsm_restore $f
4112         wait_request_state $fid RESTORE FAILED
4113         local st=$?
4114
4115         # cleanup
4116         cdt_clear_no_retry
4117
4118         # Test result
4119         [[ $st == 0 ]] || error "Restore does not failed"
4120
4121         copytool_cleanup
4122 }
4123 run_test 111b "No retry policy (release case), restore will error"\
4124               " (No such file or directory)"
4125
4126 test_112() {
4127         # test needs a running copytool
4128         copytool setup
4129
4130         mkdir -p $DIR/$tdir
4131         local f=$DIR/$tdir/$tfile
4132         local fid=$(copy_file /etc/passwd $f)
4133         cdt_disable
4134         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4135         local l=$($LFS hsm_action $f)
4136         echo $l
4137         local res=$(echo $l | cut -f 2- -d" " | grep ARCHIVE)
4138
4139         cdt_enable
4140         wait_request_state $fid ARCHIVE SUCCEED
4141
4142         # Test result
4143         [[ ! -z "$res" ]] || error "action is $l which is not an ARCHIVE"
4144 }
4145 run_test 112 "State of recorded request"
4146
4147 test_200() {
4148         # test needs a running copytool
4149         copytool setup
4150
4151         local f=$DIR/$tdir/$tfile
4152         local fid
4153         fid=$(make_custom_file_for_progress $f 103 1048576)
4154         [ $? != 0 ] && skip "not enough free space" && return
4155
4156         # test with cdt on is made in test_221
4157         cdt_disable
4158         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4159         # wait archive to register at CDT
4160         wait_request_state $fid ARCHIVE WAITING
4161         $LFS hsm_cancel $f
4162         cdt_enable
4163         wait_request_state $fid ARCHIVE CANCELED
4164         wait_request_state $fid CANCEL SUCCEED
4165 }
4166 run_test 200 "Register/Cancel archive"
4167
4168 test_201() {
4169         # test needs a running copytool
4170         copytool_setup
4171
4172         local f=$DIR/$tdir/$tfile
4173         create_archive_file $tdir/$tfile
4174         import_file $tdir/$tfile $f
4175         local fid=$(path2fid $f)
4176
4177         # test with cdt on is made in test_222
4178         cdt_disable
4179         $LFS hsm_restore $f
4180         # wait restore to register at CDT
4181         wait_request_state $fid RESTORE WAITING
4182         $LFS hsm_cancel $f
4183         cdt_enable
4184         wait_request_state $fid RESTORE CANCELED
4185         wait_request_state $fid CANCEL SUCCEED
4186
4187         copytool_cleanup
4188 }
4189 run_test 201 "Register/Cancel restore"
4190
4191 test_202() {
4192         # test needs a running copytool
4193         copytool setup
4194
4195         local f=$DIR/$tdir/$tfile
4196         local fid
4197         fid=$(make_custom_file_for_progress $f 39 1000000)
4198         [ $? != 0 ] && skip "not enough free space" && return
4199
4200         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4201         wait_request_state $fid ARCHIVE SUCCEED
4202
4203         cdt_disable
4204         $LFS hsm_remove $f
4205         # wait remove to register at CDT
4206         wait_request_state $fid REMOVE WAITING
4207         $LFS hsm_cancel $f
4208         cdt_enable
4209         wait_request_state $fid REMOVE CANCELED
4210 }
4211 run_test 202 "Register/Cancel remove"
4212
4213 test_220() {
4214         # test needs a running copytool
4215         copytool setup
4216
4217         mkdir -p $DIR/$tdir
4218
4219         local f=$DIR/$tdir/$tfile
4220         local fid=$(copy_file /etc/passwd $f)
4221
4222         changelog_setup
4223
4224         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4225         wait_request_state $fid ARCHIVE SUCCEED
4226
4227         local flags=$(changelog_get_flags ${MDT[0]} HSM $fid | tail -1)
4228         changelog_cleanup
4229
4230         local target=0x0
4231         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
4232 }
4233 run_test 220 "Changelog for archive"
4234
4235 test_220a() {
4236         # test needs a running copytool
4237         copytool setup
4238
4239         mkdir -p $DIR/$tdir
4240
4241         local f=$DIR/$tdir/$tfile
4242         local fid=$(copy_file /etc/passwd $f)
4243
4244         changelog_setup
4245
4246         # block copytool operations to allow for HSM request to be
4247         # submitted and file be unlinked (CDT will find object removed)
4248         copytool_suspend
4249
4250         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4251
4252         # wait request to reach CT
4253         wait_request_state $fid ARCHIVE STARTED
4254
4255         rm -f $f
4256
4257         copytool_continue
4258
4259         wait_request_state $fid ARCHIVE FAILED
4260
4261         local flags=$(changelog_get_flags ${MDT[0]} HSM $fid | tail -1)
4262         changelog_cleanup
4263
4264         # HE_ARCHIVE|ENOENT
4265         local target=0x2
4266         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
4267 }
4268 run_test 220a "Changelog for failed archive"
4269
4270 test_221() {
4271         # test needs a running copytool
4272         copytool setup -b 1
4273
4274         local f=$DIR/$tdir/$tfile
4275         local fid
4276         fid=$(make_custom_file_for_progress $f 103 1048576)
4277         [ $? != 0 ] && skip "not enough free space" && return
4278
4279         changelog_setup
4280
4281         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4282         wait_request_state $fid ARCHIVE STARTED
4283         $LFS hsm_cancel $f
4284         wait_request_state $fid ARCHIVE CANCELED
4285         wait_request_state $fid CANCEL SUCCEED
4286
4287         local flags=$(changelog_get_flags ${MDT[0]} HSM $fid | tail -1)
4288
4289         local target=0x7d
4290         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
4291 }
4292 run_test 221 "Changelog for archive canceled"
4293
4294 test_222a() {
4295         # test needs a running copytool
4296         copytool_setup
4297
4298         mkdir -p $DIR/$tdir
4299         copy2archive /etc/passwd $tdir/$tfile
4300
4301         local f=$DIR/$tdir/$tfile
4302         import_file $tdir/$tfile $f
4303         local fid=$(path2fid $f)
4304
4305         changelog_setup
4306
4307         $LFS hsm_restore $f
4308         wait_request_state $fid RESTORE SUCCEED
4309
4310         local flags=$(changelog_get_flags ${MDT[0]} HSM $fid | tail -1)
4311
4312         local target=0x80
4313         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
4314
4315         copytool_cleanup
4316 }
4317 run_test 222a "Changelog for explicit restore"
4318
4319 test_222b() {
4320         # test needs a running copytool
4321         copytool setup
4322
4323         mkdir -p $DIR/$tdir
4324         local f=$DIR/$tdir/$tfile
4325         local fid=$(copy_file /etc/passwd $f)
4326
4327         changelog_setup
4328         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4329         wait_request_state $fid ARCHIVE SUCCEED
4330         $LFS hsm_release $f
4331
4332         md5sum $f
4333
4334         wait_request_state $fid RESTORE SUCCEED
4335
4336         local flags=$(changelog_get_flags ${MDT[0]} HSM $fid | tail -1)
4337
4338         local target=0x80
4339         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
4340 }
4341 run_test 222b "Changelog for implicit restore"
4342
4343 test_222c() {
4344         # test needs a running copytool
4345         copytool_setup
4346
4347         mkdir -p $DIR/$tdir
4348         copy2archive /etc/passwd $tdir/$tfile
4349
4350         local f=$DIR/$tdir/$tfile
4351         import_file $tdir/$tfile $f
4352         local fid=$(path2fid $f)
4353
4354         changelog_setup
4355
4356         # block copytool operations to allow for HSM request to be
4357         # submitted and file be unlinked (CDT will find object removed)
4358         copytool_suspend
4359
4360         $LFS hsm_restore $f
4361
4362         # wait request to reach CT
4363         wait_request_state $fid RESTORE STARTED
4364
4365         rm -f $f
4366
4367         copytool_continue
4368
4369         wait_request_state $fid RESTORE FAILED
4370
4371         local flags=$(changelog_get_flags ${MDT[0]} HSM $fid | tail -1)
4372
4373         # HE_RESTORE|ENOENT
4374         local target=0x82
4375         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
4376
4377         copytool_cleanup
4378 }
4379 run_test 222c "Changelog for failed explicit restore"
4380
4381 test_222d() {
4382         # test needs a running copytool
4383         copytool_setup
4384
4385         mkdir -p $DIR/$tdir
4386         local f=$DIR/$tdir/$tfile
4387         local fid=$(copy_file /etc/passwd $f)
4388
4389         changelog_setup
4390         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4391         wait_request_state $fid ARCHIVE SUCCEED
4392         $LFS hsm_release $f
4393
4394         copytool_remove_backend $fid
4395         md5sum $f
4396
4397         wait_request_state $fid RESTORE FAILED
4398
4399         local flags=$(changelog_get_flags ${MDT[0]} HSM $fid | tail -1)
4400
4401         # HE_RESTORE|ENOENT
4402         local target=0x82
4403         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
4404
4405         copytool_cleanup
4406 }
4407 run_test 222d "Changelog for failed implicit restore"
4408
4409 test_223a() {
4410         # test needs a running copytool
4411         copytool_setup
4412
4413         local f=$DIR/$tdir/$tfile
4414         create_archive_file $tdir/$tfile
4415
4416         changelog_setup
4417
4418         import_file $tdir/$tfile $f
4419         local fid=$(path2fid $f)
4420
4421         $LFS hsm_restore $f
4422         wait_request_state $fid RESTORE STARTED
4423         $LFS hsm_cancel $f
4424         wait_request_state $fid RESTORE CANCELED
4425         wait_request_state $fid CANCEL SUCCEED
4426
4427         local flags=$(changelog_get_flags ${MDT[0]} HSM $fid | tail -1)
4428
4429         local target=0xfd
4430         [[ $flags == $target ]] ||
4431                 error "Changelog flag is $flags not $target"
4432
4433         cleanup
4434 }
4435 run_test 223a "Changelog for restore canceled (import case)"
4436
4437 test_223b() {
4438         # test needs a running copytool
4439         copytool setup -b 1
4440
4441         local f=$DIR/$tdir/$tfile
4442         local fid
4443         fid=$(make_custom_file_for_progress $f 39 1000000)
4444         [ $? != 0 ] && skip "not enough free space" && return
4445
4446         changelog_setup
4447         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4448         wait_request_state $fid ARCHIVE SUCCEED
4449         $LFS hsm_release $f
4450         $LFS hsm_restore $f
4451         wait_request_state $fid RESTORE STARTED
4452         $LFS hsm_cancel $f
4453         wait_request_state $fid RESTORE CANCELED
4454         wait_request_state $fid CANCEL SUCCEED
4455
4456         local flags=$(changelog_get_flags ${MDT[0]} HSM $fid | tail -1)
4457
4458         local target=0xfd
4459         [[ $flags == $target ]] ||
4460                 error "Changelog flag is $flags not $target"
4461
4462         copytool_cleanup
4463 }
4464 run_test 223b "Changelog for restore canceled (release case)"
4465
4466 test_224() {
4467         # test needs a running copytool
4468         copytool setup
4469
4470         mkdir -p $DIR/$tdir
4471
4472         local f=$DIR/$tdir/$tfile
4473         local fid=$(copy_file /etc/passwd $f)
4474
4475         changelog_setup
4476         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4477         wait_request_state $fid ARCHIVE SUCCEED
4478
4479         $LFS hsm_remove $f
4480         wait_request_state $fid REMOVE SUCCEED
4481
4482         local flags=$(changelog_get_flags ${MDT[0]} HSM $fid | tail -n 1)
4483
4484         local target=0x200
4485         [[ $flags == $target ]] ||
4486                 error "Changelog flag is $flags not $target"
4487 }
4488 run_test 224 "Changelog for remove"
4489
4490 test_224a() {
4491         # test needs a running copytool
4492         copytool_setup
4493
4494         mkdir -p $DIR/$tdir
4495
4496         local f=$DIR/$tdir/$tfile
4497         local fid=$(copy_file /etc/passwd $f)
4498
4499         changelog_setup
4500         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4501         wait_request_state $fid ARCHIVE SUCCEED
4502
4503         copytool_remove_backend $fid
4504
4505         # block copytool operations to allow for HSM request to be
4506         # submitted and file be unlinked (CDT will find object removed)
4507         copytool_suspend
4508
4509         $LFS hsm_remove $f
4510
4511         # wait for request to reach CT
4512         wait_request_state $fid REMOVE STARTED
4513
4514         rm -f $f
4515
4516         copytool_continue
4517
4518         wait_request_state $fid REMOVE FAILED
4519
4520         local flags=$(changelog_get_flags ${MDT[0]} HSM $fid | tail -n 1)
4521
4522         # HE_REMOVE|ENOENT
4523         local target=0x202
4524         [[ $flags == $target ]] ||
4525                 error "Changelog flag is $flags not $target"
4526
4527         cleanup
4528 }
4529 run_test 224a "Changelog for failed remove"
4530
4531 test_225() {
4532         # test needs a running copytool
4533         copytool setup
4534
4535         # test is not usable because remove request is too fast
4536         # so it is always finished before cancel can be done ...
4537         echo "Test disabled"
4538         copytool_cleanup
4539         return 0
4540
4541         local f=$DIR/$tdir/$tfile
4542         local fid
4543         fid=$(make_custom_file_for_progress $f 39 1000000)
4544         [ $? != 0 ] && skip "not enough free space" && return
4545
4546         changelog_setup
4547         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4548         wait_request_state $fid ARCHIVE SUCCEED
4549
4550         # if cdt is on, it can serve too quickly the request
4551         cdt_disable
4552         $LFS hsm_remove $f
4553         $LFS hsm_cancel $f
4554         cdt_enable
4555         wait_request_state $fid REMOVE CANCELED
4556         wait_request_state $fid CANCEL SUCCEED
4557
4558         flags=$(changelog_get_flags ${MDT[0]} RENME $fid2)
4559         local flags=$($LFS changelog ${MDT[0]} | grep HSM | grep $fid |
4560                 tail -n 1 | awk '{print $5}')
4561
4562         local target=0x27d
4563         [[ $flags == $target ]] ||
4564                 error "Changelog flag is $flags not $target"
4565 }
4566 run_test 225 "Changelog for remove canceled"
4567
4568 test_226() {
4569         # test needs a running copytool
4570         copytool setup
4571
4572         mkdir -p $DIR/$tdir
4573
4574         local f1=$DIR/$tdir/$tfile-1
4575         local f2=$DIR/$tdir/$tfile-2
4576         local f3=$DIR/$tdir/$tfile-3
4577         local fid1=$(copy_file /etc/passwd $f1)
4578         local fid2=$(copy_file /etc/passwd $f2)
4579         copy_file /etc/passwd $f3
4580
4581         changelog_setup
4582         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1
4583         wait_request_state $fid1 ARCHIVE SUCCEED
4584
4585         $LFS hsm_archive $f2
4586         wait_request_state $fid2 ARCHIVE SUCCEED
4587
4588         rm $f1 || error "rm $f1 failed"
4589
4590         local flags=$(changelog_get_flags ${MDT[0]} UNLNK $fid1)
4591
4592         local target=0x3
4593         [[ $flags == $target ]] ||
4594                 error "Changelog flag is $flags not $target"
4595
4596         mv $f3 $f2 || error "mv $f3 $f2 failed"
4597
4598         flags=$(changelog_get_flags ${MDT[0]} RENME $fid2)
4599
4600         target=0x3
4601         [[ $flags == $target ]] ||
4602                 error "Changelog flag is $flags not $target"
4603 }
4604 run_test 226 "changelog for last rm/mv with exiting archive"
4605
4606 check_flags_changes() {
4607         local f=$1
4608         local fid=$2
4609         local hsm_flag=$3
4610         local fst=$4
4611         local cnt=$5
4612
4613         local target=0x280
4614         $LFS hsm_set --$hsm_flag $f ||
4615                 error "Cannot set $hsm_flag on $f"
4616         local flags=($(changelog_get_flags ${MDT[0]} HSM $fid))
4617         local seen=${#flags[*]}
4618         cnt=$((fst + cnt))
4619         [[ $seen == $cnt ]] ||
4620                 error "set $hsm_flag: Changelog events $seen != $cnt"
4621         [[ ${flags[$((cnt - 1))]} == $target ]] ||
4622                 error "set $hsm_flag: Changelog flags are "\
4623                         "${flags[$((cnt - 1))]} not $target"
4624
4625         $LFS hsm_clear --$hsm_flag $f ||
4626                 error "Cannot clear $hsm_flag on $f"
4627         flags=($(changelog_get_flags ${MDT[0]} HSM $fid))
4628         seen=${#flags[*]}
4629         cnt=$(($cnt + 1))
4630         [[ $cnt == $seen ]] ||
4631                 error "clear $hsm_flag: Changelog events $seen != $cnt"
4632
4633         [[ ${flags[$((cnt - 1))]} == $target ]] ||
4634                 error "clear $hsm_flag: Changelog flag is "\
4635                         "${flags[$((cnt - 1))]} not $target"
4636 }
4637
4638 test_227() {
4639         # test needs a running copytool
4640         copytool setup
4641         changelog_setup
4642
4643         mkdir -p $DIR/$tdir
4644         typeset -a flags
4645
4646         for i in norelease noarchive exists archived
4647         do
4648                 local f=$DIR/$tdir/$tfile-$i
4649                 local fid=$(copy_file /etc/passwd $f)
4650                 check_flags_changes $f $fid $i 0 1
4651         done
4652
4653         f=$DIR/$tdir/$tfile---lost
4654         fid=$(copy_file /etc/passwd $f)
4655         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4656         wait_request_state $fid ARCHIVE SUCCEED
4657         check_flags_changes $f $fid lost 3 1
4658 }
4659 run_test 227 "changelog when explicit setting of HSM flags"
4660
4661 test_228() {
4662         # test needs a running copytool
4663         copytool setup
4664
4665         local fid=$(create_small_sync_file $DIR/$tfile)
4666         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tfile
4667         wait_request_state $fid ARCHIVE SUCCEED
4668
4669         $LFS hsm_release $DIR/$tfile
4670         check_hsm_flags $DIR/$tfile "0x0000000d"
4671
4672         filefrag $DIR/$tfile | grep " 1 extent found" ||
4673                 error "filefrag on released file must return only one extent"
4674
4675         # only newer versions of cp detect sparse files by stat/FIEMAP
4676         # (LU-2580)
4677         cp --sparse=auto $DIR/$tfile $DIR/$tfile.2 ||
4678                 error "copying $DIR/$tfile"
4679         cmp $DIR/$tfile $DIR/$tfile.2 || error "comparing copied $DIR/$tfile"
4680
4681         $LFS hsm_release $DIR/$tfile
4682         check_hsm_flags $DIR/$tfile "0x0000000d"
4683
4684         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
4685
4686         tar cf - --sparse $DIR/$tfile | tar xvf - -C $DIR/$tdir ||
4687                 error "tar failed"
4688         cmp $DIR/$tfile $DIR/$tdir/$DIR/$tfile ||
4689                 error "comparing untarred $DIR/$tfile"
4690
4691         rm -f $DIR/$tfile $DIR/$tfile.2 ||
4692                 error "rm $DIR/$tfile or $DIR/$tfile.2 failed"
4693 }
4694 run_test 228 "On released file, return extend to FIEMAP. For [cp,tar] --sparse"
4695
4696 test_250() {
4697         # test needs a running copytool
4698         copytool setup
4699
4700         mkdir -p $DIR/$tdir
4701         local maxrequest=$(get_hsm_param max_requests)
4702         local rqcnt=$(($maxrequest * 3))
4703         local i=""
4704
4705         cdt_disable
4706         for i in $(seq -w 1 $rqcnt); do
4707                 rm -f $DIR/$tdir/$i
4708                 dd if=/dev/urandom of=$DIR/$tdir/$i bs=1M count=10 conv=fsync
4709         done
4710         # we do it in 2 steps, so all requests arrive at the same time
4711         for i in $(seq -w 1 $rqcnt); do
4712                 $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/$i
4713         done
4714         cdt_enable
4715         local cnt=$rqcnt
4716         local wt=$rqcnt
4717         while [[ $cnt != 0 || $wt != 0 ]]; do
4718                 sleep 1
4719                 cnt=$(do_facet $SINGLEMDS "$LCTL get_param -n\
4720                         $HSM_PARAM.actions |\
4721                         grep STARTED | grep -v CANCEL | wc -l")
4722                 [[ $cnt -le $maxrequest ]] ||
4723                         error "$cnt > $maxrequest too many started requests"
4724                 wt=$(do_facet $SINGLEMDS "$LCTL get_param\
4725                         $HSM_PARAM.actions |\
4726                         grep WAITING | wc -l")
4727                 echo "max=$maxrequest started=$cnt waiting=$wt"
4728         done
4729 }
4730 run_test 250 "Coordinator max request"
4731
4732 test_251() {
4733         # test needs a running copytool
4734         copytool setup -b 1
4735
4736         local f=$DIR/$tdir/$tfile
4737         local fid
4738         fid=$(make_custom_file_for_progress $f 103 1048576)
4739         [ $? != 0 ] && skip "not enough free space" && return
4740
4741         cdt_disable
4742         # to have a short test
4743         local old_to=$(get_hsm_param active_request_timeout)
4744         set_hsm_param active_request_timeout 4
4745         # to be sure the cdt will wake up frequently so
4746         # it will be able to cancel the "old" request
4747         local old_loop=$(get_hsm_param loop_period)
4748         set_hsm_param loop_period 2
4749         cdt_enable
4750
4751         # clear locks to avoid extra delay caused by flush/cancel
4752         # and thus prevent early copytool death to timeout.
4753         cancel_lru_locks osc
4754
4755         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4756         wait_request_state $fid ARCHIVE STARTED
4757         sleep 5
4758         wait_request_state $fid ARCHIVE CANCELED
4759
4760         set_hsm_param active_request_timeout $old_to
4761         set_hsm_param loop_period $old_loop
4762 }
4763 run_test 251 "Coordinator request timeout"
4764
4765 test_252() {
4766         # test needs a running copytool
4767         copytool setup -b 1
4768
4769         mkdir -p $DIR/$tdir
4770         local f=$DIR/$tdir/$tfile
4771         local fid=$(make_custom_file_for_progress $f 103 1048576)
4772
4773         cdt_disable
4774         # to have a short test
4775         local old_timeout=$(get_hsm_param active_request_timeout)
4776         stack_trap "set_hsm_param active_request_timeout $old_timeout" EXIT
4777         set_hsm_param active_request_timeout 20
4778         # to be sure the cdt will wake up frequently so
4779         # it will be able to cancel the "old" request
4780         local old_loop_period=$(get_hsm_param loop_period)
4781         stack_trap "set_hsm_param loop_period $old_loop_period" EXIT
4782         set_hsm_param loop_period 2
4783         cdt_enable
4784
4785         # clear locks to avoid extra delay caused by flush/cancel
4786         # and thus prevent early copytool death to timeout.
4787         cancel_lru_locks osc
4788
4789         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
4790         wait_request_state $fid ARCHIVE STARTED
4791         rm -f $f
4792
4793         # wait but less than active_request_timeout+grace_delay
4794         sleep 25
4795         wait_request_state $fid ARCHIVE CANCELED
4796 }
4797 run_test 252 "Timeout'ed running archive of a removed file should be canceled"
4798
4799 test_253() {
4800         local rc
4801         # test needs a running copytool
4802         copytool setup
4803
4804         mkdir -p $DIR/$tdir
4805         local f=$DIR/$tdir/$tfile
4806
4807         dd if=/dev/zero of=$f bs=1MB count=10
4808         local fid=$(path2fid $f)
4809
4810         $LFS hsm_archive $f || error "could not archive file"
4811         wait_request_state $fid ARCHIVE SUCCEED
4812
4813         # clear locks to discard inode data
4814         cancel_lru_locks osc
4815
4816         #define OBD_FAIL_MDC_MERGE              0x807
4817         $LCTL set_param fail_loc=0x807
4818
4819         #expect error here, instead of release with wrong size
4820         $LFS hsm_release $f
4821         rc=$?
4822         if ((rc == 0)); then
4823                 file_size=$(stat -c '%s' $f)
4824                 if ((file_size != 10485760)); then
4825                         error "Wrong file size after hsm_release"
4826                 fi
4827         else
4828                 echo "could not release file"
4829         fi
4830 }
4831 run_test 253 "Check for wrong file size after release"
4832
4833 test_300() {
4834         # the only way to test ondisk conf is to restart MDS ...
4835         echo "Stop coordinator and remove coordinator state at mount"
4836         # stop coordinator
4837         cdt_shutdown
4838         # clean on disk conf set by default
4839         cdt_clear_mount_state
4840         cdt_check_state stopped
4841
4842         # check cdt still off after umount/remount
4843         fail $SINGLEMDS
4844         cdt_check_state stopped
4845
4846         echo "Set coordinator start at mount, and start coordinator"
4847         cdt_set_mount_state enabled
4848
4849         # check cdt is on
4850         cdt_check_state enabled
4851
4852         # check cdt still on after umount/remount
4853         fail $SINGLEMDS
4854         cdt_check_state enabled
4855
4856         # we are back to original state (cdt started at mount)
4857 }
4858 run_test 300 "On disk coordinator state kept between MDT umount/mount"
4859
4860 test_301() {
4861         local ai=$(get_hsm_param default_archive_id)
4862         local new=$((ai + 1))
4863
4864         set_hsm_param default_archive_id $new -P
4865         fail $SINGLEMDS
4866         local res=$(get_hsm_param default_archive_id)
4867
4868         # clear value
4869         set_hsm_param default_archive_id "" "-P -d"
4870
4871         [[ $new == $res ]] || error "Value after MDS restart is $res != $new"
4872 }
4873 run_test 301 "HSM tunnable are persistent"
4874
4875 test_302() {
4876         local ai=$(get_hsm_param default_archive_id)
4877         local new=$((ai + 1))
4878
4879         # stop coordinator
4880         cdt_shutdown
4881
4882         set_hsm_param default_archive_id $new -P
4883
4884         local mdtno
4885         for mdtno in $(seq 1 $MDSCOUNT); do
4886                 fail mds${mdtno}
4887         done
4888
4889         # check cdt is on
4890         cdt_check_state enabled
4891
4892         local res=$(get_hsm_param default_archive_id)
4893
4894         # clear value
4895         set_hsm_param default_archive_id "" "-P -d"
4896
4897         [[ $new == $res ]] || error "Value after MDS restart is $res != $new"
4898 }
4899 run_test 302 "HSM tunnable are persistent when CDT is off"
4900
4901 test_400() {
4902         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4903
4904         copytool setup
4905
4906         mkdir -p $DIR/$tdir
4907
4908         local dir_mdt0=$DIR/$tdir/mdt0
4909         local dir_mdt1=$DIR/$tdir/mdt1
4910
4911         # create 1 dir per MDT
4912         stack_trap "rm -rf $dir_mdt0"
4913         $LFS mkdir -i 0 $dir_mdt0 || error "lfs mkdir"
4914         stack_trap "rm -rf $dir_mdt1"
4915         $LFS mkdir -i 1 $dir_mdt1 || error "lfs mkdir"
4916
4917         # create 1 file in each MDT
4918         local fid1=$(create_small_file $dir_mdt0/$tfile)
4919         local fid2=$(create_small_file $dir_mdt1/$tfile)
4920
4921         # check that hsm request on mdt0 is sent to the right MDS
4922         $LFS hsm_archive $dir_mdt0/$tfile || error "lfs hsm_archive"
4923         wait_request_state $fid1 ARCHIVE SUCCEED 0 &&
4924                 echo "archive successful on mdt0"
4925
4926         # check that hsm request on mdt1 is sent to the right MDS
4927         $LFS hsm_archive $dir_mdt1/$tfile || error "lfs hsm_archive"
4928         wait_request_state $fid2 ARCHIVE SUCCEED 1 &&
4929                 echo "archive successful on mdt1"
4930 }
4931 run_test 400 "Single request is sent to the right MDT"
4932
4933 test_401() {
4934         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
4935
4936         copytool setup
4937
4938         mkdir -p $DIR/$tdir
4939
4940         local dir_mdt0=$DIR/$tdir/mdt0
4941         local dir_mdt1=$DIR/$tdir/mdt1
4942
4943         # create 1 dir per MDT
4944         stack_trap "rm -rf $dir_mdt0" EXIT
4945         $LFS mkdir -i 0 $dir_mdt0 || error "lfs mkdir"
4946         stack_trap "rm -rf $dir_mdt1" EXIT
4947         $LFS mkdir -i 1 $dir_mdt1 || error "lfs mkdir"
4948
4949         # create 1 file in each MDT
4950         local fid1=$(create_small_file $dir_mdt0/$tfile)
4951         local fid2=$(create_small_file $dir_mdt1/$tfile)
4952
4953         # check that compound requests are shunt to the rights MDTs
4954         $LFS hsm_archive $dir_mdt0/$tfile $dir_mdt1/$tfile ||
4955                 error "lfs hsm_archive"
4956         wait_request_state $fid1 ARCHIVE SUCCEED 0 &&
4957                 echo "archive successful on mdt0"
4958         wait_request_state $fid2 ARCHIVE SUCCEED 1 &&
4959                 echo "archive successful on mdt1"
4960 }
4961 run_test 401 "Compound requests split and sent to their respective MDTs"
4962
4963 mdc_change_state() # facet, MDT_pattern, activate|deactivate
4964 {
4965         local facet=$1
4966         local pattern="$2"
4967         local state=$3
4968         local node=$(facet_active_host $facet)
4969         local mdc
4970         for mdc in $(do_facet $facet "$LCTL dl | grep -E ${pattern}-mdc" |
4971                         awk '{print $4}'); do
4972                 echo "$3 $mdc on $node"
4973                 do_facet $facet "$LCTL --device $mdc $state" || return 1
4974         done
4975 }
4976
4977 test_402a() {
4978         # deactivate all mdc on agent1
4979         mdc_change_state $SINGLEAGT "$FSNAME-MDT000." "deactivate"
4980
4981         copytool setup --no-fail
4982
4983         check_agent_unregistered "uuid" # match any agent
4984
4985         # no expected running copytool
4986         search_copytools $agent && error "Copytool start should have failed"
4987
4988         # reactivate MDCs
4989         mdc_change_state $SINGLEAGT "$FSNAME-MDT000." "activate"
4990 }
4991 run_test 402a "Copytool start fails if all MDTs are inactive"
4992
4993 test_402b() {
4994         copytool setup
4995
4996         mkdir -p $DIR/$tdir
4997
4998         local f=$DIR/$tdir/$tfile
4999         touch $f || error "touch $f failed"
5000         local fid=$(path2fid $f)
5001
5002 #define OBD_FAIL_MDS_HSM_CT_REGISTER_NET        0x14d
5003         do_facet $SINGLEAGT lctl set_param fail_loc=0x14d
5004         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
5005
5006         # give time for CDT to send request and to keep it for retry
5007         wait_for_loop_period
5008
5009         wait_request_state $fid ARCHIVE WAITING
5010
5011         do_facet $SINGLEAGT lctl set_param fail_loc=0
5012
5013         # request should succeed now
5014         wait_request_state $fid ARCHIVE SUCCEED
5015 }
5016 run_test 402b "CDT must retry request upon slow start of CT"
5017
5018 test_403() {
5019         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5020
5021         local agent=$(facet_active_host $SINGLEAGT)
5022
5023         # deactivate all mdc for MDT0001
5024         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "deactivate"
5025
5026         copytool setup
5027         local uuid=$(get_agent_uuid $agent)
5028         # check the agent is registered on MDT0000, and not on MDT0001
5029         check_agent_registered_by_mdt $uuid 0
5030         check_agent_unregistered_by_mdt $uuid 1
5031
5032         # check running copytool process
5033         search_copytools $agent || error "No running copytools on $agent"
5034
5035         # reactivate all mdc for MDT0001
5036         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "activate"
5037
5038         # make sure the copytool is now registered to all MDTs
5039         check_agent_registered $uuid
5040 }
5041 run_test 403 "Copytool starts with inactive MDT and register on reconnect"
5042
5043 test_404() {
5044         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5045
5046         copytool setup
5047
5048         # create files on both MDT0000 and MDT0001
5049         mkdir -p $DIR/$tdir
5050
5051         local dir_mdt0=$DIR/$tdir/mdt0
5052         stack_trap "rm -rf $dir_mdt0" EXIT
5053         $LFS mkdir -i 0 $dir_mdt0 || error "lfs mkdir"
5054
5055         # create 1 file on mdt0
5056         local fid1=$(create_small_file $dir_mdt0/$tfile)
5057
5058         # deactivate all mdc for MDT0001
5059         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "deactivate"
5060
5061         # send an HSM request for files in MDT0000
5062         $LFS hsm_archive $dir_mdt0/$tfile || error "lfs hsm_archive"
5063
5064         # check for completion of files in MDT0000
5065         wait_request_state $fid1 ARCHIVE SUCCEED 0 &&
5066                 echo "archive successful on mdt0"
5067
5068         # reactivate all mdc for MDT0001
5069         mdc_change_state $SINGLEAGT "$FSNAME-MDT0001" "activate"
5070 }
5071 run_test 404 "Inactive MDT does not block requests for active MDTs"
5072
5073 test_405() {
5074         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
5075
5076         copytool setup
5077
5078         mkdir -p $DIR/$tdir
5079
5080         local striped_dir=$DIR/$tdir/striped_dir
5081
5082         # create striped dir on all of MDTs
5083         $LFS mkdir -i 0 -c $MDSCOUNT $striped_dir || error "lfs mkdir"
5084
5085         local fid1=$(create_small_sync_file $striped_dir/${tfile}_0)
5086         local fid2=$(create_small_sync_file $striped_dir/${tfile}_1)
5087         local fid3=$(create_small_sync_file $striped_dir/${tfile}_2)
5088         local fid4=$(create_small_sync_file $striped_dir/${tfile}_3)
5089
5090         local idx1=$($LFS getstripe -M $striped_dir/${tfile}_0)
5091         local idx2=$($LFS getstripe -M $striped_dir/${tfile}_1)
5092         local idx3=$($LFS getstripe -M $striped_dir/${tfile}_2)
5093         local idx4=$($LFS getstripe -M $striped_dir/${tfile}_3)
5094
5095         # check that compound requests are shunt to the rights MDTs
5096         $LFS hsm_archive $striped_dir/${tfile}_0 $striped_dir/${tfile}_1  \
5097                          $striped_dir/${tfile}_2 $striped_dir/${tfile}_3 ||
5098                 error "lfs hsm_archive"
5099
5100         wait_request_state $fid1 ARCHIVE SUCCEED $idx1 &&
5101                 echo "archive successful on $fid1"
5102         wait_request_state $fid2 ARCHIVE SUCCEED $idx2 &&
5103                 echo "archive successful on $fid2"
5104         wait_request_state $fid3 ARCHIVE SUCCEED $idx3 &&
5105                 echo "archive successful on $fid3"
5106         wait_request_state $fid4 ARCHIVE SUCCEED $idx4 &&
5107                 echo "archive successful on $fid4"
5108
5109         $LFS hsm_release $striped_dir/${tfile}_0 || error "lfs hsm_release 1"
5110         $LFS hsm_release $striped_dir/${tfile}_1 || error "lfs hsm_release 2"
5111         $LFS hsm_release $striped_dir/${tfile}_2 || error "lfs hsm_release 3"
5112         $LFS hsm_release $striped_dir/${tfile}_3 || error "lfs hsm_release 4"
5113
5114         cat $striped_dir/${tfile}_0 > /dev/null || error "cat ${tfile}_0 failed"
5115         cat $striped_dir/${tfile}_1 > /dev/null || error "cat ${tfile}_1 failed"
5116         cat $striped_dir/${tfile}_2 > /dev/null || error "cat ${tfile}_2 failed"
5117         cat $striped_dir/${tfile}_3 > /dev/null || error "cat ${tfile}_3 failed"
5118 }
5119 run_test 405 "archive and release under striped directory"
5120
5121 test_406() {
5122         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
5123
5124         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.64) ] &&
5125                 skip "need MDS version at least 2.7.64" && return 0
5126
5127         local fid
5128         local mdt_index
5129
5130         fid=$(create_small_file $DIR/$tdir/$tfile)
5131         echo "old fid $fid"
5132
5133         copytool setup
5134
5135         $LFS hsm_archive $DIR/$tdir/$tfile
5136         wait_request_state "$fid" ARCHIVE SUCCEED
5137         $LFS hsm_release $DIR/$tdir/$tfile
5138
5139         # Should migrate $tdir but not $tfile.
5140         $LFS mv -M1 $DIR/$tdir &&
5141                 error "migrating HSM an archived file should fail"
5142
5143         $LFS hsm_restore $DIR/$tdir/$tfile
5144         wait_request_state "$fid" RESTORE SUCCEED
5145
5146         $LFS hsm_remove $DIR/$tdir/$tfile
5147         wait_request_state "$fid" REMOVE SUCCEED
5148
5149         cat $DIR/$tdir/$tfile > /dev/null ||
5150                 error "cannot read $DIR/$tdir/$tfile"
5151
5152         $LFS mv -M1 $DIR/$tdir ||
5153                 error "cannot complete migration after HSM remove"
5154
5155         mdt_index=$($LFS getstripe -M $DIR/$tdir)
5156         if ((mdt_index != 1)); then
5157                 error "expected MDT index 1, got $mdt_index"
5158         fi
5159
5160         # Refresh fid after migration.
5161         fid=$(path2fid $DIR/$tdir/$tfile)
5162         echo "new fid $fid"
5163
5164         $LFS hsm_archive $DIR/$tdir/$tfile
5165         wait_request_state "$fid" ARCHIVE SUCCEED 1
5166
5167         lctl set_param debug=+trace
5168         $LFS hsm_release $DIR/$tdir/$tfile ||
5169                 error "cannot release $DIR/$tdir/$tfile"
5170
5171         $LFS hsm_restore $DIR/$tdir/$tfile
5172         wait_request_state "$fid" RESTORE SUCCEED 1
5173
5174         cat $DIR/$tdir/$tfile > /dev/null ||
5175                 error "cannot read $DIR/$tdir/$tfile"
5176 }
5177 run_test 406 "attempting to migrate HSM archived files is safe"
5178
5179 test_407() {
5180         needclients 2 || return 0
5181         # test needs a running copytool
5182         copytool setup
5183
5184         mkdir -p $DIR/$tdir
5185
5186         local f=$DIR/$tdir/$tfile
5187         local f2=$DIR2/$tdir/$tfile
5188         local fid
5189         fid=$(make_custom_file_for_progress $f 39 1000000)
5190         [ $? != 0 ] && skip "not enough free space" && return
5191
5192         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
5193         wait_request_state $fid ARCHIVE SUCCEED
5194         $LFS hsm_release $f
5195
5196 #define OBD_FAIL_MDS_HSM_CDT_DELAY      0x164
5197         do_facet $SINGLEMDS $LCTL set_param fail_val=5 fail_loc=0x164
5198
5199         md5sum $f &
5200         # 1st request holds layout lock while appropriate
5201         # RESTORE record is still not added to llog
5202         md5sum $f2 &
5203         sleep 2
5204
5205         # after umount hsm_actions->O/x/x log shouldn't have
5206         # double RESTORE records like below
5207         #[0x200000401:0x1:0x0]...0x58d03a0d/0x58d03a0c action=RESTORE...WAITING
5208         #[0x200000401:0x1:0x0]...0x58d03a0c/0x58d03a0d action=RESTORE...WAITING
5209         sleep 30 &&
5210                 do_facet $SINGLEMDS "$LCTL get_param $HSM_PARAM.actions"&
5211         fail $SINGLEMDS
5212
5213         wait_request_state $fid RESTORE SUCCEED
5214 }
5215 run_test 407 "Check for double RESTORE records in llog"
5216
5217 test_500()
5218 {
5219         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.6.92) ] &&
5220                 skip "HSM migrate is not supported" && return
5221
5222         test_mkdir -p $DIR/$tdir
5223         llapi_hsm_test -d $DIR/$tdir || error "One llapi HSM test failed"
5224 }
5225 run_test 500 "various LLAPI HSM tests"
5226
5227 copytool_cleanup
5228
5229 complete $SECONDS
5230 check_and_cleanup_lustre
5231 exit_status