ИМЯ
quotactl -
управление
дисковыми
квотами
ОБЗОР
#include <sys/quota.h>
#include <xfs/xqm.h> /* для квот XFS */
int quotactl(int cmd, const char *special, int id, caddr_t addr);
ОПИСАНИЕ
С помощью
системы
квот можно
задать
каждому
пользователю,
группе или
проекту
лимит
использования
дискового
пространства.
Для
пользователя
или группы
в каждой
файловой
системе
можно
указать
необязательный
(soft) и
обязательный
(hard) лимиты.
Обязательный
лимит не
может быть
превышен.
Необязательный
лимит
превышать
можно, но
будет
выдано
соответствующее
предостережение.
Более того,
пользователь
может
превышать
необязательный
лимит
только в
течении
льготного
срока (по
умолчанию,одна
неделя);
после
этого
необязательный
лимит
будет
считаться
обязательным.
Управление
квотами
выполняется
с помощью
вызова quotactl(). В
аргументе
cmd задаётся
команда,
которая
должна
быть
применена
для
пользовательского
или
группового
идентификатора,
указанного
в id. Для
инициализации
значения
аргумента
cmd
используйте
макрос QCMD(subcmd, type).
Значение type
может быть
USRQUOTA (для
пользовательских
квот), GRPQUOTA (для
групповых
квот) или
(начиная с Linux
4.1) PRJQUOTA (для
проектных
квот).
Значение
subcmd описано
ниже.
Аргумент
special
представляет
собой
указатель
на строку,
завершающуюся
null и
содержащую
путь к
блочному
устройству
(смонтированному)
с файловой
системой,
на которую
накладывается
квота.
Аргумент
addr
представляет
собой
адрес
необязательной,
зависящей
от команды,
структуры
данных,
которые
копируются
в или из
системы.
Интерпретация
addr указана
ниже (для
каждой
команды).
Значением
subcmd может
быть одно
из:
- Q_QUOTAON
- Включает
учёт квот в
файловой
системе. В
аргументе
id задаётся
используемый
идентификационный
номер
формата
квот. В
настоящее
время
поддерживается
три
формата
квот:
- QFMT_VFS_OLD
- Самая
первая
версия
формата
квот.
- QFMT_VFS_V0
- Стандартный
формат
квот VFS v0,
позволяет
работать с
32-битными UID и
GID и
ограничениями
по квотам
до 2^42 байт и 2^32
inode.
- QFMT_VFS_V1
- Данный
формат
квот
позволяет
работать с
32-битными UID и
GID и
ограничениями
по квотам
до 2^64 байт и 2^64
inode.
- Аргумент
addr
представляет
собой
указатель
на путь к
файлу, в
котором
содержатся
квоты
файловой
системы.
Файл квот
должен
существовать;
обычно он
создаётся
с помощью
программы
quotacheck(8). Данная
операция
требует
дополнительных
прав (CAP_SYS_ADMIN).
- Q_QUOTAOFF
- Выключает
учёт квот в
файловой
системе.
Аргументы
addr и id
игнорируются.
Данная
операция
требует
дополнительных
прав (CAP_SYS_ADMIN).
- Q_GETQUOTA
- Возвращает
данные по
лимитам и
текущее
значение
использованного
пространства
для
пользователя
или группы
с заданным
id.
Аргумент
addr
является
указателем
на
структуру
dqblk,
определённую
в <sys/quota.h>
следующим
образом:
-
/* uint64_t имеет тип unsigned 64-bit integer;
uint32_t имеет тип unsigned 32-bit integer */
struct dqblk { /* определение, действующее с Linux 2.4.22 */
uint64_t dqb_bhardlimit; /* абсолютный лимит на выделяемые
блоки дисковых квот */
uint64_t dqb_bsoftlimit; /* предпочтительный лимит на выделяемые
блоки дисковых квот */
uint64_t dqb_curspace; /* занятое в данный момент пространство
(в байтах) */
uint64_t dqb_ihardlimit; /* максимальное количество
выделенных инод */
uint64_t dqb_isoftlimit; /* предпочтительный лимит на иноды */
uint64_t dqb_curinodes; /* текущее количество
выделенных инод */
uint64_t dqb_btime; /* временной лимит по превышению
использования диска */
uint64_t dqb_itime; /* временной лимит по превышению
файлов */
uint32_t dqb_valid; /* битовая маска констант
QIF_* */
};
/* Флаги в dqb_valid указывают, какие поля в
структуре dqblk являются рабочими. */
#define QIF_BLIMITS 1
#define QIF_SPACE 2
#define QIF_ILIMITS 4
#define QIF_INODES 8
#define QIF_BTIME 16
#define QIF_ITIME 32
#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
#define QIF_USAGE (QIF_SPACE | QIF_INODES)
#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
- Поле dqb_valid
представляет
собой
битовую
маску,
показывающую
какие поля
в
структуре
dqblk
являются
рабочими. В
настоящее
время ядро
заполняется
все поля
структуры
dqblk и
маркирует
их как
рабочие в
поле dqb_valid.
Непривилегированные
пользователи
могут
получить
данные
только по
своим
квотам;
привилегированный
пользователь
(имеющий
мандат CAP_SYS_ADMIN)
может
получить
данные по
квотам
любого
пользователя.
- Q_GETNEXTQUOTA
(начиная с Linux
4.6)
- Эта
операция
подобна
Q_GETQUOTA, но
возвращает
информацию
о квоте для
следующего
ID, большего
или
равного id,
у которого
установлена
квота.
- Аргумент
addr
представляет
собой
указатель
на
структуру
nextdqblk с полями
как у dqblk, но
имеющей
дополнительное
поле dqb_id,
используемое
для
возврата ID,
для
которого
возвращается
информация
по квоте:
-
struct nextdqblk {
uint64_t dqb_bhardlimit;
uint64_t dqb_bsoftlimit;
uint64_t dqb_curspace;
uint64_t dqb_ihardlimit;
uint64_t dqb_isoftlimit;
uint64_t dqb_curinodes;
uint64_t dqb_btime;
uint64_t dqb_itime;
uint32_t dqb_valid;
uint32_t dqb_id;
};
- Q_SETQUOTA
- Устанавливает
квоты для
пользователя
или группы
с
указанным
id,
используя
информацию
из
структуры
dqblk, на
которую
указывает
addr. Полем dqb_valid
в
структуре
dqblk
определяется
какие
элементы
структуры
установлены
вызывающим.
Эта
операция
заменяет
предоставляемые
прежде
операции
работы с
квотами Q_SETQLIM
и Q_SETUSE. Эта
операция
требует
дополнительных
прав (CAP_SYS_ADMIN).
- Q_GETINFO
(начиная с Linux
2.4.22)
- Возвращает
информацию
(например,
льготное
время (grace times)) о
quotafile.
Аргумент
addr должен
содержать
указатель
на
структуру
dqinfo. Эта
структура
определена
в <sys/quota.h>
следующим
образом:
-
/* uint64_t имеет тип unsigned 64-bit integer;
uint32_t имеет тип unsigned 32-bit integer */
struct dqinfo { /* определена начиная с ядра 2.4.22 */
uint64_t dqi_bgrace; /* период времени, после которого блоковый
необязательный лимит становится обязательным */
uint64_t dqi_igrace; /* период времени, после которого инодовый
необязательный лимит становится обязательным */
uint32_t dqi_flags; /* флаги quotafile
(DQF_*) */
uint32_t dqi_valid;
};
/* биты из dqi_flags */
/* формат квот QFMT_VFS_OLD */
#define DQF_ROOT_SQUASH (1 << 0) /* включено ограничение для */
/* суперпользователя; до Linux v4.0 это было закрытым
определением с именем V1_DQF_RSQUASH */
/* формат квот QFMT_VFS_V0 / QFMT_VFS_V1 */
#define DQF_SYS_FILE (1 << 16) /* квота хранится в
системном файле */
/* флаги в dqi_valid, которые показывают какие поля в
структуре dqinfo рабочие. */
#define IIF_BGRACE 1
#define IIF_IGRACE 2
#define IIF_FLAGS 4
#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
- Значение
поля dqi_valid в
структуре
dqinfo
указывает
на рабочие
элементы. В
настоящее
время ядро
заполняет
все
элементы
структуры
dqinfo и
помечает
их как
рабочие в
поле dqi_valid.
Аргумент id
игнорируется.
- Q_SETINFO
(начиная с Linux
2.4.22)
- Задаёт
информацию
о quotafile.
Значение
аргумента
addr должно
быть
указателем
на
структуру
dqinfo. Полем dqi_valid
в
структуре
dqinfo
определяется,
какие
элементы
структуры
установлены
вызывающим.
Эта
операция
заменяет
операции
Q_SETGRACE и Q_SETFLAGS из
предоставляемых
прежде
операций
работы с
квотами.
Аргумент id
игнорируется.
Эта
операция
требует
дополнительных
прав (CAP_SYS_ADMIN).
- Q_GETFMT
(начиная с Linux
2.4.22)
- Возвращает
формат
квоты,
используемый
в
указанной
файловой
системе. В
аргументе
addr должен
содержаться
указатель
на
4-байтовый
буфер, в
который
будет
записан
номер
формата.
- Q_SYNC
- Обновляет
дисковую
копию
используемых
квот в
файловой
системе.
Если
значение
special равно NULL,
то
действующие
квоты
будут
синхронизированы
на всех
файловых
системах.
Аргументы
addr и id
игнорируются.
- Q_GETSTATS
(поддерживалась
до Linux 2.4.21)
- Возвращает
статистику
и другую
общую
информацию
о
подсистеме
квот.
Аргумент
addr должен
содержать
указатель
на
структуру
dqstats, в
которую
нужно
сохранить
данные. Эта
структура
определена
в <sys/quota.h>.
Аргументы
special и id
игнорируются.
- Эта
операция
устарела и
была
удалена в Linux
2.4.22.
Информацию
можно
получить
из файлов в
/proc/sys/fs/quota/.
Для
файловых
систем XFS,
использующих
XFS Quota Manager (XQM),
приведённые
выше
команды не
выполняются,
а
используются
следующие
команды:
- Q_XQUOTAON
- Включает
квоты в
файловой
системе XFS. XFS
позволяет
включать/выключать
лимиты по
квотам с
ведением
учёта.
Поэтому
для XFS в addr
ожидается
указатель
на unsigned int,
который
представляет
собой
комбинацию
следующих
флагов
(определены
в <xfs/xqm.h>):
-
#define XFS_QUOTA_UDQ_ACCT (1<<0) /* учёт пользовательских
квот */
#define XFS_QUOTA_UDQ_ENFD (1<<1) /* применение лимитов
пользовательских квот */
#define XFS_QUOTA_GDQ_ACCT (1<<2) /* учёт групповых
квот */
#define XFS_QUOTA_GDQ_ENFD (1<<3) /* применение лимитов
групповых квот */
#define XFS_QUOTA_PDQ_ACCT (1<<4) /* учёт проектных
квот */
#define XFS_QUOTA_PDQ_ENFD (1<<5) /* применение лимитов
проектных квот */
- Для этой
операции
требуются
права (CAP_SYS_ADMIN).
Аргумент id
игнорируется.
- Q_XQUOTAOFF
- Выключает
квоты для
файловой
системы XFS.
Как в Q_QUOTAON,
для
файловых
систем XFS
ожидается
указатель
на unsigned int, в
котором
задаётся
что нужно
отключить:
учёт или
применение
квот
(используются
флаги из
операции
Q_XQUOTAON). Эта
операция
требует
прав (CAP_SYS_ADMIN).
Аргумент id
игнорируется.
- Q_XGETQUOTA
- Возвращает
данные по
лимитам и
текущее
значение
использованного
пространства
для
пользователя
id.
Аргумент
addr
является
указателем
на
структуру
fs_disk_quota,
определённую
в <xfs/xqm.h>
следующим
образом:
-
/* все части blk в BB (Basic Blocks)
размером 512 байт */
#define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */
#define XFS_USER_QUOTA (1<<0) /* тип пользовательской квоты */
#define XFS_PROJ_QUOTA (1<<1) /* тип проектной квоты */
#define XFS_GROUP_QUOTA (1<<2) /* тип групповой квоты */
struct fs_disk_quota {
int8_t d_version; /* версия данной структуры */
int8_t d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */
uint16_t d_fieldmask; /* определитель поля */
uint32_t d_id; /* ID пользователя, группы или проекта */
uint64_t d_blk_hardlimit; /* абсолютный лимит на
дисковые блоки */
uint64_t d_blk_softlimit; /* предпочтительный лимит на
дисковые блоки */
uint64_t d_ino_hardlimit; /* максимальное кол-во выделяемых
инод */
uint64_t d_ino_softlimit; /* предпочтительный лимит на иноды */
uint64_t d_bcount; /* # кол-во дисковых блоков,
принадлежащих пользователю */
uint64_t d_icount; /* # кол-во инод, принадлежащих пользователю */
int32_t d_itimer; /* ноль, если лимит на иноды не превышен */
/* если нет, то нам отказывают */
int32_t d_btimer; /* подобное предыдущему, но для
дисковых блоков */
uint16_t d_iwarns; /* кол-во предупреждений в соответствии с
кол-вом инод */
uint16_t d_bwarns; /* кол-во предупреждений в соответствии с
кол-вом дисковых блоков */
int32_t d_padding2; /* заполнитель, для использования в будущем */
uint64_t d_rtb_hardlimit; /* абсолютный лимит на работу с дисковыми
блоками в реальном времени (RT) */
uint64_t d_rtb_softlimit; /* предпочтительный лимит на дисковые блоки
в RT */
uint64_t d_rtbcount; /* кол-во дисковых блоков под реальное время */
int32_t d_rtbtimer; /* подобное предыдущему, но
для дисковых блоков RT */
uint16_t d_rtbwarns; /* кол-во предупреждений в соответствии с
дисковыми блоками RT */
int16_t d_padding3; /* заполнитель, для использования в будущем */
char d_padding4[8]; /* ещё заполнитель */
};
- Непривилегированные
пользователи
могут
получить
данные
только по
своим
квотам;
привилегированный
пользователь
(с CAP_SYS_ADMIN) может
получить
информацию
о квотах
любого
пользователя.
- Q_XGETNEXTQUOTA
(начиная с Linux
4.6)
- Эта
операция
подобна
Q_XGETQUOTA, но
возвращает
(in the fs_disk_quota structure pointed by addr)
информацию
о квоте для
следующего
ID, большего
или
равного id,
у которого
установлена
квота.
Заметим,
что так как
в fs_disk_quota уже
есть поле
q_id, то
отдельного
типа для
структуры
не
требуется
(как для Q_GETQUOTA
и Q_GETNEXTQUOTA).
- Q_XSETQLIM
- Устанавливает
дисковую
квоту для
пользователя
с
указанным
id. В
аргументе
addr
задаётся
указатель
на
структуру
fs_disk_quota. Эта
операция
требует
прав (CAP_SYS_ADMIN).
- Q_XGETQSTAT
- Возвращает
доступную
только в XFS
информацию
о квоте в
структуре
fs_quota_stat, на
которую
указывает
addr. Это
полезно
для
определения
количества
пространства,
использованного
для
хранения
информации
о квоте, а
также для
получения
состояния
включения/отключения
квоты
определённой
локальной
файловой
системы XFS.
Структура
fs_quota_stat
определена
следующим
образом:
-
#define FS_QSTAT_VERSION 1 /* fs_quota_stat.qs_version */
struct fs_qfilestat {
uint64_t qfs_ino; /* номер иноды */
uint64_t qfs_nblks; /* количество BB блоков
размером 512 байт */
uint32_t qfs_nextents; /* количество экстентов */
};
struct fs_quota_stat {
int8_t qs_version; /* номер версии
для изменений в будущем */
uint16_t qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
int8_t qs_pad; /* не используется */
struct fs_qfilestat qs_uquota; /* информация о хранилище
пользовательской квоты */
struct fs_qfilestat qs_gquota; /* информация о хранилище
групповой квоты */
uint32_t qs_incoredqs; /* количество dquots в ядре */
int32_t qs_btimelimit; /* лимит для таймера на блоки*/
int32_t qs_itimelimit; /* лимит для таймера на иноды */
int32_t qs_rtbtimelimit;/* лимит для таймера на
блоки RT */
uint16_t qs_bwarnlimit; /* лимит на количество предупреждений */
uint16_t qs_iwarnlimit; /* лимит на количество предупреждений */
};
- Аргумент id
игнорируется.
- Q_XGETQSTATV
- Возвращает
доступную
только в XFS
информацию
о квоте в
структуре
fs_quota_statv, на
которую
указывает
addr. Данная
версия
операции
учитывается
версию
структуры,
а также
соответствие
расположения
(все поля
корректно
выровнены)
и
заполнителей,
чтобы не
выполнять
обработку
совместимости;
также она
предоставляет
возможность
получения
статистики
оп файлу
квот
проекта.
Структура
fs_quota_statv
определена
следующим
образом:
-
#define FS_QSTATV_VERSION1 1 /* fs_quota_statv.qs_version */
struct fs_qfilestatv {
uint64_t qfs_ino; /* номер иноды */
uint64_t qfs_nblks; /* количество BB блоков
размером 512 байт */
uint32_t qfs_nextents; /* количество экстентов */
uint32_t qfs_pad; /* заполнитель для 8-байтового выравнивания */
};
struct fs_quota_statv {
int8_t qs_version; /* версия для изменений
в будущем */
uint8_t qs_pad1; /* заполнитель для 16-битного выравнивания */
uint16_t qs_flags; /* флаги XFS_QUOTA_.* */
uint32_t qs_incoredqs; /* количество dquots incore */
struct fs_qfilestatv qs_uquota; /* информация
о пользовательской квоте */
struct fs_qfilestatv qs_gquota; /* информация
о групповой квоте */
struct fs_qfilestatv qs_pquota; /* информация
о проектной квоте */
int32_t qs_btimelimit; /* лимит по таймеру на блоки */
int32_t qs_itimelimit; /* лимит по таймеру на иноды */
int32_t qs_rtbtimelimit; /* лимит по таймеру
на блоки RT */
uint16_t qs_bwarnlimit; /* лимит на кол-во предупреждений */
uint16_t qs_iwarnlimit; /* лимит на кол-во предупреждений */
uint64_t qs_pad2[8]; /* для использования в будущем */
};
- Поле qs_version
должно
быть
заполнено
версией
структуры,
поддерживаемой
вызываемым
(пока
поддерживается
только
FS_QSTAT_VERSION1). Ядро
заполнит
структуру
согласно
предоставленной
версии.
Аргумент id
игнорируется.
- Q_XQUOTARM
- Освободить
место на
диске,
занятое
квотами. В
аргументе
addr должен
быть
указатель
на
значение
unsigned int,
содержащее
флаги (те
же, что и
для поля d_flags
структуры
fs_disk_quota),
которые
показывают
какие типы
квот
должны
быть
удалены
(заметим,
что тип
квот,
передаваемый
в
аргументе
cmd,
игнорируется,
но должен
быть
корректным,
чтобы
пройти
предварительные
проверки
обработчика
системного
вызова quotactl).
- Квоты
должны
быть
предварительно
выключены.
Аргумент id
игнорируется.
- Q_XQUOTASYNC
(начиная с Linux
2.6.15; ничего не
делает
начиная с Linux
3.4)
- Данная
команда
была
эквивалентом
Q_SYNC в XFS, но
начиная с Linux
3.4 она
ничего не
делает, так
как
информации
о квоте на
диск
теперь
записывает
sync(1) (вместе с
записью
других
метаданных
файловой
системы).
Аргументы
special, id и addr
игнорируются.
ВОЗВРАЩАЕМОЕ
ЗНАЧЕНИЕ
При
успешном
выполнении
quotactl()
возвращается
0; при ошибке
возвращается
-1, а в errno
содержится
код
ошибки.
ОШИБКИ
- EACCES
- Значение
cmd равно Q_QUOTAON
и файл
квот,
указанный
в addr,
существует,
но не
является
обычным
файлом или
находится
не в
файловой
системе,
указанной
в special.
- EBUSY
- Значение
cmd равно Q_QUOTAON,
но уже
выполняется
другой
запуск Q_QUOTAON.
- EFAULT
- Неверное
значение
addr или special.
- EINVAL
- Неверное
значение
cmd или type.
- EINVAL
- Значение
cmd равно Q_QUOTAON,
но
указанный
файл квот
повреждён.
- ENOENT
- Файл,
указанный
в special или addr,
не
существует.
- ENOSYS
- Ядро
собрано с
выключенным
параметром
CONFIG_QUOTA.
- ENOTBLK
- Значение
special не
указывает
на блочное
устройство.
- EPERM
- Вызывающий
не имеет
необходимых
прав (CAP_SYS_ADMIN)
для
выполнения
указанной
операции.
- ERANGE
- Значение
cmd равно Q_SETQUOTA,
но
заданный
лимит вне
диапазона
допустимого
форматом
квот.
- ESRCH
- Не найдена
дисковая
квота для
заданного
пользователя.
Квоты
выключены
в файловой
системе.
- ESRCH
- Значение
cmd равно Q_QUOTAON,
но
заданный
формат
квот не
найден.
- ESRCH
- Значение
cmd равно Q_GETNEXTQUOTA
или Q_XGETNEXTQUOTA, но
нет ID,
который
больше или
равен id с
активной
квотой.
ЗАМЕЧАНИЯ
Вместо
<xfs/xqm.h> может
быть
использован
<linux/dqblk_xfs.h>, но
следует
учесть, что
есть
несколько
несоответствий
названий:
- Флаги
включения
квот
(формата
XFS_QUOTA_[UGP]DQ_{ACCT,ENFD})
определены
без
начального
«X» в виде
FS_QUOTA_[UGP]DQ_{ACCT,ENFD}.
- Это же
верно и для
флагов
типов квот
XFS_{USER,GROUP,PROJ}_QUOTA,
которые
определены
как FS_{USER,GROUP,PROJ}_QUOTA.
- В
заголовочном
файле dqblk_xfs.h
определены
свои
константы
XQM_USRQUOTA, XQM_GRPQUOTA и XQM_PRJQUOTA
для
доступных
типов квот,
но их
значения
совпадают
с
константами
без
префикса
XQM_.