注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

红烧鱼

linux & windows management

 
 
 

日志

 
 
关于我
mac

专注IT基础架构设计与运维。 欢迎给我留言,或邮件沟通zjwsk@163.com

网易考拉推荐

Implementing Disk Quotas on Linux  

2008-05-30 23:59:58|  分类: Linux |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

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
setquota  [  -rm  ]  [  -u | -g ] [ -F quotaformat ] name block-softlimit  block-hardlimit inode-softlimit inode-hardlimit -a | filesystem...  

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  

warnquota - send mail to users over quota

Running warnquota without any options will email users that go over the limit.

   # warnquota  

However in this case no mail message will be sent, because the group limit was exceeded. The file "/etc/quotagrpadmins" needs to contain a username responsible for the group. Here will put in the user "sporkey", so that the file looks as follows:

   #     # This is a sample groupadmins file (/etc/quotagrpadmins)     #     #  Comments begin with hash in the beginning of the line       # In this file you specify users responsible for space used by the group     users: root     mygroup: chief     quotagrp: sporkey  

Now if warnquota is execute with the -g option, mail will be send to user "sporkey".

   # warnquota -g /quota  

Messages can be customized by editing the "/etc/warnquota.conf" file.

quotactl - C API

You may want to create your own quota tools, especially if you forsee a need to monitor quota data over time, across multiple computers. My database tool of choice for this is SQLite because it is very fast, the complete database fits into one file, there is no setup or administration needed, and databases can be combine. For detailed information on using SQLite take a look at the ("SQLite Tutorial").

Goal - Create quotadb

The goal is to create the program "quotadb" that will automatically create the necessary database ( a default database quota_database) and tables, for all filesystems and all users on the system. There will also be a "-f <database>" option to place the database file in a particular location, or just place it in the default directory as "quota_database", if no options are specified.

Create tables in /root/quota_database     # quotadb -f /root/quota_database  

Now, after the initial commad is run, quotadb can be run on a peridoic basis to update the entries in the table. Update is specified with the -u option.

 -u option updates history table     # quotadb -f /root/quota_database -u  

After the tables are created by running "quotadb -f /root/quota_database", quotadb is placed in a cron job and run nightly. To get into the cron editor as root type "cronjob -e".

#root cronjob. Type cronjob -e   # This updates history database  #MINUTE(0-59) HOUR(0-23) DAYOFMONTH(1-31) MONTHOFYEAR(1-12) DAYOFWEEK(0-6) Note 0=Sun  2 1        * * *  /usr/local/bin/quotadb  -f /root/quota_database -u  

Running this once a day, over a period of time, will populate the database table history, defined below.

     CREATE TABLE history (filesystem varchar(50),                             name varchar(50),                              uid int,                             b_curr long,                             b_slimit long,                             b_hlimit long,                             i_curr long,                             i_slimit long,                             i_hlimit long,                             timeEnter DATE );          CREATE TRIGGER insert_history_timeEnter                        AFTER  INSERT ON history                            BEGIN  UPDATE history                        SET timeEnter = DATETIME('NOW','localtime')                             WHERE rowid = new.rowid;  

The trigger definition above updates the timeEnter field with the current date and time. By the way this is localtime, hence the option 'localtime'. The default would give you UTC time.

Structure - if_dqblk

One important structure that gets passed to quotactl is if_dqblk. This is defined in the file "quota.h", included in the quota_examples.tar.gz. You will not find this structure in #include <linux/quota.h> or "/usr/include/linux/quota.h" on the Fedora distros. Instead, there is a copy of this structure in the "quota-3.12-5.src.rpm". You can get this source rpm as follows:

   $ wget http://download.fedora.redhat.com/pub/fedora/linux/core/3/SRPMS/quota-3.12-5.src.rpm     $ rpm -K quota-3.12-5.src.rpm     $ rpm -ivh quota-3.12-5.src.rpm       $ su     Password:       # rpm -ivh quota-3.12-5.src.rpm     1:quota                  ########################################### [100%]  

If you're curious, the "rpm -K" command above checks the signature on the package.

After this installation, the source can be found under "/usr/src/redhat/SOURCES".

   # ls -l /usr/src/redhat/SOURCES/quota-3.12.tar.gz  

If you "tar -xzf" this source, you'll see "quota.h", which contains the if_dqblk structure shown below. Note the block hard limit "dqb_bhardlimit", block soft limit "dqb_bsoftlimit", current space taken "dqb_curspace", and similar all 64 bit values for the inode variables as well.

    struct if_dqblk {                                    u_int64_t dqb_bhardlimit;                    u_int64_t dqb_bsoftlimit;                    u_int64_t dqb_curspace;                      u_int64_t dqb_ihardlimit;                    u_int64_t dqb_isoftlimit;                    u_int64_t dqb_curinodes;                     u_int64_t dqb_btime;                         u_int64_t dqb_itime;                         u_int32_t dqb_valid;                 };                                       

By the way, the Linux kernel source contains a quota.h file as well "/lib/modules/2.6.11-1.35_FC3smp/build/include/linux/quota.h", which has an identical structure. It cannot be used in a user-land program. Kernel values for 64 bits are defined as __u65 and not u_int64_t; but, you can certainly see these values get passed directly to the kernel.

  /* This is from the kernel source */      struct if_dqblk {             __u64 dqb_bhardlimit;             __u64 dqb_bsoftlimit;             __u64 dqb_curspace;             __u64 dqb_ihardlimit;             __u64 dqb_isoftlimit;             __u64 dqb_curinodes;             __u64 dqb_btime;             __u64 dqb_itime;             __u32 dqb_valid;    };  

Example Call to quotactl

Below is an example call to quotactl for getting quota spaced used for uid. The variable dq is defined as type struct if_dqblk and it's passed as the last parameter to quotactl. Note the macro QCMD(Q_GETQUOTA, USRQUOTA), passed as the first parameter. Q_GETQUOT, USRQUOTA are defined in "quota.h". The block device, as defined by block_device is the second parameter. And the user id value is defined in uid. The function quotactl returns 0 on success and -1 on failure.

       ...        struct if_dqblk dq;   if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), block_device, uid, (caddr_t) & dq)) {    perror("quotactl");    return 1;   } else {    printf("Device: %s\n", block_device);    printf        ("Current space:  %7.1qu \tSoft limit: %7.1qu  \tHard limit: %7.1qu \tGrace period: %qu\n",         dq.dqb_curspace, dq.dqb_bsoftlimit, dq.dqb_bhardlimit,         dq.dqb_btime);          ...  

Set Quota Options

The section above was an example of getting the quota settings. Let's move on to changing or setting the quota options for the user defined in pwd->pw_uid. It helps to have a specific example. Below we will set a block soft limit of 78, block hard limit of 96, inode soft limit of 50, and an inode hard limit of 100. This program starts with a call to getpwname which takes the user name as a string and passes back a passwd structure. The passwd structure contains the user name, password, user id, group id, real name, home directory and shell program for that particular user.

       ...         const struct passwd *pwd;         struct if_dqblk dq;                 if ((pwd = getpwnam(user)) == NULL) {             printf(stderr, "Invalid -u option \n");             exit(1);         }           dq.dqb_bsoftlimit = 78;         dq.dqb_bhardlimit = 96;         dq.dqb_isoftlimit = 50;         dq.dqb_ihardlimit = 100;           if (quotactl(QCMD(Q_SETQUOTA, USRQUOTA), block_device, pwd->pw_uid, (caddr_t) & dq)) {              perror("quotactl");              return 1;          }   

Again, the full examples can be downloaded from quota_examples.tar.gz

 

 

-----

使用Quota管理磁盘配额

在网络管理的工作中,由于硬盘的资源是有限的,常常需要为多用户的服务器设定用户的磁盘配额。这个功能对公用的多用户服务器(免费的

或者收费的)来说,更是非常必要的。Quota就是在Red Hat linux下实现磁盘配额的工具。


Quota的安装

在正式的RHLinux的光盘的/RedHat/RPMS目录下,都有相应不同版本的quota软件包,可以用ls quota*查看相关的信息,如版本号。当然你可

以方便的通过Tab键获得软件包的全名,使用如下命令安装:
rpm -ivh quota-2.00pre3-7.i386.rpm
当然,这里给出的版本号只是为了方便说明而已,这个版本是随RH7一起提供的。更新的版本请关注RedHat的官方站点。安装好软件包后,就

可以对磁盘配额进行配置了。
执行rpm -ql quota


配置系统的磁盘配额支持

首先,磁盘配额是区域性的,我们可以决定哪块分区进行磁盘配额,哪块分区不用(自然也就不用配置了)。一般而言,作为一台web虚拟主

机服务器,/home和/www(或者类似的)是供用户存放资源的分区,所以可以对这两个分区进行磁盘配额。假定我们需要对/home分区实现用户

级的限制,而对/www进行每个组的用户配额。
◆第一步,vi /etc/fstab。(对了,你是管理员吗?^&^)
找到对应于/home和/www的行,例如:
/dev/sda5 /home ext2 defaults 1 2
/dev/sda7 /www ext2 defaults 1 2
在/home里实现用户级的磁盘配额,所以对sda5行的挂装选项域做如下修改:
/dev/sda5 /home ext2 defaults,usrquota 1 2
注意,是usrquota哦。类似的,我们可以如下修改/www行:
/dev/sda7 /www ext2 defaults,grpquota 1 2

如编辑根用户 改/etc/fstab   LABEL=/ / ext2 defaults,usrquota,grpquota 1 1

说明:/etc/fstab文件的每一行由六个字段组成:

  第一个字段:文件系统(分区)的注释(类似卷标);

  第二个字段:文件系统的装载点;

  第三个字段:文件系统类型(磁盘配额只能在ext2文件系统上实现);

  第四个字段:装载文件系统是使用的选项,如果只想实现基于用户的磁盘配额,就加入usrquota关键字,只想实现基于组的磁盘配额,就

加入grpqouta关键字,如果两者都需要,就全写入,中间可以用逗号分隔。

  第五个字段:表明该文件系统(分区)是否为只读,如果是0就表示只读,1表示可以读写。

  第六个字段:表示系统启动执行fsck时检查的顺序。

  注意:请特别注意这里的拼写,是usrquota和grpquota,不要写成userquota和groupquota。


进入单用户模式 用quotacheck生成.user或.group文件
quotacheck 你的目录
example:quotacheck / ; quotacheck /home
如果单用户模式报错的话 umount 你的设备/dev/hda*
再执行就ok了

重启动系统,如果一切正常的话,quota将开始正常工作


设置用户和组配额的分配量

  对磁盘配额的限制一般是从一个用户占用磁盘大小和所有文件的数量两个方面来进行的。在具体操作之前,我们先了解一下磁盘配额的两

个基本概念:软限制和硬限制。

  软限制:一个用户在文件系统可拥有的最大磁盘空间和最多文件数量,在某个宽限期内可以暂时超过这个限制。

  硬限制:一个用户可拥有的磁盘空间或文件的绝对数量,绝对不允许超过这个限制。


a.通过edquota直接编辑数据文件:

  使用编辑配额命令edquota为用户配置定额
在重新启动系统之后,我们假设lanf是需要定额的系统帐户,可以使用如下命令来为用户分配磁盘配额:
edquota -u lanf
这个命令将启动默认文本编辑器(如vi或其他由$EDITOR 环境变量指定的编辑器),其内容如下所示:
Quotas for user lanf:
/dev/sda5:blocks in use:0,limits(soft = 0,hard = 0)
inodes in use:0,limits(soft = 0,hard = 0)
这表示lanf用户在/dev/sda5分区(该分区已经在usrquota的控制之下)中迄今使用了0个数据块(以K为单位),并且没有设限制(包括软限

制soft和硬限制hard),同样,lanf在这个分区也没有任何文件和目录,并且也没有任何软硬限制。
如果,我们想对用户进行磁盘容量的限制的话,只需要修改blocks行的limits部分就可以了,注意单位使用的是K。例如要为lanf分配100M磁

盘的软限制,400M硬限制,可以使用如下的设置:
Quotas for user lanf:
/dev/sda5:blocks in use:0,limits(soft = 102400,hard = 409800)
inodes in use:0,limits(soft = 0,hard = 0)
同样的,要对文件目录的数量限制可以相应的修改inodes行。我们也可以同时对这两项都作出限制。只需要如下的修改
Quotas for user lanf:
/dev/sda5:blocks in use:0,limits(soft = 102400,hard = 409800)
inodes in use:0,limits(soft = 12800,hard = 51200)
这表示除了相应的容量的限制外,还对文件/目录的数量做了12800个的软限制和51200个的硬限制。在保存了新的配置后,该用户的磁盘使用

就不能超过硬限制。如果用户试图超过这个限制,该操作将被取消,然后得到一个错误信息。
但是,如果每个用户都要这么麻烦的设置的话,那这种重复的体力劳动实在有点令人不寒而栗,而且也太浪费时间了。幸好edquota还有个-p

参数(prototype)可以对已有的用户设置进行拷贝。例如,我们想对Jack、Tom、Chen三个用户使用和lanf一样的限额配置,可以使用如下的

命令:
edquota -p lanf -u Jack Tom Chen
这样一来,这三个用户就被赋予了和lanf一样的磁盘配额。
对组的配额,除了edquota命令中对应-u参数的改为-g参数,例如下面对webterm1组的操作:
edquota -g webterm1

实际上,以上的限制只是对用户设定的硬限制在起作用。如果需要使软限制也起作用的话,还需要对用户的软限制设定宽限期——缺省的,软

限制的宽限期是无穷大——这可以使用edquota命令的-t选项来实现。运行下面的命令:
edquota -t
edquota将打开缺省编辑器显示如下内容:
Time units may be:days,hours,minutes,or seconds
Grace period before enforcing soft limits for users:
/dev/sda5:block grace period:0 days,file grace period:0 days
可以使用天、小时、分、秒为单位来设定宽限期。例如,在下面这个例子中,磁盘空间限制的宽限期为两天,而文件数量限制的宽限期只有6

个小时。
Time units may be:days,hours,minutes,or seconds
Grace period before enforcing soft limits for users:
/dev/sda5:block grace period:2 days,file grace period:6 hours

b.通过setquota工具加入:

  比如加入用户bye2000的磁盘配额,执行以下命令:

  setquota –u / 2000 2500 100 110 bye2000

  以下是setquota命令用法的简单描述:

  setquota [ -u|-g ] 装载点 软块数 硬块数 软文件数 硬文件数 用户名/组名

◆查看用户磁盘使用情况
要查明某一个用户使用了多少磁盘空间,例如lanf,可以使用如下的命令:
quota -u lanf
显示:
Disk quotas for user lanf(uid 503):
Filesystem blocks quota limit grace file quota limit grace
/dev/sda5 3 102400 409800 1 12800 51200
同样,可以使用quota -g groupname命令来参看某个组的磁盘使用情况。
注意: 1、如果该用户没有配置磁盘限额的话,输出显示如下:
Disk quotas for user hujm (uid 503): none
2、如果不带任何参数运行quota的话,查看的是你自己的配额使用情况。

  评论这张
 
阅读(1150)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017