Whamcloud - gitweb
LU-3815 tests: HSM sanity test suites
[fs/lustre-release.git] / lustre / tests / sanity-hsm.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # exit on error
7 set -e
8 set +o monitor
9
10 SRCDIR=$(dirname $0)
11 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/utils:$PATH:/sbin:/usr/sbin
12
13 ONLY=${ONLY:-"$*"}
14 # bug number for skipped test:    3815     3939
15 ALWAYS_EXCEPT="$SANITY_HSM_EXCEPT 34 35 36 40"
16 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
17
18 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
19
20 . $LUSTRE/tests/test-framework.sh
21 init_test_env $@
22 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
23 init_logging
24
25 MULTIOP=${MULTIOP:-multiop}
26 OPENFILE=${OPENFILE:-openfile}
27 MCREATE=${MCREATE:-mcreate}
28 MOUNT_2=${MOUNT_2:-"yes"}
29 FAIL_ON_ERROR=false
30
31 if [[ $MDSCOUNT -ge 2 ]]; then
32         skip_env "Only run with single MDT for now" && exit
33 fi
34
35 check_and_setup_lustre
36
37 if [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.4.53) ]]; then
38         skip_env "Need MDS version at least 2.4.53" && exit
39 fi
40
41 # $RUNAS_ID may get set incorrectly somewhere else
42 if [[ $UID -eq 0 && $RUNAS_ID -eq 0 ]]; then
43         skip_env "\$RUNAS_ID set to 0, but \$UID is also 0!" && exit
44 fi
45 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
46
47 build_test_filter
48
49 #
50 # In order to test multiple remote HSM agents, a new facet type named "AGT" and
51 # the following associated variables are added:
52 #
53 # AGTCOUNT: number of agents
54 # AGTDEV{N}: target HSM mount point (root path of the backend)
55 # agt{N}_HOST: hostname of the agent agt{N}
56 # SINGLEAGT: facet of the single agent
57 #
58 # The number of agents is initialized as the number of remote client nodes.
59 # By default, only single copytool is started on a remote client/agent. If there
60 # was no remote client, then the copytool will be started on the local client.
61 #
62 init_agt_vars() {
63         local n
64         local agent
65
66         export AGTCOUNT=${AGTCOUNT:-$((CLIENTCOUNT - 1))}
67         [[ $AGTCOUNT -gt 0 ]] || AGTCOUNT=1
68
69         export SHARED_DIRECTORY=${SHARED_DIRECTORY:-$TMP}
70         if [[ $CLIENTCOUNT -gt 1 ]] &&
71                 ! check_shared_dir $SHARED_DIRECTORY $CLIENTS; then
72                 skip_env "SHARED_DIRECTORY should be accessible"\
73                          "on all client nodes"
74                 exit 0
75         fi
76
77         for n in $(seq $AGTCOUNT); do
78                 eval export AGTDEV$n=\$\{AGTDEV$n:-"$SHARED_DIRECTORY/arc$n"\}
79                 agent=CLIENT$((n + 1))
80                 if [[ -z "${!agent}" ]]; then
81                         [[ $CLIENTCOUNT -eq 1 ]] && agent=CLIENT1 ||
82                                 agent=CLIENT2
83                 fi
84                 eval export agt${n}_HOST=\$\{agt${n}_HOST:-${!agent}\}
85         done
86
87         export SINGLEAGT=${SINGLEAGT:-agt1}
88
89         export HSMTOOL=${HSMTOOL:-"lhsmtool_posix"}
90         export HSMTOOL_VERBOSE=${HSMTOOL_VERBOSE:-""}
91         export HSMTOOL_BASE=$(basename "$HSMTOOL" | cut -f1 -d" ")
92         HSM_ARCHIVE=$(copytool_device $SINGLEAGT)
93         HSM_ARCHIVE_NUMBER=2
94
95         MDT_PARAM="mdt.$FSNAME-MDT0000"
96         HSM_PARAM="$MDT_PARAM.hsm"
97
98         # archive is purged at copytool setup
99         HSM_ARCHIVE_PURGE=true
100 }
101
102 # Get the backend root path for the given agent facet.
103 copytool_device() {
104         local facet=$1
105         local dev=AGTDEV$(facet_number $facet)
106
107         echo -n ${!dev}
108 }
109
110 # Stop copytool and unregister an existing changelog user.
111 cleanup() {
112         copytool_cleanup
113         changelog_cleanup
114         cdt_set_sanity_policy
115 }
116
117 search_and_kill_copytool() {
118         local agents=${1:-$(facet_active_host $SINGLEAGT)}
119
120         echo "Killing existing copytools on $agents"
121         do_nodesv $agents "killall -q $HSMTOOL_BASE" || true
122 }
123
124 copytool_setup() {
125         local facet=${1:-$SINGLEAGT}
126         local lustre_mntpnt=${2:-$MOUNT}
127         local arc_id=$3
128         local hsm_root=$(copytool_device $facet)
129         local agent=$(facet_active_host $facet)
130
131         if [[ -z "$arc_id" ]] &&
132                 do_facet $facet "pkill -CONT -x $HSMTOOL_BASE"; then
133                         echo "Wakeup copytool $facet on $agent"
134                         return 0
135         fi
136
137         if $HSM_ARCHIVE_PURGE; then
138                 echo "Purging archive on $agent"
139                 do_facet $facet "rm -rf $hsm_root/*"
140         fi
141
142         echo "Starting copytool $facet on $agent"
143         do_facet $facet "mkdir -p $hsm_root" || error "mkdir '$hsm_root' failed"
144         # bandwidth is limited to 1MB/s so the copy time is known and
145         # independent of hardware
146         local cmd="$HSMTOOL $HSMTOOL_VERBOSE --daemon --hsm-root $hsm_root"
147         [[ -z "$arc_id" ]] || cmd+=" --archive $arc_id"
148         cmd+=" --bandwidth 1 $lustre_mntpnt"
149
150         # Redirect the standard output and error to a log file which
151         # can be uploaded to Maloo.
152         local prefix=$TESTLOG_PREFIX
153         [[ -z "$TESTNAME" ]] || prefix=$prefix.$TESTNAME
154         local copytool_log=$prefix.copytool${arc_id}_log.$agent.log
155
156         do_facet $facet "$cmd < /dev/null > $copytool_log 2>&1" ||
157                 error "start copytool $facet on $agent failed"
158         trap cleanup EXIT
159 }
160
161 copytool_cleanup() {
162         trap - EXIT
163         local agents=${1:-$(facet_active_host $SINGLEAGT)}
164
165         do_nodesv $agents "pkill -INT -x $HSMTOOL_BASE" || return 0
166         sleep 1
167         echo "Copytool is stopped on $agents"
168 }
169
170 copytool_suspend() {
171         local agents=${1:-$(facet_active_host $SINGLEAGT)}
172
173         do_nodesv $agents "pkill -STOP -x $HSMTOOL_BASE" || return 0
174         echo "Copytool is suspended on $agents"
175 }
176
177 copytool_remove_backend() {
178         local fid=$1
179         local be=$(find $HSM_ARCHIVE -name $fid)
180         echo "Remove from backend: $fid = $be"
181         do_facet $SINGLEAGT rm -f $be
182 }
183
184 import_file() {
185         do_facet $SINGLEAGT \
186                 "$HSMTOOL --archive $HSM_ARCHIVE_NUMBER --hsm-root $HSM_ARCHIVE\
187                 --import $1 $2 $MOUNT" ||
188                 error "import of $1 to $2 failed"
189 }
190
191 make_archive() {
192         local file=$HSM_ARCHIVE/$1
193         do_facet $SINGLEAGT mkdir -p $(dirname $file)
194         do_facet $SINGLEAGT dd if=/dev/urandom of=$file count=32 bs=1000000 ||
195                 error "cannot create $file"
196 }
197
198 copy2archive() {
199         local file=$HSM_ARCHIVE/$2
200         do_facet $SINGLEAGT mkdir -p $(dirname $file)
201         do_facet $SINGLEAGT cp -p $1 $file || error "cannot copy $1 to $file"
202 }
203
204 changelog_setup() {
205         CL_USER=$(do_facet $SINGLEMDS $LCTL --device $MDT0\
206                   changelog_register -n)
207         do_facet $SINGLEMDS lctl set_param mdd.$MDT0.changelog_mask="+hsm"
208         $LFS changelog_clear $MDT0 $CL_USER 0
209 }
210
211 changelog_cleanup() {
212 #       $LFS changelog $MDT0
213         [[ -n "$CL_USER" ]] || return 0
214
215         $LFS changelog_clear $MDT0 $CL_USER 0
216         do_facet $SINGLEMDS lctl --device $MDT0 changelog_deregister $CL_USER
217         CL_USER=
218 }
219
220 changelog_get_flags() {
221         local mdt=$1
222         local cltype=$2
223         local fid=$3
224
225         $LFS changelog $mdt | awk "/$cltype/ && /t=\[$fid\]/ {print \$5}"
226 }
227
228 get_hsm_param() {
229         local param=$1
230         local val=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.$param)
231         echo $val
232 }
233
234 set_hsm_param() {
235         local param=$1
236         local value=$2
237         local opt=$3
238         if [[ "$value" != "" ]]; then
239                 value="=$value"
240         fi
241         do_facet $SINGLEMDS $LCTL set_param $opt -n $HSM_PARAM.$param$value
242         return $?
243 }
244
245 set_test_state() {
246         local cmd=$1
247         local target=$2
248         do_facet $SINGLEMDS $LCTL set_param $MDT_PARAM.hsm_control=$cmd
249         wait_result $SINGLEMDS "$LCTL get_param -n $MDT_PARAM.hsm_control"\
250                 $target 10 || error "cdt state is not $target"
251 }
252
253 cdt_set_sanity_policy() {
254         if [[ "$CDT_POLICY_HAD_CHANGED" ]]
255         then
256                 # clear all
257                 do_facet $SINGLEMDS $LCTL set_param $HSM_PARAM.policy=+NRA
258                 do_facet $SINGLEMDS $LCTL set_param $HSM_PARAM.policy=-NBR
259                 CDT_POLICY_HAD_CHANGED=
260         fi
261 }
262
263 cdt_set_no_retry() {
264         do_facet $SINGLEMDS $LCTL set_param $HSM_PARAM.policy=+NRA
265         CDT_POLICY_HAD_CHANGED=true
266 }
267
268 cdt_clear_no_retry() {
269         do_facet $SINGLEMDS $LCTL set_param $HSM_PARAM.policy=-NRA
270         CDT_POLICY_HAD_CHANGED=true
271 }
272
273 cdt_set_non_blocking_restore() {
274         do_facet $SINGLEMDS $LCTL set_param $HSM_PARAM.policy=+NBR
275         CDT_POLICY_HAD_CHANGED=true
276 }
277
278 cdt_clear_non_blocking_restore() {
279         do_facet $SINGLEMDS $LCTL set_param $HSM_PARAM.policy=-NBR
280         CDT_POLICY_HAD_CHANGED=true
281 }
282
283 cdt_clear_mount_state() {
284         do_facet $SINGLEMDS $LCTL set_param -d -P $MDT_PARAM.hsm_control
285 }
286
287 cdt_set_mount_state() {
288         do_facet $SINGLEMDS $LCTL set_param -P $MDT_PARAM.hsm_control=$1
289 }
290
291 cdt_check_state() {
292         local target=$1
293         wait_result $SINGLEMDS\
294                 "$LCTL get_param -n $MDT_PARAM.hsm_control" "$target" 20 ||
295                         error "cdt state is not $target"
296 }
297
298 cdt_disable() {
299         set_test_state disabled disabled
300 }
301
302 cdt_enable() {
303         set_test_state enabled enabled
304 }
305
306 cdt_shutdown() {
307         set_test_state shutdown stopped
308 }
309
310 cdt_purge() {
311         set_test_state purge enabled
312 }
313
314 cdt_restart() {
315         cdt_shutdown
316         cdt_enable
317         cdt_set_sanity_policy
318 }
319
320 needclients() {
321         local client_count=$1
322         if [[ $CLIENTCOUNT -lt $client_count ]]; then
323                 skip "Need $client_count or more clients, have $CLIENTCOUNT"
324                 return 1
325         fi
326         return 0
327 }
328
329 path2fid() {
330         $LFS path2fid $1 | tr -d '[]'
331 }
332
333 get_hsm_flags() {
334         local f=$1
335         local u=$2
336
337         if [[ $u == "user" ]]; then
338                 local st=$($RUNAS $LFS hsm_state $f)
339         else
340                 local st=$($LFS hsm_state $f)
341                 u=root
342         fi
343
344         [[ $? == 0 ]] || error "$LFS hsm_state $f failed (run as $u)"
345
346         st=$(echo $st | cut -f 2 -d" " | tr -d "()," )
347         echo $st
348 }
349
350 get_hsm_archive_id() {
351         local f=$1
352         local st=$($LFS hsm_state $f)
353         [[ $? == 0 ]] || error "$LFS hsm_state $f failed"
354
355         local ar=$(echo $st | grep "archive_id" | cut -f5 -d" " |
356                    cut -f2 -d:)
357         echo $ar
358 }
359
360 check_hsm_flags() {
361         local f=$1
362         local fl=$2
363
364         local st=$(get_hsm_flags $f)
365         [[ $st == $fl ]] || error "hsm flags on $f are $st != $fl"
366 }
367
368 check_hsm_flags_user() {
369         local f=$1
370         local fl=$2
371
372         local st=$(get_hsm_flags $f user)
373         [[ $st == $fl ]] || error "hsm flags on $f are $st != $fl"
374 }
375
376 copy_file() {
377         local f=
378
379         if [[ -d $2 ]]; then
380                 f=$2/$(basename $1)
381         else
382                 f=$2
383         fi
384
385         if [[ "$3" != 1 ]]; then
386                 f=${f/$DIR/$DIR2}
387         fi
388         rm -f $f
389         cp $1 $f || error "cannot copy $1 to $f"
390         path2fid $f || error "cannot get fid on $f"
391 }
392
393 make_small() {
394         local file2=${1/$DIR/$DIR2}
395         dd if=/dev/urandom of=$file2 count=2 bs=1M conv=fsync ||
396                 error "cannot create $file2"
397         path2fid $1 || error "cannot get fid on $1"
398 }
399
400 cleanup_large_files() {
401         local ratio=$(df $MOUNT |awk '{print $5}' |sed 's/%//g' |grep -v Use)
402         [ $ratio -gt 50 ] && find $MOUNT -size +10M -exec rm -f {} \;
403 }
404
405 make_large_for_striping() {
406         local file2=${1/$DIR/$DIR2}
407         local sz=$($LCTL get_param -n lov.*-clilov-*.stripesize | head -1)
408
409         cleanup_large_files
410
411         dd if=/dev/urandom of=$file2 count=5 bs=$sz conv=fsync ||
412                 error "cannot create $file2"
413         path2fid $1 || error "cannot get fid on $1"
414 }
415
416 make_large_for_progress() {
417         local file2=${1/$DIR/$DIR2}
418
419         cleanup_large_files
420
421         # big file is large enough, so copy time is > 30s
422         # so copytool make 1 progress
423         # size is not a multiple of 1M to avoid stripe
424         # aligment
425         dd if=/dev/urandom of=$file2 count=39 bs=1000000 conv=fsync ||
426                 error "cannot create $file2"
427         path2fid $1 || error "cannot get fid on $1"
428 }
429
430 make_large_for_progress_aligned() {
431         local file2=${1/$DIR/$DIR2}
432
433         cleanup_large_files
434
435         # big file is large enough, so copy time is > 30s
436         # so copytool make 1 progress
437         # size is a multiple of 1M to have stripe
438         # aligment
439         dd if=/dev/urandom of=$file2 count=33 bs=1M conv=fsync ||
440                 error "cannot create $file2"
441         path2fid $1 || error "cannot get fid on $1"
442 }
443
444 make_large_for_cancel() {
445         local file2=${1/$DIR/$DIR2}
446
447         cleanup_large_files
448
449         # Copy timeout is 100s. 105MB => 105s
450         dd if=/dev/urandom of=$file2 count=103 bs=1M conv=fsync ||
451                 error "cannot create $file2"
452         path2fid $1 || error "cannot get fid on $1"
453 }
454
455 wait_result() {
456         local facet=$1
457         shift
458         wait_update --verbose $(facet_active_host $facet) "$@"
459 }
460
461 wait_request_state() {
462         local fid=$1
463         local request=$2
464         local state=$3
465
466         local cmd="$LCTL get_param -n $HSM_PARAM.actions"
467         cmd+=" | awk '/'$fid'.*action='$request'/ {print \\\$13}' | cut -f2 -d="
468
469         wait_result $SINGLEMDS "$cmd" $state 100 ||
470                 error "request on $fid is not $state"
471 }
472
473 get_request_state() {
474         local fid=$1
475         local request=$2
476
477         do_facet $SINGLEMDS "$LCTL get_param -n $HSM_PARAM.actions |"\
478                 "awk '/'$fid'.*action='$request'/ {print \\\$13}' | cut -f2 -d="
479 }
480
481 get_request_count() {
482         local fid=$1
483         local request=$2
484
485         do_facet $SINGLEMDS "$LCTL get_param -n $HSM_PARAM.actions |"\
486                 "awk -vn=0 '/'$fid'.*action='$request'/ {n++}; END {print n}'"
487 }
488
489 wait_all_done() {
490         local timeout=$1
491
492         local cmd="$LCTL get_param -n $HSM_PARAM.actions"
493         cmd+=" | egrep 'WAITING|STARTED'"
494
495         wait_result $SINGLEMDS "$cmd" "" $timeout ||
496                 error "requests did not complete"
497 }
498
499 wait_for_grace_delay() {
500         local val=$(get_hsm_param grace_delay)
501         sleep $val
502 }
503
504 MDT0=$($LCTL get_param -n mdc.*.mds_server_uuid |
505         awk '{gsub(/_UUID/,""); print $1}' | head -1)
506
507 # initiate variables
508 init_agt_vars
509
510 # cleanup from previous bad setup
511 search_and_kill_copytool
512
513 # for recovery tests, coordinator needs to be started at mount
514 # so force it
515 # the lustre conf must be without hsm on (like for sanity.sh)
516 echo "Set HSM on and start"
517 cdt_set_mount_state enabled
518 cdt_check_state enabled
519
520 echo "Start copytool"
521 copytool_setup
522
523 echo "Set sanity-hsm HSM policy"
524 cdt_set_sanity_policy
525
526 # finished requests are quickly removed from list
527 set_hsm_param grace_delay 10
528
529 test_1() {
530         mkdir -p $DIR/$tdir
531         chmod 777 $DIR/$tdir
532
533         local f=$DIR/$tdir/$tfile
534         $RUNAS touch $f
535
536         # User flags
537         check_hsm_flags_user $f "0x00000000"
538
539         $RUNAS $LFS hsm_set --norelease $f ||
540                 error "user could not change hsm flags"
541         check_hsm_flags_user $f "0x00000010"
542
543         $RUNAS $LFS hsm_clear --norelease $f ||
544                 error "user could not clear hsm flags"
545         check_hsm_flags_user $f "0x00000000"
546
547         # User could not change those flags...
548         $RUNAS $LFS hsm_set --exists $f &&
549                 error "user should not set this flag"
550         check_hsm_flags_user $f "0x00000000"
551
552         # ...but root can
553         $LFS hsm_set --exists $f ||
554                 error "root could not change hsm flags"
555         check_hsm_flags_user $f "0x00000001"
556
557         $LFS hsm_clear --exists $f ||
558                 error "root could not clear hsm state"
559         check_hsm_flags_user $f "0x00000000"
560
561 }
562 run_test 1 "lfs hsm flags root/non-root access"
563
564 test_2() {
565         mkdir -p $DIR/$tdir
566         local f=$DIR/$tdir/$tfile
567         touch $f
568         # New files are not dirty
569         check_hsm_flags $f "0x00000000"
570
571         # For test, we simulate an archived file.
572         $LFS hsm_set --exists $f || error "user could not change hsm flags"
573         check_hsm_flags $f "0x00000001"
574
575         # chmod do not put the file dirty
576         chmod 600 $f || error "could not chmod test file"
577         check_hsm_flags $f "0x00000001"
578
579         # chown do not put the file dirty
580         chown $RUNAS_ID $f || error "could not chown test file"
581         check_hsm_flags $f "0x00000001"
582
583         # truncate put the file dirty
584         $TRUNCATE $f 1 || error "could not truncate test file"
585         check_hsm_flags $f "0x00000003"
586
587         $LFS hsm_clear --dirty $f || error "could not clear hsm flags"
588         check_hsm_flags $f "0x00000001"
589 }
590 run_test 2 "Check file dirtyness when doing setattr"
591
592 test_3() {
593         mkdir -p $DIR/$tdir
594         f=$DIR/$tdir/$tfile
595
596         # New files are not dirty
597         cp -p /etc/passwd $f
598         check_hsm_flags $f "0x00000000"
599
600         # For test, we simulate an archived file.
601         $LFS hsm_set --exists $f ||
602                 error "user could not change hsm flags"
603         check_hsm_flags $f "0x00000001"
604
605         # Reading a file, does not set dirty
606         cat $f > /dev/null || error "could not read file"
607         check_hsm_flags $f "0x00000001"
608
609         # Open for write without modifying data, does not set dirty
610         openfile -f O_WRONLY $f || error "could not open test file"
611         check_hsm_flags $f "0x00000001"
612
613         # Append to a file sets it dirty
614         cp -p /etc/passwd $f.append || error "could not create file"
615         $LFS hsm_set --exists $f.append ||
616                 error "user could not change hsm flags"
617         dd if=/etc/passwd of=$f.append bs=1 count=3\
618            conv=notrunc oflag=append status=noxfer ||
619                 error "could not append to test file"
620         check_hsm_flags $f.append "0x00000003"
621
622         # Modify a file sets it dirty
623         cp -p /etc/passwd $f.modify || error "could not create file"
624         $LFS hsm_set --exists $f.modify ||
625                 error "user could not change hsm flags"
626         dd if=/dev/zero of=$f.modify bs=1 count=3\
627            conv=notrunc status=noxfer ||
628                 error "could not modify test file"
629         check_hsm_flags $f.modify "0x00000003"
630
631         # Open O_TRUNC sets dirty
632         cp -p /etc/passwd $f.trunc || error "could not create file"
633         $LFS hsm_set --exists $f.trunc ||
634                 error "user could not change hsm flags"
635         cp /etc/group $f.trunc || error "could not override a file"
636         check_hsm_flags $f.trunc "0x00000003"
637
638         # Mmapped a file sets dirty
639         cp -p /etc/passwd $f.mmap || error "could not create file"
640         $LFS hsm_set --exists $f.mmap ||
641                 error "user could not change hsm flags"
642         multiop $f.mmap OSMWUc || error "could not mmap a file"
643         check_hsm_flags $f.mmap "0x00000003"
644 }
645 run_test 3 "Check file dirtyness when opening for write"
646
647 test_4() {
648         mkdir -p $DIR/$tdir
649         local f=$DIR/$tdir/$tfile
650         local fid=$(make_small $f)
651
652         $LFS hsm_cancel $f
653         local st=$(get_request_state $fid CANCEL)
654         [[ -z "$st" ]] || error "hsm_cancel must not be registered (state=$st)"
655 }
656 run_test 4 "Useless cancel must not be registered"
657
658 test_8() {
659         # test needs a running copytool
660         copytool_setup
661
662         mkdir -p $DIR/$tdir
663         local f=$DIR/$tdir/$tfile
664         local fid=$(copy_file /etc/passwd $f)
665         $LFS hsm_archive $f
666         wait_request_state $fid ARCHIVE SUCCEED
667
668         check_hsm_flags $f "0x00000009"
669
670         copytool_cleanup
671 }
672 run_test 8 "Test default archive number"
673
674 test_9() {
675         mkdir -p $DIR/$tdir
676         local f=$DIR/$tdir/$tfile
677         local fid=$(copy_file /etc/passwd $f)
678         # we do not use the default one to be sure
679         local new_an=$((HSM_ARCHIVE_NUMBER + 1))
680         copytool_cleanup
681         copytool_setup $SINGLEAGT $MOUNT $new_an
682         $LFS hsm_archive --archive $new_an $f
683         wait_request_state $fid ARCHIVE SUCCEED
684
685         check_hsm_flags $f "0x00000009"
686
687         copytool_cleanup
688 }
689 run_test 9 "Use of explict archive number, with dedicated copytool"
690
691 test_9a() {
692         needclients 3 || return 0
693
694         local n
695         local file
696         local fid
697
698         copytool_cleanup $(comma_list $(agts_nodes))
699
700         # start all of the copytools
701         for n in $(seq $AGTCOUNT); do
702                 copytool_setup agt$n
703         done
704
705         trap "copytool_cleanup $(comma_list $(agts_nodes))" EXIT
706         # archive files
707         mkdir -p $DIR/$tdir
708         for n in $(seq $AGTCOUNT); do
709                 file=$DIR/$tdir/$tfile.$n
710                 fid=$(make_small $file)
711
712                 $LFS hsm_archive $file || error "could not archive file $file"
713                 wait_request_state $fid ARCHIVE SUCCEED
714                 check_hsm_flags $file "0x00000009"
715         done
716
717         trap - EXIT
718         copytool_cleanup $(comma_list $(agts_nodes))
719 }
720 run_test 9a "Multiple remote agents"
721
722 test_10a() {
723         # test needs a running copytool
724         copytool_setup
725
726         mkdir -p $DIR/$tdir/d1
727         local f=$DIR/$tdir/$tfile
728         local fid=$(copy_file /etc/hosts $f)
729         $LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $f ||
730                 error "hsm_archive failed"
731         wait_request_state $fid ARCHIVE SUCCEED
732
733         local AFILE=$(do_facet $SINGLEAGT ls $HSM_ARCHIVE'/*/*/*/*/*/*/'$fid) ||
734                 error "fid $fid not in archive $HSM_ARCHIVE"
735         echo "Verifying content"
736         do_facet $SINGLEAGT diff $f $AFILE || error "archived file differs"
737         echo "Verifying hsm state "
738         check_hsm_flags $f "0x00000009"
739
740         echo "Verifying archive number is $HSM_ARCHIVE_NUMBER"
741         local st=$(get_hsm_archive_id $f)
742         [[ $st == $HSM_ARCHIVE_NUMBER ]] ||
743                 error "Wrong archive number, $st != $HSM_ARCHIVE_NUMBER"
744
745         copytool_cleanup
746
747 }
748 run_test 10a "Archive a file"
749
750 test_10b() {
751         # test needs a running copytool
752         copytool_setup
753
754         mkdir -p $DIR/$tdir
755         local f=$DIR/$tdir/$tfile
756         local fid=$(copy_file /etc/hosts $f)
757         $LFS hsm_archive $f || error "archive request failed"
758         wait_request_state $fid ARCHIVE SUCCEED
759
760         $LFS hsm_archive $f || error "archive of non dirty file failed"
761         local cnt=$(get_request_count $fid ARCHIVE)
762         [[ "$cnt" == "1" ]] ||
763                 error "archive of non dirty file must not make a request"
764
765         copytool_cleanup
766 }
767 run_test 10b "Archive of non dirty file must work without doing request"
768
769 test_10c() {
770         # test needs a running copytool
771         copytool_setup
772
773         mkdir -p $DIR/$tdir
774         local f=$DIR/$tdir/$tfile
775         local fid=$(copy_file /etc/hosts $f)
776         $LFS hsm_set --noarchive $f
777         $LFS hsm_archive $f && error "archive a noarchive file must fail"
778
779         copytool_cleanup
780 }
781 run_test 10c "Check forbidden archive"
782
783 test_10d() {
784         # test needs a running copytool
785         copytool_setup
786
787         mkdir -p $DIR/$tdir
788         local f=$DIR/$tdir/$tfile
789         local fid=$(copy_file /etc/hosts $f)
790         $LFS hsm_archive $f || error "cannot archive $f"
791         wait_request_state $fid ARCHIVE SUCCEED
792
793         local ar=$(get_hsm_archive_id $f)
794         local dflt=$(get_hsm_param default_archive_id)
795         [[ $ar == $dflt ]] ||
796                 error "archived file is not on default archive: $ar != $dflt"
797
798         copytool_cleanup
799 }
800 run_test 10d "Archive a file on the default archive id"
801
802 test_11() {
803         mkdir -p $DIR/$tdir
804         copy2archive /etc/hosts $tdir/$tfile
805         local f=$DIR/$tdir/$tfile
806
807         import_file $tdir/$tfile $f
808         echo -n "Verifying released state: "
809         check_hsm_flags $f "0x0000000d"
810
811         local LSZ=$(stat -c "%s" $f)
812         local ASZ=$(do_facet $SINGLEAGT stat -c "%s" $HSM_ARCHIVE/$tdir/$tfile)
813
814         echo "Verifying imported size $LSZ=$ASZ"
815         [[ $LSZ -eq $ASZ ]] || error "Incorrect size $LSZ != $ASZ"
816         echo -n "Verifying released pattern: "
817         local PTRN=$($GETSTRIPE -L $f)
818         echo $PTRN
819         [[ $PTRN == 80000001 ]] || error "Is not released"
820         local fid=$(path2fid $f)
821         echo "Verifying new fid $fid in archive"
822
823         local AFILE=$(do_facet $SINGLEAGT ls $HSM_ARCHIVE'/*/*/*/*/*/*/'$fid) ||
824                 error "fid $fid not in archive $HSM_ARCHIVE"
825 }
826 run_test 11 "Import a file"
827
828 test_12a() {
829         # test needs a running copytool
830         copytool_setup
831
832         mkdir -p $DIR/$tdir
833         copy2archive /etc/hosts $tdir/$tfile
834
835         local f=$DIR/$tdir/$tfile
836         import_file $tdir/$tfile $f
837         local f=$DIR2/$tdir/$tfile
838         echo "Verifying released state: "
839         check_hsm_flags $f "0x0000000d"
840
841         local fid=$(path2fid $f)
842         $LFS hsm_restore $f
843         wait_request_state $fid RESTORE SUCCEED
844
845         echo "Verifying file state: "
846         check_hsm_flags $f "0x00000009"
847
848         do_facet $SINGLEAGT diff -q $HSM_ARCHIVE/$tdir/$tfile $f
849
850         [[ $? -eq 0 ]] || error "Restored file differs"
851
852         copytool_cleanup
853 }
854 run_test 12a "Restore an imported file explicitly"
855
856 test_12b() {
857         # test needs a running copytool
858         copytool_setup
859
860         mkdir -p $DIR/$tdir
861         copy2archive /etc/hosts $tdir/$tfile
862
863         local f=$DIR/$tdir/$tfile
864         import_file $tdir/$tfile $f
865         echo "Verifying released state: "
866         check_hsm_flags $f "0x0000000d"
867
868         cat $f > /dev/null || error "File read failed"
869
870         echo "Verifying file state after restore: "
871         check_hsm_flags $f "0x00000009"
872
873         do_facet $SINGLEAGT diff -q $HSM_ARCHIVE/$tdir/$tfile $f
874
875         [[ $? -eq 0 ]] || error "Restored file differs"
876
877         copytool_cleanup
878 }
879 run_test 12b "Restore an imported file implicitly"
880
881 test_12c() {
882         [ "$OSTCOUNT" -lt "2" ] && skip_env "skipping 2-stripe test" && return
883
884         # test needs a running copytool
885         copytool_setup
886
887         mkdir -p $DIR/$tdir
888         local f=$DIR/$tdir/$tfile
889         $LFS setstripe -c 2 $f
890         local fid=$(make_large_for_striping $f)
891         local FILE_CRC=$(md5sum $f)
892
893         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
894         wait_request_state $fid ARCHIVE SUCCEED
895         $LFS hsm_release $f || error "release $f failed"
896
897         echo "$FILE_CRC" | md5sum -c
898
899         [[ $? -eq 0 ]] || error "Restored file differs"
900
901         copytool_cleanup
902 }
903 run_test 12c "Restore a file with stripe of 2"
904
905 test_12d() {
906         # test needs a running copytool
907         copytool_setup
908
909         mkdir -p $DIR/$tdir
910
911         local f=$DIR/$tdir/$tfile
912         local fid=$(copy_file /etc/hosts $f)
913         $LFS hsm_restore $f || error "restore of non archived file failed"
914         local cnt=$(get_request_count $fid RESTORE)
915         [[ "$cnt" == "0" ]] ||
916                 error "restore non archived must not make a request"
917         $LFS hsm_archive $f ||
918                 error "archive request failed"
919         wait_request_state $fid ARCHIVE SUCCEED
920         $LFS hsm_restore $f ||
921                 error "restore of non released file failed"
922         local cnt=$(get_request_count $fid RESTORE)
923         [[ "$cnt" == "0" ]] ||
924                 error "restore a non dirty file must not make a request"
925
926         copytool_cleanup
927 }
928 run_test 12d "Restore of a non archived, non released file must work"\
929                 " without doing request"
930
931 test_12e() {
932         # test needs a running copytool
933         copytool_setup
934
935         mkdir -p $DIR/$tdir $HSM_ARCHIVE/$tdir
936         local f=$DIR/$tdir/$tfile
937         local fid=$(copy_file /etc/hosts $f)
938         $LFS hsm_archive $f || error "archive request failed"
939         wait_request_state $fid ARCHIVE SUCCEED
940
941         # make file dirty
942         cat /etc/hosts >> $f
943         sync
944         $LFS hsm_state $f
945
946         $LFS hsm_restore $f && error "restore a dirty file must fail"
947
948         copytool_cleanup
949 }
950 run_test 12e "Check forbidden restore"
951
952 test_12f() {
953         # test needs a running copytool
954         copytool_setup
955
956         mkdir -p $DIR/$tdir
957         local f=$DIR/$tdir/$tfile
958         local fid=$(copy_file /etc/hosts $f)
959
960         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
961         wait_request_state $fid ARCHIVE SUCCEED
962         $LFS hsm_release $f || error "release of $f failed"
963         $LFS hsm_restore $f
964         wait_request_state $fid RESTORE SUCCEED
965
966         echo -n "Verifying file state: "
967         check_hsm_flags $f "0x00000009"
968
969         diff -q /etc/hosts $f
970
971         [[ $? -eq 0 ]] || error "Restored file differs"
972
973         copytool_cleanup
974 }
975 run_test 12f "Restore a released file explicitly"
976
977 test_12g() {
978         # test needs a running copytool
979         copytool_setup
980
981         mkdir -p $DIR/$tdir
982         local f=$DIR/$tdir/$tfile
983         local fid=$(copy_file /etc/hosts $f)
984
985         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
986         wait_request_state $fid ARCHIVE SUCCEED
987         $LFS hsm_release $f || error "release of $f failed"
988
989         diff -q /etc/hosts $f
990         local st=$?
991
992         # we check we had a restore done
993         wait_request_state $fid RESTORE SUCCEED
994
995         [[ $st -eq 0 ]] || error "Restored file differs"
996
997         copytool_cleanup
998 }
999 run_test 12g "Restore a released file implicitly"
1000
1001 test_12h() {
1002         needclients 2 || return 0
1003
1004         # test needs a running copytool
1005         copytool_setup
1006
1007         mkdir -p $DIR/$tdir
1008         local f=$DIR/$tdir/$tfile
1009         local fid=$(copy_file /etc/hosts $f)
1010
1011         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1012         wait_request_state $fid ARCHIVE SUCCEED
1013         $LFS hsm_release $f || error "release of $f failed"
1014
1015         do_node $CLIENT2 diff -q /etc/hosts $f
1016         local st=$?
1017
1018         # we check we had a restore done
1019         wait_request_state $fid RESTORE SUCCEED
1020
1021         [[ $st -eq 0 ]] || error "Restored file differs"
1022
1023         copytool_cleanup
1024 }
1025 run_test 12h "Restore a released file implicitly from a second node"
1026
1027 test_12m() {
1028         # test needs a running copytool
1029         copytool_setup
1030
1031         mkdir -p $DIR/$tdir
1032         local f=$DIR/$tdir/$tfile
1033         local fid=$(copy_file /etc/passwd $f)
1034         $LFS hsm_archive $f || error "archive of $f failed"
1035         wait_request_state $fid ARCHIVE SUCCEED
1036
1037         $LFS hsm_release $f || error "release of $f failed"
1038
1039         cmp /etc/passwd $f
1040
1041         [[ $? -eq 0 ]] || error "Restored file differs"
1042
1043         copytool_cleanup
1044 }
1045 run_test 12m "Archive/release/implicit restore"
1046
1047 test_12n() {
1048         # test needs a running copytool
1049         copytool_setup
1050
1051         mkdir -p $DIR/$tdir
1052         copy2archive /etc/hosts $tdir/$tfile
1053
1054         local f=$DIR/$tdir/$tfile
1055         import_file $tdir/$tfile $f
1056
1057         do_facet $SINGLEAGT cmp /etc/hosts $f ||
1058                 error "Restored file differs"
1059
1060         $LFS hsm_release $f || error "release of $f failed"
1061
1062         copytool_cleanup
1063 }
1064 run_test 12n "Import/implicit restore/release"
1065
1066 test_13() {
1067         # test needs a running copytool
1068         copytool_setup
1069
1070         local ARC_SUBDIR="import.orig"
1071         local d=""
1072         local f=""
1073
1074         # populate directory to be imported
1075         for d in $(seq 1 10); do
1076                 local CURR_DIR="$HSM_ARCHIVE/$ARC_SUBDIR/dir.$d"
1077                 do_facet $SINGLEAGT mkdir -p "$CURR_DIR"
1078                 for f in $(seq 1 10); do
1079                         CURR_FILE="$CURR_DIR/$tfile.$f"
1080                         # write file-specific data
1081                         do_facet $SINGLEAGT \
1082                                 echo "d=$d, f=$f, dir=$CURR_DIR, "\
1083                                      "file=$CURR_FILE" > $CURR_FILE
1084                 done
1085         done
1086         # import to Lustre
1087         import_file "$ARC_SUBDIR" $DIR/$tdir
1088         # diff lustre content and origin (triggers file restoration)
1089         # there must be 10x10 identical files, and no difference
1090         local cnt_ok=$(do_facet $SINGLEAGT diff -rs $HSM_ARCHIVE/$ARC_SUBDIR \
1091                        $DIR/$tdir/$ARC_SUBDIR | grep identical | wc -l)
1092         local cnt_diff=$(do_facet $SINGLEAGT diff -r $HSM_ARCHIVE/$ARC_SUBDIR \
1093                          $DIR/$tdir/$ARC_SUBDIR | wc -l)
1094
1095         [ $cnt_diff -eq 0 ] ||
1096                 error "$cnt_diff imported files differ from read data"
1097         [ $cnt_ok -eq 100 ] ||
1098                 error "not enough identical files ($cnt_ok != 100)"
1099
1100         copytool_cleanup
1101 }
1102 run_test 13 "Recursively import and restore a directory"
1103
1104 test_14() {
1105         # test needs a running copytool
1106         copytool_setup
1107
1108         # archive a file
1109         mkdir -p $DIR/$tdir
1110         local f=$DIR/$tdir/$tfile
1111         local fid=$(make_small $f)
1112         local sum=$(md5sum $f | awk '{print $1}')
1113         $LFS hsm_archive $f || error "could not archive file"
1114         wait_request_state $fid ARCHIVE SUCCEED
1115
1116         # delete the file
1117         rm -f $f
1118         # create released file (simulate llapi_hsm_import call)
1119         touch $f
1120         local fid2=$(path2fid $f)
1121         $LFS hsm_set --archived --exists $f || error "could not force hsm flags"
1122         $LFS hsm_release $f || error "could not release file"
1123
1124         # rebind the archive to the newly created file
1125         echo "rebind $fid to $fid2"
1126
1127         do_facet $SINGLEAGT \
1128                 "$HSMTOOL --archive $HSM_ARCHIVE_NUMBER --hsm-root $HSM_ARCHIVE\
1129                  --rebind $fid $fid2 $DIR" || error "could not rebind file"
1130
1131         # restore file and compare md5sum
1132         local sum2=$(md5sum $f | awk '{print $1}')
1133
1134         [[ $sum == $sum2 ]] || error "md5sum mismatch after restore"
1135
1136         copytool_cleanup
1137 }
1138 run_test 14 "Rebind archived file to a new fid"
1139
1140 test_15() {
1141         # test needs a running copytool
1142         copytool_setup
1143
1144         # archive files
1145         mkdir -p $DIR/$tdir
1146         local f=$DIR/$tdir/$tfile
1147         local count=5
1148         local tmpfile=$SHARED_DIRECTORY/tmp.$$
1149
1150         local fids=()
1151         local sums=()
1152         for i in $(seq 1 $count); do
1153                 fids[$i]=$(make_small $f.$i)
1154                 sums[$i]=$(md5sum $f.$i | awk '{print $1}')
1155                 $LFS hsm_archive $f.$i || error "could not archive file"
1156         done
1157         wait_all_done $(($count*60))
1158
1159         :>$tmpfile
1160         # delete the files
1161         for i in $(seq 1 $count); do
1162                 rm -f $f.$i
1163                 touch $f.$i
1164                 local fid2=$(path2fid $f.$i)
1165                 # add the rebind operation to the list
1166                 echo ${fids[$i]} $fid2 >> $tmpfile
1167
1168                 # set it released (simulate llapi_hsm_import call)
1169                 $LFS hsm_set --archived --exists $f.$i ||
1170                         error "could not force hsm flags"
1171                 $LFS hsm_release $f.$i || error "could not release file"
1172         done
1173         nl=$(wc -l < $tmpfile)
1174         [[ $nl == $count ]] || error "$nl files in list, $count expected"
1175
1176         echo "rebind list of files"
1177         do_facet $SINGLEAGT \
1178                 "$HSMTOOL --archive $HSM_ARCHIVE_NUMBER --hsm-root $HSM_ARCHIVE\
1179                  --rebind $tmpfile $DIR" || error "could not rebind file list"
1180
1181         # restore files and compare md5sum
1182         for i in $(seq 1 $count); do
1183                 local sum2=$(md5sum $f.$i | awk '{print $1}')
1184                 [[ $sum2 == ${sums[$i]} ]] ||
1185                     error "md5sum mismatch after restore ($sum2 != ${sums[$i]})"
1186         done
1187
1188         rm -f $tmpfile
1189         copytool_cleanup
1190 }
1191 run_test 15 "Rebind a list of files"
1192
1193 test_16() {
1194         # test needs a running copytool
1195         copytool_setup
1196
1197         local ref=/tmp/ref
1198         # create a known size file so we can verify transfer speed
1199         # 20 MB <-> 20s
1200         local goal=20
1201         dd if=/dev/zero of=$ref bs=1M count=20
1202
1203         mkdir -p $DIR/$tdir
1204         local f=$DIR/$tdir/$tfile
1205         local fid=$(copy_file $ref $f)
1206         rm $ref
1207         local start=$(date +%s)
1208         $LFS hsm_archive $f
1209         wait_request_state $fid ARCHIVE SUCCEED
1210         local end=$(date +%s)
1211         local duration=$((end - start))
1212
1213         [[ $duration -ge $goal ]] ||
1214                 error "Transfer is too fast $duration < $goal"
1215
1216         copytool_cleanup
1217 }
1218 run_test 16 "Test CT bandwith control option"
1219
1220 test_20() {
1221         mkdir -p $DIR/$tdir
1222
1223         local f=$DIR/$tdir/$tfile
1224         touch $f || error "touch $f failed"
1225
1226         # Could not release a non-archived file
1227         $LFS hsm_release $f && error "release should not succeed"
1228
1229         # For following tests, we must test them with HS_ARCHIVED set
1230         $LFS hsm_set --exists --archived $f || error "could not add flag"
1231
1232         # Could not release a file if no-release is set
1233         $LFS hsm_set --norelease $f || error "could not add flag"
1234         $LFS hsm_release $f && error "release should not succeed"
1235         $LFS hsm_clear --norelease $f || error "could not remove flag"
1236
1237         # Could not release a file if lost
1238         $LFS hsm_set --lost $f || error "could not add flag"
1239         $LFS hsm_release $f && error "release should not succeed"
1240         $LFS hsm_clear --lost $f || error "could not remove flag"
1241
1242         # Could not release a file if dirty
1243         $LFS hsm_set --dirty $f || error "could not add flag"
1244         $LFS hsm_release $f && error "release should not succeed"
1245         $LFS hsm_clear --dirty $f || error "could not remove flag"
1246 }
1247 run_test 20 "Release is not permitted"
1248
1249 test_21() {
1250         # test needs a running copytool
1251         copytool_setup
1252
1253         mkdir -p $DIR/$tdir
1254         local f=$DIR/$tdir/test_release
1255
1256         # Create a file and check its states
1257         local fid=$(make_small $f)
1258         check_hsm_flags $f "0x00000000"
1259
1260         $LFS hsm_archive $f || error "could not archive file"
1261         wait_request_state $fid ARCHIVE SUCCEED
1262
1263         [ $(stat -c "%b" $f) -ne "1" ] || error "wrong block number"
1264         local sz=$(stat -c "%s" $f)
1265         [ $sz -ne "0" ] || error "file size should not be zero"
1266
1267         # Release and check states
1268         $LFS hsm_release $f || error "could not release file"
1269         check_hsm_flags $f "0x0000000d"
1270
1271         [ $(stat -c "%b" $f) -eq "1" ] || error "wrong block number"
1272         [ $(stat -c "%s" $f) -eq $sz ] || error "wrong file size"
1273
1274         # Check we can release an file without stripe info
1275         f=$f.nolov
1276         $MCREATE $f
1277         fid=$(path2fid $f)
1278         check_hsm_flags $f "0x00000000"
1279         $LFS hsm_archive $f || error "could not archive file"
1280         wait_request_state $fid ARCHIVE SUCCEED
1281
1282         # Release and check states
1283         $LFS hsm_release $f || error "could not release file"
1284         check_hsm_flags $f "0x0000000d"
1285
1286         # Release again a file that is already released is OK
1287         $LFS hsm_release $f || fail "second release should succeed"
1288         check_hsm_flags $f "0x0000000d"
1289
1290         copytool_cleanup
1291 }
1292 run_test 21 "Simple release tests"
1293
1294 test_22() {
1295         # test needs a running copytool
1296         copytool_setup
1297
1298         mkdir -p $DIR/$tdir
1299
1300         local f=$DIR/$tdir/test_release
1301         local swap=$DIR/$tdir/test_swap
1302
1303         # Create a file and check its states
1304         local fid=$(make_small $f)
1305         check_hsm_flags $f "0x00000000"
1306
1307         $LFS hsm_archive $f || error "could not archive file"
1308         wait_request_state $fid ARCHIVE SUCCEED
1309
1310         # Release and check states
1311         $LFS hsm_release $f || error "could not release file"
1312         check_hsm_flags $f "0x0000000d"
1313
1314         make_small $swap
1315         $LFS swap_layouts $swap $f && error "swap_layouts should failed"
1316
1317         true
1318         copytool_cleanup
1319 }
1320 run_test 22 "Could not swap a release file"
1321
1322 test_23() {
1323         # test needs a running copytool
1324         copytool_setup
1325
1326         mkdir -p $DIR/$tdir
1327
1328         local f=$DIR/$tdir/test_mtime
1329
1330         # Create a file and check its states
1331         local fid=$(make_small $f)
1332         check_hsm_flags $f "0x00000000"
1333
1334         $LFS hsm_archive $f || error "could not archive file"
1335         wait_request_state $fid ARCHIVE SUCCEED
1336
1337         # Set modification time in the past
1338         touch -m -a -d @978261179 $f
1339
1340         # Release and check states
1341         $LFS hsm_release $f || error "could not release file"
1342         check_hsm_flags $f "0x0000000d"
1343
1344         local MTIME=$(stat -c "%Y" $f)
1345         local ATIME=$(stat -c "%X" $f)
1346         [ $MTIME -eq "978261179" ] || fail "bad mtime: $MTIME"
1347         [ $ATIME -eq "978261179" ] || fail "bad atime: $ATIME"
1348
1349         copytool_cleanup
1350 }
1351 run_test 23 "Release does not change a/mtime (utime)"
1352
1353 test_24a() {
1354         local file=$DIR/$tdir/$tfile
1355         local fid
1356         local atime0
1357         local atime1
1358         local mtime0
1359         local mtime1
1360         local ctime0
1361         local ctime1
1362
1363         # test needs a running copytool
1364         copytool_setup
1365
1366         mkdir -p $DIR/$tdir
1367         rm -f $file
1368         fid=$(make_small $file)
1369
1370         # Create a file and check its states
1371         check_hsm_flags $file "0x00000000"
1372
1373         # Ensure atime is less than mtime and ctime.
1374         sleep 1
1375         echo >> $file
1376
1377         atime0=$(stat -c "%X" $file)
1378         mtime0=$(stat -c "%Y" $file)
1379         ctime0=$(stat -c "%Z" $file)
1380
1381         [ $atime0 -lt $mtime0 ] ||
1382                 error "atime $atime0 is not less than mtime $mtime0"
1383
1384         [ $atime0 -lt $ctime0 ] ||
1385                 error "atime $atime0 is not less than ctime $ctime0"
1386
1387         # Archive should not change any timestamps.
1388         $LFS hsm_archive $file || error "cannot archive '$file'"
1389         wait_request_state $fid ARCHIVE SUCCEED
1390
1391         atime1=$(stat -c "%X" $file)
1392         mtime1=$(stat -c "%Y" $file)
1393         ctime1=$(stat -c "%Z" $file)
1394
1395         [ $atime0 -eq $atime1 ] ||
1396                 error "archive changed atime from $atime0 to $atime1"
1397
1398         [ $mtime0 -eq $mtime1 ] ||
1399                 error "archive changed mtime from $mtime0 to $mtime1"
1400
1401         [ $ctime0 -eq $ctime1 ] ||
1402                 error "archive changed ctime from $ctime0 to $ctime1"
1403
1404         # Release should not change any timestamps.
1405         $LFS hsm_release $file || error "cannot release '$file'"
1406         check_hsm_flags $file "0x0000000d"
1407
1408         atime1=$(stat -c "%X" $file)
1409         mtime1=$(stat -c "%Y" $file)
1410         ctime1=$(stat -c "%Z" $file)
1411
1412         [ $atime0 -eq $atime1 ] ||
1413                 error "release changed atime from $atime0 to $atime1"
1414
1415         [ $mtime0 -eq $mtime1 ] ||
1416                 error "release changed mtime from $mtime0 to $mtime1"
1417
1418         [ $ctime0 -eq $ctime1 ] ||
1419                 error "release changed ctime from $ctime0 to $ctime1"
1420
1421         # Restore should not change atime or mtime and should not
1422         # decrease ctime.
1423         $LFS hsm_restore $file
1424         wait_request_state $fid RESTORE SUCCEED
1425
1426         atime1=$(stat -c "%X" $file)
1427         mtime1=$(stat -c "%Y" $file)
1428         ctime1=$(stat -c "%Z" $file)
1429
1430         [ $atime0 -eq $atime1 ] ||
1431                 error "restore changed atime from $atime0 to $atime1"
1432
1433         [ $mtime0 -eq $mtime1 ] ||
1434                 error "restore changed mtime from $mtime0 to $mtime1"
1435
1436         [ $ctime0 -le $ctime1 ] ||
1437                 error "restore changed ctime from $ctime0 to $ctime1"
1438
1439         copytool_cleanup
1440
1441         # Once more, after unmount and mount.
1442         umount_client $MOUNT || error "cannot unmount '$MOUNT'"
1443         mount_client $MOUNT || error "cannot mount '$MOUNT'"
1444
1445         atime1=$(stat -c "%X" $file)
1446         mtime1=$(stat -c "%Y" $file)
1447         ctime1=$(stat -c "%Z" $file)
1448
1449         [ $atime0 -eq $atime1 ] ||
1450                 error "remount changed atime from $atime0 to $atime1"
1451
1452         [ $mtime0 -eq $mtime1 ] ||
1453                 error "remount changed mtime from $mtime0 to $mtime1"
1454
1455         [ $ctime0 -le $ctime1 ] ||
1456                 error "remount changed ctime from $ctime0 to $ctime1"
1457 }
1458 run_test 24a "Archive, release, and restore does not change a/mtime (i/o)"
1459
1460 test_24b() {
1461         local file=$DIR/$tdir/$tfile
1462         local fid
1463         local sum0
1464         local sum1
1465         # LU-3811
1466
1467         # Test needs a running copytool.
1468         copytool_setup
1469         mkdir -p $DIR/$tdir
1470
1471         # Check that root can do HSM actions on a ordinary user's file.
1472         rm -f $file
1473         fid=$(make_small $file)
1474         sum0=$(md5sum $file)
1475
1476         chown $RUNAS_ID:$RUNAS_GID $file ||
1477                 error "cannot chown '$file' to '$RUNAS_ID'"
1478
1479         chmod ugo-w $DIR/$tdir ||
1480                 error "cannot chmod '$DIR/$tdir'"
1481
1482         $LFS hsm_archive $file
1483         wait_request_state $fid ARCHIVE SUCCEED
1484
1485         $LFS hsm_release $file
1486         check_hsm_flags $file "0x0000000d"
1487
1488         $LFS hsm_restore $file
1489         wait_request_state $fid RESTORE SUCCEED
1490
1491         # Check that ordinary user can get HSM state.
1492         $RUNAS $LFS hsm_state $file ||
1493                 error "user '$RUNAS_ID' cannot get HSM state of '$file'"
1494
1495         $LFS hsm_release $file
1496         check_hsm_flags $file "0x0000000d"
1497
1498         # Check that ordinary user can accessed released file.
1499         sum1=$($RUNAS md5sum $file) ||
1500                 error "user '$RUNAS_ID' cannot read '$file'"
1501
1502         [ "$sum0" == "$sum1" ] ||
1503                 error "md5sum mismatch for '$file'"
1504
1505         copytool_cleanup
1506 }
1507 run_test 24b "root can archive, release, and restore user files"
1508
1509 cleanup_test_24c() {
1510         trap 0
1511         set_hsm_param user_request_mask RESTORE
1512         set_hsm_param group_request_mask RESTORE
1513         set_hsm_param other_request_mask RESTORE
1514 }
1515
1516 test_24c() {
1517         local file=$DIR/$tdir/$tfile
1518         local action=archive
1519         local user_save
1520         local group_save
1521         local other_save
1522
1523         # test needs a running copytool
1524         copytool_setup
1525
1526         mkdir -p $DIR/$tdir
1527
1528         # Save the default masks and check that cleanup_24c will
1529         # restore the request masks correctly.
1530         user_save=$(get_hsm_param user_request_mask)
1531         group_save=$(get_hsm_param group_request_mask)
1532         other_save=$(get_hsm_param other_request_mask)
1533
1534         [ "$user_save" == RESTORE ] ||
1535                 error "user_request_mask is '$user_save' expected 'RESTORE'"
1536         [ "$group_save" == RESTORE ] ||
1537                 error "group_request_mask is '$group_save' expected 'RESTORE'"
1538         [ "$other_save" == RESTORE ] ||
1539                 error "other_request_mask is '$other_save' expected 'RESTORE'"
1540
1541         trap cleanup_test_24c EXIT
1542
1543         # User.
1544         rm -f $file
1545         make_small $file
1546         chown $RUNAS_ID:nobody $file ||
1547                 error "cannot chown '$file' to '$RUNAS_ID:nobody'"
1548
1549         set_hsm_param user_request_mask ""
1550         $RUNAS $LFS hsm_$action $file &&
1551                 error "$action by user should fail"
1552
1553         set_hsm_param user_request_mask $action
1554         $RUNAS $LFS hsm_$action $file ||
1555                 error "$action by user should succeed"
1556
1557         # Group.
1558         rm -f $file
1559         make_small $file
1560         chown nobody:$RUNAS_GID $file ||
1561                 error "cannot chown '$file' to 'nobody:$RUNAS_GID'"
1562
1563         set_hsm_param group_request_mask ""
1564         $RUNAS $LFS hsm_$action $file &&
1565                 error "$action by group should fail"
1566
1567         set_hsm_param group_request_mask $action
1568         $RUNAS $LFS hsm_$action $file ||
1569                 error "$action by group should succeed"
1570
1571         # Other.
1572         rm -f $file
1573         make_small $file
1574         chown nobody:nobody $file ||
1575                 error "cannot chown '$file' to 'nobody:nobody'"
1576
1577         set_hsm_param other_request_mask ""
1578         $RUNAS $LFS hsm_$action $file &&
1579                 error "$action by other should fail"
1580
1581         set_hsm_param other_request_mask $action
1582         $RUNAS $LFS hsm_$action $file ||
1583                 error "$action by other should succeed"
1584
1585         copytool_cleanup
1586         cleanup_test_24c
1587 }
1588 run_test 24c "check that user,group,other request masks work"
1589
1590 cleanup_test_24d() {
1591         trap 0
1592         mount -o remount,rw $MOUNT2
1593 }
1594
1595 test_24d() {
1596         local file1=$DIR/$tdir/$tfile
1597         local file2=$DIR2/$tdir/$tfile
1598         local fid1
1599         local fid2
1600
1601         copytool_setup
1602
1603         mkdir -p $DIR/$tdir
1604         rm -f $file1
1605         fid1=$(make_small $file1)
1606
1607         trap cleanup_test_24d EXIT
1608
1609         mount -o remount,ro $MOUNT2
1610
1611         fid2=$(path2fid $file2)
1612         [ "$fid1" == "$fid2" ] ||
1613                 error "FID mismatch '$fid1' != '$fid2'"
1614
1615         $LFS hsm_archive $file2 &&
1616                 error "archive should fail on read-only mount"
1617         check_hsm_flags $file1 "0x00000000"
1618
1619         $LFS hsm_archive $file1
1620         wait_request_state $fid1 ARCHIVE SUCCEED
1621
1622         $LFS hsm_release $file1
1623         $LFS hsm_restore $file2
1624         wait_request_state $fid1 RESTORE SUCCEED
1625
1626         $LFS hsm_release $file1 || error "cannot release '$file1'"
1627         dd if=$file2 of=/dev/null bs=1M || "cannot read '$file2'"
1628
1629         $LFS hsm_release $file2 &&
1630                 error "release should fail on read-only mount"
1631
1632         copytool_cleanup
1633         cleanup_test_24d
1634 }
1635 run_test 24d "check that read-only mounts are respected"
1636
1637 test_25a() {
1638         # test needs a running copytool
1639         copytool_setup
1640
1641         mkdir -p $DIR/$tdir
1642         copy2archive /etc/hosts $tdir/$tfile
1643
1644         local f=$DIR/$tdir/$tfile
1645
1646         import_file $tdir/$tfile $f
1647
1648         $LFS hsm_set --lost $f
1649
1650         md5sum $f
1651         local st=$?
1652
1653         [[ $st == 1 ]] || error "lost file access should failed (returns $st)"
1654
1655         copytool_cleanup
1656 }
1657 run_test 25a "Restore lost file (HS_LOST flag) from import"\
1658              " (Operation not permitted)"
1659
1660 test_25b() {
1661         # test needs a running copytool
1662         copytool_setup
1663
1664         mkdir -p $DIR/$tdir
1665
1666         local f=$DIR/$tdir/$tfile
1667         local fid=$(copy_file /etc/passwd $f)
1668
1669         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1670         wait_request_state $fid ARCHIVE SUCCEED
1671
1672         $LFS hsm_release $f
1673         $LFS hsm_set --lost $f
1674         md5sum $f
1675         st=$?
1676
1677         [[ $st == 1 ]] || error "lost file access should failed (returns $st)"
1678
1679         copytool_cleanup
1680 }
1681 run_test 25b "Restore lost file (HS_LOST flag) after release"\
1682              " (Operation not permitted)"
1683
1684 test_26() {
1685         # test needs a running copytool
1686         copytool_setup
1687
1688         mkdir -p $DIR/$tdir
1689         local f=$DIR/$tdir/$tfile
1690         local fid=$(make_large_for_progress $f)
1691         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1692         wait_request_state $fid ARCHIVE SUCCEED
1693
1694         $LFS hsm_remove $f
1695         wait_request_state $fid REMOVE SUCCEED
1696
1697         check_hsm_flags $f "0x00000000"
1698
1699         copytool_cleanup
1700 }
1701 run_test 26 "Remove the archive of a valid file"
1702
1703 test_27a() {
1704         # test needs a running copytool
1705         copytool_setup
1706
1707         mkdir -p $DIR/$tdir
1708         make_archive $tdir/$tfile
1709         local f=$DIR/$tdir/$tfile
1710         import_file $tdir/$tfile $f
1711         local fid=$(path2fid $f)
1712
1713         $LFS hsm_remove $f
1714
1715         [[ $? != 0 ]] || error "Remove of a released file should fail"
1716
1717         copytool_cleanup
1718 }
1719 run_test 27a "Remove the archive of an imported file (Operation not permitted)"
1720
1721 test_27b() {
1722         # test needs a running copytool
1723         copytool_setup
1724
1725         mkdir -p $DIR/$tdir
1726         local f=$DIR/$tdir/$tfile
1727         local fid=$(make_large_for_progress $f)
1728         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1729         wait_request_state $fid ARCHIVE SUCCEED
1730         $LFS hsm_release $f
1731
1732         $LFS hsm_remove $f
1733
1734         [[ $? != 0 ]] || error "Remove of a released file should fail"
1735
1736         copytool_cleanup
1737 }
1738 run_test 27b "Remove the archive of a relased file (Operation not permitted)"
1739
1740 test_28() {
1741         # test needs a running copytool
1742         copytool_setup
1743
1744         mkdir -p $DIR/$tdir
1745         local f=$DIR/$tdir/$tfile
1746         local fid=$(make_large_for_progress $f)
1747         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1748         wait_request_state $fid ARCHIVE SUCCEED
1749
1750         cdt_disable
1751         $LFS hsm_remove $f
1752
1753         rm -f $f
1754
1755         cdt_enable
1756
1757         wait_request_state $fid REMOVE SUCCEED
1758
1759         copytool_cleanup
1760 }
1761 run_test 28 "Concurrent archive/file remove"
1762
1763 test_30a() {
1764         # restore at exec cannot work on agent node (because of Linux kernel
1765         # protection of executables)
1766         needclients 2 || return 0
1767
1768         # test needs a running copytool
1769         copytool_setup
1770
1771         mkdir -p $DIR/$tdir
1772         copy2archive /bin/true $tdir/$tfile
1773
1774         local f=$DIR/$tdir/true
1775         import_file $tdir/$tfile $f
1776
1777         local fid=$(path2fid $f)
1778
1779         # set no retry action mode
1780         cdt_set_no_retry
1781         do_node $CLIENT2 $f
1782         local st=$?
1783
1784         # cleanup
1785         # remove no try action mode
1786         cdt_clear_no_retry
1787         $LFS hsm_state $f
1788
1789         [[ $st == 0 ]] || error "Failed to exec a released file"
1790
1791         copytool_cleanup
1792 }
1793 run_test 30a "Restore at exec (import case)"
1794
1795 test_30b() {
1796         # restore at exec cannot work on agent node (because of Linux kernel
1797         # protection of executables)
1798         needclients 2 || return 0
1799
1800         # test needs a running copytool
1801         copytool_setup
1802
1803         mkdir -p $DIR/$tdir
1804         local f=$DIR/$tdir/true
1805         local fid=$(copy_file /bin/true $f)
1806         chmod 755 $f
1807         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1808         wait_request_state $fid ARCHIVE SUCCEED
1809         $LFS hsm_release $f
1810         $LFS hsm_state $f
1811         # set no retry action mode
1812         cdt_set_no_retry
1813         do_node $CLIENT2 $f
1814         local st=$?
1815
1816         # cleanup
1817         # remove no try action mode
1818         cdt_clear_no_retry
1819         $LFS hsm_state $f
1820
1821         [[ $st == 0 ]] || error "Failed to exec a released file"
1822
1823         copytool_cleanup
1824 }
1825 run_test 30b "Restore at exec (release case)"
1826
1827 restore_and_check_size() {
1828         local f=$1
1829         local fid=$2
1830         local s=$(stat -c "%s" $f)
1831         local n=$s
1832         local st=$(get_hsm_flags $f)
1833         local err=0
1834         local cpt=0
1835         $LFS hsm_restore $f
1836         while [[ "$st" != "0x00000009" && $cpt -le 10 ]]
1837         do
1838                 n=$(stat -c "%s" $f)
1839                 # we echo in both cases to show stat is not
1840                 # hang
1841                 if [[ $n != $s ]]; then
1842                         echo "size seen is $n != $s"
1843                         err=1
1844                 else
1845                         echo "size seen is right: $n == $s"
1846                 fi
1847                 st=$(get_hsm_flags $f)
1848                 sleep 10
1849                 cpt=$((cpt + 1))
1850         done
1851         if [[ $cpt -lt 10 ]]; then
1852                 echo " restore is too long"
1853         else
1854                 echo " "done
1855         fi
1856         wait_request_state $fid RESTORE SUCCEED
1857         return $err
1858 }
1859
1860 test_31a() {
1861         # test needs a running copytool
1862         copytool_setup
1863
1864         mkdir -p $DIR/$tdir
1865
1866         make_archive $tdir/$tfile
1867         local f=$DIR/$tdir/$tfile
1868         import_file $tdir/$tfile $f
1869         local fid=$($LFS path2fid $f)
1870         HSM_ARCHIVE_PURGE=false copytool_setup
1871
1872         restore_and_check_size $f $fid
1873         local err=$?
1874
1875         [[ $err -eq 0 ]] || error "File size changed during restore"
1876
1877         copytool_cleanup
1878 }
1879 run_test 31a "Import a large file and check size during restore"
1880
1881
1882 test_31b() {
1883         # test needs a running copytool
1884         copytool_setup
1885
1886         mkdir -p $DIR/$tdir
1887
1888         local f=$DIR/$tdir/$tfile
1889         local fid=$(make_large_for_progress $f)
1890         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1891         wait_request_state $fid ARCHIVE SUCCEED
1892         $LFS hsm_release $f
1893
1894         restore_and_check_size $f $fid
1895         local err=$?
1896
1897         [[ $err -eq 0 ]] || error "File size changed during restore"
1898
1899         copytool_cleanup
1900 }
1901 run_test 31b "Restore a large unaligned file and check size during restore"
1902
1903 test_31c() {
1904         # test needs a running copytool
1905         copytool_setup
1906
1907         mkdir -p $DIR/$tdir
1908
1909         local f=$DIR/$tdir/$tfile
1910         local fid=$(make_large_for_progress_aligned $f)
1911         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1912         wait_request_state $fid ARCHIVE SUCCEED
1913         $LFS hsm_release $f
1914
1915         restore_and_check_size $f $fid
1916         local err=$?
1917
1918         [[ $err -eq 0 ]] || error "File size changed during restore"
1919
1920         copytool_cleanup
1921 }
1922 run_test 31c "Restore a large aligned file and check size during restore"
1923
1924 test_33() {
1925         # test needs a running copytool
1926         copytool_setup
1927
1928         mkdir -p $DIR/$tdir
1929
1930         local f=$DIR/$tdir/$tfile
1931         local fid=$(make_large_for_progress $f)
1932         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1933         wait_request_state $fid ARCHIVE SUCCEED
1934         $LFS hsm_release $f
1935
1936         md5sum $f >/dev/null &
1937         local pid=$!
1938         wait_request_state $fid RESTORE STARTED
1939
1940         kill -15 $pid
1941         sleep 1
1942
1943         # Check restore trigger process was killed
1944         local killed=$(ps -o pid,comm hp $pid >/dev/null)
1945
1946         $LFS hsm_cancel $f
1947
1948         wait_request_state $fid RESTORE CANCELED
1949         wait_request_state $fid CANCEL SUCCEED
1950
1951         [ -z $killed ] ||
1952                 error "Cannot kill process waiting for restore ($killed)"
1953
1954         copytool_cleanup
1955 }
1956 run_test 33 "Kill a restore waiting process"
1957
1958 test_34() {
1959         # test needs a running copytool
1960         copytool_setup
1961
1962         mkdir -p $DIR/$tdir
1963
1964         local f=$DIR/$tdir/$tfile
1965         local fid=$(make_large_for_progress $f)
1966         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1967         wait_request_state $fid ARCHIVE SUCCEED
1968         $LFS hsm_release $f
1969
1970         md5sum $f >/dev/null &
1971         local pid=$!
1972         wait_request_state $fid RESTORE STARTED
1973
1974         rm $f || error "rm $f failed"
1975         # rm must not block during restore
1976         wait_request_state $fid RESTORE STARTED
1977
1978         wait_request_state $fid RESTORE SUCCEED
1979         # check md5sum pgm finished
1980         local there=$(ps -o pid,comm hp $pid >/dev/null)
1981         [[ -z $there ]] || error "Restore initiator does not exit"
1982
1983         local rc=$(wait $pid)
1984         [[ $rc -eq 0 ]] || error "Restore initiator failed with $rc"
1985
1986         copytool_cleanup
1987 }
1988 run_test 34 "Remove file during restore"
1989
1990 test_35() {
1991         # test needs a running copytool
1992         copytool_setup
1993
1994         mkdir -p $DIR/$tdir
1995
1996         local f=$DIR/$tdir/$tfile
1997         local f1=$DIR/$tdir/$tfile-1
1998         local fid=$(make_large_for_progress $f)
1999         local fid1=$(copy_file /etc/passwd $f1)
2000         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2001         wait_request_state $fid ARCHIVE SUCCEED
2002         $LFS hsm_release $f
2003
2004         md5sum $f >/dev/null &
2005         local pid=$!
2006         wait_request_state $fid RESTORE STARTED
2007
2008         mv $f1 $f || error "mv $f1 $f failed"
2009         # mv must not block during restore
2010         wait_request_state $fid RESTORE STARTED
2011
2012         wait_request_state $fid RESTORE SUCCEED
2013         # check md5sum pgm finished
2014         local there=$(ps -o pid,comm hp $pid >/dev/null)
2015         [[ -z $there ]] || error "Restore initiator does not exit"
2016
2017         local rc=$(wait $pid)
2018         [[ $rc -eq 0 ]] || error "Restore initiator failed with $rc"
2019
2020         fid2=$(path2fid $f)
2021         [[ $fid2 == $fid1 ]] || error "Wrong fid after mv $fid2 != $fid1"
2022
2023         copytool_cleanup
2024 }
2025 run_test 35 "Overwrite file during restore"
2026
2027 test_36() {
2028         # test needs a running copytool
2029         copytool_setup
2030
2031         mkdir -p $DIR/$tdir
2032
2033         local f=$DIR/$tdir/$tfile
2034         local fid=$(make_large_for_progress $f)
2035         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2036         wait_request_state $fid ARCHIVE SUCCEED
2037         $LFS hsm_release $f
2038
2039         md5sum $f >/dev/null &
2040         local pid=$!
2041         wait_request_state $fid RESTORE STARTED
2042
2043         mv $f $f.new
2044         # rm must not block during restore
2045         wait_request_state $fid RESTORE STARTED
2046
2047         wait_request_state $fid RESTORE SUCCEED
2048         # check md5sum pgm finished
2049         local there=$(ps -o pid,comm hp $pid >/dev/null)
2050         [[ -z $there ]] ||
2051                 error "Restore initiator does not exit"
2052
2053         local rc=$(wait $pid)
2054         [[ $rc -eq 0 ]] ||
2055                 error "Restore initiator failed with $rc"
2056
2057         copytool_cleanup
2058 }
2059 run_test 36 "Move file during restore"
2060
2061 multi_archive() {
2062         local prefix=$1
2063         local count=$2
2064         local n=""
2065
2066         for n in $(seq 1 $count); do
2067                 $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $prefix.$n
2068         done
2069         echo "$count archive requests submitted"
2070 }
2071
2072 test_40() {
2073         local stream_count=4
2074         local file_count=100
2075         mkdir -p $DIR/$tdir
2076         local f=$DIR/$tdir/$tfile
2077         local i=""
2078         local p=""
2079         local fid=""
2080
2081         for i in $(seq 1 $file_count); do
2082                 for p in $(seq 1 $stream_count); do
2083                         fid=$(copy_file /etc/hosts $f.$p.$i)
2084                 done
2085         done
2086         copytool_setup
2087         # to be sure wait_all_done will not be mislead by previous tests
2088         cdt_purge
2089         wait_for_grace_delay
2090         typeset -a pids
2091         # start archive streams in background (archive files in parallel)
2092         for p in $(seq 1 $stream_count); do
2093                 multi_archive $f.$p $file_count &
2094                 pids[$p]=$!
2095         done
2096         echo -n  "Wait for all requests being enqueued..."
2097         wait ${pids[*]}
2098         echo OK
2099         wait_all_done 100
2100         copytool_cleanup
2101 }
2102 run_test 40 "Parallel archive requests"
2103
2104 test_52() {
2105         # test needs a running copytool
2106         copytool_setup
2107
2108         mkdir -p $DIR/$tdir
2109         local f=$DIR/$tdir/$tfile
2110         local fid=$(copy_file /etc/motd $f 1)
2111
2112         $LFS hsm_archive $f || error "could not archive file"
2113         wait_request_state $fid ARCHIVE SUCCEED
2114         check_hsm_flags $f "0x00000009"
2115
2116         multiop_bg_pause $f O_c || error "multiop failed"
2117         local MULTIPID=$!
2118
2119         mds_evict_client
2120         client_up || client_up || true
2121
2122         kill -USR1 $MULTIPID
2123         wait $MULTIPID || error "multiop close failed"
2124
2125         check_hsm_flags $f "0x0000000b"
2126
2127         copytool_cleanup
2128 }
2129 run_test 52 "Opened for write file on an evicted client should be set dirty"
2130
2131 test_53() {
2132         # test needs a running copytool
2133         copytool_setup
2134
2135         mkdir -p $DIR/$tdir
2136         local f=$DIR/$tdir/$tfile
2137         local fid=$(copy_file /etc/motd $f 1)
2138
2139         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
2140                 error "could not archive file"
2141         wait_request_state $fid ARCHIVE SUCCEED
2142         check_hsm_flags $f "0x00000009"
2143
2144         multiop_bg_pause $f o_c || error "multiop failed"
2145         MULTIPID=$!
2146
2147         mds_evict_client
2148         client_up || client_up || true
2149
2150         kill -USR1 $MULTIPID
2151         wait $MULTIPID || error "multiop close failed"
2152
2153         check_hsm_flags $f "0x00000009"
2154
2155         copytool_cleanup
2156 }
2157 run_test 53 "Opened for read file on an evicted client should not be set dirty"
2158
2159 test_54() {
2160         # test needs a running copytool
2161         copytool_setup
2162
2163         mkdir -p $DIR/$tdir
2164         local f=$DIR/$tdir/$tfile
2165         local fid=$(make_small $f)
2166
2167         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
2168                 error "could not archive file"
2169         wait_request_state $fid ARCHIVE STARTED
2170
2171         check_hsm_flags $f "0x00000001"
2172
2173         # Avoid coordinator resending this request as soon it has failed.
2174         cdt_set_no_retry
2175
2176         echo "foo" >> $f
2177         sync
2178         wait_request_state $fid ARCHIVE FAILED
2179
2180         check_hsm_flags $f "0x00000003"
2181
2182         cdt_clear_no_retry
2183         copytool_cleanup
2184 }
2185 run_test 54 "Write during an archive cancels it"
2186
2187 test_55() {
2188         # test needs a running copytool
2189         copytool_setup
2190
2191         mkdir -p $DIR/$tdir
2192         local f=$DIR/$tdir/$tfile
2193         local fid=$(make_small $f)
2194
2195         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
2196                 error "could not archive file"
2197         wait_request_state $fid ARCHIVE STARTED
2198
2199         check_hsm_flags $f "0x00000001"
2200
2201         # Avoid coordinator resending this request as soon it has failed.
2202         cdt_set_no_retry
2203
2204         $TRUNCATE $f 1024 || error "truncate failed"
2205         sync
2206         wait_request_state $fid ARCHIVE FAILED
2207
2208         check_hsm_flags $f "0x00000003"
2209
2210         cdt_clear_no_retry
2211         copytool_cleanup
2212 }
2213 run_test 55 "Truncate during an archive cancels it"
2214
2215 test_56() {
2216         # test needs a running copytool
2217         copytool_setup
2218
2219         mkdir -p $DIR/$tdir
2220         local f=$DIR/$tdir/$tfile
2221         local fid=$(make_large_for_progress $f)
2222
2223         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
2224                 error "could not archive file"
2225         wait_request_state $fid ARCHIVE STARTED
2226
2227         check_hsm_flags $f "0x00000001"
2228
2229         # Change metadata and sync to be sure we are not changing only
2230         # in memory.
2231         chmod 644 $f
2232         chgrp sys $f
2233         sync
2234         wait_request_state $fid ARCHIVE SUCCEED
2235
2236         check_hsm_flags $f "0x00000009"
2237
2238         copytool_cleanup
2239 }
2240 run_test 56 "Setattr during an archive is ok"
2241
2242 test_57() {
2243         # Need one client for I/O, one for request
2244         needclients 2 || return 0
2245
2246         # test needs a running copytool
2247         copytool_setup
2248
2249         mkdir -p $DIR/$tdir
2250         local f=$DIR/$tdir/test_archive_remote
2251         # Create a file on a remote node
2252         do_node $CLIENT2 "dd if=/dev/urandom of=$f bs=1M "\
2253                 "count=2 conv=fsync"
2254
2255         # And archive it
2256         do_node $CLIENT2 "$LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $f" ||
2257                 error "hsm_archive failed"
2258         local fid=$(path2fid $f)
2259         wait_request_state $fid ARCHIVE SUCCEED
2260
2261         # Release and implicit restore it
2262         do_node $CLIENT2 "$LFS hsm_release $f" ||
2263                 error "hsm_release failed"
2264         do_node $CLIENT2 "md5sum $f" ||
2265                 error "hsm_restore failed"
2266
2267         wait_request_state $fid RESTORE SUCCEED
2268
2269         copytool_cleanup
2270 }
2271 run_test 57 "Archive a file with dirty cache on another node"
2272
2273 truncate_released_file() {
2274         local src_file=$1
2275         local trunc_to=$2
2276
2277         local sz=$(stat -c %s $src_file)
2278         local f=$DIR/$tdir/$tfile
2279         local fid=$(copy_file $1 $f)
2280         local ref=$f-ref
2281         cp $f $f-ref
2282
2283         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
2284                 error "could not archive file"
2285         wait_request_state $fid ARCHIVE SUCCEED
2286
2287         $LFS hsm_release $f || error "could not release file"
2288
2289         $TRUNCATE $f $trunc_to || error "truncate failed"
2290         sync
2291
2292         local sz1=$(stat -c %s $f)
2293         [[ $sz1 == $trunc_to ]] ||
2294                 error "size after trunc: $sz1 expect $trunc_to, original $sz"
2295
2296         $LFS hsm_state $f
2297         check_hsm_flags $f "0x0000000b"
2298
2299         local state=$(get_request_state $fid RESTORE)
2300         [[ "$state" == "SUCCEED" ]] ||
2301                 error "truncate $sz does not trig restore, state = $state"
2302
2303         $TRUNCATE $ref $trunc_to
2304         cmp $ref $f || error "file data wrong after truncate"
2305
2306         rm -f $f $f-ref
2307 }
2308
2309 test_58() {
2310         # test needs a running copytool
2311         copytool_setup
2312
2313         mkdir -p $DIR/$tdir
2314
2315         local sz=$(stat -c %s /etc/passwd)
2316
2317         echo "truncate up from $sz to $((sz*2))"
2318         truncate_released_file /etc/passwd $((sz*2))
2319
2320         echo "truncate down from $sz to $((sz/2))"
2321         truncate_released_file /etc/passwd $((sz/2))
2322
2323         echo "truncate to 0"
2324         truncate_released_file /etc/passwd 0
2325
2326         copytool_cleanup
2327 }
2328 run_test 58 "Truncate a released file will trigger restore"
2329
2330 test_90() {
2331         file_count=57
2332         mkdir -p $DIR/$tdir
2333         local f=$DIR/$tdir/$tfile
2334         local FILELIST=/tmp/filelist.txt
2335         local i=""
2336
2337         rm -f $FILELIST
2338         for i in $(seq 1 $file_count); do
2339                 fid=$(copy_file /etc/hosts $f.$i)
2340                 echo $f.$i >> $FILELIST
2341         done
2342         copytool_setup
2343         # to be sure wait_all_done will not be mislead by previous tests
2344         cdt_purge
2345         wait_for_grace_delay
2346         $LFS hsm_archive --filelist $FILELIST ||
2347                 error "cannot archive a file list"
2348         wait_all_done 100
2349         $LFS hsm_release --filelist $FILELIST ||
2350                 error "cannot release a file list"
2351         $LFS hsm_restore --filelist $FILELIST ||
2352                 error "cannot restore a file list"
2353         wait_all_done 100
2354         copytool_cleanup
2355 }
2356 run_test 90 "Archive/restore a file list"
2357
2358 double_verify_reset_hsm_param() {
2359         local p=$1
2360         echo "Testing $HSM_PARAM.$p"
2361         local val=$(get_hsm_param $p)
2362         local save=$val
2363         local val2=$(($val * 2))
2364         set_hsm_param $p $val2
2365         val=$(get_hsm_param $p)
2366         [[ $val == $val2 ]] ||
2367                 error "$HSM_PARAM.$p: $val != $val2 should be (2 * $save)"
2368         echo "Set $p to 0 must failed"
2369         set_hsm_param $p 0
2370         local rc=$?
2371         # restore value
2372         set_hsm_param $p $save
2373
2374         if [[ $rc == 0 ]]; then
2375                 error "we must not be able to set $HSM_PARAM.$p to 0"
2376         fi
2377 }
2378
2379 test_100() {
2380         double_verify_reset_hsm_param loop_period
2381         double_verify_reset_hsm_param grace_delay
2382         double_verify_reset_hsm_param active_request_timeout
2383         double_verify_reset_hsm_param max_requests
2384         double_verify_reset_hsm_param default_archive_id
2385 }
2386 run_test 100 "Set coordinator /proc tunables"
2387
2388 test_102() {
2389         cdt_disable
2390         cdt_enable
2391         cdt_restart
2392 }
2393 run_test 102 "Verify coordinator control"
2394
2395 test_103() {
2396         # test needs a running copytool
2397         copytool_setup
2398
2399         local i=""
2400         local fid=""
2401
2402         mkdir -p $DIR/$tdir
2403         for i in $(seq 1 20); do
2404                 fid=$(copy_file /etc/passwd $DIR/$tdir/$i)
2405         done
2406         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/*
2407
2408         cdt_purge
2409
2410         echo "Current requests"
2411         local res=$(do_facet $SINGLEMDS "$LCTL get_param -n\
2412                         $HSM_PARAM.actions |\
2413                         grep -v CANCELED | grep -v SUCCEED | grep -v FAILED")
2414
2415         [[ -z "$res" ]] || error "Some request have not been canceled"
2416
2417         copytool_cleanup
2418 }
2419 run_test 103 "Purge all requests"
2420
2421 DATA=CEA
2422 DATAHEX='[434541]'
2423 test_104() {
2424         # test needs a running copytool
2425         copytool_setup
2426
2427         mkdir -p $DIR/$tdir
2428         local f=$DIR/$tdir/$tfile
2429         local fid=$(make_large_for_progress $f)
2430         # if cdt is on, it can serve too quickly the request
2431         cdt_disable
2432         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER --data $DATA $f
2433         local data1=$(do_facet $SINGLEMDS "$LCTL get_param -n\
2434                         $HSM_PARAM.actions |\
2435                         grep $fid | cut -f16 -d=")
2436         cdt_enable
2437
2438         [[ "$data1" == "$DATAHEX" ]] ||
2439                 error "Data field in records is ($data1) and not ($DATAHEX)"
2440
2441         copytool_cleanup
2442 }
2443 run_test 104 "Copy tool data field"
2444
2445 test_105() {
2446         mkdir -p $DIR/$tdir
2447         local i=""
2448
2449         cdt_disable
2450         for i in $(seq -w 1 10); do
2451                 cp /etc/passwd $DIR/$tdir/$i
2452                 $LFS hsm_archive $DIR/$tdir/$i
2453         done
2454         local reqcnt1=$(do_facet $SINGLEMDS "$LCTL get_param -n\
2455                         $HSM_PARAM.actions |\
2456                         grep WAITING | wc -l")
2457         cdt_restart
2458         cdt_disable
2459         local reqcnt2=$(do_facet $SINGLEMDS "$LCTL get_param -n\
2460                         $HSM_PARAM.actions |\
2461                         grep WAITING | wc -l")
2462         cdt_enable
2463         cdt_purge
2464         [[ "$reqcnt1" == "$reqcnt2" ]] ||
2465                 error "Requests count after shutdown $reqcnt2 != "\
2466                       "before shutdown $reqcnt1"
2467 }
2468 run_test 105 "Restart of coordinator"
2469
2470 test_106() {
2471         # test needs a running copytool
2472         copytool_setup
2473
2474         local uuid=$(do_rpc_nodes $(facet_active_host $SINGLEAGT) \
2475                 get_client_uuid $MOUNT | cut -d' ' -f2)
2476         local agent=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.agents |
2477                 grep $uuid)
2478         copytool_cleanup
2479         [[ ! -z "$agent" ]] || error "My uuid $uuid not found in agent list"
2480         local agent=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.agents |
2481                 grep $uuid)
2482         [[ -z "$agent" ]] ||
2483                 error "My uuid $uuid still found in agent list,"\
2484                       " after copytool shutdown"
2485         copytool_setup
2486         local agent=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.agents |
2487                 grep $uuid)
2488         copytool_cleanup
2489         [[ ! -z "$agent" ]] ||
2490                 error "My uuid $uuid not found in agent list after"\
2491                       " copytool restart"
2492 }
2493 run_test 106 "Copytool register/unregister"
2494
2495 test_107() {
2496         # test needs a running copytool
2497         copytool_setup
2498         # create and archive file
2499         mkdir -p $DIR/$tdir
2500         local f1=$DIR/$tdir/$tfile
2501         local fid=$(copy_file /etc/passwd $f1)
2502         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1
2503         wait_request_state $fid ARCHIVE SUCCEED
2504         # shutdown and restart MDS
2505         fail $SINGLEMDS
2506         # check the copytool still gets messages from MDT
2507         local f2=$DIR/$tdir/2
2508         local fid=$(copy_file /etc/passwd $f2)
2509         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f2
2510         # main check of this sanity: this request MUST succeed
2511         wait_request_state $fid ARCHIVE SUCCEED
2512         copytool_cleanup
2513 }
2514 run_test 107 "Copytool re-register after MDS restart"
2515
2516 policy_set_and_test()
2517 {
2518         local change="$1"
2519         local target="$2"
2520         do_facet $SINGLEMDS $LCTL set_param "$HSM_PARAM.policy=\\\"$change\\\""
2521         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
2522         [[ "$policy" == "$target" ]] ||
2523                 error "Wrong policy after '$change': '$policy' != '$target'"
2524 }
2525
2526 test_109() {
2527         # to force default policy setting if error
2528         CDT_POLICY_HAD_CHANGED=true
2529
2530         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
2531         local default="NonBlockingRestore [NoRetryAction]"
2532         [[ "$policy" == "$default" ]] ||
2533                 error "default policy has changed,"\
2534                       " '$policy' != '$default' update the test"
2535         policy_set_and_test "+NBR" "[NonBlockingRestore] [NoRetryAction]"
2536         policy_set_and_test "+NRA" "[NonBlockingRestore] [NoRetryAction]"
2537         policy_set_and_test "-NBR" "NonBlockingRestore [NoRetryAction]"
2538         policy_set_and_test "-NRA" "NonBlockingRestore NoRetryAction"
2539         policy_set_and_test "NRA NBR" "[NonBlockingRestore] [NoRetryAction]"
2540         # useless bacause we know but safer for futur changes to use real value
2541         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
2542         echo "Next set_param must failed"
2543         policy_set_and_test "wrong" "$policy"
2544
2545         # return to default
2546         echo "Back to default policy"
2547         cdt_set_sanity_policy
2548 }
2549 run_test 109 "Policy display/change"
2550
2551 test_110a() {
2552         # test needs a running copytool
2553         copytool_setup
2554
2555         mkdir -p $DIR/$tdir
2556
2557         copy2archive /etc/passwd $tdir/$tfile
2558
2559         local f=$DIR/$tdir/$tfile
2560         import_file $tdir/$tfile $f
2561         local fid=$(path2fid $f)
2562
2563         cdt_set_non_blocking_restore
2564         md5sum $f
2565         local st=$?
2566
2567         # cleanup
2568         wait_request_state $fid RESTORE SUCCEED
2569         cdt_clear_non_blocking_restore
2570
2571         # Test result
2572         [[ $st == 1 ]] ||
2573                 error "md5sum returns $st != 1, "\
2574                         "should also perror ENODATA (No data available)"
2575
2576         copytool_cleanup
2577 }
2578 run_test 110a "Non blocking restore policy (import case)"
2579
2580 test_110b() {
2581         # test needs a running copytool
2582         copytool_setup
2583
2584         mkdir -p $DIR/$tdir
2585         local f=$DIR/$tdir/$tfile
2586         local fid=$(copy_file /etc/passwd $f)
2587         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2588         wait_request_state $fid ARCHIVE SUCCEED
2589         $LFS hsm_release $f
2590
2591         cdt_set_non_blocking_restore
2592         md5sum $f
2593         local st=$?
2594
2595         # cleanup
2596         wait_request_state $fid RESTORE SUCCEED
2597         cdt_clear_non_blocking_restore
2598
2599         # Test result
2600         [[ $st == 1 ]] ||
2601                 error "md5sum returns $st != 1, "\
2602                         "should also perror ENODATA (No data available)"
2603
2604         copytool_cleanup
2605 }
2606 run_test 110b "Non blocking restore policy (release case)"
2607
2608 test_111a() {
2609         # test needs a running copytool
2610         copytool_setup
2611
2612         mkdir -p $DIR/$tdir
2613         copy2archive /etc/passwd $tdir/$tfile
2614
2615         local f=$DIR/$tdir/$tfile
2616
2617         import_file $tdir/$tfile $f
2618         local fid=$(path2fid $f)
2619
2620         cdt_set_no_retry
2621
2622         copytool_remove_backend $fid
2623
2624         $LFS hsm_restore $f
2625         wait_request_state $fid RESTORE FAILED
2626         local st=$?
2627
2628         # cleanup
2629         cdt_clear_no_retry
2630
2631         # Test result
2632         [[ $st == 0 ]] || error "Restore does not failed"
2633
2634         copytool_cleanup
2635 }
2636 run_test 111a "No retry policy (import case), restore will error"\
2637               " (No such file or directory)"
2638
2639 test_111b() {
2640         # test needs a running copytool
2641         copytool_setup
2642
2643         mkdir -p $DIR/$tdir
2644         local f=$DIR/$tdir/$tfile
2645         local fid=$(copy_file /etc/passwd $f)
2646         cdt_set_no_retry
2647         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2648         wait_request_state $fid ARCHIVE SUCCEED
2649         $LFS hsm_release $f
2650
2651         copytool_remove_backend $fid
2652
2653         $LFS hsm_restore $f
2654         wait_request_state $fid RESTORE FAILED
2655         local st=$?
2656
2657         # cleanup
2658         cdt_clear_no_retry
2659
2660         # Test result
2661         [[ $st == 0 ]] || error "Restore does not failed"
2662
2663         copytool_cleanup
2664 }
2665 run_test 111b "No retry policy (release case), restore will error"\
2666               " (No such file or directory)"
2667
2668 test_112() {
2669         # test needs a running copytool
2670         copytool_setup
2671
2672         mkdir -p $DIR/$tdir
2673         local f=$DIR/$tdir/$tfile
2674         local fid=$(copy_file /etc/passwd $f)
2675         cdt_disable
2676         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2677         local l=$($LFS hsm_action $f)
2678         echo $l
2679         local res=$(echo $l | cut -f 2- -d" " | grep ARCHIVE)
2680
2681         # cleanup
2682         cdt_enable
2683         wait_request_state $fid ARCHIVE SUCCEED
2684
2685         # Test result
2686         [[ ! -z "$res" ]] || error "action is $l which is not an ARCHIVE"
2687
2688         copytool_cleanup
2689 }
2690 run_test 112 "State of recorded request"
2691
2692 test_200() {
2693         # test needs a running copytool
2694         copytool_setup
2695
2696         mkdir -p $DIR/$tdir
2697         local f=$DIR/$tdir/$tfile
2698         local fid=$(make_large_for_cancel $f)
2699         # test with cdt on is made in test_221
2700         cdt_disable
2701         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2702         $LFS hsm_cancel $f
2703         cdt_enable
2704         wait_request_state $fid ARCHIVE CANCELED
2705         wait_request_state $fid CANCEL SUCCEED
2706
2707         copytool_cleanup
2708 }
2709 run_test 200 "Register/Cancel archive"
2710
2711 test_201() {
2712         # test needs a running copytool
2713         copytool_setup
2714
2715         mkdir -p $DIR/$tdir
2716         local f=$DIR/$tdir/$tfile
2717         make_archive $tdir/$tfile
2718         import_file $tdir/$tfile $f
2719         local fid=$(path2fid $f)
2720
2721         # test with cdt on is made in test_222
2722         cdt_disable
2723         $LFS hsm_restore $f
2724         $LFS hsm_cancel $f
2725         cdt_enable
2726         wait_request_state $fid RESTORE CANCELED
2727         wait_request_state $fid CANCEL SUCCEED
2728
2729         copytool_cleanup
2730 }
2731 run_test 201 "Register/Cancel restore"
2732
2733 test_202() {
2734         # test needs a running copytool
2735         copytool_setup
2736
2737         mkdir -p $DIR/$tdir
2738         local f=$DIR/$tdir/$tfile
2739         local fid=$(make_large_for_progress $f)
2740         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2741         wait_request_state $fid ARCHIVE SUCCEED
2742
2743         cdt_disable
2744         $LFS hsm_remove $f
2745         $LFS hsm_cancel $f
2746         cdt_enable
2747         wait_request_state $fid REMOVE CANCELED
2748
2749         copytool_cleanup
2750 }
2751 run_test 202 "Register/Cancel remove"
2752
2753 test_220() {
2754         # test needs a running copytool
2755         copytool_setup
2756
2757         mkdir -p $DIR/$tdir
2758
2759         local f=$DIR/$tdir/$tfile
2760         local fid=$(copy_file /etc/passwd $f)
2761
2762         changelog_setup
2763
2764         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2765         wait_request_state $fid ARCHIVE SUCCEED
2766
2767         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2768         changelog_cleanup
2769
2770         local target=0x0
2771         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
2772
2773         copytool_cleanup
2774 }
2775 run_test 220 "Changelog for archive"
2776
2777 test_221() {
2778         # test needs a running copytool
2779         copytool_setup
2780
2781         mkdir -p $DIR/$tdir
2782
2783         local f=$DIR/$tdir/$tfile
2784         local fid=$(make_large_for_cancel $f)
2785
2786         changelog_setup
2787
2788         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2789         wait_request_state $fid ARCHIVE STARTED
2790         $LFS hsm_cancel $f
2791         wait_request_state $fid ARCHIVE CANCELED
2792         wait_request_state $fid CANCEL SUCCEED
2793
2794         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2795
2796         local target=0x7d
2797         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
2798
2799         cleanup
2800 }
2801 run_test 221 "Changelog for archive canceled"
2802
2803 test_222a() {
2804         # test needs a running copytool
2805         copytool_setup
2806
2807         mkdir -p $DIR/$tdir
2808         copy2archive /etc/passwd $tdir/$tfile
2809
2810         local f=$DIR/$tdir/$tfile
2811         import_file $tdir/$tfile $f
2812         local fid=$(path2fid $f)
2813
2814         changelog_setup
2815
2816         $LFS hsm_restore $f
2817         wait_request_state $fid RESTORE SUCCEED
2818
2819         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2820
2821         local target=0x80
2822         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
2823
2824         cleanup
2825 }
2826 run_test 222a "Changelog for explicit restore"
2827
2828 test_222b() {
2829         # test needs a running copytool
2830         copytool_setup
2831
2832         mkdir -p $DIR/$tdir
2833         local f=$DIR/$tdir/$tfile
2834         local fid=$(copy_file /etc/passwd $f)
2835
2836         changelog_setup
2837         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2838         wait_request_state $fid ARCHIVE SUCCEED
2839         $LFS hsm_release $f
2840
2841         md5sum $f
2842
2843         wait_request_state $fid RESTORE SUCCEED
2844
2845         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2846
2847         local target=0x80
2848         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
2849
2850         cleanup
2851 }
2852 run_test 222b "Changelog for implicit restore"
2853
2854 test_223a() {
2855         # test needs a running copytool
2856         copytool_setup
2857
2858         mkdir -p $DIR/$tdir
2859
2860         local f=$DIR/$tdir/$tfile
2861         make_archive $tdir/$tfile
2862
2863         changelog_setup
2864
2865         import_file $tdir/$tfile $f
2866         local fid=$(path2fid $f)
2867
2868         $LFS hsm_restore $f
2869         wait_request_state $fid RESTORE STARTED
2870         $LFS hsm_cancel $f
2871         wait_request_state $fid RESTORE CANCELED
2872         wait_request_state $fid CANCEL SUCCEED
2873
2874         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2875
2876         local target=0xfd
2877         [[ $flags == $target ]] ||
2878                 error "Changelog flag is $flags not $target"
2879
2880         cleanup
2881 }
2882 run_test 223a "Changelog for restore canceled (import case)"
2883
2884 test_223b() {
2885         # test needs a running copytool
2886         copytool_setup
2887
2888         mkdir -p $DIR/$tdir
2889
2890         local f=$DIR/$tdir/$tfile
2891         local fid=$(make_large_for_progress $f)
2892
2893         changelog_setup
2894         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2895         wait_request_state $fid ARCHIVE SUCCEED
2896         $LFS hsm_release $f
2897         $LFS hsm_restore $f
2898         wait_request_state $fid RESTORE STARTED
2899         $LFS hsm_cancel $f
2900         wait_request_state $fid RESTORE CANCELED
2901         wait_request_state $fid CANCEL SUCCEED
2902
2903         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2904
2905         local target=0xfd
2906         [[ $flags == $target ]] ||
2907                 error "Changelog flag is $flags not $target"
2908
2909         cleanup
2910 }
2911 run_test 223b "Changelog for restore canceled (release case)"
2912
2913 test_224() {
2914         # test needs a running copytool
2915         copytool_setup
2916
2917         mkdir -p $DIR/$tdir
2918
2919         local f=$DIR/$tdir/$tfile
2920         local fid=$(copy_file /etc/passwd $f)
2921
2922         changelog_setup
2923         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2924         wait_request_state $fid ARCHIVE SUCCEED
2925
2926         $LFS hsm_remove $f
2927         wait_request_state $fid REMOVE SUCCEED
2928
2929         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2930
2931         local target=0x200
2932         [[ $flags == $target ]] ||
2933                 error "Changelog flag is $flags not $target"
2934
2935         cleanup
2936 }
2937 run_test 224 "Changelog for remove"
2938
2939 test_225() {
2940         # test needs a running copytool
2941         copytool_setup
2942
2943         # test is not usable because remove request is too fast
2944         # so it is always finished before cancel can be done ...
2945         echo "Test disabled"
2946         copytool_cleanup
2947         return 0
2948
2949         mkdir -p $DIR/$tdir
2950         local f=$DIR/$tdir/$tfile
2951         local fid=$(make_large_for_progress $f)
2952
2953         changelog_setup
2954         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2955         wait_request_state $fid ARCHIVE SUCCEED
2956
2957         # if cdt is on, it can serve too quickly the request
2958         cdt_disable
2959         $LFS hsm_remove $f
2960         $LFS hsm_cancel $f
2961         cdt_enable
2962         wait_request_state $fid REMOVE CANCELED
2963         wait_request_state $fid CANCEL SUCCEED
2964
2965         flags=$(changelog_get_flags $MDT0 RENME $fid2)
2966         local flags=$($LFS changelog $MDT0 | grep HSM | grep $fid | tail -1 |
2967                 awk '{print $5}')
2968
2969         local target=0x27d
2970         [[ $flags == $target ]] ||
2971                 error "Changelog flag is $flags not $target"
2972
2973         cleanup
2974 }
2975 run_test 225 "Changelog for remove canceled"
2976
2977 test_226() {
2978         # test needs a running copytool
2979         copytool_setup
2980
2981         mkdir -p $DIR/$tdir
2982
2983         local f1=$DIR/$tdir/$tfile-1
2984         local f2=$DIR/$tdir/$tfile-2
2985         local f3=$DIR/$tdir/$tfile-3
2986         local fid1=$(copy_file /etc/passwd $f1)
2987         local fid2=$(copy_file /etc/passwd $f2)
2988         copy_file /etc/passwd $f3
2989
2990         changelog_setup
2991         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1
2992         wait_request_state $fid1 ARCHIVE SUCCEED
2993
2994         $LFS hsm_archive $f2
2995         wait_request_state $fid2 ARCHIVE SUCCEED
2996
2997         rm $f1 || error "rm $f1 failed"
2998
2999         local flags=$(changelog_get_flags $MDT0 UNLNK $fid1)
3000
3001         local target=0x3
3002         [[ $flags == $target ]] ||
3003                 error "Changelog flag is $flags not $target"
3004
3005         mv $f3 $f2 || error "mv $f3 $f2 failed"
3006
3007         flags=$(changelog_get_flags $MDT0 RENME $fid2)
3008
3009         target=0x3
3010         [[ $flags == $target ]] ||
3011                 error "Changelog flag is $flags not $target"
3012
3013         cleanup
3014 }
3015 run_test 226 "changelog for last rm/mv with exiting archive"
3016
3017 check_flags_changes() {
3018         local f=$1
3019         local fid=$2
3020         local hsm_flag=$3
3021         local fst=$4
3022         local cnt=$5
3023
3024         local target=0x280
3025         $LFS hsm_set --$hsm_flag $f ||
3026                 error "Cannot set $hsm_flag on $f"
3027         local flags=($(changelog_get_flags $MDT0 HSM $fid))
3028         local seen=${#flags[*]}
3029         cnt=$((fst + cnt))
3030         [[ $seen == $cnt ]] ||
3031                 error "set $hsm_flag: Changelog events $seen != $cnt"
3032         [[ ${flags[$((cnt - 1))]} == $target ]] ||
3033                 error "set $hsm_flag: Changelog flags are "\
3034                         "${flags[$((cnt - 1))]} not $target"
3035
3036         $LFS hsm_clear --$hsm_flag $f ||
3037                 error "Cannot clear $hsm_flag on $f"
3038         flags=($(changelog_get_flags $MDT0 HSM $fid))
3039         seen=${#flags[*]}
3040         cnt=$(($cnt + 1))
3041         [[ $cnt == $seen ]] ||
3042                 error "clear $hsm_flag: Changelog events $seen != $cnt"
3043
3044         [[ ${flags[$((cnt - 1))]} == $target ]] ||
3045                 error "clear $hsm_flag: Changelog flag is "\
3046                         "${flags[$((cnt - 1))]} not $target"
3047 }
3048
3049 test_227() {
3050         # test needs a running copytool
3051         copytool_setup
3052         changelog_setup
3053
3054         mkdir -p $DIR/$tdir
3055         typeset -a flags
3056
3057         for i in norelease noarchive exists archived
3058         do
3059                 local f=$DIR/$tdir/$tfile-$i
3060                 local fid=$(copy_file /etc/passwd $f)
3061                 check_flags_changes $f $fid $i 0 1
3062         done
3063
3064         f=$DIR/$tdir/$tfile---lost
3065         fid=$(copy_file /etc/passwd $f)
3066         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3067         wait_request_state $fid ARCHIVE SUCCEED
3068         check_flags_changes $f $fid lost 3 1
3069
3070         cleanup
3071 }
3072 run_test 227 "changelog when explicit setting of HSM flags"
3073
3074 test_228() {
3075         # test needs a running copytool
3076         copytool_setup
3077
3078         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=1 conv=sync ||
3079                 error "creating $DIR/$tfile"
3080         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tfile
3081         wait_request_state $(path2fid $DIR/$tfile) ARCHIVE SUCCEED
3082
3083         $LFS hsm_release $DIR/$tfile
3084         check_hsm_flags $DIR/$tfile "0x0000000d"
3085
3086         filefrag $DIR/$tfile | grep " 1 extent found" ||
3087                 error "filefrag on released file must return only one extent"
3088
3089         # only newer versions of cp detect sparse files by stat/FIEMAP
3090         # (LU-2580)
3091         cp --sparse=auto $DIR/$tfile $DIR/$tfile.2 ||
3092                 error "copying $DIR/$tfile"
3093         cmp $DIR/$tfile $DIR/$tfile.2 || error "comparing copied $DIR/$tfile"
3094
3095         $LFS hsm_release $DIR/$tfile
3096         check_hsm_flags $DIR/$tfile "0x0000000d"
3097
3098         mkdir $DIR/$tdir
3099
3100         tar cf - --sparse $DIR/$tfile | tar xvf - -C $DIR/$tdir ||
3101                 error "tar failed"
3102         cmp $DIR/$tfile $DIR/$tdir/$DIR/$tfile ||
3103                 error "comparing untarred $DIR/$tfile"
3104
3105         copytool_cleanup
3106 }
3107 run_test 228 "On released file, return extend to FIEMAP. For [cp,tar] --sparse"
3108
3109 test_250() {
3110         # test needs a running copytool
3111         copytool_setup
3112
3113         mkdir -p $DIR/$tdir
3114         local maxrequest=$(get_hsm_param max_requests)
3115         local rqcnt=$(($maxrequest * 3))
3116         local i=""
3117
3118         cdt_disable
3119         for i in $(seq -w 1 $rqcnt); do
3120                 rm -f $DIR/$tdir/$i
3121                 dd if=/dev/urandom of=$DIR/$tdir/$i bs=1M count=10 conv=fsync
3122         done
3123         # we do it in 2 steps, so all requests arrive at the same time
3124         for i in $(seq -w 1 $rqcnt); do
3125                 $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/$i
3126         done
3127         cdt_enable
3128         local cnt=$rqcnt
3129         local wt=$rqcnt
3130         while [[ $cnt != 0 || $wt != 0 ]]; do
3131                 sleep 1
3132                 cnt=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3133                         $HSM_PARAM.actions |\
3134                         grep STARTED | grep -v CANCEL | wc -l")
3135                 [[ $cnt -le $maxrequest ]] ||
3136                         error "$cnt > $maxrequest too many started requests"
3137                 wt=$(do_facet $SINGLEMDS "$LCTL get_param\
3138                         $HSM_PARAM.actions |\
3139                         grep WAITING | wc -l")
3140                 echo "max=$maxrequest started=$cnt waiting=$wt"
3141         done
3142
3143         copytool_cleanup
3144 }
3145 run_test 250 "Coordinator max request"
3146
3147 test_251() {
3148         # test needs a running copytool
3149         copytool_setup
3150
3151         mkdir -p $DIR/$tdir
3152         local f=$DIR/$tdir/$tfile
3153         local fid=$(make_large_for_cancel $f)
3154
3155         cdt_disable
3156         # to have a short test
3157         local old_to=$(get_hsm_param active_request_timeout)
3158         set_hsm_param active_request_timeout 4
3159         # to be sure the cdt will wake up frequently so
3160         # it will be able to cancel the "old" request
3161         local old_loop=$(get_hsm_param loop_period)
3162         set_hsm_param loop_period 2
3163         cdt_enable
3164
3165         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3166         wait_request_state $fid ARCHIVE STARTED
3167         sleep 5
3168         wait_request_state $fid ARCHIVE CANCELED
3169
3170         set_hsm_param active_request_timeout $old_to
3171         set_hsm_param loop_period $old_loop
3172
3173         copytool_cleanup
3174 }
3175 run_test 251 "Coordinator request timeout"
3176
3177 test_300() {
3178         # the only way to test ondisk conf is to restart MDS ...
3179         echo "Stop coordinator and remove coordinator state at mount"
3180         # stop coordinator
3181         cdt_shutdown
3182         # clean on disk conf set by default
3183         cdt_clear_mount_state
3184         cdt_check_state stopped
3185
3186         # check cdt still off after umount/remount
3187         fail $SINGLEMDS
3188         cdt_check_state stopped
3189
3190         echo "Set coordinator start at mount, and start coordinator"
3191         cdt_set_mount_state enabled
3192
3193         # check cdt is on
3194         cdt_check_state enabled
3195
3196         # check cdt still on after umount/remount
3197         fail $SINGLEMDS
3198         cdt_check_state enabled
3199
3200         # we are back to original state (cdt started at mount)
3201 }
3202 run_test 300 "On disk coordinator state kept between MDT umount/mount"
3203
3204 test_301() {
3205         local ai=$(get_hsm_param default_archive_id)
3206         local new=$((ai + 1))
3207
3208         set_hsm_param default_archive_id $new -P
3209         fail $SINGLEMDS
3210         local res=$(get_hsm_param default_archive_id)
3211
3212         # clear value
3213         set_hsm_param default_archive_id "" "-P -d"
3214
3215         [[ $new == $res ]] || error "Value after MDS restart is $res != $new"
3216 }
3217 run_test 301 "HSM tunnable are persistent"
3218
3219 test_302() {
3220         local ai=$(get_hsm_param default_archive_id)
3221         local new=$((ai + 1))
3222
3223         # stop coordinator
3224         cdt_shutdown
3225
3226         set_hsm_param default_archive_id $new -P
3227         fail $SINGLEMDS
3228
3229         # check cdt is on
3230         cdt_check_state enabled
3231
3232         local res=$(get_hsm_param default_archive_id)
3233
3234         # clear value
3235         set_hsm_param default_archive_id "" "-P -d"
3236
3237         [[ $new == $res ]] || error "Value after MDS restart is $res != $new"
3238 }
3239 run_test 302 "HSM tunnable are persistent when CDT is off"
3240
3241 copytool_cleanup
3242
3243 complete $SECONDS
3244 check_and_cleanup_lustre
3245 exit_status