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