Good old simple quotas

Recently we ran into some storage issues on our office NAS. We have a Raid5 (Software, MDADM) with 4 Disks (+1 Hot Spare), about 1,2 TB net space and some users decided to store their “non workstuff” there also. Because of my latest studies about ZFS (a post will follow soon) i was very aware of what is possible and what i want: quotas. Because of our Hosting work, i use many different techniques for archiving quotas (for example our Mailserver running Dovecot which quotas are based on the LDAP user database) which usually fit the needs of the very application much better. However, our office NAS (sadly) has to export storage on multiple protocols (NFS, SMB, AFS, ..) so i had to find another approach. A collegue of mine remembered me of the most simplistic approach: filesystem quotas ;)

I found a lot of articles about that matter, however, they mostly were very focused on a single issue about this topic and didnt comprehend “the whole” thing (or at least not from my point of view). So i had to read and google a lot until i fully understand what i need and can do.

Thus, here is my summary.

First of all, your kernel have to support quotas. This is very likely, if you have a remotly up-to-date system. We’re runnig mainly debian (lenny, but etch supports quotas also), so this was no problem at all. For recompiling your own kernel with quota support try google, often explained.

Then you have to install the user tools. This is under debian easily done by typing:

aptitude install quota

After thats done, you have to make your mounted disks quota-aware and then read the current usage for any user in your system (with the quotacheck tool).

vim /etc/fstab
/dev/sdc1       /some/mountpoint    ext3    defaults     0       0

change to:

/dev/sdc1       /some/mountpoint    ext3    defaults,usrquota,usrjquota=aquota.user,jqfmt=vfsv0     0       0

Now let us take a short break before runing the quotacheck and i’ll eplxain the added parameters:

  1. usrquota: makes your filesystem quota aware for USERquota (in opposite to groups, which can be used additionally or exclusivly used with grpquota and grpjquota).
  2. usrjquota: because we are sophisticated, we want journaled quotas. The name of the journaled quota file is mandatory for using the next parameter! The name aquota.user comes from the (old, in not-journaled context used) user.quota.
  3. jqfmt: the version of the journaling quota. There are vfsv0 (which is quota version 2), vfsold (aka quota version 1), xfs and some other. We focus soly on vfsv0.

So why do we use journaled ? Easy to explain (but rarely documented). As a journaled filesystem a journaled quota doesnt need to re-build/-check after unclean shutdown of the filesystem. It simply re-runs the transactions. Because the quotacheck could easily take some ten minutes to even hours (depending on the amount of files and directories) we dont want a recheck – really. However, this, of course, only works with journaled filesysystems like ext3, reiserfs and xfs. For ext2 and such you have to stick with non-journaled quota. This can be achieved by not using usrquota and jqfmt at all. By the way: for xfs you should jqfmt=xfs (which i’ve never tried, just read).

Now you need to remount the filesystems to enabled the quota attribute (but still not activate it! See below).

mount -o remount /some/mountpoint

If you run into this:

mount: wrong fs type, bad option, bad superblock on /dev/sdc1,
missing codepage or helper program, or other error
In some cases useful info is found in syslog - try
dmesg | tail  or so

.. you probably have forgotten to provide usrjquota=aquota.user, at least that was it for me.

After remounting you need now to run an initial quotacheck. This will analyse all files in the fs and writes the aquota.user file in the mount-point root (for example: if your mountpoint is /home then the file will be in /home/aquota.user with 0600 permissions). This could take some very long time if you have a lot of files!

quotacheck -c -u -m -v -F vfsv0 /some/mountpoint

The parameters used are

  1. -c: create the aquota.user file
  2. -u: create quotas for users. If you use group-quotas, add/replace with -g
  3. -m: this forces the quotacheck NOT to remount the filesystem read only for checking. Actually you shouldnt do this, data loss could occure – but i did it and it worked for me.
  4. -F vfsv0: assure quota version 2.
  5. /some/mountpoint: Whereever the filesystem is mounted you want to check. Instead you could use /dev/sdc1 directly (or whereever your disk is).

Before you activate the quota with the next command, you can run a report to see which users uses what amount of space (blocks) and files (inodes).

repquota /dev/sdc1

will return:

*** Report for user quotas on device /dev/sdc1
Block grace time: 7days; Inode grace time: 7days
Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      --  184268       0       0              3     0     0
uk        -- 19666328       0       0           3249     0     0
testquota --    5136       0   0              0     0     0

This means: the user testquota uses 5136 1kb-blocks (5MB), has neither soft nor hard limits for blocks, is not in soft-quota grace-time (explained below) either and the same for amount of files.

It also tells you, that your grace period is 7 days – meaning the quota warnings (below) will be send for 7 days, or else!

Now lets activate the quota finally:

quotaon /some/mountpoint

Ok, it is up and running. If you run the same command again you will see something like this:

quotaon: using /some/mountpoint on /dev/sdc1 [/some/mountpoint]: Device or resource busy

On the next boot, you have not to do this manually again (or something went wrong). Now lets give the user testquota some quota to restrict him to a maximum:

setquota -u testquota -F vfsv0 0 11000 0 0 /dev/sdc1

The 4 numbers (0 11000 0 0) you see are read like this:

  1. 0: no soft quota for blocksize
  2. 11000: 11.000 KB ~ 11MB hard quota for blocksize
  3. 0: no soft quota for file amount
  4. 0: no hard quota for file amount

You can instead use the edquota -t testquota -f /dev/sdc1 command and edit the quota within an editor – as you like.

However, testquota is now not allowed to use more then 11.000 KB of disk on this device. You can test this by doing this:

su testquota
# create a 6 MB File
dd if=/dev/zero of=/some/mountpoint/file1 count=6 bs=1M

# and try to create another
dd if=/dev/zero of=/some/mountpoint/file2 count=6 bs=1M

On the second attempt you should see somethign like this:

sdc1: write failed, user block limit reached.
dd: writing `file2': Disk quota exceeded

Alright :) Quota works!

But this is not all. There are some more useful things quotas can do for you. Soft quotas. Imagine the following scenario: you want to give every user a certain amount of space – lets say 1 GB. But in peak times, some of them might need a little bit more – lets say 100 MB. So you set the soft block quotas to 1000000 (1GB) and the hard block quotas to 1100000 (1,1GB). Normally each user needs is fine with his 1 GB. But when he needs these additionally 100 MB, he has – but only temporary! This is when warnquota (man warnquota) comes in. Normally it is configured spam the messy user with warnings about overusage (more then the soft quota). You can think yourself of some escalation and conter measures to handles such users. Google helps.

Ok, thats all for now, hope it helps. Finally, here are some additional sources which may help:

Leave a Reply

CAPTCHA image