When administering a Linux multiuser system with many system users, it is wise to set some kind of restrictions or limits to the resources shared by the system. On a filesystem level, you can either restrict the available hard disk space or the total file number to a fixed size at a user, group, or directory level. The introduction of such rules can prevent people from "spamming" the system, filling up its free space, and generally your users will get more aware of the differentiation between important and unimportant data and will be more likely to keep their home directories tidy and clean. Here in this recipe, we will show you how to set up a disk quota limiting system for XFS filesystems, which puts restrictions on the amount of data your system's user accounts are allowed to store.
To complete this recipe, you will require a minimal installation of the CentOS 7 operating system with root access and a console-based text editor of your choice. For this recipe to work, and in order to set quotas, you will need at least one system user account next to your root account; if you don't have one yet, please refer to the recipe Managing users and their groups in Chapter 3, Managing the System to learn how to create one. Also, in the main recipe, it is expected that your CentOS 7 uses the XFS filesystem, which is standard on installation. Finally, your CentOS 7 installation needs to have been installed on a disk with at least 64 GB space, otherwise the installer will not create a separate logical /home
volume, which is required in this recipe to make quotas work.
Here, we will learn how to set up a quota system for the XFS filesystem in two different ways: first, setting limits on the user and groups, and then on the directory (project) level. Disk quota systems have to be set on filesystem mount.
root
and open the fstab
file, which contains static mount information:vi /etc/fstab
/home
(with the up and down arrow keys) and move it to the word defaults
, and then add the following text after defaults
, separated by commas:,uquota,gquota
myserver
):/dev/mapper/myserver-home /home XFS defaults,uquota,gquota 0 0
/home
partition to activate the quota
directive:umount /home;mount -a
john
(change appropriately to match a user available on your system):xfs_quota -x -c 'limit bsoft=768m bhard=1g john' /home/
joe
, can have:xfs_quota -x -c 'limit isoft=1000 ihard=5000 joe' /home/
devgrp
(the filesystem group devgrp
must exist):xfs_quota -x -c 'limit -g bsoft=5g bhard=6g isoft=10000 ihard=50000 devgrp' /home
home
volume:xfs_quota -x -c 'report -bi -h' /home
In order to enable disk quotas for a single directory instead of user or group quotas, we have to add the project quota directive called pquota
to the volume containing the directory. As we will use a directory called /srv/data
for our project quota, we need to take the full underlying /
root partition under quota control. For the root partition, we have to set quota flags as kernel boot options:
cp /etc/default/grub /etc/default/grub.BAK vi /etc/default/grub
rootflags=pquota
directive to the end of the line (add one whitespace character before it) starting with GRUB_CMDLINE_LINUX=
before the closing double quote as shown here:GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap crashkernel=auto rhgb quiet rootflags=pquota"
grub
configuration with our new boot
option:grub2-mkconfig -o /boot/grub2/grub.cfg
pquota
flag to your root volume in /etc/fstab
as well:vi /etc/fstab
defaults
, and then add the following text, separated by a comma:,prjquota
/dev/mapper/myserver-root / XFS defaults,prjquota 0 0
root
volume:reboot
root
volume has project quota enabled, which is defined as the prjquota
flag in the volume's options (otherwise, if it is wrong and doesn't work, it will show as noquota
):cat /etc/mtab | grep root
mkdir /srv/data
echo "myProject:1400" >> /etc/projid
/srv/data
will use quota rules from our project ID:echo "1400:/srv/data" >> /etc/projects
project
quota for the root
volume:xfs_quota -xc 'project -s myProject' /
xfs_quota -x -c 'limit -p bsoft=1000m bhard=1200m myProject' /
xfs_quota -x -c 'report -bi -h' /
In this recipe, you learned how easy it is to set up a quota system on a user, group, or directory (project) level. Also, you have learned that there are two basic ways of defining quotas: either put a restriction on the total file size (called blocks), or a limit on the number of files (called inodes).
So, what have we learned from this experience?
We began this recipe by setting user and group quotas. As you have seen, a quota system can easily be enabled by adding associated directives to the partition of choice in the /etc/fstab
file. Therefore, we began this recipe by opening this file and adding the special quota keywords for the XFS user, and group quotas to our /home
partition. In order to apply these changes, we had to remount the filesystem using the mount
command. As the quota system had been successfully started, we used the xfs_quota -x -c
command line to set some quota limits on our enabled filesystem /home
. -x
enables expert mode while -c
lets us run commands as arguments on the command line. When running xfs_quota
without the -c
option, you will get to an interactive prompt instead. First, we set some user limits for the users, john
and joe
. We did this by defining the following parameters with numbers: bsoft
, bhard
, isoft
, ihard
. As you can see, there are both soft and hard limits for file size (blocks) and file amount (inodes). Block quotas can be given in the typical metrics such as kilobyte (k
), megabyte (m
), and gigabyte (g
), whereas an inode is a number. A soft limit is a threshold that, when crossed, prints out a warning message to the command line, whereas a hard limit will stop the user from adding any more data or files to the filesystem under quota protection. Afterwards, we set a group-based quota. If you use the -g
flag, the limit will be defined for a group instead of the user. Using group rules can be very helpful to separate your users into different groups depending on the amount of files or total file size they should be allowed to have. Finally, we generated a report for all our current quota limits. The command we used there was 'report -bi -h'
, which generates reports for used filespace (-b
for blocks) and the total amount of files (-i
for inodes). -h
specified that we want the output to be human-readable in megabytes or gigabytes.
To test that quotas work, let's create the following block and inode quotas for the user jack
:
xfs_quota -x -c 'limit bhard=20m jack' /home/ xfs_quota -x -c 'limit ihard=1000 jack' /home/
Log in as the user jack
(su - jack
) and run the following command:
dd if=/dev/urandom of=~/test.dd bs=1M count=21
With this command, the user john
will try to create a 21 megabyte size file, but when starting to write the twentieth megabyte, the following error message will appear:
dd: error writing '/home/jack/test.dd': Disk quota exceeded
Now, delete the ~/test.dd
file so that we can start another test. The same happens if you exceed your file amount limit. Test the following quota limit by trying to create 2,000 multiple files while the quota is limited to 1,000; do this by adding a lot of new files: for i in {1..2000}; do touch ~/test$i.txt; done
. This results in the following error message:
touch: cannot touch '/home/jack/test1001.txt': Disk quota exceeded
To temporarily turn off user and group quota checking for a specific filesystem, you can run xfs_quota -x -c 'off -u -g' /home/
(-u
for user, -g
for group) as root
user. This is only temporary; to re-enable it, you need to remount the filesystem of interest, which is umount /home;mount -a
. To remove a specific quota rule, just set its limit to zero, for example:
xfs_quota -x -c 'limit bhard=0 john' /home
Next, we set up quota on a directory, instead of the user/group level. This is a feature only XFS file systems are capable of; all other filesystems can only set quotas on a disk or partition level. Being able to control the disk usage of a directory hierarchy is useful if you do not otherwise want to set quota limits for a privileged user or groups. To activate directory quota, we first had to enable this as a kernel boot option because, by default, the root volume is flagged as noquota
. Also, we added the prjquota
directive in /etc/fstab
to the root partition to make it work. If you want to learn more about kernel boot options, read the boot loader recipe in Chapter 15, Installing CentOS. To set file system flags for the root partition, we needed to reboot the system. After doing this, we made sure that the boot option has been set successfully by looking into the mtab
file, which is a file that lists all currently mounted filesystems. Next, we set up a project name with an associated unique project ID (we randomly choose 1400
) in the /etc/projid
file. In the next step, we applied this new project ID (1400
) to a directory in the /etc/projects
file called /srv/data
. This system allows the application of specific project quota rules to many different directories. Afterwards, we initialized project quota for the root partition using the project
option with the xfs_quota
command, and then created a limit
quota rule for this project name. All directories that are defined in the /etc/projects
file under the corresponding project id are affected by this rule. This type of system can be used for fine-grain multiple folder quota rules. For every directory, you can set up a new project name or reuse a specific one, making this system very flexible.
In this recipe, we have created a block size hard limit of 1,200 megabytes for our project name, which is myProject
. To test this quota, type the following:
dd if=/dev/zero of=/srv/data/dd.img bs=1M count=1201
This should stop dd
, exactly after writing 1200 megabytes, with the following command line error message:
dd: error writing '/srv/data/dd.img': No space left on device
As the name implies, the xfs_quota
program shown in this recipe only works for XFS filesystems. If you want to use disk quotas on a user or group level for other file systems such as ext4 or btrfs, you have to install the quota
package (yum install quota
). Setting quotas works in a similar way to the steps shown in this recipe; please read the manual man quota
to get you started.