| #! /bin/bash |
| # 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 |
| # |
| #----------------------------------------------------------------------- |
| # Copyright (c) 2011 SGI. All Rights Reserved. |
| # |
| # This program is free software; you can redistribute it and/or |
| # modify it under the terms of the GNU General Public License as |
| # published by the Free Software Foundation. |
| # |
| # This program is distributed in the hope that it would be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program; if not, write the Free Software Foundation, |
| # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| #----------------------------------------------------------------------- |
| # |
| |
| 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 |