Ext4 Project Quota磁盤配額使用介紹

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.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章