Setting up quotas on a local linux file system

This is a short guide for setting up disk quotas on a local Linux file system. In this example, I am using Debian Wheezy and configure a quota for the root partition (ext4 in this case) affecting a single user. I try to note down important information that I missed in other references when searching the web.

1) Modify partition entry in /etc/fstab

Add the following options for journaled quotas to the partition of interest in /etc/fstab:

usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0

For me, the entire line looks like this:

UUID=e5aff151-ddf7-4d43-a318-7e97afcfd78e / ext4 errors=remount-ro,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0 0 1

This activates quotas by user and/or group ID using the “vfsv0” quota format (using 32 bit for UIDs/GIDs, 64 bit for space usage, and 32 bit for inode usage in this case).

2) Remount the partition (no reboot required):

# mount -o remount /

3) Install packages:

# apt-get install quota quotatool

This activates quotas during setup:

Setting up quota (4.00-4+deb7u1) ...
[ ok ] Checking quotas...done.
[ ok ] Turning on quotas...done.

Still, the bookkeeping files need to be created, which is automatically done by the command

quotacheck -vagum

4) Setting an actual quota: preparations

There are multiple ways to actually set a quota. Currently, quotatools in Wheezy is affected by a bug. I decided to use the canonical setquota command with the signature

setquota [ -rm ] [ -u | -g ] [ -F quotaformat ] name block-softlimit block-hardlimit inode-softlimit inode-hardlimit -a | filesystem

Setting a disk usage limit in common data volume units such as MB or GB requires knowledge about the block size in bytes that is used by the kernel for interpreting quotas. In many places, people state that the file system block size is key for quotas. Actually, it is not. The block size used for the quota system is defined in linux kernel header file sys/mount.h. It is therefore independent of the individual file system configuration. In my case, and on most Unix systems, one ‘quota block’ is 1024 bytes long:

$ cat /usr/include/x86_64-linux-gnu/sys/mount.h | grep BLOCK_SIZE
#define BLOCK_SIZE	1024

We can now easily transform a disk usage limit of e.g. two gigabytes into the number of ‘quota blocks’ with simple math:

# python -c "print 2 * 1024**2"
2097152

This means that 2097152 quota blocks on the partition in question correspond to 2 GB of disk space.

When setting a quota, we also need to define a maximum number of inodes (Basically counting the number of file and directory entries). If disk usage should be the limiting factor, then set this to a (moderately) large number, e.g. 1000000.

5) Setting a quota for a specific user

According to the setquota command signature above, execute

setquota -u -F vfsv0 bob 2097152 2097152 1000000 1000000 /

in order to

  • affect the root file system (/)
  • limit disk usage for the user bob to 2 GB (as calculated above)
  • limit the number of inodes for the user bob to 1000000
  • not distinguish between hard and soft limits
  • use the vfsv0 quota format (as specified in the mount options)

6) Verify whether quotas are activated

quotaon filesystem should print the following error if quotas are already in effect:

# quotaon /
quotaon: using //aquota.group on /dev/disk/by-uuid/e5aff151-ddf7-4d43-a318-7e97afcfd78e [/]: Device or resource busy
quotaon: using //aquota.user on /dev/disk/by-uuid/e5aff151-ddf7-4d43-a318-7e97afcfd78e [/]: Device or resource busy

7) Check quota report

# repquota  /
*** Report for user quotas on device /dev/disk/by-uuid/e5aff151-ddf7-4d43-a318-7e97afcfd78e
Block grace time: 7days; Inode grace time: 7days
                        Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
[...]
bob  --  273264 2097152 2097152          13976 1000000 1000000

The output is as expected, the limits are in effect. Currently, bob is using 273264 of 2097152 blocks and 13976 of 1000000 inodes.

  • Tim Boneko

    Danke für das HowTo! Ich mühte mich gestern vergeblich mit der Einrichtung ab; mein System gab immer an, dass er keine aquota.user fände. Der quotacheck- Befehl in Schritt 3 tat den Trick.