Friday, 27 July 2012


Implementing Disk Quotas on Linux
This tutorial walks you through implementing disk quotas for both users and groups on Linux, using a virtual filesystem, which is a filesystem created from a disk file. Since quotas work on a per-filesystem basis, this is a way to implement quotas on a sub-section, or even multiple subsections of your drive, without reformatting. This tutorial also covers quotactl, or quota's C interface, by way of an example program that can store disk usage in a SQLite database for monitoring data usage over time.
This tutorial was tested on Fedora Core 2, 3, and 4. I'm assuming you have the quota tools installed. If you're not sure, try the following test, which will return 3.12-6 or 3.12-5 depending on which version of Fedora Core you are using.

    $ rpm -q quota
    quota-3.12-6    
Creating a Virtual Filesystem
The following steps walk you through creating a ext3 virtual filesystem mounted on "/quota" with a size of 20 MB. Again, since quotas are installed on a filesystem, we're going to create an isolated filesystem.
The mount point for this filesystem will be "quota". As root, first create the mount point quota, which at this point is just a directory.

   # mkdir -p /quota
Next, create a 20M file (disk image) in a suitable location. What I did below is create the file disk-quota.ext3 in the directory /usr/disk-img.

   # mkdir -p /usr/disk-img
   # dd if=/dev/zero of=/usr/disk-img/disk-quota.ext3 count=40960
The dd command above created a 20MB file because, by default, dd uses a block size of 512 bytes. That makes this size: 40960*512=20971520. For kicks, we'll confirm this size.

   # ls -lh /usr/disk-img/disk-quota.ext3
   -rw-r--r--  1 root root 20M Jul 19 14:34 /usr/disk-img/disk-quota.ext3
Next, format this as an ext3 filesystem.

   # /sbin/mkfs -t ext3 -q /usr/disk-img/disk-quota.ext3 -F
The "-t" gives it the type. You're not limited to ext3. In fact, you could use ext2 or other filesystems installed on your system. The "-q" is for the device, and "-F" is to force the creation without warning us that this is a file and not a block device.
Add the following line to "/etc/fstab". This will make the filesystem always available on reboot, plus it's easier to mount and unmout when testing.

    /usr/disk-img/disk-quota.ext3    /quota ext3    rw,loop,usrquota,grpquota  0 0
Now, mount this filesystem.

    # mount /quota

 Or if you didn't edit /etc/fstab above

    # mount -o loop,rw,usrquota,grpquota /usr/disk-img/disk-quota.ext3 /quota
Now take a look at /quota. You should see the "lost+found" directory. Plus, you can take a look at /proc/mounts to see that you have an "ext3" type filesystem. At this point you can create and add files if you want.

    # ls
    lost+found

    # grep 'quota' /proc/mounts
    /dev/loop0 /quota ext3 rw 0 0 

The mount command below shows us usrquota and grpquota options have been added.

    # mount | grep '/quota' 
    /usr/disk-img/disk-quota.ext3 on /quota type ext3 (rw,loop=/dev/loop0,usrquota,grpquota)

Sharing a Directory amoung Several Users
This step creates a group and implements group rights on a directory within the quota filesystem. Specifically, this step creates the group, "quotagrp" and adds the two existing users "chirico" and "sporkey" into this group. The direcory "/quota/share" is setup so that any files created in this directory by these two users will be sharable by default for members of this group. This is done by setting the setgid bit on the directory.
First create the group and add any existing users.

   # groupadd quotagrp
   # usermod -G quotagrp chirico
   # usermod -G quotagrp sporkey
Create the directory /quota/share and set the access rights so that files created in this directory can be edited by any group members.

   # mkdir -p /quota/share
   # chown -R root.quotagrp /quota/share
   # chmod 2775 /quota/share
Above the command "2755" sets the "setgid" bit. You can see this with the "ls" command below.

   # ls -ld /quota/share
   drwxrwsr-x  2 root quotagrp 1024 Jul 19 15:16 /quota/share/
         ^---------- Note the s, setgid bit, from  chmod 2775
An important note here. If the users above "chirico" and "sporkey" are currently logged in when they were added to the group, they will not get access to the group. These users need to login again. Having these users run "newgrp" or even "newgrp -" (Fedora core 4) will give them access to the group; however, this will not correctly set group file permissions. To avoid trouble in a production environment have users login again or execute "su - " to corrently initilize their environment.

  Execute from chirico account. 

   $ groups
   chirico

   $ su - chirico
   Password:

   $ groups   
   quotagrp chirico
Quotas
Run quotecheck. The first time you run this command, use the "-c" option to create the necessary database files. The following should be run as root.

   # quotacheck -cug /quota
Note that two files have been created "aquota.group" and "aquota.user".

   # ls -l /quota
   aquota.group  aquota.user  lost+found  share
Use "edquota" to grant the user "chirico" the desired quota.

   # edquota -f /quota chirico
Executing the command above brings up a text file in your default editor. You will change entries in this file.

 Disk quotas for user chirico (uid 500):
  Filesystem                   blocks       soft       hard     inodes     soft     hard
  /dev/loop0                        0          0          0          0        0        0
Above for user chirico there have been no blocks or inodes used on this filesystem. Note that an inode is used for each file and directory. We'll change the settings as follows:

 Disk quotas for user chirico (uid 500):
  Filesystem                   blocks       soft       hard     inodes     soft     hard
  /dev/loop0                        0        100        200          0       10       15

Note that the numbers under "blocks" and "inodes" indicated the current blocks and inodes in use by this user. Those values should not be edited, since they are only used for reference.
setquota - command line quota editor
You can also use the setquota command, which has the advantage of not using an editor making it ideal for implementing in a script. For example, to set the soft block limit to 100, a hard block limit of 200, a soft inode to 10 and a hard inode to 15 as we did above, execute the following command.

   # setquota -u chirico 100 200 10 15  -a /dev/loop0
Turn quotas on with the following command.

  # quotaon /quota
From the root user you can "su" into the chirico account to see the changes.

  # su - chirico
  $ touch /quota/share/t1
  $ quota
  Disk quotas for user chirico (uid 500):
       Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
       /dev/loop0       1     100     200               1      10      20

As an interesting test, still under this user, create a hard link as follows with the ln command. Then execute the quota command to see how many inodes are taken.

  $ ln  /quota/share/t1 /quota/share/t2

  $ quota
  Disk quotas for user chirico (uid 500):
       Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
       /dev/loop0       1     100     200               1      10      20
Note that the number of files has not changed. However, if you create a symbolic link, sometimes called a soft link, with the "ln -s" command, the number will increse to 2, because an additional inode is created with a soft link.

  $ ln -s /quota/share/t1 /quota/share/t3

  $ quota
  Disk quotas for user chirico (uid 500):
       Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
       /dev/loop0       2     100     200               2      10      20

Quotas for Groups
To set quotas for the group "quotagrp", use the following command.

   # edquota -g quotagrp
   Disk quotas for group quotagrp (gid 619):
     Filesystem                   blocks       soft       hard     inodes     soft     hard
     /dev/loop0                        6          0          0          4        0        0

Now make the following changes.

   Disk quotas for group quotagrp (gid 619):
     Filesystem                   blocks       soft       hard     inodes     soft     hard
     /dev/loop0                        6          5        100          4        6       10
Or, use the "setquota" command as follows:

   # setquota -g quotagrp 5 100 6 10 -a /dev/loop0
Now run the following command under the user account that has group access, which will attempt to create 15 files.

   $ for i in $(seq 15); do  touch "/quota/share/file_$i"; done
   loop0: warning, group file quota exceeded.
   loop0: write failed, group file limit reached.
   touch: cannot touch `/quota/share/file_7': Disk quota exceeded
Reports
The "repquota" command prints a summarized report. It should be run with root.

   # repquota /quota
   *** Report for user quotas on device /dev/loop0
   Block grace time: 7days; Inode grace time: 7days
                           Block limits                File limits
   User            used    soft    hard  grace    used  soft  hard  grace
   ----------------------------------------------------------------------
   root      --    1204       0       0              5     0     0
   chirico   --      10     100     200              9    10    20
To get a report by group, use the -g option as follows.

   # repquota -g /quota
   *** Report for group quotas on device /dev/loop0
   Block grace time: 7days; Inode grace time: 7days
                           Block limits                File limits
   Group           used    soft    hard  grace    used  soft  hard  grace
   ----------------------------------------------------------------------
   root      --    1202       0       0              4     0     0
   quotagrp  ++      12       5     100  6days      10     6    10  6days
Note the "++" above for quotagrp indicating that both the block limit and inode limits have been exceeded.
Or to get everything, run repquota with the -a option as follows.

   # repquota -a

No comments:

Post a Comment