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

# pmRecord(3)

record mode support for PMAPI clients

## NAME

**pmRecordSetup**, **pmRecordAddHost**, **pmRecordControl** - record mode support for PMAPI clients

## C SYNOPSIS

**#include \<pcp/pmafm.h\>**

**FILE \*pmRecordSetup(const char \****folio***,** **const char \****creator***,** **int** *replay***);**\
 **int pmRecordAddHost(const char \****host***,** **int** *isdefault***,** **pmRecordHost \*\****rhp***);**\
 **int pmRecordControl(pmRecordHost \****rhp***,** **int** *request***,** **const char \****options***);**

**cc ... -lpcp\_gui**

## DESCRIPTION

These routines may be used to create a Performance Co-Pilot (PCP) archive \`\`on the fly'' to support \`\`record mode'' services for PMAPI client applications.

Each record mode \`\`session'' involves one or more PCP archives each created using a dedicated [**pmlogger**(1)](/pmlogger/1.md) process, with an overall Archive Folio format as understood by [**pmafm**(1)](/pmafm/1.md), to name and collect all of the archives associated with a single recording session.

The *pmRecordHost* structure is used to maintain state information between the creator of the recording session and the associated **pmlogger** process(es).  The structure is defined as:

```
typedef struct {
    FILE   *f_config;    /* caller writes pmlogger configuration here */
    int    fd_ipc;       /* IPC channel to pmlogger */
    char   *logfile;     /* full pathname for pmlogger error logfile */
    pid_t  pid;          /* process id for pmlogger */
    int    status;       /* exit status, -1 if unknown */
} pmRecordHost;
```

The routines are used in combination to create a recording session as follows.

- 1\.

  Call **pmRecordSetup** to establish a new recording session.  A new Archive Folio will be created using the name *folio*; if the file or directory *folio* already exists, or the file *folio* cannot be created, this is an error. The application that is creating the session is identified by *creator* (most often this would be the same as the global PMAPI application name, as returned by [**pmGetProgname**(3)](/pmGetProgname/3.md)). If the application knows how to create its own configuration file to replay the recorded session, then *replay* should be non-zero.

  **pmRecordSetup** returns a *stdio* stream onto which the application should write the text of the required replay configuration file, if any.

- 2\.

  For each *host* that is to be included in the recording session, call **pmRecordAddHost**. A new *pmRecordHost* structure is returned via *rhp*. It is assumed that [**pmcd**(1)](/pmcd/1.md) is running on *host* as this is how [**pmlogger**(1)](/pmlogger/1.md) will retrieve the required performance metrics.

  If this *host* is the default host for this recording session, then *isdefault* should be non-zero.  This will ensure that the corresponding archive appears first in the PCP archive folio, and hence the tools used to replay the archive folio will make the correct determination of the archive associated with the default host. At most one *host* per recording session may be nominated as the default host.

  The calling application should write the desired **pmlogger** configuration onto the *stdio* stream returned via the *f\_config* field in the *pmRecordHost* structure.

- 3\.

  Optionally add arguments to the command line that will be used to launch [**pmlogger**(1)](/pmlogger/1.md) by calling **pmRecordControl** with a *request* of **PM\_REC\_SETARG**. The argument is passed via *options* and one call to **pmRecordControl** is required for each distinct argument.

  An argument may be added for a particular **pmlogger** instance identified by *rhp*, or if the *rhp* argument is NULL the argument is added for all **pmlogger** instances that will be launched in the current recording session.

  Independent of any calls to **pmRecordControl** with a *request* of **PM\_REC\_SETARG**, each **pmlogger** instance will automatically be launched with the following arguments: **-c**, **-h**, **-l**, **-x** and the basename for the PCP archive.

- 4\.

  To commence the recording session, call **pmRecordControl** with a *request* of **PM\_REC\_ON**, and *rhp* must be NULL. This will launch one [**pmlogger**(1)](/pmlogger/1.md) process for each host in the recording session, and initialize the *fd\_ipc*, *logfile*, *pid* and *status* fields in the associated *pmRecordHost* structure(s).

- 5\.

  To terminate a **pmlogger** instance identified by *rhp*, call **pmRecordControl** with a *request* of **PM\_REC\_OFF**. If the *rhp* argument to **pmRecordControl** is NULL, the termination request is broadcast to all **pmlogger** processes in the current recording session.

  An informative dialog is generated directly by each **pmlogger** process and hence note the comments on the disposition of output from **pmlogger** below.

  Alternatively, **pmlogger** can be started with options to limit the duration of logging, e.g. the **-T** or **-s** arguments, in which case there is no need to call **pmRecordControl** with a *request* of **PM\_REC\_OFF** and no dialog is generated.

- 6\.

  To display the current status of the **pmlogger** instance identified by *rhp*, call **pmRecordControl** with a *request* of **PM\_REC\_STATUS**. If the *rhp* argument to **pmRecordControl** is NULL, the status request is broadcast to all **pmlogger** processes in the current recording session.

  The display is generated directly by each **pmlogger** process and hence note the comments on the disposition of output from **pmlogger** below.

- 7\.

  To detach a **pmlogger** instance identified by *rhp* and allow it to continue independent of the application that launched the recording session, call **pmRecordControl** with a *request* of **PM\_REC\_DETACH**. If the *rhp* argument to **pmRecordControl** is NULL, the detach request is broadcast to all **pmlogger** processes in the current recording session.

  An informative dialog is generated directly by each **pmlogger** process and hence note the comments on the disposition of output from **pmlogger** below.

The calling application should not close any of the returned *stdio* streams; this will be done by **pmRecordControl** when recording is commenced.

Once **pmlogger** has been started for a recording session, then **pmlogger** will assume responsibility for any dialog with the user in the event that the application that launched the recording session should exit, particularly without terminating the recording session.

By default, information and dialogs from **pmlogger** will be displayed using [**pmquery**(1)](/pmquery/1.md) on the assumption that most applications wishing to launch a recording session are GUI-based.  In the event that **pmquery** fails to display the information (for example, because the **DISPLAY** environment variable is not set), **pmlogger** will write on its own *stderr* stream (**not** the *stderr* stream of the launching process); the output will be assigned to the *XXXXXX.host.**log*** file described in the FILES section below. For convenience, the full pathname to this file is provided via the *logfile* field in the *pmRecordHost* structure.

If the *options* argument to **pmRecordControl** is not NULL, this string may be used to pass additional arguments to [**pmquery**(1)](/pmquery/1.md) in those cases where a dialog is to be displayed.  One use of this capability would be to provide a **-geometry** string to control the placement of the dialog.

Premature termination of a launched **pmlogger** process may be determined using the *pmRecordHost* structure, by calling [**select**(2)](/select/2.md) on the *fd\_ipc* field or polling the *status* field that will contain the termination status from [**waitpid**(2)](/waitpid/2.md) if known, else -1.

## DIAGNOSTICS

**pmRecordSetup** may return **NULL** in the event of an error. Check *errno* for the real cause, but the value **EINVAL** typically means that the order of calls to these routines is not correct (there is obvious state associated with the current recording session that is maintained across calls to these routines). For example the following calls would produce this **EINVAL** error; calling **pmRecordControl** before calling **pmRecordAddHost** at least once, or calling **pmRecordAddHost** before calling **pmRecordSetup**.

**pmRecordControl** and **pmRecordAddHost** both return 0 on success, else a value less than 0 suitable for decoding with [**pmErrStr**(3)](/pmErrStr/3.md) on failure. The value **-EINVAL** has the same interpretation as *errno* being set to **EINVAL** as described above.

**pmRecordControl** will return **PM\_ERR\_IPC** if the associated **pmlogger** process has already exited.

## FILES

These routines create a number of files in the **same directory** as the *folio* file named in the call to **pmRecordSetup**. In all cases, the \`\`XXXXXX'' component is the result of calling [**mktemp**(3)](/mktemp/3.md).

- *XXXXXX*

  If *replay* is non-zero, this is the creator's replay configuration file, else an empty control file, used to guarantee uniqueness.

- *folio*

  The PCP Archive Folio, suitable for use with [**pmafm**(1)](/pmafm/1.md).

- *XXXXXX.host.**config***

  The [**pmlogger**(1)](/pmlogger/1.md) configuration for each *host* - if the same *host* is used in different calls to **pmRecordAddHost** within the same recording session then one of the letters \`\`a'' through \`\`z'' will be appended to the \`\`XXXXXX'' part of all associated file names to ensure uniqueness.

- *XXXXXX.host.**log***

  *stdout* and *stderr* for the [**pmlogger**(1)](/pmlogger/1.md) instance for each *host*.

- *XXXXXX.host.{**0**,**meta**,**index**}*

  The files comprising a single PCP archive for each *host*.

## SEE ALSO

[**pmafm**(1)](/pmafm/1.md), [**pmlogger**(1)](/pmlogger/1.md), [**pmquery**(1)](/pmquery/1.md) and [**PMAPI**(3)](/PMAPI/3.md).
