这里使用了exf4
中prjquota
的特性。
假如想要调整的目录路径为:/disk/Individual-limits/machunjie
那么,只需要以下步骤即可:
mkdir -p /disk/Individual-limits/machunjie
echo "machunjie:2002" >> /etc/projid
echo "2002:/disk/Individual-limits/machunjie" >> /etc/projects
xfs_quota -x -f -c "project -s machunjie" /disk
xfs_quota -x -f -c "limit -p bsoft=280G bhard=300G machunjie" /disk
xfs_quota -x -f -c "report -p" /disk
可以看到结果:
1 2 3 |
root@autodl:/disk/Individual-limits/machunjie# df -hT /disk/Individual-limits/machunjie Filesystem Type Size Used Avail Use% Mounted on /dev/sdc1 ext4 280G 4.0K 280G 1% /disk |
有几点需要注意:
1、2002
是身份ID
,可以随意设置,只要与其他目录不一致就行
2、需要先确认你的挂载点/disk
是否开启prjquota
特性
3、这里设置了软限制和硬限制,区别:
Soft limit
:超过这个值时,系统会开始发出警告,但在宽限期(grace period
)内仍允许写入。
Hard limit
:绝对上限,超过就直接报 Disk quota exceeded
,无法再写入。
自动化脚本
下面提供一个自动化脚本,可以方便的创建磁盘限额,使用的时候,以 root
运行,把挂载点(默认 /disk
)改成你的实际挂载点即可。
脚本名称:set_project_quota.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
#!/usr/bin/env bash set -euo pipefail # Usage: # set_project_quota.sh <name> <path> <soft> <hard> [--mount /disk] [--id 2001] [--grace 7days] # # Examples: # set_project_quota.sh lijiaqing /disk/Individual-limits/lijiaqing 0 200G --mount /disk # set_project_quota.sh machunjie /disk/Individual-limits/machunjie 280G 300G --mount /disk --id 2002 --grace 3days NAME="${1:-}"; shift || true PATH_DIR="${1:-}"; shift || true SOFT="${1:-}"; shift || true HARD="${1:-}"; shift || true MOUNT_POINT="/disk" EXPLICIT_ID="" GRACE="" # ---- Parse optional flags ---- while [[ $# -gt 0 ]]; do case "$1" in --mount) MOUNT_POINT="${2:-}"; shift 2;; --id) EXPLICIT_ID="${2:-}"; shift 2;; --grace) GRACE="${2:-}"; shift 2;; *) echo "Unknown arg: $1"; exit 1;; esac done if [[ -z "${NAME}" || -z "${PATH_DIR}" || -z "${SOFT}" || -z "${HARD}" ]]; then echo "Usage: set_project_quota.sh <name> <path> <soft> <hard> [--mount /disk] [--id 2001] [--grace 7days]" exit 1 fi command -v xfs_quota >/dev/null 2>&1 || { echo "xfs_quota not found. Install xfsprogs."; exit 1; } # ---- Basic checks ---- [[ -d "${MOUNT_POINT}" ]] || { echo "Mount point ${MOUNT_POINT} not found."; exit 1; } mount | grep -qE " on ${MOUNT_POINT} " || { echo "${MOUNT_POINT} is not a mount point."; exit 1; } mount | grep -E " on ${MOUNT_POINT} " | grep -q prjquota || { echo "WARNING: ${MOUNT_POINT} not mounted with prjquota. Please enable 'prjquota' and remount."; exit 1; } mkdir -p "${PATH_DIR}" # ---- Ensure /etc/projid and /etc/projects exist ---- touch /etc/projid /etc/projects # ---- Get or assign Project ID ---- get_id_by_name() { awk -F: -v n="$1" '$1==n{print $2}' /etc/projid | tail -n1 } get_path_by_id() { awk -F: -v i="$1" '$1==i{print $2}' /etc/projects | tail -n1 } PID="$(get_id_by_name "${NAME}")" if [[ -n "${EXPLICIT_ID}" ]]; then PID="${EXPLICIT_ID}" fi if [[ -z "${PID}" ]]; then # auto-generate numeric ID from name, avoid collisions # start from checksum; if occupied, add 1 until free BASE=$(echo -n "${NAME}" | cksum | awk '{print $1}') PID="${BASE}" while grep -qE "^${PID}:" /etc/projects || grep -qE "^.*:${PID}$" /etc/projid; do PID=$((PID + 1)) done fi # ---- Wire name<->id and id<->path (idempotent updates) ---- # /etc/projid: NAME:PID if grep -qE "^${NAME}:" /etc/projid; then # update existing name mapping sed -i -E "s|^(${NAME}:).*|\1${PID}|" /etc/projid else echo "${NAME}:${PID}" >> /etc/projid fi # /etc/projects: PID:/path if grep -qE "^${PID}:" /etc/projects; then # update path for this PID sed -i -E "s|^(${PID}:).*|\1${PATH_DIR}|" /etc/projects else echo "${PID}:${PATH_DIR}" >> /etc/projects fi # ---- Initialize project on filesystem ---- xfs_quota -x -f -c "project -s ${NAME}" "${MOUNT_POINT}" # ---- Set limits ---- # SOFT=0 means clear soft limit if [[ "${SOFT}" == "0" || "${SOFT}" == "none" || "${SOFT}" == "NONE" ]]; then xfs_quota -x -f -c "limit -p bsoft=0 bhard=${HARD} ${NAME}" "${MOUNT_POINT}" else xfs_quota -x -f -c "limit -p bsoft=${SOFT} bhard=${HARD} ${NAME}" "${MOUNT_POINT}" fi # ---- Set grace (optional, only matters if bsoft>0) ---- if [[ -n "${GRACE}" && "${SOFT}" != "0" && "${SOFT}" != "none" && "${SOFT}" != "NONE" ]]; then xfs_quota -x -f -c "timer -p bsoft=${GRACE}" "${MOUNT_POINT}" || true fi # ---- Show result ---- echo "==== Quota report for ${NAME} (PID ${PID}) on ${MOUNT_POINT} ====" xfs_quota -x -f -c "report -p" "${MOUNT_POINT}" | awk -v n="${NAME}" 'NR==1,NR==3{print; next} $1==n{print; seen=1} END{if(!seen) print "Not found in report (unexpected)."}' echo "Done." |
命令:
1. 给 machunjie 新建目录并设置 300G 硬限额(不设软限额):
bash set_project_quota.sh machunjie /disk/Individual-limits/machunjie 0 300G --mount /disk --id 2002
1. 给 machunjie 新建目录并设置 180G软限额和300G 硬限额:
bash set_project_quota.sh machunjie /disk/Individual-limits/machunjiee 180G 200G --mount /disk