QUOTACTL(2)

ИМЯ
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_.

СМОТРИТЕ ТАКЖЕ
quota(1), getrlimit(2), quotacheck(8), quotaon(8)