ИМЯ 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).
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;
в структуре 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 должен содержать указатель на структуру 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 */ 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; /* количество экстентов */ }; групповой квоты */ 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 должен быть Данная команда была эквивалентом 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_.
|