summaryrefslogtreecommitdiff
path: root/src/include/pcp/pmapi.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/pcp/pmapi.h')
-rw-r--r--src/include/pcp/pmapi.h884
1 files changed, 884 insertions, 0 deletions
diff --git a/src/include/pcp/pmapi.h b/src/include/pcp/pmapi.h
new file mode 100644
index 0000000..be4b45e
--- /dev/null
+++ b/src/include/pcp/pmapi.h
@@ -0,0 +1,884 @@
+/*
+ * Copyright (c) 2012-2014 Red Hat.
+ * Copyright (c) 1997,2004 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _PMAPI_H
+#define _PMAPI_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+
+/*
+ * Platform and environment customization
+ */
+#include "platform_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PMAPI_VERSION_2 2
+#define PMAPI_VERSION PMAPI_VERSION_2
+
+/*
+ * -------- Naming Services --------
+ */
+typedef unsigned int pmID; /* Metric Identifier */
+#define PM_ID_NULL 0xffffffff
+
+typedef unsigned int pmInDom; /* Instance-Domain */
+#define PM_INDOM_NULL 0xffffffff
+#define PM_IN_NULL 0xffffffff
+
+#define PM_NS_DEFAULT NULL /* default name */
+
+/*
+ * Encoding for the units (dimensions Time and Space) and scale
+ * for Performance Metric Values
+ *
+ * For example, a pmUnits struct of
+ * { 1, -1, 0, PM_SPACE_MBYTE, PM_TIME_SEC, 0 }
+ * represents Mbytes/sec, while
+ * { 0, 1, -1, 0, PM_TIME_HOUR, 6 }
+ * represents hours/million-events
+ */
+typedef struct {
+#ifdef HAVE_BITFIELDS_LTOR
+ signed int dimSpace : 4; /* space dimension */
+ signed int dimTime : 4; /* time dimension */
+ signed int dimCount : 4; /* event dimension */
+ unsigned int scaleSpace : 4; /* one of PM_SPACE_* below */
+ unsigned int scaleTime : 4; /* one of PM_TIME_* below */
+ signed int scaleCount : 4; /* one of PM_COUNT_* below */
+ unsigned int pad : 8;
+#else
+ unsigned int pad : 8;
+ signed int scaleCount : 4; /* one of PM_COUNT_* below */
+ unsigned int scaleTime : 4; /* one of PM_TIME_* below */
+ unsigned int scaleSpace : 4; /* one of PM_SPACE_* below */
+ signed int dimCount : 4; /* event dimension */
+ signed int dimTime : 4; /* time dimension */
+ signed int dimSpace : 4; /* space dimension */
+#endif
+} pmUnits; /* dimensional units and scale of value */
+
+/* pmUnits.scaleSpace */
+#define PM_SPACE_BYTE 0 /* bytes */
+#define PM_SPACE_KBYTE 1 /* Kilobytes (1024) */
+#define PM_SPACE_MBYTE 2 /* Megabytes (1024^2) */
+#define PM_SPACE_GBYTE 3 /* Gigabytes (1024^3) */
+#define PM_SPACE_TBYTE 4 /* Terabytes (1024^4) */
+#define PM_SPACE_PBYTE 5 /* Petabytes (1024^5) */
+#define PM_SPACE_EBYTE 6 /* Exabytes (1024^6) */
+/* pmUnits.scaleTime */
+#define PM_TIME_NSEC 0 /* nanoseconds */
+#define PM_TIME_USEC 1 /* microseconds */
+#define PM_TIME_MSEC 2 /* milliseconds */
+#define PM_TIME_SEC 3 /* seconds */
+#define PM_TIME_MIN 4 /* minutes */
+#define PM_TIME_HOUR 5 /* hours */
+/*
+ * pmUnits.scaleCount (e.g. count events, syscalls, interrupts, etc.)
+ * -- these are simply powers of 10, and not enumerated here,
+ * e.g. 6 for 10^6, or -3 for 10^-3
+ */
+#define PM_COUNT_ONE 0 /* 1 */
+
+/* Performance Metric Descriptor */
+typedef struct {
+ pmID pmid; /* unique identifier */
+ int type; /* base data type (see below) */
+ pmInDom indom; /* instance domain */
+ int sem; /* semantics of value (see below) */
+ pmUnits units; /* dimension and units */
+} pmDesc;
+
+/* pmDesc.type -- data type of metric values */
+#define PM_TYPE_NOSUPPORT -1 /* not implemented in this version */
+#define PM_TYPE_32 0 /* 32-bit signed integer */
+#define PM_TYPE_U32 1 /* 32-bit unsigned integer */
+#define PM_TYPE_64 2 /* 64-bit signed integer */
+#define PM_TYPE_U64 3 /* 64-bit unsigned integer */
+#define PM_TYPE_FLOAT 4 /* 32-bit floating point */
+#define PM_TYPE_DOUBLE 5 /* 64-bit floating point */
+#define PM_TYPE_STRING 6 /* array of char */
+#define PM_TYPE_AGGREGATE 7 /* arbitrary binary data (aggregate) */
+#define PM_TYPE_AGGREGATE_STATIC 8 /* static pointer to aggregate */
+#define PM_TYPE_EVENT 9 /* packed pmEventArray */
+#define PM_TYPE_HIGHRES_EVENT 10 /* packed pmHighResEventArray */
+#define PM_TYPE_UNKNOWN 255 /* used in pmValueBlock, not pmDesc */
+
+/* pmDesc.sem -- semantics/interpretation of metric values */
+#define PM_SEM_COUNTER 1 /* cumulative counter (monotonic increasing) */
+ /* was PM_SEM_RATE, no longer used now */
+#define PM_SEM_INSTANT 3 /* instantaneous value, continuous domain */
+#define PM_SEM_DISCRETE 4 /* instantaneous value, discrete domain */
+
+#define PM_ERR_BASE2 12345
+#define PM_ERR_BASE PM_ERR_BASE2
+
+/* PMAPI Error Conditions */
+
+#define PM_ERR_GENERIC (-PM_ERR_BASE-0) /* Generic error, already reported above */
+#define PM_ERR_PMNS (-PM_ERR_BASE-1) /* Problems parsing PMNS definitions */
+#define PM_ERR_NOPMNS (-PM_ERR_BASE-2) /* PMNS not accessible */
+#define PM_ERR_DUPPMNS (-PM_ERR_BASE-3) /* Attempt to reload the PMNS */
+#define PM_ERR_TEXT (-PM_ERR_BASE-4) /* Oneline or help text is not available */
+#define PM_ERR_APPVERSION (-PM_ERR_BASE-5) /* Metric not supported by this version of monitored application */
+#define PM_ERR_VALUE (-PM_ERR_BASE-6) /* Missing metric value(s) */
+/* retired PM_ERR_LICENSE (-PM_ERR_BASE-7) Current PCP license does not permit this operation */
+#define PM_ERR_TIMEOUT (-PM_ERR_BASE-8) /* Timeout waiting for a response from PMCD */
+#define PM_ERR_NODATA (-PM_ERR_BASE-9) /* Empty archive log file */
+#define PM_ERR_RESET (-PM_ERR_BASE-10) /* pmcd reset or configuration changed */
+/* retired PM_ERR_FILE (-PM_ERR_BASE-11) Cannot locate a file */
+#define PM_ERR_NAME (-PM_ERR_BASE-12) /* Unknown metric name */
+#define PM_ERR_PMID (-PM_ERR_BASE-13) /* Unknown or illegal metric identifier */
+#define PM_ERR_INDOM (-PM_ERR_BASE-14) /* Unknown or illegal instance domain identifier */
+#define PM_ERR_INST (-PM_ERR_BASE-15) /* Unknown or illegal instance identifier */
+#define PM_ERR_UNIT (-PM_ERR_BASE-16) /* Illegal pmUnits specification */
+#define PM_ERR_CONV (-PM_ERR_BASE-17) /* Impossible value or scale conversion */
+#define PM_ERR_TRUNC (-PM_ERR_BASE-18) /* Truncation in value conversion */
+#define PM_ERR_SIGN (-PM_ERR_BASE-19) /* Negative value in conversion to unsigned */
+#define PM_ERR_PROFILE (-PM_ERR_BASE-20) /* Explicit instance identifier(s) required */
+#define PM_ERR_IPC (-PM_ERR_BASE-21) /* IPC protocol failure */
+/* retired PM_ERR_NOASCII (-PM_ERR_BASE-22) ASCII format not supported for this PDU */
+#define PM_ERR_EOF (-PM_ERR_BASE-23) /* IPC channel closed */
+#define PM_ERR_NOTHOST (-PM_ERR_BASE-24) /* Operation requires context with host source of metrics */
+#define PM_ERR_EOL (-PM_ERR_BASE-25) /* End of PCP archive log */
+#define PM_ERR_MODE (-PM_ERR_BASE-26) /* Illegal mode specification */
+#define PM_ERR_LABEL (-PM_ERR_BASE-27) /* Illegal label record at start of a PCP archive log file */
+#define PM_ERR_LOGREC (-PM_ERR_BASE-28) /* Corrupted record in a PCP archive log */
+#define PM_ERR_NOTARCHIVE (-PM_ERR_BASE-29) /* Operation requires context with archive source of metrics */
+#define PM_ERR_LOGFILE (-PM_ERR_BASE-30) /* Missing archive file */
+#define PM_ERR_NOCONTEXT (-PM_ERR_BASE-31) /* Attempt to use an illegal context */
+#define PM_ERR_PROFILESPEC (-PM_ERR_BASE-32) /* NULL pmInDom with non-NULL instlist */
+#define PM_ERR_PMID_LOG (-PM_ERR_BASE-33) /* Metric not defined in the PCP archive log */
+#define PM_ERR_INDOM_LOG (-PM_ERR_BASE-34) /* Instance domain identifier not defined in the PCP archive log */
+#define PM_ERR_INST_LOG (-PM_ERR_BASE-35) /* Instance identifier not defined in the PCP archive log */
+#define PM_ERR_NOPROFILE (-PM_ERR_BASE-36) /* Missing profile - protocol botch */
+#define PM_ERR_NOAGENT (-PM_ERR_BASE-41) /* No pmcd agent for domain of request */
+#define PM_ERR_PERMISSION (-PM_ERR_BASE-42) /* No permission to perform requested operation */
+#define PM_ERR_CONNLIMIT (-PM_ERR_BASE-43) /* PMCD connection limit for this host exceeded */
+#define PM_ERR_AGAIN (-PM_ERR_BASE-44) /* try again. Info not currently available */
+#define PM_ERR_ISCONN (-PM_ERR_BASE-45) /* already connected */
+#define PM_ERR_NOTCONN (-PM_ERR_BASE-46) /* not connected */
+#define PM_ERR_NEEDPORT (-PM_ERR_BASE-47) /* port name required */
+/* retired PM_ERR_WANTACK (-PM_ERR_BASE-48) can not send due to pending acks */
+#define PM_ERR_NONLEAF (-PM_ERR_BASE-49) /* PMNS node is not a leaf node */
+/* retired PM_ERR_OBJSTYLE (-PM_ERR_BASE-50) user/kernel object style mismatch */
+/* retired PM_ERR_PMCDLICENSE (-PM_ERR_BASE-51) PMCD is not licensed to accept connections */
+#define PM_ERR_TYPE (-PM_ERR_BASE-52) /* Unknown or illegal metric type */
+#define PM_ERR_THREAD (-PM_ERR_BASE-53) /* Operation not supported for multi-threaded applications */
+
+/* retired PM_ERR_CTXBUSY (-PM_ERR_BASE-97) Context is busy */
+#define PM_ERR_TOOSMALL (-PM_ERR_BASE-98) /* Insufficient elements in list */
+#define PM_ERR_TOOBIG (-PM_ERR_BASE-99) /* Result size exceeded */
+#define PM_ERR_FAULT (-PM_ERR_BASE-100) /* QA fault injected */
+
+#define PM_ERR_PMDAREADY (-PM_ERR_BASE-1048) /* now ready to respond */
+#define PM_ERR_PMDANOTREADY (-PM_ERR_BASE-1049) /* not yet ready to respond */
+#define PM_ERR_NYI (-PM_ERR_BASE-8999) /* Functionality not yet implemented [end-of-range mark] */
+
+/*
+ * Report PMAPI errors messages
+ */
+extern char *pmErrStr(int); /* NOT thread-safe */
+extern char *pmErrStr_r(int, char *, int);
+/* safe size for a pmErrStr_r buffer to accommodate all error messages */
+#define PM_MAXERRMSGLEN 128
+
+/*
+ * Load a Performance Metrics Name Space
+ */
+extern int pmLoadNameSpace(const char *);
+extern int pmLoadASCIINameSpace(const char *, int);
+extern void pmUnloadNameSpace(void);
+
+/*
+ * Where is PMNS located - added for distributed PMNS.
+ */
+extern int pmGetPMNSLocation(void);
+#define PMNS_LOCAL 1
+#define PMNS_REMOTE 2
+#define PMNS_ARCHIVE 3
+
+/*
+ * Trim a name space with respect to the current context
+ * (usually from an archive, or after processing an archive)
+ */
+extern int pmTrimNameSpace(void);
+
+/*
+ * Expand a list of names to a list of metrics ids
+ */
+extern int pmLookupName(int, char **, pmID *);
+
+/*
+ * Find the names of descendent nodes in the PMNS
+ * and in the latter case get the status of each child.
+ */
+extern int pmGetChildren(const char *, char ***);
+extern int pmGetChildrenStatus(const char *, char ***, int **);
+#define PMNS_LEAF_STATUS 0 /* leaf node in PMNS tree */
+#define PMNS_NONLEAF_STATUS 1 /* non-terminal node in PMNS tree */
+
+/*
+ * Reverse Lookup: find name(s) given a metric id
+ */
+extern int pmNameID(pmID, char **); /* one */
+extern int pmNameAll(pmID, char ***); /* all */
+
+/*
+ * Handy recursive descent of the PMNS
+ */
+extern int pmTraversePMNS(const char *, void(*)(const char *));
+extern int pmTraversePMNS_r(const char *, void(*)(const char *, void *), void *);
+
+/*
+ * Given a metric, find it's descriptor (caller supplies buffer for desc),
+ * from the current context.
+ */
+extern int pmLookupDesc(pmID, pmDesc *);
+
+/*
+ * Return the internal instance identifier, from the current context,
+ * given an instance domain and the external instance name.
+ * Archive variant scans the union of the indom entries in the archive
+ * log.
+ */
+extern int pmLookupInDom(pmInDom, const char *);
+extern int pmLookupInDomArchive(pmInDom, const char *);
+
+/*
+ * Return the external instance name, from the current context,
+ * given an instance domain and the internal instance identifier.
+ * Archive variant scans the union of the indom entries in the archive
+ * log.
+ */
+extern int pmNameInDom(pmInDom, int, char **);
+extern int pmNameInDomArchive(pmInDom, int, char **);
+
+/*
+ * Return all of the internal instance identifiers (instlist) and external
+ * instance names (namelist) for the given instance domain in the current
+ * context.
+ * Archive variant returns the union of the indom entries in the archive
+ * log.
+ */
+extern int pmGetInDom(pmInDom, int **, char ***);
+extern int pmGetInDomArchive(pmInDom, int **, char ***);
+
+/*
+ * Given context ID, return the host name associated with that context,
+ * or the empty string if no name can be found
+ */
+extern const char *pmGetContextHostName(int);
+extern char *pmGetContextHostName_r(int, char *, int);
+
+/*
+ * Return the handle of the current context
+ */
+extern int pmWhichContext(void);
+
+/*
+ * Destroy a context and close its connection
+ */
+extern int pmDestroyContext(int);
+
+/*
+ * Establish a new context (source of performance data + instance profile)
+ * for the named host
+ */
+extern int pmNewContext(int, const char *);
+#define PM_CONTEXT_UNDEF -1 /* current context is undefined */
+#define PM_CONTEXT_HOST 1 /* host via pmcd */
+#define PM_CONTEXT_ARCHIVE 2 /* PCP archive */
+#define PM_CONTEXT_LOCAL 3 /* local host, no pmcd connection */
+#define PM_CONTEXT_TYPEMASK 0xff /* mask to separate types / flags */
+/* #define PM_CTXFLAG_SHALLOW (1U<<8) -- don't actually connect to host */
+/* #define PM_CTXFLAG_EXCLUSIVE (1U<<9) -- don't share socket among ctxts */
+#define PM_CTXFLAG_SECURE (1U<<10)/* encrypted socket comms channel */
+#define PM_CTXFLAG_COMPRESS (1U<<11)/* compressed socket host channel */
+#define PM_CTXFLAG_RELAXED (1U<<12)/* encrypted if possible else not */
+#define PM_CTXFLAG_AUTH (1U<<13)/* make authenticated connection */
+
+/*
+ * Duplicate current context -- returns handle to new one for pmUseContext()
+ */
+extern int pmDupContext(void);
+
+/*
+ * Restore (previously established or duplicated) context
+ */
+extern int pmUseContext(int);
+
+/*
+ * Reconnect an existing context (when pmcd dies, etc). All existing context
+ * settings are preserved and the previous context settings are restored.
+ */
+extern int pmReconnectContext(int);
+
+/*
+ * Add to instance profile.
+ * If pmInDom == PM_INDOM_NULL, then all instance domains are selected.
+ * If no inst parameters are given, then all instances are selected.
+ * e.g. to select all available instances in all domains,
+ * then use pmAddProfile(PM_INDOM_NULL, 0, NULL).
+ */
+extern int pmAddProfile(pmInDom, int, int *);
+
+/*
+ * Delete from instance profile.
+ * Similar (but negated) functional semantics to pmProfileAdd.
+ * E.g. to disable all instances in all domains then use
+ * pmDelProfile(PM_INDOM_NULL, 0, NULL).
+ */
+extern int pmDelProfile(pmInDom, int, int *);
+
+/*
+ * ---------- Collection services ----------
+ *
+ * Result from pmFetch is encoded as a timestamp and vector of pointers
+ * to pmValueSet instances (one per PMID in the result).
+ * Each pmValueSet has a PMID, a value count, a value format, and a vector of
+ * instance-value pairs. Aggregate, string and non-int values are returned
+ * via one further level of indirection using pmValueBlocks.
+ *
+ * timeStamp
+ * ->pmID
+ * value format
+ * instance, value
+ * instance, value
+ * ... etc
+ *
+ * ->pmID
+ * value format
+ * instance, value
+ * ... etc
+ *
+ *
+ * Notes on pmValueBlock
+ * 0. may be used for arbitrary binary data
+ * 1. only ever allocated dynamically, and vbuf expands to accommodate
+ * an arbitrary value (don't believe the [1] size!)
+ * 2. len is the length of the len field + the real size of vbuf
+ * (which includes the null-byte terminator if there is one)
+ */
+typedef struct {
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int vtype : 8; /* value type */
+ unsigned int vlen : 24; /* bytes for vtype/vlen + vbuf */
+#else
+ unsigned int vlen : 24; /* bytes for vtype/vlen + vbuf */
+ unsigned int vtype : 8; /* value type */
+#endif
+ char vbuf[1]; /* the value */
+} pmValueBlock;
+
+#define PM_VAL_HDR_SIZE 4 /* bytes for the vtype/vlen header */
+#define PM_VAL_VLEN_MAX 0x00ffffff /* maximum vbuf[] size */
+
+typedef struct {
+ int inst; /* instance identifier */
+ union {
+ pmValueBlock *pval; /* pointer to value-block */
+ int lval; /* integer value insitu (lval 'cuz it WAS a long) */
+ } value;
+} pmValue;
+
+typedef struct {
+ pmID pmid; /* metric identifier */
+ int numval; /* number of values */
+ int valfmt; /* value style */
+ pmValue vlist[1]; /* set of instances/values */
+} pmValueSet;
+
+/* values for valfmt */
+#define PM_VAL_INSITU 0 /* value.lval is it */
+#define PM_VAL_DPTR 1 /* value.pval->vbuf is it, and dynamic alloc */
+#define PM_VAL_SPTR 2 /* value.pval->vbuf is it, and static alloc */
+
+
+/* Result returned by pmFetch() */
+typedef struct {
+ struct timeval timestamp; /* time stamped by collector */
+ int numpmid; /* number of PMIDs */
+ pmValueSet *vset[1]; /* set of value sets, one per PMID */
+} pmResult;
+
+/* High resolution event timer result from pmUnpackHighResEventRecords() */
+typedef struct {
+ struct timespec timestamp; /* time stamped by collector */
+ int numpmid; /* number of PMIDs */
+ pmValueSet *vset[1]; /* set of value sets, one per PMID */
+} pmHighResResult;
+
+/* Generic Union for Value-Type conversions */
+typedef union {
+ __int32_t l; /* 32-bit signed */
+ __uint32_t ul; /* 32-bit unsigned */
+ __int64_t ll; /* 64-bit signed */
+ __uint64_t ull; /* 64-bit unsigned */
+ float f; /* 32-bit floating point */
+ double d; /* 64-bit floating point */
+ char *cp; /* char ptr */
+ pmValueBlock *vbp; /* pmValueBlock ptr */
+} pmAtomValue;
+
+/*
+ * Fetch metrics. Value/instances returned depends on current instance profile.
+ * By default, all available instances for each requested metric id are
+ * returned. The metrics argument is terminated with PM_NULL_ID
+ *
+ * The value sets returned are in the same order as the metrics argument,
+ * and the number of value sets returned is guaranteed to be the same as
+ * the number of metrics in the agument.
+ */
+extern int pmFetch(int, pmID *, pmResult **);
+
+/*
+ * PMCD state changes returned as pmFetch function result for PM_CONTEXT_HOST
+ * contexts, i.e. when communicating with PMCD
+ */
+#define PMCD_NO_CHANGE 0
+#define PMCD_ADD_AGENT 1
+#define PMCD_RESTART_AGENT 2
+#define PMCD_DROP_AGENT 4
+
+/*
+ * Variant that is used to return a pmResult from an archive
+ */
+extern int pmFetchArchive(pmResult **);
+
+/*
+ * struct timeval is sometimes 2 x 64-bit ... we use a 2 x 32-bit format for
+ * PDUs, internally within libpcp and for (external) archive logs
+ */
+typedef struct {
+ __int32_t tv_sec; /* seconds since Jan. 1, 1970 */
+ __int32_t tv_usec; /* and microseconds */
+} __pmTimeval;
+
+typedef struct {
+ __int64_t tv_sec; /* seconds since Jan. 1, 1970 */
+ __int64_t tv_nsec; /* and nanoseconds */
+} __pmTimespec;
+
+/*
+ * Label Record at the start of every log file - as exported above
+ * the PMAPI ...
+ * NOTE MAXHOSTNAMELEN is a bad choice here for ll_hostname[], as
+ * it may vary on different hosts ... we use PM_LOG_MAXHOSTLEN instead, and
+ * size this to be the same as MAXHOSTNAMELEN in IRIX 5.3
+ * NOTE that the struct timeval means we have another struct (__pmLogLabel)
+ * for internal use that has a __pmTimeval in place of the struct timeval.
+ */
+#define PM_TZ_MAXLEN 40
+#define PM_LOG_MAXHOSTLEN 64
+#define PM_LOG_MAGIC 0x50052600
+#define PM_LOG_VERS02 0x2
+#define PM_LOG_VOL_TI -2 /* temporal index */
+#define PM_LOG_VOL_META -1 /* meta data */
+typedef struct {
+ int ll_magic; /* PM_LOG_MAGIC | log format version no. */
+ pid_t ll_pid; /* PID of logger */
+ struct timeval ll_start; /* start of this log */
+ char ll_hostname[PM_LOG_MAXHOSTLEN]; /* name of collection host */
+ char ll_tz[PM_TZ_MAXLEN]; /* $TZ at collection host */
+} pmLogLabel;
+
+/*
+ * Get the label record from the current archive context, and discover
+ * when the archive ends
+ */
+extern int pmGetArchiveLabel(pmLogLabel *);
+extern int pmGetArchiveEnd(struct timeval *);
+
+/* Free result buffer */
+extern void pmFreeResult(pmResult *);
+extern void pmFreeHighResResult(pmHighResResult *);
+
+/* Value extract from pmValue and type conversion */
+extern int pmExtractValue(int, const pmValue *, int, pmAtomValue *, int);
+
+/* Print single pmValue */
+extern void pmPrintValue(FILE *, int, int, const pmValue *, int);
+
+/* Scale conversion, based on value format, value type and scale */
+extern int pmConvScale(int, const pmAtomValue *, const pmUnits *, pmAtomValue *,
+ const pmUnits *);
+
+/* Sort instances for each metric within a pmResult */
+extern void pmSortInstances(pmResult *);
+
+/* Adjust collection time and/or mode for pmFetch */
+extern int pmSetMode(int, const struct timeval *, int);
+#define PM_MODE_LIVE 0
+#define PM_MODE_INTERP 1
+#define PM_MODE_FORW 2
+#define PM_MODE_BACK 3
+
+/* Modify the value of one or more metrics */
+extern int pmStore(const pmResult *);
+
+/* Get help and descriptive text */
+extern int pmLookupText(pmID, int, char **);
+extern int pmLookupInDomText(pmInDom, int, char **);
+#define PM_TEXT_ONELINE 1
+#define PM_TEXT_HELP 2
+
+/*
+ * Some handy formatting routines for messages, and other output
+ */
+extern const char *pmIDStr(pmID); /* NOT thread-safe */
+extern char *pmIDStr_r(pmID, char *, int);
+extern const char *pmInDomStr(pmInDom); /* NOT thread-safe */
+extern char *pmInDomStr_r(pmInDom, char *, int);
+extern const char *pmTypeStr(int); /* NOT thread-safe */
+extern char *pmTypeStr_r(int, char *, int);
+extern const char *pmUnitsStr(const pmUnits *); /* NOT thread-safe */
+extern char *pmUnitsStr_r(const pmUnits *, char *, int);
+extern const char *pmAtomStr(const pmAtomValue *, int); /* NOT thread-safe */
+extern char *pmAtomStr_r(const pmAtomValue *, int, char *, int);
+extern const char *pmNumberStr(double); /* NOT thread-safe */
+extern char *pmNumberStr_r(double, char *, int);
+extern const char *pmEventFlagsStr(int); /* NOT thread-safe */
+extern char *pmEventFlagsStr_r(int, char *, int);
+
+/* Extended time base definitions and macros */
+#define PM_XTB_FLAG 0x1000000
+
+#define PM_XTB_SET(type) (PM_XTB_FLAG | ((type) << 16))
+#define PM_XTB_GET(x) (((x) & PM_XTB_FLAG) ? (((x) & 0xff0000) >> 16) : -1)
+
+/* Parse -t, -S, -T, -A and -O options */
+extern int pmParseInterval(const char *, struct timeval *, char **);
+extern int pmParseTimeWindow(
+ const char *, const char *, const char *, const char *,
+ const struct timeval *, const struct timeval *,
+ struct timeval *, struct timeval *, struct timeval *, char **);
+
+/* Reporting timezone */
+extern int pmUseZone(const int);
+extern int pmNewZone(const char *);
+extern int pmNewContextZone(void);
+extern int pmWhichZone(char **);
+extern char *pmCtime(const time_t *, char *);
+extern struct tm *pmLocaltime(const time_t *, struct tm *);
+
+/* Parse host:metric[instances] or archive/metric[instances] */
+typedef struct {
+ int isarch; /* source type: 0 -> live host, 1 -> archive, 2 -> local context */
+ char *source; /* name of source host or archive */
+ char *metric; /* name of metric */
+ int ninst; /* number of instances, 0 -> all */
+ char *inst[1]; /* array of instance names */
+} pmMetricSpec;
+
+/* Parsing of host:metric[instances] or archive/metric[instances] */
+extern int pmParseMetricSpec(const char *, int, char *, pmMetricSpec **,
+ char **);
+extern void pmFreeMetricSpec(pmMetricSpec *p);
+
+/*
+ * Configurable error reporting
+ */
+#ifdef __GNUC__
+# define __PM_PRINTFLIKE(idx,cnt) __attribute__ ((format (printf, idx,cnt)))
+#else
+# define __PM_PRINTFLIKE(idx,cnt)
+#endif
+
+extern int pmprintf(const char *, ...) __PM_PRINTFLIKE(1,2);
+extern int pmflush(void);
+
+/*
+ * Wrapper for config/environment variables. Warning: this will exit() with
+ * a FATAL error if /etc/pcp.conf does not exist and $PCP_CONF is not set.
+ * Return values point to strings in the environment.
+ */
+extern char *pmGetConfig(const char *);
+
+/*
+ * Common command line argument parsing interfaces
+ */
+
+#define PMAPI_OPTIONS "A:a:D:gh:n:O:p:S:s:T:t:VZ:z?"
+#define PMAPI_OPTIONS_HEADER(s) { "", 0, '-', 0, (s) }
+#define PMAPI_OPTIONS_TEXT(s) { "", 0, '|', 0, (s) }
+#define PMAPI_OPTIONS_END { NULL, 0, 0, 0, NULL }
+
+#define PMOPT_ALIGN { "align", 1, 'A', "TIME", \
+ "align sample times on natural boundaries" }
+#define PMOPT_ARCHIVE { "archive", 1, 'a', "FILE", \
+ "metrics source is a PCP log archive" }
+#define PMOPT_DEBUG { "debug", 1, 'D', "DBG", \
+ NULL }
+#define PMOPT_GUIMODE { "guimode", 0, 'g', 0, \
+ "start in GUI mode with new time control" }
+#define PMOPT_HOST { "host", 1, 'h', "HOST", \
+ "metrics source is PMCD on host" }
+#define PMOPT_HOSTSFILE { "hostsfile", 1, 'H', "FILE", \
+ "read metric source hosts from a file" }
+#define PMOPT_SPECLOCAL { "spec-local", 1, 'K', "SPEC", \
+ "optional additional PMDA spec for local connection" }
+#define PMOPT_LOCALPMDA { "local-PMDA", 0, 'L', 0, \
+ "metrics source is local connection to a PMDA" }
+#define PMOPT_NAMESPACE { "namespace", 1, 'n', "FILE", \
+ "use an alternative PMNS" }
+#define PMOPT_DUPNAMES { "dupnames", 1, 'N', "FILE", \
+ "use an alternative PMNS (duplicate names allowed)" }
+#define PMOPT_ORIGIN { "origin", 1, 'O', "TIME", \
+ "initial sample time within the time window" }
+#define PMOPT_GUIPORT { "guiport", 1, 'p', "N", \
+ "port for connection to existing time control" }
+#define PMOPT_START { "start", 1, 'S', "TIME", \
+ "start of the time window" }
+#define PMOPT_SAMPLES { "samples", 1, 's', "N", \
+ "terminate after this many samples" }
+#define PMOPT_FINISH { "finish", 1, 'T', "TIME", \
+ "end of the time window" }
+#define PMOPT_INTERVAL { "interval", 1, 't', "DELTA", \
+ "sampling interval" }
+#define PMOPT_VERSION { "version", 0, 'V', 0, \
+ "display version number and exit" }
+#define PMOPT_TIMEZONE { "timezone", 1, 'Z', "TZ", \
+ "set reporting timezone" }
+#define PMOPT_HOSTZONE { "hostzone", 0, 'z', 0, \
+ "set reporting timezone to local time of metrics source" }
+#define PMOPT_HELP { "help", 0, '?', 0, \
+ "show this usage message and exit" }
+
+#define PMAPI_GENERAL_OPTIONS \
+ PMAPI_OPTIONS_HEADER("General options"), \
+ PMOPT_ALIGN, \
+ PMOPT_ARCHIVE, \
+ PMOPT_DEBUG, \
+ PMOPT_GUIMODE, \
+ PMOPT_HOST, \
+ PMOPT_NAMESPACE, \
+ PMOPT_ORIGIN, \
+ PMOPT_GUIPORT, \
+ PMOPT_START, \
+ PMOPT_SAMPLES, \
+ PMOPT_FINISH, \
+ PMOPT_INTERVAL, \
+ PMOPT_TIMEZONE, \
+ PMOPT_HOSTZONE, \
+ PMOPT_VERSION, \
+ PMOPT_HELP
+
+/* long-only standard options */
+#define PMLONGOPT_ARCHIVE_LIST "archive-list"
+#define PMOPT_ARCHIVE_LIST { PMLONGOPT_ARCHIVE_LIST, 1, 0, "FILES", \
+ "comma-separated list of metric source archives" }
+#define PMLONGOPT_ARCHIVE_FOLIO "archive-folio"
+#define PMOPT_ARCHIVE_FOLIO { PMLONGOPT_ARCHIVE_FOLIO, 1, 0, "FILE", \
+ "read metric source archives from a folio" }
+#define PMLONGOPT_HOST_LIST "host-list"
+#define PMOPT_HOST_LIST { PMLONGOPT_HOST_LIST, 1, 0, "HOSTS", \
+ "comma-separated list of metric source hosts" }
+
+/* pmOptions flags */
+#define PM_OPTFLAG_INIT (1<<0) /* initialisation done */
+#define PM_OPTFLAG_DONE (1<<1) /* parsing is complete */
+#define PM_OPTFLAG_MULTI (1<<2) /* allow multi-context */
+#define PM_OPTFLAG_USAGE_ERR (1<<3) /* argument parse fail */
+#define PM_OPTFLAG_RUNTIME_ERR (1<<4) /* any runtime failure */
+#define PM_OPTFLAG_EXIT (1<<5) /* tool should exit(0) */
+#define PM_OPTFLAG_POSIX (1<<6) /* POSIXLY_CORRECT set */
+#define PM_OPTFLAG_MIXED (1<<7) /* allow hosts+archives */
+#define PM_OPTFLAG_ENV_ONLY (1<<8) /* use env options only */
+#define PM_OPTFLAG_LONG_ONLY (1<<9) /* use long options only */
+#define PM_OPTFLAG_BOUNDARIES (1<<10) /* calculate time window */
+#define PM_OPTFLAG_STDOUT_TZ (1<<11) /* write timezone change */
+#define PM_OPTFLAG_NOFLUSH (1<<12) /* caller issues pmflush */
+#define PM_OPTFLAG_QUIET (1<<13) /* silence getopt errors */
+
+struct __pmOptions;
+typedef int (*pmOptionOverride)(int, struct __pmOptions *);
+
+typedef struct {
+ const char * long_opt;
+ int has_arg;
+ int short_opt;
+ const char * argname;
+ const char * message;
+} pmLongOptions;
+
+typedef struct __pmOptions {
+ int version;
+ int flags;
+
+ /* in: define set of all options */
+ const char * short_options;
+ pmLongOptions * long_options;
+ const char * short_usage;
+
+ /* in: method for general override */
+ pmOptionOverride override;
+
+ /* out: usual getopt information */
+ int index;
+ int optind;
+ int opterr;
+ int optopt;
+ char *optarg;
+
+ /* internals; do not ever access */
+ int __initialized;
+ char * __nextchar;
+ int __ordering;
+ int __posixly_correct;
+ int __first_nonopt;
+ int __last_nonopt;
+
+ /* out: error count */
+ int errors;
+
+ /* out: PMAPI options and values */
+ int context; /* PM_CONTEXT_{HOST,ARCHIVE,LOCAL} */
+ int nhosts;
+ int narchives;
+ char ** hosts;
+ char ** archives;
+ struct timeval start;
+ struct timeval finish;
+ struct timeval origin;
+ struct timeval 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;
+
+extern int pmgetopt_r(int, char *const *, pmOptions *);
+extern int pmGetOptions(int, char *const *, pmOptions *);
+extern int pmGetContextOptions(int, pmOptions *);
+extern void pmUsageMessage(pmOptions *);
+extern void pmFreeOptions(pmOptions *);
+
+/*
+ * Derived Metrics support
+ */
+extern int pmLoadDerivedConfig(const char *);
+extern char *pmRegisterDerived(const char *, const char *);
+extern char *pmDerivedErrStr(void);
+
+/*
+ * Event Record support
+ */
+typedef struct {
+ pmID ep_pmid;
+ /* vtype and vlen fields the format same as for pmValueBlock */
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int ep_type : 8; /* value type */
+ unsigned int ep_len : 24; /* bytes for type/len + vbuf */
+#else
+ unsigned int ep_len : 24; /* bytes for type/len + vbuf */
+ unsigned int ep_type : 8; /* value type */
+#endif
+ /* actual value (vbuf) goes here ... */
+} pmEventParameter;
+
+typedef struct {
+ __pmTimeval er_timestamp; /* must be 2 x 32-bit format */
+ unsigned int er_flags; /* event record characteristics */
+ int er_nparams; /* number of er_param[] entries */
+ pmEventParameter er_param[1];
+} pmEventRecord;
+
+typedef struct {
+ __pmTimespec er_timestamp; /* must be 2 x 64-bit format */
+ unsigned int er_flags; /* event record characteristics */
+ int er_nparams; /* number of er_param[] entries */
+ pmEventParameter er_param[1];
+} pmHighResEventRecord;
+
+/* Potential flags bits set in er_flags (above) */
+#define PM_EVENT_FLAG_POINT (1U<<0) /* an observation, default type */
+#define PM_EVENT_FLAG_START (1U<<1) /* marking start of a new event */
+#define PM_EVENT_FLAG_END (1U<<2) /* completion of a traced event */
+#define PM_EVENT_FLAG_ID (1U<<3) /* 1st parameter is a trace ID */
+#define PM_EVENT_FLAG_PARENT (1U<<4) /* 2nd parameter is parents ID */
+#define PM_EVENT_FLAG_MISSED (1U<<31)/* nparams shows #missed events */
+
+typedef struct {
+ /* align initial declarations with start of pmValueBlock */
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int ea_type : 8; /* value type */
+ unsigned int ea_len : 24; /* bytes for type/len + vbuf */
+#else
+ unsigned int ea_len : 24; /* bytes for type/len + vbuf */
+ unsigned int ea_type : 8; /* value type */
+#endif
+ /* real event records start here */
+ int ea_nrecords; /* number of ea_record[] entries */
+ pmEventRecord ea_record[1];
+} pmEventArray;
+
+typedef struct {
+ /* align initial declarations with start of pmValueBlock */
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int ea_type : 8; /* value type */
+ unsigned int ea_len : 24; /* bytes for type/len + vbuf */
+#else
+ unsigned int ea_len : 24; /* bytes for type/len + vbuf */
+ unsigned int ea_type : 8; /* value type */
+#endif
+ /* real event records start here */
+ int ea_nrecords; /* number of ea_record[] entries */
+ pmHighResEventRecord ea_record[1];
+} pmHighResEventArray;
+
+/* Unpack a PM_TYPE_EVENT value into a set on pmResults */
+extern int pmUnpackEventRecords(pmValueSet *, int, pmResult ***);
+
+/* Free set of pmResults from pmUnpackEventRecords */
+extern void pmFreeEventResult(pmResult **);
+
+/* Unpack a PM_TYPE_HIGHRES_EVENT value into a set on pmHighResResults */
+extern int pmUnpackHighResEventRecords(pmValueSet *, int, pmHighResResult ***);
+
+/* Free set of pmHighResResults from pmUnpackEventRecords */
+extern void pmFreeHighResEventResult(pmHighResResult **);
+
+/* Service discovery, for clients. */
+#define PM_SERVER_SERVICE_SPEC "pmcd"
+#define PM_SERVER_PROXY_SPEC "pmproxy"
+#define PM_SERVER_WEBD_SPEC "pmwebd"
+
+extern int pmDiscoverServices(const char *, const char *, char ***);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PMAPI_H */