PMGETOPTIONS(3)
πΈ PMGETOPTIONS(3) β the PMAPI command line glow-up π
Library Functions Manual Β· part of the PCP crew
β¨ NAME β¨
pmgetopt_r, pmGetOptions, pmGetContextOptions, pmFreeOptions, pmUsageMessage β command line handling for PMAPI tools π
π¦ C SYNOPSIS π¦
#include <pcp/pmapi.h>
int pmgetopt_r(int argc, char *const *argv, pmOptions *opts);
int pmGetOptions(int argc, char *const *argv, pmOptions *opts);
int pmGetContextOptions(int ctx, pmOptions *opts);
void pmUsageMessage(pmOptions *opts);
void pmFreeOptions(pmOptions *opts);
cc ... -lpcp
π DESCRIPTION π
okay bestie, sit down, because pmGetOptions is literally the moment. it hands you command line option processing services for both monitor and collector PMAPI(3) tools, like it's not even picky. it's modelled on the thread-safe variants of the GNU getopt_long(3) API, and the main way it differs is that it's obsessed (in the best way) with generalised processing for the de-facto standard PCP command line options described in PCPIntro(1). we're talking host and archive specification, time windows, timezones, sample counts, time intervals, and so on. the whole standard-options starter pack. β¨
the main character here is pmGetOptions, and you should pass it the argc argument count and the argv array exactly as they arrived in your main() function on program invocation. the final opts argument is the one that describes the set of long and short options your tool is prepared to process, plus all the other metadata about how those options should be processed. it's giving "here's the menu, now let's cook". π
the pmgetopt_r interface β which pmGetOptions uses internally β behaves in a similar fashion, but ngl, it does not perform any common option processing. so it's more suited to PCP collector processes, whereas PCP monitor tools tend to reach for pmGetOptions. iykyk. π
the opts argument consists of an array of pmLongOpts entries describing the arguments, plus the enclosing pmOptions struct, and they're defined like this (internal fields are not presented, for brevity):
typedef struct {
const char * long_opt;
int has_arg;
int short_opt;
const char * argname;
const char * message;
} pmLongOptions;
typedef struct {
int version;
int flags;
const char * short_options;
pmLongOptions * long_options;
const char * short_usage;
pmOptionOverride override;
int index;
int optind;
int opterr;
int optopt;
char *optarg;
/* [internal fields, undocumented] */
int errors;
int context; /* PM_CONTEXT_{HOST,ARCHIVE,LOCAL} */
int nhosts;
int narchives;
char ** hosts;
char ** archives;
struct timespec start;
struct timespec finish;
struct timespec origin;
struct timespec interval;
char * align_optarg;
char * start_optarg;
char * finish_optarg;
char * origin_optarg;
char * guiport_optarg;
char * timezone;
int samples;
int guiport;
int padding;
unsigned int guiflag : 1;
unsigned int tzflag : 1;
unsigned int nsflag : 1;
unsigned int Lflag : 1;
unsigned int zeroes : 28;
} pmOptions;
the initial flags and version fields describe how the rest of the pmOptions structure is to be interpreted, okay? these fields can be zeroed, which specifies a default interpretation. alternatively, the PMAPI_VERSION macro can be used to specify the API level to use (currently, values of 3 or less are allowed, so don't get any ideas π). Version 2 is the default, and version 3 introduces high resolution time window and interval fields β that's struct timespec as opposed to struct timeval, for the record. when you're using that latter form, before including <pcp/pmapi.h> the PMAPI_VERSION macro must be set to 3 to ensure the correct layout of the pmOptions structure is used by the application. do not skip that step, i am begging. π the flags field can be used to modify option processing behaviour as described in the FLAGS VALUES section below.
the array of long_options pmLongOpts structures must be terminated by a sentinel, and the PMAPI_OPTIONS_END macro can be used to effect this termination. individual records within the long_options array can be of two types β options headers, or actual options. an options header is constructed using the PMAPI_OPTIONS_HEADER macro, and it's used for usage message option grouping. free form text can be inserted into the usage message at any point using the PMAPI_OPTIONS_TEXT macro β this one is intended for additional explanatory text covering detailed usage that is beyond the scope of the individual headers or options. otherwise, the array entry specifies an option, and those should:
- be named (
long_opt) if a long-option form is allowed, - specify whether or not they take an argument (
has_arg), - specify the single character variant argument (
short_opt) if a short-option form is allowed, - and finally specify how to present the option in the usage message.
that last component consists of a short, one-word description of the optional argument (argname) and a one-line description of what the command-line option does (message). cute and functional, we love to see it. π«Ά
the short_usage string is also used only when constructing the usage message. it forms the component of the usage message that follows the program name (i.e. argv[0]).
the optional short_options string is the normal getopt command-line option specification string, using individual characters β those with arguments are designated as such using the ':' character β as used by all getopt implementations. classic. π
a facility is provided to extend the existing set of common options with additional options, as well as to re-task the standard options into non-standard roles for individual tools. the latter is achieved using the override method, which allows a callback function to be provided that will be called on receipt of every argument, prior to common processing. if this callback returns a non-zero value, the common processing will be short-circuited for that option; otherwise, processing continues. so each client tool is free to choose exactly which of the standard options they wish to support β this can be all, some, or none, and no matter what they choose, each tool always has access to the long option parsing capability and the usage message generation facility. main character energy for every single tool, no cap. π
the remaining pmOptions structure fields are filled in as a result of processing the arguments, and they're largely self-explanatory. further discussion of these is deferred to the FLAGS VALUES section below. the errors field contains a count of errors detected during option processing. these can be either usage or runtime errors, as indicated by the flags field (set, and passed out to the caller). typically, a command line tool will fail to start successfully and will produce an error message (e.g. via pmUsageMessage) if the errors field is non-zero at the end of either pmGetOptions or pmGetContextOptions. so like, check it, bestie. π
some command line option post-processing can only be performed once the tool has established a PMAPI context via pmNewContext(3). this processing includes use of context-aware timezones (-z), and time window processing (-A, -O, -S, -T) that may be affected by the timezone, for example. the pmGetContextOptions function is available for exactly those situations, and it completes any remaining processing of opts with respect to the ctx context identifier given. β¨
the pmUsageMessage function generates a usage message for the tool, and it includes both standard PCP options and custom options for each tool, as specified by the pmLongOptions array. it supports grouping of options (via PMAPI_OPTIONS_HEADER) as well as neat formatting of all options β short and long β their arguments, and individual explanatory messages. it will build this usage message using pmprintf(3), upon which it will issue a single pmflush(3) before returning to the caller, provided the PM_OPTFLAG_USAGE_ERR flag is set in flags β which will happen automatically during option parsing, when usage errors are detected. it's giving "i already knew you'd mess up, and i formatted a whole message about it". π
lowkey important: in certain situations, such as recording lists of host specifications or PCP archive paths, thepmGetOptionsroutine may allocate memory, and store pointers to it withinopts. should a program wish to free this memory before exiting, it can use thepmFreeOptionsroutine to do so. this is safe to call irrespective of whether memory was allocated dynamically, provided thatoptswas zeroed initially. β¨
β¦and that's only part 1, bestie, there's more where that came from π
πΈ FLAGS VALUES πΈ
okay bestie, here's the whole flag fam π each one is a little switch you can flip, and they do very specific things, so let's go one by one:
PM_OPTFLAG_INITβ this one is a library-internal lil thing. It's there to mark that initialisation has already happened, so on the next calls it won't get done all over again. iykyk β¨PM_OPTFLAG_DONEβ mostly an internal flag too, and it means the final option processing is officially wrapped up. That processing? It cross-references a bunch of the options β checking for mutual exclusion, for example. There might be other post-processing happening at this stage too, as long as it doesn't need a PMAPI context. no cap π₯PM_OPTFLAG_MULTIβ this lets you specify more than one host or set of archives. Default vibe is one source of metrics only, but some of the more sophisticated tools allow multiple metric sources, and each one gets handled inside its own separate context. also peepPM_OPTFLAG_MIXEDπPM_OPTFLAG_USAGE_ERRβ tells you the library caught a command-line usage error. we're talking stuff like an option needing an argument but getting none, or conflicting options being specified (like-sand-T, which is giving chaos π).PM_OPTFLAG_RUNTIME_ERRβ the library spotted an error at run time. this is like failing to retrieve timezone info frompmcd(1), or failing to load an alternate metric namespace from a local file (via the-noption). not the vibe πPM_OPTFLAG_EXITβ this is the library gently suggesting your tool should exit cleanly. it gets used when the version number is requested, for example (that's the-Voption and thePMOPT_VERSIONmacro). bye bestie, on purpose π«ΆPM_OPTFLAG_POSIXβ strict POSIX command line argument handling, periodt. that means options and the arguments that follow them will not be reordered, so you can't put additional options after command line arguments. this can matter a lot for tools where the arguments can be negative numbers, for example, because those should not be treated as command line options in that case. important!! βPM_OPTFLAG_MIXEDβ allows both live and archive metric sources to be specified. default is one type of metric context only, but some of the more sophisticated tools permit multiple context types. see alsoPM_OPTFLAG_MULTIπPM_OPTFLAG_ENV_ONLYβ so many options can be specified either through the command line or from similarly-named environment variables. this flag disables all argument parsing, and only changesoptsbased on the environment variables. lowkey useful for tools that want to make sure no command line option conflicts pop up between their own set and the standard PCP option set (think an existing tool, reimplemented using PMAPI services). iconic πPM_OPTFLAG_LONG_ONLYβ only process long options. short options? not invited. π«PM_OPTFLAG_BOUNDARIESβ defaultpmGetOptionsbehaviour is to parse the time window options (that's-A,-O,-Sand-T) only if one of those options was specified on the command line. but this flag lets you (especially with archive contexts) find the start and finish times associated with the context(s) even when no time window options were specified. and with multiple archives? the time window is defined as the time window spanning all of the archives. slay πPM_OPTFLAG_STDOUT_TZβ the timezone being used gets reported on the standard output stream during option parsing. default behaviour is to not report it, and instead just return timezone info via the timezone (-Z) andtzflag(-z) fields in theoptsstructure. β¨PM_OPTFLAG_NOFLUSHβ if this flag is set, the finalpmflushcall issued bypmUsageMessagegets skipped. super handy when the caller wants to append additional test to the generated usage message before flushing. π¦PM_OPTFLAG_QUIETβ suppresses the messages frompmgetopt_rabout unrecognised command line options. this is equivalent to setting theopterrfield in theoptparameter (which mimics thegetoptvariable of the same name). peace and quiet, we love to see it π€« π
π OPTIONS VIA ENVIRONMENT VARIABLES π
okay bestie, plot twist: some of these options can also be set through environment variables instead of typing flags on the command line. π
but listen β this mechanism is primarily for internal use by PCP tools. if you're a regular human, pleeease just use the command line options. fr fr. they show your intent way more clearly, make debugging like a million times easier, and save you from the absolute chaos of a command line option fighting an environment variable (and yeah, when they throw hands, the command line options usually ``win''). π
here's the rundown of every environment variable that can stand in for a command line option, with its short option, long option and what it actually means:
$PCP_ALIGN_TIMEβ short option-A, long option--alignβ align sample times on natural boundaries β¨$PCP_ARCHIVEβ short option-a, long option--archiveβ metrics source is a PCP archive π¦$PCP_ARCHIVE_LISTβ no short option, long option--archive listβ a comma-separated list of metric source archives$PCP_FOLIOβ no short option, long option--archive-folioβ the metric source is amkaf(1)archives folio$PCP_DEBUGβ short option-D, long option--debugβ a comma-separated list ofpmSetDebug(3)debugging options π$PCP_GUIMODEβ short option-g, long option--guimodeβ start in GUI mode with newpmtime(1)time control π₯οΈ$PCP_HOSTβ short option-h, long option--hostβ metrics source ispmcd(1)on a host π$PCP_HOST_LISTβ no short option, long option--host-listβ a comma-separated list of metric source hosts$PCP_SPECLOCALβ short option-K, long option--spec-localβ optional extra local context PMDA DSO information$PCP_LOCALPMDAor$PCP_LOCALMODEβ short option-L, long option--local-PMDAβ metrics source is a local connection to a DSO PMDA π«Ά$PCP_NAMESPACEβ short option-n, long option--namespaceβ use alternative PMNS (Perform-ance Metrics Name Space)$PCP_UNIQNAMESβ short option-N, long option--uniqnamesβ like-nbut only one name allowed for each metric in the PMNS$PCP_ORIGINor$PCP_ORIGIN_TIMEβ short option-O, long option--originβ initial sample time within the time window β°$PCP_GUIPORTβ short option-p, long option--guiportβ port of existingpmtime(1)time control$PCP_START_TIMEβ short option-S, long option--startβ start of the time window$PCP_SAMPLESβ short option-s, long option--samplesβ terminate after this many samples π’$PCP_FINISH_TIMEβ short option-T, long option--finishβ end of the time window$PCP_INTERVALβ short option-t, long option--intervalβ sample interval β±οΈ$PCP_TIMEZONEβ short option-Z, long option--timezoneβ set reporting timezone π$PCP_HOSTZONEβ short option-z, long option--hostzoneβ set reporting timezone to local time of metrics source π°οΈ
π« COMPATIBILITY π«
history lesson time, bestie, don't scroll past this one π«£
back before PCP 7.0 and libpcp.so.4, the start, finish, origin and interval members of the pmOptions struct were struct timevals. wild, right? π
so to support the PMAPI transition, the old interfaces and semantics can still be used if applications are linked with libpcp.so.3 or recompiled with -DPMAPI_VERSION=2. π
β¨ RETURN VALUE β¨
okay bestie, here's the tea on what these functions hand back to you π«Ά
pmGetOptions returns either when it spots a command-line option that is not one of the standard PCP set, or when it hits the end of the command line options β and at that point -1 gets returned. that's it, that's the whole exit strategy.
both pmgetopt_r and pmGetOptions give control back to the caller in exactly the same way a regular getopt call would, with the return value telling you one of three things:
- the end of all processing (
-1) π - the single character form of the option currently being processed
- zero, for the special long-option-only case
and for all the option-processing cases, the opts structure comes back containing filled out optarg, opterr, optopt, optind, and index fields as normal.
β οΈ bestie do NOT use the globaloptargoroptindfrom your platform C library β those will NOT be modified. like, at all. use the struct. i'm begging. π
pmGetOptions does not return to the caller when any of the standard PCP options are being processed (although the override mechanism can be used to still detect such options if needed). so if you're sitting there waiting for a return that never comes... that's why. π
pmGetContextOptions is the chill one β it returns zero on success, or a negative PCP error code on failure. and in that failure case, the error field within the opts parameter will also be non-zero. so like, two places to check, both valid, no cap. β¨
πΈ PCP ENVIRONMENT πΈ
environment variables with the prefix PCP_ are used to parameterize the file and directory names used by PCP. it's giving "everything is configurable, we love a flexible queen" π
on each installation, the file /etc/pcp.conf contains the local values for these variables. so that's where the β¨loreβ¨ lives.
the $PCP_CONF variable may be used to specify an alternative configuration file, as described in pcp.conf(5). yes, you can point it somewhere else, you're the main character, go off π
and values for these variables may be obtained programmatically using the pmGetOptions(3) function. so it's a whole little ecosystem, iykyk. π
π¦ SEE ALSO π¦
go read these next, they're iconic, they're all part of the same friend group fr fr:
PCPIntro(1)pmcd(1)pminfo(1)pmstat(1)getopt(3)getopt_long(3)pmNewContext(3)pmGetConfig(3)pmprintf(3)pmflush(3)PMAPI(3)
and that's the whole page bestie!! π this one is brought to you by Performance Co-Pilot (that's the source) and PCP (that's the version/collection), page PMGETOPTIONS(3). you ate this, genuinely. go write some option-parsing code that actually respects its opts struct. periodt. πβ¨π«Ά
π¦ where this page comes from
- arch rolling: pcp 7.2.2-2 Β· GPL-2.0-or-later AND LGPL-2.1-or-later AND CC-BY-3.0
- fedora 43: pcp-doc 7.2.2-1.fc43
- fedora 43: pcp-doc 7.2.2-2.fc43 Β· GPL-2.0-or-later AND CC-BY-3.0
- fedora 44: pcp-doc 7.2.2-1.fc44
- fedora 44: pcp-doc 7.2.2-2.fc44 Β· GPL-2.0-or-later AND CC-BY-3.0
- Copyright (c) 2014-2016 Red Hat
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms