#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2011 SGI. All Rights Reserved. # # FS QA Test No. 386 # # This test checks the project quota values reported by the quota # "df" and "report" subcommands to ensure they match what they # should be. There was a bug (fixed by xfsprogs commit 7cb2d41b) # where the values reported were double what they should have been. # # SGI PV 1015651 # seq=$(basename $0) seqres=$RESULT_DIR/$seq echo "QA output created by $seq" here=$(pwd) rm -f $seqres.full tmp=/tmp/$$ my_projects=$tmp.projects my_projid=$tmp.projid proj_name=test_project proj_num=1 qlimit_meg=500 # 500M limit imposed = 500 * 1024 * 1024 bytes status=1 # failure is the default! trap "_cleanup; exit \$status" 0 1 2 3 15 _cleanup() { cd / rm -f $tmp.* } # get standard environment, filters and checks . ./common/rc . ./common/filter . ./common/quota echo "Silence is golden." # real QA test starts here proj_dir="$SCRATCH_MNT/test" # Modify as appropriate. _supported_fs generic _supported_os Linux _require_quota _require_xfs_quota_foreign _require_scratch # Make sure the hard limits reported are what was set. # It is entirely too clever... # It exploits the fact that we've set the soft and hard limits to # the same value, and as a result the value in the fourth field in # both the "df" and the "report" output. For "report", the line we're # interested in contains our project name in the first field. For "df" # it contains our project directory in the last field. # But if the device name is too long, the "df" output is broke into two # lines, the fourth field is not correct, so take $(nf-2) of "df" _filter_quota_rpt() { awk ' BEGIN { proj_name = "'${proj_name}'"; proj_dir = "'${proj_dir}'"; qlimit_meg = '${qlimit_meg}'; qlimit = qlimit_meg * 1024 * 1024; } # This function parses the human-readable values produced # by xfs_quota output function byte_size(value, result) { result = strtonum(value); unit = value; gsub("[0-9][0-9]*", "", unit); shift = index("KMGTPE", unit); while (shift--) result *= 1024; return result; } { if ($1 =~ proj_name) { # this is the "report" output bsize = byte_size($4); } else if ($nf =~ proj_dir) { # this is the "df" output bsize = byte_size($(nf-2)); } else { next; } if (bsize != qlimit) printf("hard limit %d bytes, expected %d\n", bsize, qlimit); } ' } _quota_cmd() { $XFS_QUOTA_PROG -P "$my_projid" -D "$my_projects" -x \ -c "$@" "$SCRATCH_MNT" } # Set up--mount scratch and create the project directory echo $proj_name:$proj_num > "$my_projid" echo $proj_num:$proj_dir > "$my_projects" _scratch_mkfs >> "$seqres.full" 2>&1 _scratch_enable_pquota _qmount_option "prjquota" _qmount _require_prjquota $SCRATCH_DEV mkdir -p "${proj_dir}" # Setup the project quota directory _quota_cmd "project -s ${proj_name}" >> "$seqres.full" 2>&1 # Assign block quota limits _quota_cmd "limit -p bhard=${qlimit_meg}m bsoft=${qlimit_meg}m ${proj_name}" \ 2>> "$seqres.full" 1>&2 # See what gets reported _quota_cmd "report" | _filter_quota_rpt 2>> "$seqres.full" _quota_cmd "df" | _filter_quota_rpt 2>> "$seqres.full" # This time using "human readable" output _quota_cmd "report -h" | _filter_quota_rpt 2>> "$seqres.full" _quota_cmd "df -h" | _filter_quota_rpt 2>> "$seqres.full" # Clean up rm -rf "$proj_dir" _scratch_unmount status=0 # success, all done