.\" Copyright (c) 2003-2004 Andrey Simonenko .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)$Id: ipa_mod.3,v 1.2.2.4 2007/07/20 09:53:40 simon Exp $ .\" .TH IPA_MOD 3 "16 апреля 2005 г." .SH НАИМЕНОВАНИЕ ipa_mod -\- API модулей IPA .SH СИНТАКСИС \fB#include \fP .SH ОПИСАНИЕ Эта страница документации описывает API всех типов IPA модулей. Будем называть любой IPA модуль просто ``модулем''. Информация, представленная в этом фале, в основном для разработчиков, но она может быть интересна любому, кто желает понять как утилиты IPA работают с IPA модулями. .PP Эта страница документации содержит описания следующих API: .PP ipa_memfunc API версия 1 (IPA_MEMFUNC_API_VERSION); .br ipa_ac_mod API версия 1 (IPA_AC_MOD_API_VERSION); .br ipa_db_mod API версия 1 (IPA_DB_MOD_API_VERSION); .br ipa_st_mod API версия 1 (IPA_ST_MOD_API_VERSION). .PP В этой документации используется тип \fIu_int\fP, который на самом деле является \fIunsigned\ int\fP, и он не определён в \fB\fP. .PP \fBИменование символов в модулях.\fP .PP Любой модуль это файл с именем подобным \fIfoobar\-x.y.z.so\fP. После загрузки модуля при помощи функции dlopen(3) или аналогичной, IPA утилита убирает номер версии и суффикс из имени файла модуля и пытается найти символ \fIfoobar_ac_mod\fP, \fIfoobar_db_mod\fP или \fIfoobar_st_mod\fP в модуле если модуль является модулем учёта, базы данных или статистики. Если модуль содержит искомый символ, то он принимается за IPA модуль. .PP Затем найдены указатель (void\ *) преобразуется в один из трёх указателей \fI(struct\ ipa_XX_mod\ *)\fP. Структуры \fIstruct\ ipa_XX_mod\fP определяют API между IPA утилитами и модулями. .PP Такой метод именования символов в модулях позволяет хранить несколько модулей различных типов в одном файле. Также возможно создать линки с различными именами на файл модуля, чтобы следовать заданной схеме именования. .PP \fBОдно- и многопотоковые модули.\fP .PP Любой модуль может быть однопотоковым или многопотоковым. Если не ожидается, что модуль может быть заблокирован в какой-то из своих функций, то он может быть спроектирован как однопотоковый. Если ожидается, что модуль может быть заблокирован в какой-то из своих функций или если модуль должен постоянно осуществлять мониторинг некоторого события, то этот модуль должен быть спроектирован как многопотоковый. В качестве альтернативы модуль может вызвать fork(2) и использовать некоторую форму IPC, чтобы взаимодействовать с новым процессом из какой-либо своей функции и используемая функция для организации IPC должна быть неблокируемая. .PP Если модуль однопотоковый, то он может использовать сигналы в личных целях (например SIGALRM, чтобы реализовать таймаут), за исключением сигналов, используемых IPA утилитой, которая загрузила этот модуль. Если модель многопотоковый, то ему не разрешается использовать сигналы. .PP Очень важно вернуться из функции модуля как можно быстрее, так как IPA утилиты ожитают, что функции модуля не будут блокироваться. Если модуль проводит слишком много времени в своих функциях, то временные отметки статистики и реакция на запланированные события не будут очень точными. .PP Даже если модуль не спроектирован как многопотоковый, то другие модули могут быть многопотоковыми. Все загружаемые модуль должны быть либо однопотоковыми, либо многопотоковыми. Таким образом любой однопотоковый модуль должен быть готовым для сборки как многопотоковый. Модуль всегда должен устанавливать правильный флаг в своей структуре API, для того, чтобы сообщить является он однопотоковым или многопотоковым. .PP Утилиты IPA созданы как однопотоковые, но если используется хотябы один многопотоковый модуль, то они должны быть собраны как многопотоковые. В многопотоковом режиме функции из \fIipa_memfunc\fP, которая экспортируется IPA утилитами, становятся готовыми к многопотоковой работе. .PP Модулям разрешается создавать потоки, только после фазы конфигурации. .PP \fBЭкспортируемые модулю функции работы с памятью.\fP .PP API модулей требуют определённой организации данных в модулях. Функции \fIipa_memfunc\fP экспортируются модуля и пытаются помочь модулю в работе с памятью. Модуль свободен в выборе использовать или нет эти функции. В некоторых функциях требуется использования функций из \fIipa_memfunc\fP. .PP Существуют четыре типа функций в \fIipa_memfunc\fP: функции инициализации и деинициализации, функции работы с памятью общего назначения, функции работы с mzone и функции работы с marray. .PP Функции \fImem_*\fP для работы с памятью общего назначения это врапперы для стандартных функций работы с памятью из библиотеки (malloc(3), calloc(3), realloc(3), free(3), strdup(3) и для функции vasprintf(3), присутствующей на некоторых системах). Все эти функции выполняют дополнительные проверки. Любая память выделенная с помощью функции \fImem_*\fP должна быть освобождена с помощью функции \fImem_free\fP. Эти функции принимают дополнительный аргумент, называемый \fImem_type\fP (тип памяти), который используется для сбора статистики об использовании памяти. Этот \fImem_type\fP должен быть создан функцией \fImem_type_new\fP. .PP М-массивы используются для создания массивов некоторых элементов. М-зоны используются для создание элементов одного размера. Все функции \fImarray_*\fP и \fImzone_*\fP сами используют функции \fImem_*\fP. .PP Функции из \fIipa_memfunc\fP обнаруживают неправильные указатели и некорректные аргументы в функциях \fImem_*\fP, \fImarray_*\fP и \fImzone_*\fP. Если будет обнаружена критическая ошибка в любой из этих функций, то эта функция завершит выполнение программы с генерацией дампа памяти. .PP Если IPA утилиты были собраны с определённой макропеременной WITH_MEMFUNC_DEBUG, то выделяемая и освобождаемая память заполняется случайными байтами, таким образом, если некоторая часть кода продолжает использовать уже освобождённую память, то вероятно, что эта ошибка будет обнаружена. Также \fImem_realloc\fP в этом случае является эквивалентом такой последовательности: malloc(3) для новой области памяти, memcpy(3) старой области памяти в новую, free(3) для старой области памяти. .PP Любая IPA утилита во время завершения работы и во время реконфигурации проверяет размер выделенной и не освобождённой памяти, если этот размер не равен нулю, то посылается отладочное сообщение. Если какая-то mzone или marray не был деинициализирован, то также посылается отладочное сообщение с соответствующим именем. .PP Структура \fIipa_memfunc\fP имеет следующий формат: .PP .nf typedef struct ipa_mem_type_struct ipa_mem_type; typedef struct ipa_marray_struct ipa_marray; typedef struct ipa_mzone_struct ipa_mzone; typedef struct { u_int api_ver; int (*memfunc_init)(void); void (*memfunc_deinit)(int foreign); ipa_mem_type *m_parser; ipa_mem_type *(*mem_type_new)(const char *name, const char *desc, u_int flags); void *(*mem_malloc)(size_t size, ipa_mem_type *mem_type); void *(*mem_calloc)(size_t number, size_t size, ipa_mem_type *mem_type); void *(*mem_realloc)(void *ptr, size_t size, ipa_mem_type *mem_type); char *(*mem_strdup)(const char *str, ipa_mem_type *mem_type); int (*mem_vasprintf)(ipa_mem_type *mem_type, char **bufp, const char *format, va_list ap); void (*mem_free)(void *ptr, ipa_mem_type *mem_type); ipa_marray *(*marray_init)(const char *name, const char *desc, u_int flags, void **arr, size_t isize, u_int nitems, u_int nalloc); void (*marray_deinit)(ipa_marray *marray); int (*marray_alloc)(ipa_marray *marray, u_int *idxp, int fixed); void (*marray_free)(ipa_marray *marray, u_int idx); void (*marray_minimize)(ipa_marray *marray); int (*marray_check_index)(ipa_marray *marray, u_int idx); u_int (*marray_nused)(ipa_marray *marray); ipa_mzone *(*mzone_init)(const char *name, const char *desc, u_int flags, size_t isize, u_int nitems, u_int nalloc); void (*mzone_deinit)(ipa_mzone *mzone); void *(*mzone_alloc)(ipa_mzone *mzone); void (*mzone_free)(ipa_mzone *mzone, void *ptr); u_int (*mzone_nused)(ipa_mzone *mzone); } ipa_memfunc; .fi .IP \fIapi_ver\fP Версия API \fIipa_memfunc\fP, модуль должен проверить версии поддерживаемых API с IPA_MEMFUNC_API_VERSION во время компиляции. .IP \fImemfunc_init\fP Потомок модуля может вызвать эту функцию чтобы инициализировать другие \fIipa_memfunc\fP функции. .IP \fImemfunc_deinit\fP Потомок модуля может вызвать эту функцию чтобы освободить всю память в mzone и marray, и деинициализировать собственные структуры \fIipa_memfunc\fP. Если флаг \fIforeign\fP не равен нулю, то все сообщения об утечке памяти не будут выводится и статистика об использовании памяти будет обнулена. Заметьте, что эта и предыдущая функция могут быть вызваны только в потомке модуля. .IP \fIm_parser\fP Это указатель на mem_type используемый в парсере во время разбора конфигурационного файла. .IP \fImem_type_new\fP Создать новый mem_type, \fIname\fP это короткое имя для нового mem_type, \fIdesc\fP это его описание (обычно несколько слов) и \fIflags\fP это флажки для нового mem_type. На данный момент определён только один флаг IPA_MEMFUNC_FLAG_PTHREAD, который должен быть установлен если память с этим mem_type будет выделяться или освобождаться в нескольких потоках асинхронно. Эта функция возвращает указатель на новый mem_type или NULL в случае ошибки. .IP \fImem_malloc\fP Аналог malloc(3). .IP \fImem_calloc\fP Аналог calloc(3). .IP \fImem_realloc\fP Аналог realloc(3). .IP \fImem_strdup\fP Аналог strdup(3). .IP \fImem_vasprintf\fP Аналог vasprintf(3) присутствующей на некоторых системах. Эта функция устанавливает в \fI*bufp\fP указатель на буфер достаточного объёма для хранения форматированной строки. Если не удалось выделить достаточного объёма памяти, то эта функция возвращает -1 и устанавливает в \fI*bufp\fP NULL. Аргументы \fIformat\fP и \fIap\fP аналогичны аргументам в функции vprintf(3). .IP \fImem_free\fP Аналог free(3). .IP \fImarray_init\fP Создать marray, \fIname\fP это имя marray, которое должно существовать, пока marray не будет деинициализирован. Лучше давать имя marray в форме :. \fIdesc\fP это его описание (обычно несколько слов). \fIflags\fP определяет флажки для нового marray, на данный момент определён только один флаг IPA_MEMFUNC_FLAG_PTHREAD, этот флаг должен быть определён, если элементы из этого marray будет выделяться и освобождаться несколькими потоками асинхронно. \fIarr\fP это указатель памяти где необходимо сохранять указатель на действительный массив элементов. \fIisize\fP это размер одного элемента в массиве. \fInitems\fP обозначает количество элементов, под которое необходимо изначально выделить память. \fInalloc\fP обозначает количество элементов, которое необходимо выделять, если в marray не осталось ни одного свободного элемента. Если вы не уверены в значениях этих аргументов, то установите их в 1. Эта функция возвращает указатель на только что созданный marray или NULL, если возникла какая-то ошибка. Заметьте, что указатель сохранённый в памяти указываемой \fIarr\fP может быть изменён последующими вызовами функций \fImarray_alloc\fP и \fImarray_free\fP. .IP \fImarray_deinit\fP Освободить память занимаемую \fImarray\fP. Если модуль не вызовет эту функцию, то IPA утилита сообщит об утечке памяти и деинициализирует marray модуля, но эта деинициализация не означает, что утечка памяти не возможна, так как деинициализация marray не освобождает память, на которую, возможно, указывают элементы массива. Если \fImarray\fP равен NULL, то эта функция ничего не делает. .IP \fImarray_alloc\fP Выделить память для нового элемента в \fImarray\fP. Если \fIfixed\fP не равен нулю, то \fI*idxp\fP должен указывать быть желаемым индексом нового элемента в \fImarray\fP, иначе эта функция должна выделить память для элемента с наименьшим возможным индексом и сохранить этот индекс в \fI*idxp\fP. Эта функция возвращает 0, если память под новый элемент была выделена и -1, в случае ошибки. Обычно модуль вызывает эту функцию с ненулевым значением \fIfixed\fP. .IP \fImarray_free\fP Вернуть прежде выделенный элемент с индексом \fIidx\fP в \fImarray\fP. .IP \fImarray_minimize\fP Попробовать минимизировать память, занимаемую \fImarray\fP. Такая минимизация возможна, так как \fImarray_alloc\fP и \fImarray_free\fP пытаются держать дополнительную память для новых элементов. .IP \fImarray_check_index\fP Эта функция проверяет был ли выделен элемент с индексом \fIidx\fP в \fImarray\fP и если он не был выделен, то возвращается 0, иначе возвращается ненулевое значение. .IP \fImarray_nused\fP Функция возвращает количество выделенных элементов в \fImarray\fP. .IP \fImzone_init\fP Создать mzone, \fIname\fP это имя mzone, которое должно существовать, пока mzone не будет деинициализирована. Лучше давать имя mzone в форм :. \fIdesc\fP это её описание (обычно несколько слов). \fIflags\fP означает тоже самое, что и в функции \fImarray_init\fP, mzone также воспринимает ещё флаг IPA_MEMFUNC_FLAG_OPTIMIZE, этот флаг должен быть установлен, если в mzone будет много элементов. \fIisize\fP это размер одного элемента в mzone. \fInitems\fP обозначает количество элементов, под которое необходимо изначально выделить память. \fInalloc\fP обозначает количество элементов, которое необходимо выделять, если в mzone не осталось ни одного свободного элемента. Если вы не уверены в значениях этих аргументов, то установите их в 1. Эта функция возвращает указатель на только что созданную mzone или NULL, если возникла какая-то ошибка. .IP \fImzone_deinit\fP Освободить память занимаемую \fImzone\fP. Если модуль не вызовет эту функцию, то IPA утилита сообщит об утечке памяти и деинициализирует mzone модуля, но эта деинициализация не означает, что утечка памяти не возможна, так как деинициализация mzone не освобождает память, на которую, возможно, указывают элементы массива. Если \fImzone\fP равен NULL, то эта функция ничего не делает. .IP \fImzone_alloc\fP Выделить новый элемент в \fImzone\fP. Эта функция возвращает указатель на новый элемент или NULL, если возникла ошибка. .IP \fImzone_free\fP Вернуть прежде выделенный элемент указываемый \fIptr\fP в \fImzone\fP. .IP \fImzone_nused\fP Функция возвращает количество выделенных элементов в \fImzone\fP. .PP \fBЭкспортируемые модулю функции поддержки.\fP .PP Иногда модулю необходимо добавить макропеременную в некоторую секцию конфигурационного файла, или необходимо вывести собственные параметры, когда IPA утилита выводит разобранный конфигурационный файл, или необходимо послать лог-сообщение. Так как модулю не известно каким образом это сделать, IPA утилита, использующая этот модуль, экспортирует модулю функции \fIipa_memfunc\fP: .PP .nf typedef struct { void (*print_string)(const char *string); void (*print_bytes)(const uint64_t *value); void (*print_time)(const uint64_t *value); void (*print_value)(const uint64_t *value, u_int value_type); void (*print_boolean)(int value); void (*print_space)(void); void (*set_indent)(int indent); void (*print_param_name)(const char *prefix, const char *param); void (*print_param_args)(const char *format, va_list ap); void (*print_param_end)(void); void (*print_sect_name)(const char *prefix, const char *sect); void (*print_sect_args)(const char *format, va_list ap); void (*print_sect_begin)(void); void (*print_sect_end)(void); void (*open_log)(void); void (*close_log)(void); void (*logmsg)(const char *mod_name, int priority, int code, const char *format, va_list ap); void (*logconferr)(const char *mod_name, int code, const char *format, va_list ap); int (*local_sym_add)(char *sym, char *val, int copy_flag); int (*local_sym_del)(cost char *sym); int (*global_sym_add)(char *sym, char *val, int copy_flag); int (*global_sym_del)(cost char *sym); } ipa_suppfunc; .fi .IP \fIprint_string\fP Эта функция выводит строку в кавычках. .IP \fIprint_bytes\fP Эта функция выводит байты. .IP \fIprint_time\fP Эта функция выводит время. .IP \fIprint_value\fP Эта функция выводит байты, время или 64-битовое беззнаковое целое, если \fIvalue_type\fP равно IPA_CONF_TYPE_BYTES, IPA_CONF_TYPE_TIME или IPA_CONF_TYPE_UINT64 соответственно. .IP \fIprint_boolean\fP Эта функция выводит логическое значение. .IP \fIprint_space\fP Эта функция выводит один пробельный символ, если он не был выведен прежде. .IP \fIset_indent\fP Модуль должен вызвать эту функцию перед выводом любого параметра или секции внутри собственной секции, чтобы выставить правильное выравнивание \fIindent\fP, которое задаётся как уровень выравнивания. .IP \fIprint_param_name\fP Эта функция выводит имя параметра \fIparam\fP, с конфигурационным префиксом \fIprefix\fP. Если параметр не имеет конфигурационного префикса, то \fIprefix\fP должен быть равен NULL. .IP \fIprint_param_args\fP Эта vprintf(3) подобная функция выводит аргументы параметра, может вызываться несколько раз для одного и того же параметра. .IP \fIprint_param_end\fP Эта функция должна быть вызвана после вывода всех аргументов параметра. .IP \fIprint_sect_name\fP Эта функция выводит имя секции \fIsect\fP с конфигурационным префиксом \fIprefix\fP. Если секция не имеет конфигурационного префикса, то \fIprefix\fP должен быть равен NULL. .IP \fIprint_sect_args\fP Эта vprintf(3) подобная функция выводит аргументы секции, может вызываться несколько раз для одной и той же секции. .IP \fIprint_sect_end\fP Эта функция должна быть вызвана после вывода всех аргументов секции. .IP \fIopen_log\fP .IP \fIclose_log\fP Если необходимо запустить другой процесс (посредством fork(2)), то порождённый процесс может использовать функцию \fIlogmsg\fP (описана ниже), но если ему необходимо закрыть какие-то дескрипторы, а затем использовать систему лог-сообщений, то этот процесс должен вызвать сначала функцию \fIclose_log\fP, а затем \fIopen_log\fP. Создание дескриптора для отправки лог-сообщений задерживается до тех пор пока не будет послано первое сообщение. .IP \fIlogmsg\fP Модуль должен использовать эту функцию для вывода лог-сообщений в любой части своего кода, но только не в функциях по обработке конфигурации. \fImod_name\fP это имя модуля. \fIpriority\fP это приоритет сообщения: IPA_LOG_INFO, IPA_LOG_WARNING или IPA_LOG_ERR. \fIcode\fP это значение errno(2) или 0 если нет состояния ошибки. \fIformat\fP и \fIap\fP это vprintf(3) подобные аргументы. .IP \fIlogconferr\fP Модуль должен использовать эту функцию для вывода сообщений об ошибках во время разбора конфигурационного файла. Аргументы аналогичны аргументам функции \fIlogmsg\fP. .IP \fIlocal_sym_add\fP Создать локальную макропеременную с именем \fIsym\fP и значением \fIval\fP, если \fIcopy_flag\fP не равен нулю, то будет выделена память и \fIsym\fP и \fIval\fP будут скопированы в эту память, иначе будут использоваться оригинальные указатели. Эта функция возвращает 0, если макропеременная была создана и -1, если произошла ошибка выделения памяти. .IP \fIlocal_sym_del\fP Удалить локальную макропеременную с именем \fIsym\fP. Если не существует локальной макропеременной с именем \fIsym\fP, то возвращается -1, иначе 0. У модуля есть выбор не вызывать эту функцию, так как IPA утилита вызовет её автоматически. .IP \fIglobal_sym_add\fP Аналогично \fIlocal_sym_add\fP, но для глобальных макропеременных. .IP \fIglobal_sym_del\fP Аналогично \fIlocal_sym_del\fP, но для глобальных макропеременных. .PP \fBОписание конфигурационной секции.\fP .PP Структура \fIipa_conf_sect\fP определена следующим образом: .PP .nf typedef struct { const char *sect_name; u_int sect_id; int arg_nargs; const char *arg_pattern; regex_t *arg_regexp; u_int arg_type; const u_int *sect_where; int (*arg_parse)(void *arg); } ipa_conf_sect; .fi .IP \fIsect_name\fP Имя секции. .IP \fIsect_id\fP Идентификатор секции, значение которого локально для модуля. Это значение должно быть больше чем IPA_CONF_SECT_CUSTOM_OFFSET. .IP \fIarg_nargs\fP Число аргументов секции. Установите это поле в 0, если секция не должна иметь ни одного аргумента. Если секция может иметь переменное число аргументов, то необходимо установить в этом поле отрицательное число, абсолютное значение которого равно минимально допустимому числу аргументов секции. .IP \fIarg_pattern\fP Аргумент секции должен соответствовать данному регулярному выражению POSIX (расширенный формат). Если такого регулярного выражения нет, то это поле следует установить в NULL. .IP \fIarg_regexp\fP Указатель на переменную типа regex_t. Если \fIarg_pattern\fP не NULL, то это значение тоже должно быть не NULL. Возможно разделять регулярные выражения между секциями и параметрами и не тратить лишней памяти для дополнительных переменных. В этом случае только одна секция или параметр должна иметь указатель в \fIarg_pattern\fP, все другие секции и параметры должны установить \fIarg_pattern\fP в NULL. .IP \fIarg_type\fP Тип аргумента. Определены следующие типы: IPA_CONF_TYPE_INT32\ \ \ \ -\ int32_t; .br IPA_CONF_TYPE_UINT32\ \ \ -\ uint32_t; .br IPA_CONF_TYPE_INT64\ \ \ \ -\ int64_t; .br IPA_CONF_TYPE_UINT64\ \ \ -\ uint64_t; .br IPA_CONF_TYPE_STRING\ \ \ -\ строка; .br IPA_CONF_TYPE_BYTES\ \ \ \ -\ байты; .br IPA_CONF_TYPE_TIME\ \ \ \ \ -\ время; .br IPA_CONF_TYPE_VALUE\ \ \ \ -\ значение; .br IPA_CONF_TYPE_PER_CENT\ -\ процент; .br IPA_CONF_TYPE_BOOLEAN\ \ -\ логическое значение; .br IPA_CONF_TYPE_MISC\ \ \ \ \ -\ без формата. Обычно модуль использует регулярное выражение (поле \fIarg_regexp\fP) с типом аргумента IPA_CONF_TYPE_MISC и не использует регулярного выражения с другими типами аргумента. IPA_CONF_TYPE_VALUE обозначает байты, время или uint64_t значение. См. ниже детали. .IP \fIsect_where\fP Это поле определяет где секция должна быть расположена, это указатель на массив u_int значений, каждое значение это идентификатор секции, последний элемент в этом массиве должен быть равен нулю. Предопределённые идентификаторы секций следующие: IPA_CONF_SECT_ROOT\ \ \ -\ нет секции; .br IPA_CONF_SECT_GLOBAL\ -\ секция \fBglobal\fP; .br IPA_CONF_SECT_RULE\ \ \ -\ секция \fBrule\fP; .br IPA_CONF_SECT_LIMIT\ \ -\ секция \fBlimit\fP; .br IPA_CONF_SECT_THRESHOLD\ -\ секция \fBthreshold\fP; .br IPA_CONF_SECT_AUTORULE\ -\ секция \fBautorule\fP; .br IPA_CONF_SECT_RULEPAT\ \ -\ секция \fBrulepat\fP. .IP \fIarg_parse\fP Эта функция вызывается для обработки аргументов. Модуль может установить это поле в NULL, если для секции нет такой функции. \fIarg\fP это указатель на данные, которые зависят от значения \fIarg_type\fP и функция \fIarg_parse\fP должна выполнить следующие преобразования типов: IPA_CONF_TYPE_INT32\ \ \ -\ *(int32_t\ *)arg; .br IPA_CONF_TYPE_UINT32\ \ -\ *(uint32_t\ *)arg; .br IPA_CONF_TYPE_INT64\ \ \ -\ *(int64_t\ *)arg; .br IPA_CONF_TYPE_UINT64\ \ -\ *(uint64_t\ *)arg; .br IPA_CONF_TYPE_STRING\ \ -\ *(char\ **)arg; .br IPA_CONF_TYPE_BYTES\ \ \ -\ *(uint64_t\ *)arg; .br IPA_CONF_TYPE_TIME\ \ \ \ -\ *(uint64_t\ *)arg; .br IPA_CONF_TYPE_VALUE\ \ \ -\ *(uint64_t\ *)arg, *((uint64_t\ *)arg\ +\ 1) .br IPA_CONF_TYPE_BOOLEAN\ -\ *(int\ *)arg; .br IPA_CONF_TYPE_MISC\ \ \ \ -\ *(char\ **)arg. Если значение \fIarg_type\fP равно IPA_CONF_TYPE_STRING, то \fIarg\fP является указателем на память, в которую скопировано значение строки (без кавычек), эта память выделяется при помощи \fImem_malloc\fP с mem_type \fIm_parser\fP и модуль должен освободить эту память если он в ней не нуждается при помощи \fImem_free\fP. В других случаях функция \fIarg_parse\fP должна копировать необходимые данные и не использовать данные по указателям, также разрешено модифицировать данные на которые указывает \fIarg\fP. Если значение \fIarg_type\fP равно IPA_CONF_TYPE_MISC, то \fIarg\fP не будет начинаться с пробельных символов и не будет заканчиваться пробельными символами, также между любыми двумя аргументами в \fIarg\fP будет всего один символ `\ '. Если значение \fIarg_type\fP равно IPA_CONF_TYPE_VALUE, то \fIarg\fP указывает на массив, первый элемент которого имеет значение IPA_CONF_TYPE_BYTES, IPA_CONF_TYPE_TIME или IPA_CONF_TYPE_UINT64, второй элемент это само значение. .PP \fBОписание конфигурационного параметра.\fP .PP Структура \fIipa_conf_param\fP определена следующим образом: .PP .nf typedef struct { const char *param_name; int arg_nargs; const char *arg_pattern; regex_t *arg_regexp; u_int arg_type; const u_int *param_where; int (*arg_parse)(void *arg); } ipa_conf_param; .fi .IP \fIparam_name\fP Имя параметра. .IP \fIarg_nargs\fP Объяснено выше. .IP \fIarg_pattern\fP Объяснено выше. .IP \fIarg_regexp\fP Объяснено выше. .IP \fIarg_type\fP Объяснено выше. .IP \fIparam_where\fP Объяснено выше для \fIsect_where\fP. .IP \fIarg_parse\fP Объяснено выше. .PP \fBСтруктура для представления дат.\fP .PP Структура \fIipa_tm\fP определена следующим образом: .PP .nf typedef struct tm ipa_tm; .fi .PP Только следующие поля в структуре \fIipa_tm\fP могут быть использованы: \fItm_year\fP, \fItm_mon\fP, \fItm_mday\fP, \fItm_hour\fP, \fItm_min\fP, \fItm_sec\fP. Эти поля определяют локальную дату. \fItm_year\fP равно реальному значению года и \fItm_mon\fP равно реальному значению месяца. .PP \fBСостояние лимита.\fP .PP Состояние лимита описывается структурой \fIipa_limit_state\fP: .PP .nf struct ipa_limit_state { uint64_t lim; uint64_t cnt; u_int event_date_set; ipa_tm event_date[IPA_LIMIT_EVENT_NUM]; }; .fi .IP \fIlim\fP Значение параметра \fBlimit\fP. .IP \fIcnt\fP Значение счётчика лимита. .IP \fIevent_date_set\fP Это битовое поле, которое определяет действительные элементы в массиве \fIevent_date\fP, каждый IPA_LIMIT_EVENT_xxx элемент в массиве \fIevent_date\fP имеет соответствующий бит IPA_LIMIT_EVENT_xxx_SET в \fIevent_date_set\fP. .IP \fIevent_date\fP Это массив дат событий лимита. Определены следующие элементы в этом массиве: IPA_LIMIT_EVENT_START\ -\ дата, когда лимит был запущен; IPA_LIMIT_EVENT_RESTART\ -\ дата, когда лимит будет перезапущен или был перезапущен; IPA_LIMIT_EVENT_RESTART_EXEC\ -\ дата, когда были запущены команды для перезапущенного лимита; IPA_LIMIT_EVENT_REACH \ -\ дата, когда лимит был достигнут; IPA_LIMIT_EVENT_REACH_EXEC\ -\ дата, когда были запущены команды для достигнутого лимита; IPA_LIMIT_EVENT_EXPIRE\ -\ дата, когда истечёт срок достигнутого лимита и лимит будет перезапущен или дата, когда истёк срок достигнутого лимита и он был перезапущен; IPA_LIMIT_EVENT_EXPIRE_EXEC\ -\ дата, когда были запущены команды для лимита, у которого истёк срок с момента достижения. IPA_LIMIT_EVENT_UPDATED\ -\ дата, когда лимита был обновлён в последний раз. .PP \fBСостояние порога.\fP .PP Состояние порога описывается структурой \fIipa_threshold_state\fP: .PP .nf struct ipa_threshold_state { uint64_t thr; uint64_t cnt; ipa_tm tm_from; ipa_tm tm_updated; }; .fi .IP \fIthr\fP Значение параметра \fBthreshold\fP. .IP \fIcnt\fP Значение счётчика порога. .IP \fItm_from\fP .IP \fItm_updated\fP Две временные отметки порога. .PP \fBAPI модуля учёта.\fP .PP API модуля учёта экспортируется модулем IPA утилите в структуре \fIipa_ac_mod\fP: .PP .nf struct ipa_ac_mod { u_int api_ver; u_int mod_flags; const char *ac_name; const ipa_suppfunc *suppfunc; const ipa_memfunc *memfunc; const char *conf_prefix; ipa_conf_sect *conf_sect_tbl; ipa_conf_param *conf_param_tbl; int (*conf_init)(void); int (*conf_deinit)(void); int (*conf_event)(u_int event, u_int no, const void *arg); int (*conf_mimic_real)(void); int (*conf_inherit)(u_int rulepatno, u_int ruleno, const char *rule_name); void (*conf_show)(u_int sect_id, u_int no); int (*ac_pre_init)(void) int (*ac_init_autorule)(u_int autoruleno, const char *autorule_name); int (*ac_init_dynrule)(u_int autoruleno, u_int ruleno, const char *rule_name); int (*ac_init_statrule)(u_int ruleno, const char *rule_name); int (*ac_init)(void); int (*ac_deinit_rule)(u_int ruleno); int (*ac_deinit_autorule)(u_int autoruleno); int (*ac_deinit)(void); int (*ac_get_stat)(void); int (*ac_get_rule_stat)(u_int stat_generation, int newstat, u_int ruleno, int *addition, uint64_t *chunk); int (*ac_set_autorule_active)(u_int autoruleno, int active); int (*ac_set_rule_active)(u_int ruleno, int active); int (*ac_set_limit_active)(u_int ruleno, u_int limitno, int active); int (*ac_set_threshold_active)(u_int ruleno, u_int thresholdno, int active); int (*ac_limit_event)(u_int ruleno, u_int limitno, u_int event); int (*ac_threshold_event)(u_int ruleno, u_int thresholdno, u_int event); int (*ac_create_rule)(const char *mod_name, u_int autoruleno, u_int *ruleno, const char *rule_name, const char *rule_info); void (*ac_delete_rule)(const char *mod_name, u_int ruleno); }; .fi .IP \fIapi_ver\fP Версия API модуля учёта, модуль должен проверять версии поддерживаемых API с IPA_AC_MOD_API_VERSION во время компиляции. После загрузки модуля этот номер версии сравнивается с версией используемого API. .IP \fImod_flags\fP Флажки определяющие режимы работы модуля. Определён только один флаг IPA_MOD_FLAG_PTHREAD_SAFE и он должен быть установлен если модуль может работать в многопотоковой версии IPA утилиты. .IP \fIac_name\fP Имя системы учёта модуля. .IP \fIsuppfunc\fP Указатель на структуру \fIipa_suppfunc\fP, которая экспортируется модулю. .IP \fImemfunc\fP Указатель на структуру \fIipa_memfunc\fP, которая экспортируется модулю. .IP \fIconf_prefix\fP Конфигурационный префикс для секций и параметров модуля. .IP \fIconf_sect_tbl\fP Указатель на массив \fIipa_conf_sect\fP структур, которые определяют секции модуля. Последний элемент в этом массиве должен иметь \fIsect_name\fP равное NULL. .IP \fIconf_param_tbl\fP Указатель на массив \fIipa_conf_param\fP структур, которые определяют параметры модуля. Последний элемент в этом массиве должен иметь \fIparam_name\fP равное NULL. .IP \fIconf_init\fP Эта функция вызывается после того, как модуль загружен. .IP \fIconf_deinit\fP Эта функция вызывается после того, как обработан весь конфигурационный файл. .IP \fIconf_event\fP Эта функция вызывается каждый раз, когда происходит некоторое событие во время конфигурации. \fIconf_event\fP описывает событие конфигурации. Конфигурационные события позволяют модулю узнать для какой секции принадлежит его параметр или секция. Определены следующие события конфигурации: IPA_CONF_EVENT_GLOBAL_BEGIN\ -\ начало секции \fBglobal\fP; IPA_CONF_EVENT_GLOBAL_END\ -\ конец секции \fBglobal\fP; IPA_CONF_EVENT_RULE_BEGIN\ -\ начало секции \fBrule\fP, \fIarg\fP это указатель на строку с именем правила и должен быть преобразован в (const\ char\ *), \fIno\fP это порядковый номер этой секции в конфигурационном файле, начиная с 0; IPA_CONF_EVENT_RULE_END\ -\ конец секции \fBrule\fP; IPA_CONF_EVENT_LIMIT_BEGIN\ -\ начало секции \fBlimit\fP, \fIarg\fP указывает на строку с именем лимита и должен быть преобразован в (const\ char\ *), \fIno\fP это порядковый номер этой секции в текущей секции, начиная с 0; IPA_CONF_EVENT_LIMIT_END\ -\ конец секции \fBlimit\fP; IPA_CONF_EVENT_THRESHOLD_BEGIN\ -\ начало секции \fBthreshold\fP, \fIarg\fP указывает на строку с именем порога и должен быть преобразован в (const\ char\ *), \fIno\fP это порядковый номер этой секции в текущей секции, начиная с 0; IPA_CONF_EVENT_THRESHOLD_END\ -\ конец секции \fBthreshold\fP; IPA_CONF_EVENT_AUTORULE_BEGIN\ -\ начало секции \fBautorule\fP, \fIarg\fP указывает на строку с именем автоправила и должен быть преобразован в (const\ char\ *), \fIno\fP это порядковый номер этой секции в конфигурационном файле, начиная с 0; IPA_CONF_EVENT_AUTORULE_END\ -\ конец секции \fBautorule\fP; IPA_CONF_EVENT_RULEPAT_BEGIN\ -\ начала секции \fBrulepat\fP, \fIarg\fP указывает на регялрное выражение POSIX и должен быть преобразован в (const\ char\ *), \fIno\fP это порядковый номер этой секции в конфигурационном файле, начиная с 0; IPA_CONF_EVENT_RULEPAT_END\ -\ конец секции \fBrulepat\fP; IPA_CONF_EVENT_CUSTOM_SECT_BEGIN\ -\ начало собственной секции модуля, \fIno\fP это идентификатор секции модуля; IPA_CONF_EVENT_CUSTOM_SECT_END\ -\ конец собственной секции модуля. Для каждого IPA_CONF_EVENT_xxx_END \fIno\fP означает тоже самое, что и для соответствующего IPA_CONF_EVENT_xxx_BEGIN. .IP \fIconf_mimic\fP Если эта функция вызвана, то модуль должен сымитировать реальную конфигурацию. .IP \fIconf_inherit\fP В этой функции модуль должен унаследовать все установки из секции \fBrulepat\fP номер \fIrulepatno\fP для правила номер \fIruleno\fP с именем \fIrule_name\fP. Если эта функция вызывается до \fIac_pre_init\fP, то модуль должен использовать функцию \fIlogconferr\fP для сообщений о возникших ошибках, иначе должна быть использована функция \fIlogmsg\fP. .IP \fIconf_show\fP Эта функция вызывается, когда IPA утилита выводит обработанный конфигурационный файл. \fIsect_id\fP это идентификатор секции. \fIno\fP это порядковый номер секции с данным идентификатором. Если модуль имеет конфигурацию в секции с данным идентификатором, то он должен вывести эту конфигурацию. Модуль не должен напрямую выводить свою конфигурацию, вместо этого следует использовать функции из структуры \fIsuppfunc\fP. .IP \fIac_pre_init\fP Эта функция вызывается после обработки конфигурационного файла. Модуль должен выполнить предварительную инициализацию своей системы учёта. Эта функция всегда вызывается перед остальными функциями \fIac_init*\fP. .IP \fIac_init_autorule\fP Эта функция вызывается, если некоторое автоправило использует модуль. \fIautoruleno\fP это номер автоправила, \fIautorule_name\fP это его имя. .IP \fIac_init_dynrule\fP Эта функция вызывается, если некоторое динамическое правило использует модуль. \fIautoruleno\fP это номер автоправила из которого было сгенерировано динамическое правило, \fIruleno\fP это номер динамического правила, \fIrule_name\fP это его имя. Данные на которые указывает \fIrule_name\fP будут существовать до тех пор пока не будет вызвана \fIac_deinit_rule\fP для этого правила. Эта функция вызывается тогда, когда модуль вызывает \fIac_create_rule\fP из \fIac_get_stat\fP. .IP \fIac_init_statrule\fP Тоже самое что и \fIac_init_dynrule\fP, только для статических правил и эта функция вызывается после фазы конфигурации. .IP \fIac_init\fP Эта функция вызывается после все остальных функций \fIac_init*\fP (за исключением \fIac_init_dynrule\fP, которая вызывается из \fIac_create_rule\fP). .IP \fIac_deinit_rule\fP Эта функция вызывается при деинициализации правила, использующего модуль. Модуль не должен ожидать, что функция \fIac_init_*rule\fP была вызвана прежде для этого правила. Эта функция вызывается для статических и динамических правил. .IP \fIac_deinit_autorule\fP Эта функция вызывается при деинициализации автоправила, использующего модуль. Модуль не должен ожидать, что функция \fIac_init_autorule\fP была вызвана прежде для этого автоправила. .IP \fIac_deinit\fP Эта функция вызывается при деинициализации модуля. Модуль не должен ожидать, что функции \fIac_*init\fP были вызваны прежде. Эта функция всегда вызывается после всех остальных функций \fIac_deinit_*\fP. .IP \fIac_get_stat\fP Эта функция вызывается перед вызовом функции \fIac_get_rule_stat\fP. Существует внутренний номер генерации статистики, который изменяется всякий раз когда вызывается функция \fIac_get_stat\fP любого из модулей и его значение всегда больше нуля. .IP \fIac_get_rule_stat\fP Эта функция должна возвращать статистику для правила номер \fIruleno\fP. Значение \fIstat_generation\fP это номер генерации статистики (см. описание выше). Флаг \fInewstat\fP обозначает, что модуль должен рассматривать, что это первый вызов этой функции (например, этот флаг не равен нулю когда правило становится активным). \fIchunk\fP указывает на статистику возвращаемую модулем и \fI*addition\fP определяет действие со статистикой, если его значение не равно нулю, то возвращаемая статистика добавляется, иначе вычитается. Здесь под статистикой понимается статистика за период между двумя вызовами функции \fIac_get_rule_stat\fP. Эта функция не вызывается если правило, которое использует этот модуль, неактивно. .IP \fIac_set_autorule_active\fP Эта функция должна отметить автоправило как активное или неактивное. Если флаг \fIactive\fP равен нулю, то автоправило должно быть отмечено как неактивное в модуле, иначе как активное. .IP \fIac_set_rule_active\fP Аналогично предыдущему, только для правила. .IP \fIac_set_limit_active\fP Аналогично предыдущему, только для лимита. .IP \fIac_set_threshold_active\fP Аналогично предыдущему, только для порога. .IP \fIac_limit_event\fP Эта функция вызывается когда происходит некоторое событие с лимитом. Событие \fIevent\fP может быть: IPA_LIMIT_EVENT_RESTART\ -\ лимит перезапущен; .br IPA_LIMIT_EVENT_REACH\ \ -\ лимит достигнут; .br IPA_LIMIT_EVENT_EXPIRE\ -\ достигнутый лимит перезапущен; .br IPA_LIMIT_EVENT_STARTUP_IF_REACHED\ -\ достигнутый при старте; .br IPA_LIMIT_EVENT_STARTUP_IF_NOT_REACHED\ -\ не достигнутый при старте; .br IPA_LIMIT_EVENT_SHUTDOWN_IF_REACHED\ -\ достигнутый во время останова; .br IPA_LIMIT_EVENT_SHUTDOWN_IF_NOT_REACHED\ -\ не достигнутый во время останова. .IP \fIac_threshold_event\fP Эта функция вызывается когда происходит некоторое событие с порогом. Событие \fIevent\fP означает, что значение счётчика порога: IPA_THRESHOLD_EVENT_BELOW\ -\ ниже значения \fBthreshold\fP; .br IPA_THRESHOLD_EVENT_EQUAL\ -\ равно значению \fBthreshold\fP; .br IPA_THRESHOLD_EVENT_ABOVE\ -\ выше значения \fBthreshold\fP. .IP \fIac_create_rule\fP Эта функция экспортируется модулю. Модуль должен вызывать эту функцию только из функции \fIac_get_stat\fP чтобы создать динамическое правило. \fImod_name\fP это имя модуля (используется только для отладки и только в этой функции). \fIautoruleno\fP это номер автоправила из которого необходимо сгенерировать динамическое правило. \fIrule_name\fP это имя правила, \fIrule_info\fP это его описание, эти строки не используются по указателям, поэтому если модуль выделил память для них, то он должен сам освободить эту память. Если не произошла какая-нибудь ошибка, то вызывается \fIac_init_dynrule\fP. Эта функция возвращает 0, если динамическое правило было создано, -2 если правило с данным именем уже существует и -1 если произошла какая-то критическая ошибка, в этом случае модуль обязан вернуть -1 из \fIac_get_stat\fP. .IP \fIac_delete_rule\fP Эта функция экспортируется модулю. Модуль должен вызывать эту функцию только из функции \fIac_get_stat\fP чтобы деинициализировать динамическое правило номер \fIruleno\fP созданное прежде функцией \fIac_create_rule\fP. \fImod_name\fP это имя модуля (используется только для отладки и только в этой функции). Для данного правила в какой-то момент будет вызвана функция \fIac_deinit_rule\fP. Если не произошла какая-нибудь ошибка, то эта функция возвращает 0. Если возникли проблемы с деинициализацией, то возвращается -1, в этом случае модуль обязан вернуть -1 из \fIac_get_stat\fP. .PP Если какая-то функция, кроме \fIac_create_rule\fP, возвращает числовое значение, то в случае успешного выволнения эта функция должна вернуть значение 0, иначе должно быть возвращено значение -1. .PP Если модуль не поддерживает какую-то функцию для статического или динамического правила, для автоправила, для лимита или порога, то он должен установить соответствующее поле в NULL. .PP Если какая-то функция экспортируется модулю, то соответствующее поле может быть установлено в любое значение (обычно NULL). .PP \fBAPI модуля базы данных.\fP .PP API модуля базы данных экспортируется модулем IPA утилите в структуре \fIipa_db_mod\fP: .PP .nf struct ipa_db_mod { u_int api_ver; u_int mod_flags; const char *db_name; const ipa_suppfunc *suppfunc; const ipa_memfunc *memfunc; const char *conf_prefix; ipa_conf_sect *conf_sect_tbl; ipa_conf_param *conf_param_tbl; int (*conf_init)(void); int (*conf_deinit)(void); int (*conf_event)(u_int event, u_int no, const void *arg); int (*conf_mimic_real)(void); int (*conf_inherit)(u_int rulepatno, u_int ruleno, const char *rule_name); void (*conf_show)(u_int sect_id, u_int no); int (*db_pre_init)(void); int (*db_init_dynrule)(u_int autoruleno, u_int ruleno, const char *rule_name, const char *rule_info); int (*db_init_statrule)(u_int ruleno, const char *rule_name, const char *rule_info); int (*db_init_dynlimit)(u_int autoruleno, u_int ruleno, const char *rule_name, const char *rule_info, u_int limitno, const char *limit_name, const char *limit_info); int (*db_init_statlimit)(u_int ruleno, const char *rule_name, const char *rule_info, u_int limitno, const char *limit_name, const char *limit_info); int (*db_init_dynthreshold)(u_int autoruleno, u_int ruleno, const char *rule_name, const char *rule_info, u_int thresholdno, const char *threshold_name, const char *threshold_info); int (*db_init_statthreshold)(u_int ruleno, const char *rule_name, const char *rule_info, u_int thresholdno, const char *threshold_name, const char *threshold_info); int (*db_init)(void); int (*db_get_limit_state)(u_int ruleno, u_int limitno, struct ipa_limit_state *state); int (*db_set_limit_state)(u_int ruleno, u_int limitno, const struct ipa_limit_state *state, int new_state); int (*db_get_threshold_state)(u_int ruleno, u_int thresholdno, struct ipa_threshold_state *state); int (*db_set_threshold_state)(u_int ruleno, u_int thresholdno, const struct ipa_threshold_state *state); int (*db_deinit_threshold)(u_int ruleno, u_int thresholdno); int (*db_deinit_limit)(u_int ruleno, u_int limitno); int (*db_deinit_rule)(u_int ruleno); int (*db_deinit)(void); int (*db_append_rule)(u_int ruleno, const uint64_t *cnt, const ipa_tm *ctm); int (*db_update_rule)(u_int ruleno, const uint64_t *cnt, const ipa_tm *ctm); int (*db_update_limit)(u_int ruleno, u_int limitno, const uint64_t *value, const ipa_tm *ctm); int (*db_limit_event)(u_int ruleno, u_int limitno, u_int event, const ipa_tm *etm, const ipa_tm *ctm); int (*db_update_threshold)(u_int ruleno, u_int thresholdno, const uint64_t *cnt, const ipa_tm *tm_from, const ipa_tm *tm_updated); int (*db_set_rule_active)(u_int ruleno, int active); int (*db_set_limit_active)(u_int ruleno, u_int limitno, int active); int (*db_set_threshold_active)(u_int ruleno, u_int thresholdno, int active); } .fi .IP \fIapi_ver\fP Версия API модуля базы данных, модуль должен проверять версии поддерживаемых API с IPA_DB_MOD_API_VERSION во время компиляции. После загрузки модуля этот номер версии сравнивается с версией используемого API. .IP \fImod_flags\fP Объяснено выше. .IP \fIdb_name\fP Имя базы данных модуля. .IP \fIsuppfunc\fP Объяснено выше. .IP \fImemfunc\fP Объяснено выше. .IP \fIconf_prefix\fP Объяснено выше. .IP \fIconf_sect_tbl\fP Объяснено выше. .IP \fIconf_param_tbl\fP Объяснено выше. .IP \fIconf_init\fP Объяснено выше. .IP \fIconf_deinit\fP Объяснено выше. .IP \fIconf_event\fP Объяснено выше. .IP \fIconf_mimic_real\fP Объяснено выше. .IP \fIconf_inherit\fP Объяснено выше. .IP \fIconf_show\fP Объяснено выше. .IP \fIdb_pre_init\fP Эта функция вызывается после обработки конфигурационного файла. Модуль должен выполнить общую инициализацию своей базы данных. Эта функция всегда вызывается перед остальными функциями \fIdb_init*\fP. .IP \fIdb_init_dynrule\fP Эта функция вызывается, если некоторое динамическое правило использует модуль. \fIautoruleno\fP это номер автоправила из которого было сгенерировано динамическое правило, \fIruleno\fP это номер динамического правила, \fIrule_name\fP это имя правила, \fIrule_info\fP это описание правила. Только данные на которые указывает \fIrule_name\fP будут существовать до тех пор пока не будет вызвана \fIdb_deinit_rule\fP для этого правила. .IP \fIdb_init_statrule\fP Тоже самое что и \fIdb_init_dynrule\fP, только для статических правил. .IP \fIdb_init_dynlimit\fP Эта функция вызывается, если некоторый лимит из динамического правила использует модуль. \fIlimitno\fP это порядковый номер лимита в правиле, \fIlimit_name\fP это его имя и \fIlimit_info\fP это его описание. Остальные аргументы означают тоже самое что и в \fIdb_init_dynrule\fP. Только данные на которые указывают \fIrule_name\fP и \fIlimit_name\fP будут существовать до тех пор пока не будет вызвана \fIdb_deinit_limit\fP для этого лимита. Так как правило может использовать другую базу данных, то модуль не должен ожидать, что функция \fIdb_init_dynrule\fP была вызвана прежде для правила лимита. Если правило лимита также использует этот модуль, то \fIdb_init_dynrule\fP для правила вызывается первой. .IP \fIdb_init_statlimit\fP Тоже самое что и \fIdb_init_dynlimit\fP, только для лимитов статических правил. .IP \fIdb_init_dynthreshold\fP Эта функция вызывается, если некоторый порог из динамического правила использует модуль. \fIthresholdno\fP это порядковый номер порога в правиле, \fIthreshold_name\fP это его имя и \fIthreshold_info\fP это его описание. Остальные аргументы означают тоже самое что и в \fIdb_init_dynrule\fP. Только данные на которые указывают \fIrule_name\fP и \fIthreshold_name\fP будут существовать до тех пор пока не будет вызвана \fIdb_deinit_threshold\fP для этого порога. Так как правило может использовать другую базу данных, то модуль не должен ожидать, что функция \fIdb_init_dynrule\fP была вызвана прежде для правила порога. Если правило порога также использует этот модуль, то \fIdb_init_dynrule\fP для правила вызывается первой. .IP \fIdb_init_threshold\fP Тоже самое что и \fIdb_init_dynthreshold\fP, только для порогов статических правил. .IP \fIdb_init\fP Эта функция вызывается после все остальных функций \fIdb_init_stat*\fP. .IP \fIdb_get_limit_state\fP Эта функция должна возвращать текущее состояние лимита. Если модуль не имеет текущего состояния лимита (например, для нового лимита), то поле \fIlim\fP в \fIstate\fP должно быть установлено в нуль. .IP \fIdb_set_limit_state\fP Эта функция должна установить новое состояние лимита. Если \fInew_state\fP равно нуль, то текущее состояние лимита в базе данных должно быть обновлено, иначе должно быть зарегестрировано новое состояние лимита. .IP \fIdb_get_threshold_state\fP Эта функция должна возвращать текущее состояние порога. Если модуль не имеет текущего состояния порога (например, для нового порога), то поле \fIthr\fP в \fIstate\fP должно быть установлено в нуль. .IP \fIdb_set_threshold_state\fP Эта функция должна обновить текущее состояние порога. .IP \fIdb_deinit_threshold\fP Эта функция вызывается при деинициализации порога, использующего модуль. Модуль не должен ожидать, что функция \fIdb_init_*threshold\fP была вызвана прежде для этого порога. .IP \fIdb_deinit_limit\fP Эта функция вызывается при деинициализации лимита, использующего модуль. Модуль не должен ожидать, что функция \fIdb_init_*limit\fP была вызвана прежде для этого лимита. .IP \fIdb_deinit_rule\fP Эта функция вызывается при деинициализации правила, использующего модуль. Если какой-то лимит или порог правила также использует этот модуль, то функция \fIdb_deinit_limit\fP или \fIdb_deinit_threshold\fP вызывается первой. Модуль не должен ожидать, что функция \fIdb_init_*rule\fP была вызвана прежде для этого правила. .IP \fIdb_deinit\fP Эта функция вызывается при деинициализации модуля. Модуль не должен ожидать, что функции \fIdb_*init\fP были вызваны прежде. Эта функция всегда вызывается после всех остальных функций \fIdb_deinit_*\fP. .IP \fIdb_append_rule\fP Эта функция должна добавлять новую запись в базу данных для заданного правила. \fIcnt\fP это указатель на новое значение счётчика правила. \fIctm\fP это текущая локальная дата. Эта функция вызвается перед первым вызовом функции \fIdb_update_rule\fP. .IP \fIdb_update_rule\fP Эта функция должна обновлять запись в базе данных для данного правила. \fIcnt\fP это указатель на новое значение счётчика, \fIctm\fP это текущая локальная дата. .IP \fIdb_update_limit\fP Эта функция должна обновлять состояние лимита в базе данных. \fIcnt\fP это указатель на новое значение счётчика, \fIctm\fP это текущая локальная дата. Модуль также должен обновить дату IPA_LIMIT_EVENT_UPDATED. .IP \fIdb_update_threshold\fP Эта функция должна обновлять состояние порога в базе данных. \fIcnt\fP это указатель на новое значение счётчика, \fItm_from\fP и \fItm_updated\fP это две временные отметки порога. .IP \fIdb_limit_event\fP Эта функция должна регистрировать событие \fIevent\fP для лимита в базе данных. Данное событие может происходить прямо сейчас или в будущем. \fIetm\fP равно локальной дате данного события, а \fIctm\fP равно текущей локальной дате. Модуль также должен обновить дату IPA_LIMIT_EVENT_UPDATED. Эта функция вызывается только для следующих событий лимита IPA_LIMIT_EVENT_: RESTART_EXEC, REACH, REACH_EXEC, EXPIRE и EXPIRE_EXEC. .IP \fIdb_set_rule_active\fP Объяснено выше в \fIac_set_rule_active\fP. Если правило помечается как активное, то \fIdb_append_rule\fP будет вызвана перед \fIdb_update_rule\fP. .IP \fIdb_set_limit_active\fP Объяснено выше в \fIac_set_limit_active\fP. .IP \fIdb_set_threshold_active\fP Объяснено выше в \fIac_set_threshold_active\fP. .PP Если какая-то функция возвращает числовое значение, то в случае успешного выполнения эта функция должна вернуть значение 0, иначе должно быть возвращено значение -1. .PP Если модуль базы данных не поддерживает динамических правил, лимитов или порогов, то он должен установить соответствующее поле \fIdb_init_dyn*\fP в NULL. Если модуль базы данных не поддерживает статических правил, лимитов или порогов, то необходимо установить соответствующее поле \fIdb_init_stat*\fP в NULL. .PP Если модуль базы данных не поддерживает функцию \fIdb_get_limit_state\fP, \fIdb_get_threshold_state\fP, \fIdb_set_*active\fP, то необходимо установить соответствующее поле в NULL. .PP Если какая-то функция экспортируется модулю, то соответствующее поле может быть установлено в любое значение (обычно NULL). .PP \fBAPI модуля статистики.\fP .PP API модуля статистики экспортируется модулем IPA утилите в структуре \fIipa_st_mod\fP: .PP .nf struct ipa_entity_desc { char *name; char *info; }; struct ipa_rule_stat { u_int year; unsigned char mon; unsigned char mday; unsigned char h1, m1, s1; unsigned char h2, m2, s2; uint64_t cnt; }; struct ipa_st_mod { u_int api_ver; u_int mod_flags; const char *st_name; const ipa_suppfunc *suppfunc; const ipa_memfunc *memfunc; const char *conf_prefix; ipa_conf_sect *conf_sect_tbl; ipa_conf_param *conf_param_tbl; int (*conf_init)(void); int (*conf_deinit)(void); int (*conf_event)(u_int event, u_int no, const void *arg); int (*conf_mimic_real)(void); int (*conf_inherit)(u_int rulepatno, u_int ruleno, const char *rule_name); void (*conf_show)(u_int sect_id, u_int no); int (*st_pre_init)(void); int (*st_init_rule)(u_int ruleno, const char *rule_name); int (*st_init_limit)(u_int ruleno, const char *rule_name, u_int limitno, const char *limit_name); int (*st_init_threshold)(u_int ruleno, const char *rule_name, u_int thresholdno, const char *threshold_name); int (*st_init)(void); int (*st_deinit_threshold)(u_int ruleno, u_int thresholdno); int (*st_deinit_limit)(u_int ruleno, u_int limitno); int (*st_deinit_rule)(u_int ruleno); int (*st_deinit)(void); int (*st_get_rule_info)(u_int ruleno, ipa_mem_type *mem_type, char **infop); int (*st_get_limit_info)(u_int ruleno, u_int limitno, ipa_mem_type *mem_type, char **infop); int (*st_get_threshold_info)(u_int ruleno, u_int thresholdno, ipa_mem_type *mem_type, char **infop); int (*st_get_rules_list)(const char *pat, const regex_t *pat_reg, ipa_mem_type *mem_type, u_int *n, struct ipa_entity_desc **bufp); int (*st_get_limits_list)(u_int ruleno, const char *pat, const regex_t *pat_reg, ipa_mem_type *mem_type, u_int *n, struct ipa_entity_desc **bufp); int (*st_get_thresholds_list)(u_int ruleno, const char *pat, const regex_t *pat_reg, ipa_mem_type *mem_type, u_int *n, struct ipa_entity_desc **bufp); int (*st_get_rule_stat)(u_int ruleno, const ipa_tm *tm1, const ipa_tm *tm2, int exact, ipa_mem_type *mem_type, u_int *n, struct ipa_rule_stat **bufp); int (*st_get_limit_stat)(u_int ruleno, u_int limitno, const ipa_tm *tm1, const ipa_tm *tm2, ipa_mem_type *mem_type, u_int *n, struct ipa_limit_state **bufp); int (*st_get_threshold_stat)(u_int ruleno, u_int thresholdno, struct ipa_threshold_state *buf); }; .fi .IP \fIapi_ver\fP Версия API модуля статистики модуль должен проверять версии поддерживаемых API с IPA_ST_MOD_API_VERSION во время компиляции. После загрузки модуля этот номер версии сравнивается с версией используемого API. .IP \fImod_flags\fP Объяснено выше. .IP \fIst_name\fP Имя системы статистики модуля. .IP \fIsuppfunc\fP Объяснено выше. .IP \fImemfunc\fP Объяснено выше. .IP \fIconf_prefix\fP Объяснено выше. .IP \fIconf_sect_tbl\fP Объяснено выше. .IP \fIconf_param_tbl\fP Объяснено выше. .IP \fIconf_init\fP Объяснено выше. .IP \fIconf_deinit\fP Объяснено выше. .IP \fIconf_event\fP Объяснено выше. .IP \fIconf_mimic_real\fP Объяснено выше. .IP \fIconf_inherit\fP Объяснено выше. .IP \fIconf_show\fP Объяснено выше. .IP \fIst_pre_init\fP Эта функция вызывается после обработки конфигурационного файла. Модуль должен выполнить общую инициализацию своей системы статистики. Эта функция всегда вызывается перед остальными функциями \fIst_init*\fP. .IP \fIst_init_rule\fP Эта функция вызывается, если некоторое правило использует модуль. \fIruleno\fP это номер правила, \fIrule_name\fP это его имя. Данные на которые указывает \fIrule_name\fP будут существовать пока не будет вызвана функция \fIst_deinit_rule\fP для этого правила. Эта функция может быть вызвана для правила, которое имеет соответствующую секцию в конфигурационном файле и для правила, которое было сгенерировано на лету (можно рассматривать как динамическое правило). .IP \fIst_init_limit\fP Эта функция вызывается, если некоторый лимит использует модуль. \fIlimitno\fP это порядковый номер лимита в правиле, \fIlimit_name\fP это его имя. Только данные на которые указывает \fIrule_name\fP и \fIlimit_name\fP будут существовать пока не будет вызвана функция \fIst_deinit_limit\fP для этого лимита. Так как правило может использовать другую систему статистики, то модуль не должен ожидать, что функция \fIst_init_rule\fP была вызвана прежде для правила лимита. Если правило лимита также использует этот модуль, то \fIst_init_rule\fP для правила вызывается первой. Подобно \fIst_init_rule\fP эта функция может быть вызвана для правила и/или лимита, которое имеет соответствующую секцию в конфигурационном файле и для правила и/или лимита, которое было сгенерировано на лету (могут рассматриваться как динамическое правило и/или лимит). .IP \fIst_init_threshold\fP Эта функция вызывается, если некоторый порог использует модуль. \fIthresholdno\fP это порядковый номер порога в правиле, \fIthreshold_name\fP это его имя. Только данные на которые указывает \fIrule_name\fP и \fIthreshold_name\fP будут существовать пока не будет вызвана функция \fIst_deinit_threshold\fP для этого порога. Так как правило может использовать другую систему статистики, то модуль не должен ожидать, что функция \fIst_init_rule\fP была вызвана прежде для правила порога. Если правило порога также использует этот модуль, то \fIst_init_rule\fP для правила вызывается первой. Подобно \fIst_init_rule\fP эта функция может быть вызвана для правила и/или порога, которое имеет соответствующую секцию в конфигурационном файле и для правила и/или порога, которое было сгенерировано на лету (могут рассматриваться как динамическое правило и/или порог). .IP \fIst_init\fP Эта функция вызывается после все остальных функций \fIst_init*\fP. .IP \fIst_deinit_threshold\fP Эта функция вызывается при деинициализации порога, использующего модуль. Модуль не должен ожидать, что функция \fIst_init_threshold\fP была вызвана прежде для этого порога. .IP \fIst_deinit_limit\fP Эта функция вызывается при деинициализации лимита, использующего модуль. Модуль не должен ожидать, что функция \fIst_init_limit\fP была вызвана прежде для этого лимита. .IP \fIst_deinit_rule\fP Эта функция вызывается при деинициализации правила, использующего модуль. Если какой-то лимит или порог правила также использует этот модуль, то функция \fIst_deinit_limit\fP или \fIst_deinit_threshold\fP вызывается первой. Модуль не должен ожидать, что функция \fIst_init_rule\fP была вызвана прежде для этого правила. .IP \fIst_deinit\fP Эта функция вызывается при деинициализации модуля. Модуль не должен ожидать, что функции \fIst_*init\fP были вызваны прежде. Эта функция всегда вызывается после всех остальных функций \fIst_deinit_*\fP. .IP \fIst_get_rule_info\fP Эта функция должна вернуть описание для правила номер \fIruleno\fP, указатель на описание правила должен быть сохранён в \fI*infop\fP. Если правило не имеет описания, то \fI*infop\fP должно быть установлено в NULL. .IP \fIst_get_limit_info\fP Тоже самое что и \fIst_get_rule_info\fP, только для лимита. .IP \fIst_get_threshold_info\fP Тоже самое что и \fIst_get_rule_info\fP, только для порога. .IP \fIst_get_rules_list\fP Эта функция должна вернуть массив с именами и описаниями правил. Если регулярное выражение POSIX \fIpat\fP не NULL, то модуль должен вернуть только правила с именами, соответствующими этому регулярному выражению (\fIpat_reg\fP это скомпилированное регулярное выражение \fIpat\fP). Указатель на массив структур \fIstruct\ ipa_entity_desc\fP должен быть сохранён в \fI*bufp\fP, число элементов массива должно быть сохранено в \fI*n\fP. Если число элементов массива равно нулю, то \fI*bufp\fP должно быть установлено в NULL. .IP \fIst_get_limits_list\fP Тоже самое что и \fIst_get_rules_list\fP, только для лимитов. .IP \fIst_get_thresholds_list\fP Тоже самое что и \fIst_get_rules_list\fP, только для порогов. .IP \fIst_get_rule_stat\fP Эта функция используется для запроса статистики для правила номер \fIruleno\fP за временной интервал с \fItm1\fP по \fItm2\fP. Если \fIexact\fP равно нулю, то обе временные отметки записей правила должны быть внутри данного временного интервала, иначе только одна из временных отметок записей правила должна быть внутри данного временного интервала. Указатель на массив структур \fIstruct\ ipa_rule_stat\fP должен быть сохранён в \fI*bufp\fP, число элементов массива должно быть сохранено в \fI*n\fP. Если число элементов массива равно нулю, то \fI*bufp\fP должно быть установлено в NULL. В структуре \fIstruct\ ipa_rule_stat\fP поля \fIyear\fP, \fImon\fP и \fImday\fP определяют дату обоих временных отметок записи правила (новая запись для правила всегда добавляется для нового дня, поэтому достаточно всего трёх полей для обоих временных отметок). \fIt1\fP, \fIm1\fP и \fIs1\fP это время первой временной отметки, \fIt2\fP, \fIm2\fP и \fIs1\fP это время второй временной отметки. \fIcnt\fP это статистика одной записи правила. .IP \fIst_get_limit_stat\fP Эта функция используется для запроса статистики для лимита номер \fIlimitno\fP из правила номер \fIruleno\fP, даты когда лимит был запущен должны быть в интервале от \fItm1\fP до \fItm2\fP. Указатель на массив структур \fIstruct\ ipa_limit_state\fP должен быть сохранён в \fI*bufp\fP, число элементов массива должно быть сохранено в \fI*n\fP. Если число элементов массива равно нулю, то значение \fI*bufp\fP должно быть установлено в NULL. Если \fItm1\fP равно NULL, то должно быть возвращено текущее состояние лимита. Если модуль не имеет текущего состояния для лимита, то он должен установить поле \fIlim\fP в элементе \fI*bufp\fP в нуль. .IP \fIst_get_threshold_stat\fP Эта функция используется для запроса текущего состояния для порога номер \fIthresholdno\fP из правила номер \fIruleno\fP. Если модуль не имеет текущего состояния для порога, то он должен установить поле \fIthr\fP в \fIbuf\fP в нуль. .PP Если какая-то функция возвращает числовое значение, то в случае успешного выполнения эта функция должна вернуть значение 0, иначе должно быть возвращено значение -1. .PP Если модуль статистики не поддерживает какие-то функции по запросу статистики или описания, то необходимо установить соответствующие поля в NULL. .PP Если какая-то функция принимает аргумент \fImem_type\fP, то вся память выделяемая этой функцией и возвращаемая как результат должна быть выделена с помощью функций \fIipa_memfunc\fP с типом памяти \fImem_type\fP. .PP Если какая-то функция экспортируется модулю, то соответствующее поле может быть установлено в любое значение (обычно NULL). .PP .SH ДРУГИЕ ИСТОЧНИКИ ipa(8), ipactl(8), ipastat(8), ipa.conf(5), ipastat.conf(5) .SH АВТОР Andrey\ Simonenko\ .SH НЕДОРАБОТКИ Если вы обнаружите какие-либо ошибки, то, пожалуйста, сообщите мне по email.