Man Linux: Main Page and Category List


       pmdaMain,  pmdaMainLoop,  pmdaSetResultCallBack,  pmdaSetCheckCallBack,
       pmdaSetDoneCallBack,  pmdaMainLoopFreeResultCallback  -   generic   PDU
       processing for a PMDA


       #include <pcp/pmapi.h>
       #include <pcp/impl.h>
       #include <pcp/pmda.h>

       cc ... -lpcp_pmda -lpcp

       PMDA Interface 2 or higher

       void pmdaMain(pmdaInterface *dispatch);

       void  pmdaSetResultCallBack(pmdaInterface *dispatch, pmdaResultCallBack

       void  pmdaSetCheckCallBack(pmdaInterface  *dispatch,  pmdaCheckCallBack

       void   pmdaSetDoneCallBack(pmdaInterface   *dispatch,  pmdaDoneCallBack

       PMDA Interface 1

       void pmdaMainLoop(char *name, int infd, int outfd,  _pmPMDA  *dispatch,
       int (*check)(void), void (*done)(void));

       void pmdaMainLoopFreeResultCallback(void (*callback)(pmResult *res));


       For  Performance  Metric  Domain  Agents (PMDA(3)) using the binary PDU
       protocols to communicate with pmcd(1), the routine pmdaMain provides  a
       generic implementation of the PDU-driven main loop.

       pmdaMainLoop  and pmdaMainLoopFreeResultCallback implemented an earlier
       version of this functionality.  Both functions will  be  removed  in  a
       later release and should not be used.

       The  arguments that are now encapsulated in pmdaExt that were passed to
       pmdaMainLoop include the name of the PMDA (used only in error messages)
       and  the  file descriptors infd and outfd used to receive and send PDUs
       to the pmcd(1) process.

       dispatch describes how to process each incoming PDU. It is a vector  of
       function  pointers,  one  per  request  PDU  type,  as  used in the DSO
       interface for a PMDA, namely:

        * Interface Definitions for PMDA Methods
       typedef struct {
           int domain;         /* set/return performance metrics domain id here */
           struct {
               unsigned int    pmda_interface: 8; /* PMDA DSO interface version */
               unsigned int    pmapi_version : 8; /* PMAPI version */
               unsigned int    flags : 16;        /* usage TBD */
           } comm;             /* set/return communication and version info */
           int status;         /* return initialization status here */

           union {
               struct {                              /* PMDA_INTERFACE_1 */
                   int (*profile)(__pmProfile *);
                   int (*fetch)(int, pmID *, pmResult **);
                   int (*desc)(pmID, pmDesc *);
                   int (*instance)(pmInDom, int, char *, __pmInResult **);
                   int (*text)(int, int, char **);
                   int (*control)(pmResult *, int, int, int);
                   int (*store)(pmResult *);
               } one;

               struct {                              /* PMDA_INTERFACE_2 or _3 */
                   pmdaExt *e_ext;
                   int (*profile)(__pmProfile *, pmdaExt *);
                   int (*fetch)(int, pmID *, pmResult **, pmdaExt *);
                   int (*desc)(pmID, pmDesc *, pmdaExt *);
                   int (*instance)(pmInDom, int, char *, __pmInResult **, pmdaExt *);
                   int (*text)(int, int, char **, pmdaExt *);
                   int (*store)(pmResult *, pmdaExt *);
               } two;

               struct {                              /* PMDA_INTERFACE_4 */
                   pmdaExt *ext;
                   int     (*profile)(__pmProfile *, pmdaExt *);
                   int     (*fetch)(int, pmID *, pmResult **, pmdaExt *);
                   int     (*desc)(pmID, pmDesc *, pmdaExt *);
                   int     (*instance)(pmInDom, int, char *, __pmInResult **, pmdaExt *);
                   int     (*text)(int, int, char **, pmdaExt *);
                   int     (*store)(pmResult *, pmdaExt *);
                   int     (*pmid)(char *, pmID *, pmdaExt *);
                   int     (*name)(pmID, char ***, pmdaExt *);
                   int     (*children)(char *, int, char ***, int **, pmdaExt *);
               } four;
           } version;

       } pmdaInterface;

       This structure has been extended to incorporate the multiple  interface
       versions  that  have evolved over time.  For pmdaMain, dispatch->domain
       and dispatch->status are ignored.   The  comm.pmda_interface  field  is
       used  to  determine the interface used by the PMDA.  Setting this field
       to PMDA_INTERFACE_1 will force pmdaMain to use  the  callbacks  in  the    structure.     A    setting   of   PMDA_INTERFACE_2   or
       PMDA_INTERFACE_3 will force  pmdaMain  to  use  the  callbacks  in  the
       version.two  structure.   A  setting  of  PMDA_INTERFACE_4  will  force
       pmdaMain to use the callbacks in the version.four structure.  Any other
       value will result in an error and termination of pmdaMain.

       Note  that the use of dispatch as the interface between the pmcd(1) and
       the methods of the PMDA allows each PMDA to be implemented as though it
       were  a  DSO,  with pmdaMain providing a convenient wrapper that may be
       used to convert from the DSO interface to the binary PDU (daemon  PMDA)

       pmdaMainLoop provided two additional callbacks, check and done.  If not
       null, check is called after each PDU is received  (but  before  it  was
       processed),  and  done  is  called  after  each  PDU is sent.  If check
       returns a value  less  than  zero  (typically  PM_ERR_AGAIN),  the  PDU
       processing  is skipped and in most cases the function value is returned
       as an error PDU to pmcd(1) - this may be used for  PMDAs  that  require
       some  sort  of  deferred  connection  or  reconnect  protocols  for the
       underlying sources of performance metrics,  e.g.  a  DBMS.   The  error
       indication  from check is not passed back to pmcd(1) in the cases where
       no acknowledgment is expected, e.g. for a PDU_PROFILE.

       The callback done  would  typically  be  used  to  monitor  termination
       conditions, or do PMDA housekeeping required after PDU processing.

       These  callbacks  should  now  be  set  with  pmdaSetCheckCallBack  and
       pmdaSetDoneCallBack when using pmdaMain.

       One further callback mechanism is provided for  handling  the  pmResult
       built for a PDU_RESULT in response to a PDU_FETCH request.  By default,
       pmdaMain will free the pmResult once the result has been  sent  to  the
       pmcd(1).   For  some  PMDAs this is inappropriate, e.g. the pmResult is
       statically allocated,  or  contains  a  hybrid  of  pinned  PDU  buffer
       information       and      dynamically      allocated      information.
       pmdaSetResultCallback may be used to  define  an  alternative  callback
       from  pmdaMain.   The  routine  pmdaMainLoopFreeResultCallback has been
       replaced by pmdaSetResultCallBack.

       pmdaMain executes as a continuous loop, returning only when an  end  of
       file is encountered on the PDU input file descriptor.


       pmcd(1), pmdbg(1), PMAPI(3) and PMDA(3).


       These messages may be appended to the PMDA’s log file:

       PMDA interface version interface not supported
                                The  interface  version  is  not  supported by

       Unrecognized pdu type    The PMDA received a PDU from pmcd that it does
                                not recognize. This may indicate that the pmcd
                                process is using  a  more  advanced  interface
                                than pmdaMain.

       If   the   PMAPI(3)   debug   control   variable   (pmdebug)   has  the
       DBG_TRACE_LIBPMDA flag set then each PDU that is received  is  reported
       in the PMDA’s log file.