2015年3月8日 星期日

[转载]Linux的磁盘配额

今天在服务器上装软件的时候遇到这种情况:dm-0: write failed, user block limit reached.看来应该是空间被限制了.
原文地址:Linux的磁盘配额作者:zhuchen0515
不管磁盘空间有多么大,磁盘空间不够使用似乎是一个永远的事实。而且Linux系统在默认情况下,并不限制每个用户使用磁盘空间的大小,如果某个用户疏忽或恶意将磁盘占满,将导致系统无法进行写操作甚至崩溃。因此Linux提供了限制用户磁盘空间的手段,以便促使每个用户合理有效地使用分配给他的空间。

设置用户和组配额的分配量对磁盘配额的限制一般是从一个用户占用磁盘大小和所有文件的数量两个方面来进行的。设置磁盘配额时,“某用户在系统中共计只能使用50MB磁盘空间”,这样的限制要求是无法实现的;只能设置“某用户在/home分区能使用30MB,在/backup分区能使用20MB”。磁盘配额的设置单位是分区,针对分区启用配额限制功能后才可以对用户设置,而不理会用户文件放在该文件系统中的哪个目录中,其他系统,如Unix、Windows,原理与Linux相同。在具体操作之前,我们先了解一下磁盘配额的两个基本概念:软限制和硬限制。

◆软限制:一个用户在一定时间范围内(默认为一周,可以使用命令“edquota -t”重新设置,时间单位可以为天、小时、分钟、秒)超过其限制的额度,在不超出硬限制的范围内可以继续使用空间,系统会发出警告(警告信息设置文件为“/etc/warnquota.conf”),但如果用户达到时间期限仍未释放空间到限制的额度下,系统将不再允许该用户使用更多的空间。
◆硬限制:一个用户可拥有的磁盘空间或文件的绝对数量,绝对不允许超过这个限制。

明白了上面的基本概念,我们就可以配置磁盘配额了。设置磁盘配额的步骤:
(1)启动分区配额功能;
(2)生成配额信息文件;
(3)设置用户和组配额;
(4)启动磁盘配额服务。


1. 启动分区配额功能
    用管理员身份登录系统,编辑系统配置文件/etc/fstab中相应分区(以/home分区为例)的设置选项,若开启用户配额添加选项“usrquota”,用户组配额添加选项“grpquota”,中间以逗号隔开。
LABEL=/home  /home  ext3  defaults,usrquota  1  2
    用户组配额用以限定一组用户共计可以使用的空间数,一般应用较少,本例只启动用户配额。
    分区配额功能生效需要重新启动系统,或者简单一点,重新挂载此分区,让其新加参数生效:
# mount -o remount /home

2. 生成配额信息文件
    检测分区中当前用户空间使用情况,并生成保存配额信息的数据库文件:
# quotacheck -F vfsv0 -uv /home (生成符合系统要求的 aquota.usr)
# quotacheck -g /home (生成符合系统要求的 aquota.group)
    选项“-F vfsv0”指定磁盘配额功能实现的软件版本,当前流行的Linux版本基本都为Quota 2.0 ,可以使用命令“man quotacheck”查看到此信息,不必像绝大多数的文章和书籍资料中手工“touch”创建。
    选项“-u”指定生成用户配额信息文件“aquota.user”(Quota 1.0为quota.user),如果设置了用户组配额则添加选项“-g”生成配额信息文件“aquota.group”,选项“-v”表示执行时显示详细信息。执行结果中自动报告了分区/home的空间使用情况,并自动生成了配额信息文件“aquota.user”,其权限为600 。
    若较老的Linux系统(Quota 1.0)要升级到Quota 2.0 ,可以使用命令“convertquota”将老格式文件“quota.user”和“quota.group”转换为新格式“aquota.user”和“aquota.group”。

3. 设置用户和组配额
    使用edquota命令为每个用户设置磁盘配额,如下例为用户Sam设置配额:
# edquota Sam
    系统会调用Vim/Vi生成一临时文件,编辑方法与vi完全相同,以ZZ或:wq命令退出。在此文件中可对用户Sam配额信息进行编辑,默认文件内容如下:
Disk quotas for user Sam (uid 500):
Filesystem     blocks       soft       hard     inodes     soft    hard
/dev/hda3        5          0         0         5             0

    其中“Filesystem”字段表明使用磁盘配额的分区对应的设备名称,“blocks”和“inodes”分别表明了用户当前已经使用的磁盘空间(以KB为单位)和建立的文件数(此限制一般较少应用),“soft”和“hard”即为前文提及的软限制和硬限制(大多数应用不设置软限制)。
    编辑此文件,把软、硬限制设置到合适的数值,保存退出,可以看到“aquota.user”文件的大小改变,说明用户的配额已经储存。设置组配额可以使用命令“edquota -g 组名”。
    设置大量用户的磁盘配额,若分配给用户的配额相同,可以使用命令edquota的“-p”选项在用户之间复制配额设置,可用下面的命令给这些用户赋予与protuser相同的限额:
# edquota [-u] -p protuser user1 user2 user3
# edquota -g -p protgroup group1 group2 group3

    例如将用户Sam的配额信息复制给Helen和Jack:
# edquota -p Sam Helen Jack
    这样可将配额模板用户设置复制给任意多用户,或可利用此命令编写shell脚本批量复制。此外,也可以使用命令“setquota”来设置磁盘配额,如:
# setquota Mary 0 20480 0 0 /home
    这样可以限定用户Mary可以在/home分区使用空间20MB ,具体用法在此不在赘述。

    在第三步中设置用户Sam配额为10MB ,如下:
Disk quotas for user Sam (uid 500):
Filesystem     blocks       soft       hard     inodes     soft    hard
/dev/hda3        5          0        10240      5        0       0

    切换到用户Sam ,做磁盘爆满测试:
# dd if=/dev/zero of=quotatest bs=1024k count=10240000
hda3: write failed, user block limit reached.
dd: writing `quotatest': Disk quota exceeded
1+0 records in
0+0 records out
1036288 bytes (1.0 MB) copied, 0.0174559 seconds, 59.4 MB/s

    用户Sam达到限定的磁盘空间,出现了上面的提示信息,他将不能再创建文件,有效的控制了用户磁盘空间的使用。
 
4. 启动磁盘配额服务
    使用命令quotaon用来激活配额系统并允许配额检查:
# quotaon /home
    若关闭配额服务则使用命令“quotaoff”。
    分区的磁盘配额功能设置后,每次开机会自动加载并启动服务,务须另行在启动脚本中设置。

5. 其他功能设置设定soft quota和hard quota之间的时间
# edquota -t
出现一个 vi 窗口:
Grace period before enforcing soft limits for users:
Time units may be: days, hours, minutes, or seconds
Filesystem Block grace period Inode grace period
/dev/hda7 7days 7days


修改成自己所需要的,并保存退出就设置这个时间啦。在这之后可能需要重新启动,以使磁盘限额生效。

6. 检查磁盘空间限制的一致性
    系统会自动每次重新启动时,在检查硬盘后进行( /etc/rc.sysinit ),无须亲自进行。假若分区已经以“读写”方式挂上时要小心,例如:
# quotacheck /home
quotacheck: Quota for users is enabled on mountpoint /home so quotacheck might damage the file.
Please turn quotas off or use -f to force checking.

    这时, 由于某种需要,或者在某种情况,“不得不”运行这个命令 :
# quotacheck -mf [-u] /dev/hda7
# quotacheck -mf -g /dev/hda7

    参数 -m[M] 意思是:强迫在“读、写”模式下检查硬盘的 quota (有一定的“正在写”的数据丢失可能,应确保没有进程在写这个分区。建议在单用户模式下进行。

例如:(在平时检查)
# quotacheck /var/spool/ -f
quotacheck: Cannot remount filesystem mounted on /var/spool read-only so counted values might not be right.
Please stop all programs writing to filesystem or use -m flag to force checking.


# quotacheck /var/spool/ -m

quotacheck: Quota for users is enabled on mountpoint /var/spool so quotacheck might damage the file.
Please turn quotas off or use -f to force checking.


7. 取消磁盘空间和i节点数目的限制
# quotaoff /home (取消磁盘空间限制。)
# quotaon /home (现在启动磁盘空间限制。)
# quotaon /home (如果已经启动磁盘空间限制,会出现以下错误:)

quotaon: using /home/aquota.group on /dev/hda7: Device or resource busy
quotaon: using /home/aquota.user on /dev/hda7: Device or resource busy

8. 查看磁盘配额  用户查看自己当前的配额信息,可使用命令“quota”:
# quota
Disk quotas for user Sam (uid 500):
Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
/dev/hda3    1022     0    1024            6      0      0    

    其中“quota”字段为软限制,“limit”字段为硬限制,“grace”字段为软限制达到后宽限期(前文“edquota -t”设定的时间)。
    若管理员查看各个用户的磁盘配额使用情况,可以使用命令“repquota”:
# repquota /home
*** Report for user quotas on device /dev/hda3
Block grace time: 7days; Inode grace time: 7days
Block limits                File limits
User        used        soft        hard  grace        used        soft        hard  grace
-----------------------------------------------------------------
root  --        10545        0        0        4        0        0     
sam  --                1024        0        1024        8        0        0     
helen  --        5        0        10240        5        0        0
…………

    从结果中可以方便的查看到用户的配额使用情况。如果想获得其他更多信息还可以执行命令“quotastats”,详见帮助。

inode与block使用说明
    磁盘配额限制空间使用的方法有两种,即分别对inode和block进行限制。磁盘配额可以限定用户在分区中使用的空间大小(blocks),也可以限定用户可以在分区中最多创建的文件数(inodes),需要注意的是,只要用户所创建的文件超过他可以使用的inode数额,即使这些文件是空的,他再次创建文件的行为也将被限制。
    此处说明一下inode的概念。在Linux中创建一个文件,系统就为该文件分配一个惟一的inode ,文件的inode用于访问文件的属性。也就是说,Linux系统中每个文件都要对应一个inode,通俗点说Linux内核不认识字母,所以用户要有UID、用户组要有GID、进程要有PID……,文件要有inode ,一旦inode丢失文件将无法被访问。
使用命令“ls -i”可以查看到文件的inode号。
# ls -i
163523 inittab  163524 services  163525 a b
    Linux系统中的硬链接文件与原文件大小一样,且可同步更新,因为硬链接是一个指向文件的指针,它与原文件的inode相同。
    如果系统中有名称特殊的文件,如“a b”,使用“rm”命令无法对其操作(因“rm”会判断为要删除两个文件“a”和“b”),此时可以利用inode的原理,假设“a b”的inode为163535,查看详细信息执行:
# find . -inum 163535 -exec ls -l {} ;
-rw-r--r-- 1 root root 0 Nov 27 15:21 ./a b
    删除此文件执行:
# find . -inum 163535 -exec rm {} ;
    选项“-inum”即为查找文件的inode ,选项“-exec”为find命令的连接符。
    另外,在部署磁盘配额前,要考虑哪些分区需要设置。一般而言,保存用户宿主目录的分区(一般为/home)一定要设置磁盘配额,公共存储用户数据的分区要设置磁盘配额(如公司的网络备份应用服务器)。
 
磁盘爆满测试
    一个没有设置磁盘配额的Linux系统中,使用某一普通用户登录,执行命令:
# dd if=/dev/zero of=quotatest bs=1024k count=10240000
    命令将生成一个固定大小的文件。其中“if”表示输入,伪设备/dev/zero不断生成字符串“0”,初始化文件;“of”表示输出,此例为在用户当前 目录下生成文件“quotatest”;“bs”为“block size”指定数据块大小,单位设定为“1024k”即1MB;“count”为总计生成的文件(“quotatest”)大小,若“bs”为1MB,则 “10240000”为10000GB。
    大多数服务器磁盘空间没有这么大,上面的命令没执行完空间就耗光了。笔者用一台一般配置的笔记本电脑测试,写入速度约为60MB/s,一分钟就可以写 3GB,如果您的服务器是100GB的,半个小时后磁盘空间就会达到100%,此时用户无法创建文件、管理员无法添加用户、系统无法写入日志……甚至系统 重启后将无法正常启动,因为磁盘空间爆满,启动过程中临时文件无法生成。
    如果您真的做了上述的测试,系统无法正常启动,可以使用Linux安装光盘引导,在安装界面输入“linux rescue”进入修复模式后删掉文件“quotatest”,即可恢复。
    由此可见,若不设置磁盘配额,即使不是黑客,任一普通用户都可以随时摧毁我们的系统。

沒有留言:

張貼留言