# pmrecord

## 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) process, with an  over‐
           all  Archive  Folio  format as understood by pmafm(1), 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_ can‐
               not 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 re‐
               turned by pmGetProgname(3)).  If the application knows how to
               create its own configuration file to replay the recorded ses‐
               sion, then _replay_ should be non-zero.
    
               **pmRecordSetup** returns a _stdio_ stream onto which the applica‐
               tion should write the text of the required replay configura‐
               tion file, if any.
    
           2.  For each _host_ that is to be included in the recording session,
               call **pmRecordAddHost**.  A new _pmRecordHost_ structure is re‐
               turned via _rhp_.  It is assumed that pmcd(1) is running on _host_
               as this is how pmlogger(1) will retrieve the required perfor‐
               mance 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** con‐
               figuration 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) by calling **pmRecordControl** with a _re‐_
               _quest_ 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) process for each host in the recording ses‐
               sion, 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 **pm‐**
               **RecordControl** with a _request_ of **PM_REC_OFF**.  If the _rhp_ argu‐
               ment 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 out‐
               put 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 identi‐
               fied 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** process‐
               es 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 **pm‐**
               **logger** 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** process‐
               es in the current recording session.
    
               An informative dialog is generated directly by each **pmlogger**
               process and hence note the comments on the disposition of out‐
               put 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 **pm‐**
           **logger** 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 ses‐
           sion.
    
           By default, information and dialogs from **pmlogger** will be dis‐
           played using pmquery(1) 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, be‐
           cause 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) 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 deter‐
           mined using the _pmRecordHost_ structure, by calling select(2) on
           the _fd_ipc_ field or polling the _status_ field that will contain the
           termination status from waitpid(2) if known, else -1.
    


## DIAGNOSTICS



           **pmRecordSetup** may return **NULL** in the event of an error.  Check _er‐_
           _rno_ for the real cause, but the value **EINVAL** typically means that
           the order of calls to these routines is not correct (there is ob‐
           vious state associated with the current recording session that is
           maintained across calls to these routines).  For example the fol‐
           lowing calls would produce this **EINVAL** error; calling **pmRecordCon‐**
           **trol** before calling **pmRecordAddHost** at least once, or calling **pm‐**
           **RecordAddHost** before calling **pmRecordSetup**.
    
           **pmRecordControl** and **pmRecordAddHost** both return 0 on success, else
           a value less than 0 suitable for decoding with pmErrStr(3) 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).
    
           _XXXXXX_ If _replay_ is non-zero, this is the creator's replay config‐
                  uration file, else an empty control file, used to guarantee
                  uniqueness.
           _folio_  The PCP Archive Folio, suitable for use with pmafm(1).
           _XXXXXX.host._**config**
                  The pmlogger(1) 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) instance for each
                  _host_.
           _XXXXXX.host._{**0** ,**meta** ,**index**}
                  The files comprising a single PCP archive for each _host_.
    


* * *