Whamcloud - gitweb
LU-10092 pcc: Non-blocking PCC caching
[fs/lustre-release.git] / lustre / tests / sanity-pcc.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # exit on error
7 set -e
8 set +o monitor
9
10 SRCDIR=$(dirname $0)
11 export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/utils:$PATH:/sbin:/usr/sbin
12
13 ONLY=${ONLY:-"$*"}
14 # bug number for skipped test:
15 ALWAYS_EXCEPT=""
16 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
17
18 ENABLE_PROJECT_QUOTAS=${ENABLE_PROJECT_QUOTAS:-true}
19
20 LUSTRE=${LUSTRE:-$(cd $(dirname $0)/..; echo $PWD)}
21
22 . $LUSTRE/tests/test-framework.sh
23 init_test_env $@
24 . ${CONFIG:=$LUSTRE/tests/cfg/$NAME.sh}
25 init_logging
26
27 MULTIOP=${MULTIOP:-multiop}
28 OPENFILE=${OPENFILE:-openfile}
29 MMAP_CAT=${MMAP_CAT:-mmap_cat}
30 MOUNT_2=${MOUNT_2:-"yes"}
31 FAIL_ON_ERROR=false
32
33 # script only handles up to 10 MDTs (because of MDT_PREFIX)
34 [ $MDSCOUNT -gt 9 ] &&
35         error "script cannot handle more than 9 MDTs, please fix" && exit
36
37 check_and_setup_lustre
38
39 if [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.52) ]]; then
40         skip_env "Need MDS version at least 2.12.52" && exit
41 fi
42
43 # $RUNAS_ID may get set incorrectly somewhere else
44 if [[ $UID -eq 0 && $RUNAS_ID -eq 0 ]]; then
45         skip_env "\$RUNAS_ID set to 0, but \$UID is also 0!" && exit
46 fi
47 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
48 if getent group nobody; then
49         GROUP=nobody
50 elif getent group nogroup; then
51         GROUP=nogroup
52 else
53         error "No generic nobody group"
54 fi
55
56 build_test_filter
57
58 # if there is no CLIENT1 defined, some tests can be ran on localhost
59 CLIENT1=${CLIENT1:-$HOSTNAME}
60 # if CLIENT2 doesn't exist then use CLIENT1 instead
61 # All tests should use CLIENT2 with MOUNT2 only therefore it will work if
62 # $CLIENT2 == CLIENT1
63 # Exception is the test which need two separate nodes
64 CLIENT2=${CLIENT2:-$CLIENT1}
65
66 check_file_size()
67 {
68         local client="$1"
69         local fpath="$2"
70         local expected_size="$3"
71
72         size=$(do_facet $client stat "--printf=%s" $fpath)
73         [[ $size == "$expected_size" ]] || error \
74                 "expected $fpath size: $expected_size got: $size"
75 }
76
77 check_lpcc_sizes()
78 {
79         local client="$1"
80         local lpcc_fpath="$2"
81         local lustre_fpath="$3"
82         local expected_size="$4"
83
84         check_file_size $client $lpcc_fpath $expected_size
85         check_file_size $client $lustre_fpath $expected_size
86 }
87
88 check_file_data()
89 {
90         local client="$1"
91         local path="$2"
92         local expected_data="$3"
93
94         path_data=$(do_facet $client cat $path)
95         [[ "x$path_data" == "x$expected_data" ]] || error \
96                 "expected $path: $expected_data, got: $path_data"
97 }
98
99 check_lpcc_data()
100 {
101         local client="$1"
102         local lpcc_fpath="$2"
103         local lustre_fpath="$3"
104         local expected_data="$4"
105
106         check_file_data  "$client" "$lpcc_fpath" "$expected_data"
107         check_file_data  "$client" "$lustre_fpath" "$expected_data"
108 }
109
110 lpcc_fid2path()
111 {
112         local hsm_root="$1"
113         local lustre_path="$2"
114         local fid=$(path2fid $lustre_path)
115
116         local -a f_seq
117         local -a f_oid
118         local -a f_ver
119
120         f_seq=$(echo $fid | awk -F ':' '{print $1}')
121         f_oid=$(echo $fid | awk -F ':' '{print $2}')
122         f_ver=$(echo $fid | awk -F ':' '{print $3}')
123
124         printf "%s/%04x/%04x/%04x/%04x/%04x/%04x/%s" \
125                 $hsm_root $(($f_oid & 0xFFFF)) \
126                 $(($f_oid >> 16 & 0xFFFF)) \
127                 $(($f_seq & 0xFFFF)) \
128                 $(($f_seq >> 16 & 0xFFFF)) \
129                 $(($f_seq >> 32 & 0xFFFF)) \
130                 $(($f_seq >> 48 & 0xFFFF)) $fid
131 }
132
133 check_lpcc_state()
134 {
135         local lustre_path="$1"
136         local expected_state="$2"
137         local facet=${3:-$SINGLEAGT}
138         local state=$(do_facet $facet $LFS pcc state $lustre_path |
139                         awk -F 'type: ' '{print $2}' | awk -F ',' '{print $1}')
140
141         [[ "x$state" == "x$expected_state" ]] || error \
142                 "$lustre_path expected pcc state: $expected_state, but got: $state"
143 }
144
145 # initiate variables
146 init_agt_vars
147
148 # populate MDT device array
149 get_mdt_devices
150
151 # cleanup from previous bad setup
152 kill_copytools
153
154 # for recovery tests, coordinator needs to be started at mount
155 # so force it
156 # the lustre conf must be without hsm on (like for sanity.sh)
157 echo "Set HSM on and start"
158 cdt_set_mount_state enabled
159 cdt_check_state enabled
160
161 echo "Set sanity-hsm HSM policy"
162 cdt_set_sanity_policy
163
164 # finished requests are quickly removed from list
165 set_hsm_param grace_delay 10
166
167 cleanup_pcc_mapping() {
168         local facet=${1:-$SINGLEAGT}
169
170         do_facet $facet $LCTL pcc clear $MOUNT
171 }
172
173 setup_pcc_mapping() {
174         local facet=${1:-$SINGLEAGT}
175         local hsm_root=${hsm_root:-$(hsm_root "$facet")}
176         local param="$2"
177
178         [ -z "$param" ] && param="$HSM_ARCHIVE_NUMBER\ 100"
179         cleanup_pcc_mapping $facet
180         do_facet $facet $LCTL pcc add $MOUNT $hsm_root -p $param
181 }
182
183 lpcc_rw_test() {
184         local restore="$1"
185         local project="$2"
186         local project_id=100
187         local agt_facet=$SINGLEAGT
188         local hsm_root=$(hsm_root)
189         local file=$DIR/$tdir/$tfile
190         local -a state
191         local -a lpcc_path
192         local -a size
193
194         $project && enable_project_quota
195
196         do_facet $SINGLEAGT rm -rf $hsm_root
197         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
198
199         is_project_quota_supported || project=false
200
201         do_facet $SINGLEAGT mkdir -p $DIR/$tdir
202         setup_pcc_mapping
203         $project && lfs project -sp $project_id $DIR/$tdir
204
205         do_facet $SINGLEAGT "echo -n attach_origin > $file"
206         if ! $project; then
207                 check_lpcc_state $file "none"
208                 do_facet $SINGLEAGT $LFS pcc attach -i \
209                         $HSM_ARCHIVE_NUMBER $file ||
210                         error "pcc attach $file failed"
211         fi
212
213         check_lpcc_state $file "readwrite"
214         # HSM released exists archived status
215         check_hsm_flags $file "0x0000000d"
216         lpcc_path=$(lpcc_fid2path $hsm_root $file)
217         check_lpcc_data $SINGLEAGT $lpcc_path $file "attach_origin"
218
219         do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=7654321 count=1
220         check_lpcc_sizes $SINGLEAGT $lpcc_path $file 7654321
221
222         do_facet $SINGLEAGT $TRUNCATE $file 1234567 ||
223                 error "truncate failed"
224         check_lpcc_sizes $SINGLEAGT $lpcc_path $file 1234567
225         check_lpcc_state $file "readwrite"
226
227         do_facet $SINGLEAGT "echo -n file_data > $file"
228         check_lpcc_state $file "readwrite"
229         # HSM released exists archived status
230         check_hsm_flags $file "0x0000000d"
231         check_lpcc_data $SINGLEAGT $lpcc_path $file "file_data"
232
233         if [ $CLIENTCOUNT -lt 2 -o $restore ]; then
234                 $LFS hsm_restore $file || error \
235                         "failed to restore $file"
236                 wait_request_state $(path2fid $file) RESTORE SUCCEED
237         else
238                 path_data=$(do_node $CLIENT2 cat $file)
239                 [[ "x$path_data" == "xfile_data" ]] || error \
240                         "expected file_data, got: $path_data"
241         fi
242
243         check_lpcc_state $file "none"
244         # HSM exists archived status
245         check_hsm_flags $file "0x00000009"
246
247         echo -n "new_data" > $file
248         check_lpcc_state $file "none"
249         # HSM exists dirty archived status
250         check_hsm_flags $file "0x0000000b"
251         check_file_data $SINGLEAGT $file "new_data"
252
253         echo "Attach and detach testing"
254         rm -f $file
255         do_facet $SINGLEAGT "echo -n new_data2 > $file"
256         if ! $project; then
257                 check_lpcc_state $file "none"
258                 do_facet $SINGLEAGT $LFS pcc attach -i \
259                         $HSM_ARCHIVE_NUMBER $file ||
260                         error "PCC attach $file failed"
261         fi
262         check_lpcc_state $file "readwrite"
263         # HSM released exists archived status
264         check_hsm_flags $file "0x0000000d"
265         do_facet $SINGLEAGT "echo -n attach_detach > $file"
266         echo "Start to detach the $file"
267         do_facet $SINGLEAGT $LFS pcc detach $file ||
268                 error "PCC detach $file failed"
269         check_lpcc_state $file "none"
270         # HSM released exists archived status
271         check_hsm_flags $file "0x0000000d"
272         check_file_data $SINGLEAGT $file "attach_detach"
273
274         cleanup_pcc_mapping
275 }
276
277 test_1a() {
278         lpcc_rw_test true false
279 }
280 run_test 1a "Test manual lfs pcc attach with manual HSM restore"
281
282 test_1b() {
283         lpcc_rw_test false false
284 }
285 run_test 1b "Test manual lfs pcc attach with restore on remote access"
286
287 test_1c() {
288         lpcc_rw_test true true
289 }
290 run_test 1c "Test automated attach using Project ID with manual HSM restore"
291
292 test_1d() {
293         lpcc_rw_test false true
294 }
295 run_test 1d "Test Project ID with remote access"
296
297 #
298 # When a process created a LPCC file and holding the open,
299 # another process on the same client should be able to open the file.
300 #
301 test_2a() {
302         local project_id=100
303         local agt_facet=$SINGLEAGT
304         local hsm_root=$(hsm_root)
305         local agt_host=$(facet_active_host $SINGLEAGT)
306
307         ! is_project_quota_supported &&
308                 skip "project quota is not supported" && return
309
310         enable_project_quota
311         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
312         setup_pcc_mapping
313         file=$DIR/$tdir/multiop
314         mkdir -p $DIR/$tdir
315         rm -f $file
316
317         do_facet $SINGLEAGT $LFS project -sp $project_id $DIR/$tdir ||
318                 error "failed to set project quota"
319         rmultiop_start $agt_host $file O_c || error "open $file failed"
320         # HSM released exists archived status
321         check_hsm_flags $file "0x0000000d"
322         do_facet $SINGLEAGT "echo -n multiopen_data > $file" ||
323                 error "failed to echo multiopen_data to $file"
324
325         lpcc_path=$(lpcc_fid2path $hsm_root $file)
326         do_facet $SINGLEAGT ls -l $lpcc_path ||
327                 error "failed to ls $lpcc_path"
328         check_lpcc_data $SINGLEAGT $lpcc_path $file "multiopen_data"
329         # HSM released exists archived status
330         check_hsm_flags $file "0x0000000d"
331
332         rmultiop_stop $agt_host || error "close $file failed"
333         cleanup_pcc_mapping
334 }
335 run_test 2a "Test multi open when creating"
336
337 get_remote_client() {
338         current_id=$(do_facet $SINGLEAGT hostname)
339         for client in ${CLIENTS//,/ }
340         do
341                 r_id=$(do_node $client hostname)
342                 if [ $r_id != $current_id ]; then
343                         echo $client
344                         return
345                 fi
346         done
347 }
348
349 #
350 # When a process created a LPCC file and holding the open, another
351 # process on the different client should be able to open the file
352 # and perform IO on the file.
353 #
354 test_2b() {
355         local agt_facet=$SINGLEAGT
356         local hsm_root=$(hsm_root)
357         local agt_host=$(facet_active_host $SINGLEAGT)
358
359         needclients 2 || return 0
360
361         remote_client=$(get_remote_client)
362
363         enable_project_quota
364         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
365         setup_pcc_mapping
366         file=$DIR/$tdir/multiop
367         mkdir -p $DIR/$tdir
368         rm -f $file
369
370         do_facet $SINGLEAGT "echo -n file_data > $file"
371         do_facet $SINGLEAGT lfs pcc attach -i $HSM_ARCHIVE_NUMBER \
372                 $file || error "PCC attach $file failed"
373         check_lpcc_state $file "readwrite"
374
375         rmultiop_start $agt_host $file O_c || error "open $file failed"
376
377         do_node $remote_client "echo -n multiopen_data > $file"
378
379         # PCC cached file should be automatically detached
380         check_lpcc_state $file "none"
381
382         check_file_data $SINGLEAGT $file "multiopen_data"
383         rmultiop_stop $agt_host || error "close $file failed"
384         check_file_data $SINGLEAGT $file "multiopen_data"
385
386         do_node $remote_client cat $file || error \
387                 "cat $file on remote client failed"
388         do_node $remote_client echo -n "multiopen_data" > $file \
389                 || error "write $file on remote client failed"
390         cleanup_pcc_mapping
391 }
392 run_test 2b "Test multi remote open when creating"
393
394 test_2c() {
395         local agt_host=$(facet_active_host $SINGLEAGT)
396         local file=$DIR/$tdir/$tfile
397         local file2=$DIR2/$tdir/$tfile
398
399         enable_project_quota
400         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
401         setup_pcc_mapping
402         mkdir -p $DIR/$tdir
403         rm -f $file
404
405         do_facet $SINGLEAGT "echo -n file_data > $file"
406         do_facet $SINGLEAGT lfs pcc attach -i $HSM_ARCHIVE_NUMBER \
407                 $file || error "PCC attach $file failed"
408         check_lpcc_state $file "readwrite"
409
410         rmultiop_start $agt_host $file O_c || error "open $file failed"
411
412         echo -n multiopen_data > $file2
413
414         # PCC cached file should be automatically detached
415         check_lpcc_state $file "none"
416
417         check_file_data $SINGLEAGT $file "multiopen_data"
418         rmultiop_stop $agt_host || error "close $file failed"
419         check_file_data $SINGLEAGT $file "multiopen_data"
420
421         cat $file2 || error "cat $file on mount $MOUNT2 failed"
422         echo -n "multiopen_data" > $file2 ||
423                 error "write $file on mount $MOUNT2 failed"
424
425         cleanup_pcc_mapping
426 }
427 run_test 2c "Test multi open on different mount points when creating"
428
429 test_3a() {
430         local file=$DIR/$tdir/$tfile
431
432         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
433         setup_pcc_mapping
434
435         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
436         dd if=/dev/zero of=$file bs=1024 count=1 ||
437                 error "failed to dd write to $file"
438
439         echo "Start to attach/detach the file: $file"
440         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file ||
441                 error "failed to attach file $file"
442         check_lpcc_state $file "readwrite"
443         do_facet $SINGLEAGT $LFS pcc detach $file ||
444                 error "failed to detach file $file"
445         check_lpcc_state $file "none"
446
447         echo "Repeat to attach/detach the same file: $file"
448         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file ||
449                 error "failed to attach file $file"
450         check_lpcc_state $file "readwrite"
451         do_facet $SINGLEAGT $LFS pcc detach $file ||
452                 error "failed to detach file $file"
453         check_lpcc_state $file "none"
454
455         cleanup_pcc_mapping
456 }
457 run_test 3a "Repeat attach/detach operations"
458
459 test_3b() {
460         local n
461         local file=$DIR/$tdir/$tfile
462
463         needclients 3 || return 0
464
465         # Start all of the copytools and setup PCC
466         for n in $(seq $AGTCOUNT); do
467                 copytool setup -f agt$n -a $n -m $MOUNT
468                 setup_pcc_mapping agt$n "$n\ 100"
469         done
470
471         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
472         dd if=/dev/zero of=$file bs=1024 count=1 ||
473                 error "failed to dd write to $file"
474
475         echo "Start to attach/detach $file on $agt1_HOST"
476         do_facet agt1 $LFS pcc attach -i 1 $file ||
477                 error "failed to attach file $file"
478         check_lpcc_state $file "readwrite" agt1
479         do_facet agt1 $LFS pcc detach $file ||
480                 error "failed to detach file $file"
481         check_lpcc_state $file "none" agt1
482
483         echo "Repeat to attach/detach $file on $agt2_HOST"
484         do_facet agt2 $LFS pcc attach -i 2 $file ||
485                 error "failed to attach file $file"
486         check_lpcc_state $file "readwrite" agt2
487         do_facet agt2 $LFS pcc detach $file ||
488                 error "failed to detach file $file"
489         check_lpcc_state $file "none" agt2
490
491         echo "Try attach on two agents"
492         do_facet agt1 $LFS pcc attach -i 1 $file ||
493                 error "failed to attach file $file"
494         check_lpcc_state $file "readwrite" agt1
495         do_facet agt2 $LFS pcc attach -i 2 $file ||
496                 error "failed to attach file $file"
497         check_lpcc_state $file "readwrite" agt2
498         # The later attach PCC agent should succeed,
499         # the former agent should be detached automatically.
500         check_lpcc_state $file "none" agt1
501         do_facet agt2 $LFS pcc detach $file ||
502                 error "failed to detach file $file"
503         check_lpcc_state $file "none" agt2
504
505         for n in $(seq $AGTCOUNT); do
506                 cleanup_pcc_mapping agt$n
507         done
508 }
509 run_test 3b "Repeat attach/detach operations on multiple clients"
510
511 test_4() {
512         local project_id=100
513
514         ! is_project_quota_supported &&
515                 skip "project quota is not supported" && return
516
517         enable_project_quota
518         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
519         setup_pcc_mapping
520
521         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
522         lfs project -sp $project_id $DIR/$tdir ||
523                 error "lfs project -sp $project_id $DIR/$tdir failed"
524
525         # mmap_sanity tst7 failed on the local ext4 filesystem.
526         # It seems that Lustre filesystem does special process for tst 7.
527         # Thus, we exclude tst7 from the PCC testing.
528         $LUSTRE/tests/mmap_sanity -d $DIR/$tdir -m $DIR2/$tdir -e 7 ||
529                 error "mmap_sanity test failed"
530         sync; sleep 1; sync
531
532         cleanup_pcc_mapping
533 }
534 run_test 4 "Auto cache test for mmap"
535
536 test_5() {
537         local file=$DIR/$tdir/$tfile
538
539         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
540         setup_pcc_mapping
541
542         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
543         do_facet $SINGLEAGT "echo -n attach_mmap_data > $file" ||
544                 error "echo $file failed"
545
546         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file ||
547                 error "failed to attach file $file"
548         check_lpcc_state $file "readwrite"
549
550         local content=$($MMAP_CAT $file)
551
552         [[ $content == "attach_mmap_data" ]] ||
553                 error "mmap cat data mismatch: $content"
554
555         $LFS hsm_restore $file || error "failed to restore $file"
556         wait_request_state $(path2fid $file) RESTORE SUCCEED
557         check_lpcc_state $file "none"
558
559         content=$($MMAP_CAT $file)
560         [[ $content == "attach_mmap_data" ]] ||
561                 error "mmap cat data mismatch: $content"
562
563         cleanup_pcc_mapping
564 }
565 run_test 5 "Mmap & cat a RW-PCC cached file"
566
567 test_6() {
568         local file=$DIR/$tdir/$tfile
569         local content
570
571         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
572         setup_pcc_mapping
573
574         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
575
576         echo -n mmap_write_data > $file || error "echo write $file failed"
577         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file ||
578                 error "failed to attach file $file"
579         check_lpcc_state $file "readwrite"
580
581         do_facet $SINGLEAGT $MULTIOP $file OSMWUc ||
582                 error "could not mmap $file"
583         check_lpcc_state $file "readwrite"
584         content=$(do_facet $SINGLEAGT $MMAP_CAT $file)
585         # After mmap write via multiop, the first character of each page
586         # increases with 1.
587         [[ $content == "nmap_write_data" ]] ||
588                 error "mmap write data mismatch: $content"
589         check_lpcc_state $file "readwrite"
590
591         do_facet $SINGLEAGT $LFS pcc detach $file ||
592                 error "failed to detach file $file"
593
594         content=$(do_facet $SINGLEAGT $MMAP_CAT $file)
595         [[ $content == "nmap_write_data" ]] ||
596                 error "mmap write data mismatch: $content"
597
598         cleanup_pcc_mapping
599 }
600 run_test 6 "Test mmap write on RW-PCC "
601
602 test_7a() {
603         local file=$DIR/$tdir/$tfile
604         local content
605
606         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
607         setup_pcc_mapping
608
609         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
610         echo "QQQQQ" > $file
611         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file ||
612                 error "failed to attach file $file"
613         check_lpcc_state $file "readwrite"
614         check_file_data $SINGLEAGT $file "QQQQQ"
615         # define OBD_FAIL_LLITE_PCC_DETACH_MKWRITE      0x1412
616         do_facet $SINGLEAGT $LCTL set_param fail_loc=0x1412
617         # HSM released exists archived status
618         check_hsm_flags $file "0x0000000d"
619
620         # multiop mmap write increase the first character of each page with 1
621         do_facet $SINGLEAGT $MULTIOP $file OSMWUc ||
622                 error "mmap write $file failed"
623         check_lpcc_state $file "none"
624         content=$(do_facet $SINGLEAGT $MMAP_CAT $file)
625         [[ $content == "RQQQQ" ]] || error "data mismatch: $content"
626
627         cleanup_pcc_mapping
628 }
629 run_test 7a "Fake file detached between fault() and page_mkwrite() for RW-PCC"
630
631 test_7b() {
632         local file=$DIR/$tdir/$tfile
633         local content
634         local pid
635
636         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
637         setup_pcc_mapping
638
639         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
640         echo "QQQQQ" > $file
641         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file ||
642                 error "failed to attach file $file"
643         check_lpcc_state $file "readwrite"
644         check_file_data $SINGLEAGT $file "QQQQQ"
645         # define OBD_FAIL_LLITE_PCC_MKWRITE_PAUSE       0x1413
646         do_facet $SINGLEAGT $LCTL set_param fail_loc=0x1413 fail_val=20
647         # HSM released exists archived status
648         check_hsm_flags $file "0x0000000d"
649
650         # multiop mmap write increase the first character of each page with 1
651         do_facet $SINGLEAGT $MULTIOP $file OSMWUc &
652         pid=$!
653
654         do_facet $SINGLEAGT $LFS pcc detach $file ||
655                 error "failed to detach file $file"
656
657         wait $pid || error "multiop mmap write failed"
658         check_lpcc_state $file "none"
659         content=$(do_facet $SINGLEAGT $MMAP_CAT $file)
660         [[ $content == "RQQQQ" ]] || error "data mismatch: $content"
661
662         cleanup_pcc_mapping
663 }
664 run_test 7b "Test the race with concurrent mkwrite and detach"
665
666 test_8() {
667         local file=$DIR/$tdir/$tfile
668
669         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
670         setup_pcc_mapping
671
672         mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
673
674         echo "QQQQQ" > $file
675         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file ||
676                 error "failed to attach file $file"
677         check_lpcc_state $file "readwrite"
678         check_file_data $SINGLEAGT $file "QQQQQ"
679
680         # define OBD_FAIL_LLITE_PCC_FAKE_ERROR  0x1411
681         do_facet $SINGLEAGT $LCTL set_param fail_loc=0x1411
682         do_facet $SINGLEAGT "echo -n ENOSPC_write > $file"
683         # Above write will return -ENOSPC failure and retry the IO on normal
684         # IO path. It will restore the HSM released file.
685         check_lpcc_state $file "none"
686         check_file_data $SINGLEAGT $file "ENOSPC_write"
687
688         cleanup_pcc_mapping
689 }
690 run_test 8 "Test fake -ENOSPC tolerance for RW-PCC"
691
692 setup_loopdev() {
693         local facet=$1
694         local file=$2
695         local mntpt=$3
696         local size=${4:-50}
697
698         do_facet $facet mkdir -p $mntpt || error "mkdir -p $hsm_root failed"
699         stack_trap "do_facet $facet rm -rf $mntpt" EXIT
700         do_facet $facet dd if=/dev/zero of=$file bs=1M count=$size
701         stack_trap "do_facet $facet rm -f $file" EXIT
702         do_facet $facet mkfs.ext4 $file ||
703                 error "mkfs.ext4 $file failed"
704         do_facet $facet file $file
705         do_facet $facet mount -t ext4 -o loop,usrquota,grpquota $file $mntpt ||
706                 error "mount -o loop,usrquota,grpquota $file $mntpt failed"
707         stack_trap "do_facet $facet $UMOUNT $mntpt" EXIT
708 }
709
710 test_9() {
711         local loopfile="$TMP/$tfile"
712         local mntpt="/mnt/pcc.9a"
713         local hsm_root="$mntpt/$tdir"
714         local file=$DIR/$tfile
715
716         setup_loopdev $SINGLEAGT $loopfile $mntpt 50
717
718         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMVER" -h "$hsm_root"
719         setup_pcc_mapping
720         do_facet $SINGLEAGT $LCTL pcc list $MOUNT
721
722         touch $file || error "touch $file failed"
723         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file ||
724                 error "fail to attach $file"
725         check_lpcc_state $file "readwrite"
726         # write 60M data, it is larger than the capacity of PCC backend
727         do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=1M count=60 ||
728                 error "fail to dd write $file"
729         check_lpcc_state $file "none"
730         check_file_size $SINGLEAGT $file 62914560
731
732         cleanup_pcc_mapping
733 }
734 run_test 9 "Test -ENOSPC tolerance on loop PCC device for RW-PCC"
735
736 test_10() {
737         local file=$DIR/$tdir/$tfile
738         local hsm_root=$(hsm_root)
739         local file=$DIR/$tdir/$tfile
740         local -a lpcc_path
741         local lpcc_dir
742
743         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
744         setup_pcc_mapping
745
746         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
747         do_facet $SINGLEAGT "echo -n QQQQQ > $file"
748         lpcc_path=$(lpcc_fid2path $hsm_root $file)
749         lpcc_dir=$(dirname $lpcc_path)
750         echo "Lustre file: $file LPCC dir: $lpcc_dir"
751         do_facet $SINGLEAGT mkdir -p $lpcc_dir ||
752                 error "mkdir -p $lpcc_dir failed"
753         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file ||
754                 error "failed to attach $file"
755         check_lpcc_state $file "readwrite"
756         check_file_data $SINGLEAGT $file "QQQQQ"
757         do_facet $SINGLEAGT $LFS pcc detach $file ||
758                 error "failed to detach $file"
759         rm $file || error "rm $file failed"
760
761         # The parent directory of the PCC file is immutable
762         do_facet $SINGLEAGT "echo -n immutable_dir > $file"
763         lpcc_path=$(lpcc_fid2path $hsm_root $file)
764         lpcc_dir=$(dirname $lpcc_path)
765         echo "Lustre file: $file LPCC dir: $lpcc_dir"
766         do_facet $SINGLEAGT mkdir -p $lpcc_dir ||
767                 error "mkdir -p $lpcc_dir failed"
768         do_facet $SINGLEAGT chattr +i $lpcc_dir ||
769                 error "chattr +i $lpcc_dir failed"
770         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file &&
771                 error "attach $file with immutable directory should be failed"
772         do_facet $SINGLEAGT chattr -i $lpcc_dir ||
773                 error "chattr -i $lpcc_dir failed"
774         rm $file || error "rm $file failed"
775
776         # The PCC file path is set to a directory
777         do_facet $SINGLEAGT "echo -n pcc_file_path_is_dir > $file"
778         lpcc_path=$(lpcc_fid2path $hsm_root $file)
779         do_facet $SINGLEAGT mkdir -p $lpcc_path ||
780                 error "mkdir -p $lpcc_path failed"
781         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file &&
782                 error "attach $file should fail as PCC path is a directory"
783         rm $file || error "rm $file failed"
784
785         cleanup_pcc_mapping
786 }
787 run_test 10 "Test attach fault injection with simulated PCC file path"
788
789 test_11() {
790         local file=$DIR/$tfile
791         local pid
792
793         copytool setup -m "$MOUNT" -a "$HSM_ARCHIVE_NUMBER"
794         setup_pcc_mapping
795
796         echo  -n race_rw_attach_hsmremove > $file
797         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file ||
798                 error "attach $file failed"
799         do_facet $SINGLEAGT $LFS pcc detach $file || error "detach $file failed"
800         # HSM released exists archived status
801         check_hsm_flags $file "0x0000000d"
802         # define OBD_FAIL_LLITE_PCC_ATTACH_PAUSE        0x1414
803         do_facet $SINGLEAGT $LCTL set_param fail_loc=0x1414 fail_val=20
804         do_facet $SINGLEAGT $LFS pcc attach -i $HSM_ARCHIVE_NUMBER $file &
805         pid=$!
806         $LFS hsm_state $file
807         sleep 3
808         wait_request_state $(path2fid $file) RESTORE SUCCEED
809         $LFS hsm_remove $file || error "hsm remove $file failed"
810         wait $pid && error "RW-PCC attach $file should fail"
811
812         cleanup_pcc_mapping
813 }
814 run_test 11 "RW-PCC attach races with concurrent HSM remove"
815
816 complete $SECONDS
817 check_and_cleanup_lustre
818 exit_status