NAME
pmdaMain, pmdaMainLoop, pmdaSetResultCallBack,
pmdaSetCheckCallBack, pmdaSetDoneCallBack, pmdaMain
LoopFreeResultCallback - generic PDU processing for a PMDA
C SYNOPSIS
#include <pcp/pmapi.h>
#include <pcp/impl.h>
#include <pcp/pmda.h>
cc ... -lpcp_pmda -lpcp
PMDA Interface 2
void pmdaMain(pmdaInterface *dispatch);
void pmdaSetResultCallBack(pmdaInterface *dispatch,
pmdaResultCallBack callback);
void pmdaSetCheckCallBack(pmdaInterface *dispatch,
pmdaCheckCallBack callback);
void pmdaSetDoneCallBack(pmdaInterface *dispatch,
pmdaDoneCallBack callback);
PMDA Interface 1
void pmdaMainLoop(char *name, int infd, int outfd, _pmPMDA
*dispatch, int (*check)(void), void (*done)(void));
void pmdaMainLoopFreeResultCallback(void (*callback)(pmRe
sult *res));
DESCRIPTION
For Performance Metric Domain Agents (PMDA(3)) using the
binary PDU protocols to communicate with pmcd(1), the rou
tine pmdaMain provides a generic implementation of the
PDU-driven main loop.
pmdaMainLoop and pmdaMainLoopFreeResultCallback imple
mented 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,
/*
* 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 later */
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;
} version;
} pmdaInterface;
This structure has been extended to incorporate the two
interface versions. 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 version.one structure. A set
ting of PMDA_INTERFACE_2 or later will force pmdaMain to
use the callbacks in the version.two 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 provid
ing a convenient wrapper that may be used to convert from
the DSO interface to the binary PDU interface.
pmdaMainLoop provided two additional callbacks, check and
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 met
rics, e.g. a DBMS. The error indication from check is not
passed back to pmcd(1) in the cases where no acknowledg
ment is expected, e.g. for a PDU_PROFILE.
The callback done would typically be used to monitor ter
mination conditions, or do PMDA housekeeping required
after PDU processing.
These callbacks should now be set with pmdaSetCheckCall
Back 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 pmdaMainLoopFreeRe
sultCallback 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.
SEE ALSO
pmcd(1), pmdbg(1), PMAPI(3) and PMDA(3).
DIAGNOSTICS
These messages may be appended to the PMDA's log file:
PMDA interface version interface not supported
The interface version is not sup
ported by pmdaMain.
Unrecognized pdu type The PMDA received a PDU from pmcd
that it does not recognize. This
may indicate that the pmcd pro
cess 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.
Man(1) output converted with
man2html