---
name: "pmdaFetch"
section: "3"
platform: "linux"
package: "pcp"
version: "7.2.2-2"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/pmdaFetch"
---

# pmdaFetch(3)

fill a pmResult structure with the requested metric values

## 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)](/PMDA/3.md) to process a fetch request from [**pmcd**(1)](/pmcd/1.md). The request from **pmcd** is initiated by a client calling [**pmFetch**(3)](/pmFetch/3.md).

This is one of the few generic callbacks in *libpcp\_pmda* (see [**PMDA**(3)](/PMDA/3.md)) 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)](/pmdaProfile/3.md)) 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)](/malloc/3.md), [**calloc**(3)](/calloc/3.md), [**realloc**(3)](/realloc/3.md), **strdup (3)** etc. and **pmdaFetch** should release the memory by calling [*free*(3)](/free/3.md) 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 **PMDA\_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 allocated 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 instances (X1 and X2).  The instance domain and metrics description tables (see [**pmdaInit**(3)](/pmdaInit/3.md)) 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)](/pmdaDSO/3.md) or [**pmdaDaemon**(3)](/pmdaDaemon/3.md).

## DIAGNOSTICS

The following error messages indicate that there is discrepancy between the namespace, **pmdaMetric** and **pmdaIndom** tables passed to [**pmdaInit**(3)](/pmdaInit/3.md), 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)](/PMDA/3.md) may contain additional 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 **pmdaMetric** table, but is not supported by the callback method.

- **pmdaFetch: Instance** *inst* **of PMID** *pmid* **not handled by fetch callback**

  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 **pmdaMetric** table is illegal.

**pmdaFetch** will return **-errno** if an error occurred while allocating the **pmResult** structure or copying the value from the **pmAtomValue**.

## SEE ALSO

[**pmcd**(1)](/pmcd/1.md), [**PMAPI**(3)](/PMAPI/3.md), [**PMDA**(3)](/PMDA/3.md), [**pmdaDaemon**(3)](/pmdaDaemon/3.md), [**pmdaDSO**(3)](/pmdaDSO/3.md), [**pmdaInit**(3)](/pmdaInit/3.md) and [**pmFetch**(3)](/pmFetch/3.md).
