Enabling and Managing Disk Quotas

Overview:

Disk quotas limit how much hard disk space can be consumed per user (and optionally per group), per filesystem.  Unix and Linux filesystems support quotas but not all filesystem types do.  Quotas can be used to limit how much disk space a user can consume per partition, how many files (actually inodes) they can create per partition, or both.

To use quotas, the first requirement is that the kernel must have quota support enabled.  (Today all *nix systems do.)  Next you must use a filesystem type that supports quotas.  Most common *nix filesystems do (ext2/3, ufs, jfs, ...) but not all will.  (In particular the Solaris 10 ZFS doesn't support per user or per group quotas, although it uses the term quota, it means something different for ZFS.)  Next you must mount or remount each filesystem with the appropriate quota option flag(s).  (And update /etc/fstab too.)

Then you must create initial quota database files at the root of each filesystem.  The current Linux quota system uses a different database format than the original one, and also uses different filenames: aquota.user and/or aquota.group.  The old system called these files quota.user and quota.group.  Note that if you want users to be able to see their current quotas, these files must be world-readable.

The last step is to turn on the quota checking system.  It may pay to also have the quotas checked periodically via cron, or at each reboot (Red Hat does this), or both.

Quotas have soft limits, hard limits, and a grace period.  A user may exceed the soft limit but never the hard limit.  As soon as a user has exceed the soft limit, a count-down timer is set to the grace period and starts counting down.  When the user reaches the end of the grace period the excess over the soft limit may be deleted, or the account disabled, or the limit may be frozen, or some combination of these.

Quotas can be enabled by mounting a partition with the usrquota (and optionally the grpquota) mount option(s).  Normally this is done by editing /etc/fstab and adding usrquota to the mount options part of the entry for some filesystem.  Then that filesystem must be remounted ("mount -o remount filesystem").

Then the quota database files on each partition must be initialized with the quotacheck command, which should should also run monthly or possibly weekly from cron.  (Run this command as often as you would fsck.)

Use the commands edquota or setquota to edit the quota limits for individual users per partition (and the grace period too).  Note there is no easy way to set a default quota to apply to all existing users, or for future users.  A shell script that loops over existing users, and a custom add-users script to set defaults for new accounts works well.

Use repquota to generate a quota report for all users.  Use "quota user" to see the quota for some user.

You can use quotaon and quotaoff to manually turn on or off quota checking, although this is usually done automatically by the boot up rc scripts.

One thing you must do is to determine which uses require quotas for which filesystems.  Typically all accounts for most user-writable filesystems should have quotas.  This can include system accounts as a security measure, in case someone manages to use one of these accounts to create files.

Next you must detemine what the quotas should be, for each user on each filesystem.  The quotas for system accounts should be close to zero!  For regular user accounts, the quotas should reflect the expected work of that person: admin (small quotas), developer (medium), multimedia developer (huge quotas).  One way to determine quotas is by dividing the space available in the filesystem by the number of users.  But don't forget to leave room for additional users later, or if one (or a few) users need their quotas enlarged later.

Step by Step Directions:  Setting a quota for a user "auser" on /home

  1. To practice using quotas and experimenting with going over the soft and hard limits, you should create a test user with very small quota limits.  If you have ever logged in as auser from the GUI, the desktop environment used (kde or gnome) will create a large number of additional files (big ones) and directories in the user's home directory.  If you have never done this, you most likely have about 90k of disk space used and only a few dozen files, and you can practice with quota limits of 100k blocks (soft) and 200k blocks (hard), 100 files (soft) and 200 files (hard), and a grace period of 1 (one) hour or less.

    However if you've ever used the GUI you most likely have used about 600k of disk space used by about 600 files, so don't use those small quota limits.  Instead use the du -h command to determine how much space is actually used and set the quotas to that value plus 50k (soft) and that value plus 100k (hard), with a grace period of 1 (one) hour or less.  If you used the smaller values, don't ever log into auser or buser from the GUI (or the attempt to create 530k of files will fail, causing the GUI system to be corrupted for that user). 

    In real life quotas are set based on the expected need of a user.  Software developers need little, multi-media developers may need a lot.  (Managers often need the least but this may be a political issue!)

  2. Next, you must enable quotes for the filesystems you selected, and then have the kernel start enforcing these.  One way is to use a GUI tool.  Here are the directions using Webmin:
    1. Login to webmin.  Click the "System" button.
    2. Now click on Disk and Network Filesystems.  Click the /home link.  Change the drop-down list for Use Quotas? to either User only or User and Group.  Save your changes and go back to the main Webmin page.  Note:  If /home is in use you can't remount it to activate the new mount option(s).  Instead you can save the changes to /etc/fstab (i.e., the permanent mount list).  Then remount /home before proceeding (by making /home not busy, say by logging out as a regular user and logging in as root and then remounting; or you can reboot the machine.)
    3. No go back a couple of screens and click on Disk Quotas.  You should see a line now for /home.  Make sure Quotas are enabled for this partition (they are if you see Disable Quotas at the end of the line.)  Click the /home link.  Before editing any quotas or grace periods, click the Check Quotas button.  (This will create the empty default files needed the first time.)
    4. Now enter the username auser (or select auser from the popup list you get by clicking on the "..." button).  Enter your quotas and limits for this user.  Remember that you specify disk quotas in 1k disk blocks.  When done click the apply button.

    And here are directions using command line tools:

    1. Edit /etc/fstab to add "usrquota" (and, if desired ",grpquota" too) for each filesystem that needs quotas.
    2. Remount these filesystems:  "mount -o remount /home".
    3. Initialize the quota database using the quotacheck command:
         quotaoff -a  # just in case you rebooted and they are on
         quotacheck -acRv  # or -acRvug
      

      See the man page for the meanings of the options.  This command checks all (-a) filesystems, except root (-R), ignoring any existing quota database files and recreating them from scratch (-c).  The -v optiuon causes progress information to be displayed while running.  (The -u says to check user quotas only (the default) and -g says to check group quotas only.  Use both options to check both.)

      If running quotacheck to repair or update an existing quota database, use the -n option instead of the -c option.

      Why was the -R option used to omit the root filesystem?  Because to work correctly and accurately the filesystem must not be in use while quotacheck is running.  To enforce this the command remounts the filesystem as read-only during the scan.  In fact, ideally you should run quotacheck while in single user mode, on unmounted filesystems.  Note that you won't be able to remount your /home filesystem while it is in use, so you can't do this if any regular users are logged in.

      However it isn't possible to remount the root ("/") partition while the system is running.  You could reboot your system and enter some emergency mode, or use a Live CD such as Knoppix, or modify the startup scripts, to enable you to run quotacheck before the boot process remounts the root partition as read-write.  Indeed, on Red Hat systems the startup scripts will run quotacheck at boot time, and turn on the quota system for you, if any filesystems are mounted with any quota options.  However if the filesystem is mounted read-only, you won't be able to create the quota files!  The answer is to create empty quota database files in the root directory of each filesystem with quotas, then reboot.  This is usually only a problem for the root partition.  Here's the command to use (as super-user):

         touch /aquota.user  # also /aquota.group if group quotas are used
      

      A simpler way is to bring the system into a quiesent state, say in single user mode with few processes running (don't forget to turn off cron).  Then use this command to check the root partition without remounting in read-only mode:

         telinit 1          # change to single user mode (runlevel 1)
         quotacheck -Mcv /  # or -Mcvug.  If updating, as above use -n not -c
         telinit 5          # (or 3 or whatever runlevel is normal)
      
    4. To allow users to check their own quotas, the quota database files must be readable by all.  If you chose to allow this, change the permissions on all of the quota database files.  Here's the command to change the permissions for the /home databas(es), but you should do this step on all the filesystem with quotas:
         chmod a+r /home/aquota.*
      
    5. Set the quotas for users, using the edquota or the setquota commands.  The first is interactive, putting you into vi where you edit the quotas, one line per user.  The second command uses command line arguments to set quotas, making it suitable for scripting.
    6. Finally turn the quota system back on, using:
           quotaon -a
      
  3. Test out quotas by logging in as auser.  (Don't login from the GUI unless you set the quota limits appropriately!)  Now go over your soft limit.  You can copy files (from /usr/share/doc), create large files by using dd command, or by saving large man pages as files by running the command:
        man xterm | col -bx > xterm.txt
    

    Use the du command and verify you are over your soft limit.  Check this user's email.  Was any email sent as a result of going over the quota?  Use the quota command to see the current quota status.  Run the command:

       ( ls -alsR; quota; ) | lpr -T "your-name: before"
    

    Suppose you remain over your soft limit for more than the grace period (set earlier).  See what happens.

  4. Now wait for the grace period to expire (do not log out!) and verify what actually did happen by performing these steps:  Run the command:
        ( ls -alsR; quota; ) | lpr -T "your-name: after"
    

    See what is different between the "after" and the "before" output.

    Try to create a small file using vi (staying under the hard limit).  What happens if you try to create more large files in the user's home directory, that would cause the user to go over the hard limit.  See what happened when you attempted to go over the hard limit.

    Now log out and attempt to login again as auser.  See if this was allowed.  If so, see if any email sent.  (See if warnquota is run by cron.)

    Finally, remove the large files from /home/auser.  (You may have to do this step as root.)  Now attempt to login as auser.  If this was allowed, check if any email was sent.  Run the quota command now.  See what the "grace" period is now.

Differences for Solaris 10 Quota System

Solaris 10 ZFS filesystem doesn't support user or group quotas.  (ZFS has a different concept of a quota.)  The UFS filesystem does support user quotas, but not group quotas.  The commands used are the same as for Linux but with different/fewer options.

First of all the mount option to use in vfstab is "rq", not "usrquota".  Next you must always manually create the empty quota database files in the root of each filesystem with quotas.  The database file is simpla named "quotas".  You must set the correct permissions too, depending if you want users to be able to check their own quotas or not:

   touch /quotas # or /export/home/quotas or where ever
   chmod 600 /quotas # or 644
   quotacheck -av
   quotaon -a

Finally you must use edquota to set up quotas for users.  Solaris 10 lacks the setquota scriptable command (although if you work really hard at it you can script edquota).