1PMDA(3) Library Functions Manual PMDA(3)
2
3
4
6 PMDA - introduction to the Performance Metrics Domain Agent support
7 library
8
10 #include <pcp/pmapi.h>
11 #include <pcp/impl.h>
12 #include <pcp/pmda.h>
13
14 cc ... -lpcp_pmda -lpcp
15
17 To assist in the development of Performance Metric Domain Agents
18 (PMDAs) for the Performance Co-Pilot (PCP), a procedural interface is
19 provided that extends the Performance Metrics Application Programming
20 Interface ( PMAPI(3)) library. These procedures are designed to enable
21 a programmer to quickly build a PMDA which can then be tested and
22 refined. However, this also implies that a PMDA has a particular
23 structure which may not be suitable for all applications.
24
25 Once you are familiar with the PCP and PMDA frameworks, you can quickly
26 implement a new PMDA with only a few data structures and functions.
27 This is covered in far greater detail in the Performance Co-Pilot Pro‐
28 grammer's Guide.
29
30 A PMDA is responsible for a set of performance metrics, in the sense
31 that it must respond to requests from pmcd(1) for information about
32 performance metrics, instance domains, and instantiated values. The
33 pmcd(1) process generates requests on behalf of performance tools that
34 make requests using PMAPI(3) routines.
35
36 This man page contains sections of the simple PMDA which is located at
37 $PCP_PMDAS_DIR/simple.
38
40 Two approaches may be used for connecting a PMDA to a pmcd(1) process.
41 A Dynamic Shared Object (DSO) can be attached by pmcd(1) using
42 dlopen(3) when the pmcd(1) process is started. A procedural interface
43 referenced through a shared data structure is used to handle requests
44 from pmcd(1) to the PMDA.
45
46 The preferred approach is for a separate process (daemon) to communi‐
47 cate with pmcd(1) using the Performance Data Units (PDU) Inter-Process
48 Communication (IPC) protocol.
49
50 All PMDAs are launched and controlled by the pmcd(1) process on the
51 local host. The requests from the clients are received by pmcd(1) and
52 forwarded to the appropriate PMDAs. Responses, when required, are
53 returned through pmcd(1) to the clients. The requests (PDUs) that may
54 be sent to a PMDA from pmcd(1) are PDU_FETCH, PDU_PROFILE,
55 PDU_INSTANCE_REQ, PDU_DESC_REQ, PDU_TEXT_REQ and PDU_RESULT.
56
58 To allow a consistent framework, pmdaMain(3) can be used by a daemon
59 PMDA to handle the communication protocol using the same callbacks as a
60 DSO PMDA. The structure pmdaInterface is used to convey the common
61 procedural interface and state information that is used by pmcd(1) and
62 a PMDA. This state information includes tables describing the sup‐
63 ported metrics and instance domains.
64
65 As most of the procedural interface is identical for all PMDAs, they
66 are provided as part of this support library (pmdaProfile(3),
67 pmdaFetch(3), pmdaInstance(3), pmdaDesc(3), pmdaText(3) and pmdaS‐
68 tore(3)). However, these routines require access to the pmdaInterface
69 state information so it must be correctly initialized using pmdaCon‐
70 nect(3), pmdaDaemon(3), pmdaOpenLog(3), pmdaDSO(3), pmdaGetOpt(3) and
71 pmdaInit(3).
72
74 Three structures are declared in /usr/include/pcp/pmda.h which provide
75 a framework for declaring the metrics and instances supported by the
76 PMDA.
77
78 Every instance requires a unique integer identifier and a unique name,
79 as defined by the structure pmdaInstid:
80
81 /*
82 * Instance description: index and name
83 */
84
85 typedef struct {
86 int i_inst; /* internal instance identifier */
87 char *i_name; /* external instance identifier */
88 } pmdaInstid;
89
90 An instance domain requires its own unique identification (pmInDom),
91 the number of instances the domain represents, and a pointer to an
92 array of instance descriptions. This is defined in the structure
93 pmdaIndom:
94
95 /*
96 * Instance domain description: unique instance id,
97 * number of instances in this domain, and the list of
98 * instances (not null terminated).
99 */
100
101 typedef struct {
102 pmInDom it_indom; /* indom, filled in */
103 int it_numinst; /* number of instances */
104 pmdaInstid *it_set; /* instance identifiers */
105 } pmdaIndom;
106
107 The simple PMDA has one instance domain for simple.color with three
108 instances (red, green and blue), and a second instance domain for sim‐
109 ple.now with instances which can be specified at run-time. These
110 instance domains are defined as:
111
112 static pmdaInstid _color[] = {
113 { 0, "red" }, { 1, "green" }, { 2, "blue" }
114 };
115 static pmdaInstid *_timenow = NULL;
116
117 static pmdaIndom indomtab[] = {
118 #define COLOR_INDOM 0
119 { COLOR_INDOM, 3, _color },
120 #define NOW_INDOM 1
121 { NOW_INDOM, 0, NULL },
122 };
123
124 The preprocessor macros COLOR_INDOM and NOW_INDOM are used in the met‐
125 ric description table to identify the instance domains of individual
126 metrics. These correspond to the serial value in the instance domain
127 pmInDom structure (the domain field is set by pmdaInit(3) at run-time).
128 The serial value must be unique for each instance domain within the
129 PMDA.
130
131 The indom table shown above which is usually passed to pmdaInit(3) does
132 not need to be created if one wants to write one's own Fetch and
133 Instance functions. See pmdaInit(3) for more details.
134
136 Every PMDA has its own unique namespace using the format defined in
137 pmns(4). In summary, the namespace matches the names of the metrics to
138 the unique identifier. The simple PMDA defines five metrics: sim‐
139 ple.numfetch, simple.color, simple.time.user, simple.time.sys and sim‐
140 ple.now. The namespace for these metrics is defined in
141 $PCP_PMDAS_DIR/simple/pmns and is installed as:
142
143 simple {
144 numfetch 253:0:0
145 color 253:0:1
146 time
147 now 253:2:4
148 }
149
150 simple.time {
151 user 253:1:2
152 sys 253:1:3
153 }
154
155 The domain number of 253 is obtained from $PCP_VAR_DIR/pmns/stdpmid.
156 New PMDAs should specify a unique domain number in this file, and
157 obtain the number during installation. This allows the domain number
158 to change by modifying only the file $PCP_VAR_DIR/pmns/stdpmid.
159
160 The simple.time and simple.now metrics are defined in separate clusters
161 to the other metrics which allows a PMDA to support more than 1024 met‐
162 rics, as well as grouping similar metrics together. Therefore, the
163 item numbers for a new cluster may be identical to the item numbers in
164 other clusters. The simple PMDA continues to increment the item num‐
165 bers to permit direct mapping (see pmdaInit(3)).
166
167 The namespace file should be installed and removed with the agent using
168 pmnsadd(1) and pmnsdel(1). See the later sections on INSTALLATION and
169 REMOVAL.
170
171 A simple ASCII namespace can be constructed by creating a file similar
172 to $PCP_PMDAS_DIR/simple/root:
173
174 /*
175 * fake "root" for validating the local PMNS subtree
176 */
177
178 #include "$PCP_VAR_DIR/pmns/stdpmid"
179
180 root { simple }
181
182 #include "pmns"
183
184
185 and can be referred to with the -n option in most PCP tools.
186
188 Each metric requires a description (pmDesc), which contains its PMID,
189 data type specification, instance domain, semantics and units (see
190 pmLookupDesc(3)). A handle is also provided for application specific
191 information in the pmdaMetric structure:
192
193 /*
194 * Metric description: handle for extending description,
195 * and the description.
196 */
197
198 typedef struct {
199 void* m_user; /* for users external use */
200 pmDesc m_desc; /* metric description */
201 } pmdaMetric;
202
203 The simple PMDA defines the metrics as:
204
205 static pmdaMetric metrictab[] = {
206 /* numfetch */
207 { (void *)0,
208 { PMDA_PMID(0,0), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
209 { 0,0,0,0,0,0} }, },
210 /* color */
211 { (void *)0,
212 { PMDA_PMID(0,1), PM_TYPE_32, COLOR_INDOM, PM_SEM_INSTANT,
213 { 0,0,0,0,0,0} }, },
214 /* time.user */
215 { (void*)0,
216 { PMDA_PMID(1,2), PM_TYPE_DOUBLE, PM_INDOM_NULL, PM_SEM_COUNTER,
217 { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
218 /* time.sys */
219 { (void*)0,
220 { PMDA_PMID(1,3), PM_TYPE_DOUBLE, PM_INDOM_NULL, PM_SEM_COUNTER,
221 { 0, 1, 0, 0, PM_TIME_SEC, 0 } }, },
222 /* now */
223 { NULL,
224 { PMDA_PMID(2,4), PM_TYPE_U32, NOW_INDOM, PM_SEM_INSTANT,
225 { 0,0,0,0,0,0 } }, },
226 };
227
228 The macro PMDA_PMID (defined in /usr/include/pcp/pmda.h) is used to
229 specify each metric's cluster and unit number in the __pmID_int struc‐
230 ture defined in /usr/include/pcp/impl.h. As with instance domains, the
231 domain field is set by pmdaInit(3) at run-time, however, the default
232 domain is assumed to be defined by the PMDA in the macro MYDOMAIN.
233
234 The metric table shown above which is usually passed to pmdaInit(3)
235 does not need to be created if one wants to write one's own Fetch and
236 Descriptor functions. See pmdaInit(3) for more details.
237
239 A PMDA that is run as a DSO is opened by pmcd(1) with dlopen(3). pmcd
240 will call the PMDA's initialization function that is specified in
241 $PCP_PMCDCONF_PATH. This function is passed a pointer to a pmdaInter‐
242 face structure which must be completed. Any callbacks which are not
243 the default PMDA support library callbacks must be specified in the
244 pmdaInterface structure.
245
246 The simple PMDA uses its own store and fetch callback. simple_fetch()
247 calls pmdaFetch(3) which requires a callback to be set with pmdaSet‐
248 FetchCallBack(3) as can be seen in $PCP_PMDAS_DIR/simple/simple.c.
249
250 The flag _isDSO is used to determine if the PMDA is a daemon or a DSO
251 so that the correct initialization routine, pmdaDaemon(3) or
252 pmdaDSO(3), is called.
253
255 A PMDA that is run as a daemon is forked and executed by pmcd(1).
256 Therefore, unlike a DSO PMDA, the starting point for a daemon PMDA is
257 main(). The agent should parse the command line arguments, create a
258 log file and initialize some data structures that pmcd would initialize
259 for a DSO agent.
260
261 The pmdaInterface structure must be completely defined by the daemon
262 PMDA. The function pmdaDaemon(3) can be called at the start of main()
263 to set most of these fields. Command line parsing can be simplified by
264 using pmdaGetOpt(3), which is similar to getopt(2), but extracts a com‐
265 mon set of options into the pmdaInterface structure. stderr can be
266 mapped to a log file using pmdaOpenLog(3) to simplify debugging and
267 error messages. The connection to pmcd can be made with pmdaConnect(3)
268 and the loop which handles the incoming PDUs, pmdaMain(3), should be
269 the last function called. This can be seen in $PCP_PMDAS_DIR/sim‐
270 ple/simple.c.
271
272 The simple_init() routine is common to an agent that can be run as both
273 a Daemon and DSO PMDA.
274
276 Each PMDA must be able to provide pmcd with the help text for each met‐
277 ric. Most PMDAs use specially created files with indexes to support
278 efficient retrieval of the help text. Tools are provided with PCP to
279 create the help text files of appropriate format. See newhelp(1).
280
282 A series of shell procedures are defined in
283 $PCP_SHARE_DIR/lib/pmdaproc.sh which greatly simplify the installation
284 and removal of a PMDA. The Install scripts for most PMDAs should only
285 need to specify the name of the PMDA in iam, call _setup which check
286 licenses and whether the PMDA has been previously installed, specify
287 the communication protocols, and finally call _install. The Remove
288 scripts are even simpler as the communication protocols are not
289 required. Further information is contained in the
290 $PCP_SHARE_DIR/lib/pmdaproc.sh file.
291
293 Any PMDA which uses this library can set PMAPI(3) debug control vari‐
294 able pmDebug (with -D on the command line) to DBG_TRACE_LIBPMDA to
295 enable the display of debugging information which may be useful during
296 development (see pmdbg(1)).
297
298 The status field of the pmdaInterface structure should be zero after
299 pmdaDaemon, pmdaDSO, pmdaGetOpt, pmdaConnect and pmdaInit are called.
300 A value less than zero indicates that initialization has failed.
301
302 Some error messages that are common to most functions in this library
303 are:
304
305 PMDA interface version interface not supported
306 Most of the functions require that the comm.version
307 field of the pmdaInterface structure be set to
308 PMDA_INTERFACE_2 or later. PMDA_INTERFACE_2 or
309 PMDA_INTERFACE_3 implies that the version.two fields are
310 correctly initialized, while PMDA_INTERFACE_4 implies
311 that the version.four fields are correctly initialized
312 (see pmdaDaemon(3) and pmdaDSO(3)).
313
315 Failing to complete any of the data structures or calling any of the
316 library routines out of order may cause unexpected behavior in the
317 PMDA.
318
319 Due to changes to the PMAPI(3) and PMDA(3) API in the PCP 2.0 release,
320 as described in the product release notes, PMDAs built using PCP 2.0
321 must specify PMDA_INTERFACE_2 or later and link with libpcp_pmda.so.2
322 and libpcp.so.2. Pre-existing Daemon PMDAs specifying PMDA_PROTOCOL_1
323 will continue to function using the backwards compatible
324 libpcp_pmda.so.1 and libpcp.so.1 libraries and may be recompiled using
325 the headers installed in /usr/include/pcp1.x/ without any modification.
326 These backwards compatible headers and libraries are contained in the
327 pcp.sw.compat subsystem.
328
330 /usr/include/pcp/pmda.h
331 Header file for the PMDA support library.
332
333 /usr/lib/libpcp_pmda.so
334 Dynamic library containing PMDA support library routines.
335
336 $PCP_PMDAS_DIR/trivial
337 The source of the trivial PMDA.
338
339 $PCP_PMDAS_DIR/simple
340 The source of the simple PMDA.
341
342 $PCP_PMDAS_DIR/txmon
343 The source of the txmon PMDA.
344
345 $PCP_PMCDCONF_PATH
346 Configuration file for pmcd(1).
347
348 $PCP_VAR_DIR/pmns
349 Location of namespace descriptions for every PMDA.
350
351 $PCP_VAR_DIR/pmns/stdpmid
352 The unique domain identifiers for each PMDA.
353
354 $PCP_SHARE_DIR/lib/pmdaproc.sh
355 Shell procedures for installing and removing a PMDA.
356
358 Environment variables with the prefix PCP_ are used to parameterize the
359 file and directory names used by PCP. On each installation, the file
360 /etc/pcp.conf contains the local values for these variables. The
361 $PCP_CONF variable may be used to specify an alternative configuration
362 file, as described in pcp.conf(4). Values for these variables may be
363 obtained programatically using the pmGetConfig(3) function.
364
366 dbpmda(1), newhelp(1), pmcd(1), pmnsadd(1), pmnsdel(1), PMAPI(3), pmda‐
367 Connect(3), pmdaDaemon(3), pmdaDesc(3), pmdaDSO(3), pmdaFetch(3),
368 pmdaGetOpt(3), pmdaInit(3), pmdaInstance(3), pmdaMain(3), pmdaOpen‐
369 Log(3), pmdaProfile(3), pmdaStore(3), pmdaText(3), pmLookupDesc(3) and
370 pmns(4).
371
372 For a complete description of the pcp_pmda library and the PMDA devel‐
373 opment process, refer to the Insight book Performance Co-Pilot Program‐
374 mer's Guide.
375
376
377
378Performance Co-Pilot SGI PMDA(3)