# pmdafetch

## NAME



           **pmdaFetch** , **pmdaSetFetchCallBack** - fill a pmResult structure with
           the requested metric values
    


## C SYNOPSIS



           **#include <pcp/pmapi.h>**
           **#include <pcp/pmda.h>**
    
           **int pmdaFetch(int** _numpmid_**, pmID ***_pmidlist_**, pmResult ****_resp_**,**
                         **pmdaExt ***_pmda_**);**
           **void pmdaSetFetchCallBack(pmdaInterface ***_dispatch_**,**
                                     **pmdaFetchCallBack** _callback_**);**
    
           **cc ... -lpcp_pmda -lpcp**
    


## DESCRIPTION



           **pmdaFetch** is  a  generic  callback used by a PMDA(3) to process a
           fetch request from pmcd(1).  The request from **pmcd** is initiated by
           a client calling pmFetch(3).
    
           This is one of the  few  generic  callbacks  in  _libpcp_pmda_  (see
           PMDA(3)) that is incomplete, requiring a further **pmdaFetchCallBack**
           method  of  its own.  The additional callback should be registered
           using **pmdaSetFetchCallBack** and the  **pmdaFetchCallBack** method  has
           the following prototype:
           int func(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *avp)
    
           **pmdaFetch** will  allocate and resize the _resp_ result structure, to
           store values for the _numpmid_ metrics listed in _pmidlist_.
    
           For each instance listed in the profile  (see  pmdaProfile(3))  of
           each  metric  listed  in _pmidlist_ , the **pmdaFetchCallBack** method is
           called to fill the **pmAtomValue** structure identified by _avp_ with  a
           value for a specific metric-instance pair identified by the metric
           descriptor _mdesc_ and the instance _inst_.  This value is then copied
           into the **pmResult** structure.
    
           The  **pmdaFetchCallBack** method should return a value less than zero
           for an error, and the most likely cases would  be  **PM_ERR_PMID** if
           the  metric  identified  by  _mdesc_  is not known to the method, or
           **PM_ERR_INST** if the method believes the instance _inst_ is not  known
           for the metric identified by _mdesc_.
    
           The  success  error  codes depend on the version of **PMDA_INTERFACE**
           the PMDA is using.
    
           If  the  PMDA  is  using  **PMDA_INTERFACE_2** then  on  success  the
           **pmdaFetchCallBack** method should return **0**.
    
           If  the PMDA is using **PMDA_INTERFACE_3** or **PMDA_INTERFACE_4** then on
           success the **pmdaFetchCallBack** method should return **1** if a value is
           returned via _avp_ , else **0** if no values are currently available  for
           the  requested  metric-instance  pair although _mdesc_ and _inst_ both
           seem reasonable.
    
           If the PMDA is using **PMDA_INTERFACE_5** or later then on success the
           **pmdaFetchCallBack** method should return  **PMDA_FETCH_STATIC**(**1**)  if
           the value returned via _avp_ can be ignored by **pmdaFetch** once it has
           been  copied  into the **pmResult** structure, else **PMDA_FETCH_DYNAMIC**
           (**2**) if the value returned via _avp_ uses the either  the  **vp** or  **cp**
           fields  of  the  **pmAtomValue** and the associated value (buffer) was
           allocated using one of malloc(3), calloc(3), realloc(3), strdup(3)
           etc. and **pmdaFetch** should release the memory  by  calling  free(3)
           once  a  new  buffer has been allocated and the value copied, else
           **PMDA_FETCH_NOVALUES**(**0**) if no values are currently  available  for
           the  requested  metric-instance  pair although _mdesc_ and _inst_ both
           seem reasonable.
    
           If the **pmdaFetchCallBack** method returns a value for an instance of
           a metric of type **PM_TYPE_STRING** or **PM_TYPE_AGGREGATE** some  special
           care is needed – the method should either use a static buffer, set
           _avp- >cp_  or  _avp- >vp_  to  the address of the buffer and return **PM‐**
           **DA_FETCH_STATIC** , or use a dynamically  allocated  buffer,  keep  a
           static reference to the buffer's address, return **PMDA_FETCH_STATIC**
           and  free(3)  or  realloc(3) or reuse the buffer the next time the
           **pmdaFetchCallBack** method is called, else use a  dynamically  allo‐
           cated buffer and return **PMDA_FETCH_DYNAMIC**.
    


## EXAMPLE



           The  following code fragments are for a hypothetical PMDA has with
           metrics (A, B, C and D) and an instance domain (X)  with  two  in‐
           stances  (X1 and X2).  The instance domain and metrics description
           tables (see pmdaInit(3)) could be defined as:
    
                static pmdaInstid _X[] = {
                    { 0, "X1" }, { 1, "X2" }
                };
                static pmdaIndom indomtab[] = {
                #define X_INDOM 0
                    { 0, 2, _X },
                };
                static pmdaMetric metrictab[] = {
                /* A */
                    { (void *)0,
                      { PMDA_PMID(0,0), PM_TYPE_32, PM_INDOM_NULL,
                        PM_SEM_INSTANT, {0,0,0,0,0,0} }, },
                /* B */
                    { (void *)0,
                      { PMDA_PMID(0,1), PM_TYPE_DOUBLE, X_INDOM,
                        PM_SEM_INSTANT, {0,1,0,0,PM_TIME_SEC,0} }, },
                /* C */
                    { (void *)0,
                      { PMDA_PMID(0,2), PM_TYPE_STRING, PM_INDOM_NULL,
                        PM_SEM_INSTANT, {0,0,0,0,0,0} }, },
                /* D */
                    { (void *)0,
                      { PMDA_PMID(0,3), PM_TYPE_STRING, PM_INDOM_NULL,
                        PM_SEM_INSTANT, {0,0,0,0,0,0} }, },
                };
    
           A **pmdaFetchCallBack** method to be called from  **pmdaFetch** could  be
           defined as:
    
                int
                myFetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *avp)
                {
                  static char sbuf[20]; // reuse this buffer
                  char        *dbuf;    // malloc'd
                  switch (pmID_item(mdesc->m_desc.pmid)) {
                    case 0:
                      /* assign some value for metric A */;
                      avp->l = ...
                      break;
                    case 1:
                      switch (inst) {
                          case 0:
                           /* assign a value for metric B, instance X1 */;
                              avp->d = ...
                              break;
                          case 1:
                           /* assign a value for metric B, instance X2 */;
                              avp->d = ...
                              break;
                          default:
                              return PM_ERR_INST;
                      }
                    case 2:
                      /* place value for metric C in dbuf[] */
                      memcpy(dbuf, ...);
                      avp->cp = dbuf;
                      break;
                    case 3:
                      avp->cp = (char *)malloc(somesize);
                      /* place value in avp->cp */
                      pmsprintf(avp->cp, somesize, ...);
                      return PMDA_FETCH_DYNAMIC;
                    default:
                      return PM_ERR_PMID;
                  }
                  return PMDA_FETCH_STATIC;
                }
    


## CAVEAT



           The  PMDA must be using **PMDA_INTERFACE_2** or later, as specified in
           the call to pmdaDSO(3) or pmdaDaemon(3).
    


## DIAGNOSTICS



           The following error messages indicate that  there  is  discrepancy
           between  the  namespace, **pmdaMetric** and **pmdaIndom** tables passed to
           pmdaInit(3), and the registered fetch callback:
    
           **pmdaFetch: Requested metric** _metric_ **is not defined**
                  A requested metric _metric_ is not listed in the **pmdaMetric**
                  table.  The namespace for this PMDA(3) may contain addi‐
                  tional metrics.
    
           **pmdaFetch: PMID** _pmid_ **not handled by fetch callback**
                  The **pmdaFetchCallBack** method has returned **PM_ERR_PMID**.
                  This indicates that a metric may be listed in the **pmdaMet‐**
                  **ric** table, but is not supported by the callback method.
    
           **pmdaFetch: Instance** _inst_ **of PMID** _pmid_ **not handled by fetch call‐**
           **back**
                  The **pmdaFetchCallBack** method has returned **PM_ERR_INST**.
                  This indicates that an instance of metric is listed in the
                  **pmdaIndom** table, but is not supported by the callback
                  method.
    
           **pmdaFetch: Fetch callback error:**
                  The **pmdaFetchCallBack** method returned a result other than
                  **PMDA_FETCH_NOVALUES** , **PMDA_FETCH_STATIC** , **PMDA_FETCH_DYNAMIC** ,
                  **PM_ERR_PMID** or **PM_ERR_INST**.
    
           **pmdaFetch: Descriptor type (**_type_**) for metric** _pmid_ **is bad**
                  The data type _type_ specified for the metric _pmid_ in the **pm‐**
                  **daMetric** table is illegal.
    
           **pmdaFetch** will return **-errno** if an error occurred while allocating
           the **pmResult** structure or copying the value from the **pmAtomValue**.
    


* * *