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