Whamcloud - gitweb
LU-4064 hsm: create files to be imported on agent node
[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 test_30c() {
1828         needclients 2 || return 0
1829
1830         # test needs a running copytool
1831         copytool_setup
1832
1833         mkdir -p $DIR/$tdir
1834         local f=$DIR/$tdir/SLEEP
1835         local fid=$(copy_file /bin/sleep $f)
1836         chmod 755 $f
1837         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1838         wait_request_state $fid ARCHIVE SUCCEED
1839         $LFS hsm_release $f
1840         check_hsm_flags $f "0x0000000d"
1841         # set no retry action mode
1842         cdt_set_no_retry
1843         do_node $CLIENT2 "$f 10" &
1844         local pid=$!
1845         sleep 3
1846         echo 'Hi!' > $f
1847         [[ $? == 0 ]] && error "Update during exec of released file must fail"
1848         wait $pid
1849         [[ $? == 0 ]] || error "Execution failed during run"
1850         cmp /bin/sleep $f
1851         [[ $? == 0 ]] || error "Binary overwritten during exec"
1852
1853         # cleanup
1854         # remove no try action mode
1855         cdt_clear_no_retry
1856         check_hsm_flags $f "0x00000009"
1857
1858         copytool_cleanup
1859 }
1860 run_test 30c "Update during exec of released file must fail"
1861
1862 restore_and_check_size() {
1863         local f=$1
1864         local fid=$2
1865         local s=$(stat -c "%s" $f)
1866         local n=$s
1867         local st=$(get_hsm_flags $f)
1868         local err=0
1869         local cpt=0
1870         $LFS hsm_restore $f
1871         while [[ "$st" != "0x00000009" && $cpt -le 10 ]]
1872         do
1873                 n=$(stat -c "%s" $f)
1874                 # we echo in both cases to show stat is not
1875                 # hang
1876                 if [[ $n != $s ]]; then
1877                         echo "size seen is $n != $s"
1878                         err=1
1879                 else
1880                         echo "size seen is right: $n == $s"
1881                 fi
1882                 st=$(get_hsm_flags $f)
1883                 sleep 10
1884                 cpt=$((cpt + 1))
1885         done
1886         if [[ $cpt -lt 10 ]]; then
1887                 echo " restore is too long"
1888         else
1889                 echo " "done
1890         fi
1891         wait_request_state $fid RESTORE SUCCEED
1892         return $err
1893 }
1894
1895 test_31a() {
1896         # test needs a running copytool
1897         copytool_setup
1898
1899         mkdir -p $DIR/$tdir
1900
1901         make_archive $tdir/$tfile
1902         local f=$DIR/$tdir/$tfile
1903         import_file $tdir/$tfile $f
1904         local fid=$($LFS path2fid $f)
1905         HSM_ARCHIVE_PURGE=false copytool_setup
1906
1907         restore_and_check_size $f $fid
1908         local err=$?
1909
1910         [[ $err -eq 0 ]] || error "File size changed during restore"
1911
1912         copytool_cleanup
1913 }
1914 run_test 31a "Import a large file and check size during restore"
1915
1916
1917 test_31b() {
1918         # test needs a running copytool
1919         copytool_setup
1920
1921         mkdir -p $DIR/$tdir
1922
1923         local f=$DIR/$tdir/$tfile
1924         local fid=$(make_large_for_progress $f)
1925         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1926         wait_request_state $fid ARCHIVE SUCCEED
1927         $LFS hsm_release $f
1928
1929         restore_and_check_size $f $fid
1930         local err=$?
1931
1932         [[ $err -eq 0 ]] || error "File size changed during restore"
1933
1934         copytool_cleanup
1935 }
1936 run_test 31b "Restore a large unaligned file and check size during restore"
1937
1938 test_31c() {
1939         # test needs a running copytool
1940         copytool_setup
1941
1942         mkdir -p $DIR/$tdir
1943
1944         local f=$DIR/$tdir/$tfile
1945         local fid=$(make_large_for_progress_aligned $f)
1946         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1947         wait_request_state $fid ARCHIVE SUCCEED
1948         $LFS hsm_release $f
1949
1950         restore_and_check_size $f $fid
1951         local err=$?
1952
1953         [[ $err -eq 0 ]] || error "File size changed during restore"
1954
1955         copytool_cleanup
1956 }
1957 run_test 31c "Restore a large aligned file and check size during restore"
1958
1959 test_33() {
1960         # test needs a running copytool
1961         copytool_setup
1962
1963         mkdir -p $DIR/$tdir
1964
1965         local f=$DIR/$tdir/$tfile
1966         local fid=$(make_large_for_progress $f)
1967         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
1968         wait_request_state $fid ARCHIVE SUCCEED
1969         $LFS hsm_release $f
1970
1971         md5sum $f >/dev/null &
1972         local pid=$!
1973         wait_request_state $fid RESTORE STARTED
1974
1975         kill -15 $pid
1976         sleep 1
1977
1978         # Check restore trigger process was killed
1979         local killed=$(ps -o pid,comm hp $pid >/dev/null)
1980
1981         $LFS hsm_cancel $f
1982
1983         wait_request_state $fid RESTORE CANCELED
1984         wait_request_state $fid CANCEL SUCCEED
1985
1986         [ -z $killed ] ||
1987                 error "Cannot kill process waiting for restore ($killed)"
1988
1989         copytool_cleanup
1990 }
1991 run_test 33 "Kill a restore waiting process"
1992
1993 test_34() {
1994         # test needs a running copytool
1995         copytool_setup
1996
1997         mkdir -p $DIR/$tdir
1998
1999         local f=$DIR/$tdir/$tfile
2000         local fid=$(make_large_for_progress $f)
2001         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2002         wait_request_state $fid ARCHIVE SUCCEED
2003         $LFS hsm_release $f
2004
2005         md5sum $f >/dev/null &
2006         local pid=$!
2007         wait_request_state $fid RESTORE STARTED
2008
2009         rm $f || error "rm $f failed"
2010         # rm must not block during restore
2011         wait_request_state $fid RESTORE STARTED
2012
2013         wait_request_state $fid RESTORE SUCCEED
2014         # check md5sum pgm finished
2015         local there=$(ps -o pid,comm hp $pid >/dev/null)
2016         [[ -z $there ]] || error "Restore initiator does not exit"
2017
2018         local rc=$(wait $pid)
2019         [[ $rc -eq 0 ]] || error "Restore initiator failed with $rc"
2020
2021         copytool_cleanup
2022 }
2023 run_test 34 "Remove file during restore"
2024
2025 test_35() {
2026         # test needs a running copytool
2027         copytool_setup
2028
2029         mkdir -p $DIR/$tdir
2030
2031         local f=$DIR/$tdir/$tfile
2032         local f1=$DIR/$tdir/$tfile-1
2033         local fid=$(make_large_for_progress $f)
2034         local fid1=$(copy_file /etc/passwd $f1)
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 $f1 $f || error "mv $f1 $f failed"
2044         # mv 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 ]] || error "Restore initiator does not exit"
2051
2052         local rc=$(wait $pid)
2053         [[ $rc -eq 0 ]] || error "Restore initiator failed with $rc"
2054
2055         fid2=$(path2fid $f)
2056         [[ $fid2 == $fid1 ]] || error "Wrong fid after mv $fid2 != $fid1"
2057
2058         copytool_cleanup
2059 }
2060 run_test 35 "Overwrite file during restore"
2061
2062 test_36() {
2063         # test needs a running copytool
2064         copytool_setup
2065
2066         mkdir -p $DIR/$tdir
2067
2068         local f=$DIR/$tdir/$tfile
2069         local fid=$(make_large_for_progress $f)
2070         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2071         wait_request_state $fid ARCHIVE SUCCEED
2072         $LFS hsm_release $f
2073
2074         md5sum $f >/dev/null &
2075         local pid=$!
2076         wait_request_state $fid RESTORE STARTED
2077
2078         mv $f $f.new
2079         # rm must not block during restore
2080         wait_request_state $fid RESTORE STARTED
2081
2082         wait_request_state $fid RESTORE SUCCEED
2083         # check md5sum pgm finished
2084         local there=$(ps -o pid,comm hp $pid >/dev/null)
2085         [[ -z $there ]] ||
2086                 error "Restore initiator does not exit"
2087
2088         local rc=$(wait $pid)
2089         [[ $rc -eq 0 ]] ||
2090                 error "Restore initiator failed with $rc"
2091
2092         copytool_cleanup
2093 }
2094 run_test 36 "Move file during restore"
2095
2096 multi_archive() {
2097         local prefix=$1
2098         local count=$2
2099         local n=""
2100
2101         for n in $(seq 1 $count); do
2102                 $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $prefix.$n
2103         done
2104         echo "$count archive requests submitted"
2105 }
2106
2107 test_40() {
2108         local stream_count=4
2109         local file_count=100
2110         mkdir -p $DIR/$tdir
2111         local f=$DIR/$tdir/$tfile
2112         local i=""
2113         local p=""
2114         local fid=""
2115
2116         for i in $(seq 1 $file_count); do
2117                 for p in $(seq 1 $stream_count); do
2118                         fid=$(copy_file /etc/hosts $f.$p.$i)
2119                 done
2120         done
2121         copytool_setup
2122         # to be sure wait_all_done will not be mislead by previous tests
2123         cdt_purge
2124         wait_for_grace_delay
2125         typeset -a pids
2126         # start archive streams in background (archive files in parallel)
2127         for p in $(seq 1 $stream_count); do
2128                 multi_archive $f.$p $file_count &
2129                 pids[$p]=$!
2130         done
2131         echo -n  "Wait for all requests being enqueued..."
2132         wait ${pids[*]}
2133         echo OK
2134         wait_all_done 100
2135         copytool_cleanup
2136 }
2137 run_test 40 "Parallel archive requests"
2138
2139 test_52() {
2140         # test needs a running copytool
2141         copytool_setup
2142
2143         mkdir -p $DIR/$tdir
2144         local f=$DIR/$tdir/$tfile
2145         local fid=$(copy_file /etc/motd $f 1)
2146
2147         $LFS hsm_archive $f || error "could not archive file"
2148         wait_request_state $fid ARCHIVE SUCCEED
2149         check_hsm_flags $f "0x00000009"
2150
2151         multiop_bg_pause $f O_c || error "multiop failed"
2152         local MULTIPID=$!
2153
2154         mds_evict_client
2155         client_up || client_up || true
2156
2157         kill -USR1 $MULTIPID
2158         wait $MULTIPID || error "multiop close failed"
2159
2160         check_hsm_flags $f "0x0000000b"
2161
2162         copytool_cleanup
2163 }
2164 run_test 52 "Opened for write file on an evicted client should be set dirty"
2165
2166 test_53() {
2167         # test needs a running copytool
2168         copytool_setup
2169
2170         mkdir -p $DIR/$tdir
2171         local f=$DIR/$tdir/$tfile
2172         local fid=$(copy_file /etc/motd $f 1)
2173
2174         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
2175                 error "could not archive file"
2176         wait_request_state $fid ARCHIVE SUCCEED
2177         check_hsm_flags $f "0x00000009"
2178
2179         multiop_bg_pause $f o_c || error "multiop failed"
2180         MULTIPID=$!
2181
2182         mds_evict_client
2183         client_up || client_up || true
2184
2185         kill -USR1 $MULTIPID
2186         wait $MULTIPID || error "multiop close failed"
2187
2188         check_hsm_flags $f "0x00000009"
2189
2190         copytool_cleanup
2191 }
2192 run_test 53 "Opened for read file on an evicted client should not be set dirty"
2193
2194 test_54() {
2195         # test needs a running copytool
2196         copytool_setup
2197
2198         mkdir -p $DIR/$tdir
2199         local f=$DIR/$tdir/$tfile
2200         local fid=$(make_small $f)
2201
2202         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
2203                 error "could not archive file"
2204         wait_request_state $fid ARCHIVE STARTED
2205
2206         check_hsm_flags $f "0x00000001"
2207
2208         # Avoid coordinator resending this request as soon it has failed.
2209         cdt_set_no_retry
2210
2211         echo "foo" >> $f
2212         sync
2213         wait_request_state $fid ARCHIVE FAILED
2214
2215         check_hsm_flags $f "0x00000003"
2216
2217         cdt_clear_no_retry
2218         copytool_cleanup
2219 }
2220 run_test 54 "Write during an archive cancels it"
2221
2222 test_55() {
2223         # test needs a running copytool
2224         copytool_setup
2225
2226         mkdir -p $DIR/$tdir
2227         local f=$DIR/$tdir/$tfile
2228         local fid=$(make_small $f)
2229
2230         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
2231                 error "could not archive file"
2232         wait_request_state $fid ARCHIVE STARTED
2233
2234         check_hsm_flags $f "0x00000001"
2235
2236         # Avoid coordinator resending this request as soon it has failed.
2237         cdt_set_no_retry
2238
2239         $TRUNCATE $f 1024 || error "truncate failed"
2240         sync
2241         wait_request_state $fid ARCHIVE FAILED
2242
2243         check_hsm_flags $f "0x00000003"
2244
2245         cdt_clear_no_retry
2246         copytool_cleanup
2247 }
2248 run_test 55 "Truncate during an archive cancels it"
2249
2250 test_56() {
2251         # test needs a running copytool
2252         copytool_setup
2253
2254         mkdir -p $DIR/$tdir
2255         local f=$DIR/$tdir/$tfile
2256         local fid=$(make_large_for_progress $f)
2257
2258         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
2259                 error "could not archive file"
2260         wait_request_state $fid ARCHIVE STARTED
2261
2262         check_hsm_flags $f "0x00000001"
2263
2264         # Change metadata and sync to be sure we are not changing only
2265         # in memory.
2266         chmod 644 $f
2267         chgrp sys $f
2268         sync
2269         wait_request_state $fid ARCHIVE SUCCEED
2270
2271         check_hsm_flags $f "0x00000009"
2272
2273         copytool_cleanup
2274 }
2275 run_test 56 "Setattr during an archive is ok"
2276
2277 test_57() {
2278         # Need one client for I/O, one for request
2279         needclients 2 || return 0
2280
2281         # test needs a running copytool
2282         copytool_setup
2283
2284         mkdir -p $DIR/$tdir
2285         local f=$DIR/$tdir/test_archive_remote
2286         # Create a file on a remote node
2287         do_node $CLIENT2 "dd if=/dev/urandom of=$f bs=1M "\
2288                 "count=2 conv=fsync"
2289
2290         # And archive it
2291         do_node $CLIENT2 "$LFS hsm_archive -a $HSM_ARCHIVE_NUMBER $f" ||
2292                 error "hsm_archive failed"
2293         local fid=$(path2fid $f)
2294         wait_request_state $fid ARCHIVE SUCCEED
2295
2296         # Release and implicit restore it
2297         do_node $CLIENT2 "$LFS hsm_release $f" ||
2298                 error "hsm_release failed"
2299         do_node $CLIENT2 "md5sum $f" ||
2300                 error "hsm_restore failed"
2301
2302         wait_request_state $fid RESTORE SUCCEED
2303
2304         copytool_cleanup
2305 }
2306 run_test 57 "Archive a file with dirty cache on another node"
2307
2308 truncate_released_file() {
2309         local src_file=$1
2310         local trunc_to=$2
2311
2312         local sz=$(stat -c %s $src_file)
2313         local f=$DIR/$tdir/$tfile
2314         local fid=$(copy_file $1 $f)
2315         local ref=$f-ref
2316         cp $f $f-ref
2317
2318         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f ||
2319                 error "could not archive file"
2320         wait_request_state $fid ARCHIVE SUCCEED
2321
2322         $LFS hsm_release $f || error "could not release file"
2323
2324         $TRUNCATE $f $trunc_to || error "truncate failed"
2325         sync
2326
2327         local sz1=$(stat -c %s $f)
2328         [[ $sz1 == $trunc_to ]] ||
2329                 error "size after trunc: $sz1 expect $trunc_to, original $sz"
2330
2331         $LFS hsm_state $f
2332         check_hsm_flags $f "0x0000000b"
2333
2334         local state=$(get_request_state $fid RESTORE)
2335         [[ "$state" == "SUCCEED" ]] ||
2336                 error "truncate $sz does not trig restore, state = $state"
2337
2338         $TRUNCATE $ref $trunc_to
2339         cmp $ref $f || error "file data wrong after truncate"
2340
2341         rm -f $f $f-ref
2342 }
2343
2344 test_58() {
2345         # test needs a running copytool
2346         copytool_setup
2347
2348         mkdir -p $DIR/$tdir
2349
2350         local sz=$(stat -c %s /etc/passwd)
2351
2352         echo "truncate up from $sz to $((sz*2))"
2353         truncate_released_file /etc/passwd $((sz*2))
2354
2355         echo "truncate down from $sz to $((sz/2))"
2356         truncate_released_file /etc/passwd $((sz/2))
2357
2358         echo "truncate to 0"
2359         truncate_released_file /etc/passwd 0
2360
2361         copytool_cleanup
2362 }
2363 run_test 58 "Truncate a released file will trigger restore"
2364
2365 test_90() {
2366         file_count=57
2367         mkdir -p $DIR/$tdir
2368         local f=$DIR/$tdir/$tfile
2369         local FILELIST=/tmp/filelist.txt
2370         local i=""
2371
2372         rm -f $FILELIST
2373         for i in $(seq 1 $file_count); do
2374                 fid=$(copy_file /etc/hosts $f.$i)
2375                 echo $f.$i >> $FILELIST
2376         done
2377         copytool_setup
2378         # to be sure wait_all_done will not be mislead by previous tests
2379         cdt_purge
2380         wait_for_grace_delay
2381         $LFS hsm_archive --filelist $FILELIST ||
2382                 error "cannot archive a file list"
2383         wait_all_done 100
2384         $LFS hsm_release --filelist $FILELIST ||
2385                 error "cannot release a file list"
2386         $LFS hsm_restore --filelist $FILELIST ||
2387                 error "cannot restore a file list"
2388         wait_all_done 100
2389         copytool_cleanup
2390 }
2391 run_test 90 "Archive/restore a file list"
2392
2393 double_verify_reset_hsm_param() {
2394         local p=$1
2395         echo "Testing $HSM_PARAM.$p"
2396         local val=$(get_hsm_param $p)
2397         local save=$val
2398         local val2=$(($val * 2))
2399         set_hsm_param $p $val2
2400         val=$(get_hsm_param $p)
2401         [[ $val == $val2 ]] ||
2402                 error "$HSM_PARAM.$p: $val != $val2 should be (2 * $save)"
2403         echo "Set $p to 0 must failed"
2404         set_hsm_param $p 0
2405         local rc=$?
2406         # restore value
2407         set_hsm_param $p $save
2408
2409         if [[ $rc == 0 ]]; then
2410                 error "we must not be able to set $HSM_PARAM.$p to 0"
2411         fi
2412 }
2413
2414 test_100() {
2415         double_verify_reset_hsm_param loop_period
2416         double_verify_reset_hsm_param grace_delay
2417         double_verify_reset_hsm_param active_request_timeout
2418         double_verify_reset_hsm_param max_requests
2419         double_verify_reset_hsm_param default_archive_id
2420 }
2421 run_test 100 "Set coordinator /proc tunables"
2422
2423 test_102() {
2424         cdt_disable
2425         cdt_enable
2426         cdt_restart
2427 }
2428 run_test 102 "Verify coordinator control"
2429
2430 test_103() {
2431         # test needs a running copytool
2432         copytool_setup
2433
2434         local i=""
2435         local fid=""
2436
2437         mkdir -p $DIR/$tdir
2438         for i in $(seq 1 20); do
2439                 fid=$(copy_file /etc/passwd $DIR/$tdir/$i)
2440         done
2441         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/*
2442
2443         cdt_purge
2444
2445         echo "Current requests"
2446         local res=$(do_facet $SINGLEMDS "$LCTL get_param -n\
2447                         $HSM_PARAM.actions |\
2448                         grep -v CANCELED | grep -v SUCCEED | grep -v FAILED")
2449
2450         [[ -z "$res" ]] || error "Some request have not been canceled"
2451
2452         copytool_cleanup
2453 }
2454 run_test 103 "Purge all requests"
2455
2456 DATA=CEA
2457 DATAHEX='[434541]'
2458 test_104() {
2459         # test needs a running copytool
2460         copytool_setup
2461
2462         mkdir -p $DIR/$tdir
2463         local f=$DIR/$tdir/$tfile
2464         local fid=$(make_large_for_progress $f)
2465         # if cdt is on, it can serve too quickly the request
2466         cdt_disable
2467         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER --data $DATA $f
2468         local data1=$(do_facet $SINGLEMDS "$LCTL get_param -n\
2469                         $HSM_PARAM.actions |\
2470                         grep $fid | cut -f16 -d=")
2471         cdt_enable
2472
2473         [[ "$data1" == "$DATAHEX" ]] ||
2474                 error "Data field in records is ($data1) and not ($DATAHEX)"
2475
2476         copytool_cleanup
2477 }
2478 run_test 104 "Copy tool data field"
2479
2480 test_105() {
2481         mkdir -p $DIR/$tdir
2482         local i=""
2483
2484         cdt_disable
2485         for i in $(seq -w 1 10); do
2486                 cp /etc/passwd $DIR/$tdir/$i
2487                 $LFS hsm_archive $DIR/$tdir/$i
2488         done
2489         local reqcnt1=$(do_facet $SINGLEMDS "$LCTL get_param -n\
2490                         $HSM_PARAM.actions |\
2491                         grep WAITING | wc -l")
2492         cdt_restart
2493         cdt_disable
2494         local reqcnt2=$(do_facet $SINGLEMDS "$LCTL get_param -n\
2495                         $HSM_PARAM.actions |\
2496                         grep WAITING | wc -l")
2497         cdt_enable
2498         cdt_purge
2499         [[ "$reqcnt1" == "$reqcnt2" ]] ||
2500                 error "Requests count after shutdown $reqcnt2 != "\
2501                       "before shutdown $reqcnt1"
2502 }
2503 run_test 105 "Restart of coordinator"
2504
2505 test_106() {
2506         # test needs a running copytool
2507         copytool_setup
2508
2509         local uuid=$(do_rpc_nodes $(facet_active_host $SINGLEAGT) \
2510                 get_client_uuid $MOUNT | cut -d' ' -f2)
2511         local agent=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.agents |
2512                 grep $uuid)
2513         copytool_cleanup
2514         [[ ! -z "$agent" ]] || error "My uuid $uuid not found in agent list"
2515         local agent=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.agents |
2516                 grep $uuid)
2517         [[ -z "$agent" ]] ||
2518                 error "My uuid $uuid still found in agent list,"\
2519                       " after copytool shutdown"
2520         copytool_setup
2521         local agent=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.agents |
2522                 grep $uuid)
2523         copytool_cleanup
2524         [[ ! -z "$agent" ]] ||
2525                 error "My uuid $uuid not found in agent list after"\
2526                       " copytool restart"
2527 }
2528 run_test 106 "Copytool register/unregister"
2529
2530 test_107() {
2531         # test needs a running copytool
2532         copytool_setup
2533         # create and archive file
2534         mkdir -p $DIR/$tdir
2535         local f1=$DIR/$tdir/$tfile
2536         local fid=$(copy_file /etc/passwd $f1)
2537         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1
2538         wait_request_state $fid ARCHIVE SUCCEED
2539         # shutdown and restart MDS
2540         fail $SINGLEMDS
2541         # check the copytool still gets messages from MDT
2542         local f2=$DIR/$tdir/2
2543         local fid=$(copy_file /etc/passwd $f2)
2544         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f2
2545         # main check of this sanity: this request MUST succeed
2546         wait_request_state $fid ARCHIVE SUCCEED
2547         copytool_cleanup
2548 }
2549 run_test 107 "Copytool re-register after MDS restart"
2550
2551 policy_set_and_test()
2552 {
2553         local change="$1"
2554         local target="$2"
2555         do_facet $SINGLEMDS $LCTL set_param "$HSM_PARAM.policy=\\\"$change\\\""
2556         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
2557         [[ "$policy" == "$target" ]] ||
2558                 error "Wrong policy after '$change': '$policy' != '$target'"
2559 }
2560
2561 test_109() {
2562         # to force default policy setting if error
2563         CDT_POLICY_HAD_CHANGED=true
2564
2565         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
2566         local default="NonBlockingRestore [NoRetryAction]"
2567         [[ "$policy" == "$default" ]] ||
2568                 error "default policy has changed,"\
2569                       " '$policy' != '$default' update the test"
2570         policy_set_and_test "+NBR" "[NonBlockingRestore] [NoRetryAction]"
2571         policy_set_and_test "+NRA" "[NonBlockingRestore] [NoRetryAction]"
2572         policy_set_and_test "-NBR" "NonBlockingRestore [NoRetryAction]"
2573         policy_set_and_test "-NRA" "NonBlockingRestore NoRetryAction"
2574         policy_set_and_test "NRA NBR" "[NonBlockingRestore] [NoRetryAction]"
2575         # useless bacause we know but safer for futur changes to use real value
2576         local policy=$(do_facet $SINGLEMDS $LCTL get_param -n $HSM_PARAM.policy)
2577         echo "Next set_param must failed"
2578         policy_set_and_test "wrong" "$policy"
2579
2580         # return to default
2581         echo "Back to default policy"
2582         cdt_set_sanity_policy
2583 }
2584 run_test 109 "Policy display/change"
2585
2586 test_110a() {
2587         # test needs a running copytool
2588         copytool_setup
2589
2590         mkdir -p $DIR/$tdir
2591
2592         copy2archive /etc/passwd $tdir/$tfile
2593
2594         local f=$DIR/$tdir/$tfile
2595         import_file $tdir/$tfile $f
2596         local fid=$(path2fid $f)
2597
2598         cdt_set_non_blocking_restore
2599         md5sum $f
2600         local st=$?
2601
2602         # cleanup
2603         wait_request_state $fid RESTORE SUCCEED
2604         cdt_clear_non_blocking_restore
2605
2606         # Test result
2607         [[ $st == 1 ]] ||
2608                 error "md5sum returns $st != 1, "\
2609                         "should also perror ENODATA (No data available)"
2610
2611         copytool_cleanup
2612 }
2613 run_test 110a "Non blocking restore policy (import case)"
2614
2615 test_110b() {
2616         # test needs a running copytool
2617         copytool_setup
2618
2619         mkdir -p $DIR/$tdir
2620         local f=$DIR/$tdir/$tfile
2621         local fid=$(copy_file /etc/passwd $f)
2622         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2623         wait_request_state $fid ARCHIVE SUCCEED
2624         $LFS hsm_release $f
2625
2626         cdt_set_non_blocking_restore
2627         md5sum $f
2628         local st=$?
2629
2630         # cleanup
2631         wait_request_state $fid RESTORE SUCCEED
2632         cdt_clear_non_blocking_restore
2633
2634         # Test result
2635         [[ $st == 1 ]] ||
2636                 error "md5sum returns $st != 1, "\
2637                         "should also perror ENODATA (No data available)"
2638
2639         copytool_cleanup
2640 }
2641 run_test 110b "Non blocking restore policy (release case)"
2642
2643 test_111a() {
2644         # test needs a running copytool
2645         copytool_setup
2646
2647         mkdir -p $DIR/$tdir
2648         copy2archive /etc/passwd $tdir/$tfile
2649
2650         local f=$DIR/$tdir/$tfile
2651
2652         import_file $tdir/$tfile $f
2653         local fid=$(path2fid $f)
2654
2655         cdt_set_no_retry
2656
2657         copytool_remove_backend $fid
2658
2659         $LFS hsm_restore $f
2660         wait_request_state $fid RESTORE FAILED
2661         local st=$?
2662
2663         # cleanup
2664         cdt_clear_no_retry
2665
2666         # Test result
2667         [[ $st == 0 ]] || error "Restore does not failed"
2668
2669         copytool_cleanup
2670 }
2671 run_test 111a "No retry policy (import case), restore will error"\
2672               " (No such file or directory)"
2673
2674 test_111b() {
2675         # test needs a running copytool
2676         copytool_setup
2677
2678         mkdir -p $DIR/$tdir
2679         local f=$DIR/$tdir/$tfile
2680         local fid=$(copy_file /etc/passwd $f)
2681         cdt_set_no_retry
2682         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2683         wait_request_state $fid ARCHIVE SUCCEED
2684         $LFS hsm_release $f
2685
2686         copytool_remove_backend $fid
2687
2688         $LFS hsm_restore $f
2689         wait_request_state $fid RESTORE FAILED
2690         local st=$?
2691
2692         # cleanup
2693         cdt_clear_no_retry
2694
2695         # Test result
2696         [[ $st == 0 ]] || error "Restore does not failed"
2697
2698         copytool_cleanup
2699 }
2700 run_test 111b "No retry policy (release case), restore will error"\
2701               " (No such file or directory)"
2702
2703 test_112() {
2704         # test needs a running copytool
2705         copytool_setup
2706
2707         mkdir -p $DIR/$tdir
2708         local f=$DIR/$tdir/$tfile
2709         local fid=$(copy_file /etc/passwd $f)
2710         cdt_disable
2711         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2712         local l=$($LFS hsm_action $f)
2713         echo $l
2714         local res=$(echo $l | cut -f 2- -d" " | grep ARCHIVE)
2715
2716         # cleanup
2717         cdt_enable
2718         wait_request_state $fid ARCHIVE SUCCEED
2719
2720         # Test result
2721         [[ ! -z "$res" ]] || error "action is $l which is not an ARCHIVE"
2722
2723         copytool_cleanup
2724 }
2725 run_test 112 "State of recorded request"
2726
2727 test_200() {
2728         # test needs a running copytool
2729         copytool_setup
2730
2731         mkdir -p $DIR/$tdir
2732         local f=$DIR/$tdir/$tfile
2733         local fid=$(make_large_for_cancel $f)
2734         # test with cdt on is made in test_221
2735         cdt_disable
2736         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2737         $LFS hsm_cancel $f
2738         cdt_enable
2739         wait_request_state $fid ARCHIVE CANCELED
2740         wait_request_state $fid CANCEL SUCCEED
2741
2742         copytool_cleanup
2743 }
2744 run_test 200 "Register/Cancel archive"
2745
2746 test_201() {
2747         # test needs a running copytool
2748         copytool_setup
2749
2750         mkdir -p $DIR/$tdir
2751         local f=$DIR/$tdir/$tfile
2752         make_archive $tdir/$tfile
2753         import_file $tdir/$tfile $f
2754         local fid=$(path2fid $f)
2755
2756         # test with cdt on is made in test_222
2757         cdt_disable
2758         $LFS hsm_restore $f
2759         $LFS hsm_cancel $f
2760         cdt_enable
2761         wait_request_state $fid RESTORE CANCELED
2762         wait_request_state $fid CANCEL SUCCEED
2763
2764         copytool_cleanup
2765 }
2766 run_test 201 "Register/Cancel restore"
2767
2768 test_202() {
2769         # test needs a running copytool
2770         copytool_setup
2771
2772         mkdir -p $DIR/$tdir
2773         local f=$DIR/$tdir/$tfile
2774         local fid=$(make_large_for_progress $f)
2775         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2776         wait_request_state $fid ARCHIVE SUCCEED
2777
2778         cdt_disable
2779         $LFS hsm_remove $f
2780         $LFS hsm_cancel $f
2781         cdt_enable
2782         wait_request_state $fid REMOVE CANCELED
2783
2784         copytool_cleanup
2785 }
2786 run_test 202 "Register/Cancel remove"
2787
2788 test_220() {
2789         # test needs a running copytool
2790         copytool_setup
2791
2792         mkdir -p $DIR/$tdir
2793
2794         local f=$DIR/$tdir/$tfile
2795         local fid=$(copy_file /etc/passwd $f)
2796
2797         changelog_setup
2798
2799         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2800         wait_request_state $fid ARCHIVE SUCCEED
2801
2802         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2803         changelog_cleanup
2804
2805         local target=0x0
2806         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
2807
2808         copytool_cleanup
2809 }
2810 run_test 220 "Changelog for archive"
2811
2812 test_221() {
2813         # test needs a running copytool
2814         copytool_setup
2815
2816         mkdir -p $DIR/$tdir
2817
2818         local f=$DIR/$tdir/$tfile
2819         local fid=$(make_large_for_cancel $f)
2820
2821         changelog_setup
2822
2823         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2824         wait_request_state $fid ARCHIVE STARTED
2825         $LFS hsm_cancel $f
2826         wait_request_state $fid ARCHIVE CANCELED
2827         wait_request_state $fid CANCEL SUCCEED
2828
2829         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2830
2831         local target=0x7d
2832         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
2833
2834         cleanup
2835 }
2836 run_test 221 "Changelog for archive canceled"
2837
2838 test_222a() {
2839         # test needs a running copytool
2840         copytool_setup
2841
2842         mkdir -p $DIR/$tdir
2843         copy2archive /etc/passwd $tdir/$tfile
2844
2845         local f=$DIR/$tdir/$tfile
2846         import_file $tdir/$tfile $f
2847         local fid=$(path2fid $f)
2848
2849         changelog_setup
2850
2851         $LFS hsm_restore $f
2852         wait_request_state $fid RESTORE SUCCEED
2853
2854         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2855
2856         local target=0x80
2857         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
2858
2859         cleanup
2860 }
2861 run_test 222a "Changelog for explicit restore"
2862
2863 test_222b() {
2864         # test needs a running copytool
2865         copytool_setup
2866
2867         mkdir -p $DIR/$tdir
2868         local f=$DIR/$tdir/$tfile
2869         local fid=$(copy_file /etc/passwd $f)
2870
2871         changelog_setup
2872         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2873         wait_request_state $fid ARCHIVE SUCCEED
2874         $LFS hsm_release $f
2875
2876         md5sum $f
2877
2878         wait_request_state $fid RESTORE SUCCEED
2879
2880         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2881
2882         local target=0x80
2883         [[ $flags == $target ]] || error "Changelog flag is $flags not $target"
2884
2885         cleanup
2886 }
2887 run_test 222b "Changelog for implicit restore"
2888
2889 test_223a() {
2890         # test needs a running copytool
2891         copytool_setup
2892
2893         mkdir -p $DIR/$tdir
2894
2895         local f=$DIR/$tdir/$tfile
2896         make_archive $tdir/$tfile
2897
2898         changelog_setup
2899
2900         import_file $tdir/$tfile $f
2901         local fid=$(path2fid $f)
2902
2903         $LFS hsm_restore $f
2904         wait_request_state $fid RESTORE STARTED
2905         $LFS hsm_cancel $f
2906         wait_request_state $fid RESTORE CANCELED
2907         wait_request_state $fid CANCEL SUCCEED
2908
2909         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2910
2911         local target=0xfd
2912         [[ $flags == $target ]] ||
2913                 error "Changelog flag is $flags not $target"
2914
2915         cleanup
2916 }
2917 run_test 223a "Changelog for restore canceled (import case)"
2918
2919 test_223b() {
2920         # test needs a running copytool
2921         copytool_setup
2922
2923         mkdir -p $DIR/$tdir
2924
2925         local f=$DIR/$tdir/$tfile
2926         local fid=$(make_large_for_progress $f)
2927
2928         changelog_setup
2929         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2930         wait_request_state $fid ARCHIVE SUCCEED
2931         $LFS hsm_release $f
2932         $LFS hsm_restore $f
2933         wait_request_state $fid RESTORE STARTED
2934         $LFS hsm_cancel $f
2935         wait_request_state $fid RESTORE CANCELED
2936         wait_request_state $fid CANCEL SUCCEED
2937
2938         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2939
2940         local target=0xfd
2941         [[ $flags == $target ]] ||
2942                 error "Changelog flag is $flags not $target"
2943
2944         cleanup
2945 }
2946 run_test 223b "Changelog for restore canceled (release case)"
2947
2948 test_224() {
2949         # test needs a running copytool
2950         copytool_setup
2951
2952         mkdir -p $DIR/$tdir
2953
2954         local f=$DIR/$tdir/$tfile
2955         local fid=$(copy_file /etc/passwd $f)
2956
2957         changelog_setup
2958         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2959         wait_request_state $fid ARCHIVE SUCCEED
2960
2961         $LFS hsm_remove $f
2962         wait_request_state $fid REMOVE SUCCEED
2963
2964         local flags=$(changelog_get_flags $MDT0 HSM $fid | tail -1)
2965
2966         local target=0x200
2967         [[ $flags == $target ]] ||
2968                 error "Changelog flag is $flags not $target"
2969
2970         cleanup
2971 }
2972 run_test 224 "Changelog for remove"
2973
2974 test_225() {
2975         # test needs a running copytool
2976         copytool_setup
2977
2978         # test is not usable because remove request is too fast
2979         # so it is always finished before cancel can be done ...
2980         echo "Test disabled"
2981         copytool_cleanup
2982         return 0
2983
2984         mkdir -p $DIR/$tdir
2985         local f=$DIR/$tdir/$tfile
2986         local fid=$(make_large_for_progress $f)
2987
2988         changelog_setup
2989         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
2990         wait_request_state $fid ARCHIVE SUCCEED
2991
2992         # if cdt is on, it can serve too quickly the request
2993         cdt_disable
2994         $LFS hsm_remove $f
2995         $LFS hsm_cancel $f
2996         cdt_enable
2997         wait_request_state $fid REMOVE CANCELED
2998         wait_request_state $fid CANCEL SUCCEED
2999
3000         flags=$(changelog_get_flags $MDT0 RENME $fid2)
3001         local flags=$($LFS changelog $MDT0 | grep HSM | grep $fid | tail -1 |
3002                 awk '{print $5}')
3003
3004         local target=0x27d
3005         [[ $flags == $target ]] ||
3006                 error "Changelog flag is $flags not $target"
3007
3008         cleanup
3009 }
3010 run_test 225 "Changelog for remove canceled"
3011
3012 test_226() {
3013         # test needs a running copytool
3014         copytool_setup
3015
3016         mkdir -p $DIR/$tdir
3017
3018         local f1=$DIR/$tdir/$tfile-1
3019         local f2=$DIR/$tdir/$tfile-2
3020         local f3=$DIR/$tdir/$tfile-3
3021         local fid1=$(copy_file /etc/passwd $f1)
3022         local fid2=$(copy_file /etc/passwd $f2)
3023         copy_file /etc/passwd $f3
3024
3025         changelog_setup
3026         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f1
3027         wait_request_state $fid1 ARCHIVE SUCCEED
3028
3029         $LFS hsm_archive $f2
3030         wait_request_state $fid2 ARCHIVE SUCCEED
3031
3032         rm $f1 || error "rm $f1 failed"
3033
3034         local flags=$(changelog_get_flags $MDT0 UNLNK $fid1)
3035
3036         local target=0x3
3037         [[ $flags == $target ]] ||
3038                 error "Changelog flag is $flags not $target"
3039
3040         mv $f3 $f2 || error "mv $f3 $f2 failed"
3041
3042         flags=$(changelog_get_flags $MDT0 RENME $fid2)
3043
3044         target=0x3
3045         [[ $flags == $target ]] ||
3046                 error "Changelog flag is $flags not $target"
3047
3048         cleanup
3049 }
3050 run_test 226 "changelog for last rm/mv with exiting archive"
3051
3052 check_flags_changes() {
3053         local f=$1
3054         local fid=$2
3055         local hsm_flag=$3
3056         local fst=$4
3057         local cnt=$5
3058
3059         local target=0x280
3060         $LFS hsm_set --$hsm_flag $f ||
3061                 error "Cannot set $hsm_flag on $f"
3062         local flags=($(changelog_get_flags $MDT0 HSM $fid))
3063         local seen=${#flags[*]}
3064         cnt=$((fst + cnt))
3065         [[ $seen == $cnt ]] ||
3066                 error "set $hsm_flag: Changelog events $seen != $cnt"
3067         [[ ${flags[$((cnt - 1))]} == $target ]] ||
3068                 error "set $hsm_flag: Changelog flags are "\
3069                         "${flags[$((cnt - 1))]} not $target"
3070
3071         $LFS hsm_clear --$hsm_flag $f ||
3072                 error "Cannot clear $hsm_flag on $f"
3073         flags=($(changelog_get_flags $MDT0 HSM $fid))
3074         seen=${#flags[*]}
3075         cnt=$(($cnt + 1))
3076         [[ $cnt == $seen ]] ||
3077                 error "clear $hsm_flag: Changelog events $seen != $cnt"
3078
3079         [[ ${flags[$((cnt - 1))]} == $target ]] ||
3080                 error "clear $hsm_flag: Changelog flag is "\
3081                         "${flags[$((cnt - 1))]} not $target"
3082 }
3083
3084 test_227() {
3085         # test needs a running copytool
3086         copytool_setup
3087         changelog_setup
3088
3089         mkdir -p $DIR/$tdir
3090         typeset -a flags
3091
3092         for i in norelease noarchive exists archived
3093         do
3094                 local f=$DIR/$tdir/$tfile-$i
3095                 local fid=$(copy_file /etc/passwd $f)
3096                 check_flags_changes $f $fid $i 0 1
3097         done
3098
3099         f=$DIR/$tdir/$tfile---lost
3100         fid=$(copy_file /etc/passwd $f)
3101         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3102         wait_request_state $fid ARCHIVE SUCCEED
3103         check_flags_changes $f $fid lost 3 1
3104
3105         cleanup
3106 }
3107 run_test 227 "changelog when explicit setting of HSM flags"
3108
3109 test_228() {
3110         # test needs a running copytool
3111         copytool_setup
3112
3113         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=1 conv=sync ||
3114                 error "creating $DIR/$tfile"
3115         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tfile
3116         wait_request_state $(path2fid $DIR/$tfile) ARCHIVE SUCCEED
3117
3118         $LFS hsm_release $DIR/$tfile
3119         check_hsm_flags $DIR/$tfile "0x0000000d"
3120
3121         filefrag $DIR/$tfile | grep " 1 extent found" ||
3122                 error "filefrag on released file must return only one extent"
3123
3124         # only newer versions of cp detect sparse files by stat/FIEMAP
3125         # (LU-2580)
3126         cp --sparse=auto $DIR/$tfile $DIR/$tfile.2 ||
3127                 error "copying $DIR/$tfile"
3128         cmp $DIR/$tfile $DIR/$tfile.2 || error "comparing copied $DIR/$tfile"
3129
3130         $LFS hsm_release $DIR/$tfile
3131         check_hsm_flags $DIR/$tfile "0x0000000d"
3132
3133         mkdir $DIR/$tdir
3134
3135         tar cf - --sparse $DIR/$tfile | tar xvf - -C $DIR/$tdir ||
3136                 error "tar failed"
3137         cmp $DIR/$tfile $DIR/$tdir/$DIR/$tfile ||
3138                 error "comparing untarred $DIR/$tfile"
3139
3140         copytool_cleanup
3141 }
3142 run_test 228 "On released file, return extend to FIEMAP. For [cp,tar] --sparse"
3143
3144 test_250() {
3145         # test needs a running copytool
3146         copytool_setup
3147
3148         mkdir -p $DIR/$tdir
3149         local maxrequest=$(get_hsm_param max_requests)
3150         local rqcnt=$(($maxrequest * 3))
3151         local i=""
3152
3153         cdt_disable
3154         for i in $(seq -w 1 $rqcnt); do
3155                 rm -f $DIR/$tdir/$i
3156                 dd if=/dev/urandom of=$DIR/$tdir/$i bs=1M count=10 conv=fsync
3157         done
3158         # we do it in 2 steps, so all requests arrive at the same time
3159         for i in $(seq -w 1 $rqcnt); do
3160                 $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $DIR/$tdir/$i
3161         done
3162         cdt_enable
3163         local cnt=$rqcnt
3164         local wt=$rqcnt
3165         while [[ $cnt != 0 || $wt != 0 ]]; do
3166                 sleep 1
3167                 cnt=$(do_facet $SINGLEMDS "$LCTL get_param -n\
3168                         $HSM_PARAM.actions |\
3169                         grep STARTED | grep -v CANCEL | wc -l")
3170                 [[ $cnt -le $maxrequest ]] ||
3171                         error "$cnt > $maxrequest too many started requests"
3172                 wt=$(do_facet $SINGLEMDS "$LCTL get_param\
3173                         $HSM_PARAM.actions |\
3174                         grep WAITING | wc -l")
3175                 echo "max=$maxrequest started=$cnt waiting=$wt"
3176         done
3177
3178         copytool_cleanup
3179 }
3180 run_test 250 "Coordinator max request"
3181
3182 test_251() {
3183         # test needs a running copytool
3184         copytool_setup
3185
3186         mkdir -p $DIR/$tdir
3187         local f=$DIR/$tdir/$tfile
3188         local fid=$(make_large_for_cancel $f)
3189
3190         cdt_disable
3191         # to have a short test
3192         local old_to=$(get_hsm_param active_request_timeout)
3193         set_hsm_param active_request_timeout 4
3194         # to be sure the cdt will wake up frequently so
3195         # it will be able to cancel the "old" request
3196         local old_loop=$(get_hsm_param loop_period)
3197         set_hsm_param loop_period 2
3198         cdt_enable
3199
3200         $LFS hsm_archive --archive $HSM_ARCHIVE_NUMBER $f
3201         wait_request_state $fid ARCHIVE STARTED
3202         sleep 5
3203         wait_request_state $fid ARCHIVE CANCELED
3204
3205         set_hsm_param active_request_timeout $old_to
3206         set_hsm_param loop_period $old_loop
3207
3208         copytool_cleanup
3209 }
3210 run_test 251 "Coordinator request timeout"
3211
3212 test_300() {
3213         # the only way to test ondisk conf is to restart MDS ...
3214         echo "Stop coordinator and remove coordinator state at mount"
3215         # stop coordinator
3216         cdt_shutdown
3217         # clean on disk conf set by default
3218         cdt_clear_mount_state
3219         cdt_check_state stopped
3220
3221         # check cdt still off after umount/remount
3222         fail $SINGLEMDS
3223         cdt_check_state stopped
3224
3225         echo "Set coordinator start at mount, and start coordinator"
3226         cdt_set_mount_state enabled
3227
3228         # check cdt is on
3229         cdt_check_state enabled
3230
3231         # check cdt still on after umount/remount
3232         fail $SINGLEMDS
3233         cdt_check_state enabled
3234
3235         # we are back to original state (cdt started at mount)
3236 }
3237 run_test 300 "On disk coordinator state kept between MDT umount/mount"
3238
3239 test_301() {
3240         local ai=$(get_hsm_param default_archive_id)
3241         local new=$((ai + 1))
3242
3243         set_hsm_param default_archive_id $new -P
3244         fail $SINGLEMDS
3245         local res=$(get_hsm_param default_archive_id)
3246
3247         # clear value
3248         set_hsm_param default_archive_id "" "-P -d"
3249
3250         [[ $new == $res ]] || error "Value after MDS restart is $res != $new"
3251 }
3252 run_test 301 "HSM tunnable are persistent"
3253
3254 test_302() {
3255         local ai=$(get_hsm_param default_archive_id)
3256         local new=$((ai + 1))
3257
3258         # stop coordinator
3259         cdt_shutdown
3260
3261         set_hsm_param default_archive_id $new -P
3262         fail $SINGLEMDS
3263
3264         # check cdt is on
3265         cdt_check_state enabled
3266
3267         local res=$(get_hsm_param default_archive_id)
3268
3269         # clear value
3270         set_hsm_param default_archive_id "" "-P -d"
3271
3272         [[ $new == $res ]] || error "Value after MDS restart is $res != $new"
3273 }
3274 run_test 302 "HSM tunnable are persistent when CDT is off"
3275
3276 copytool_cleanup
3277
3278 complete $SECONDS
3279 check_and_cleanup_lustre
3280 exit_status