a public resource for all things web hosting, systems administration, and dedicated server management.

Configuring server file system quotas

Quotas are sexy and quite useful on dedicated servers with multiple users that you don't trust. Of course we use quotas on our shared web hosting servers. Sometimes you'll get customers who want quotas on their dedicated server, which is great.

Quotas (on ext2/3) work by keeping metadata in the root of the filesystem, in files aquota.user and/or aquota.group. Some filesystems like XFS have direct support for quotas. Updates to the filesystem are caught and the metadata is updated accordingly.

Procedure

  1. Install the necessary packages, quota and quotatool if you've got it

    apt-get install quota quotatool
    up2date quota
    yum install quota
  2. Add the usrquota or grpquota option to the fstab entry

    • quotas are a filesystem feature, while bind-mounts work on the VFS layer. Thus, you can only do quotas on the root of a filesystem. The practical effect of this would be that a bind-mounted /home will have to be done on /data. Quotas will also affect stuff like /var/lib/mysql, or /usr/local/foo. Keep this in mind when you set quotas, but that tends to be system stuff, and you shouldn't be setting quotas on system users.

  3. Remount the filesystem with mount -o remount /home

  4. Gather the initial quota metadata with quotacheck

    1. On Red Hat, quotacheck -cug /home

    2. On Debian, /etc/init.d/quota start will do this for you (recommended). quotacheck -augmv is another option, best to check nothing is using the FS when you do it, as it may skew quota data, I think.

  5. Enable quotas
    1. On Red Hat, quotacheck -avug

    2. On Debian, quotaon -augv, although the initscript method should have done that for you already

Setting quotas

Filesystems (at least in the case of ext2/3) work with 1024 byte blocks, not bytes, so you need to calculate stuff a bit. If you have the quotatool package, you can specify quantities in bytes and MB, which is sane. quotatool also allows scripted quota setting, whereas doing lots of users with edquota would blow cocks.

  1. On a shared hosting server we have convenient aliases to set the quota to common amounts. Run

     alias|grep quota
    to see what is available.
  2. edquota is good for this, but not ideal for lots of users.

  3. RTFM for great justice and saved time
  4. A helpful shell script you can use for en-mass quota-setting

    if [ $# -ne 1 ]
    then
            echo "Need a single username to set quota for!"
            echo "Exiting."
            exit 1
    fi
    
    quotatool -v -u $1 -b -l '24MB' /data
    quotatool -v -u $1 -b -q '20MB' /data
  5. adduser on debian has a feature that lets you run a sort of "post-add" script, which is perfect for setting quotas. It resides at /usr/local/sbin/adduser.local, and here's one I prepared earlier (syntax and expected behaviour is detailed in the adduser manpage)

    if [ $# -ne 4 ]
    then
            echo "Needs four args, username, uid, gid and homedir!"
            exit 1
    fi
    
    case "$VERBOSE" in
      2)
            # verbose
            echo "username is $1"
            echo "uid is $2"
            echo "gid is $3"
            echo "homedir is $4"
            ;;
      *)
            ;;
    esac
    
    # Give new users a soft quota of 20meg, and a hard limit of 24meg,
    # will help things a little if it gets to breaking point
    case "$VERBOSE" in
      2)
            echo -n "Setting 24meg hard limit... "
            quotatool -v -u $1 -b -l '24MB' /data
            echo "Done"
            echo -n "Setting 20meg soft limit... "
            quotatool -v -u $1 -b -q '20MB' /data
            echo "Done"
            ;;
      0)
            quotatool -v -u $1 -b -l '24MB' /data &>/dev/null
            quotatool -v -u $1 -b -q '20MB' /data &>/dev/null
            ;;
      *)
            quotatool -v -u $1 -b -l '24MB' /data
            quotatool -v -u $1 -b -q '20MB' /data
            ;;
    esac

Niceties

It's good to know if you've got a user over quota. You can easily set warnquota to do this for you, but it primarily emails the user, which may be irrelevant in some circumstances. Thankfully, you can use this and modify it to suit your needs. Just run it out of /etc/cron.daily/

ADMIN_EMAIL=bofh@meidokon.net
# A plus-sign appears in the unlabeled status column to indicate an over-quota situation
# This is more reliable that searching for "days" on the line, which refers to remaining grace time
MESSAGE_BODY=`repquota -au | grep '\+'`

repquota -au | grep '\+' > /dev/null
RET=$?
if [ $RET -eq 0 ]
then
#echo Found user over quota! Sending mail to $ADMIN_EMAIL
/usr/sbin/sendmail -t <<EOMAIL
From: $ADMIN_EMAIL
To: $ADMIN_EMAIL
Subject: User over quota

$MESSAGE_BODY
EOMAIL

fi

Fixes

If a machine goes down hard and needs a fsck, there's a chance that the quota metadata is corrupt or incorrect. Procedure goes here on how to deal with such a situation. quotacheck is your friend.

Reference links

https://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/sysadmin-guide/ch-disk-quotas.html

http://www.extremetech.com/article2/0,1697,2140153,00.asp


More articles : Web hosting support, dedicated server administration and useful hosting tools