IPA_MOD(3)                                                          IPA_MOD(3)



NAME
       ipa_mod -- IPA modules APIs

SYNOPSIS
       #include <ipa_mod.h>

DESCRIPTION
       This manual page describes API of IPA modules.  Let's call any IPA mod-
       ule simply ``a module''.  Information given  in  this  manual  page  is
       mainly for developers, but it can be interesting for anybody who wishes
       to understand how IPA utilities work with IPA modules.

       This manual page has descriptions of the following APIs:

       ipa_memfunc API version 1 (IPA_MEMFUNC_API_VERSION);
       ipa_ac_mod API version 2 (IPA_AC_MOD_API_VERSION);
       ipa_db_mod API version 2 (IPA_DB_MOD_API_VERSION);
       ipa_st_mod API version 2 (IPA_ST_MOD_API_VERSION).

   Module's symbols naming
       Any module is stored in a file  with  the  name  like  foobar-x.y.z.so.
       After  loading a module using the dlopen(3) or similar function, any of
       IPA utilities removes a suffix and a version number from  the  module's
       file  name  and  tries  to  find  foobar_ac_mod,  foobar_db_mod or foo-
       bar_st_mod symbol in a module if a module is  accounting,  database  or
       statistics module.  If a module has a searched symbol, then a module is
       considered as an IPA module.

       Then found (void *) pointer to a symbol is converted to  one  of  three
       (struct ipa_XX_mod *)  pointers.   Structures ipa_XX_mod determine APIs
       between IPA utilities and modules.

       Such method of naming symbols in modules allows to have several modules
       of  different  types  in  one file.  You can create links to a module's
       file with different names to follow above given naming scheme.

   Single-threaded and multi-threaded modules
       Any module can be single-threaded or multi-threaded.  If a module  does
       not  block  in  its functions, then it can be built as single-threaded.
       If a module can block in some of its functions or if a module needs  to
       continuously  monitor  some  event,  then  it  must  be built as multi-
       threaded.  Alternatively a module can fork(2) another process  and  use
       some form of IPC to communicate with it from some of its functions, and
       used IPC functions also must be nonblockable.

       If a module is single-threaded, then it can use signals for own purpose
       (for  example  SIGALRM to implement timeout), except signals used by an
       IPA utility, which loaded this module.  If a module is  multi-threaded,
       then it is not allowed to use signals.

       It  is  very important to return from a module's function as quickly as
       possible, since IPA utilities expect, that module's functions will  not
       block.   If  a module spends too much time in its functions, then time-
       stamps of statistics and reaction on some planned events  will  be  not
       very accurate in IPA utilities.

       Even  if  a module is not designed as multi-threaded, other modules can
       be multi-threaded.  All loaded modules must be all  single-threaded  or
       must  be  all  multi-threaded.  So any single-threaded module should be
       able to be built as multi-threaded.  A module always should set correct
       flag in its API structure to say if it is single- or multi-threaded.

       IPA utilities are single-threaded by design, but if at least one multi-
       threaded module is used, then they must be built as multi-threaded.  In
       multi-threaded  regime functions from ipa_memfunc, which is exported by
       IPA utilities to modules, become thread-safe.

       Modules are allowed to create  threads  only  after  the  configuration
       phase.

   Exported memory allocation functions for a module
       Modules  APIs  require  some  type  of organization of data in modules.
       ipa_memfunc functions are exported to a module and try to help a module
       with  memory  manipulation.   A module is free to decide if it will use
       these functions or if it will  not.   In  some  functions  modules  are
       required to use functions from ipa_memfunc.

       There  are four types of functions from ipa_memfunc: initialization and
       deinitialization functions, functions for general purpose memory  allo-
       cation,  functions  for  working  with mzones and functions for working
       with marrays.

       Functions mem_* for general purpose memory allocation are wrappers  for
       standard  library  memory  allocation  functions  malloc(3), calloc(3),
       realloc(3), free(3), strdup(3) and for vasprintf(3) function, found  on
       some systems.  Any memory allocated with some of mem_* functions should
       be freed with mem_free function.   These  functions  accept  extra  one
       argument,  called  mem_type (memory type), which is used for collecting
       statistics about memory usage.  This mem_type should be created by  the
       mem_type_new function.

       Marrays  (memory arrays) are used for creating arrays of items.  Mzones
       (memory zones) are used for creating items of the same size.  All  mar-
       ray_*  and  mzone_*  functions  internally  use mem_* memory allocation
       functions.

       Functions from ipa_memfunc detect wrong pointers  and  incorrect  argu-
       ments in mem_*, marray_* and mzone_* functions.  If some critical error
       is found in any of these functions, then this function terminates  exe-
       cution of a program and a core dump is generated.

       If IPA utilities were built with defined WITH_MEMFUNC_DEBUG macro vari-
       able, then allocated and freed memory  objects  are  filled  with  some
       garbage  bytes, so if some part of code uses already freed memory, then
       it is likely, that it will get an error.  Also mem_realloc in this case
       is  equivalent to malloc(3) new memory area, memcpy(3) data to new mem-
       ory area, free(3) old memory area.

       Any IPA utility during exit stage  and  during  reconfiguration  checks
       size  of  allocated  and not freed memory, if this size is not equal to
       zero, then a debug message is sent to the log.  If some mzone of marray
       was not deinitialized, then its name appears in a debug message.

       The ipa_memfunc has following format:

       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 {
           unsigned 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, unsigned 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 **buf_ptr, 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,
                               unsigned int flags, void **arr, size_t isize,
                               unsigned int nitems, unsigned int nalloc);
           void            (*marray_deinit)(ipa_marray *marray);
           int             (*marray_alloc)(ipa_marray *marray,
                               unsigned int *idxp, int fixed);
           void            (*marray_free)(ipa_marray *marray,
                               unsigned int idx);
           void            (*marray_minimize)(ipa_marray *marray);
           int             (*marray_check_index)(ipa_marray *marray,
                               unsigned int idx);
           unsigned int    (*marray_nused)(ipa_marray *marray);
           ipa_mzone       *(*mzone_init)(const char *name, const char *desc,
                               unsigned int flags, size_t isize,
                               unsigned int nitems, unsigned int nalloc);
           void            (*mzone_deinit)(ipa_mzone *mzone);
           void            *(*mzone_alloc)(ipa_mzone *mzone);
           void            (*mzone_free)(ipa_mzone *mzone, void *ptr);
           unsigned int    (*mzone_nused)(ipa_mzone *mzone);
       } ipa_memfunc;

       api_ver
              Version  of the ipa_memfunc API, a module should check values of
              supported API versions with IPA_MEMFUNC_API_VERSION during  com-
              pilation.

       memfunc_init
              A  child  of  a  module can call this function to initialize all
              other ipa_memfunc functions.

       memfunc_deinit
              A child of a module can call this function to  free  all  memory
              allocated  in  mzones  and  marrays,  and deinitialize all other
              ipa_memfunc own structures.  If foreign flag is  non-zero,  then
              all  messages  about memory leaks will be suppressed and statis-
              tics about memory usage will be flushed.   Note  that  this  and
              previous functions can be called only in a child of some module.

       m_parser
              This is a pointer to mem_type used by a parser to allocate  mem-
              ory during configuration file parsing.

       mem_type_new
              Create new mem_type, name is a short name for new mem_type, desc
              is its description  (usually  several  words).   name  and  desc
              should  exist  until  marray  is  deinitialized.  flags are ORed
              flags for  new  mem_type.   Currently  only  one  flag  IPA_MEM-
              FUNC_FLAG_PTHREAD  is  defined, which should be set if memory of
              this mem_type will be allocated  or  freed  by  several  threads
              asynchronously.  This function returns a pointer to new mem_type
              or NULL if an error occurred.

       mem_malloc
              Analogous to malloc(3).

       mem_calloc
              Analogous to calloc(3).

       mem_realloc
              Analogous to realloc(3).

       mem_strdup
              Analogous to strdup(3).

       mem_vasprintf
              Analogous to vasprintf(3) found on some systems.  This  function
              sets  *buf_ptr to be a pointer to a buffer sufficiently large to
              hold the formatted string and returns the number  of  characters
              in  a  buffer  (not including the trailing `\0').  If sufficient
              space cannot be allocated, this function will return -1 and  set
              *buf_ptr to be a NULL pointer.  format and ap are the same argu-
              ments as for vprintf(3).

       mem_free
              Analogous to free(3).

       marray_init
              Create marray, name is a name of marray, desc is its description
              (usually  several words).  name and desc should exist until mar-
              ray is deinitialized.  flags determines ORed flags for new  mar-
              ray,   currently   only  one  flag  IPA_MEMFUNC_FLAG_PTHREAD  is
              defined, this flag must be set if items from this marray can  be
              allocated and freed by several threads asynchronously.  arr is a
              pointer where to store the pointer to the actual array of items.
              isize  is  a size of one item in marray.  nitems means number of
              items to allocate initially.  nalloc means number  of  items  to
              allocate if there is not any unused items in marray.  If you are
              not sure about these values, then set them to 1.  This  function
              returns  a  pointer  to  just created marray or NULL if an error
              occurred.  Note that the pointer saved in memory pointed by  arr
              can  be  changed  by next marray_alloc and marray_free functions
              calls.

       marray_deinit
              Release memory used by marray.  If a module does not  call  this
              function,  then  an IPA utility will report about leak of memory
              and deinitialize module's marray, but this deinitialization does
              not  mean  that memory leak is avoided, because deinitialization
              of marray is not deep-free for its items.  If  marray  is  NULL,
              then this function does nothing.

       marray_alloc
              Allocate a new item in marray.  If fixed is non-zero, then *idxp
              should be a desired index number of a new item in  marray,  else
              this  function  will  allocate  an item with the lowest possible
              unused index number and save this index number in  *idxp.   This
              function  returns  0  if  a  new item was allocated and -1 if an
              error occurred.  Usually a module calls this function with  non-
              zero value of the fixed argument.

       marray_free
              Return previously allocated item with index idx to marray.

       marray_minimize
              Try  to  minimize  memory  used by marray.  Such minimization is
              possible because marray_alloc and marray_free try to keep  extra
              memory for future items allocations.

       marray_check_index
              This  function  checks  whether  an  item with the idx index was
              allocated previously in marray.  If an item was allocated,  then
              0 is returned, else non-zero value is returned.

       marray_nused
              Return number of allocated items in marray.

       mzone_init
              Create  mzone,  name is a name of mzone, desc is its description
              (usually several words).  name and desc should exist until  mar-
              ray  is  deinitialized.   flags means the same as in marray_init
              function, mzone  also  accepts  IPA_MEMFUNC_FLAG_OPTIMIZE,  this
              flag  should be set if it will be many items in mzone.  isize is
              a size of one item in mzone.  nitems means number  of  items  to
              allocate initially.  nalloc means number of items to allocate if
              there is not any unused item in mzone.   If  you  are  not  sure
              about these values, then set them to 1.  This function returns a
              pointer to just created mzone or NULL if an error occurred.

       mzone_deinit
              Release memory used by mzone.  If a module does  not  call  this
              function,  then  an IPA utility will report about leak of memory
              and deinitialize module's mzone, but this deinitialization  does
              not  mean  that memory leak is avoided, because deinitialization
              of mzone is not deep-free for its items.  If mzone is NULL, then
              this function does nothing.

       mzone_alloc
              Allocate a new item from mzone.  This function returns a pointer
              to a new item or NULL if an error occurred.

       mzone_free
              Return previously allocated item pointed by ptr to mzone.

       mzone_nused
              Return number of allocated items from mzone.

   Exported support functions for a module
       Sometime a module needs to add some macro variable to some  section  of
       the  configuration  file, or needs to output own parameters when an IPA
       utility outputs parsed configuration file, or needs to send a log  mes-
       sage.   Since  a  module  does not know how to do this, an IPA utility,
       which uses this module, exports ipa_suppfunc functions to a module:

       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,
                       unsigned int value_type);
           void    (*print_boolean)(int value);
           void    (*print_space)(void);
           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)(const char *sym);
           int     (*global_sym_add)(char *sym, char *val, int copy_flag);
           int     (*global_sym_del)(const char *sym);
       } ipa_suppfunc;

       print_string
              This function prints a string with quotes.

       print_bytes
              This function prints bytes value.

       print_time
              This function prints time value.

       print_value
              This function prints bytes, time or 64-bit  unsigned  number  if
              value_type   is   IPA_CONF_TYPE_BYTES,   IPA_CONF_TYPE_TIME   or
              IPA_CONF_TYPE_UINT64 respectively.

       print_boolean
              This function prints boolean value.

       print_space
              This function prints one space character if it was  not  printed
              yet.

       print_param_name
              This  function  outputs a parameter's name param with configura-
              tion prefix prefix.  If a parameter does not have  a  configura-
              tion prefix, then prefix should be NULL.

       print_param_args
              This vprintf(3)-like function outputs parameter's arguments.  It
              can be invoked several times for the same parameter.

       print_param_end
              This function should be called after outputting all  parameter's
              arguments.

       print_sect_name
              This  function  outputs a section's name sect with configuration
              prefix prefix.  If a section does not have a configuration  pre-
              fix, then prefix should be NULL.

       print_sect_args
              This  vprintf(3)-like  function outputs section's arguments.  It
              can be invoked several times for the same section.

       print_sect_begin
              This function should be called after  outputting  all  section's
              arguments.

       print_sect_end
              This function should be called at the end of a module's section.

       open_log, close_log
              If a module needs to fork another process, then that process can
              use  logmsg function (described below), but if it needs to close
              some descriptors and then use log system again, then  it  should
              call close_log and then open_log function.  Creation of the file
              descriptor for sending log messages is delayed until  the  first
              message is sent.

       logmsg A  module should use this function for sending log messages from
              any part of its code, but not from  configuration  file  parsing
              functions.  mod_name is a module's name.  priority is a priority
              of the message: IPA_LOG_INFO,  IPA_LOG_WARNING  or  IPA_LOG_ERR.
              code is the errno(2) value or 0 if there is not any error condi-
              tion.  format and ap are vprintf(3)-like arguments.

       logconferr
              A module should use this function  for  sending  messages  about
              errors  during  configuration file parsing.  Arguments means the
              same as for logmsg function.

       local_sym_add
              Create a local macro variable with name sym and  value  val,  if
              copy_flag is non-zero, then memory will be allocated and sym and
              val will be copied to it, else original pointers will  be  used.
              This  function  returns 0 if a macro variable was created and -1
              if memory could not be allocated.

       local_sym_del
              Delete a local macro variable with name sym.   If  there  is  no
              local  variable with the given name, then -1 is returned, else 0
              is returned.  A module has a choice not to  call  this  function
              for  each variable previously created by the local_sym_add func-
              tion, because an IPA utility automatically handles this.

       global_sym_add
              Like local_sym_add, but for global macro variables.

       global_sym_del
              Like local_sym_del, but for global macro variables.

   Configuration section description
       The ipa_conf_sect structure is defined as:

       typedef struct {
           const char      *sect_name;
           unsigned int    sect_id;
           int             arg_nargs;
           const char      *arg_pattern;
           regex_t         *arg_regexp;
           unsigned int    arg_type;
           const unsigned int *sect_where;
           int             (*arg_parse)(void *arg);
       } ipa_conf_sect;

       sect_name
              This is a name of the section.

       sect_id
              This is a section ID, which is local for a module.   This  value
              should be greater than IPA_CONF_SECT_CUSTOM_OFFSET.

       arg_nargs
              This  is  a number of arguments a section should have.  Set this
              field to zero if a section does not expect any arguments.  If  a
              section  can  have  variable  number of arguments, then set this
              field to negative number, which absolute value is equal to mini-
              mal number of arguments a section should have.

       arg_pattern
              A section's argument should match the given extended POSIX regu-
              lar expression.  If there is  not  such  expression,  then  this
              field should be set to NULL.

       arg_regexp
              This  is  a  pointer  to  the  variable  with  regex_t type.  if
              arg_pattern is not NULL, then this  field  also  should  not  be
              NULL.  It is possible share some regular expression between sec-
              tions and parameters and do not waste  memory  for  extra  vari-
              ables.   In  this  case  only one section or parameter must have
              valid pointer in arg_pattern, all others sections and parameters
              must set arg_pattern to NULL.

       arg_type
              This is a type of the argument.  There are following types:

              IPA_CONF_TYPE_INT32    - int32_t;
              IPA_CONF_TYPE_UINT32   - uint32_t;
              IPA_CONF_TYPE_INT64    - int64_t;
              IPA_CONF_TYPE_UINT64   - uint64_t;
              IPA_CONF_TYPE_STRING   - a string;
              IPA_CONF_TYPE_BYTES    - bytes;
              IPA_CONF_TYPE_TIME     - time;
              IPA_CONF_TYPE_VALUE    - value;
              IPA_CONF_TYPE_PER_CENT - per cent;
              IPA_CONF_TYPE_BOOLEAN  - boolean;
              IPA_CONF_TYPE_MISC     - without any format.

              Usually  a  module  uses a regular expression (field arg_regexp)
              with IPA_CONF_TYPE_MISC argument type and does not use a regular
              expression with other argument types.  IPA_CONF_TYPE_VALUE means
              time, bytes or uint64_t value.  See below details.

       sect_where
              This field determines where this section should be placed, it is
              a pointer to an array of 'unsigned int' values, each value is an
              ID of a section, last element in this array should be  equal  to
              zero.  Predefined sections IDs are follows:

              IPA_CONF_SECT_ROOT      - no section;
              IPA_CONF_SECT_GLOBAL    - the global section;
              IPA_CONF_SECT_RULE      - the rule section;
              IPA_CONF_SECT_LIMIT     - the limit section;
              IPA_CONF_SECT_THRESHOLD - the threshold section;
              IPA_CONF_SECT_AUTORULE  - the autorule section;
              IPA_CONF_SECT_RULEPAT   - the rulepat section;
              IPA_CONF_SECT_RESTART   - the restart section;
              IPA_CONF_SECT_REACH     - the reach section;
              IPA_CONF_SECT_EXPIRE    - the expire section;
              IPA_CONF_SECT_STARTUP   - the startup section;
              IPA_CONF_SECT_SHUTDOWN  - the shutdown section;
              IPA_CONF_SECT_IF_REACHED - the if_reached section;
              IPA_CONF_SECT_IF_NOT_REACHED - the if_not_reached section;
              IPA_CONF_SECT_IF_ALL_REACHED - the if_all_reached section;
              IPA_CONF_SECT_IF_ANY_REACHED - the if_any_reached section;
              IPA_CONF_SECT_IF_ALL_NOT_REACHED - the if_all_not_reached section;
              IPA_CONF_SECT_IF_ANY_NOT_REACHED - the if_any_not_reached section;
              IPA_CONF_SECT_BELOW_THRESHOLD - the below_threshold section;
              IPA_CONF_SECT_EQUAL_THRESHOLD - the equal_threshold section;
              IPA_CONF_SECT_ABOVE_THRESHOLD - the above_threshold section.

       arg_parse
              This function is called for parsing section arguments.  A module
              can set this field to NULL if it has not  any  parsing  function
              for  arguments.  arg is a pointer to some data, which depends on
              arg_type, and arg_parse function should perform following casts:

              IPA_CONF_TYPE_INT32   - *(int32_t *)arg;
              IPA_CONF_TYPE_UINT32  - *(uint32_t *)arg;
              IPA_CONF_TYPE_INT64   - *(int64_t *)arg;
              IPA_CONF_TYPE_UINT64  - *(uint64_t *)arg;
              IPA_CONF_TYPE_STRING  - *(char **)arg;
              IPA_CONF_TYPE_BYTES   - *(uint64_t *)arg;
              IPA_CONF_TYPE_TIME    - *(uint64_t *)arg;
              IPA_CONF_TYPE_VALUE   - *(uint64_t *)arg, *((uint64_t *)arg + 1);
              IPA_CONF_TYPE_BOOLEAN - *(int *)arg;
              IPA_CONF_TYPE_MISC    - *(char **)arg.

              If  arg_type  is  IPA_CONF_TYPE_STRING, then arg is a pointer to
              the allocated memory with the parsed string (whithout quotes) by
              mem_malloc  function with m_parser mem_type, and a module should
              free this memory if it does not need it  by  mem_free  function.
              In  other  cases  arg_parse function should copy any needed data
              and do not use data by pointers, also it is  allowed  to  modify
              data  arg  points  to.   If arg_type is IPA_CONF_TYPE_MISC, then
              there are not space characters at the beginning and at the  tail
              of  arg,  also  there  is only one ` ' character between any two
              arguments in arg.  If arg_type is IPA_CONF_TYPE_VALUE, then  arg
              is  a  pointer to an array, first item of this array has type of
              value      IPA_CONF_TYPE_BYTES,      IPA_CONF_TYPE_TIME       or
              IPA_CONF_TYPE_UINT64, second item has a value itself.

   Configuration parameter description
       The ipa_conf_param structure is defined as:

       typedef struct {
           const char      *param_name;
           int             arg_nargs;
           const char      *arg_pattern;
           regex_t         *arg_regexp;
           unsigned int    arg_type;
           const unsigned int *param_where;
           int             (*arg_parse)(void *arg);
       } ipa_conf_param;

       param_name
              This is a name of the parameter.

       arg_nargs
              Explained above.

       arg_pattern
              Explained above.

       arg_regexp
              Explained above.

       arg_type
              Explained above.

       param_where
              Explained above for sect_where.

       arg_parse
              Explained above.

   Structure for representing dates
       The ipa_tm structure is defined as:

       typedef struct tm ipa_tm;

       Only  following  fields  in  the ipa_tm structure can be used: tm_year,
       tm_mon, tm_mday, tm_hour, tm_min, tm_sec  and  tm_wday.   These  fields
       determine  some  local date.  tm_year is equal to the real value of the
       year and tm_mon is equal to the real value of the month.

   Limit's state
       The state of any limit is kept in the ipa_limit_state structure:

       struct ipa_limit_state {
           uint64_t        lim;
           uint64_t        cnt;
           unsigned int    event_date_set;
           ipa_tm          event_date[IPA_LIMIT_EVENT_NUM];
       };

       lim    This is a value of the limit parameter.

       cnt    This is a value of the limit's counter.

       event_date_set
              This  is  a  bits  filed,  which  determines  valid  entries  in
              event_date array, each IPA_LIMIT_EVENT_xxx element in event_date
              array   has   corresponding   IPA_LIMIT_EVENT_xxx_SET   bit   in
              event_date_set.

       event_date
              This  is  an array of limit's events dates.  There are following
              entries in this array:

              IPA_LIMIT_EVENT_START - date when the limit started;

              IPA_LIMIT_EVENT_RESTART - date when the limit  will  restart  or
              restarted;

              IPA_LIMIT_EVENT_RESTART_EXEC - date   when   commands   for  the
              restarted limit were run;

              IPA_LIMIT_EVENT_REACH - date when the limit reached;

              IPA_LIMIT_EVENT_REACH_EXEC - date when commands for the  reached
              limit were run;

              IPA_LIMIT_EVENT_EXPIRE - date when the reached limit will expire
              and will restart or expired and restarted;

              IPA_LIMIT_EVENT_EXPIRE_EXEC - date when commands for the expired
              limit were run;

              IPA_LIMIT_EVENT_UPDATED - date  when  the limit was updated last
              time.

   Threshold's state
       The state of any threshold is kept in  the  ipa_threshold_state  struc-
       ture:

       struct ipa_threshold_state {
           uint64_t        thr;
           uint64_t        cnt;
           ipa_tm          tm_from;
           ipa_tm          tm_updated;
       };

       thr    This is a value of the threshold parameter.

       cnt    This is a value of the threshold's counter.

       tm_from, tm_updated
              Two timestamps for the threshold.

   Accounting module API
       Accounting  module API is exported by a module to an IPA utility in the
       ipa_ac_mod structure:

       struct ipa_ac_mod {
           unsigned int    api_ver;
           unsigned 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)(unsigned int event, unsigned int no,
                               const void *arg);
           int             (*conf_mimic_real)(void);
           int             (*conf_inherit)(unsigned int rulepatno,
                               unsigned int ruleno, const char *rule_name);
           void            (*conf_show)(unsigned int sect_id, unsigned int no);
           int             (*ac_pre_init)(void)
           int             (*ac_init_autorule)(unsigned int autoruleno,
                               const char *autorule_name);
           int             (*ac_init_dynrule)(unsigned int autoruleno,
                               unsigned int ruleno, const char *rule_name);
           int             (*ac_init_statrule)(unsigned int ruleno,
                               const char *rule_name);
           int             (*ac_init)(void);
           int             (*ac_deinit_rule)(unsigned int ruleno);
           int             (*ac_deinit_autorule)(unsigned int autoruleno);
           int             (*ac_deinit)(void);
           int             (*ac_get_stat)(const struct ipa_tm *);
           int             (*ac_get_rule_stat)(unsigned int stat_generation,
                               int newstat, unsigned int ruleno,
                               int *addition, uint64_t *chunk);
           int             (*ac_set_autorule_active)(unsigned int autoruleno,
                               int active);
           int             (*ac_set_rule_active)(unsigned int ruleno,
                               int active);
           int             (*ac_set_limit_active)(unsigned int ruleno,
                               unsigned int limitno, int active);
           int             (*ac_set_threshold_active)(unsigned int ruleno,
                               unsigned int thresholdno, int active);
           int             (*ac_limit_event)(unsigned int ruleno,
                               unsigned int limitno, unsigned int event);
           int             (*ac_threshold_event)(unsigned int ruleno,
                               unsigned int thresholdno, unsigned int event);
           int             (*ac_create_rule)(const char *mod_name,
                               unsigned int autoruleno, unsigned int *ruleno,
                               const char *rule_name, const char *rule_info);
           void            (*ac_delete_rule)(const char *mod_name,
                               unsigned int ruleno);
       };

       api_ver
              This is the version of  the  accounting  module  API,  a  module
              should   check   values   of   supported   API   versions   with
              IPA_AC_MOD_API_VERSION during compilation.  After loading a mod-
              ule,  this  version  number  is checked with version of used API
              version.

       mod_flags
              Flags, which describe module working  regimes.   Only  one  flag
              IPA_MOD_FLAG_PTHREAD_SAFE  is  defined,  and it must be set if a
              module is thread-safe.

       ac_name
              This is a name of the module's accounting system.

       suppfunc
              This is a pointer to ipa_suppfunc structure, which  is  exported
              to a module.

       memfunc
              This is a pointer to ipa_memfunc structure, which is exported to
              a module.

       conf_prefix
              This is a configuration prefix for module's sections and parame-
              ters.   If  a  module does not have a configuration prefix, then
              set this field to NULL.

       conf_sect_tbl
              This is a pointer to the array of the ipa_conf_sect  structures,
              which  describe  module's  sections.   Last  item  in this table
              should have sect_name equal to NULL.  If a module does not  have
              sections, then set this field to NULL.

       conf_param_tbl
              This is a pointer to the array of the ipa_param_sect structures,
              which describe module's parameters.  Last  item  in  this  table
              should have param_name equal to NULL.  If a module does not have
              parameters, then set this field to NULL.

       conf_init
              After loading a module, this function is called.

       conf_deinit
              After parsing a configuration file, this function is called.

       conf_event
              This function is called each time when some configuration  event
              occurs.  conf_event describes a configuration event.  Configura-
              tion events allows a module to know for which section its param-
              eter  or  section  belongs.   There  are following configuration
              events:

              IPA_CONF_EVENT_GLOBAL_BEGIN - the begin of the global section;

              IPA_CONF_EVENT_RULE_BEGIN - the begin of the rule  section,  arg
              points  to a string with the rule's name and should be casted to
              (const char *), no is an ordinal number of this section,  start-
              ing from 0;

              IPA_CONF_EVENT_LIMIT_BEGIN - the begin of the limit section, arg
              points to a string with the limit's name and should be casted to
              (const char *),  no  is an ordinal number of this section in the
              current section, starting from 0;

              IPA_CONF_EVENT_THRESHOLD_BEGIN - the begin of the threshold sec-
              tion,  arg  points  to  a  string  with the threshold's name and
              should be casted to (const char *), no is an ordinal  number  of
              this section in the current section, starting from 0;

              IPA_CONF_EVENT_AUTORULE_BEGIN - the  begin  of the autorule sec-
              tion, arg points to a string with the autorule's name and should
              be  casted  to  (const char *),  no is an ordinal number of this
              section, starting from 0;

              IPA_CONF_EVENT_RULEPAT_BEGIN - the begin of the rulepat section,
              arg points to a POSIX regular expression and should be casted to
              (const char *), no is an ordinal number of this section,  start-
              ing from 0;

              IPA_CONF_EVENT_CUSTOM_SECT_BEGIN - the  begin  of  some module's
              section, no is the ID of  a  module's  section,  arg  should  be
              ignored;

              There  are  IPA_CONF_EVENT_xxx_BEGIN  configuration  events  for
              other of IPA_CONF_SECT_xxx sections, but no and  arg  should  be
              ignored by a module for them.

              For  all above listed configuration events there are correspond-
              ing IPA_CONF_EVENT_xxx_END configuration events, with  the  same
              arguments.

       conf_mimic_real
              If this function is called, then a module should mimic real con-
              figuration.

       conf_inherit
              In this function a module should inherit all settings  from  the
              rulepat section number rulepatno for the rule number ruleno with
              name rule_name.  This function  is  called  before  ac_pre_init,
              then a module should use logconferr function for reporting about
              occurred errors, else logmsg function should be used.

       conf_show
              This function is called when IPA utility outputs the parsed con-
              figuration  file.   sect_id  is  the  ID of a section.  no is an
              ordinal number of a section with the given  section  ID.   If  a
              module  has  some configuration for this section, then it should
              output this configuration.  A module should not directly  output
              any  configuration,  instead  it should use one of the functions
              from the suppfunc structure.

       ac_pre_init
              This function is called after parsing a configuration  file.   A
              module  should  make general preinitialization of its accounting
              system.  This function is always called  before  other  ac_init*
              functions.

       ac_init_autorule
              This function is called if some autorule uses a module.  autoru-
              leno is a number of the autorule, autorule_name is its name.

       ac_init_dynrule
              This function is called if some  dynamic  rule  uses  a  module.
              autoruleno  is  a number of the autorule from which this dynamic
              rule was generated, ruleno is a  number  of  the  dynamic  rule,
              rule_name  is  its  name.  Data, rule_name points to, will exist
              until ac_deinit_rule is called for this rule.  This function  is
              called when a module calls ac_create_rule from ac_get_stat.

       ac_init_statrule
              The  same  as ac_init_dynrule but for static rules and is called
              after configuration phase.

       ac_init
              This function is  called  after  all  other  ac_init*  functions
              (except ac_init_dynrule, which is called from ac_create_rule).

       ac_deinit_rule
              This  function  is  called  to deinitialize a rule, which uses a
              module.  A module should not expect, that ac_init_*rule for this
              rule  was called before.  This function is called for static and
              dynamic rules.

       ac_deinit_autorule
              This function is called to deinitialize an autorule, which  uses
              a module.  A module should not expect, that ac_init_autorule was
              called for this autorule before.

       ac_deinit
              This function is called to  deinitialize  a  module.   A  module
              should  not  expect  that ac_*init functions were called before.
              This function is always  called  after  all  others  ac_deinit_*
              functions.

       ac_get_stat
              This  function  is called before calls to ac_get_rule_stat func-
              tion.  ctm is the current local date.  There is internal statis-
              tics generation number, which is changed each time when any mod-
              ule's ac_get_stat function is called and  its  value  is  always
              greater than zero.

       ac_get_rule_stat
              This  function  should  return  statistics  for  the rule number
              ruleno.  The stat_generation value is the  value  of  statistics
              generation number (see above for description).  The newstat flag
              means, that a module should consider that this is a first  invo-
              cation  of this function (for example this flag is non-zero when
              a rule becomes active).  chunk points to statistics returned  by
              the  module  and  *addition  determines what to do with returned
              statistics, if it  is  non-zero,  then  returned  statistics  is
              added,  else it is subtracted.  Here statistics means statistics
              for period between two invocations of the ac_get_rule_stat func-
              tion.  This function is not called if a rule which uses a module
              is inactive.

       ac_set_autorule_active
              This function should mark an autorule as active or inactive.  If
              flag  active is equal to zero, then an autorule should be marked
              as inactive in a module, else an autorule should  be  marked  as
              active.

       ac_set_rule_active
              The same as above, but for a rule.

       ac_set_limit_active
              The same as above, but for a limit.

       ac_set_threshold_active
              The same as above, but for a threshold.

       ac_limit_event
              This function is called when some event occurred with the limit.
              event can be:

              IPA_LIMIT_EVENT_RESTART - the limit is restarted;
              IPA_LIMIT_EVENT_REACH   - the limit becomes reached;
              IPA_LIMIT_EVENT_EXPIRE  - the reached limit expires;
              IPA_LIMIT_EVENT_STARTUP_IF_REACHED - reached at startup;
              IPA_LIMIT_EVENT_STARTUP_IF_NOT_REACHED - not reached at startup;
              IPA_LIMIT_EVENT_SHUTDOWN_IF_REACHED - reached at shutdown;
              IPA_LIMIT_EVENT_SHUTDOWN_IF_NOT_REACHED - not reached at shutdown.

       ac_threshold_event
              This function is  called  when  some  event  occurred  with  the
              threshold.  event means that threshold's counter is:

              IPA_THRESHOLD_EVENT_BELOW - below threshold's value;
              IPA_THRESHOLD_EVENT_EQUAL - equal to threshold's value;
              IPA_THRESHOLD_EVENT_ABOVE - above threshold's value.

       ac_create_rule
              This function is exported to a module.

              A  module  should  call  this function only from the ac_get_stat
              function to create a dynamic rule.  mod_name is a module's  name
              (is used only for debugging and only in this function).  autoru-
              leno is a number of the autorule from which to create a  dynamic
              rule.   rule_name is a rule's name and rule_info is its descrip-
              tion, these strings are not used by pointers,  so  if  a  module
              allocated  memory  for  them, then it should release this memory
              itself.  If  everything  is  correct,  then  ac_init_dynrule  is
              called.

              This  function  returns 0 if a dynamic rule was created, -2 if a
              rule with the same name already exists and -1 if  some  critical
              error  occurred,  in  this  case  a  module  must return -1 from
              ac_get_stat.

       ac_delete_rule
              This function is exported to a module.

              A module should call this function  only  from  the  ac_get_stat
              function  to delete a dynamic rule number ruleno previously cre-
              ated by the ac_create_rule function.   mod_name  is  a  module's
              name (is used only for debugging and only in this function).  At
              some point the ac_deinit_rule is called for the given rule.

              If everything is correct, then this  functions  returns  0.   If
              there were problems with the deinitialization, then -1 should be
              returned, in this case a module must return -1 from ac_get_stat.

       If some function, except ac_create_rule, returns integer value, then it
       should return the value -1 if an error occurred, else  zero  should  be
       returned.

       If  a module does not support some function for dynamic or static rule,
       for autorules, for limits or thresholds, then it should set correspond-
       ing field to NULL.

       If  some  function is exported to a module, then corresponding field in
       API structure can be set to any value (usually NULL).

   Database module API
       Database module API is exported by a module to an IPA  utility  in  the
       ipa_db_mod structure:

       struct ipa_db_mod {
           unsigned int    api_ver;
           unsigned 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)(unsigned int event, unsigned int no,
                               const void *arg);
           int             (*conf_mimic_real)(void);
           int             (*conf_inherit)(unsigned int rulepatno,
                               unsigned int ruleno, const char *rule_name);
           void            (*conf_show)(unsigned int sect_id, unsigned int no);
           int             (*db_pre_init)(void);
           int             (*db_init_dynrule)(unsigned int autoruleno,
                               unsigned int ruleno, const char *rule_name,
                               const char *rule_info);
           int             (*db_init_statrule)(unsigned int ruleno,
                               const char *rule_name, const char *rule_info);
           int             (*db_init_dynlimit)(unsigned int autoruleno,
                               unsigned int ruleno, const char *rule_name,
                               const char *rule_info, unsigned int limitno,
                               const char *limit_name, const char *limit_info);
           int             (*db_init_statlimit)(unsigned int ruleno,
                               const char *rule_name, const char *rule_info,
                               unsigned int limitno, const char *limit_name,
                               const char *limit_info);
           int             (*db_init_dynthreshold)(unsigned int autoruleno,
                               unsigned int ruleno, const char *rule_name,
                               const char *rule_info, unsigned int thresholdno,
                               const char *threshold_name,
                               const char *threshold_info);
           int             (*db_init_statthreshold)(unsigned int ruleno,
                               const char *rule_name, const char *rule_info,
                               unsigned int thresholdno,
                               const char *threshold_name,
                               const char *threshold_info);
           int             (*db_init)(void);
           int             (*db_get_limit_state)(unsigned int ruleno,
                               unsigned int limitno,
                               struct ipa_limit_state *state);
           int             (*db_set_limit_state)(unsigned int ruleno,
                               unsigned int limitno,
                               const struct ipa_limit_state *state,
                               int new_state);
           int             (*db_get_threshold_state)(unsigned int ruleno,
                               unsigned int thresholdno,
                               struct ipa_threshold_state *state);
           int             (*db_set_threshold_state)(unsigned int ruleno,
                               unsigned int thresholdno,
                               const struct ipa_threshold_state *state);
           int             (*db_deinit_threshold)(unsigned int ruleno,
                               unsigned int thresholdno);
           int             (*db_deinit_limit)(unsigned int ruleno,
                               unsigned int limitno);
           int             (*db_deinit_rule)(unsigned int ruleno);
           int             (*db_deinit)(void);
           int             (*db_append_rule)(unsigned int ruleno,
                               const uint64_t *cnt, const ipa_tm *ctm);
           int             (*db_update_rule)(unsigned int ruleno,
                               const uint64_t *cnt, const ipa_tm *ctm);
           int             (*db_update_limit)(unsigned int ruleno,
                               unsigned int limitno, const uint64_t *value,
                               const ipa_tm *ctm);
           int             (*db_limit_event)(unsigned int ruleno,
                               unsigned int limitno, unsigned int event,
                               const ipa_tm *etm, const ipa_tm *ctm);
           int             (*db_update_threshold)(unsigned int ruleno,
                               unsigned int thresholdno, const uint64_t *cnt,
                               const ipa_tm *tm_from,
                               const ipa_tm *tm_updated);
           int             (*db_set_rule_active)(unsigned int ruleno,
                               int active);
           int             (*db_set_limit_active)(unsigned int ruleno,
                               unsigned int limitno, int active);
           int             (*db_set_threshold_active)(unsigned int ruleno,
                               unsigned int thresholdno, int active);
       }

       api_ver
              This  is the version of the database module API, a module should
              check values of supported API versions with  IPA_DB_MOD_API_VER-
              SION  during  compilation.  After loading a module, this version
              number is checked with version of used API version.

       mod_flags
              Explained above.

       db_name
              This is a name of the module's database.

       suppfunc
              Explained above.

       memfunc
              Explained above.

       conf_prefix
              Explained above.

       conf_sect_tbl
              Explained above.

       conf_param_tbl
              Explained above.

       conf_init
              Explained above.

       conf_deinit
              Explained above.

       conf_event
              Explained above.

       conf_mimic_real
              Explained above.

       conf_inherit
              Explained above.

       conf_show
              Explained above.

       db_pre_init
              This function is called after parsing a configuration  file.   A
              module should make general initialization of its database.  This
              function always is called before other db_init* functions.

       db_init_dynrule
              This function is called if some  dynamic  rule  uses  a  module.
              autoruleno  is  a number of the autorule from which this dynamic
              rule was generated, ruleno is a  number  of  the  dynamic  rule,
              rule_name  is  its  name and rule_info is its description.  Only
              data, rule_name points to, will exist  until  db_deinit_rule  is
              called for this rule.

       db_init_statrule
              The same as db_init_dynrule but for static rules.

       db_init_dynlimit
              This function is called if some limit from a dynamic rule uses a
              module.  limitno is an ordinal number of the limit in the  rule,
              limit_name  is its name and limit_info is its description.  Rest
              of arguments means the same as in db_init_dynrule.   Only  data,
              rule_name   and   limit_name   point   to,   will   exist  until
              db_deinit_limit is called for this limit.  Since a rule can  use
              another  database, than its limits use, then a module should not
              expect that db_init_dynrule was  called  before  for  a  limit's
              rule.  If a limit's rule uses this module too, then db_init_dyn-
              rule for a rule is called first.

       db_init_statlimit
              The same as db_init_dynlimit but for limits from static rules.

       db_init_dynthreshold
              This function is called if some threshold from  a  dynamic  rule
              uses  a module.  thresholdno is an ordinal number of the thresh-
              old in the rule, threshold_name is its name  and  threshold_info
              is  its  description.   Rest  of  arguments means the same as in
              db_init_dynrule.  Only data, rule_name and threshold_name  point
              to,  will  exist  until  db_deinit_threshold  is called for this
              threshold.  Since a rule can  use  another  database,  than  its
              thresholds   use,   then   a   module  should  not  expect  that
              db_init_dynrule was called before for a threshold's rule.  If  a
              threshold's  rule uses this module too, then db_init_dynrule for
              a rule is called first.

       db_init_statthreshold
              The same as db_init_dynthreshold but for thresholds from  static
              rules.

       db_init
              This function is called after all other db_init_stat* functions.

       db_get_limit_state
              This function should return the current state of the limit.   If
              a  module  does  not  have current state for the limit, then the
              return value should be zero.  If a module has current state  for
              the limit, then the return value should be 1.

       db_set_limit_state
              This  function  should  set  a  new  state  for  the  limit.  If
              new_state is zero, then current limit's state  in  the  database
              should  be  updated,  else  a new limit's state should be regis-
              tered.

       db_get_threshold_state
              This function should return the current state of the  threshold.
              If  a module does not have current state for the threshold, then
              the return value should be zero.  If a module has current  state
              for the threshold, then the return value should be 1.

       db_set_threshold_state
              This function should update the current state for the threshold.

       db_deinit_threshold
              This function is called to deinitialize a threshold, which  uses
              a  module.   A module should not expect, that db_init_*threshold
              was called for this threshold before.

       db_deinit_limit
              This function is called to deinitialize a limit,  which  uses  a
              module.   A  module  should  not expect, that db_init_*limit was
              called for this limit before.

       db_deinit_rule
              This function is called to deinitialize a  rule,  which  uses  a
              module.   If some of rule's limits or thresholds use this module
              too,  then  db_deinit_limit  or  db_deinit_threshold  is  called
              first.   A module should not expect, that db_init_*rule for this
              rule was called before.

       db_deinit
              This function is called to  deinitialize  a  module.   A  module
              should  not  expect  that db_*init functions were called before.
              This function is always called after all other db_deinit_* func-
              tions.

       db_append_rule
              This  function  should  append  a new record for the given rule.
              cnt is a pointer to a new value of the rule's counter.   ctm  is
              the  current  local  date.  This function is called before first
              call of the db_update_rule function.

       db_update_rule
              This function should update a  database  record  for  the  given
              rule.   cnt  is  a pointer to a new value of the rule's counter,
              ctm is the current local date.

       db_update_limit
              This function should update a state of the limit  in  the  data-
              base.   cnt  is  a pointer to a new value of the counter, ctm is
              the current local date.  IPA_LIMIT_EVENT_UPDATED date should  be
              also updated by a module.

       db_limit_event
              This  function  should  register an event event for the limit in
              the database.  The given event can take place right  now  or  in
              future.  etm is the local date of the given event and ctm is the
              current local date.  IPA_LIMIT_EVENT_UPDATED date should be also
              updated by a module.  This function is called only for following
              limit's   events    IPA_LIMIT_EVENT_:    RESTART_EXEC,    REACH,
              REACH_EXEC, EXPIRE and EXPIRE_EXEC.

       db_update_threshold
              This  function  should  update  a  state of the threshold in the
              database.  cnt is a pointer to  a  new  value  of  the  counter,
              tm_from and tm_updated are two timestamps for the threshold.

       db_set_rule_active
              Explained above in ac_set_rule_active.  When a rule is marked as
              active,   then   db_append_rule   will    be    called    before
              db_update_rule.

       db_set_limit_active
              Explained above in ac_set_limit_active.

       db_set_threshold_active
              Explained above in ac_set_threshold_active.

       If some function returns integer value, then it should return the value
       -1 if an error occurred, else zero should be returned (if corresponding
       description does not specify another value).

       If  a database module does not support dynamic rules, limits or thresh-
       olds, then it should set corresponding db_init_dyn* fields to NULL.  If
       a  database module does not support static rules, limits or thresholds,
       then set corresponding db_init_stat* fields to NULL.

       If   a   database   module   does   not   support   db_get_limit_state,
       db_get_threshold_state, db_set_*active function, then set corresponding
       field to NULL.

       If some function is exported to a module, then corresponding  field  in
       API structure can be set to any value (usually NULL).

   Statistics module API
       Statistics  module API is exported by a module to an IPA utility in the
       ipa_st_mod structure:

       struct ipa_entity_desc {
           char            *name;
           char            *info;
       };

       struct ipa_rule_stat {
           unsigned 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 {
           unsigned int    api_ver;
           unsigned 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)(unsigned int event, unsigned int no,
                               const void *arg);
           int             (*conf_mimic_real)(void);
           int             (*conf_inherit)(unsigned int rulepatno,
                               unsigned int ruleno, const char *rule_name);
           void            (*conf_show)(unsigned int sect_id, unsigned int no);
           int             (*st_pre_init)(void);
           int             (*st_init_rule)(unsigned int ruleno,
                               const char *rule_name);
           int             (*st_init_limit)(unsigned int ruleno,
                               const char *rule_name, unsigned int limitno,
                               const char *limit_name);
           int             (*st_init_threshold)(unsigned int ruleno,
                               const char *rule_name, unsigned int thresholdno,
                               const char *threshold_name);
           int             (*st_init)(void);
           int             (*st_deinit_threshold)(unsigned int ruleno,
                               unsigned int thresholdno);
           int             (*st_deinit_limit)(unsigned int ruleno,
                               unsigned int limitno);
           int             (*st_deinit_rule)(unsigned int ruleno);
           int             (*st_deinit)(void);
           int             (*st_get_rule_info)(unsigned int ruleno,
                               ipa_mem_type *mem_type, char **info_ptr);
           int             (*st_get_limit_info)(unsigned int ruleno,
                               unsigned int limitno,
                               ipa_mem_type *mem_type, char **info_ptr);
           int             (*st_get_threshold_info)(unsigned int ruleno,
                               unsigned int thresholdno,
                               ipa_mem_type *mem_type, char **info_ptr);
           int             (*st_get_rules_list)(const char *pat,
                               const regex_t *pat_reg, ipa_mem_type *mem_type,
                               unsigned int *n,
                               struct ipa_entity_desc **buf_ptr);
           int             (*st_get_limits_list)(unsigned int ruleno,
                               const char *pat, const regex_t *pat_reg,
                               ipa_mem_type *mem_type, unsigned int *n,
                               struct ipa_entity_desc **buf_ptr);
           int             (*st_get_thresholds_list)(unsigned int ruleno,
                               const char *pat, const regex_t *pat_reg,
                               ipa_mem_type *mem_type, unsigned int *n,
                               struct ipa_entity_desc **buf_ptr);
           int             (*st_get_rule_stat)(unsigned int ruleno,
                               const ipa_tm *tm1, const ipa_tm *tm2,
                               int exact, ipa_mem_type *mem_type,
                               unsigned int *n,
                               struct ipa_rule_stat **buf_ptr);
           int             (*st_get_limit_stat)(unsigned int ruleno,
                               unsigned int limitno, const ipa_tm *tm1,
                               const ipa_tm *tm2, ipa_mem_type *mem_type,
                               unsigned int *n,
                               struct ipa_limit_state **buf_ptr);
           int             (*st_get_threshold_stat)(unsigned int ruleno,
                               unsigned int thresholdno,
                               struct ipa_threshold_state *buf);
       };

       api_ver
              This is the version of  the  statistics  module  API,  a  module
              should   check   values   of   supported   API   versions   with
              IPA_ST_MOD_API_VERSION during compilation.  After loading a mod-
              ule,  this  version  number  is checked with version of used API
              version.

       mod_flags
              Explained above.

       st_name
              This is a name of the module's statistics system.

       suppfunc
              Explained above.

       memfinc
              Explained above.

       conf_prefix
              Explained above.

       conf_sect_tbl
              Explained above.

       conf_param_tbl
              Explained above.

       conf_init
              Explained above.

       conf_deinit
              Explained above.

       conf_event
              Explained above.

       conf_mimic_real
              Explained above.

       conf_inherit
              Explained above.

       conf_show
              Explained above.

       st_pre_init
              This function is called after parsing a configuration  file.   A
              module should make general initialization of its statistics sys-
              tem.  This function always is called before other st_init* func-
              tions.

       st_init_rule
              This  function  is  called if a rule uses a module.  ruleno is a
              number of the rule, rule_name  is  its  name.   Data,  rule_name
              points  to,  will  exist until st_deinit_rule is called for this
              rule.  This function can be called for a rule which  has  corre-
              sponding section in the configuration file, and for a rule which
              was generated on-the-fly (can be considered as a dynamic  rule).

       st_init_limit
              This function is called if some limit from a rule uses a module.
              limitno  is  an  ordinal  number  of  the  limit  in  the  rule,
              limit_name  is  a its name.  Only data, rule_name and limit_name
              point to, will exist until st_deinit_limit is  called  for  this
              limit.  Since a rule can use another statistics system, than its
              limits use, then a module should not  expect  that  st_init_rule
              was  called  before  for a limit's rule.  If a limit's rule uses
              this module too, then st_init_rule for a limit's rule is  called
              first.  Like st_init_rule this function can be called for a rule
              and/or a limit which has corresponding section in the configura-
              tion  file,  and for a rule and/or limit which was generated on-
              the-fly (can be considered as a dynamic rule and/or a limit).

       st_init_threshold
              This function is called if some threshold from  a  rule  uses  a
              module.   thresholdno  is  an ordinal number of the threshold in
              the rule, threshold_name is a its name.   Only  data,  rule_name
              and  threshold_name point to, will exist until st_deinit_thresh-
              old is called for this threshold.  Since a rule can use  another
              statistics system, than its thresholds use, then a module should
              not expect that st_init_rule was called before for a threshold's
              rule.   If  a  threshold's  rule  uses  this  module  too,  then
              st_init_rule for a  threshold's  rule  is  called  first.   Like
              st_init_rule  this  function  can  be called for a rule and/or a
              threshold which has corresponding section in  the  configuration
              file,  and  for  a rule and/or threshold which was generated on-
              the-fly (can be considered as a dynamic rule  and/or  a  thresh-
              old).

       st_init
              This function is called after all other st_init* functions.

       st_deinit_threshold
              This  function is called to deinitialize a threshold, which uses
              a module.  A module should not  expect,  that  st_init_threshold
              was called for this threshold before.

       st_deinit_limit
              This  function  is  called to deinitialize a limit, which uses a
              module.  A module should  not  expect,  that  st_init_limit  was
              called for this limit before.

       st_deinit_rule
              This  function  is  called  to deinitialize a rule, which uses a
              module.  If some of rule's limits or thresholds use this  module
              too,  then  st_deinit_limit or st_deinit_threshold is called for
              such rule's limits or thresholds before.  A  module  should  not
              expect, that st_init_rule for this rule was called before.

       st_deinit
              This  function  is  called  to  deinitialize a module.  A module
              should not expect that st_*init functions  were  called  before.
              This function is always called after all other st_deinit_* func-
              tions.

       st_get_rule_info
              This function should return a description for  the  rule  number
              ruleno,  pointer  to  a rule's description should be returned in
              *info_ptr.   If  a  rule  does  not  have  a  description,  then
              *info_ptr should be set to NULL.

       st_get_limit_info
              The same as st_get_rule_info, but for a limit.

       st_get_threshold_info
              The same as st_get_rule_info, but for a threshold.

       st_get_rules_list
              This  function  should  return  an  array  with  rules names and
              descriptions.  If the POSIX regular expression pat is not  NULL,
              then a module should return only rules, with names which matched
              this regular expression (pat_reg is a compiled  regular  expres-
              sion  pat).   The pointer to the array of struct ipa_entity_desc
              should be returned in *buf_ptr, number of entries in this  array
              should  be  returned  in  *n.   If number of entries is equal to
              zero, then *buf_ptr must be NULL.

       st_get_limits_list
              The same as st_get_rules_list, buf for limits.

       st_get_thresholds_list
              The same as st_get_rules_list, buf for thresholds.

       st_get_rule_stat
              This function is used for querying statistics for a rule  number
              ruleno  for  time interval from tm1 till tm2.  If exact is zero,
              then both of rule's records  timestamps  should  be  inside  the
              given  time interval, else only one of rule's records timestamps
              should be inside the given time interval.  The  pointer  to  the
              array  of  struct ipa_rule_stat  should be returned in *buf_ptr,
              number of entries in this array should be returned  in  *n.   If
              number  of entries is equal to zero, then *buf_ptr must be NULL.

              Structure  struct ipa_rule_stat  represents  statistics  of  one
              rule's  record.   In  struct ipa_rule_stat  fields year, mon and
              mday specify date of both timestamps of a rule's record  (a  new
              record for any rule is always appended for a new day, that's why
              it is enough only these three fields for  dates  of  both  time-
              stamps).   t1,  m1 and s1 is time of first timestamp; t2, m2 and
              s2 is time of second timestamp.  cnt is statistics for the  time
              interval in one rule's record.

       st_get_limit_stat
              This function is used for querying statistics for a limit number
              limitno in a rule number ruleno, dates when a limit was  started
              should  be  in  time interval from tm1 till tm2.  The pointer to
              the  array  of  struct ipa_limit_state  should  be  returned  in
              *buf_ptr,  number of entries in this array should be returned in
              *n.  If number of entries is equal to zero, then  *buf_ptr  must
              be  NULL.   If  tm1  is NULL, then current limit state should be
              returned.

       st_get_threshold_stat
              This function is used for querying current state for a threshold
              number  thresholdno  in  a rule number ruleno.  If a module does
              not have current state for the threshold, then the return  value
              should  be  0.  If a module has current state for the threshold,
              then the return value should be 1.

       If some function returns integer value, then it should return the value
       -1 if an error occurred, else zero should be returned (if corresponding
       description does not specify another value).

       If a statistics module does not support  some  functions,  which  query
       statistics or description, then set corresponding fields to NULL.

       If  some  function  accepts  mem_type argument, then all allocated data
       being returned by this function should be allocated with the help  from
       ipa_memfunc functions with the given mem_type.

       If  some  function is exported to a module, then corresponding field in
       API structure can be set to any value (usually NULL).

SEE ALSO
       ipa(8), ipactl(8), ipastat(8), ipa.conf(5), ipastat.conf(5)

AUTHOR
       Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>

BUGS
       If you find any, please send email me.



                               December 5, 2010                     IPA_MOD(3)