}
run_test 100 "race among PCC unlink | read | write | detach for PCC-RO file"
+test_200() {
+ local loopfile="$TMP/$tfile"
+ local mntpt="/mnt/pcc.$tdir"
+ local hsm_root="$mntpt/$tdir"
+ local file=$DIR/$tfile
+ local high_usage=90
+ local low_usage=50
+
+ $LCTL get_param -n mdc.*.connect_flags | grep -q pcc_ro ||
+ skip "Server does not support PCC-RO"
+
+ setup_loopdev $SINGLEAGT $loopfile $mntpt 14
+ do_facet $SINGLEAGT mkdir $hsm_root || error "mkdir $hsm_root failed"
+ setup_pcc_mapping $SINGLEAGT \
+ "fname={*.dat}\ roid=$HSM_ARCHIVE_NUMBER\ ropcc=1"
+ do_facet $SINGLEAGT $LCTL pcc list $MOUNT
+
+ # create 100 data files
+ mkdir $DIR/$tdir
+ for i in {1..100}; do
+ file=$DIR/$tdir/$tfile.$i.dat
+ do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=100K count=1 status=none ||
+ error "Write $file failed"
+ done
+
+ # read the 100 data files, expect 96% pcc usage in this case
+ for i in {1..100}; do
+ file=$DIR/$tdir/$tfile.$i.dat
+ do_facet $SINGLEAGT cat $file > /dev/null ||
+ error "Read $file failed"
+ done
+
+ # Get cache usage
+ usage=$(do_facet $SINGLEAGT df $mntpt --output=pcent | tail -n +2 | sed 's/%//')
+ usage=$(echo $usage) # remove leading spaces
+ if [[ -z "$usage" ]]; then
+ error "Failed to get disk usage of cache device $mntpt"
+ elif [[ "$usage" -lt "$high_usage" ]]; then
+ error "cache device usage ($usage) < high_usage ($high_usage)"
+ else
+ echo "cache device usage($usage) >= high_usage($high_usage)"
+ fi
+
+ pidfile=lpcc_purge-${HSM_ARCHIVE_NUMBER}.pid
+ do_facet $SINGLEAGT /usr/bin/lpcc_purge --mount $MOUNT --cache $hsm_root \
+ --high-usage $high_usage --low-usage $low_usage \
+ --roid $HSM_ARCHIVE_NUMBER --pidfile $pidfile --interval 1 -b &
+ sleep 5
+ do_facet $SINGLEAGT pkill --pidfile $pidfile -- lpcc_purge
+
+ # Get cache usage
+ usage=$(do_facet $SINGLEAGT df $mntpt --output=pcent | tail -n +2 | sed 's/%//')
+ usage=$(echo $usage) # remvoe leading spaces
+ if [[ -z "$usage" ]]; then
+ error "Failed to get disk usage of cache device $mntpt"
+ elif [[ "$usage" -gt "50" ]]; then
+ error "cache device usage ($usage) > low_usage ($low_usage)"
+ else
+ echo "cache device usage($usage) <= low_usage($low_usage)"
+ fi
+
+ for i in {1..100}; do
+ file=$DIR/$tdir/$tfile.$i.dat
+ do_facet $SINGLEAGT $LFS pcc detach $file
+ done
+}
+run_test 200 "lpcc_purge: purge files from >high_usage to <low_usage"
+
+test_201() {
+ local loopfile="$TMP/$tfile"
+ local mntpt="/mnt/pcc.$tdir"
+ local hsm_root="$mntpt/$tdir"
+ local file=$DIR/$tfile
+ local high_usage=90
+ local low_usage=50
+
+ $LCTL get_param -n mdc.*.connect_flags | grep -q pcc_ro ||
+ skip "Server does not support PCC-RO"
+
+ setup_loopdev $SINGLEAGT $loopfile $mntpt 14
+ do_facet $SINGLEAGT mkdir $hsm_root || error "mkdir $hsm_root failed"
+ setup_pcc_mapping $SINGLEAGT \
+ "fname={*.dat}\ roid=$HSM_ARCHIVE_NUMBER\ ropcc=1"
+ do_facet $SINGLEAGT $LCTL pcc list $MOUNT
+
+ # create 100 data files
+ mkdir $DIR/$tdir
+ for i in {1..100}; do
+ file=$DIR/$tdir/$tfile.$i.dat
+ do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=100K count=1 status=none ||
+ error "Write $file failed"
+ done
+
+ # read 80 data files, expect pcc usage between low and high
+ for i in {1..80}; do
+ file=$DIR/$tdir/$tfile.$i.dat
+ do_facet $SINGLEAGT cat $file > /dev/null ||
+ error "Read $file failed"
+ done
+
+ # Get cache usage
+ usage=$(do_facet $SINGLEAGT df $mntpt --output=pcent | tail -n +2 | sed 's/%//')
+ usage=$(echo $usage) # remove leading spaces
+ if [[ -z "$usage" ]]; then
+ error "Failed to get disk usage of cache device $mntpt"
+ elif [[ "$usage" -gt "$high_usage" || "$usage" -lt "$low_usage" ]]; then
+ error "cache device usage ($usage) out of range ($low_usage, $high_usage)"
+ else
+ echo "cache device usage ($usage)"
+ fi
+
+ pidfile=lpcc_purge-${HSM_ARCHIVE_NUMBER}.pid
+ do_facet $SINGLEAGT /usr/bin/lpcc_purge --mount $MOUNT --cache $hsm_root \
+ --high-usage $high_usage --low-usage $low_usage \
+ --roid $HSM_ARCHIVE_NUMBER --pidfile $pidfile --interval 1 -b &
+ sleep 5
+ do_facet $SINGLEAGT pkill --pidfile $pidfile -- lpcc_purge
+
+ # Get cache usage
+ usage2=$(do_facet $SINGLEAGT df $mntpt --output=pcent | tail -n +2 | sed 's/%//')
+ usage2=$(echo $usage2) # remvoe leading spaces
+ if [[ -z "$usage2" ]]; then
+ error "Failed to get disk usage of cache device $mntpt"
+ elif [[ "$usage2" != "$usage" ]]; then
+ error "cache device usage changed"
+ else
+ echo "cache device usage did not change"
+ fi
+
+ for i in {1..100}; do
+ file=$DIR/$tdir/$tfile.$i.dat
+ do_facet $SINGLEAGT $LFS pcc detach $file
+ done
+}
+run_test 201 "lpcc_purge: do nothing if usage is between low_usage and high_usage"
+
+test_202() {
+ local loopfile="$TMP/$tfile"
+ local mntpt="/mnt/pcc.$tdir"
+ local hsm_root="$mntpt/$tdir"
+ local file=$DIR/$tfile
+ local high_usage=90
+ local low_usage=50
+ local non_cache_file=$hsm_root/non_cache_file_1
+
+ $LCTL get_param -n mdc.*.connect_flags | grep -q pcc_ro ||
+ skip "Server does not support PCC-RO"
+
+ setup_loopdev $SINGLEAGT $loopfile $mntpt 14
+ do_facet $SINGLEAGT mkdir $hsm_root || error "mkdir $hsm_root failed"
+ setup_pcc_mapping $SINGLEAGT \
+ "fname={*.dat}\ roid=$HSM_ARCHIVE_NUMBER\ ropcc=1"
+ do_facet $SINGLEAGT $LCTL pcc list $MOUNT
+
+ # create 100 data files
+ mkdir $DIR/$tdir
+ for i in {1..100}; do
+ file=$DIR/$tdir/$tfile.$i.dat
+ do_facet $SINGLEAGT dd if=/dev/zero of=$file bs=100K count=1 status=none ||
+ error "Write $file failed"
+ done
+
+ # create an independent file not matching the FID format
+ do_facet $SINGLEAGT touch $non_cache_file ||
+ error "Cannot create file '$non_cache_file'"
+ # read the files one by one, sleep 0.1 sec after each file
+ for i in {1..100}; do
+ file=$DIR/$tdir/$tfile.$i.dat
+ do_facet $SINGLEAGT cat $file > /dev/null ||
+ error "Read $file failed"
+ sleep 0.1
+ done
+
+ pidfile=lpcc_purge-${HSM_ARCHIVE_NUMBER}.pid
+ do_facet $SINGLEAGT /usr/bin/lpcc_purge --mount $MOUNT --cache $hsm_root \
+ --high-usage $high_usage --low-usage $low_usage \
+ --roid $HSM_ARCHIVE_NUMBER --pidfile $pidfile --interval 1 -b &
+ sleep 5
+ do_facet $SINGLEAGT pkill --pidfile $pidfile -- lpcc_purge
+
+ # verify that the independent file was not removed
+ do_facet $SINGLEAGT test -f $non_cache_file ||
+ error "the independent file '$non_cache_file' was removed"
+ do_facet $SINGLEAGT rm -f $non_cache_file
+
+ # there should be 54 files been purged
+ # in theroy, file 1-54 should be purge, 55-100 should be kept.
+ # But since we are an approxomate LRU algorithm, we test f.50 being
+ # purged and f.60 not
+
+ file=$DIR/$tdir/$tfile.50.dat
+ check_lpcc_state $file "none"
+ file=$DIR/$tdir/$tfile.60.dat
+ check_lpcc_state $file "readonly"
+
+ for i in {1..100}; do
+ file=$DIR/$tdir/$tfile.$i.dat
+ do_facet $SINGLEAGT $LFS pcc detach $file
+ done
+}
+run_test 202 "lpcc_purge: match cache file name and approximate LRU"
+
complete $SECONDS
check_and_cleanup_lustre
exit_status