На сервере с несколькими пользователями рано или поздно один аккаунт съедает весь свободный раздел, и остальные остаются без места для собственных файлов. Пакет quota решает эту проблему на уровне файловой системы: администратор задаёт каждому пользователю или группе предел по объёму данных и количеству файлов, а система сама следит за соблюдением границы, не требуя постоянного ручного контроля со стороны администратора. Разбираемся, как включить квоты на ext4, назначить лимиты и затем контролировать, кто и сколько места реально расходует.

Что такое дисковые квоты и зачем они нужны

Квота ограничивает пользователя сразу по двум параметрам: количеству занятых блоков, то есть фактическому объёму данных, и количеству inode, то есть числу файлов и каталогов независимо от их размера. Второй параметр часто недооценивают, но именно он спасает сервер от ситуации, когда пользователь создаёт миллионы крошечных файлов и исчерпывает таблицу inode задолго до того, как закончится физическое место на диске. У каждого лимита в quota есть два уровня: мягкий (soft) и жёсткий (hard). Мягкий лимит можно временно превысить, система лишь предупредит пользователя и включит обратный отсчёт грационного периода, а жёсткий лимит превысить невозможно в принципе, запись новых данных просто завершится ошибкой нехватки места. Такая двухуровневая модель удобна на практике: она даёт пользователю время разобраться с переполнением, например удалить старые файлы, вместо того чтобы резко обрывать его работу в момент превышения границы. На практике проблема с исчерпанием inode встречается чаще, чем кажется на первый взгляд: почтовый сервер, который хранит письма отдельными файлами, система сборки с тысячами промежуточных объектных файлов или неаккуратный скрипт резервного копирования способны создать миллионы мелких записей и полностью забить таблицу inode на разделе объёмом всего в несколько гигабайт, тогда как физическое место на диске при этом останется практически нетронутым. Именно поэтому грамотная настройка квот всегда учитывает оба параметра одновременно, а не ограничивается только объёмом данных в мегабайтах и гигабайтах.

Установка пакета и подготовка файловой системы

В большинстве дистрибутивов инструменты для управления квотами собраны в отдельном пакете, который ставится одной командой:

apt install quota
dnf install quota

Далее файловую систему нужно подготовить к учёту квот. Для этого в файле /etc/fstab у нужного раздела добавляются опции монтирования usrquota для пользовательских лимитов и grpquota для групповых:

/dev/sdb1  /home  ext4  defaults,usrquota,grpquota  0  2

После правки файла раздел нужно перемонтировать без перезагрузки сервера:

mount -o remount /home

На современных ядрах и актуальных версиях ext4 квоты чаще всего реализованы как встроенная функция файловой системы со скрытыми служебными inode, и в этом случае отдельного шага с построением файлов учёта уже не требуется. На более старых системах или при использовании внешнего формата квот нужно вручную создать файлы учёта командой quotacheck, которая просканирует раздел и построит базу данных по текущему использованию места каждым пользователем и группой:

quotacheck -cug /home

Флаг -c указывает создать файлы заново, -u включает учёт по пользователям, а -g по группам. После этого квоты остаётся только включить. Стоит также отметить разницу между старым внешним форматом хранения квот и более новым журналируемым форматом vfsv1: журналируемые квоты хранят учётные данные внутри самого журнала файловой системы, за счёт чего переживают внезапную перезагрузку или сбой питания без необходимости заново пересчитывать использование каждым пользователем командой quotacheck, тогда как классический внешний формат в таких ситуациях иногда требует ручного пересчёта после нештатного выключения сервера.

Включение учёта и первый запуск ограничений

Активация квот на уже подготовленном разделе выполняется командой quotaon:

quotaon -v /home

Флаг -v включает подробный вывод, чтобы сразу увидеть, для каких категорий, пользователей или групп, учёт заработал. Если впоследствии квоты понадобится временно снять, не удаляя саму настройку, для этого есть обратная команда quotaoff, которая отключает принудительное соблюдение лимитов, но сохраняет уже накопленную статистику использования. Стоит иметь в виду, что на XFS вся эта цепочка выглядит иначе: там нет ни quotacheck, ни classic quotaon, а квоты включаются напрямую опциями монтирования uquota и gquota, после чего управление идёт через отдельную утилиту xfs_quota, разница между двумя подсистемами разбирается ближе к концу статьи.

Назначение лимитов через edquota и setquota

Для интерактивной настройки конкретного пользователя используется команда edquota, которая открывает временный файл в текстовом редакторе, заданном переменной окружения EDITOR:

edquota -u alice

Файл выглядит примерно так:

Disk quotas for user alice (uid 1001):
Filesystem  blocks  soft  hard  inodes  soft  hard
/dev/sdb1    44043     0     0   37418     0     0

Первая пара soft и hard задаёт лимит по объёму данных в килобайтах, вторая пара по количеству файлов. Нулевое значение означает отсутствие ограничения по этой категории. Для ускорения процесса те же значения можно задать одной командой без открытия редактора через setquota, что особенно удобно при автоматизации настройки через скрипты:

setquota -u alice 5242880 6291456 0 0 /home

В этом примере пользователю alice выделяется 5 гигабайт мягкого лимита и 6 гигабайт жёсткого при отсутствии ограничения по числу файлов, поскольку значения по inode оставлены нулевыми. При попытке записать файл сверх жёсткого лимита система немедленно откажет с ошибкой, которую хорошо видно даже в выводе обычной команды копирования:

dd: writing 'testfile': Disk quota exceeded

Это поведение полезно держать в уме при диагностике: если пользователь жалуется, что программа неожиданно обрывает запись файла без видимой причины, в первую очередь стоит проверить именно квоту пользователя, а не списывать сбой на неисправность диска, повреждение файловой системы или ошибку в самом приложении. Групповые квоты настраиваются той же парой команд с флагом -g вместо -u, и распространяются на все файлы этой группы, независимо от того, какой конкретно пользователь их создал.

Шаблоны и массовое применение лимитов

Когда одинаковые лимиты нужно назначить сразу нескольким учётным записям, вручную повторять edquota для каждой из них неудобно. Для этого edquota поддерживает флаг -p, который копирует уже настроенные лимиты одного пользователя как шаблон на список других:

edquota -p alice bob charlie dave

Команда возьмёт значения soft и hard, уже сохранённые для alice, и применит их к bob, charlie и dave за один проход. Такой подход особенно полезен при добавлении новых учётных записей на сервер: администратор один раз настраивает эталонного пользователя, а затем распространяет его лимиты на всех вновь заведённых сотрудников без риска опечататься в конкретных цифрах при ручном вводе для каждого аккаунта по отдельности. Ту же задачу легко завернуть в простой цикл в скрипте, если список новых пользователей регулярно приходит из внешней системы кадрового учёта или из скрипта автоматического создания учётных записей:

for user in bob charlie dave; do
  edquota -p alice "$user"
done

Такой подход избавляет от необходимости хранить конкретные числовые значения лимитов сразу в нескольких местах: достаточно один раз поправить квоту эталонного пользователя, а затем заново прогнать цикл по остальным аккаунтам.

Грационный период и что происходит при превышении лимита

Мягкий лимит без ограничения по времени был бы бесполезен, поэтому у него есть отдельная настройка грационного периода, задаваемая для всей файловой системы сразу командой edquota -t. Она открывает редактор со списком разделов и позволяет указать, сколько времени пользователю разрешено оставаться выше мягкого лимита, прежде чем система начнёт обращаться с ним как с превысившим жёсткий лимит:

edquota -t

По умолчанию период обычно равен семи дням, но его можно сократить до нескольких часов или, наоборот, увеличить, в зависимости от того, насколько строго администратор хочет контролировать временные всплески использования места. Пока действует грационный период, пользователь по-прежнему может создавать новые файлы, но получает предупреждение при каждой попытке записи, а когда время истекает, система перестаёт принимать новые данные точно так же, как при достижении жёсткого лимита, пока пользователь не освободит место ниже границы мягкого лимита. На практике грационный период стоит настраивать с оглядкой на реальные рабочие сценарии на сервере: слишком короткий срок вроде нескольких часов будет постоянно раздражать пользователей ложными предупреждениями во время обычных пиков активности, например при массовой загрузке отпускных фотографий, а слишком длинный период в несколько недель фактически превращает мягкий лимит в чистую формальность и лишает квоту практического смысла как инструмента контроля.

Контроль расхода места и автоматизация отчётов

Для проверки собственного использования диска обычный пользователь может выполнить простую команду:

quota -s

Флаг -s переводит вывод в человекочитаемые единицы вроде мегабайт и гигабайт вместо голых чисел блоков. Администратору для обзора сразу всех пользователей раздела пригодится repquota, показывающая текущее потребление, лимиты и остаток грационного периода одной таблицей:

repquota -s /home

В выводе символ плюс рядом с именем пользователя означает превышение мягкого лимита, а минус говорит о том, что использование пока укладывается в границы; отдельная колонка grace показывает, сколько времени осталось до того, как превышение мягкого лимита начнёт трактоваться как жёсткое. Для регулярного контроля эту команду удобно поставить в задачу планировщика cron, чтобы отчёт о состоянии квот приходил на почту администратора автоматически без необходимости заходить на сервер и проверять состояние дисков вручную:

0 7 * * 1  repquota -us /home | mail -s "Еженедельный отчёт по квотам" [email protected]

Наконец, для XFS вся логика назначения и проверки лимитов переезжает в единую утилиту xfs_quota, работающую в интерактивном или пакетном режиме через флаг -x:

xfs_quota -x -c 'limit bsoft=5g bhard=6g alice' /data
xfs_quota -x -c 'report -ubh' /data

Несмотря на разный набор команд, логика полностью совпадает с классической подсистемой quota: тот же принцип мягкого и жёсткого лимита, та же двойная граница по блокам и inode, только вместо связки quotacheck, edquota и repquota всё управление сосредоточено в одной команде с разными подрежимами. Отдельного упоминания заслуживают проектные квоты, исторически появившиеся именно в XFS, но сегодня поддерживаемые и на ext4 начиная с ядра Linux 4.4 и пакета e2fsprogs 1.43: они ограничивают не пользователя или группу, а конкретный каталог целиком, независимо от того, кто именно из пользователей туда пишет, что удобно для общих каталогов вроде логов приложений или загрузок с сайта, где важно ограничить именно директорию, а не отдельного владельца файлов внутри неё. Список директорий для проектных квот задаётся в файле /etc/projects, а человекочитаемые имена проектов сопоставляются с числовыми идентификаторами через /etc/projid, после чего на XFS лимиты назначаются командой xfs_quota с флагом -p вместо -u или -g, а на ext4 каталог сначала привязывается к номеру проекта командой chattr -p ID +P /путь/к/папке, после чего сами лимиты задаются уже привычной edquota с флагом -P. Для домашнего или небольшого рабочего сервера обе схемы одинаково надёжны, и выбор между ними определяется в первую очередь тем, какая файловая система уже стоит на разделе с пользовательскими данными, а не абстрактным превосходством одного набора утилит над другим.