Disk quota磁盘配额技术是一种限制文件系统空间使用的技术。在Linux系统中,系统管理员可以通过该技术限制其他用户在指定的容量范围内使用文件系统,从而防止个别用户过量使用而影响到其他的用户,因此早先的磁盘配额技术都是基于user id和group id实现的。本文介绍的project quota技术是社区近来新实现的一种磁盘配额技术,它不再基于用户和组来划分空间,而基于project id实现,限额的粒度可以细到某个目录甚至单个文件,实现对文件系统空间布局进行控制。本文主要介绍project quota的基本概念和使用方法。

示例环境:

hardware:rpi3

Linux kernel version:4.12.y

e2fsprogs version:1.43.5-WIP  (git clone git://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git)

quota tools version:4.0.3+ (git clone git://git.kernel.org/pub/scm/utils/quota/quota-tools.git)

说明:Linux内核在4.5版本中实现对ext4 project quota的支持,需使用>=4.5.y的版本;e2fsprogs在1.43.4 release版本中仍存在少量影响使用的bug,请使用>1.43.4的版本;quota tool最新的4.0.3 release版本不支持project quota,需通过上述链接下载最新代码仓库自行编译安装。


概述

Disk quota简介

在Linux系统中,Disk quota磁盘配额针对单个文件系统,每个文件系统可以设置不同的配额。目前从限制的客体进行分类可以分为两种:

1、usage quota或block quota:限制磁盘空间的使用,例如一个100GB的文件系统配置只允许某用户使用20GB空间,而对文件的个数不关心;

2、file quota或inode quota:限制文件或inode的分配,例如只允许创建100个文件或目录,而对文件的总大小不关心。

以上两种类型的quota可以同时生效。另外从限制的主体进行分类可以分为三种:

1、user id quota和group id quota:这两种类型的quota实现的时间很早,支持的文件系统较多,如ext2/3/4、xfs、jfs、ocfs2、gfs2和reiserfs等。它以用户和组为主体,基于文件中的uid和gid为区分进行限制,如有一个100GB大小的文件系统,则可以设置uid/gid为A的配额为20GB/500个inode,uid/gid为B的配额为80GB/2000个inode,但对于用户或组如何使用这空间和inode(即文件和目录的分布)则不关心,不同的用户可以在同一个目录下创建属于自己uid/gid的文件;

2、project id quota:这种类型的quota目前仅在xfs和ext4其中支持,其中xfs是单独实现的,而ext4实现的相对较晚,是在uid/gid quota的基础之上实现的。它基于project id作为限制主体,对文件系统种的某些文件或目录进行配额限制,从而实现对文件和目录的分布进行控制,例如在某个目录下配置只允许创建20个文件或使用50BG的空间,这在下一节中详细介绍。

以上三种类型的quota也同样可以同时生效(前提是文件系统必须支持)。最后从限制的类型分类分为两种:

1、hardlimit:顾名思义,hardlimit就是“绝对”不允许突破的硬限制(除非进程拥有CAP_SYS_RESOURCE能力),若用户想要突破这个限制则会收到内核返回的-EDQUOT错误和告警;

2、softlimit:softlimit是可以在一定时间限制内突破的软限制,在突破的时候会向用户发送告警,同时倒计时grace period开始,在倒计时结束之前,用户仍可以在softlimit~hardlimit之间使用配额,但一旦倒计时结束,softlimit将上升为hardlimit,不再允许用户使用过量的配额。

在默认的情况下,在用户突破softlimit、grace time倒计时到期和达到hardlimit时,内核会在终端输出告警以通知用户,但是这种告警的方式存在局限性,用户可能不一定能够机制获取该告警信息。因此若开启了内核的CONFIG_QUOTA_NETLINK_INTERFACE配置选项,则内核同时会通过netlink接口主动向用户态的应用程序主动上报告警通知。

Quota一共有三种标准VFS磁盘文件格式:vfsold、vfsv0和vfsv1,其中vfsold在早起的linux2.4版本中使用;vfsv0则支持32位UIDs和GIDs,配额限制的上限位2^42字节和2^32个inode;vfsv1可以支持32位UIDs和GIDs,配额的上限达到2^64字节和2^64个inode。当然,这三种格式只是标准的vfs文件格式,内核中有些文件系统因为历史原因或特殊性使用自己特有的format类型,如ocfs2和xfs。


Ext4 pqoject quota

Ext4文件系统中使用project quota需要在格式化文件系统时开启两个文件选项:project和quota。其中project选项的含义是允许用户为inode设置project id,同uid和gid类似,它将不同的文件和目录进行分组标记,这样project quota就可以通过inode的project id来进行限额主体的区分(目前project id的作用也仅用于quota)。例如可以设置某一个目录dir的project id为123,然后限制project id为123的quota为20GB和20个文件,这样在该目录下创建的文件和子目录将不能超过20个,使用的空间大小也不能够超过20GB,以此达到对目录进行限额的目的。

早先的ext4文件系统并不支持project特性,而project特性的引入涉及到了文件系统超级块和inode元数据结构的变化。超级块和inode中引入了新的字段来保存project quota file inode和project id。于此同时,quota属性的引入也改变了以往usr id quota和group id quota的使用方式。未开启quota属性的ext4文件系统,它们的quota file是由quotacheck工具生成,存在文件系统根目录下且是用户可见的,而启用quota属性的文件系统quota file则是隐藏的,用户无法感知,所有的配置必须通过quota-tools工具集来完成,其中usr quota和grp quota file分别使用3和4inode,project quota file则使用普通的inode。

最后,启用quota属性的Ext4文件系统的project quota format指定使用最新的vfsv1类型,用户无法修改。


使用示例

准备文件系统启用project和quota属性

用户可以通过mkfs.ext4来格式化新的文件系统,也可以通过tune2fs对老的文件系统进行update而不影响到现有文件系统中的文件:

# mkfs.ext4 -O project,quota /dev/sdb3       #格式化新文件系统
# tune2fs -O project,quota /dev/sdb3          #对老的文件系统进行update

文件系统格式化完毕以后,使用dumpe2fs工具确认该文件系统已经支持pqoject和quota属性:

# dumpe2fs -h /dev/sdb3
...
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isizequota project
...

挂载文件系统

在挂载文件系统时,有一个mount option称为prjquota,如果设置了该挂载选项则project quota的limit功能将自动开启,否则不会启用limit功能,需要通过quotaon命令手动启用。

# mount -o prjquota /dev/sdb3 /mnt/
# mount | grep sdb3
/dev/sdb3 on /mnt type ext4 (rw,relatime,prjquota,data=ordered)


文件和目录设置project id

工具:chattr [-pRVf] [-+=aAcCdDeijPsStTu] [-v version] files...

           lsattr [-RVadlpv] [files...]

创建一个目录dir和文件file,然后设置它们的project id为123:

# chattr -p 123 /mnt/dir 
# chattr -p 123 /mnt/file 
# lsattr -p /mnt
 
  123 --------------e---- /mnt/dir
  123 --------------e---- /mnt/file

此时可以看到dir和file的project id已经设置为123了,而没有明确设定的project id的文件默认为0。与此同时,此时的dir目录并没有project id的继承属性,在该目录下创建的文件不会继承父目录的project id:

# touch /mnt/dir/aa
# lsattr -p /mnt/dir/aa

    0 --------------e---- /mnt/dir/aa

下面通过设置P属性开启dir目录的project id继承属性:

# chattr +P /mnt/dir
# touch /mnt/dir/bb
# lsattr -p /mnt/dir

    0 --------------e---- /mnt/dir/aa
  123 --------------e---P /mnt/dir/bb

这样在dir目录下新创建的文件或子目录都将有用dir的project id,P继承属性也会同时继承,不过设置之前的不会改变。


配置project quota限额

工具:edquota和setquota

1)edquota: Usage:
        edquota [-u] [-F formatname] [-p username] [-f filesystem] username ...
        edquota -g [-F formatname] [-p groupname] [-f filesystem] groupname ...
        edquota -P [-F formatname] [-p projectname] [-f filesystem] projectname ...
        edquota [-u|g|-P] [-F formatname] [-f filesystem] -t
        edquota [-u|g|-P] [-F formatname] [-f filesystem] -T username|groupname|projectname ...

2)setquota: Usage:
  setquota [-u|-g|-P] [-F quotaformat] <user|group|project> <block-softlimit> <block-hardlimit> <inode-softlimit> <inode-hardlimit> -a|<filesystem>...
  setquota [-u|-g|-P] [-F quotaformat] <-p protouser|protogroup|protoproject> <user|group|project> -a|<filesystem>...
  setquota [-u|-g|-P] [-F quotaformat] -b [-c] -a|<filesystem>...
  setquota [-u|-g|-P] [-F quotaformat] -t <blockgrace> <inodegrace> -a|<filesystem>...
  setquota [-u|-g|-P] [-F quotaformat] <user|group|project> -T <blockgrace> <inodegrace> -a|<filesystem>...

这两个工具都可以用于修改project quota的soft limit、hard limit、静态grace period和动态调整grace period。下面设置project 123的soft limit为10MB/5个inode、hard limit为20MB/10个inode(默认为0,即无限制),grace period为5分钟(默认为7天):

# edquota -P -f /dev/sdb3 123
Disk quotas for project 123 (pid 123):
  Filesystem        blocks       soft       hard     inodes     soft     hard
  /dev/sdb3              4         10M       20M             3        5       10

其中blocks和inodes这两个字段表示当前文件系统中的使用状态,不可配置,blocks的默认单位是KB,可以配置为K\M\G\T等单位。下面将block grace period和inode grace period分别设置为5分钟,这两个字段可以以days、hours、minutes和seconds为单位结尾。

# edquota -P -f /dev/sdb3 -t
Grace period before enforcing soft limits for projects:
Time units may be: days, hours, minutes, or seconds
  Filesystem             Block grace period     Inode grace period
  /dev/sdb3                     5minutes                     5minutes


启停quota limit功能

工具:quotaon和quotaoff

1)quotaon: Usage:
        quotaon [-guPvp] [-F quotaformat] [-x state] -a
        quotaon [-guPvp] [-F quotaformat] [-x state] filesys ...

2)quotaoff: Usage:
        quotaoff [-guPvp] [-F quotaformat] [-x state] -a
        quotaoff [-guPvp] [-F quotaformat] [-x state] filesys ...

在前文中的挂载文件系统阶段,由于已经设置了prjquota挂载选项,所以limit功能已经自动启用了,如果没有启用则可以通过quotaon和quotaoff命令手动启停,同时quota的限制状态也可以通过-pv选项进行查看:

# quotaon -P /dev/sdb3     #启用project quota
# quotaon -Ppv /dev/sdb3
project quota on /mnt (/dev/sdb3) is on (enforced)
# quotaoff -P /dev/sdb3     #停用project quota
# quotaon -Ppv /dev/sdb3 
project quota on /mnt (/dev/sdb3) is on (accounting)

注:在查询project quota状态时,必须增加-v选项以查看详细信息,因为开启quota属性的ext4文件系统quota的状态一直都是on的(即usage enable,这一点不同于未开启quota属性的文件系统),quotaon和quotaoff命令改变的只是limit enable,这里通过-v选项显示的enforced表示limit enable,而accounting表示limit disable,即只做使用计数而不做限制。


限额溢出演示

工具:quota和repquota

1)quota: Usage: quota [-guPqvswim] [-l | [-Q | -A]] [-F quotaformat]
        quota [-qvswim] [-l | [-Q | -A]] [-F quotaformat] -u username ...
        quota [-qvswim] [-l | [-Q | -A]] [-F quotaformat] -g groupname ...
        quota [-qvswugPQm] [-F quotaformat] -f filesystem ...

2)repquota: Utility for reporting quotas.
Usage:
repquota [-vugsi] [-c|C] [-t|n] [-F quotaformat] [-O (default | xml | csv)] (-a | mntpoint)

使用quota和repquota工具可以查看磁盘的配额的当前状态:

# quota -P -s 123  
Disk quotas for project #123 (pid 123): 
     Filesystem   space   quota   limit   grace   files   quota   limit   grace
      /dev/sdb3      4K  10240K  20480K               3       5      10        

# repquota -P /dev/sdb3   
*** Report for project quotas on device /dev/sdb3
Block grace time: 00:05; Inode grace time: 00:05
                        Block limits                File limits
Project         used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
#0        --      20            0           0              2     0     0       
#123      --       4   10240   20480              2     5    10       

以上两条命令打印出sdb3文件系统的project 123所使用的配额状态和限制(当前使用了4KB空间和2个inode...),一目了然。

下面通过往/mnt/dir里创建文件和写入数据的方式来突破softlimit和hardlimit限制,观察系统的反馈(注意:由于root用户默认拥有CAP_SYS_RESOURCE能力,因此hardlimit将不生效,所以需要切换到其他非特权用户进行实验):

$ cd /mnt/dir
$ dd if=/dev/zero of=15M bs=1k count=15k

sdb3: warning, project block quota exceeded.
$ touch xx yy zz aa bb
sdb3: warning, project file quota exceeded.

此时block softlimit和inode softlimit已经被突破,grace period倒计时从预设的5mins开始递减:

quota -P -s 123
Disk quotas for project #123 (pid 123): 
     Filesystem   space   quota   limit   grace   files   quota   limit   grace
      /dev/sdb3  15364K* 10240K  20480K   00:03       8*      5      10   00:03

现在在grace period到期之前可以再继续创建文件和使用空间配额,但是若想要突破hardlimit时会收到以下“Disk quota exceeded”告警,同时命令会执行失败:

$ touch cc dd ee
sdb3: write failed, project file limit reached.
touch: cannot touch 'ee': Disk quota exceeded
$ dd if=/dev/zero of=10M bs=1k count=10k 
dd: failed to open '10M': Disk quota exceeded

然后等待grace period超期,再继续创建文件和写入数据会收到以下“project file quota exceeded too long”的告警,同时命令也执行失败:

$ touch ff
sdb3: write failed, project file quota exceeded too long.
touch: cannot touch 'ff': Disk quota exceeded
$ echo a > aa
sdb3: write failed, project block quota exceeded too long.
-bash: echo: write error: Disk quota exceeded

下面可以使用edquota和setquota的-T选项动态调整倒计时grace time,使之可以继续使用磁盘配额(注:动态调整必须在softlimit限制已经生效的情况下才生效):

# edquota -P -f /dev/sdb3 -T 123
Times to enforce softlimit for project 123 (pid 123):
Time units may be: days, hours, minutes, or seconds
  Filesystem                         block grace               inode grace
  /dev/sdb3                          300seconds                300seconds
# quota -P -s 123                              
Disk quotas for project #123 (pid 123): 
     Filesystem   space   quota   limit   grace   files   quota   limit   grace
      /dev/sdb3  15364K* 10240K  20480K   00:05       8*      5      10   00:05

# setquota -P 123 -T 100 100 /dev/sdb3                           #将grace time设置为100s
# quota -P -s 123
Disk quotas for project #123 (pid 123): 
     Filesystem   space   quota   limit   grace   files   quota   limit   grace
      /dev/sdb3  15364K* 10240K  20480K   00:02       8*      5      10   00:02 

有一点需要注意,使用edquota命令只能将grace time设置为预设值,而setquota则可以设置为任意值,其设置单位为秒。


使用netlink接收内核告警

使用quota的netlink功能需要开启内核的CONFIG_QUOTA_NETLINK_INTERFACE配置选项,同时需安装dbus-devel和libnl3-devel这两个lib,然后在配置quota-tool启用--enable-netlink选项。

应用层使用quota_nld工具来获取内核发送的netlink消息,该工具会创建一个守护进行(默认情况下),然后向终端和DBUS转送netlink上报的告警信息,但是project quota不支持向终端报警。使用方式如下:

quota_nld: Usage: quota_nld [options]
Options are:
 -h --help         shows this text
 -V --version      shows version information
 -C --no-console   do not try to write messages to console
 -b --print-below  write to console also information about getting below hard/soft limits
 -D --no-dbus      do not try to write messages to DBUS
 -F --foreground   run daemon in foreground

运行该程序后,终端会收到以下信息:

# quota_nld -b
$ Warning: project #123 file quota exceeded.
$ Info: project #123 got below file quota.


相关工具命令

quota tool工具包提供了以下几个工具:quota、edquota、quotacheck、quota_nld、quotaon、quotastats、quotasync、repquota、rpc.rquotad、setquota、warnquota、xqmstats和convertquota

其中有一些已经在前文中得示例中见过了,不再赘述,下面简单介绍一下余下得几个工具的功能,详细的可参见manual page:

quotacheck:针对未设置quota属性的文件系统使用user/group quota功能,主要用于检测和修复(创建)quota file,project quota并不涉及;
quotastats:用于查看quota的内核统计计数,输出的参数基本均来自/proc/sys/fs/quota下的proc接口文件中,包括quota实例的创建查询计数等等,将在下一篇博文中详细介绍;
quotasync:类似与sync之类的命令,执行后将直接对quota file同磁盘进行同步;
rpc.rquotad:远程rpc quota服务器,在nfs中使用,不展开;
warnquota:检测文件系统的配额状态,如果有告警消息将通过email发送到超过限额用户的邮箱;
xqmstats:xfs quota manager,ext4文件系统不涉及;
convertquota:该工具用于将未设置quota属性的文件系统中老旧的quota format切换到新的format,只在usr quota和group quota中使用。注:在如果文件系统已经使用old format类型的usr/grp quota,那么若想开启文件系统的quota属性,在使用tune2fs对文件系统添加quota属性之前必须用该工具将quota format切换到最新的,否则tune2fs会返回失败。


总结

本文主要介绍了disk quota和其中project quota的基本知识以及演示了如何在ext4文件系统中使用project quota。总的看来project quota主要继承了以前user/group quota的用法,但社区的开发人员也对内核中ext4文件系统驱动器和vfs层以及相关工具进行了大量的修改,使得这个更加灵活的功能得以支持,用户得以适用与不同的场合中。下一篇博文将介绍project quota得磁盘quota file布局和内核实现。

参考文献

1、Linux man page;
2、Wikipedia:https://en.wikipedia.org/wiki/Disk_quota;
3、kernel/Documentation/filesystems/quota.txt;
4、quota-tools、e2fsprogs and Linux kernel source code.

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐