summaryrefslogtreecommitdiff
path: root/qa/src
diff options
context:
space:
mode:
Diffstat (limited to 'qa/src')
-rw-r--r--qa/src/19970807.09.54.0bin0 -> 1768 bytes
-rw-r--r--qa/src/19970807.09.54.indexbin0 -> 152 bytes
-rw-r--r--qa/src/19970807.09.54.metabin0 -> 464 bytes
-rw-r--r--qa/src/19970807.09.59.0bin0 -> 2176 bytes
-rw-r--r--qa/src/19970807.09.59.indexbin0 -> 152 bytes
-rw-r--r--qa/src/19970807.09.59.metabin0 -> 464 bytes
-rw-r--r--qa/src/20041125.0bin0 -> 346004 bytes
-rw-r--r--qa/src/20041125.indexbin0 -> 272 bytes
-rw-r--r--qa/src/20041125.metabin0 -> 13681 bytes
-rw-r--r--qa/src/20101004-trunc.0bin0 -> 190512 bytes
-rw-r--r--qa/src/20101004-trunc.indexbin0 -> 352 bytes
-rw-r--r--qa/src/20101004-trunc.metabin0 -> 46494 bytes
-rw-r--r--qa/src/20130706.0.bz2bin0 -> 478716 bytes
-rw-r--r--qa/src/20130706.indexbin0 -> 1912 bytes
-rw-r--r--qa/src/20130706.metabin0 -> 23669 bytes
-rw-r--r--qa/src/540117-short.0bin0 -> 4000 bytes
-rw-r--r--qa/src/540117-short.indexbin0 -> 232 bytes
-rw-r--r--qa/src/540117-short.metabin0 -> 5241 bytes
-rw-r--r--qa/src/541380.0bin0 -> 268 bytes
-rw-r--r--qa/src/541380.indexbin0 -> 152 bytes
-rw-r--r--qa/src/541380.metabin0 -> 270 bytes
-rw-r--r--qa/src/541380_v2.0bin0 -> 268 bytes
-rw-r--r--qa/src/541380_v2.indexbin0 -> 152 bytes
-rw-r--r--qa/src/541380_v2.metabin0 -> 351 bytes
-rw-r--r--qa/src/573184.0bin0 -> 1840 bytes
-rw-r--r--qa/src/573184.indexbin0 -> 172 bytes
-rw-r--r--qa/src/573184.metabin0 -> 408 bytes
-rw-r--r--qa/src/779246.c131
-rw-r--r--qa/src/951127.23.01.0bin0 -> 3580 bytes
-rw-r--r--qa/src/951127.23.01.indexbin0 -> 192 bytes
-rw-r--r--qa/src/951127.23.01.metabin0 -> 531 bytes
-rw-r--r--qa/src/951127.23.01_v2.0bin0 -> 3580 bytes
-rw-r--r--qa/src/951127.23.01_v2.indexbin0 -> 172 bytes
-rw-r--r--qa/src/951127.23.01_v2.metabin0 -> 629 bytes
-rw-r--r--qa/src/960624.08.17.0bin0 -> 15580 bytes
-rw-r--r--qa/src/960624.08.17.indexbin0 -> 172 bytes
-rw-r--r--qa/src/960624.08.17.metabin0 -> 8989 bytes
-rw-r--r--qa/src/960624.08.17_v2.0bin0 -> 15580 bytes
-rw-r--r--qa/src/960624.08.17_v2.indexbin0 -> 172 bytes
-rw-r--r--qa/src/960624.08.17_v2.metabin0 -> 15195 bytes
-rw-r--r--qa/src/GNUlocaldefs787
-rw-r--r--qa/src/GNUmakefile35
-rw-r--r--qa/src/GNUmakefile.install43
-rw-r--r--qa/src/ac15.0bin0 -> 2084 bytes
-rw-r--r--qa/src/ac15.indexbin0 -> 192 bytes
-rw-r--r--qa/src/ac15.metabin0 -> 1253 bytes
-rw-r--r--qa/src/ace.0bin0 -> 6592 bytes
-rw-r--r--qa/src/ace.indexbin0 -> 252 bytes
-rw-r--r--qa/src/ace.metabin0 -> 1335 bytes
-rw-r--r--qa/src/ace_v2.0bin0 -> 5776 bytes
-rw-r--r--qa/src/ace_v2.indexbin0 -> 152 bytes
-rw-r--r--qa/src/ace_v2.metabin0 -> 1978 bytes
-rw-r--r--qa/src/agenttimeout.c177
-rw-r--r--qa/src/aggrstore.c129
-rw-r--r--qa/src/all-irix-6.5.25.0bin0 -> 122892 bytes
-rw-r--r--qa/src/all-irix-6.5.25.indexbin0 -> 372 bytes
-rw-r--r--qa/src/all-irix-6.5.25.metabin0 -> 93346 bytes
-rw-r--r--qa/src/all-sles9-sp1.0bin0 -> 97892 bytes
-rw-r--r--qa/src/all-sles9-sp1.indexbin0 -> 392 bytes
-rw-r--r--qa/src/all-sles9-sp1.metabin0 -> 38879 bytes
-rw-r--r--qa/src/anon-sa.c111
-rw-r--r--qa/src/arch_a.0bin0 -> 488 bytes
-rw-r--r--qa/src/arch_a.indexbin0 -> 192 bytes
-rw-r--r--qa/src/arch_a.metabin0 -> 414 bytes
-rw-r--r--qa/src/arch_b.0bin0 -> 488 bytes
-rw-r--r--qa/src/arch_b.indexbin0 -> 192 bytes
-rw-r--r--qa/src/arch_b.metabin0 -> 414 bytes
-rw-r--r--qa/src/arch_maxfd.c145
-rw-r--r--qa/src/archinst.c292
-rw-r--r--qa/src/atomstr.c135
-rw-r--r--qa/src/babylon.percpu.0bin0 -> 93732 bytes
-rw-r--r--qa/src/babylon.percpu.indexbin0 -> 172 bytes
-rw-r--r--qa/src/babylon.percpu.metabin0 -> 710 bytes
-rw-r--r--qa/src/babylon.percpu_v2.0bin0 -> 93732 bytes
-rw-r--r--qa/src/babylon.percpu_v2.indexbin0 -> 152 bytes
-rw-r--r--qa/src/babylon.percpu_v2.metabin0 -> 941 bytes
-rw-r--r--qa/src/babylon.pmview.0bin0 -> 368772 bytes
-rw-r--r--qa/src/babylon.pmview.indexbin0 -> 232 bytes
-rw-r--r--qa/src/babylon.pmview.metabin0 -> 2507 bytes
-rw-r--r--qa/src/babylon.pmview_v2.0bin0 -> 368772 bytes
-rw-r--r--qa/src/babylon.pmview_v2.indexbin0 -> 152 bytes
-rw-r--r--qa/src/babylon.pmview_v2.metabin0 -> 3271 bytes
-rw-r--r--qa/src/badlen-0.0bin0 -> 1928 bytes
-rw-r--r--qa/src/badlen-0.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-0.metabin0 -> 851 bytes
-rw-r--r--qa/src/badlen-1.0bin0 -> 1928 bytes
-rw-r--r--qa/src/badlen-1.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-1.metabin0 -> 851 bytes
-rw-r--r--qa/src/badlen-10.0bin0 -> 131 bytes
-rw-r--r--qa/src/badlen-10.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-10.metabin0 -> 851 bytes
-rw-r--r--qa/src/badlen-11.0bin0 -> 133 bytes
-rw-r--r--qa/src/badlen-11.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-11.metabin0 -> 851 bytes
-rw-r--r--qa/src/badlen-2.0bin0 -> 260 bytes
-rw-r--r--qa/src/badlen-2.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-2.metabin0 -> 851 bytes
-rw-r--r--qa/src/badlen-3.0bin0 -> 252 bytes
-rw-r--r--qa/src/badlen-3.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-3.metabin0 -> 851 bytes
-rw-r--r--qa/src/badlen-4.01
-rw-r--r--qa/src/badlen-4.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-4.metabin0 -> 851 bytes
-rw-r--r--qa/src/badlen-5.0bin0 -> 42 bytes
-rw-r--r--qa/src/badlen-5.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-5.metabin0 -> 851 bytes
-rw-r--r--qa/src/badlen-6.0bin0 -> 1928 bytes
-rw-r--r--qa/src/badlen-6.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-6.metabin0 -> 851 bytes
-rw-r--r--qa/src/badlen-7.0bin0 -> 1928 bytes
-rw-r--r--qa/src/badlen-7.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-7.metabin0 -> 851 bytes
-rw-r--r--qa/src/badlen-8.0bin0 -> 1928 bytes
-rw-r--r--qa/src/badlen-8.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-8.metabin0 -> 851 bytes
-rw-r--r--qa/src/badlen-9.0bin0 -> 1932 bytes
-rw-r--r--qa/src/badlen-9.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badlen-9.metabin0 -> 840 bytes
-rw-r--r--qa/src/badloglabel.c70
-rw-r--r--qa/src/badpmcdpmid.c45
-rw-r--r--qa/src/badpmda.c126
-rw-r--r--qa/src/badti-1.0bin0 -> 1976 bytes
-rw-r--r--qa/src/badti-1.indexbin0 -> 162 bytes
-rw-r--r--qa/src/badti-1.metabin0 -> 851 bytes
-rw-r--r--qa/src/badti-2.0bin0 -> 1976 bytes
-rw-r--r--qa/src/badti-2.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badti-2.metabin0 -> 851 bytes
-rw-r--r--qa/src/badti-3.0bin0 -> 1976 bytes
-rw-r--r--qa/src/badti-3.indexbin0 -> 192 bytes
-rw-r--r--qa/src/badti-3.metabin0 -> 851 bytes
-rwxr-xr-xqa/src/batch_import.perl78
l---------qa/src/batch_import.pl1
-rw-r--r--qa/src/bigace.0bin0 -> 1197788 bytes
-rw-r--r--qa/src/bigace.indexbin0 -> 792 bytes
-rw-r--r--qa/src/bigace.metabin0 -> 74306 bytes
-rw-r--r--qa/src/bigace.pmns103
-rw-r--r--qa/src/bigace_v2.0bin0 -> 1197788 bytes
-rw-r--r--qa/src/bigace_v2.indexbin0 -> 612 bytes
-rw-r--r--qa/src/bigace_v2.metabin0 -> 75462 bytes
-rw-r--r--qa/src/binning.0bin0 -> 3580 bytes
-rw-r--r--qa/src/binning.indexbin0 -> 192 bytes
-rw-r--r--qa/src/binning.metabin0 -> 524 bytes
-rw-r--r--qa/src/bozo.client.0bin0 -> 1432 bytes
-rw-r--r--qa/src/bozo.client.indexbin0 -> 192 bytes
-rw-r--r--qa/src/bozo.client.metabin0 -> 445 bytes
-rw-r--r--qa/src/bozo.client_v2.0bin0 -> 1432 bytes
-rw-r--r--qa/src/bozo.client_v2.indexbin0 -> 172 bytes
-rw-r--r--qa/src/bozo.client_v2.metabin0 -> 585 bytes
-rw-r--r--qa/src/bozo.client_v2.meta.bad.1bin0 -> 585 bytes
-rw-r--r--qa/src/bozo.client_v2.meta.bad.2bin0 -> 585 bytes
-rw-r--r--qa/src/bug.0bin0 -> 2328 bytes
-rw-r--r--qa/src/bug.indexbin0 -> 192 bytes
-rw-r--r--qa/src/bug.metabin0 -> 496 bytes
-rw-r--r--qa/src/bug1057.0bin0 -> 167960 bytes
-rw-r--r--qa/src/bug1057.indexbin0 -> 232 bytes
-rw-r--r--qa/src/bug1057.metabin0 -> 22122 bytes
-rw-r--r--qa/src/bug_v2.0bin0 -> 2328 bytes
-rw-r--r--qa/src/bug_v2.indexbin0 -> 172 bytes
-rw-r--r--qa/src/bug_v2.metabin0 -> 634 bytes
-rw-r--r--qa/src/changeinst.0bin0 -> 2200 bytes
-rw-r--r--qa/src/changeinst.indexbin0 -> 312 bytes
-rw-r--r--qa/src/changeinst.metabin0 -> 1416 bytes
-rw-r--r--qa/src/check_fault_injection.c56
-rw-r--r--qa/src/check_import.c175
-rwxr-xr-xqa/src/check_import.perl139
l---------qa/src/check_import.pl1
l---------qa/src/check_import.py1
-rwxr-xr-xqa/src/check_import.python69
-rw-r--r--qa/src/check_import_name.c47
-rw-r--r--qa/src/chk_memleak.c141
-rw-r--r--qa/src/chk_metric_types.c313
-rw-r--r--qa/src/chkacc1.c165
-rw-r--r--qa/src/chkacc2.c175
-rw-r--r--qa/src/chkacc3.c240
-rw-r--r--qa/src/chkacc4.c198
-rw-r--r--qa/src/chkconnect.c180
-rw-r--r--qa/src/chkctx2.c205
-rw-r--r--qa/src/chkhelp.c107
-rw-r--r--qa/src/chknumval.c289
-rw-r--r--qa/src/chkopenlog.c54
-rw-r--r--qa/src/chkoptfetch.c285
-rw-r--r--qa/src/chkputlogresult.c183
-rw-r--r--qa/src/chktrim.c107
-rw-r--r--qa/src/churnctx.c429
-rw-r--r--qa/src/clientid.c91
-rw-r--r--qa/src/compare.c114
-rw-r--r--qa/src/config.bar18
-rw-r--r--qa/src/config.bigbin14
-rw-r--r--qa/src/config.dodgey-all9
-rw-r--r--qa/src/config.dodgey-mixed13
-rw-r--r--qa/src/config.dodgey-some9
-rw-r--r--qa/src/config.foo11
-rw-r--r--qa/src/config1.interp7
-rw-r--r--qa/src/config2.interp7
-rw-r--r--qa/src/conn20070309.0bin0 -> 299620 bytes
-rw-r--r--qa/src/conn20070309.indexbin0 -> 212 bytes
-rw-r--r--qa/src/conn20070309.metabin0 -> 236 bytes
-rw-r--r--qa/src/context_fd_leak.c111
-rw-r--r--qa/src/context_test.c281
-rw-r--r--qa/src/count-mark.0bin0 -> 548648 bytes
-rw-r--r--qa/src/count-mark.indexbin0 -> 272 bytes
-rw-r--r--qa/src/count-mark.metabin0 -> 322 bytes
-rw-r--r--qa/src/crashpmcd.c85
-rw-r--r--qa/src/defctx.c232
-rw-r--r--qa/src/descreqX2.c100
-rw-r--r--qa/src/disk_test.c144
-rw-r--r--qa/src/drain-server.c127
-rw-r--r--qa/src/dumb_pmda.c81
-rw-r--r--qa/src/endian.c130
-rw-r--r--qa/src/eofarch.c208
-rw-r--r--qa/src/eol.c198
-rw-r--r--qa/src/err.c57
-rw-r--r--qa/src/err_v1.0bin0 -> 516 bytes
-rw-r--r--qa/src/err_v1.dump68
-rw-r--r--qa/src/err_v1.indexbin0 -> 192 bytes
-rw-r--r--qa/src/err_v1.metabin0 -> 398 bytes
-rw-r--r--qa/src/eventrec-old.0bin0 -> 1184 bytes
-rw-r--r--qa/src/eventrec-old.indexbin0 -> 172 bytes
-rw-r--r--qa/src/eventrec-old.metabin0 -> 975 bytes
-rw-r--r--qa/src/eventrec.0bin0 -> 4176 bytes
-rw-r--r--qa/src/eventrec.indexbin0 -> 192 bytes
-rw-r--r--qa/src/eventrec.metabin0 -> 2074 bytes
-rw-r--r--qa/src/exercise.c197
-rw-r--r--qa/src/exercise_fault.c79
-rw-r--r--qa/src/exerlock.c58
-rw-r--r--qa/src/exertz.c249
-rw-r--r--qa/src/fcsw_indom.0bin0 -> 7140 bytes
-rw-r--r--qa/src/fcsw_indom.indexbin0 -> 192 bytes
-rw-r--r--qa/src/fcsw_indom.metabin0 -> 2343 bytes
-rw-r--r--qa/src/fetchpdu.c112
-rw-r--r--qa/src/fetchrate.c121
-rwxr-xr-xqa/src/fixhosts47
-rw-r--r--qa/src/getconfig.c55
-rw-r--r--qa/src/getcontexthost.c121
-rw-r--r--qa/src/getoptions.c257
-rw-r--r--qa/src/gmt-boring.0bin0 -> 416 bytes
-rw-r--r--qa/src/gmt-boring.indexbin0 -> 172 bytes
-rw-r--r--qa/src/gmt-boring.metabin0 -> 402 bytes
-rwxr-xr-xqa/src/grind-tools387
-rw-r--r--qa/src/grind_conv.c192
-rw-r--r--qa/src/grind_ctx.c161
-rw-r--r--qa/src/hashwalk.c69
-rw-r--r--qa/src/hex2nbo.c113
-rw-r--r--qa/src/hp-mib.c202
-rw-r--r--qa/src/hrunpack.c479
-rw-r--r--qa/src/import_limit_test.perl72
l---------qa/src/import_limit_test.pl1
-rw-r--r--qa/src/indom.c310
-rw-r--r--qa/src/interp0.c277
-rw-r--r--qa/src/interp1.c248
-rw-r--r--qa/src/interp2.c198
-rw-r--r--qa/src/interp3.c425
-rw-r--r--qa/src/interp4.c302
-rw-r--r--qa/src/interp_bug.c349
-rw-r--r--qa/src/interp_bug2.c417
-rw-r--r--qa/src/interpmark.0bin0 -> 140712 bytes
-rw-r--r--qa/src/interpmark.indexbin0 -> 492 bytes
-rw-r--r--qa/src/interpmark.metabin0 -> 4798 bytes
-rw-r--r--qa/src/iostat26
-rw-r--r--qa/src/iostat-c11
-rw-r--r--qa/src/iostat-d17
-rw-r--r--qa/src/iostat-d-k17
-rw-r--r--qa/src/iostat-d-m17
-rw-r--r--qa/src/iostat-p-ALL137
-rw-r--r--qa/src/iostat-t29
-rw-r--r--qa/src/iostat-t.ISO29
-rw-r--r--qa/src/iostat-x26
-rw-r--r--qa/src/iostat-z23
-rw-r--r--qa/src/iostat-z-p-ALL36
-rw-r--r--qa/src/ipc.c303
-rwxr-xr-xqa/src/ipcs_clear39
-rw-r--r--qa/src/kenj-pc-1.0bin0 -> 310264 bytes
-rw-r--r--qa/src/kenj-pc-1.indexbin0 -> 252 bytes
-rw-r--r--qa/src/kenj-pc-1.metabin0 -> 1567 bytes
-rw-r--r--qa/src/kenj-pc-2.0bin0 -> 58168 bytes
-rw-r--r--qa/src/kenj-pc-2.config10
-rw-r--r--qa/src/kenj-pc-2.indexbin0 -> 852 bytes
-rw-r--r--qa/src/kenj-pc-2.metabin0 -> 5599 bytes
-rw-r--r--qa/src/kenj-pc-diskstat.0bin0 -> 4408 bytes
-rw-r--r--qa/src/kenj-pc-diskstat.indexbin0 -> 192 bytes
-rw-r--r--qa/src/kenj-pc-diskstat.metabin0 -> 1022 bytes
-rw-r--r--qa/src/keycache.c278
-rw-r--r--qa/src/keycache2.c412
-rw-r--r--qa/src/killparent.c13
-rw-r--r--qa/src/late.0bin0 -> 5332 bytes
-rw-r--r--qa/src/late.indexbin0 -> 192 bytes
-rw-r--r--qa/src/late.metabin0 -> 638 bytes
-rw-r--r--qa/src/logcontrol.c260
-rw-r--r--qa/src/logsummary-bug.0bin0 -> 236 bytes
-rw-r--r--qa/src/logsummary-bug.indexbin0 -> 172 bytes
-rw-r--r--qa/src/logsummary-bug.metabin0 -> 197 bytes
-rwxr-xr-xqa/src/make.dodgey35
-rw-r--r--qa/src/mark-bug.0bin0 -> 26296 bytes
-rw-r--r--qa/src/mark-bug.c386
-rw-r--r--qa/src/mark-bug.indexbin0 -> 272 bytes
-rw-r--r--qa/src/mark-bug.metabin0 -> 1347 bytes
-rw-r--r--qa/src/markmerge.0bin0 -> 6648 bytes
-rw-r--r--qa/src/markmerge.indexbin0 -> 232 bytes
-rw-r--r--qa/src/markmerge.metabin0 -> 747 bytes
-rw-r--r--qa/src/matchInstanceName.c36
-rwxr-xr-xqa/src/memcachestats.pl66
-rw-r--r--qa/src/mirage-1.0bin0 -> 3969 bytes
-rw-r--r--qa/src/mirage-1.indexbin0 -> 272 bytes
-rw-r--r--qa/src/mirage-1.metabin0 -> 1333 bytes
-rw-r--r--qa/src/mirage-2.0bin0 -> 2673 bytes
-rw-r--r--qa/src/mirage-2.indexbin0 -> 332 bytes
-rw-r--r--qa/src/mirage-2.metabin0 -> 1736 bytes
-rw-r--r--qa/src/mirage.0bin0 -> 3992 bytes
-rw-r--r--qa/src/mirage.indexbin0 -> 532 bytes
-rw-r--r--qa/src/mirage.metabin0 -> 2731 bytes
-rwxr-xr-xqa/src/mkarch-all48
-rwxr-xr-xqa/src/mkbadlen110
-rwxr-xr-xqa/src/mkbadti107
-rwxr-xr-xqa/src/mkbig178
-rwxr-xr-xqa/src/mkeventrec22
-rw-r--r--qa/src/mkfiles.c63
-rwxr-xr-xqa/src/mkinterpmark148
-rwxr-xr-xqa/src/mkmirage35
-rwxr-xr-xqa/src/mkmultihost65
-rwxr-xr-xqa/src/mknuma37
-rwxr-xr-xqa/src/mkpermslist209
-rwxr-xr-xqa/src/mkproc31
-rwxr-xr-xqa/src/mkrewrite33
-rwxr-xr-xqa/src/mksa-sysstat44
-rwxr-xr-xqa/src/mksample_expr32
-rwxr-xr-xqa/src/mktzchange35
-rw-r--r--qa/src/mmv_genstats.c131
-rw-r--r--qa/src/mmv_instances.c92
-rw-r--r--qa/src/mmv_noinit.c128
-rw-r--r--qa/src/mmv_nostats.c23
-rw-r--r--qa/src/mmv_poke.c94
-rw-r--r--qa/src/moomba.client.0bin0 -> 2144 bytes
-rw-r--r--qa/src/moomba.client.indexbin0 -> 192 bytes
-rw-r--r--qa/src/moomba.client.metabin0 -> 843 bytes
-rw-r--r--qa/src/moomba.pmkstat.0bin0 -> 6520 bytes
-rw-r--r--qa/src/moomba.pmkstat.indexbin0 -> 192 bytes
-rw-r--r--qa/src/moomba.pmkstat.metabin0 -> 1563 bytes
-rw-r--r--qa/src/multi-vm00.0bin0 -> 12684 bytes
-rw-r--r--qa/src/multi-vm00.indexbin0 -> 192 bytes
-rw-r--r--qa/src/multi-vm00.metabin0 -> 4162 bytes
-rw-r--r--qa/src/multi-vm01.0bin0 -> 12584 bytes
-rw-r--r--qa/src/multi-vm01.indexbin0 -> 192 bytes
-rw-r--r--qa/src/multi-vm01.metabin0 -> 4135 bytes
-rw-r--r--qa/src/multi-vm02.0bin0 -> 12684 bytes
-rw-r--r--qa/src/multi-vm02.indexbin0 -> 192 bytes
-rw-r--r--qa/src/multi-vm02.metabin0 -> 4162 bytes
-rw-r--r--qa/src/multi-vm03.0bin0 -> 12604 bytes
-rw-r--r--qa/src/multi-vm03.indexbin0 -> 192 bytes
-rw-r--r--qa/src/multi-vm03.metabin0 -> 4128 bytes
-rw-r--r--qa/src/multifetch.c202
-rw-r--r--qa/src/multithread0.c68
-rw-r--r--qa/src/multithread1.c228
-rw-r--r--qa/src/multithread2.c209
-rw-r--r--qa/src/multithread3.c222
-rw-r--r--qa/src/multithread4.c137
-rw-r--r--qa/src/multithread5.c270
-rw-r--r--qa/src/multithread6.c299
-rw-r--r--qa/src/multithread7.c342
-rw-r--r--qa/src/multithread8.c285
-rw-r--r--qa/src/multithread9.c387
-rw-r--r--qa/src/nameall.c179
-rw-r--r--qa/src/naslog.0bin0 -> 848264 bytes
-rw-r--r--qa/src/naslog.indexbin0 -> 372 bytes
-rw-r--r--qa/src/naslog.metabin0 -> 5812 bytes
-rw-r--r--qa/src/new_mysql.0bin0 -> 856 bytes
-rw-r--r--qa/src/new_mysql.indexbin0 -> 172 bytes
-rw-r--r--qa/src/new_mysql.metabin0 -> 627 bytes
-rw-r--r--qa/src/new_snmp.0bin0 -> 4764 bytes
-rw-r--r--qa/src/new_snmp.indexbin0 -> 172 bytes
-rw-r--r--qa/src/new_snmp.metabin0 -> 4762 bytes
-rw-r--r--qa/src/node_archive.0bin0 -> 704 bytes
-rw-r--r--qa/src/node_archive.indexbin0 -> 252 bytes
-rw-r--r--qa/src/node_archive.metabin0 -> 996 bytes
-rw-r--r--qa/src/nullinst.c115
-rw-r--r--qa/src/numa.0bin0 -> 14404 bytes
-rw-r--r--qa/src/numa.indexbin0 -> 212 bytes
-rw-r--r--qa/src/numa.metabin0 -> 3238 bytes
-rw-r--r--qa/src/numberstr.c29
-rw-r--r--qa/src/nvidia-ml.c216
-rw-r--r--qa/src/obs.c33
-rw-r--r--qa/src/ok-bigbin.0bin0 -> 492288 bytes
-rw-r--r--qa/src/ok-bigbin.indexbin0 -> 272 bytes
-rw-r--r--qa/src/ok-bigbin.metabin0 -> 1271 bytes
-rw-r--r--qa/src/ok-foo.0bin0 -> 1976 bytes
-rw-r--r--qa/src/ok-foo.indexbin0 -> 192 bytes
-rw-r--r--qa/src/ok-foo.metabin0 -> 851 bytes
-rw-r--r--qa/src/ok-mv-bigbin.0bin0 -> 49984 bytes
-rw-r--r--qa/src/ok-mv-bigbin.1bin0 -> 49824 bytes
-rw-r--r--qa/src/ok-mv-bigbin.2bin0 -> 49824 bytes
-rw-r--r--qa/src/ok-mv-bigbin.3bin0 -> 49824 bytes
-rw-r--r--qa/src/ok-mv-bigbin.4bin0 -> 49824 bytes
-rw-r--r--qa/src/ok-mv-bigbin.5bin0 -> 49824 bytes
-rw-r--r--qa/src/ok-mv-bigbin.6bin0 -> 49824 bytes
-rw-r--r--qa/src/ok-mv-bigbin.7bin0 -> 49824 bytes
-rw-r--r--qa/src/ok-mv-bigbin.8bin0 -> 49824 bytes
-rw-r--r--qa/src/ok-mv-bigbin.9bin0 -> 44904 bytes
-rw-r--r--qa/src/ok-mv-bigbin.indexbin0 -> 372 bytes
-rw-r--r--qa/src/ok-mv-bigbin.metabin0 -> 1271 bytes
-rw-r--r--qa/src/ok-mv-foo.0bin0 -> 916 bytes
-rw-r--r--qa/src/ok-mv-foo.1bin0 -> 760 bytes
-rw-r--r--qa/src/ok-mv-foo.2bin0 -> 548 bytes
-rw-r--r--qa/src/ok-mv-foo.indexbin0 -> 232 bytes
-rw-r--r--qa/src/ok-mv-foo.metabin0 -> 851 bytes
-rw-r--r--qa/src/ok-noti-bigbin.0bin0 -> 492288 bytes
-rw-r--r--qa/src/ok-noti-bigbin.metabin0 -> 1271 bytes
-rw-r--r--qa/src/ok-truncbin.0bin0 -> 204800 bytes
-rw-r--r--qa/src/ok-truncbin.indexbin0 -> 272 bytes
-rw-r--r--qa/src/ok-truncbin.metabin0 -> 1271 bytes
-rw-r--r--qa/src/old_xfs.0bin0 -> 76060 bytes
-rw-r--r--qa/src/old_xfs.indexbin0 -> 192 bytes
-rw-r--r--qa/src/old_xfs.metabin0 -> 11011 bytes
-rw-r--r--qa/src/omen.client.0bin0 -> 1876 bytes
-rw-r--r--qa/src/omen.client.indexbin0 -> 192 bytes
-rw-r--r--qa/src/omen.client.metabin0 -> 805 bytes
-rw-r--r--qa/src/papi.c97
-rw-r--r--qa/src/parsehostattrs.c65
-rw-r--r--qa/src/parsehostspec.c46
-rw-r--r--qa/src/parseinterval.c29
-rw-r--r--qa/src/parsemetricspec.c43
-rw-r--r--qa/src/pcp-free.0bin0 -> 14784 bytes
-rw-r--r--qa/src/pcp-free.indexbin0 -> 172 bytes
-rw-r--r--qa/src/pcp-free.metabin0 -> 3174 bytes
-rw-r--r--qa/src/pcp-numastat-1-node.0bin0 -> 1192 bytes
-rw-r--r--qa/src/pcp-numastat-1-node.indexbin0 -> 172 bytes
-rw-r--r--qa/src/pcp-numastat-1-node.metabin0 -> 552 bytes
-rw-r--r--qa/src/pcp-uptime.0bin0 -> 732 bytes
-rw-r--r--qa/src/pcp-uptime.indexbin0 -> 172 bytes
-rw-r--r--qa/src/pcp-uptime.metabin0 -> 381 bytes
-rw-r--r--qa/src/pcp_lite_crash.c132
-rw-r--r--qa/src/pcpcmd.0bin0 -> 1412 bytes
-rw-r--r--qa/src/pcpcmd.indexbin0 -> 192 bytes
-rw-r--r--qa/src/pcpcmd.metabin0 -> 2035 bytes
-rw-r--r--qa/src/pdu-server.c768
-rw-r--r--qa/src/pducheck.c1512
-rw-r--r--qa/src/pducrash.c1278
-rw-r--r--qa/src/permfetch.c224
-rw-r--r--qa/src/permslist16
-rw-r--r--qa/src/pmatop-log.0bin0 -> 176352 bytes
-rw-r--r--qa/src/pmatop-log.folio9
-rw-r--r--qa/src/pmatop-log.indexbin0 -> 212 bytes
-rw-r--r--qa/src/pmatop-log.metabin0 -> 17317 bytes
-rw-r--r--qa/src/pmcdgone.c414
-rw-r--r--qa/src/pmconvscale.c146
-rw-r--r--qa/src/pmdacache.c102
-rw-r--r--qa/src/pmdaqueue.c309
-rw-r--r--qa/src/pmdashutdown.c60
-rw-r--r--qa/src/pmlcmacro.c59
-rw-r--r--qa/src/pmnsinarchives.c179
-rw-r--r--qa/src/pmnsunload.c144
-rw-r--r--qa/src/pmprintf.c51
-rw-r--r--qa/src/pmsocks_objstyle.c184
-rw-r--r--qa/src/proc.0bin0 -> 56329 bytes
-rw-r--r--qa/src/proc.indexbin0 -> 192 bytes
-rw-r--r--qa/src/proc.metabin0 -> 28161 bytes
-rw-r--r--qa/src/proc_test.c624
-rw-r--r--qa/src/pthread_barrier.h86
-rw-r--r--qa/src/pv.c77
-rw-r--r--qa/src/pyapi.0bin0 -> 155208 bytes
-rw-r--r--qa/src/pyapi.indexbin0 -> 232 bytes
-rw-r--r--qa/src/pyapi.metabin0 -> 41830 bytes
-rw-r--r--qa/src/qa_test.c7
-rw-r--r--qa/src/qa_timezone.c37
-rw-r--r--qa/src/rattle.0bin0 -> 1824 bytes
-rw-r--r--qa/src/rattle.indexbin0 -> 212 bytes
-rw-r--r--qa/src/rattle.metabin0 -> 590 bytes
-rw-r--r--qa/src/read-bf.c106
-rw-r--r--qa/src/recon.c123
-rw-r--r--qa/src/record-setarg.c69
-rw-r--r--qa/src/record.c120
-rw-r--r--qa/src/reduce-1.0bin0 -> 50932 bytes
-rw-r--r--qa/src/reduce-1.indexbin0 -> 192 bytes
-rw-r--r--qa/src/reduce-1.metabin0 -> 2074 bytes
-rw-r--r--qa/src/reduce-2.0bin0 -> 50932 bytes
-rw-r--r--qa/src/reduce-2.indexbin0 -> 192 bytes
-rw-r--r--qa/src/reduce-2.metabin0 -> 2074 bytes
-rw-r--r--qa/src/reduce.config21
-rw-r--r--qa/src/rewrite.0bin0 -> 3437 bytes
-rw-r--r--qa/src/rewrite.indexbin0 -> 212 bytes
-rw-r--r--qa/src/rewrite.metabin0 -> 1727 bytes
-rw-r--r--qa/src/root_irix2114
-rw-r--r--qa/src/root_pmns2146
-rw-r--r--qa/src/rtimetest.c159
-rw-r--r--qa/src/sa-sysstat-10.0.1bin0 -> 267596 bytes
-rw-r--r--qa/src/sa-sysstat-10.0.5bin0 -> 383412 bytes
-rw-r--r--qa/src/sa-sysstat-10.2.0bin0 -> 815288 bytes
-rw-r--r--qa/src/sa-sysstat-9.0.4bin0 -> 392172 bytes
-rw-r--r--qa/src/sa-sysstat-9.0.6bin0 -> 263780 bytes
-rw-r--r--qa/src/sa-sysstat-9.0.6.1bin0 -> 282588 bytes
-rw-r--r--qa/src/sa-sysstat-9.1.7bin0 -> 284012 bytes
-rw-r--r--qa/src/sample-secs.0bin0 -> 2532 bytes
-rw-r--r--qa/src/sample-secs.indexbin0 -> 172 bytes
-rw-r--r--qa/src/sample-secs.metabin0 -> 465 bytes
-rw-r--r--qa/src/sample_expr.0bin0 -> 6005 bytes
-rw-r--r--qa/src/sample_expr.indexbin0 -> 192 bytes
-rw-r--r--qa/src/sample_expr.metabin0 -> 1305 bytes
-rw-r--r--qa/src/scale.c209
-rw-r--r--qa/src/section-a.0bin0 -> 46764 bytes
-rw-r--r--qa/src/section-a.indexbin0 -> 252 bytes
-rw-r--r--qa/src/section-a.metabin0 -> 2906 bytes
-rw-r--r--qa/src/section-b.0bin0 -> 46764 bytes
-rw-r--r--qa/src/section-b.indexbin0 -> 252 bytes
-rw-r--r--qa/src/section-b.metabin0 -> 2906 bytes
-rw-r--r--qa/src/section-c.0bin0 -> 756 bytes
-rw-r--r--qa/src/section-c.indexbin0 -> 192 bytes
-rw-r--r--qa/src/section-c.metabin0 -> 1039 bytes
-rw-r--r--qa/src/section-d.0bin0 -> 46764 bytes
-rw-r--r--qa/src/section-d.indexbin0 -> 252 bytes
-rw-r--r--qa/src/section-d.metabin0 -> 2906 bytes
-rw-r--r--qa/src/sgi.bfbin0 -> 8 bytes
-rwxr-xr-xqa/src/show-args11
-rw-r--r--qa/src/simple-resave.csv5
-rw-r--r--qa/src/simple-resave.xlsxbin0 -> 7962 bytes
-rw-r--r--qa/src/simple.csv5
-rw-r--r--qa/src/simple.odsbin0 -> 9018 bytes
-rw-r--r--qa/src/simple.sxcbin0 -> 8881 bytes
-rw-r--r--qa/src/simple.xlsbin0 -> 6144 bytes
-rw-r--r--qa/src/simple.xlsxbin0 -> 4793 bytes
-rw-r--r--qa/src/slow.0bin0 -> 453852 bytes
-rw-r--r--qa/src/slow.indexbin0 -> 252 bytes
-rw-r--r--qa/src/slow.metabin0 -> 352 bytes
-rw-r--r--qa/src/slow_af.c152
-rw-r--r--qa/src/snort-disks.0bin0 -> 8416 bytes
-rw-r--r--qa/src/snort-disks.indexbin0 -> 192 bytes
-rw-r--r--qa/src/snort-disks.metabin0 -> 938 bytes
-rw-r--r--qa/src/store.c232
-rw-r--r--qa/src/storepast.c134
-rw-r--r--qa/src/storepdu.c104
-rw-r--r--qa/src/stripmark.c78
-rw-r--r--qa/src/t_fetch.c71
-rw-r--r--qa/src/tabort.c31
-rw-r--r--qa/src/template.c316
l---------qa/src/test_mmv.py1
-rwxr-xr-xqa/src/test_mmv.python109
l---------qa/src/test_pcp.py1
-rwxr-xr-xqa/src/test_pcp.python481
l---------qa/src/test_pcp_getopts.py1
-rwxr-xr-xqa/src/test_pcp_getopts.python113
l---------qa/src/test_pcp_options.py1
-rwxr-xr-xqa/src/test_pcp_options.python96
l---------qa/src/test_pcp_time.py1
-rwxr-xr-xqa/src/test_pcp_time.python33
l---------qa/src/test_pmcc.py1
-rw-r--r--qa/src/test_pmcc.python140
l---------qa/src/test_pmi.py1
-rwxr-xr-xqa/src/test_pmi.python108
l---------qa/src/test_webapi.py1
-rw-r--r--qa/src/test_webapi.python131
-rw-r--r--qa/src/tiny.pmns15
-rw-r--r--qa/src/torture-eol.c249
-rw-r--r--qa/src/torture_api.c516
-rw-r--r--qa/src/torture_cache.c599
-rw-r--r--qa/src/torture_indom.c374
-rw-r--r--qa/src/torture_logmeta.c350
-rw-r--r--qa/src/torture_pmns.c495
-rw-r--r--qa/src/torture_trace.c156
-rw-r--r--qa/src/tstate.c78
-rw-r--r--qa/src/tzchange-10-a.0bin0 -> 436 bytes
-rw-r--r--qa/src/tzchange-10-a.indexbin0 -> 172 bytes
-rw-r--r--qa/src/tzchange-10-a.metabin0 -> 403 bytes
-rw-r--r--qa/src/tzchange-10-b.0bin0 -> 436 bytes
-rw-r--r--qa/src/tzchange-10-b.indexbin0 -> 172 bytes
-rw-r--r--qa/src/tzchange-10-b.metabin0 -> 403 bytes
-rw-r--r--qa/src/tzchange-11-a.0bin0 -> 436 bytes
-rw-r--r--qa/src/tzchange-11-a.indexbin0 -> 172 bytes
-rw-r--r--qa/src/tzchange-11-a.metabin0 -> 403 bytes
-rw-r--r--qa/src/tzchange-11-b.0bin0 -> 436 bytes
-rw-r--r--qa/src/tzchange-11-b.indexbin0 -> 172 bytes
-rw-r--r--qa/src/tzchange-11-b.metabin0 -> 403 bytes
-rw-r--r--qa/src/tzchange-12-a.0bin0 -> 436 bytes
-rw-r--r--qa/src/tzchange-12-a.indexbin0 -> 172 bytes
-rw-r--r--qa/src/tzchange-12-a.metabin0 -> 403 bytes
-rw-r--r--qa/src/tzchange-12-b.0bin0 -> 436 bytes
-rw-r--r--qa/src/tzchange-12-b.indexbin0 -> 172 bytes
-rw-r--r--qa/src/tzchange-12-b.metabin0 -> 403 bytes
-rw-r--r--qa/src/tztest.c81
-rw-r--r--qa/src/unpack.c479
-rw-r--r--qa/src/username.c33
-rw-r--r--qa/src/uwrap.0bin0 -> 5088 bytes
-rw-r--r--qa/src/uwrap.config8
-rw-r--r--qa/src/uwrap.indexbin0 -> 172 bytes
-rw-r--r--qa/src/uwrap.metabin0 -> 408 bytes
-rw-r--r--qa/src/versiondefs18
-rw-r--r--qa/src/vldb-disks.0bin0 -> 13764 bytes
-rw-r--r--qa/src/vldb-disks.indexbin0 -> 192 bytes
-rw-r--r--qa/src/vldb-disks.metabin0 -> 7141 bytes
-rw-r--r--qa/src/whichtimezone.c43
-rw-r--r--qa/src/wrap.0bin0 -> 688 bytes
-rw-r--r--qa/src/wrap.config8
-rw-r--r--qa/src/wrap.indexbin0 -> 172 bytes
-rw-r--r--qa/src/wrap.metabin0 -> 407 bytes
-rw-r--r--qa/src/wrap_int.c120
-rw-r--r--qa/src/write-bf.c106
-rw-r--r--qa/src/xarch.c425
-rw-r--r--qa/src/xbug1.0bin0 -> 512 bytes
-rw-r--r--qa/src/xbug1.indexbin0 -> 192 bytes
-rw-r--r--qa/src/xbug1.metabin0 -> 799 bytes
-rw-r--r--qa/src/xlog.c230
-rw-r--r--qa/src/xmktime.c68
-rw-r--r--qa/src/xval.c525
-rw-r--r--qa/src/xxx.c63
600 files changed, 39735 insertions, 0 deletions
diff --git a/qa/src/19970807.09.54.0 b/qa/src/19970807.09.54.0
new file mode 100644
index 0000000..1219210
--- /dev/null
+++ b/qa/src/19970807.09.54.0
Binary files differ
diff --git a/qa/src/19970807.09.54.index b/qa/src/19970807.09.54.index
new file mode 100644
index 0000000..3d88a0a
--- /dev/null
+++ b/qa/src/19970807.09.54.index
Binary files differ
diff --git a/qa/src/19970807.09.54.meta b/qa/src/19970807.09.54.meta
new file mode 100644
index 0000000..cb42394
--- /dev/null
+++ b/qa/src/19970807.09.54.meta
Binary files differ
diff --git a/qa/src/19970807.09.59.0 b/qa/src/19970807.09.59.0
new file mode 100644
index 0000000..833d142
--- /dev/null
+++ b/qa/src/19970807.09.59.0
Binary files differ
diff --git a/qa/src/19970807.09.59.index b/qa/src/19970807.09.59.index
new file mode 100644
index 0000000..e44d6ba
--- /dev/null
+++ b/qa/src/19970807.09.59.index
Binary files differ
diff --git a/qa/src/19970807.09.59.meta b/qa/src/19970807.09.59.meta
new file mode 100644
index 0000000..7b13202
--- /dev/null
+++ b/qa/src/19970807.09.59.meta
Binary files differ
diff --git a/qa/src/20041125.0 b/qa/src/20041125.0
new file mode 100644
index 0000000..46675ba
--- /dev/null
+++ b/qa/src/20041125.0
Binary files differ
diff --git a/qa/src/20041125.index b/qa/src/20041125.index
new file mode 100644
index 0000000..bd6018f
--- /dev/null
+++ b/qa/src/20041125.index
Binary files differ
diff --git a/qa/src/20041125.meta b/qa/src/20041125.meta
new file mode 100644
index 0000000..3bcc737
--- /dev/null
+++ b/qa/src/20041125.meta
Binary files differ
diff --git a/qa/src/20101004-trunc.0 b/qa/src/20101004-trunc.0
new file mode 100644
index 0000000..2564f12
--- /dev/null
+++ b/qa/src/20101004-trunc.0
Binary files differ
diff --git a/qa/src/20101004-trunc.index b/qa/src/20101004-trunc.index
new file mode 100644
index 0000000..0ec5a54
--- /dev/null
+++ b/qa/src/20101004-trunc.index
Binary files differ
diff --git a/qa/src/20101004-trunc.meta b/qa/src/20101004-trunc.meta
new file mode 100644
index 0000000..37b35d6
--- /dev/null
+++ b/qa/src/20101004-trunc.meta
Binary files differ
diff --git a/qa/src/20130706.0.bz2 b/qa/src/20130706.0.bz2
new file mode 100644
index 0000000..85f157f
--- /dev/null
+++ b/qa/src/20130706.0.bz2
Binary files differ
diff --git a/qa/src/20130706.index b/qa/src/20130706.index
new file mode 100644
index 0000000..69a5704
--- /dev/null
+++ b/qa/src/20130706.index
Binary files differ
diff --git a/qa/src/20130706.meta b/qa/src/20130706.meta
new file mode 100644
index 0000000..7f57943
--- /dev/null
+++ b/qa/src/20130706.meta
Binary files differ
diff --git a/qa/src/540117-short.0 b/qa/src/540117-short.0
new file mode 100644
index 0000000..ad46b4a
--- /dev/null
+++ b/qa/src/540117-short.0
Binary files differ
diff --git a/qa/src/540117-short.index b/qa/src/540117-short.index
new file mode 100644
index 0000000..a80b59d
--- /dev/null
+++ b/qa/src/540117-short.index
Binary files differ
diff --git a/qa/src/540117-short.meta b/qa/src/540117-short.meta
new file mode 100644
index 0000000..364c655
--- /dev/null
+++ b/qa/src/540117-short.meta
Binary files differ
diff --git a/qa/src/541380.0 b/qa/src/541380.0
new file mode 100644
index 0000000..53c06bb
--- /dev/null
+++ b/qa/src/541380.0
Binary files differ
diff --git a/qa/src/541380.index b/qa/src/541380.index
new file mode 100644
index 0000000..8001574
--- /dev/null
+++ b/qa/src/541380.index
Binary files differ
diff --git a/qa/src/541380.meta b/qa/src/541380.meta
new file mode 100644
index 0000000..52122ff
--- /dev/null
+++ b/qa/src/541380.meta
Binary files differ
diff --git a/qa/src/541380_v2.0 b/qa/src/541380_v2.0
new file mode 100644
index 0000000..21e1f8e
--- /dev/null
+++ b/qa/src/541380_v2.0
Binary files differ
diff --git a/qa/src/541380_v2.index b/qa/src/541380_v2.index
new file mode 100644
index 0000000..eb834b5
--- /dev/null
+++ b/qa/src/541380_v2.index
Binary files differ
diff --git a/qa/src/541380_v2.meta b/qa/src/541380_v2.meta
new file mode 100644
index 0000000..a65b6b5
--- /dev/null
+++ b/qa/src/541380_v2.meta
Binary files differ
diff --git a/qa/src/573184.0 b/qa/src/573184.0
new file mode 100644
index 0000000..1412736
--- /dev/null
+++ b/qa/src/573184.0
Binary files differ
diff --git a/qa/src/573184.index b/qa/src/573184.index
new file mode 100644
index 0000000..b72c46f
--- /dev/null
+++ b/qa/src/573184.index
Binary files differ
diff --git a/qa/src/573184.meta b/qa/src/573184.meta
new file mode 100644
index 0000000..24df027
--- /dev/null
+++ b/qa/src/573184.meta
Binary files differ
diff --git a/qa/src/779246.c b/qa/src/779246.c
new file mode 100644
index 0000000..13752ac
--- /dev/null
+++ b/qa/src/779246.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * pv 779246 - check sample pmda returns type on sample.sysinfo
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#ifdef HAVE_SYS_SYSINFO_H
+#include <sys/sysinfo.h>
+#endif
+
+#define NUM 1
+
+static int
+dometric(void)
+{
+ int n;
+ pmID pmid;
+ pmDesc desc;
+ pmResult *result;
+ char *namelist[NUM] = { "sample.sysinfo" };
+ pmID pmidlist[NUM] = { 0 };
+
+ if ((n = pmLookupName(NUM, namelist, pmidlist)) < 0) {
+ printf("pmLookupDesc: %s\n", pmErrStr(n));
+ return 1;
+ }
+
+ pmid=pmidlist[0];
+
+ if ((n = pmLookupDesc(pmid, &desc)) < 0) {
+ printf("pmLookupDesc: %s\n", pmErrStr(n));
+ return 1;
+ }
+ __pmPrintDesc(stdout, &desc);
+
+ if ((n = pmFetch(1, &pmid, &result)) < 0)
+ printf("pmFetch: %s\n", pmErrStr(n));
+
+ if (result->numpmid !=1 ) {
+ printf("pmFetch, numpmid == %d (1)\n",
+ result->numpmid);
+ return 1;
+ }
+
+ if (result->vset[0]->numval < 0) {
+ printf("pmFetch, numval: %s\n", pmErrStr(result->vset[0]->numval));
+ return 1;
+ } else if (result->vset[0]->numval != 1) {
+ printf("pmFetch, numval: == %d (1)\n",
+ result->vset[0]->numval);
+ return 1;
+ }
+
+ if (result->vset[0]->valfmt==PM_VAL_INSITU) {
+ printf("sample.sysinfo is in-situ !?\n");
+ return 1;
+ }
+ printf("sample.sysinfo vtype == %d\n",
+ result->vset[0]->vlist[0].value.pval->vtype);
+
+ __pmDumpResult(stdout, result);
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+ static char *debug = "[-D N] ";
+ static char *usage = "[-h hostname]";
+
+ __pmSetProgname(pmProgname);
+
+ while ((c = getopt(argc, argv, "D:h:")) != EOF) {
+ switch (c) {
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'h': /* hostname for PMCD to contact */
+ host = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc) {
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* Size of struct sysinfo is different on different platforms, so
+ * give a hint how many bytes are expected in the output */
+#ifdef HAVE_SYSINFO
+ printf("+++ Expect %d bytes\n", (int)sizeof(struct sysinfo));
+#else
+ printf("+++ Local struct sysinfo size unknown\n");
+#endif
+ return dometric();
+}
diff --git a/qa/src/951127.23.01.0 b/qa/src/951127.23.01.0
new file mode 100644
index 0000000..1b81a44
--- /dev/null
+++ b/qa/src/951127.23.01.0
Binary files differ
diff --git a/qa/src/951127.23.01.index b/qa/src/951127.23.01.index
new file mode 100644
index 0000000..bd6f34e
--- /dev/null
+++ b/qa/src/951127.23.01.index
Binary files differ
diff --git a/qa/src/951127.23.01.meta b/qa/src/951127.23.01.meta
new file mode 100644
index 0000000..f8f5160
--- /dev/null
+++ b/qa/src/951127.23.01.meta
Binary files differ
diff --git a/qa/src/951127.23.01_v2.0 b/qa/src/951127.23.01_v2.0
new file mode 100644
index 0000000..0721879
--- /dev/null
+++ b/qa/src/951127.23.01_v2.0
Binary files differ
diff --git a/qa/src/951127.23.01_v2.index b/qa/src/951127.23.01_v2.index
new file mode 100644
index 0000000..a305a83
--- /dev/null
+++ b/qa/src/951127.23.01_v2.index
Binary files differ
diff --git a/qa/src/951127.23.01_v2.meta b/qa/src/951127.23.01_v2.meta
new file mode 100644
index 0000000..d34b4a7
--- /dev/null
+++ b/qa/src/951127.23.01_v2.meta
Binary files differ
diff --git a/qa/src/960624.08.17.0 b/qa/src/960624.08.17.0
new file mode 100644
index 0000000..2fc33e6
--- /dev/null
+++ b/qa/src/960624.08.17.0
Binary files differ
diff --git a/qa/src/960624.08.17.index b/qa/src/960624.08.17.index
new file mode 100644
index 0000000..0965614
--- /dev/null
+++ b/qa/src/960624.08.17.index
Binary files differ
diff --git a/qa/src/960624.08.17.meta b/qa/src/960624.08.17.meta
new file mode 100644
index 0000000..635502a
--- /dev/null
+++ b/qa/src/960624.08.17.meta
Binary files differ
diff --git a/qa/src/960624.08.17_v2.0 b/qa/src/960624.08.17_v2.0
new file mode 100644
index 0000000..7866ef7
--- /dev/null
+++ b/qa/src/960624.08.17_v2.0
Binary files differ
diff --git a/qa/src/960624.08.17_v2.index b/qa/src/960624.08.17_v2.index
new file mode 100644
index 0000000..0920904
--- /dev/null
+++ b/qa/src/960624.08.17_v2.index
Binary files differ
diff --git a/qa/src/960624.08.17_v2.meta b/qa/src/960624.08.17_v2.meta
new file mode 100644
index 0000000..648c27c
--- /dev/null
+++ b/qa/src/960624.08.17_v2.meta
Binary files differ
diff --git a/qa/src/GNUlocaldefs b/qa/src/GNUlocaldefs
new file mode 100644
index 0000000..98f85f4
--- /dev/null
+++ b/qa/src/GNUlocaldefs
@@ -0,0 +1,787 @@
+#
+# Copyright (c) 2012-2014 Red Hat.
+# Copyright (c) 2009 Aconex. All Rights Reserved.
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+PMLOGGER = $(PCP_BINADM_DIR)/pmlogger
+PMLOGEXTRACT = $(PCP_BINADM_DIR)/pmlogextract
+
+#DBG = -DPCP_DEBUG -DDEBUG -DMALLOC_AUDIT -g
+DBG = -DPCP_DEBUG -DDEBUG -g
+
+DEBUG = $(DBG)
+
+HAVE_64 = $(shell test `uname -m | sed -e 's/.*64/64/g'` = "64" && echo 1 || echo 0)
+
+SRCARCH = mirage.0 moomba.client.0 \
+ babylon.percpu.0 babylon.percpu_v2.0 \
+ omen.client.0 bozo.client.0 bozo.client_v2.0 \
+ late.0 ok-bigbin.0 ok-mv-bigbin.0 ok-truncbin.0 \
+ babylon.pmview.0 babylon.pmview_v2.0 ok-foo.0 ok-mv-foo.0 \
+ bug.0 bug_v2.0 ace.0 ace_v2.0 bigace.0 bigace_v2.0 \
+ 951127.23.01.0 951127.23.01_v2.0 960624.08.17.0 960624.08.17_v2.0 \
+ rattle.0 mark-bug.0 arch_a.0 arch_b.0 \
+ err_v1.0 changeinst.0 19970807.09.54.0 19970807.09.59.0 \
+ binning.0 wrap.0 573184.0 xbug1.0 pcpcmd.0 markmerge.0 \
+ sample-secs.0 gmt-boring.0 kenj-pc-1.0 kenj-pc-2.0 \
+ reduce-1.0 reduce-2.0 kenj-pc-diskstat.0 snort-disks.0 \
+ vldb-disks.0 moomba.pmkstat.0 fcsw_indom.0 \
+ uwrap.0 20041125.0 ac15.0 conn20070309.0 logsummary-bug.0 \
+ tzchange-10-a.0 tzchange-10-b.0 tzchange-11-a.0 tzchange-11-b.0 \
+ tzchange-12-a.0 tzchange-12-b.0 sample_expr.0 \
+ mirage-1.0 mirage-2.0 eventrec-old.0 eventrec.0 \
+ badlen-0.0 badlen-1.0 badlen-2.0 badlen-3.0 badlen-4.0 \
+ badlen-5.0 badlen-6.0 badlen-7.0 badlen-8.0 badlen-9.0 \
+ badlen-10.0 badlen-11.0 \
+ 540117-short.0 541380.0 541380_v2.0 573184.0 20101004-trunc.0 \
+ bozo.client_v2.meta.bad.1 bozo.client_v2.meta.bad.2 \
+ rewrite.0 proc.0 section-a.0 section-b.0 section-c.0 section-d.0 \
+ interpmark.0 all-irix-6.5.25.0 all-sles9-sp1.0 naslog.0 \
+ multi-vm00.0 multi-vm01.0 multi-vm02.0 multi-vm03.0 pmatop-log.0 \
+ new_mysql.0 new_snmp.0 old_xfs.0 node_archive.0 count-mark.0 \
+ pyapi.0 pcp-free.0 pcp-uptime.0 pcp-numastat-1-node.0 numa.0 \
+ slow.0 bug1057.0
+
+SRCARCHPART = ok-noti-bigbin.0 pmatop-log.folio \
+ 20130706.0.bz2 20130706.index 20130706.meta
+
+MKARCH = foo.0 mv-foo.0 noti-foo.0 bar.0 mv-bar.0 noti-bar.0 \
+ bigbin.0 mv-bigbin.0 noti-bigbin.0 truncbin.0 null.0 \
+ interp.0 mv-interp.0 noti-interp.0 noti-ok-foo.0 gap.0 gap2.0 \
+ dodgey-some.0 dodgey-all.0 dodgey-mixed.0 reduce-gap.0
+
+CFILES = disk_test.c exercise.c context_test.c chkoptfetch.c \
+ xval.c xxx.c chkopenlog.c chkconnect.c t_fetch.c \
+ hp-mib.c agenttimeout.c chkctx2.c pmcdgone.c chkhelp.c \
+ scale.c chktrim.c store.c torture_api.c logcontrol.c xlog.c \
+ hex2nbo.c chknumval.c xarch.c eofarch.c defctx.c chkacc1.c chkacc2.c \
+ chkacc3.c storepast.c pmdashutdown.c exertz.c badpmcdpmid.c \
+ permfetch.c archinst.c pmlcmacro.c whichtimezone.c eol.c \
+ interp0.c interp1.c interp2.c interp3.c interp4.c \
+ pcp_lite_crash.c compare.c mkfiles.c nameall.c nullinst.c \
+ storepdu.c fetchpdu.c badloglabel.c interp_bug2.c interp_bug.c \
+ xmktime.c descreqX2.c recon.c torture_indom.c \
+ fetchrate.c stripmark.c pmnsinarchives.c \
+ endian.c chk_memleak.c chk_metric_types.c mark-bug.c \
+ pmnsunload.c parsemetricspec.c parseinterval.c \
+ pducheck.c pducrash.c pdu-server.c \
+ pmprintf.c pmsocks_objstyle.c numberstr.c \
+ read-bf.c write-bf.c slow_af.c indom.c tztest.c \
+ multifetch.c pmconvscale.c torture-eol.c \
+ crashpmcd.c dumb_pmda.c torture_cache.c wrap_int.c \
+ matchInstanceName.c torture_pmns.c \
+ mmv_genstats.c mmv_instances.c mmv_poke.c mmv_noinit.c mmv_nostats.c \
+ record.c record-setarg.c clientid.c killparent.c grind_ctx.c \
+ pmdacache.c check_import.c unpack.c hrunpack.c aggrstore.c atomstr.c \
+ grind_conv.c getconfig.c err.c torture_logmeta.c keycache.c \
+ keycache2.c pmdaqueue.c drain-server.c template.c anon-sa.c \
+ username.c rtimetest.c getcontexthost.c badpmda.c chkputlogresult.c \
+ churnctx.c
+
+ifeq ($(shell test -f ../localconfig && echo 1), 1)
+include ../localconfig
+else
+ifeq ($(shell cd ..; ( $(MAKE) localconfig >/dev/null && echo 1 )), 1)
+include ../localconfig
+else
+$(error Cannot make qa/localconfig)
+endif
+endif
+
+ifeq ($(shell test $(PCP_VER) -ge 3600 && echo 1), 1)
+CFILES += multithread0.c multithread1.c multithread2.c multithread3.c \
+ multithread4.c multithread5.c multithread6.c multithread7.c \
+ multithread8.c multithread9.c \
+ exerlock.c
+else
+MYFILES += multithread0.c multithread1.c multithread2.c multithread3.c \
+ multithread4.c multithread5.c multithread6.c multithread7.c \
+ multithread8.c multithread9.c \
+ exerlock.c
+LDIRT += multithread0 multithread1 multithread2 multithread3 \
+ multithread4 multithread5 multithread6 multithread7 \
+ multithread8 multithread9 \
+ exerlock
+endif
+
+ifeq ($(shell test $(PCP_VER) -ge 3700 && echo 1), 1)
+CFILES += hashwalk.c
+else
+MYFILES += hashwalk.c
+LDIRT += hashwalk
+endif
+
+ifeq ($(shell test $(PCP_VER) -ge 3800 && echo 1), 1)
+CFILES += parsehostattrs.c parsehostspec.c check_import_name.c
+else
+MYFILES += parsehostattrs.c parsehostspec.c check_import_name.c
+LDIRT += parsehostattrs parsehostspec check_import_name
+endif
+
+ifeq ($(shell test $(PCP_VER) -ge 3802 && echo 1), 1)
+CFILES += chkacc4.c
+else
+MYFILES += chkacc4.c
+LDIRT += chkacc4
+endif
+
+ifeq ($(shell test $(PCP_VER) -ge 3901 && echo 1), 1)
+CFILES += getoptions.c
+else
+MYFILES += getoptions.c
+LDIRT += getoptions
+endif
+
+ifeq ($(shell test $(PCP_VER) -ge 3811 && echo 1), 1)
+CONFIG_INTERP = config2.interp
+else
+CONFIG_INTERP = config1.interp
+endif
+
+ifeq ($(shell test -f /usr/include/pcp/fault.h && echo 1), 1)
+# only make these ones if the fault injection version of libpcp
+# appears to have been installed (assumes PCP >= 3.5), and then
+# only for the setup target (so not in the build)
+#
+XTRATARGETS += check_fault_injection exercise_fault
+endif
+MYFILES += check_fault_injection.c exercise_fault.c
+LDIRT += check_fault_injection exercise_fault
+
+POSIXFILES = \
+ ipc.c proc_test.c context_fd_leak.c arch_maxfd.c torture_trace.c \
+ 779246.c
+
+TRACEFILES = \
+ obs.c tstate.c tabort.c
+
+PERLFILES = \
+ batch_import.perl check_import.perl import_limit_test.perl
+# not installed:
+PLFILES = $(shell echo $(PERLFILES) | sed -e 's/\.perl/.pl/g')
+
+PYTHONFILES = \
+ test_pcp.python test_pmcc.python \
+ test_pmi.python check_import.python \
+ test_mmv.python test_webapi.python \
+ test_pcp_options.python test_pcp_getopts.python \
+ test_pcp_time.python
+# not installed:
+PYFILES = $(shell echo $(PYTHONFILES) | sed -e 's/\.python/.py/g')
+
+ifneq "$(TARGET_OS)" "mingw"
+CFILES += $(POSIXFILES) $(TRACEFILES)
+else
+MYFILES += $(POSIXFILES) $(TRACEFILES)
+endif
+
+MYFILES += $(SRCARCH) \
+ $(patsubst %.0,%.meta,$(SRCARCH)) $(patsubst %.0,%.index,$(SRCARCH)) \
+ ok-mv-bigbin.[1-9] ok-mv-foo.[12] \
+ $(SRCARCHPART) \
+ ok-noti-bigbin.meta err_v1.dump \
+ bigace.pmns \
+ config.bar config.bigbin config.dodgey-all config.dodgey-mixed \
+ config.dodgey-some config.foo config1.interp config2.interp \
+ kenj-pc-2.config reduce.config uwrap.config wrap.config \
+ root_irix root_pmns tiny.pmns sgi.bf versiondefs \
+ simple.csv simple.ods simple-resave.csv simple-resave.xlsx \
+ simple.sxc simple.xls simple.xlsx \
+ iostat iostat-c iostat-d iostat-d-k iostat-d-m iostat-p-ALL \
+ iostat-t iostat-t.ISO iostat-x iostat-z iostat-z-p-ALL \
+ pthread_barrier.h pv.c qa_test.c qa_timezone.c \
+ sa-sysstat-9.0.4 sa-sysstat-9.0.6 sa-sysstat-9.0.6.1 \
+ sa-sysstat-10.0.1 sa-sysstat-10.0.5 sa-sysstat-10.2.0 \
+ permslist
+
+MYSCRIPTS = grind-tools ipcs_clear make.dodgey mkarch-all mkbadlen \
+ mkeventrec mkinterpmark mkmirage mkproc mkrewrite mksample_expr \
+ mksa-sysstat mktzchange show-args mkbig1 fixhosts mkpermslist \
+ memcachestats.pl
+
+PSCRIPTS = $(PERLFILES) $(PYTHONFILES)
+
+CFILES_TARGETS = $(CFILES)
+
+TARGETS = $(subst broken_pmda,,$(basename $(CFILES_TARGETS))) \
+ chkctx2_lite template \
+ fetchrate_lite pv
+
+ifeq ($(HAVE_64), 1)
+TARGETS += pv64
+endif
+
+LCFLAGS = -DHAVE_TRACE
+LLDLIBS = $(PCPLIB) $(LDFLAGS)
+
+ifneq ($(NVIDIAQALIB),)
+LIBTARGET = true
+MYCFILES += nvidia-ml.c
+LCFLAGS += $(NVIDIACFLAGS)
+TARGETS += $(NVIDIAQALIB)
+endif
+
+# libpcp_trace is ready
+TRACELIB = -lpcp_trace $(LLDLIBS)
+
+# all archives, except the ones checked into the source tree,
+# then add executables beyond $(TARGETS)
+#
+LDIRT += *.log domain.h help.pag help.dir \
+ foo.0 foo.index foo.meta \
+ mv-foo.[0-9] mv-foo.index mv-foo.meta \
+ noti-foo.0 noti-foo.meta \
+ bar.0 bar.index bar.meta \
+ big[0-2].[0-2] big[0-2].index big[0-2].meta \
+ mv-bar.[0-9] mv-bar.index mv-bar.meta \
+ noti-bar.0 noti-bar.meta \
+ bigbin.0 bigbin.index bigbin.meta \
+ mv-bigbin.[0-9] mv-bigbin.index mv-bigbin.meta \
+ noti-bigbin.0 noti-bigbin.meta \
+ truncbin.0 truncbin.index truncbin.meta \
+ null.0 null.index null.meta \
+ interp.0 interp.index interp.meta \
+ mv-interp.[0-9] mv-interp.index mv-interp.meta \
+ noti-interp.0 noti-interp.meta \
+ noti-ok-foo.0 noti-ok-foo.meta \
+ gap.0 gap.index gap.meta \
+ gap2.0 gap2.index gap2.meta \
+ dodgey-some.0 dodgey-some.index dodgey-some.meta \
+ dodgey-all.0 dodgey-all.index dodgey-all.meta \
+ dodgey-mixed.0 dodgey-mixed.index dodgey-mixed.meta \
+ reduce-gap.0 reduce-gap.index reduce-gap.meta \
+ chkctx2_lite.c fetchrate_lite.c \
+ localconfig.h gmon.out \
+ $(TARGETS)
+
+.ORDER: torture_api \
+ chkctx2 fetchrate
+
+default default_pcp: \
+ $(CFILES_TARGETS) $(TARGETS) \
+ $(SRCARCH) $(SRCARCHPART) \
+ $(PLFILES) $(PYFILES) \
+ ipcs_clear
+
+setup: default $(MKARCH) $(XTRATARGETS)
+
+$(TARGETS):
+
+include $(BUILDRULES)
+
+# remove just the binaries, not the archives
+#
+clean-exec:
+ rm -f $(TARGETS)
+ rm -f $(OBJECTS)
+ rm -f pv64
+
+# remake just the archives, not the binaries
+#
+clean-arch:
+ rm -f $(MKARCH) $(subst 0,meta,$(MKARCH)) $(subst 0,index,$(MKARCH))
+
+OBJECTS = $(shell echo $(CFILES) | sed -e 's/\.c/.o/g')
+
+# make just the archives, not the binaries
+#
+arch: $(SRCARCH) $(SRCARCHPART) $(MKARCH)
+
+# --- do NOT need libpcp
+#
+
+pause: pause.c
+ $(CCF) $(CDEFS) -o pause pause.c
+
+errmap: errmap.c
+ $(CCF) $(CDEFS) -o errmap errmap.c
+
+cpuload: cpuload.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ cpuload.c
+
+load_o2000: load_o2000.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ load_o2000.c
+
+chain: chain.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ chain.c
+
+syscall: syscall.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ syscall.c
+
+getpagesize: getpagesize.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ getpagesize.c
+
+rdwr: rdwr.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ rdwr.c
+
+spawn: spawn.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ spawn.c
+
+diowr: diowr.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ diowr.c
+
+endian: endian.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ endian.c
+
+pmlcmacro: pmlcmacro.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ pmlcmacro.c
+
+sys5_ipc: sys5_ipc.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ sys5_ipc.c
+
+stripmark: stripmark.c
+ $(CCF) $(CDEFS) -o $@ stripmark.c
+
+anon-sa: anon-sa.c
+ $(CCF) $(CDEFS) -o $@ anon-sa.c
+
+# --- need libpcp
+#
+
+template: template.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ template.c $(LDLIBS)
+
+exercise: exercise.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ exercise.c $(LDLIBS)
+
+chkacc1: chkacc1.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ chkacc1.c $(LDLIBS)
+
+chkacc2: chkacc2.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ chkacc2.c $(LDLIBS)
+
+chkacc3: chkacc3.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ chkacc3.c $(LDLIBS)
+
+ipc: ipc.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ ipc.c $(LDLIBS)
+
+chk_memleak: chk_memleak.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ chk_memleak.c $(LDLIBS)
+
+chknumval: chknumval.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ chknumval.c $(LDLIBS)
+
+logcontrol: logcontrol.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ logcontrol.c $(LDLIBS)
+
+numberstr: numberstr.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ numberstr.c $(LDLIBS)
+
+pmcdgone: pmcdgone.c localconfig.h
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ pmcdgone.c $(LDLIBS)
+
+slow_af: slow_af.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ slow_af.c $(LDLIBS)
+
+mmv_poke: mmv_poke.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ mmv_poke.c $(LDLIBS)
+
+# --- need libpcp but also PM_CONTEXT_LOCAL
+#
+
+fetchrate_lite: fetchrate_lite.c
+ rm -f $@
+ $(CCF) $(CDEFS) -DLITE=1 -o $@ fetchrate_lite.c $(LDLIBS)
+
+fetchrate_lite.c: fetchrate.c
+ rm -f $@
+ ln -s fetchrate.c fetchrate_lite.c
+
+chkctx2_lite: chkctx2_lite.c
+ rm -f $@
+ $(CCF) $(CDEFS) -DLITE=1 -o $@ chkctx2_lite.c $(LDLIBS)
+
+chkctx2_lite.c: chkctx2.c
+ rm -f $@
+ ln -s chkctx2.c chkctx2_lite.c
+
+hp-mib: hp-mib.c
+ rm -f $@
+ $(CCF) $(CDEFS) -DLITE=1 -o $@ hp-mib.c $(LDLIBS)
+
+pcp_lite_crash: pcp_lite_crash.c
+ rm -f $@
+ $(CCF) $(CDEFS) -DLITE=1 -o $@ pcp_lite_crash.c $(LDLIBS)
+
+store: store.c
+ rm -f $@
+ $(CCF) $(CDEFS) -DLITE=1 -o $@ store.c $(LDLIBS)
+
+# --- need libpcp_pmda
+#
+
+domain.h: $(PCP_VAR_DIR)/pmns/stdpmid
+ rm -f $@
+ echo "/*" >domain.h
+ echo " * built from $(PCP_VAR_DIR)/pmns/stdpmid on `date`" >>domain.h
+ echo " */" >>domain.h
+ sed -n -e 's/[ ]*$$//' -e '/define[ ]BROKEN[ ]/s/.*[ ]/#define BROKEN /p' $(PCP_VAR_DIR)/pmns/stdpmid >>domain.h
+ sed -n -e 's/[ ]*$$//' -e '/define[ ]DYNAMIC[ ]/s/.*[ ]/#define DYNAMIC /p' $(PCP_VAR_DIR)/pmns/stdpmid >>domain.h
+
+pmdashutdown: pmdashutdown.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ pmdashutdown.c -lpcp_pmda $(LDLIBS)
+
+dumb_pmda: dumb_pmda.c
+ $(CCF) $(LCDEFS) $(LCOPTS) -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+pmdacache: pmdacache.c
+ $(CCF) $(LCDEFS) $(LCOPTS) -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+pmdaqueue: pmdaqueue.c
+ $(CCF) $(LCDEFS) $(LCOPTS) -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+atomstr: atomstr.c
+ $(CCF) $(LCDEFS) $(LCOPTS) -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+keycache: keycache.c
+ $(CCF) $(LCDEFS) $(LCOPTS) -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+keycache2: keycache2.c
+ $(CCF) $(LCDEFS) $(LCOPTS) -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+badpmda: badpmda.c
+ $(CCF) $(LCDEFS) $(LCOPTS) -o $@ $@.c -lpcp_pmda $(LDLIBS)
+
+# --- need libpcp_gui
+#
+
+record: record.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c -lpcp_gui $(LDLIBS)
+
+record-setarg: record-setarg.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c -lpcp_gui $(LDLIBS)
+
+# --- need libpcp_mmv
+#
+mmv_genstats: mmv_genstats.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c -lpcp_mmv $(LDLIBS)
+
+mmv_instances: mmv_instances.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c -lpcp_mmv $(LDLIBS)
+
+mmv_noinit: mmv_noinit.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c -lpcp_mmv $(LDLIBS)
+
+mmv_nostats: mmv_nostats.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c -lpcp_mmv $(LDLIBS)
+
+pducheck: pducheck.o
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ pducheck.o $(TRACELIB) -lpcp_pmda $(LDLIBS)
+
+pducrash: pducrash.o
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ pducrash.o $(TRACELIB) $(LDLIBS)
+
+pdu-server: pdu-server.o
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ pdu-server.o $(TRACELIB) $(LIBSOL) $(LDLIBS)
+
+torture_cache: torture_cache.o
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ torture_cache.o -lpcp_pmda $(LDLIBS)
+
+obs: obs.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ obs.c $(TRACELIB)
+
+torture_trace: torture_trace.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ torture_trace.c $(LIB_FOR_PTHREADS) $(TRACELIB)
+
+tstate: tstate.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ tstate.c $(TRACELIB)
+
+tabort: tabort.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ tabort.c $(TRACELIB)
+
+# --- need libpcp_import
+#
+
+check_import: check_import.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c -lpcp_import $(LDLIBS)
+
+check_import_name: check_import_name.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c -lpcp_import $(LDLIBS)
+
+# --- need libpcp_fault
+#
+
+check_fault_injection: check_fault_injection.c
+ rm -f $@
+ $(CCF) $(CDEFS) -DPM_FAULT_INJECTION=1 -o $@ $@.c -lpcp_fault -lpcp -lpcp_pmda
+
+exercise_fault: exercise_fault.c
+ rm -f $@
+ $(CCF) $(CDEFS) -DPM_FAULT_INJECTION=1 -o $@ $@.c -lpcp_fault -lpcp -lpcp_pmda
+
+# --- need lib for pthreads
+#
+
+multithread0: multithread0.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c $(LIB_FOR_PTHREADS) $(LDLIBS)
+
+multithread1: multithread1.c
+ rm -f $@
+ifeq "$(TARGET_OS)" "darwin"
+ @# see comments in multithread1.c to explain this crock
+ $(CCF) $(CDEFS) -Ddarwin_hack=1 -o $@ $@.c $(LIB_FOR_PTHREADS) -framework CoreFoundation $(LDLIBS)
+else
+ $(CCF) $(CDEFS) -o $@ $@.c $(LIB_FOR_PTHREADS) $(LDLIBS)
+endif
+
+multithread2: multithread2.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c $(LIB_FOR_PTHREADS) $(LDLIBS)
+
+multithread3: multithread3.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c $(LIB_FOR_PTHREADS) $(LDLIBS)
+
+multithread4: multithread4.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c $(LIB_FOR_PTHREADS) $(LDLIBS)
+
+multithread5: multithread5.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c $(LIB_FOR_PTHREADS) $(LDLIBS)
+
+multithread6: multithread6.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c $(LIB_FOR_PTHREADS) $(LDLIBS)
+
+multithread7: multithread7.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c $(LIB_FOR_PTHREADS) $(LDLIBS)
+
+multithread8: multithread8.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c $(LIB_FOR_PTHREADS) $(LDLIBS)
+
+multithread9: multithread9.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c $(LIB_FOR_PTHREADS) $(LDLIBS)
+
+exerlock: exerlock.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ $@.c $(LIB_FOR_PTHREADS) $(LDLIBS)
+
+# --- binary format dependencies
+#
+
+ifeq ($(HAVE_64), 1)
+pv64: pv.c
+ $(CCF) $(CDEFS) -o $@ pv.c $(LDLIBS)
+endif
+
+# -- archives
+#
+
+foo.0: config.foo
+ rm -f foo.index foo.meta foo.0
+ $(PMLOGGER) -c config.foo -s 8 foo
+
+mv-foo.0: config.foo
+ rm -f mv-foo.index mv-foo.meta mv-foo.?
+ $(PMLOGGER) -c config.foo -s 8 -v 3 mv-foo
+
+noti-foo.0: foo.0
+ cp foo.0 noti-foo.0
+ cp foo.meta noti-foo.meta
+
+noti-ok-foo.0: ok-foo.0
+ cp ok-foo.0 noti-ok-foo.0
+ cp ok-foo.meta noti-ok-foo.meta
+
+bar.0: config.bar
+ rm -f bar.index bar.meta bar.0
+ $(PMLOGGER) -c config.bar -s 70 bar
+
+mv-bar.0: config.bar
+ rm -f mv-bar.index mv-bar.meta mv-bar.?
+ $(PMLOGGER) -c config.bar -s 70 -v 20 mv-bar
+
+noti-bar.0: bar.0
+ cp bar.0 noti-bar.0
+ cp bar.meta noti-bar.meta
+
+mirage.0:
+ rm -f mirage.index mirage.meta mirage.0
+ $(PMLOGGER) -c config.mirage -s 20 mirage
+
+dodgey-some.0: make.dodgey config.dodgey-some
+ ./make.dodgey some 50
+
+dodgey-all.0: make.dodgey config.dodgey-all
+ ./make.dodgey all 50
+
+dodgey-mixed.0: make.dodgey config.dodgey-mixed
+ ./make.dodgey mixed 150
+
+bigbin.0: config.bigbin
+ rm -f bigbin.index bigbin.meta bigbin.0
+ sync
+ sleep 3
+ $(PMLOGGER) -c config.bigbin -s 1000 bigbin
+
+mv-bigbin.0: config.bigbin
+ rm -f mv-bigbin.index mv-bigbin.meta mv-bigbin.?
+ sync
+ sleep 3
+ $(PMLOGGER) -c config.bigbin -s 1000 -v 101 mv-bigbin
+
+noti-bigbin.0: bigbin.0
+ cp bigbin.0 noti-bigbin.0
+ cp bigbin.meta noti-bigbin.meta
+
+interp.0: $(CONFIG_INTERP)
+ rm -f interp.index interp.meta interp.0
+ $(PMLOGGER) -c $(CONFIG_INTERP) -s 30 interp
+
+mv-interp.0: $(CONFIG_INTERP)
+ rm -f mv-interp.index mv-interp.meta mv-interp.?
+ $(PMLOGGER) -c $(CONFIG_INTERP) -s 30 -v 10 mv-interp
+
+noti-interp.0: interp.0
+ cp interp.0 noti-interp.0
+ cp interp.meta noti-interp.meta
+
+truncbin.0: bigbin.0
+ rm -f truncbin.index truncbin.meta truncbin.0
+ ln bigbin.meta truncbin.meta
+ ln bigbin.index truncbin.index
+ dd ibs=1024 count=200 if=bigbin.0 of=truncbin.0
+
+# just the label record
+null.0: foo.0
+ rm -f null.index null.meta null.0
+ ln foo.meta null.meta
+ ln foo.index null.index
+ dd ibs=132 count=1 if=foo.0 of=null.0
+
+# 4 secs, 3 sec gap, 4 secs, 3 sec gap, 4 secs
+# and indom changes ... checked in, this is the recipe that was
+# used
+#
+changeinst.0:
+ rm -rf tmp
+ mkdir tmp
+ echo 'log mandatory on once { hinv.ncpu }' >tmp/A.config
+ echo 'log mandatory on 1sec {' >>tmp/A.config
+ echo ' sample.seconds,hinv.ncpu,sample.bin["bin-100","bin-200","bin-400"]' >>tmp/A.config
+ echo ' sample.drift' >>tmp/A.config
+ echo ' irix.network.interface.total.packets["lo0","ec0"]' >>tmp/A.config
+ echo '}' >>tmp/A.config
+ echo 'log mandatory on once { sample.bin["bin-500"] }' >tmp/B.config
+ echo 'log mandatory on 1sec {' >>tmp/B.config
+ echo ' sample.seconds,sample.milliseconds,sample.bin["bin-100","bin-300","bin-400"]' >>tmp/B.config
+ echo '}' >>tmp/B.config
+ echo 'log mandatory on once { hinv.ncpu }' >tmp/C.config
+ echo 'log mandatory on 1sec {' >>tmp/C.config
+ echo ' sample.drift' >>tmp/C.config
+ echo ' sample.seconds,sample.bin["bin-200","bin-300","bin-400","bin-500"]' >>tmp/C.config
+ echo ' irix.network.interface.total.packets["ec2","lo0"]' >>tmp/C.config
+ echo '}' >>tmp/C.config
+ $(PMLOGGER) -s 5 -c tmp/A.config tmp/A
+ sleep 3
+ $(PMLOGGER) -s 5 -c tmp/B.config tmp/B
+ sleep 3
+ $(PMLOGGER) -s 5 -c tmp/C.config tmp/C
+ rm -f changeinst.index changeinst.meta changeinst.0
+ $(PMLOGEXTRACT) tmp/A tmp/B tmp/C changeinst
+ rm -rf tmp
+
+# gap: 10 sec data, 5 sec gap, 10 sec data
+# gap2: 10 sec data, 5 sec gap, 10 sec data, 5 sec gap, 10 sec data
+# sample.bin instances change across gaps
+#
+gap.0 gap2.0:
+ rm -rf tmp
+ mkdir tmp
+ echo 'log mandatory on 1sec { pmcd.pdu_in,pmcd.numagents,hinv.ncpu,sample.bin["bin-100","bin-200","bin-400"] }' >tmp/A.config
+ echo 'log mandatory on 1sec { pmcd.pdu_in,pmcd.numagents,hinv.ncpu,sample.bin["bin-100","bin-300","bin-400"] }' >tmp/B.config
+ echo 'log mandatory on 1sec { pmcd.pdu_in,pmcd.numagents,hinv.ncpu,sample.bin["bin-100","bin-400"] }' >tmp/C.config
+ $(PMLOGGER) -s 10 -c tmp/A.config tmp/A
+ sleep 5
+ $(PMLOGGER) -s 10 -c tmp/B.config tmp/B
+ sleep 5
+ $(PMLOGGER) -s 10 -c tmp/C.config tmp/C
+ rm -f gap.index gap.meta gap.0
+ $(PMLOGEXTRACT) tmp/A tmp/B gap
+ rm -f gap2.index gap2.meta gap2.0
+ $(PMLOGEXTRACT) tmp/A tmp/B tmp/C gap2
+ rm -rf tmp
+
+reduce-gap.0: reduce-1.0 reduce-2.0
+ rm -f reduce-gap.*
+ $(PMLOGEXTRACT) reduce-1 reduce-2 reduce-gap
+
+torture_indom: torture_indom.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ torture_indom.c $(LDLIBS)
+
+torture_pmns: torture_pmns.c
+ rm -f $@
+ $(CCF) $(CDEFS) -o $@ torture_pmns.c $(LDLIBS)
+
+# --- miscellaneous
+#
+qa_timezone.$(DSOSUFFIX): qa_timezone.o
+ $(LD) -shared -o $@ -nostdlib $<
+
+ifneq ($(NVIDIAQALIB),)
+$(NVIDIAQALIB): nvidia-ml.o
+ $(CC) $(LDFLAGS) $(_SHAREDOPTS) -o $@ $<
+endif
+
+arch_maxfd.o: localconfig.h
+scale.o: localconfig.h
+
+bozo:
+ @echo TARGETS=$(TARGETS)
+
+# Suffix rules to support transition for perl and python scripts
+%.py : %.python
+ $(LN_S) $< $@
+
+%.pl : %.perl
+ $(LN_S) $< $@
+
diff --git a/qa/src/GNUmakefile b/qa/src/GNUmakefile
new file mode 100644
index 0000000..c1b715f
--- /dev/null
+++ b/qa/src/GNUmakefile
@@ -0,0 +1,35 @@
+#!gmake
+#
+# Copyright (c) 2012,2014 Red Hat.
+# Copyright (c) 2009 Aconex. All Rights Reserved.
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+TOPDIR = ../..
+include $(TOPDIR)/src/include/builddefs
+
+TESTDIR = $(PCP_VAR_DIR)/testsuite/src
+
+LLDFLAGS = -L$(TOPDIR)/src/libpcp_trace/$(LIBPCP_ABIDIR) \
+ -L$(TOPDIR)/src/libpcp_mmv/$(LIBPCP_ABIDIR) \
+ -L$(TOPDIR)/src/libpcp_gui/$(LIBPCP_ABIDIR) \
+ -L$(TOPDIR)/src/libpcp_import/$(LIBPCP_ABIDIR)
+
+NVIDIACFLAGS = -I$(TOPDIR)/src/pmdas/nvidia
+NVIDIAQALIB = libnvidia-ml.$(DSOSUFFIX)
+
+LSRCFILES = $(MYFILES) $(MYSCRIPTS) $(PSCRIPTS) GNUmakefile.install GNUlocaldefs
+LDIRT += localconfig.h
+
+include GNUlocaldefs
+
+localconfig.h: ../localconfig
+ @awk -F= '{ print "#define",$$1,$$2 }' < ../localconfig > localconfig.h
+
+install install_pcp:
+ $(INSTALL) -m 755 -d $(TESTDIR)
+ $(INSTALL) -m 644 $(CFILES) $(MYFILES) $(PSCRIPTS) $(TESTDIR)
+ $(INSTALL) -m 755 $(MYSCRIPTS) $(TESTDIR)
+ $(INSTALL) -m 755 $(NVIDIAQALIB) $(TESTDIR)/$(NVIDIAQALIB)
+ $(INSTALL) -m 644 GNUlocaldefs $(TESTDIR)/GNUlocaldefs
+ $(INSTALL) -m 644 GNUmakefile.install $(TESTDIR)/GNUmakefile
diff --git a/qa/src/GNUmakefile.install b/qa/src/GNUmakefile.install
new file mode 100644
index 0000000..1e41df4
--- /dev/null
+++ b/qa/src/GNUmakefile.install
@@ -0,0 +1,43 @@
+#!gmake
+#
+# Copyright (c) 2012 Red Hat.
+# Copyright (c) 2009 Aconex. All Rights Reserved.
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+
+ifdef PCP_CONF
+include $(PCP_CONF)
+else
+include $(PCP_DIR)/etc/pcp.conf
+endif
+PATH = $(shell . $(PCP_DIR)/etc/pcp.env; echo $$PATH)
+include $(PCP_INC_DIR)/builddefs
+
+# remove -Lpath and -Ipath options from builddefs CFLAGS value
+#
+PCP_LIBS =
+TMP := $(CFLAGS:-I%=)
+ifdef PCP_DIR
+# put -Ipath and -Lpath back but use paths for run-time environment
+#
+CFLAGS = $(TMP) -I$(PCP_INC_DIR)/..
+LDFLAGS = -L$(PCP_LIB_DIR)
+else
+CFLAGS = $(TMP)
+endif
+
+ifeq ($(shell test -f ../localconfig && echo 1), 1)
+include ../localconfig
+else
+# Warning: ../localconfig does not exist, assuming PCP 3.0
+PCP_VER=3000
+endif
+LDIRT += localconfig.h
+
+include GNUlocaldefs
+
+localconfig.h:
+ @cd .. && ./mk.localconfig
+ @awk -F= '{ print "#define",$$1,$$2 }' < ../localconfig > localconfig.h
+
+install install_pcp:
diff --git a/qa/src/ac15.0 b/qa/src/ac15.0
new file mode 100644
index 0000000..e73e4c6
--- /dev/null
+++ b/qa/src/ac15.0
Binary files differ
diff --git a/qa/src/ac15.index b/qa/src/ac15.index
new file mode 100644
index 0000000..82fe81c
--- /dev/null
+++ b/qa/src/ac15.index
Binary files differ
diff --git a/qa/src/ac15.meta b/qa/src/ac15.meta
new file mode 100644
index 0000000..a64c0f4
--- /dev/null
+++ b/qa/src/ac15.meta
Binary files differ
diff --git a/qa/src/ace.0 b/qa/src/ace.0
new file mode 100644
index 0000000..c66a917
--- /dev/null
+++ b/qa/src/ace.0
Binary files differ
diff --git a/qa/src/ace.index b/qa/src/ace.index
new file mode 100644
index 0000000..9370506
--- /dev/null
+++ b/qa/src/ace.index
Binary files differ
diff --git a/qa/src/ace.meta b/qa/src/ace.meta
new file mode 100644
index 0000000..bb73f28
--- /dev/null
+++ b/qa/src/ace.meta
Binary files differ
diff --git a/qa/src/ace_v2.0 b/qa/src/ace_v2.0
new file mode 100644
index 0000000..6d33f60
--- /dev/null
+++ b/qa/src/ace_v2.0
Binary files differ
diff --git a/qa/src/ace_v2.index b/qa/src/ace_v2.index
new file mode 100644
index 0000000..fc818b8
--- /dev/null
+++ b/qa/src/ace_v2.index
Binary files differ
diff --git a/qa/src/ace_v2.meta b/qa/src/ace_v2.meta
new file mode 100644
index 0000000..5b52391
--- /dev/null
+++ b/qa/src/ace_v2.meta
Binary files differ
diff --git a/qa/src/agenttimeout.c b/qa/src/agenttimeout.c
new file mode 100644
index 0000000..dbcd3ba
--- /dev/null
+++ b/qa/src/agenttimeout.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <sys/types.h>
+#include <time.h>
+#include <stdio.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ int timeout;
+ int domain;
+ char *endPtr;
+ time_t tBegin, tEnd;
+ char *name;
+ pmID timeoutPmid;
+ pmResult *result;
+ pmID pmid;
+ int sts;
+ unsigned pmcdTimeout;
+ unsigned oldTimeout;
+ pmValueSet *vsp;
+ __pmID_int *pip;
+ int tElapsed;
+ int tMax;
+ int errflag = 0;
+
+ __pmSetProgname(pmProgname);
+
+ while ((c = getopt(argc, argv, "D:?")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ argc -= optind-1;
+ argv += optind-1;
+
+ if (errflag || argc != 3) {
+ fprintf(stderr, "Usage: agenttimeout domain timeout\n");
+ exit(1);
+ }
+
+ domain = strtol(argv[1], &endPtr, 0);
+ if (*endPtr != '\0' || domain < 0 || domain >= 255) {
+ fprintf(stderr, "domain '%s' is not a valid pmID domain identifier\n", argv[1]);
+ exit(1);
+ }
+
+ timeout = strtol(argv[2], &endPtr, 0);
+ if (*endPtr != '\0' || timeout < 0) {
+ fprintf(stderr, "timeout '%s' is not valid\n", argv[2]);
+ exit(1);
+ }
+
+ printf("Agent timeout test, domain = %d, timeout = %d\n", domain, timeout);
+ if ((sts = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) {
+ fprintf(stderr, "pmLoadNameSpace: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ fprintf(stderr, "pmNewContext(..., \"localhost\"): %s\n",
+ pmErrStr(sts));
+ exit(1);
+ }
+
+ name = "pmcd.control.timeout";
+ if ((sts = pmLookupName(1, &name, &timeoutPmid)) < 0) {
+ fprintf(stderr, "pmLookupName(%s): %s\n", name, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* fetch pmcd.control.timeout and make sure the result is OK */
+ if ((sts = pmFetch(1, &timeoutPmid, &result)) < 0) {
+ fprintf(stderr, "pmFetch(pmcd.control.timeout): %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ if (result->numpmid != 1) {
+ fprintf(stderr, "pmFetch(pmcd.control.timeout): %d values fetched!\n", result->numpmid);
+ exit(1);
+ }
+ vsp = result->vset[0];
+ if (vsp->pmid != timeoutPmid || vsp->numval != 1) {
+ fprintf(stderr, "pmFetch(pmcd.control.timeout): bad pmID or numval in result\n");
+ exit(1);
+ }
+ oldTimeout = vsp->vlist[0].value.lval;
+
+ /* Now store the new value then fetch it back to check */
+ vsp->vlist[0].value.lval = timeout;
+ if ((sts = pmStore(result)) < 0) {
+ fprintf(stderr, "pmStore(pmcd.control.timeout): %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmFetch(1, &timeoutPmid, &result)) < 0) {
+ fprintf(stderr, "#2 pmFetch(pmcd.control.timeout): %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ if (result->numpmid != 1) {
+ fprintf(stderr, "#2 pmFetch(pmcd.control.timeout): %d values fetched!\n", result->numpmid);
+ exit(1);
+ }
+ vsp = result->vset[0];
+ if (vsp->pmid != timeoutPmid || vsp->numval != 1) {
+ fprintf(stderr, "#2 pmFetch(pmcd.control.timeout): bad pmID or numval in result\n");
+ exit(1);
+ }
+ if (vsp->vlist[0].value.lval != timeout) {
+ fprintf(stderr, "pmcd timeout update failed, old = %d, new = %d, returned = %d\n",
+ oldTimeout, timeout, vsp->vlist[0].value.lval);
+ exit(1);
+ }
+ pmcdTimeout = vsp->vlist[0].value.lval;
+ pmFreeResult(result);
+ printf(" timeout is now %d seconds\n", pmcdTimeout);
+
+ pip = (__pmID_int *)&pmid;
+ pip->domain = domain;
+ pip->cluster = 0;
+ pip->item = 0;
+ tBegin = time((time_t *)0);
+ if ((sts = pmFetch(1, &pmid, &result)) < 0) {
+ fprintf(stderr, "fetch error = %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ vsp = result->vset[0];
+ if (vsp->numval != PM_ERR_TIMEOUT)
+ fprintf(stderr, "Timeout fetch didn't time out\n");
+ pmFreeResult(result);
+ tEnd = time((time_t *)0);
+#ifdef DESPERATE
+ printf(" %d seconds for fetch\n", tEnd - tBegin);
+#endif
+ tElapsed = tEnd - tBegin;
+
+ /* The way pmcd timeouts work, the time before an agent is timed-out
+ * varies between the timeout and 2 * timeout. It's actually even more
+ * complicated to calculate the maximum timeout interval if the timeout is
+ * changed, since the timeout sproc continually reschedules itself
+ * asynchronously. There are two extrema:
+ * . If the (old) timeout had just gone off and has been requeued for
+ * the old interval just prior to the change being made.
+ * . If the old timeout is just about to go off but the change gets
+ * made first
+ */
+ if (pmcdTimeout <= oldTimeout)
+ tMax = oldTimeout + pmcdTimeout;
+ else
+ tMax = 2 * pmcdTimeout;
+
+ if (tElapsed < pmcdTimeout)
+ fprintf(stderr, "Fetch timed out prematurely: elapsed = %d\n", tElapsed);
+ else if (tElapsed > tMax + 2) /* Allow 2 second's delay in processing */
+ fprintf(stderr, "Fetch took too long to time out: %d\n", tElapsed);
+ exit(0);
+}
diff --git a/qa/src/aggrstore.c b/qa/src/aggrstore.c
new file mode 100644
index 0000000..a45dc80
--- /dev/null
+++ b/qa/src/aggrstore.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2010 Ken McDonell. All Rights Reserved.
+ *
+ * Store a string value into an aggregate metric
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int type = PM_CONTEXT_HOST;
+ int c;
+ int sts;
+ int errflag = 0;
+ char *host = "localhost";
+ static char *usage = "[-D N] [-h hostname] metric stringvalue";
+ int len;
+ int n;
+ char *namelist[1];
+ pmID pmidlist[1];
+ pmResult *res;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:h:")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ host = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc-2) {
+ printf("Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ if ((sts = pmNewContext(type, host)) < 0) {
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ namelist[0] = argv[optind];
+ n = pmLookupName(1, namelist, pmidlist);
+ if (n < 0 || pmidlist[0] == PM_ID_NULL) {
+ printf("pmLookupName: %s\n", pmErrStr(n));
+ exit(1);
+ }
+
+ if ((n = pmFetch(1, pmidlist, &res)) < 0) {
+ printf("pmFetch: %s\n", pmErrStr(n));
+ exit(1);
+ }
+
+ /*
+ * expecting one value and a pmValueBlock with a type
+ * of PM_TYPE_AGGREGATE
+ */
+ if (res->vset[0]->numval != 1) {
+ printf("Expecting numval 1, found %d\n", res->vset[0]->numval);
+ __pmDumpResult(stdout, res);
+ exit(1);
+ }
+ if (res->vset[0]->valfmt == PM_VAL_INSITU) {
+ printf("Not expecing PM_VAL_INSITU\n");
+ __pmDumpResult(stdout, res);
+ exit(1);
+ }
+ if (res->vset[0]->vlist[0].value.pval->vtype != PM_TYPE_AGGREGATE) {
+ printf("Not expecing type %s\n", pmTypeStr(res->vset[0]->vlist[0].value.pval->vtype));
+ __pmDumpResult(stdout, res);
+ exit(1);
+ }
+ printf("%s old value: ", namelist[0]);
+ pmPrintValue(stdout, res->vset[0]->valfmt, res->vset[0]->vlist[0].value.pval->vtype, &res->vset[0]->vlist[0], 0);
+
+ /*
+ * old value is probably from a pinned PDU buffer ... don't free
+ * and accept small mem leak here
+ */
+ len = strlen(argv[optind+1]);
+ res->vset[0]->vlist[0].value.pval = (pmValueBlock *)malloc(len + PM_VAL_HDR_SIZE);
+
+ res->vset[0]->vlist[0].value.pval->vtype = PM_TYPE_AGGREGATE;
+ res->vset[0]->vlist[0].value.pval->vlen = len + PM_VAL_HDR_SIZE;
+ memcpy(res->vset[0]->vlist[0].value.pval->vbuf, argv[optind+1], len);
+
+ if ((n = pmStore(res)) < 0) {
+ printf("pmStore: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ pmFreeResult(res);
+
+ if ((n = pmFetch(1, pmidlist, &res)) < 0) {
+ printf("pmFetch again: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ printf(" new value: ");
+ pmPrintValue(stdout, res->vset[0]->valfmt, res->vset[0]->vlist[0].value.pval->vtype, &res->vset[0]->vlist[0], 0);
+ putchar('\n');
+
+ pmFreeResult(res);
+
+ exit(0);
+}
diff --git a/qa/src/all-irix-6.5.25.0 b/qa/src/all-irix-6.5.25.0
new file mode 100644
index 0000000..e5a0d5e
--- /dev/null
+++ b/qa/src/all-irix-6.5.25.0
Binary files differ
diff --git a/qa/src/all-irix-6.5.25.index b/qa/src/all-irix-6.5.25.index
new file mode 100644
index 0000000..4412251
--- /dev/null
+++ b/qa/src/all-irix-6.5.25.index
Binary files differ
diff --git a/qa/src/all-irix-6.5.25.meta b/qa/src/all-irix-6.5.25.meta
new file mode 100644
index 0000000..78c0bf6
--- /dev/null
+++ b/qa/src/all-irix-6.5.25.meta
Binary files differ
diff --git a/qa/src/all-sles9-sp1.0 b/qa/src/all-sles9-sp1.0
new file mode 100644
index 0000000..ed3d3f7
--- /dev/null
+++ b/qa/src/all-sles9-sp1.0
Binary files differ
diff --git a/qa/src/all-sles9-sp1.index b/qa/src/all-sles9-sp1.index
new file mode 100644
index 0000000..45f5b99
--- /dev/null
+++ b/qa/src/all-sles9-sp1.index
Binary files differ
diff --git a/qa/src/all-sles9-sp1.meta b/qa/src/all-sles9-sp1.meta
new file mode 100644
index 0000000..2f73a66
--- /dev/null
+++ b/qa/src/all-sles9-sp1.meta
Binary files differ
diff --git a/qa/src/anon-sa.c b/qa/src/anon-sa.c
new file mode 100644
index 0000000..2d5672e
--- /dev/null
+++ b/qa/src/anon-sa.c
@@ -0,0 +1,111 @@
+/*
+ * Anonymise binary sa data files: rewrite sa files
+ * from users that are suitable for sharing/qa'ing.
+ *
+ * When sniffing out starting offsets of hostnames,
+ * something like this command can prove handy:
+ * dd if=rhel5-sa20.bin bs=1 skip=109 count=100
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#define SA_UTSNAME_LEN 65
+
+long
+seek_magic_and_reposition_for_hostname(int fd)
+{
+ int i;
+ unsigned short sa_magic;
+
+ struct magic {
+ unsigned short magic_offset;
+
+ /* check magic - not endian neutral in sa ... :| */
+ unsigned short numeric;
+ unsigned short swabbed;
+
+ /* fortunately, all same length so far (65 bytes) */
+ unsigned long utsname_offset;
+ } magic[] = {
+ { 0, 0xd596, 0xd596, 89 }, /* sysstat-9.x & -10.x */
+ { 40, 0x216e, 0x6e21, 113 }, /* sysstat-8.x */
+ { 36, 0x2169, 0x6921, 109 }, /* sysstat-7.x */
+ };
+
+ for (i = 0; i < sizeof(magic) / sizeof(struct magic); i++) {
+ if ((lseek(fd, magic[i].magic_offset, SEEK_SET)) < 0) {
+ perror("lseek magic");
+ continue;
+ }
+ if (read(fd, &sa_magic, sizeof(sa_magic)) < 0) {
+ perror("read magic");
+ continue;
+ }
+ if (sa_magic == magic[i].numeric || sa_magic == magic[i].swabbed) {
+ if ((lseek(fd, magic[i].utsname_offset, SEEK_SET)) < 0) {
+ perror("hostname lseek");
+ return -1;
+ }
+ return magic[i].utsname_offset; /* all good */
+ }
+ }
+ printf(" non-sa data file - cannot find any sa magic - ignored\n");
+ return -1;
+}
+
+int main(int argc, char **argv)
+{
+ int count, fixit = 0, updates = 0;
+
+ for (count = 1; count < argc; count++) {
+ char hostname[SA_UTSNAME_LEN] = { 0 };
+ char *file = argv[count];
+ int fd, bytes, length;
+ long offset;
+
+ if (strcmp(file, "-f") == 0) {
+ fixit = 1;
+ continue;
+ }
+ printf("Filename: %s\n", file);
+ if ((fd = open(file, O_RDWR)) < 0) {
+ perror("open");
+ continue;
+ }
+ if ((offset = seek_magic_and_reposition_for_hostname(fd)) < 0) {
+ close(fd);
+ continue;
+ }
+ if ((bytes = read(fd, hostname, sizeof(hostname))) < 0) {
+ perror("read");
+ close(fd);
+ continue;
+ }
+ hostname[sizeof(hostname)-1] = '\0';
+ length = strlen(hostname);
+ printf(" hostname: %s (%d bytes)\n", hostname, length);
+
+ if (fixit) {
+ memset(hostname, 0, length); // clear old name
+ strcpy(hostname, "pcp.qa.org"); // reset it
+ if ((lseek(fd, offset, SEEK_SET)) < 0) {
+ perror("lseek2");
+ close(fd);
+ continue;
+ }
+ if (write(fd, hostname, length) < 0) {
+ perror("write");
+ close(fd);
+ continue;
+ }
+ updates++;
+ }
+ close(fd);
+ }
+ printf("%d files scanned, %d files updated\n", count-1-fixit, updates);
+ return 0;
+}
diff --git a/qa/src/arch_a.0 b/qa/src/arch_a.0
new file mode 100644
index 0000000..ad55205
--- /dev/null
+++ b/qa/src/arch_a.0
Binary files differ
diff --git a/qa/src/arch_a.index b/qa/src/arch_a.index
new file mode 100644
index 0000000..eb71ea7
--- /dev/null
+++ b/qa/src/arch_a.index
Binary files differ
diff --git a/qa/src/arch_a.meta b/qa/src/arch_a.meta
new file mode 100644
index 0000000..a4406e3
--- /dev/null
+++ b/qa/src/arch_a.meta
Binary files differ
diff --git a/qa/src/arch_b.0 b/qa/src/arch_b.0
new file mode 100644
index 0000000..3264214
--- /dev/null
+++ b/qa/src/arch_b.0
Binary files differ
diff --git a/qa/src/arch_b.index b/qa/src/arch_b.index
new file mode 100644
index 0000000..731e084
--- /dev/null
+++ b/qa/src/arch_b.index
Binary files differ
diff --git a/qa/src/arch_b.meta b/qa/src/arch_b.meta
new file mode 100644
index 0000000..6a7a5d0
--- /dev/null
+++ b/qa/src/arch_b.meta
Binary files differ
diff --git a/qa/src/arch_maxfd.c b/qa/src/arch_maxfd.c
new file mode 100644
index 0000000..16bc2da
--- /dev/null
+++ b/qa/src/arch_maxfd.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Exercise pmNewContext() for archives close to the NOFILE max fd limit.
+ * For incident: 504616
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <strings.h>
+#include <errno.h>
+#include <sys/resource.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#include "localconfig.h"
+
+#if PCP_VER < 2200
+#define PRINTF_P_PFX ""
+#endif
+
+static char *sfx[] = { "0", "index", "meta" };
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int i;
+ int j;
+ int max_ctx;
+ int max_nofile;
+ int numopen = 0; /* pander to gcc */
+ int ctx = -1; /* pander to gcc */
+ int last_ctx;
+ char buf[100];
+ char lbuf[100];
+ struct rlimit top;
+ char *start = NULL;
+ char *end;
+
+ __pmSetProgname(pmProgname);
+
+ while ((c = getopt(argc, argv, "D:?")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ sts = getrlimit(RLIMIT_NOFILE, &top);
+
+ for (max_nofile = 30; max_nofile > 20; max_nofile--) {
+ top.rlim_cur = max_nofile;
+ sts = setrlimit(RLIMIT_NOFILE, &top);
+ if (sts < 0) {
+ fprintf(stderr, "setrlimit(NOFILE=%d) failed: %s\n", max_nofile, strerror(errno));
+ exit(1);
+ }
+ sts = dup(0);
+ if (sts < 0) {
+ fprintf(stderr, "dup(0) failed: %s\n", strerror(errno));
+ exit(1);
+ }
+ max_ctx = (max_nofile + 2 - sts) / 3;
+ close(sts);
+
+ printf("max fd: %d max ctx#: %d\n", max_nofile, max_ctx);
+ last_ctx = -1;
+
+ for (i = 0; i <= max_ctx; i++) {
+
+ for (j = 0; j < 3; j++) {
+ sprintf(lbuf, "qa-tmp-%d.%s", i, sfx[j]);
+ sprintf(buf, "%s.%s", argv[optind], sfx[j]);
+ sts = link(buf, lbuf);
+ if (sts < 0) {
+ fprintf(stderr, "link %s -> %s failed: %s\n",
+ lbuf, buf, strerror(errno));
+ break;
+ }
+ }
+
+ sprintf(lbuf, "qa-tmp-%d", i);
+ ctx = pmNewContext(PM_CONTEXT_ARCHIVE, lbuf);
+
+ for (j = 0; j < 3; j++) {
+ sprintf(lbuf, "qa-tmp-%d.%s", i, sfx[j]);
+ sts = unlink(lbuf);
+ if (sts < 0) {
+ fprintf(stderr, "unlink %s failed: %s\n",
+ lbuf, strerror(errno));
+ break;
+ }
+ }
+
+ if (ctx < 0) {
+ printf("pmNewContext(): %s\n", pmErrStr(ctx));
+ if (i != max_ctx && i != max_ctx-1)
+ printf("Error: failure after ctx# %d, expected after %d or %d\n", last_ctx, max_ctx, max_ctx-1);
+ break;
+ }
+ else
+ numopen++;
+ last_ctx = ctx;
+ }
+
+ if (ctx >= 0)
+ printf("Error: pmNewContext() did not fail?\n");
+
+ for (i = 0; i <= last_ctx; i++)
+ pmDestroyContext(i);
+
+ if (start == NULL) {
+ start = sbrk(0);
+ numopen = 0;
+ }
+ }
+
+ end = sbrk(0);
+
+ if (end - start > 16*1024) {
+ printf("Memory leak? after first pass, %ld bytes per archive open-close\n",
+ (long)((end - start) / numopen));
+ printf("start: " PRINTF_P_PFX "%p end: " PRINTF_P_PFX "%p diff: %ld numopen: %d\n", start, end,
+ (long)(end - start), numopen);
+ }
+
+ return 0;
+}
diff --git a/qa/src/archinst.c b/qa/src/archinst.c
new file mode 100644
index 0000000..4b5c501
--- /dev/null
+++ b/qa/src/archinst.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <unistd.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+dometric(char *name)
+{
+ int i;
+ pmID pmidlist[] = { PM_ID_NULL };
+ pmDesc desc;
+ int sts;
+ char *iname;
+ int *ilist;
+ char **nlist;
+
+ if ((sts = pmLookupName(1, &name, pmidlist)) < 0)
+ return sts;
+
+ if ((sts = pmLookupDesc(pmidlist[0], &desc)) < 0)
+ return sts;
+
+ for (i = 0; i < 2; i++) {
+ iname = "no match";
+ printf("pm*InDom: inst=%d", i);
+ if ((sts = pmNameInDom(desc.indom, i, &iname)) < 0)
+ printf(" %s\n", pmErrStr(sts));
+ else {
+ printf(" iname=%s reverse lookup:", iname);
+ if ((sts = pmLookupInDom(desc.indom, iname)) < 0)
+ printf(" %s\n", pmErrStr(sts));
+ else
+ printf(" inst=%d\n", sts);
+ }
+ iname = "no match";
+ printf("pm*InDomArchive: inst=%d", i);
+ if ((sts = pmNameInDomArchive(desc.indom, i, &iname)) < 0)
+ printf(" %s\n", pmErrStr(sts));
+ else {
+ printf(" iname=%s reverse lookup:", iname);
+ if ((sts = pmLookupInDomArchive(desc.indom, iname)) < 0)
+ printf(" %s\n", pmErrStr(sts));
+ else
+ printf(" inst=%d\n", sts);
+ }
+ }
+
+ if ((sts = pmGetInDom(desc.indom, &ilist, &nlist)) < 0)
+ printf("pmGetInDom: %s\n", pmErrStr(sts));
+ else {
+ printf("pmGetInDom:\n");
+ for (i = 0; i < sts; i++) {
+ printf(" [%d] %s\n", ilist[i], nlist[i]);
+ }
+ free(ilist);
+ free(nlist);
+ }
+
+ if ((sts = pmGetInDomArchive(desc.indom, &ilist, &nlist)) < 0)
+ printf("pmGetInDomArchive: %s\n", pmErrStr(sts));
+ else {
+ printf("pmGetInDomArchive:\n");
+ for (i = 0; i < sts; i++) {
+ printf(" [%d] %s\n", ilist[i], nlist[i]);
+ }
+ free(ilist);
+ free(nlist);
+ }
+ return sts;
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ int force = 0;
+ int verbose = 0;
+ char *host = NULL; /* pander to gcc */
+ char *configfile = (char *)0;
+ char *logfile = (char *)0;
+ pmLogLabel label; /* get hostname for archives */
+ int zflag = 0; /* for -z */
+ char *tz = (char *)0; /* for -Z timezone */
+ int tzh; /* initial timezone handle */
+ char local[MAXHOSTNAMELEN];
+ char *namespace = PM_NS_DEFAULT;
+ int samples = -1;
+ double delta = 1.0;
+ char *endnum;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:c:D:fh:l:n:s:t:VzZ:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'c': /* configfile */
+ if (configfile != (char *)0) {
+ fprintf(stderr, "%s: at most one -c option allowed\n", pmProgname);
+ errflag++;
+ }
+ configfile = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'f': /* force */
+ force++;
+ break;
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'l': /* logfile */
+ logfile = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples < 0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 't': /* delta seconds (double) */
+ delta = strtod(optarg, &endnum);
+ if (*endnum != '\0' || delta <= 0.0) {
+ fprintf(stderr, "%s: -t requires floating point argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'V': /* verbose */
+ verbose++;
+ break;
+
+ case 'z': /* timezone from host */
+ if (tz != (char *)0) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ zflag++;
+ break;
+
+ case 'Z': /* $TZ timezone */
+ if (zflag) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ tz = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (zflag && type == 0) {
+ fprintf(stderr, "%s: -z requires an explicit -a or -h option\n", pmProgname);
+ errflag++;
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -c configfile file to load configuration from\n\
+ -D debug standard PCP debug flag\n\
+ -f force .. \n\
+ -h host metrics source is PMCD on host\n\
+ -l logfile redirect diagnostics and trace output\n\
+ -n namespace use an alternative PMNS\n\
+ -s samples terminate after this many iterations\n\
+ -t delta sample interval in seconds(float) [default 1.0]\n\
+ -V verbose/diagnostic output\n\
+ -z set reporting timezone to local time for host from -a or -h\n\
+ -Z timezone set reporting timezone\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (logfile != (char *)0) {
+ __pmOpenLog(pmProgname, logfile, stderr, &sts);
+ if (sts < 0) {
+ fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmProgname, logfile);
+ }
+ }
+
+ if (namespace != PM_NS_DEFAULT) {
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ if (zflag) {
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+ if (type == PM_CONTEXT_ARCHIVE)
+ printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n",
+ label.ll_hostname);
+ else
+ printf("Note: timezone set to local timezone of host \"%s\"\n\n", host);
+ }
+ else if (tz != (char *)0) {
+ if ((tzh = pmNewZone(tz)) < 0) {
+ fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n",
+ pmProgname, tz, pmErrStr(tzh));
+ exit(1);
+ }
+ printf("Note: timezone set to \"TZ=%s\"\n\n", tz);
+ }
+ else
+ tzh = pmNewContextZone();
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ while (optind < argc) {
+ printf("%s:\n", argv[optind]);
+ sts = dometric(argv[optind]);
+ if (sts < 0)
+ printf("Error: %s\n", pmErrStr(sts));
+ optind++;
+ }
+
+ exit(0);
+}
diff --git a/qa/src/atomstr.c b/qa/src/atomstr.c
new file mode 100644
index 0000000..0373e88
--- /dev/null
+++ b/qa/src/atomstr.c
@@ -0,0 +1,135 @@
+
+/*
+ * Copyright (c) 2010 Ken McDonell. All Rights Reserved.
+ *
+ * Make pmAtomStr jump through hoops
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ static char *usage = "[-D N]";
+ pmAtomValue atom;
+ char aggr[] = {
+ '\00', '\01', '\02', '\03', '\04', '\05', '\06', '\07',
+ '\10', '\11', '\12', '\13', '\14', '\15', '\16', '\17'
+ };
+ int hdl;
+ struct timeval stamp = { 123, 456 };
+ struct timespec hrstamp = { 123456, 78901234 };
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc) {
+ printf("Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ atom.l = -42;
+ printf("%d -> %s\n", atom.l, pmAtomStr(&atom, PM_TYPE_32));
+
+ atom.ul = 0x80000000;
+ printf("%u -> %s\n", atom.ul, pmAtomStr(&atom, PM_TYPE_U32));
+
+ atom.ll = -1234567890123LL;
+ printf("%lld -> %s\n", (long long)atom.ll, pmAtomStr(&atom, PM_TYPE_64));
+
+ atom.ull = 0x8000000000000000LL;
+ printf("%llu -> %s\n", (unsigned long long)atom.ull, pmAtomStr(&atom, PM_TYPE_U64));
+
+ atom.f = 123.456;
+ printf("%.3f -> %s\n", atom.f, pmAtomStr(&atom, PM_TYPE_FLOAT));
+
+ atom.d = 0.123456789;
+ printf("%.9f -> %s\n", atom.d, pmAtomStr(&atom, PM_TYPE_DOUBLE));
+
+ atom.cp = "mary had a little lamb";
+ printf("%s-> %s\n", atom.cp, pmAtomStr(&atom, PM_TYPE_STRING));
+ atom.cp = NULL;
+ printf("%s-> %s\n", atom.cp, pmAtomStr(&atom, PM_TYPE_STRING));
+ /* length = 37 */
+ atom.cp = "abcdefghijklmnopqrstuvwxyz0123456789X";
+ printf("%s -> %s\n", atom.cp, pmAtomStr(&atom, PM_TYPE_STRING));
+ /* length = 39 */
+ atom.cp = "abcdefghijklmnopqrstuvwxyz0123456789XYZ";
+ printf("%s -> %s\n", atom.cp, pmAtomStr(&atom, PM_TYPE_STRING));
+
+ hdl = pmdaEventNewArray();
+ atom.vbp = (pmValueBlock *)pmdaEventGetAddr(hdl);
+ printf("??? -> %s\n", pmAtomStr(&atom, PM_TYPE_EVENT));
+ pmdaEventAddRecord(hdl, &stamp, 0);
+ atom.l = -42;
+ pmdaEventAddParam(hdl, PM_ID_NULL, PM_TYPE_32, &atom);
+ atom.vbp = (pmValueBlock *)pmdaEventGetAddr(hdl);
+ printf("??? -> %s\n", pmAtomStr(&atom, PM_TYPE_EVENT));
+ pmdaEventAddRecord(hdl, &stamp, 0);
+ atom.cp = "hullo world";
+ pmdaEventAddParam(hdl, PM_ID_NULL, PM_TYPE_STRING, &atom);
+ atom.vbp = (pmValueBlock *)pmdaEventGetAddr(hdl);
+ printf("??? -> %s\n", pmAtomStr(&atom, PM_TYPE_EVENT));
+
+ hdl = pmdaEventNewHighResArray();
+ atom.vbp = (pmValueBlock *)pmdaEventGetAddr(hdl);
+ printf("??? -> %s\n", pmAtomStr(&atom, PM_TYPE_HIGHRES_EVENT));
+ pmdaEventAddHighResRecord(hdl, &hrstamp, 0);
+ atom.l = -42;
+ pmdaEventAddParam(hdl, PM_ID_NULL, PM_TYPE_32, &atom);
+ atom.vbp = (pmValueBlock *)pmdaEventGetAddr(hdl);
+ printf("??? -> %s\n", pmAtomStr(&atom, PM_TYPE_HIGHRES_EVENT));
+ pmdaEventAddHighResRecord(hdl, &hrstamp, 0);
+ atom.cp = "hullo world";
+ pmdaEventAddParam(hdl, PM_ID_NULL, PM_TYPE_STRING, &atom);
+ atom.vbp = (pmValueBlock *)pmdaEventGetAddr(hdl);
+ printf("??? -> %s\n", pmAtomStr(&atom, PM_TYPE_HIGHRES_EVENT));
+
+ atom.vbp = (pmValueBlock *)malloc(PM_VAL_HDR_SIZE + sizeof(aggr));
+ atom.vbp->vlen = PM_VAL_HDR_SIZE + sizeof(aggr);
+ atom.vbp->vtype = PM_TYPE_AGGREGATE_STATIC;
+ memcpy(atom.vbp->vbuf, (void *)aggr, sizeof(aggr));
+ printf("??? -> %s\n", pmAtomStr(&atom, PM_TYPE_AGGREGATE_STATIC));
+ atom.vbp->vtype = PM_TYPE_AGGREGATE;
+ for (atom.vbp->vlen = PM_VAL_HDR_SIZE; atom.vbp->vlen <= PM_VAL_HDR_SIZE + sizeof(aggr); atom.vbp->vlen += 2) {
+ printf("??? [len=%d] -> %s\n", atom.vbp->vlen - PM_VAL_HDR_SIZE, pmAtomStr(&atom, PM_TYPE_AGGREGATE));
+ }
+ free(atom.vbp);
+ atom.vbp = NULL;
+ printf("NULL -> %s\n", pmAtomStr(&atom, PM_TYPE_AGGREGATE));
+
+ printf("\nAnd now some error cases ...\n");
+ printf("bad type -> %s\n", pmAtomStr(&atom, 123));
+ printf("no support type -> %s\n", pmAtomStr(&atom, PM_TYPE_NOSUPPORT));
+ printf("unknown type -> %s\n", pmAtomStr(&atom, PM_TYPE_UNKNOWN));
+
+ exit(0);
+}
diff --git a/qa/src/babylon.percpu.0 b/qa/src/babylon.percpu.0
new file mode 100644
index 0000000..bd4901c
--- /dev/null
+++ b/qa/src/babylon.percpu.0
Binary files differ
diff --git a/qa/src/babylon.percpu.index b/qa/src/babylon.percpu.index
new file mode 100644
index 0000000..7b51589
--- /dev/null
+++ b/qa/src/babylon.percpu.index
Binary files differ
diff --git a/qa/src/babylon.percpu.meta b/qa/src/babylon.percpu.meta
new file mode 100644
index 0000000..085dc58
--- /dev/null
+++ b/qa/src/babylon.percpu.meta
Binary files differ
diff --git a/qa/src/babylon.percpu_v2.0 b/qa/src/babylon.percpu_v2.0
new file mode 100644
index 0000000..a721e55
--- /dev/null
+++ b/qa/src/babylon.percpu_v2.0
Binary files differ
diff --git a/qa/src/babylon.percpu_v2.index b/qa/src/babylon.percpu_v2.index
new file mode 100644
index 0000000..5d86a1b
--- /dev/null
+++ b/qa/src/babylon.percpu_v2.index
Binary files differ
diff --git a/qa/src/babylon.percpu_v2.meta b/qa/src/babylon.percpu_v2.meta
new file mode 100644
index 0000000..2eed638
--- /dev/null
+++ b/qa/src/babylon.percpu_v2.meta
Binary files differ
diff --git a/qa/src/babylon.pmview.0 b/qa/src/babylon.pmview.0
new file mode 100644
index 0000000..7f0c1fe
--- /dev/null
+++ b/qa/src/babylon.pmview.0
Binary files differ
diff --git a/qa/src/babylon.pmview.index b/qa/src/babylon.pmview.index
new file mode 100644
index 0000000..2ebca57
--- /dev/null
+++ b/qa/src/babylon.pmview.index
Binary files differ
diff --git a/qa/src/babylon.pmview.meta b/qa/src/babylon.pmview.meta
new file mode 100644
index 0000000..38504c7
--- /dev/null
+++ b/qa/src/babylon.pmview.meta
Binary files differ
diff --git a/qa/src/babylon.pmview_v2.0 b/qa/src/babylon.pmview_v2.0
new file mode 100644
index 0000000..58e07c1
--- /dev/null
+++ b/qa/src/babylon.pmview_v2.0
Binary files differ
diff --git a/qa/src/babylon.pmview_v2.index b/qa/src/babylon.pmview_v2.index
new file mode 100644
index 0000000..7565899
--- /dev/null
+++ b/qa/src/babylon.pmview_v2.index
Binary files differ
diff --git a/qa/src/babylon.pmview_v2.meta b/qa/src/babylon.pmview_v2.meta
new file mode 100644
index 0000000..4479349
--- /dev/null
+++ b/qa/src/babylon.pmview_v2.meta
Binary files differ
diff --git a/qa/src/badlen-0.0 b/qa/src/badlen-0.0
new file mode 100644
index 0000000..e6b6894
--- /dev/null
+++ b/qa/src/badlen-0.0
Binary files differ
diff --git a/qa/src/badlen-0.index b/qa/src/badlen-0.index
new file mode 100644
index 0000000..10b3899
--- /dev/null
+++ b/qa/src/badlen-0.index
Binary files differ
diff --git a/qa/src/badlen-0.meta b/qa/src/badlen-0.meta
new file mode 100644
index 0000000..b02b4ad
--- /dev/null
+++ b/qa/src/badlen-0.meta
Binary files differ
diff --git a/qa/src/badlen-1.0 b/qa/src/badlen-1.0
new file mode 100644
index 0000000..60dc4d5
--- /dev/null
+++ b/qa/src/badlen-1.0
Binary files differ
diff --git a/qa/src/badlen-1.index b/qa/src/badlen-1.index
new file mode 100644
index 0000000..10b3899
--- /dev/null
+++ b/qa/src/badlen-1.index
Binary files differ
diff --git a/qa/src/badlen-1.meta b/qa/src/badlen-1.meta
new file mode 100644
index 0000000..b02b4ad
--- /dev/null
+++ b/qa/src/badlen-1.meta
Binary files differ
diff --git a/qa/src/badlen-10.0 b/qa/src/badlen-10.0
new file mode 100644
index 0000000..4f514d1
--- /dev/null
+++ b/qa/src/badlen-10.0
Binary files differ
diff --git a/qa/src/badlen-10.index b/qa/src/badlen-10.index
new file mode 100644
index 0000000..10b3899
--- /dev/null
+++ b/qa/src/badlen-10.index
Binary files differ
diff --git a/qa/src/badlen-10.meta b/qa/src/badlen-10.meta
new file mode 100644
index 0000000..b02b4ad
--- /dev/null
+++ b/qa/src/badlen-10.meta
Binary files differ
diff --git a/qa/src/badlen-11.0 b/qa/src/badlen-11.0
new file mode 100644
index 0000000..0c0d166
--- /dev/null
+++ b/qa/src/badlen-11.0
Binary files differ
diff --git a/qa/src/badlen-11.index b/qa/src/badlen-11.index
new file mode 100644
index 0000000..10b3899
--- /dev/null
+++ b/qa/src/badlen-11.index
Binary files differ
diff --git a/qa/src/badlen-11.meta b/qa/src/badlen-11.meta
new file mode 100644
index 0000000..b02b4ad
--- /dev/null
+++ b/qa/src/badlen-11.meta
Binary files differ
diff --git a/qa/src/badlen-2.0 b/qa/src/badlen-2.0
new file mode 100644
index 0000000..01f30a9
--- /dev/null
+++ b/qa/src/badlen-2.0
Binary files differ
diff --git a/qa/src/badlen-2.index b/qa/src/badlen-2.index
new file mode 100644
index 0000000..10b3899
--- /dev/null
+++ b/qa/src/badlen-2.index
Binary files differ
diff --git a/qa/src/badlen-2.meta b/qa/src/badlen-2.meta
new file mode 100644
index 0000000..b02b4ad
--- /dev/null
+++ b/qa/src/badlen-2.meta
Binary files differ
diff --git a/qa/src/badlen-3.0 b/qa/src/badlen-3.0
new file mode 100644
index 0000000..84ac3df
--- /dev/null
+++ b/qa/src/badlen-3.0
Binary files differ
diff --git a/qa/src/badlen-3.index b/qa/src/badlen-3.index
new file mode 100644
index 0000000..10b3899
--- /dev/null
+++ b/qa/src/badlen-3.index
Binary files differ
diff --git a/qa/src/badlen-3.meta b/qa/src/badlen-3.meta
new file mode 100644
index 0000000..b02b4ad
--- /dev/null
+++ b/qa/src/badlen-3.meta
Binary files differ
diff --git a/qa/src/badlen-4.0 b/qa/src/badlen-4.0
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/qa/src/badlen-4.0
@@ -0,0 +1 @@
+
diff --git a/qa/src/badlen-4.index b/qa/src/badlen-4.index
new file mode 100644
index 0000000..10b3899
--- /dev/null
+++ b/qa/src/badlen-4.index
Binary files differ
diff --git a/qa/src/badlen-4.meta b/qa/src/badlen-4.meta
new file mode 100644
index 0000000..b02b4ad
--- /dev/null
+++ b/qa/src/badlen-4.meta
Binary files differ
diff --git a/qa/src/badlen-5.0 b/qa/src/badlen-5.0
new file mode 100644
index 0000000..f00bb30
--- /dev/null
+++ b/qa/src/badlen-5.0
Binary files differ
diff --git a/qa/src/badlen-5.index b/qa/src/badlen-5.index
new file mode 100644
index 0000000..10b3899
--- /dev/null
+++ b/qa/src/badlen-5.index
Binary files differ
diff --git a/qa/src/badlen-5.meta b/qa/src/badlen-5.meta
new file mode 100644
index 0000000..b02b4ad
--- /dev/null
+++ b/qa/src/badlen-5.meta
Binary files differ
diff --git a/qa/src/badlen-6.0 b/qa/src/badlen-6.0
new file mode 100644
index 0000000..ce4b6a6
--- /dev/null
+++ b/qa/src/badlen-6.0
Binary files differ
diff --git a/qa/src/badlen-6.index b/qa/src/badlen-6.index
new file mode 100644
index 0000000..10b3899
--- /dev/null
+++ b/qa/src/badlen-6.index
Binary files differ
diff --git a/qa/src/badlen-6.meta b/qa/src/badlen-6.meta
new file mode 100644
index 0000000..b02b4ad
--- /dev/null
+++ b/qa/src/badlen-6.meta
Binary files differ
diff --git a/qa/src/badlen-7.0 b/qa/src/badlen-7.0
new file mode 100644
index 0000000..769d0d8
--- /dev/null
+++ b/qa/src/badlen-7.0
Binary files differ
diff --git a/qa/src/badlen-7.index b/qa/src/badlen-7.index
new file mode 100644
index 0000000..10b3899
--- /dev/null
+++ b/qa/src/badlen-7.index
Binary files differ
diff --git a/qa/src/badlen-7.meta b/qa/src/badlen-7.meta
new file mode 100644
index 0000000..b02b4ad
--- /dev/null
+++ b/qa/src/badlen-7.meta
Binary files differ
diff --git a/qa/src/badlen-8.0 b/qa/src/badlen-8.0
new file mode 100644
index 0000000..0d0af0e
--- /dev/null
+++ b/qa/src/badlen-8.0
Binary files differ
diff --git a/qa/src/badlen-8.index b/qa/src/badlen-8.index
new file mode 100644
index 0000000..10b3899
--- /dev/null
+++ b/qa/src/badlen-8.index
Binary files differ
diff --git a/qa/src/badlen-8.meta b/qa/src/badlen-8.meta
new file mode 100644
index 0000000..b02b4ad
--- /dev/null
+++ b/qa/src/badlen-8.meta
Binary files differ
diff --git a/qa/src/badlen-9.0 b/qa/src/badlen-9.0
new file mode 100644
index 0000000..a85ecd6
--- /dev/null
+++ b/qa/src/badlen-9.0
Binary files differ
diff --git a/qa/src/badlen-9.index b/qa/src/badlen-9.index
new file mode 100644
index 0000000..0ddacab
--- /dev/null
+++ b/qa/src/badlen-9.index
Binary files differ
diff --git a/qa/src/badlen-9.meta b/qa/src/badlen-9.meta
new file mode 100644
index 0000000..1c42267
--- /dev/null
+++ b/qa/src/badlen-9.meta
Binary files differ
diff --git a/qa/src/badloglabel.c b/qa/src/badloglabel.c
new file mode 100644
index 0000000..6657228
--- /dev/null
+++ b/qa/src/badloglabel.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int sts;
+ int ch;
+ int errflag = 0;
+ int a, b, c;
+
+ __pmSetProgname(argv[0]);
+
+ while ((ch = getopt(argc, argv, "D:?")) != EOF) {
+ switch (ch) {
+
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc-2) {
+ fprintf(stderr, "Usage: %s archive1 archive2\n", pmProgname);
+ exit(1);
+ }
+
+ a = pmNewContext(PM_CONTEXT_ARCHIVE, argv[optind]);
+ if (a < 0) {
+ fprintf(stderr, "%s: first pmNewContext(..., %s): %s\n", pmProgname, argv[optind], pmErrStr(a));
+ exit(1);
+ }
+
+ pmDestroyContext(a);
+
+ b = pmNewContext(PM_CONTEXT_HOST, "localhost");
+ if (b < 0) {
+ fprintf(stderr, "%s: pmNewContext(..., localhost): %s\n", pmProgname, pmErrStr(b));
+ exit(1);
+ }
+
+ c = pmNewContext(PM_CONTEXT_ARCHIVE, argv[optind+1]);
+ if (c < 0) {
+ fprintf(stderr, "%s: second pmNewContext(..., %s): %s\n", pmProgname, argv[optind+1], pmErrStr(c));
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/badpmcdpmid.c b/qa/src/badpmcdpmid.c
new file mode 100644
index 0000000..75f19cb
--- /dev/null
+++ b/qa/src/badpmcdpmid.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * pmcd pmda was botched
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main()
+{
+ pmID pmid;
+ __pmID_int *p = (__pmID_int *)&pmid;
+ pmResult *rp;
+ int sts;
+
+ pmid = 0;
+ p->domain = 2; /* pmcd */
+ p->cluster = 13; /* bogus */
+
+ sts = pmNewContext(PM_CONTEXT_HOST, "localhost");
+ if (sts < 0) {
+ fprintf(stderr, "pmNewContext(localhost) failed: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ sts = pmFetch(1, &pmid, &rp);
+ if (sts != 0)
+ printf("expect no error, got: %d %s\n", sts, pmErrStr(sts));
+ if (rp->numpmid != 1)
+ printf("expect 1 pmid, got %d\n", rp->numpmid);
+ if (rp->vset[0]->pmid != pmid) {
+ printf("pmid mismatch! %s", pmIDStr(pmid));
+ printf(" != %s\n", pmIDStr(rp->vset[0]->pmid));
+ }
+ if (rp->vset[0]->numval == 1)
+ printf("%d values is bogus\n", rp->vset[0]->numval);
+ else
+ printf("no value in pmResult -- expected\n");
+
+ exit(0);
+}
diff --git a/qa/src/badpmda.c b/qa/src/badpmda.c
new file mode 100644
index 0000000..aa1625e
--- /dev/null
+++ b/qa/src/badpmda.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2004 Ken McDonell. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+static pmdaInterface dispatch;
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int id = 0;
+ int port = -1;
+ char *sockname = NULL;
+
+ /* trim cmd name of leading directory components */
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "c:p:s:?")) != EOF) {
+ switch (c) {
+
+ case 'c': /* case number */
+ id = atoi(optarg);
+ break;
+
+ case 's': /* socket name */
+ sockname = optarg;
+ break;
+
+ case 'p': /* port number */
+ port = atoi(optarg);
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s [options]\n\
+\n\
+Options:\n\
+ -c number case number (default 0)\n\
+ -s name socket name\n\
+ -p number port number\n",
+ pmProgname);
+ exit(1);
+ }
+
+ switch (id) {
+ case 0:
+ fprintf(stderr, "--- case 0 pmdaConnect() ---\n");
+ pmdaConnect(&dispatch);
+ sts = dispatch.status;
+ if (sts < 0)
+ fprintf(stderr, "pmdaConnect: Error: %s\n", pmErrStr(sts));
+ else
+ fprintf(stderr, "pmdaConnect: OK\n");
+ break;
+
+ case 1:
+ fprintf(stderr, "--- case 1 pmdaExt alloc + pmdaConnect() ---\n");
+ dispatch.version.any.ext = (pmdaExt *)calloc(1, sizeof(pmdaExt));
+ pmdaConnect(&dispatch);
+ sts = dispatch.status;
+ if (sts < 0)
+ fprintf(stderr, "pmdaConnect: Error: %s\n", pmErrStr(sts));
+ else
+ fprintf(stderr, "pmdaConnect: OK\n");
+ break;
+
+ case 2:
+ fprintf(stderr, "--- case 2 pmdaDaemon() + pmdaInet + pmdaConnect() ---\n");
+ pmdaDaemon(&dispatch, PMDA_INTERFACE_LATEST, "badpmda", 123, NULL, NULL);
+ sts = dispatch.status;
+ if (sts < 0)
+ fprintf(stderr, "pmdaDaemon: Error: %s\n", pmErrStr(sts));
+ else
+ fprintf(stderr, "pmdaDaemon: OK\n");
+ dispatch.version.any.ext->e_io = pmdaInet;
+ dispatch.version.any.ext->e_port = port;
+ pmdaConnect(&dispatch);
+ sts = dispatch.status;
+ if (sts < 0)
+ fprintf(stderr, "pmdaConnect: Error: %s\n", pmErrStr(sts));
+ else
+ fprintf(stderr, "pmdaConnect: OK\n");
+ break;
+
+ case 3:
+ fprintf(stderr, "--- case 3 pmdaDaemon() + pmdaInet + pmdaConnect() + pmdaConnect() ---\n");
+ pmdaDaemon(&dispatch, PMDA_INTERFACE_LATEST, "badpmda", 123, NULL, NULL);
+ sts = dispatch.status;
+ if (sts < 0)
+ fprintf(stderr, "pmdaDaemon: Error: %s\n", pmErrStr(sts));
+ else
+ fprintf(stderr, "pmdaDaemon: OK\n");
+ dispatch.version.any.ext->e_io = pmdaUnix;
+ dispatch.version.any.ext->e_sockname = sockname;
+ pmdaConnect(&dispatch);
+ sts = dispatch.status;
+ if (sts < 0)
+ fprintf(stderr, "pmdaConnect: Error: %s\n", pmErrStr(sts));
+ else
+ fprintf(stderr, "pmdaConnect: OK\n");
+ pmdaConnect(&dispatch);
+ sts = dispatch.status;
+ if (sts < 0)
+ fprintf(stderr, "pmdaConnect: Error: %s\n", pmErrStr(sts));
+ else
+ fprintf(stderr, "pmdaConnect: OK\n");
+ break;
+
+ }
+
+ return 0;
+}
diff --git a/qa/src/badti-1.0 b/qa/src/badti-1.0
new file mode 100644
index 0000000..a09c48c
--- /dev/null
+++ b/qa/src/badti-1.0
Binary files differ
diff --git a/qa/src/badti-1.index b/qa/src/badti-1.index
new file mode 100644
index 0000000..d7acf83
--- /dev/null
+++ b/qa/src/badti-1.index
Binary files differ
diff --git a/qa/src/badti-1.meta b/qa/src/badti-1.meta
new file mode 100644
index 0000000..2a6edab
--- /dev/null
+++ b/qa/src/badti-1.meta
Binary files differ
diff --git a/qa/src/badti-2.0 b/qa/src/badti-2.0
new file mode 100644
index 0000000..a09c48c
--- /dev/null
+++ b/qa/src/badti-2.0
Binary files differ
diff --git a/qa/src/badti-2.index b/qa/src/badti-2.index
new file mode 100644
index 0000000..465e753
--- /dev/null
+++ b/qa/src/badti-2.index
Binary files differ
diff --git a/qa/src/badti-2.meta b/qa/src/badti-2.meta
new file mode 100644
index 0000000..2a6edab
--- /dev/null
+++ b/qa/src/badti-2.meta
Binary files differ
diff --git a/qa/src/badti-3.0 b/qa/src/badti-3.0
new file mode 100644
index 0000000..a09c48c
--- /dev/null
+++ b/qa/src/badti-3.0
Binary files differ
diff --git a/qa/src/badti-3.index b/qa/src/badti-3.index
new file mode 100644
index 0000000..9134473
--- /dev/null
+++ b/qa/src/badti-3.index
Binary files differ
diff --git a/qa/src/badti-3.meta b/qa/src/badti-3.meta
new file mode 100644
index 0000000..2a6edab
--- /dev/null
+++ b/qa/src/badti-3.meta
Binary files differ
diff --git a/qa/src/batch_import.perl b/qa/src/batch_import.perl
new file mode 100755
index 0000000..e68f365
--- /dev/null
+++ b/qa/src/batch_import.perl
@@ -0,0 +1,78 @@
+#
+# Exercise libpcp_import "batching" extensions in Perl import API
+#
+# Copyright (c) 2013 Red Hat.
+#
+use strict;
+use warnings;
+
+$| = 1; # don't buffer output
+use PCP::LogImport;
+
+my $ctx1;
+my $ctx2;
+my $hdl1;
+my $hdl2;
+
+sub check
+{
+ my ($sts, $name) = @_;
+ if ($sts < 0) { print $name . ": Error: " . pmiErrStr($sts) . "\n"; }
+ else {
+ print $name . ": OK";
+ if ($sts != 0) { print " ->$sts"; }
+ print "\n";
+ }
+}
+
+$ctx1 = pmiStart("myarchive", 0);
+check($ctx1, "pmiStart");
+
+$_ = pmiSetHostname("batching.com");
+check($_, "pmiSetHostname");
+$_ = pmiSetTimezone("GMT-12");
+check($_, "pmiSetTimezone");
+
+$_ = pmiUseContext($ctx1);
+check($_, "pmiUseContext");
+
+$_ = pmiAddMetric("my.metric.foo", pmid_build(PMI_DOMAIN,0,1), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(1,-1,0,PM_SPACE_MBYTE,PM_TIME_SEC,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.bar", PM_ID_NULL, PM_TYPE_U64, pmInDom_build(PMI_DOMAIN,1), PM_SEM_INSTANT, pmiUnits(1,-1,0,PM_SPACE_MBYTE,PM_TIME_SEC,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.long", PM_ID_NULL, PM_TYPE_64, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.double", PM_ID_NULL, PM_TYPE_DOUBLE, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.string", PM_ID_NULL, PM_TYPE_STRING, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.float", PM_ID_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_DISCRETE, pmiUnits(0,0,0,0,0,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.strung", PM_ID_NULL, PM_TYPE_STRING, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+check($_, "pmiAddMetric");
+
+$_ = pmiBatchPutValue("my.metric.string", "", "a third string value");
+check($_, "pmiBatchPutValue");
+$_ = pmiBatchWrite(2, 70000);
+check($_, "pmiBatchWrite");
+$_ = pmiBatchPutValue("my.metric.strung", "", "a first string value");
+check($_, "pmiBatchPutValue");
+$_ = pmiBatchPutValue("my.metric.string", "", "a second string value");
+check($_, "pmiBatchPutValue");
+$_ = pmiBatchWrite(0, 110000);
+check($_, "pmiBatchWrite");
+$hdl1 = pmiGetHandle("my.metric.string", "");
+check($hdl1, "pmiGetHandle");
+$_ = pmiBatchPutValueHandle($hdl1, "a fourth string value");
+check($_, "pmiBatchPutValueHandle");
+$hdl2 = pmiGetHandle("my.metric.strung", "");
+check($hdl2, "pmiGetHandle");
+$_ = pmiBatchPutValueHandle($hdl2, "a fifth string value");
+check($_, "pmiBatchPutValueHandle");
+$_ = pmiBatchWrite(3, 10000);
+check($_, "pmiBatchWrite");
+
+$_ = pmiBatchEnd();
+check($_, "pmiBatchEnd");
+
+pmiDump();
diff --git a/qa/src/batch_import.pl b/qa/src/batch_import.pl
new file mode 120000
index 0000000..3b1a8c8
--- /dev/null
+++ b/qa/src/batch_import.pl
@@ -0,0 +1 @@
+batch_import.perl \ No newline at end of file
diff --git a/qa/src/bigace.0 b/qa/src/bigace.0
new file mode 100644
index 0000000..ad5d835
--- /dev/null
+++ b/qa/src/bigace.0
Binary files differ
diff --git a/qa/src/bigace.index b/qa/src/bigace.index
new file mode 100644
index 0000000..8ee2cc3
--- /dev/null
+++ b/qa/src/bigace.index
Binary files differ
diff --git a/qa/src/bigace.meta b/qa/src/bigace.meta
new file mode 100644
index 0000000..53bea53
--- /dev/null
+++ b/qa/src/bigace.meta
Binary files differ
diff --git a/qa/src/bigace.pmns b/qa/src/bigace.pmns
new file mode 100644
index 0000000..80ab373
--- /dev/null
+++ b/qa/src/bigace.pmns
@@ -0,0 +1,103 @@
+/*
+ * fixed pmns for bigace archive (V.1)
+ */
+
+root {
+ irix
+}
+
+irix {
+ kernel
+ disk
+ network
+}
+
+irix.kernel {
+ all
+}
+
+/*
+ * kernel.all.load
+ * kernel.all.pswitch
+ * kernel.all.readch
+ * kernel.all.writech
+ * kernel.all.runocc
+ * kernel.all.runque
+ * kernel.all.syscall
+ * kernel.all.cpu.idle
+ * kernel.all.cpu.intr
+ * kernel.all.cpu.sys
+ * kernel.all.cpu.sxbrk
+ * kernel.all.cpu.user
+ * kernel.all.cpu.wait.total
+ * kernel.all.ipc.msg
+ * kernel.all.ipc.sema
+ */
+
+irix.kernel.all {
+ load 1:18:3
+ pswitch 1:10:3
+ readch 1:10:14
+ writech 1:10:29
+ runocc 1:10:15
+ runque 1:10:16
+ syscall 1:10:19
+ cpu
+ ipc
+}
+
+irix.kernel.all.cpu {
+ idle 1:10:7
+ intr 1:10:8
+ sys 1:10:9
+ sxbrk 1:10:10
+ user 1:10:11
+ wait
+}
+
+irix.kernel.all.cpu.wait {
+ total 1:10:12
+}
+
+irix.kernel.all.ipc {
+ msg 1:10:53
+ sema 1:10:54
+}
+
+/*
+ * disk.dev.read
+ * disk.dev.write
+ * disk.dev.total
+ */
+
+irix.disk {
+ dev
+}
+
+irix.disk.dev {
+ read 1:80:1
+ write 1:80:2
+ total 1:80:7
+}
+
+/*
+ * network.interface.in.bytes
+ * network.interface.out.bytes
+ */
+
+irix.network {
+ interface
+}
+
+irix.network.interface {
+ in
+ out
+}
+
+irix.network.interface.in {
+ bytes 1:25:7
+}
+
+irix.network.interface.out {
+ bytes 1:25:12
+}
diff --git a/qa/src/bigace_v2.0 b/qa/src/bigace_v2.0
new file mode 100644
index 0000000..c41de07
--- /dev/null
+++ b/qa/src/bigace_v2.0
Binary files differ
diff --git a/qa/src/bigace_v2.index b/qa/src/bigace_v2.index
new file mode 100644
index 0000000..f2cc9ea
--- /dev/null
+++ b/qa/src/bigace_v2.index
Binary files differ
diff --git a/qa/src/bigace_v2.meta b/qa/src/bigace_v2.meta
new file mode 100644
index 0000000..d65b5b4
--- /dev/null
+++ b/qa/src/bigace_v2.meta
Binary files differ
diff --git a/qa/src/binning.0 b/qa/src/binning.0
new file mode 100644
index 0000000..6db02b9
--- /dev/null
+++ b/qa/src/binning.0
Binary files differ
diff --git a/qa/src/binning.index b/qa/src/binning.index
new file mode 100644
index 0000000..e8bfe76
--- /dev/null
+++ b/qa/src/binning.index
Binary files differ
diff --git a/qa/src/binning.meta b/qa/src/binning.meta
new file mode 100644
index 0000000..322dbe8
--- /dev/null
+++ b/qa/src/binning.meta
Binary files differ
diff --git a/qa/src/bozo.client.0 b/qa/src/bozo.client.0
new file mode 100644
index 0000000..9ee0985
--- /dev/null
+++ b/qa/src/bozo.client.0
Binary files differ
diff --git a/qa/src/bozo.client.index b/qa/src/bozo.client.index
new file mode 100644
index 0000000..1ae4bb1
--- /dev/null
+++ b/qa/src/bozo.client.index
Binary files differ
diff --git a/qa/src/bozo.client.meta b/qa/src/bozo.client.meta
new file mode 100644
index 0000000..a48df2e
--- /dev/null
+++ b/qa/src/bozo.client.meta
Binary files differ
diff --git a/qa/src/bozo.client_v2.0 b/qa/src/bozo.client_v2.0
new file mode 100644
index 0000000..f5af1c3
--- /dev/null
+++ b/qa/src/bozo.client_v2.0
Binary files differ
diff --git a/qa/src/bozo.client_v2.index b/qa/src/bozo.client_v2.index
new file mode 100644
index 0000000..12967df
--- /dev/null
+++ b/qa/src/bozo.client_v2.index
Binary files differ
diff --git a/qa/src/bozo.client_v2.meta b/qa/src/bozo.client_v2.meta
new file mode 100644
index 0000000..1b22c8a
--- /dev/null
+++ b/qa/src/bozo.client_v2.meta
Binary files differ
diff --git a/qa/src/bozo.client_v2.meta.bad.1 b/qa/src/bozo.client_v2.meta.bad.1
new file mode 100644
index 0000000..d895abe
--- /dev/null
+++ b/qa/src/bozo.client_v2.meta.bad.1
Binary files differ
diff --git a/qa/src/bozo.client_v2.meta.bad.2 b/qa/src/bozo.client_v2.meta.bad.2
new file mode 100644
index 0000000..bd2ba91
--- /dev/null
+++ b/qa/src/bozo.client_v2.meta.bad.2
Binary files differ
diff --git a/qa/src/bug.0 b/qa/src/bug.0
new file mode 100644
index 0000000..bcc9744
--- /dev/null
+++ b/qa/src/bug.0
Binary files differ
diff --git a/qa/src/bug.index b/qa/src/bug.index
new file mode 100644
index 0000000..402fdc9
--- /dev/null
+++ b/qa/src/bug.index
Binary files differ
diff --git a/qa/src/bug.meta b/qa/src/bug.meta
new file mode 100644
index 0000000..a396b0a
--- /dev/null
+++ b/qa/src/bug.meta
Binary files differ
diff --git a/qa/src/bug1057.0 b/qa/src/bug1057.0
new file mode 100644
index 0000000..cc7839e
--- /dev/null
+++ b/qa/src/bug1057.0
Binary files differ
diff --git a/qa/src/bug1057.index b/qa/src/bug1057.index
new file mode 100644
index 0000000..c4fb01f
--- /dev/null
+++ b/qa/src/bug1057.index
Binary files differ
diff --git a/qa/src/bug1057.meta b/qa/src/bug1057.meta
new file mode 100644
index 0000000..d473031
--- /dev/null
+++ b/qa/src/bug1057.meta
Binary files differ
diff --git a/qa/src/bug_v2.0 b/qa/src/bug_v2.0
new file mode 100644
index 0000000..82eb0d4
--- /dev/null
+++ b/qa/src/bug_v2.0
Binary files differ
diff --git a/qa/src/bug_v2.index b/qa/src/bug_v2.index
new file mode 100644
index 0000000..5dc618b
--- /dev/null
+++ b/qa/src/bug_v2.index
Binary files differ
diff --git a/qa/src/bug_v2.meta b/qa/src/bug_v2.meta
new file mode 100644
index 0000000..1e27f6f
--- /dev/null
+++ b/qa/src/bug_v2.meta
Binary files differ
diff --git a/qa/src/changeinst.0 b/qa/src/changeinst.0
new file mode 100644
index 0000000..2f62135
--- /dev/null
+++ b/qa/src/changeinst.0
Binary files differ
diff --git a/qa/src/changeinst.index b/qa/src/changeinst.index
new file mode 100644
index 0000000..dd5af9d
--- /dev/null
+++ b/qa/src/changeinst.index
Binary files differ
diff --git a/qa/src/changeinst.meta b/qa/src/changeinst.meta
new file mode 100644
index 0000000..c30b7d1
--- /dev/null
+++ b/qa/src/changeinst.meta
Binary files differ
diff --git a/qa/src/check_fault_injection.c b/qa/src/check_fault_injection.c
new file mode 100644
index 0000000..765a0ef
--- /dev/null
+++ b/qa/src/check_fault_injection.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * Check if libpcp built with -DPM_FAULT_INJECTION ... answer
+ * is in the exit status.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/fault.h>
+#include <string.h>
+#include <errno.h>
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *usage = "[-D debug]";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc) {
+ fprintf(stderr, "Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ __pmFaultInject("test", 0);
+ /*
+ * will only return in the OK case
+ */
+
+ return 0;
+}
diff --git a/qa/src/check_import.c b/qa/src/check_import.c
new file mode 100644
index 0000000..0e3ef3c
--- /dev/null
+++ b/qa/src/check_import.c
@@ -0,0 +1,175 @@
+/*
+ * Exercise libpcp_import
+ *
+ * Copyright (c) 2009 Ken McDonell. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/import.h>
+
+static void
+check(int sts, char *name)
+{
+ if (sts < 0) fprintf(stderr, "%s: Error: %s\n", name, pmiErrStr(sts));
+ else {
+ fprintf(stderr, "%s: OK", name);
+ if (sts != 0) fprintf(stderr, " ->%d", sts);
+ fputc('\n', stderr);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int sts;
+ int ctx1;
+ int ctx2;
+ int hdl1;
+ int hdl2;
+ int errflag = 0;
+ int c;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N] ";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ pmiDump();
+
+ ctx1 = pmiStart("myarchive", 0);
+ check(ctx1, "pmiStart");
+ pmiDump();
+
+ sts = pmiSetHostname("somehost.com");
+ check(sts, "pmiSetHostname");
+ sts = pmiSetTimezone("GMT-12");
+ check(sts, "pmiSetTimezone");
+
+ sts = pmiUseContext(3);
+ check(sts, "pmiUseContext");
+ sts = pmiUseContext(ctx1);
+ check(sts, "pmiUseContext");
+
+ sts = pmiAddMetric("my.metric.foo", pmid_build(245,0,1), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(1,-1,0,PM_SPACE_MBYTE,PM_TIME_SEC,0));
+ check(sts, "pmiAddMetric");
+ sts = pmiAddMetric("my.metric.bar", PM_ID_NULL, PM_TYPE_U64, pmInDom_build(245,1), PM_SEM_INSTANT, pmiUnits(1,-1,0,PM_SPACE_MBYTE,PM_TIME_SEC,0));
+ check(sts, "pmiAddMetric");
+ sts = pmiAddMetric("my.metric.foo", 1, 2, 3, 4, pmiUnits(0,0,0,0,0,0));
+ check(sts, "pmiAddMetric");
+ sts = pmiAddMetric("my.metric.long", PM_ID_NULL, PM_TYPE_64, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+ check(sts, "pmiAddMetric");
+ sts = pmiAddMetric("my.metric.double", PM_ID_NULL, PM_TYPE_DOUBLE, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+ check(sts, "pmiAddMetric");
+ sts = pmiAddMetric("my.metric.string", PM_ID_NULL, PM_TYPE_STRING, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+ check(sts, "pmiAddMetric");
+ sts = pmiAddMetric("my.dup.pmid", pmid_build(245,0,3), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+ check(sts, "pmiAddMetric");
+ sts = pmiAddMetric("my.metric.float", PM_ID_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_DISCRETE, pmiUnits(0,0,0,0,0,0));
+ check(sts, "pmiAddMetric");
+
+ sts = pmiAddInstance(pmInDom_build(245,1), "eek really", 1);
+ check(sts, "pmiAddInstance");
+ sts = pmiAddInstance(pmInDom_build(245,1), "eek", 2);
+ check(sts, "pmiAddInstance");
+ sts = pmiAddInstance(pmInDom_build(245,1), "blah", 3);
+ check(sts, "pmiAddInstance");
+ sts = pmiAddInstance(pmInDom_build(245,1), "not-blah-again", 3);
+ check(sts, "pmiAddInstance");
+
+ sts = pmiPutValue("my.metric.foo", NULL, "123");
+ check(sts, "pmiPutValue");
+ sts = pmiPutValue("my.metric.foo", "should be null", "1234");
+ check(sts, "pmiPutValue");
+ sts = pmiPutValue("my.metric.bar", "eek", "4567890123456");
+ check(sts, "pmiPutValue");
+ sts = pmiPutValue("my.metric.bar", "blah", "4567890123457");
+ check(sts, "pmiPutValue");
+ sts = pmiPutValue("my.metric.bar", "not-blah", "4567890123457");
+ check(sts, "pmiPutValue");
+ sts = pmiPutValue("my.metric.bar", NULL, "42");
+ check(sts, "pmiPutValue");
+ sts = pmiPutValue("my.metric.string", "", "a new string value");
+ check(sts, "pmiPutValue");
+ sts = pmiPutValue("my.metric.long", "", "123456789012345");
+ check(sts, "pmiPutValue");
+ sts = pmiPutValue("my.metric.double", "", "1.23456789012");
+ check(sts, "pmiPutValue");
+ sts = pmiPutValue("my.metric.float", "", "-1.234567");
+ check(sts, "pmiPutValue");
+
+ hdl1 = pmiGetHandle("my.metric.foo", "");
+ check(hdl1, "pmiGetHandle");
+ sts = pmiGetHandle("my.bad", "");
+ check(sts, "pmiGetHandle");
+ sts = pmiPutValueHandle(hdl1, "321");
+ check(sts, "pmiPutValueHandle");
+ sts = pmiPutValueHandle(0, "error");
+ check(sts, "pmiPutValueHandle");
+
+ pmiDump();
+
+ sts = pmiWrite((int)(365.25*30*24*60*60), 0);
+ check(sts, "pmiWrite");
+ sts = pmiPutValueHandle(hdl1, "4321");
+ check(sts, "pmiPutValueHandle");
+ sts = pmiPutValue("my.metric.string", "", "a second string value");
+ check(sts, "pmiPutValue");
+ sts = pmiWrite(-1, -1);
+ check(sts, "pmiWrite");
+ sts = pmiPutValue("my.metric.string", "", "a third string value");
+ check(sts, "pmiPutValue");
+ sts = pmiWrite(-1, -1);
+ check(sts, "pmiWrite");
+ sts = pmiWrite(-1, -1);
+ check(sts, "pmiWrite");
+
+ sts = pmiEnd();
+ check(sts, "pmiEnd");
+
+ ctx2 = pmiStart("myotherarchive", 1);
+ check(ctx2, "pmiStart");
+ sts = pmiAddInstance(pmInDom_build(245,1), "other", 2);
+ check(sts, "pmiAddInstance");
+ hdl2 = pmiGetHandle("my.metric.bar", "eek");
+ check(hdl2, "pmiGetHandle");
+ sts = pmiPutValueHandle(hdl2, "6543210987654");
+ check(sts, "pmiPutValueHandle");
+ sts = pmiPutValueHandle(3, "error");
+ check(sts, "pmiPutValueHandle");
+
+ pmiDump();
+
+ exit(0);
+}
diff --git a/qa/src/check_import.perl b/qa/src/check_import.perl
new file mode 100755
index 0000000..352f332
--- /dev/null
+++ b/qa/src/check_import.perl
@@ -0,0 +1,139 @@
+#
+# Exercise libpcp_import ... Perl version of check_import.c
+#
+# Copyright (c) 2009 Ken McDonell. All Rights Reserved.
+#
+use strict;
+use warnings;
+
+$| = 1; # don't buffer output
+
+use PCP::LogImport;
+
+print "PCP::LogImport symbols ...\n";
+foreach (%PCP::LogImport::) {
+ print "$_\n";
+}
+print "\n";
+
+pmiDump();
+
+my $ctx1;
+my $ctx2;
+my $hdl1;
+my $hdl2;
+
+sub check
+{
+ my ($sts, $name) = @_;
+ if ($sts < 0) { print $name . ": Error: " . pmiErrStr($sts) . "\n"; }
+ else {
+ print $name . ": OK";
+ if ($sts != 0) { print " ->$sts"; }
+ print "\n";
+ }
+}
+
+$ctx1 = pmiStart("myarchive", 0);
+check($ctx1, "pmiStart");
+pmiDump();
+
+$_ = pmiSetHostname("somehost.com");
+check($_, "pmiSetHostname");
+$_ = pmiSetTimezone("GMT-12");
+check($_, "pmiSetTimezone");
+
+$_ = pmiUseContext(3);
+check($_, "pmiUseContext");
+
+$_ = pmiUseContext($ctx1);
+check($_, "pmiUseContext");
+
+$_ = pmiAddMetric("my.metric.foo", pmid_build(PMI_DOMAIN,0,1), PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(1,-1,0,PM_SPACE_MBYTE,PM_TIME_SEC,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.bar", PM_ID_NULL, PM_TYPE_U64, pmInDom_build(PMI_DOMAIN,1), PM_SEM_INSTANT, pmiUnits(1,-1,0,PM_SPACE_MBYTE,PM_TIME_SEC,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.foo", 1, 2, 3, 4, pmiUnits(0,0,0,0,0,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.long", PM_ID_NULL, PM_TYPE_64, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.double", PM_ID_NULL, PM_TYPE_DOUBLE, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.string", PM_ID_NULL, PM_TYPE_STRING, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.dup.pmid", pmid_build(PMI_DOMAIN,0,3), PM_TYPE_32, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0,0,0,0,0,0));
+check($_, "pmiAddMetric");
+$_ = pmiAddMetric("my.metric.float", PM_ID_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_DISCRETE, pmiUnits(0,0,0,0,0,0));
+check($_, "pmiAddMetric");
+
+$_ = pmiAddInstance(pmInDom_build(PMI_DOMAIN,1), "eek really", 1);
+check($_, "pmiAddInstance");
+$_ = pmiAddInstance(pmInDom_build(PMI_DOMAIN,1), "eek", 2);
+check($_, "pmiAddInstance");
+$_ = pmiAddInstance(pmInDom_build(PMI_DOMAIN,1), "blah", 3);
+check($_, "pmiAddInstance");
+$_ = pmiAddInstance(pmInDom_build(PMI_DOMAIN,1), "not-blah-again", 3);
+check($_, "pmiAddInstance");
+
+$_ = pmiPutValue("my.metric.foo", "", 123);
+check($_, "pmiPutValue");
+$_ = pmiPutValue("my.metric.foo", "should be null", "1234");
+check($_, "pmiPutValue");
+$_ = pmiPutValue("my.metric.bar", "eek", "4567890123456");
+check($_, "pmiPutValue");
+$_ = pmiPutValue("my.metric.bar", "blah", "4567890123457");
+check($_, "pmiPutValue");
+$_ = pmiPutValue("my.metric.bar", "not-blah", "4567890123457");
+check($_, "pmiPutValue");
+$_ = pmiPutValue("my.metric.bar", "", "42");
+check($_, "pmiPutValue");
+$_ = pmiPutValue("my.metric.string", "", "a new string value");
+check($_, "pmiPutValue");
+$_ = pmiPutValue("my.metric.long", "", 123456789012345);
+check($_, "pmiPutValue");
+$_ = pmiPutValue("my.metric.double", "", "1.23456789012");
+check($_, "pmiPutValue");
+$_ = pmiPutValue("my.metric.float", "", "-1.234567");
+check($_, "pmiPutValue");
+
+$hdl1 = pmiGetHandle("my.metric.foo", "");
+check($hdl1, "pmiGetHandle");
+$_ = pmiGetHandle("my.bad", "");
+check($_, "pmiGetHandle");
+$_ = pmiPutValueHandle($hdl1, "321");
+check($_, "pmiPutValueHandle");
+$_ = pmiPutValueHandle(0, "error");
+check($_, "pmiPutValueHandle");
+
+pmiDump();
+
+$_ = pmiWrite(int(365.25*30*24*60*60), 0);
+check($_, "pmiWrite");
+$_ = pmiPutValueHandle($hdl1, "4321");
+check($_, "pmiPutValueHandle");
+$_ = pmiPutValue("my.metric.string", "", "a second string value");
+check($_, "pmiPutValue");
+$_ = pmiWrite(-1, -1);
+check($_, "pmiWrite");
+$_ = pmiPutValue("my.metric.string", "", "a third string value");
+check($_, "pmiPutValue");
+$_ = pmiWrite(-1, -1);
+check($_, "pmiWrite");
+$_ = pmiWrite(-1, -1);
+check($_, "pmiWrite");
+
+$_ = pmiEnd();
+check($_, "pmiEnd");
+
+$ctx2 = pmiStart("myotherarchive", 1);
+check($ctx2, "pmiStart");
+$_ = pmiAddInstance(pmInDom_build(PMI_DOMAIN,1), "other", 2);
+check($_, "pmiAddInstance");
+$hdl2 = pmiGetHandle("my.metric.bar", "eek");
+check($hdl2, "pmiGetHandle");
+$_ = pmiPutValueHandle($hdl2, "6543210987654");
+check($_, "pmiPutValueHandle");
+$_ = pmiPutValueHandle(3, "error");
+check($_, "pmiPutValueHandle");
+
+pmiDump();
diff --git a/qa/src/check_import.pl b/qa/src/check_import.pl
new file mode 120000
index 0000000..46e09d4
--- /dev/null
+++ b/qa/src/check_import.pl
@@ -0,0 +1 @@
+check_import.perl \ No newline at end of file
diff --git a/qa/src/check_import.py b/qa/src/check_import.py
new file mode 120000
index 0000000..f8694e4
--- /dev/null
+++ b/qa/src/check_import.py
@@ -0,0 +1 @@
+check_import.python \ No newline at end of file
diff --git a/qa/src/check_import.python b/qa/src/check_import.python
new file mode 100755
index 0000000..a10ece2
--- /dev/null
+++ b/qa/src/check_import.python
@@ -0,0 +1,69 @@
+""" Python test case for Log Import API wrapper module
+"""
+#
+# Copyright (C) 2012-2014 Red Hat Inc.
+#
+# 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.
+#
+
+import sys
+import math
+import time
+import cpmapi
+from pcp import pmi
+from pcp import pmapi
+
+def check_import(archive, hostname, timezone):
+ """ Test body - check many of the Log Import API wrapper interfaces
+ """
+ log = pmi.pmiLogImport(archive)
+ log.pmiSetHostname(hostname)
+ log.pmiSetTimezone(timezone)
+
+ domain = 60 # Linux kernel
+ pmid = log.pmiID(domain, 2, 0)
+ indom = log.pmiInDom(domain, 2)
+ units = log.pmiUnits(0, 0, 0, 0, 0, 0)
+
+ # create a metric with no instances (hinv.ncpu)
+ log.pmiAddMetric("hinv.ncpu", cpmapi.PM_ID_NULL, cpmapi.PM_TYPE_U32,
+ cpmapi.PM_INDOM_NULL, cpmapi.PM_SEM_DISCRETE, units)
+
+ # give it a value
+ log.pmiPutValue("hinv.ncpu", "", "%d" % 42)
+
+ # create a metric with instances (kernel.all.load)
+ log.pmiAddMetric("kernel.all.load", pmid,
+ cpmapi.PM_TYPE_FLOAT, indom, cpmapi.PM_SEM_INSTANT, units)
+ log.pmiAddInstance(indom, "1 minute", 1)
+ log.pmiAddInstance(indom, "5 minute", 5)
+ log.pmiAddInstance(indom, "15 minute", 15)
+
+ # give them values
+ log.pmiPutValue("kernel.all.load", "1 minute", "%f" % 0.01)
+ log.pmiPutValue("kernel.all.load", "5 minute", "%f" % 0.05)
+ log.pmiPutValue("kernel.all.load", "15 minute", "%f" % 0.15)
+
+ timetuple = math.modf(time.time())
+ useconds = int(timetuple[0] * 1000000)
+ seconds = int(timetuple[1])
+ log.pmiWrite(seconds, useconds)
+
+ del log
+
+if __name__ == '__main__':
+
+ if (len(sys.argv) != 2):
+ print("Usage: " + sys.argv[0] + " <path>")
+ sys.exit(1)
+
+ check_import(sys.argv[1], "www.abc.com", "EST-10")
+
diff --git a/qa/src/check_import_name.c b/qa/src/check_import_name.c
new file mode 100644
index 0000000..8efa3e8
--- /dev/null
+++ b/qa/src/check_import_name.c
@@ -0,0 +1,47 @@
+/*
+ * Exercise libpcp_import metric name validation.
+ *
+ * Copyright (c) 2013 Red Hat.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/import.h>
+
+static void
+check(int sts, char *name)
+{
+ if (sts < 0) {
+ fprintf(stderr, "%s: Error: %s\n", name, pmiErrStr(sts));
+ } else {
+ fprintf(stderr, "%s: OK", name);
+ if (sts != 0)
+ fprintf(stderr, " -> %d", sts);
+ fputc('\n', stderr);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int sts;
+
+ if (argc != 2) {
+ printf("Usage: %s <name>\n", argv[0]);
+ exit(1);
+ }
+
+ sts = pmiStart("tmplog", 0);
+ check(sts, "pmiStart");
+ sts = pmiSetHostname("tmphost.com");
+ check(sts, "pmiSetHostname");
+ sts = pmiSetTimezone("GMT-12");
+ check(sts, "pmiSetTimezone");
+
+ printf("Checking metric name: \"%s\" ...\n", argv[1]);
+ sts = pmiAddMetric(argv[1], pmid_build(245,0,1),
+ PM_TYPE_U32, PM_INDOM_NULL, PM_SEM_INSTANT,
+ pmiUnits(1,-1,0,PM_SPACE_MBYTE,PM_TIME_SEC,0));
+ check(sts, "pmiAddMetric");
+ exit(0);
+}
diff --git a/qa/src/chk_memleak.c b/qa/src/chk_memleak.c
new file mode 100644
index 0000000..aeba5dc
--- /dev/null
+++ b/qa/src/chk_memleak.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * check open/close archive for mem leaks
+ */
+
+#include <sys/time.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int vflag = 0;
+static int tflag = 0;
+
+int
+main(int argc, char **argv)
+{
+ int i, c;
+ int sts;
+ int errflag = 0;
+ char *archive = "foo";
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N]";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-D N] [-L] [-h host] [-a archive] [-n namespace] [-v] [-i iterations]";
+ int niter = 100;
+ int contype = PM_CONTEXT_HOST;
+ unsigned long first_memusage;
+ unsigned long last_memusage = 0;
+ unsigned long memusage;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "Li:h:a:D:n:tv")) != EOF) {
+ switch (c) {
+
+ case 'i': /* iterations */
+ niter = atoi(optarg);
+ break;
+ case 'L': /* local */
+ contype = PM_CONTEXT_LOCAL;
+ break;
+ case 'h': /* host */
+ host = optarg;
+ contype = PM_CONTEXT_HOST;
+ break;
+
+ case 'a': /* archive */
+ archive = optarg;
+ contype = PM_CONTEXT_ARCHIVE;
+ break;
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'v': /* verbose output */
+ vflag++;
+ break;
+
+ case 't': /* trim namespace */
+ tflag++;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if (namespace != PM_NS_DEFAULT) {
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ for (i = 0; i < niter; i++) {
+ switch (contype) {
+ case PM_CONTEXT_LOCAL:
+ if ((c = pmNewContext(PM_CONTEXT_LOCAL, NULL)) < 0) {
+ printf("%s: Cannot create local context: %s\n", pmProgname, pmErrStr(c));
+ exit(1);
+ }
+ break;
+ case PM_CONTEXT_ARCHIVE:
+ if ((c = pmNewContext(PM_CONTEXT_ARCHIVE, archive)) < 0) {
+ printf("%s: Cannot connect to archive \"%s\": %s\n", pmProgname, archive, pmErrStr(c));
+ exit(1);
+ }
+ break;
+ case PM_CONTEXT_HOST:
+ if ((c = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ printf("%s: Cannot connect to host \"%s\": %s\n", pmProgname, host, pmErrStr(c));
+ exit(1);
+ }
+ break;
+ }
+
+ pmDestroyContext(c);
+ if (i == 0) {
+ __pmProcessDataSize(&first_memusage);
+ }
+ else {
+ __pmProcessDataSize(&memusage);
+ if (memusage - first_memusage > 0) {
+ if (i > 1)
+ printf("iteration %d: leaked %lu bytes\n", i,
+ memusage - last_memusage);
+ last_memusage = memusage;
+ }
+ }
+ }
+
+ exit(0);
+}
+
diff --git a/qa/src/chk_metric_types.c b/qa/src/chk_metric_types.c
new file mode 100644
index 0000000..a748474
--- /dev/null
+++ b/qa/src/chk_metric_types.c
@@ -0,0 +1,313 @@
+/*
+ * chk_metric_types - check pmResult value types match pmDesc.
+ *
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <unistd.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static void checkMetric(const char *);
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ int verbose = 0;
+ char *host = NULL; /* pander to gcc */
+ int mode = PM_MODE_INTERP; /* mode for archives */
+ char *configfile = NULL;
+ char *logfile = NULL;
+ pmLogLabel label; /* get hostname for archives */
+ int zflag = 0; /* for -z */
+ char *tz = NULL; /* for -Z timezone */
+ int tzh; /* initial timezone handle */
+ char local[MAXHOSTNAMELEN];
+ char *pmnsfile = PM_NS_DEFAULT;
+ int samples = -1;
+ double delta = 1.0;
+ char *endnum;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:c:D:h:l:Ln:s:t:U:VzZ:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'c': /* configfile */
+ if (configfile != NULL) {
+ fprintf(stderr, "%s: at most one -c option allowed\n", pmProgname);
+ errflag++;
+ }
+ configfile = optarg;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'L': /* LOCAL, no PMCD */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ host = NULL;
+ type = PM_CONTEXT_LOCAL;
+ putenv("PMDA_LOCAL_PROC="); /* if proc PMDA needed */
+ putenv("PMDA_LOCAL_SAMPLE="); /* if sampledso PMDA needed */
+ break;
+
+ case 'l': /* logfile */
+ logfile = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ pmnsfile = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples < 0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 't': /* delta seconds (double) */
+ delta = strtod(optarg, &endnum);
+ if (*endnum != '\0' || delta <= 0.0) {
+ fprintf(stderr, "%s: -t requires floating point argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'U': /* uninterpolated archive log */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ mode = PM_MODE_FORW;
+ host = optarg;
+ break;
+
+ case 'V': /* verbose */
+ verbose++;
+ break;
+
+ case 'z': /* timezone from host */
+ if (tz != NULL) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ zflag++;
+ break;
+
+ case 'Z': /* $TZ timezone */
+ if (zflag) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ tz = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (zflag && type == 0) {
+ fprintf(stderr, "%s: -z requires an explicit -a, -h or -U option\n", pmProgname);
+ errflag++;
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -c configfile file to load configuration from\n\
+ -D debug standard PCP debug flag\n\
+ -h host metrics source is PMCD on host\n\
+ -l logfile redirect diagnostics and trace output\n\
+ -L use local context instead of PMCD\n\
+ -n pmnsfile use an alternative PMNS\n\
+ -s samples terminate after this many iterations\n\
+ -t delta sample interval in seconds(float) [default 1.0]\n\
+ -U archive metrics source is an uninterpolated archive log\n\
+ -V verbose/diagnostic output\n\
+ -z set reporting timezone to local time for host from -a, -h or -U\n\
+ -Z timezone set reporting timezone\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (logfile != NULL) {
+ __pmOpenLog(pmProgname, logfile, stderr, &sts);
+ if (sts < 0) {
+ fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmProgname, logfile);
+ }
+ }
+
+ if (pmnsfile != PM_NS_DEFAULT && (sts = pmLoadNameSpace(pmnsfile)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname,
+ pmnsfile, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if (mode != PM_MODE_INTERP) {
+ if ((sts = pmSetMode(mode, &label.ll_start, 0)) < 0) {
+ fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ }
+
+
+ if (zflag) {
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+ if (type == PM_CONTEXT_ARCHIVE)
+ printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n",
+ label.ll_hostname);
+ else
+ printf("Note: timezone set to local timezone of host \"%s\"\n\n", host);
+ }
+ else if (tz != NULL) {
+ if ((tzh = pmNewZone(tz)) < 0) {
+ fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n",
+ pmProgname, tz, pmErrStr(tzh));
+ exit(1);
+ }
+ printf("Note: timezone set to \"TZ=%s\"\n\n", tz);
+ }
+ else
+ tzh = pmNewContextZone();
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ if (optind == argc) {
+ if ((sts = pmTraversePMNS(NULL, checkMetric)) < 0) {
+ fprintf(stderr, "%s: pmTraversePMNS: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ else
+ while (optind < argc) {
+ if ((sts = pmTraversePMNS(argv[optind], checkMetric)) < 0) {
+ fprintf(stderr, "%s: pmTraversePMNS: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ optind++;
+ }
+
+ return 0;
+}
+
+void
+checkMetric(const char *metric)
+{
+ int sts;
+ int i;
+ char *nameList[] = { NULL };
+ pmID pmidList[] = { PM_IN_NULL };
+ pmDesc desc;
+ pmResult *result;
+
+ /* pmLookupName will not modify this string */
+ nameList[0] = (char *)metric;
+
+ if ((sts = pmLookupName(1, nameList, pmidList)) < 0) {
+ fprintf(stderr, "%s: pmLookupName: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmLookupDesc(pmidList[0], &desc)) < 0) {
+ fprintf(stderr, "%s: pmLookupDesc: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (desc.type == PM_TYPE_NOSUPPORT)
+ return;
+
+ if ((sts = pmFetch(1, pmidList, &result)) < 0) {
+ fprintf(stderr, "%s: pmfetch: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (result->numpmid > 0) {
+ for (i=0; i < result->vset[0]->numval; i++) {
+ if (result->vset[0]->valfmt != PM_VAL_INSITU) {
+ pmValue *val = &result->vset[0]->vlist[i];
+ if (val->value.pval->vtype == PM_TYPE_UNKNOWN) {
+ printf("metric \"%s\" vtype for instance %d is PM_TYPE_UNKNOWN\n",
+ metric, val->inst);
+ }
+ else
+ if (val->value.pval->vtype != desc.type) {
+ printf("metric \"%s\" vtype for instance %d, type (%s)",
+ metric, val->inst, pmTypeStr(val->value.pval->vtype));
+ printf(" does not match descriptor (%s)\n", pmTypeStr(desc.type));
+
+ }
+ }
+ }
+ }
+
+
+ pmFreeResult(result);
+}
diff --git a/qa/src/chkacc1.c b/qa/src/chkacc1.c
new file mode 100644
index 0000000..4eaca46
--- /dev/null
+++ b/qa/src/chkacc1.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2012-2014 Red Hat.
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include "localconfig.h"
+
+int
+main(int argc, char **argv)
+{
+ int s, sts, op, host;
+ unsigned int i;
+ char name[4*8 + 7 + 1]; /* handles full IPv6 address, if supported */
+ int ipv4 = -1;
+ int ipv6 = -1;
+ int errflag = 0;
+ int c;
+ __pmSockAddr *inaddr;
+
+ /* trim cmd name of leading directory components */
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "46D:?")) != EOF) {
+ switch (c) {
+
+ case '4': /* ipv4 (default) */
+ ipv4 = 1;
+ break;
+
+ case '6': /* ipv6 */
+ ipv6 = 1;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s [options]\n\
+\n\
+Options:\n\
+ -4 do IPv4 (default)\n\
+ -6 do IPv6\n",
+ pmProgname);
+ return 1;
+ }
+
+ /* defaults */
+ if (ipv4 == -1) ipv4 = 1;
+ if (ipv6 == -1) ipv6 = 0;
+
+ sts = 0;
+ for (op = 0; op < WORD_BIT; op++) {
+ if ((s = __pmAccAddOp(1 << op)) < 0) {
+ printf("Bad op %d: %s\n", op, strerror(errno));
+ sts = s;
+ }
+ if ((s = __pmAccAddOp(1 << op)) >= 0) {
+ printf("duplicate op test failed for op %d\n", op);
+ sts = -EINVAL;
+ }
+ }
+ if (sts < 0)
+ return 1;
+
+ for (host = 0; host < WORD_BIT; host++) {
+ if (ipv4) {
+ sprintf(name, "155.%d.%d.%d", host * 3, 17+host, host);
+ if ((s = __pmAccAddHost(name, 1 << host, 1 << host, 0)) < 0) {
+ printf("cannot add inet host for op%d: %s\n", host, strerror(s));
+ sts = s;
+ }
+ }
+ if (ipv6) {
+ sprintf(name, "fec0::%x:%x:%x:%x:%x:%x",
+ host * 3, 17+host, host,
+ host * 3, 17+host, host);
+ if ((s = __pmAccAddHost(name, 1 << host, 1 << host, 0)) < 0) {
+ printf("cannot add IPv6 host for op%d: %s\n", host, strerror(s));
+ sts = s;
+ }
+ }
+ }
+ if (sts < 0)
+ return 1;
+
+ putc('\n', stderr);
+
+ putc('\n', stderr);
+ __pmAccDumpHosts(stderr);
+
+ putc('\n', stderr);
+
+ if (ipv4) {
+ for (host = 0; host < WORD_BIT; host++) {
+ char buf[20];
+
+ sprintf(buf, "%d.%d.%d.%d", 155, host * 3, 17+host, host);
+ if ((inaddr =__pmStringToSockAddr(buf)) == NULL) {
+ printf("insufficient memory\n");
+ continue;
+ }
+ sts = __pmAccAddClient(inaddr, &i);
+ __pmSockAddrFree(inaddr);
+
+ if (sts < 0) {
+ printf("add inet client from host %d: %s\n", host, pmErrStr(sts));
+ continue;
+ }
+ else if (i != (1 << host))
+ printf("inet host %d: __pmAccAddClient returns denyOpsResult 0x%x (expected 0x%x)\n",
+ host, i, 1 << host);
+ }
+ }
+
+ if (ipv6) {
+ for (host = 0; host < WORD_BIT; host++) {
+ char buf[4*8 + 7 + 1]; /* handles full IPv6 address */
+
+ sprintf(buf, "fec0::%x:%x:%x:%x:%x:%x",
+ host * 3, 17+host, host,
+ host * 3, 17+host, host);
+ if ((inaddr =__pmStringToSockAddr(buf)) == NULL) {
+ printf("insufficient memory\n");
+ continue;
+ }
+ sts = __pmAccAddClient(inaddr, &i);
+ __pmSockAddrFree(inaddr);
+
+ if (sts < 0) {
+ printf("add IPv6 client from host %d: %s\n", host, pmErrStr(sts));
+ continue;
+ }
+ else if (i != (1 << host))
+ printf("IPv6 host %d: __pmAccAddClient returns denyOpsResult 0x%x (expected 0x%x)\n",
+ host, i, 1 << host);
+ }
+ }
+
+ putc('\n', stderr);
+
+ putc('\n', stderr);
+ __pmAccDumpHosts(stderr);
+
+ putc('\n', stderr);
+
+ return 0;
+}
diff --git a/qa/src/chkacc2.c b/qa/src/chkacc2.c
new file mode 100644
index 0000000..597367c
--- /dev/null
+++ b/qa/src/chkacc2.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2012-2014 Red Hat.
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/* Check all ops except one turned off for all combinations.
+ * Check connection limits
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include "localconfig.h"
+
+int
+main(int argc, char **argv)
+{
+ int s, sts, op, host;
+ unsigned int i;
+ char name[4*8 + 7 + 1]; /* handles full IPv6 address, if supported */
+ int ipv4 = -1;
+ int ipv6 = -1;
+ int errflag = 0;
+ int c;
+ __pmSockAddr *inaddr;
+
+ /* trim cmd name of leading directory components */
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "46D:?")) != EOF) {
+ switch (c) {
+
+ case '4': /* ipv4 (default) */
+ ipv4 = 1;
+ break;
+
+ case '6': /* ipv6 */
+ ipv6 = 1;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s [options]\n\
+\n\
+Options:\n\
+ -4 do IPv4 (default)\n\
+ -6 do IPv6\n",
+ pmProgname);
+ return 1;
+ }
+
+ /* defaults */
+ if (ipv4 == -1) ipv4 = 1;
+ if (ipv6 == -1) ipv6 = 0;
+
+ sts = 0;
+ for (op = 0; op < WORD_BIT; op++)
+ if ((s = __pmAccAddOp(1 << op)) < 0) {
+ printf("Bad op %d: %s\n", op, strerror(errno));
+ sts = s;
+ }
+
+ if (sts < 0)
+ return 1;
+
+
+ for (host = 0; host < WORD_BIT; host++) {
+ if (ipv4) {
+ sprintf(name, "155.%d.%d.%d", host * 3, 17+host, host);
+ if ((s = __pmAccAddHost(name, ~(1 << host), ~(1 << host), host)) < 0) {
+ printf("cannot add inet host for op%d: %s\n", host, strerror(s));
+ sts = s;
+ }
+ }
+ if (ipv6) {
+ sprintf(name, "fec0::%x:%x:%x:%x:%x:%x",
+ host * 3, 17+host, host,
+ host * 3, 17+host, host);
+ if ((s = __pmAccAddHost(name, ~(1 << host), ~(1 << host), host)) < 0) {
+ printf("cannot add IPv6 host for op%d: %s\n", host, strerror(s));
+ sts = s;
+ }
+ }
+ }
+ if (sts < 0)
+ return 1;
+
+ putc('\n', stderr);
+
+ putc('\n', stderr);
+ __pmAccDumpHosts(stderr);
+
+ putc('\n', stderr);
+
+ if (ipv4) {
+ for (host = 0; host < WORD_BIT; host++) {
+ int j;
+
+ for (j = 0; j <= host; j++) {
+ char buf[20];
+ sprintf(buf, "%d.%d.%d.%d", 155, host * 3, 17+host, host);
+ if ((inaddr =__pmStringToSockAddr(buf)) == NULL) {
+ printf("insufficient memory\n");
+ continue;
+ }
+ sts = __pmAccAddClient(inaddr, &i);
+ __pmSockAddrFree(inaddr);
+ if (sts < 0) {
+ if (j == host && sts == PM_ERR_CONNLIMIT)
+ continue;
+ printf("add inet client from host %d (j=%d): %s\n",
+ j, host, pmErrStr(sts));
+ continue;
+ }
+ else if (i != (~(1 << host)))
+ printf("inet host %d: __pmAccAddClient returns denyOpsResult 0x%x (expected 0x%x)\n",
+ host, i, ~(1 << host));
+ }
+ }
+ }
+ if (ipv6) {
+ for (host = 0; host < WORD_BIT; host++) {
+ int j;
+
+ for (j = 0; j <= host; j++) {
+ char buf[4*8 + 7 + 1]; /* handles full IPv6 address */
+ sprintf(buf, "fec0::%x:%x:%x:%x:%x:%x",
+ host * 3, 17+host, host,
+ host * 3, 17+host, host);
+ if ((inaddr =__pmStringToSockAddr(buf)) == NULL) {
+ printf("insufficient memory\n");
+ continue;
+ }
+ sts = __pmAccAddClient(inaddr, &i);
+ __pmSockAddrFree(inaddr);
+ if (sts < 0) {
+ if (j == host && sts == PM_ERR_CONNLIMIT)
+ continue;
+ printf("add IPv6 client from host %d (j=%d): %s\n",
+ j, host, pmErrStr(sts));
+ continue;
+ }
+ else if (i != (~(1 << host)))
+ printf("IPv6 host %d: __pmAccAddClient returns denyOpsResult 0x%x (expected 0x%x)\n",
+ host, i, ~(1 << host));
+ }
+ }
+ }
+
+ putc('\n', stderr);
+
+ putc('\n', stderr);
+ __pmAccDumpHosts(stderr);
+
+ putc('\n', stderr);
+
+ return 0;
+}
diff --git a/qa/src/chkacc3.c b/qa/src/chkacc3.c
new file mode 100644
index 0000000..299bd5e
--- /dev/null
+++ b/qa/src/chkacc3.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2012-2014 Red Hat.
+ */
+
+/* Check access control wildcarding, bad ops etc. */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include "localconfig.h"
+
+int a[4] = {0, 37, 235, 126};
+int b[4] = {0, 201, 77, 127};
+int c[4] = {0, 15, 191, 64};
+int d[4] = {0, 1, 127, 254};
+
+int
+main(int argc, char **argv)
+{
+ int s, sts, op, i, ai, bi, ci, di;
+ unsigned int perm;
+ int ipv4 = -1;
+ int ipv6 = -1;
+ int errflag = 0;
+ int copt;
+ char name[4*8 + 7 + 1]; /* handles full IPv6 address, if supported */
+ char *wnames[4] = { ".*", "38.*", "38.202.*", "38.202.16.*" };
+ char *wnames6[4] = { ":*", "26:*", "26:ca:*", "26:ca:10:*" };
+ __pmSockAddr *inaddr;
+
+ /* trim cmd name of leading directory components */
+ __pmSetProgname(argv[0]);
+
+ while ((copt = getopt(argc, argv, "46D:?")) != EOF) {
+ switch (copt) {
+
+ case '4': /* ipv4 (default) */
+ ipv4 = 1;
+ break;
+
+ case '6': /* ipv6 */
+ ipv6 = 1;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s [options]\n\
+\n\
+Options:\n\
+ -4 do IPv4 (default)\n\
+ -6 do IPv6\n",
+ pmProgname);
+ return 1;
+ }
+
+ /* defaults */
+ if (ipv4 == -1) ipv4 = 1;
+ if (ipv6 == -1) ipv6 = 0;
+
+
+ /* there are 10 ops numbered from 0 to 9 */
+ sts = 0;
+ for (op = 0; op < 10; op++)
+ if ((s = __pmAccAddOp(1 << op)) < 0) {
+ fprintf(stderr, "Bad op %d: %s\n", op, strerror(errno));
+ sts = s;
+ }
+
+ if (sts < 0)
+ return 1;
+
+ /* every address except address 0.* and 0:* leaves ops 8 and 9 unspecified */
+ op = 0;
+ for (ai = 0; ai < 4; ai++)
+ for (bi = 0; bi < 4; bi++)
+ for (ci = 0; ci < 4; ci++)
+ for (di = 0; di < 4; di++) {
+ perm = ++op;
+ if (ipv4) {
+ sprintf(name, "%d.%d.%d.%d", a[ai], b[bi], c[ci], d[di]);
+ if (perm >= 1 << 8) {
+ fprintf(stderr, "expect error, perm=%d (>255):\n", perm);
+ perm = 1 << 10;
+ }
+ if (ai == 0) {
+ /* 0.0.* gets y,y; 0.201.* gets n,y; 0.77.* gets y,n;
+ * 0.127.* gets n,n
+ */
+ perm |= (bi << 8);
+ s = __pmAccAddHost(name, 0x3ff, perm, 0);
+ }
+ else
+ s = __pmAccAddHost(name, 0xff, perm, 0);
+ if (s < 0) {
+ fprintf(stderr, "add host for host %s error: %s\n",
+ name, pmErrStr(s));
+ continue;
+ }
+ fprintf(stderr, "set %03x for host %d.%d.%d.%d\n",
+ perm, a[ai], b[bi], c[ci], d[di]);
+ }
+ if (ipv6) {
+ sprintf(name, "%x:%x:%x:%x:%x:%x:%x:%x",
+ a[ai], b[bi], c[ci], d[di],
+ a[ai], b[bi], c[ci], d[di]);
+ perm = op;
+ if (perm >= 1 << 8) {
+ fprintf(stderr, "expect error, perm=%d (>255):\n", perm);
+ perm = 1 << 10;
+ }
+ if (ai == 0) {
+ /* 0.0.* gets y,y; 0.201.* gets n,y; 0.77.* gets y,n;
+ * 0.127.* gets n,n
+ */
+ perm |= (bi << 8);
+ s = __pmAccAddHost(name, 0x3ff, perm, 0);
+ }
+ else
+ s = __pmAccAddHost(name, 0xff, perm, 0);
+ if (s < 0) {
+ fprintf(stderr, "add host for host %s error: %s\n",
+ name, pmErrStr(s));
+ continue;
+ }
+ fprintf(stderr, "set %03x for host %x:%x:%x:%x:%x:%x:%x:%x\n",
+ perm,
+ a[ai], b[bi], c[ci], d[di],
+ a[ai], b[bi], c[ci], d[di]);
+ }
+ }
+
+ /* ops 8 and 9 are for wildcard testing:
+ * hosts matching op8 op9
+ * * y y
+ * 38.* y n
+ * 38.202.* n y
+ * 38.202.16 n n
+ * 26:* y n
+ * 26:ca:* n y
+ * 26:ca:10:* n n
+ */
+ sts = 0;
+ for (i = 0; i < 4; i++) {
+ if (ipv4) {
+ if ((s = __pmAccAddHost(wnames[i], 0x300, (i << 8), 0)) < 0) {
+ fprintf(stderr, "cannot add inet host for op%d: %s\n", i, strerror(s));
+ sts = s;
+ }
+ }
+ if (ipv6) {
+ if ((s = __pmAccAddHost(wnames6[i], 0x300, (i << 8), 0)) < 0) {
+ fprintf(stderr, "cannot add IPv6 host for op%d: %s\n", i, strerror(s));
+ sts = s;
+ }
+ }
+ }
+ if (sts < 0)
+ return 1;
+
+ putc('\n', stderr);
+
+ putc('\n', stderr);
+ __pmAccDumpHosts(stderr);
+
+ putc('\n', stderr);
+
+ putc('\n', stderr);
+ if (ipv4) {
+ for (i = 0; i < 2; i++)
+ for (ai = 0; ai < 4; ai++)
+ for (bi = 0; bi < 4; bi++)
+ for (ci = 0; ci < 4; ci++)
+ for (di = 0; di < 4; di++) {
+ char buf[20];
+ char *host;
+ sprintf(buf, "%d.%d.%d.%d", a[ai]+i, b[bi]+i, c[ci]+i, d[di]+i);
+ if ((inaddr =__pmStringToSockAddr(buf)) == NULL) {
+ printf("insufficient memory\n");
+ continue;
+ }
+ s = __pmAccAddClient(inaddr, &perm);
+ host = __pmSockAddrToString(inaddr);
+ __pmSockAddrFree(inaddr);
+ if (s < 0) {
+ fprintf(stderr, "from %s error: %s\n", host, pmErrStr(s));
+ free(host);
+ continue;
+ }
+ fprintf(stderr, "got %03x for host %s\n", perm, host);
+ free(host);
+ }
+ }
+ if (ipv6) {
+ for (i = 0; i < 2; i++)
+ for (ai = 0; ai < 4; ai++)
+ for (bi = 0; bi < 4; bi++)
+ for (ci = 0; ci < 4; ci++)
+ for (di = 0; di < 4; di++) {
+ char buf[4*8 + 7 + 1]; /* handles full IPv6 address */
+ char *host;
+ sprintf(buf, "%x:%x:%x:%x:%x:%x:%x:%x",
+ a[ai]+i, b[bi]+i, c[ci]+i, d[di]+i,
+ a[ai]+i, b[bi]+i, c[ci]+i, d[di]+i);
+ if ((inaddr =__pmStringToSockAddr(buf)) == NULL) {
+ printf("insufficient memory\n");
+ continue;
+ }
+ s = __pmAccAddClient(inaddr, &perm);
+ host = __pmSockAddrToString(inaddr);
+ __pmSockAddrFree(inaddr);
+ if (s < 0) {
+ fprintf(stderr, "from %s error: %s\n", host, pmErrStr(s));
+ free(host);
+ continue;
+ }
+ fprintf(stderr, "got %03x for host %s\n", perm, host);
+ free(host);
+ }
+ }
+
+ return 0;
+}
diff --git a/qa/src/chkacc4.c b/qa/src/chkacc4.c
new file mode 100644
index 0000000..3c25825
--- /dev/null
+++ b/qa/src/chkacc4.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2013 Red Hat.
+ *
+ * Exercise basic user access control checking APIs.
+ * (non-Win32 variant of the test, uses uid_t/gid_t)
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#if defined(HAVE_PWD_H)
+#include <pwd.h>
+#endif
+#if defined(HAVE_GRP_H)
+#include <grp.h>
+#endif
+
+gid_t gid;
+struct group *grp, *groups;
+int ngroups;
+uid_t uid;
+struct passwd *usr, *users;
+int nusers;
+unsigned int op;
+
+int
+check_users(void)
+{
+ int c, s, sts = 0;
+
+ for (c = 0; c < nusers; c++) {
+ usr = &users[c];
+ if ((s = __pmAccAddUser(usr->pw_name, 1 << c, 1 << c, 0)) < 0) {
+ printf("cannot add user for op%d: %s\n", c, pmErrStr(s));
+ sts = s;
+ }
+ }
+ if (sts < 0)
+ return 1;
+
+ putc('\n', stderr);
+ __pmAccDumpUsers(stderr);
+ putc('\n', stderr);
+
+ for (c = 0; c < WORD_BIT; c++) {
+ usr = &users[c % nusers];
+ sts = __pmAccAddAccount(usr->pw_name, NULL, &op);
+ if (sts < 0) {
+ printf("add user #%d (%s): %s\n", c, usr->pw_name, pmErrStr(sts));
+ continue;
+ }
+ else if (op != (1 << c))
+ printf("account %d: __pmAccAddAccount returns denyOpsResult 0x%x (expected 0x%x)\n",
+ c, op, 1 << c);
+ }
+
+ putc('\n', stderr);
+ __pmAccDumpUsers(stderr);
+ putc('\n', stderr);
+ return 0;
+}
+
+int
+check_groups(void)
+{
+ int c, s, sts = 0;
+
+ for (c = 0; c < ngroups; c++) {
+ grp = &groups[c];
+ if ((s = __pmAccAddGroup(grp->gr_name, 1 << c, 1 << c, 0)) < 0) {
+ printf("cannot add group for op%d: %s\n", c, pmErrStr(s));
+ sts = s;
+ }
+ }
+ if (sts < 0)
+ return 1;
+
+ putc('\n', stderr);
+ __pmAccDumpGroups(stderr);
+ putc('\n', stderr);
+
+ for (c = 0; c < WORD_BIT; c++) {
+ grp = &groups[c % ngroups];
+ sts = __pmAccAddAccount(NULL, grp->gr_name, &op);
+ if (sts < 0) {
+ printf("add group #%d (%s): %s\n", c, grp->gr_name, pmErrStr(sts));
+ continue;
+ }
+ else if (op != (1 << c))
+ printf("account %d: __pmAccAddAccount returns denyOpsResult 0x%x (expected 0x%x)\n",
+ c, op, 1 << c);
+ }
+
+ putc('\n', stderr);
+ __pmAccDumpGroups(stderr);
+ putc('\n', stderr);
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int c, sts;
+ int errflag = 0;
+ char *name;
+ size_t size;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:u:g:?")) != EOF) {
+ switch (c) {
+ case 'D': /* debug flag */
+ if ((sts = __pmParseDebug(optarg)) < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'g': /* another group ID */
+ gid = atoi(optarg);
+ if ((grp = getgrgid(gid)) == NULL) {
+ fprintf(stderr, "%s: getgrgid: unknown group identifier (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ break;
+ }
+ size = (ngroups + 1) * sizeof(*grp);
+ if ((groups = realloc(groups, size)) == NULL)
+ __pmNoMem("gid realloc", size, PM_FATAL_ERR);
+ groups[ngroups] = *grp;
+ for (c = 0, name = grp->gr_mem[0]; name; c++, name++)
+ groups[ngroups].gr_mem[c] = strdup(name);
+ ngroups++;
+ break;
+
+ case 'u': /* another user ID */
+ uid = atoi(optarg);
+ if ((usr = getpwuid(uid)) == NULL) {
+ fprintf(stderr, "%s: getpwuid: unknown user identifier (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ break;
+ }
+ size = (nusers + 1) * sizeof(*usr);
+ if ((users = realloc(users, size)) == NULL)
+ __pmNoMem("uid realloc", size, PM_FATAL_ERR);
+ memset(&users[nusers], 0, sizeof(*usr));
+ users[nusers].pw_name = strdup(usr->pw_name);
+ users[nusers].pw_uid = usr->pw_uid;
+ users[nusers].pw_gid = usr->pw_gid;
+ nusers++;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s [options] uid ...\n\
+\n\
+Options:\n\
+ -D pmdebug set debugging diagnostics flag\n\
+ -u uid add numeric user ID to set used in testing\n\
+ -g gid add numeric group ID to set used in testing\n",
+ pmProgname);
+ return 1;
+ }
+
+ sts = 0;
+ for (op = 0; op < WORD_BIT; op++) {
+ if ((c = __pmAccAddOp(1 << op)) < 0) {
+ printf("Bad op %d: %s\n", op, pmErrStr(c));
+ sts = c;
+ }
+ if ((c = __pmAccAddOp(1 << op)) >= 0) {
+ printf("duplicate op test failed for op %d\n", op);
+ sts = -EINVAL;
+ }
+ }
+ if (sts < 0)
+ return 1;
+
+ if (nusers)
+ if ((sts = check_users()) != 0)
+ return sts;
+
+ if (ngroups)
+ if ((sts = check_groups()) != 0)
+ return sts;
+
+ return 0;
+}
diff --git a/qa/src/chkconnect.c b/qa/src/chkconnect.c
new file mode 100644
index 0000000..03e211b
--- /dev/null
+++ b/qa/src/chkconnect.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <unistd.h>
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int j;
+ int numpmid;
+ int numval;
+ char *namelist[20];
+ pmID pmidlist[20];
+ pmResult *result;
+ int c;
+ int sts;
+ int i;
+ int errflag = 0;
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+ char *endnum;
+ int iter = 100;
+
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N]";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-h hostname] [-i iterations] [-n namespace]";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:h:i:n:")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ host = optarg;
+ break;
+
+ case 'i': /* iteration count */
+ iter = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: -i requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ fprintf(stderr, "pmLoadNameSpace(%s): %s\n", namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ i = 0;
+ namelist[i++] = "sample.control";
+ namelist[i++] = "sampledso.control";
+ namelist[i++] = "sampledso.control";
+ namelist[i++] = "pmcd.control.debug";
+ namelist[i++] = "sample.control";
+ namelist[i++] = "pmcd.control.debug";
+ namelist[i++] = "sampledso.control";
+ namelist[i++] = "pmcd.control.debug";
+ namelist[i++] = "sample.control";
+ namelist[i++] = "sampledso.control";
+ namelist[i++] = "pmcd.control.debug";
+ namelist[i++] = "sample.control";
+ numpmid = i;
+ sts = pmLookupName(numpmid, namelist, pmidlist);
+ if (sts < 0) {
+ fprintf(stderr, "pmLookupName: %s\n", pmErrStr(sts));
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ printf(" %s - not known\n", namelist[i]);
+ }
+ exit(1);
+ }
+
+ for (i = 0; i < iter; i++) {
+ sts = pmNewContext(PM_CONTEXT_HOST, host);
+ if (sts < 0) {
+ fprintf(stderr, "pmNewContext: [iteration %d] %s\n", i, pmErrStr(sts));
+ exit(1);
+ }
+ else if (sts != i * 2)
+ fprintf(stderr, "Error: [iteration %d] pmNewContext handle expected %d, got %d\n", i, i * 2, sts);
+
+ numpmid = 1 + lrand48() % 12;
+ if ((sts = pmFetch(numpmid, pmidlist, &result)) < 0) {
+ fprintf(stderr, "pmFetch: [iteration %d] %s\n", i, pmErrStr(sts));
+ exit(1);
+ }
+ numval = 0;
+ for (j = 0; j < result->numpmid; j++) {
+ if (result->vset[j]->numval >= 0)
+ numval += result->vset[j]->numval;
+ }
+ if (numval != numpmid) {
+ fprintf(stderr, "Error: [iteration %d] pmFetch numval expected %d, got %d\n", i, numpmid, numval);
+ }
+ pmFreeResult(result);
+
+ sts = pmDupContext();
+ if (sts < 0) {
+ fprintf(stderr, "pmDupContext: [iteration %d] %s\n", i, pmErrStr(sts));
+ exit(1);
+ }
+ else if (sts != i * 2 + 1)
+ fprintf(stderr, "Error: [iteration %d] pmDupContext handle expected %d, got %d\n", i, i * 2 + 1, sts);
+
+ numpmid = 1 + lrand48() % 12;
+ if ((sts = pmFetch(numpmid, pmidlist, &result)) < 0) {
+ fprintf(stderr, "pmFetch: [iteration %d, dup context] %s\n", i, pmErrStr(sts));
+ exit(1);
+ }
+ numval = 0;
+ for (j = 0; j < result->numpmid; j++) {
+ if (result->vset[j]->numval >= 0)
+ numval += result->vset[j]->numval;
+ }
+ if (numval != numpmid) {
+ fprintf(stderr, "Error: [iteration %d] pmFetch numval expected %d, got %d\n", i, numpmid, numval);
+ }
+ pmFreeResult(result);
+
+ if ((sts = pmReconnectContext(i)) < 0) {
+ fprintf(stderr, "pmReconnectContext: [iteration %d] %s\n", i, pmErrStr(sts));
+ exit(1);
+ }
+
+ numpmid = 1 + lrand48() % 12;
+ if ((sts = pmFetch(numpmid, pmidlist, &result)) < 0) {
+ fprintf(stderr, "pmFetch: [iteration %d, recon] %s\n", i, pmErrStr(sts));
+ exit(1);
+ }
+ numval = 0;
+ for (j = 0; j < result->numpmid; j++) {
+ if (result->vset[j]->numval >= 0)
+ numval += result->vset[j]->numval;
+ }
+ if (numval != numpmid) {
+ fprintf(stderr, "Error: [iteration %d, recon] pmFetch numval expected %d, got %d\n", i, numpmid, numval);
+ }
+ pmFreeResult(result);
+
+ }
+
+ return 0;
+}
diff --git a/qa/src/chkctx2.c b/qa/src/chkctx2.c
new file mode 100644
index 0000000..84100bf
--- /dev/null
+++ b/qa/src/chkctx2.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#define SOURCE handle == 0 ? "host" : ( type == PM_CONTEXT_ARCHIVE ? "archive" : "host" )
+#define HOST handle == 0 ? "localhost" : host
+
+/*
+ * context and profile exerciser
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int inst_bin[] = { 100, 200, 300, 400, 500, 600, 700, 800, 900 };
+
+static int xpect_bin[] = { 1 };
+static int xpect_colour[] = { 0 };
+
+static char *namelist[] = {
+ "sampledso.bin",
+ "sampledso.colour"
+};
+
+/*
+ * handle profile values expected
+ * 0 bin=500, no colour 1 bin 0 colour
+ */
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+ pmInDom indom_bin, indom_colour;
+ pmID metrics[2];
+ pmResult *resp;
+ pmDesc desc;
+ int handle;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N] ";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-a archive] [-h hostname] [-L] [-n namespace]";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:h:Ln:")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'L': /* local mode, no PMCD */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ host = NULL;
+ type = PM_CONTEXT_LOCAL;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmLookupName(2, namelist, metrics)) < 0) {
+ fprintf(stderr, "pmLookupName: %s\n", pmErrStr(sts));
+ fprintf(stderr, "pmids: 0x%x 0x%x\n", metrics[0], metrics[1]);
+ exit(1);
+ }
+
+ /* make context 0 the default localhost one */
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ fprintf(stderr, "pmNewContext(..., \"localhost\"): %s\n",
+ pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0)
+ type = PM_CONTEXT_HOST; /* default */
+
+ if (type == PM_CONTEXT_HOST) {
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ fprintf(stderr, "handle: pmNewContext(host=%s): %s\n", host, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ else if (type == PM_CONTEXT_LOCAL) {
+ if ((sts = pmNewContext(PM_CONTEXT_LOCAL, host)) < 0) {
+ fprintf(stderr, "handle: pmNewContext(local): %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ }
+ else {
+ if ((sts = pmNewContext(PM_CONTEXT_ARCHIVE, host)) < 0) {
+ fprintf(stderr, "handle: pmNewContext(archive=%s): %s\n", host, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ handle = sts;
+
+ while (handle >= 0) {
+ pmUseContext(handle);
+
+ if ((sts = pmLookupDesc(metrics[0], &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc: context=%d %s=%s %s: %s\n",
+ handle, SOURCE, HOST, namelist[0], pmErrStr(sts));
+ exit(1);
+ }
+ indom_bin = desc.indom;
+ if ((sts = pmLookupDesc(metrics[1], &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc: context=%d %s=%s %s: %s\n",
+ handle, SOURCE, HOST, namelist[1], pmErrStr(sts));
+ exit(1);
+ }
+ indom_colour = desc.indom;
+
+ pmDelProfile(indom_bin, 0, (int *)0);
+ pmAddProfile(indom_bin, 1, &inst_bin[4]);
+ pmDelProfile(indom_colour, 0, (int *)0);
+
+ sts = pmFetch(2, metrics, &resp);
+ if (sts < 0) {
+ fprintf(stderr, "botch @ context=%d %s=%s: pmFetch: %s\n",
+ handle, SOURCE, HOST, pmErrStr(sts));
+ }
+ else {
+ if (resp->numpmid != 2) {
+ fprintf(stderr, "botch @ context=%d %s=%s: numpmid %d != 2\n",
+ handle, SOURCE, HOST, resp->numpmid);
+ }
+ else {
+ if (resp->vset[0]->numval != xpect_bin[0]) {
+ fprintf(stderr, "botch @ context=%d %s=%s: [indom %s] numval got: %d expect: %d\n",
+ handle, SOURCE, HOST, pmInDomStr(indom_bin),
+ resp->vset[0]->numval, xpect_bin[0]);
+ }
+ if (resp->vset[1]->numval != xpect_colour[0]) {
+ fprintf(stderr, "botch @ context=%d %s=%s: [indom %s] numval got: %d expect: %d\n",
+ handle, SOURCE, HOST, pmInDomStr(indom_colour),
+ resp->vset[1]->numval, xpect_colour[0]);
+ }
+ }
+ pmFreeResult(resp);
+ }
+ if (handle) {
+ if ((sts = pmDestroyContext(handle)) < 0)
+ fprintf(stderr, "pmDestroyContext %d %s=%s: %s\n",
+ handle, SOURCE, HOST, pmErrStr(sts));
+ }
+ handle--;
+ }
+
+ exit(0);
+}
diff --git a/qa/src/chkhelp.c b/qa/src/chkhelp.c
new file mode 100644
index 0000000..6a65fc5
--- /dev/null
+++ b/qa/src/chkhelp.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * exercise the help facilities
+ */
+
+#include <unistd.h>
+#include <ctype.h>
+#include <pcp/pmapi.h>
+
+int
+main()
+{
+ int i;
+ int j;
+ char *namelist[2];
+ pmID pmidlist[2];
+ int n;
+ int numpmid;
+ char *buf;
+ pmDesc desc;
+
+ if ((n = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) {
+ fprintf(stderr, "pmLoadNameSpace: %s\n", pmErrStr(n));
+ exit(1);
+ }
+
+ if ((n = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ fprintf(stderr, "pmNewContext(..., \"localhost\"): %s\n",
+ pmErrStr(n));
+ exit(1);
+ }
+
+ i = 0;
+ namelist[i++] = "sample.colour";
+ namelist[i++] = "sample.byte_ctr";
+ numpmid = i;
+ n = pmLookupName(numpmid, namelist, pmidlist);
+ if (n != numpmid) {
+ fprintf(stderr, "pmLookupName: %s\n", pmErrStr(n));
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ fprintf(stderr, " %s - not known\n", namelist[i]);
+ }
+ exit(1);
+ }
+
+ for (j = 0; j < 3; j++) {
+ /* default context (j==0) then NewContext(j==1) then DupContext(j==2) */
+ for (i = 0; i < numpmid; i++) {
+ if (j == 0)
+ fprintf(stderr, "\nDefault Context\n");
+ else if (j == 1) {
+ fprintf(stderr, "\nNew Context\n");
+ if ((n = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ fprintf(stderr, "pmNewContext: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ }
+ else {
+ fprintf(stderr, "\nDup Context\n");
+ if ((n = pmDupContext()) < 0) {
+ fprintf(stderr, "pmDupContext: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ }
+
+ fprintf(stderr, "metric: %s\n", namelist[i]);
+ if ((n = pmLookupDesc(pmidlist[i], &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc failed: %s\n", pmErrStr(n));
+ exit(1);
+ }
+
+ if ((n = pmLookupText(pmidlist[i], PM_TEXT_ONELINE, &buf)) < 0)
+ fprintf(stderr, "pmLookupText: %s\n", pmErrStr(n));
+ else {
+ fprintf(stderr, "\nOneline Text: %s\n", buf);
+ free(buf);
+ }
+
+ if ((n = pmLookupInDomText(desc.indom, PM_TEXT_ONELINE, &buf)) < 0)
+ fprintf(stderr, "pmLookupInDomText: %s\n", pmErrStr(n));
+ else {
+ fprintf(stderr, "\nOneline InDomText: %s\n", buf);
+ free(buf);
+ }
+
+ if ((n = pmLookupText(pmidlist[i], PM_TEXT_HELP, &buf)) < 0)
+ fprintf(stderr, "pmLookupText: %s\n", pmErrStr(n));
+ else {
+ fprintf(stderr, "\nHelp Text: %s\n", buf);
+ free(buf);
+ }
+
+ if ((n = pmLookupInDomText(desc.indom, PM_TEXT_HELP, &buf)) < 0)
+ fprintf(stderr, "pmLookupInDomText: %s\n", pmErrStr(n));
+ else {
+ fprintf(stderr, "\nHelp InDomText: %s\n", buf);
+ free(buf);
+ }
+ }
+ }
+
+ exit(0);
+}
diff --git a/qa/src/chknumval.c b/qa/src/chknumval.c
new file mode 100644
index 0000000..6293876
--- /dev/null
+++ b/qa/src/chknumval.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * chknumval - check out new encoding of errors within numval of a pmResult
+ *
+ * also drives pmStore, __pmConnectLogger and __pmControlLog testing
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *errmsg;
+ int type = 0;
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+ int i;
+ int ctlport;
+ int pid = PM_LOG_PRIMARY_PID;
+ int port = PM_LOG_NO_PORT;
+ char *namelist[20];
+ pmID pmidlist[20];
+ int *instlist;
+ char **inamelist;
+ int numpmid = 0;
+ int default_metrics = 0;
+ pmResult *req;
+ pmResult *status;
+ pmDesc desc;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:h:K:Ln:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'h': /* hostname for PMCD to contact */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of --h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'K': /* update local PMDA table */
+ if ((errmsg = __pmSpecLocalPMDA(optarg)) != NULL) {
+ fprintf(stderr, "%s: __pmSpecLocalPMDA failed: %s\n", pmProgname, errmsg);
+ errflag++;
+ }
+ break;
+
+ case 'L': /* local PMDA connection, no PMCD */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_LOCAL;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s [options] [metricname ...]\n\
+\n\
+Options\n\
+ -D debug standard PCP debug flag\n\
+ -h host metrics source is PMCD on host (default is localhost)\n\
+ -L metrics source is local connection to PMDA, no PMCD\n\
+ -K spec optional additional PMDA spec for local connection\n\
+ spec is of the form op,domain,dso-path,init-routine\n\
+ -n namespace use an alternative PMNS\n\
+ -v be verbose\n",
+ pmProgname);
+ exit(1);
+ }
+
+ while (optind < argc) {
+ namelist[numpmid++] = argv[optind];
+ optind++;
+ }
+ if (numpmid > 0 && numpmid < 3) {
+ printf("Quitting need at least 3 metrics (not %d) for numval tests\n", numpmid);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: pmLoadNameSpace: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) type = PM_CONTEXT_HOST;
+ if ((sts = pmNewContext(type, host)) < 0) {
+ printf("%s: pmNewContext(%d, %s): %s\n", pmProgname, type, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = __pmConnectLogger(host, &pid, &port)) < 0) {
+ printf("%s: Cannot connect to primary pmlogger on host \"%s\": %s\n", pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+ ctlport = sts;
+
+ if (numpmid == 0) {
+ /* default metrics */
+ default_metrics = 1;
+ i = 0;
+ namelist[i++] = "pmcd.control.debug";
+ namelist[i++] = "sampledso.long.write_me";
+ namelist[i++] = "sample.colour";
+ numpmid = i;
+ }
+
+ sts = pmLookupName(numpmid, namelist, pmidlist);
+ if (sts != numpmid) {
+ printf("pmLookupName: failed: %s\n", sts < 0 ? pmErrStr(sts) : "");
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ printf(" %s - not known\n", namelist[i]);
+ }
+ exit(1);
+ }
+
+ if ((sts = pmFetch(numpmid, pmidlist, &req)) < 0) {
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = __pmControlLog(ctlport, req, PM_LOG_MANDATORY, PM_LOG_OFF, 0, &status)) < 0) {
+ printf("__pmControlLog: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ __pmDumpResult(stdout, req);
+
+ printf("\nbase store test (failures not unexpected) ...\n");
+ if ((sts = pmStore(req)) < 0)
+ printf("pmStore: %s\n", pmErrStr(sts));
+ else
+ printf("pmStore: OK\n");
+
+ printf("\nnumpmid == 0 tests (failures expected) ...\n");
+ req->numpmid = 0;
+ __pmDumpResult(stdout, req);
+
+ if ((sts = pmStore(req)) < 0)
+ printf("pmStore: %s\n", pmErrStr(sts));
+ else
+ printf("pmStore: botch, PM_ERR_TOOSMALL expected\n");
+ if ((sts = __pmControlLog(ctlport, req, PM_LOG_ENQUIRE, 0, 0, &status)) < 0)
+ printf("__pmControlLog: %s\n", pmErrStr(sts));
+ else {
+ printf("__pmControlLog: OK\n");
+ __pmDumpResult(stdout, status);
+ pmFreeResult(status);
+ }
+
+ printf("\nnumval == 0 tests (failures expected) ...\n");
+ req->numpmid = numpmid;
+ req->vset[1]->numval = 0;
+ __pmDumpResult(stdout, req);
+
+ if ((sts = pmStore(req)) < 0)
+ printf("pmStore: %s\n", pmErrStr(sts));
+ else
+ printf("pmStore: botch, PM_ERR_VALUE expected\n");
+ if ((sts = __pmControlLog(ctlport, req, PM_LOG_ENQUIRE, 0, 0, &status)) < 0)
+ printf("__pmControlLog: %s\n", pmErrStr(sts));
+ else {
+ printf("__pmControlLog: OK\n");
+ __pmDumpResult(stdout, status);
+ pmFreeResult(status);
+ }
+
+ printf("\nnumval < 0 tests (failures expected) ...\n");
+ req->vset[1]->numval = 1;
+ req->vset[2]->numval = PM_ERR_NOAGENT;
+ __pmDumpResult(stdout, req);
+
+ if ((sts = pmStore(req)) < 0)
+ printf("pmStore: %s\n", pmErrStr(sts));
+ else
+ printf("pmStore: botch, PM_ERR_VALUE expected\n");
+ if ((sts = __pmControlLog(ctlport, req, PM_LOG_ENQUIRE, 0, 0, &status)) < 0)
+ printf("__pmControlLog: %s\n", pmErrStr(sts));
+ else {
+ printf("__pmControlLog: OK\n");
+ __pmDumpResult(stdout, status);
+ pmFreeResult(status);
+ }
+
+ /* exercise *.needprofile */
+ pmFreeResult(req);
+
+ if (default_metrics) {
+ i = 0;
+ namelist[i++] = "sampledso.long.hundred";
+ namelist[i++] = "sampledso.needprofile";
+ namelist[i++] = "sample.long.hundred";
+ namelist[i++] = "sample.needprofile";
+ numpmid = i;
+ }
+ else {
+ if (numpmid < 4) {
+ printf("Quitting need at least 4 metrics for profile tests\n");
+ exit(1);
+ }
+ printf("Warning: running profile tests with non-default metrics ...\n");
+ printf("... metric %s needs an indom with at least %d instances\n", namelist[1], 5);
+ printf("... metric %s needs an indom with at least %d instances\n", namelist[3], 4);
+ }
+
+ sts = pmLookupName(numpmid, namelist, pmidlist);
+ if (sts != numpmid) {
+ printf("pmLookupName: failed: %s\n", sts < 0 ? pmErrStr(sts) : "");
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ printf(" %s - not known\n", namelist[i]);
+ }
+ exit(1);
+ }
+
+ if ((sts = pmFetch(numpmid, pmidlist, &req)) < 0) {
+ printf("pmFetch: botch, %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ __pmDumpResult(stdout, req);
+
+ if ((sts = pmLookupDesc(pmidlist[1], &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmGetInDom(desc.indom, &instlist, &inamelist)) < 0) {
+ printf("pmGetInDom: %s\n", pmErrStr(sts));
+ }
+ pmAddProfile(desc.indom, 1, &instlist[0]);
+ pmAddProfile(desc.indom, 1, &instlist[2]);
+ pmAddProfile(desc.indom, 1, &instlist[4]);
+ free(instlist);
+ free(inamelist);
+
+ if ((sts = pmLookupDesc(pmidlist[3], &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmGetInDom(desc.indom, &instlist, &inamelist)) < 0) {
+ printf("pmGetInDom: %s\n", pmErrStr(sts));
+ }
+ pmAddProfile(desc.indom, 1, &instlist[1]);
+ pmAddProfile(desc.indom, 1, &instlist[3]);
+ free(instlist);
+ free(inamelist);
+
+ if ((sts = pmFetch(numpmid, pmidlist, &req)) < 0) {
+ printf("pmFetch: botch, %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ __pmDumpResult(stdout, req);
+
+ exit(0);
+}
diff --git a/qa/src/chkopenlog.c b/qa/src/chkopenlog.c
new file mode 100644
index 0000000..eb5c22c
--- /dev/null
+++ b/qa/src/chkopenlog.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char *argv[])
+{
+ int sts;
+ FILE *f;
+ FILE *fout;
+ int fd;
+ int nextfd;
+
+ close(3); /* some stdio versions start with this open */
+ close(4); /* some stdio versions start with this open */
+ fd = atoi(argv[1]);
+ if (fd == 1) fout = stdout;
+ else if (fd == 2) fout = stderr;
+ else fout = fopen("/tmp/chk.fout", "w");
+ if (fout == NULL) {
+ fprintf(stderr, "chkopenlog: botched open ... fd=%d\n", fd);
+ sts = system("ls -l /tmp/chk.fout");
+ exit(sts == 0 ? 1 : sts);
+ }
+
+ fprintf(fout, "This message on oldstream before __pmOpenLog() called\n");
+
+
+#define whatis(f) (f == (stderr) ? " (stderr)" : (f == (stdout) ? " (stdout)" : (f == NULL ? " (NULL)" : "")))
+
+ nextfd = open("/dev/null", 0);
+ if (nextfd < 0) {
+ fprintf(stderr, "chkopenlog: failed /dev/null open\n");
+ exit(2);
+ }
+ fprintf(stderr, "Starting with oldstream%s fd=%d, nextfd=%d\n", whatis(fout), fileno(fout), nextfd);
+ close(nextfd);
+
+ nextfd = open("/dev/null", 0);
+ f = __pmOpenLog("chkopenlog", argv[2], fout, &sts);
+ fprintf(stderr, "__pmOpenLog -> sts=%d, log %s newstream%s fd=%d, nextfd=%d\n",
+ sts, argv[2], whatis(f), f != NULL ? fileno(f) : -1, nextfd);
+ if (f != NULL)
+ fprintf(f, "[a helpful little message]\n");
+
+ exit(0);
+}
diff --git a/qa/src/chkoptfetch.c b/qa/src/chkoptfetch.c
new file mode 100644
index 0000000..7fde1b0
--- /dev/null
+++ b/qa/src/chkoptfetch.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static fetchctl_t *root;
+
+static optreq_t *req;
+static pmDesc *desc;
+static int *cost;
+static int *nfetch;
+static pmUnits nounits;
+
+static void
+setup(int i, int pmid_d, int pmid_i, int indom_d, int indom_s, int loinst, int hiinst)
+{
+ int j;
+ int numinst;
+ static int pmid = 0;
+ static int indom = 0;
+ static __pmID_int *pmidp = (__pmID_int *)&pmid;
+ static __pmInDom_int *indomp = (__pmInDom_int *)&indom;
+
+ pmidp->flag = 0;
+ pmidp->domain = pmid_d;
+ pmidp->cluster = 0;
+ pmidp->item = pmid_i;
+ indomp->flag = 0;
+ indomp->domain = indom_d;
+ indomp->serial = indom_s;
+
+ desc = (pmDesc *)realloc(desc, (i+1) * sizeof(desc[0]));
+ if (desc == (pmDesc *)0) {
+ __pmNoMem("setup.desc", (i+1) * sizeof(desc[0]), PM_FATAL_ERR);
+ }
+ desc[i].pmid = pmid;
+ desc[i].type = PM_TYPE_32;
+ desc[i].indom = indom;
+ desc[i].sem = PM_SEM_DISCRETE;
+ desc[i].units = nounits;
+
+ req = (optreq_t *)realloc(req, (i+1) * sizeof(req[0]));
+ if (req == (optreq_t *)0) {
+ __pmNoMem("setup.req", (i+1) * sizeof(req[0]), PM_FATAL_ERR);
+ }
+ if (loinst != -1) {
+ req[i].r_numinst = numinst = (hiinst - loinst + 1);
+ req[i].r_instlist = (int *)malloc(numinst * sizeof(req[i].r_instlist[0]));
+ if (req[i].r_instlist == (int *)0) {
+ __pmNoMem("setup.instlist", numinst * sizeof(req[i].r_instlist[0]), PM_FATAL_ERR);
+ }
+ for (j = 0; j < numinst; j++)
+ req[i].r_instlist[j] = loinst + j;
+ }
+ else {
+ /* use loinst == -1 to flag "all" instances here */
+ req[i].r_numinst = 0;
+ req[i].r_instlist = (int *)0;
+ }
+
+ cost = (int *)realloc(cost, (i+1) * sizeof(cost[0]));
+ if (cost == (int *)0) {
+ __pmNoMem("setup.cost", (i+1) * sizeof(cost[0]), PM_FATAL_ERR);
+ }
+ nfetch = (int *)realloc(nfetch, (i+1) * sizeof(nfetch[0]));
+ if (nfetch == (int *)0) {
+ __pmNoMem("setup.nfetch", (i+1) * sizeof(nfetch[0]), PM_FATAL_ERR);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int errflag = 0;
+ int sts;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N] ";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "";
+ int i;
+ int numreq;
+ int numfetch;
+ int totcost;
+ int dump;
+ int numfail;
+ optcost_t ocp = { 4, 1, 15, 10, 2, 0 }; /* my costs */
+ fetchctl_t *fp;
+
+ __pmSetProgname(pmProgname);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ __pmOptFetchPutParams(&ocp);
+ __pmOptFetchGetParams(&ocp);
+ fprintf(stderr, "optFetch Cost Parameters:\n pmid=%d indom=%d fetch=%d indomsize=%d, xtrainst=%d scope=%d\n",
+ ocp.c_pmid, ocp.c_indom, ocp.c_fetch,
+ ocp.c_indomsize, ocp.c_xtrainst, ocp.c_scope);
+
+ i = 0;
+ setup(i, 3, 4, 3, 7, 1, 3);
+ nfetch[i] = 1;
+ cost[i] = ocp.c_fetch + ocp.c_pmid + ocp.c_indom;
+ setup(++i, 3, 4, 3, 7, -1, -1);
+ nfetch[i] = 1;
+ cost[i] = cost[i-1] - ocp.c_fetch;
+ setup(++i, 3, 5, 3, 7, 1, 5);
+ nfetch[i] = 1;
+ cost[i] = ocp.c_pmid + ocp.c_indom + (ocp.c_indomsize - 5) * ocp.c_xtrainst;
+ setup(++i, 3, 6, 3, 7, 1, 8);
+ nfetch[i] = 1;
+ cost[i] = cost[i-1] + (ocp.c_indomsize - 8) * ocp.c_xtrainst;
+ setup(++i, 3, 7, 3, 7, 11, 11);
+ nfetch[i] = 1;
+ cost[i] = cost[i-1] + (ocp.c_indomsize - 1) * ocp.c_xtrainst;
+ setup(++i, 4, 4, 3, 7, -1, -1);
+ nfetch[i] = 1;
+ cost[i] = cost[i-1] + ocp.c_pmid;
+ setup(++i, 5, 4, 3, 7, 1, 5);
+ nfetch[i] = 1;
+ cost[i] = cost[i-1] + ocp.c_pmid + (ocp.c_indomsize - 5) * ocp.c_xtrainst;
+ setup(++i, 6, 4, 3, 7, 1, 8);
+ nfetch[i] = 1;
+ cost[i] = cost[i-1] + ocp.c_pmid + (ocp.c_indomsize - 8) * ocp.c_xtrainst;
+ setup(++i, 7, 4, 3, 7, 11, 11);
+ nfetch[i] = 2;
+ cost[i] = cost[i-1] + ocp.c_fetch + ocp.c_pmid + ocp.c_indom;
+ setup(++i, 7, 4, 3, 7, 10, 12);
+ nfetch[i] = 2;
+ cost[i] = cost[i-1] - ocp.c_fetch;
+ setup(++i, 7, 4, 3, 7, 9, 13);
+ nfetch[i] = 2;
+ cost[i] = cost[i-1];
+
+ numreq = ++i;
+
+ numfail = 0;
+ for (i = 0; i < numreq; i++) {
+ req[i].r_desc = &desc[i];
+ __pmOptFetchAdd(&root, &req[i]);
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_OPTFETCH) {
+ fprintf(stdout, "\nAdd request %d @ " PRINTF_P_PFX "%p\n", i, &req[i]);
+ __pmOptFetchDump(stdout, root);
+ }
+#endif
+ numfetch = 0;
+ totcost = 0;
+ for (fp = root; fp != (fetchctl_t *)0; fp = fp->f_next) {
+ fp->f_state &= (~ OPT_STATE_UMASK);
+ totcost += fp->f_cost;
+ numfetch++;
+ }
+ dump = 0;
+ if (numfetch != nfetch[i]) {
+ printf("After adding request %d, no. fetches %d, expected %d\n",
+ i, numfetch, nfetch[i]);
+ dump = 1;
+ }
+ if (totcost != cost[i]) {
+ printf("After adding request %d, total cost %d, expected %d\n",
+ i, totcost, cost[i]);
+ dump = 1;
+ }
+ if (dump == 1) {
+ numfail++;
+ __pmOptFetchDump(stdout, root);
+ }
+ }
+
+ printf("Passed %d of %d addition tests\n", numreq - numfail, numreq);
+
+ numfail = 0;
+ for (i = numreq-1; i >= 0; i--) {
+ __pmOptFetchDel(&root, &req[i]);
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_OPTFETCH) {
+ fprintf(stdout, "\nDelete request %d @ " PRINTF_P_PFX "%p\n", i, &req[i]);
+ __pmOptFetchDump(stdout, root);
+ }
+#endif
+ if (i == 0)
+ continue;
+ numfetch = 0;
+ totcost = 0;
+ for (fp = root; fp != (fetchctl_t *)0; fp = fp->f_next) {
+ fp->f_state &= (~ OPT_STATE_UMASK);
+ totcost += fp->f_cost;
+ numfetch++;
+ }
+ /* handle special costs when we added another fetch to the group */
+ if (i == 1)
+ totcost += ocp.c_fetch;
+ else if (nfetch[i-1] != nfetch[i-2])
+ totcost += ocp.c_fetch * (nfetch[i-1] - nfetch[i-2]);
+
+ dump = 0;
+ if (numfetch != nfetch[i-1]) {
+ printf("After deleting data set %d, no. fetches %d, expected %d\n",
+ i, numfetch, nfetch[i-1]);
+ dump = 1;
+ }
+ if (totcost != cost[i-1]) {
+ printf("After deleting request %d, total cost %d, expected %d\n",
+ i, totcost, cost[i-1]);
+ dump = 1;
+ }
+ if (dump == 1) {
+ numfail++;
+ __pmOptFetchDump(stdout, root);
+ }
+ }
+ if (root != (fetchctl_t *)0) {
+ printf("Botch: expected no fetch lists after all requests deleted, got ...\n");
+ __pmOptFetchDump(stdout, root);
+ root = (fetchctl_t *)0;
+ numfail++;
+ }
+
+ printf("Passed %d of %d deletion tests\n", numreq - numfail, numreq);
+
+ /* add them all back again */
+ for (i = 0; i < numreq; i++) {
+ req[i].r_desc = &desc[i];
+ __pmOptFetchAdd(&root, &req[i]);
+ }
+ numfetch = 0;
+ totcost = 0;
+ for (fp = root; fp != (fetchctl_t *)0; fp = fp->f_next) {
+ totcost += fp->f_cost;
+ numfetch++;
+ }
+ printf("Before re-arrangement no. fetches %d, total cost %d\n", numfetch, totcost);
+
+ /* and re-arrange, a few times */
+ for (i = 0; i < 10; i++) {
+ __pmOptFetchRedo(&root);
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_OPTFETCH) {
+ fprintf(stdout, "\nNow try a redo ...\n");
+ __pmOptFetchDump(stdout, root);
+ }
+#endif
+ numfetch = 0;
+ totcost = 0;
+ for (fp = root; fp != (fetchctl_t *)0; fp = fp->f_next) {
+ totcost += fp->f_cost;
+ numfetch++;
+ }
+ printf("After re-arrangement no. fetches %d, total cost %d\n", numfetch, totcost);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/chkputlogresult.c b/qa/src/chkputlogresult.c
new file mode 100644
index 0000000..17c2835
--- /dev/null
+++ b/qa/src/chkputlogresult.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+ *
+ * Excercise __pmLogPutResult() and __pmLogPutResult2().
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <assert.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int i;
+ int sts;
+ int bflag = 0;
+ int errflag = 0;
+ char *metrics[] = {
+ "sampledso.long.one",
+ "sampledso.ulonglong.one",
+ "sampledso.float.one",
+ "sampledso.double.one",
+ "sampledso.string.hullo",
+ "sampledso.bin",
+ };
+ int nmetric = sizeof(metrics)/sizeof(metrics[0]);
+ pmID *pmids;
+ pmDesc desc;
+ pmResult *rp;
+ __pmLogCtl ctl = { 0 };
+ __pmPDU *pdp;
+ __pmTimeval epoch = { 0, 0 };
+ int numinst;
+ int *ilist;
+ char **nlist;
+
+ /* trim cmd name of leading directory components */
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "bD::?")) != EOF) {
+ switch (c) {
+
+ case 'b': /* backwards compatibility */
+ bflag++;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc-1) {
+ fprintf(stderr,
+"Usage: %s [options] archive\n\
+\n\
+Options:\n\
+ -b backwards compatibility (use __pmLogPutResult() instead\n\
+ __pmLogPutResult2(), the default\n\
+ -D debugflag[,...]\n\
+",
+ pmProgname);
+ exit(1);
+ }
+
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, "local:")) < 0) {
+ fprintf(stderr, "%s: Cannot connect to PMCD on \"local:\": %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = __pmLogCreate("qatest", argv[optind], LOG_PDU_VERSION, &ctl)) != 0) {
+ fprintf(stderr, "%s: __pmLogCreate failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ ctl.l_state = PM_LOG_STATE_INIT;
+
+ /*
+ * make the archive label deterministic
+ */
+ ctl.l_label.ill_pid = 1234;
+ ctl.l_label.ill_start.tv_sec = epoch.tv_sec;
+ ctl.l_label.ill_start.tv_usec = epoch.tv_usec;
+ strcpy(ctl.l_label.ill_hostname, "happycamper");
+ strcpy(ctl.l_label.ill_tz, "UTC");
+
+ ctl.l_label.ill_vol = PM_LOG_VOL_TI;
+ if ((sts = __pmLogWriteLabel(ctl.l_tifp, &ctl.l_label)) != 0) {
+ fprintf(stderr, "%s: __pmLogWriteLabel TI failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ ctl.l_label.ill_vol = PM_LOG_VOL_META;
+ if ((sts = __pmLogWriteLabel(ctl.l_mdfp, &ctl.l_label)) != 0) {
+ fprintf(stderr, "%s: __pmLogWriteLabel META failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ ctl.l_label.ill_vol = 0;
+ if ((sts = __pmLogWriteLabel(ctl.l_mfp, &ctl.l_label)) != 0) {
+ fprintf(stderr, "%s: __pmLogWriteLabel VOL 0 failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ fflush(ctl.l_mfp);
+ fflush(ctl.l_mdfp);
+ __pmLogPutIndex(&ctl, &epoch);
+
+ pmids = (pmID *)malloc(nmetric*sizeof(pmID));
+ assert(pmids != NULL);
+ for (i = 0; i < nmetric; i++) {
+ if ((sts = pmLookupName(1, &metrics[i], &pmids[i])) != 1) {
+ fprintf(stderr, "%s: pmLookupName(\"%s\") failed: %s\n", pmProgname, metrics[i], pmErrStr(sts));
+ exit(1);
+ }
+ printf("%s -> %s\n", metrics[i], pmIDStr(pmids[i]));
+ if ((sts = pmLookupDesc(pmids[i], &desc)) < 0) {
+ fprintf(stderr, "%s: pmLookupDesc(\"%s\") failed: %s\n", pmProgname, pmIDStr(pmids[i]), pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = __pmLogPutDesc(&ctl, &desc, 1, &metrics[i])) < 0) {
+ fprintf(stderr, "%s: __pmLogPutDesc(\"%s\") failed: %s\n", pmProgname, pmIDStr(pmids[i]), pmErrStr(sts));
+ exit(1);
+ }
+ if (desc.indom != PM_INDOM_NULL) {
+ if ((numinst = pmGetInDom(desc.indom, &ilist, &nlist)) < 0) {
+ printf("pmGetInDom: %s: %s\n", pmInDomStr(desc.indom), pmErrStr(numinst));
+ exit(1);
+ }
+ if ((sts = __pmLogPutInDom(&ctl, desc.indom, &epoch, numinst, ilist, nlist)) < 0) {
+ fprintf(stderr, "%s: __pmLogPutInDom(...,indom=%s,numinst=%d,...) failed: %s\n", pmProgname, pmInDomStr(desc.indom), numinst, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ }
+ for (i = 0; i < nmetric; i++) {
+ if ((sts = pmFetch(i+1, pmids, &rp)) < 0) {
+ fprintf(stderr, "%s: pmFetch(%d, ...) failed: %s\n", pmProgname, i+1, pmErrStr(sts));
+ exit(1);
+ }
+ rp->timestamp.tv_sec = ++epoch.tv_sec;
+ rp->timestamp.tv_usec = epoch.tv_usec;
+ if ((sts = __pmEncodeResult(fileno(ctl.l_mfp), rp, &pdp)) < 0) {
+ fprintf(stderr, "%s: __pmEncodeResult failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ __pmOverrideLastFd(fileno(ctl.l_mfp));
+ if (bflag) {
+ printf("__pmLogPutResult: %d metrics ...\n", i+1);
+ if ((sts = __pmLogPutResult(&ctl, pdp)) < 0) {
+ fprintf(stderr, "%s: __pmLogPutResult failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ else {
+ printf("__pmLogPutResult2: %d metrics ...\n", i+1);
+ if ((sts = __pmLogPutResult2(&ctl, pdp)) < 0) {
+ fprintf(stderr, "%s: __pmLogPutResult2 failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ __pmUnpinPDUBuf(pdp);
+ pmFreeResult(rp);
+ }
+
+ fflush(ctl.l_mfp);
+ fflush(ctl.l_mdfp);
+ __pmLogPutIndex(&ctl, &epoch);
+
+ return 0;
+}
diff --git a/qa/src/chktrim.c b/qa/src/chktrim.c
new file mode 100644
index 0000000..28bae81
--- /dev/null
+++ b/qa/src/chktrim.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * Check new functionality of pmTrimNameSpace
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+extern int errno;
+
+static char tag;
+
+static void
+dometric(const char *name)
+{
+ printf("%c %s\n", tag, name);
+}
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *namespace = PM_NS_DEFAULT;
+ int ctx; /* context for localhost */
+ int arch; /* context for archive */
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N]";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-n namespace] archive";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:n:")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc-1) {
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((ctx = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ printf("%s: pmNewContext(localhost): %s\n", pmProgname, pmErrStr(ctx));
+ exit(1);
+ }
+
+ printf("0 NameSpace for host context ...\n");
+ tag = '0';
+ pmTraversePMNS("sample", dometric);
+
+ if ((arch = pmNewContext(PM_CONTEXT_ARCHIVE, argv[optind])) < 0) {
+ printf("%s: pmNewContext(%s): %s\n", pmProgname, argv[optind], pmErrStr(arch));
+ exit(1);
+ }
+
+ printf("1\n1 Trimmed NameSpace for archive context ...\n");
+ pmTrimNameSpace();
+ tag = '1';
+ pmTraversePMNS("", dometric);
+
+ printf("2\n2 Trimmed NameSpace for host context ...\n");
+ pmUseContext(ctx);
+ pmTrimNameSpace();
+ tag = '2';
+ pmTraversePMNS("sample", dometric);
+
+ exit(0);
+}
diff --git a/qa/src/churnctx.c b/qa/src/churnctx.c
new file mode 100644
index 0000000..bfedad7
--- /dev/null
+++ b/qa/src/churnctx.c
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+ *
+ * Churn a context ... looking for memory leaks a la
+ * http://oss.sgi.com/bugzilla/show_bug.cgi?id=1057
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#define BUILD_STANDALONE 1
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int ctx;
+ int dupctx = 0;
+ int nmetric;
+ int iter;
+ int errflag = 0;
+ int type = 0;
+ char *host = NULL; /* pander to gcc */
+ int mode = PM_MODE_INTERP; /* mode for archives */
+ char *configfile = NULL;
+ char *start = NULL;
+ char *finish = NULL;
+ char *align = NULL;
+ char *offset = NULL;
+ char *logfile = NULL;
+ pmLogLabel label; /* get hostname for archives */
+ int zflag = 0; /* for -z */
+ char *tz = NULL; /* for -Z timezone */
+ int tzh; /* initial timezone handle */
+ char local[MAXHOSTNAMELEN];
+ char *pmnsfile = PM_NS_DEFAULT;
+ int samples = 1;
+ char *endnum;
+ char **name = NULL;
+ pmID *pmid = NULL;
+ pmResult *rp;
+ char *highwater = NULL;
+ struct timeval delta = { 15, 0 };
+ struct timeval startTime;
+ struct timeval endTime;
+ struct timeval appStart;
+ struct timeval appEnd;
+ struct timeval appOffset;
+
+ /* trim cmd name of leading directory components */
+ __pmSetProgname(argv[0]);
+
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+
+ while ((c = getopt(argc, argv, "a:A:c:D:dh:l:Ln:O:s:S:t:T:U:zZ:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+#ifdef BUILD_STANDALONE
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+#else
+ fprintf(stderr, "%s: at most one of -a and -h allowed\n", pmProgname);
+#endif
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'A': /* time alignment */
+ align = optarg;
+ break;
+
+ case 'c': /* configfile */
+ if (configfile != NULL) {
+ fprintf(stderr, "%s: at most one -c option allowed\n", pmProgname);
+ errflag++;
+ }
+ configfile = optarg;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'd': /* dup context rather than new context */
+ dupctx = 1;
+ break;
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+#ifdef BUILD_STANDALONE
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+#else
+ fprintf(stderr, "%s: at most one of -a and -h allowed\n", pmProgname);
+#endif
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+#ifdef BUILD_STANDALONE
+ case 'L': /* LOCAL, no PMCD */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ host = NULL;
+ type = PM_CONTEXT_LOCAL;
+ putenv("PMDA_LOCAL_PROC="); /* if proc PMDA needed */
+ putenv("PMDA_LOCAL_SAMPLE="); /* if sampledso PMDA needed */
+ break;
+#endif
+
+ case 'l': /* logfile */
+ logfile = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ pmnsfile = optarg;
+ break;
+
+ case 'O': /* sample offset time */
+ offset = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples < 0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'S': /* start time */
+ start = optarg;
+ break;
+
+ case 't': /* change update interval */
+ if (pmParseInterval(optarg, &delta, &endnum) < 0) {
+ fprintf(stderr, "%s: illegal -t argument\n", pmProgname);
+ fputs(endnum, stderr);
+ free(endnum);
+ errflag++;
+ }
+ break;
+
+ case 'T': /* terminate time */
+ finish = optarg;
+ break;
+
+ case 'U': /* uninterpolated archive log */
+ if (type != 0) {
+#ifdef BUILD_STANDALONE
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+#else
+ fprintf(stderr, "%s: at most one of -a, -h and -U allowed\n", pmProgname);
+#endif
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ mode = PM_MODE_FORW;
+ host = optarg;
+ break;
+
+ case 'z': /* timezone from host */
+ if (tz != NULL) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ zflag++;
+ break;
+
+ case 'Z': /* $TZ timezone */
+ if (zflag) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ tz = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (zflag && type == 0) {
+ fprintf(stderr, "%s: -z requires an explicit -a, -h or -U option\n", pmProgname);
+ errflag++;
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s [options] [metrics ...]\n\
+\n\
+Options:\n\
+ -a archive metrics source is a PCP log archive\n\
+ -A align align sample times on natural boundaries\n\
+ -c configfile file to load configuration from\n\
+ -d use pmDupContext [default: pmNewContext]\n\
+ -h host metrics source is PMCD on host\n\
+ -l logfile redirect diagnostics and trace output\n"
+#ifdef BUILD_STANDALONE
+" -L use local context instead of PMCD\n"
+#endif
+" -n pmnsfile use an alternative PMNS\n\
+ -O offset initial offset into the time window\n\
+ -s samples terminate after this many iterations [default 1]\n\
+ -S starttime start of the time window\n\
+ -t interval sample interval [default 15.0 seconds]\n\
+ -T endtime end of the time window\n\
+ -z set reporting timezone to local time of metrics source\n\
+ -Z timezone set reporting timezone\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (logfile != NULL) {
+ __pmOpenLog(pmProgname, logfile, stderr, &sts);
+ if (sts < 0) {
+ fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmProgname, logfile);
+ }
+ }
+
+ if (pmnsfile != PM_NS_DEFAULT && (sts = pmLoadNameSpace(pmnsfile)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname,
+ pmnsfile, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ (void)gethostname(local, MAXHOSTNAMELEN);
+ local[MAXHOSTNAMELEN-1] = '\0';
+ host = local;
+ }
+ if ((ctx = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(ctx));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(ctx));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ startTime = label.ll_start;
+ if ((sts = pmGetArchiveEnd(&endTime)) < 0) {
+ endTime.tv_sec = INT_MAX;
+ endTime.tv_usec = 0;
+ fflush(stdout);
+ fprintf(stderr, "%s: Cannot locate end of archive: %s\n",
+ pmProgname, pmErrStr(sts));
+ fprintf(stderr, "\nWARNING: This archive is sufficiently damaged that it may not be possible to\n");
+ fprintf(stderr, " produce complete information. Continuing and hoping for the best.\n\n");
+ fflush(stderr);
+ }
+ }
+ else {
+ gettimeofday(&startTime, NULL);
+ endTime.tv_sec = INT_MAX;
+ }
+
+ if (zflag) {
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+ if (type == PM_CONTEXT_ARCHIVE)
+ printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n",
+ label.ll_hostname);
+ else
+ printf("Note: timezone set to local timezone of host \"%s\"\n\n", host);
+ }
+ else if (tz != NULL) {
+ if ((tzh = pmNewZone(tz)) < 0) {
+ fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n",
+ pmProgname, tz, pmErrStr(tzh));
+ exit(1);
+ }
+ printf("Note: timezone set to \"TZ=%s\"\n\n", tz);
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ nmetric = 0;
+ while (optind < argc) {
+ nmetric++;
+ if ((name = (char **)realloc(name, nmetric*sizeof(name[0]))) == NULL) {
+ fprintf(stderr, "name[%d] malloc failed @ %s\n", nmetric-1, argv[optind]);
+ exit(1);
+ }
+ name[nmetric-1] = argv[optind];
+ if ((pmid = (pmID *)realloc(pmid, nmetric*sizeof(pmid[0]))) == NULL) {
+ fprintf(stderr, "pmid[%d] malloc failed @ %s\n", nmetric-1, argv[optind]);
+ exit(1);
+ }
+ if ((sts = pmLookupName(1, &name[nmetric-1], &pmid[nmetric-1])) < 0) {
+ fprintf(stderr, "Warning: pmLookupName(\"%s\",...) failed: %s\n", name[nmetric-1], pmErrStr(sts));
+ }
+ optind++;
+ }
+
+ if (align != NULL && type != PM_CONTEXT_ARCHIVE) {
+ fprintf(stderr, "%s: -A option only supported for PCP archives, alignment request ignored\n",
+ pmProgname);
+ align = NULL;
+ }
+
+ sts = pmParseTimeWindow(start, finish, align, offset, &startTime,
+ &endTime, &appStart, &appEnd, &appOffset,
+ &endnum);
+ if (sts < 0) {
+ fprintf(stderr, "%s: illegal time window specification\n%s", pmProgname, endnum);
+ exit(1);
+ }
+
+ iter = 1;
+ while (samples == -1 || samples-- > 0) {
+ int new_ctx;
+ char *check;
+
+ if (dupctx) {
+ if ((new_ctx = pmDupContext()) < 0) {
+ fprintf(stderr, "%s: pmDupContext failed: %s\n", pmProgname, pmErrStr(new_ctx));
+ exit(1);
+ }
+ }
+ else {
+ if ((new_ctx = pmNewContext(type, host)) < 0) {
+ fprintf(stderr, "%s: pmNewContext failed: %s\n", pmProgname, pmErrStr(new_ctx));
+ exit(1);
+ }
+
+ }
+
+ if ((sts = pmDestroyContext(ctx)) < 0) {
+ fprintf(stderr, "%s: pmDestroyContex failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmUseContext(new_ctx)) < 0) {
+ fprintf(stderr, "%s: pmUseContext(%d) failed: %s\n", pmProgname, new_ctx, pmErrStr(sts));
+ exit(1);
+ }
+ ctx = new_ctx;
+ /* dump out PDU buffer pool state */
+ __pmFindPDUBuf(-1);
+ /* check for outrageous memory leaks */
+ check = (char *)sbrk(0);
+ if (highwater != NULL) {
+ if (check - highwater > 4096) {
+ printf("Memory growth (iteration %d): %ld\n", iter, (long)(check - highwater));
+ highwater = check;
+ }
+ }
+ else
+ highwater = check;
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if (mode == PM_MODE_INTERP) {
+ int delta_msec;
+ delta_msec = delta.tv_sec*1000 + delta.tv_usec/1000;
+ if ((sts = pmSetMode(mode, &appStart, delta_msec)) < 0) {
+ fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ appStart.tv_sec += delta.tv_sec;
+ appStart.tv_usec += delta.tv_usec;
+ if (appStart.tv_usec > 1000000) {
+ appStart.tv_usec -= 1000000;
+ appStart.tv_sec++;
+ }
+ }
+
+ if (nmetric > 0) {
+ if ((sts = pmFetch(nmetric, pmid, &rp)) < 0) {
+ fprintf(stderr, "%s: pmFetch failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ else {
+ int i;
+ char now[26];
+ time_t stamp;
+ stamp = rp->timestamp.tv_sec;
+ printf("%s", pmCtime(&stamp, now));
+ for (i = 0; i < nmetric; i++) {
+ printf("%s: %d values\n", pmIDStr(rp->vset[i]->pmid), rp->vset[i]->numval);
+ }
+ pmFreeResult(rp);
+ }
+
+ if (type != PM_CONTEXT_ARCHIVE) {
+ __pmtimevalSleep(delta);
+ }
+ }
+ else
+ printf("Nothing to be fetched\n");
+ iter++;
+ }
+
+ if ((sts = pmDestroyContext(ctx)) < 0) {
+ fprintf(stderr, "%s: final pmDestroyContex failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/qa/src/clientid.c b/qa/src/clientid.c
new file mode 100644
index 0000000..066f304
--- /dev/null
+++ b/qa/src/clientid.c
@@ -0,0 +1,91 @@
+/*
+ * Exercise __pmSetClientId()
+ *
+ * Copyright (c) 2009 Ken McDonell. All Rights Reserved.
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#define TAG "QA-clientid "
+
+int
+main(int argc, char *argv[])
+{
+ int ctx;
+ int sts;
+ int c;
+ int a;
+ int lflag = 0;
+ int errflag = 0;
+ static char *usage = "[-l] [-D debugopts]";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:l")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'l': /* linger when done */
+ lflag = 1;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ fprintf(stderr, "Error expected ...\n");
+ if ((sts = __pmSetClientId("no context yet, bozo")) < 0) {
+ fprintf(stderr, "__pmSetClientId(...): %s\n",
+ pmErrStr(sts));
+ }
+
+ if ((ctx = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ fprintf(stderr, "pmNewContext(..., \"localhost\"): %s\n",
+ pmErrStr(ctx));
+ exit(1);
+ }
+
+ for (a = optind; a < argc; a++) {
+ char *cp;
+ cp = (char *)malloc(strlen(argv[a])+strlen(TAG)+1);
+ strcpy(cp, TAG);
+ strcat(cp, argv[a]);
+ if ((sts = __pmSetClientId(cp)) < 0) {
+ fprintf(stderr, "__pmSetClientId(%s): %s\n",
+ cp, pmErrStr(sts));
+ }
+ else {
+ sts = system("pminfo -f pmcd.client.whoami");
+ if (sts != 0)
+ fprintf(stderr, "Warning: pminfo command: exit status %d\n", sts);
+ }
+ free(cp);
+ }
+
+ if (lflag)
+ pause();
+
+ exit(0);
+}
diff --git a/qa/src/compare.c b/qa/src/compare.c
new file mode 100644
index 0000000..b283995
--- /dev/null
+++ b/qa/src/compare.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <math.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char *argv[])
+{
+ double d[3];
+ long l[3];
+ char *endp;
+ int haveDouble = 0;
+ int i, j;
+ int smallVal = 2;
+ int smallDVal = 2.0;
+ double tolerance = 0.1;
+ int c;
+ int err = 0;
+ int nArgs;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "s:t:")) != EOF)
+ switch (c) {
+ case 's': /* small value */
+ smallVal = (int)strtol(optarg, &endp, 0);
+ if (*endp == '.') {
+ smallDVal = strtod(optarg, &endp);
+ haveDouble = 1;
+ }
+ if (*endp != '\0') {
+ fprintf(stderr, "small value \"%s\" was not numeric\n", optarg);
+ err++;
+ }
+ break;
+
+ case 't': /* tolerance (fraction of max) */
+ tolerance = strtod(optarg, &endp);
+ if (*endp != '\0') {
+ fprintf(stderr, "tolerance \"%s\" was not numeric\n", optarg);
+ err++;
+ }
+ break;
+
+ case '?':
+ err++;
+ }
+
+ nArgs = argc - optind;
+ if (err || nArgs < 2 || nArgs > 3) {
+ fprintf(stderr,
+ "Usage: %s [-t tolerance] [-s small] number number [number]\n",
+ pmProgname);
+ exit(1);
+ }
+
+ for (i = 0; i < nArgs; i++) {
+ if (!haveDouble) {
+ l[i] = strtol(argv[optind + i], &endp, 0);
+ if (*endp == '.') {
+ for (j = 0; j < i; j++)
+ d[j] = (double)l[j];
+ d[i] = strtod(argv[i], &endp);
+ haveDouble = 1;
+ }
+ }
+ else
+ d[i] = strtod(argv[optind + i], &endp);
+ if (*endp != '\0') {
+ fprintf(stderr, "%s: non-numeric argument \"%s\"\n", pmProgname, argv[optind + i]);
+ exit(1);
+ }
+ }
+
+ if (nArgs == 2)
+ /* check for 2 values within within 10% or one small and the delta small */
+ if (haveDouble) {
+ double
+ delta = fabs(d[1] - d[0]),
+ max = d[0] > d[1] ? d[0] : d[1];
+ if (delta / max <= tolerance)
+ exit(0);
+ else
+ if ((d[0] <= smallDVal || d[1] <= smallDVal) && delta <= smallDVal)
+ exit(0);
+ exit(1);
+ }
+ else {
+ long
+ delta = l[1] > l[0] ? l[1] - l[0] : l[0] - l[1],
+ max = l[0] > l[1] ? l[0] : l[1];
+ if ((float)delta / (float)max <= tolerance)
+ exit(0);
+ else
+ if ((l[0] <= smallVal || l[1] <= smallVal) && delta <= smallVal)
+ exit(0);
+ exit(1);
+ }
+ else
+ if (haveDouble)
+ if (d[0] <= d[1] && d[1] <= d[2])
+ exit(0);
+ else
+ exit(1);
+ else
+ if (l[0] <= l[1] && l[1] <= l[2])
+ exit(0);
+ else
+ exit(1);
+
+}
diff --git a/qa/src/config.bar b/qa/src/config.bar
new file mode 100644
index 0000000..2c8691b
--- /dev/null
+++ b/qa/src/config.bar
@@ -0,0 +1,18 @@
+#
+# this one is for the util progs and QA
+#
+
+log mandatory on 100 msec {
+ sampledso.bin["bin-100"]
+ sampledso.milliseconds
+}
+
+log mandatory on 500 msec {
+ sampledso.bin["bin-500"]
+ sampledso.milliseconds
+}
+
+log mandatory on 900 msec {
+ sampledso.bin["bin-900"]
+ sampledso.milliseconds
+}
diff --git a/qa/src/config.bigbin b/qa/src/config.bigbin
new file mode 100644
index 0000000..d08d4b7
--- /dev/null
+++ b/qa/src/config.bigbin
@@ -0,0 +1,14 @@
+#
+# this one is for the util progs and QA
+#
+
+log mandatory on 20 msec {
+ sample.milliseconds
+ sample.colour
+ sample.bucket
+ sample.bin
+ sampledso.milliseconds
+ sampledso.colour
+ sampledso.bucket
+ sampledso.bin
+}
diff --git a/qa/src/config.dodgey-all b/qa/src/config.dodgey-all
new file mode 100644
index 0000000..4d11d09
--- /dev/null
+++ b/qa/src/config.dodgey-all
@@ -0,0 +1,9 @@
+#
+# this one is for the util progs and QA - check for changes in the
+# instance domain during the log ... problems with interplote mode
+# and missing instances
+#
+
+log mandatory on 500 msec {
+ sample.dodgey.value
+}
diff --git a/qa/src/config.dodgey-mixed b/qa/src/config.dodgey-mixed
new file mode 100644
index 0000000..a82122a
--- /dev/null
+++ b/qa/src/config.dodgey-mixed
@@ -0,0 +1,13 @@
+#
+# this one is for the util progs and QA - check for changes in the
+# instance domain during the log ... problems with interplote mode
+# and missing instances
+#
+
+log mandatory on 500 msec {
+ sample.dodgey.value [ d3 d4 d5 ]
+}
+
+log mandatory on 250 msec {
+ sample.dodgey.value [ d1 d2 ]
+}
diff --git a/qa/src/config.dodgey-some b/qa/src/config.dodgey-some
new file mode 100644
index 0000000..ebd017d
--- /dev/null
+++ b/qa/src/config.dodgey-some
@@ -0,0 +1,9 @@
+#
+# this one is for the util progs and QA - check for changes in the
+# instance domain during the log ... problems with interplote mode
+# and missing instances
+#
+
+log mandatory on 500 msec {
+ sample.dodgey.value [ d2 d3 d4 d5 ]
+}
diff --git a/qa/src/config.foo b/qa/src/config.foo
new file mode 100644
index 0000000..2acfe6c
--- /dev/null
+++ b/qa/src/config.foo
@@ -0,0 +1,11 @@
+#
+# this one is to make the "foo" archive(s) for PCP QA suite
+#
+
+log mandatory on 1 sec {
+ sample.seconds
+ sample.bin
+ sample.colour
+ sample.drift
+ sample.lights
+}
diff --git a/qa/src/config1.interp b/qa/src/config1.interp
new file mode 100644
index 0000000..a1a2aef
--- /dev/null
+++ b/qa/src/config1.interp
@@ -0,0 +1,7 @@
+log advisory on 10 secs {
+ sample.seconds
+}
+
+log advisory on 3 sec {
+ sample.milliseconds
+}
diff --git a/qa/src/config2.interp b/qa/src/config2.interp
new file mode 100644
index 0000000..bd4778d
--- /dev/null
+++ b/qa/src/config2.interp
@@ -0,0 +1,7 @@
+log advisory on 3 sec {
+ sample.milliseconds
+}
+
+log advisory on 10 secs {
+ sample.seconds
+}
diff --git a/qa/src/conn20070309.0 b/qa/src/conn20070309.0
new file mode 100644
index 0000000..5beb137
--- /dev/null
+++ b/qa/src/conn20070309.0
Binary files differ
diff --git a/qa/src/conn20070309.index b/qa/src/conn20070309.index
new file mode 100644
index 0000000..907a92a
--- /dev/null
+++ b/qa/src/conn20070309.index
Binary files differ
diff --git a/qa/src/conn20070309.meta b/qa/src/conn20070309.meta
new file mode 100644
index 0000000..634211d
--- /dev/null
+++ b/qa/src/conn20070309.meta
Binary files differ
diff --git a/qa/src/context_fd_leak.c b/qa/src/context_fd_leak.c
new file mode 100644
index 0000000..5f67c0a
--- /dev/null
+++ b/qa/src/context_fd_leak.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * Check that file descriptors from pmNewContext are closed on an exec()
+ * call. If not, every open pmcd file descriptor is carried across into the
+ * new program and even if the new program uses libpcp, libpcp can't know what
+ * the file descriptors are for. In other words we leak fds across an exec().
+ *
+ * This was fixed by setting the close on exec flag in pmNewContext.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <sys/wait.h>
+
+void
+printNextFd(void)
+{
+ int fd;
+ int sts;
+
+ fd = open("/dev/null", O_RDONLY);
+ if (fd < 0) {
+ perror("printNextFd");
+ exit(1);
+ }
+ printf("next free file descriptor = %d", fd);
+ sts = close(fd);
+ if (sts < 0) {
+ fprintf(stderr, "error closing fd = %d\n", fd);
+ exit(1);
+ }
+}
+
+int
+main(int argc, char* argv[])
+{
+ int sts;
+ long run;
+ char *endp;
+ int fd;
+
+ __pmSetProgname(argv[0]);
+
+ if (argc != 2) {
+ fprintf(stderr,
+ "Usage: %s count\nwhere count is the number of runs required\n",
+ pmProgname);
+ exit(1);
+ }
+ run = strtol(argv[1], &endp, 0);
+ if (*endp || run < 0) {
+ fprintf(stderr, "bad run count specified: %s\n", argv[1]);
+ exit(1);
+ }
+
+ /*
+ * Some stdio environments start with strange fd's open ... close
+ * 'em all to give us some breathing space
+ */
+ for (fd = 3; fd < 100; fd++)
+ close(fd);
+
+ printf("invocation %ld: ", run);
+ fputs(" at startup, ", stdout);
+ printNextFd();
+ sts = pmNewContext(PM_CONTEXT_HOST, "localhost");
+ if (sts < 0) {
+ fprintf(stderr, "_pmNewContext(localhost): %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ fputs((run > 1) ? " at exec, " : " at exit, ", stdout);
+ printNextFd();
+ fputs("\n", stdout);
+
+ if (run > 1) {
+ pid_t childPid;
+
+ childPid = fork();
+ if (childPid < 0) {
+ perror("fork() failed");
+ exit(1);
+ }
+ else if (childPid) {
+ int sts;
+
+ wait(&sts);
+ }
+ else {
+ char* childArgv[3];
+ int sts;
+
+ childArgv[0] = argv[0];
+ /* numeric arguments will get shorter, not longer so this is safe */
+ childArgv[1] = strdup(argv[1]);
+ if (childArgv[1] == NULL) {
+ perror("can't copy argv[1]\n");
+ exit(1);
+ }
+ sprintf(childArgv[1], "%ld", run - 1);
+ childArgv[2] = NULL;
+ sts = execvp(childArgv[0], childArgv);
+ if (sts < 0) {
+ perror("execvp() failed");
+ exit(1);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/qa/src/context_test.c b/qa/src/context_test.c
new file mode 100644
index 0000000..fcce843
--- /dev/null
+++ b/qa/src/context_test.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * context and profile exerciser
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int inst_bin[] = { 100, 200, 300, 400, 500, 600, 700, 800, 900 };
+static int inst_colour[] = { 0, 1, 2 };
+
+static int xpect_bin[] = { 9, 0, 1, 5, 0 };
+static int xpect_colour[] = { 3, 3, 0, 1, 2 };
+
+#define MAXC (sizeof(xpect_bin)/sizeof(xpect_bin[0]))
+
+static char *namelist[] = {
+ "sample.bin",
+ "sample.colour"
+};
+
+/*
+ * handle profile values expected
+ * 0 everything 9 bins 3 colours
+ * 1 no bins 0 bins 3 colours
+ * 2 bin=500, no colour 1 bin 0 colour
+ * 3 bin=100 .. 500, colour=0 5 bin 1 colour
+ * 4 no bins, not 1 0 bins 2 colours
+ */
+
+void
+_err(int handle)
+{
+ int sts;
+
+ sts = pmUseContext(handle);
+ if (sts != PM_ERR_NOCONTEXT)
+ printf("pmUseContext(%d): Unexpected Error: %s\n", handle, pmErrStr(sts));
+
+ sts = pmDestroyContext(handle);
+ if (sts != PM_ERR_NOCONTEXT)
+ printf("pmDestroyContext(%d): Unexpected Error: %s\n", handle, pmErrStr(sts));
+
+ sts = pmReconnectContext(handle);
+ if (sts != PM_ERR_NOCONTEXT)
+ printf("pmReconnectContext(%d): Unexpected Error: %s\n", handle, pmErrStr(sts));
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int i;
+ int iter = 2;
+ int fail;
+ int failiter = 0;
+ int errflag = 0;
+ int type = 0;
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+ char *endnum;
+ pmInDom indom_bin, indom_colour;
+ pmID metrics[2];
+ pmResult *resp;
+ pmDesc desc;
+ int handle[50]; /* need 3 x MAXC */
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N] ";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-a archive] [-h hostname] [-i iterations] [-n namespace]";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:i:h:n:")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'i': /* iteration count */
+ iter = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: -i requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmLookupName(2, namelist, metrics)) < 0) {
+ fprintf(stderr, "pmLookupName: %s\n", pmErrStr(sts));
+ fprintf(stderr, "pmids: 0x%x 0x%x\n", metrics[0], metrics[1]);
+ exit(1);
+ }
+
+ if (type == 0)
+ type = PM_CONTEXT_HOST; /* default */
+
+ for (i = 0; i < 3*MAXC; i++) {
+ if (i & 1) {
+ /* odd ones are dup of the previous context */
+ if ((sts = pmDupContext()) < 0) {
+ fprintf(stderr, "handle[%d]: pmDupContext(): %s\n", i, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ else {
+ if (type == PM_CONTEXT_HOST) {
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ fprintf(stderr, "handle[%d]: pmNewContext(host=%s): %s\n", i, host, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ else {
+ if ((sts = pmNewContext(PM_CONTEXT_ARCHIVE, host)) < 0) {
+ fprintf(stderr, "handle[%d]: pmNewContext(archive=%s): %s\n", i, host, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ }
+ handle[i] = sts;
+
+ if ((sts = pmLookupDesc(metrics[0], &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc: context=%d bin: %s\n", handle[i], pmErrStr(sts));
+ exit(1);
+ }
+ indom_bin = desc.indom;
+ if ((sts = pmLookupDesc(metrics[1], &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc: context=%d colour: %s\n", handle[i], pmErrStr(sts));
+ exit(1);
+ }
+ indom_colour = desc.indom;
+
+ switch (i % MAXC) {
+ case 0:
+ break;
+ case 1:
+ pmDelProfile(indom_bin, 0, (int *)0);
+ break;
+ case 2:
+ pmDelProfile(indom_bin, 0, (int *)0);
+ pmAddProfile(indom_bin, 1, &inst_bin[4]);
+ pmDelProfile(indom_colour, 0, (int *)0);
+ break;
+ case 3:
+ pmDelProfile(indom_bin, 0, (int *)0);
+ pmAddProfile(indom_bin, 5, &inst_bin[0]);
+ pmDelProfile(indom_colour, 0, (int *)0);
+ pmAddProfile(indom_colour, 1, &inst_colour[0]);
+ break;
+ case 4:
+ pmDelProfile(indom_bin, 0, (int *)0);
+ pmAddProfile(indom_colour, 0, (int *)0);
+ pmDelProfile(indom_colour, 1, &inst_colour[1]);
+ break;
+ }
+ }
+
+ for (i=0; i < iter; i++) {
+ fail = 0;
+ for (c = 0; c < 3*MAXC; c++) {
+ errflag = 0;
+ pmUseContext(handle[c]);
+ sts = pmFetch(2, metrics, &resp);
+ if (sts < 0) {
+ fprintf(stderr, "botch @ iter=%d, context=%d: pmFetch: %s\n",
+ i, handle[c], pmErrStr(sts));
+ errflag = 2;
+ }
+ else {
+ if (resp->numpmid != 2) {
+ fprintf(stderr, "botch @ iter=%d, context=%d: numpmid %d != 2\n",
+ i, handle[c], resp->numpmid);
+ errflag = 1;
+ }
+ else {
+ if (resp->vset[0]->numval != xpect_bin[c % MAXC]) {
+ fprintf(stderr, "botch @ iter=%d, context=%d: [indom %s] numval got: %d expect: %d\n",
+ i, handle[c], pmInDomStr(indom_bin),
+ resp->vset[0]->numval, xpect_bin[c % MAXC]);
+ errflag = 1;
+ }
+ if (resp->vset[1]->numval != xpect_colour[c % MAXC]) {
+ fprintf(stderr, "botch @ iter=%d, context=%d: [indom %s] numval got: %d expect: %d\n",
+ i, handle[c], pmInDomStr(indom_colour),
+ resp->vset[1]->numval, xpect_colour[c % MAXC]);
+ errflag = 1;
+ }
+ }
+ }
+ if (errflag) {
+ __pmDumpContext(stderr, handle[c], PM_INDOM_NULL);
+ if (errflag != 2)
+ __pmDumpResult(stderr, resp);
+ fail++;
+ }
+ if (errflag != 2) {
+ if (type == PM_CONTEXT_ARCHIVE) {
+ resp->timestamp.tv_usec--;
+ pmSetMode(PM_MODE_FORW, &resp->timestamp, 0);
+ }
+ pmFreeResult(resp);
+ }
+ }
+ if (fail)
+ failiter++;
+ else {
+ putchar('.');
+ fflush(stdout);
+ }
+ }
+ for (c = 0; c < 3*MAXC; c++) {
+ if ((sts = pmDestroyContext(handle[c])) < 0)
+ fprintf(stderr, "pmDestroyContext %d: %s\n", handle[c], pmErrStr(sts));
+ }
+
+ printf("\nPassed %d of %d iterations\n", iter-failiter, iter);
+
+ /*
+ * exercise error conditions at PMAPI relating to "handle" use
+ */
+ printf("Check error handling at PMAPI ...\n");
+ _err(-1); /* too small */
+ _err(3*MAXC); /* too big */
+ _err(1); /* was valid, now destroyed */
+
+ exit(0);
+}
diff --git a/qa/src/count-mark.0 b/qa/src/count-mark.0
new file mode 100644
index 0000000..e251592
--- /dev/null
+++ b/qa/src/count-mark.0
Binary files differ
diff --git a/qa/src/count-mark.index b/qa/src/count-mark.index
new file mode 100644
index 0000000..036b38d
--- /dev/null
+++ b/qa/src/count-mark.index
Binary files differ
diff --git a/qa/src/count-mark.meta b/qa/src/count-mark.meta
new file mode 100644
index 0000000..ad54b83
--- /dev/null
+++ b/qa/src/count-mark.meta
Binary files differ
diff --git a/qa/src/crashpmcd.c b/qa/src/crashpmcd.c
new file mode 100644
index 0000000..9f9e944
--- /dev/null
+++ b/qa/src/crashpmcd.c
@@ -0,0 +1,85 @@
+/*
+ * Crashes pmcd on IRIX. Linux seems to be OK. PV 935490.
+ */
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static __pmPDUHdr hdr;
+static char *target;
+
+void
+try(int len)
+{
+ int fd;
+ int sts;
+ static int first = 1;
+ static struct sockaddr_in myAddr;
+ static struct hostent* servInfo;
+ char buf[256];
+
+ if (first) {
+ first = 0;
+ if ((servInfo = gethostbyname(target)) == NULL) {
+ fprintf(stderr, "host \"%s\" unknown\n", target);
+ exit(1);
+ }
+ memset(&myAddr, 0, sizeof(myAddr));
+ myAddr.sin_family = AF_INET;
+ memcpy(&myAddr.sin_addr, servInfo->h_addr, servInfo->h_length);
+ myAddr.sin_port = htons(SERVER_PORT);
+ }
+
+ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ fprintf(stderr, "socket failed: %s\n", pmErrStr(errno));
+ return;
+ }
+
+ if ((sts = connect(fd, (struct sockaddr*) &myAddr, sizeof(myAddr))) < 0) {
+ fprintf(stderr, "connect failed: %s\n", pmErrStr(sts));
+ close(fd);
+ return;
+ }
+
+ if ((sts = write(fd, &hdr, len)) != len) {
+ fprintf(stderr, "write failed: %s\n", pmErrStr(sts));
+ close(fd);
+ return;
+ }
+ sts = read(fd, buf, sizeof(buf));
+ if (sts < 0) {
+ /* in this case don't really care about the return code from read() */
+ ;
+ }
+ close(fd);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int j;
+ int k;
+
+ __pmSetProgname(argv[0]);
+
+ target = argc == 2 ? argv[1] : "localhost";
+
+ hdr.from = htonl(12345);
+
+ for (k = -1; k <= 12; k++) {
+ hdr.len = htonl(k);
+ hdr.type = htonl(0x55aa0000);
+ for (j = 0; j <= 12; j++) {
+ try(j);
+ }
+ }
+
+ for (k = 0; k <= 12; k++) {
+ hdr.len = htonl(k<<24);
+ hdr.type = htonl(0x000055aa);
+ for (j = 0; j <= 12; j++) {
+ try(j);
+ }
+ }
+
+ return 0;
+}
diff --git a/qa/src/defctx.c b/qa/src/defctx.c
new file mode 100644
index 0000000..36e15e8
--- /dev/null
+++ b/qa/src/defctx.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * play with default contexts of various sorts
+ */
+
+#include <unistd.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int ctx0 = -1;
+ int ctx1 = -1;
+ int sts;
+ int inst;
+ int errflag = 0;
+ int type = 0;
+ char *host = NULL; /* pander to gcc */
+ char *namespace = PM_NS_DEFAULT;
+ pmDesc desc;
+ pmID pmid;
+ char *name = "sample.colour";
+ pmResult *resp;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:h:n:s:")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options:\n\
+ -a archive use archive log, not host source\n\
+ -D N set pmDebug debugging flag to N\n\
+ -h hostname connect to PMCD on this host\n\
+ -n namespace alternative PMNS specification file\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type != 0) {
+ /* create an explicit context */
+ if ((ctx0 = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ /*
+ * Add to profile, fetch, ...
+ */
+ if ((sts = pmLookupName(1, &name, &pmid)) < 0) {
+ printf("%s: pmLookupName(%s): %s\n", pmProgname, name, pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmLookupDesc(pmid, &desc)) < 0) {
+ printf("%s: pmLookupDesc(%s): %s\n", pmProgname, pmIDStr(pmid), pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((inst = pmLookupInDomArchive(desc.indom, "green")) < 0) {
+ printf("%s: pmLookupInDomArchive(%s): %s\n", pmProgname, pmInDomStr(desc.indom), pmErrStr(inst));
+ exit(1);
+ }
+ }
+ else {
+ if ((inst = pmLookupInDom(desc.indom, "green")) < 0) {
+ printf("%s: pmLookupInDom(%s): %s\n", pmProgname, pmInDomStr(desc.indom), pmErrStr(inst));
+ exit(1);
+ }
+ }
+
+ if ((sts = pmDelProfile(PM_INDOM_NULL, 1, (int *)0)) < 0) {
+ printf("%s: pmDelProfile: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmAddProfile(desc.indom, 1, &inst)) < 0) {
+ printf("%s: pmAddProfile: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmFetch(1, &pmid, &resp)) < 0) {
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ }
+ else {
+ printf("first pmFetch is OK\n");
+ __pmDumpResult(stdout, resp);
+ pmFreeResult(resp);
+ }
+
+ /*
+ * Now destroy context and try again, ... should see an invalid context
+ */
+ if ((sts = pmDestroyContext(ctx0)) < 0)
+ printf("%s: pmDestroyContext: %s\n", pmProgname, pmErrStr(sts));
+
+ if ((sts = pmDelProfile(PM_INDOM_NULL, 1, (int *)0)) < 0) {
+ printf("%s: pmDelProfile: %s\n", pmProgname, pmErrStr(sts));
+ }
+ if ((sts = pmAddProfile(desc.indom, 1, &inst)) < 0) {
+ printf("%s: pmAddProfile: %s\n", pmProgname, pmErrStr(sts));
+ }
+ if ((sts = pmFetch(1, &pmid, &resp)) < 0) {
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ }
+ else {
+ printf("second pmFetch is OK\n");
+ __pmDumpResult(stdout, resp);
+ pmFreeResult(resp);
+ }
+
+ /*
+ * destroy that one
+ */
+ if ((ctx0 = pmWhichContext()) < 0)
+ printf("%s: pmWhichContext: %s\n", pmProgname, pmErrStr(ctx0));
+ else
+ if ((sts = pmDestroyContext(ctx0)) < 0)
+ printf("%s: pmDestroyContext: %s\n", pmProgname, pmErrStr(sts));
+
+ if (type != 0) {
+ /* play some more games */
+ if ((ctx0 = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+ printf("NewContext: %d\n", ctx0);
+ if ((ctx1 = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+ printf("NewContext: %d\n", ctx1);
+ if ((sts = pmDestroyContext(ctx0)) < 0)
+ printf("%s: pmDestroyContext: %s\n", pmProgname, pmErrStr(sts));
+ else
+ printf("Destroy(%d)\n", ctx0);
+ if ((sts = pmWhichContext()) < 0)
+ printf("%s: pmWhichContext: %s\n", pmProgname, pmErrStr(sts));
+ else
+ printf("WhichContext: %d\n", sts);
+
+ if ((ctx0 = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+ printf("NewContext: %d\n", ctx0);
+ if ((sts = pmDestroyContext(ctx0)) < 0)
+ printf("%s: pmDestroyContext: %s\n", pmProgname, pmErrStr(sts));
+ else
+ printf("Destroy(%d)\n", ctx0);
+ if ((sts = pmDestroyContext(ctx1)) < 0)
+ printf("%s: pmDestroyContext: %s\n", pmProgname, pmErrStr(sts));
+ else
+ printf("Destroy(%d)\n", ctx1);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/descreqX2.c b/qa/src/descreqX2.c
new file mode 100644
index 0000000..634e518
--- /dev/null
+++ b/qa/src/descreqX2.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * 2 DESC_REQs back-to-back ... trying to understand www.sgi.com PMDA deaths
+ */
+
+#include <stdio.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int fd;
+ int ctx;
+ int errflag = 0;
+ int e;
+ int sts;
+ __pmContext *ctxp;
+ __pmPDU *pb;
+ pmID pmid;
+ char *name = "sample.seconds";
+
+ __pmSetProgname(argv[0]);
+
+ if (argc > 1) {
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind > argc) {
+ fprintf(stderr, "Usage: %s [-D]\n", pmProgname);
+ exit(1);
+ }
+ }
+
+ if ((ctx = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ fprintf(stderr, "pmNewContext: %s\n", pmErrStr(ctx));
+ exit(1);
+ }
+
+ if ((ctxp = __pmHandleToPtr(ctx)) == NULL) {
+ fprintf(stderr, "__pmHandleToPtr failed: eh?\n");
+ exit(1);
+ }
+
+ fd = ctxp->c_pmcd->pc_fd;
+
+ if ((e = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) {
+ fprintf(stderr, "pmLoadNameSpace: %s\n", pmErrStr(e));
+ exit(1);
+ }
+
+ if ((e = pmLookupName(1, &name, &pmid)) < 0) {
+ printf("pmLookupName: Unexpected error: %s\n", pmErrStr(e));
+ exit(1);
+ }
+
+ if ((e = __pmSendDescReq(fd, FROM_ANON, pmid)) < 0) {
+ fprintf(stderr, "Error: SendDescReqX1: %s\n", pmErrStr(e));
+ exit(1);
+ }
+
+ if ((e = __pmSendDescReq(fd, FROM_ANON, pmid)) < 0) {
+ fprintf(stderr, "Error: SendDescReqX2: %s\n", pmErrStr(e));
+ exit(1);
+ }
+
+ if ((e = __pmGetPDU(fd, ANY_SIZE, TIMEOUT_DEFAULT, &pb)) < 0)
+ fprintf(stderr, "Error: __pmGetPDUX1: %s\n", pmErrStr(e));
+ else
+ fprintf(stderr, "__pmGetPDUX1 -> 0x%x\n", e);
+
+ if ((e = __pmGetPDU(fd, ANY_SIZE, TIMEOUT_DEFAULT, &pb)) < 0)
+ fprintf(stderr, "Error: __pmGetPDUX2: %s\n", pmErrStr(e));
+ else
+ fprintf(stderr, "__pmGetPDUX2 -> 0x%x\n", e);
+
+ exit(0);
+}
+
diff --git a/qa/src/disk_test.c b/qa/src/disk_test.c
new file mode 100644
index 0000000..bb24af9
--- /dev/null
+++ b/qa/src/disk_test.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int listOne[2];
+#define LEN(l) (sizeof(l)/sizeof(l[0]))
+
+static char *namelist[] = {
+ "disk.dev.read"
+};
+
+#define NCONTEXTS 2
+
+int
+main(int argc, char **argv)
+{
+ int e, i;
+ int h[NCONTEXTS];
+ pmID metrics[2];
+ pmResult *resp;
+ pmInDom diskindom;
+ pmDesc desc;
+ int *inst;
+ char **name;
+ int numinst;
+ int c;
+ int sts;
+ int errflag = 0;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:?")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc) {
+ fprintf(stderr, "Usage: %s [-D n]\n", pmProgname);
+ exit(1);
+ }
+
+ for (i=0; i < NCONTEXTS; i++) {
+ if ((h[i] = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ printf("pmNewContext: %s\n", pmErrStr(h[i]));
+ exit(1);
+ }
+
+ if ((e = pmLookupName(1, namelist, metrics)) < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(e));
+ exit(1);
+ }
+
+ if ((e = pmLookupDesc(metrics[0], &desc)) < 0) {
+ printf("pmLookupDesc: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ }
+
+ diskindom = desc.indom;
+ if ((numinst = pmGetInDom(diskindom, &inst, &name)) < 0) {
+ printf("pmGetInDom: %s\n", pmErrStr(numinst));
+ exit(1);
+ }
+ printf("Disks:\n");
+ for (i = 0; i < numinst; i++)
+ printf("\t[%d]: %d %s\n", i, inst[i], name[i]);
+
+ for (i=0; i < NCONTEXTS; i++) {
+ pmUseContext(h[i]);
+
+ listOne[0] = inst[0];
+ listOne[1] = inst[numinst-1];
+
+ pmAddProfile(diskindom, 0, (int *)0);
+ printf("all drives should be included here\n");
+ if ((e = pmFetch(1, metrics, &resp)) < 0) {
+ printf("pmFetch[2]: %s\n", pmErrStr(e));
+ }
+ else
+ __pmDumpResult(stdout, resp);
+
+ pmDelProfile(diskindom, 0, (int *)0);
+ putchar('\n');
+ printf("no drives should be included here\n");
+ if ((e = pmFetch(1, metrics, &resp)) < 0) {
+ printf("pmFetch[3]: %s\n", pmErrStr(e));
+ }
+ else
+ __pmDumpResult(stdout, resp);
+
+ pmDelProfile(diskindom, 0, (int *)0);
+ pmAddProfile(diskindom, LEN(listOne), listOne);
+ putchar('\n');
+ printf("only the first and last drive should be included here\n");
+ if ((e = pmFetch(1, metrics, &resp)) < 0) {
+ printf("pmFetch[0]: %s\n", pmErrStr(e));
+ }
+ else
+ __pmDumpResult(stdout, resp);
+
+ pmDelProfile(diskindom, 0, (int *)0);
+ pmAddProfile(diskindom, numinst, inst);
+ pmDelProfile(diskindom, 1, listOne);
+ putchar('\n');
+ printf("all except drive zero should be included here\n");
+ if ((e = pmFetch(1, metrics, &resp)) < 0) {
+ printf("pmFetch[1]: %s\n", pmErrStr(e));
+ }
+ else
+ __pmDumpResult(stdout, resp);
+
+ pmDelProfile(diskindom, 0, (int *)0);
+ pmAddProfile(diskindom, 1, inst);
+ putchar('\n');
+ printf("drive zero ONLY should be included here\n");
+ if ((e = pmFetch(1, metrics, &resp)) < 0) {
+ printf("pmFetch[1]: %s\n", pmErrStr(e));
+ }
+ else
+ __pmDumpResult(stdout, resp);
+ }
+
+ exit(0);
+}
+
diff --git a/qa/src/drain-server.c b/qa/src/drain-server.c
new file mode 100644
index 0000000..f66208e
--- /dev/null
+++ b/qa/src/drain-server.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * Drain server ...
+ * accepts a connection and then reads until end of input
+ *
+ * Based on pdu-server.c
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char *argv[])
+{
+ int fd;
+ int port = 1214;
+ /* default port assigned to kazaa what ever that is! */
+ int hang = 0;
+ int i, sts;
+ int c;
+ int newfd;
+ struct sockaddr_in myAddr;
+ struct linger noLinger = {1, 0};
+ char *endnum;
+ int errflag = 0;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:hp:?")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'h': /* hang after accept */
+ hang = 1;
+ break;
+
+ case 'p':
+ port = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: port argument must be a numeric internet port number\n", pmProgname);
+ exit(1);
+ }
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc) {
+ fprintf(stderr, "Usage: %s [-D n] [-h] [-p port]\n", pmProgname);
+ exit(1);
+ }
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd < 0) {
+ perror("socket");
+ exit(1);
+ }
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &i,
+ sizeof(i)) < 0) {
+ perror("setsockopt(nodelay)");
+ exit(1);
+ }
+ /* Don't linger on close */
+ if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &noLinger, sizeof(noLinger)) < 0) {
+ perror("setsockopt(nolinger)");
+ exit(1);
+ }
+
+ memset(&myAddr, 0, sizeof(myAddr));
+ myAddr.sin_family = AF_INET;
+ myAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ myAddr.sin_port = htons(port);
+ sts = bind(fd, (struct sockaddr*)&myAddr, sizeof(myAddr));
+ if (sts < 0) {
+ fprintf(stderr, "bind(%d): %s\n", port, strerror(errno));
+ exit(1);
+ }
+
+ sts = listen(fd, 5); /* Max. of 5 pending connection requests */
+ if (sts == -1) {
+ perror("listen");
+ exit(1);
+ }
+
+ newfd = accept(fd, (struct sockaddr *)0, 0);
+ if (newfd < 0) {
+ fprintf(stderr, "%s: accept: %s\n", pmProgname, strerror(errno));
+ exit(1);
+ }
+
+ if (hang) {
+ /* wait for a signal ... */
+ pause();
+ exit(0);
+ }
+
+ /* drain input */
+ while ((sts = read(newfd, &c, 1)) == 1)
+ ;
+
+ if (sts < 0) {
+ /*
+ * ECONNRESET is expected when client exits w/out closing
+ * socket.
+ */
+ if (errno != ECONNRESET)
+ fprintf(stderr, "%s: read error: %s\n", pmProgname, pmErrStr(-errno));
+ }
+
+ exit(0);
+}
diff --git a/qa/src/dumb_pmda.c b/qa/src/dumb_pmda.c
new file mode 100644
index 0000000..c60225f
--- /dev/null
+++ b/qa/src/dumb_pmda.c
@@ -0,0 +1,81 @@
+/*
+ * Dumb, a PMDA which never responds to requests ... used in qa/023
+ *
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+#include "localconfig.h"
+
+#if PCP_VER < 3611
+#define __pmRead read
+#endif
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s [options] controlwords\n\n", pmProgname);
+ fputs("Options:\n"
+ " -D N set pmDebug debugging flag to N\n"
+ " -d domain use domain (numeric) for metrics domain of PMDA\n"
+ " -h helpfile get help text from helpfile rather then default path\n"
+ " -l logfile write log into logfile rather than using default log name\n",
+ stderr);
+ exit(1);
+}
+
+/*
+ * Set up the agent if running as a daemon.
+ */
+
+int
+main(int argc, char **argv)
+{
+ int err = 0;
+ int sts;
+ pmdaInterface desc = { 0 };
+ char c;
+ int exit_action = 0;
+
+ __pmSetProgname(argv[0]);
+
+ pmdaDaemon(&desc, PMDA_INTERFACE_3, pmProgname, desc.domain, "dumb_pmda.log", NULL);
+ if (desc.status != 0) {
+ fprintf(stderr, "pmdaDaemon() failed!\n");
+ exit(1);
+ }
+
+ if (pmdaGetOpt(argc, argv, "D:d:h:l:", &desc, &err) != EOF)
+ err++;
+ if (err)
+ usage();
+
+ /*
+ * scan cmd line args for action keywords ...
+ */
+ for (; optind < argc; optind++) {
+ if (strcmp(argv[optind], "exit") == 0) exit_action = 1;
+ }
+
+ pmdaOpenLog(&desc);
+ pmdaConnect(&desc);
+
+ /*
+ * We have connection to pmcd ... consume PDUs from pmcd,
+ * ignore them, optionally execute an action and exit on end of file
+ */
+
+ while ((sts = __pmRead(desc.version.two.ext->e_infd, &c, 1)) == 1) {
+ if (exit_action) exit(1);
+ }
+
+ if (sts < 0) {
+ fprintf(stderr, "dumb_pmda: Error on read from pmcd?: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/endian.c b/qa/src/endian.c
new file mode 100644
index 0000000..eb56612
--- /dev/null
+++ b/qa/src/endian.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+#include "localconfig.h"
+
+int
+main()
+{
+ int *ip;
+ int sts = 0;
+ pmUnits units;
+ pmValueBlock vb;
+ __pmID_int pmid;
+ __pmInDom_int indom;
+ __pmPDUInfo pduinfo;
+ __pmCred cred;
+
+ printf("pmUnits: ");
+ ip = (int *)&units;
+ *ip = 0;
+ units.dimSpace = 0x1;
+ units.dimTime = 0x2;
+ units.dimCount = 0x3;
+ units.scaleSpace = 0x4;
+ units.scaleTime = 0x5;
+ units.scaleCount = 0x6;
+ units.pad = 0x78;
+
+ if (*ip == 0x12345678)
+ printf("OK\n");
+ else {
+ printf("FAIL get 0x%x, expected 0x12345678\n", *ip);
+ sts = 1;
+ }
+
+ printf("pmValueBlock (header): ");
+ ip = (int *)&vb;
+ *ip = 0;
+ vb.vtype = 0x12;
+ vb.vlen = 0x345678;
+
+ if (*ip == 0x12345678)
+ printf("OK\n");
+ else {
+ printf("FAIL get 0x%x, expected 0x12345678\n", *ip);
+ sts = 1;
+ }
+
+ printf("__pmCred: ");
+ ip = (int *)&cred;
+ *ip = 0;
+ cred.c_type = 0x12;
+ cred.c_vala = 0x34;
+ cred.c_valb = 0x56;
+ cred.c_valc = 0x78;
+
+ if (*ip == 0x12345678)
+ printf("OK\n");
+ else {
+ printf("FAIL get 0x%x, expected 0x12345678\n", *ip);
+ sts = 1;
+ }
+
+ printf("__pmID_int: ");
+ ip = (int *)&pmid;
+ *ip = 0;
+ pmid.flag = 0x1;
+ pmid.domain = (0x123 >> 2) & 0x1ff;
+ pmid.cluster = (0x3456 >> 2) & 0xfff;
+ pmid.item = 0x678 & 0x3ff;
+
+ if (*ip == 0x92345678)
+ printf("OK\n");
+ else {
+ printf("FAIL get 0x%x, expected 0x92345678\n", *ip);
+ sts = 1;
+ }
+
+ printf("__pmInDom_int: ");
+ ip = (int *)&indom;
+ *ip = 0;
+ indom.flag = 0x1;
+ indom.domain = (0x123 >> 2) & 0x1ff;
+ indom.serial = 0x345678 & 0x3fffff;
+
+ if (*ip == 0x92345678)
+ printf("OK\n");
+ else {
+ printf("FAIL get 0x%x, expected 0x92345678\n", *ip);
+ sts = 1;
+ }
+
+ printf("__pmPDUInfo: ");
+ ip = (int *)&pduinfo;
+ *ip = 0;
+ pduinfo.zero = 0x1;
+ pduinfo.version = 0x12 & 0x7f;
+ pduinfo.licensed = 0x34;
+#if PCP_VER >= 3611
+ pduinfo.features = 0x5678;
+#else
+ pduinfo.authorize = 0x5678;
+#endif
+
+ if (*ip == 0x92345678)
+ printf("OK\n");
+ else {
+ printf("FAIL get 0x%x, expected 0x92345678\n", *ip);
+ sts = 1;
+ }
+
+#ifdef TODO
+ /*
+ * write tests
+ */
+ pmUnits units;
+ pmValueBlock vb;
+ __pmID_int pmid;
+ __pmInDom_int indom;
+ __pmPDUInfo pduinfo;
+ __pmCred cred;
+#endif
+
+ exit(sts);
+}
diff --git a/qa/src/eofarch.c b/qa/src/eofarch.c
new file mode 100644
index 0000000..f702fa4
--- /dev/null
+++ b/qa/src/eofarch.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * exercise outside feasible log range operations ... before start
+ * and after end
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int vflag;
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int ctx;
+ int errflag = 0;
+ char *archive = "foo";
+ char *namespace = PM_NS_DEFAULT;
+ static char *usage = "[-a archive] [-n namespace] [-v]";
+ pmResult *resp;
+ int resnum = 0;
+ pmID pmid = 0;
+ struct timeval when;
+ struct timeval first;
+ struct timeval last;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:n:v")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive */
+ archive = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'v': /* verbose output */
+ vflag++;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((ctx = pmNewContext(PM_CONTEXT_ARCHIVE, archive)) < 0) {
+ printf("%s: Cannot connect to archive \"%s\": %s\n", pmProgname, archive, pmErrStr(ctx));
+ exit(1);
+ }
+
+ when.tv_sec = 0;
+ when.tv_usec = 0;
+ if ((sts = pmSetMode(PM_MODE_FORW, &when, 0)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ printf("\nPass 1: forward scan\n");
+ for (;;) {
+ if ((sts = pmFetchArchive(&resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("pmFetchArchive: %s\n", pmErrStr(sts));
+ break;
+ }
+ if (resnum == 0) {
+ first = resp->timestamp;
+ pmid = resp->vset[0]->pmid;
+ }
+ else
+ last = resp->timestamp;
+ resnum++;
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ pmFreeResult(resp);
+ }
+ printf("Found %d samples, with %d log reads\n", resnum, __pmLogReads);
+
+ printf("\nPass 2: before start of log scan\n");
+ first.tv_sec--;
+ printf(" 2.1: FORWARD, expect success\n");
+ __pmLogReads = 0;
+ if ((sts = pmSetMode(PM_MODE_FORW, &first, 0)) < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmFetchArchive(&resp)) < 0) {
+ printf(" %s with %d log_reads\n", pmErrStr(sts), __pmLogReads);
+ }
+ else {
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ printf(" found 1 with %d log reads\n", __pmLogReads);
+ pmFreeResult(resp);
+ }
+ printf(" 2.2: BACKWARD, expect EOL\n");
+ __pmLogReads = 0;
+ if ((sts = pmSetMode(PM_MODE_BACK, &first, 0)) < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmFetchArchive(&resp)) < 0) {
+ printf(" %s with %d log_reads\n", pmErrStr(sts), __pmLogReads);
+ }
+ else {
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ printf(" found 1 with %d log reads\n", __pmLogReads);
+ pmFreeResult(resp);
+ }
+ printf(" 2.3: INTERP, expect EOL\n");
+ __pmLogReads = 0;
+ if ((sts = pmSetMode(PM_MODE_INTERP, &first, 0)) < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmFetch(1, &pmid, &resp)) < 0) {
+ printf(" %s with %d log_reads\n", pmErrStr(sts), __pmLogReads);
+ }
+ else {
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ printf(" found 1 with %d log reads\n", __pmLogReads);
+ pmFreeResult(resp);
+ }
+
+ printf("\nPass 3: after end of log scan\n");
+ last.tv_sec++;
+ printf(" 3.1: FORWARD, expect EOL\n");
+ __pmLogReads = 0;
+ if ((sts = pmSetMode(PM_MODE_FORW, &last, 0)) < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmFetchArchive(&resp)) < 0) {
+ printf(" %s with %d log_reads\n", pmErrStr(sts), __pmLogReads);
+ }
+ else {
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ printf(" found 1 with %d log reads\n", __pmLogReads);
+ pmFreeResult(resp);
+ }
+ printf(" 3.2: BACKWARD, expect success\n");
+ __pmLogReads = 0;
+ if ((sts = pmSetMode(PM_MODE_BACK, &last, 0)) < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmFetchArchive(&resp)) < 0) {
+ printf(" %s with %d log_reads\n", pmErrStr(sts), __pmLogReads);
+ }
+ else {
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ printf(" found 1 with %d log reads\n", __pmLogReads);
+ pmFreeResult(resp);
+ }
+ printf(" 3.3: INTERP, expect EOL\n");
+ __pmLogReads = 0;
+ if ((sts = pmSetMode(PM_MODE_INTERP, &last, 0)) < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmFetch(1, &pmid, &resp)) < 0) {
+ printf(" %s with %d log_reads\n", pmErrStr(sts), __pmLogReads);
+ }
+ else {
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ printf(" found 1 with %d log reads\n", __pmLogReads);
+ pmFreeResult(resp);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/eol.c b/qa/src/eol.c
new file mode 100644
index 0000000..f259b5a
--- /dev/null
+++ b/qa/src/eol.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * eol - exercise _pmLogFindEOF
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static void
+printstamp(struct timeval *tp)
+{
+ static struct tm *tmp;
+
+ tmp = localtime(&tp->tv_sec);
+ printf("%02d:%02d:%02d.%03d", tmp->tm_hour, tmp->tm_min, tmp->tm_sec, (int)(tp->tv_usec/1000));
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int ahtype = 0;
+ char *host = NULL; /* pander to gcc */
+ pmLogLabel label; /* get hostname for archives */
+ char *namespace = PM_NS_DEFAULT;
+ pmResult *result;
+ pmResult *prev;
+ struct timeval end;
+ int numpmid = 3;
+ char *name[] = { "sample.seconds", "sample.drift", "sample.milliseconds" };
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:n:s:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (ahtype != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ ahtype = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -n namespace use an alternative PMNS\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (ahtype != PM_CONTEXT_ARCHIVE) {
+ fprintf(stderr, "%s: -a is not optional!\n", pmProgname);
+ exit(1);
+ }
+ if ((sts = pmNewContext(ahtype, host)) < 0) {
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ if (optind < argc) {
+ numpmid = 0;
+ while (optind < argc && numpmid < 3) {
+ name[numpmid] = argv[optind];
+ printf("metric[%d]: %s\n", numpmid, name[numpmid]);
+ optind++;
+ numpmid++;
+ }
+ }
+
+ sts = pmGetArchiveEnd(&end);
+ if (sts < 0) {
+ printf("pmGetArchiveEnd: %s\n", pmErrStr(sts));
+ }
+ else {
+ printf("pmGetArchiveEnd time: ");
+ printstamp(&end);
+ printf("\n");
+ }
+ printf("required %d log reads\n", __pmLogReads);
+ __pmLogReads = 0;
+
+ putchar('\n');
+ sts = pmSetMode(PM_MODE_BACK, &end, 0);
+ if (sts < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ sts = pmFetchArchive(&result);
+ if (sts < 0) {
+ printf("pmFetchArchive: %s\n", pmErrStr(sts));
+ }
+ else {
+ printf("last result time (direct): ");
+ printstamp(&result->timestamp);
+ printf("\n");
+ pmFreeResult(result);
+ }
+ printf("required %d log reads\n", __pmLogReads);
+ __pmLogReads = 0;
+
+ putchar('\n');
+ end.tv_sec = 0x7fffffff;
+ end.tv_usec = 0;
+ sts = pmSetMode(PM_MODE_BACK, &end, 0);
+ if (sts < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ sts = pmFetchArchive(&result);
+ if (sts < 0) {
+ printf("pmFetchArchive: %s\n", pmErrStr(sts));
+ }
+ else {
+ printf("last result time (indirect): ");
+ printstamp(&result->timestamp);
+ printf("\n");
+ pmFreeResult(result);
+ }
+ printf("required %d log reads\n", __pmLogReads);
+ __pmLogReads = 0;
+
+ putchar('\n');
+ prev = (pmResult *)0;
+ end.tv_sec = 0;
+ sts = pmSetMode(PM_MODE_FORW, &end, 0);
+ if (sts < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ while ((sts = pmFetchArchive(&result)) >= 0) {
+ if (prev != (pmResult *)0)
+ pmFreeResult(prev);
+ prev = result;
+ }
+ printf("pmFetchArchive: %s\n", pmErrStr(sts));
+ if (prev == (pmResult *)0) {
+ printf("no results!\n");
+ }
+ else {
+ printf("last result time (serial): ");
+ printstamp(&prev->timestamp);
+ printf("\n");
+ pmFreeResult(prev);
+ }
+ printf("required %d log reads\n", __pmLogReads);
+ __pmLogReads = 0;
+
+ exit(0);
+}
diff --git a/qa/src/err.c b/qa/src/err.c
new file mode 100644
index 0000000..a177a91
--- /dev/null
+++ b/qa/src/err.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ */
+
+/*
+ * Check pmErrStr()
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *usage = "[-D debug] errcode ...";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind >= argc) {
+ fprintf(stderr, "Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ while (optind < argc) {
+ sts = atoi(argv[optind]);
+ printf("%s (%d) -> %s\n", argv[optind], sts, pmErrStr(sts));
+ sts = -sts;
+ printf("-(%s) (%d) -> %s\n", argv[optind], sts, pmErrStr(sts));
+ optind++;
+ }
+
+ exit(0);
+}
diff --git a/qa/src/err_v1.0 b/qa/src/err_v1.0
new file mode 100644
index 0000000..8cc4aa8
--- /dev/null
+++ b/qa/src/err_v1.0
Binary files differ
diff --git a/qa/src/err_v1.dump b/qa/src/err_v1.dump
new file mode 100644
index 0000000..0d4165a
--- /dev/null
+++ b/qa/src/err_v1.dump
@@ -0,0 +1,68 @@
+Note: timezone set to local timezone of host "splat" from archive
+
+Log Label (Log Format Version 1)
+Performance metrics from host splat
+ commencing Thu Jul 24 04:48:42.327 1997
+ ending Thu Jul 24 04:48:46.557 1997
+
+Descriptions for Metrics in the Log ...
+PMID: 3.4.2 (proc.psusage.utime)
+ Data Type: 32-bit unsigned int InDom: 3.0 0xc00000
+ Semantics: counter Units: millisec
+PMID: 29.0.9 (sample.noinst)
+ Data Type: 32-bit int InDom: PM_INDOM_NULL 0xffffffff
+ Semantics: instant Units: none
+PMID: 29.0.49 (sample.needprofile)
+ Data Type: float InDom: 29.4 0x7400004
+ Semantics: discrete Units: none
+PMID: 29.0.55 (sample.bad.nosupport)
+ Data Type: Not Supported
+PMID: 2.3.2 (pmcd.pmlogger.archive)
+ Data Type: string InDom: 2.1 0x800001
+ Semantics: instant Units: none
+PMID: 2.3.0 (pmcd.pmlogger.port)
+ Data Type: 32-bit unsigned int InDom: 2.1 0x800001
+ Semantics: instant Units: none
+PMID: 2.3.3 (pmcd.pmlogger.host)
+ Data Type: string InDom: 2.1 0x800001
+ Semantics: instant Units: none
+
+Instance Domains in the Log ...
+InDom: 2.1
+04:48:42.327 1 instances
+ 14737 or "14737"
+
+Temporal Index
+ Log Vol end(meta) end(log)
+04:48:42.327 0 132 132
+04:48:42.584 0 270 256
+04:48:46.557 0 398 516
+
+04:48:42.327 2.3.3 (pmcd.pmlogger.host): inst [14737 or "14737"] value "splat.melbourne.sgi.com"
+ 2.3.0 (pmcd.pmlogger.port): inst [14737 or "14737"] value 4332
+ 2.3.2 (pmcd.pmlogger.archive): inst [14737 or "14737"] value "/tmp/err_v1"
+
+04:48:42.584 29.0.55 (sample.bad.nosupport): Metric not supported by this version of monitored application
+ 29.0.49 (sample.needprofile): Explicit instance identifier(s) required
+ 29.0.9 (sample.noinst): No values returned!
+ 3.4.2 (proc.psusage.utime): Explicit instance identifier(s) required
+
+04:48:43.547 29.0.55 (sample.bad.nosupport): Metric not supported by this version of monitored application
+ 29.0.49 (sample.needprofile): Explicit instance identifier(s) required
+ 29.0.9 (sample.noinst): No values returned!
+ 3.4.2 (proc.psusage.utime): Explicit instance identifier(s) required
+
+04:48:44.557 29.0.55 (sample.bad.nosupport): Metric not supported by this version of monitored application
+ 29.0.49 (sample.needprofile): Explicit instance identifier(s) required
+ 29.0.9 (sample.noinst): No values returned!
+ 3.4.2 (proc.psusage.utime): Explicit instance identifier(s) required
+
+04:48:45.557 29.0.55 (sample.bad.nosupport): Metric not supported by this version of monitored application
+ 29.0.49 (sample.needprofile): Explicit instance identifier(s) required
+ 29.0.9 (sample.noinst): No values returned!
+ 3.4.2 (proc.psusage.utime): Explicit instance identifier(s) required
+
+04:48:46.557 29.0.55 (sample.bad.nosupport): Metric not supported by this version of monitored application
+ 29.0.49 (sample.needprofile): Explicit instance identifier(s) required
+ 29.0.9 (sample.noinst): No values returned!
+ 3.4.2 (proc.psusage.utime): Explicit instance identifier(s) required
diff --git a/qa/src/err_v1.index b/qa/src/err_v1.index
new file mode 100644
index 0000000..14507cf
--- /dev/null
+++ b/qa/src/err_v1.index
Binary files differ
diff --git a/qa/src/err_v1.meta b/qa/src/err_v1.meta
new file mode 100644
index 0000000..00fadf7
--- /dev/null
+++ b/qa/src/err_v1.meta
Binary files differ
diff --git a/qa/src/eventrec-old.0 b/qa/src/eventrec-old.0
new file mode 100644
index 0000000..333573d
--- /dev/null
+++ b/qa/src/eventrec-old.0
Binary files differ
diff --git a/qa/src/eventrec-old.index b/qa/src/eventrec-old.index
new file mode 100644
index 0000000..179fa66
--- /dev/null
+++ b/qa/src/eventrec-old.index
Binary files differ
diff --git a/qa/src/eventrec-old.meta b/qa/src/eventrec-old.meta
new file mode 100644
index 0000000..814a979
--- /dev/null
+++ b/qa/src/eventrec-old.meta
Binary files differ
diff --git a/qa/src/eventrec.0 b/qa/src/eventrec.0
new file mode 100644
index 0000000..44cef73
--- /dev/null
+++ b/qa/src/eventrec.0
Binary files differ
diff --git a/qa/src/eventrec.index b/qa/src/eventrec.index
new file mode 100644
index 0000000..37dd0fe
--- /dev/null
+++ b/qa/src/eventrec.index
Binary files differ
diff --git a/qa/src/eventrec.meta b/qa/src/eventrec.meta
new file mode 100644
index 0000000..47ccfec
--- /dev/null
+++ b/qa/src/eventrec.meta
Binary files differ
diff --git a/qa/src/exercise.c b/qa/src/exercise.c
new file mode 100644
index 0000000..6371f91
--- /dev/null
+++ b/qa/src/exercise.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * General exerciser, checks (for licensed/unlicensed PMCDs)
+ * - PMCD availability
+ * - pmDesc availability
+ * - indom availiability
+ * - metric value availability
+ * - memory leaks (when -i used to make iterations > 1)
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+extern int errno;
+
+static int _metrics;
+static int _indom;
+static int _insitu;
+static int _ptr;
+
+static void
+dometric(const char *name)
+{
+ int n;
+ pmID pmidlist[] = { PM_ID_NULL };
+ pmDesc desc;
+ int *instlist = NULL;
+ char **instname = NULL;
+ pmResult *result;
+ extern int pmDebug;
+
+ _metrics++;
+
+ /* cast const away as pmLookupName will not modify this string */
+ if ((n = pmLookupName(1, (char **)&name, pmidlist)) < 0) {
+ printf("%s: pmLookupName: %s\n", name, pmErrStr(n));
+ return;
+ }
+ if ((n = pmLookupDesc(pmidlist[0], &desc)) < 0) {
+ printf("%s: pmLookupDesc: %s\n", name, pmErrStr(n));
+ return;
+ }
+ if (desc.indom != PM_INDOM_NULL) {
+ _indom++;
+ if ((n = pmGetInDom(desc.indom, &instlist, &instname)) < 0) {
+ printf("%s: pmGetInDom: %s\n", name, pmErrStr(n));
+ return;
+ }
+ if (instlist)
+ free(instlist);
+ if (instname)
+ free(instname);
+ }
+ if ((n = pmFetch(1, pmidlist, &result)) < 0) {
+ printf("%s: pmFetch: %s\n", name, pmErrStr(n));
+ return;
+ }
+ if (result->numpmid != 1) {
+ printf("%s: pmFetch: numpmid=%d, not 1\n", name, result->numpmid);
+ }
+ else {
+ if (result->vset[0]->numval == 0)
+ printf("%s: pmFetch: no value available\n", name);
+ else if (result->vset[0]->numval < 0)
+ printf("%s: pmFetch: %s\n", name, pmErrStr(result->vset[0]->numval));
+ else {
+ if (result->vset[0]->valfmt == PM_VAL_INSITU) {
+ _insitu++;
+ if (pmDebug && DBG_TRACE_APPL0)
+ printf("%s: insitu type=%s\n", name, pmTypeStr(desc.type));
+ }
+ else {
+ _ptr++;
+ if (pmDebug && DBG_TRACE_APPL0)
+ printf("%s: ptr size=%d valtype=%d descrtype=%s\n",
+ name,
+ result->vset[0]->vlist[0].value.pval->vlen,
+ result->vset[0]->vlist[0].value.pval->vtype,
+ pmTypeStr(desc.type));
+ }
+ }
+ }
+ pmFreeResult(result);
+}
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int c;
+ int sts;
+ int i;
+ int errflag = 0;
+ char *host = "localhost";
+ char *namespace = NULL;
+ char *endnum;
+ int iter = 1;
+ unsigned long datasize;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N]";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-h hostname] [-i iterations] [-n namespace] [-l licenseflag ] [name ...]";
+
+ __pmProcessDataSize(NULL);
+ __pmSetProgname(pmProgname);
+
+ while ((c = getopt(argc, argv, "D:h:i:l:n:")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ host = optarg;
+ break;
+
+ case 'i': /* iteration count */
+ iter = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: -i requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ sts = pmNewContext(PM_CONTEXT_HOST, host);
+
+ if (sts < 0) {
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (namespace != NULL) {
+ /*
+ * only explicitly load namespace if -n specified
+ */
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+
+ for (i = 0; i < iter; i++) {
+ if (optind >= argc)
+ pmTraversePMNS("", dometric);
+ else {
+ int a;
+ for (a = optind; a < argc; a++) {
+ pmTraversePMNS(argv[a], dometric);
+ }
+ }
+ __pmProcessDataSize(&datasize);
+ printf("[%d] %d metrics, %d getindom, %d insitu, %d ptr",
+ i, _metrics, _indom, _insitu, _ptr);
+ if (datasize)
+ printf(", mem leak: %ld Kbytes", datasize);
+ putchar('\n');
+ _metrics = _indom = _insitu = _ptr = 0;
+ }
+
+ exit(0);
+}
diff --git a/qa/src/exercise_fault.c b/qa/src/exercise_fault.c
new file mode 100644
index 0000000..3c75471
--- /dev/null
+++ b/qa/src/exercise_fault.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * Exercise fault injection infrastructure.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/fault.h>
+#include <string.h>
+#include <errno.h>
+
+static void
+exercise(void)
+{
+ int i;
+ void *p;
+ for (i = 1; i <= 10; i++) {
+ __pmFaultInject("QA:1", PM_FAULT_ALLOC);
+ p = malloc(10);
+ if (p == NULL)
+ fprintf(stderr, "malloc:1[%d] %s\n", i, strerror(errno));
+ else
+ free(p);
+ __pmFaultInject("QA:2", PM_FAULT_ALLOC);
+ p = malloc(100);
+ if (p == NULL)
+ fprintf(stderr, "malloc:2[%d] %s\n", i, strerror(errno));
+ else
+ free(p);
+ __pmFaultInject("QA:3", PM_FAULT_ALLOC);
+ p = malloc(1000);
+ if (p == NULL)
+ fprintf(stderr, "malloc:3[%d] %s\n", i, strerror(errno));
+ else
+ free(p);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *usage = "[-D debug]";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc) {
+ fprintf(stderr, "Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ exercise();
+
+ return 0;
+}
diff --git a/qa/src/exerlock.c b/qa/src/exerlock.c
new file mode 100644
index 0000000..96d0b83
--- /dev/null
+++ b/qa/src/exerlock.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise low-level libpcp locking primitives
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static void
+timeout(int i, void *j)
+{
+ fprintf(stderr, "Timeout!\n");
+ exit(2);
+}
+
+static void
+_usage()
+{
+ fprintf(stderr, "Usage: exerlock reqs\n");
+ fprintf(stderr, "reqs is a string of: i (initialize), l (lock) and u (unlock)\n");
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *p;
+ struct timeval delta = { 1, 0 };
+
+ if (argc != 2) _usage();
+
+ __pmAFregister(&delta, NULL, timeout);
+#ifdef DBG_TRACE_DESPERATE
+ pmDebug |= DBG_TRACE_DESPERATE;
+#endif
+
+ for (p = argv[1]; *p; p++) {
+ switch (*p) {
+ case 'i':
+ fprintf(stderr, "initialize\n");
+ PM_INIT_LOCKS();
+ break;
+ case 'l':
+ fprintf(stderr, "lock\n");
+ PM_LOCK(__pmLock_libpcp);
+ break;
+ case 'u':
+ fprintf(stderr, "unlock\n");
+ PM_UNLOCK(__pmLock_libpcp);
+ break;
+ default:
+ _usage();
+ }
+ }
+
+ return 0;
+}
diff --git a/qa/src/exertz.c b/qa/src/exertz.c
new file mode 100644
index 0000000..5972104
--- /dev/null
+++ b/qa/src/exertz.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ int force = 0;
+ int verbose = 0;
+ char *host = NULL; /* pander to gcc */
+ char *configfile = (char *)0;
+ char *logfile = (char *)0;
+ char *tz = (char *)0;
+ char *tzhost = (char *)0;
+ int tzh = -1; /* pander to gcc */
+ char local[MAXHOSTNAMELEN];
+ char *namespace = PM_NS_DEFAULT;
+ int samples = -1;
+ double delta = 1.0;
+ char *endnum;
+ time_t now;
+ int tzh2;
+ char s[28];
+
+ __pmSetProgname(argv[0]);
+
+ now = 24 * 60 * 60; /* epoch + 1 day */
+ putenv("TZ=UTC"); /* sane starting point */
+
+ printf("UTC pmCtime(): %s", pmCtime(&now, s));
+ printf("UTC ctime(): %s", ctime(&now));
+
+ while ((c = getopt(argc, argv, "a:c:D:f:h:ln:s:t:Vz:Z:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'c': /* configfile */
+ if (configfile != (char *)0) {
+ fprintf(stderr, "%s: at most one -c option allowed\n", pmProgname);
+ errflag++;
+ }
+ configfile = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'f': /* force */
+ force++;
+ break;
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'l': /* logfile */
+ logfile = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples <= 0.0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 't': /* delta seconds (double) */
+ delta = strtod(optarg, &endnum);
+ if (*endnum != '\0' || delta <= 0.0) {
+ fprintf(stderr, "%s: -t requires floating point argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'V': /* verbose */
+ verbose++;
+ break;
+
+ case 'z': /* timezone from host */
+ if (tz != (char *)0) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ tzhost = optarg;
+ break;
+
+ case 'Z': /* $TZ timezone */
+ if (tzhost != (char *)0) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ tz = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -c configfile file to load configuration from\n\
+ -D debug standard PCP debug flag\n\
+ -f force .. \n\
+ -h host metrics source is PMCD on host\n\
+ -l logfile redirect diagnostics and trace output\n\
+ -n namespace use an alternative PMNS\n\
+ -s samples terminate after this many iterations\n\
+ -t delta sample interval in seconds(float) [default 1.0]\n\
+ -V verbose/diagnostic output\n\
+ -z host set reporting timezone to local time for host\n\
+ -Z timezone set reporting timezone\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (logfile != (char *)0) {
+ __pmOpenLog(pmProgname, logfile, stderr, &sts);
+ if (sts < 0) {
+ fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmProgname, logfile);
+ }
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+ if (tzhost == (char *)0 && tz == (char *)0)
+ tzh = pmNewContextZone();
+
+ if (tzhost != (char *)0) {
+ if (type == PM_CONTEXT_ARCHIVE) {
+ pmLogLabel label;
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if (strcmp(tzhost, label.ll_hostname) != 0) {
+ fprintf(stderr, "%s: mismatched host name between -z (%s) and archive (%s)\n",
+ pmProgname, tzhost, label.ll_hostname);
+ exit(1);
+ }
+ }
+ else if (strcmp(tzhost, host) != 0) {
+ fprintf(stderr, "%s: -z and -h must agree on the name of the host\n", pmProgname);
+ exit(1);
+ }
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+ }
+
+ if (tz != (char *)0) {
+ if ((tzh = pmNewZone(tz)) < 0) {
+ fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n",
+ pmProgname, tz, pmErrStr(tzh));
+ exit(1);
+ }
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ while (optind < argc) {
+ printf("extra argument[%d]: %s\n", optind, argv[optind]);
+ optind++;
+ }
+
+ while (samples == -1 || samples-- > 0) {
+ /* put real stuff here */
+ break;
+ }
+
+ printf("PMAPI context pmCtime(): %s", pmCtime(&now, s));
+ printf("UTC ctime(): %s", ctime(&now));
+
+ tzh2 = pmNewZone("PST8PDT");
+ printf("and in California: %s", pmCtime(&now, s));
+ printf("UTC ctime(): %s", ctime(&now));
+ pmNewZone("EST-11EST-10,86/2:00,303/2:00");
+ printf("and in Melbourne: %s", pmCtime(&now, s));
+ printf("UTC ctime(): %s", ctime(&now));
+ pmUseZone(tzh2);
+ printf("back to California: %s", pmCtime(&now, s));
+ printf("UTC ctime(): %s", ctime(&now));
+
+ pmUseZone(tzh);
+ printf("back to the PMAPI context pmCtime(): %s", pmCtime(&now, s));
+ printf("UTC ctime(): %s", ctime(&now));
+
+ exit(0);
+}
diff --git a/qa/src/fcsw_indom.0 b/qa/src/fcsw_indom.0
new file mode 100644
index 0000000..93369b7
--- /dev/null
+++ b/qa/src/fcsw_indom.0
Binary files differ
diff --git a/qa/src/fcsw_indom.index b/qa/src/fcsw_indom.index
new file mode 100644
index 0000000..3fe4996
--- /dev/null
+++ b/qa/src/fcsw_indom.index
Binary files differ
diff --git a/qa/src/fcsw_indom.meta b/qa/src/fcsw_indom.meta
new file mode 100644
index 0000000..fb55c4c
--- /dev/null
+++ b/qa/src/fcsw_indom.meta
Binary files differ
diff --git a/qa/src/fetchpdu.c b/qa/src/fetchpdu.c
new file mode 100644
index 0000000..6260117
--- /dev/null
+++ b/qa/src/fetchpdu.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+
+int
+main(int argc, char **argv)
+{
+
+ int c;
+ int sts;
+ int errflag = 0;
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N] ";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-h hostname] [-n namespace]";
+ int i;
+ int n;
+ char *namelist[20];
+ pmID midlist[20];
+ int numpmid;
+ pmResult *rslt;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:h:n:")) != EOF) {
+ switch (c) {
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ host = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ i = 0;
+ namelist[i++] = "sample.long.one";
+ namelist[i++] = "sampledso.long.one";
+ numpmid = i;
+ n = pmLookupName(numpmid, namelist, midlist);
+ if (n < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(n));
+ for (i = 0; i < numpmid; i++) {
+ if (midlist[i] == PM_ID_NULL)
+ printf(" %s is bad\n", namelist[i]);
+ }
+ exit(1);
+ }
+
+ if ((n = pmFetch(numpmid, midlist, &rslt)) < 0) {
+ printf("pmFetch rslt: %s\n", pmErrStr(n));
+ exit(1);
+ }
+
+ for (i = 0; i < numpmid; i++) {
+ printf("%s: ", namelist[i]);
+ if (rslt->vset[i]->numval < 0)
+ printf("%s\n", pmErrStr(rslt->vset[i]->numval));
+ else
+ printf("%d\n", rslt->vset[i]->vlist[0].value.lval);
+ }
+
+/*
+ __pmDumpResult(stdout, rslt);
+*/
+
+ exit(0);
+}
diff --git a/qa/src/fetchrate.c b/qa/src/fetchrate.c
new file mode 100644
index 0000000..38e4078
--- /dev/null
+++ b/qa/src/fetchrate.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *host = "localhost";
+ int type = PM_CONTEXT_HOST;
+ char *namespace = PM_NS_DEFAULT;
+ int iterations = 2000;
+ int iter;
+ char *metric;
+ pmID pmid;
+ pmResult *result;
+ struct timeval before, after;
+ double delta;
+ static char *usage = "[-h hostname] [-L] [-n namespace] [-i iterations] metric";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:h:Ln:i:")) != EOF) {
+ switch (c) {
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ type = PM_CONTEXT_HOST;
+ host = optarg;
+ break;
+
+ case 'L': /* local, no PMCD */
+ putenv("PMDA_LOCAL_SAMPLE=");
+ type = PM_CONTEXT_LOCAL;
+ host = NULL;
+ break;
+
+ case 'i': /* iterations */
+ iterations = atoi(optarg);
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+USAGE:
+ fprintf(stderr, "Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, host, pmErrStr(sts));
+ else
+ printf("%s: Cannot make standalone local connection: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ if (optind >= argc)
+ goto USAGE;
+
+ metric = argv[optind];
+ if ((sts = pmLookupName(1, &metric, &pmid)) < 0) {
+ printf("%s: metric ``%s'' : %s\n", pmProgname, metric, pmErrStr(sts));
+ exit(1);
+ }
+
+ gettimeofday(&before, (struct timezone *)0);
+ for (iter=0; iter < iterations; iter++) {
+ sts = pmFetch(1, &pmid, &result);
+ if (sts < 0) {
+ printf("%s: iteration %d : %s\n", pmProgname, iter, pmErrStr(sts));
+ exit(1);
+ }
+ pmFreeResult(result);
+ }
+ gettimeofday(&after, (struct timezone *)0);
+
+ if ((sts = pmWhichContext()) < 0) {
+ printf("%s: pmWhichContext: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ pmDestroyContext(sts);
+
+ delta = __pmtimevalSub(&after, &before);
+ printf("%s: metric %s %.2lf fetches/second\n",
+ pmProgname, metric, (double)iterations / delta);
+
+ exit(0);
+}
diff --git a/qa/src/fixhosts b/qa/src/fixhosts
new file mode 100755
index 0000000..8b207e2
--- /dev/null
+++ b/qa/src/fixhosts
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# For QA ...
+#
+
+if grep '155.0.17.0 pcpqa-4-00.sgi.com' /etc/hosts >/dev/null
+then
+ # already done
+ exit 0
+fi
+
+tmp=/var/tmp/$$
+trap "rm -f $tmp; exit 0" 0 1 2 3 15
+
+awk </dev/null >$tmp '
+BEGIN {
+ print ""
+ print "# bogus entries for PCP QA, added by qa/src/fixhosts"
+ print "#"
+ print "# ipv4"
+ # see chkacc1.c or chkacc2.c for why this makes sense
+ for (host = 0; host < 32; host++)
+ printf "155.%d.%d.%d pcpqa-4-%02d.sgi.com\n", host*3, 17+host, host, host
+ #print "# ipv6"
+ #for (host = 0; host < 32; host++)
+ #printf "fec0::%x:%x:%x:%x:%x:%x pcpqa-6-%02d.sgi.com\n", host*3, 17+host, host, host*3, 17+host, host, host
+ # this lot from chkacc3.c
+ a[0] = 0; a[1] = 37; a[2] = 235; a[3] = 126
+ b[0] = 0; b[1] = 201; b[2] = 77; b[3] = 127
+ c[0] = 0; c[1] = 15; c[2] = 191; c[3] = 64
+ d[0] = 0; d[1] = 1; d[2] = 127; d[3] = 254
+ host = 0
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ for (k = 0; k < 4; k++) {
+ for (l = 0; l < 4; l++) {
+ printf "%d.%d.%d.%d pcpqa-%03d.sgi.com\n", a[i], b[j], c[k], d[l], host
+ host++
+ }
+ }
+ }
+ }
+ }'
+
+sudo sh -c "cat $tmp >>/etc/hosts"
+
+
diff --git a/qa/src/getconfig.c b/qa/src/getconfig.c
new file mode 100644
index 0000000..03f959e
--- /dev/null
+++ b/qa/src/getconfig.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ */
+
+/*
+ * Check pmConfig()
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *usage = "[-D debug] configvar ...";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind >= argc) {
+ fprintf(stderr, "Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ while (optind < argc) {
+ printf("%s -> ", argv[optind]);
+ printf("%s\n", pmGetConfig(argv[optind]));
+ optind++;
+ }
+
+ exit(0);
+}
diff --git a/qa/src/getcontexthost.c b/qa/src/getcontexthost.c
new file mode 100644
index 0000000..324f3f6
--- /dev/null
+++ b/qa/src/getcontexthost.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2014 Ken McDonell. All Rights Reserved.
+ *
+ * exercise pmGetContextHostName
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int ctx1;
+ int ctx2;
+ int errflag = 0;
+ int type = 0;
+ char *host = NULL; /* pander to gcc */
+ char local[MAXHOSTNAMELEN];
+ char buf[MAXHOSTNAMELEN];
+
+ /* trim cmd name of leading directory components */
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:h:L?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'L': /* LOCAL, no PMCD */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ host = NULL;
+ type = PM_CONTEXT_LOCAL;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind < argc) {
+ fprintf(stderr,
+"Usage: %s [options]\n\
+\n\
+Options:\n\
+ -a archive metrics source is a PCP log archive\n\
+ -h host metrics source is PMCD on host\n\
+ -L use local context instead of PMCD\n",
+ pmProgname);
+ exit(1);
+ }
+
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ (void)gethostname(local, MAXHOSTNAMELEN);
+ local[MAXHOSTNAMELEN-1] = '\0';
+ host = local;
+ }
+ if ((ctx1 = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(ctx1));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(ctx1));
+ /* continue on in this case to test a bad context */
+ }
+
+ printf("pmGetContextHostName(%d)=\"%s\"\n", ctx1, pmGetContextHostName(ctx1));
+ printf("pmGetContextHostName_r(%d, ...) => \"%s\"\n", ctx1, pmGetContextHostName_r(ctx1, buf, sizeof(buf)));
+
+ ctx2 = pmDupContext();
+ if (ctx2 >= 0)
+ printf("pmDupConext()=%d\n", ctx2);
+ else
+ printf("pmDupContext()=%d - %s\n", ctx2, pmErrStr(ctx2));
+
+ printf("dup ctx pmGetContextHostName(%d)=\"%s\"\n", ctx2, pmGetContextHostName(ctx2));
+ printf("dup ctx pmGetContextHostName_r(%d, ...) => \"%s\"\n", ctx2, pmGetContextHostName_r(ctx2, buf, sizeof(buf)));
+
+ printf("original ctx pmGetContextHostName(%d)=\"%s\"\n", ctx1, pmGetContextHostName(ctx1));
+ printf("original ctx pmGetContextHostName_r(%d, ...) => \"%s\"\n", ctx1, pmGetContextHostName_r(ctx1, buf, sizeof(buf)));
+
+
+ return 0;
+}
diff --git a/qa/src/getoptions.c b/qa/src/getoptions.c
new file mode 100644
index 0000000..d3eaee9
--- /dev/null
+++ b/qa/src/getoptions.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2014 Red Hat.
+ *
+ * Exercise the pmGetOptions() series of PMAPI interfaces
+ */
+
+#include <pcp/pmapi.h>
+
+int
+getversion(void)
+{
+ int version = 0;
+ char *value;
+
+ if ((value = getenv("PMAPI_VERSION")) != NULL)
+ version = atoi(value);
+ return version;
+}
+
+int
+getflags(void)
+{
+ int flags = 0;
+
+ if (getenv("PM_OPTFLAG_MULTI") != NULL)
+ flags |= PM_OPTFLAG_MULTI;
+ if (getenv("PM_OPTFLAG_POSIX") != NULL)
+ flags |= PM_OPTFLAG_POSIX;
+ if (getenv("PM_OPTFLAG_MIXED") != NULL)
+ flags |= PM_OPTFLAG_MIXED;
+ if (getenv("PM_OPTFLAG_ENV_ONLY") != NULL)
+ flags |= PM_OPTFLAG_ENV_ONLY;
+ if (getenv("PM_OPTFLAG_LONG_ONLY") != NULL)
+ flags |= PM_OPTFLAG_LONG_ONLY;
+ if (getenv("PM_OPTFLAG_BOUNDARIES") != NULL)
+ flags |= PM_OPTFLAG_BOUNDARIES;
+ if (getenv("PM_OPTFLAG_STDOUT_TZ") != NULL)
+ flags |= PM_OPTFLAG_STDOUT_TZ;
+ return flags;
+}
+
+char *
+flagsstr(pmOptions *opts)
+{
+ static char flags[128];
+
+ if (opts->flags & PM_OPTFLAG_INIT)
+ strcat(flags, ",init");
+ if (opts->flags & PM_OPTFLAG_DONE)
+ strcat(flags, ",done");
+ if (opts->flags & PM_OPTFLAG_MULTI)
+ strcat(flags, ",multi");
+ if (opts->flags & PM_OPTFLAG_USAGE_ERR)
+ strcat(flags, ",usage_err");
+ if (opts->flags & PM_OPTFLAG_RUNTIME_ERR)
+ strcat(flags, ",runtime_err");
+ if (opts->flags & PM_OPTFLAG_EXIT)
+ strcat(flags, ",exit");
+ if (opts->flags & PM_OPTFLAG_POSIX)
+ strcat(flags, ",posix");
+ if (opts->flags & PM_OPTFLAG_MIXED)
+ strcat(flags, ",mixed");
+ if (opts->flags & PM_OPTFLAG_ENV_ONLY)
+ strcat(flags, ",env_only");
+ if (opts->flags & PM_OPTFLAG_LONG_ONLY)
+ strcat(flags, ",long_only");
+ if (opts->flags & PM_OPTFLAG_BOUNDARIES)
+ strcat(flags, ",boundaries");
+ if (opts->flags & PM_OPTFLAG_STDOUT_TZ)
+ strcat(flags, ",stdout_tz");
+
+ if (flags[0] == '\0') /* no flags */
+ flags[1] = '-';
+ return &flags[1];
+}
+
+char *
+contextstr(pmOptions *opts)
+{
+ if (opts->context == PM_CONTEXT_HOST)
+ return "host";
+ if (opts->context == PM_CONTEXT_ARCHIVE)
+ return "archive";
+ if (opts->context == PM_CONTEXT_LOCAL)
+ return "local";
+ return "-";
+}
+
+char *
+timevalstr(struct timeval *tp)
+{
+ struct tm tmp;
+ time_t then;
+ int msecs = tp->tv_usec / 1000;
+ int len;
+ static char tv[128];
+
+ if (tp->tv_sec == 0)
+ return "-";
+ memset(tv, 0, sizeof(tv));
+ then = (time_t)tp->tv_sec;
+ pmLocaltime(&then, &tmp);
+ len = sprintf(tv, "%s", asctime(&tmp));
+ sprintf(&tv[len-1], " [msec=%d]", msecs);
+ return tv;
+}
+
+char *
+intervalstr(struct timeval *tp)
+{
+ struct tm tmp;
+ time_t then;
+ int msecs = tp->tv_usec / 1000;
+ static char it[128];
+
+ if (tp->tv_sec == 0)
+ return "-";
+ memset(it, 0, sizeof(it));
+ then = (time_t)tp->tv_sec;
+ pmLocaltime(&then, &tmp);
+ sprintf(it, "%02d:%02d.%03d", tmp.tm_min, tmp.tm_sec, msecs);
+ return it;
+}
+
+char *
+isempty(char *string)
+{
+ if (string == NULL)
+ return "-";
+ return string;
+}
+
+void
+dumpall(pmOptions *opts)
+{
+ int i;
+
+ printf("Options structure dump:\n");
+ printf(" version: %d\n", opts->version);
+ printf(" flags: 0x%x (%s)\n", opts->flags, flagsstr(opts));
+ printf(" errors: %d\n", opts->errors);
+ printf(" context: 0x%x (%s)\n", opts->context, contextstr(opts));
+ printf(" nhosts: %d\n", opts->nhosts);
+ if (opts->nhosts > 0) {
+ printf(" hosts: %s", opts->hosts[0]);
+ for (i = 1; i < opts->nhosts; i++)
+ printf(",%s", opts->hosts[i]);
+ printf("\n");
+ }
+ printf(" narchives: %d\n", opts->narchives);
+ if (opts->narchives > 0) {
+ printf(" archives: %s", opts->archives[0]);
+ for (i = 1; i < opts->narchives; i++)
+ printf(",%s", opts->archives[i]);
+ printf("\n");
+ }
+ printf(" start: %s\n", timevalstr(&opts->start));
+ printf(" finish: %s\n", timevalstr(&opts->finish));
+ printf(" origin: %s\n", timevalstr(&opts->finish));
+ printf(" interval: %s\n", intervalstr(&opts->interval));
+ printf(" align_optarg: %s\n", isempty(opts->align_optarg));
+ printf(" start_optarg: %s\n", isempty(opts->start_optarg));
+ printf(" finish_optarg: %s\n", isempty(opts->finish_optarg));
+ printf(" origin_optarg: %s\n", isempty(opts->origin_optarg));
+ printf(" guiport_optarg: %s\n", isempty(opts->guiport_optarg));
+ printf(" timezone: %s\n", isempty(opts->timezone));
+ printf(" samples: %d\n", opts->samples);
+ printf(" guiport: %d\n", opts->guiport);
+ printf(" guiflag: %d\n", opts->guiflag);
+ printf(" tzflag: %d\n", opts->tzflag);
+ printf(" Lflag: %d\n", opts->Lflag);
+}
+
+int
+main(int argc, char *argv[])
+{
+ pmLongOptions longopts[] = {
+ PMAPI_GENERAL_OPTIONS,
+ PMAPI_OPTIONS_HEADER("Context options"),
+ PMOPT_SPECLOCAL,
+ PMOPT_LOCALPMDA,
+ PMOPT_HOSTSFILE,
+ PMOPT_HOST_LIST,
+ PMOPT_ARCHIVE_LIST,
+ PMOPT_ARCHIVE_FOLIO,
+ PMAPI_OPTIONS_HEADER("Testing options"),
+ { "extra", 0, 'x', 0, "an extra option, for testing" },
+ { "eXtra", 1, 'X', "ARG", "an extra option with an argument" },
+ { "", 0, 'y', 0, "a short-option-only without argument" },
+ { "", 1, 'Y', "N", "a short-option-only with an argument" },
+ { "fubar", 0, 0, 0, "a long-option-only without argument" },
+ { "foobar", 1, 0, "N", "a long-option-only with an argument" },
+ PMAPI_OPTIONS_END
+ };
+ pmOptions opts = {
+ .short_options = PMAPI_OPTIONS "H:K:L" "XxYy",
+ .long_options = longopts,
+ };
+ char *tz;
+ int c;
+
+ opts.version = getversion();
+ opts.flags = getflags();
+ while ((c = pmGetOptions(argc, argv, &opts)) != EOF) {
+ printf("Got option: %c index=%d [errors=%d]\n", c? c: '-', opts.index, opts.errors);
+ switch(c) {
+ case 'x':
+ printf(" -> x option has no argument\n");
+ break;
+ case 'X':
+ printf(" -> X option argument was: '%s'\n", opts.optarg);
+ break;
+ case 'y':
+ printf(" -> y option has no argument\n");
+ break;
+ case 'Y':
+ printf(" -> Y option argument was: '%s'\n", opts.optarg);
+ break;
+ case 0: /* long-only options */
+ printf(" -> long-only option index=%d\n", opts.index);
+ break;
+ default:
+ printf(" -> unexpected option: '%c'\n", c);
+ pmUsageMessage(&opts);
+ exit(1);
+ }
+ }
+ printf("End of option processing\n");
+
+ if (opts.flags & PM_OPTFLAG_USAGE_ERR)
+ fprintf(stderr, "Warning: usage error detected\n");
+ if (opts.flags & PM_OPTFLAG_RUNTIME_ERR)
+ fprintf(stderr, "Warning: runtime error detected\n");
+ if (opts.padding != 0)
+ fprintf(stderr, "Warning: non-zero padding\n");
+ if (opts.zeroes != 0)
+ fprintf(stderr, "Warning: unexpected non-zeroes\n");
+
+ if (opts.flags & PM_OPTFLAG_USAGE_ERR)
+ pmUsageMessage(&opts);
+ if (opts.flags & PM_OPTFLAG_RUNTIME_ERR)
+ pmflush();
+
+ if (opts.timezone) /* ensure we have deterministic output */
+ tz = opts.timezone;
+ else
+ tz = "UTC";
+
+ if ((c = pmNewZone(tz)) < 0)
+ fprintf(stderr, "Warning: TZ failure - %s: %s\n",
+ opts.timezone, pmErrStr(c));
+
+ dumpall(&opts);
+
+ pmFreeOptions(&opts);
+ exit(0);
+}
diff --git a/qa/src/gmt-boring.0 b/qa/src/gmt-boring.0
new file mode 100644
index 0000000..3350c6f
--- /dev/null
+++ b/qa/src/gmt-boring.0
Binary files differ
diff --git a/qa/src/gmt-boring.index b/qa/src/gmt-boring.index
new file mode 100644
index 0000000..e2785b6
--- /dev/null
+++ b/qa/src/gmt-boring.index
Binary files differ
diff --git a/qa/src/gmt-boring.meta b/qa/src/gmt-boring.meta
new file mode 100644
index 0000000..3af4953
--- /dev/null
+++ b/qa/src/gmt-boring.meta
Binary files differ
diff --git a/qa/src/grind-tools b/qa/src/grind-tools
new file mode 100755
index 0000000..648374f
--- /dev/null
+++ b/qa/src/grind-tools
@@ -0,0 +1,387 @@
+#!/bin/sh
+
+_usage()
+{
+ echo "Usage: $0 [-v] [-a archive] [-h host] metricspec [...]"
+ echo
+ echo "metricspec one of the forms:"
+ echo " metric-name"
+ echo " metric-name[instance]"
+ exit 1
+}
+
+# Get standard environment
+. $PCP_DIR/etc/pcp.env
+
+status=0
+tmp=/tmp/$$
+trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15
+rm -f $tmp.*
+
+verbose=false
+very_verbose=false
+host=localhost
+archive=""
+while getopts "a:h:v" c
+do
+ case "$c"
+ in
+ a)
+ src="-a $OPTARG"
+ archive=$OPTARG
+ host=""
+ ;;
+ h)
+ src="-h $OPTARG"
+ archive=""
+ host=$OPTARG
+ ;;
+ v)
+ $verbose && very_verbose=true
+ verbose=true
+ ;;
+ *)
+ _usage
+ # NOTREACHED
+ ;;
+ esac
+done
+shift `expr $OPTIND - 1`
+
+if [ $# -lt 1 ]
+then
+ _usage
+ # NOTREACHHED
+fi
+
+for arg
+do
+ case "$arg"
+ in
+ *[*)
+ echo "$arg" >>$tmp.all
+ ;;
+ *)
+ pmprobe -I $src $arg \
+ | sed \
+ -e 's/ "/ /' \
+ -e 's/" "/ /g' \
+ -e 's/"$//' \
+ -e 's/ /\
+/g' \
+ | sed -e '1,2d' \
+ | while read inst
+ do
+ echo "$arg[$inst]" >>$tmp.all
+ done
+ ;;
+ esac
+done
+
+sed <$tmp.all -e 's/\[.*//' \
+| sort -u >$tmp.metrics
+
+# cat $tmp.metrics
+# echo
+# cat $tmp.all
+
+# pmie
+#
+sed <$tmp.all >$tmp.config \
+ -e "s/\[/ #'/" \
+ -e "s/]/'/" \
+ -e 's/$/+/' \
+ -e '$s/$/1;/'
+$very_verbose && echo "pmie config ..." && cat $tmp.config
+if pmie $src -c $tmp.config -C
+then
+ $verbose && echo "pmie OK"
+else
+ echo "pmie FAILED"
+ echo "pmie config:"
+ cat $tmp.config
+ status=1
+fi
+
+# pmval
+#
+sed -e 's/]//' -e 's/\[/ /' <$tmp.all \
+ | $PCP_AWK_PROG '
+BEGIN { printf "pmval -s 2 -t 1sec '"$src"' -i " }
+$1 != metric { if (NR > 1) {
+ print " " metric
+ printf "pmval -s 2 -t 1sec '"$src"' -i "
+ }
+ metric = $1
+ }
+NR > 1 { printf "," }
+ { printf $2 }
+END { print " " metric
+ }' \
+| sed -e "s/-i /-i '/" -e "s/ [^ ]*\$/'&/" >$tmp.config
+$very_verbose && echo "pmval cmd ..." && cat $tmp.config
+cat $tmp.config | sh >$tmp.out 2>&1
+if grep '^samples: *2$' $tmp.out >/dev/null
+then
+ $verbose && echo "pmval OK"
+else
+ echo "pmval FAILED"
+ echo "pmval cmd:"
+ cat $tmp.config
+ cat $tmp.out
+ status=1
+fi
+
+# pmlogger
+#
+if [ -z "$host" ]
+then
+ echo "pmlogger skipped, source is an archive"
+else
+ echo "log mandatory on default {" >$tmp.config
+ sed -e 's/]//' -e 's/\[/ /' <$tmp.all \
+ | $PCP_AWK_PROG >>$tmp.config '
+$1 != metric { if (NR > 1) print " ]"
+ print $1," ["
+ metric = $1
+ }
+ { print " \"" $2 "\"" }
+END { print " ]"
+ print "}"
+ }'
+ $very_verbose && echo "pmlogger config ..." && cat $tmp.config
+ if pmlogger -l $tmp.log $src -s 2 -t 1sec -c $tmp.config $tmp
+ then
+ $verbose && echo "pmlogger OK"
+ archive=$tmp
+ else
+ echo "pmlogger FAILED"
+ cat $tmp.log
+ echo "pmlogger config:"
+ cat $tmp.config
+ status=1
+ fi
+fi
+
+# pmdumptext - simple with -a or -h
+#
+if which pmdumptext >/dev/null 2>&1
+then
+ sed -e 's/]//' -e 's/\[/ /' <$tmp.all \
+ | $PCP_AWK_PROG '
+BEGIN { printf "pmdumptext -s 2 -t 1sec '"$src"'" }
+$1 != metric { if (NR > 1) {
+ print "]"
+ printf "pmdumptext -s 2 -t 1sec '"$src"'"
+ }
+ metric = $1
+ printf " %s[",metric
+ first = 1
+ }
+ { if (first) {
+ printf "%s",$2
+ first = 0
+ }
+ else
+ printf ",%s",$2
+ }
+END { print "]"
+ }' >$tmp.config
+ $very_verbose && echo "pmdumptext cmd ..." && cat $tmp.config
+ cat $tmp.config | sh >$tmp.out 2>&1
+ ok=`grep '^[A-Z][a-z][a-z] [A-Z][a-z][a-z]' $tmp.out | wc -l | sed -e 's/ //g'`
+ if [ "$ok" -eq 2 ]
+ then
+ $verbose && echo "pmdumptext (simple) OK"
+ else
+ echo "pmdumptext (simple) FAILED"
+ echo "pmdumptext cmd:"
+ cat $tmp.config
+ cat $tmp.out
+ status=1
+ fi
+else
+ echo "pmdumptext skipped, no binary installed"
+fi
+
+# pmdumptext - extended notation ...
+# myhost:kernel.all.cpu.idle[cpu0,cpu3]
+# /path/to/myarchive/kernel.all.cpu.idle[cpu1]
+#
+if which pmdumptext >/dev/null 2>&1
+then
+ if [ -n "$host" ]
+ then
+ pfx="$host:"
+ else
+ pfx="$archive/"
+ fi
+ sed -e 's/]//' -e 's/\[/ /' <$tmp.all \
+ | $PCP_AWK_PROG '
+BEGIN { printf "pmdumptext -s 2 -t 1sec" }
+$1 != metric { metric = $1
+ first = 1
+ if (NR > 1) printf "]"
+ }
+ { if (first) {
+ printf " %s%s[%s","'"$pfx"'",metric,$2
+ first = 0
+ }
+ else
+ printf ",%s",$2
+ }
+END { print "]" }' >$tmp.config
+ $very_verbose && echo "pmdumptext cmd ..." && cat $tmp.config
+ cat $tmp.config | sh >$tmp.out 2>&1
+ ok=`grep '^[A-Z][a-z][a-z] [A-Z][a-z][a-z]' $tmp.out | wc -l | sed -e 's/ //g'`
+ if [ "$ok" -eq 2 ]
+ then
+ $verbose && echo "pmdumptext (extended) OK"
+ else
+ echo "pmdumptext (extended) FAILED"
+ echo "pmdumptext cmd:"
+ cat $tmp.config
+ cat $tmp.out
+ status=1
+ fi
+fi
+
+# pmchart
+#
+if which pmchart >/dev/null 2>&1
+then
+ echo "#pmchart" >$tmp.config
+ echo "Version 2.0 host dynamic" >>$tmp.config
+ echo "Chart Title "test" Style line" >>$tmp.config
+ sed <$tmp.all >>$tmp.config \
+ -e 's/]//' \
+ -e 's/\[/ Instance /' \
+ -e 's/^/ Plot Color #-cycle Host * Metric /'
+ $very_verbose && echo "pmchart config ..." && cat $tmp.config
+ if pmchart -C -c $tmp.config $src
+ then
+ $verbose && echo "pmchart OK"
+ else
+ echo "pmchart FAILED"
+ echo "pmchart config:"
+ cat $tmp.config
+ status=1
+ fi
+else
+ echo "pmchart skipped, no binary installed"
+fi
+
+# pmview
+#
+if which pmview >/dev/null 2>&1
+then
+ echo 'pmview Version 2.1 "foo" "bar"' >$tmp.config
+ $PCP_AWK_PROG <$tmp.all >>$tmp.config '
+BEGIN { printf "_colorlist l1 (" }
+NR % 3 == 0 { printf " red" }
+NR % 3 == 1 { printf " green" }
+NR % 3 == 2 { printf " blue" }
+END { print " )" }'
+ $PCP_AWK_PROG <$tmp.metrics >>$tmp.config '
+BEGIN { printf "_colorlist l2 (" }
+NR % 3 == 0 { printf " red" }
+NR % 3 == 1 { printf " green" }
+NR % 3 == 2 { printf " blue" }
+END { print " )" }'
+ sed <$tmp.all \
+ -e 's/]//' \
+ -e 's/\[/ /' \
+ | $PCP_AWK_PROG '
+BEGIN { print "_grid ("
+ print " _bar 0 0 ("
+ print " _metrics ("
+ }
+ { printf " %s[%s] 10 \"%d\"\n",$1,$2,NR }
+END { print " )"
+ print " _colorlist l1"
+ print " )"
+ }' >>$tmp.config
+ sed <$tmp.all \
+ -e 's/]//' \
+ -e 's/\[/ /' \
+ | $PCP_AWK_PROG '
+BEGIN { print " _bar 1 0 ("
+ print " _metrics ("
+ }
+$1 != metric { if (NR > 1) {
+ printf "] 100 \"%d\"\n",NR
+ }
+ metric = $1
+ printf " %s[%s",$1,$2
+ next
+ }
+ { printf ",%s",$2 }
+END { printf "] 100 \"%d\"\n",NR
+ print " )"
+ print " _colorlist l2"
+ print " )"
+ }' >>$tmp.config
+ sed <$tmp.all \
+ -e 's/]//' \
+ -e 's/\[/ /' \
+ | $PCP_AWK_PROG '
+BEGIN { print " _stack 2 0 ("
+ print " _metrics ("
+ }
+ { printf " %s[%s] 10\n",$1,$2 }
+END { print " )"
+ print " _colorlist l1"
+ print " )"
+ print ")"
+ }' >>$tmp.config
+ $very_verbose && echo "pmview config ..." && cat $tmp.config
+ if pmview -C -c $tmp.config $src
+ then
+ $verbose && echo "pmview OK"
+ else
+ echo "pmview FAILED"
+ echo "pmview config:"
+ cat $tmp.config
+ status=1
+ fi
+else
+ echo "pmview skipped, no binary installed"
+fi
+
+# pmgadgets
+#
+if which pmgadgets >/dev/null 2>&1
+then
+ if [ -z "$host" ]
+ then
+ echo "pmgadgets skipped, source is an archive"
+ else
+ cat <<End-of-File >$tmp.config
+pmgadgets 1 "foo" "bar"
+_legend l (
+ _default green3
+ 10 yellow
+)
+End-of-File
+ sed <$tmp.all \
+ -e 's/]//' \
+ -e 's/\[/ /' \
+ | $PCP_AWK_PROG '
+ { printf "_led 10 %d 5 5\n",10*NR
+ printf " _metric %s[\"%s\"]\n",$1,$2
+ printf " _legend l\n"
+ }' >>$tmp.config
+ $very_verbose && echo "pmgadgets config ..." && cat $tmp.config
+ if pmgadgets -C -c $tmp.config $src
+ then
+ $verbose && echo "pmgadgets OK"
+ else
+ echo "pmgadgets FAILED"
+ echo "pmgadgets config:"
+ cat $tmp.config
+ status=1
+ fi
+ fi
+else
+ echo "pmgadgets skipped, no binary installed"
+fi
diff --git a/qa/src/grind_conv.c b/qa/src/grind_conv.c
new file mode 100644
index 0000000..8b43501
--- /dev/null
+++ b/qa/src/grind_conv.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ */
+
+/*
+ * grind_conv - exercise pmConvScale, pmAtomStr, pmUnitsStr
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ static char *usage = "[-D debug] type value iunit ounit\n"
+"\n"
+"iunit and ounit are in the 6-integer format:\n"
+"dimspace:dimtime:dimcount:scalespace:scaletime:scalecount\n";
+ pmUnits iu;
+ pmUnits ou;
+ int type;
+ int vbase;
+ pmAtomValue iv;
+ pmAtomValue ov;
+ char *vp;
+ char *q;
+
+ __pmSetProgname(argv[0]);
+
+ /* stop at type arg, so value may have leading "-" */
+ putenv("POSIXLY_CORRECT=yes");
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || argc - optind != 4) {
+ fprintf(stderr, "Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ type = atoi(argv[optind]);
+ optind++;
+
+ if (strncmp(argv[optind], "0x", 2) == 0) {
+ vp = &argv[optind][2];
+ vbase = 16;
+ }
+ else {
+ vp = argv[optind];
+ vbase = 10;
+ }
+
+ q = vp;
+ switch (type) {
+ case PM_TYPE_32:
+ iv.l = strtol(vp, &q, vbase);
+ break;
+ case PM_TYPE_U32:
+ iv.ul = strtoul(vp, &q, vbase);
+ break;
+ case PM_TYPE_64:
+ iv.ll = strtoll(vp, &q, vbase);
+ break;
+ case PM_TYPE_U64:
+ iv.ull = strtoull(vp, &q, vbase);
+ break;
+ case PM_TYPE_FLOAT:
+ sts = sscanf(vp, "%f", &iv.f);
+ if (sts == 1) q = "";
+ break;
+ case PM_TYPE_DOUBLE:
+ sts = sscanf(vp, "%lf", &iv.d);
+ if (sts == 1) q = "";
+ break;
+ default:
+ case PM_TYPE_STRING:
+ iv.cp = vp;
+ q = "";
+ break;
+ case PM_TYPE_AGGREGATE:
+ case PM_TYPE_AGGREGATE_STATIC:
+ iv.vbp = (pmValueBlock *)malloc(PM_VAL_HDR_SIZE+strlen(vp));
+ iv.vbp->vlen = PM_VAL_HDR_SIZE+strlen(vp);
+ iv.vbp->vtype = type;
+ strncpy(iv.vbp->vbuf, vp, strlen(vp));
+ q = "";
+ break;
+ case PM_TYPE_EVENT: // ignore the value, force 0 event records
+ iv.vbp = (pmValueBlock *)malloc(sizeof(pmEventArray)-sizeof(pmEventRecord));
+ iv.vbp->vlen = sizeof(pmEventArray)-sizeof(pmEventRecord);
+ iv.vbp->vtype = type;
+ memset((void *)iv.vbp->vbuf, 0, sizeof(int));
+ q = "";
+ break;
+ case PM_TYPE_HIGHRES_EVENT: // ignore the value, force 0 event records
+ iv.vbp = (pmValueBlock *)malloc(sizeof(pmHighResEventArray)-sizeof(pmHighResEventRecord));
+ iv.vbp->vlen = sizeof(pmHighResEventArray)-sizeof(pmHighResEventRecord);
+ iv.vbp->vtype = type;
+ memset((void *)iv.vbp->vbuf, 0, sizeof(int));
+ q = "";
+ break;
+ }
+ optind++;
+
+ if (*q != '\0') {
+ fprintf(stderr, "Value botched @ %s\n", q);
+ exit(1);
+ }
+
+ vp = argv[optind];
+ iu.dimSpace = strtol(vp, &q, 10);
+ if (*q != ':') goto bad_in;
+ vp = ++q;
+ iu.dimTime = strtol(vp, &q, 10);
+ if (*q != ':') goto bad_in;
+ vp = ++q;
+ iu.dimCount = strtol(vp, &q, 10);
+ if (*q != ':') goto bad_in;
+ vp = ++q;
+ iu.scaleSpace = strtol(vp, &q, 10);
+ if (*q != ':') goto bad_in;
+ vp = ++q;
+ iu.scaleTime = strtol(vp, &q, 10);
+ if (*q != ':') goto bad_in;
+ vp = ++q;
+ iu.scaleCount = strtol(vp, &q, 10);
+ if (*q != '\0') goto bad_in;
+ optind++;
+
+ vp = argv[optind];
+ ou.dimSpace = strtol(vp, &q, 10);
+ if (*q != ':') goto bad_out;
+ vp = ++q;
+ ou.dimTime = strtol(vp, &q, 10);
+ if (*q != ':') goto bad_out;
+ vp = ++q;
+ ou.dimCount = strtol(vp, &q, 10);
+ if (*q != ':') goto bad_out;
+ vp = ++q;
+ ou.scaleSpace = strtol(vp, &q, 10);
+ if (*q != ':') goto bad_out;
+ vp = ++q;
+ ou.scaleTime = strtol(vp, &q, 10);
+ if (*q != ':') goto bad_out;
+ vp = ++q;
+ ou.scaleCount = strtol(vp, &q, 10);
+ if (*q != '\0') goto bad_out;
+
+ printf("type=%d input units=%s value=%s\n", type, pmUnitsStr(&iu), pmAtomStr(&iv, type));
+
+ if ((sts = pmConvScale(type, &iv, &iu, &ov, &ou)) < 0)
+ printf("pmConvScale Error: %s\n", pmErrStr(sts));
+ else
+ printf("output units=%s value=%s\n", pmUnitsStr(&ou), pmAtomStr(&ov, type));
+
+ exit(0);
+
+bad_in:
+ fprintf(stderr, "Input units botch @ %s\n", q);
+ exit(1);
+
+bad_out:
+ fprintf(stderr, "Output units botch @ %s\n", q);
+ exit(1);
+}
+
diff --git a/qa/src/grind_ctx.c b/qa/src/grind_ctx.c
new file mode 100644
index 0000000..da2832f
--- /dev/null
+++ b/qa/src/grind_ctx.c
@@ -0,0 +1,161 @@
+/*
+ * Repeatedly call pmNewContext ... then pmDestroyContext ...
+ *
+ * Looking for memory leaks, malloc botches etc, especially in the
+ * presence of derived metrics.
+ *
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * (largely borrowed from chkctx2.c)
+ */
+
+#define SOURCE handle == 0 ? "host" : ( type == PM_CONTEXT_ARCHIVE ? "archive" : "host" )
+#define HOST handle == 0 ? "localhost" : host
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#define NUMCTX 10
+
+static void
+grind(int type, char *host)
+{
+ int ctx[NUMCTX];
+ int i;
+ int sts;
+
+ for (i = 0; i < NUMCTX; i++) {
+ if (type == PM_CONTEXT_HOST) {
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ fprintf(stderr, "pmNewContext(host=%s): %s\n", host, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ else if (type == PM_CONTEXT_LOCAL) {
+ if ((sts = pmNewContext(PM_CONTEXT_LOCAL, host)) < 0) {
+ fprintf(stderr, "pmNewContext(local): %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ }
+ else {
+ if ((sts = pmNewContext(PM_CONTEXT_ARCHIVE, host)) < 0) {
+ fprintf(stderr, "pmNewContext(archive=%s): %s\n", host, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ ctx[i] = sts;
+ }
+
+ for (i = NUMCTX-1; i >=0; i--) {
+ if ((sts = pmDestroyContext(ctx[i])) < 0) {
+ fprintf(stderr, "pmDestroyContext(%d): %s\n", ctx[i], pmErrStr(sts));
+ }
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ int iter = 5;
+ char *host = "localhost";
+ char *endnum;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N] ";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-a archive] [-c dmfile] [-h hostname] [-L] [-n namespace] [-s iterations]";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:c:D:h:Ln:s:")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'c': /* derived metrics config file */
+ sts = pmLoadDerivedConfig(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: -c error: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ break;
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'L': /* local mode, no PMCD */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ host = NULL;
+ type = PM_CONTEXT_LOCAL;
+ break;
+
+ case 'n': /* alternative name space file */
+ if ((sts = pmLoadNameSpace(optarg)) < 0) {
+ fprintf(stderr, "%s: cannot load namespace from \"%s\": %s\n", pmProgname, optarg, pmErrStr(sts));
+ exit(1);
+ }
+ break;
+
+ case 's': /* iterations */
+ iter = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || iter < 0) {
+ fprintf(stderr, "%s: -s requires poisitive numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if (type == 0)
+ type = PM_CONTEXT_HOST; /* default */
+
+ while (iter-- > 0) {
+ printf("Iteration %d\n", iter);
+ grind(type, host);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/hashwalk.c b/qa/src/hashwalk.c
new file mode 100644
index 0000000..05f2551
--- /dev/null
+++ b/qa/src/hashwalk.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2013 Red Hat.
+ *
+ * Exercise libpcp hash walk interfaces
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+void
+dumpnode(unsigned int key, long data)
+{
+ printf("%u => %ld\n", key, data);
+}
+
+__pmHashWalkState
+walker(const __pmHashNode *n, void *v)
+{
+ __pmHashWalkState state = (__pmHashWalkState)(long)v;
+ dumpnode(n->key, (long)n->data);
+ return state;
+}
+
+void
+chained(__pmHashCtl *h)
+{
+ __pmHashNode *n;
+
+ for (n = __pmHashWalk(h, PM_HASH_WALK_START);
+ n != NULL;
+ n = __pmHashWalk(h, PM_HASH_WALK_NEXT)) {
+ dumpnode(n->key, (long)n->data);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ __pmHashCtl hc = { 0 };
+
+ printf("adding entries\n");
+ __pmHashAdd(0, (void *)0L, &hc);
+ __pmHashAdd(1, (void *)1L, &hc);
+ __pmHashAdd(2, (void *)2L, &hc);
+ __pmHashAdd(3, (void *)3L, &hc);
+
+ if (argc >= 2) {
+ if (strcmp(argv[1], "callback") == 0)
+ __pmHashWalkCB(walker, (void *)PM_HASH_WALK_NEXT, &hc);
+ else if (strcmp(argv[1], "linked") == 0)
+ chained(&hc);
+ exit(0);
+ }
+
+ printf("iterating WALK_STOP\n");
+ __pmHashWalkCB(walker, (void *)PM_HASH_WALK_STOP, &hc);
+ printf("iterating WALK_NEXT\n");
+ __pmHashWalkCB(walker, (void *)PM_HASH_WALK_NEXT, &hc);
+ printf("iterating WALK_DELETE_STOP\n");
+ __pmHashWalkCB(walker, (void *)PM_HASH_WALK_DELETE_STOP, &hc);
+ printf("iterating WALK_NEXT\n");
+ __pmHashWalkCB(walker, (void *)PM_HASH_WALK_NEXT, &hc);
+ printf("iterating WALK_DELETE_NEXT\n");
+ __pmHashWalkCB(walker, (void *)PM_HASH_WALK_DELETE_NEXT, &hc);
+ printf("iterating WALK_NEXT\n");
+ __pmHashWalkCB(walker, (void *)PM_HASH_WALK_NEXT, &hc);
+
+ exit(0);
+}
diff --git a/qa/src/hex2nbo.c b/qa/src/hex2nbo.c
new file mode 100644
index 0000000..dc6707d
--- /dev/null
+++ b/qa/src/hex2nbo.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+/*
+ * internal structs with field order reversed for the not network
+ * byte order case
+ */
+typedef struct {
+ unsigned int serial : 22; /* unique within PMD */
+ unsigned int domain : 9; /* the administrative PMD */
+ int flag : 1;
+} __pmInDom_rev;
+
+typedef struct {
+ unsigned int item : 10;
+ unsigned int cluster : 12;
+ unsigned int domain : 9;
+ int flag : 1;
+} __pmID_rev;
+
+int
+main(int argc, char **argv)
+{
+ char buf[4096];
+ char *p;
+ char *q;
+ char *last;
+ char *t;
+ char c;
+ unsigned long val;
+ unsigned long nval;
+ int type; /* 0 plain, 1 indom, 2 pmid */
+ __pmInDom_int *ip;
+ __pmInDom_rev *nip;
+ __pmID_int *pp;
+ __pmID_rev *npp;
+
+ /* 0x01020304 */
+
+ while (fgets(buf, sizeof(buf), stdin) != NULL) {
+ p = buf;
+ while ((q = strstr(p, "0x")) != NULL) {
+ q += 2;
+ c = *q;
+ *q = '\0';
+ fputs(p, stdout);
+ type = 0;
+ last = p;
+ if ((t = strstr(p, "InDom")) >= last) {
+ last = t;
+ type = 1;
+ }
+ if ((t = strstr(p, "indom:")) >= last) {
+ last = t;
+ type = 1;
+ }
+ if ((t = strstr(p, "indom=")) >= last) {
+ last = t;
+ type = 1;
+ }
+ if ((t = strstr(p, "instance id:")) >= last) {
+ last = t;
+ type = -1; /* don't convert */
+ }
+ if ((t = strstr(p, "PMID")) >= last) {
+ last = t;
+ type = 2;
+ }
+ /* final check, no assignment needed */
+ if (strstr(p, "pmid:") >= last) {
+ type = 2;
+ }
+ *q = c;
+ p = q;
+ val = strtoul(p, &q, 16);
+ if (q-p > 0 && val != (nval = htonl(val))) {
+ if (type == -1) {
+ /* don't convert */
+ nval = val;
+ }
+ else if (type == 0) {
+ /* full-word byte swap */
+ ;
+ }
+ else if (type == 1) {
+ /* instance domain */
+ ip = (__pmInDom_int *)&val;
+ nip = (__pmInDom_rev *)&nval;
+ nip->flag = ip->flag;
+ nip->domain = ip->domain;
+ nip->serial = ip->serial;
+ }
+ else if (type == 2) {
+ /* metric identifier */
+ pp = (__pmID_int *)&val;
+ npp = (__pmID_rev *)&nval;
+ npp->flag = pp->flag;
+ npp->domain = pp->domain;
+ npp->cluster = pp->cluster;
+ npp->item = pp->item;
+ }
+ printf("%0*x", (int)(q-p), (unsigned)nval);
+ p = q;
+ }
+ }
+ fputs(p, stdout);
+ }
+ return 0;
+}
diff --git a/qa/src/hp-mib.c b/qa/src/hp-mib.c
new file mode 100644
index 0000000..fb31b93
--- /dev/null
+++ b/qa/src/hp-mib.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/* short test program for hp-mib metrics */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static char *metrics[] = {
+ "proc.nprocs",
+ "proc.psinfo.pid",
+ "proc.psinfo.uid",
+ "proc.psinfo.ppid",
+ "proc.psinfo.nice",
+ "proc.psinfo.ttydev",
+ "proc.psinfo.gid",
+ "proc.psinfo.pgrp",
+ "proc.psinfo.pri",
+ "proc.psinfo.oldpri",
+ "proc.psinfo.addr",
+ "proc.psinfo.cpu",
+ "proc.psinfo.uname",
+ "proc.psinfo.gname",
+ "proc.psinfo.ttyname",
+ "proc.pstatus.utime",
+ "proc.pstatus.stime",
+ "proc.psusage.starttime",
+ "proc.pstatus.flags",
+ "proc.psinfo.state",
+ "proc.psinfo.sname",
+ "proc.psinfo.wchan",
+ "proc.psinfo.fname",
+ "proc.psinfo.psargs",
+ "proc.psinfo.time",
+ "proc.psusage.tstamp",
+ "proc.psusage.starttime",
+ "proc.psinfo.clname",
+ "proc.psinfo.time",
+ "proc.psusage.rss",
+ "proc.pscred.suid",
+ "proc.psinfo.ttydev",
+ "proc.memory.virtual.txt",
+ "proc.memory.virtual.dat",
+ "proc.memory.virtual.bss",
+ "proc.memory.virtual.stack",
+ "proc.memory.virtual.shm",
+ "proc.memory.physical.txt",
+ "proc.memory.physical.dat",
+ "proc.memory.physical.bss",
+ "proc.memory.physical.stack",
+ "proc.memory.physical.shm"
+};
+
+#define NMETRICS (sizeof(metrics) / sizeof(metrics[0]))
+static pmID pmids[NMETRICS];
+
+static int
+int_compare(int *a, int *b)
+{
+ return *a - *b;
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *namespace = PM_NS_DEFAULT;
+ pmResult *result;
+ pmDesc desc;
+ int all_n;
+ int *all_inst;
+ char **all_names;
+ int (*int_cmp)() = int_compare;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N]";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = " [-n namespace]";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:n:")) != EOF) {
+ switch (c) {
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+
+ /*
+ * Startup:
+ * a) load the name space
+ * b) lookup the metrics in the name space
+ * c) establish a context
+ * d) get the instance domain identifier
+ * [Note: these steps only have to be done once on startup]
+ */
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmLookupName(NMETRICS, metrics, pmids)) < 0) {
+ printf("%s: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ putenv("PMDA_LOCAL_PROC=");
+ if ((sts = pmNewContext(PM_CONTEXT_LOCAL, NULL)) < 0) {
+ printf("%s: Cannot make local connection: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmLookupDesc(pmids[1], &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+
+
+ /*
+ * Enumerate the instance domain
+ * [This has to be done before every fetch]
+ */
+ if (desc.indom != PM_INDOM_NULL) {
+ all_n = pmGetInDom(desc.indom, &all_inst, &all_names);
+ if (all_n < 0) {
+ printf("%s: pmGetInDom: %s\n", pmProgname, pmErrStr(all_n));
+ exit(1);
+ }
+ }
+ else {
+ printf("%s: botch: metric %s (%s) should have an instance domain\n", pmProgname, metrics[1], pmIDStr(pmids[1]));
+ exit(1);
+ }
+
+ /*
+ * sort the instance identifiers
+ * [This has to be done before every fetch]
+ */
+ qsort(all_inst, all_n, sizeof(int), int_cmp);
+
+ /*
+ * establish an explicit instance profile
+ * [This has to be done before every fetch]
+ */
+ pmDelProfile(desc.indom, 0, (int *)0); /* exclude everything first */
+ pmAddProfile(desc.indom, all_n, all_inst); /* and then explicitly include our list of pids */
+
+ /*
+ * fetch the desired metrics
+ */
+ sts = pmFetch(NMETRICS, pmids, &result);
+ if (sts < 0) {
+ printf("%s: fetch all %d instances : %s\n", pmProgname, all_n, pmErrStr(sts));
+ exit(1);
+ }
+
+
+
+ printf("\n\n-------- Result Dump --------------\n");
+ __pmDumpResult(stdout, result);
+
+ /* note: in a loop, you need to free(all_inst); free(all_names); on every iteration */
+
+ free(all_inst);
+ free(all_names);
+ pmFreeResult(result);
+ if ((sts = pmWhichContext()) < 0) {
+ printf("%s: pmWhichContext: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ pmDestroyContext(sts);
+ exit(0);
+}
+
diff --git a/qa/src/hrunpack.c b/qa/src/hrunpack.c
new file mode 100644
index 0000000..e7de2a1
--- /dev/null
+++ b/qa/src/hrunpack.c
@@ -0,0 +1,479 @@
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+static int mydomain = 29;
+
+static pmValueSet vs;
+static char *ebuf;
+static int ebuflen;
+static char *eptr;
+static char *ebufend;
+
+static pmHighResEventArray *hreap;
+static pmHighResEventRecord *hrerp;
+
+static int
+check_buf(int need)
+{
+ int offset = eptr - ebuf;
+
+ while (&eptr[need] >= ebufend) {
+ ebuflen *= 2;
+ if ((ebuf = (char *)realloc(ebuf, ebuflen)) == NULL)
+ return -errno;
+ eptr = &ebuf[offset];
+ ebufend = &ebuf[ebuflen-1];
+ vs.vlist[0].value.pval = (pmValueBlock *)ebuf;
+ }
+ return 0;
+}
+
+static int
+add_param(pmID pmid, int type, pmAtomValue *avp)
+{
+ int need; /* bytes in the buffer */
+ int vlen; /* value only length */
+ int sts;
+ pmEventParameter *epp;
+ void *src;
+
+ need = sizeof(pmEventParameter);
+ switch (type) {
+ case PM_TYPE_32:
+ case PM_TYPE_U32:
+ vlen = sizeof(avp->l);
+ need += vlen;
+ src = &avp->l;
+ break;
+ case PM_TYPE_64:
+ case PM_TYPE_U64:
+ vlen = sizeof(avp->ll);
+ need += vlen;
+ src = &avp->ll;
+ break;
+ case PM_TYPE_FLOAT:
+ vlen = sizeof(avp->f);
+ need += vlen;
+ src = &avp->f;
+ break;
+ case PM_TYPE_DOUBLE:
+ vlen = sizeof(avp->d);
+ need += vlen;
+ src = &avp->d;
+ break;
+ case PM_TYPE_STRING:
+ vlen = strlen(avp->cp);
+ need += PM_PDU_SIZE_BYTES(vlen);
+ src = avp->cp;
+ break;
+ case PM_TYPE_AGGREGATE:
+ case PM_TYPE_AGGREGATE_STATIC:
+ vlen = avp->vbp->vlen - PM_VAL_HDR_SIZE;
+ need += PM_PDU_SIZE_BYTES(vlen);
+ src = avp->vbp->vbuf;
+ break;
+ default:
+ fprintf(stderr, "add_parameter failed: bad type (%d)\n", type);
+ exit(1);
+ }
+ if ((sts = check_buf(need)) < 0) {
+ fprintf(stderr, "add_parameter failed: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ epp = (pmEventParameter *)eptr;
+ epp->ep_pmid = pmid;
+ epp->ep_len = PM_VAL_HDR_SIZE + vlen;
+ epp->ep_type = type;
+ memcpy((void *)(eptr + sizeof(pmEventParameter)), src, vlen);
+ eptr += need;
+ hrerp->er_nparams++;
+ return 0;
+}
+
+static void
+reset(void)
+{
+ eptr = ebuf;
+ hreap = (pmHighResEventArray *)eptr;
+ hreap->ea_nrecords = 0;
+ eptr += sizeof(pmHighResEventArray) - sizeof(pmHighResEventRecord);
+ vs.numval = 1;
+ vs.valfmt = PM_VAL_DPTR;
+ vs.vlist[0].inst = PM_IN_NULL;
+}
+
+static int
+add_record(struct timespec *ts, int flags)
+{
+ int sts;
+ size_t size = sizeof(pmHighResEventRecord) - sizeof(pmEventParameter);
+
+ if ((sts = check_buf(size)) < 0) {
+ fprintf(stderr, "add_record failed: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ hreap->ea_nrecords++;
+ hrerp = (pmHighResEventRecord *)eptr;
+ hrerp->er_timestamp.tv_sec = (__int64_t)ts->tv_sec;
+ hrerp->er_timestamp.tv_nsec = (__int64_t)ts->tv_nsec;
+ hrerp->er_nparams = 0;
+ hrerp->er_flags = flags;
+ eptr += sizeof(pmHighResEventRecord) - sizeof(pmEventParameter);
+ return 0;
+}
+
+static void
+dump(char *xpect)
+{
+ pmHighResResult **res;
+ int nmissed;
+ int nrecords;
+ int r;
+ int k;
+ static pmID pmid_flags = 0;
+ static pmID pmid_missed;
+
+ fprintf(stderr, "Expecting ... %s\n", xpect);
+
+ for (k = 0; k < vs.numval || vs.numval == PM_ERR_GENERIC; k++) {
+ if (vs.vlist[k].inst != PM_IN_NULL)
+ fprintf(stderr, "[instance %d]\n", vs.vlist[k].inst);
+ nrecords = pmUnpackHighResEventRecords(&vs, k, &res);
+
+ if (nrecords < 0) {
+ fprintf(stderr, "pmUnpackHighResEventRecords: %s\n",
+ pmErrStr(nrecords));
+ return;
+ }
+
+ /* lifted from pminfo.c */
+ if (pmid_flags == 0) {
+ /*
+ * get PMID for event.flags and event.missed
+ * note that pmUnpackHighResEventRecords() will have called
+ * __pmRegisterAnon(), so the anon metrics
+ * should now be in the PMNS
+ */
+ char *name_flags = "event.flags";
+ char *name_missed = "event.missed";
+ int sts;
+ sts = pmLookupName(1, &name_flags, &pmid_flags);
+ if (sts < 0) {
+ /* should not happen! */
+ fprintf(stderr, "Warning: cannot get PMID for %s: %s\n", name_flags, pmErrStr(sts));
+ /* avoid subsequent warnings ... */
+ __pmid_int(&pmid_flags)->item = 1;
+ }
+ sts = pmLookupName(1, &name_missed, &pmid_missed);
+ if (sts < 0) {
+ /* should not happen! */
+ fprintf(stderr, "Warning: cannot get PMID for %s: %s\n", name_missed, pmErrStr(sts));
+ /* avoid subsequent warnings ... */
+ __pmid_int(&pmid_missed)->item = 1;
+ }
+ }
+
+ nmissed = 0;
+ for (r = 0; r < nrecords; r++) {
+ if (res[r]->numpmid == 2 && res[r]->vset[0]->pmid == pmid_flags &&
+ (res[r]->vset[0]->vlist[0].value.lval & PM_EVENT_FLAG_MISSED) &&
+ res[r]->vset[1]->pmid == pmid_missed) {
+ nmissed += res[r]->vset[1]->vlist[0].value.lval;
+ }
+ }
+
+ fprintf(stderr, "Array contains %d records and %d missed records\n", nrecords, nmissed);
+ if (nrecords == 0)
+ continue;
+
+ for (r = 0; r < nrecords; r++) {
+ fprintf(stderr, "pmHighResResult[%d]\n", r);
+ __pmDumpHighResResult(stderr, res[r]);
+ }
+ pmFreeHighResEventResult(res);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int errflag = 0;
+ int sts;
+ int c;
+ struct timespec stamp;
+ pmAtomValue atom;
+ int savelen;
+ pmEventParameter *epp;
+/* === begin largely copied from samplepmda events.c === */
+ static pmValueBlock *aggr;
+ static char aggrval[] = { '\01', '\03', '\07', '\017', '\037', '\077', '\177', '\377' };
+ pmID pmid_array = PMDA_PMID(4095,0); /* event.highres_records */
+ pmID pmid_type = PMDA_PMID(0,127); /* event.type */
+ pmID pmid_32 = PMDA_PMID(0,128); /* event.param_32 */
+ pmID pmid_u32 = PMDA_PMID(0,129); /* event.param_u32 */
+ pmID pmid_64 = PMDA_PMID(0,130); /* event.param_64 */
+ pmID pmid_u64 = PMDA_PMID(0,131); /* event.param_u64 */
+ pmID pmid_float = PMDA_PMID(0,132); /* event.param_float */
+ pmID pmid_double = PMDA_PMID(0,133); /* event.param_double */
+ pmID pmid_string = PMDA_PMID(0,134); /* event.param_string */
+ pmID pmid_aggregate = PMDA_PMID(0,135); /* event.param_string */
+
+ /* first time, punt on a 512 byte buffer */
+ ebuflen = 512;
+ ebuf = eptr = (char *)malloc(ebuflen);
+ if (ebuf == NULL) {
+ fprintf(stderr, "initial ebuf malloc failed: %s\n", strerror(errno));
+ exit(1);
+ }
+ ebufend = &ebuf[ebuflen-1];
+ /*
+ * also, fix the domain field in the event parameter PMIDs ...
+ * note these PMIDs must match the corresponding metrics in
+ * desctab[] and this cannot easily be done automatically
+ */
+ ((__pmID_int *)&pmid_array)->domain = mydomain;
+ ((__pmID_int *)&pmid_type)->domain = mydomain;
+ ((__pmID_int *)&pmid_32)->domain = mydomain;
+ ((__pmID_int *)&pmid_u32)->domain = mydomain;
+ ((__pmID_int *)&pmid_64)->domain = mydomain;
+ ((__pmID_int *)&pmid_u64)->domain = mydomain;
+ ((__pmID_int *)&pmid_float)->domain = mydomain;
+ ((__pmID_int *)&pmid_double)->domain = mydomain;
+ ((__pmID_int *)&pmid_string)->domain = mydomain;
+ ((__pmID_int *)&pmid_aggregate)->domain = mydomain;
+ /* build pmValueBlock for aggregate value */
+ aggr = (pmValueBlock *)malloc(PM_VAL_HDR_SIZE + sizeof(aggrval));
+ aggr->vtype = PM_TYPE_AGGREGATE;
+ aggr->vlen = PM_VAL_HDR_SIZE + sizeof(aggrval);
+ memcpy(aggr->vbuf, (void *)aggrval, sizeof(aggrval));
+
+/* === end copied from samplepmda events.c === */
+
+ vs.pmid = pmid_array;
+ vs.numval = 1;
+ vs.valfmt = PM_VAL_DPTR;
+ vs.vlist[0].inst = PM_IN_NULL;
+ vs.vlist[0].value.pval = (pmValueBlock *)ebuf;
+
+ __pmSetProgname(argv[0]);
+
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s ...\n", pmProgname);
+ fprintf(stderr, "options:\n");
+ fprintf(stderr, "-D debug\n");
+ exit(1);
+ }
+
+ reset();
+ __pmGetTimespec(&stamp);
+ /* rebase event records 10 secs in past, add 1 sec for each new record */
+ stamp.tv_sec -= 10;
+
+ hreap->ea_type = 0;
+ hreap->ea_len = 0;
+ dump("Unknown or illegal metric type");
+ hreap->ea_type = PM_TYPE_HIGHRES_EVENT;
+
+ hreap->ea_nrecords = -1;
+ hreap->ea_len = eptr - ebuf;
+ dump("Error - ea_nrecords < 0");
+ hreap->ea_nrecords = 0;
+
+ hreap->ea_len = PM_VAL_HDR_SIZE;
+ dump("Error - vlen way too small");
+
+ hreap->ea_len = eptr - ebuf;
+ dump("No records");
+
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ hreap->ea_len = eptr - ebuf;
+ dump("1 record, no params");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 1;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ hreap->ea_len = eptr - ebuf;
+ dump("1 record, u32 param = 1");
+
+ reset();
+ add_record(&stamp, 1);
+ stamp.tv_sec++;
+ atom.ul = 2;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.ll = -3;
+ add_param(pmid_64, PM_TYPE_64, &atom);
+ hreap->ea_len = eptr - ebuf;
+ dump("1 record, u32 param = 2, u64 param = -3");
+ hreap->ea_len--;
+ dump("Error - buffer overrun @ parameter");
+
+ reset();
+ add_record(&stamp, PM_EVENT_FLAG_MISSED);
+ stamp.tv_sec++;
+ hrerp->er_nparams = 3;
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 4;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.ull = 5;
+ add_param(pmid_u64, PM_TYPE_U64, &atom);
+ atom.cp = "6";
+ add_param(pmid_string, PM_TYPE_STRING, &atom);
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 7;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.d = 8;
+ add_param(pmid_double, PM_TYPE_DOUBLE, &atom);
+ atom.d = -9;
+ add_param(pmid_double, PM_TYPE_DOUBLE, &atom);
+ add_record(&stamp, 2);
+ stamp.tv_sec++;
+ atom.ul = 10;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.ull = 11;
+ add_param(pmid_u64, PM_TYPE_U64, &atom);
+ atom.cp = "twelve";
+ add_param(pmid_string, PM_TYPE_STRING, &atom);
+ atom.cp = "thirteen";
+ add_param(pmid_string, PM_TYPE_STRING, &atom);
+ atom.l = 14;
+ add_param(pmid_32, PM_TYPE_32, &atom);
+ atom.ul = 15;
+ add_param(pmid_u32, PM_TYPE_U32, &atom);
+ add_record(&stamp, PM_EVENT_FLAG_MISSED);
+ stamp.tv_sec++;
+ hrerp->er_nparams = 4;
+ savelen = eptr - ebuf;
+ add_record(&stamp,0);
+ stamp.tv_sec++;
+ atom.ul = 16;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.f = -17;
+ add_param(pmid_float, PM_TYPE_FLOAT, &atom);
+ atom.vbp = aggr;
+ add_param(pmid_aggregate, PM_TYPE_AGGREGATE, &atom);
+ hreap->ea_len = eptr - ebuf;
+ dump("6 records, 7 missed [u32=4 u64=5 str=\"6\"][u32=7 d=8 d=-9][u32=10 u64=11 str=\"twelve\" str=\"thirteen\" 32=-14 u32=15][u32=16 f=-17 aggr=...]");
+
+ hreap->ea_len = savelen;
+ dump("Error - buffer overrun @ record");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 1;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ hreap->ea_len = eptr - ebuf;
+ vs.numval = PM_ERR_GENERIC;
+ dump("bad numval");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 1;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ hreap->ea_len = eptr - ebuf;
+ vs.valfmt = 42;
+ dump("bad valfmt");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 1;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ hreap->ea_len = eptr - ebuf;
+ vs.vlist[0].inst = 42;
+ dump("odd instance");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.vbp = aggr;
+ epp = (pmEventParameter *)eptr;
+ add_param(pmid_aggregate, PM_TYPE_AGGREGATE, &atom);
+ epp->ep_type = PM_TYPE_HIGHRES_EVENT;
+ hreap->ea_len = eptr - ebuf;
+ dump("1 record, nested event type @ 1st parameter");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 18;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 19;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.vbp = aggr;
+ epp = (pmEventParameter *)eptr;
+ add_param(pmid_aggregate, PM_TYPE_AGGREGATE, &atom);
+ epp->ep_type = PM_TYPE_HIGHRES_EVENT;
+ atom.ul = 20;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 21;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ hreap->ea_len = eptr - ebuf;
+ dump("3 records, nested event type @ 2nd parameter of 2nd record");
+
+ printf("\n");
+ printf("__pmDumpHighResEventRecords coverage test ...\n");
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.l = 22;
+ add_param(pmid_type, PM_TYPE_32, &atom);
+ atom.ul = 23;
+ add_param(pmid_u32, PM_TYPE_U32, &atom);
+ atom.ll = -24;
+ add_param(pmid_64, PM_TYPE_64, &atom);
+ atom.ull = 25;
+ add_param(pmid_u64, PM_TYPE_U64, &atom);
+ atom.f = -26;
+ add_param(pmid_float, PM_TYPE_FLOAT, &atom);
+ atom.d = 27;
+ add_param(pmid_double, PM_TYPE_DOUBLE, &atom);
+ atom.cp = "minus twenty-eight";
+ add_param(pmid_string, PM_TYPE_STRING, &atom);
+ atom.vbp = aggr;
+ add_param(pmid_aggregate, PM_TYPE_AGGREGATE, &atom);
+ add_param(pmid_aggregate, PM_TYPE_AGGREGATE_STATIC, &atom);
+ epp = (pmEventParameter *)eptr;
+ atom.l = 29;
+ add_param(pmid_32, PM_TYPE_32, &atom);
+ hreap->ea_len = eptr - ebuf;
+ pmDebug |= DBG_TRACE_FETCH;
+ dump("all good");
+ epp->ep_type = PM_TYPE_UNKNOWN;
+ __pmDumpHighResEventRecords(stdout, &vs, 0);
+
+ return 0;
+}
diff --git a/qa/src/import_limit_test.perl b/qa/src/import_limit_test.perl
new file mode 100644
index 0000000..6cafbc2
--- /dev/null
+++ b/qa/src/import_limit_test.perl
@@ -0,0 +1,72 @@
+#
+# Copyright (c) Red Hat.
+#
+# Thanks to Marko Myllynen for writing this test case, and
+# neatly exposing the underlying bug (Fedora/EPEL 968210).
+#
+
+use strict;
+use warnings;
+use Date::Parse;
+use Date::Format;
+use PCP::LogImport;
+
+my $r;
+my $LOW = 1020;
+my $HIGH = 1030;
+my $date = "2013-05-29T00:00:00";
+
+pmiStart("test-limit", 0);
+exit 1 if pmiSetHostname("localhost");
+
+for (my $i = 0; $i < $LOW; $i++) {
+ my $metric = "x_$i";
+ $r = pmiAddMetric($metric,
+ PM_ID_NULL, PM_TYPE_DOUBLE, PM_INDOM_NULL,
+ PM_SEM_INSTANT, pmiUnits(0,0,1,0,0,PM_COUNT_ONE));
+ if ($r != 0) {
+ print "pmiAddMetric failed for $metric / round $i with: ";
+ print pmiErrStr($r) . "\n";
+ exit 2;
+ }
+ $r = pmiPutValue($metric, "", $i);
+ if ($r != 0) {
+ print "pmiPutValue failed for $metric / round $i with: ";
+ print pmiErrStr($r) . "\n";
+ exit 3;
+ }
+}
+
+for (my $j = $LOW; $j < $HIGH; $j++) {
+ my $metric = "t_$j";
+ pmiAddMetric($metric,
+ PM_ID_NULL, PM_TYPE_DOUBLE, PM_INDOM_NULL,
+ PM_SEM_INSTANT, pmiUnits(0,0,1,0,0,PM_COUNT_ONE));
+ if ($r != 0) {
+ print "pmiAddMetric failed for $metric / round $j with: ";
+ print pmiErrStr($r) . "\n";
+ exit 4;
+ }
+ pmiPutValue($metric, "", $j);
+ if ($r != 0) {
+ print "pmiPutValue failed for $metric / round $j with: ";
+ print pmiErrStr($r) . "\n";
+ exit 5;
+ }
+}
+
+$r = pmiWrite(str2time($date, "UTC"), 0);
+if ($r != 0) {
+ print "pmiWrite failed for $date / " . str2time($date, "UTC") . " with: ";
+ print pmiErrStr($r) . "\n";
+ exit 6;
+}
+
+pmiEnd();
+if ($r != 0) {
+ print "pmiEnd failed with: ";
+ print pmiErrStr($r) . "\n";
+ exit 7;
+}
+
+exit 0;
diff --git a/qa/src/import_limit_test.pl b/qa/src/import_limit_test.pl
new file mode 120000
index 0000000..98daf24
--- /dev/null
+++ b/qa/src/import_limit_test.pl
@@ -0,0 +1 @@
+import_limit_test.perl \ No newline at end of file
diff --git a/qa/src/indom.c b/qa/src/indom.c
new file mode 100644
index 0000000..273c846
--- /dev/null
+++ b/qa/src/indom.c
@@ -0,0 +1,310 @@
+/*
+ * indom - exercise pmGetInDom, pmNameInDom and pmLookupInDom
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int type;
+static int inst;
+
+int
+dometric(char *name)
+{
+ pmID pmid;
+ pmDesc desc;
+ int sts;
+ char *iname;
+ int *ilist;
+ char **nlist;
+
+ if ((sts = pmLookupName(1, &name, &pmid)) < 0)
+ return sts;
+
+ if ((sts = pmLookupDesc(pmid, &desc)) < 0)
+ return sts;
+
+ iname = "no match";
+ printf("pm*InDom: inst=[%d]", inst);
+ if ((sts = pmNameInDom(desc.indom, inst, &iname)) < 0)
+ printf(" {%s}\n", pmErrStr(sts));
+ else {
+ printf(" iname=<%s> reverse lookup:", iname);
+ if ((sts = pmLookupInDom(desc.indom, iname)) < 0)
+ printf(" {%s}\n", pmErrStr(sts));
+ else
+ printf(" inst=[%d]\n", sts);
+ }
+ if (type == PM_CONTEXT_ARCHIVE) {
+ iname = "no match";
+ printf("pm*InDomArchive: inst=[%d]", inst);
+ if ((sts = pmNameInDomArchive(desc.indom, inst, &iname)) < 0)
+ printf(" {%s}\n", pmErrStr(sts));
+ else {
+ printf(" iname=<%s> reverse lookup:", iname);
+ if ((sts = pmLookupInDomArchive(desc.indom, iname)) < 0)
+ printf(" {%s}\n", pmErrStr(sts));
+ else
+ printf(" inst=[%d]\n", sts);
+ }
+ }
+
+ if ((sts = pmGetInDom(desc.indom, &ilist, &nlist)) < 0)
+ printf("pmGetInDom: {%s}\n", pmErrStr(sts));
+ else {
+ int i;
+ printf("pmGetInDom:\n");
+ for (i = 0; i < sts; i++) {
+ if (ilist[i] == inst) {
+ printf(" [%d] <%s>\n", ilist[i], nlist[i]);
+ break;
+ }
+ }
+ free(ilist);
+ free(nlist);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetInDomArchive(desc.indom, &ilist, &nlist)) < 0)
+ printf("pmGetInDomArchive: {%s}\n", pmErrStr(sts));
+ else {
+ int i;
+ printf("pmGetInDomArchive:\n");
+ for (i = 0; i < sts; i++) {
+ if (i == inst) {
+ printf(" [%d] <%s>\n", ilist[i], nlist[i]);
+ break;
+ }
+ }
+ free(ilist);
+ free(nlist);
+ }
+ }
+
+ return sts;
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int force = 0;
+ int verbose = 0;
+ char *host = NULL; /* pander to gcc */
+ char *configfile = (char *)0;
+ char *logfile = (char *)0;
+ pmLogLabel label; /* get hostname for archives */
+ int zflag = 0; /* for -z */
+ char *tz = (char *)0; /* for -Z timezone */
+ int tzh; /* initial timezone handle */
+ char local[MAXHOSTNAMELEN];
+ char *namespace = PM_NS_DEFAULT;
+ int samples = -1;
+ double delta = 1.0;
+ char *endnum;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:c:D:fh:i:l:n:s:t:VzZ:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'c': /* configfile */
+ if (configfile != (char *)0) {
+ fprintf(stderr, "%s: at most one -c option allowed\n", pmProgname);
+ errflag++;
+ }
+ configfile = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'f': /* force */
+ force++;
+ break;
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'i': /* instance */
+ inst = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || inst < 0) {
+ fprintf(stderr, "%s: -i requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'l': /* logfile */
+ logfile = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples < 0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 't': /* delta seconds (double) */
+ delta = strtod(optarg, &endnum);
+ if (*endnum != '\0' || delta <= 0.0) {
+ fprintf(stderr, "%s: -t requires floating point argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'V': /* verbose */
+ verbose++;
+ break;
+
+ case 'z': /* timezone from host */
+ if (tz != (char *)0) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ zflag++;
+ break;
+
+ case 'Z': /* $TZ timezone */
+ if (zflag) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ tz = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (zflag && type == 0) {
+ fprintf(stderr, "%s: -z requires an explicit -a or -h option\n", pmProgname);
+ errflag++;
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -c configfile file to load configuration from\n\
+ -D debug standard PCP debug flag\n\
+ -f force .. \n\
+ -h host metrics source is PMCD on host\n\
+ -l logfile redirect diagnostics and trace output\n\
+ -n namespace use an alternative PMNS\n\
+ -s samples terminate after this many iterations\n\
+ -t delta sample interval in seconds(float) [default 1.0]\n\
+ -V verbose/diagnostic output\n\
+ -z set reporting timezone to local time for host from -a or -h\n\
+ -Z timezone set reporting timezone\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (logfile != (char *)0) {
+ __pmOpenLog(pmProgname, logfile, stderr, &sts);
+ if (sts < 0) {
+ fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmProgname, logfile);
+ }
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ if (zflag) {
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+ if (type == PM_CONTEXT_ARCHIVE)
+ printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n",
+ label.ll_hostname);
+ else
+ printf("Note: timezone set to local timezone of host \"%s\"\n\n", host);
+ }
+ else if (tz != (char *)0) {
+ if ((tzh = pmNewZone(tz)) < 0) {
+ fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n",
+ pmProgname, tz, pmErrStr(tzh));
+ exit(1);
+ }
+ printf("Note: timezone set to \"TZ=%s\"\n\n", tz);
+ }
+ else
+ tzh = pmNewContextZone();
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ while (optind < argc) {
+ printf("%s:\n", argv[optind]);
+ sts = dometric(argv[optind]);
+ if (sts < 0)
+ printf("Error: %s\n", pmErrStr(sts));
+ optind++;
+ }
+
+ exit(0);
+}
diff --git a/qa/src/interp0.c b/qa/src/interp0.c
new file mode 100644
index 0000000..badd07c
--- /dev/null
+++ b/qa/src/interp0.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * interp0 - basic PM_MODE_INTERP exercises
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int j;
+ double tdiff;
+ int errflag = 0;
+ int ahtype = 0;
+ char *host = NULL; /* pander to gcc */
+ pmLogLabel label; /* get hostname for archives */
+ char *namespace = PM_NS_DEFAULT;
+ int samples = 10;
+ double delta = 1.0;
+ int msec;
+ char *endnum;
+ pmResult *result;
+ pmResult *prev = (pmResult *)0;
+ int i;
+ int numpmid = 3;
+ pmID pmid[3];
+ char *name[] = { "sample.seconds", "sample.drift", "sample.milliseconds" };
+ pmDesc desc;
+ int type[3];
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:n:s:t:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (ahtype != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ ahtype = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples < 0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 't': /* delta seconds (double) */
+ delta = strtod(optarg, &endnum);
+ if (*endnum != '\0' || delta <= 0.0) {
+ fprintf(stderr, "%s: -t requires floating point argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -D debug standard PCP debug flag\n\
+ -n namespace use an alternative PMNS\n\
+ -s samples terminate after this many iterations\n\
+ -t delta sample interval in seconds(float) [default 1.0]\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (namespace != PM_NS_DEFAULT) {
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ if (ahtype != PM_CONTEXT_ARCHIVE) {
+ fprintf(stderr, "%s: -a is not optional!\n", pmProgname);
+ exit(1);
+ }
+ if ((sts = pmNewContext(ahtype, host)) < 0) {
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ if (optind < argc) {
+ numpmid = 0;
+ while (optind < argc && numpmid < 3) {
+ name[numpmid] = argv[optind];
+ printf("metric[%d]: %s\n", numpmid, name[numpmid]);
+ optind++;
+ numpmid++;
+ }
+ }
+
+ /* skip preamble */
+ sts = pmFetchArchive(&result);
+ if (sts < 0) {
+ printf("pmFetchArchive: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ pmFreeResult(result);
+
+ sts = pmFetchArchive(&result);
+ if (sts < 0) {
+ printf("pmFetchArchive: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+
+ msec = delta * 1000;
+ sts = pmSetMode(PM_MODE_INTERP, &result->timestamp, msec);
+ if (sts < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ pmFreeResult(result);
+
+ sts = pmLookupName(numpmid, name, pmid);
+ if (sts < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ for (i = 0; i < numpmid; i++) {
+ sts = pmLookupDesc(pmid[i], &desc);
+ if (sts < 0) {
+ printf("Warning: pmLookupDesc(%s): %s\n", name[i], pmErrStr(sts));
+ type[i] = -1;
+ }
+ else
+ type[i] = desc.type;
+ }
+
+ for (i = 0; i < samples; i++) {
+ sts = pmFetch(numpmid, pmid, &result);
+ if (sts < 0) {
+ printf("sample[%d] pmFetch: %s\n", i, pmErrStr(sts));
+ if (sts == PM_ERR_EOL)
+ break;
+ printf("... this is unexpected and fatal!\n");
+ exit(1);
+ }
+ if (prev) {
+ tdiff = result->timestamp.tv_sec - prev->timestamp.tv_sec +
+ (double)(result->timestamp.tv_usec - prev->timestamp.tv_usec) / 1000000;
+ printf("\nsample %d, delta time=%.3f secs\n", i, tdiff);
+ for (j = 0; j < numpmid; j++) {
+ printf("%s: ", name[j]);
+ if (result->vset[j]->numval != 1 || prev->vset[j]->numval != 1) {
+ if (result->vset[j]->numval == 0)
+ printf("no current values ");
+ if (prev->vset[j]->numval == 0)
+ printf("no prior values ");
+ if (result->vset[j]->numval < 0)
+ printf("current error %s ", pmErrStr(result->vset[j]->numval));
+ if (prev->vset[j]->numval < 0 && prev->vset[j]->numval != result->vset[j]->numval)
+ printf("prior error %s ", pmErrStr(prev->vset[j]->numval));
+ putchar('\n');
+ }
+ else {
+ if (type[j] == PM_TYPE_32 || type[j] == PM_TYPE_U32) {
+ printf("delta: %d\n",
+ result->vset[j]->vlist[0].value.lval -
+ prev->vset[j]->vlist[0].value.lval);
+ }
+ else if (type[j] == PM_TYPE_DOUBLE) {
+ void *cp = (void *)result->vset[j]->vlist[0].value.pval->vbuf;
+ void *pp = (void *)prev->vset[j]->vlist[0].value.pval->vbuf;
+ double cv, pv;
+ pmAtomValue av;
+
+ memcpy((void *)&av, cp, sizeof(pmAtomValue));
+ cv = av.d;
+ memcpy((void *)&av, pp, sizeof(pmAtomValue));
+ pv = av.d;
+ printf("delta: %.0f\n",
+ cv - pv);
+ }
+ else if (type[j] == PM_TYPE_EVENT) {
+ pmResult **records;
+ int r, param;
+
+ printf("%d event records found\n", result->vset[j]->numval);
+ sts = pmUnpackEventRecords(result->vset[j], 0, &records);
+ if (sts < 0) {
+ printf("event decode error: %s\n", pmErrStr(sts));
+ } else {
+ for (r = 0; r < sts; r++) {
+ tdiff = records[r]->timestamp.tv_sec - prev->timestamp.tv_sec + (double)
+ (records[r]->timestamp.tv_usec - prev->timestamp.tv_usec) / 1000000;
+ printf("\nevent %d, offset time=%.3f secs, param ids:", j+1, tdiff);
+ for (param = 0; param < records[r]->numpmid; param++)
+ printf(" %s", pmIDStr(records[r]->vset[param]->pmid));
+ }
+ pmFreeEventResult(records);
+ putchar('\n');
+ }
+ }
+ else if (type[j] == PM_TYPE_HIGHRES_EVENT) {
+ pmHighResResult **hrecords;
+ int r, param;
+
+ printf("%d highres event records found\n", result->vset[j]->numval);
+ sts = pmUnpackHighResEventRecords(result->vset[j], 0, &hrecords);
+ if (sts < 0) {
+ printf("highres event decode error: %s\n", pmErrStr(sts));
+ } else {
+ for (r = 0; r < sts; r++) {
+ tdiff = hrecords[r]->timestamp.tv_sec - prev->timestamp.tv_sec + (double)
+ (hrecords[r]->timestamp.tv_nsec - prev->timestamp.tv_usec * 1000)
+ / 1000000000;
+ printf("\nhighres event %d, offset time=%.9f secs, param ids:", j+1, tdiff);
+ for (param = 0; param < hrecords[r]->numpmid; param++)
+ printf(" %s", pmIDStr(hrecords[r]->vset[param]->pmid));
+ }
+ pmFreeHighResEventResult(hrecords);
+ putchar('\n');
+ }
+ }
+ else
+ printf("don't know how to display type %d for PMID %s\n",
+ type[j], pmIDStr(pmid[j]));
+ }
+ }
+ pmFreeResult(prev);
+ }
+ prev = result;
+ }
+
+ printf("\n%d samples required %d log reads\n", i, __pmLogReads);
+
+ exit(0);
+}
diff --git a/qa/src/interp1.c b/qa/src/interp1.c
new file mode 100644
index 0000000..7a6d84b
--- /dev/null
+++ b/qa/src/interp1.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * interp1 - backward PM_MODE_INTERP exercises
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int j;
+ int k;
+ double tdiff;
+ int dflag = 0;
+ int errflag = 0;
+ int ahtype = 0;
+ char *host = NULL; /* pander to gcc */
+ pmLogLabel label; /* get hostname for archives */
+ char *namespace = PM_NS_DEFAULT;
+ int samples = 10;
+ double delta = 1.0;
+ int msec;
+ char *endnum;
+ pmResult *result;
+ pmResult *prev = (pmResult *)0;
+ int i;
+ int numpmid = 3;
+ pmID pmid[3];
+ char *name[] = { "sample.seconds", "sample.drift", "sample.milliseconds" };
+ pmDesc desc[3];
+ struct timeval tend = {0x7fffffff, 0};
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:dn:s:t:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (ahtype != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ ahtype = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'd': /* use metric descriptor to decide on rate conversion */
+ dflag++;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples < 0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 't': /* delta seconds (double) */
+ delta = strtod(optarg, &endnum);
+ if (*endnum != '\0' || delta <= 0.0) {
+ fprintf(stderr, "%s: -t requires floating point argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -d use metric descriptors to decide on value or delta\n\
+ -D debug standard PCP debug flag\n\
+ -n namespace use an alternative PMNS\n\
+ -s samples terminate after this many iterations\n\
+ -t delta sample interval in seconds(float) [default 1.0]\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (ahtype == 0) {
+ fprintf(stderr, "%s: -a is not optional!\n", pmProgname);
+ exit(1);
+ }
+ if ((sts = pmNewContext(ahtype, host)) < 0) {
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ if (optind < argc) {
+ numpmid = 0;
+ while (optind < argc && numpmid < 3) {
+ name[numpmid] = argv[optind];
+ printf("metric[%d]: %s\n", numpmid, name[numpmid]);
+ optind++;
+ numpmid++;
+ }
+ }
+
+ sts = pmSetMode(PM_MODE_BACK, &tend, 0);
+ if (sts < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ sts = pmFetchArchive(&result);
+ if (sts < 0) {
+ printf("pmFetchArchive: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ msec = -delta * 1000;
+ sts = pmSetMode(PM_MODE_INTERP, &result->timestamp, msec);
+ if (sts < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ pmFreeResult(result);
+
+ sts = pmLookupName(numpmid, name, pmid);
+ if (sts < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ for (i = 0; i < numpmid; i++) {
+ sts = pmLookupDesc(pmid[i], &desc[i]);
+ if (sts < 0) {
+ printf("Warning: pmLookupDesc(%s): %s\n", pmIDStr(pmid[i]), pmErrStr(sts));
+ desc[i].type = -1;
+ }
+ }
+
+ for (i = 0; i < samples; i++) {
+ sts = pmFetch(numpmid, pmid, &result);
+ if (sts < 0) {
+ printf("sample[%d] pmFetch: %s\n", i, pmErrStr(sts));
+ break;
+ }
+ if (prev) {
+ tdiff = result->timestamp.tv_sec - prev->timestamp.tv_sec +
+ (double)(result->timestamp.tv_usec - prev->timestamp.tv_usec) / 1000000;
+ printf("\nsample %d, delta time=%.3f secs\n", i, tdiff);
+ for (j = 0; j < numpmid; j++) {
+ printf("%s: ", name[j]);
+ if (result->vset[j]->numval == 0)
+ printf("no current values ");
+ if (prev->vset[j]->numval == 0)
+ printf("no prior values ");
+ if (result->vset[j]->numval < 0)
+ printf("current error %s ", pmErrStr(result->vset[j]->numval));
+ if (prev->vset[j]->numval < 0 && prev->vset[j]->numval != result->vset[j]->numval)
+ printf("prior error %s ", pmErrStr(prev->vset[j]->numval));
+ putchar('\n');
+ for (k = 0; k < prev->vset[j]->numval && k < result->vset[j]->numval; k++) {
+ if (result->vset[j]->vlist[k].inst != prev->vset[j]->vlist[k].inst) {
+ printf("inst[%d]: mismatch, prior=%d, current=%d\n", k,
+ prev->vset[j]->vlist[k].inst,
+ result->vset[j]->vlist[k].inst);
+ continue;
+ }
+ if (desc[j].type == PM_TYPE_32 || desc[j].type == PM_TYPE_U32) {
+ if (!dflag || desc[j].sem == PM_SEM_COUNTER)
+ printf("delta[%d]: %d\n", k,
+ result->vset[j]->vlist[k].value.lval -
+ prev->vset[j]->vlist[k].value.lval);
+ else
+ printf("value[%d]: %d\n", k,
+ result->vset[j]->vlist[k].value.lval);
+ }
+ else if (desc[j].type == PM_TYPE_DOUBLE) {
+ void *cp = (void *)result->vset[j]->vlist[k].value.pval->vbuf;
+ void *pp = (void *)prev->vset[j]->vlist[k].value.pval->vbuf;
+ double cv, pv;
+ pmAtomValue av;
+
+ memcpy((void *)&av, cp, sizeof(pmAtomValue));
+ cv = av.d;
+ if (!dflag || desc[j].sem == PM_SEM_COUNTER) {
+ memcpy((void *)&av, pp, sizeof(pmAtomValue));
+ pv = av.d;
+ printf("delta[%d]: %.0f\n", k, cv - pv);
+ }
+ else
+ printf("value[%d]: %.0f\n", k, cv);
+ }
+ else if (desc[j].type == PM_TYPE_STRING) {
+ printf("value[%d]: %s\n", k,
+ result->vset[j]->vlist[k].value.pval->vbuf);
+ }
+ else {
+ printf("don't know how to display type %d for PMID %s\n",
+ desc[j].type, pmIDStr(pmid[j]));
+ break;
+ }
+ }
+ }
+ pmFreeResult(prev);
+ }
+ prev = result;
+ }
+
+ printf("\n%d samples required %d log reads\n", i, __pmLogReads);
+
+ exit(0);
+}
diff --git a/qa/src/interp2.c b/qa/src/interp2.c
new file mode 100644
index 0000000..11dff00
--- /dev/null
+++ b/qa/src/interp2.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * interp2 - random offset PM_MODE_INTERP exercises
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static void
+mung(struct timeval *start, struct timeval *end,
+ int pct, struct timeval *mid)
+{
+ __int64_t sec, usec;
+ sec = (50 + pct * (__int64_t)end->tv_sec + (100 - pct) * (__int64_t)start->tv_sec) / 100;
+ usec = (50 + pct * (__int64_t)end->tv_usec + (100 - pct) * (__int64_t)start->tv_usec) / 100;
+ while (usec > 1000000) {
+ usec -= 1000000;
+ sec++;
+ }
+ while (usec < 0) {
+ usec += 1000000;
+ sec--;
+ }
+ mid->tv_sec = sec;
+ mid->tv_usec = usec;
+}
+
+static void
+printstamp(struct timeval *tp)
+{
+ static struct tm *tmp;
+
+ tmp = localtime(&tp->tv_sec);
+ printf("%02d:%02d:%02d.%03d", tmp->tm_hour, tmp->tm_min, tmp->tm_sec, (int)(tp->tv_usec/1000));
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int ahtype = 0;
+ char *host = NULL; /* pander to gcc */
+ pmLogLabel label; /* get hostname for archives */
+ char *namespace = PM_NS_DEFAULT;
+ pmResult *result;
+ struct timeval tend;
+ struct timeval twant;
+ int msec;
+ int forw;
+ int back;
+ int pct;
+ int numpmid = 3;
+ pmID pmid[3];
+ char *name[] = { "sample.seconds", "sample.drift", "sample.milliseconds" };
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:n:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (ahtype != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ ahtype = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -D debug standard PCP debug flag\n\
+ -n namespace use an alternative PMNS\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (ahtype == 0) {
+ fprintf(stderr, "%s: -a is not optional!\n", pmProgname);
+ exit(1);
+ }
+ if ((sts = pmNewContext(ahtype, host)) < 0) {
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ sts = pmGetArchiveEnd(&tend);
+ if (sts < 0) {
+ printf("pmGetArchiveEnd: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ if (optind < argc) {
+ numpmid = 0;
+ while (optind < argc && numpmid < 3) {
+ name[numpmid] = argv[optind];
+ printf("metric[%d]: %s\n", numpmid, name[numpmid]);
+ optind++;
+ numpmid++;
+ }
+ }
+
+ sts = pmLookupName(numpmid, name, pmid);
+ if (sts < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ printf("start: ");
+ printstamp(&label.ll_start);
+ putchar('\n');
+ printf("end: ");
+ printstamp(&tend);
+ putchar('\n');
+ mung(&label.ll_start, &tend, 2, &twant);
+#if 0
+ msec = 1000 * (twant.tv_sec - label.ll_start.tv_sec) +
+ (twant.tv_usec - label.ll_start.tv_usec) / 1000;
+#else
+ msec = 100;
+#endif
+ printf("step: %d msec\n", msec);
+ for (pct = 0; pct <= 100; pct += 10) {
+ __pmLogReads = 0;
+ mung(&label.ll_start, &tend, pct, &twant);
+ printf("%3d%% ", pct);
+ printstamp(&twant);
+ forw = back = 0;
+ sts = pmSetMode(PM_MODE_INTERP, &twant, msec);
+ if (sts < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ while (pmFetch(numpmid, pmid, &result) >= 0) {
+ forw++;
+ pmFreeResult(result);
+ }
+ printf("%4d forw + ", forw);
+ sts = pmSetMode(PM_MODE_INTERP, &twant, -msec);
+ if (sts < 0) {
+ printf("pmSetMode: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ while (pmFetch(numpmid, pmid, &result) >= 0) {
+ back++;
+ pmFreeResult(result);
+ }
+ printf("%4d back = %d, %d log reads\n",
+ back, forw + back, __pmLogReads);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/interp3.c b/qa/src/interp3.c
new file mode 100644
index 0000000..61c7b95
--- /dev/null
+++ b/qa/src/interp3.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * exercise archive-based pmFetch and pmSetMode ops in interpolate mode
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int vflag;
+static int tflag;
+static int numpmid;
+static pmID pmidlist[20];
+static char *namelist[20];
+static double delta = 500;
+
+static void
+cmpres(int n, pmResult *e, pmResult *g)
+{
+ int i;
+ int j;
+ int err = 0;
+
+ if (e->timestamp.tv_sec != g->timestamp.tv_sec ||
+ e->timestamp.tv_usec != g->timestamp.tv_usec) {
+ printf("[sample %d] pmResult.timestamp: expected %ld.%06ld, got %ld.%06ld\n",
+ n, (long)e->timestamp.tv_sec, (long)e->timestamp.tv_usec,
+ (long)g->timestamp.tv_sec, (long)g->timestamp.tv_usec);
+ goto FAILED;
+ }
+ if (e->numpmid != g->numpmid) {
+ printf("[sample %d] pmResult.numpmid: expected %d, got %d\n",
+ n, e->numpmid, g->numpmid);
+ goto FAILED;
+ }
+
+ for (i = 0; i < e->numpmid; i++) {
+ if (e->vset[i]->pmid != g->vset[i]->pmid) {
+ printf("[sample %d] pmResult.vset[%d].pmid: expected %s",
+ n, i, pmIDStr(e->vset[i]->pmid));
+ printf(" got %s\n", pmIDStr(g->vset[i]->pmid));
+ err++;
+ }
+ if (e->vset[i]->numval != g->vset[i]->numval) {
+ printf("[sample %d] pmResult.vset[%d].numval: expected %d, got %d\n",
+ n, i, e->vset[i]->numval, g->vset[i]->numval);
+ err++;
+ continue;
+ }
+ if (e->vset[i]->valfmt != g->vset[i]->valfmt) {
+ printf("[sample %d] pmResult.vset[%d].valfmt: expected %d, got %d\n",
+ n, i, e->vset[i]->valfmt, g->vset[i]->valfmt);
+ err++;
+ continue;
+ }
+ if (e->vset[i]->valfmt != PM_VAL_INSITU)
+ continue;
+ for (j = 0; j < e->vset[i]->numval; j++) {
+ if (e->vset[i]->vlist[j].inst != g->vset[i]->vlist[j].inst) {
+ printf("[sample %d] pmResult.vset[%d].vlist[%d].inst: expected %d, got %d\n",
+ n, i, j, e->vset[i]->vlist[j].inst, g->vset[i]->vlist[j].inst);
+ err++;
+ }
+ if (e->vset[i]->vlist[j].value.lval != g->vset[i]->vlist[j].value.lval) {
+ printf("[sample %d] pmResult.vset[%d].vlist[%d].lval: expected %d, got %d\n",
+ n, i, j, e->vset[i]->vlist[j].value.lval, g->vset[i]->vlist[j].value.lval);
+ err++;
+ }
+ }
+ }
+
+ if (err == 0)
+ return;
+
+FAILED:
+ printf("Expected ...\n");
+ __pmDumpResult(stdout, e);
+ printf("Got ...\n");
+ __pmDumpResult(stdout, g);
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int ctx[2];
+ int errflag = 0;
+ char *archive = "foo";
+ char *namespace = PM_NS_DEFAULT;
+ static char *usage = "[-a archive] [-n namespace] [-T] [-t delta] [-v]";
+ int i;
+ int j;
+ int k;
+ int n;
+ pmLogLabel loglabel;
+ pmResult *resp;
+ pmResult **resvec = (pmResult **)0;
+ int resnum = 0;
+ struct timeval when;
+ int done;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:n:Tt:v")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive */
+ archive = optarg;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'v': /* verbose output */
+ vflag++;
+ break;
+
+ case 'T': /* trim namespace */
+ tflag++;
+ break;
+
+ case 't': /* sample interval */
+ delta = 1000 * atof(optarg);
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((ctx[0] = pmNewContext(PM_CONTEXT_ARCHIVE, archive)) < 0) {
+ printf("%s: Cannot connect to archive \"%s\": %s\n", pmProgname, archive, pmErrStr(ctx[0]));
+ exit(1);
+ }
+ if ((sts = pmGetArchiveLabel(&loglabel)) < 0) {
+ printf("%s: pmGetArchiveLabel(%d): %s\n", pmProgname, ctx[0], pmErrStr(sts));
+ exit(1);
+ }
+
+ when = loglabel.ll_start;
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((ctx[1] = pmDupContext()) < 0) {
+ printf("%s: Cannot dup context to archive \"%s\": %s\n", pmProgname, archive, pmErrStr(ctx[0]));
+ exit(1);
+ }
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ pmUseContext(ctx[0]);
+ if (tflag)
+ pmTrimNameSpace();
+
+ /*
+ * metrics biased towards log "foo"
+ */
+ i = 0;
+ namelist[i++] = "sample.seconds";
+ namelist[i++] = "sample.colour";
+ namelist[i++] = "sample.drift";
+ namelist[i++] = "sample.lights";
+ namelist[i++] = "sampledso.milliseconds";
+ namelist[i++] = "sampledso.bin";
+ numpmid = i;
+
+ sts = pmLookupName(numpmid, namelist, pmidlist);
+ if (sts < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(sts));
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ printf(" %s - not known\n", namelist[i]);
+ }
+ }
+
+ printf("\nPass 1: forward scan\n");
+ __pmLogReads = 0;
+ for (;;) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ resnum++;
+ resvec = (pmResult **)realloc(resvec, resnum * sizeof(resvec[0]));
+ resvec[resnum - 1] = resp;
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "%d pmLogReads\n", __pmLogReads);
+#endif
+ fflush(stderr);
+ printf("Found %d samples\n", resnum);
+ fflush(stdout);
+
+ printf("\nPass 2: backwards scan\n");
+ __pmLogReads = 0;
+ when = resvec[resnum - 1]->timestamp;
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, -delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ n = 0;
+ for (;;) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ n++;
+ cmpres(n, resvec[resnum - n], resp);
+ pmFreeResult(resp);
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "%d pmLogReads\n", __pmLogReads);
+#endif
+ fflush(stderr);
+ printf("Found %d samples\n", n);
+ fflush(stdout);
+
+ printf("\nPass 3: concurrent forwards and backwards scans\n");
+ __pmLogReads = 0;
+ pmUseContext(ctx[0]);
+ when = loglabel.ll_start;
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ pmUseContext(ctx[1]);
+ when = resvec[resnum - 1]->timestamp;
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, -delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ done = 0;
+ n = 0;
+ while (!done) {
+ pmUseContext(ctx[0]);
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ done = 1;
+ }
+ else {
+ n++;
+ cmpres(n, resvec[n/2], resp);
+ pmFreeResult(resp);
+ }
+
+ pmUseContext(ctx[1]);
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ done = 1;
+ }
+ else {
+ n++;
+ cmpres(n, resvec[resnum - n/2], resp);
+ pmFreeResult(resp);
+ }
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "%d pmLogReads\n", __pmLogReads);
+#endif
+ fflush(stderr);
+ printf("Found %d samples\n", n);
+ fflush(stdout);
+
+ printf("\nPass 4: cascading forward scan, 100%%, 75%%, 50%%, 25%%, 0%%\n");
+ pmUseContext(ctx[0]);
+ for (k = 0; k < 5; k++) {
+ __pmLogReads = 0;
+ j = 0;
+ i = ( k * resnum ) / 4;
+ if (i >= resnum)
+ i = resnum - 1;
+ when = resvec[i]->timestamp;
+
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ n = i;
+ for (;;) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ j++;
+ n++;
+ cmpres(j, resvec[n - 1], resp);
+ pmFreeResult(resp);
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "%d pmLogReads\n", __pmLogReads);
+#endif
+ fflush(stderr);
+ printf("Found %d samples\n", j);
+ fflush(stdout);
+ }
+
+ printf("\nPass 5: cascading backward scan, 100%%, 75%%, 50%%, 25%%, 0%%\n");
+ pmUseContext(ctx[0]);
+ for (k = 0; k < 5; k++) {
+ __pmLogReads = 0;
+ j = 0;
+ i = resnum - ( k * resnum ) / 4 - 1;
+ if (i < 0)
+ i = 0;
+ when = resvec[i]->timestamp;
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, -delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ for (;;) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ cmpres(i, resvec[i], resp);
+ pmFreeResult(resp);
+ i--;
+ j++;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "%d pmLogReads\n", __pmLogReads);
+#endif
+ fflush(stderr);
+ printf("Found %d samples\n", j);
+ fflush(stdout);
+ }
+
+ printf("\nPass 6: cascading forward/reverse scan, 100%%, 75%%, 50%%, 25%%, 0%%\n");
+ pmUseContext(ctx[0]);
+ for (k = 4; k >= 0; k--) {
+ __pmLogReads = 0;
+ j = 0;
+ i = ( k * resnum ) / 4;
+ if (i >= resnum)
+ i = resnum - 1;
+
+ when = resvec[0]->timestamp;
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ for (j = 0; j <= i; j++) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ cmpres(j+1, resvec[j], resp);
+ pmFreeResult(resp);
+ }
+
+ when = resvec[i]->timestamp;
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, -delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ for (j = i; j >= 0; j--) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ cmpres(j+1, resvec[j], resp);
+ pmFreeResult(resp);
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "%d pmLogReads\n", __pmLogReads);
+#endif
+ fflush(stderr);
+ printf("Found %d samples\n", i+1);
+ }
+ printf("Pass 6 done\n");
+ fflush(stdout);
+
+ exit(0);
+}
diff --git a/qa/src/interp4.c b/qa/src/interp4.c
new file mode 100644
index 0000000..9c81ceb
--- /dev/null
+++ b/qa/src/interp4.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * EOL and clock advancing in interpolate mode
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int vflag;
+static int tflag;
+static int numpmid;
+static pmID pmidlist[20];
+static char *namelist[20];
+static double delta = 500;
+
+static void
+cmpres(int n, pmResult *e, pmResult *g)
+{
+ int i;
+ int j;
+ int err = 0;
+
+ if (e->timestamp.tv_sec != g->timestamp.tv_sec ||
+ e->timestamp.tv_usec != g->timestamp.tv_usec) {
+ printf("[sample %d] pmResult.timestamp: expected %ld.%06ld, got %ld.%06ld\n",
+ n, (long)e->timestamp.tv_sec, (long)e->timestamp.tv_usec,
+ (long)g->timestamp.tv_sec, (long)g->timestamp.tv_usec);
+ goto FAILED;
+ }
+ if (e->numpmid != g->numpmid) {
+ printf("[sample %d] pmResult.numpmid: expected %d, got %d\n",
+ n, e->numpmid, g->numpmid);
+ goto FAILED;
+ }
+
+ for (i = 0; i < e->numpmid; i++) {
+ if (e->vset[i]->pmid != g->vset[i]->pmid) {
+ printf("[sample %d] pmResult.vset[%d].pmid: expected %s",
+ n, i, pmIDStr(e->vset[i]->pmid));
+ printf(" got %s\n", pmIDStr(g->vset[i]->pmid));
+ err++;
+ }
+ if (e->vset[i]->numval != g->vset[i]->numval) {
+ printf("[sample %d] pmResult.vset[%d].numval: expected %d, got %d\n",
+ n, i, e->vset[i]->numval, g->vset[i]->numval);
+ err++;
+ continue;
+ }
+ if (e->vset[i]->valfmt != g->vset[i]->valfmt) {
+ printf("[sample %d] pmResult.vset[%d].valfmt: expected %d, got %d\n",
+ n, i, e->vset[i]->valfmt, g->vset[i]->valfmt);
+ err++;
+ continue;
+ }
+ if (e->vset[i]->valfmt != PM_VAL_INSITU)
+ continue;
+ for (j = 0; j < e->vset[i]->numval; j++) {
+ if (e->vset[i]->vlist[j].inst != g->vset[i]->vlist[j].inst) {
+ printf("[sample %d] pmResult.vset[%d].vlist[%d].inst: expected %d, got %d\n",
+ n, i, j, e->vset[i]->vlist[j].inst, g->vset[i]->vlist[j].inst);
+ err++;
+ }
+ if (e->vset[i]->vlist[j].value.lval != g->vset[i]->vlist[j].value.lval) {
+ printf("[sample %d] pmResult.vset[%d].vlist[%d].lval: expected %d, got %d\n",
+ n, i, j, e->vset[i]->vlist[j].value.lval, g->vset[i]->vlist[j].value.lval);
+ err++;
+ }
+ }
+ }
+
+ if (err == 0)
+ return;
+
+FAILED:
+ printf("Expected ...\n");
+ __pmDumpResult(stdout, e);
+ printf("Got ...\n");
+ __pmDumpResult(stdout, g);
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int ctx;
+ int errflag = 0;
+ char *archive = "foo";
+ char *namespace = PM_NS_DEFAULT;
+ static char *usage = "[-a archive] [-n namespace] [-T] [-t delta] [-v]";
+ int i;
+ int n;
+ pmLogLabel loglabel;
+ pmResult *resp;
+ pmResult **resvec = (pmResult **)0;
+ int resnum = 0;
+ struct timeval when;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:n:Tt:v")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive */
+ archive = optarg;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'v': /* verbose output */
+ vflag++;
+ break;
+
+ case 'T': /* trim namespace */
+ tflag++;
+ break;
+
+ case 't': /* sample interval */
+ delta = 1000 * atof(optarg);
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((ctx = pmNewContext(PM_CONTEXT_ARCHIVE, archive)) < 0) {
+ printf("%s: Cannot connect to archive \"%s\": %s\n", pmProgname, archive, pmErrStr(ctx));
+ exit(1);
+ }
+ if ((sts = pmGetArchiveLabel(&loglabel)) < 0) {
+ printf("%s: pmGetArchiveLabel(%d): %s\n", pmProgname, ctx, pmErrStr(sts));
+ exit(1);
+ }
+
+ when = loglabel.ll_start;
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (tflag)
+ pmTrimNameSpace();
+
+ /*
+ * metrics biased towards log "foo"
+ */
+ i = 0;
+ namelist[i++] = "sample.seconds";
+ numpmid = i;
+
+ sts = pmLookupName(numpmid, namelist, pmidlist);
+ if (sts < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(sts));
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ printf(" %s - not known\n", namelist[i]);
+ }
+ }
+
+ printf("\nPass 1: forward scan\n");
+ fflush(stdout);
+ for (;;) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ resnum++;
+ resvec = (pmResult **)realloc(resvec, resnum * sizeof(resvec[0]));
+ resvec[resnum - 1] = resp;
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ when = resp->timestamp;
+ }
+ fflush(stderr);
+ printf("Found %d samples\n", resnum);
+
+ printf("\nPass 1.1: forwards past EOL\n");
+ fflush(stdout);
+ for (i = 0; i < 10; i++) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ }
+ when.tv_usec += delta * 1000;
+ if (when.tv_usec > 1000000) {
+ when.tv_sec++;
+ when.tv_usec -= 1000000;
+ }
+ }
+ fflush(stderr);
+
+ printf("\nPass 1.2: backwards past EOL\n");
+ fflush(stdout);
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, -delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ for (i = 0; i < 10; i++) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ }
+ }
+ fflush(stderr);
+
+ printf("\nPass 2: backwards scan\n");
+ fflush(stdout);
+ n = 0;
+ for (;;) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ n++;
+ cmpres(n, resvec[resnum - n], resp);
+ when = resp->timestamp;
+ pmFreeResult(resp);
+ }
+ fflush(stderr);
+ printf("Found %d samples\n", n);
+
+ printf("\nPass 2.1: backwards prior to SOL\n");
+ fflush(stdout);
+ for (i = 0; i < 10; i++) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ } else {
+ pmFreeResult(resp);
+ }
+ when.tv_usec -= delta * 1000;
+ if (when.tv_usec < 0) {
+ when.tv_sec--;
+ when.tv_usec += 1000000;
+ }
+ }
+ fflush(stderr);
+
+ printf("\nPass 2.2: forwards prior to SOL\n");
+ fflush(stdout);
+ if ((sts = pmSetMode(PM_MODE_INTERP, &when, delta)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ for (i = 0; i < 10; i++) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ }
+ }
+ fflush(stderr);
+
+ printf("\nPass 3: forwards scan\n");
+ fflush(stdout);
+ for (n = 0;; n++) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ cmpres(n, resvec[n], resp);
+ pmFreeResult(resvec[n]);
+ pmFreeResult(resp);
+ }
+ fflush(stderr);
+ printf("Found %d samples\n", n);
+ fflush(stdout);
+ free(resvec);
+
+ exit(0);
+}
diff --git a/qa/src/interp_bug.c b/qa/src/interp_bug.c
new file mode 100644
index 0000000..45364e7
--- /dev/null
+++ b/qa/src/interp_bug.c
@@ -0,0 +1,349 @@
+/*
+ * interp_bug - demonstrate archive interpolation mode bug
+ *
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#define N_PMID_A sizeof(metrics_a)/sizeof(metrics_a[0])
+#define N_PMID_B sizeof(metrics_b)/sizeof(metrics_b[0])
+
+static char *metrics_a[] = {
+ "sample.long.one",
+ "kernel.all.syscall"
+};
+
+static char *metrics_b[] = {
+ "sample.long.one",
+ "kernel.all.sysexec"
+};
+
+static pmID pmid_a[N_PMID_A];
+static pmID pmid_b[N_PMID_B];
+
+static void
+printstamp(struct timeval *tp)
+{
+ static struct tm tmp;
+
+ pmLocaltime(&tp->tv_sec, &tmp);
+ printf("%02d:%02d:%02d.%03d", tmp.tm_hour, tmp.tm_min, tmp.tm_sec, (int)(tp->tv_usec/1000));
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ int force = 0;
+ int verbose = 0;
+ char *host = NULL; /* pander to gcc */
+ char *configfile = (char *)0;
+ char *logfile = (char *)0;
+ pmLogLabel label; /* get hostname for archives */
+ int zflag = 0; /* for -z */
+ char *tz = (char *)0; /* for -Z timezone */
+ int tzh; /* initial timezone handle */
+ char local[MAXHOSTNAMELEN];
+ char *namespace = PM_NS_DEFAULT;
+ int samples = -1;
+ int sample;
+ struct timeval start;
+ double delta = 1.0;
+ char *endnum;
+ pmResult *result;
+ int i;
+ int status = 0;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:c:D:fl:n:s:t:VzZ:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'c': /* configfile */
+ if (configfile != (char *)0) {
+ fprintf(stderr, "%s: at most one -c option allowed\n", pmProgname);
+ errflag++;
+ }
+ configfile = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'f': /* force */
+ force++;
+ break;
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'l': /* logfile */
+ logfile = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples < 0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 't': /* delta seconds (double) */
+ delta = strtod(optarg, &endnum);
+ if (*endnum != '\0' || delta <= 0.0) {
+ fprintf(stderr, "%s: -t requires floating point argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'V': /* verbose */
+ verbose++;
+ break;
+
+ case 'z': /* timezone from host */
+ if (tz != (char *)0) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ zflag++;
+ break;
+
+ case 'Z': /* $TZ timezone */
+ if (zflag) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ tz = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (zflag && type == 0) {
+ fprintf(stderr, "%s: -z requires an explicit -a or -h option\n", pmProgname);
+ errflag++;
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -c configfile file to load configuration from\n\
+ -D debug standard PCP debug flag\n\
+ -f force .. \n\
+ -h host metrics source is PMCD on host\n\
+ -l logfile redirect diagnostics and trace output\n\
+ -n namespace use an alternative PMNS\n\
+ -s samples terminate after this many iterations\n\
+ -t delta sample interval in seconds(float) [default 1.0]\n\
+ -V verbose/diagnostic output\n\
+ -z set reporting timezone to local time for host from -a or -h\n\
+ -Z timezone set reporting timezone\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (logfile != (char *)0) {
+ __pmOpenLog(pmProgname, logfile, stderr, &sts);
+ if (sts < 0) {
+ fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmProgname, logfile);
+ }
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ if (zflag) {
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+ if (type == PM_CONTEXT_ARCHIVE)
+ printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n",
+ label.ll_hostname);
+ else
+ printf("Note: timezone set to local timezone of host \"%s\"\n\n", host);
+ }
+ else if (tz != (char *)0) {
+ if ((tzh = pmNewZone(tz)) < 0) {
+ fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n",
+ pmProgname, tz, pmErrStr(tzh));
+ exit(1);
+ }
+ printf("Note: timezone set to \"TZ=%s\"\n\n", tz);
+ }
+ else
+ tzh = pmNewContextZone();
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ while (optind < argc) {
+ printf("extra argument[%d]: %s\n", optind, argv[optind]);
+ optind++;
+ }
+
+ sts = pmLookupName(N_PMID_A, metrics_a, pmid_a);
+ for (i = 0; i < N_PMID_A; i++) {
+ printf("metrics_a[%d]: %s %s\n", i, metrics_a[i], pmIDStr(pmid_a[i]));
+ }
+ if (sts != N_PMID_A) {
+ fprintf(stderr, "%s: pmLookupName: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ sts = pmLookupName(N_PMID_B, metrics_b, pmid_b);
+ for (i = 0; i < N_PMID_B; i++) {
+ printf("metrics_b[%d]: %s %s\n", i, metrics_b[i], pmIDStr(pmid_b[i]));
+ }
+ if (sts != N_PMID_B) {
+ fprintf(stderr, "%s: pmLookupName: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* skip the first two seconds, due to staggered start in log */
+ start = label.ll_start;
+ start.tv_sec += 2;
+
+ printf("Start at: ");
+ printstamp(&start);
+ printf("\n\n");
+
+ printf("Pass One: rewind and fetch metrics_a until end of log\n");
+ if ((sts = pmSetMode(PM_MODE_INTERP, &start, (int)(delta * 1000))) < 0) {
+ fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ for (sample=0; ; sample++) {
+ if ((sts = pmFetch(N_PMID_A, pmid_a, &result)) < 0) {
+ if (sts != PM_ERR_EOL) {
+ fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ status = 1;
+ }
+ break;
+ }
+
+ printf("sample %3d time=", sample);
+ printstamp(&result->timestamp);
+ putchar(' ');
+ if (result->numpmid != N_PMID_A || result->vset[0]->numval != 1) {
+ printf("expected %d (got %d) value sets, with one value in the first.\n",
+ (int)(N_PMID_A), result->numpmid);
+ status = 1;
+ }
+ else {
+ if (result->vset[0]->vlist[0].value.lval != 1) {
+ printf("expected value=1, got value=%d\n", result->vset[0]->vlist[0].value.lval);
+ __pmDumpResult(stdout, result);
+ status = 1;
+ }
+ else
+ printf("correct result\n");
+ }
+ pmFreeResult(result);
+ }
+
+ printf("Pass Two: rewind and fetch metrics_b until end of log\n");
+ if ((sts = pmSetMode(PM_MODE_INTERP, &start, (int)(delta * 1000))) < 0) {
+ fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ for (sample=0; ; sample++) {
+ if ((sts = pmFetch(N_PMID_B, pmid_b, &result)) < 0) {
+ if (sts != PM_ERR_EOL) {
+ fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ status = 1;
+ }
+ break;
+ }
+
+ printf("sample %3d time=", sample);
+ printstamp(&result->timestamp);
+ putchar(' ');
+ if (result->numpmid != N_PMID_B || result->vset[0]->numval != 1) {
+ printf("expected %d (got %d) value sets, with 1 (got %d) value in the first.\n",
+ (int)(N_PMID_B), result->numpmid, result->vset[0]->numval);
+ status = 1;
+ }
+ else {
+ if (result->vset[0]->vlist[0].value.lval != 1) {
+ printf("expected value=1, got value=%d\n", result->vset[0]->vlist[0].value.lval);
+ status = 1;
+ __pmDumpResult(stdout, result);
+ }
+ else
+ printf("correct result\n");
+ }
+ pmFreeResult(result);
+ }
+
+ exit(status);
+}
diff --git a/qa/src/interp_bug2.c b/qa/src/interp_bug2.c
new file mode 100644
index 0000000..30d6c30
--- /dev/null
+++ b/qa/src/interp_bug2.c
@@ -0,0 +1,417 @@
+/*
+ * interp_bug - demonstrate archive interpolation mode bug
+ *
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <unistd.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#define N_PMID_A sizeof(metrics_a)/sizeof(metrics_a[0])
+#define N_PMID_B sizeof(metrics_b)/sizeof(metrics_b[0])
+#define N_PMID_C sizeof(metrics_c)/sizeof(metrics_c[0])
+
+static char *metrics_a[] = {
+ "proc.nprocs",
+};
+
+static char *metrics_b[] = {
+ "proc.nprocs",
+ "kernel.all.syscall"
+};
+
+static char *metrics_c[] = {
+ "proc.nprocs",
+ "kernel.all.sysexec"
+};
+
+static pmID pmid_a[N_PMID_A];
+static pmID pmid_b[N_PMID_B];
+static pmID pmid_c[N_PMID_C];
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ int force = 0;
+ int verbose = 0;
+ char *host = NULL; /* pander to gcc */
+ char *configfile = (char *)0;
+ char *logfile = (char *)0;
+ pmLogLabel label; /* get hostname for archives */
+ int zflag = 0; /* for -z */
+ char *tz = (char *)0; /* for -Z timezone */
+ int tzh; /* initial timezone handle */
+ char local[MAXHOSTNAMELEN];
+ char *namespace = PM_NS_DEFAULT;
+ int samples = -1;
+ int sample;
+ struct timeval start;
+ struct timeval eol;
+ double delta = 1.0;
+ char *endnum;
+ pmResult *result;
+ int i;
+ int status = 0;
+ int done;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:c:D:fl:n:s:t:VzZ:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'c': /* configfile */
+ if (configfile != (char *)0) {
+ fprintf(stderr, "%s: at most one -c option allowed\n", pmProgname);
+ errflag++;
+ }
+ configfile = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'f': /* force */
+ force++;
+ break;
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'l': /* logfile */
+ logfile = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples < 0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 't': /* delta seconds (double) */
+ delta = strtod(optarg, &endnum);
+ if (*endnum != '\0' || delta <= 0.0) {
+ fprintf(stderr, "%s: -t requires floating point argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'V': /* verbose */
+ verbose++;
+ break;
+
+ case 'z': /* timezone from host */
+ if (tz != (char *)0) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ zflag++;
+ break;
+
+ case 'Z': /* $TZ timezone */
+ if (zflag) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ tz = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (zflag && type == 0) {
+ fprintf(stderr, "%s: -z requires an explicit -a or -h option\n", pmProgname);
+ errflag++;
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -c configfile file to load configuration from\n\
+ -D debug standard PCP debug flag\n\
+ -f force .. \n\
+ -h host metrics source is PMCD on host\n\
+ -l logfile redirect diagnostics and trace output\n\
+ -n namespace use an alternative PMNS\n\
+ -s samples terminate after this many iterations\n\
+ -t delta sample interval in seconds(float) [default 1.0]\n\
+ -V verbose/diagnostic output\n\
+ -z set reporting timezone to local time for host from -a or -h\n\
+ -Z timezone set reporting timezone\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (logfile != (char *)0) {
+ __pmOpenLog(pmProgname, logfile, stderr, &sts);
+ if (sts < 0) {
+ fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmProgname, logfile);
+ }
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ pmGetArchiveEnd(&eol);
+ eol.tv_sec -= 1;
+ }
+ else {
+ fprintf(stderr, "%s: must use an archive\n", pmProgname);
+ exit(1);
+ }
+
+ if (zflag) {
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+ if (type == PM_CONTEXT_ARCHIVE)
+ printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n",
+ label.ll_hostname);
+ else
+ printf("Note: timezone set to local timezone of host \"%s\"\n\n", host);
+ }
+ else if (tz != (char *)0) {
+ if ((tzh = pmNewZone(tz)) < 0) {
+ fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n",
+ pmProgname, tz, pmErrStr(tzh));
+ exit(1);
+ }
+ printf("Note: timezone set to \"TZ=%s\"\n\n", tz);
+ }
+ else
+ tzh = pmNewContextZone();
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ while (optind < argc) {
+ printf("extra argument[%d]: %s\n", optind, argv[optind]);
+ optind++;
+ }
+
+
+ if ((sts = pmLookupName(N_PMID_A, metrics_a, pmid_a)) != N_PMID_A) {
+ fprintf(stderr, "%s: pmLookupName: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ for (i = 0; i < N_PMID_A; i++) {
+ printf("metrics_a[%d]: %s %s\n", i, metrics_a[i], pmIDStr(pmid_a[i]));
+ }
+
+ if ((sts = pmLookupName(N_PMID_B, metrics_b, pmid_b)) != N_PMID_B) {
+ fprintf(stderr, "%s: pmLookupName: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ for (i = 0; i < N_PMID_B; i++) {
+ printf("metrics_b[%d]: %s %s\n", i, metrics_b[i], pmIDStr(pmid_b[i]));
+ }
+
+ if ((sts = pmLookupName(N_PMID_C, metrics_c, pmid_c)) != N_PMID_C) {
+ fprintf(stderr, "%s: pmLookupName: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ for (i = 0; i < N_PMID_C; i++) {
+ printf("metrics_c[%d]: %s %s\n", i, metrics_c[i], pmIDStr(pmid_c[i]));
+ }
+
+ /* skip the first two seconds, due to staggered start in log */
+ start = label.ll_start;
+ start.tv_sec += 2;
+
+ printf("Start at: ");
+ __pmPrintStamp(stdout, &start);
+ printf("\n\n");
+
+ printf("Pass One: rewind and fetch metrics_a until end of log\n");
+ if ((sts = pmSetMode(PM_MODE_INTERP, &start, (int)(delta * 1000))) < 0) {
+ fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ done = 0;
+ for (sample=0; !done; sample++) {
+ if ((sts = pmFetch(N_PMID_A, pmid_a, &result)) < 0) {
+ if (sts != PM_ERR_EOL) {
+ fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ status = 1;
+ }
+ break;
+ }
+
+ printf("sample %3d time=", sample);
+ __pmPrintStamp(stdout, &result->timestamp);
+ putchar(' ');
+ if (result->numpmid != N_PMID_A) {
+ printf("Error: expected %d (got %d) value sets\n",
+ (int)(N_PMID_A), (int)result->numpmid);
+ status = 1;
+ }
+ else {
+ if (result->vset[0]->numval != 1) {
+ printf("Error: incorrect number of values\n");
+ __pmDumpResult(stdout, result);
+ status = 1;
+ }
+ else
+ printf("correct result\n");
+ }
+
+ if (result->timestamp.tv_sec >= eol.tv_sec &&
+ result->timestamp.tv_usec > eol.tv_usec)
+ done = 1;
+
+ pmFreeResult(result);
+ }
+
+ printf("Pass Two: rewind and fetch metrics_b until end of log\n");
+ if ((sts = pmSetMode(PM_MODE_INTERP, &start, (int)(delta * 1000))) < 0) {
+ fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ done = 0;
+ for (sample=0; !done; sample++) {
+ if ((sts = pmFetch(N_PMID_B, pmid_b, &result)) < 0) {
+ if (sts != PM_ERR_EOL) {
+ fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ status = 1;
+ }
+ break;
+ }
+
+ printf("sample %3d time=", sample);
+ __pmPrintStamp(stdout, &result->timestamp);
+ putchar(' ');
+ if (result->numpmid != N_PMID_B) {
+ printf("Error: expected %d (got %d) value sets\n",
+ (int)(N_PMID_B), result->numpmid);
+ status = 1;
+ }
+ else {
+ if (result->vset[0]->numval != 1 ||
+ result->vset[1]->numval != 1) {
+ printf("Error: incorrect number of values\n");
+ status = 1;
+ __pmDumpResult(stdout, result);
+ }
+ else
+ printf("correct result\n");
+ }
+
+ if (result->timestamp.tv_sec >= eol.tv_sec &&
+ result->timestamp.tv_usec > eol.tv_usec)
+ done = 1;
+
+ pmFreeResult(result);
+ }
+
+ printf("Pass Three: rewind and fetch metrics_c until end of log\n");
+ if ((sts = pmSetMode(PM_MODE_INTERP, &start, (int)(delta * 1000))) < 0) {
+ fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ done = 0;
+ for (sample=0; !done; sample++) {
+ if ((sts = pmFetch(N_PMID_C, pmid_c, &result)) < 0) {
+ if (sts != PM_ERR_EOL) {
+ fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ status = 1;
+ }
+ break;
+ }
+
+ printf("sample %3d time=", sample);
+ __pmPrintStamp(stdout, &result->timestamp);
+ putchar(' ');
+ if (result->numpmid != N_PMID_C) {
+ printf("Error: expected %d (got %d) value sets\n",
+ (int)(N_PMID_C), result->numpmid);
+ status = 1;
+ }
+ else {
+ if (result->vset[0]->numval != 1 ||
+ result->vset[1]->numval != 1) {
+ printf("Error: incorrect number of values\n");
+ status = 1;
+ __pmDumpResult(stdout, result);
+ }
+ else
+ printf("correct result\n");
+ }
+
+ if (result->timestamp.tv_sec >= eol.tv_sec &&
+ result->timestamp.tv_usec > eol.tv_usec)
+ done = 1;
+
+ pmFreeResult(result);
+ }
+
+ exit(status);
+}
diff --git a/qa/src/interpmark.0 b/qa/src/interpmark.0
new file mode 100644
index 0000000..307a978
--- /dev/null
+++ b/qa/src/interpmark.0
Binary files differ
diff --git a/qa/src/interpmark.index b/qa/src/interpmark.index
new file mode 100644
index 0000000..e4193b2
--- /dev/null
+++ b/qa/src/interpmark.index
Binary files differ
diff --git a/qa/src/interpmark.meta b/qa/src/interpmark.meta
new file mode 100644
index 0000000..3b6a14f
--- /dev/null
+++ b/qa/src/interpmark.meta
Binary files differ
diff --git a/qa/src/iostat b/qa/src/iostat
new file mode 100644
index 0000000..2bc0fa6
--- /dev/null
+++ b/qa/src/iostat
@@ -0,0 +1,26 @@
+Linux 2.6.32-23-generic (bozo) 27/07/10 _i686_ (1 CPU)
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 3.30 0.09 0.94 0.53 0.00 95.14
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 0.53 8.87 7.79 19338695 16980829
+sdb 1.39 26.74 9.00 58264230 19612656
+scd0 0.00 0.01 0.00 21528 0
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 36.12 0.00 22.07 41.81 0.00 0.00
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 2.34 69.57 13.38 208 40
+sdb 78.93 634.11 0.00 1896 0
+scd0 0.00 0.00 0.00 0 0
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 1.00 0.00 2.34 96.66 0.00 0.00
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 4.35 0.00 61.54 0 184
+sdb 124.08 976.59 1139.80 2920 3408
+scd0 0.00 0.00 0.00 0 0
+
diff --git a/qa/src/iostat-c b/qa/src/iostat-c
new file mode 100644
index 0000000..993bce7
--- /dev/null
+++ b/qa/src/iostat-c
@@ -0,0 +1,11 @@
+Linux 2.6.32-23-generic (bozo) 27/07/10 _i686_ (1 CPU)
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 3.30 0.09 0.94 0.53 0.00 95.14
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 75.00 0.00 25.00 0.00 0.00 0.00
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 85.62 0.00 14.38 0.00 0.00 0.00
+
diff --git a/qa/src/iostat-d b/qa/src/iostat-d
new file mode 100644
index 0000000..d34d587
--- /dev/null
+++ b/qa/src/iostat-d
@@ -0,0 +1,17 @@
+Linux 2.6.32-23-generic (bozo) 27/07/10 _i686_ (1 CPU)
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 0.53 8.89 7.79 19382231 16986485
+sdb 1.39 26.74 9.02 58292750 19660048
+scd0 0.00 0.01 0.00 21528 0
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 3.34 10.70 77.59 32 232
+sdb 10.03 243.48 0.00 728 0
+scd0 0.00 0.00 0.00 0 0
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 9.27 42.38 135.10 128 408
+sdb 83.44 182.78 1634.44 552 4936
+scd0 0.00 0.00 0.00 0 0
+
diff --git a/qa/src/iostat-d-k b/qa/src/iostat-d-k
new file mode 100644
index 0000000..7b7a03d
--- /dev/null
+++ b/qa/src/iostat-d-k
@@ -0,0 +1,17 @@
+Linux 2.6.32-23-generic (bozo) 27/07/10 _i686_ (1 CPU)
+
+Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
+sda 0.53 4.45 3.90 9706667 8499886
+sdb 1.39 13.36 4.53 29151467 9885640
+scd0 0.00 0.00 0.00 10764 0
+
+Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
+sda 0.00 0.00 0.00 0 0
+sdb 5.00 0.00 366.67 0 1100
+scd0 0.00 0.00 0.00 0 0
+
+Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
+sda 3.32 0.00 42.52 0 128
+sdb 0.00 0.00 0.00 0 0
+scd0 0.00 0.00 0.00 0 0
+
diff --git a/qa/src/iostat-d-m b/qa/src/iostat-d-m
new file mode 100644
index 0000000..cdfa18a
--- /dev/null
+++ b/qa/src/iostat-d-m
@@ -0,0 +1,17 @@
+Linux 2.6.32-23-generic (bozo) 27/07/10 _i686_ (1 CPU)
+
+Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
+sda 0.53 0.00 0.00 9482 8302
+sdb 1.39 0.01 0.00 28468 9672
+scd0 0.00 0.00 0.00 10 0
+
+Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
+sda 98.01 0.59 0.05 1 0
+sdb 0.00 0.00 0.00 0 0
+scd0 0.00 0.00 0.00 0 0
+
+Device: tps MB_read/s MB_wrtn/s MB_read MB_wrtn
+sda 113.33 0.73 0.00 2 0
+sdb 1.00 0.00 0.01 0 0
+scd0 0.00 0.00 0.00 0 0
+
diff --git a/qa/src/iostat-p-ALL b/qa/src/iostat-p-ALL
new file mode 100644
index 0000000..86cd324
--- /dev/null
+++ b/qa/src/iostat-p-ALL
@@ -0,0 +1,137 @@
+Linux 2.6.32-23-generic (bozo) 27/07/10 _i686_ (1 CPU)
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 3.31 0.09 0.94 0.53 0.00 95.14
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+ram0 0.00 0.00 0.00 0 0
+ram1 0.00 0.00 0.00 0 0
+ram2 0.00 0.00 0.00 0 0
+ram3 0.00 0.00 0.00 0 0
+ram4 0.00 0.00 0.00 0 0
+ram5 0.00 0.00 0.00 0 0
+ram6 0.00 0.00 0.00 0 0
+ram7 0.00 0.00 0.00 0 0
+ram8 0.00 0.00 0.00 0 0
+ram9 0.00 0.00 0.00 0 0
+ram10 0.00 0.00 0.00 0 0
+ram11 0.00 0.00 0.00 0 0
+ram12 0.00 0.00 0.00 0 0
+ram13 0.00 0.00 0.00 0 0
+ram14 0.00 0.00 0.00 0 0
+ram15 0.00 0.00 0.00 0 0
+loop0 0.00 0.00 0.00 0 0
+loop1 0.00 0.00 0.00 0 0
+loop2 0.00 0.00 0.00 0 0
+loop3 0.00 0.00 0.00 0 0
+loop4 0.00 0.00 0.00 0 0
+loop5 0.00 0.00 0.00 0 0
+loop6 0.00 0.00 0.00 0 0
+loop7 0.00 0.00 0.00 0 0
+fd0 0.00 0.00 0.00 0 0
+sda 0.53 8.90 7.79 19412519 16995765
+sda1 0.06 0.57 0.68 1240077 1485928
+sda2 0.01 0.29 0.38 637666 820720
+sda3 0.20 2.59 5.94 5646650 12952688
+sda4 0.00 0.00 0.00 12 0
+sda5 0.25 5.42 0.79 11826333 1715152
+sda6 0.00 0.03 0.01 61533 21277
+sdb 1.39 26.73 9.05 58302926 19733240
+sdb1 0.00 0.00 0.00 582 0
+sdb2 0.00 0.00 0.00 582 0
+sdb3 0.00 0.00 0.00 392 0
+sdb4 0.00 0.00 0.00 12 0
+sdb5 0.00 0.00 0.00 386 0
+sdb6 1.39 26.73 9.05 58300724 19733240
+scd0 0.00 0.01 0.00 21528 0
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 84.67 0.00 15.33 0.00 0.00 0.00
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+ram0 0.00 0.00 0.00 0 0
+ram1 0.00 0.00 0.00 0 0
+ram2 0.00 0.00 0.00 0 0
+ram3 0.00 0.00 0.00 0 0
+ram4 0.00 0.00 0.00 0 0
+ram5 0.00 0.00 0.00 0 0
+ram6 0.00 0.00 0.00 0 0
+ram7 0.00 0.00 0.00 0 0
+ram8 0.00 0.00 0.00 0 0
+ram9 0.00 0.00 0.00 0 0
+ram10 0.00 0.00 0.00 0 0
+ram11 0.00 0.00 0.00 0 0
+ram12 0.00 0.00 0.00 0 0
+ram13 0.00 0.00 0.00 0 0
+ram14 0.00 0.00 0.00 0 0
+ram15 0.00 0.00 0.00 0 0
+loop0 0.00 0.00 0.00 0 0
+loop1 0.00 0.00 0.00 0 0
+loop2 0.00 0.00 0.00 0 0
+loop3 0.00 0.00 0.00 0 0
+loop4 0.00 0.00 0.00 0 0
+loop5 0.00 0.00 0.00 0 0
+loop6 0.00 0.00 0.00 0 0
+loop7 0.00 0.00 0.00 0 0
+fd0 0.00 0.00 0.00 0 0
+sda 4.67 0.00 128.00 0 384
+sda1 4.67 0.00 128.00 0 384
+sda2 0.00 0.00 0.00 0 0
+sda3 0.00 0.00 0.00 0 0
+sda4 0.00 0.00 0.00 0 0
+sda5 0.00 0.00 0.00 0 0
+sda6 0.00 0.00 0.00 0 0
+sdb 9.33 0.00 768.00 0 2304
+sdb1 0.00 0.00 0.00 0 0
+sdb2 0.00 0.00 0.00 0 0
+sdb3 0.00 0.00 0.00 0 0
+sdb4 0.00 0.00 0.00 0 0
+sdb5 0.00 0.00 0.00 0 0
+sdb6 9.33 0.00 768.00 0 2304
+scd0 0.00 0.00 0.00 0 0
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 88.33 0.00 11.67 0.00 0.00 0.00
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+ram0 0.00 0.00 0.00 0 0
+ram1 0.00 0.00 0.00 0 0
+ram2 0.00 0.00 0.00 0 0
+ram3 0.00 0.00 0.00 0 0
+ram4 0.00 0.00 0.00 0 0
+ram5 0.00 0.00 0.00 0 0
+ram6 0.00 0.00 0.00 0 0
+ram7 0.00 0.00 0.00 0 0
+ram8 0.00 0.00 0.00 0 0
+ram9 0.00 0.00 0.00 0 0
+ram10 0.00 0.00 0.00 0 0
+ram11 0.00 0.00 0.00 0 0
+ram12 0.00 0.00 0.00 0 0
+ram13 0.00 0.00 0.00 0 0
+ram14 0.00 0.00 0.00 0 0
+ram15 0.00 0.00 0.00 0 0
+loop0 0.00 0.00 0.00 0 0
+loop1 0.00 0.00 0.00 0 0
+loop2 0.00 0.00 0.00 0 0
+loop3 0.00 0.00 0.00 0 0
+loop4 0.00 0.00 0.00 0 0
+loop5 0.00 0.00 0.00 0 0
+loop6 0.00 0.00 0.00 0 0
+loop7 0.00 0.00 0.00 0 0
+fd0 0.00 0.00 0.00 0 0
+sda 0.00 0.00 0.00 0 0
+sda1 0.00 0.00 0.00 0 0
+sda2 0.00 0.00 0.00 0 0
+sda3 0.00 0.00 0.00 0 0
+sda4 0.00 0.00 0.00 0 0
+sda5 0.00 0.00 0.00 0 0
+sda6 0.00 0.00 0.00 0 0
+sdb 0.00 0.00 0.00 0 0
+sdb1 0.00 0.00 0.00 0 0
+sdb2 0.00 0.00 0.00 0 0
+sdb3 0.00 0.00 0.00 0 0
+sdb4 0.00 0.00 0.00 0 0
+sdb5 0.00 0.00 0.00 0 0
+sdb6 0.00 0.00 0.00 0 0
+scd0 0.00 0.00 0.00 0 0
+
diff --git a/qa/src/iostat-t b/qa/src/iostat-t
new file mode 100644
index 0000000..7d85515
--- /dev/null
+++ b/qa/src/iostat-t
@@ -0,0 +1,29 @@
+Linux 2.6.32-23-generic (bozo) 27/07/10 _i686_ (1 CPU)
+
+27/07/10 12:47:34
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 3.30 0.09 0.94 0.53 0.00 95.14
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 0.53 8.87 7.79 19319431 16971317
+sdb 1.39 26.74 9.00 58263542 19612320
+scd0 0.00 0.01 0.00 21528 0
+
+27/07/10 12:47:37
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 1.99 0.00 5.32 21.93 0.00 70.76
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 172.09 2583.39 90.37 7776 272
+sdb 1.00 0.00 21.26 0 64
+scd0 0.00 0.00 0.00 0 0
+
+27/07/10 12:47:40
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 1.67 0.00 2.00 0.00 0.00 96.33
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 104.67 1392.00 34.67 4176 104
+sdb 0.00 0.00 0.00 0 0
+scd0 0.00 0.00 0.00 0 0
+
diff --git a/qa/src/iostat-t.ISO b/qa/src/iostat-t.ISO
new file mode 100644
index 0000000..ebfa885
--- /dev/null
+++ b/qa/src/iostat-t.ISO
@@ -0,0 +1,29 @@
+Linux 2.6.32-23-generic (bozo) 2010-07-27 _i686_ (1 CPU)
+
+2010-07-27T12:46:07+1000
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 3.30 0.09 0.94 0.53 0.00 95.14
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 0.52 8.84 7.78 19267823 16953677
+sdb 1.39 26.74 9.00 58263070 19610200
+scd0 0.00 0.01 0.00 21528 0
+
+2010-07-27T12:46:10+1000
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 3.99 0.00 3.99 0.66 0.00 91.36
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 93.02 1427.24 10.63 4296 32
+sdb 0.00 0.00 0.00 0 0
+scd0 0.00 0.00 0.00 0 0
+
+2010-07-27T12:46:13+1000
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 1.33 0.00 1.33 35.67 0.00 61.67
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 121.00 1701.33 464.00 5104 1392
+sdb 1.67 2.67 24.00 8 72
+scd0 0.00 0.00 0.00 0 0
+
diff --git a/qa/src/iostat-x b/qa/src/iostat-x
new file mode 100644
index 0000000..03a747a
--- /dev/null
+++ b/qa/src/iostat-x
@@ -0,0 +1,26 @@
+Linux 2.6.32-23-generic (bozo) 27/07/10 _i686_ (1 CPU)
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 3.30 0.09 0.94 0.53 0.00 95.14
+
+Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
+sda 0.03 0.76 0.32 0.21 8.90 7.79 31.61 0.01 13.37 2.11 0.11
+sdb 0.01 0.61 0.87 0.52 26.73 9.03 25.76 0.11 81.06 3.45 0.48
+scd0 0.00 0.00 0.00 0.00 0.01 0.00 180.91 0.00 176.64 98.79 0.00
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 85.38 0.00 14.62 0.00 0.00 0.00
+
+Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
+sda 0.00 10.30 0.00 4.32 0.00 116.94 27.08 0.00 0.31 0.31 0.13
+sdb 0.00 83.39 0.33 10.63 2.66 754.82 69.09 0.05 4.36 0.85 0.93
+scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 83.28 0.00 16.72 0.00 0.00 0.00
+
+Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
+sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
+sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
+scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
+
diff --git a/qa/src/iostat-z b/qa/src/iostat-z
new file mode 100644
index 0000000..281b5c0
--- /dev/null
+++ b/qa/src/iostat-z
@@ -0,0 +1,23 @@
+Linux 2.6.32-23-generic (bozo) 27/07/10 _i686_ (1 CPU)
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 3.30 0.09 0.94 0.53 0.00 95.14
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 0.53 8.90 7.79 19412391 16992325
+sdb 1.39 26.73 9.03 58302910 19688352
+scd0 0.00 0.01 0.00 21528 0
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 1.00 0.00 0.67 0.00 0.00 98.33
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 2.67 0.00 37.33 0 112
+sdb 0.33 2.67 0.00 8 0
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 1.00 0.00 0.67 0.00 0.00 98.33
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sdb 1.00 0.00 24.00 0 72
+
diff --git a/qa/src/iostat-z-p-ALL b/qa/src/iostat-z-p-ALL
new file mode 100644
index 0000000..0c8787b
--- /dev/null
+++ b/qa/src/iostat-z-p-ALL
@@ -0,0 +1,36 @@
+Linux 2.6.32-23-generic (bozo) 27/07/10 _i686_ (1 CPU)
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 3.31 0.09 0.94 0.53 0.00 95.13
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 0.53 8.90 7.79 19412519 16998349
+sda1 0.06 0.57 0.68 1240077 1488128
+sda2 0.01 0.29 0.38 637666 820720
+sda3 0.20 2.59 5.94 5646650 12953072
+sda4 0.00 0.00 0.00 12 0
+sda5 0.25 5.42 0.79 11826333 1715152
+sda6 0.00 0.03 0.01 61533 21277
+sdb 1.39 26.73 9.06 58302926 19759672
+sdb1 0.00 0.00 0.00 582 0
+sdb2 0.00 0.00 0.00 582 0
+sdb3 0.00 0.00 0.00 392 0
+sdb4 0.00 0.00 0.00 12 0
+sdb5 0.00 0.00 0.00 386 0
+sdb6 1.39 26.73 9.06 58300724 19759672
+scd0 0.00 0.01 0.00 21528 0
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 86.00 0.00 14.00 0.00 0.00 0.00
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+
+avg-cpu: %user %nice %system %iowait %steal %idle
+ 86.05 0.00 13.95 0.00 0.00 0.00
+
+Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
+sda 2.99 0.00 77.08 0 232
+sda1 2.99 0.00 77.08 0 232
+sdb 20.60 2.66 890.37 8 2680
+sdb6 20.60 2.66 890.37 8 2680
+
diff --git a/qa/src/ipc.c b/qa/src/ipc.c
new file mode 100644
index 0000000..de67b88
--- /dev/null
+++ b/qa/src/ipc.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/sem.h>
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#define SEMAPHORES /* comment this to NOT test semaphores */
+
+#define IPC_N 4
+#define NSEMS 8
+
+int shm_list[IPC_N], shm_n=0, shmindom;
+int sem_list[IPC_N * NSEMS], sem_n=0, semindom;
+int semset_list[IPC_N], semset_n = 0, semsetindom;
+
+static char *metrics[] = {
+ "ipc.shm.nattch",
+ "ipc.shm.segsz",
+#ifdef SEMAPHORES
+ "ipc.sem.nsems",
+ "ipc.sem.ncnt",
+ "ipc.sem.zcnt",
+#endif
+NULL };
+
+static int npmids;
+static pmID pmids[sizeof(metrics) / sizeof(metrics[0])];
+
+static void
+_force_err_noprofile(pmInDom indom, pmID pmid)
+{
+ pmResult *result;
+ int sts;
+
+ pmAddProfile(indom, 0, NULL);
+ sts = pmFetch(1, &pmid, &result);
+ fprintf(stderr, "\n\ndeliberate error check (no explicit profile) : %s\n", pmErrStr(sts));
+ __pmDumpResult(stderr, result);
+ pmFreeResult(result);
+}
+
+static void
+_force_err_unknown_inst(pmInDom indom, pmID pmid)
+{
+ pmResult *result;
+ int sts;
+ int i;
+
+ pmDelProfile(indom, 0, NULL);
+ i = -3;
+ pmAddProfile(indom, 1, &i);
+ sts = pmFetch(1, &pmid, &result);
+ fprintf(stderr, "\n\ndeliberate error check (1 unknown instance) : %s\n", pmErrStr(sts));
+ __pmDumpResult(stderr, result);
+ pmFreeResult(result);
+}
+
+static void
+_force_err_unknown_and_known_inst(pmInDom indom, int inst, pmID pmid)
+{
+ pmResult *result;
+ int sts;
+ int i;
+
+ pmDelProfile(indom, 0, NULL);
+ i = -3; pmAddProfile(indom, 1, &i);
+ pmAddProfile(indom, 1, &inst);
+ sts = pmFetch(1, &pmid, &result);
+ fprintf(stderr, "\n\ndeliberate error check (1 unknown instance + 1 known) : %s\n", pmErrStr(sts));
+ __pmDumpResult(stderr, result);
+ pmFreeResult(result);
+}
+
+static void
+_force_err(pmInDom indom, int inst, pmID pmid)
+{
+ _force_err_noprofile(indom, pmid);
+ _force_err_unknown_inst(indom, pmid);
+ _force_err_unknown_and_known_inst(indom, inst, pmid);
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int i;
+ int j;
+ key_t key;
+ int sts;
+ char *p;
+ int errflag = 0;
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+ int iterations = 1;
+ int iter;
+ pmResult *result;
+ pmDesc desc;
+ int id;
+ int e;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N] ";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-h hostname] [-n namespace] [-i iterations]";
+ extern char *optarg;
+ extern int optind;
+ extern int pmDebug;
+
+ /* trim command name of leading directory components */
+ pmProgname = argv[0];
+ for (p = pmProgname; *p; p++) {
+ if (*p == '/')
+ pmProgname = p+1;
+ }
+
+ while ((c = getopt(argc, argv, "D:h:l:n:i:")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ host = optarg;
+ break;
+
+ case 'i': /* iterations */
+ iterations = atoi(optarg);
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+USAGE:
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ sts = pmNewContext(PM_CONTEXT_HOST, host);
+
+ if (sts < 0) {
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ if (optind > argc)
+ goto USAGE;
+
+ memset(pmids, 0, sizeof(pmids));
+ for (npmids=0; metrics[npmids]; npmids++) {
+ if ((sts = pmLookupName(1, &metrics[npmids], &pmids[npmids])) < 0) {
+ fprintf(stderr, "%s: metric ``%s'' : %s\n", pmProgname, metrics[npmids], pmErrStr(sts));
+ exit(1);
+ }
+ fprintf(stderr, "pmid=%s <%s>\n", pmIDStr(pmids[npmids]), metrics[npmids]);
+ }
+
+ if ((e = pmLookupDesc(pmids[0], &desc)) < 0) {
+ printf("pmLookupDesc: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ shmindom = desc.indom;
+
+#ifdef SEMAPHORES
+ if ((e = pmLookupDesc(pmids[2], &desc)) < 0) {
+ printf("pmLookupDesc: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ semsetindom = desc.indom;
+ if ((e = pmLookupDesc(pmids[3], &desc)) < 0) {
+ printf("pmLookupDesc: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ semindom = desc.indom;
+#endif
+
+ fprintf(stderr, "shmindom=%s", pmInDomStr(shmindom));
+#ifdef SEMAPHORES
+ fprintf(stderr, " semsetindom=%s", pmInDomStr(semsetindom));
+ fprintf(stderr, " semindom=%s", pmInDomStr(semindom));
+#endif
+ fputc('\n', stderr);
+
+ key = (key_t)0xabcd0000;
+ for (i=0; i < IPC_N; i++) {
+ if ((id = shmget(key++, 4096, IPC_CREAT|IPC_EXCL|0777)) >= 0) {
+ shm_list[shm_n++] = id;
+ fprintf(stderr, "SHMID_%d\n", id);
+ }
+ else {
+ perror("shmget");
+ goto CLEANUP;
+ }
+
+#ifdef SEMAPHORES
+ if ((id = semget(key++, NSEMS, IPC_CREAT|IPC_EXCL|0777)) >= 0) {
+ semset_list[semset_n++] = id;
+ fprintf(stderr, "SEMSET_%d\n", id);
+ for (j=0; j < NSEMS; j++) {
+ sem_list[sem_n++] = (id << 16) | j;
+ fprintf(stderr, "SEMID_%d.%d ", id, j);
+ }
+ fputc('\n', stderr);
+ }
+ else {
+ perror("semget");
+ goto CLEANUP;
+ }
+#endif
+ }
+
+ pmDelProfile(shmindom, 0, NULL);
+ pmAddProfile(shmindom, shm_n, shm_list);
+
+#ifdef SEMAPHORES
+ pmDelProfile(semsetindom, 0, NULL);
+ pmAddProfile(semsetindom, semset_n, semset_list);
+ pmDelProfile(semindom, 0, NULL);
+ pmAddProfile(semindom, sem_n, sem_list);
+#endif
+
+ fprintf(stderr, "Single Metrics ...\n");
+ for (j = 0; j < npmids; j++) {
+ sts = pmFetch(1, &pmids[j], &result);
+ if (sts < 0) {
+ fprintf(stderr, "%s: metric %s : %s\n", pmProgname, metrics[j], pmErrStr(sts));
+ exit(1);
+ }
+ __pmDumpResult(stderr, result);
+ pmFreeResult(result);
+ }
+
+ fprintf(stderr, "Cascading Sets of Metrics ...\n");
+ for (iter=0; iter < iterations; iter++) {
+ fprintf(stderr, "Iteration: %d\n", iter);
+ for (j = 0; j < npmids; j++) {
+ sts = pmFetch(j+1, pmids, &result);
+ if (sts < 0) {
+ fprintf(stderr, "%s: iteration %d cascade %d : %s\n",
+ pmProgname, iter, j, pmErrStr(sts));
+ exit(1);
+ }
+ __pmDumpResult(stderr, result);
+ pmFreeResult(result);
+ }
+ }
+
+
+ /* now test the err conditions */
+ _force_err(shmindom, shm_list[0], pmids[0]);
+
+#ifdef SEMAPHORES
+ _force_err(semsetindom, semset_list[0], pmids[2]);
+ _force_err(semindom, sem_list[0], pmids[3]);
+#endif
+
+CLEANUP:
+ for (i=0; i < shm_n; i++) {
+ if (shm_list[i] >= 0)
+ if (shmctl(shm_list[i], IPC_RMID, 0) < 0)
+ perror("shmctl(IPC_RMID)");
+ }
+#ifdef SEMAPHORES
+ for (i=0; i < sem_n; i += NSEMS) {
+ if (sem_list[i] >= 0)
+ if (semctl(sem_list[i] >> 16, 0, IPC_RMID) < 0)
+ perror("semctl(IPC_RMID)");
+ }
+#endif
+
+ exit(0);
+}
diff --git a/qa/src/ipcs_clear b/qa/src/ipcs_clear
new file mode 100755
index 0000000..f46794a
--- /dev/null
+++ b/qa/src/ipcs_clear
@@ -0,0 +1,39 @@
+#! /bin/sh
+#
+# Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+#
+# Cleanup my seamphores and shared memory segments ... leave
+# smh segment id 0, things owned by root and/or Oracle
+#
+
+# Get standard environment
+. $PCP_DIR/etc/pcp.env
+
+if [ $PCP_PLATFORM = irix ]
+then
+ ipcrm `ipcs -ms | $PCP_AWK_PROG '
+$5 == "root" { next }
+$5 == "oracle" { next }
+$5 == "sybase" { next }
+$5 == "informix" { next }
+/^m/ { if ($2 != 0) printf "-m %d ", $2 }
+/^s/ { printf "-s %d ", $2 }
+END { print "" }'`
+elif [ $PCP_PLATFORM = linux ]
+then
+ ipcs -ms | $PCP_AWK_PROG '
+$5 == "root" { next }
+$5 == "oracle" { next }
+$5 == "sybase" { next }
+$5 == "informix" { next }
+/^m/ { if ($2 != 0) print "shm %d", $2 }
+/^s/ { print "sem %d", $2 }' \
+ | while read args
+ do
+ ipcrm $args
+ done
+else
+ bozo! - how do you do this ipc stuff
+fi
+
+exit 0
diff --git a/qa/src/kenj-pc-1.0 b/qa/src/kenj-pc-1.0
new file mode 100644
index 0000000..6c9b3cd
--- /dev/null
+++ b/qa/src/kenj-pc-1.0
Binary files differ
diff --git a/qa/src/kenj-pc-1.index b/qa/src/kenj-pc-1.index
new file mode 100644
index 0000000..7a0e93e
--- /dev/null
+++ b/qa/src/kenj-pc-1.index
Binary files differ
diff --git a/qa/src/kenj-pc-1.meta b/qa/src/kenj-pc-1.meta
new file mode 100644
index 0000000..f6c2c8c
--- /dev/null
+++ b/qa/src/kenj-pc-1.meta
Binary files differ
diff --git a/qa/src/kenj-pc-2.0 b/qa/src/kenj-pc-2.0
new file mode 100644
index 0000000..29513e5
--- /dev/null
+++ b/qa/src/kenj-pc-2.0
Binary files differ
diff --git a/qa/src/kenj-pc-2.config b/qa/src/kenj-pc-2.config
new file mode 100644
index 0000000..1e6885c
--- /dev/null
+++ b/qa/src/kenj-pc-2.config
@@ -0,0 +1,10 @@
+log advisory on default {
+ sample.mirage
+ sample.sysinfo
+ sample.rapid
+ sample.string
+ sample.aggregate
+ sample.wrap
+ sample.dodgey
+ sample.dynamic
+}
diff --git a/qa/src/kenj-pc-2.index b/qa/src/kenj-pc-2.index
new file mode 100644
index 0000000..6281deb
--- /dev/null
+++ b/qa/src/kenj-pc-2.index
Binary files differ
diff --git a/qa/src/kenj-pc-2.meta b/qa/src/kenj-pc-2.meta
new file mode 100644
index 0000000..deb89f6
--- /dev/null
+++ b/qa/src/kenj-pc-2.meta
Binary files differ
diff --git a/qa/src/kenj-pc-diskstat.0 b/qa/src/kenj-pc-diskstat.0
new file mode 100644
index 0000000..a775d6b
--- /dev/null
+++ b/qa/src/kenj-pc-diskstat.0
Binary files differ
diff --git a/qa/src/kenj-pc-diskstat.index b/qa/src/kenj-pc-diskstat.index
new file mode 100644
index 0000000..e521697
--- /dev/null
+++ b/qa/src/kenj-pc-diskstat.index
Binary files differ
diff --git a/qa/src/kenj-pc-diskstat.meta b/qa/src/kenj-pc-diskstat.meta
new file mode 100644
index 0000000..ea391a3
--- /dev/null
+++ b/qa/src/kenj-pc-diskstat.meta
Binary files differ
diff --git a/qa/src/keycache.c b/qa/src/keycache.c
new file mode 100644
index 0000000..39a7640
--- /dev/null
+++ b/qa/src/keycache.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * Exercise pmdaCacheStoreKey() in libpcp_pmda
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+#include <arpa/inet.h>
+
+static int histo[128];
+static int vflag = 0;
+
+static void
+do_key(int i, int j, int k, char *name, int *keylen, int *key)
+{
+ if (j == 1)
+ key[0] = (i << 8) | j;
+ else if (j == 2)
+ key[0] = (i << 16) | (j << 8) | k;
+ else
+ key[0] = (i << 24) | (j << 16) | (k << 8) | i;
+ *keylen = (k+1)*sizeof(int);
+ switch (k) {
+ case 0:
+ sprintf(name, "%08x", key[0]);
+ break;
+ case 1:
+ key[1] = i;
+ sprintf(name, "%08x-%08x", key[0], key[1]);
+ break;
+ case 2:
+ key[1] = i;
+ key[2] = j;
+ sprintf(name, "%08x-%08x-%08x", key[0], key[1], key[2]);
+ break;
+ case 3:
+ key[1] = i;
+ key[2] = j;
+ key[3] = k;
+ sprintf(name, "%08x-%08x-%08x-%08x", key[0], key[1], key[2], key[3]);
+ break;
+ }
+
+ if (vflag)
+ fprintf(stderr, "do_key(%d, %d, %d, ...) -> %s\n", i, j, k, name);
+}
+
+/*
+ * Assume we're following -d or -dk, so dealing with the smaller
+ * set of keys the -d implies
+ */
+static void
+load_n_go(pmInDom indom)
+{
+ int sts;
+ int keylen;
+ int key[4];
+ char name[40];
+ int i;
+ int j;
+ int k;
+ int kflag;
+ int inst;
+
+ sts = pmdaCacheOp(indom, PMDA_CACHE_LOAD);
+ if (sts < 0)
+ fprintf(stderr, "pmdaCacheOp(%s, PMDA_CACHE_LOAD) failed: %s\n", pmInDomStr(indom), pmErrStr(sts));
+ fprintf(stderr, "Cache loaded ...\n");
+ pmdaCacheOp(indom, PMDA_CACHE_DUMP);
+
+ for (i = 0; i < 5; i++) { /* one more iteration than -d in main() */
+ for (j = 1; j < 5; ) { /* one more iteration than -d in main() */
+ for (k = 0; k < 4; k++) { /* one more iteration than -d in main() */
+ do_key(i, j, k, name, &keylen, key);
+ for (kflag = 1; kflag >= 0; kflag--) {
+ /* force duplicate keys by culling the key[] or name[] */
+ if (kflag)
+ keylen = 4;
+ else
+ name[13] = '\0';
+
+ if (kflag) {
+ int c;
+ for (c = 0; c < keylen/sizeof(int); c++)
+ key[c] = htonl(key[c]);
+ inst = pmdaCacheStoreKey(indom, PMDA_CACHE_ADD, name, keylen, (const void *)key, NULL);
+ for (c = 0; c < keylen/sizeof(int); c++)
+ key[c] = ntohl(key[c]);
+ }
+ else
+ inst = pmdaCacheStoreKey(indom, PMDA_CACHE_ADD, name, 0, NULL, NULL);
+ if (kflag) {
+ int c;
+ fprintf(stderr, "%d <- %s ", inst, name);
+ for (c = 0; c < keylen/sizeof(int); c++) {
+ if (c == 0)
+ fprintf(stderr, "[%d", key[c]);
+ else
+ fprintf(stderr, ",%d", key[c]);
+ }
+ fputc(']', stderr);
+ fputc('\n', stderr);
+ }
+ else
+ fprintf(stderr, "%d <- %s\n", inst, name);
+ if (inst < 0)
+ fprintf(stderr, "pmdaCacheStoreKey failed: %s\n", pmErrStr(inst));
+ }
+ }
+ j++;
+ }
+ }
+ pmdaCacheOp(indom, PMDA_CACHE_DUMP_ALL);
+}
+
+int
+main(int argc, char **argv)
+{
+ int key[4]; /* key[3] not used as yet */
+ int inst;
+ pmInDom indom;
+ int i;
+ int j;
+ int k;
+ int keylen;
+ int s;
+ int c;
+ int n = 0;
+ char name[40];
+ int sts;
+ int errflag = 0;
+ int kflag = 0;
+ int dflag = 0;
+ int lflag = 0;
+ char *usage = "[-D debug] [-dkl]";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:dklv")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'd': /* exercise duplicate checking, save, smaller set of keys */
+ dflag = 1;
+ break;
+
+ case 'k': /* use key[], default is to use name[] */
+ kflag = 1;
+ break;
+
+ case 'l': /* load */
+ lflag = 1;
+ break;
+
+ case 'v': /* verbose */
+ vflag = 1;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc) {
+ fprintf(stderr, "Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ indom = pmInDom_build(42, 42);
+
+ if (lflag) {
+ load_n_go(indom);
+ exit(0);
+ }
+
+ /*
+ * pattern of keys here is
+ * - 32, 64 or 96 bits long
+ * - features grouping and runs of values, as might be found in
+ * multi-dimensional indexes that need to be mapped to a value
+ * no larger than 2^31 - 1 for an internal instance identifier
+ */
+
+ for (i = 0; i < 255; i++) {
+ for (j = 1; j < 255; ) {
+ for (k = 0; k < 3; k++) {
+ do_key(i, j, k, name, &keylen, key);
+
+ if (dflag) {
+ /* force duplicate keys by culling the key[] or name[] */
+ if (kflag)
+ keylen = 4;
+ else
+ name[13] = '\0';
+ }
+
+ if (kflag) {
+ int c;
+ for (c = 0; c < keylen/sizeof(int); c++)
+ key[c] = htonl(key[c]);
+ inst = pmdaCacheStoreKey(indom, PMDA_CACHE_ADD, name, keylen, (const void *)key, NULL);
+ for (c = 0; c < keylen/sizeof(int); c++)
+ key[c] = ntohl(key[c]);
+ }
+ else
+ inst = pmdaCacheStoreKey(indom, PMDA_CACHE_ADD, name, 0, NULL, NULL);
+ if (kflag) {
+ fprintf(stderr, "%d <- %s ", inst, name);
+ for (c = 0; c < keylen/sizeof(int); c++) {
+ if (c == 0)
+ fprintf(stderr, "[%d", key[c]);
+ else
+ fprintf(stderr, ",%d", key[c]);
+ }
+ fputc(']', stderr);
+ fputc('\n', stderr);
+ }
+ else
+ fprintf(stderr, "%d <- %s\n", inst, name);
+ if (inst < 0) {
+ fprintf(stderr, "pmdaCacheStoreKey failed: %s\n", pmErrStr(inst));
+ continue;
+ }
+ histo[(int)(inst/(0x7fffffff/128))]++;
+ n++;
+ }
+ if (dflag && j == 3)
+ break;
+ if (j < 32)
+ j++;
+ else
+ j = 2*j + 1;
+ }
+ if (dflag && i == 3) {
+ pmdaCacheOp(indom, PMDA_CACHE_DUMP_ALL);
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ if (sts < 0)
+ fprintf(stderr, "pmdaCacheOp(%s, PMDA_CACHE_SAVE) failed: %s\n", pmInDomStr(indom), pmErrStr(sts));
+ sts = pmdaCacheOp(indom, PMDA_CACHE_CULL);
+ if (sts < 0)
+ fprintf(stderr, "pmdaCacheOp(%s, PMDA_CACHE_CULL) failed: %s\n", pmInDomStr(indom), pmErrStr(sts));
+ exit(0);
+ }
+ }
+
+ for (s = 1; s <= 64; s *= 2) {
+ fprintf(stderr, "\nInstances distribution across %d bins\n", 128/s);
+ c = 0;
+ for (j = 0; j < 128; j += s) {
+ i = 0;
+ for (k = 0; k < s; k++)
+ i += histo[j+k];
+ fprintf(stderr, "%.5f ", (double)i/n);
+ c++;
+ if (c == 10) {
+ fputc('\n', stderr);
+ c = 0;
+ }
+ }
+ fputc('\n', stderr);
+ }
+
+ return 0;
+}
diff --git a/qa/src/keycache2.c b/qa/src/keycache2.c
new file mode 100644
index 0000000..d54e8be
--- /dev/null
+++ b/qa/src/keycache2.c
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * Exercise pmdaCacheLookup(), pmdaCacheLookupName() and pmdaCacheLookupKey()
+ * in libpcp_pmda
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+#include <arpa/inet.h>
+
+static __uint32_t hash(const char *, int, __uint32_t);
+
+/* hash attempts looking for hash synonyms */
+#define MAXPOKE 200000
+
+typedef struct {
+ int inst;
+ int key;
+} inst_key_t;
+
+static int
+compar(const void *a, const void *b)
+{
+ const inst_key_t *ia = (inst_key_t *)a;
+ const inst_key_t *ib = (inst_key_t *)b;
+
+ if (ib->inst != ia->inst)
+ return ib->inst - ia->inst;
+ /*
+ * inst same (synonyms), reverse sort on key to make results deterministic
+ */
+ return ia->key - ib->key;
+}
+
+int
+main(int argc, char **argv)
+{
+ int key;
+ int inst;
+ pmInDom indom;
+ int c;
+ char name[40];
+ char *oname;
+ void *addr;
+ int sts;
+ int errflag = 0;
+ int kflag = 0;
+ char *usage = "[-D debug] [-k]";
+ __uint32_t try = 0;
+ int dup;
+ inst_key_t poke[MAXPOKE];
+ int mykeylen = 0; /* pander to gcc */
+ void *mykey = NULL; /* pander to gcc */
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:k")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'k': /* use key[], default is to use name[] */
+ kflag = 1;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc) {
+ fprintf(stderr, "Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ indom = pmInDom_build(42, 42);
+
+ /*
+ * hash MAXPOKE keys
+ */
+ if (kflag) {
+ mykeylen = sizeof(key);
+ mykey = (void *)&key;
+ }
+ for (key = 0; key < MAXPOKE; key++) {
+ if (!kflag) {
+ sprintf(name, "key-%d", key);
+ mykeylen = strlen(name);
+ mykey = (void *)name;
+ }
+ key = htonl(key);
+ try = hash((char *)mykey, mykeylen, 0);
+ key = ntohl(key);
+ /* strip top bit ... instance id must be positive */
+ inst = try & ~(1 << (8*sizeof(__uint32_t)-1));
+ poke[key].inst = inst;
+ poke[key].key = key;
+ }
+
+ /* sort on hash value */
+ qsort(poke, MAXPOKE, sizeof(poke[0]), compar);
+
+ /*
+ * look for hash synonyms, and stuff them away in pairs in the
+ * start of poke[]
+ */
+ dup = 0;
+ for (key = 1; key < MAXPOKE; key++) {
+ if (poke[key-1].inst == poke[key].inst) {
+ if (kflag)
+ fprintf(stderr, "keys %d & %d hash to %d\n", poke[key-1].key, poke[key].key, poke[key-1].inst);
+ else
+ fprintf(stderr, "keys \"key-%d\" & \"key-%d\" hash to %d\n", poke[key-1].key, poke[key].key, poke[key-1].inst);
+ sprintf(name, "key-%d", poke[key-1].key);
+ if (kflag) {
+ mykeylen = sizeof(key);
+ mykey = (void *)&poke[key-1].key;
+ }
+ else {
+ mykeylen = strlen(name);
+ mykey = (void *)name;
+ }
+ poke[key-1].key = htonl(poke[key-1].key);
+ sts = pmdaCacheStoreKey(indom, PMDA_CACHE_ADD, name, mykeylen, mykey, &poke[dup]);
+ poke[key-1].key = ntohl(poke[key-1].key);
+ if (sts < 0) {
+ if (kflag)
+ fprintf(stderr, "pmdaCacheStoreKey(... %s, ... %d): %s\n", name, poke[key-1].key, pmErrStr(sts));
+ else
+ fprintf(stderr, "pmdaCacheStoreKey(... %s, ... NULL): %s\n", name, pmErrStr(sts));
+ }
+ else
+ fprintf(stderr, "%s -> %d\n", name, sts);
+ poke[dup].key = poke[key-1].key;
+ poke[dup++].inst = sts;
+ sprintf(name, "key-%d", poke[key].key);
+ if (kflag) {
+ mykeylen = sizeof(key);
+ mykey = (void *)&poke[key].key;
+ }
+ else {
+ mykeylen = strlen(name);
+ mykey = (void *)name;
+ }
+ poke[key].key = htonl(poke[key].key);
+ sts = pmdaCacheStoreKey(indom, PMDA_CACHE_ADD, name, mykeylen, mykey, &poke[dup]);
+ poke[key].key = ntohl(poke[key].key);
+ if (sts < 0) {
+ if (kflag)
+ fprintf(stderr, "pmdaCacheStoreKey(... %s, ... %d): %s\n", name, poke[key].key, pmErrStr(sts));
+ else
+ fprintf(stderr, "pmdaCacheStoreKey(... %s, ... NULL): %s\n", name, pmErrStr(sts));
+ }
+ else
+ fprintf(stderr, "%s -> %d\n", name, sts);
+ poke[dup].key = poke[key].key;
+ poke[dup++].inst = sts;
+ }
+ }
+
+ /* mark the first and last as inactive, and cull the middle entry */
+ sprintf(name, "key-%d", poke[0].key);
+ sts = pmdaCacheStore(indom, PMDA_CACHE_HIDE, name, NULL);
+ if (sts < 0)
+ fprintf(stderr, "pmdaCacheStore(... HIDE \"%s\", ...) failed: %s\n", name, pmErrStr(sts));
+ sprintf(name, "key-%d", poke[dup-1].key);
+ sts = pmdaCacheStore(indom, PMDA_CACHE_HIDE, name, NULL);
+ if (sts < 0)
+ fprintf(stderr, "pmdaCacheStore(... HIDE \"%s\", ...) failed: %s\n", name, pmErrStr(sts));
+ sprintf(name, "key-%d", poke[dup/2].key);
+ sts = pmdaCacheStore(indom, PMDA_CACHE_CULL, name, NULL);
+ if (sts < 0)
+ fprintf(stderr, "pmdaCacheStore(... CULL \"%s\", ...) failed: %s\n", name, pmErrStr(sts));
+
+ pmdaCacheOp(indom, PMDA_CACHE_DUMP);
+
+ for (key = 0; key < dup; key++) {
+ sprintf(name, "key-%d", poke[key].key);
+
+ sts = pmdaCacheLookup(indom, poke[key].inst, &oname, &addr);
+ fprintf(stderr, "pmdaCacheLookup(... %d, ...)", poke[key].inst);
+ if (sts < 0)
+ fprintf(stderr, ": %s", pmErrStr(sts));
+ else {
+ if (sts == PMDA_CACHE_ACTIVE)
+ fprintf(stderr, " -> active");
+ else if (sts == PMDA_CACHE_INACTIVE)
+ fprintf(stderr, " -> inactive");
+ else
+ fprintf(stderr, " -> %d?", sts);
+ if (strcmp(name, oname) == 0)
+ fprintf(stderr, " name ok");
+ else
+ fprintf(stderr, " name? \"%s\" [expected \"%s\"]", oname, name);
+ if (addr == (void *)&poke[key])
+ fprintf(stderr, " private ok");
+ else
+ fprintf(stderr, " private? %p [expected %p]", &poke[key], addr);
+ }
+ fputc('\n', stderr);
+
+ sts = pmdaCacheLookupName(indom, name, &inst, &addr);
+ fprintf(stderr, "pmdaCacheLookupName(... \"%s\", ...)", name);
+ if (sts < 0)
+ fprintf(stderr, ": %s", pmErrStr(sts));
+ else {
+ if (sts == PMDA_CACHE_ACTIVE)
+ fprintf(stderr, " -> active");
+ else if (sts == PMDA_CACHE_INACTIVE)
+ fprintf(stderr, " -> inactive");
+ else
+ fprintf(stderr, " -> %d?", sts);
+ if (inst == poke[key].inst)
+ fprintf(stderr, " inst ok");
+ else
+ fprintf(stderr, " inst? %d [expected %d]", inst, poke[key].inst);
+ if (addr == (void *)&poke[key])
+ fprintf(stderr, " private ok");
+ else
+ fprintf(stderr, " private? %p [expected %p]", &poke[key], addr);
+ }
+ fputc('\n', stderr);
+
+ if (kflag) {
+ mykeylen = sizeof(key);
+ mykey = (void *)&poke[key].key;
+ }
+ else {
+ mykeylen = strlen(name);
+ mykey = (void *)name;
+ }
+ poke[key].key = htonl(poke[key].key);
+ sts = pmdaCacheLookupKey(indom, name, mykeylen, mykey, &oname, &inst, &addr);
+ poke[key].key = ntohl(poke[key].key);
+ fprintf(stderr, "pmdaCacheLookupKey(... \"%s\", ...)", name);
+ if (sts < 0)
+ fprintf(stderr, ": %s", pmErrStr(sts));
+ else {
+ if (sts == PMDA_CACHE_ACTIVE)
+ fprintf(stderr, " -> active");
+ else if (sts == PMDA_CACHE_INACTIVE)
+ fprintf(stderr, " -> inactive");
+ else
+ fprintf(stderr, " -> %d?", sts);
+ if (strcmp(name, oname) == 0)
+ fprintf(stderr, " name ok");
+ else
+ fprintf(stderr, " name? \"%s\" [expected \"%s\"]", oname, name);
+ if (inst == poke[key].inst)
+ fprintf(stderr, " inst ok");
+ else
+ fprintf(stderr, " inst? %d [expected %d]", inst, poke[key].inst);
+ if (addr == (void *)&poke[key])
+ fprintf(stderr, " private ok");
+ else
+ fprintf(stderr, " private? %p [expected %p]", &poke[key], addr);
+ }
+ fputc('\n', stderr);
+
+ }
+
+
+ return 0;
+}
+
+/*
+ * lifted directly from libpcp_pmda/src/cache.c
+ */
+
+/*
+--------------------------------------------------------------------
+lookup2.c, by Bob Jenkins, December 1996, Public Domain.
+hash(), hash2(), hash3, and mix() are externally useful functions.
+Routines to test the hash are included if SELF_TEST is defined.
+You can use this free for any purpose. It has no warranty.
+--------------------------------------------------------------------
+*/
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+typedef unsigned long int ub4; /* unsigned 4-byte quantities */
+typedef unsigned char ub1;
+
+#define hashsize(n) ((ub4)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+
+/*
+--------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+For every delta with one or two bit set, and the deltas of all three
+ high bits or all three low bits, whether the original value of a,b,c
+ is almost all zero or is uniformly distributed,
+* If mix() is run forward or backward, at least 32 bits in a,b,c
+ have at least 1/4 probability of changing.
+* If mix() is run forward, every bit of c will change between 1/3 and
+ 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
+mix() was built out of 36 single-cycle latency instructions in a
+ structure that could supported 2x parallelism, like so:
+ a -= b;
+ a -= c; x = (c>>13);
+ b -= c; a ^= x;
+ b -= a; x = (a<<8);
+ c -= a; b ^= x;
+ c -= b; x = (b>>13);
+ ...
+ Unfortunately, superscalar Pentiums and Sparcs can't take advantage
+ of that parallelism. They've also turned some of those single-cycle
+ latency instructions into multi-cycle latency instructions. Still,
+ this is the fastest good hash I could find. There were about 2^^68
+ to choose from. I only looked at a billion or so.
+--------------------------------------------------------------------
+*/
+#define mix(a,b,c) \
+{ \
+ a -= b; a -= c; a ^= (c>>13); \
+ b -= c; b -= a; b ^= (a<<8); \
+ c -= a; c -= b; c ^= (b>>13); \
+ a -= b; a -= c; a ^= (c>>12); \
+ b -= c; b -= a; b ^= (a<<16); \
+ c -= a; c -= b; c ^= (b>>5); \
+ a -= b; a -= c; a ^= (c>>3); \
+ b -= c; b -= a; b ^= (a<<10); \
+ c -= a; c -= b; c ^= (b>>15); \
+}
+
+/*
+--------------------------------------------------------------------
+hash() -- hash a variable-length key into a 32-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ len : the length of the key, counting by bytes
+ level : can be any 4-byte value
+Returns a 32-bit value. Every bit of the key affects every bit of
+the return value. Every 1-bit and 2-bit delta achieves avalanche.
+About 36+6len instructions.
+
+The best hash table sizes are powers of 2. There is no need to do
+mod a prime (mod is sooo slow!). If you need less than 32 bits,
+use a bitmask. For example, if you need only 10 bits, do
+ h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (ub1 **)k, do it like this:
+ for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
+
+By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
+code any way you wish, private, educational, or commercial. It's free.
+
+See http://burlteburtle.net/bob/hash/evahash.html
+Use for hash table lookup, or anything where one collision in 2^32 is
+acceptable. Do NOT use for cryptographic purposes.
+--------------------------------------------------------------------
+*/
+
+static __uint32_t
+hash(const char *k, int length, __uint32_t initval)
+{
+ __uint32_t a,b,c,len;
+
+ /* Set up the internal state */
+ len = length;
+ a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
+ c = initval; /* the previous hash value */
+
+ /*---------------------------------------- handle most of the key */
+ while (len >= 12)
+ {
+ a += (k[0] +((__uint32_t)k[1]<<8) +((__uint32_t)k[2]<<16)
+ +((__uint32_t)k[3]<<24));
+ b += (k[4] +((__uint32_t)k[5]<<8) +((__uint32_t)k[6]<<16)
+ +((__uint32_t)k[7]<<24));
+ c += (k[8] +((__uint32_t)k[9]<<8)
+ +((__uint32_t)k[10]<<16)+((__uint32_t)k[11]<<24));
+ mix(a,b,c);
+ k += 12; len -= 12;
+ }
+
+ /*------------------------------------- handle the last 11 bytes */
+ c += length;
+ switch(len) /* all the case statements fall through */
+ {
+ case 11: c+=((__uint32_t)k[10]<<24);
+ case 10: c+=((__uint32_t)k[9]<<16);
+ case 9 : c+=((__uint32_t)k[8]<<8);
+ /* the first byte of c is reserved for the length */
+ case 8 : b+=((__uint32_t)k[7]<<24);
+ case 7 : b+=((__uint32_t)k[6]<<16);
+ case 6 : b+=((__uint32_t)k[5]<<8);
+ case 5 : b+=k[4];
+ case 4 : a+=((__uint32_t)k[3]<<24);
+ case 3 : a+=((__uint32_t)k[2]<<16);
+ case 2 : a+=((__uint32_t)k[1]<<8);
+ case 1 : a+=k[0];
+ /* case 0: nothing left to add */
+ }
+ mix(a,b,c);
+ /*-------------------------------------------- report the result */
+ return c;
+}
diff --git a/qa/src/killparent.c b/qa/src/killparent.c
new file mode 100644
index 0000000..b8e0ca2
--- /dev/null
+++ b/qa/src/killparent.c
@@ -0,0 +1,13 @@
+/*
+ * Unconditionally kill your parent ... BEWARE!
+ */
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+
+int
+main()
+{
+ kill(getppid(), SIGKILL);
+ return(0);
+}
diff --git a/qa/src/late.0 b/qa/src/late.0
new file mode 100644
index 0000000..499e644
--- /dev/null
+++ b/qa/src/late.0
Binary files differ
diff --git a/qa/src/late.index b/qa/src/late.index
new file mode 100644
index 0000000..749b305
--- /dev/null
+++ b/qa/src/late.index
Binary files differ
diff --git a/qa/src/late.meta b/qa/src/late.meta
new file mode 100644
index 0000000..b99a162
--- /dev/null
+++ b/qa/src/late.meta
Binary files differ
diff --git a/qa/src/logcontrol.c b/qa/src/logcontrol.c
new file mode 100644
index 0000000..cd0ca1a
--- /dev/null
+++ b/qa/src/logcontrol.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * Utility to control archive logging for metrics
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int i;
+ int j;
+ int sts;
+ int ctlport;
+ int pid = PM_LOG_PRIMARY_PID;
+ int port = PM_LOG_NO_PORT;
+ int newstate;
+ int errflag = 0;
+ char *host = "localhost";
+ char *namespace = NULL;
+ char *instance = (char *)0;
+ char *endnum;
+ int numpmid;
+ pmID *pmidlist;
+ char *control_arg;
+ int control;
+ char *state_arg;
+ int state;
+ pmResult *request;
+ pmDesc desc;
+ int inst;
+ pmResult *status;
+ int delta = 5000;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:h:i:n:P:p:r:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'h': /* hostname for PMCD to contact */
+ host = optarg;
+ break;
+
+ case 'i': /* instance identifier */
+ instance = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'P': /* port for pmlogger */
+ port = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: -P requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'p': /* pid for pmlogger */
+ pid = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: -p requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'r': /* logging delta */
+ delta = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: -r requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind > argc-2) {
+USAGE:
+ fprintf(stderr,
+"Usage: %s [options] action metric ...\n"
+"\n"
+"Options\n"
+" -D level set debug level\n"
+" -h hostname contact PMCD at this host\n"
+" -i instance apply only to this instance\n"
+" -n namespace use and alternative name space\n"
+" -P port port for pmlogger instance\n"
+" -p pid pid for pmlogger instance\n"
+" -r delta requested logging interval (msec)\n"
+"\n"
+"Actions\n"
+" mandatory {on|off|maybe}\n"
+" advisory {on|off}\n"
+" enquire\n"
+ , pmProgname);
+ exit(1);
+ }
+
+ control_arg = argv[optind++];
+ if (strcmp("mandatory", control_arg) == 0)
+ control = PM_LOG_MANDATORY;
+ else if (strcmp("advisory", control_arg) == 0)
+ control = PM_LOG_ADVISORY;
+ else if (strcmp("enquire", control_arg) == 0)
+ control = PM_LOG_ENQUIRE;
+ else
+ goto USAGE;
+
+ if (control == PM_LOG_ENQUIRE)
+ state = 0;
+ else {
+ state_arg = argv[optind++];
+ if (strcmp("on", state_arg) == 0)
+ state = PM_LOG_ON;
+ else if (strcmp("off", state_arg) == 0)
+ state = PM_LOG_OFF;
+ else if (control == PM_LOG_MANDATORY && strcmp("maybe", state_arg) == 0)
+ state = PM_LOG_MAYBE;
+ else
+ goto USAGE;
+ }
+
+ if (namespace != NULL && (sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = __pmConnectLogger(host, &pid, &port)) < 0) {
+ printf("%s: Cannot connect to pmlogger (%d) on host \"%s\": %s\n",
+ pmProgname, pid, host, pmErrStr(sts));
+ exit(1);
+ }
+ ctlport = sts;
+
+ numpmid = argc - optind;
+ pmidlist = (pmID *)malloc(numpmid * sizeof(pmID));
+
+ if ((sts = pmLookupName(numpmid, &argv[optind], pmidlist)) < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL) {
+ printf("Error: metric %s is unknown\n", argv[optind+i]);
+ exit(1);
+ }
+ if (instance != (char *)0) {
+ if ((sts = pmLookupDesc(pmidlist[i], &desc)) < 0) {
+ printf("pmDesc(%s %s): %s\n",
+ argv[optind+i], pmIDStr(pmidlist[i]), pmErrStr(sts));
+ exit(1);
+ }
+ if ((inst = pmLookupInDom(desc.indom, instance)) < 0) {
+ printf("pmLookupInDom(%s): %s\n", instance, pmErrStr(inst));
+ exit(1);
+ }
+ if ((sts = pmDelProfile(desc.indom, 0, (int *)0)) < 0) {
+ printf("pmDelProfile(%s): %s\n", pmInDomStr(desc.indom), pmErrStr(inst));
+ exit(1);
+ }
+ if ((sts = pmAddProfile(desc.indom, 1, &inst)) < 0) {
+ printf("pmAddProfile(%s): %s\n", pmInDomStr(desc.indom), pmErrStr(inst));
+ exit(1);
+ }
+ }
+ }
+
+ if ((sts = pmFetch(numpmid, pmidlist, &request)) < 0) {
+ printf("pmFetch: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ sts = __pmControlLog(ctlport, request, control, state, delta, &status);
+ if (sts < 0) {
+ printf("%s: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ for (i = 0; i < numpmid; i++) {
+ if ((sts = pmLookupDesc(pmidlist[i], &desc)) < 0) {
+ printf("pmDesc(%s): %s\n", pmIDStr(pmidlist[i]), pmErrStr(sts));
+ goto done;
+ }
+ printf("%s", argv[optind+i]);
+ if (status->vset[i]->numval < 0)
+ printf(" Error: %s\n", pmErrStr(status->vset[i]->numval));
+ else if (status->vset[i]->numval == 0)
+ printf(" No value?\n");
+ else {
+ for (j = 0; j < status->vset[i]->numval; j++) {
+ pmValue *vp = &status->vset[i]->vlist[j];
+ char *p;
+ if (status->vset[i]->numval > 1 || desc.indom != PM_INDOM_NULL) {
+ if (j == 0)
+ putchar('\n');
+ printf(" inst [%d", vp->inst);
+ if (pmNameInDom(desc.indom, vp->inst, &p) < 0)
+ printf(" or ???]");
+ else {
+ printf(" or \"%s\"]", p);
+ free(p);
+ }
+ }
+ newstate = PMLC_GET_STATE(vp->value.lval);
+ printf(" %d (%s %s", newstate,
+ PMLC_GET_MAND(vp->value.lval) ? "mand" : "adv",
+ PMLC_GET_ON(vp->value.lval) ? "on" : "off");
+ if (PMLC_GET_ON(vp->value.lval))
+ printf(", delta=%d msec", PMLC_GET_DELTA(vp->value.lval));
+ if (PMLC_GET_INLOG(vp->value.lval))
+ printf(", inlog");
+ if (PMLC_GET_AVAIL(vp->value.lval))
+ printf(", avail");
+ printf(")\n");
+ }
+ }
+ }
+
+ free(pmidlist);
+ pmFreeResult(request);
+ pmFreeResult(status);
+ if ((sts = pmWhichContext()) < 0) {
+ printf("%s: pmWhichContext: %s\n", pmProgname, pmErrStr(sts));
+ goto done;
+ }
+ pmDestroyContext(sts);
+
+done:
+ close(ctlport);
+ sleep(1);
+
+ exit(0);
+}
diff --git a/qa/src/logsummary-bug.0 b/qa/src/logsummary-bug.0
new file mode 100644
index 0000000..c13b2c2
--- /dev/null
+++ b/qa/src/logsummary-bug.0
Binary files differ
diff --git a/qa/src/logsummary-bug.index b/qa/src/logsummary-bug.index
new file mode 100644
index 0000000..f1c3e01
--- /dev/null
+++ b/qa/src/logsummary-bug.index
Binary files differ
diff --git a/qa/src/logsummary-bug.meta b/qa/src/logsummary-bug.meta
new file mode 100644
index 0000000..cfdfcd4
--- /dev/null
+++ b/qa/src/logsummary-bug.meta
Binary files differ
diff --git a/qa/src/make.dodgey b/qa/src/make.dodgey
new file mode 100755
index 0000000..ae223cf
--- /dev/null
+++ b/qa/src/make.dodgey
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+#
+# Make the various "dodgey" logs
+#
+
+. $PCP_DIR/etc/pcp.env
+
+if [ $# -ne 2 ]
+then
+ echo "Usage: make-dodgey type nsample"
+ exit 1
+fi
+
+if [ ! -f config.dodgey-$1 ]
+then
+ echo "make-dodgey: cannot find config file \"config.dodgey-$1\""
+ exit 1
+fi
+
+
+rm -f dodgey-$1.index dodgey-$1.meta dodgey-$1.0
+pmstore sample.dodgey.control 5
+pmlogger -c config.dodgey-$1 -s $2 dodgey-$1 &
+sleep 3; pmstore sample.dodgey.control 3
+sleep 3; pmstore sample.dodgey.control 4
+sleep 3; pmstore sample.dodgey.control 5
+sleep 3; pmstore sample.dodgey.control 0
+sleep 3; pmstore sample.dodgey.control 5
+sleep 3; pmstore sample.dodgey.control -1044
+sleep 3; pmstore sample.dodgey.control 5
+sleep 3
+
+wait
diff --git a/qa/src/mark-bug.0 b/qa/src/mark-bug.0
new file mode 100644
index 0000000..6729108
--- /dev/null
+++ b/qa/src/mark-bug.0
Binary files differ
diff --git a/qa/src/mark-bug.c b/qa/src/mark-bug.c
new file mode 100644
index 0000000..c9de132
--- /dev/null
+++ b/qa/src/mark-bug.c
@@ -0,0 +1,386 @@
+/*
+ * mark-bug - tests rewind over a mark (merged log)
+ *
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <unistd.h>
+#include <limits.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+char *namelist[2] = {"hinv.ncpu", "irix.kernel.all.cpu.idle"};
+pmID pmidlist[2];
+pmResult *result;
+struct timeval curpos;
+static void check_result(char *, pmResult *);
+
+static char timebuf[26];
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int i;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ int verbose = 0;
+ char *host = NULL; /* pander to gcc */
+ int mode = PM_MODE_INTERP; /* mode for archives */
+ char *configfile = NULL;
+ char *start = NULL;
+ char *finish = NULL;
+ char *align = NULL;
+ char *offset = NULL;
+ char *logfile = NULL;
+ pmLogLabel label; /* get hostname for archives */
+ int zflag = 0; /* for -z */
+ char *tz = NULL; /* for -Z timezone */
+ int tzh; /* initial timezone handle */
+ char local[MAXHOSTNAMELEN];
+ char *pmnsfile = PM_NS_DEFAULT;
+ int samples = -1;
+ double delta = 1.0;
+ char *endnum;
+ struct timeval startTime;
+ struct timeval endTime;
+ struct timeval appStart;
+ struct timeval appEnd;
+ struct timeval appOffset;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:A:c:D:h:l:Ln:O:s:S:t:T:U:VzZ:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'A': /* time alignment */
+ align = optarg;
+ break;
+
+ case 'c': /* configfile */
+ if (configfile != NULL) {
+ fprintf(stderr, "%s: at most one -c option allowed\n", pmProgname);
+ errflag++;
+ }
+ configfile = optarg;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'L': /* LOCAL, no PMCD */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ host = NULL;
+ type = PM_CONTEXT_LOCAL;
+ putenv("PMDA_LOCAL_PROC="); /* if proc PMDA needed */
+ putenv("PMDA_LOCAL_SAMPLE="); /* if sampledso PMDA needed */
+ break;
+
+ case 'l': /* logfile */
+ logfile = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ pmnsfile = optarg;
+ break;
+
+ case 'O': /* sample offset time */
+ offset = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples < 0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'S': /* start time */
+ start = optarg;
+ break;
+
+ case 't': /* delta seconds (double) */
+ delta = strtod(optarg, &endnum);
+ if (*endnum != '\0' || delta <= 0.0) {
+ fprintf(stderr, "%s: -t requires floating point argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'T': /* terminate time */
+ finish = optarg;
+ break;
+
+ case 'U': /* uninterpolated archive log */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ mode = PM_MODE_FORW;
+ host = optarg;
+ break;
+
+ case 'V': /* verbose */
+ verbose++;
+ break;
+
+ case 'z': /* timezone from host */
+ if (tz != NULL) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ zflag++;
+ break;
+
+ case 'Z': /* $TZ timezone */
+ if (zflag) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ tz = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (zflag && type == 0) {
+ fprintf(stderr, "%s: -z requires an explicit -a, -h or -U option\n", pmProgname);
+ errflag++;
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -A align time alignment\n\
+ -c configfile file to load configuration from\n\
+ -D debug standard PCP debug flag\n\
+ -h host metrics source is PMCD on host\n\
+ -l logfile redirect diagnostics and trace output\n\
+ -L use local context instead of PMCD\n\
+ -n pmnsfile use an alternative PMNS\n\
+ -O offset offset sample time\n\
+ -s samples terminate after this many iterations\n\
+ -S start start at this time\n\
+ -t delta sample interval in seconds(float) [default 1.0]\n\
+ -T finish finish at this time\n\
+ -U archive metrics source is an uninterpolated archive log\n\
+ -V verbose/diagnostic output\n\
+ -z set reporting timezone to local time for host from -a, -h or -U\n\
+ -Z timezone set reporting timezone\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (logfile != NULL) {
+ __pmOpenLog(pmProgname, logfile, stderr, &sts);
+ if (sts < 0) {
+ fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmProgname, logfile);
+ }
+ }
+
+ if (pmnsfile != PM_NS_DEFAULT && (sts = pmLoadNameSpace(pmnsfile)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname,
+ pmnsfile, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if (mode != PM_MODE_INTERP) {
+ if ((sts = pmSetMode(mode, &label.ll_start, 0)) < 0) {
+ fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ startTime = label.ll_start;
+ sts = pmGetArchiveEnd(&endTime);
+ if (sts < 0) {
+ fprintf(stderr, "%s: pmGetArchiveEnd: %s\n", pmProgname,
+ pmErrStr(sts));
+ exit(1);
+ }
+ }
+ else {
+ gettimeofday(&startTime, NULL);
+ endTime.tv_sec = INT_MAX;
+ }
+
+ if (zflag) {
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+ if (type == PM_CONTEXT_ARCHIVE)
+ printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n",
+ label.ll_hostname);
+ else
+ printf("Note: timezone set to local timezone of host \"%s\"\n\n", host);
+ }
+ else if (tz != NULL) {
+ if ((tzh = pmNewZone(tz)) < 0) {
+ fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n",
+ pmProgname, tz, pmErrStr(tzh));
+ exit(1);
+ }
+ printf("Note: timezone set to \"TZ=%s\"\n\n", tz);
+ }
+ else
+ tzh = pmNewContextZone();
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ while (optind < argc) {
+ printf("extra argument[%d]: %s\n", optind, argv[optind]);
+ optind++;
+ }
+
+ if (align != NULL && type != PM_CONTEXT_ARCHIVE) {
+ fprintf(stderr, "%s: -A option only supported for PCP archives, alignment request ignored\n",
+ pmProgname);
+ align = NULL;
+ }
+
+ sts = pmParseTimeWindow(start, finish, align, offset, &startTime,
+ &endTime, &appStart, &appEnd, &appOffset,
+ &endnum);
+
+ if (sts < 0) {
+ fprintf(stderr, "%s: %s\n", pmProgname, endnum);
+ exit(1);
+ }
+
+ if ((sts = pmLookupName(2, namelist, pmidlist)) < 0) {
+ fprintf(stderr, "%s: pmLookupName failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* goto the start */
+ if ((sts = pmSetMode(PM_MODE_INTERP, &appStart, (int)(delta * 1000))) < 0) {
+ fprintf(stderr, "%s: pmSetMode failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ pmCtime(&appStart.tv_sec, timebuf);
+ printf("archive %s\nstartTime: %.24s+%-8d\n",
+ host, timebuf, (int)appStart.tv_usec);
+ pmCtime(&appEnd.tv_sec, timebuf);
+ printf("endTime : %.24s+%-8d\nsamples=%d delta=%dms\n",
+ timebuf, (int)appEnd.tv_usec, samples, (int)(delta * 1000));
+
+ /* play forwards over the mark */
+ for (i=0; i < samples; i++) {
+ if ((sts = pmFetch(2, pmidlist, &result)) < 0) {
+ fprintf(stderr, "%s: pmFetch failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ check_result("forwards ", result);
+ curpos = result->timestamp; /* struct cpy */
+ pmFreeResult(result);
+ }
+
+ /* rewind back over the mark */
+ if ((sts = pmSetMode(PM_MODE_INTERP, &curpos, (int)(delta * -1000))) < 0) {
+ fprintf(stderr, "%s: pmSetMode failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ for (i=0; i < samples; i++) {
+ if ((sts = pmFetch(2, pmidlist, &result)) < 0) {
+ fprintf(stderr, "%s: pmFetch failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ check_result("rewinding", result);
+ pmFreeResult(result);
+ }
+
+
+ return 0;
+}
+
+static void
+check_result(char *title, pmResult *result)
+{
+ int err= 0;
+ if (result->numpmid != 2) {
+ pmCtime(&result->timestamp.tv_sec, timebuf);
+ printf("%s @ %.24s+%-8d numpmid=%d\n", title,
+ timebuf, (int)result->timestamp.tv_usec, result->numpmid);
+ err++;
+ }
+ if (result->numpmid >= 0 && result->vset[0]->numval != 1) {
+ pmCtime(&result->timestamp.tv_sec, timebuf);
+ printf("%s @ %.24s+%-8d vset[0]->numval=%d\n", title,
+ timebuf, (int)result->timestamp.tv_usec, result->vset[0]->numval);
+ err++;
+ }
+ if (result->numpmid >= 1 && result->vset[1]->numval != 1) {
+ pmCtime(&result->timestamp.tv_sec, timebuf);
+ printf("%s @ %.24s+%-8d vset[1]->numval=%d\n", title,
+ timebuf, (int)result->timestamp.tv_usec, result->vset[0]->numval);
+ err++;
+ }
+ if (err == 0) {
+ pmCtime(&result->timestamp.tv_sec, timebuf);
+ printf("fetch OK %s @ %.24s+%-8d\n", title,
+ timebuf, (int)result->timestamp.tv_usec);
+ }
+}
diff --git a/qa/src/mark-bug.index b/qa/src/mark-bug.index
new file mode 100644
index 0000000..0e99776
--- /dev/null
+++ b/qa/src/mark-bug.index
Binary files differ
diff --git a/qa/src/mark-bug.meta b/qa/src/mark-bug.meta
new file mode 100644
index 0000000..c1afde3
--- /dev/null
+++ b/qa/src/mark-bug.meta
Binary files differ
diff --git a/qa/src/markmerge.0 b/qa/src/markmerge.0
new file mode 100644
index 0000000..c007356
--- /dev/null
+++ b/qa/src/markmerge.0
Binary files differ
diff --git a/qa/src/markmerge.index b/qa/src/markmerge.index
new file mode 100644
index 0000000..5d8da19
--- /dev/null
+++ b/qa/src/markmerge.index
Binary files differ
diff --git a/qa/src/markmerge.meta b/qa/src/markmerge.meta
new file mode 100644
index 0000000..ec382f4
--- /dev/null
+++ b/qa/src/markmerge.meta
Binary files differ
diff --git a/qa/src/matchInstanceName.c b/qa/src/matchInstanceName.c
new file mode 100644
index 0000000..efcad9d
--- /dev/null
+++ b/qa/src/matchInstanceName.c
@@ -0,0 +1,36 @@
+/*
+ * for PV 939998 affecting pmgadgets instance cache
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+static int
+matchInstanceName(char *p, char *q)
+{
+ for (;; p++, q++) {
+ if ((*p == ' ' || *p == '\0') &&
+ (*q == ' ' || *q == '\0'))
+ return 1;
+
+ if (*p != *q || *p == ' ' || *p == '\0' ||
+ *q == ' ' || *q == '\0')
+ return 0;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *a = argv[1];
+ char *b = argv[2];
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s string1 string2\n", argv[0]);
+ exit(1);
+ }
+
+ printf("\"%s\" \"%s\" %s\n", a, b,
+ matchInstanceName(a, b) ? "true" : "false");
+ exit(0);
+}
diff --git a/qa/src/memcachestats.pl b/qa/src/memcachestats.pl
new file mode 100755
index 0000000..a2bfb28
--- /dev/null
+++ b/qa/src/memcachestats.pl
@@ -0,0 +1,66 @@
+#!/usr/bin/perl -w
+
+#
+# liberally borrowed from memcache-top at
+# https://code.google.com/p/memcache-top/
+#
+
+use strict;
+use IO::Socket;
+use Getopt::Long;
+
+my (@default_instances, @instances, $remote, $default_port);
+
+# List of servers/ ports to query.
+@default_instances = ( '127.0.0.1:11211' );
+
+# Default port to connect to, if not specified
+$default_port = "11211";
+
+if (@ARGV) {
+ GetOptions (
+ 'instances=s' => \@instances,
+ 'port=i' => \$default_port,
+ );
+ if (@instances) {
+ @instances = split(/,/,join(',',@instances));
+ } else {
+ @instances = @default_instances;
+ }
+}
+else {
+ @instances = @default_instances;
+}
+
+foreach my $instance (@instances) {
+
+ my ($server);
+
+ my @split = split(/:/,$instance);
+ unless ( $split[1] ) {
+ $instance = $instance . ":" . $default_port;
+ }
+
+ $remote = IO::Socket::INET->new($instance);
+ unless ( defined($remote) ) {
+ print "no cigar: $!\n";
+ exit(1);
+ }
+ $remote->autoflush(1);
+
+ my @commands = ("stats", "stats slabs", "stats items" );
+ foreach my $command (@commands) {
+ print $remote "$command\n";
+
+ LINE: while ( defined ( my $line = <$remote> ) ) {
+ last LINE if ( $line =~ /^END/ );
+ chomp $line;
+ $line =~ s/^STAT //;
+ $line =~ s/ //;
+ print $line . "\n";
+ next LINE;
+ }
+ }
+
+ close $remote;
+}
diff --git a/qa/src/mirage-1.0 b/qa/src/mirage-1.0
new file mode 100644
index 0000000..7bb29c1
--- /dev/null
+++ b/qa/src/mirage-1.0
Binary files differ
diff --git a/qa/src/mirage-1.index b/qa/src/mirage-1.index
new file mode 100644
index 0000000..2af5077
--- /dev/null
+++ b/qa/src/mirage-1.index
Binary files differ
diff --git a/qa/src/mirage-1.meta b/qa/src/mirage-1.meta
new file mode 100644
index 0000000..cf84ca6
--- /dev/null
+++ b/qa/src/mirage-1.meta
Binary files differ
diff --git a/qa/src/mirage-2.0 b/qa/src/mirage-2.0
new file mode 100644
index 0000000..1fa050f
--- /dev/null
+++ b/qa/src/mirage-2.0
Binary files differ
diff --git a/qa/src/mirage-2.index b/qa/src/mirage-2.index
new file mode 100644
index 0000000..dd40f52
--- /dev/null
+++ b/qa/src/mirage-2.index
Binary files differ
diff --git a/qa/src/mirage-2.meta b/qa/src/mirage-2.meta
new file mode 100644
index 0000000..5bfdfa3
--- /dev/null
+++ b/qa/src/mirage-2.meta
Binary files differ
diff --git a/qa/src/mirage.0 b/qa/src/mirage.0
new file mode 100644
index 0000000..1e6d68e
--- /dev/null
+++ b/qa/src/mirage.0
Binary files differ
diff --git a/qa/src/mirage.index b/qa/src/mirage.index
new file mode 100644
index 0000000..6daca30
--- /dev/null
+++ b/qa/src/mirage.index
Binary files differ
diff --git a/qa/src/mirage.meta b/qa/src/mirage.meta
new file mode 100644
index 0000000..37dba30
--- /dev/null
+++ b/qa/src/mirage.meta
Binary files differ
diff --git a/qa/src/mkarch-all b/qa/src/mkarch-all
new file mode 100755
index 0000000..7120842
--- /dev/null
+++ b/qa/src/mkarch-all
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+if [ $# -ne 2 ]
+then
+ echo "Usage: mkarch-all hostname archive"
+ exit 1
+fi
+
+rm -f $2.0 $2.meta $2.index $2.log
+
+cat <<End-of-File | pmlogger -l $2.log -t 3 -T 10s -h $1 $2
+log mandatory on once hinv
+log mandatory on once hw
+
+log mandatory on default buffer_cache
+log mandatory on default cihb
+log mandatory on default cms
+log mandatory on default cxfs
+log mandatory on default disk
+log mandatory on default espping
+log mandatory on default filesys
+log mandatory on default gfx
+log mandatory on default ipc
+log mandatory on default kaio
+log mandatory on default kernel
+log mandatory on default mem
+log mandatory on default name_cache
+log mandatory on default network
+log mandatory on default nfs
+log mandatory on default nfs3
+log mandatory on default numa
+log mandatory on default origin
+log mandatory on default pmcd
+log mandatory on default pmda
+log mandatory on default resource
+log mandatory on default rpc
+log mandatory on default stream
+log mandatory on default swap
+log mandatory on default swapdev
+log mandatory on default udf
+log mandatory on default vfs
+log mandatory on default vnodes
+log mandatory on default xbow
+log mandatory on default xfs
+log mandatory on default xlv
+End-of-File
+
+echo "Archive $2 created, log in $2.log"
diff --git a/qa/src/mkbadlen b/qa/src/mkbadlen
new file mode 100755
index 0000000..c77b3b2
--- /dev/null
+++ b/qa/src/mkbadlen
@@ -0,0 +1,110 @@
+#!/bin/sh
+#
+# Recipes for making badlen-* family of archives.
+#
+# Every one is based on a version of foo, with binary editing using
+# bvi (or similar) and cut-n-paste with dd.
+
+tmp=/var/tmp/$$
+trap "rm -f $tmp.*; exit 0" 0 1 2 3 15
+
+# Set up for a new badlen-X archive
+#
+X=0
+while true
+do
+ [ ! -f badlen-$X.index ] && break
+ X=`expr $X + 1`
+ if [ $X -eq 100 ]
+ then
+ echo "Botch: all archives badlen-0...badlen-99 already exist?"
+ exit 1
+ fi
+done
+if [ $X -eq 0 ]
+then
+ cp foo.0 badlen-0.0
+ cp foo.meta badlen-0.meta
+ cp foo.index badlen-0.index
+ X=1
+fi
+
+ln badlen-0.meta badlen-$X.meta
+ln badlen-0.index badlen-$X.index
+
+case $X
+in
+ 1) # Trailer len of first pmResult smaller than header len.
+ cp foo.0 badlen-$X.0
+ echo '263s\\.\\80\\' >$tmp.ex
+ ;;
+
+ 2) # Data file truncated just before first trailer record ... 132
+ # bytes for label and 128 (4 bytes short) for first data record.
+ dd if=badlen-0.0 of=badlen-$X.0 bs=1 count=260
+ ;;
+
+ 3) # Data file truncated mid way thru first pmResult ... 132 bytes for
+ # label and 120 (12 bytes short) for first partial data record.
+ dd if=badlen-0.0 of=badlen-$X.0 bs=1 count=252
+ ;;
+
+ 4) # Empty data file
+ echo >badlen-$X.0
+ ;;
+
+ 5) # Short label record (42 bytes, not 132)
+ dd if=badlen-0.0 of=badlen-$X.0 bs=1 count=42
+ ;;
+
+ 6) # Label header len 64 not 132 as expected
+ cp foo.0 badlen-$X.0
+ echo '3s\\.\\40\\' >$tmp.ex
+ ;;
+
+ 7) # Label trailer len 64 not 132 as expected
+ cp foo.0 badlen-$X.0
+ echo '131s\\.\\40\\' >$tmp.ex
+ ;;
+
+ 8) # Label bad PM_LOG_VER
+ cp foo.0 badlen-$X.0
+ echo '7s\\.\\FF\\' >$tmp.ex
+ ;;
+
+ 9) # Truncated metadata file
+ cp foo.0 badlen-$X.0
+ cp foo.index badlen-$X.index
+ rm -f badlen-$X.meta
+ dd if=foo.meta of=badlen-$X.meta bs=1 count=840
+ ;;
+
+ 10) # Data file truncated in trailer of label record
+ dd if=badlen-0.0 of=badlen-$X.0 bs=1 count=131
+ ;;
+
+ 11) # Data file truncated in header of first pmResult
+ dd if=badlen-0.0 of=badlen-$X.0 bs=1 count=133
+ ;;
+
+esac
+
+if [ -f $tmp.ex ]
+then
+ echo 'w' >>$tmp.ex
+ echo 'q' >>$tmp.ex
+
+ if which bvi >/dev/null 2>&1
+ then
+ bvi -f $tmp.ex badlen-$X.0
+ else
+ echo "bvi not installed"
+ echo "Need to apply the equivalent of this binary editing to badlen-$X.0"
+ cat $tmp.ex
+ fi
+fi
+
+echo "badlen-$X created."
+
+exit
+
diff --git a/qa/src/mkbadti b/qa/src/mkbadti
new file mode 100755
index 0000000..bcb27b0
--- /dev/null
+++ b/qa/src/mkbadti
@@ -0,0 +1,107 @@
+#!/bin/sh
+#
+# Recipes for making badti-* family of archives.
+#
+# Every one is based on a version of ok-foo, with binary editing using
+# bvi (or similar) and cut-n-paste with dd.
+#
+# This is the good temporal index
+#
+# Timestamp Log Vol end(meta) end(log) offset
+# 0 <- label record
+# 04:34:32.257 0 132 132 132
+# 04:34:33.248 0 350 284 152
+# 04:34:40.258 0 851 1768 172
+# 191 <- EOF
+
+tmp=/var/tmp/$$
+trap "rm -f $tmp.*; exit 0" 0 1 2 3 15
+
+# Set up for a new badti-X archive
+#
+X=`ls badti-*.index 2>/dev/null | tail -1 | sed -e 's/badti-//' -e 's/\.index//'`
+if [ -z "$X" ]
+then
+ X=1
+else
+ X=`expr $X + 1`
+fi
+
+ln ok-foo.meta badti-$X.meta
+ln ok-foo.0 badti-$X.0
+
+case $X
+in
+ 1) # index broken in the middle of an entry
+ dd if=ok-foo.index of=badti-$X.index bs=1 count=162
+ ;;
+
+ 2) # entry[2] volume is negative
+ # entry[2] tv_usec in timestamp is >99999
+ # entry[3] tv_sec in timestamp is negative
+ # entry[3] tv_usec in timestamp is negative
+ cp ok-foo.index badti-$X.index
+ echo '140s\\....\\FFFFFFFF\\' >$tmp.ex
+ echo '136s\\....\\000F4240\\' >>$tmp.ex
+ echo '172s\\....\\FFFFFFFE\\' >>$tmp.ex
+ echo '176s\\....\\FFFFFFFC\\' >>$tmp.ex
+ ;;
+
+ 3) # entry[1] volume -> non existant file, and then volume goes backwards
+ # entry[3] meta and log offsets past end of file
+ cp ok-foo.index badti-$X.index
+ echo '132s\\....\\00000002\\' >$tmp.ex
+ echo '184s\\....\\00000354\\' >>$tmp.ex
+ echo '188s\\....\\000007B9\\' >>$tmp.ex
+ ;;
+
+ 4) # tv_usec in timestamp is negative
+ cp ok-foo.index badti-$X.index
+ ;;
+
+ 5) # Short label record (42 bytes, not 132)
+ dd if=badti-0.0 of=badti-$X.0 bs=1 count=42
+ ;;
+
+ 6) # Label header len 64 not 132 as expected
+ cp ok-foo.0 badti-$X.0
+ echo '3s\\.\\40\\' >$tmp.ex
+ ;;
+
+ 7) # Label trailer len 64 not 132 as expected
+ cp ok-foo.0 badti-$X.0
+ echo '131s\\.\\40\\' >$tmp.ex
+ ;;
+
+ 8) # Label bad PM_LOG_VER
+ cp ok-foo.0 badti-$X.0
+ echo '7s\\.\\FF\\' >$tmp.ex
+ ;;
+
+ 9) # Truncated metadata file
+ cp ok-foo.0 badti-$X.0
+ cp ok-foo.index badti-$X.index
+ rm -f badti-$X.meta
+ dd if=ok-foo.meta of=badti-$X.meta bs=1 count=840
+
+esac
+
+if [ -f $tmp.ex ]
+then
+ echo 'w' >>$tmp.ex
+ echo 'q' >>$tmp.ex
+
+ if which bvi >/dev/null 2>&1
+ then
+ bvi -f $tmp.ex badti-$X.index
+ else
+ echo "bvi not installed"
+ echo "Need to apply the equivalent of this binary editing to badti-$X.0"
+ cat $tmp.ex
+ fi
+fi
+
+echo "badti-$X created."
+
+exit
+
diff --git a/qa/src/mkbig1 b/qa/src/mkbig1
new file mode 100755
index 0000000..3c35faf
--- /dev/null
+++ b/qa/src/mkbig1
@@ -0,0 +1,78 @@
+#!/bin/sh
+#
+# remake the big1 archive.
+# Needs a lot of disk space, so is guarded by df check ... output
+# archive is used by multiple tests. If return code is non-zero,
+# then output is suitable for a notrun message.
+#
+# Copyright (c) 2012 Red Hat.
+# Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+#
+
+[ -f ../common.rc ] && cd .. # from src directory
+. ./common.rc # for $sudo, $tmp, $here and pcp.env
+. ./common.check
+
+# cleanup any archives in the old location (not src)
+$sudo rm -f big1.*
+
+# don't recreate the archive unless we really have to
+[ -s src/big1.0 -a -s src/big1.1 -a -s src/big1.index -a -s src/big1.meta ] && exit 0
+
+# 10GB should keep us out of trouble
+free=`_check_freespace 10240`
+if [ -n "$free" ]
+then
+ echo $free
+ exit 1
+fi
+
+status=1
+iam=mkbig1
+$sudo rm -rf $tmp.*
+trap "_cleanup; rm -f $tmp.*; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ if [ ! -f $tmp.done ]
+ then
+ cd $here/pmdas/bigun
+ $sudo ./Remove >>$here/src/$iam.log
+ cd $here
+ touch $tmp.done
+ fi
+}
+
+cd $here/pmdas/bigun
+make >$here/src/$iam.log 2>&1
+$sudo ./Install </dev/null >>$here/src/$iam.log
+if [ $? != 0 ]
+then
+ echo "bigun pmda Install failed ... see $here/src/$iam.log"
+ exit
+fi
+if pmprobe bigun 2>&1 | tee -a $here/src/$iam.log | grep ' [0-9]$'
+then
+ :
+else
+ echo "bigun pmda Install failed ... see $here/src/$iam.log"
+ exit
+fi
+cd $here
+
+cat <<End-of-File >$tmp.config
+log mandatory on default {
+ bigun
+ sample.hordes
+}
+End-of-File
+
+$sudo rm -f big1.*
+pmlogger -r -c $tmp.config -l $tmp.out -t 10msec -s 2049 src/big1
+echo >>$here/src/$iam.log
+cat $tmp.out >>$here/src/$iam.log
+echo >>$here/src/$iam.log
+ls -l src/big1.* >>$here/src/$iam.log
+
+status=0
+exit
diff --git a/qa/src/mkeventrec b/qa/src/mkeventrec
new file mode 100755
index 0000000..ab82b56
--- /dev/null
+++ b/qa/src/mkeventrec
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# create the eventrec archive
+#
+. $PCP_DIR/etc/pcp.env
+
+pmstore sample.event.reset 3
+
+rm -f eventrec.0 eventrec.meta eventrec.index pmlogger.log
+
+cat <<End-of-File | pmlogger -s 5 eventrec
+log mandatory on 1 sec {
+ sample.event.records
+ sample.event.highres_records
+ sample.event.no_indom_records
+ sample.colour
+ sampledso.event.records
+ sampledso.event.no_indom_records
+}
+End-of-File
+
+cat pmlogger.log
diff --git a/qa/src/mkfiles.c b/qa/src/mkfiles.c
new file mode 100644
index 0000000..0a241af
--- /dev/null
+++ b/qa/src/mkfiles.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+/* Be careful when changing LIMIT. Also change malloc and sprintf! */
+
+#define LIMIT 10000 /* max nfiles allowed */
+
+static void
+usage (void)
+{
+ fprintf(stderr, "Usage %s: basename nfiles\n", pmProgname);
+ exit(1);
+}
+
+int
+main(int argc, char* argv[])
+{
+ char *endp;
+ long nfiles;
+ char *namebuf;
+ char *extptr;
+ int i, sts;
+
+ __pmSetProgname(argv[0]);
+
+ if (argc != 3)
+ usage();
+
+ nfiles = strtol(argv[2], &endp, 0);
+ if (*endp != '\0') {
+ fprintf(stderr, "nfiles \"%s\" is not numeric\n", argv[2]);
+ usage();
+ }
+ if (nfiles > LIMIT) {
+ fprintf(stderr, "be reasonable: nfiles limited to %d\n", LIMIT);
+ usage();
+ }
+
+ i = (int)strlen(argv[1]);
+ namebuf = (char *)malloc(i + 6);
+ if (namebuf == (char *)0) {
+ perror("error allocating filename buffer");
+ exit(1);
+ }
+ strcpy(namebuf, argv[1]);
+ namebuf[i++] = '.';
+ extptr = &namebuf[i];
+
+ for (i = 0; i < nfiles; i++) {
+ sprintf(extptr, "%04d", i);
+ if ((sts = creat(namebuf, 0777)) < 0) {
+ fprintf(stderr, "Error creating %s: %s\n", namebuf, strerror(errno));
+ exit(1);
+ }
+ else
+ close(sts);
+ }
+ exit(0);
+}
diff --git a/qa/src/mkinterpmark b/qa/src/mkinterpmark
new file mode 100755
index 0000000..fd9d034
--- /dev/null
+++ b/qa/src/mkinterpmark
@@ -0,0 +1,148 @@
+#!/bin/sh
+#
+# Recipe to recreate the interpmark archive
+#
+# Final archive is
+# section-a
+# <mark>
+# section-b
+# <mark>
+# section-c
+# <mark>
+# [nothing]
+# <mark>
+# section-d
+#
+# section-a contains metrics from this matrix
+# semantics { counter, discrete, instant } x
+# type { 32-bit, 64-bit } x
+# instances { singular, indom } x
+# sample intervals { 500msec, 2sec, 10sec (once or 2sec for discrete) }
+# for a total time of 35 seconds
+#
+# metric semantics type indom sample
+# disk.dev.read counter U64 60.1 500msec
+# disk.dev.write counter U64 60.1 2sec
+# disk.dev.total counter U64 60.1 10sec
+# disk.all.read counter U64 NULL 500msec
+# disk.all.write counter U64 NULL 2sec
+# disk.all.total counter U64 NULL 10sec
+# disk.dev.read_bytes counter U32 60.1 500msec
+# disk.dev.write_bytes counter U32 60.1 2sec
+# disk.dev.total_bytes counter U32 60.1 10sec
+# disk.all.read_bytes counter U32 NULL 500msec
+# disk.all.write_bytes counter U32 NULL 2sec
+# disk.all.total_bytes counter U32 NULL 10sec
+#
+# filesys.used instant U64 60.5 500msec
+# sample.longlong.bin instant 64 29.2 2sec
+# filesys.free instant U64 60.5 10sec
+# sample.longlong.one instant 64 NULL 500msec
+# swap.length instant U64 NULL 2sec
+# mem.util.kernelStack instant U64 NULL 10sec
+# filesys.usedfiles instant U32 60.5 500msec
+# swapdev.free instant U32 60.6 2sec
+# pmcd.buf.alloc instant 32 2.5 10sec
+# sample.control instant 32 NULL 500msec
+# kernel.all.uptime instant U32 NULL 2sec
+# network.tcpconn.close instant U32 NULL 10sec
+#
+# filesys.capacity discrete U64 60.5 2sec
+# tmpfs.capacity discrete U64 60.18 once
+#
+# mem.physmem discrete U64 NULL 2sec
+#
+# filesys.capacity discrete U32 60.5 2sec
+# hinv.cpu.cache discrete U32 60.0 once
+# filesys.maxfiles discrete U32 60.5 once
+# hinv.physmem discrete U32 NULL 2sec
+# hinv.pagesize discrete U32 NULL once
+# hinv.ncpu discrete U32 NULL once
+#
+# section-b and section-d are the same as section-a (same pmlogger config)
+#
+# section-c contains only one sample for the 500msec sampling data
+#
+
+tmp=/var/tmp/$$
+trap "rm -f $tmp.*; exit 0" 0 1 2 3 15
+
+cat >$tmp.conf <<End-of-File
+log mandatory on once {
+ tmpfs.capacity
+ hinv.cpu.cache
+ filesys.maxfiles
+ hinv.pagesize
+ hinv.ncpu
+}
+
+log mandatory on 500msec {
+ disk.dev.read
+ disk.all.read
+ disk.dev.read_bytes
+ disk.all.read_bytes
+ filesys.used
+ sample.longlong.one
+ filesys.usedfiles
+ sample.control
+}
+
+log mandatory on 2sec {
+ disk.dev.write
+ disk.all.write
+ disk.dev.write_bytes
+ disk.all.write_bytes
+ sample.longlong.bin
+ swap.length
+ swapdev.free
+ kernel.all.uptime
+ filesys.capacity
+ mem.physmem
+ filesys.capacity
+ hinv.physmem
+}
+
+log mandatory on 10sec {
+ disk.dev.total
+ disk.all.total
+ disk.dev.total_bytes
+ disk.all.total_bytes
+ filesys.free
+ mem.util.kernelStack
+ pmcd.buf.alloc
+ network.tcpconn.close
+}
+End-of-File
+
+cat >$tmp.conf.c <<End-of-File
+log mandatory on once {
+ disk.dev.read
+ disk.all.read
+ disk.dev.read_bytes
+ disk.all.read_bytes
+ filesys.used
+ sample.longlong.one
+ filesys.usedfiles
+ sample.control
+}
+End-of-File
+
+echo "section-a"
+rm -f section-a.*
+pmlogger -c $tmp.conf -l a.log -T +35sec section-a
+sleep 2
+echo "section-b"
+rm -f section-b.*
+pmlogger -c $tmp.conf -l b.log -T +35sec section-b
+sleep 2
+echo "section-c"
+rm -f section-c.*
+pmlogger -c $tmp.conf.c -l c.log -s 1 section-c
+sleep 10
+echo "section-d"
+rm -f section-d.*
+pmlogger -c $tmp.conf -l d.log -T +35sec section-d
+
+rm interpmark.*
+pmlogextract section-a section-b section-c section-d interpmark
+
diff --git a/qa/src/mkmirage b/qa/src/mkmirage
new file mode 100755
index 0000000..318a998
--- /dev/null
+++ b/qa/src/mkmirage
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# remake the mirage-1 and mirage-2 archives ... these are
+# intended to be checked in and not remade, this script is
+# simply a record of how they were created.
+#
+
+tmp=/var/tmp/$$
+rm -f $tmp.*
+trap "rm -f $tmp.*; exit 0" 0 1 2 3 15
+
+cat <<End-of-File >>$tmp.config
+log mandatory on default {
+ sample.mirage
+ sample.bin
+ sample.many.int
+}
+End-of-File
+
+rm -r mirage-1.* mirage-2.*
+
+pmlogger -t 3sec -c $tmp.config -s 15 mirage-1 &
+sleep 5
+pmstore sample.many.count 5
+pmlogger -t 1sec -c $tmp.config -s 10 mirage-2 &
+i=6
+while [ $i -lt 12 ]
+do
+ sleep 1
+ pmstore sample.many.count $i
+ i=`expr $i + 1`
+done
+wait
+pmstore sample.many.count 5
+
diff --git a/qa/src/mkmultihost b/qa/src/mkmultihost
new file mode 100755
index 0000000..2706f2a
--- /dev/null
+++ b/qa/src/mkmultihost
@@ -0,0 +1,65 @@
+#!/bin/sh
+#
+# recreate the multiple concurrent archives ... multi-<host>
+#
+
+tmp=/var/tmp/$$
+sts=0
+trap "rm -f $tmp.*; exit \$sts" 0 1 2 3 15
+
+cat <<End-of-File >$tmp.config
+log mandatory on default {
+ hinv
+ sampledso.colour
+ sampledso.bin
+ sampledso.part_bin
+ sampledso.drift
+ sampledso.kbyte_ctr
+ sampledso.kbyte_rate
+ sampledso.ulong
+ sampledso.longlong
+ sampledso.double
+ sampledso.scale_step
+ sampledso.const_rate
+}
+End-of-File
+
+rm -f $tmp.bad
+for host
+do
+ for ext in 0 index meta
+ do
+ [ -f multi-"$host".$ext ] && echo "$0: multi-$host.$ext exists" && touch $tmp.bad
+ done
+done
+
+if [ -f $tmp.bad ]
+then
+ echo "$0: Need to rm archives first ... we won't clobber 'em by default"
+ sts=1
+ exit
+fi
+
+# randomize the pmcd's a little
+#
+for host
+do
+ rm -f $tmp.tmp.* $tmp.$host
+ date >/dev/null 2>&1 &
+ n=`echo $! | awk '{ srand($1); print int(rand()*5)+1 }'`
+ echo "$host: prime with $n samples"
+ pmlogger -t 100msec -s $n -l $tmp.$host -c $tmp.config -T10sec -h $host $tmp.tmp
+done
+
+for host
+do
+ pmlogger -t 2sec -l $tmp.$host -c $tmp.config -T10sec -h $host multi-$host &
+done
+
+wait
+
+for host
+do
+ cat $tmp.$host
+done
+
diff --git a/qa/src/mknuma b/qa/src/mknuma
new file mode 100755
index 0000000..4ea5b45
--- /dev/null
+++ b/qa/src/mknuma
@@ -0,0 +1,37 @@
+#!/bin/sh
+#
+# remake the numa archive ...
+# this archive is intended to be checked in and not remade, this script is
+# simply a record of how it was created
+#
+
+. /etc/pcp.env
+
+tmp=/var/tmp/$$
+rm -f $tmp.*
+trap "rm -f $tmp.*; exit 0" 0 1 2 3 15
+
+nnode=`pmprobe -v hinv.nnode | $PCP_AWK_PROG '{print $NF}'`
+if [ -z "$nnode" -o "$nnode" -lt 2 ]
+then
+ echo "$0: Error: hinv.nnode ($nnode) not > 1"
+ exit 1
+fi
+
+cat <<End-of-File >>$tmp.config
+log mandatory on once {
+ hinv
+}
+
+log mandatory on 1 sec {
+ mem.numa.alloc
+ kernel.pernode
+End-of-File
+
+pminfo mem.vmstat | grep numa_ | sed -e 's/^/ /' >>$tmp.config
+
+echo "}" >>$tmp.config
+
+rm -f numa.0 numa.meta numa.index
+
+pmlogger -s 10 -c $tmp.config numa
diff --git a/qa/src/mkpermslist b/qa/src/mkpermslist
new file mode 100755
index 0000000..4738eec
--- /dev/null
+++ b/qa/src/mkpermslist
@@ -0,0 +1,209 @@
+#!/bin/sh
+#
+# Build a new QA permslist file by descend the source tree finding
+# install lines for files with non-default mode (not 0644 for files or
+# 0755 for directories) and/or non-default user and group (not root)
+#
+
+. /etc/pcp.env
+
+tmp=/var/tmp/$$
+sts=0
+TOP=../..
+trap "rm -f $tmp.*; exit \$sts" 0 1 2 3 15
+
+cat <<End-of-File >$tmp.new
+# Control file of targets from the PCP source code that are installed
+# with non-default mode and/or owner and/or group permissions.
+# Generate by qa/src/mkpermslist on `date`
+#
+End-of-File
+
+rm -f tmp.debug.*
+( cd $TOP ; find GNU* src -type f -name "GNU*" ) \
+| while read makefile
+do
+ rm -f $tmp.raw
+ grep -i 'INSTALL' $TOP/$makefile >$tmp.tmp
+ #debug# cat $tmp.tmp >>tmp.debug.0
+ # check for -m xxx for xxx not 644 or 755
+ #
+ sed -n <$tmp.tmp >>$tmp.raw \
+ -e '/-m[ ][ ]*/{
+/-m[ ][ ]*644/d
+/-m[ ][ ]*755/d
+s/\(-[a-z]\)[ ][ ]*/\1/g
+p
+}'
+ # check for -g or -o
+ #
+ sed -n <$tmp.tmp >>$tmp.raw \
+ -e '/-[og][ ][ ]*/{
+/-[og][ ][ ]*root/d
+s/\(-[a-z]\)[ ][ ]*/\1/g
+p
+}'
+ # expand PCP env vars we expect to find
+ #
+ sed <$tmp.raw >$tmp.tmp \
+ -e 's/$(INSTALL)//' \
+ -e "s@^@$makefile@"
+ mv $tmp.tmp $tmp.raw
+
+ # special cases ... these are makefile lines that do not match
+ # the generic format and need special handling on a per makefile
+ # basis
+ #
+ case "$makefile"
+ in
+ GNUmakefile)
+ # this INSTALL line is optional depending on packaging
+ # $(INSTALL) -m 775 -g $(PCP_GROUP) -d $(PCP_RUN_DIR)
+ #
+ sed -e '/PCP_RUN_DIR)$/s/$/|optional/' <$tmp.raw >$tmp.tmp
+ diff $tmp.raw $tmp.tmp >tmp.debug.2
+ mv $tmp.tmp $tmp.raw
+ ;;
+
+ src/libpcp_pmcd/src/GNUmakefile)
+ # this INSTALL line is optional depending on platform and
+ # build options
+ # $(INSTALL) -m 444 pmcd.stp $(PCP_SHARE_DIR)/../systemtap/tapset/pmcd.stp
+ sed -e '/pmcd.stp$/s/$/|optional/' <$tmp.raw >$tmp.tmp
+ mv $tmp.tmp $tmp.raw
+ ;;
+
+ src/perl/GNUmakefile)
+ # this INSTALL line is safe because mode is 0644 or 0755
+ # if [ -x $$src ] ; then mode=0755; else mode=0644; fi; \
+ # $(INSTALL) -m $$mode $$src $$dn/$$bn || exit 1; \
+ #
+ sed -e '/\$\$mode/d' <$tmp.raw >$tmp.tmp
+ mv $tmp.tmp $tmp.raw
+ ;;
+
+ src/pmie/GNUmakefile)
+ # this INSTALL line is optional because there if conditional
+ # gmake control around it
+ # $(INSTALL) -m 1777 -d $(PCP_TMP_DIR)/pmie
+ sed -e '/PCP_TMP_DIR)\/pmie$/s/$/|optional/' <$tmp.raw >$tmp.tmp
+ mv $tmp.tmp $tmp.raw
+ ;;
+
+ src/pmlogger/GNUmakefile)
+ # this INSTALL line is optional because there if conditional
+ # gmake control around it
+ # $(INSTALL) -m 1777 -d $(PCP_TMP_DIR)/pmlogger
+ sed -e '/PCP_TMP_DIR)\/pmlogger$/s/$/|optional/' <$tmp.raw >$tmp.tmp
+ mv $tmp.tmp $tmp.raw
+ ;;
+
+ src/pmdas/bash/GNUmakefile)
+ # this INSTALL line is optional because there if conditional
+ # gmake control around it
+ # $(INSTALL) -m 1777 -d $(PCP_TMP_DIR)/pmdabash
+ #
+ sed -e '/PCP_TMP_DIR)\/pmdabash$/s/$/|optional/' <$tmp.raw >$tmp.tmp
+ mv $tmp.tmp $tmp.raw
+ ;;
+
+ src/pmdas/mmv/GNUmakefile)
+ # this INSTALL line is optional because there if conditional
+ # gmake control around it
+ # $(INSTALL) -m 1777 -d $(PCP_TMP_DIR)/mmv
+ #
+ sed -e '/PCP_TMP_DIR)\/mmv$/s/$/|optional/' <$tmp.raw >$tmp.tmp
+ mv $tmp.tmp $tmp.raw
+ ;;
+
+ src/pmwebapi/GNUmakefile)
+ # all the INSTALL lines here are conditional, including this one
+ # $(INSTALL) -m 775 -o $(PCP_USER) -g $(PCP_GROUP) -d $(PCP_LOG_DIR)/pmwebd
+ sed -e '/PCP_LOG_DIR)\/pmwebd$/s/$/|optional/' <$tmp.raw >$tmp.tmp
+ mv $tmp.tmp $tmp.raw
+ ;;
+
+ esac
+
+ # any left over $'s are bad ...
+ #
+
+ grep '\$' $tmp.raw | grep -v '\$(PCP_' >$tmp.tmp
+ if [ -s $tmp.tmp ]
+ then
+ cat >&2 $tmp.tmp
+ echo >&2 "Need fixup for shell variables or makefile macros in $makefile"
+ rm -f $tmp.new
+ break
+ fi
+
+ # translate into a generic format
+ # makefile|mode|owner|group|target-file-name|optional
+ #
+ awk <$tmp.raw '
+ { mode = ""; group = "root"; owner = "root"; list = ""
+ for (i = 2; i <= NF; i++) {
+ if ($i ~ /-m/) mode = substr($i, 3, length($i));
+ else if ($i ~ /-g/) group = substr($i, 3, length($i));
+ else if ($i ~ /-o/) owner = substr($i, 3, length($i));
+ else if ($i ~ /-d/) {
+ dir = ""
+ list = substr($i, 3, length($i));
+ }
+ else if (i == NF) {
+ dir = $i
+ }
+ else if (list == "") {
+ list = $i
+ }
+ else {
+ list = list " " $i
+ }
+ }
+ if (dir != "" && list == "") {
+ print $1 "|" mode "|" owner "|" group "|" dir
+ }
+ else if (dir == "" && list != "") {
+ print $1 "|" mode "|" owner "|" group "|" list
+ }
+ else {
+ n = split(list, files)
+ if (n == 1) {
+ print $1 "|" mode "|" owner "|" group "|" dir
+ }
+ else {
+ for (i = 0; i < n; i++)
+ print $1 "|" mode "|" owner "|" group "|" dir "/" files[i]
+ }
+ }
+
+ }'
+
+done \
+| sort | uniq >$tmp.new
+
+if [ -s $tmp.new ]
+then
+ :
+else
+ sts=1
+ exit
+fi
+
+if [ -f permslist ]
+then
+ sed -e '/^#/d' <permslist >$tmp.old.strip
+ sed -e '/^#/d' <$tmp.new >$tmp.new.strip
+ if cmp $tmp.old.strip $tmp.new.strip >/dev/null
+ then
+ echo "No changes."
+ else
+ diff -u permslist $tmp.new
+ mv permslist permslist.old
+ cp $tmp.new permslist
+ echo "Updated (previous permslist saved as permslist.old)."
+ fi
+else
+ echo "Created permslist."
+ cp $tmp.new permslist
+fi
diff --git a/qa/src/mkproc b/qa/src/mkproc
new file mode 100755
index 0000000..cd5cdcf
--- /dev/null
+++ b/qa/src/mkproc
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# Recipe to remake proc archive
+#
+
+rm -f proc.0 proc.index proc.meta
+
+. $PCP_DIR/etc/pcp.env
+
+pmcd_pid=`$PCP_PS_PROG $PCP_PS_ALL_FLAGS | grep '[p]mcd' | $PCP_AWK_PROG '{ print $2 }'`
+if [ -z "$pmcd_pid" ]
+then
+ echo "Failed to get pmcd PID"
+ exit 1
+fi
+
+pmlogger_pid=`$PCP_PS_PROG $PCP_PS_ALL_FLAGS | grep '[p]mlogger -P' | $PCP_AWK_PROG '{ print $2 }'`
+if [ -z "$pmlogger_pid" ]
+then
+ echo "Failed to get primary pmlogger PID"
+ exit 1
+fi
+
+cat <<End-of-File | $PCP_BINADM_DIR/pmlogger -s 4 -l proc.log proc
+log mandatory on 500msec {
+ hinv
+ proc [$pmcd_pid,$pmlogger_pid]
+ kernel
+ disk
+}
+End-of-File
diff --git a/qa/src/mkrewrite b/qa/src/mkrewrite
new file mode 100755
index 0000000..9f94d44
--- /dev/null
+++ b/qa/src/mkrewrite
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# Recipe to remake rewrite archive
+#
+
+rm -f rewrite.0 rewrite.index rewrite.meta
+
+. $PCP_DIR/etc/pcp.env
+
+cat <<End-of-File | $PCP_BINADM_DIR/pmlogger -s 5 -l rewrite.log rewrite
+log mandatory on 150msec {
+ sampledso.long.bin_ctr[100,200,800,900]
+ sample.float.bin_ctr
+ sampledso.double.hundred
+ sample.longlong.bin_ctr
+ sampledso.bin[100,200,800,900]
+ sample.part_bin
+ sampledso.long.hundred
+ sample.ulonglong.hundred
+}
+
+log mandatory on 125msec {
+ sample.ulong.bin_ctr
+ sampledso.milliseconds
+ sample.ulonglong.bin_ctr
+ sampledso.float.hundred
+ sample.bin
+ sampledso.part_bin
+ sampledso.ulong.hundred
+ sampledso.double.bin_ctr[100,200,800,900]
+ sampledso.longlong.hundred
+}
+End-of-File
diff --git a/qa/src/mksa-sysstat b/qa/src/mksa-sysstat
new file mode 100755
index 0000000..22a6085
--- /dev/null
+++ b/qa/src/mksa-sysstat
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# Recreate the sadc data file for QA/370
+#
+
+if which sar >/dev/null 2>&1
+then
+ :
+else
+ echo "Error: sar not installed"
+ exit 1
+fi
+
+version=`sar -V 2>&1 | sed -n -e '/sysstat version /s/.* //p'`
+if [ -z "$version" ]
+then
+ echo "Arrgh ... cannot extract version from sar -V output ..."
+ sar -V
+ exit 1
+fi
+
+if [ -f sa-sysstat-$version ]
+then
+ echo "Error: data file sa-sysstat-$version already exists!"
+ exit 1
+fi
+
+sadc=""
+[ -x /usr/lib/sa/sadc ] && sadc=/usr/lib/sa/sadc
+[ -x /usr/lib64/sa/sadc ] && sadc=/usr/lib64/sa/sadc
+[ -x /usr/lib/sysstat/sadc ] && sadc=/usr/lib/sysstat/sadc
+if [ "X$sadc" = X ]
+then
+ echo "Error: cannot find sadc in any of the known places"
+ exit 1
+fi
+
+# collect data every 5 secs for 3 mins
+echo -n "Creating sa-sysstat-$version ..."
+$sadc -S XALL 5 36 sa-sysstat-$version
+echo
+
+exit 0
+
diff --git a/qa/src/mksample_expr b/qa/src/mksample_expr
new file mode 100755
index 0000000..d813189
--- /dev/null
+++ b/qa/src/mksample_expr
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# remake the sample_expr archive ... that is intended to be checked in
+# and not remade, this script is simply a record of it was created.
+#
+# sample_expr is used in the evaluation of derived metrics to confirm
+# the values are deterministic with known input values
+#
+
+tmp=/var/tmp/$$
+rm -f $tmp.*
+trap "rm -f $tmp.*; exit 0" 0 1 2 3 15
+
+. $PCP_DIR/etc/pcp.env
+
+cat <<End-of-File >>$tmp.config
+log mandatory on default {
+ sample.mirage
+ sample.mirage_longlong
+ sample.byte_rate
+ sample.byte_rate_perhour
+ sample.byte_ctr
+ sample.kbyte_ctr
+ sample.scale_step
+}
+End-of-File
+
+rm -f sample_expr.* pmlogger.log
+
+pmlogger -t 0.5sec -c $tmp.config -s 10 sample_expr
+
+cat pmlogger.log
diff --git a/qa/src/mktzchange b/qa/src/mktzchange
new file mode 100755
index 0000000..f69217f
--- /dev/null
+++ b/qa/src/mktzchange
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# Script to recreate the tzshift series of archives
+#
+
+. ../common.rc # for $sudo, $tmp, $here and pcp.env
+
+if make qa_timezone.so
+then
+ :
+else
+ echo "make qa_timezone.so failed ... I give up!"
+ exit 1
+fi
+
+$sudo $PCP_RC_DIR/pcp stop
+
+[ -d $PCP_RUN_DIR ] && $sudo chmod 777 $PCP_RUN_DIR
+
+for hr in 10 11 12
+do
+ export PCPQA_TZ=EST-$hr
+ export LD_PRELOAD=`pwd`/qa_timezone.so
+ pmcd &
+ rm -f tzchange-$hr-*
+ for a in a b
+ do
+ echo "log mandatory on 200msec sample.drift" | pmlogger tzchange-$hr-$a -s 4
+ done
+ $sudo $PCP_RC_DIR/pcp stop
+done
+
+[ -d $PCP_RUN_DIR ] && $sudo chmod 755 $PCP_RUN_DIR
+unset LD_PRELOAD
+$sudo $PCP_RC_DIR/pcp start
diff --git a/qa/src/mmv_genstats.c b/qa/src/mmv_genstats.c
new file mode 100644
index 0000000..e10e19f
--- /dev/null
+++ b/qa/src/mmv_genstats.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2009 Aconex. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/mmv_stats.h>
+
+static mmv_instances_t test_instances [] = {
+ { 0, "zero" },
+ { 1, "hero" },
+};
+
+static mmv_instances_t nest_instances [] = {
+ { 0, "bird" },
+ { 1, "tree" },
+ { 2, "eggs" },
+};
+
+static mmv_indom_t indoms[] = {
+ { .serial = 1,
+ .count = 2,
+ .instances = test_instances,
+ .shorttext = "We can be heroes",
+ .helptext = "We can be heroes, just for one day",
+ },
+ { .serial = 2,
+ .count = 3,
+ .instances = nest_instances,
+ /* exercise no-help-text case */
+ },
+};
+
+static mmv_metric_t metrics[] = {
+ { .name = "counter",
+ .item = 1,
+ .type = MMV_TYPE_U32,
+ .semantics = MMV_SEM_COUNTER,
+ .dimension = MMV_UNITS(0,0,1,0,0,PM_COUNT_ONE),
+ .shorttext = "test counter metric",
+ .helptext = "Yes, this is a test counter metric",
+ },
+ { .name = "discrete",
+ .item = 2,
+ .type = MMV_TYPE_I32,
+ .semantics = MMV_SEM_DISCRETE,
+ .dimension = MMV_UNITS(0,0,0,0,0,0),
+ .shorttext = "test discrete metric",
+ .helptext = "Yes, this is a test discrete metric",
+ },
+ { .name = "indom",
+ .item = 3,
+ .type = MMV_TYPE_U32,
+ .semantics = MMV_SEM_INSTANT,
+ .dimension = MMV_UNITS(0,0,1,0,0,PM_COUNT_ONE),
+ .indom = 1,
+ /* exercise no-help-text, no indom case */
+ },
+ { .name = "interval",
+ .item = 4,
+ .type = MMV_TYPE_ELAPSED,
+ .semantics = MMV_SEM_COUNTER,
+ .dimension = MMV_UNITS(0,1,0,0,PM_TIME_USEC,0),
+ .indom = 2,
+ /* exercise no-help-text case */
+ },
+ { .name = "string",
+ .item = 5,
+ .type = MMV_TYPE_STRING,
+ .dimension = MMV_UNITS(0,0,0,0,0,0),
+ .semantics = MMV_SEM_INSTANT,
+ /* exercise no-help-text, string value case */
+ },
+ { .name = "strings",
+ .item = 6,
+ .type = MMV_TYPE_STRING,
+ .semantics = MMV_SEM_INSTANT,
+ .dimension = MMV_UNITS(0,0,0,0,0,0),
+ .indom = 1,
+ .shorttext = "test string metrics",
+ .helptext = "Yes, this is a test string metric with instances",
+ },
+};
+
+static inline int indom_count() { return sizeof(indoms)/sizeof(indoms[0]); }
+static inline int metric_count() { return sizeof(metrics)/sizeof(metrics[0]); }
+
+int
+main(int ac, char * av[])
+{
+ pmAtomValue * atom;
+ char * file = (ac > 1) ? av[1] : "test";
+ int sleeper = (ac > 2) ? atoi(av[2]) : 0;
+ void * addr = mmv_stats_init(file, 0, 0,
+ metrics, metric_count(), indoms, indom_count());
+
+ if (!addr) {
+ fprintf(stderr, "mmv_stats_init failed : %s\n", strerror(errno));
+ return 1;
+ }
+
+ /* start an interval */
+ atom = mmv_stats_interval_start(addr, NULL, "interval", "eggs");
+
+ /* add ... */
+ mmv_stats_add(addr, "counter", "", 40);
+ /* add 1 ... */
+ mmv_stats_inc(addr, "counter", "");
+
+ /* set string values */
+ mmv_stats_set_string(addr, "string", "", "g'day world");
+ mmv_stats_set_strlen(addr, "strings", "zero", "00oo00oo00", 10);
+ mmv_stats_set_strlen(addr, "strings", "zero", "00oo00oo00", 6);
+ mmv_stats_set_strlen(addr, "strings", "hero", "ZERO", 4);
+ mmv_stats_set_strlen(addr, "strings", "hero", "", 0);
+
+ /* set discrete value ... */
+ mmv_stats_set(addr, "discrete", "", 41);
+ mmv_stats_inc(addr, "discrete", "");
+
+ /* add to instance or another if first doesn't exist */
+ mmv_stats_add_fallback(addr, "indom", "foobar", "unknown", 42);
+ mmv_stats_add_fallback(addr, "indom", "zero", "unknown", 43);
+
+ sleep(sleeper);
+
+ /* end an interval */
+ mmv_stats_interval_end(addr, atom);
+
+ return 0;
+}
diff --git a/qa/src/mmv_instances.c b/qa/src/mmv_instances.c
new file mode 100644
index 0000000..566a4c7
--- /dev/null
+++ b/qa/src/mmv_instances.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2009 Aconex. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/mmv_stats.h>
+
+static mmv_instances_t dogs[] = {
+ { 0, "Fido" },
+ { 1, "Brutus" },
+};
+
+static mmv_instances_t cats[] = {
+ { 10, "Tom" },
+};
+
+static mmv_instances_t mice[] = {
+ { 20, "Jerry" },
+};
+
+static mmv_indom_t indoms[] = {
+ { .serial = 1,
+ .shorttext = "Set of animal names",
+ .helptext = "Animal names - cats, dogs, and more",
+ },
+};
+
+static mmv_metric_t metrics[] = {
+ { .name = "animals.tag",
+ .item = 33,
+ .type = MMV_TYPE_U32,
+ .semantics = MMV_SEM_DISCRETE,
+ .dimension = MMV_UNITS(0,0,0,0,0,0),
+ .indom = 1,
+ .shorttext = "Animal tag identifiers",
+ .helptext = "Tags associated with each animal we have found",
+ },
+};
+
+static inline int dogs_count() { return sizeof(dogs)/sizeof(dogs[0]); }
+static inline int cats_count() { return sizeof(cats)/sizeof(cats[0]); }
+static inline int mice_count() { return sizeof(mice)/sizeof(mice[0]); }
+
+static inline int indom_count() { return sizeof(indoms)/sizeof(indoms[0]); }
+static inline int metric_count() { return sizeof(metrics)/sizeof(metrics[0]); }
+
+static inline int pets_cluster() { return 420; }
+
+int
+main(int argc, char * argv[])
+{
+ void * addr;
+ int i, error = 0;
+
+ if (argc == 2) {
+ if (strcmp(argv[1], "dogs") == 0) {
+ indoms[0].instances = dogs;
+ indoms[0].count = dogs_count();
+ }
+ else if (strcmp(argv[1], "cats") == 0) {
+ indoms[0].instances = cats;
+ indoms[0].count = cats_count();
+ }
+ else if (strcmp(argv[1], "mice") == 0) {
+ indoms[0].instances = mice;
+ indoms[0].count = mice_count();
+ }
+ else
+ error++;
+ }
+ else
+ error++;
+
+ if (error) {
+ fprintf(stderr, "Usage: mmv_instances <cats|dogs|mice>\n");
+ exit(1);
+ }
+
+ addr = mmv_stats_init(argv[1], pets_cluster(), MMV_FLAG_NOPREFIX,
+ metrics, metric_count(), indoms, indom_count());
+ if (!addr) {
+ fprintf(stderr, "mmv_stats_init failed: %s\n", strerror(errno));
+ return 1;
+ }
+
+ for (i = 0; i < indoms[0].count; i++) {
+ mmv_stats_set(addr, "animals.tag",
+ indoms[0].instances[i].external, indoms[0].instances[i].internal);
+ }
+
+ return 0;
+}
diff --git a/qa/src/mmv_noinit.c b/qa/src/mmv_noinit.c
new file mode 100644
index 0000000..7a8fa3e
--- /dev/null
+++ b/qa/src/mmv_noinit.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2010 Aconex. All Rights Reserved.
+ *
+ * This test emulates a client which directly overwrites the
+ * MMV data file without unlinking and recreating it (Parfait
+ * does this) - we're relying on the generation number change
+ * as the mechanism available to pmdammv to detect this.
+ *
+ * We use this test program in conjunction with a traditional
+ * (C) MMV API client (like mmv_genstats.c) to do this test.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/mmv_stats.h>
+#include <pcp/mmv_dev.h>
+#include <pcp/impl.h>
+
+static mmv_disk_header_t hdr = {
+ .magic = "MMV",
+ .version = MMV_VERSION,
+ .tocs = 2,
+};
+
+static mmv_disk_toc_t toc[] = {
+ { .type = MMV_TOC_METRICS, .count = 1, },
+ { .type = MMV_TOC_VALUES, .count = 1, },
+};
+
+static mmv_disk_metric_t metric = {
+ .name = "noinit",
+ .item = 1,
+ .type = MMV_TYPE_U32,
+ .semantics = MMV_SEM_COUNTER,
+ .dimension = MMV_UNITS(0,0,1,0,0,PM_COUNT_ONE),
+};
+
+static mmv_disk_value_t values;
+
+static size_t
+mmv_filesize(void)
+{
+ return sizeof(mmv_disk_header_t) +
+ sizeof(mmv_disk_toc_t) * 2 +
+ sizeof(mmv_disk_metric_t) +
+ sizeof(mmv_disk_value_t);
+}
+
+static void *
+mmv_noinit(const char *filename)
+{
+ char path[MAXPATHLEN];
+ size_t size = mmv_filesize();
+ int fd, sep = __pmPathSeparator();
+ void *addr = NULL;
+ int sts;
+
+ snprintf(path, sizeof(path), "%s%c" "mmv" "%c%s",
+ pmGetConfig("PCP_TMP_DIR"), sep, sep, filename);
+
+ fd = open(path, O_RDWR, 0644);
+ if (fd < 0) {
+ fprintf(stderr, "noinit: failed to open %s: %s\n",
+ path, strerror(errno));
+ return NULL;
+ }
+ sts = ftruncate(fd, size);
+ if (sts != 0) {
+ fprintf(stderr, "Error: ftruncate() returns %d\n", sts);
+ exit(1);
+ }
+ addr = __pmMemoryMap(fd, size, 1);
+
+ close(fd);
+ return addr;
+}
+
+static __uint64_t
+mmv_generation(void)
+{
+ struct timeval now;
+ __uint32_t gen1, gen2;
+
+ gettimeofday(&now, NULL);
+ gen1 = now.tv_sec;
+ gen2 = now.tv_usec;
+ return (((__uint64_t)gen1 << 32) | (__uint64_t)gen2);
+}
+
+int
+main(int ac, char * av[])
+{
+ char * file = (ac > 1) ? av[1] : "test";
+ void * addr = mmv_noinit(file);
+ char * data = addr;
+ __uint64_t gennum = mmv_generation();
+
+ if (!addr) {
+ perror("noinit");
+ return 1;
+ }
+
+ /*
+ * Write ondisk structures directly into file.
+ * fixing up offsets, etc, as we go.
+ */
+ hdr.g1 = gennum;
+ hdr.process = getpid();
+ memcpy(data, &hdr, sizeof(hdr));
+
+ data += sizeof(hdr);
+ toc[0].offset = sizeof(hdr) + sizeof(toc);
+ toc[1].offset = sizeof(hdr) + sizeof(toc) + sizeof(metric);
+ memcpy(data, &toc, sizeof(toc));
+
+ data += sizeof(toc);
+ memcpy(data, &metric, sizeof(metric));
+
+ values.value.ul = 42;
+ values.metric = sizeof(hdr) + sizeof(toc);
+ data += sizeof(metric);
+ memcpy(data, &values, sizeof(values));
+
+ /* "unlock" the file and bail out */
+ hdr.g2 = (__uint64_t) gennum;
+ memcpy(addr, &hdr, sizeof(hdr));
+ __pmMemoryUnmap(addr, mmv_filesize());
+ return 0;
+}
diff --git a/qa/src/mmv_nostats.c b/qa/src/mmv_nostats.c
new file mode 100644
index 0000000..d82bd60
--- /dev/null
+++ b/qa/src/mmv_nostats.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2010 Aconex. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/mmv_stats.h>
+
+int
+main(int ac, char * av[])
+{
+ char * file = (ac > 1) ? av[1] : "nostats";
+ void * addr = mmv_stats_init(file, 0, 0,
+ NULL, 0, NULL, 0);
+
+ if (!addr) {
+ fprintf(stderr, "mmv_stats_init failed : %s\n", strerror(errno));
+ return 1;
+ }
+
+ mmv_stats_add(addr, "counter", "", 40);
+
+ return 0;
+}
diff --git a/qa/src/mmv_poke.c b/qa/src/mmv_poke.c
new file mode 100644
index 0000000..65dda3c
--- /dev/null
+++ b/qa/src/mmv_poke.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2010 Aconex. All Rights Reserved.
+ * Modify values within an MMV data file for PCPQA.
+ */
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/mmv_stats.h>
+#include <pcp/mmv_dev.h>
+
+void *addr;
+
+void
+usage(void)
+{
+ fprintf(stderr,
+ "Usage: %s: [options] file\n\n"
+ "Options:\n"
+ " -f flag set flag in header (none, noprefix, process)\n"
+ " -p pid overwrite MMV file PID with given PID\n",
+ pmProgname);
+ exit(1);
+}
+
+void
+write_flags(char *flags)
+{
+ mmv_disk_header_t *hdr = (mmv_disk_header_t *)addr;
+
+ if (strcmp(flags, "noprefix") == 0)
+ hdr->flags |= MMV_FLAG_NOPREFIX;
+ if (strcmp(flags, "process") == 0)
+ hdr->flags |= MMV_FLAG_PROCESS;
+ if (strcmp(flags, "none") == 0)
+ hdr->flags = 0;
+ hdr->g1 = ++hdr->g2;
+}
+
+void
+write_pid(int pid)
+{
+ mmv_disk_header_t *hdr = (mmv_disk_header_t *)addr;
+
+ hdr->process = pid;
+ hdr->g1 = ++hdr->g2;
+}
+
+int
+main(int argc, char **argv)
+{
+ struct stat sbuf;
+ char *file, *flags = NULL;
+ int c, err = 0, pid = 0;
+
+ __pmSetProgname(argv[0]);
+ while ((c = getopt(argc, argv, "f:p:")) != EOF) {
+ switch (c) {
+ case 'f':
+ flags = optarg;
+ break;
+ case 'p':
+ pid = atoi(optarg);
+ break;
+ default:
+ err++;
+ }
+ }
+
+ if (err || argc != optind + 1)
+ usage();
+
+ file = argv[optind];
+
+ c = open(file, O_RDWR, 0644);
+ if (c < 0) {
+ fprintf(stderr, "Cannot open %s for writing: %s\n",
+ file, strerror(errno));
+ exit(1);
+ }
+ fstat(c, &sbuf);
+ addr = __pmMemoryMap(c, sbuf.st_size, 1);
+ close(c);
+
+ if (flags)
+ write_flags(flags);
+
+ if (pid)
+ write_pid(pid);
+
+ __pmMemoryUnmap(addr, sbuf.st_size);
+ exit(0);
+}
diff --git a/qa/src/moomba.client.0 b/qa/src/moomba.client.0
new file mode 100644
index 0000000..8eb0c80
--- /dev/null
+++ b/qa/src/moomba.client.0
Binary files differ
diff --git a/qa/src/moomba.client.index b/qa/src/moomba.client.index
new file mode 100644
index 0000000..d2fc0c3
--- /dev/null
+++ b/qa/src/moomba.client.index
Binary files differ
diff --git a/qa/src/moomba.client.meta b/qa/src/moomba.client.meta
new file mode 100644
index 0000000..b3557c2
--- /dev/null
+++ b/qa/src/moomba.client.meta
Binary files differ
diff --git a/qa/src/moomba.pmkstat.0 b/qa/src/moomba.pmkstat.0
new file mode 100644
index 0000000..e9ac65c
--- /dev/null
+++ b/qa/src/moomba.pmkstat.0
Binary files differ
diff --git a/qa/src/moomba.pmkstat.index b/qa/src/moomba.pmkstat.index
new file mode 100644
index 0000000..5f165fd
--- /dev/null
+++ b/qa/src/moomba.pmkstat.index
Binary files differ
diff --git a/qa/src/moomba.pmkstat.meta b/qa/src/moomba.pmkstat.meta
new file mode 100644
index 0000000..4483200
--- /dev/null
+++ b/qa/src/moomba.pmkstat.meta
Binary files differ
diff --git a/qa/src/multi-vm00.0 b/qa/src/multi-vm00.0
new file mode 100644
index 0000000..5bd6c58
--- /dev/null
+++ b/qa/src/multi-vm00.0
Binary files differ
diff --git a/qa/src/multi-vm00.index b/qa/src/multi-vm00.index
new file mode 100644
index 0000000..c8cb185
--- /dev/null
+++ b/qa/src/multi-vm00.index
Binary files differ
diff --git a/qa/src/multi-vm00.meta b/qa/src/multi-vm00.meta
new file mode 100644
index 0000000..8a9e02d
--- /dev/null
+++ b/qa/src/multi-vm00.meta
Binary files differ
diff --git a/qa/src/multi-vm01.0 b/qa/src/multi-vm01.0
new file mode 100644
index 0000000..004389b
--- /dev/null
+++ b/qa/src/multi-vm01.0
Binary files differ
diff --git a/qa/src/multi-vm01.index b/qa/src/multi-vm01.index
new file mode 100644
index 0000000..da46d70
--- /dev/null
+++ b/qa/src/multi-vm01.index
Binary files differ
diff --git a/qa/src/multi-vm01.meta b/qa/src/multi-vm01.meta
new file mode 100644
index 0000000..9685954
--- /dev/null
+++ b/qa/src/multi-vm01.meta
Binary files differ
diff --git a/qa/src/multi-vm02.0 b/qa/src/multi-vm02.0
new file mode 100644
index 0000000..fc07710
--- /dev/null
+++ b/qa/src/multi-vm02.0
Binary files differ
diff --git a/qa/src/multi-vm02.index b/qa/src/multi-vm02.index
new file mode 100644
index 0000000..b624e3a
--- /dev/null
+++ b/qa/src/multi-vm02.index
Binary files differ
diff --git a/qa/src/multi-vm02.meta b/qa/src/multi-vm02.meta
new file mode 100644
index 0000000..33d062f
--- /dev/null
+++ b/qa/src/multi-vm02.meta
Binary files differ
diff --git a/qa/src/multi-vm03.0 b/qa/src/multi-vm03.0
new file mode 100644
index 0000000..d97179d
--- /dev/null
+++ b/qa/src/multi-vm03.0
Binary files differ
diff --git a/qa/src/multi-vm03.index b/qa/src/multi-vm03.index
new file mode 100644
index 0000000..92e9a08
--- /dev/null
+++ b/qa/src/multi-vm03.index
Binary files differ
diff --git a/qa/src/multi-vm03.meta b/qa/src/multi-vm03.meta
new file mode 100644
index 0000000..8ca7c9b
--- /dev/null
+++ b/qa/src/multi-vm03.meta
Binary files differ
diff --git a/qa/src/multifetch.c b/qa/src/multifetch.c
new file mode 100644
index 0000000..c8c0748
--- /dev/null
+++ b/qa/src/multifetch.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 1994-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <unistd.h>
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ char *cmd = argv[0];
+ int errflag = 0;
+ int type = 0;
+ char *host = NULL; /* pander to gcc */
+ char *logfile = (char *)0;
+ pmLogLabel label; /* get hostname for archives */
+ char local[MAXHOSTNAMELEN];
+ char *namespace = PM_NS_DEFAULT;
+ int samples = 1000;
+ double delta = 1.0;
+ int i;
+ int j;
+ char *namelist[20];
+ pmID pmidlist[20];
+ int n;
+ int numpmid;
+ pmResult *resp;
+ char *endnum;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:h:l:n:s:t:T:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", cmd);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+#ifdef DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", cmd);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'l': /* logfile */
+ logfile = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples < 0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", cmd);
+ errflag++;
+ }
+ break;
+
+ case 't': /* delta seconds (double) */
+ delta = strtod(optarg, &endnum);
+ if (*endnum != '\0' || delta <= 0.0) {
+ fprintf(stderr, "%s: -t requires floating point argument\n", cmd);
+ errflag++;
+ }
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -D debug standard PCP debug flag\n\
+ -h host metrics source is PMCD on host\n\
+ -l logfile redirect diagnostics and trace output\n\
+ -n namespace use an alternative PMNS\n\
+ -s samples terminate after this many iterations\n\
+ -t delta sample interval in seconds(float) [default 1.0]\n",
+ cmd);
+ exit(1);
+ }
+
+ if (logfile != (char *)0) {
+ __pmOpenLog(cmd, logfile, stderr, &sts);
+ if (sts < 0) {
+ fprintf(stderr, "%s: Could not open logfile\n", pmProgname);
+ }
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", cmd, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ cmd, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ cmd, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ cmd, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ while (optind < argc) {
+ printf("extra argument[%d]: %s\n", optind, argv[optind]);
+ optind++;
+ }
+
+ i = 0;
+ /* we just want metrics from different pmdas here. choose ones
+ supported on both linux & irix */
+ namelist[i++] = "network.interface.in.bytes";
+ namelist[i++] = "network.interface.in.packets";
+ namelist[i++] = "network.interface.out.errors";
+ namelist[i++] = "network.interface.out.packets";
+ namelist[i++] = "simple.color";
+ namelist[i++] = "simple.time.user";
+ namelist[i++] = "simple.numfetch";
+ namelist[i++] = "sample.step";
+ namelist[i++] = "sample.lights";
+ namelist[i++] = "sample.magnitude";
+ numpmid = i;
+
+ n = pmLookupName(numpmid, namelist, pmidlist);
+ if (n < 0) {
+ fprintf(stderr, "pmLookupName: %s\n", pmErrStr(n));
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ printf(" %s - not known\n", namelist[i]);
+ }
+ exit(1);
+ }
+
+ for (j = 0; j < samples; j++) {
+ pmDesc desc;
+ for (i = 0; i < numpmid; i++) {
+ if ((n = pmLookupDesc(pmidlist[i], &desc)) < 0) {
+ fprintf(stderr, "pmFetch: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ }
+ for (i = 0; i < 5; i++) {
+ if ((n = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ fprintf(stderr, "pmFetch: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ pmFreeResult(resp);
+ }
+ }
+
+ exit(0);
+}
diff --git a/qa/src/multithread0.c b/qa/src/multithread0.c
new file mode 100644
index 0000000..390db5b
--- /dev/null
+++ b/qa/src/multithread0.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise __pmMultiThreaded()
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pthread.h>
+
+#ifndef HAVE_PTHREAD_BARRIER_T
+#include "pthread_barrier.h"
+#endif
+
+static void *
+func(void *arg)
+{
+ if (__pmMultiThreaded(PM_SCOPE_DSO_PMDA))
+ printf("func: is multithreaded\n");
+ else
+ printf("func: is NOT multithreaded\n");
+ pthread_exit(NULL);
+}
+
+int
+main()
+{
+ pthread_t tid1;
+ pthread_t tid2;
+ int sts;
+ char *msg;
+
+ if (__pmMultiThreaded(PM_SCOPE_DSO_PMDA))
+ printf("main0: is multithreaded\n");
+ else
+ printf("main0: is NOT multithreaded\n");
+
+ sts = pthread_create(&tid1, NULL, func, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid1: sts=%d\n", sts);
+ exit(1);
+ }
+
+ if (__pmMultiThreaded(PM_SCOPE_DSO_PMDA))
+ printf("main1: is multithreaded\n");
+ else
+ printf("main1: is NOT multithreaded\n");
+
+ sts = pthread_create(&tid2, NULL, func, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid2: sts=%d\n", sts);
+ exit(1);
+ }
+
+ if (__pmMultiThreaded(PM_SCOPE_DSO_PMDA))
+ printf("main2: is multithreaded\n");
+ else
+ printf("main2: is NOT multithreaded\n");
+
+ pthread_join(tid1, (void *)&msg);
+ if (msg != NULL) printf("tid1: %s\n", msg);
+ pthread_join(tid2, (void *)&msg);
+ if (msg != NULL) printf("tid2: %s\n", msg);
+
+ exit(0);
+}
diff --git a/qa/src/multithread1.c b/qa/src/multithread1.c
new file mode 100644
index 0000000..c1fc355
--- /dev/null
+++ b/qa/src/multithread1.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise multi-threaded checks for PM_CONTEXT_LOCAL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pthread.h>
+#if darwin_hack
+#include <dlfcn.h>
+#endif
+
+#ifndef HAVE_PTHREAD_BARRIER_T
+#include "pthread_barrier.h"
+#endif
+
+static pthread_barrier_t barrier;
+
+static int ctx = -1;
+static char *namelist[] = { "sampledso.colour" };
+static pmID pmidlist[] = { 0 };
+static pmDesc desc;
+static char **instname;
+static int *instance;
+static pmResult *rp;
+
+static void
+func(void)
+{
+ int sts;
+ char **children;
+ char *p;
+
+ if ((sts = pmUseContext(ctx)) < 0) {
+ printf("pmUseContext(%d): %s\n", ctx, pmErrStr(sts));
+ pthread_exit(NULL);
+ }
+
+ /*
+ * expect this to fail for the second thread through when
+ * using PM_CONTEXT_LOCAL
+ */
+ if ((sts = pmDupContext()) < 0)
+ printf("pmDupContext: %s\n", pmErrStr(sts));
+ else
+ printf("pmDupContext: -> %d\n", sts);
+
+ if ((sts = pmUseContext(ctx)) < 0) {
+ printf("pmUseContext(%d): %s\n", ctx, pmErrStr(sts));
+ pthread_exit(NULL);
+ }
+ else
+ printf("pmUseContext(%d) -> %d\n", ctx, sts);
+
+ if ((sts = pmLookupName(1, namelist, pmidlist)) < 0)
+ printf("pmLookupName: %s\n", pmErrStr(sts));
+ else
+ printf("pmLookupName: -> %s\n", pmIDStr(pmidlist[0]));
+
+ pthread_barrier_wait(&barrier);
+
+ if (pmidlist[0] == 0)
+ pthread_exit("Loser failed to get pmid!");
+
+ if ((sts = pmGetPMNSLocation()) < 0)
+ printf("pmGetPMNSLocation: %s\n", pmErrStr(sts));
+ else
+ printf("pmGetPMNSLocation: -> %d\n", sts);
+
+ /* leaf node, expect no children */
+ if ((sts = pmGetChildrenStatus(namelist[0], &children, NULL)) < 0)
+ printf("pmGetChildrenStatus: %s\n", pmErrStr(sts));
+ else
+ printf("pmGetChildrenStatus: -> %d\n", sts);
+
+ if ((sts = pmLookupDesc(pmidlist[0], &desc)) < 0)
+ printf("pmLookupDesc: %s\n", pmErrStr(sts));
+ else
+ printf("pmLookupDesc: -> %s type=%s indom=%s\n", pmIDStr(desc.pmid), pmTypeStr(desc.type), pmInDomStr(desc.indom));
+
+ pthread_barrier_wait(&barrier);
+
+ if (desc.pmid == 0)
+ pthread_exit("Loser failed to get pmDesc!");
+
+ if ((sts = pmLookupText(pmidlist[0], PM_TEXT_ONELINE, &p)) < 0)
+ printf("pmLookupText: %s\n", pmErrStr(sts));
+ else
+ printf("pmLookupText: -> %s\n", p);
+
+ if ((sts = pmGetInDom(desc.indom, &instance, &instname)) < 0)
+ printf("pmGetInDom: %s: %s\n", pmInDomStr(desc.indom), pmErrStr(sts));
+ else
+ printf("pmGetInDom: -> %d\n", sts);
+
+ pthread_barrier_wait(&barrier);
+
+ if (instance == NULL)
+ pthread_exit("Loser failed to get indom!");
+
+ if ((sts = pmNameInDom(desc.indom, instance[0], &p)) < 0)
+ printf("pmNameInDom: %s\n", pmErrStr(sts));
+ else
+ printf("pmNameInDom: %d -> %s\n", instance[0], p);
+
+ if ((sts = pmLookupInDom(desc.indom, instname[0])) < 0)
+ printf("pmLookupInDom: %s\n", pmErrStr(sts));
+ else
+ printf("pmLookupInDom: %s -> %d\n", instname[0], sts);
+
+ if ((sts = pmFetch(1, pmidlist, &rp)) < 0)
+ printf("pmFetch: %s\n", pmErrStr(sts));
+ else
+ printf("pmFetch: -> OK\n");
+
+ pthread_barrier_wait(&barrier);
+
+ if (rp == NULL)
+ pthread_exit("Loser failed to get pmResult!");
+
+ if ((sts = pmStore(rp)) < 0)
+ printf("pmStore: %s\n", pmErrStr(sts));
+ else
+ printf("pmStore: -> OK\n");
+
+ pthread_exit(NULL);
+}
+
+static void *
+func1(void *arg)
+{
+ int sts;
+
+ if ((sts = pmNewContext(PM_CONTEXT_LOCAL, NULL)) < 0)
+ printf("pmNewContext: %s\n", pmErrStr(sts));
+ else {
+ ctx = sts;
+ printf("pmNewContext: -> %d\n", ctx);
+ }
+
+ pthread_barrier_wait(&barrier);
+ pthread_barrier_wait(&barrier);
+
+ func();
+ /*NOTREACHED*/
+ return NULL;
+}
+
+static void *
+func2(void *arg)
+{
+ int sts;
+
+ pthread_barrier_wait(&barrier);
+
+ /*
+ * expect this to fail for the second thread through when
+ * using PM_CONTEXT_LOCAL
+ */
+ if ((sts = pmNewContext(PM_CONTEXT_LOCAL, NULL)) < 0)
+ printf("pmNewContext: %s\n", pmErrStr(sts));
+ else {
+ ctx = sts;
+ printf("pmNewContext: -> %d\n", ctx);
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ func();
+ /*NOTREACHED*/
+ return NULL;
+}
+
+int
+main()
+{
+ pthread_t tid1;
+ pthread_t tid2;
+ int sts;
+ char *msg;
+
+#if darwin_hack
+ /*
+ * This is just too bizarre!
+ * On Mac OS X, if one falls into the "CoreFoundation" libraries
+ * in a thread, without first having run the initialization code
+ * from the mainline, you die with a SIGTRAP! Calling dlopen() with
+ * doomed to fail parameters suffices.
+ *
+ * See also the -framework CoreFoundation glue needed in
+ * GNUmakefile.
+ *
+ * I am not making this up, check out
+ * http://openradar.appspot.com/7209349
+ */
+ dlopen("/no/such/dso", RTLD_LAZY);
+#endif
+
+ sts = pthread_barrier_init(&barrier, NULL, 2);
+ if (sts != 0) {
+ printf("pthread_barrier_init: sts=%d\n", sts);
+ exit(1);
+ }
+
+ sts = pthread_create(&tid1, NULL, func1, NULL);
+ if (sts != 0) {
+ printf("pthread_create: tid1: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid2, NULL, func2, NULL);
+ if (sts != 0) {
+ printf("pthread_create: tid2: sts=%d\n", sts);
+ exit(1);
+ }
+
+ pthread_join(tid1, (void *)&msg);
+ if (msg != NULL) printf("tid1: %s\n", msg);
+ pthread_join(tid2, (void *)&msg);
+ if (msg != NULL) printf("tid2: %s\n", msg);
+
+ if (rp != NULL)
+ pmFreeResult(rp);
+
+ exit(0);
+}
diff --git a/qa/src/multithread2.c b/qa/src/multithread2.c
new file mode 100644
index 0000000..238241f
--- /dev/null
+++ b/qa/src/multithread2.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2012-2013 Red Hat.
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise multi-threaded checks for PM_SCOPE_AF and PM_SCOPE_ACL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pthread.h>
+
+#ifndef HAVE_PTHREAD_BARRIER_T
+#include "pthread_barrier.h"
+#endif
+
+#include "localconfig.h"
+
+#if PCP_VER >= 3611
+__pmSockAddr *addr;
+#else
+__pmIPAddr addr;
+#endif
+
+static pthread_barrier_t barrier;
+
+static void
+wakeup(int tag, void *data)
+{
+ printf("Woops, wakeup(%d, %p) called?\n", tag, data);
+}
+
+static void *
+func1(void *arg)
+{
+ int sts;
+ int afid;
+ struct timeval when = { 1000, 0 };
+ char *fn = "func1";
+ unsigned int op;
+
+ afid = __pmAFregister(&when, NULL, wakeup);
+ if (afid >= 0)
+ printf("%s: __pmAFregister -> OK\n", fn);
+ else
+ printf("%s: __pmAFregister -> %s\n", fn, pmErrStr(afid));
+ sts = __pmAFunregister(afid);
+ if (sts >= 0)
+ printf("%s: __pmAFunregister -> OK\n", fn);
+ else
+ printf("%s: __pmAFunregister -> %s\n", fn, pmErrStr(sts));
+
+ pthread_barrier_wait(&barrier);
+ pthread_barrier_wait(&barrier);
+
+ sts = __pmAccAddOp(1);
+ if (sts == 0)
+ printf("%s: __pmAccAddOp(1) -> OK\n", fn);
+ else
+ printf("%s: __pmAccAddOp(1) -> %s\n", fn, pmErrStr(sts));
+ sts = __pmAccAddOp(2);
+ if (sts == 0)
+ printf("%s: __pmAccAddOp(2) -> OK\n", fn);
+ else
+ printf("%s: __pmAccAddOp(2) -> %s\n", fn, pmErrStr(sts));
+ sts = __pmAccAddHost("localhost", 1, 2, 3);
+ if (sts == 0)
+ printf("%s: __pmAccAddHost -> OK\n", fn);
+ else
+ printf("%s: __pmAccAddHost -> %s\n", fn, pmErrStr(sts));
+#if PCP_VER >= 3801
+ putc('\n', stdout);
+#endif
+ __pmAccDumpHosts(stdout);
+#if PCP_VER >= 3801
+ putc('\n', stdout);
+#endif
+ sts = __pmAccSaveHosts();
+ if (sts == 0)
+ printf("%s: __pmAccSaveHosts -> OK\n", fn);
+ else
+ printf("%s: __pmAccSaveHosts -> %s\n", fn, pmErrStr(sts));
+ sts = __pmAccRestoreHosts();
+ if (sts == 0)
+ printf("%s: __pmAccRestoreHosts -> OK\n", fn);
+ else
+ printf("%s: __pmAccRestoreHosts -> %s\n", fn, pmErrStr(sts));
+ sts = __pmAccAddClient(addr, &op);
+ if (sts == 0)
+ printf("%s: __pmAccAddClient -> %d\n", fn, op);
+ else
+ printf("%s: __pmAccAddClient -> %s\n", fn, pmErrStr(sts));
+
+ pthread_barrier_wait(&barrier);
+
+ pthread_exit(NULL);
+}
+
+static void *
+func2(void *arg)
+{
+ int sts;
+ int afid;
+ struct timeval when = { 1000, 0 };
+ char *fn = "func2";
+ unsigned int op;
+
+ pthread_barrier_wait(&barrier);
+
+ afid = __pmAFregister(&when, NULL, wakeup);
+ if (afid >= 0)
+ printf("%s: __pmAFregister -> OK\n", fn);
+ else
+ printf("%s: __pmAFregister -> %s\n", fn, pmErrStr(afid));
+ sts = __pmAFunregister(afid);
+ if (sts >= 0)
+ printf("%s: __pmAFunregister -> OK\n", fn);
+ else
+ printf("%s: __pmAFunregister -> %s\n", fn, pmErrStr(sts));
+
+ pthread_barrier_wait(&barrier);
+ pthread_barrier_wait(&barrier);
+
+ sts = __pmAccAddOp(1);
+ if (sts == 0)
+ printf("%s: __pmAccAddOp(1) -> OK\n", fn);
+ else
+ printf("%s: __pmAccAddOp(1) -> %s\n", fn, pmErrStr(sts));
+ sts = __pmAccAddOp(2);
+ if (sts == 0)
+ printf("%s: __pmAccAddOp(2) -> OK\n", fn);
+ else
+ printf("%s: __pmAccAddOp(2) -> %s\n", fn, pmErrStr(sts));
+ sts = __pmAccAddHost("localhost", 1, 2, 3);
+ if (sts == 0)
+ printf("%s: __pmAccAddHost -> OK\n", fn);
+ else
+ printf("%s: __pmAccAddHost -> %s\n", fn, pmErrStr(sts));
+ /* expect an error here - so no need for version-specific EOLs */
+ __pmAccDumpHosts(stdout);
+ sts = __pmAccSaveHosts();
+ if (sts == 0)
+ printf("%s: __pmAccSaveHosts -> OK\n", fn);
+ else
+ printf("%s: __pmAccSaveHosts -> %s\n", fn, pmErrStr(sts));
+ sts = __pmAccRestoreHosts();
+ if (sts == 0)
+ printf("%s: __pmAccRestoreHosts -> OK\n", fn);
+ else
+ printf("%s: __pmAccRestoreHosts -> %s\n", fn, pmErrStr(sts));
+ sts = __pmAccAddClient(addr, &op);
+ if (sts == 0)
+ printf("%s: __pmAccAddClient -> %d\n", fn, op);
+ else
+ printf("%s: __pmAccAddClient -> %s\n", fn, pmErrStr(sts));
+
+ pthread_exit(NULL);
+}
+
+int
+main()
+{
+ pthread_t tid1;
+ pthread_t tid2;
+ int sts;
+ char *msg;
+
+#if PCP_VER >= 3702
+ addr = __pmLoopBackAddress(AF_INET);
+#elif PCP_VER >= 3611
+ addr = __pmLoopBackAddress();
+#else
+ addr = __pmLoopbackAddress();
+#endif
+
+ sts = pthread_barrier_init(&barrier, NULL, 2);
+ if (sts != 0) {
+ printf("pthread_barrier_init: sts=%d\n", sts);
+ exit(1);
+ }
+
+ /* only need this to initialize library mutexes */
+ if ((sts = pmNewContext(PM_CONTEXT_LOCAL, NULL)) < 0) {
+ printf("pmNewContext: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ sts = pthread_create(&tid1, NULL, func1, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid1: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid2, NULL, func2, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid2: sts=%d\n", sts);
+ exit(1);
+ }
+
+ pthread_join(tid1, (void *)&msg);
+ if (msg != NULL) printf("tid1: %s\n", msg);
+ pthread_join(tid2, (void *)&msg);
+ if (msg != NULL) printf("tid2: %s\n", msg);
+
+#if PCP_VER >= 3611
+ __pmSockAddrFree(addr);
+#endif
+ exit(0);
+}
diff --git a/qa/src/multithread3.c b/qa/src/multithread3.c
new file mode 100644
index 0000000..c31ee57
--- /dev/null
+++ b/qa/src/multithread3.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise multi-threaded support for local PMNS functions
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pthread.h>
+
+#ifndef HAVE_PTHREAD_BARRIER_T
+#include "pthread_barrier.h"
+#endif
+
+static pthread_barrier_t barrier;
+
+static char *pmnsfile;
+static char pmns[] = "#undef EXTRA\n\
+root {\n\
+ a\n\
+ b 1:0:0\n\
+ c 2:0:0\n\
+#ifdef EXTRA\n\
+ d\n\
+ e 4:0:0\n\
+#endif\n\
+}\n\
+a {\n\
+ one 0:0:0\n\
+ two 0:1:0\n\
+ three\n\
+}\n\
+a.three {\n\
+ foo 0:2:0\n\
+ bar 0:2:1\n\
+}\n\
+#ifdef EXTRA\n\
+d {\n\
+ mumble 3:0:0\n\
+ f\n\
+}\n\
+d.f {\n\
+ fumble 3:0:1\n\
+}\n\
+#endif\n\
+";
+
+
+static void *
+func1(void *arg)
+{
+ int sts;
+ char *fn = "func1";
+ char **offspring;
+ int *status;
+ int i;
+ int j;
+ char *namelist[] = { "b", "a.three.foo", "d.f.fumble" };
+ pmID pmidlist[3];
+
+ pthread_barrier_wait(&barrier);
+
+ __pmDumpNameSpace(stdout, 1);
+
+ sts = pmGetChildrenStatus("", &offspring, &status);
+ if (sts >= 0) {
+ printf("%s: pmGetChildrenStatus -> %d\n", fn, sts);
+ for (i = 0; i < sts; i++) {
+ printf("[%d] %s %s\n", i, offspring[i], status[i] == PMNS_LEAF_STATUS ? "leaf" : "non-leaf");
+ }
+ free(offspring);
+ free(status);
+ }
+ else
+ printf("%s: pmGetChildrenStatus -> %s\n", fn, pmErrStr(sts));
+
+ for (i = 0; i < 5; i++) {
+ pthread_barrier_wait(&barrier);
+ sts = pmLookupName(sizeof(namelist)/sizeof(namelist[0]), namelist, pmidlist);
+ if (sts < 0)
+ printf("%s: pmGetChildrenStatus[%d] -> %s\n", fn, i, pmErrStr(sts));
+ else {
+ for (j = 0; j < sizeof(namelist)/sizeof(namelist[0]); j++) {
+ printf("%s: [%d] %s -> %s", fn, i, namelist[j], pmIDStr(pmidlist[j]));
+ if (pmidlist[j] == PM_ID_NULL)
+ printf("\n");
+ else {
+ char *name;
+ sts = pmNameID(pmidlist[j], &name);
+ if (sts < 0)
+ printf(": pmNameID -> %s\n", pmErrStr(sts));
+ else {
+ printf(" -> %s\n", name);
+ free(name);
+ }
+ }
+ }
+ }
+ pthread_barrier_wait(&barrier);
+ }
+
+ pthread_exit(NULL);
+}
+
+static void *
+func2(void *arg)
+{
+ int sts;
+ char *fn = "func2";
+ char *p;
+ FILE *f;
+
+ pthread_barrier_wait(&barrier);
+
+ /* iter 0 */
+ pthread_barrier_wait(&barrier);
+ pthread_barrier_wait(&barrier);
+
+ /* iter 1 */
+ pmUnloadNameSpace();
+ pthread_barrier_wait(&barrier);
+ pthread_barrier_wait(&barrier);
+
+ /* iter 2 */
+ if ((sts = pmLoadNameSpace(pmnsfile)) < 0) {
+ printf("%s: pmLoadNameSpace: [reload] %s\n", fn, pmErrStr(sts));
+ exit(1);
+ }
+ pthread_barrier_wait(&barrier);
+ pthread_barrier_wait(&barrier);
+
+ /* iter 3 */
+ pmUnloadNameSpace();
+ for (p = pmns; *p; p++) {
+ if (*p == 'u') {
+ *p++ = 'd';
+ *p++ = 'e';
+ *p++ = 'f';
+ *p++ = 'i';
+ *p++ = 'n';
+ *p++ = 'e';
+ break;
+ }
+ }
+ if ((f = fopen(pmnsfile, "w")) == NULL) {
+ printf("fopen: %s: failed: %s\n", pmnsfile, pmErrStr(-oserror()));
+ exit(1);
+ }
+ if (fwrite(pmns, strlen(pmns), 1, f) != 1) {
+ printf("fwrite: %s: failed: %s\n", pmnsfile, pmErrStr(-oserror()));
+ exit(1);
+ }
+ fclose(f);
+ if ((sts = pmLoadNameSpace(pmnsfile)) < 0) {
+ printf("%s: pmLoadNameSpace: [extra reload] %s\n", fn, pmErrStr(sts));
+ exit(1);
+ }
+ pthread_barrier_wait(&barrier);
+ pthread_barrier_wait(&barrier);
+
+ /* iter 4 */
+ pthread_barrier_wait(&barrier);
+ pthread_barrier_wait(&barrier);
+
+ pthread_exit(NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+ pthread_t tid1;
+ pthread_t tid2;
+ int sts;
+ char *msg;
+ FILE *f;
+
+ if (argc != 2) {
+ printf("Usage: multithread3 tmpfile\n");
+ exit(1);
+ }
+ pmnsfile = argv[1];
+ if ((f = fopen(pmnsfile, "w")) == NULL) {
+ printf("fopen: %s: failed: %s\n", pmnsfile, pmErrStr(-oserror()));
+ exit(1);
+ }
+ if (fwrite(pmns, strlen(pmns), 1, f) != 1) {
+ printf("fwrite: %s: failed: %s\n", pmnsfile, pmErrStr(-oserror()));
+ exit(1);
+ }
+ fclose(f);
+
+ sts = pthread_barrier_init(&barrier, NULL, 2);
+ if (sts != 0) {
+ printf("pthread_barrier_init: sts=%d\n", sts);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(pmnsfile)) < 0) {
+ printf("pmLoadNameSpace: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ sts = pthread_create(&tid1, NULL, func1, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid1: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid2, NULL, func2, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid2: sts=%d\n", sts);
+ exit(1);
+ }
+
+ pthread_join(tid1, (void *)&msg);
+ if (msg != NULL) printf("tid1: %s\n", msg);
+ pthread_join(tid2, (void *)&msg);
+ if (msg != NULL) printf("tid2: %s\n", msg);
+
+ exit(0);
+}
diff --git a/qa/src/multithread4.c b/qa/src/multithread4.c
new file mode 100644
index 0000000..110ba08
--- /dev/null
+++ b/qa/src/multithread4.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise multi-threaded support for traverse and load/unload
+ * PMNS operations
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pthread.h>
+
+#ifndef HAVE_PTHREAD_BARRIER_T
+#include "pthread_barrier.h"
+#endif
+
+#define ITER 10
+
+static int nmetric;
+
+void
+dometric(const char *name)
+{
+ nmetric++;
+}
+
+static void *
+func1(void *arg)
+{
+ int sts;
+ int i;
+ char msgbuf[PM_MAXERRMSGLEN];
+
+ for (i = 0; i < ITER; i++) {
+ nmetric = 0;
+ sts = pmTraversePMNS("", dometric);
+ if (sts >= 0)
+ printf("traverse: found %d metrics, sts %d\n", nmetric, sts);
+ else {
+ /*
+ * expect 0 metrics and PM_ERR_NOPMNS if the pmTraversePMNS
+ * gets in between the pmUnloadPMNS and the pmLoadPMNS in the
+ * other thread
+ */
+ if (nmetric > 0 || sts != PM_ERR_NOPMNS)
+ printf("traverse: found %d metrics, sts %s\n", nmetric, pmErrStr_r(sts, msgbuf, PM_MAXERRMSGLEN));
+ else {
+ /*
+ * nmetric == 0 && sts == PM_ERR_NOPMNS, so try again ...
+ * won't loop forever because eventually func2() will
+ * finish
+ */
+ i--;
+ }
+ }
+ }
+
+ pthread_exit(NULL);
+}
+
+static void *
+func2(void *arg)
+{
+ int sts;
+ char *fn = "func2";
+ int i;
+ char msgbuf[PM_MAXERRMSGLEN];
+
+ for (i = 0; i < ITER; i++) {
+ pmUnloadNameSpace();
+ if ((sts = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) {
+ printf("%s: pmLoadNameSpace[%d]: %s\n", fn, i, pmErrStr_r(sts, msgbuf, PM_MAXERRMSGLEN));
+ exit(1);
+ }
+ }
+
+ pthread_exit(NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+ pthread_t tid1;
+ pthread_t tid2;
+ int sts;
+ char *msg;
+ unsigned int in[PDU_MAX+1];
+ unsigned int out[PDU_MAX+1];
+ int i;
+ char msgbuf[PM_MAXERRMSGLEN];
+
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ if (argc != 1) {
+ printf("Usage: multithread4\n");
+ exit(1);
+ }
+
+ for (i = 0; i <= PDU_MAX; i++) {
+ in[i] = out[i] = 0;
+ }
+ __pmSetPDUCntBuf(in, out);
+
+ if ((sts = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) {
+ printf("%s: pmLoadNameSpace: %s\n", argv[0], pmErrStr_r(sts, msgbuf, PM_MAXERRMSGLEN));
+ exit(1);
+ }
+
+ sts = pthread_create(&tid1, NULL, func1, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid1: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid2, NULL, func2, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid2: sts=%d\n", sts);
+ exit(1);
+ }
+
+ pthread_join(tid1, (void *)&msg);
+ if (msg != NULL) printf("tid1: %s\n", msg);
+ pthread_join(tid2, (void *)&msg);
+ if (msg != NULL) printf("tid2: %s\n", msg);
+
+ printf("Total PDU counts\n");
+ printf("in:");
+ for (i = 0; i <= PDU_MAX; i++)
+ printf(" %d", in[i]);
+ putchar('\n');
+ printf("out:");
+ for (i = 0; i <= PDU_MAX; i++)
+ printf(" %d", out[i]);
+ putchar('\n');
+
+ exit(0);
+}
diff --git a/qa/src/multithread5.c b/qa/src/multithread5.c
new file mode 100644
index 0000000..46165b6
--- /dev/null
+++ b/qa/src/multithread5.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise multi-threaded multiple host contexts with pmLookupDesc()
+ * as the simplest possible case
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pthread.h>
+
+#ifndef HAVE_PTHREAD_BARRIER_T
+#include "pthread_barrier.h"
+#endif
+
+#define NMETRIC 5
+
+static char *namelist[NMETRIC] = {
+ "sample.seconds",
+ "sampledso.milliseconds",
+ "sample.ulonglong.bin_ctr",
+ "pmcd.cputime.total",
+ "pmcd.buf.alloc",
+};
+static pmID pmidlist[NMETRIC];
+
+static pthread_barrier_t barrier;
+
+static int ctx1;
+static int ctx2;
+static int ctx3;
+
+static void
+foo(FILE *f, char *fn, int i)
+{
+ pmDesc desc;
+ char strbuf[60];
+ int sts;
+
+ sts = pmLookupDesc(pmidlist[i], &desc);
+ if (sts < 0) {
+ fprintf(f, "%s: pmLookupDesc[%s] -> %s\n", fn, pmIDStr_r(pmidlist[i], strbuf, sizeof(strbuf)), pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ else if (pmidlist[i] != desc.pmid) {
+ fprintf(f, "%s: pmLookupDesc: Expecting PMID: %s", fn, pmIDStr_r(pmidlist[i], strbuf, sizeof(strbuf)));
+ fprintf(f, " got: %s\n", pmIDStr_r(desc.pmid, strbuf, sizeof(strbuf)));
+ pthread_exit("botch");
+ }
+ else {
+ fprintf(f, "%s: %s (%s) ->", fn, namelist[i], pmIDStr_r(pmidlist[i], strbuf, sizeof(strbuf)));
+ fprintf(f, " %s", pmTypeStr_r(desc.type, strbuf, sizeof(strbuf)));
+ fprintf(f, " %s", pmInDomStr_r(desc.indom, strbuf, sizeof(strbuf)));
+ if (desc.sem == PM_SEM_COUNTER) fprintf(f, " counter");
+ else if (desc.sem == PM_SEM_INSTANT) fprintf(f, " instant");
+ else if (desc.sem == PM_SEM_DISCRETE) fprintf(f, " discrete");
+ else fprintf(f, " sem-%d", desc.sem);
+ fprintf(f, " %s\n", pmUnitsStr_r(&desc.units, strbuf, sizeof(strbuf)));
+ }
+}
+
+static void *
+func1(void *arg)
+{
+ char *fn = "func1";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func1.out", "w")) == NULL) {
+ perror("func1 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx1);
+ if (j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx1, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = 0; i < NMETRIC; i++)
+ foo(f, fn, i);
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+static void *
+func2(void *arg)
+{
+ char *fn = "func2";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func2.out", "w")) == NULL) {
+ perror("func2 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx2);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx2, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = NMETRIC-1; i >= 0; i--)
+ foo(f, fn, i);
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+static void *
+func3(void *arg)
+{
+ char *fn = "func3";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func3.out", "w")) == NULL) {
+ perror("func3 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx3);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx3, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = 0; i < NMETRIC; i += 2)
+ foo(f, fn, i);
+ for (i = 1; i < NMETRIC; i += 2)
+ foo(f, fn, i);
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+ pthread_t tid1;
+ pthread_t tid2;
+ pthread_t tid3;
+ int sts;
+ char *msg;
+ int errflag = 0;
+ int c;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind == argc || argc-optind > 3) {
+ fprintf(stderr, "Usage: %s [-D...] host1 [host2 [host3]]\n", pmProgname);
+ exit(1);
+ }
+
+ ctx1 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx1 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx1));
+ exit(1);
+ }
+ optind++;
+
+ if (optind < argc) {
+ ctx2 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx2 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx2));
+ exit(1);
+ }
+ optind++;
+ }
+ else
+ ctx2 = ctx1;
+
+ if (optind < argc) {
+ ctx3 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx3 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx2));
+ exit(1);
+ }
+ optind++;
+ }
+ else
+ ctx3 = ctx2;
+
+ sts = pmLookupName(NMETRIC, namelist, pmidlist);
+ if (sts != NMETRIC) {
+ int i;
+ printf("Error: pmLookupName -> %s\n", pmErrStr(sts));
+ for (i = 0; i < NMETRIC; i++) {
+ printf(" %s -> %s\n", namelist[i], pmIDStr(pmidlist[i]));
+ }
+ exit(1);
+ }
+
+ sts = pthread_barrier_init(&barrier, NULL, 3);
+ if (sts != 0) {
+ printf("pthread_barrier_init: sts=%d\n", sts);
+ exit(1);
+ }
+
+ sts = pthread_create(&tid1, NULL, func1, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid1: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid2, NULL, func2, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid2: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid3, NULL, func3, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid3: sts=%d\n", sts);
+ exit(1);
+ }
+
+ pthread_join(tid1, (void *)&msg);
+ if (msg != NULL) printf("tid1: %s\n", msg);
+ pthread_join(tid2, (void *)&msg);
+ if (msg != NULL) printf("tid2: %s\n", msg);
+ pthread_join(tid3, (void *)&msg);
+ if (msg != NULL) printf("tid3: %s\n", msg);
+ pthread_cancel(tid1);
+ pthread_cancel(tid2);
+ pthread_cancel(tid3);
+
+ exit(0);
+}
diff --git a/qa/src/multithread6.c b/qa/src/multithread6.c
new file mode 100644
index 0000000..ade1d9f
--- /dev/null
+++ b/qa/src/multithread6.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise multi-threaded multiple host contexts with instance domain
+ * functions
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pthread.h>
+
+#ifndef HAVE_PTHREAD_BARRIER_T
+#include "pthread_barrier.h"
+#endif
+
+#define NMETRIC 5
+
+static char *namelist[NMETRIC] = {
+ "sample.colour",
+ "pmcd.control.register",
+ "sampledso.bin",
+ "sample.ulonglong.ten",
+ "pmcd.buf.alloc",
+};
+static pmID pmidlist[NMETRIC];
+static pmDesc desclist[NMETRIC];
+
+static pthread_barrier_t barrier;
+
+static int ctx1;
+static int ctx2;
+static int ctx3;
+
+static void
+foo(FILE *f, char *fn, int i)
+{
+ int sts;
+ int j;
+ int numinst;
+ int *inst;
+ char **name;
+ char *tmp;
+
+
+ if (desclist[i].indom == PM_INDOM_NULL) {
+ fprintf(f, "%s: %s: singular\n", fn, namelist[i]);
+ return;
+ }
+ if ((sts = pmGetInDom(desclist[i].indom, &inst, &name)) < 0) {
+ fprintf(f, "%s: %s: pmGetInDom Error: %s\n", fn, namelist[i], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ numinst = sts;
+ fprintf(f, "%s: %s: indom contains %d instances: ", fn, namelist[i], numinst);
+ for (j = 0; j < numinst; j++) {
+ if ((sts = pmNameInDom(desclist[i].indom, inst[j], &tmp)) < 0) {
+ fprintf(f, "\n%s: inst %d: pmNameInDom Error: %s\n", fn, inst[j], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ if (strcmp(tmp, name[j]) != 0) {
+ fprintf(f, "\n%s: inst %d: expecting \"%s\", got \"%s\"\n", fn, inst[j], name[j], tmp);
+ pthread_exit("botch");
+ }
+ fputc('i', f);
+ free(tmp);
+ }
+ fputc(' ', f);
+ for (j = 0; j < numinst; j++) {
+ if ((sts = pmLookupInDom(desclist[i].indom, name[j])) < 0) {
+ fprintf(f, "\n%s: inst \"%s\": pmLookupInDom Error: %s\n", fn, name[j], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ if (sts != inst[j]) {
+ fprintf(f, "\n%s: inst \"%s\": expecting %d, got %d\n", fn, name[j], inst[j], sts);
+ pthread_exit("botch");
+ }
+ fputc('n', f);
+ }
+ fputc('\n', f);
+
+ free(inst);
+ free(name);
+}
+
+static void *
+func1(void *arg)
+{
+ char *fn = "func1";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func1.out", "w")) == NULL) {
+ perror("func1 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx1);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx1, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = 0; i < NMETRIC; i++) {
+ foo(f, fn, i);
+ }
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+static void *
+func2(void *arg)
+{
+ char *fn = "func2";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func2.out", "w")) == NULL) {
+ perror("func2 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx2);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx2, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = NMETRIC-1; i >= 0; i--) {
+ foo(f, fn, i);
+ }
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+static void *
+func3(void *arg)
+{
+ char *fn = "func3";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func3.out", "w")) == NULL) {
+ perror("func3 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx3);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx3, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = 0; i < NMETRIC; i += 2)
+ foo(f, fn, i);
+ for (i = 1; i < NMETRIC; i += 2)
+ foo(f, fn, i);
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+ pthread_t tid1;
+ pthread_t tid2;
+ pthread_t tid3;
+ int sts;
+ char *msg;
+ int errflag = 0;
+ int c;
+ int i;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind == argc || argc-optind > 3) {
+ fprintf(stderr, "Usage: %s [-D...] host1 [host2 [host3]]\n", pmProgname);
+ exit(1);
+ }
+
+ ctx1 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx1 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx1));
+ exit(1);
+ }
+ optind++;
+
+ if (optind < argc) {
+ ctx2 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx2 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx2));
+ exit(1);
+ }
+ optind++;
+ }
+ else
+ ctx2 = ctx1;
+
+ if (optind < argc) {
+ ctx3 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx3 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx2));
+ exit(1);
+ }
+ optind++;
+ }
+ else
+ ctx3 = ctx2;
+
+ sts = pmLookupName(NMETRIC, namelist, pmidlist);
+ if (sts != NMETRIC) {
+ printf("Error: pmLookupName -> %s\n", pmErrStr(sts));
+ for (i = 0; i < NMETRIC; i++) {
+ printf(" %s -> %s\n", namelist[i], pmIDStr(pmidlist[i]));
+ }
+ exit(1);
+ }
+
+ for (i = 0; i < NMETRIC; i++) {
+ if ((sts = pmLookupDesc(pmidlist[i], &desclist[i])) < 0) {
+ printf("Error: pmLookupDesc(%s) -> %s\n", namelist[i], pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ sts = pthread_barrier_init(&barrier, NULL, 3);
+ if (sts != 0) {
+ printf("pthread_barrier_init: sts=%d\n", sts);
+ exit(1);
+ }
+
+ sts = pthread_create(&tid1, NULL, func1, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid1: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid2, NULL, func2, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid2: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid3, NULL, func3, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid3: sts=%d\n", sts);
+ exit(1);
+ }
+
+ pthread_join(tid1, (void *)&msg);
+ if (msg != NULL) printf("tid1: %s\n", msg);
+ pthread_join(tid2, (void *)&msg);
+ if (msg != NULL) printf("tid2: %s\n", msg);
+ pthread_join(tid3, (void *)&msg);
+ if (msg != NULL) printf("tid3: %s\n", msg);
+
+ exit(0);
+}
diff --git a/qa/src/multithread7.c b/qa/src/multithread7.c
new file mode 100644
index 0000000..067156e
--- /dev/null
+++ b/qa/src/multithread7.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise multi-threaded multiple host contexts with profile and
+ * fetch functions
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pthread.h>
+
+#ifndef HAVE_PTHREAD_BARRIER_T
+#include "pthread_barrier.h"
+#endif
+
+#define NMETRIC 5
+
+static char *namelist[NMETRIC] = {
+ "sample.colour",
+ "pmcd.control.register",
+ "sampledso.bin",
+ "sample.ulonglong.ten",
+ "pmcd.buf.alloc",
+};
+static pmID pmidlist[NMETRIC];
+static pmDesc desclist[NMETRIC];
+
+static pthread_barrier_t barrier;
+
+static int ctx1;
+static int ctx2;
+static int ctx3;
+
+static pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
+
+/*
+ * context use ...
+ *
+ * args tid1 tid2 tid3
+ * 1 0 0 0
+ * 2 0 1 1 <- needs app-level locking
+ * 3 0 1 2
+ */
+
+/*
+ * fetch pmidlist[i] ... pmidlist[NMETRIC-1]
+ */
+static void
+foo(FILE *f, char *fn, int i)
+{
+ int sts;
+ int j;
+ pmResult *rp;
+
+ if ((sts = pmFetch(NMETRIC-i, &pmidlist[i], &rp)) < 0) {
+ fprintf(f, "%s: %s ...: pmFetch Error: %s\n", fn, namelist[i], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ fprintf(f, "%s:", fn);
+ for (j = 0; j < rp->numpmid; j++)
+ fprintf(f, " %s: %d values", namelist[i+j], rp->vset[j]->numval);
+ fputc('\n', f);
+ pmFreeResult(rp);
+}
+
+static void *
+func1(void *arg)
+{
+ char *fn = "func1";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func1.out", "w")) == NULL) {
+ perror("func1 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx1);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx1, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = 0; i < NMETRIC; i++) {
+ foo(f, fn, i);
+ }
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+static void *
+func2(void *arg)
+{
+ char *fn = "func2";
+ int i;
+ int j;
+ int sts;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func2.out", "w")) == NULL) {
+ perror("func2 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx2);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx2, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = NMETRIC-1; i >= 0; i--) {
+ if (ctx2 != ctx1) {
+ /*
+ * limit pmcd.control.register [1] in context 2
+ * - select 5 instances below
+ */
+ int instlist[] = { 0, 1, 2, 4, 8 };
+ pthread_mutex_lock(&mymutex);
+ if ((sts = pmDelProfile(desclist[1].indom, 0, NULL)) < 0) {
+ fprintf(f, "Error: pmDelProfile(%s) -> %s\n", namelist[1], pmErrStr(sts));
+ fclose(f);
+ pthread_exit("botch");
+ }
+ if ((sts = pmAddProfile(desclist[1].indom, sizeof(instlist)/sizeof(instlist[0]), instlist)) < 0) {
+ fprintf(f, "Error: pmAddProfile(%s) -> %s\n", namelist[1], pmErrStr(sts));
+ fclose(f);
+ pthread_exit("botch");
+ }
+ }
+ foo(f, fn, i);
+ if (ctx2 != ctx1)
+ pthread_mutex_unlock(&mymutex);
+ }
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+static void *
+func3(void *arg)
+{
+ char *fn = "func3";
+ int i;
+ int j;
+ int sts;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func3.out", "w")) == NULL) {
+ perror("func3 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx3);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx3, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = 0; i < NMETRIC; i += 2) {
+ if (ctx3 != ctx2) {
+ /*
+ * limit sampledso.bin [2] in context 3
+ * - exclude instances below, leaving 7 instances 200, ... 800
+ */
+ int instlist[] = { 100, 900 };
+ if ((sts = pmAddProfile(desclist[2].indom, 0, NULL)) < 0) {
+ fprintf(f, "Error: pmAddProfile(%s) -> %s\n", namelist[2], pmErrStr(sts));
+ fclose(f);
+ pthread_exit("botch");
+ }
+ if ((sts = pmDelProfile(desclist[2].indom, sizeof(instlist)/sizeof(instlist[0]), instlist)) < 0) {
+ fprintf(f, "Error: pmDelProfile(%s) -> %s\n", namelist[2], pmErrStr(sts));
+ fclose(f);
+ pthread_exit("botch");
+ }
+ }
+ else {
+ pthread_mutex_lock(&mymutex);
+ if ((sts = pmAddProfile(desclist[1].indom, 0, NULL)) < 0) {
+ fprintf(f, "Error: pmAddProfile(%s) -> %s\n", namelist[1], pmErrStr(sts));
+ fclose(f);
+ pthread_exit("botch");
+ }
+ }
+ foo(f, fn, i);
+ if (ctx3 == ctx2)
+ pthread_mutex_unlock(&mymutex);
+ }
+ for (i = 1; i < NMETRIC; i += 2) {
+ /* inherit instance profile from loop above */
+ if (ctx3 == ctx2) {
+ pthread_mutex_lock(&mymutex);
+ if ((sts = pmAddProfile(desclist[1].indom, 0, NULL)) < 0) {
+ fprintf(f, "Error: pmAddProfile(%s) -> %s\n", namelist[1], pmErrStr(sts));
+ fclose(f);
+ pthread_exit("botch");
+ }
+ }
+ foo(f, fn, i);
+ if (ctx3 == ctx2)
+ pthread_mutex_unlock(&mymutex);
+ }
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+ pthread_t tid1;
+ pthread_t tid2;
+ pthread_t tid3;
+ int sts;
+ char *msg;
+ int errflag = 0;
+ int c;
+ int i;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind == argc || argc-optind > 3) {
+ fprintf(stderr, "Usage: %s [-D...] host1 [host2 [host3]]\n", pmProgname);
+ exit(1);
+ }
+
+ ctx1 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx1 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx1));
+ exit(1);
+ }
+ optind++;
+
+ if (optind < argc) {
+ ctx2 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx2 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx2));
+ exit(1);
+ }
+ optind++;
+ }
+ else
+ ctx2 = ctx1;
+
+ if (optind < argc) {
+ ctx3 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx3 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx2));
+ exit(1);
+ }
+ optind++;
+ }
+ else
+ ctx3 = ctx2;
+
+ sts = pmLookupName(NMETRIC, namelist, pmidlist);
+ if (sts != NMETRIC) {
+ printf("Error: pmLookupName -> %s\n", pmErrStr(sts));
+ for (i = 0; i < NMETRIC; i++) {
+ printf(" %s -> %s\n", namelist[i], pmIDStr(pmidlist[i]));
+ }
+ exit(1);
+ }
+
+ for (i = 0; i < NMETRIC; i++) {
+ if ((sts = pmLookupDesc(pmidlist[i], &desclist[i])) < 0) {
+ printf("Error: pmLookupDesc(%s) -> %s\n", namelist[i], pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ sts = pthread_barrier_init(&barrier, NULL, 3);
+ if (sts != 0) {
+ printf("pthread_barrier_init: sts=%d\n", sts);
+ exit(1);
+ }
+
+ sts = pthread_create(&tid1, NULL, func1, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid1: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid2, NULL, func2, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid2: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid3, NULL, func3, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid3: sts=%d\n", sts);
+ exit(1);
+ }
+
+ pthread_join(tid1, (void *)&msg);
+ if (msg != NULL) printf("tid1: %s\n", msg);
+ pthread_join(tid2, (void *)&msg);
+ if (msg != NULL) printf("tid2: %s\n", msg);
+ pthread_join(tid3, (void *)&msg);
+ if (msg != NULL) printf("tid3: %s\n", msg);
+
+ exit(0);
+}
diff --git a/qa/src/multithread8.c b/qa/src/multithread8.c
new file mode 100644
index 0000000..7d2dfd3
--- /dev/null
+++ b/qa/src/multithread8.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise multi-threaded multiple host contexts with help text
+ * functions
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pthread.h>
+
+#ifndef HAVE_PTHREAD_BARRIER_T
+#include "pthread_barrier.h"
+#endif
+
+static char *namelist[] = {
+ "pmcd.control.register",
+ "pmcd.version",
+ "sampledso.bin",
+ "sample.longlong.one"
+};
+
+#define NMETRIC (sizeof(namelist)/sizeof(namelist[0]))
+static pmID pmidlist[NMETRIC];
+static pmDesc desclist[NMETRIC];
+
+static pthread_barrier_t barrier;
+
+static int ctx1;
+static int ctx2;
+static int ctx3;
+
+static void
+foo(FILE *f, char *fn, int i)
+{
+ int sts;
+ char *tmp;
+
+ if ((sts = pmLookupText(pmidlist[i], PM_TEXT_ONELINE, &tmp)) < 0) {
+ fprintf(f, "%s: %s: pmLookupText oneline Error: %s\n", fn, namelist[i], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ fprintf(f, "%s: %s: %d", fn, namelist[i], (int)strlen(tmp));
+ free(tmp);
+ if ((sts = pmLookupText(pmidlist[i], PM_TEXT_HELP, &tmp)) < 0) {
+ fprintf(f, "\n%s: %s: pmLookupText help Error: %s\n", fn, namelist[i], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ fprintf(f, " & %d", (int)strlen(tmp));
+ free(tmp);
+
+ if (desclist[i].indom != PM_INDOM_NULL) {
+ char strbuf[20];
+ if ((sts = pmLookupInDomText(desclist[i].indom, PM_TEXT_ONELINE, &tmp)) < 0) {
+ fprintf(f, "\n%s: %s: pmLookupInDomText %s oneline Error: %s\n", fn, namelist[i], pmInDomStr_r(desclist[i].indom, strbuf, sizeof(strbuf)), pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ fprintf(f, " %s: %d", pmInDomStr_r(desclist[i].indom, strbuf, sizeof(strbuf)), (int)strlen(tmp));
+ free(tmp);
+ if ((sts = pmLookupInDomText(desclist[i].indom, PM_TEXT_HELP, &tmp)) < 0) {
+ fprintf(f, "\n%s: %s: pmLookupInDomText %s help Error: %s\n", fn, namelist[i], pmInDomStr_r(desclist[i].indom, strbuf, sizeof(strbuf)), pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ fprintf(f, " & %d", (int)strlen(tmp));
+ free(tmp);
+ }
+ fputc('\n', f);
+}
+
+static void *
+func1(void *arg)
+{
+ char *fn = "func1";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func1.out", "w")) == NULL) {
+ perror("func1 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx1);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx1, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = 0; i < NMETRIC; i++) {
+ foo(f, fn, i);
+ }
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+static void *
+func2(void *arg)
+{
+ char *fn = "func2";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func2.out", "w")) == NULL) {
+ perror("func2 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx2);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx2, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = NMETRIC-1; i >= 0; i--) {
+ foo(f, fn, i);
+ }
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+static void *
+func3(void *arg)
+{
+ char *fn = "func3";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func3.out", "w")) == NULL) {
+ perror("func3 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx3);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx3, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = 0; i < NMETRIC; i += 2)
+ foo(f, fn, i);
+ for (i = 1; i < NMETRIC; i += 2)
+ foo(f, fn, i);
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+ pthread_t tid1;
+ pthread_t tid2;
+ pthread_t tid3;
+ int sts;
+ char *msg;
+ int errflag = 0;
+ int c;
+ int i;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind == argc || argc-optind > 3) {
+ fprintf(stderr, "Usage: %s [-D...] host1 [host2 [host3]]\n", pmProgname);
+ exit(1);
+ }
+
+ ctx1 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx1 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx1));
+ exit(1);
+ }
+ optind++;
+
+ if (optind < argc) {
+ ctx2 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx2 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx2));
+ exit(1);
+ }
+ optind++;
+ }
+ else
+ ctx2 = ctx1;
+
+ if (optind < argc) {
+ ctx3 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx3 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx2));
+ exit(1);
+ }
+ optind++;
+ }
+ else
+ ctx3 = ctx2;
+
+ sts = pmLookupName(NMETRIC, namelist, pmidlist);
+ if (sts != NMETRIC) {
+ printf("Error: pmLookupName -> %s\n", pmErrStr(sts));
+ for (i = 0; i < NMETRIC; i++) {
+ printf(" %s -> %s\n", namelist[i], pmIDStr(pmidlist[i]));
+ }
+ exit(1);
+ }
+
+ for (i = 0; i < NMETRIC; i++) {
+ if ((sts = pmLookupDesc(pmidlist[i], &desclist[i])) < 0) {
+ printf("Error: pmLookupDesc(%s) -> %s\n", namelist[i], pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ sts = pthread_barrier_init(&barrier, NULL, 3);
+ if (sts != 0) {
+ printf("pthread_barrier_init: sts=%d\n", sts);
+ exit(1);
+ }
+
+ sts = pthread_create(&tid1, NULL, func1, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid1: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid2, NULL, func2, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid2: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid3, NULL, func3, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid3: sts=%d\n", sts);
+ exit(1);
+ }
+
+ pthread_join(tid1, (void *)&msg);
+ if (msg != NULL) printf("tid1: %s\n", msg);
+ pthread_join(tid2, (void *)&msg);
+ if (msg != NULL) printf("tid2: %s\n", msg);
+ pthread_join(tid3, (void *)&msg);
+ if (msg != NULL) printf("tid3: %s\n", msg);
+
+ exit(0);
+}
+
diff --git a/qa/src/multithread9.c b/qa/src/multithread9.c
new file mode 100644
index 0000000..f911cb9
--- /dev/null
+++ b/qa/src/multithread9.c
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * exercise multi-threaded multiple host contexts with PMNS functions
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pthread.h>
+
+#ifndef HAVE_PTHREAD_BARRIER_T
+#include "pthread_barrier.h"
+#endif
+
+static char *namelist[] = {
+ "sample.secret", // non-leaf
+ "sampledso.bin",
+ "sample.longlong.one",
+ "pmcd.pmlogger" // non-leaf
+};
+
+#define NMETRIC (sizeof(namelist)/sizeof(namelist[0]))
+static pmID pmidlist[NMETRIC];
+static pmDesc desclist[NMETRIC];
+static char **chn[NMETRIC];
+static int leaf_chn[NMETRIC];
+static int nonleaf_chn[NMETRIC];
+/*
+ * values here come from
+ * pminfo sample.secret | wc -lc => 9 273 => 264
+ * pminfo pmcd.pmlogger | wc -lc => 4 84 => 80
+ */
+static int sum_traverse[NMETRIC] = { 264, 0, 0, 80 };
+
+static pthread_barrier_t barrier;
+
+static int ctx1;
+static int ctx2;
+static int ctx3;
+
+static int count1;
+static int count2;
+static int count3;
+
+static void
+dometric(const char *name, void *closure)
+{
+ *((int *)closure) += strlen(name);
+}
+
+static void
+foo(FILE *f, char *fn, int i, void *closure)
+{
+ int sts;
+ int j;
+ int leaf;
+ pmID pmids[NMETRIC];
+ char *tmp;
+ char **tmpset;
+ int *stsset;
+ char strbuf[20];
+
+ if ((sts = pmLookupName(NMETRIC-i, &namelist[i], pmids)) < 0) {
+ if (sts != PM_ERR_NONLEAF) {
+ fprintf(f, "%s: %s ...: pmLookupName Error: %s\n", fn, namelist[i], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ }
+ for (j = i; j < NMETRIC; j++) {
+ if (pmids[j-i] != pmidlist[j]) {
+ fprintf(f, "%s: %s: Botch: expecting %s", fn, namelist[j], pmIDStr_r(pmidlist[j], strbuf, sizeof(strbuf)));
+ fprintf(f, ", got %s\n", pmIDStr_r(pmids[j-i], strbuf, sizeof(strbuf)));
+ pthread_exit("botch");
+ }
+ }
+ fprintf(f, "%s: %s ... pmLookupName OK\n", fn, namelist[i]);
+
+ fprintf(f, "%s: %s", fn, namelist[i]);
+ if (pmidlist[i] != PM_ID_NULL) {
+ /* leaf node in PMNS */
+ if ((sts = pmNameID(pmidlist[i], &tmp)) < 0) {
+ fprintf(f, "\n%s: %s ...: pmNameID Error: %s\n", fn, namelist[i], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ if (strcmp(tmp, namelist[i]) != 0) {
+ fprintf(f, "\n%s: %s: Botch: expecting %s, got %s\n", fn, pmIDStr_r(pmidlist[i], strbuf, sizeof(strbuf)), namelist[i], tmp);
+ pthread_exit("botch");
+ }
+ free(tmp);
+ fprintf(f, " pmNameID OK");
+ if ((sts = pmNameAll(pmidlist[i], &tmpset)) < 0) {
+ fprintf(f, "\n%s: %s ...: pmNameAll Error: %s\n", fn, namelist[i], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ if (sts != 1) {
+ fprintf(f, "\n%s: %s ...: pmNameAll Botch: expecting %d, got %d\n", fn, namelist[i], 1, sts);
+ pthread_exit("botch");
+ }
+ if (strcmp(tmpset[0], namelist[i]) != 0) {
+ fprintf(f, "\n%s: %s: Botch: expecting %s, got %s\n", fn, pmIDStr_r(pmidlist[i], strbuf, sizeof(strbuf)), namelist[i], tmpset[0]);
+ pthread_exit("botch");
+ }
+ free(tmpset);
+ fprintf(f, " pmNameAll OK");
+ }
+ else {
+ /* non-leaf node in PMNS */
+ int keep = 0;
+ if ((sts = pmGetChildrenStatus(namelist[i], &tmpset, &stsset)) < 0) {
+ fprintf(f, "\n%s: %s ...: pmGetChildrenStatus Error: %s\n", fn, namelist[i], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ leaf = 0;
+ for (j = 0; j < sts; j++) {
+ if (stsset[j] == PMNS_LEAF_STATUS) leaf++;
+ }
+ if (leaf_chn[i] == -1) {
+ leaf_chn[i] = leaf;
+ nonleaf_chn[i] = sts - leaf;
+ chn[i] = tmpset;
+ keep = 1;
+ }
+ else {
+ if (leaf != leaf_chn[i] || sts - leaf != nonleaf_chn[i]) {
+ fprintf(f, "\n%s: %s: Botch: expecting %d leaf & %d non-leaf, got %d leaf & %d non-leaf\n", fn, namelist[i], leaf_chn[i], nonleaf_chn[i], leaf, sts - leaf);
+ pthread_exit("botch");
+ }
+ for (j = 0; j < sts; j++) {
+ if (strcmp(chn[i][j], tmpset[j]) != 0) {
+ fprintf(f, "\n%s: %s: Botch: child[%d] expecting %s, got %s\n", fn, namelist[i], j, chn[i][j], tmpset[j]);
+ pthread_exit("botch");
+ }
+ }
+ }
+ if (keep == 0)
+ free(tmpset);
+ free(stsset);
+ fprintf(f, " pmGetChildrenStatus OK");
+ if ((sts = pmGetChildren(namelist[i], &tmpset)) < 0) {
+ fprintf(f, "\n%s: %s ...: pmGetChildren Error: %s\n", fn, namelist[i], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ if (sts != leaf_chn[i] + nonleaf_chn[i]) {
+ fprintf(f, "\n%s: %s: Botch: expecting %d children, got %d\n", fn, namelist[i], leaf_chn[i] + nonleaf_chn[i], sts);
+ pthread_exit("botch");
+ }
+ for (j = 0; j < sts; j++) {
+ if (strcmp(chn[i][j], tmpset[j]) != 0) {
+ fprintf(f, "\n%s: %s: Botch: child[%d] expecting %s, got %s\n", fn, namelist[i], j, chn[i][j], tmpset[j]);
+ pthread_exit("botch");
+ }
+ }
+ free(tmpset);
+ fprintf(f, " pmGetChildren OK");
+ *((int *)closure) = 0;
+ if ((sts = pmTraversePMNS_r(namelist[i], dometric, closure)) < 0) {
+ fprintf(f, "\n%s: %s ...: pmTraversePMNS_r Error: %s\n", fn, namelist[i], pmErrStr(sts));
+ pthread_exit("botch");
+ }
+ if (sum_traverse[i] != *((int *)closure)) {
+ fprintf(f, "\n%s: %s: Botch: sum strlen(descendent names) expecting %d, got %d\n", fn, namelist[i], sum_traverse[i], *((int *)closure));
+ pthread_exit("botch");
+ }
+ fprintf(f, " pmTraversePMNS_r OK");
+ }
+ fputc('\n', f);
+
+}
+
+static void *
+func1(void *arg)
+{
+ char *fn = "func1";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func1.out", "w")) == NULL) {
+ perror("func1 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx1);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx1, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = 0; i < NMETRIC; i++) {
+ foo(f, fn, i, &count1);
+ }
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+static void *
+func2(void *arg)
+{
+ char *fn = "func2";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func2.out", "w")) == NULL) {
+ perror("func2 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx2);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx2, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = NMETRIC-1; i >= 0; i--) {
+ foo(f, fn, i, &count2);
+ }
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+static void *
+func3(void *arg)
+{
+ char *fn = "func3";
+ int i;
+ int j;
+ FILE *f;
+
+ if ((f = fopen("/tmp/func3.out", "w")) == NULL) {
+ perror("func3 fopen");
+ pthread_exit("botch");
+ }
+
+ j = pmUseContext(ctx3);
+ if ( j < 0) {
+ fprintf(f, "Error: %s: pmUseContext(%d) -> %s\n", fn, ctx3, pmErrStr(j));
+ fclose(f);
+ pthread_exit("botch");
+ }
+
+ pthread_barrier_wait(&barrier);
+
+ for (j = 0; j < 100; j++) {
+ for (i = 0; i < NMETRIC; i += 2)
+ foo(f, fn, i, &count3);
+ for (i = 1; i < NMETRIC; i += 2)
+ foo(f, fn, i, &count3);
+ }
+
+ fclose(f);
+ pthread_exit(NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+ pthread_t tid1;
+ pthread_t tid2;
+ pthread_t tid3;
+ int sts;
+ char *msg;
+ int errflag = 0;
+ int c;
+ int i;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind == argc || argc-optind > 3) {
+ fprintf(stderr, "Usage: %s [-D...] host1 [host2 [host3]]\n", pmProgname);
+ exit(1);
+ }
+
+ ctx1 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx1 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx1));
+ exit(1);
+ }
+ optind++;
+
+ if (optind < argc) {
+ ctx2 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx2 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx2));
+ exit(1);
+ }
+ optind++;
+ }
+ else
+ ctx2 = ctx1;
+
+ if (optind < argc) {
+ ctx3 = pmNewContext(PM_CONTEXT_HOST, argv[optind]);
+ if (ctx3 < 0) {
+ printf("Error: pmNewContext(%s) -> %s\n", argv[optind], pmErrStr(ctx2));
+ exit(1);
+ }
+ optind++;
+ }
+ else
+ ctx3 = ctx2;
+
+ sts = pmLookupName(NMETRIC, namelist, pmidlist);
+ if (sts != NMETRIC) {
+ printf("Warning: pmLookupName -> %s\n", pmErrStr(sts));
+ for (i = 0; i < NMETRIC; i++) {
+ printf(" %s -> %s\n", namelist[i], pmIDStr(pmidlist[i]));
+ }
+ }
+
+ for (i = 0; i < NMETRIC; i++) {
+ if (pmidlist[i] != PM_ID_NULL) {
+ if ((sts = pmLookupDesc(pmidlist[i], &desclist[i])) < 0) {
+ printf("Error: pmLookupDesc(%s) -> %s\n", namelist[i], pmErrStr(sts));
+ exit(1);
+ }
+ }
+ chn[i] = NULL;
+ leaf_chn[i] = nonleaf_chn[i] = -1;
+ }
+
+ sts = pthread_barrier_init(&barrier, NULL, 3);
+ if (sts != 0) {
+ printf("pthread_barrier_init: sts=%d\n", sts);
+ exit(1);
+ }
+
+ sts = pthread_create(&tid1, NULL, func1, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid1: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid2, NULL, func2, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid2: sts=%d\n", sts);
+ exit(1);
+ }
+ sts = pthread_create(&tid3, NULL, func3, NULL);
+ if (sts != 0) {
+ printf("thread_create: tid3: sts=%d\n", sts);
+ exit(1);
+ }
+
+ pthread_join(tid1, (void *)&msg);
+ if (msg != NULL) printf("tid1: %s\n", msg);
+ pthread_join(tid2, (void *)&msg);
+ if (msg != NULL) printf("tid2: %s\n", msg);
+ pthread_join(tid3, (void *)&msg);
+ if (msg != NULL) printf("tid3: %s\n", msg);
+
+ exit(0);
+}
diff --git a/qa/src/nameall.c b/qa/src/nameall.c
new file mode 100644
index 0000000..c859811
--- /dev/null
+++ b/qa/src/nameall.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * nameall - exercise pmNameAll
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#if PMAPI_VERSION == 2
+static int pmns_style = 1;
+#endif
+static int vflag;
+static char *host = "localhost";
+static char *namespace = PM_NS_DEFAULT;
+static int dupok = 0;
+
+static void
+dometric(const char *name)
+{
+ pmID pmid;
+ int i;
+ int n;
+ char **nameset;
+
+ /* cast const away as pmLookUpName will not modify this string */
+ n = pmLookupName(1, (char **)&name, &pmid);
+ if (n < 0) {
+ printf("pmLookupName(%s): %s\n", name, pmErrStr(n));
+ return;
+ }
+ n = pmNameAll(pmid, &nameset);
+ if (n < 0) {
+ printf("pmNameAll(%s): %s\n", name, pmErrStr(n));
+ return;
+ }
+ for (i = 0; i < n; i++) {
+ if (strcmp(name, nameset[i]) != 0)
+ printf("%s alias %s and %s\n", pmIDStr(pmid), name, nameset[i]);
+ }
+ free(nameset);
+}
+
+void
+parse_args(int argc, char **argv)
+{
+ int errflag = 0;
+ int c;
+ int sts;
+ static char *usage = "[-h hostname] [-[N|n] namespace] [-v]";
+ char *endnum;
+
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N]";
+#else
+ static char *debug = "";
+#endif
+
+#if PMAPI_VERSION == 2
+ static char *style_str = "[-s 1|2]";
+#else
+ static char *style_str = "";
+#endif
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:h:N:n:s:v")) != EOF) {
+ switch (c) {
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ host = optarg;
+ break;
+
+ case 'N':
+ dupok=1;
+ /*FALLTHROUGH*/
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'v': /* verbose */
+ vflag++;
+ break;
+
+#if PMAPI_VERSION == 2
+ case 's': /* pmns style */
+ pmns_style = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ printf("%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+#endif
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s%s%s\n", pmProgname, debug, style_str, usage);
+ exit(1);
+ }
+}
+
+void
+load_namespace(char *namespace)
+{
+ struct timeval now, then;
+ int sts;
+
+ gettimeofday(&then, (struct timezone *)0);
+ if (dupok)
+ sts = pmLoadASCIINameSpace(namespace, 1);
+ else
+ sts = pmLoadNameSpace(namespace);
+ if (sts < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ gettimeofday(&now, (struct timezone *)0);
+ printf("Name space load: %.2f msec\n", __pmtimevalSub(&now, &then)*1000);
+}
+
+void
+test_nameall(int argc, char *argv[])
+{
+ int sts;
+
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+
+ if (vflag > 1)
+ __pmDumpNameSpace(stdout, 1);
+
+ for ( ; optind < argc; optind++)
+ pmTraversePMNS(argv[optind], dometric);
+}
+
+
+int
+main(int argc, char **argv)
+{
+ parse_args(argc, argv);
+
+ if (pmns_style == 2) {
+ /* test it the new way with distributed namespace */
+ /* i.e. no client loaded namespace */
+ test_nameall(argc, argv);
+ }
+ else {
+ /* test it the old way with namespace file */
+ load_namespace(namespace);
+ test_nameall(argc, argv);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/naslog.0 b/qa/src/naslog.0
new file mode 100644
index 0000000..f519919
--- /dev/null
+++ b/qa/src/naslog.0
Binary files differ
diff --git a/qa/src/naslog.index b/qa/src/naslog.index
new file mode 100644
index 0000000..6e39921
--- /dev/null
+++ b/qa/src/naslog.index
Binary files differ
diff --git a/qa/src/naslog.meta b/qa/src/naslog.meta
new file mode 100644
index 0000000..ca2d142
--- /dev/null
+++ b/qa/src/naslog.meta
Binary files differ
diff --git a/qa/src/new_mysql.0 b/qa/src/new_mysql.0
new file mode 100644
index 0000000..acb5c33
--- /dev/null
+++ b/qa/src/new_mysql.0
Binary files differ
diff --git a/qa/src/new_mysql.index b/qa/src/new_mysql.index
new file mode 100644
index 0000000..1246f3f
--- /dev/null
+++ b/qa/src/new_mysql.index
Binary files differ
diff --git a/qa/src/new_mysql.meta b/qa/src/new_mysql.meta
new file mode 100644
index 0000000..0fc1d15
--- /dev/null
+++ b/qa/src/new_mysql.meta
Binary files differ
diff --git a/qa/src/new_snmp.0 b/qa/src/new_snmp.0
new file mode 100644
index 0000000..be9dc46
--- /dev/null
+++ b/qa/src/new_snmp.0
Binary files differ
diff --git a/qa/src/new_snmp.index b/qa/src/new_snmp.index
new file mode 100644
index 0000000..2d97633
--- /dev/null
+++ b/qa/src/new_snmp.index
Binary files differ
diff --git a/qa/src/new_snmp.meta b/qa/src/new_snmp.meta
new file mode 100644
index 0000000..811a0bf
--- /dev/null
+++ b/qa/src/new_snmp.meta
Binary files differ
diff --git a/qa/src/node_archive.0 b/qa/src/node_archive.0
new file mode 100644
index 0000000..08f8ca5
--- /dev/null
+++ b/qa/src/node_archive.0
Binary files differ
diff --git a/qa/src/node_archive.index b/qa/src/node_archive.index
new file mode 100644
index 0000000..79d2853
--- /dev/null
+++ b/qa/src/node_archive.index
Binary files differ
diff --git a/qa/src/node_archive.meta b/qa/src/node_archive.meta
new file mode 100644
index 0000000..79175b0
--- /dev/null
+++ b/qa/src/node_archive.meta
Binary files differ
diff --git a/qa/src/nullinst.c b/qa/src/nullinst.c
new file mode 100644
index 0000000..180da0c
--- /dev/null
+++ b/qa/src/nullinst.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * nullinst - check metrics with indom PM_INDOM_NULL return 1
+ * value with inst == PM_IN_NULL
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static void
+dometric(const char *name)
+{
+ pmID pmid;
+ int n;
+ pmDesc desc;
+ pmResult *rp;
+
+ if ((n = pmLookupName(1, (char **)&name, &pmid)) < 0) {
+ printf("pmLookupName(%s): %s\n", name, pmErrStr(n));
+ return;
+ }
+ if ((n = pmLookupDesc(pmid, &desc)) < 0) {
+ printf("pmLookupDesc(%s): %s\n", name, pmErrStr(n));
+ return;
+ }
+ if (desc.indom != PM_INDOM_NULL)
+ return;
+
+ if ((n = pmFetch(1, &pmid, &rp)) < 0) {
+ printf("pmFetch(%s): %s\n", name, pmErrStr(n));
+ return;
+ }
+
+ if (rp->numpmid == 1) {
+ if (rp->vset[0]->numval == 1) {
+ if (rp->vset[0]->vlist[0].inst != PM_IN_NULL)
+ printf("%s: bad inst (%d)\n", name, rp->vset[0]->vlist[0].inst);
+ }
+ /* ignore errors from unsupported metrics on this platform */
+ else if (rp->vset[0]->numval != PM_ERR_APPVERSION &&
+#ifdef ENOPKG
+ rp->vset[0]->numval != -ENOPKG &&
+#endif
+ rp->vset[0]->numval != PM_ERR_AGAIN)
+ printf("%s: bad numval (%d)\n", name, rp->vset[0]->numval);
+ }
+ else
+ printf("%s: bad numpmid (%d)\n", name, rp->numpmid);
+
+ pmFreeResult(rp);
+
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+ static char *usage = "[-n namespace] metric ...";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:n:")) != EOF) {
+ switch (c) {
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind == argc) {
+ printf("Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ for ( ; optind < argc; optind++)
+ pmTraversePMNS(argv[optind], dometric);
+
+ exit(0);
+}
diff --git a/qa/src/numa.0 b/qa/src/numa.0
new file mode 100644
index 0000000..596ef7c
--- /dev/null
+++ b/qa/src/numa.0
Binary files differ
diff --git a/qa/src/numa.index b/qa/src/numa.index
new file mode 100644
index 0000000..5e46ae3
--- /dev/null
+++ b/qa/src/numa.index
Binary files differ
diff --git a/qa/src/numa.meta b/qa/src/numa.meta
new file mode 100644
index 0000000..704df6d
--- /dev/null
+++ b/qa/src/numa.meta
Binary files differ
diff --git a/qa/src/numberstr.c b/qa/src/numberstr.c
new file mode 100644
index 0000000..ccfeaff
--- /dev/null
+++ b/qa/src/numberstr.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char *argv[])
+{
+ double d;
+ char *endptr;
+
+ __pmSetProgname(argv[0]);
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s double\n", pmProgname);
+ exit(1);
+ }
+
+ d = strtod(argv[1], &endptr);
+ if (endptr != NULL && endptr[0] != '\0') {
+ fprintf(stderr, "%s does not smell like a double, bozo!\n", argv[1]);
+ exit(1);
+ }
+
+ printf("%s\n", pmNumberStr(d));
+
+ return 0;
+}
diff --git a/qa/src/nvidia-ml.c b/qa/src/nvidia-ml.c
new file mode 100644
index 0000000..707dd05
--- /dev/null
+++ b/qa/src/nvidia-ml.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2014 Red Hat.
+ *
+ * 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.
+ */
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include "localnvml.h"
+
+/*
+ * Testing library for exercising the NVIDIA GPU PMDA. By injecting this
+ * library into the PMDA to supply values that the real nvidia-ml usually
+ * would, we are able to obtain synthesized statistics and exercise many
+ * of the code paths through pmda_nvidia. No substitute for using actual
+ * hardware, of course - but better than a poke in the eye with a sharp
+ * stick (or worse, no testing at all).
+ */
+
+/*
+ * Table of the GPU hardware we'll be faking.
+ * Using simple static values here so that tests are deterministic.
+ */
+#define NUM_GPUS (sizeof(gpu_table)/sizeof(gpu_table[0]))
+struct gputab {
+ char name[NVML_DEVICE_NAME_BUFFER_SIZE];
+ nvmlPciInfo_t pciinfo;
+ unsigned int fanspeed;
+ unsigned int temperature;
+ nvmlUtilization_t util;
+ nvmlPstates_t state;
+ nvmlMemory_t mem;
+} gpu_table[] = {
+ {
+ .name = "GeForce 100M Series",
+ .pciinfo = {
+ .busId = "0:1:0x2:3:4",
+ .domain = 0,
+ .bus = 1,
+ .device = 0x2,
+ .pciDeviceId = 3,
+ .pciSubSystemId = 4,
+ },
+ .fanspeed = 5,
+ .temperature = 6,
+ .util = {
+ .gpu = 7,
+ .memory = 8,
+ },
+ .state = 9,
+ .mem = {
+ .total = 256 * 1024 * 1024,
+ .free = 156 * 1024 * 1024,
+ .used = 100 * 1024 * 1024,
+ },
+ },
+ {
+ .name = "Quadro FX 200M Series",
+ .pciinfo = {
+ .busId = "20:21:0x2:23:24",
+ .domain = 20,
+ .bus = 21,
+ .device = 0x22,
+ .pciDeviceId = 23,
+ .pciSubSystemId = 24,
+ },
+ .fanspeed = 25,
+ .temperature = 26,
+ .util = {
+ .gpu = 27,
+ .memory = 28,
+ },
+ .state = 29,
+ .mem = {
+ .total = 8ULL * 1024 * 1024 * 1024,
+ .free = 2ULL * 1024 * 1024 * 1024,
+ .used = 6ULL * 1024 * 1024 * 1024,
+ },
+ }
+};
+
+static int refcount;
+
+int
+nvmlInit(void)
+{
+ refcount++;
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "qa-nvidia-ml: nvmlInit [%d - %d]\n",
+ refcount - 1, refcount);
+ return 0;
+}
+
+int
+nvmlShutdown(void)
+{
+ refcount--;
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "qa-nvidia-ml: nvmlShutdown [%d - %d]\n",
+ refcount + 1, refcount);
+ return NVML_SUCCESS;
+}
+
+int
+nvmlDeviceGetCount(unsigned int *count)
+{
+ *count = sizeof(gpu_table) / sizeof(gpu_table[0]);
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "qa-nvidia-ml: nvmlDeviceGetCount [%u]\n", *count);
+ return NVML_SUCCESS;
+}
+
+#define CHECK_INDEX(index) { \
+ if ((index) < 0) return NVML_ERROR_INVALID_ARGUMENT; \
+ if ((index) >= NUM_GPUS) return NVML_ERROR_GPU_IS_LOST; }
+
+#define CHECK_DEVICE(devp) { \
+ if ((devp) < gpu_table) return NVML_ERROR_INVALID_ARGUMENT; \
+ if ((devp) >= gpu_table + NUM_GPUS) return NVML_ERROR_GPU_IS_LOST; }
+
+int
+nvmlDeviceGetHandleByIndex(unsigned int index, nvmlDevice_t *dp)
+{
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "qa-nvidia-ml: nvmlDeviceGetHandleByIndex %u\n", index);
+ CHECK_INDEX(index);
+ *dp = &gpu_table[index];
+ return NVML_SUCCESS;
+}
+
+int
+nvmlDeviceGetName(nvmlDevice_t device, char *buffer, unsigned int length)
+{
+ struct gputab *dev = (struct gputab *)device;
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "qa-nvidia-ml: nvmlDeviceGetName\n");
+ CHECK_DEVICE(dev);
+ strncpy(buffer, dev->name, length);
+ buffer[length-1] = '\0';
+ return NVML_SUCCESS;
+}
+
+int
+nvmlDeviceGetPciInfo(nvmlDevice_t device, nvmlPciInfo_t *info)
+{
+ struct gputab *dev = (struct gputab *)device;
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "qa-nvidia-ml: nvmlDeviceGetPciInfo\n");
+ CHECK_DEVICE(dev);
+ *info = dev->pciinfo;
+ return NVML_SUCCESS;
+}
+
+int
+nvmlDeviceGetFanSpeed(nvmlDevice_t device, unsigned int *speed)
+{
+ struct gputab *dev = (struct gputab *)device;
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "qa-nvidia-ml: nvmlDeviceGetFanSpeed\n");
+ CHECK_DEVICE(dev);
+ *speed = dev->fanspeed;
+ return NVML_SUCCESS;
+}
+
+int
+nvmlDeviceGetTemperature(nvmlDevice_t device, nvmlTemperatureSensors_t sensor, unsigned int *value)
+{
+ struct gputab *dev = (struct gputab *)device;
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "qa-nvidia-ml: nvmlDeviceGetTemperature\n");
+ CHECK_DEVICE(dev);
+ if (sensor >= NVML_TEMPERATURE_COUNT)
+ return NVML_ERROR_INVALID_ARGUMENT;
+ *value = dev->temperature;
+ return NVML_SUCCESS;
+}
+
+int
+nvmlDeviceGetUtilizationRates(nvmlDevice_t device, nvmlUtilization_t *util)
+{
+ struct gputab *dev = (struct gputab *)device;
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "qa-nvidia-ml: nvmlDeviceGetUtilizationRates\n");
+ CHECK_DEVICE(dev);
+ *util = dev->util;
+ return NVML_SUCCESS;
+}
+
+int
+nvmlDeviceGetMemoryInfo(nvmlDevice_t device, nvmlMemory_t *mem)
+{
+ struct gputab *dev = (struct gputab *)device;
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "qa-nvidia-ml: nvmlDeviceGetMemoryInfo\n");
+ CHECK_DEVICE(dev);
+ *mem = dev->mem;
+ return NVML_SUCCESS;
+}
+
+int
+nvmlDeviceGetPerformanceState(nvmlDevice_t device, nvmlPstates_t *state)
+{
+ struct gputab *dev = (struct gputab *)device;
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "qa-nvidia-ml: nvmlDeviceGetPerformanceState\n");
+ CHECK_DEVICE(dev);
+ *state = dev->state;
+ return NVML_SUCCESS;
+}
diff --git a/qa/src/obs.c b/qa/src/obs.c
new file mode 100644
index 0000000..ea7c63c
--- /dev/null
+++ b/qa/src/obs.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pcp/trace.h>
+
+
+int
+main(int argc, char **argv)
+{
+ int sts;
+ char *prog;
+
+ prog = argv[0];
+
+ if ((sts = pmtraceobs("simple", 6.09)) < 0) {
+ fprintf(stderr, "%s: (1) pmtraceobs error: %s\n",
+ prog, pmtraceerrstr(sts));
+ exit(1);
+ }
+ if ((sts = pmtraceobs("test", 888888.8888)) < 0) {
+ fprintf(stderr, "%s: (2) pmtraceobs error: %s\n",
+ prog, pmtraceerrstr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmtraceobs("simple", 76)) < 0) {
+ fprintf(stderr, "%s: (3) pmtraceobs error: %s\n",
+ prog, pmtraceerrstr(sts));
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/ok-bigbin.0 b/qa/src/ok-bigbin.0
new file mode 100644
index 0000000..2befcb1
--- /dev/null
+++ b/qa/src/ok-bigbin.0
Binary files differ
diff --git a/qa/src/ok-bigbin.index b/qa/src/ok-bigbin.index
new file mode 100644
index 0000000..2dbd34a
--- /dev/null
+++ b/qa/src/ok-bigbin.index
Binary files differ
diff --git a/qa/src/ok-bigbin.meta b/qa/src/ok-bigbin.meta
new file mode 100644
index 0000000..893ab91
--- /dev/null
+++ b/qa/src/ok-bigbin.meta
Binary files differ
diff --git a/qa/src/ok-foo.0 b/qa/src/ok-foo.0
new file mode 100644
index 0000000..a09c48c
--- /dev/null
+++ b/qa/src/ok-foo.0
Binary files differ
diff --git a/qa/src/ok-foo.index b/qa/src/ok-foo.index
new file mode 100644
index 0000000..8dd5ac5
--- /dev/null
+++ b/qa/src/ok-foo.index
Binary files differ
diff --git a/qa/src/ok-foo.meta b/qa/src/ok-foo.meta
new file mode 100644
index 0000000..2a6edab
--- /dev/null
+++ b/qa/src/ok-foo.meta
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.0 b/qa/src/ok-mv-bigbin.0
new file mode 100644
index 0000000..30ec19c
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.0
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.1 b/qa/src/ok-mv-bigbin.1
new file mode 100644
index 0000000..90d908e
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.1
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.2 b/qa/src/ok-mv-bigbin.2
new file mode 100644
index 0000000..103eb49
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.2
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.3 b/qa/src/ok-mv-bigbin.3
new file mode 100644
index 0000000..081a3ac
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.3
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.4 b/qa/src/ok-mv-bigbin.4
new file mode 100644
index 0000000..e57c2c9
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.4
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.5 b/qa/src/ok-mv-bigbin.5
new file mode 100644
index 0000000..18ac314
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.5
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.6 b/qa/src/ok-mv-bigbin.6
new file mode 100644
index 0000000..7118ca1
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.6
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.7 b/qa/src/ok-mv-bigbin.7
new file mode 100644
index 0000000..3aaaafb
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.7
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.8 b/qa/src/ok-mv-bigbin.8
new file mode 100644
index 0000000..b769520
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.8
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.9 b/qa/src/ok-mv-bigbin.9
new file mode 100644
index 0000000..b1a577e
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.9
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.index b/qa/src/ok-mv-bigbin.index
new file mode 100644
index 0000000..cf85d3b
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.index
Binary files differ
diff --git a/qa/src/ok-mv-bigbin.meta b/qa/src/ok-mv-bigbin.meta
new file mode 100644
index 0000000..84a6885
--- /dev/null
+++ b/qa/src/ok-mv-bigbin.meta
Binary files differ
diff --git a/qa/src/ok-mv-foo.0 b/qa/src/ok-mv-foo.0
new file mode 100644
index 0000000..21eb486
--- /dev/null
+++ b/qa/src/ok-mv-foo.0
Binary files differ
diff --git a/qa/src/ok-mv-foo.1 b/qa/src/ok-mv-foo.1
new file mode 100644
index 0000000..6b02578
--- /dev/null
+++ b/qa/src/ok-mv-foo.1
Binary files differ
diff --git a/qa/src/ok-mv-foo.2 b/qa/src/ok-mv-foo.2
new file mode 100644
index 0000000..5914c6d
--- /dev/null
+++ b/qa/src/ok-mv-foo.2
Binary files differ
diff --git a/qa/src/ok-mv-foo.index b/qa/src/ok-mv-foo.index
new file mode 100644
index 0000000..3ec1caf
--- /dev/null
+++ b/qa/src/ok-mv-foo.index
Binary files differ
diff --git a/qa/src/ok-mv-foo.meta b/qa/src/ok-mv-foo.meta
new file mode 100644
index 0000000..e05a5fb
--- /dev/null
+++ b/qa/src/ok-mv-foo.meta
Binary files differ
diff --git a/qa/src/ok-noti-bigbin.0 b/qa/src/ok-noti-bigbin.0
new file mode 100644
index 0000000..2befcb1
--- /dev/null
+++ b/qa/src/ok-noti-bigbin.0
Binary files differ
diff --git a/qa/src/ok-noti-bigbin.meta b/qa/src/ok-noti-bigbin.meta
new file mode 100644
index 0000000..893ab91
--- /dev/null
+++ b/qa/src/ok-noti-bigbin.meta
Binary files differ
diff --git a/qa/src/ok-truncbin.0 b/qa/src/ok-truncbin.0
new file mode 100644
index 0000000..99127ca
--- /dev/null
+++ b/qa/src/ok-truncbin.0
Binary files differ
diff --git a/qa/src/ok-truncbin.index b/qa/src/ok-truncbin.index
new file mode 100644
index 0000000..cd1e9c7
--- /dev/null
+++ b/qa/src/ok-truncbin.index
Binary files differ
diff --git a/qa/src/ok-truncbin.meta b/qa/src/ok-truncbin.meta
new file mode 100644
index 0000000..c445780
--- /dev/null
+++ b/qa/src/ok-truncbin.meta
Binary files differ
diff --git a/qa/src/old_xfs.0 b/qa/src/old_xfs.0
new file mode 100644
index 0000000..7b872a9
--- /dev/null
+++ b/qa/src/old_xfs.0
Binary files differ
diff --git a/qa/src/old_xfs.index b/qa/src/old_xfs.index
new file mode 100644
index 0000000..950d78c
--- /dev/null
+++ b/qa/src/old_xfs.index
Binary files differ
diff --git a/qa/src/old_xfs.meta b/qa/src/old_xfs.meta
new file mode 100644
index 0000000..d0ba464
--- /dev/null
+++ b/qa/src/old_xfs.meta
Binary files differ
diff --git a/qa/src/omen.client.0 b/qa/src/omen.client.0
new file mode 100644
index 0000000..160fe03
--- /dev/null
+++ b/qa/src/omen.client.0
Binary files differ
diff --git a/qa/src/omen.client.index b/qa/src/omen.client.index
new file mode 100644
index 0000000..41e2b01
--- /dev/null
+++ b/qa/src/omen.client.index
Binary files differ
diff --git a/qa/src/omen.client.meta b/qa/src/omen.client.meta
new file mode 100644
index 0000000..c643600
--- /dev/null
+++ b/qa/src/omen.client.meta
Binary files differ
diff --git a/qa/src/papi.c b/qa/src/papi.c
new file mode 100644
index 0000000..4b6e229
--- /dev/null
+++ b/qa/src/papi.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014 Red Hat.
+ *
+ * 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.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <papi.h>
+
+
+
+int
+PAPI_add_event(int EventSet, int EventCode)
+{
+
+}
+
+int
+PAPI_enum_event( int *EventCode, int modifier )
+{
+
+}
+
+int
+PAPI_state( int EventSet, int *status )
+{
+
+}
+
+int
+PAPI_library_init( int version )
+{
+
+}
+
+int
+PAPI_create_eventset( int *EventSet )
+{
+
+}
+
+int
+PAPI_start( int EventSet )
+{
+
+}
+
+int
+PAPI_read( int EventSet, long long *values )
+{
+
+}
+
+int
+PAPI_stop( int EventSet, long long *values )
+{
+
+}
+
+int
+PAPI_destroy_eventset( int *EventSet )
+{
+
+}
+
+int
+PAPI_cleanup_eventset( int EventSet )
+{
+
+}
+
+int
+PAPI_get_event_info( int EventCode, PAPI_event_info_t *info )
+{
+
+}
+
+int
+PAPI_reset( int EventSet )
+{
+
+}
+
+int
+PAPI_remove_events( int EventSet, int *Events, int number )
+{
+
+}
diff --git a/qa/src/parsehostattrs.c b/qa/src/parsehostattrs.c
new file mode 100644
index 0000000..68a3a42
--- /dev/null
+++ b/qa/src/parsehostattrs.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static __pmHashWalkState
+print_attribute(const __pmHashNode *tp, void *cp)
+{
+ char buffer[256];
+
+ if (!__pmAttrStr_r(tp->key, tp->data, buffer, sizeof(buffer))) {
+ fprintf(stderr, "Found unrecognised attribute (%d: \"%s\")\n",
+ tp->key, tp->data ? (char *)tp->data : "");
+ }
+ buffer[sizeof(buffer)-1] = '\0';
+ printf("%s\n", buffer);
+ return PM_HASH_WALK_NEXT;
+}
+
+int
+main(int argc, char **argv)
+{
+ char *msg;
+ char buffer[512];
+ __pmHashCtl attrs;
+ pmHostSpec *hosts;
+ int count, sts, i, j;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: parsehostattrs spec\n");
+ exit(1);
+ }
+
+ __pmHashInit(&attrs);
+ printf("pmParseHostAttrsSpec(\"%s\", ...)\n", argv[1]);
+ sts = __pmParseHostAttrsSpec(argv[1], &hosts, &count, &attrs, &msg);
+ if (sts < 0) {
+ if (sts == PM_ERR_GENERIC)
+ printf("pmParseHostAttrsSpec error:\n%s\n", msg);
+ else
+ printf("Error: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ for (i = 0; i < count; i++) {
+ printf("host[%d]: \"%s\"", i, hosts[i].name);
+ if (hosts[i].nports == 1)
+ printf(" port:");
+ else if (hosts[i].nports > 1)
+ printf(" ports:");
+ for (j = 0; j < hosts[i].nports; j++)
+ printf(" %d", hosts[i].ports[j]);
+ putchar('\n');
+ }
+ __pmHashWalkCB(print_attribute, NULL, &attrs);
+
+ sts = __pmUnparseHostAttrsSpec(hosts, count, &attrs, buffer, sizeof(buffer));
+ if (sts < 0) {
+ printf("pmUnparseHostAttrsSpec: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ printf("pmUnparseHostAttrsSpec(\"%s\") -> \"%s\"\n", argv[1], buffer);
+
+ __pmFreeHostAttrsSpec(hosts, count, &attrs);
+ __pmHashClear(&attrs);
+ exit(0);
+}
diff --git a/qa/src/parsehostspec.c b/qa/src/parsehostspec.c
new file mode 100644
index 0000000..00197c2
--- /dev/null
+++ b/qa/src/parsehostspec.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ char *msg, buffer[512];
+ pmHostSpec *hosts;
+ int count, sts, i, j;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: parsehostspec spec\n");
+ exit(1);
+ }
+
+ printf("pmParseHostSpec(\"%s\", ...)\n", argv[1]);
+ sts = __pmParseHostSpec(argv[1], &hosts, &count, &msg);
+ if (sts < 0) {
+ if (sts == PM_ERR_GENERIC)
+ printf("pmParseHostSpec error:\n%s\n", msg);
+ else
+ printf("Error: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ for (i = 0; i < count; i++) {
+ printf("host[%d]: \"%s\"", i, hosts[i].name);
+ if (hosts[i].nports == 1)
+ printf(" port:");
+ else if (hosts[i].nports > 1)
+ printf(" ports:");
+ for (j = 0; j < hosts[i].nports; j++)
+ printf(" %d", hosts[i].ports[j]);
+ putchar('\n');
+ }
+
+ sts = __pmUnparseHostSpec(hosts, count, buffer, sizeof(buffer));
+ if (sts < 0) {
+ printf("pmUnparseHostSpec: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ printf("pmUnparseHostSpec(\"%s\") -> \"%s\"\n", argv[1], buffer);
+
+ __pmFreeHostSpec(hosts, count);
+ exit(0);
+}
diff --git a/qa/src/parseinterval.c b/qa/src/parseinterval.c
new file mode 100644
index 0000000..f72e1d5
--- /dev/null
+++ b/qa/src/parseinterval.c
@@ -0,0 +1,29 @@
+#include <pcp/pmapi.h>
+
+int
+main(int argc, char *argv[])
+{
+ int sts;
+ char *err;
+ struct timeval time;
+
+ while (argc > 1) {
+ printf("\"%s\"", argv[1]);
+ sts = pmParseInterval(argv[1], &time, &err);
+ if (sts == -1) {
+ printf(" Error:\n%s", err);
+ free(err);
+ }
+ else if (sts == 0) {
+ printf(" Time: %ld.%06ld sec\n",
+ (long)time.tv_sec, (long)time.tv_usec);
+ }
+ else {
+ printf(" Bogus return value: %d\n", sts);
+ }
+ argc--;
+ argv++;
+ }
+
+ return 0;
+}
diff --git a/qa/src/parsemetricspec.c b/qa/src/parsemetricspec.c
new file mode 100644
index 0000000..5a7c37b
--- /dev/null
+++ b/qa/src/parsemetricspec.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <pcp/pmapi.h>
+
+int
+main(int argc, char **argv)
+{
+ int isarch;
+ char *msg;
+ pmMetricSpec *rslt;
+ int sts;
+ int i;
+
+ if (argc != 4) {
+ fprintf(stderr, "Usage: parsemetricspec spec isarch host\n");
+ exit(1);
+ }
+
+ if (strcmp(argv[1], "NULL") == 0) argv[1] = NULL;
+ isarch = atol(argv[2]);
+ if (strcmp(argv[3], "NULL") == 0) argv[3] = NULL;
+
+ printf("pmParseMetricSpec(\"%s\", %d, \"%s\", ...)\n",
+ argv[1], isarch, argv[3]);
+
+ sts = pmParseMetricSpec(argv[1], isarch, argv[3], &rslt, &msg);
+
+ if (sts < 0) {
+ if (sts == PM_ERR_GENERIC)
+ printf("pmParseMetricSpec Error:\n%s\n", msg);
+ else
+ printf("error: %s\n", pmErrStr(sts));
+ }
+ else {
+ printf("isarch: %d\n", rslt->isarch);
+ printf("source: \"%s\"\n", rslt->source);
+ printf("metric: \"%s\"\n", rslt->metric);
+ for (i = 0; i < rslt->ninst; i++) {
+ printf("inst[%d]: \"%s\"\n", i, rslt->inst[i]);
+ }
+ }
+
+ exit(0);
+}
diff --git a/qa/src/pcp-free.0 b/qa/src/pcp-free.0
new file mode 100644
index 0000000..5efe10b
--- /dev/null
+++ b/qa/src/pcp-free.0
Binary files differ
diff --git a/qa/src/pcp-free.index b/qa/src/pcp-free.index
new file mode 100644
index 0000000..2effb7e
--- /dev/null
+++ b/qa/src/pcp-free.index
Binary files differ
diff --git a/qa/src/pcp-free.meta b/qa/src/pcp-free.meta
new file mode 100644
index 0000000..cbfad55
--- /dev/null
+++ b/qa/src/pcp-free.meta
Binary files differ
diff --git a/qa/src/pcp-numastat-1-node.0 b/qa/src/pcp-numastat-1-node.0
new file mode 100644
index 0000000..076366d
--- /dev/null
+++ b/qa/src/pcp-numastat-1-node.0
Binary files differ
diff --git a/qa/src/pcp-numastat-1-node.index b/qa/src/pcp-numastat-1-node.index
new file mode 100644
index 0000000..88974d4
--- /dev/null
+++ b/qa/src/pcp-numastat-1-node.index
Binary files differ
diff --git a/qa/src/pcp-numastat-1-node.meta b/qa/src/pcp-numastat-1-node.meta
new file mode 100644
index 0000000..8e0e85c
--- /dev/null
+++ b/qa/src/pcp-numastat-1-node.meta
Binary files differ
diff --git a/qa/src/pcp-uptime.0 b/qa/src/pcp-uptime.0
new file mode 100644
index 0000000..fd68abf
--- /dev/null
+++ b/qa/src/pcp-uptime.0
Binary files differ
diff --git a/qa/src/pcp-uptime.index b/qa/src/pcp-uptime.index
new file mode 100644
index 0000000..ae79782
--- /dev/null
+++ b/qa/src/pcp-uptime.index
Binary files differ
diff --git a/qa/src/pcp-uptime.meta b/qa/src/pcp-uptime.meta
new file mode 100644
index 0000000..5924a1d
--- /dev/null
+++ b/qa/src/pcp-uptime.meta
Binary files differ
diff --git a/qa/src/pcp_lite_crash.c b/qa/src/pcp_lite_crash.c
new file mode 100644
index 0000000..0727bbd
--- /dev/null
+++ b/qa/src/pcp_lite_crash.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * pcp_lite_crash - crash pcp lite
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char local[MAXHOSTNAMELEN];
+ char *namespace = PM_NS_DEFAULT;
+ pmID pmid;
+ pmDesc desc;
+ int type = 0;
+ char *host = NULL;
+ char *metric = "kernel.all.cpu.idle";
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:h:Ln:")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'L': /* local, no PMCD */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ host = NULL;
+ type = PM_CONTEXT_LOCAL;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options:\n\
+ -a archive use archive log, not host source\n\
+ -D N set pmDebug debugging flag to N\n\
+ -h hostname connect to PMCD on this host\n\
+ -L connect local, no PMCD\n\
+ -n namespace alternative PMNS specification file\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else if (type == PM_CONTEXT_LOCAL)
+ fprintf(stderr, "%s: Cannot connect in local standalone mode: %s\n",
+ pmProgname, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmLookupName(1, &metric, &pmid)) < 0) {
+ printf("%s: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* crash in here: dereference a null pointer to function */
+ if ((sts = pmLookupDesc(pmid, &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/pcpcmd.0 b/qa/src/pcpcmd.0
new file mode 100644
index 0000000..7ca8979
--- /dev/null
+++ b/qa/src/pcpcmd.0
Binary files differ
diff --git a/qa/src/pcpcmd.index b/qa/src/pcpcmd.index
new file mode 100644
index 0000000..7fd831b
--- /dev/null
+++ b/qa/src/pcpcmd.index
Binary files differ
diff --git a/qa/src/pcpcmd.meta b/qa/src/pcpcmd.meta
new file mode 100644
index 0000000..8d4bbf6
--- /dev/null
+++ b/qa/src/pcpcmd.meta
Binary files differ
diff --git a/qa/src/pdu-server.c b/qa/src/pdu-server.c
new file mode 100644
index 0000000..a413eba
--- /dev/null
+++ b/qa/src/pdu-server.c
@@ -0,0 +1,768 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * PCP PDU echo server.
+ *
+ * with -r (raw)
+ * sends PDUs straightback w/out inspection (uses only
+ * the PDU header to determine the length
+ *
+ * without -r
+ * uses libpcp routines to decode the PDU and then the
+ * send the PDU ... exercises local recv and xmit logic
+ * for PDUs
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/trace.h>
+#include <pcp/trace_dev.h>
+#include <strings.h>
+#include "localconfig.h"
+
+static int raw; /* if set, echo PDUs, do not decode/encode */
+
+typedef struct { /* from src/libpcp/src/p_pmns.c */
+ __pmPDUHdr hdr;
+ int sts; /* to encode status of pmns op */
+ int numids;
+ pmID idlist[1];
+} idlist_t;
+
+/*
+ * use pid as "from" context for backwards compatibility to
+ * keep QA tests happy, rather than FROM_ANON which would be
+ * the more normal value for this usage.
+ */
+static pid_t mypid;
+
+static int
+decode_encode(int fd, __pmPDU *pb, int type)
+{
+ int e;
+ int code;
+ int proto;
+ pmResult *rp;
+ __pmProfile *profp;
+ int ctxnum;
+ int fail = -1;
+ __pmTimeval now;
+ int numpmid;
+ pmID *pmidp;
+ pmID pmid;
+ pmDesc desc;
+ pmInDom indom;
+ int inst;
+ char *name;
+ __pmInResult *inres;
+ int control;
+ int length;
+ int state;
+ int attr;
+ int rate;
+ int ident;
+ int txtype;
+ char *buffer;
+ int xtype;
+ int xlen;
+ int sender;
+ int count;
+ __pmCred *creds;
+ idlist_t *idlist_p;
+ static int numpmidlist;
+ static pmID *pmidlist;
+ int numlist;
+ char **namelist;
+ int *statlist;
+ __pmLoggerStatus *lsp;
+ double value;
+
+ switch (type) {
+
+ case PDU_ERROR:
+ if ((e = __pmDecodeError(pb, &code)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeError: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "+ PDU_ERROR: code=%d\n", code);
+#endif
+ if ((e = __pmSendError(fd, mypid, code)) < 0) {
+ fprintf(stderr, "%s: Error: SendError: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_RESULT:
+ if ((e = __pmDecodeResult(pb, &rp)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeResult: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ PDU_RESULT:\n");
+ __pmDumpResult(stderr, rp);
+ }
+#endif
+ e = __pmSendResult(fd, mypid, rp);
+ pmFreeResult(rp);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: SendResult: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_PROFILE:
+ if ((e = __pmDecodeProfile(pb, &ctxnum, &profp)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeProfile: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ PDU_PROFILE: ctxnum=%d\n", ctxnum);
+ __pmDumpProfile(stderr, PM_INDOM_NULL, profp);
+ }
+#endif
+ e = __pmSendProfile(fd, mypid, ctxnum, profp);
+ free(profp->profile);
+ free(profp);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: SendProfile: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_FETCH:
+ if ((e = __pmDecodeFetch(pb, &ctxnum, &now, &numpmid, &pmidp)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeFetch: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ int j;
+ struct timeval foo;
+ fprintf(stderr, "+ PDU_FETCH: ctxnum=%d now=%d.%06d ",
+ ctxnum, now.tv_sec, now.tv_usec);
+ foo.tv_sec = now.tv_sec;
+ foo.tv_usec = now.tv_usec;
+ __pmPrintStamp(stderr, &foo);
+ fprintf(stderr, " numpmid=%d\n+ PMIDs:", numpmid);
+ for (j = 0; j < numpmid; j++)
+ fprintf(stderr, " %s", pmIDStr(pmidp[j]));
+ fputc('\n', stderr);
+ }
+#endif
+ e = __pmSendFetch(fd, mypid, ctxnum, &now, numpmid, pmidp);
+ __pmUnpinPDUBuf(pmidp);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: SendFetch: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_DESC_REQ:
+ if ((e = __pmDecodeDescReq(pb, &pmid)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeDescReq: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "+ PDU_DESC_REQ: pmid=%s\n", pmIDStr(pmid));
+#endif
+ if ((e = __pmSendDescReq(fd, mypid, pmid)) < 0) {
+ fprintf(stderr, "%s: Error: SendDescReq: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_DESC:
+ if ((e = __pmDecodeDesc(pb, &desc)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeDesc: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ PDU_DESC: ");
+ __pmPrintDesc(stderr, &desc);
+ }
+#endif
+ if ((e = __pmSendDesc(fd, mypid, &desc)) < 0) {
+ fprintf(stderr, "%s: Error: SendDesc: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_INSTANCE_REQ:
+ if ((e = __pmDecodeInstanceReq(pb, &now, &indom, &inst, &name)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeInstanceReq: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ struct timeval foo;
+ fprintf(stderr, "+ PDU_INSTANCE_REQ: now=%d.%06d ",
+ now.tv_sec, now.tv_usec);
+ foo.tv_sec = now.tv_sec;
+ foo.tv_usec = now.tv_usec;
+ __pmPrintStamp(stderr, &foo);
+ fprintf(stderr, " indom=%s", pmInDomStr(indom));
+ if (inst == PM_IN_NULL)
+ fprintf(stderr, " inst=PM_IN_NULL");
+ else
+ fprintf(stderr, " inst=%d", inst);
+ if (name == NULL)
+ fprintf(stderr, " name=NULL\n");
+ else
+ fprintf(stderr, " name=\"%s\"\n", name);
+ }
+#endif
+ e = __pmSendInstanceReq(fd, mypid, &now, indom, inst, name);
+ if (name)
+ free(name);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: SendInstanceReq: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_INSTANCE:
+ if ((e = __pmDecodeInstance(pb, &inres)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeInstance: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ PDU_INSTANCE: ");
+ __pmDumpInResult(stderr, inres);
+ }
+#endif
+ e = __pmSendInstance(fd, mypid, inres);
+ __pmFreeInResult(inres);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: SendInstance: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_TEXT_REQ:
+ if ((e = __pmDecodeTextReq(pb, &ident, &txtype)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeTextReq: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ PDU_TEXT_REQ: ident=%d ", ident);
+ if (txtype & PM_TEXT_INDOM)
+ fprintf(stderr, "INDOM %s", pmInDomStr((pmInDom)ident));
+ if (txtype & PM_TEXT_PMID)
+ fprintf(stderr, "PMID %s", pmIDStr((pmID)ident));
+ fprintf(stderr, " txtype=%d\n", txtype);
+ }
+#endif
+ if ((e = __pmSendTextReq(fd, mypid, ident, txtype)) < 0) {
+ fprintf(stderr, "%s: Error: SendTextReq: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_TEXT:
+ if ((e = __pmDecodeText(pb, &ident, &buffer)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeText: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ int len;
+ int c;
+ fprintf(stderr, "+ PDU_TEXT: ident=%d", ident);
+ len = strlen(buffer);
+ c = buffer[len - 1];
+ buffer[len - 1] = '\0';
+ if (len < 30)
+ fprintf(stderr, " text=\"%s\"\n", buffer);
+ else {
+ fprintf(stderr, " text=\"%12.12s ... ", buffer);
+ fprintf(stderr, "%s\"\n", &buffer[len - 18]);
+ }
+ buffer[len - 1] = c;
+ }
+#endif
+ if ((e = __pmSendText(fd, mypid, ident, buffer)) < 0) {
+ fprintf(stderr, "%s: Error: SendText: %s\n", pmProgname, pmErrStr(e));
+ free(buffer);
+ break;
+ }
+ fail = 0;
+ free(buffer);
+ break;
+
+#if PCP_VER >= 3800
+ case PDU_AUTH:
+ if ((e = __pmDecodeAuth(pb, &attr, &buffer, &length)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeAuth: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ char buf[32] = { 0 };
+
+ fprintf(stderr, "+ PDU_AUTH: attr=%d length=%d", attr, length);
+ if (length < sizeof(buf)-2) {
+ strncpy(buf, buffer, length);
+ fprintf(stderr, " value=\"%s\"\n", buf);
+ } else {
+ strncpy(buf, buffer, sizeof(buf)-2);
+ fprintf(stderr, " value=\"%12.12s ... ", buf);
+ strncpy(buf, &buffer[length-18], sizeof(buf)-2);
+ fprintf(stderr, "%s\"\n", buf);
+ }
+ }
+#endif
+ if ((e = __pmSendAuth(fd, mypid, attr, buffer, length)) < 0) {
+ fprintf(stderr, "%s: Error: SendAuth: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+#endif
+
+ case PDU_CREDS:
+ if ((e = __pmDecodeCreds(pb, &sender, &count, &creds)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeCreds: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ int i;
+ fprintf(stderr, "+ PDU_CREDS: sender=%d count=%d\n",
+ sender, count);
+ for (i = 0; i < count; i++) {
+ fprintf(stderr, "+ [%d] type=%d a=%d b=%d c=%d\n",
+ i, creds[i].c_type, creds[i].c_vala, creds[i].c_valb,
+ creds[i].c_valc);
+ }
+ }
+#endif
+ e = __pmSendCreds(fd, mypid, count, creds);
+ if (count > 0)
+ free(creds);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: SendCreds: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_PMNS_IDS:
+ idlist_p = (idlist_t *)pb;
+ numpmid = ntohl(idlist_p->numids);
+ if (numpmid > numpmidlist) {
+ if (pmidlist != NULL)
+ free(pmidlist);
+ if ((pmidlist = (pmID *)malloc(numpmid * sizeof(pmidlist[0]))) == NULL) {
+ fprintf(stderr, "malloc pmidlist[%d]: %s\n", numpmid, strerror(errno));
+ numpmidlist = 0;
+ break;
+ }
+ numpmidlist = numpmid;
+ }
+ if ((e = __pmDecodeIDList(pb, numpmid, pmidlist, &code)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeIDList: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ PDU_PMNS_IDS: sts arg=%d\n", code);
+ __pmDumpIDList(stderr, numpmid, pmidlist);
+ }
+#endif
+ e = __pmSendIDList(fd, mypid, numpmid, pmidlist, code);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: SendIDList: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_PMNS_NAMES:
+ if ((e = __pmDecodeNameList(pb, &numlist, &namelist, &statlist)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeNameList: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ PDU_PMNS_NAMES:\n");
+ if (namelist != NULL)
+ __pmDumpNameList(stderr, numlist, namelist);
+ if (statlist != NULL)
+ __pmDumpStatusList(stderr, numlist, statlist);
+ }
+#endif
+ e = __pmSendNameList(fd, mypid, numlist, namelist, statlist);
+ if (namelist != NULL)
+ free(namelist);
+ if (statlist != NULL)
+ free(statlist);
+ if (e < 0) {
+ fprintf(stderr, "%s Error: SendNameList: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_PMNS_CHILD:
+ if ((e = __pmDecodeChildReq(pb, &name, &code)) < 0) {
+ fprintf(stderr, "%s Error: DecodeChildReq: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ PDU_PMNS_CHILD: name=\"%s\" code=%d\n", name, code);
+ }
+#endif
+ e = __pmSendChildReq(fd, mypid, name, code);
+ free(name);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: SendChildReq: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_PMNS_TRAVERSE:
+ if ((e = __pmDecodeTraversePMNSReq(pb, &name)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeTraversePMNSReq: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ PDU_PMNS_TRAVERSE: name=\"%s\"\n", name);
+ }
+#endif
+ e = __pmSendTraversePMNSReq(fd, mypid, name);
+ free(name);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: SendTraversePMNSReq: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_LOG_CONTROL:
+ if ((e = __pmDecodeLogControl(pb, &rp, &control, &state, &rate)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeLogControl: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ PDU_LOG_CONTROL: control=%d state=%d rate=%d\n",
+ control, state, rate);
+ __pmDumpResult(stderr, rp);
+ }
+#endif
+ e = __pmSendLogControl(fd, rp, control, state, rate);
+ pmFreeResult(rp);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: SendLogControl: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_LOG_STATUS:
+ if ((e = __pmDecodeLogStatus(pb, &lsp)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeLogStatus: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ struct timeval foo;
+ fprintf(stderr, "+ PDU_LOG_STATUS: start=%d.%06d ",
+ lsp->ls_start.tv_sec, lsp->ls_start.tv_usec);
+ foo.tv_sec = lsp->ls_start.tv_sec;
+ foo.tv_usec = lsp->ls_start.tv_usec;
+ __pmPrintStamp(stderr, &foo);
+ fprintf(stderr, "\nlast=%d.%06d ",
+ lsp->ls_last.tv_sec, lsp->ls_last.tv_usec);
+ foo.tv_sec = lsp->ls_last.tv_sec;
+ foo.tv_usec = lsp->ls_last.tv_usec;
+ __pmPrintStamp(stderr, &foo);
+ fprintf(stderr, " now=%d.%06d ",
+ lsp->ls_timenow.tv_sec, lsp->ls_timenow.tv_usec);
+ foo.tv_sec = lsp->ls_timenow.tv_sec;
+ foo.tv_usec = lsp->ls_timenow.tv_usec;
+ __pmPrintStamp(stderr, &foo);
+ fprintf(stderr, "\nstate=%d vol=%d size=%lld host=%s tz=\"%s\" tzlogger=\"%s\"\n",
+ lsp->ls_state, lsp->ls_vol, (long long)lsp->ls_size,
+ lsp->ls_hostname, lsp->ls_tz, lsp->ls_tzlogger);
+ }
+#endif
+ e = __pmSendLogStatus(fd, lsp);
+ __pmUnpinPDUBuf(pb);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: SendLogStatus: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case PDU_LOG_REQUEST:
+ if ((e = __pmDecodeLogRequest(pb, &control)) < 0) {
+ fprintf(stderr, "%s: Error: DecodeLogRequest: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ PDU_LOG_REQUEST: request=");
+ if (control == LOG_REQUEST_NEWVOLUME)
+ fprintf(stderr, "new volume\n");
+ else if (control == LOG_REQUEST_STATUS)
+ fprintf(stderr, "status\n");
+ else if (control == LOG_REQUEST_SYNC)
+ fprintf(stderr, "sync\n");
+ else
+ fprintf(stderr, " unknown (%d)!\n", control);
+ }
+#endif
+ if ((e = __pmSendLogRequest(fd, control)) < 0) {
+ fprintf(stderr, "%s: Error: SendLogRequest: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case TRACE_PDU_ACK:
+ if ((e = __pmtracedecodeack(pb, &control)) < 0) {
+ fprintf(stderr, "%s: Error: tracedecodeack: %s\n", pmProgname, pmtraceerrstr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ TRACE_PDU_ACK: ack=%d\n", control);
+ }
+#endif
+ if ((e = __pmtracesendack(fd, control)) < 0) {
+ fprintf(stderr, "%s: Error: tracesendack: %s\n", pmProgname, pmtraceerrstr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ case TRACE_PDU_DATA:
+ if ((e = __pmtracedecodedata(pb, &name, &xlen, &xtype, &proto, &value)) < 0) {
+ fprintf(stderr, "%s: Error: tracedecodedata: %s\n", pmProgname, pmtraceerrstr(e));
+ break;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "+ TRACE_PDU_DATA: tag=\"%s\" taglen=%d type=",
+ name, xlen);
+ if (xtype == TRACE_TYPE_TRANSACT)
+ fprintf(stderr, "transact");
+ else if (xtype == TRACE_TYPE_POINT)
+ fprintf(stderr, "point");
+ else if (xtype == TRACE_TYPE_OBSERVE)
+ fprintf(stderr, "observe");
+ else
+ fprintf(stderr, "unknown (%d)!", xtype);
+ fprintf(stderr, " value=%g\n", value);
+ }
+#endif
+ e = __pmtracesenddata(fd, name, xlen, xtype, value);
+ free(name);
+ if (e < 0) {
+ fprintf(stderr, "%s: Error: tracesenddata: %s\n", pmProgname, pmtraceerrstr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ default:
+ if ((e = __pmSendError(fd, mypid, PM_ERR_NYI)) < 0) {
+ fprintf(stderr, "%s: Error: SendError: %s\n", pmProgname, pmErrStr(e));
+ break;
+ }
+ fail = 0;
+ break;
+
+ }
+
+ fflush(stderr);
+
+ return fail;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int fd;
+ int port = 4323;
+ /* default port for remote connection to pdu-server */
+ int i, sts;
+ int c;
+ int newfd;
+ int new;
+ struct sockaddr_in myAddr;
+ struct linger noLinger = {1, 0};
+ char *endnum;
+ int errflag = 0;
+ __pmPDU *pb;
+ __pmPDUHdr *php;
+ char *fmt;
+ char *p;
+
+ __pmSetProgname(argv[0]);
+ mypid = getpid();
+
+ while ((c = getopt(argc, argv, "D:p:rZ:?")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'r': /* raw mode, no decode/encode */
+ raw = 1;
+ break;
+
+ case 'p':
+ port = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: port argument must be a numeric internet port number\n", pmProgname);
+ exit(1);
+ }
+ break;
+
+ case 'Z': /* $TZ timezone */
+ pmNewZone(optarg);
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc) {
+ fprintf(stderr, "Usage: %s [-D n] [-p port] [-r] [-Z timezone]\n", pmProgname);
+ exit(1);
+ }
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd < 0) {
+ perror("socket");
+ exit(1);
+ }
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &i,
+ sizeof(i)) < 0) {
+ perror("setsockopt(nodelay)");
+ exit(1);
+ }
+ /* Don't linger on close */
+ if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &noLinger, sizeof(noLinger)) < 0) {
+ perror("setsockopt(nolinger)");
+ exit(1);
+ }
+
+ memset(&myAddr, 0, sizeof(myAddr));
+ myAddr.sin_family = AF_INET;
+ myAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ myAddr.sin_port = htons(port);
+ sts = bind(fd, (struct sockaddr*)&myAddr, sizeof(myAddr));
+ if (sts < 0) {
+ fprintf(stderr, "bind(%d): %s\n", port, strerror(errno));
+ exit(1);
+ }
+
+ sts = listen(fd, 5); /* Max. of 5 pending connection requests */
+ if (sts == -1) {
+ perror("listen");
+ exit(1);
+ }
+
+ fprintf(stderr, "%s: MYPID %" FMT_PID, pmProgname, mypid);
+ /* don't have %x equivalent of FMT_PID unfortunately */
+ fmt = strdup(" %" FMT_PID "\n");
+ p = index(fmt, 'd');
+ *p = 'x';
+ fprintf(stderr, fmt, mypid);
+ free(fmt);
+
+ for ( ; ; ) {
+
+ newfd = accept(fd, (struct sockaddr *)0, 0);
+ if (newfd < 0) {
+ fprintf(stderr, "%s: accept: %s\n", pmProgname, strerror(errno));
+ exit(1);
+ }
+
+ new = 1;
+
+ if (!raw && __pmSetVersionIPC(newfd, PDU_VERSION) < 0) {
+ fprintf(stderr, "%s: __pmSetVersionIPC: %s\n", pmProgname, pmErrStr(-errno));
+ exit(1);
+ }
+
+ for ( ; ; ) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0)
+ fprintf(stderr, "\n%s: waiting ...\n", pmProgname);
+#endif
+ sts = __pmGetPDU(newfd, ANY_SIZE, TIMEOUT_NEVER, &pb);
+ if (sts == 0) {
+ fprintf(stderr, "%s: end-of-file\n", pmProgname);
+ break;
+ }
+ else if (sts < 0) {
+ fprintf(stderr, "%s: __pmGetPDU: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+
+ if (new) {
+ php = (__pmPDUHdr *)pb;
+ fprintf(stderr, "\n%s: new connection fd=%d CLIENTPID %d %x\n\n",
+ pmProgname, newfd, php->from, php->from);
+ new = 0;
+ }
+
+ if (raw) {
+ sts = __pmXmitPDU(newfd, pb);
+ if (sts < 0) {
+ fprintf(stderr, "%s: __pmXmitPDU: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ continue;
+ }
+
+ /*
+ * use PDU type to decode via libpcp, and then libpcp to
+ * send (encode + xmit)
+ */
+ if ((sts = decode_encode(newfd, pb, sts)) < 0) {
+ fprintf(stderr, "%s: decode_encode error, disconnect\n", pmProgname);
+ break;
+ }
+ }
+
+ close(newfd);
+ }
+
+}
diff --git a/qa/src/pducheck.c b/qa/src/pducheck.c
new file mode 100644
index 0000000..376bdf7
--- /dev/null
+++ b/qa/src/pducheck.c
@@ -0,0 +1,1512 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * Mongo PDU conversion exerciser --
+ * + if run standalone uses Send and Recv down its own pipe.
+ * + if run remotely uses pdu-server at other end to echo PDUs
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/trace.h>
+#include <pcp/trace_dev.h>
+#include <math.h>
+#include "localconfig.h"
+
+static int fd[2];
+static int standalone = 1;
+static int e;
+static pmID pmidlist[6];
+
+/*
+ * warning:
+ * instlist[], namelist[] and statlist[] must have the same number
+ * of elements!
+ */
+
+static int instlist[] = {
+ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024
+};
+
+static char *namelist[] = {
+ /* 1 */ "alpha",
+ /* 2 */ "beta",
+ /* 4 */ "gamma",
+ /* 8 */ "long-non-greek-letter-name-in-the-middle",
+ /* 16 */ "delta",
+ /* 32 */ "epsilon",
+ /* 64 */ "phi",
+ /* 128 */ "mu",
+ /* 256 */ "lambda",
+ /* 512 */ "omega",
+ /* 1024 */ "theta"
+};
+
+static int statlist[] = {
+ -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5
+};
+
+static struct {
+ int inst;
+ char *name;
+} indomlist[] = {
+ { 0xdead, NULL },
+ { 0, "fisho" },
+ { 0, NULL }
+};
+
+static pmDesc desc = {
+ 0xdeadbeef, PM_TYPE_64, 0xface, PM_SEM_COUNTER,
+ { 1, -1 , 0, PM_SPACE_MBYTE, PM_TIME_HOUR, 0 }
+};
+
+__pmLoggerStatus logstat;
+
+static int timeout = TIMEOUT_DEFAULT;
+static int iter = 5;
+static int pass;
+
+static long
+foorand(void)
+{
+ static long rn[] = {
+ 851401618, 1804928587, 758783491, 959030623, 684387517, 1903590565,
+ 33463914, 1254324197, 342241519, 824023566, 1483920592, 126398554,
+ 1932422408, 351212254, 341603450, 1144747756, 1297389768, 1251336619,
+ 579758561, 838545539, 630072926, 1594243340, 641078858, 162216788,
+ 869693583, 1841205112, 2022861571, 1423418003, 1817792895, 5916492,
+ 992951867, 1143741253, 1691952160, 570397931, 2110444415, 658816051,
+ 1290326580, 1307206911, 456208845, 1902445306, 654246144, 326116574,
+ 725123414, 832100416, 1382141583, 1618243337, 1296255701, 1141662977,
+ 986468767, 1401208270, 702616199, 2032315143, 790359597, 2026989069,
+ 15952070, 1109389944, 585771160, 52182039, 1271212614, 440155785
+ };
+ static int cnum = sizeof(rn) / sizeof (long);
+ static int cur=-1;
+
+
+ cur = (cur+1) % cnum;
+ return (rn[cur]);
+}
+
+static void
+_z(void)
+{
+ __pmPDU *pb;
+ __pmTracePDU *tpb;
+ int i;
+ int j;
+ int k;
+ int n;
+ pmID pmid;
+ pmResult *rp;
+ pmValueBlock myvb;
+ pmValueBlock *gvbp;
+ pmValueBlock *xvbp;
+ pmAtomValue av;
+ int ident;
+ int type;
+ char *buffer;
+ int control;
+ int attr;
+ int rate;
+ int state;
+ int num;
+ pmID *pmidp;
+ __pmInResult inres;
+ __pmInResult *inresp;
+ pmInDom indom;
+ int inst;
+ pmDesc result_desc;
+ pmDesc *descp = &result_desc;
+ int ctxnum;
+ __pmTimeval now;
+ __pmProfile curprof;
+ __pmInDomProfile idp[2];
+ __pmProfile *profp;
+ pmResult *resp;
+ int code;
+ int nv;
+ int sav_nv;
+ int sav_np;
+ int sender;
+ int count;
+ char *vp;
+ __pmCred increds[1];
+ __pmCred *outcreds;
+ char *resname;
+ char **resnamelist;
+ int *resstatlist;
+ __pmLoggerStatus *lsp;
+ double pi = M_PI;
+ char mytag[10];
+ /*
+ * use pid as "from" context for backwards compatibility to
+ * keep QA tests happy, rather than FROM_ANON which would be
+ * the more normal value for this usage.
+ */
+ pid_t mypid = getpid();
+
+/* PDU_ERROR */
+ for (i = -1; i < 2; i += 2) {
+ if ((e = __pmSendError(fd[1], mypid, i * PM_ERR_GENERIC)) < 0) {
+ fprintf(stderr, "Error: SendError: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvError: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvError: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_ERROR) {
+ fprintf(stderr, "Error: RecvError: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ __pmOverrideLastFd(PDU_OVERRIDE2);
+ if ((e = __pmDecodeError(pb, &code)) < 0) {
+ fprintf(stderr, "Error: DecodeError: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (code != i * PM_ERR_GENERIC)
+ fprintf(stderr, "Botch: Error: code: got: 0x%x expect: 0x%x\n",
+ code, i * PM_ERR_GENERIC);
+ }
+ }
+ }
+ }
+
+/* PDU_RESULT */
+ resp = NULL;
+ num = 7; /* the _maximum_ number of merics we have */
+ rp = (pmResult *)malloc(sizeof(*rp) + (num -1)*sizeof(pmValueSet *));
+ rp->timestamp.tv_sec = 30 * 60 * 60; /* 30 hrs after the epoch */
+ rp->timestamp.tv_usec = 123456; /* plus a gnat */
+ i = 0;
+ /* singular instance, insitu value */
+ rp->vset[i] = (pmValueSet *)malloc(sizeof(*rp->vset[0]));
+ rp->vset[i]->pmid = 0xdead;
+ rp->vset[i]->numval = 1;
+ rp->vset[i]->valfmt = PM_VAL_INSITU;
+ rp->vset[i]->vlist[0].inst = PM_IN_NULL;
+ rp->vset[i]->vlist[0].value.lval = 1234;
+ i++;
+ /* 3 instances, all values insitu */
+ rp->vset[i] = (pmValueSet *)malloc(sizeof(*rp->vset[1])+2*sizeof(pmValue));
+ rp->vset[i]->pmid = 0xbeef;
+ rp->vset[i]->numval = 3;
+ rp->vset[i]->valfmt = PM_VAL_INSITU;
+ rp->vset[i]->vlist[0].inst = 2;
+ rp->vset[i]->vlist[0].value.lval = 2345;
+ rp->vset[i]->vlist[1].inst = 4;
+ rp->vset[i]->vlist[1].value.lval = 3456;
+ rp->vset[i]->vlist[2].inst = 8;
+ rp->vset[i]->vlist[2].value.lval = 4567;
+ i++;
+ /* singular instance, STRING value in pmValueBlock */
+ rp->vset[i] = (pmValueSet *)malloc(sizeof(*rp->vset[0]));
+ rp->vset[i]->pmid = pmidlist[0];
+ rp->vset[i]->numval = 1;
+ rp->vset[i]->valfmt = PM_VAL_DPTR;
+ rp->vset[i]->vlist[0].inst = PM_IN_NULL;
+ rp->vset[i]->vlist[0].value.pval = &myvb;
+ rp->vset[i]->vlist[0].value.pval->vtype = PM_TYPE_STRING;
+ rp->vset[i]->vlist[0].value.pval->vlen = PM_VAL_HDR_SIZE + 2;
+ av.cp = "0";
+ if ((e = __pmStuffValue(&av, &rp->vset[i]->vlist[0], PM_TYPE_STRING)) < 0) {
+ fprintf(stderr, "Error: __pmStuffValue vset[%d] PM_TYPE_STRING: %s\n", i, pmErrStr(e));
+ exit(1);
+ }
+ rp->vset[i]->vlist[0].value.pval->vbuf[0] = '0' + pass;
+ i++;
+ /* singular instance, U64 value in pmValueBlock */
+ rp->vset[i] = (pmValueSet *)malloc(sizeof(*rp->vset[0]));
+ rp->vset[i]->pmid = pmidlist[1];
+ rp->vset[i]->numval = 1;
+ rp->vset[i]->vlist[0].inst = PM_IN_NULL;
+ av.ull = 0x8765432112345678LL;
+ if ((e = __pmStuffValue(&av, &rp->vset[i]->vlist[0], PM_TYPE_U64)) < 0) {
+ fprintf(stderr, "Error: __pmStuffValue vset[%d] PM_TYPE_U64: %s\n", i, pmErrStr(e));
+ exit(1);
+ }
+ rp->vset[i]->valfmt = e;
+ i++;
+ /* singular instance, FLOAT value in pmValueBlock */
+ rp->vset[i] = (pmValueSet *)malloc(sizeof(*rp->vset[0]));
+ rp->vset[i]->pmid = pmidlist[2];
+ rp->vset[i]->numval = 1;
+ rp->vset[i]->vlist[0].inst = PM_IN_NULL;
+ av.f = 4.3E+21;
+ if ((e = __pmStuffValue(&av, &rp->vset[i]->vlist[0], PM_TYPE_FLOAT)) < 0) {
+ fprintf(stderr, "Error: __pmStuffValue vset[%d] PM_TYPE_FLOAT: %s\n", i, pmErrStr(e));
+ exit(1);
+ }
+ rp->vset[i]->valfmt = e;
+ i++;
+ /* singular instance, DOUBLE value in pmValueBlock */
+ rp->vset[i] = (pmValueSet *)malloc(sizeof(*rp->vset[0]));
+ rp->vset[i]->pmid = pmidlist[3];
+ rp->vset[i]->numval = 1;
+ rp->vset[i]->vlist[0].inst = PM_IN_NULL;
+ av.d = 4.56E+123;
+ if ((e = __pmStuffValue(&av, &rp->vset[i]->vlist[0], PM_TYPE_DOUBLE)) < 0) {
+ fprintf(stderr, "Error: __pmStuffValue vset[%d] PM_TYPE_DOUBLE: %s\n", i, pmErrStr(e));
+ exit(1);
+ }
+ rp->vset[i]->valfmt = e;
+ i++;
+ /* no values */
+ rp->vset[i] = (pmValueSet *)malloc(sizeof(*rp->vset[0]));
+ rp->vset[i]->pmid = 0xdeadcafe;
+ rp->vset[i]->numval = PM_ERR_GENERIC;
+ i++;
+ /* done with setup, do it! */
+ rp->numpmid = i;
+ if ((e = __pmSendResult(fd[1], mypid, rp)) < 0) {
+ fprintf(stderr, "Error: SendResult: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvResult: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvResult: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_RESULT) {
+ fprintf(stderr, "Error: RecvResult: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmDecodeResult(pb, &resp)) < 0) {
+ fprintf(stderr, "Error: DecodeResult: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ }
+ }
+ if (resp->timestamp.tv_sec != rp->timestamp.tv_sec)
+ fprintf(stderr, "Botch: Result: tv_sec: got: %d expect: %d\n",
+ (int)resp->timestamp.tv_sec, (int)rp->timestamp.tv_sec);
+ if (resp->timestamp.tv_usec != rp->timestamp.tv_usec)
+ fprintf(stderr, "Botch: Result: tv_usec: got: %d expect: %d\n",
+ (int)resp->timestamp.tv_usec, (int)rp->timestamp.tv_usec);
+ if (resp->numpmid != rp->numpmid)
+ fprintf(stderr, "Botch: Result: numpmid: got: %d expect: %d\n",
+ resp->numpmid, rp->numpmid);
+ for (i = 0; i < rp->numpmid; i++) {
+ if (resp->vset[i]->pmid != rp->vset[i]->pmid)
+ fprintf(stderr, "Botch: Result: vset[%d].pmid: got: 0x%x expect: 0x%x\n",
+ i, resp->vset[i]->pmid, rp->vset[i]->pmid);
+ if (resp->vset[i]->numval != rp->vset[i]->numval) {
+ fprintf(stderr, "Botch: Result: vset[%d].numval: got: %d expect: %d\n",
+ i, resp->vset[i]->numval, rp->vset[i]->numval);
+ continue;
+ }
+ if (resp->vset[i]->numval < 0)
+ continue;
+ if (resp->vset[i]->valfmt != rp->vset[i]->valfmt)
+ fprintf(stderr, "Botch: Result: vset[%d].valfmt: got: %d expect: %d\n",
+ i, resp->vset[i]->valfmt, rp->vset[i]->valfmt);
+ for (j = 0; j < rp->vset[i]->numval; j++) {
+ if (resp->vset[i]->vlist[j].inst != rp->vset[i]->vlist[j].inst)
+ fprintf(stderr, "Botch: Result: vset[%d][%d].inst: got: %d expect: %d\n",
+ i, j, resp->vset[i]->vlist[j].inst,
+ rp->vset[i]->vlist[j].inst);
+ if (resp->vset[i]->valfmt != rp->vset[i]->valfmt)
+ continue;
+ if (resp->vset[i]->valfmt == PM_VAL_INSITU) {
+ if (resp->vset[i]->vlist[j].value.lval != rp->vset[i]->vlist[j].value.lval)
+ fprintf(stderr, "Botch: Result: vset[%d][%d].value.lval: got: %d expect: %d\n",
+ i, j, resp->vset[i]->vlist[j].value.lval,
+ rp->vset[i]->vlist[j].value.lval);
+ continue;
+ }
+ /* NOT insitu */
+ gvbp = resp->vset[i]->vlist[j].value.pval;
+ xvbp = rp->vset[i]->vlist[j].value.pval;
+ if (gvbp->vlen != xvbp->vlen)
+ fprintf(stderr, "Botch: Result: vset[%d][%d].value.pval->vlen: got %d expect %d\n",
+ i, j, gvbp->vlen, xvbp->vlen);
+ if (gvbp->vtype != xvbp->vtype) {
+ fprintf(stderr, "Botch: Result: vset[%d][%d].value.pval->vtype: got %d expect %d\n",
+ i, j, gvbp->vtype, xvbp->vtype);
+ continue;
+ }
+ switch (gvbp->vtype) {
+ pmAtomValue gav;
+ pmAtomValue xav;
+ case PM_TYPE_STRING:
+ if (strncmp(gvbp->vbuf, xvbp->vbuf, gvbp->vlen - sizeof(int)) != 0)
+ fprintf(stderr, "Botch: Result: vset[%d][%d].value.pval->vbuf: got \"%*.*s\" expect \"%*.*s\"\n",
+ i, j, gvbp->vlen, gvbp->vlen, gvbp->vbuf,
+ gvbp->vlen, gvbp->vlen, xvbp->vbuf);
+ break;
+ case PM_TYPE_64:
+ case PM_TYPE_U64:
+ memcpy(&gav.ull, gvbp->vbuf, sizeof(__uint64_t));
+ memcpy(&xav.ull, xvbp->vbuf, sizeof(__uint64_t));
+ if (gav.ull != xav.ull)
+ fprintf(stderr, "Botch: Result: vset[%d][%d].value.pval->ull: got %lld expect %lld\n",
+ i, j, (long long)gav.ull, (long long)xav.ull);
+ break;
+ case PM_TYPE_FLOAT:
+ memcpy(&gav.f, gvbp->vbuf, sizeof(float));
+ memcpy(&xav.f, xvbp->vbuf, sizeof(float));
+ if (gav.f != xav.f)
+ fprintf(stderr, "Botch: Result: vset[%d][%d].value.pval->ull: got %e expect %e\n",
+ i, j, (double)gav.f, (double)xav.f);
+ break;
+ case PM_TYPE_DOUBLE:
+ memcpy(&gav.d, gvbp->vbuf, sizeof(double));
+ memcpy(&xav.d, xvbp->vbuf, sizeof(double));
+ if (gav.d != xav.d)
+ fprintf(stderr, "Botch: Result: vset[%d][%d].value.pval->ull: got %e expect %e\n",
+ i, j, gav.d, xav.d);
+ break;
+ }
+ }
+ }
+ if (resp != NULL)
+ pmFreeResult(resp);
+
+/* PDU_PROFILE */
+ n = sizeof(instlist) / sizeof(instlist[0]);
+ curprof.state = PM_PROFILE_EXCLUDE;
+ curprof.profile_len = 2;
+ curprof.profile = idp;
+ idp[0].indom = 0xdeadcafe;
+ idp[0].state = PM_PROFILE_INCLUDE;
+ idp[0].instances_len = 1 + (foorand() % n);
+ idp[0].instances = instlist;
+ idp[1].indom = 0xface;
+ idp[1].state = PM_PROFILE_EXCLUDE;
+ idp[1].instances_len = 1 + (foorand() % n);
+ idp[1].instances = &instlist[n - idp[1].instances_len];
+ /* context no == 42 ... hack */
+ if ((e = __pmSendProfile(fd[1], mypid, 42, &curprof)) < 0) {
+ fprintf(stderr, "Error: SendProfile: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvProfile: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvProfile: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_PROFILE) {
+ fprintf(stderr, "Error: RecvProfile: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ profp = NULL;
+ if ((e = __pmDecodeProfile(pb, &ctxnum, &profp)) < 0) {
+ fprintf(stderr, "Error: DecodeProfile: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (ctxnum != 42)
+ fprintf(stderr, "Botch: Profile: ctxnum: got: %d expect: %d\n",
+ ctxnum, 42);
+ if (profp == NULL)
+ fprintf(stderr, "Botch: Profile: profp is NULL!\n");
+ else {
+ if (profp->state != curprof.state)
+ fprintf(stderr, "Botch: Profile: global state: got: %d expect: %d\n",
+ profp->state, curprof.state);
+ if (profp->profile_len != curprof.profile_len)
+ fprintf(stderr, "Botch: Profile: profile_len: got: %d expect: %d\n",
+ profp->profile_len, curprof.profile_len);
+ if (profp->profile == NULL)
+ fprintf(stderr, "Botch: Profile: profp->profile is NULL!\n");
+ else {
+ for (i = 0; i < curprof.profile_len; i++) {
+ if (profp->profile[i].indom != curprof.profile[i].indom)
+ fprintf(stderr, "Botch: Profile: [%d]indom: got: 0x%x expect: 0x%x\n",
+ i, profp->profile[i].indom, curprof.profile[i].indom);
+ if (profp->profile[i].state != curprof.profile[i].state)
+ fprintf(stderr, "Botch: Profile: [%d]state: got: %d expect: %d\n",
+ i, profp->profile[i].state, curprof.profile[i].state);
+ if (profp->profile[i].instances_len != curprof.profile[i].instances_len)
+ fprintf(stderr, "Botch: Profile: [%d]instances_len: got: %d expect: %d\n",
+ i, profp->profile[i].instances_len, curprof.profile[i].instances_len);
+ else if (profp->profile[i].instances == NULL)
+ fprintf(stderr, "Botch: Profile: profp->profile[%d].instances is NULL!\n", i);
+ else {
+ for (k = 0; k <curprof.profile[i].instances_len; k++) {
+ if (profp->profile[i].instances[k] != curprof.profile[i].instances[k])
+ fprintf(stderr, "Botch: Profile: [%d]instances[%d]: got: %d expect: %d\n",
+ i, k, profp->profile[i].instances[k], curprof.profile[i].instances[k]);
+ }
+ free(profp->profile[i].instances);
+ }
+ }
+ free(profp->profile);
+ }
+ free(profp);
+ }
+ }
+ }
+ }
+
+/* PDU_FETCH */
+ n = sizeof(pmidlist) / sizeof(pmidlist[0]);
+ if (pass != 0)
+ n = 1 + (foorand() % n);
+ if ((e = __pmSendFetch(fd[1], mypid, 43, (__pmTimeval *)0, n, pmidlist)) < 0) {
+ fprintf(stderr, "Error: SendFetch: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvFetch: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvFetch: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_FETCH) {
+ fprintf(stderr, "Error: RecvFetch: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmDecodeFetch(pb, &ctxnum, &now, &num, &pmidp)) < 0) {
+ fprintf(stderr, "Error: DecodeFetch: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (ctxnum != 43)
+ fprintf(stderr, "Botch: Fetch: ctxnum: got: %d expect: %d\n",
+ ctxnum, 43);
+ if (num != n)
+ fprintf(stderr, "Botch: Fetch: num: got: %d expect: %d\n",
+ num, n);
+ else {
+ for (i = 0; i < num; i++) {
+ if (pmidlist[i] != pmidp[i])
+ fprintf(stderr, "Botch: Fetch: pmidlist[%d]: got: 0x%x expect: 0x%x\n",
+ i, pmidp[i], pmidlist[i]);
+ }
+ }
+ __pmUnpinPDUBuf(pmidp);
+ }
+ }
+ }
+
+/* PDU_DESC_REQ */
+ if ((e = __pmSendDescReq(fd[1], mypid, 0xdeadbeef)) < 0) {
+ fprintf(stderr, "Error: SendDescReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvDescReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvDescReq: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_DESC_REQ) {
+ fprintf(stderr, "Error: RecvDescReq: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmDecodeDescReq(pb, &pmid)) < 0) {
+ fprintf(stderr, "Error: DecodeDescReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (pmid != 0xdeadbeef)
+ fprintf(stderr, "Botch: DescReq: pmid: got: 0x%x expect: 0x%x\n",
+ pmid, 0xdeadbeef);
+ }
+ }
+ }
+
+/* PDU_DESC */
+ if ((e = __pmSendDesc(fd[1], mypid, &desc)) < 0) {
+ fprintf(stderr, "Error: SendDesc: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvDesc: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvDesc: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_DESC) {
+ fprintf(stderr, "Error: RecvDesc: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmDecodeDesc(pb, descp)) < 0) {
+ fprintf(stderr, "Error: DecodeDesc: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (descp->pmid != desc.pmid)
+ fprintf(stderr, "Botch: Desc: pmid: got: 0x%x expect: 0x%x\n",
+ descp->pmid, desc.pmid);
+ if (descp->type != desc.type)
+ fprintf(stderr, "Botch: Desc: type: got: %d expect: %d\n",
+ descp->type, desc.type);
+ if (descp->indom != desc.indom)
+ fprintf(stderr, "Botch: Desc: indom: got: 0x%x expect: 0x%x\n",
+ descp->indom, desc.indom);
+ if (descp->sem != desc.sem)
+ fprintf(stderr, "Botch: Desc: sem: got: %d expect: %d\n",
+ descp->sem, desc.sem);
+ if (descp->units.dimSpace != desc.units.dimSpace)
+ fprintf(stderr, "Botch: Desc: dimSpace: got: %d expect: %d\n",
+ descp->units.dimSpace, desc.units.dimSpace);
+ if (descp->units.dimTime != desc.units.dimTime)
+ fprintf(stderr, "Botch: Desc: dimTime: got: %d expect: %d\n",
+ descp->units.dimTime, desc.units.dimTime);
+ if (descp->units.dimCount != desc.units.dimCount)
+ fprintf(stderr, "Botch: Desc: dimCount: got: %d expect: %d\n",
+ descp->units.dimCount, desc.units.dimCount);
+ if (descp->units.scaleSpace != desc.units.scaleSpace)
+ fprintf(stderr, "Botch: Desc: scaleSpace: got: %d expect: %d\n",
+ descp->units.scaleSpace, desc.units.scaleSpace);
+ if (descp->units.scaleTime != desc.units.scaleTime)
+ fprintf(stderr, "Botch: Desc: scaleTime: got: %d expect: %d\n",
+ descp->units.scaleTime, desc.units.scaleTime);
+ if (descp->units.scaleCount != desc.units.scaleCount)
+ fprintf(stderr, "Botch: Desc: scaleCount: got: %d expect: %d\n",
+ descp->units.scaleCount, desc.units.scaleCount);
+ }
+ }
+ }
+
+/* PDU_INSTANCE_REQ */
+ n = sizeof(indomlist) / sizeof(indomlist[0]);
+ if (pass != 0)
+ n = 1 + (foorand() % n);
+ now.tv_sec = 60 * 60 * 60; /* 60 hrs after the epoch */
+ now.tv_usec = 654321; /* plus a gnat */
+ for (i = 0; i < n; i++) {
+ __pmTimeval tmp;
+ if ((e = __pmSendInstanceReq(fd[1], mypid, &now, 0xface, indomlist[i].inst, indomlist[i].name)) < 0) {
+ fprintf(stderr, "Error: SendInstanceReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvInstanceReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvInstanceReq: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_INSTANCE_REQ) {
+ fprintf(stderr, "Error: RecvInstanceReq: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmDecodeInstanceReq(pb, &tmp, &indom, &inst, &resname)) < 0) {
+ fprintf(stderr, "Error: DecodeInstanceReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (tmp.tv_sec != now.tv_sec || tmp.tv_usec != now.tv_usec)
+ fprintf(stderr, "Botch: InstanceReq: when: got: %d,%d expect: %d,%d\n",
+ tmp.tv_sec, tmp.tv_usec, now.tv_sec, now.tv_usec);
+ if (indom != 0xface)
+ fprintf(stderr, "Botch: InstanceReq: indom: got: 0x%x expect: 0x%x\n",
+ indom, 0xface);
+ if (inst != indomlist[i].inst)
+ fprintf(stderr, "Botch: InstanceReq: inst: got: %d expect: %d\n",
+ inst, indomlist[i].inst);
+ if (resname != (char *)0 && indomlist[i].name != (char *)0 &&
+ strcmp(resname, indomlist[i].name) != 0)
+ fprintf(stderr, "Botch: InstanceReq: name: got: \"%s\" expect: \"%s\"\n",
+ resname, indomlist[i].name);
+ if ((resname == (char *)0 || indomlist[i].name == 0) &&
+ resname != indomlist[i].name)
+ fprintf(stderr, "Botch: InstanceReq: name: got: " PRINTF_P_PFX "%p expect: " PRINTF_P_PFX "%p\n",
+ resname, indomlist[i].name);
+ if (resname != (char *)0)
+ free(resname);
+ }
+ }
+ }
+ }
+
+/* PDU_INSTANCE */
+ n = sizeof(instlist) / sizeof(instlist[0]);
+ if (pass != 0)
+ n = (foorand() % n); /* zero is ok here */
+ inres.indom = 0x1234;
+ inres.numinst = n;
+ for (k = 0; k < 3; k++) {
+
+ if (k == 0) {
+ inres.instlist = instlist;
+ inres.namelist = namelist;
+ }
+ else if (k == 1) {
+ inres.instlist = NULL;
+ inres.namelist = namelist;
+ }
+ else {
+ inres.instlist = instlist;
+ inres.namelist = NULL;
+ }
+ inresp = NULL;
+ if ((e = __pmSendInstance(fd[1], mypid, &inres)) < 0) {
+ fprintf(stderr, "Error: SendInstance: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvInstance: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvInstance: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_INSTANCE) {
+ fprintf(stderr, "Error: RecvInstance: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmDecodeInstance(pb, &inresp)) < 0) {
+ fprintf(stderr, "Error: DecodeInstance: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (inresp->indom != inres.indom)
+ fprintf(stderr, "Botch: Instance: indom: got: 0x%x expect: 0x%x\n",
+ inresp->indom, inres.indom);
+ if (inresp->numinst != inres.numinst)
+ fprintf(stderr, "Botch: Instance: numinst: got: %d expect: %d\n",
+ inresp->numinst, inres.numinst);
+ else {
+ for (i = 0; i < inres.numinst; i++) {
+ if (inres.instlist != NULL &&
+ inresp->instlist[i] != inres.instlist[i])
+ fprintf(stderr, "Botch: Instance: instlist[%d]: got: %d expect: %d\n",
+ i, inresp->instlist[i], inres.instlist[i]);
+ if (inres.namelist != NULL &&
+ strcmp(inresp->namelist[i], inres.namelist[i]) != 0)
+ fprintf(stderr, "Botch: Instance: namelist[%d]: got: \"%s\" expect: \"%s\"\n",
+ i, inresp->namelist[i], inres.namelist[i]);
+ }
+ }
+ }
+ }
+ }
+ if (inresp != NULL)
+ __pmFreeInResult(inresp);
+ }
+
+/* PDU_TEXT_REQ */
+ if ((e = __pmSendTextReq(fd[1], mypid, 0x12341234, PM_TEXT_PMID|PM_TEXT_ONELINE)) < 0) {
+ fprintf(stderr, "Error: SendTextReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvTextReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvTextReq: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_TEXT_REQ) {
+ fprintf(stderr, "Error: RecvTextReq: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmDecodeTextReq(pb, &ident, &type)) < 0) {
+ fprintf(stderr, "Error: DecodeTextReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (ident != 0x12341234)
+ fprintf(stderr, "Botch: TextReq: ident: got: 0x%x expect: 0x%x\n",
+ ident, 0x12341234);
+ if (type != (PM_TEXT_PMID|PM_TEXT_ONELINE))
+ fprintf(stderr, "Botch: TextReq: type: got: 0x%x expect: 0x%x\n",
+ type, PM_TEXT_PMID|PM_TEXT_ONELINE);
+ }
+ }
+ }
+
+/* PDU_TEXT */
+#define MARY "mary had a little lamb\nits fleece was white as snow\n"
+ if ((e = __pmSendText(fd[1], mypid, 0x43214321, MARY)) < 0) {
+ fprintf(stderr, "Error: SendText: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvText: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvText: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_TEXT) {
+ fprintf(stderr, "Error: RecvText: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ buffer = NULL;
+ if ((e = __pmDecodeText(pb, &ident, &buffer)) < 0) {
+ fprintf(stderr, "Error: DecodeText: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (ident != 0x43214321)
+ fprintf(stderr, "Botch: TextReq: ident: got: 0x%x expect: 0x%x\n",
+ ident, 0x43214321);
+ if (buffer == NULL)
+ fprintf(stderr, "Botch: TextReq: buffer is NULL!\n");
+ else {
+ if (strcmp(buffer, MARY) != 0)
+ fprintf(stderr, "Botch: Text: buffer: got: \"%s\" expect: \"%s\"\n",
+ buffer, MARY);
+ free(buffer);
+ }
+ }
+ }
+ }
+
+#if PCP_VER >= 3800
+/* PDU_AUTH */
+#define USERNAME "pcpqa"
+ if ((e = __pmSendAuth(fd[1], mypid, PCP_ATTR_USERNAME, USERNAME, sizeof(USERNAME))) < 0) {
+ fprintf(stderr, "Error: SendAuth: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvAuth: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvAuth: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_AUTH) {
+ fprintf(stderr, "Error: RecvAuth: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ buffer = NULL;
+ if ((e = __pmDecodeAuth(pb, &attr, &buffer, &count)) < 0) {
+ fprintf(stderr, "Error: DecodeAuth: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (attr != PCP_ATTR_USERNAME)
+ fprintf(stderr, "Botch: AuthAttr: attr: got: 0x%x expect: 0x%x\n",
+ attr, PCP_ATTR_USERNAME);
+ if (count != sizeof(USERNAME))
+ fprintf(stderr, "Botch: AuthAttr: length: got: 0x%x expect: 0x%x\n",
+ count, (int)sizeof(USERNAME));
+ if (buffer == NULL)
+ fprintf(stderr, "Botch: AuthAttr: payload is NULL!\n");
+ else {
+ if (strncmp(buffer, USERNAME, sizeof(USERNAME)) != 0)
+ fprintf(stderr, "Botch: AuthAttr: payload: got: \"%s\" expect: \"%s\"\n",
+ buffer, USERNAME);
+ }
+ }
+ }
+ }
+#endif
+
+/* PDU_CREDS */
+ sender = 0;
+ count = -1;
+ outcreds = NULL;
+ increds[0].c_type = CVERSION;
+ increds[0].c_vala = (unsigned char)PDU_VERSION;
+ increds[0].c_valb = (unsigned char)10;
+ increds[0].c_valc = (unsigned char)11;
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "0 = %x\n", *(unsigned int*)&(increds[0]));
+ }
+#endif
+ if ((e = __pmSendCreds(fd[1], mypid, 1, increds)) < 0) {
+ fprintf(stderr, "Error: SendCreds: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvCreds: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvCreds: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_CREDS) {
+ fprintf(stderr, "Error: RecvCreds: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ outcreds = NULL;
+ if ((e = __pmDecodeCreds(pb, &sender, &count, &outcreds)) < 0) {
+ fprintf(stderr, "Error: DecodeCreds: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (outcreds == NULL)
+ fprintf(stderr, "Botch: DecodeCreds: outcreds is NULL!\n");
+ else {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ fprintf(stderr, "0 = %x\n", *(unsigned int*)&(outcreds[0]));
+ }
+#endif
+ if (outcreds[0].c_type != CVERSION)
+ fprintf(stderr, "Botch: Creds: type: got: %x expect: %x\n",
+ (unsigned int)outcreds[0].c_type, (unsigned int)CVERSION);
+ if ((outcreds[0].c_vala != (unsigned char)PDU_VERSION) ||
+ (outcreds[0].c_valb != (unsigned char)10) ||
+ (outcreds[0].c_valc != (unsigned char)11))
+ fprintf(stderr, "Botch: Creds: value mismatch (cred #0)\n");
+ if (standalone && sender != mypid)
+ fprintf(stderr, "Botch: Creds: sender pid mismatch: got:%d expect:%" FMT_PID "\n",
+ sender, mypid);
+ if (count != 1)
+ fprintf(stderr, "Botch: Creds: PDU count: got:%d expect:%d\n", count, 1);
+ if (outcreds != NULL)
+ free(outcreds);
+ }
+ }
+ }
+
+/* PDU_PMNS_IDS */
+ n = sizeof(pmidlist) / sizeof(pmidlist[0]);
+ if (pass != 0)
+ n = 1 + (foorand() % n);
+ if ((e = __pmSendIDList(fd[1], mypid, n, pmidlist, 43)) < 0) {
+ fprintf(stderr, "Error: SendIDList: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvIDList: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvIDList: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_PMNS_IDS) {
+ fprintf(stderr, "Error: RecvIDList: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ pmID mylist[6];
+ if ((e = __pmDecodeIDList(pb, n, mylist, &k)) < 0) {
+ fprintf(stderr, "Error: DecodeIDList: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ for (i = 0; i < n; i++) {
+ if (pmidlist[i] != mylist[i])
+ fprintf(stderr, "Botch: IDList: pmidlist[%d]: got: 0x%x expect: 0x%x\n",
+ i, mylist[i], pmidlist[i]);
+ }
+ if (k != 43)
+ fprintf(stderr, "Botch: IDList: sts: got: %d expect: %d\n",
+ k, 43);
+ }
+ }
+ }
+
+/* PDU_PMNS_NAMES */
+ n = sizeof(namelist) / sizeof(namelist[0]);
+ if (pass != 0)
+ n = 1 + (foorand() % n);
+ if ((e = __pmSendNameList(fd[1], mypid, n, namelist, statlist)) < 0) {
+ fprintf(stderr, "Error: SendNameList: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvNameList: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvNameList: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_PMNS_NAMES) {
+ fprintf(stderr, "Error: RecvNameList: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ resnamelist = NULL;
+ resstatlist = NULL;
+ if ((e = __pmDecodeNameList(pb, &num, &resnamelist, &resstatlist)) < 0) {
+ fprintf(stderr, "Error: DecodeNameList: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (num != n)
+ fprintf(stderr, "Botch: NameList: num: got: %d expect: %d\n",
+ num, n);
+ if (resnamelist == NULL)
+ fprintf(stderr, "Botch: NameList: resnamelist is NULL!\n");
+ else if (resstatlist == NULL)
+ fprintf(stderr, "Botch: NameList: resstatlist is NULL!\n");
+ else {
+ for (i = 0; i < num; i++) {
+ if (strcmp(resnamelist[i], namelist[i]) != 0)
+ fprintf(stderr, "Botch: NameList: name[%d]: got: \"%s\" expect: \"%s\"\n",
+ i, resnamelist[i], namelist[i]);
+ if (resstatlist[i] != statlist[i])
+ fprintf(stderr, "Botch: NameList: stat[%d]: got: %d expect: %d\n",
+ i, resstatlist[i], statlist[i]);
+ }
+ free(resnamelist);
+ free(resstatlist);
+ }
+ }
+ }
+ }
+ /* and again, with NULL statlist */
+ if ((e = __pmSendNameList(fd[1], mypid, n, namelist, NULL)) < 0) {
+ fprintf(stderr, "Error: SendNameList-2: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvNameList-2: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvNameList-2: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_PMNS_NAMES) {
+ fprintf(stderr, "Error: RecvNameList-2: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ resnamelist = NULL;
+ resstatlist = NULL;
+ if ((e = __pmDecodeNameList(pb, &num, &resnamelist, &resstatlist)) < 0) {
+ fprintf(stderr, "Error: DecodeNameList-2: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (num != n)
+ fprintf(stderr, "Botch: NameList-2: num: got: %d expect: %d\n",
+ num, n);
+ if (resstatlist != NULL) {
+ fprintf(stderr, "Botch: NameList-2: resstatlist is NOT NULL!\n");
+ free(resstatlist);
+ }
+ if (resnamelist == NULL)
+ fprintf(stderr, "Botch: NameList-2: resnamelist is NULL!\n");
+ else {
+ for (i = 0; i < num; i++) {
+ if (strcmp(resnamelist[i], namelist[i]) != 0)
+ fprintf(stderr, "Botch: NameList-2: name[%d]: got: \"%s\" expect: \"%s\"\n",
+ i, resnamelist[i], namelist[i]);
+ }
+ free(resnamelist);
+ }
+ }
+ }
+ }
+
+/* PDU_PMNS_CHILD */
+ if ((e = __pmSendChildReq(fd[1], mypid, "mumble.fumble", 1)) < 0) {
+ fprintf(stderr, "Error: SendChildReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvChildReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvChildReq: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_PMNS_CHILD) {
+ fprintf(stderr, "Error: RecvChildReq: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ resname = NULL;
+ if ((e = __pmDecodeChildReq(pb, &resname, &k)) < 0) {
+ fprintf(stderr, "Error: DecodeChildReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (resname == NULL)
+ fprintf(stderr, "Botch: DecodeChildReq: resname is NULL!\n");
+ else {
+ if (strcmp(resname, "mumble.fumble") != 0)
+ fprintf(stderr, "Botch: DecodeChildReq: name: got: \"%s\" expect: \"%s\"\n",
+ resname, "mumble.fumble");
+ if (k != 1)
+ fprintf(stderr, "Botch: DecodeChildReq: subtype: got: %d expect: %d\n",
+ k, 1);
+ free(resname);
+ }
+ }
+ }
+ }
+
+/* PDU_PMNS_TRAVERSE */
+ if ((e = __pmSendTraversePMNSReq(fd[1], mypid, "foo.bar.snort")) < 0) {
+ fprintf(stderr, "Error: SendTraversePMNSReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvTraversePMNSReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvTraversePMNSReq: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_PMNS_TRAVERSE) {
+ fprintf(stderr, "Error: RecvTraversePMNSReq: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ resname = NULL;
+ if ((e = __pmDecodeTraversePMNSReq(pb, &resname)) < 0) {
+ fprintf(stderr, "Error: DecodeTraversePMNSReq: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (resname == NULL)
+ fprintf(stderr, "Botch: DecodeTraversePMNSReq: resname is NULL!\n");
+ else {
+ if (strcmp(resname, "foo.bar.snort") != 0)
+ fprintf(stderr, "Botch: DecodeTraversePMNSReq: name: got: \"%s\" expect: \"%s\"\n",
+ resname, "mumble.fumble");
+ free(resname);
+ }
+ }
+ }
+ }
+
+/* PDU_LOG_CONTROL */
+ sav_nv = rp->vset[0]->numval;
+ sav_np = rp->numpmid;
+ for (nv = -1; nv < 2; nv++) {
+ rp->numpmid = 2; /* use only first 2 from PDU_RESULT above */
+ rp->vset[0]->numval = nv;
+ if ((e = __pmSendLogControl(fd[1], rp, PM_LOG_MANDATORY, PM_LOG_MAYBE, 1000)) < 0) {
+ fprintf(stderr, "Error: SendLogControl: numval=%d %s\n", nv, pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvLogControl: numval=%d %s\n", nv, pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvLogControl: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_LOG_CONTROL) {
+ fprintf(stderr, "Error: RecvLogControl: numval=%d %s wrong type PDU!\n", nv, __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmDecodeLogControl(pb, &resp, &control, &state, &rate)) < 0) {
+ fprintf(stderr, "Error: DecodeLogControl: numval=%d %s\n", nv, pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (state != PM_LOG_MAYBE)
+ fprintf(stderr, "Botch: LogControl: numval=%d state: got: %d expect: %d\n",
+ nv, state, PM_LOG_MAYBE);
+ if (control != PM_LOG_MANDATORY)
+ fprintf(stderr, "Botch: LogControl: numval=%d control: got: %d expect: %d\n",
+ nv, control, PM_LOG_MANDATORY);
+ if (rate != 1000)
+ fprintf(stderr, "Botch: LogControl: numval=%d rate: got: %d expect: %d\n",
+ nv, rate, 1000);
+ if (resp->numpmid != rp->numpmid)
+ fprintf(stderr, "Botch: LogControl: numval=%d numpmid: got: %d expect: %d\n",
+ nv, resp->numpmid, rp->numpmid);
+ else {
+ for (i = 0; i < rp->numpmid; i++) {
+ if (resp->vset[i]->pmid != rp->vset[i]->pmid)
+ fprintf(stderr, "Botch: LogControl: numval=%d vset[%d].pmid: got: 0x%x expect: 0x%x\n",
+ nv, i, resp->vset[i]->pmid, rp->vset[i]->pmid);
+ if (resp->vset[i]->valfmt != rp->vset[i]->valfmt)
+ fprintf(stderr, "Botch: LogControl: numval=%d vset[%d].valfmt: got: %d expect: %d\n",
+ nv, i, resp->vset[i]->valfmt, rp->vset[i]->valfmt);
+ if (resp->vset[i]->numval != rp->vset[i]->numval)
+ fprintf(stderr, "Botch: LogControl: numval=%d vset[%d].numval: got: %d expect: %d\n",
+ nv, i, resp->vset[i]->numval, rp->vset[i]->numval);
+ else {
+ for (j = 0; j < rp->vset[i]->numval; j++) {
+ if (resp->vset[i]->vlist[j].inst != rp->vset[i]->vlist[j].inst)
+ fprintf(stderr, "Botch: LogControl: numval=%d vset[%d][%d].inst: got: %d expect: %d\n",
+ nv, i, j, resp->vset[i]->vlist[j].inst, rp->vset[i]->vlist[j].inst);
+ if (resp->vset[i]->vlist[j].value.lval != rp->vset[i]->vlist[j].value.lval)
+ fprintf(stderr, "Botch: LogControl: numval=%d vset[%d][%d].value.lval: got: %d expect: %d\n",
+ nv, i, j, resp->vset[i]->vlist[j].value.lval, rp->vset[i]->vlist[j].value.lval);
+ }
+ }
+ }
+ }
+ pmFreeResult(resp);
+ }
+ }
+ }
+ }
+ rp->vset[0]->numval = sav_nv;
+ rp->numpmid = sav_np;
+
+/* PDU_LOG_STATUS */
+ logstat.ls_start.tv_sec = 13 * 60 * 60; /* 13 hrs after the epoch */
+ logstat.ls_start.tv_usec = 12345; /* and a bit */
+ logstat.ls_last.tv_sec = 13 * 60 * 60 + 10;
+ logstat.ls_last.tv_usec = 23456;
+ logstat.ls_timenow.tv_sec = 13 * 60 * 60 + 20;
+ logstat.ls_timenow.tv_usec = 34567;
+ logstat.ls_state = PM_LOG_MAYBE;
+ logstat.ls_vol = 1;
+ logstat.ls_size = 2048;
+ strcpy(logstat.ls_hostname, "foo");
+ strcpy(logstat.ls_fqdn, "foo.bar.com");
+ strcpy(logstat.ls_tz, "TZ-THERE");
+ strcpy(logstat.ls_tzlogger, "TZ-HERE");
+ if ((e = __pmSendLogStatus(fd[1], &logstat)) < 0) {
+ fprintf(stderr, "Error: SendLogStatus: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvLogStatus: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvLogStatus: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_LOG_STATUS) {
+ fprintf(stderr, "Error: RecvLogStatus: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmDecodeLogStatus(pb, &lsp)) < 0) {
+ fprintf(stderr, "Error: DecodeLogStatus: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (lsp->ls_start.tv_sec != logstat.ls_start.tv_sec)
+ fprintf(stderr, "Botch: LogStatus: ls_staty.tv_sec: got: %d expect: %d\n",
+ lsp->ls_start.tv_sec, logstat.ls_start.tv_sec);
+ if (lsp->ls_start.tv_usec != logstat.ls_start.tv_usec)
+ fprintf(stderr, "Botch: LogStatus: ls_staty.tv_usec: got: %d expect: %d\n",
+ lsp->ls_start.tv_usec, logstat.ls_start.tv_usec);
+ if (lsp->ls_last.tv_sec != logstat.ls_last.tv_sec)
+ fprintf(stderr, "Botch: LogStatus: ls_staty.tv_sec: got: %d expect: %d\n",
+ lsp->ls_last.tv_sec, logstat.ls_last.tv_sec);
+ if (lsp->ls_last.tv_usec != logstat.ls_last.tv_usec)
+ fprintf(stderr, "Botch: LogStatus: ls_staty.tv_usec: got: %d expect: %d\n",
+ lsp->ls_last.tv_usec, logstat.ls_last.tv_usec);
+ if (lsp->ls_timenow.tv_sec != logstat.ls_timenow.tv_sec)
+ fprintf(stderr, "Botch: LogStatus: ls_staty.tv_sec: got: %d expect: %d\n",
+ lsp->ls_timenow.tv_sec, logstat.ls_timenow.tv_sec);
+ if (lsp->ls_timenow.tv_usec != logstat.ls_timenow.tv_usec)
+ fprintf(stderr, "Botch: LogStatus: ls_staty.tv_usec: got: %d expect: %d\n",
+ lsp->ls_timenow.tv_usec, logstat.ls_timenow.tv_usec);
+ if (lsp->ls_state != logstat.ls_state)
+ fprintf(stderr, "Botch: LogStatus: ls_state: got: 0x%x expect: 0x%x\n",
+ lsp->ls_state, logstat.ls_state);
+ if (lsp->ls_vol != logstat.ls_vol)
+ fprintf(stderr, "Botch: LogStatus: ls_vol: got: 0x%x expect: 0x%x\n",
+ lsp->ls_vol, logstat.ls_vol);
+ if (lsp->ls_size != logstat.ls_size)
+ fprintf(stderr, "Botch: LogStatus: ls_size: got: 0x%x expect: 0x%x\n",
+ (int)lsp->ls_size, (int)logstat.ls_size);
+ if (strcmp(lsp->ls_hostname, logstat.ls_hostname) != 0)
+ fprintf(stderr, "Botch: LogStatus: ls_hostname: got: \"%s\" expect: \"%s\"\n",
+ lsp->ls_hostname, logstat.ls_hostname);
+ if (strcmp(lsp->ls_fqdn, logstat.ls_fqdn) != 0)
+ fprintf(stderr, "Botch: LogStatus: ls_fqdn: got: \"%s\" expect: \"%s\"\n",
+ lsp->ls_fqdn, logstat.ls_fqdn);
+ if (strcmp(lsp->ls_tz, logstat.ls_tz) != 0)
+ fprintf(stderr, "Botch: LogStatus: ls_tz: got: \"%s\" expect: \"%s\"\n",
+ lsp->ls_tz, logstat.ls_tz);
+ if (strcmp(lsp->ls_tzlogger, logstat.ls_tzlogger) != 0)
+ fprintf(stderr, "Botch: LogStatus: ls_tzlogger: got: \"%s\" expect: \"%s\"\n",
+ lsp->ls_tzlogger, logstat.ls_tzlogger);
+ __pmUnpinPDUBuf(pb);
+ }
+ }
+ }
+
+/* PDU_LOG_REQUEST */
+ if ((e = __pmSendLogRequest(fd[1], LOG_REQUEST_SYNC)) < 0) {
+ fprintf(stderr, "Error: SendLogRequest: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmGetPDU(fd[0], ANY_SIZE, timeout, &pb)) < 0) {
+ fprintf(stderr, "Error: RecvLogRequest: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: RecvLogRequest: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != PDU_LOG_REQUEST) {
+ fprintf(stderr, "Error: RecvLogRequest: %s wrong type PDU!\n", __pmPDUTypeStr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmDecodeLogRequest(pb, &k)) < 0) {
+ fprintf(stderr, "Error: DecodeLogRequest: %s\n", pmErrStr(e));
+ exit(1);
+ }
+ else {
+ if (k != LOG_REQUEST_SYNC)
+ fprintf(stderr, "Botch: LogRequest: request: got: 0x%x expect: 0x%x\n",
+ k, LOG_REQUEST_SYNC);
+ }
+ }
+ }
+
+/* TRACE_PDU_ACK */
+ if ((e = __pmtracesendack(fd[1], 0x41)) < 0) {
+ fprintf(stderr, "Error: tracesendack: %s\n", pmtraceerrstr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmtracegetPDU(fd[0], TRACE_TIMEOUT_DEFAULT, &tpb)) < 0) {
+ fprintf(stderr, "Error: tracegetPDU: %s\n", pmtraceerrstr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: tracegetPDU: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != TRACE_PDU_ACK) {
+ fprintf(stderr, "Error: tracegetPDU: 0x%x wrong type PDU!\n", e);
+ exit(1);
+ }
+ else {
+ if ((e = __pmtracedecodeack(tpb, &k)) < 0) {
+ fprintf(stderr, "Error: tracedecodeack: %s\n", pmtraceerrstr(e));
+ exit(1);
+ }
+ else {
+ if (k != 0x41)
+ fprintf(stderr, "Botch: traceack: request: got: 0x%x expect: 0x%x\n",
+ k, 0x41);
+ }
+ }
+ }
+
+/* TRACE_PDU_DATA */
+ strcpy(mytag, "b1+b2");
+ for (i = 5; i > 0; i--) {
+ int proto;
+ double d;
+ mytag[i] = '\0';
+ if ((e = __pmtracesenddata(fd[1], mytag, i+1, TRACE_TYPE_OBSERVE, i * pi)) < 0) {
+ fprintf(stderr, "Error: tracesenddata: %s\n", pmtraceerrstr(e));
+ exit(1);
+ }
+ else {
+ if ((e = __pmtracegetPDU(fd[0], TRACE_TIMEOUT_DEFAULT, &tpb)) < 0) {
+ fprintf(stderr, "Error: tracegetPDU: %s\n", pmtraceerrstr(e));
+ exit(1);
+ }
+ else if (e == 0) {
+ fprintf(stderr, "Error: tracegetPDU: end-of-file!\n");
+ exit(1);
+ }
+ else if (e != TRACE_PDU_DATA) {
+ fprintf(stderr, "Error: tracegetPDU: 0x%x wrong type PDU!\n", e);
+ exit(1);
+ }
+ else {
+ if ((e = __pmtracedecodedata(tpb, &vp, &j, &k, &proto, &d)) < 0) {
+ fprintf(stderr, "Error: tracedecodedata: %s\n", pmtraceerrstr(e));
+ exit(1);
+ }
+ else {
+ if (strcmp(vp, mytag) != 0)
+ fprintf(stderr, "Botch: tracedata: tag: got: \"%s\" expect: \"%s\"\n",
+ vp, mytag);
+ if (j != i+1)
+ fprintf(stderr, "Botch: tracedata: taglen: got: 0x%x expect: 0x%x\n",
+ j, i);
+ if (k != TRACE_TYPE_OBSERVE)
+ fprintf(stderr, "Botch: tracedata: type: got: 0x%x expect: 0x%x\n",
+ k, TRACE_TYPE_OBSERVE);
+ if (d != i * pi)
+ fprintf(stderr, "Botch: tracedata: value: got: %g expect: %g\n",
+ d, i * pi);
+ free(vp);
+ }
+ }
+ }
+ }
+
+ /* done with rp by now */
+ for (i = 0; i < rp->numpmid; i++) {
+ if (rp->vset[i]->numval > 0 && rp->vset[i]->valfmt == PM_VAL_DPTR) {
+ for (j = 0; j < rp->vset[i]->numval; j++) {
+ if (rp->vset[i]->vlist[j].value.pval != NULL)
+ free(rp->vset[i]->vlist[j].value.pval);
+ }
+ }
+ free(rp->vset[i]);
+ }
+ free(rp);
+
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int port = 4323; /* default port for remote connection */
+ char *endnum;
+ __pmID_int *pmidp;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:i:Np:?")) != EOF) {
+ switch (c) {
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'i': /* iterations */
+ iter = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: -i requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'N': /* TIMEOUT_NEVER */
+ timeout = TIMEOUT_NEVER;
+ fprintf(stderr, "+ Using TIMEOUT_NEVER instead of TIMEOUT_DEFAULT +\n");
+ break;
+
+ case 'p': /* port */
+ port = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: -p requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind < argc-1) {
+ fprintf(stderr, "Usage: %s [-N] [-D n] [-i iter] [-p port] [host]\n", pmProgname);
+ exit(1);
+ }
+
+ if ((e = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) {
+ fprintf(stderr, "pmLoadNameSpace: %s\n", pmErrStr(e));
+ exit(1);
+ }
+
+ if (optind == argc) {
+ /* standalone, use a pipe */
+ if (pipe(fd) < 0) {
+ perror("pipe");
+ exit(1);
+ }
+ }
+ else {
+ /* remote connection, use a TCP/IP socket */
+ char *host = argv[optind];
+ if ((e = __pmAuxConnectPMCDPort(host, port)) < 0) {
+ fprintf(stderr, "__pmAuxConnectPMCDPort(%s,%d): %s\n", host, port, pmErrStr(e));
+ exit(1);
+ }
+ fd[0] = fd[1] = e;
+ standalone = 0;
+ }
+
+ if (__pmSetVersionIPC(fd[0], PDU_VERSION) < 0 ||
+ __pmSetVersionIPC(fd[1], PDU_VERSION) < 0) {
+ fprintf(stderr, "Error: __pmSetVersionIPC: %s\n", pmErrStr(-errno));
+ exit(1);
+ }
+
+ pmidlist[0] = (pmID)0;
+ pmidlist[1] = (pmID)0;
+ pmidp = (__pmID_int *)&pmidlist[1];
+ pmidp->domain = 123;
+ pmidp->cluster = 456;
+ pmidp->item = 789;
+ pmidlist[2] = (pmID)0;
+ pmidp = (__pmID_int *)&pmidlist[2];
+ pmidp->domain = 255;
+ pmidlist[3] = (pmID)0;
+ pmidp = (__pmID_int *)&pmidlist[3];
+ pmidp->cluster = 4095;
+ pmidlist[4] = (pmID)0;
+ pmidp = (__pmID_int *)&pmidlist[4];
+ pmidp->item = 1023;
+ pmidlist[5] = PM_ID_NULL;
+
+ for (pass = 0; pass < iter; pass++) {
+ fprintf(stderr, "+++++++++++++++++++++++++++\n");
+ fprintf(stderr, "+ Mode: PDU_BINARY Pass %d +\n", pass);
+ fprintf(stderr, "+++++++++++++++++++++++++++\n");
+
+ _z();
+ }
+
+ if (standalone) {
+ __pmCloseSocket(fd[0]);
+ __pmCloseSocket(fd[1]);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/pducrash.c b/qa/src/pducrash.c
new file mode 100644
index 0000000..91af348
--- /dev/null
+++ b/qa/src/pducrash.c
@@ -0,0 +1,1278 @@
+/*
+ * Feed all manner of horrendous PDUs into the decode routines
+ * to see what level of havoc can be caused. Builds up custom
+ * PDU structs (not possible using the __pmSend* routines) and
+ * calls the __pmDecode* routines.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/trace.h>
+#include <pcp/trace_dev.h>
+
+#include "localconfig.h"
+
+#if PCP_VER >= 3800
+static void
+decode_auth(const char *name)
+{
+ char *value;
+ int sts, attr, length;
+ struct auth {
+ __pmPDUHdr hdr;
+ int attr;
+ char value[0];
+ } *auth;
+
+ auth = (struct auth *)malloc(sizeof(*auth));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(auth, 0, sizeof(*auth));
+ sts = __pmDecodeAuth((__pmPDU *)auth, &attr, &value, &length);
+ fprintf(stderr, " __pmDecodeAuth: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking negative length\n", name);
+ memset(auth, 0, sizeof(*auth));
+ auth->hdr.len = -512;
+ auth->hdr.type = PDU_AUTH;
+ auth->attr = htonl(PCP_ATTR_USERID);
+ sts = __pmDecodeAuth((__pmPDU *)auth, &attr, &value, &length);
+ fprintf(stderr, " __pmDecodeAuth: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking empty value\n", name);
+ memset(auth, 0, sizeof(*auth));
+ auth->hdr.len = sizeof(*auth);
+ auth->hdr.type = PDU_AUTH;
+ auth->attr = htonl(PCP_ATTR_USERID);
+ sts = __pmDecodeAuth((__pmPDU *)auth, &attr, &value, &length);
+ fprintf(stderr, " __pmDecodeAuth: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond limit\n", name);
+ memset(auth, 0, sizeof(*auth));
+ auth->hdr.len = INT_MAX;
+ auth->hdr.type = PDU_AUTH;
+ auth->attr = htonl(PCP_ATTR_USERID);
+ sts = __pmDecodeAuth((__pmPDU *)auth, &attr, &value, &length);
+ fprintf(stderr, " __pmDecodeAuth: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(auth);
+}
+#else
+static void decode_auth(const char *name) { (void)name; }
+#endif
+
+static void
+decode_creds(const char *name)
+{
+ __pmCred *outcreds;
+ int sts, count, sender;
+ struct creds {
+ __pmPDUHdr hdr;
+ int numcreds;
+ __pmCred credslist[0];
+ } *creds;
+
+ creds = (struct creds *)malloc(sizeof(*creds));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(creds, 0, sizeof(*creds));
+ sts = __pmDecodeCreds((__pmPDU *)creds, &sender, &count, &outcreds);
+ fprintf(stderr, " __pmDecodeCreds: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outcreds); }
+
+ fprintf(stderr, "[%s] checking large numcred field\n", name);
+ memset(creds, 0, sizeof(*creds));
+ creds->hdr.len = sizeof(*creds);
+ creds->hdr.type = PDU_CREDS;
+ creds->numcreds = htonl(INT_MAX - 1);
+ sts = __pmDecodeCreds((__pmPDU *)creds, &sender, &count, &outcreds);
+ fprintf(stderr, " __pmDecodeCreds: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outcreds); }
+
+ fprintf(stderr, "[%s] checking negative numcred field\n", name);
+ memset(creds, 0, sizeof(*creds));
+ creds->hdr.len = sizeof(*creds);
+ creds->hdr.type = PDU_CREDS;
+ creds->numcreds = htonl(-2);
+ sts = __pmDecodeCreds((__pmPDU *)creds, &sender, &count, &outcreds);
+ fprintf(stderr, " __pmDecodeCreds: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outcreds); }
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(creds, 0, sizeof(*creds));
+ creds->hdr.len = sizeof(*creds);
+ creds->hdr.type = PDU_CREDS;
+ creds->numcreds = htonl(2);
+ sts = __pmDecodeCreds((__pmPDU *)creds, &sender, &count, &outcreds);
+ fprintf(stderr, " __pmDecodeCreds: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outcreds); }
+
+ free(creds);
+}
+
+static void
+decode_error(const char *name)
+{
+ int sts, code, data;
+ struct error {
+ __pmPDUHdr hdr;
+ } *error;
+ struct xerror {
+ __pmPDUHdr hdr;
+ int code[1];
+ } *xerror;
+
+ error = (struct error *)malloc(sizeof(*error));
+ xerror = (struct xerror *)malloc(sizeof(*xerror));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(error, 0, sizeof(*error));
+ sts = __pmDecodeError((__pmPDU *)error, &code);
+ fprintf(stderr, " __pmDecodeError: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking all-zeroes extended structure\n", name);
+ memset(xerror, 0, sizeof(*xerror));
+ sts = __pmDecodeXtendError((__pmPDU *)xerror, &code, &data);
+ fprintf(stderr, " __pmDecodeXtendError: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(error, 0, sizeof(*error));
+ error->hdr.len = sizeof(*error);
+ error->hdr.type = PDU_ERROR;
+ sts = __pmDecodeError((__pmPDU *)error, &code);
+ fprintf(stderr, " __pmDecodeError: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(xerror, 0, sizeof(*xerror));
+ xerror->hdr.len = sizeof(*xerror);
+ xerror->hdr.type = PDU_ERROR;
+ sts = __pmDecodeXtendError((__pmPDU *)xerror, &code, &data);
+ fprintf(stderr, " __pmDecodeXtendError: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(xerror);
+ free(error);
+}
+
+static void
+decode_profile(const char *name)
+{
+ __pmProfile *outprofs;
+ int sts, ctxnum;
+ struct profile {
+ __pmPDUHdr hdr;
+ int unused[2];
+ int numprof;
+ int padding;
+ } *profile;
+ struct instprof {
+ struct profile profile;
+ pmInDom indom;
+ int state;
+ int numinst;
+ int padding;
+ } *instprof;
+
+ profile = (struct profile *)malloc(sizeof(*profile));
+ instprof = (struct instprof *)malloc(sizeof(*instprof));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(profile, 0, sizeof(*profile));
+ sts = __pmDecodeProfile((__pmPDU *)profile, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking large numprof field\n", name);
+ memset(profile, 0, sizeof(*profile));
+ profile->hdr.len = sizeof(*profile);
+ profile->hdr.type = PDU_PROFILE;
+ profile->numprof = htonl(INT_MAX - 42);
+ sts = __pmDecodeProfile((__pmPDU *)profile, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking negative numprof field\n", name);
+ memset(profile, 0, sizeof(*profile));
+ profile->hdr.len = sizeof(*profile);
+ profile->hdr.type = PDU_PROFILE;
+ profile->numprof = htonl(-2);
+ sts = __pmDecodeProfile((__pmPDU *)profile, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(profile, 0, sizeof(*profile));
+ profile->hdr.len = sizeof(*profile);
+ profile->hdr.type = PDU_PROFILE;
+ profile->numprof = htonl(2);
+ sts = __pmDecodeProfile((__pmPDU *)profile, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking large numinst field\n", name);
+ memset(instprof, 0, sizeof(*instprof));
+ instprof->profile.hdr.len = sizeof(*instprof);
+ instprof->profile.hdr.type = PDU_PROFILE;
+ instprof->profile.numprof = htonl(1);
+ instprof->numinst = htonl(INT_MAX - 3);
+ sts = __pmDecodeProfile((__pmPDU *)instprof, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking negative numinst field\n", name);
+ memset(instprof, 0, sizeof(*instprof));
+ instprof->profile.hdr.len = sizeof(*instprof);
+ instprof->profile.hdr.type = PDU_PROFILE;
+ instprof->profile.numprof = htonl(1);
+ instprof->numinst = htonl(-3);
+ sts = __pmDecodeProfile((__pmPDU *)instprof, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(instprof, 0, sizeof(*instprof));
+ instprof->profile.hdr.len = sizeof(*instprof);
+ instprof->profile.hdr.type = PDU_PROFILE;
+ instprof->profile.numprof = htonl(1);
+ instprof->numinst = htonl(2);
+ sts = __pmDecodeProfile((__pmPDU *)instprof, &ctxnum, &outprofs);
+ fprintf(stderr, " __pmDecodeProfile: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(outprofs); }
+
+ free(instprof);
+ free(profile);
+}
+
+static void
+decode_fetch(const char *name)
+{
+ __pmTimeval when;
+ pmID *pmidlist;
+ int sts, ctx, count;
+ struct fetch {
+ __pmPDUHdr hdr;
+ int ctxnum;
+ __pmTimeval when;
+ int numpmid;
+ pmID pmidlist[0];
+ } *fetch;
+
+ fetch = (struct fetch *)malloc(sizeof(*fetch));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(fetch, 0, sizeof(*fetch));
+ sts = __pmDecodeFetch((__pmPDU *)fetch, &ctx, &when, &count, &pmidlist);
+ fprintf(stderr, " __pmDecodeFetch: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(pmidlist); }
+
+ fprintf(stderr, "[%s] checking large numpmid field\n", name);
+ memset(fetch, 0, sizeof(*fetch));
+ fetch->hdr.len = sizeof(*fetch);
+ fetch->hdr.type = PDU_FETCH;
+ fetch->numpmid = htonl(INT_MAX - 1);
+ sts = __pmDecodeFetch((__pmPDU *)fetch, &ctx, &when, &count, &pmidlist);
+ fprintf(stderr, " __pmDecodeFetch: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(pmidlist); }
+
+ fprintf(stderr, "[%s] checking negative numpmid field\n", name);
+ memset(fetch, 0, sizeof(*fetch));
+ fetch->hdr.len = sizeof(*fetch);
+ fetch->hdr.type = PDU_FETCH;
+ fetch->numpmid = htonl(-2);
+ sts = __pmDecodeFetch((__pmPDU *)fetch, &ctx, &when, &count, &pmidlist);
+ fprintf(stderr, " __pmDecodeFetch: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(pmidlist); }
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(fetch, 0, sizeof(*fetch));
+ fetch->hdr.len = sizeof(*fetch);
+ fetch->hdr.type = PDU_FETCH;
+ fetch->numpmid = htonl(2);
+ sts = __pmDecodeFetch((__pmPDU *)fetch, &ctx, &when, &count, &pmidlist);
+ fprintf(stderr, " __pmDecodeFetch: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(pmidlist); }
+
+ free(fetch);
+}
+
+static void
+decode_desc_req(const char *name)
+{
+ pmID pmid;
+ int sts;
+ struct desc_req {
+ __pmPDUHdr hdr;
+ } *desc_req;
+
+ desc_req = (struct desc_req *)malloc(sizeof(*desc_req));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(desc_req, 0, sizeof(*desc_req));
+ sts = __pmDecodeDescReq((__pmPDU *)desc_req, &pmid);
+ fprintf(stderr, " __pmDecodeDescReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(desc_req, 0, sizeof(*desc_req));
+ desc_req->hdr.len = sizeof(*desc_req);
+ desc_req->hdr.type = PDU_DESC_REQ;
+ sts = __pmDecodeDescReq((__pmPDU *)desc_req, &pmid);
+ fprintf(stderr, " __pmDecodeDescReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(desc_req);
+}
+
+static void
+decode_desc(const char *name)
+{
+ pmDesc pmdesc;
+ int sts;
+ struct desc {
+ __pmPDUHdr hdr;
+ } *desc;
+
+ desc = (struct desc *)malloc(sizeof(*desc));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(desc, 0, sizeof(*desc));
+ sts = __pmDecodeDesc((__pmPDU *)desc, &pmdesc);
+ fprintf(stderr, " __pmDecodeDesc: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(desc, 0, sizeof(*desc));
+ desc->hdr.len = sizeof(*desc);
+ desc->hdr.type = PDU_DESC;
+ sts = __pmDecodeDesc((__pmPDU *)desc, &pmdesc);
+ fprintf(stderr, " __pmDecodeDesc: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(desc);
+}
+
+static void
+decode_instance_req(const char *name)
+{
+ __pmTimeval when;
+ pmInDom indom;
+ int inst, sts;
+ char *resname;
+ struct instance_req {
+ __pmPDUHdr hdr;
+ pmInDom indom;
+ __pmTimeval when;
+ int inst;
+ int namelen;
+ char name[0];
+ } *instance_req, *xinstance_req;
+
+ instance_req = (struct instance_req *)malloc(sizeof(*instance_req));
+ xinstance_req = (struct instance_req *)malloc(sizeof(*xinstance_req)+16);
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(instance_req, 0, sizeof(*instance_req));
+ sts = __pmDecodeInstanceReq((__pmPDU *)instance_req, &when, &indom, &inst, &resname);
+ fprintf(stderr, " __pmDecodeInstanceReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(resname); }
+
+ fprintf(stderr, "[%s] checking large namelen field\n", name);
+ memset(instance_req, 0, sizeof(*instance_req));
+ instance_req->hdr.len = sizeof(*instance_req);
+ instance_req->hdr.type = PDU_INSTANCE_REQ;
+ instance_req->namelen = htonl(INT_MAX - 1);
+ sts = __pmDecodeInstanceReq((__pmPDU *)instance_req, &when, &indom, &inst, &resname);
+ fprintf(stderr, " __pmDecodeInstanceReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(resname); }
+
+ fprintf(stderr, "[%s] checking negative namelen field\n", name);
+ memset(instance_req, 0, sizeof(*instance_req));
+ instance_req->hdr.len = sizeof(*instance_req);
+ instance_req->hdr.type = PDU_INSTANCE_REQ;
+ instance_req->namelen = htonl(-2);
+ sts = __pmDecodeInstanceReq((__pmPDU *)instance_req, &when, &indom, &inst, &resname);
+ fprintf(stderr, " __pmDecodeInstanceReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(resname); }
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(instance_req, 0, sizeof(*instance_req));
+ instance_req->hdr.len = sizeof(*instance_req);
+ instance_req->hdr.type = PDU_INSTANCE_REQ;
+ instance_req->namelen = htonl(1);
+ sts = __pmDecodeInstanceReq((__pmPDU *)instance_req, &when, &indom, &inst, &resname);
+ fprintf(stderr, " __pmDecodeInstanceReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(resname); }
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(xinstance_req, 0, sizeof(*xinstance_req) + 16);
+ xinstance_req->hdr.len = sizeof(*xinstance_req) + 16;
+ xinstance_req->hdr.type = PDU_INSTANCE_REQ;
+ xinstance_req->namelen = htonl(32);
+ sts = __pmDecodeInstanceReq((__pmPDU *)xinstance_req, &when, &indom, &inst, &resname);
+ fprintf(stderr, " __pmDecodeInstanceReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) {free(resname); }
+
+ free(xinstance_req);
+ free(instance_req);
+}
+
+static void
+decode_instance(const char *name)
+{
+ __pmInResult *inresult;
+ int sts;
+ struct instance {
+ __pmPDUHdr hdr;
+ pmInDom indom;
+ int numinst;
+ __pmPDU rest[0];
+ } *instance;
+ struct instlist {
+ struct instance instance;
+ int inst;
+ int namelen;
+ char name[0];
+ } *instlist;
+
+ instance = (struct instance *)malloc(sizeof(*instance));
+ instlist = (struct instlist *)malloc(sizeof(*instlist));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(instance, 0, sizeof(*instance));
+ sts = __pmDecodeInstance((__pmPDU *)instance, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking large numinst field\n", name);
+ memset(instance, 0, sizeof(*instance));
+ instance->hdr.len = sizeof(*instance);
+ instance->hdr.type = PDU_INSTANCE;
+ instance->numinst = htonl(INT_MAX - 42);
+ sts = __pmDecodeInstance((__pmPDU *)instance, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking negative numinst field\n", name);
+ memset(instance, 0, sizeof(*instance));
+ instance->hdr.len = sizeof(*instance);
+ instance->hdr.type = PDU_INSTANCE;
+ instance->numinst = htonl(-2);
+ sts = __pmDecodeInstance((__pmPDU *)instance, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(instance, 0, sizeof(*instance));
+ instance->hdr.len = sizeof(*instance);
+ instance->hdr.type = PDU_INSTANCE;
+ instance->numinst = htonl(1);
+ sts = __pmDecodeInstance((__pmPDU *)instance, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking large namelen field\n", name);
+ memset(instlist, 0, sizeof(*instlist));
+ instlist->instance.hdr.len = sizeof(*instlist);
+ instlist->instance.hdr.type = PDU_INSTANCE;
+ instlist->instance.numinst = htonl(1);
+ instlist->namelen = htonl(INT_MAX - 5);
+ sts = __pmDecodeInstance((__pmPDU *)instlist, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking negative namelen field\n", name);
+ memset(instlist, 0, sizeof(*instlist));
+ instlist->instance.hdr.len = sizeof(*instlist);
+ instlist->instance.hdr.type = PDU_INSTANCE;
+ instlist->instance.numinst = htonl(1);
+ instlist->namelen = htonl(-2);
+ sts = __pmDecodeInstance((__pmPDU *)instlist, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(instlist, 0, sizeof(*instlist));
+ instlist->instance.hdr.len = sizeof(*instlist);
+ instlist->instance.hdr.type = PDU_INSTANCE;
+ instlist->instance.numinst = htonl(1);
+ instlist->namelen = htonl(32);
+ sts = __pmDecodeInstance((__pmPDU *)instlist, &inresult);
+ fprintf(stderr, " __pmDecodeInstance: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) __pmFreeInResult(inresult);
+
+ free(instlist);
+ free(instance);
+}
+
+static void
+decode_pmns_ids(const char *name)
+{
+ pmID idarray[10];
+ int idsts, sts;
+ struct idlist {
+ __pmPDUHdr hdr;
+ int sts;
+ int numids;
+ pmID idlist[0];
+ } *idlist;
+
+ idlist = (struct idlist *)malloc(sizeof(*idlist));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(idlist, 0, sizeof(*idlist));
+ sts = __pmDecodeIDList((__pmPDU *)idlist, 10, idarray, &idsts);
+ fprintf(stderr, " __pmDecodeIDList: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking large numids field\n", name);
+ memset(idlist, 0, sizeof(*idlist));
+ idlist->hdr.len = sizeof(*idlist);
+ idlist->hdr.type = PDU_PMNS_IDS;
+ idlist->numids = htonl(INT_MAX - 1);
+ sts = __pmDecodeIDList((__pmPDU *)idlist, 10, idarray, &idsts);
+ fprintf(stderr, " __pmDecodeIDList: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking negative numids field\n", name);
+ memset(idlist, 0, sizeof(*idlist));
+ idlist->hdr.len = sizeof(*idlist);
+ idlist->hdr.type = PDU_PMNS_IDS;
+ idlist->numids = htonl(-2);
+ sts = __pmDecodeIDList((__pmPDU *)idlist, 10, idarray, &idsts);
+ fprintf(stderr, " __pmDecodeIDList: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(idlist, 0, sizeof(*idlist));
+ idlist->hdr.len = sizeof(*idlist);
+ idlist->hdr.type = PDU_PMNS_IDS;
+ idlist->numids = htonl(2);
+ sts = __pmDecodeIDList((__pmPDU *)idlist, 10, idarray, &idsts);
+ fprintf(stderr, " __pmDecodeIDList: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(idlist);
+}
+
+static void
+decode_pmns_names(const char *name)
+{
+ int sts, numnames, *status;
+ char **names;
+ struct namelist {
+ __pmPDUHdr hdr;
+ int nstrbytes;
+ int numstatus;
+ int numnames;
+ pmID names[0];
+ } *namelist;
+ struct namestatus {
+ struct namelist namelist;
+ int status;
+ int namelen;
+ char name[0];
+ } *namestatus;
+
+ namelist = (struct namelist *)malloc(sizeof(*namelist));
+ namestatus = (struct namestatus *)malloc(sizeof(*namestatus));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking large numnames field\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ namelist->hdr.len = sizeof(*namelist);
+ namelist->hdr.type = PDU_PMNS_NAMES;
+ namelist->numnames = htonl(INT_MAX - 42);
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking negative numnames field\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ namelist->hdr.len = sizeof(*namelist);
+ namelist->hdr.type = PDU_PMNS_NAMES;
+ namelist->numnames = htonl(-42);
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking large nstrbytes field\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ namelist->hdr.len = sizeof(*namelist);
+ namelist->hdr.type = PDU_PMNS_NAMES;
+ namelist->numnames = htonl(42);
+ namelist->nstrbytes = htonl(INT_MAX - 42);
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking negative nstrbytes field\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ namelist->hdr.len = sizeof(*namelist);
+ namelist->hdr.type = PDU_PMNS_NAMES;
+ namelist->numnames = htonl(42);
+ namelist->nstrbytes = htonl(-42);
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(namelist, 0, sizeof(*namelist));
+ namelist->hdr.len = sizeof(*namelist);
+ namelist->hdr.type = PDU_PMNS_NAMES;
+ namelist->numnames = htonl(1);
+ sts = __pmDecodeNameList((__pmPDU *)namelist, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking large namelen field\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = htonl(1);
+ namestatus->namelen = htonl(INT_MAX - 5);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking negative namelen field\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = htonl(1);
+ namestatus->namelen = htonl(-2);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = htonl(1);
+ namestatus->namelen = htonl(32);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking large namelen field (+statuslist)\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = namestatus->namelist.numstatus = htonl(1);
+ namestatus->namelen = htonl(INT_MAX - 5);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking negative namelen field (+statuslist)\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = namestatus->namelist.numstatus = htonl(1);
+ namestatus->namelen = htonl(-2);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer (+statuslist)\n", name);
+ memset(namestatus, 0, sizeof(*namestatus));
+ namestatus->namelist.hdr.len = sizeof(*namestatus);
+ namestatus->namelist.hdr.type = PDU_PMNS_NAMES;
+ namestatus->namelist.numnames = namestatus->namelist.numstatus = htonl(1);
+ namestatus->namelen = htonl(32);
+ sts = __pmDecodeNameList((__pmPDU *)namestatus, &numnames, &names, &status);
+ fprintf(stderr, " __pmDecodeNameList: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(status); free(names); }
+
+ free(namestatus);
+ free(namelist);
+}
+
+/* Wraps __pmDecodeChildReq and __pmDecodeTraversePMNSReq interfaces */
+static void
+decode_name_request(const char *name, const char *caller, int pdutype)
+{
+ char *resnames;
+ int sts, restype;
+ struct name_req {
+ __pmPDUHdr hdr;
+ int subtype;
+ int namelen;
+ char name[0];
+ } *name_req, *xname_req;
+
+ name_req = (struct name_req *)malloc(sizeof(*name_req));
+ xname_req = (struct name_req *)malloc(sizeof(*name_req) + 16);
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(name_req, 0, sizeof(*name_req));
+ sts = (pdutype == PDU_PMNS_TRAVERSE) ?
+ __pmDecodeTraversePMNSReq((__pmPDU *)name_req, &resnames) :
+ __pmDecodeChildReq((__pmPDU *)name_req, &resnames, &restype);
+ fprintf(stderr, " __pmDecode%sReq: sts = %d (%s)\n", caller, sts, pmErrStr(sts));
+ if (sts >= 0) { free(resnames); }
+
+ fprintf(stderr, "[%s] checking large namelen field\n", name);
+ memset(name_req, 0, sizeof(*name_req));
+ name_req->hdr.len = sizeof(*name_req);
+ name_req->hdr.type = pdutype;
+ name_req->namelen = htonl(INT_MAX - 1);
+ sts = (pdutype == PDU_PMNS_TRAVERSE) ?
+ __pmDecodeTraversePMNSReq((__pmPDU *)name_req, &resnames) :
+ __pmDecodeChildReq((__pmPDU *)name_req, &resnames, &restype);
+ fprintf(stderr, " __pmDecode%sReq: sts = %d (%s)\n", caller, sts, pmErrStr(sts));
+ if (sts >= 0) { free(resnames); }
+
+ fprintf(stderr, "[%s] checking negative namelen field\n", name);
+ memset(name_req, 0, sizeof(*name_req));
+ name_req->hdr.len = sizeof(*name_req);
+ name_req->hdr.type = pdutype;
+ name_req->namelen = htonl(-2);
+ sts = (pdutype == PDU_PMNS_TRAVERSE) ?
+ __pmDecodeTraversePMNSReq((__pmPDU *)name_req, &resnames) :
+ __pmDecodeChildReq((__pmPDU *)name_req, &resnames, &restype);
+ fprintf(stderr, " __pmDecode%sReq: sts = %d (%s)\n", caller, sts, pmErrStr(sts));
+ if (sts >= 0) { free(resnames); }
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(name_req, 0, sizeof(*name_req));
+ name_req->hdr.len = sizeof(*name_req);
+ name_req->hdr.type = pdutype;
+ name_req->namelen = htonl(1);
+ sts = (pdutype == PDU_PMNS_TRAVERSE) ?
+ __pmDecodeTraversePMNSReq((__pmPDU *)name_req, &resnames) :
+ __pmDecodeChildReq((__pmPDU *)name_req, &resnames, &restype);
+ fprintf(stderr, " __pmDecode%sReq: sts = %d (%s)\n", caller, sts, pmErrStr(sts));
+ if (sts >= 0) { free(resnames); }
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(xname_req, 0, sizeof(*xname_req));
+ xname_req->hdr.len = sizeof(*xname_req) + 16;
+ xname_req->hdr.type = pdutype;
+ xname_req->namelen = htonl(32);
+ sts = (pdutype == PDU_PMNS_TRAVERSE) ?
+ __pmDecodeTraversePMNSReq((__pmPDU *)xname_req, &resnames) :
+ __pmDecodeChildReq((__pmPDU *)xname_req, &resnames, &restype);
+ fprintf(stderr, " __pmDecode%sReq: sts = %d (%s)\n", caller, sts, pmErrStr(sts));
+ if (sts >= 0) { free(resnames); }
+
+ free(xname_req);
+ free(name_req);
+}
+
+static void
+decode_pmns_child(const char *name)
+{
+ decode_name_request(name, "Child", PDU_PMNS_CHILD);
+}
+
+static void
+decode_pmns_traverse(const char *name)
+{
+ decode_name_request(name, "TraversePMNS", PDU_PMNS_TRAVERSE);
+}
+
+static void
+decode_log_control(const char *name)
+{
+ pmResult *result;
+ int sts, ctl, state, delta;
+ struct log_ctl {
+ __pmPDUHdr hdr;
+ int el[3];
+ int numpmid;
+ __pmPDU data[0];
+ } *log_ctl;
+ struct logvlist {
+ struct log_ctl log_ctl;
+ pmID pmid;
+ int numval;
+ __pmValue_PDU vlist[0];
+ } *logvlist;
+
+ log_ctl = (struct log_ctl *)malloc(sizeof(*log_ctl));
+ logvlist = (struct logvlist *)malloc(sizeof(*logvlist));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(log_ctl, 0, sizeof(*log_ctl));
+ sts = __pmDecodeLogControl((__pmPDU *)log_ctl, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ fprintf(stderr, "[%s] checking large numpmid field\n", name);
+ memset(log_ctl, 0, sizeof(*log_ctl));
+ log_ctl->hdr.len = sizeof(*log_ctl);
+ log_ctl->hdr.type = PDU_LOG_CONTROL;
+ log_ctl->numpmid = htonl(INT_MAX - 42);
+ sts = __pmDecodeLogControl((__pmPDU *)log_ctl, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ fprintf(stderr, "[%s] checking negative numpmid field\n", name);
+ memset(log_ctl, 0, sizeof(*log_ctl));
+ log_ctl->hdr.len = sizeof(*log_ctl);
+ log_ctl->hdr.type = PDU_LOG_CONTROL;
+ log_ctl->numpmid = htonl(-42);
+ sts = __pmDecodeLogControl((__pmPDU *)log_ctl, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(log_ctl, 0, sizeof(*log_ctl));
+ log_ctl->hdr.len = sizeof(*log_ctl);
+ log_ctl->hdr.type = PDU_LOG_CONTROL;
+ log_ctl->numpmid = htonl(2);
+ sts = __pmDecodeLogControl((__pmPDU *)log_ctl, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ fprintf(stderr, "[%s] checking large numval field\n", name);
+ memset(logvlist, 0, sizeof(*logvlist));
+ logvlist->log_ctl.hdr.len = sizeof(*logvlist);
+ logvlist->log_ctl.hdr.type = PDU_LOG_CONTROL;
+ logvlist->log_ctl.numpmid = htonl(1);
+ logvlist->numval = htonl(INT_MAX - 3);
+ sts = __pmDecodeLogControl((__pmPDU *)logvlist, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(logvlist, 0, sizeof(*logvlist));
+ logvlist->log_ctl.hdr.len = sizeof(*logvlist);
+ logvlist->log_ctl.hdr.type = PDU_LOG_CONTROL;
+ logvlist->log_ctl.numpmid = htonl(1);
+ logvlist->numval = htonl(2);
+ sts = __pmDecodeLogControl((__pmPDU *)logvlist, &result, &ctl, &state, &delta);
+ fprintf(stderr, " __pmDecodeLogControl: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(result);
+
+ free(log_ctl);
+ free(logvlist);
+}
+
+static void
+decode_log_status(const char *name)
+{
+ __pmLoggerStatus *log;
+ int sts;
+ struct log_sts {
+ __pmPDUHdr hdr;
+ int pad;
+ __pmLoggerStatus sts;
+ } *log_sts;
+
+ log_sts = (struct log_sts *)malloc(sizeof(*log_sts));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(log_sts, 0, sizeof(*log_sts));
+ sts = __pmDecodeLogStatus((__pmPDU *)log_sts, &log);
+ fprintf(stderr, " __pmDecodeLogStatus: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(log_sts, 0, sizeof(*log_sts));
+ log_sts->hdr.len = sizeof(*log_sts) - 4;
+ log_sts->hdr.type = PDU_LOG_STATUS;
+ sts = __pmDecodeLogStatus((__pmPDU *)log_sts, &log);
+ fprintf(stderr, " __pmDecodeLogStatus: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(log_sts);
+}
+
+static void
+decode_log_request(const char *name)
+{
+ int type, sts;
+ struct log_req {
+ __pmPDUHdr hdr;
+ } *log_req;
+
+ log_req = (struct log_req *)malloc(sizeof(*log_req));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(log_req, 0, sizeof(*log_req));
+ sts = __pmDecodeLogRequest((__pmPDU *)log_req, &type);
+ fprintf(stderr, " __pmDecodeLogRequest: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(log_req, 0, sizeof(*log_req));
+ log_req->hdr.len = sizeof(*log_req);
+ log_req->hdr.type = PDU_LOG_REQUEST;
+ sts = __pmDecodeLogRequest((__pmPDU *)log_req, &type);
+ fprintf(stderr, " __pmDecodeLogRequest: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(log_req);
+}
+
+static void
+decode_result(const char *name)
+{
+ int sts;
+ pmResult *resp;
+ struct result {
+ __pmPDUHdr hdr;
+ __pmTimeval stamp;
+ int numpmid;
+ __pmPDU data[0];
+ } *result;
+ struct resultlist {
+ struct result result;
+ pmID pmid;
+ int numval;
+ int valfmt;
+ __pmValue_PDU vlist[0];
+ } *resultlist;
+ struct resultdynlist {
+ struct resultlist vlist;
+ __pmValue_PDU values;
+ pmValueBlock block[0];
+ } *resultdynlist;
+
+ result = (struct result *)malloc(sizeof(*result));
+ resultlist = (struct resultlist *)malloc(sizeof(*resultlist));
+ resultdynlist = (struct resultdynlist *)malloc(sizeof(*resultdynlist));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(result, 0, sizeof(*result));
+ sts = __pmDecodeResult((__pmPDU *)result, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking large numpmid field\n", name);
+ memset(result, 0, sizeof(*result));
+ result->hdr.len = sizeof(*result);
+ result->hdr.type = PDU_RESULT;
+ result->numpmid = htonl(INT_MAX - 42);
+ sts = __pmDecodeResult((__pmPDU *)result, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking negative numpmid field\n", name);
+ memset(result, 0, sizeof(*result));
+ result->hdr.len = sizeof(*result);
+ result->hdr.type = PDU_RESULT;
+ result->numpmid = htonl(-42);
+ sts = __pmDecodeResult((__pmPDU *)result, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking access beyond basic buffer\n", name);
+ memset(result, 0, sizeof(*result));
+ result->hdr.len = sizeof(*result);
+ result->hdr.type = PDU_RESULT;
+ result->numpmid = htonl(4);
+ sts = __pmDecodeResult((__pmPDU *)result, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking large numval field\n", name);
+ memset(resultlist, 0, sizeof(*resultlist));
+ resultlist->result.hdr.len = sizeof(*resultlist);
+ resultlist->result.hdr.type = PDU_RESULT;
+ resultlist->result.numpmid = htonl(1);
+ resultlist->numval = htonl(INT_MAX - 3);
+ sts = __pmDecodeResult((__pmPDU *)resultlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking negative numval field\n", name);
+ memset(resultlist, 0, sizeof(*resultlist));
+ resultlist->result.hdr.len = sizeof(*resultlist);
+ resultlist->result.hdr.type = PDU_RESULT;
+ resultlist->result.numpmid = htonl(1);
+ resultlist->numval = htonl(-3);
+ sts = __pmDecodeResult((__pmPDU *)resultlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking access beyond extended buffer\n", name);
+ memset(resultlist, 0, sizeof(*resultlist));
+ resultlist->result.hdr.len = sizeof(*resultlist);
+ resultlist->result.hdr.type = PDU_LOG_CONTROL;
+ resultlist->result.numpmid = htonl(1);
+ resultlist->numval = htonl(2);
+ sts = __pmDecodeResult((__pmPDU *)resultlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking insitu valfmt field\n", name);
+ memset(resultlist, 0, sizeof(*resultlist));
+ resultlist->result.hdr.len = sizeof(*resultlist);
+ resultlist->result.hdr.type = PDU_RESULT;
+ resultlist->result.numpmid = htonl(1);
+ resultlist->valfmt = htonl(PM_VAL_INSITU);
+ resultlist->numval = htonl(1);
+ sts = __pmDecodeResult((__pmPDU *)resultlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking non-insitu valfmt field\n", name);
+ memset(resultlist, 0, sizeof(*resultlist));
+ resultlist->result.hdr.len = sizeof(*resultlist);
+ resultlist->result.hdr.type = PDU_RESULT;
+ resultlist->result.numpmid = htonl(1);
+ resultlist->valfmt = htonl(PM_VAL_DPTR);
+ resultlist->numval = htonl(1);
+ sts = __pmDecodeResult((__pmPDU *)resultlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ fprintf(stderr, "[%s] checking access beyond non-insitu valfmt field\n", name);
+ memset(resultdynlist, 0, sizeof(*resultdynlist));
+ resultdynlist->vlist.result.hdr.len = sizeof(*resultdynlist);
+ resultdynlist->vlist.result.hdr.type = PDU_RESULT;
+ resultdynlist->vlist.result.numpmid = htonl(1);
+ resultdynlist->vlist.valfmt = htonl(PM_VAL_DPTR);
+ resultdynlist->vlist.numval = htonl(1);
+ resultdynlist->values.value.lval = htonl(10);
+ sts = __pmDecodeResult((__pmPDU *)resultdynlist, &resp);
+ fprintf(stderr, " __pmDecodeResult: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) pmFreeResult(resp);
+
+ free(resultdynlist);
+ free(resultlist);
+ free(result);
+}
+
+static void
+decode_text_req(const char *name)
+{
+ int ident, type, sts;
+ struct text_req {
+ __pmPDUHdr hdr;
+ int val[1];
+ } *text_req;
+
+ text_req = (struct text_req *)malloc(sizeof(*text_req));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(text_req, 0, sizeof(*text_req));
+ sts = __pmDecodeTextReq((__pmPDU *)text_req, &ident, &type);
+ fprintf(stderr, " __pmDecodeTextReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(text_req, 0, sizeof(*text_req));
+ text_req->hdr.len = sizeof(*text_req);
+ text_req->hdr.type = PDU_TEXT_REQ;
+ sts = __pmDecodeTextReq((__pmPDU *)text_req, &ident, &type);
+ fprintf(stderr, " __pmDecodeTextReq: sts = %d (%s)\n", sts, pmErrStr(sts));
+
+ free(text_req);
+}
+
+static void
+decode_text(const char *name)
+{
+ int ident, sts;
+ char *buffer;
+ struct text {
+ __pmPDUHdr hdr;
+ int ident;
+ int buflen;
+ char buffer[0];
+ } *text;
+
+ text = (struct text *)malloc(sizeof(*text));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(text, 0, sizeof(*text));
+ sts = __pmDecodeText((__pmPDU *)text, &ident, &buffer);
+ fprintf(stderr, " __pmDecodeText: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(buffer); }
+
+ fprintf(stderr, "[%s] checking large buflen field\n", name);
+ memset(text, 0, sizeof(*text));
+ text->hdr.len = sizeof(*text);
+ text->hdr.type = PDU_TEXT;
+ text->buflen = htonl(INT_MAX - 1);
+ sts = __pmDecodeText((__pmPDU *)text, &ident, &buffer);
+ fprintf(stderr, " __pmDecodeText: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(buffer); }
+
+ fprintf(stderr, "[%s] checking negative buflen field\n", name);
+ memset(text, 0, sizeof(*text));
+ text->hdr.len = sizeof(*text);
+ text->hdr.type = PDU_TEXT;
+ text->buflen = htonl(-2);
+ sts = __pmDecodeText((__pmPDU *)text, &ident, &buffer);
+ fprintf(stderr, " __pmDecodeText: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(buffer); }
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(text, 0, sizeof(*text));
+ text->hdr.len = sizeof(*text);
+ text->hdr.type = PDU_TEXT;
+ text->buflen = htonl(2);
+ sts = __pmDecodeText((__pmPDU *)text, &ident, &buffer);
+ fprintf(stderr, " __pmDecodeText: sts = %d (%s)\n", sts, pmErrStr(sts));
+ if (sts >= 0) { free(buffer); }
+
+ free(text);
+}
+
+static void
+decode_trace_ack(const char *name)
+{
+ int sts, ack;
+ struct trace_ack {
+ __pmTracePDUHdr hdr;
+ } *trace_ack;
+
+ trace_ack = (struct trace_ack *)malloc(sizeof(*trace_ack));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(trace_ack, 0, sizeof(*trace_ack));
+ sts = __pmtracedecodeack((__pmPDU *)trace_ack, &ack);
+ fprintf(stderr, " __pmtracedecodeack: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(trace_ack, 0, sizeof(*trace_ack));
+ trace_ack->hdr.len = sizeof(*trace_ack);
+ trace_ack->hdr.type = TRACE_PDU_ACK;
+ sts = __pmtracedecodeack((__pmPDU *)trace_ack, &ack);
+ fprintf(stderr, " __pmtracedecodeack: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+
+ free(trace_ack);
+}
+
+static void
+decode_trace_data(const char *name)
+{
+ int sts, len, type, p, *ip;
+ char *tag;
+ double data;
+ struct trace_data {
+ __pmTracePDUHdr hdr;
+ struct {
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int version : 8;
+ unsigned int taglen : 8;
+ unsigned int tagtype : 8;
+ unsigned int protocol : 1;
+ unsigned int pad : 7;
+#else
+ unsigned int pad : 7;
+ unsigned int protocol : 1;
+ unsigned int tagtype : 8;
+ unsigned int taglen : 8;
+ unsigned int version : 8;
+#endif
+ } bits;
+ double value;
+ char tag[0];
+ } *trace_data;
+
+ trace_data = (struct trace_data *)malloc(sizeof(*trace_data));
+
+ fprintf(stderr, "[%s] checking all-zeroes structure\n", name);
+ memset(trace_data, 0, sizeof(*trace_data));
+ sts = __pmtracedecodedata((__pmPDU *)trace_data, &tag, &len, &type, &p, &data);
+ fprintf(stderr, " __pmtracedecodedata: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+ if (sts >= 0) { free(tag); }
+
+ fprintf(stderr, "[%s] checking large taglen field\n", name);
+ memset(trace_data, 0, sizeof(*trace_data));
+ trace_data->hdr.len = sizeof(*trace_data);
+ trace_data->hdr.type = TRACE_PDU_DATA;
+ trace_data->bits.version = TRACE_PDU_VERSION;
+ trace_data->bits.taglen = CHAR_MAX - 1;
+ ip = (int *)&trace_data->bits;
+ *ip = htonl(*ip);
+ sts = __pmtracedecodedata((__pmPDU *)trace_data, &tag, &len, &type, &p, &data);
+ fprintf(stderr, " __pmtracedecodedata: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+ if (sts >= 0) { free(tag); }
+
+ fprintf(stderr, "[%s] checking negative taglen field\n", name);
+ memset(trace_data, 0, sizeof(*trace_data));
+ trace_data->hdr.len = sizeof(*trace_data);
+ trace_data->hdr.type = TRACE_PDU_DATA;
+ trace_data->bits.version = TRACE_PDU_VERSION;
+ trace_data->bits.taglen = -1;
+ ip = (int *)&trace_data->bits;
+ *ip = htonl(*ip);
+ sts = __pmtracedecodedata((__pmPDU *)trace_data, &tag, &len, &type, &p, &data);
+ fprintf(stderr, " __pmtracedecodedata: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+ if (sts >= 0) { free(tag); }
+
+ fprintf(stderr, "[%s] checking access beyond buffer\n", name);
+ memset(trace_data, 0, sizeof(*trace_data));
+ trace_data->hdr.len = sizeof(*trace_data);
+ trace_data->hdr.type = TRACE_PDU_DATA;
+ trace_data->bits.version = TRACE_PDU_VERSION;
+ trace_data->bits.taglen = 2;
+ ip = (int *)&trace_data->bits;
+ *ip = htonl(*ip);
+ sts = __pmtracedecodedata((__pmPDU *)trace_data, &tag, &len, &type, &p, &data);
+ fprintf(stderr, " __pmtracedecodedata: sts = %d (%s)\n", sts, pmtraceerrstr(sts));
+ if (sts >= 0) { free(tag); }
+
+ free(trace_data);
+}
+
+typedef void (*decode_t)(const char *);
+
+struct pdu {
+ const char *name;
+ decode_t decode;
+} pdus[] = {
+ { "cred", decode_creds },
+ { "error", decode_error },
+ { "profile", decode_profile },
+ { "fetch", decode_fetch },
+ { "desc_req", decode_desc_req },
+ { "desc", decode_desc },
+ { "instance_req", decode_instance_req },
+ { "instance", decode_instance },
+ { "pmns_ids", decode_pmns_ids },
+ { "pmns_names", decode_pmns_names },
+ { "pmns_child", decode_pmns_child },
+ { "pmns_traverse", decode_pmns_traverse },
+ { "log_control", decode_log_control },
+ { "log_status", decode_log_status },
+ { "log_request", decode_log_request },
+ { "result", decode_result },
+ { "text_req", decode_text_req },
+ { "text", decode_text },
+ { "trace_ack", decode_trace_ack },
+ { "trace_data", decode_trace_data },
+ { "auth", decode_auth },
+};
+
+int
+main(int argc, char **argv)
+{
+ int c, d;
+ int sts, errflag = 0;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:?")) != EOF) {
+ switch (c) {
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind < argc-1) {
+ fprintf(stderr, "Usage: %s [-D n]\n", pmProgname);
+ exit(1);
+ }
+
+ if (argc == optind) {
+ for (d = 0; d < sizeof(pdus)/sizeof(struct pdu); d++)
+ pdus[d].decode(pdus[d].name);
+ } else {
+ for (c = 0; c < (argc - optind); c++)
+ for (d = 0; d < sizeof(pdus)/sizeof(struct pdu); d++)
+ if (strcmp(argv[optind + c], pdus[d].name) == 0)
+ pdus[d].decode(pdus[d].name);
+ }
+ exit(0);
+}
diff --git a/qa/src/permfetch.c b/qa/src/permfetch.c
new file mode 100644
index 0000000..71ceac9
--- /dev/null
+++ b/qa/src/permfetch.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * permfetch - fetch, permute and fetch again - for a bunch of metrics
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+typedef struct {
+ char *base;
+ int numpmid;
+ char **namelist;
+ pmID *pmidlist;
+ pmResult *rp;
+} state_t;
+
+state_t *todolist;
+static int todo;
+
+static void
+dometric(const char *name)
+{
+ int done = todolist[todo].numpmid;
+
+ todolist[todo].namelist = (char **)realloc(todolist[todo].namelist, (1+done)*sizeof(char *));
+ todolist[todo].pmidlist = (pmID *)realloc(todolist[todo].pmidlist, (1+done)*sizeof(pmID));
+ todolist[todo].namelist[done] = strdup(name);
+ todolist[todo].numpmid++;
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int n;
+ int j;
+ int numpmid;
+ pmID pmid;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ int verbose = 0;
+ char *host = NULL; /* pander to gcc */
+ char local[MAXHOSTNAMELEN];
+ char *namespace = PM_NS_DEFAULT;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:h:n:V?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'V': /* verbose */
+ verbose++;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options:\n\
+ -a archive metrics source is an archive log\n\
+ -D debug standard PCP debug flag\n\
+ -h host metrics source is PMCD on host\n\
+ -n namespace use an alternative PMNS\n\
+ -V verbose/diagnostic output\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ while (optind < argc) {
+ todolist = (state_t *)realloc(todolist, (todo+1)*sizeof(state_t));
+ todolist[todo].base = argv[optind];
+ todolist[todo].numpmid = 0;
+ todolist[todo].namelist = (char **)0;
+ todolist[todo].pmidlist = (pmID *)0;
+ pmTraversePMNS(argv[optind], dometric);
+ printf("%s:\n", argv[optind]);
+ if (verbose)
+ printf("... %d metrics,", todolist[todo].numpmid);
+ if (todolist[todo].numpmid == 0) {
+ printf("... no metrics in PMNS ... skip tests\n");
+ goto next;
+ }
+ sts = pmLookupName(todolist[todo].numpmid, todolist[todo].namelist, todolist[todo].pmidlist);
+ if (sts != todolist[todo].numpmid) {
+ int i;
+ putchar('\n');
+ if (sts < 0)
+ fprintf(stderr, "%s: pmLookupName: %s\n", pmProgname, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: pmLookupName: ...\n", pmProgname);
+ for (i = 0; i < todolist[todo].numpmid; i++) {
+ if (todolist[todo].pmidlist[i] == PM_ID_NULL)
+ fprintf(stderr, " %s is bad\n", todolist[todo].namelist[i]);
+ }
+ exit(1);
+ }
+ sts = pmFetch(todolist[todo].numpmid, todolist[todo].pmidlist, &todolist[todo].rp);
+ if (sts < 0) {
+ putchar('\n');
+ fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if (verbose)
+ printf(" %d value sets\n", todolist[todo].rp->numpmid);
+ if (todolist[todo].numpmid != todolist[todo].rp->numpmid)
+ printf("botch: %d metrics != %d value sets!\n",
+ todolist[todo].numpmid, todolist[todo].rp->numpmid);
+
+next:
+ optind++;
+ todo++;
+ }
+
+ for (n = 0; n < todo; n++) {
+ if (todolist[todo-n-1].numpmid <= 0)
+ continue;
+ printf("%s: free names and result\n", todolist[todo-n-1].base);
+ for (j = 0; j < todolist[todo-n-1].numpmid; j++) {
+ free(todolist[todo-n-1].namelist[j]);
+ }
+ free(todolist[todo-n-1].namelist);
+ pmFreeResult(todolist[todo-n-1].rp);
+ }
+ /* reverse pmids in list */
+ for (n = 0; n < todo; n++) {
+ numpmid = todolist[n].numpmid;
+ for (j = 0; j < numpmid / 2; j++) {
+ pmid = todolist[n].pmidlist[numpmid-j-1];
+ todolist[n].pmidlist[numpmid-j-1] = todolist[n].pmidlist[j];
+ todolist[n].pmidlist[j] = pmid;
+ }
+ }
+ for (n = 0; n < todo; n++) {
+ if (todolist[n].numpmid <= 0)
+ continue;
+ printf("%s (reverse):\n", todolist[n].base);
+ if (verbose)
+ printf("... %d metrics,", todolist[n].numpmid);
+ sts = pmFetch(todolist[n].numpmid, todolist[n].pmidlist, &todolist[n].rp);
+ if (sts < 0) {
+ putchar('\n');
+ fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if (todolist[n].numpmid != todolist[n].rp->numpmid)
+ printf("botch: %d metrics != %d value sets!\n",
+ todolist[n].numpmid, todolist[n].rp->numpmid);
+
+ if (verbose) {
+ printf(" %d value sets", todolist[n].rp->numpmid);
+ printf(" free result\n");
+ }
+ pmFreeResult(todolist[n].rp);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/permslist b/qa/src/permslist
new file mode 100644
index 0000000..0d33cdb
--- /dev/null
+++ b/qa/src/permslist
@@ -0,0 +1,16 @@
+GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_LOG_DIR)
+GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_RUN_DIR)|optional
+GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_TMP_DIR)
+GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_VAR_DIR)/config/pmda
+src/libpcp_pmcd/src/GNUmakefile|444|root|root|$(PCP_SHARE_DIR)/../systemtap/tapset/pmcd.stp|optional
+src/pmcd/GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_LOG_DIR)/pmcd
+src/pmie/GNUmakefile|664|$(PCP_USER)|$(PCP_GROUP)|$(PCP_PMIECONTROL_PATH)
+src/pmie/GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_LOG_DIR)/pmie
+src/pmie/GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_SYSCONF_DIR)/pmie
+src/pmie/GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_TMP_DIR)/pmie|optional
+src/pmlogger/GNUmakefile|664|$(PCP_USER)|$(PCP_GROUP)|$(PCP_PMLOGGERCONTROL_PATH)
+src/pmlogger/GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_LOG_DIR)/pmlogger
+src/pmlogger/GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_SYSCONF_DIR)/pmlogger
+src/pmlogger/GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_TMP_DIR)/pmlogger|optional
+src/pmproxy/GNUmakefile|775|$(PCP_USER)|$(PCP_USER)|$(PCP_LOG_DIR)/pmproxy
+src/pmwebapi/GNUmakefile|775|$(PCP_USER)|$(PCP_GROUP)|$(PCP_LOG_DIR)/pmwebd|optional
diff --git a/qa/src/pmatop-log.0 b/qa/src/pmatop-log.0
new file mode 100644
index 0000000..bd7366e
--- /dev/null
+++ b/qa/src/pmatop-log.0
Binary files differ
diff --git a/qa/src/pmatop-log.folio b/qa/src/pmatop-log.folio
new file mode 100644
index 0000000..bde516f
--- /dev/null
+++ b/qa/src/pmatop-log.folio
@@ -0,0 +1,9 @@
+PCPFolio
+Version: 1
+# use pmafm(1) to process this PCP Archive Folio
+#
+Created: on dieyong at Fri May 23 15:51:10 2014
+Creator: pmcollectl
+# Host Basename
+#
+Archive: dieyong pmatop-log
diff --git a/qa/src/pmatop-log.index b/qa/src/pmatop-log.index
new file mode 100644
index 0000000..c3a39e4
--- /dev/null
+++ b/qa/src/pmatop-log.index
Binary files differ
diff --git a/qa/src/pmatop-log.meta b/qa/src/pmatop-log.meta
new file mode 100644
index 0000000..def1656
--- /dev/null
+++ b/qa/src/pmatop-log.meta
Binary files differ
diff --git a/qa/src/pmcdgone.c b/qa/src/pmcdgone.c
new file mode 100644
index 0000000..ed3c43d
--- /dev/null
+++ b/qa/src/pmcdgone.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 2012 Red Hat. All Rights Reserved.
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * ping pmcd 4 times, kill off pmcd, ping 4 more times, restart pmcd,
+ * ping 4 more times ... and some reconnect attempts for good measure ...
+ * and some more pings ...
+ * sleep 10 seconds after change of state for pmcd
+ *
+ * Has to be run as root to control pmcd
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#include "localconfig.h"
+
+static pmResult *_store;
+static pmDesc _desc;
+static int _numinst;
+static int *_instlist;
+static char **_inamelist;
+static int _text;
+static int _indom_text;
+static int ctlport;
+
+static void
+_ConnectLogger(void)
+{
+ int n;
+ int pid = PM_LOG_PRIMARY_PID;
+ int port = PM_LOG_NO_PORT;
+
+ if ((n = __pmConnectLogger("localhost", &pid, &port)) < 0) {
+ printf("Cannot connect to primary pmlogger on \"localhost\": %s\n", pmErrStr(n));
+ exit(1);
+ }
+ ctlport = n;
+}
+
+static int
+x_indom(int xpecterr)
+{
+ int err = 0;
+ int n;
+ int j;
+ int numinst;
+ int *instlist;
+ char **inamelist;
+ char *name = NULL;
+
+ if ((numinst = pmGetInDom(_desc.indom, &instlist, &inamelist)) < 0) {
+ fprintf(stderr, "pmGetInDom: %s", pmErrStr(numinst));
+ if (xpecterr)
+ fprintf(stderr, " -- error expected\n");
+ else {
+ fprintf(stderr, "\n");
+ err++;
+ }
+ }
+ else {
+ free(instlist);
+ free(inamelist);
+ }
+
+ j = _numinst / 2;
+
+ if ((n = pmNameInDom(_desc.indom, _instlist[j], &name)) < 0) {
+ fprintf(stderr, "pmNameInDom: %s", pmErrStr(n));
+ if (xpecterr)
+ fprintf(stderr, " -- error expected\n");
+ else {
+ fprintf(stderr, "\n");
+ err++;
+ }
+ }
+
+ if ((n = pmLookupInDom(_desc.indom, name)) < 0) {
+ fprintf(stderr, "pmLookupInDom: %s", pmErrStr(n));
+ if (xpecterr)
+ fprintf(stderr, " -- error expected\n");
+ else {
+ fprintf(stderr, "\n");
+ err++;
+ }
+ }
+ else {
+ if (n != _instlist[j]) {
+ err++;
+ fprintf(stderr, "botch: pmLookupInDom returns 0x%x, expected 0x%x\n",
+ n, _instlist[j]);
+ }
+ free(name);
+ }
+
+ return err;
+}
+
+static int
+exer(int numpmid, pmID *pmidlist, int xpecterr)
+{
+ int i;
+ int j;
+ int n;
+ int err = 0;
+ pmDesc desc;
+ char *buf;
+ pmResult *resp, *lresp;
+
+ for (i = 0; i < 4; i++) {
+ if (!xpecterr)
+ fputc('.', stderr);
+
+ if ((n = pmLookupDesc(pmidlist[0], &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc: %s", pmErrStr(n));
+ if (xpecterr)
+ fprintf(stderr, " -- error expected\n");
+ else {
+ fprintf(stderr, "\n");
+ err++;
+ }
+ }
+ else if (xpecterr)
+ err++;
+
+ err += x_indom(xpecterr);
+
+ if ((n = pmLookupText(pmidlist[1], PM_TEXT_HELP, &buf)) < 0) {
+ fprintf(stderr, "pmLookupText: %s", pmErrStr(n));
+ if (xpecterr)
+ fprintf(stderr, " -- error expected\n");
+ else {
+ fprintf(stderr, "\n");
+ err++;
+ }
+ }
+ else {
+ if (xpecterr)
+ err++;
+ if (!_text) {
+ fprintf(stderr, "Text: %s\n", buf);
+ _text = 1;
+ }
+ free(buf);
+ }
+
+ if ((n = pmLookupInDomText(_desc.indom, PM_TEXT_HELP, &buf)) < 0) {
+ fprintf(stderr, "pmLookupInDomText: %s", pmErrStr(n));
+ if (xpecterr)
+ fprintf(stderr, " -- error expected\n");
+ else {
+ fprintf(stderr, "\n");
+ err++;
+ }
+ }
+ else {
+ if (xpecterr)
+ err++;
+ if (!_indom_text) {
+ fprintf(stderr, "InDomText: %s\n", buf);
+ _indom_text = 1;
+ }
+ free(buf);
+ }
+
+ if ((n = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ fprintf(stderr, "pmFetch: %s", pmErrStr(n));
+ if (xpecterr)
+ fprintf(stderr, " -- error expected\n");
+ else {
+ fprintf(stderr, "\n");
+ err++;
+ }
+ }
+ else {
+ if (xpecterr)
+ err++;
+ if (resp->numpmid != numpmid) {
+ err++;
+ __pmDumpResult(stderr, resp);
+ }
+ else for (j = 0; j < resp->numpmid; j++) {
+ if (resp->vset[j]->numval < 1) {
+ err++;
+ __pmDumpResult(stderr, resp);
+ break;
+ }
+ }
+ pmFreeResult(resp);
+ }
+
+ if ((n = pmStore(_store)) < 0) {
+ fprintf(stderr, "pmStore: %s", pmErrStr(n));
+ if (xpecterr)
+ fprintf(stderr, " -- error expected\n");
+ else {
+ fprintf(stderr, "\n");
+ err++;
+ }
+ }
+ else if (xpecterr)
+ err++;
+
+ if ((n = __pmControlLog(ctlport, _store, PM_LOG_ENQUIRE, 0, 0, &lresp)) < 0) {
+ fprintf(stderr, "__pmControlLog: %s", pmErrStr(n));
+ if (xpecterr)
+ fprintf(stderr, " -- error expected\n");
+ else {
+ fprintf(stderr, "\n");
+ err++;
+ }
+ }
+ else {
+ pmFreeResult(lresp);
+ }
+
+ }
+ if (!xpecterr)
+ fputc('\n', stderr);
+
+
+ return err;
+}
+
+int
+main(int argc, char **argv)
+{
+ int err = 0;
+ int sts;
+ int i;
+ int j;
+ char *namelist[4];
+ pmID pmidlist[4];
+ int n;
+ int numpmid;
+ int ctx0;
+ int ctx1;
+ int c;
+ int errflag = 0;
+ char *binadm = pmGetConfig("PCP_BINADM_DIR");
+ char path[MAXPATHLEN];
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options:\n\
+ -D N set pmDebug debugging flag to N\n",
+ pmProgname);
+ exit(1);
+ }
+
+#ifndef IS_MINGW
+ if ((n = geteuid()) != 0) {
+ fprintf(stderr, "pmcdgone: Must be run as root, not uid %d!\n", n);
+ exit(1);
+ }
+#endif
+
+ if ((n = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) {
+ fprintf(stderr, "pmLoadNameSpace: %s\n", pmErrStr(n));
+ exit(1);
+ }
+
+ if ((ctx0 = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ fprintf(stderr, "pmNewContext: %s\n", pmErrStr(ctx0));
+ exit(1);
+ }
+ if ((ctx1 = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ fprintf(stderr, "pmNewContext: %s\n", pmErrStr(ctx1));
+ exit(1);
+ }
+ _ConnectLogger();
+
+ i = 0;
+ namelist[i++] = "sample.long.write_me";
+ namelist[i++] = "sample.colour";
+ namelist[i++] = "sampledso.bin";
+ numpmid = i;
+ n = pmLookupName(numpmid, namelist, pmidlist);
+ if (n < 0) {
+ fprintf(stderr, "pmLookupName: %s\n", pmErrStr(n));
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ fprintf(stderr, " %s - not known\n", namelist[i]);
+ }
+ exit(1);
+ }
+ if ((n = pmFetch(1, pmidlist, &_store)) < 0) {
+ fprintf(stderr, "initial pmFetch failed: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ if ((n = pmLookupDesc(pmidlist[1], &_desc)) < 0) {
+ fprintf(stderr, "initial pmLookupDesc failed: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ if ((_numinst = pmGetInDom(_desc.indom, &_instlist, &_inamelist)) < 0) {
+ fprintf(stderr, "initial pmGetInDom failed: %s\n", pmErrStr(n));
+ exit(1);
+ }
+
+ err += exer(numpmid, pmidlist, 0);
+
+ fprintf(stderr, "Kill off pmcd ...\n");
+ sts = system(". $PCP_DIR/etc/pcp.env; $PCP_RC_DIR/pcp stop");
+ if (sts != 0)
+ fprintf(stderr, "Warning: stop script returns %d\n", sts);
+ sleep(10);
+ _text = _indom_text = 0;
+ __pmCloseSocket(ctlport);
+
+ err += exer(numpmid, pmidlist, 1);
+
+ for (j = 0; j < 2; j++) {
+ if (j == 0)
+ i = ctx1;
+ else
+ i = ctx0;;
+ fprintf(stderr, "Reconnect to pmcd context %d ...\n", i);
+ if ((n = pmReconnectContext(i)) < 0) {
+ fprintf(stderr, "pmReconnectContext: %s -- error expected\n", pmErrStr(n));
+ }
+ else {
+ fprintf(stderr, "pmReconnectContext: success after pmcd killed!?\n");
+ err++;
+ }
+
+ err += exer(numpmid, pmidlist, 1);
+ }
+
+ /*
+ * tricky part begins ...
+ * 1. get rid of the archive folio to avoid timestamp clashes with last
+ * created folio
+ * 2. re-start pmcd
+ * 3. wait for pmcd to be accepting connections
+ * 4. wait for pmlogger to be accepting connections from pmlc
+ * 5. connect to pmlogger
+ */
+ fprintf(stderr, "Restart pmcd ...\n");
+ sts = system(". $PCP_DIR/etc/pcp.env; path_opt=''; if [ $PCP_PLATFORM = linux ]; then path_opt=pmlogger/; fi; pmafm $PCP_LOG_DIR/$path_opt`hostname`/Latest remove 2>/dev/null | sh");
+ if (sts != 0)
+ fprintf(stderr, "Warning: folio removal script %d\n", sts);
+ __pmCloseSocket(ctlport);
+ sts = system(". $PCP_DIR/etc/pcp.env; $PCP_RC_DIR/pcp start");
+ if (sts != 0)
+ fprintf(stderr, "Warning: stop script returns %d\n", sts);
+
+ sprintf(path, "%s/pmcd_wait", binadm);
+ if(access(path, X_OK) == 0) {
+ sts = system(". $PCP_DIR/etc/pcp.env; [ -x $PCP_BINADM_DIR/pmcd_wait ] && $PCP_BINADM_DIR/pmcd_wait");
+ if (sts != 0)
+ fprintf(stderr, "Warning: pmcd_wait script returns %d\n", sts);
+ }
+
+ sts = system(". $PCP_DIR/etc/pcp.env; ( cat common.check; echo _wait_for_pmlogger -P $PCP_LOG_DIR/pmlogger/`hostname`/pmlogger.log ) | sh");
+ if (sts != 0)
+ fprintf(stderr, "Warning: _wait_for_pmlogger script returns %d\n", sts);
+ _ConnectLogger();
+
+ err += exer(numpmid, pmidlist, 1);
+
+ /*
+ * more trickery ...
+ * need to sleep here for at least 1 second so that timestamp of
+ * IPC failure above is more than 1 second ago, so we wait long enough
+ * that pmReconnectContext() really does the connect() attempt, rather
+ * than returning -ETIMEDOUT immediately ... but sleep(1) is unreliable,
+ * hence ...
+ */
+ sleep(3);
+
+ for (j = 0; j < 2; j++) {
+ if (j == 0)
+ i = ctx1;
+ else
+ i = ctx0;
+ fprintf(stderr, "Reconnect to pmcd context %d ...\n", i);
+ if ((n = pmReconnectContext(i)) < 0) {
+ fprintf(stderr, "pmReconnectContext: %s\n", pmErrStr(n));
+ err++;
+ }
+
+ err += exer(numpmid, pmidlist, 0);
+ }
+
+ fprintf(stderr, "%d unexpected errors.\n", err);
+ exit(0);
+}
diff --git a/qa/src/pmconvscale.c b/qa/src/pmconvscale.c
new file mode 100644
index 0000000..5d03e38
--- /dev/null
+++ b/qa/src/pmconvscale.c
@@ -0,0 +1,146 @@
+/*
+ * pmconvscale - tests bug in pmConvScale
+ *
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <unistd.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+/* default is the "no" dimension case */
+pmUnits units = {0, 0, 0, 0, 0, 0};
+pmUnits oldunits = {0, 0, 0, 0, 0, 0};
+
+static int sscales[] = { PM_SPACE_GBYTE, PM_SPACE_TBYTE, PM_SPACE_GBYTE, PM_SPACE_MBYTE, PM_SPACE_KBYTE, PM_SPACE_BYTE, PM_SPACE_KBYTE, PM_SPACE_MBYTE };
+static int n_sscales = sizeof(sscales) / sizeof(sscales[0]);
+
+static int tscales[] = { PM_TIME_MIN, PM_TIME_HOUR, PM_TIME_MIN, PM_TIME_SEC, PM_TIME_MSEC, PM_TIME_USEC, PM_TIME_NSEC, PM_TIME_USEC, PM_TIME_MSEC, PM_TIME_SEC };
+static int n_tscales = sizeof(tscales) / sizeof(tscales[0]);
+
+static int cscales[] = {1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -7, -6, -5, -4, -3, -2, -1, 0 };
+static int n_cscales = sizeof(cscales) / sizeof(cscales[0]);
+
+/* just for PBYTE and EBYTE space extensions */
+#ifdef HAVE_BITFIELDS_LTOR
+pmUnits myunits = { 1, -1, 0, PM_SPACE_EBYTE, PM_TIME_SEC, 0 };
+#else
+pmUnits myunits = { 0, 0, PM_TIME_SEC, PM_SPACE_EBYTE, 0, -1, 1 };
+#endif
+
+int
+main(int argc, char **argv)
+{
+ int i, sts;
+ int mode = 1;
+ int limit = 0;
+ pmAtomValue value, newvalue;
+ char olds[64], news[64];
+
+ value.f = 12345678;
+
+ if (argc > 1) {
+ if (argv[1][0] == 'c') {
+ /* crude, but effective ... the "count" dimension case */
+ units.dimCount = 1;
+ mode = 1;
+ }
+ else if (argv[1][0] == 's') {
+ /* crude, but effective ... the "space" dimension case */
+ units.dimSpace = 1;
+ units.scaleSpace = PM_SPACE_MBYTE;
+ mode = 2;
+ }
+ else if (argv[1][0] == 'r') {
+ /* crude, but effective ... the "space/time" dimension case */
+ units.dimSpace = 1;
+ units.dimTime = -1;
+ units.scaleSpace = PM_SPACE_MBYTE;
+ units.scaleTime = PM_TIME_SEC;
+ mode = 2;
+ }
+ else if (argv[1][0] == 't') {
+ /* crude, but effective ... the "time" dimension case */
+ units.dimTime = 1;
+ units.scaleTime = PM_TIME_SEC;
+ mode = 3;
+ }
+ else if (argv[1][0] == 'x') {
+ /* PBYTE and EBYTE space extensions */
+ value.f = 1;
+ while (myunits.scaleSpace > 0) {
+ units = myunits;
+ units.scaleSpace--;
+ sts = pmConvScale(PM_TYPE_FLOAT, &value, &myunits, &newvalue, &units);
+ if (sts < 0) {
+ strcpy(olds, pmUnitsStr(&oldunits));
+ strcpy(news, pmUnitsStr(&units));
+ fprintf(stderr, "pmConvScale \"%s\" -> \"%s\" failed: %s\n", olds, news, pmErrStr(sts));
+ exit(1);
+ }
+ printf("%12.1f %s -> ", value.f, pmUnitsStr(&myunits));
+ printf("%12.1f %s\n", newvalue.f, pmUnitsStr(&units));
+ myunits.scaleSpace--;
+ value.f = newvalue.f / 512;
+ }
+ value.f *= 512;
+ while (myunits.scaleSpace < PM_SPACE_EBYTE) {
+ units = myunits;
+ units.scaleSpace++;
+ sts = pmConvScale(PM_TYPE_FLOAT, &value, &myunits, &newvalue, &units);
+ if (sts < 0) {
+ strcpy(olds, pmUnitsStr(&oldunits));
+ strcpy(news, pmUnitsStr(&units));
+ fprintf(stderr, "pmConvScale \"%s\" -> \"%s\" failed: %s\n", olds, news, pmErrStr(sts));
+ exit(1);
+ }
+ printf("%12.1f %s -> ", value.f, pmUnitsStr(&myunits));
+ printf("%12.1f %s\n", newvalue.f, pmUnitsStr(&units));
+ myunits.scaleSpace++;
+ value.f = newvalue.f * 512;
+ }
+ exit(0);
+ }
+ }
+
+ oldunits = units;
+
+ if (mode == 1)
+ limit = n_cscales;
+ else if (mode == 2)
+ limit = n_sscales;
+ else if (mode == 3)
+ limit = n_tscales;
+
+ for (i=0; i < limit; i++) {
+ if (mode == 1)
+ units.scaleCount = cscales[i];
+ else if (mode == 2)
+ units.scaleSpace = sscales[i];
+ else if (mode == 3)
+ units.scaleTime = tscales[i];
+
+ strcpy(olds, pmUnitsStr(&oldunits));
+ strcpy(news, pmUnitsStr(&units));
+
+ sts = pmConvScale(PM_TYPE_FLOAT, &value, &oldunits, &newvalue, &units);
+ if (sts < 0) {
+ fprintf(stderr, "pmConvScale \"%s\" -> \"%s\" failed: %s\n", olds, news, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (mode == 1)
+ printf("scaleCount=%d old: %12.1f \"%s\" new: %12.1f \"%s\"\n",
+ units.scaleCount, value.f, olds, newvalue.f, news);
+ else if (mode == 2)
+ printf("scaleSpace=%d old: %12.1f \"%s\" new: %12.1f \"%s\"\n",
+ units.scaleSpace, value.f, olds, newvalue.f, news);
+ else if (mode == 3)
+ printf("scaleTime=%d old: %12.1f \"%s\" new: %12.1f \"%s\"\n",
+ units.scaleTime, value.f, olds, newvalue.f, news);
+
+ value.f = newvalue.f;
+ oldunits = units;
+ }
+ exit(0);
+}
diff --git a/qa/src/pmdacache.c b/qa/src/pmdacache.c
new file mode 100644
index 0000000..c035c73
--- /dev/null
+++ b/qa/src/pmdacache.c
@@ -0,0 +1,102 @@
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+int
+main(int argc, char **argv)
+{
+ int errflag = 0;
+ int indom = 123;
+ int sts;
+ int c;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "Cc:D:dh:LSs:")) != EOF) {
+ switch (c) {
+
+ case 'C':
+ sts = pmdaCacheOp(indom, PMDA_CACHE_CULL);
+ fprintf(stderr, "cull() -> %d", sts);
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case 'c':
+ sts = pmdaCacheStore(indom, PMDA_CACHE_CULL, optarg, NULL);
+ fprintf(stderr, "cull(%s) -> %d", optarg, sts);
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'd':
+#ifdef PMDA_CACHE_DUMP_ALL
+ sts = pmdaCacheOp(indom, PMDA_CACHE_DUMP_ALL);
+#else
+ sts = pmdaCacheOp(indom, PMDA_CACHE_DUMP);
+#endif
+ break;
+
+ case 'h':
+ sts = pmdaCacheStore(indom, PMDA_CACHE_HIDE, optarg, NULL);
+ fprintf(stderr, "hide(%s) -> %d", optarg, sts);
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case 'L':
+ sts = pmdaCacheOp(indom, PMDA_CACHE_LOAD);
+ fprintf(stderr, "load() -> %d", sts);
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case 'S':
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ fprintf(stderr, "save() -> %d", sts);
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case 's':
+ sts = pmdaCacheStore(indom, PMDA_CACHE_ADD, optarg, NULL);
+ fprintf(stderr, "store(%s) -> %d", optarg, sts);
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s ...\n", pmProgname);
+ fprintf(stderr, "options:\n");
+ fprintf(stderr, "-C cull all\n");
+ fprintf(stderr, "-c inst cull one\n");
+ fprintf(stderr, "-D debug\n");
+ fprintf(stderr, "-d dump\n");
+ fprintf(stderr, "-h inst hide\n");
+ fprintf(stderr, "-L load\n");
+ fprintf(stderr, "-S store\n");
+ fprintf(stderr, "-s inst save\n");
+ exit(1);
+ }
+
+ return 0;
+}
+
diff --git a/qa/src/pmdaqueue.c b/qa/src/pmdaqueue.c
new file mode 100644
index 0000000..d8e4d1f
--- /dev/null
+++ b/qa/src/pmdaqueue.c
@@ -0,0 +1,309 @@
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+/*
+ * Make a dummy event, timestamped now
+ */
+void *make_event(size_t size, struct timeval *tv)
+{
+ void *buffer = malloc(size);
+ if (buffer)
+ memset(buffer, 0xA, size);
+ gettimeofday(tv, NULL);
+ return buffer;
+}
+
+/*
+ * Simple filter based on event size, also report whenever called
+ */
+int apply_filter(void *data, void *event, size_t size)
+{
+ size_t filter = *(size_t *)data;
+
+ fprintf(stderr, "=> apply-filter(%d<%d) -> %d\n",
+ (int)filter, (int)size, size >= filter);
+ return (size >= filter);
+}
+
+/*
+ * Client context ended, ensure release method is called
+ */
+void release_filter(void *data)
+{
+ size_t filter = *(size_t *)data;
+ fprintf(stderr, "=> release filter(%d)\n", (int)filter);
+}
+
+/*
+ * Report stats about the state of given queue identifier
+ */
+void queue_statistics(int q)
+{
+ pmAtomValue count, bytes, clients, memory;
+
+ pmdaEventQueueCounter(q, &count);
+ pmdaEventQueueBytes(q, &bytes);
+ pmdaEventQueueClients(q, &clients);
+ pmdaEventQueueMemory(q, &memory);
+
+ fprintf(stderr, "event queue#%d count=%d, bytes=%d, clients=%d, mem=%lld\n",
+ q, (int)count.ul, (int)bytes.ull, (int)clients.ul,
+ (long long)memory.ull);
+}
+
+/*
+ * Report and check contents of events in a given queue identifier
+ * decode_event is a callback, called once per-event.
+ */
+
+int decode_event(int key, void *event, size_t size,
+ struct timeval *timestamp, void *data)
+{
+ char *buffer = (char *)event;
+ int *datap = (int *)data;
+ int queueid = datap[0];
+ int context = datap[1];
+ int i, ok = 1;
+
+ for (i = 0; i < size; i++)
+ if (buffer[i] != 0xA)
+ ok = 0;
+ fprintf(stderr, "queue#%d client#%d event: %p, size=%d check=%s\n",
+ queueid, context, event, (int)size, ok? "ok" : "bad");
+ return 0;
+}
+
+void queue_events(int q, int context)
+{
+ pmAtomValue records;
+ int data[2] = { q, context };
+
+ fprintf(stderr, "walking queue#%d events for client#%d\n", q, context);
+ pmdaEventQueueRecords(q, &records, context, decode_event, &data);
+ fprintf(stderr, "end walk queue#%d\n", q);
+}
+
+int
+main(int argc, char **argv)
+{
+ int c, sts;
+ int errflag = 0;
+ int context, queueid;
+ size_t size;
+ size_t filter_size;
+ struct timeval tv;
+ char *s, *name;
+ void *event;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "A:a:C:c:D:E:e:F:f:q:s:S:")) != EOF) {
+ switch (c) {
+
+ case 'a': /* disallow a clients queue access */
+ case 'A': /* allow a clients queue access */
+ s = optarg;
+ name = strsep(&s, ",");
+ if (!s) {
+ fprintf(stderr, "%s: invalid client queue access specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ break;
+ }
+ context = atoi(name);
+ queueid = pmdaEventQueueHandle(s);
+
+ sts = pmdaEventSetAccess(context, queueid, (c == 'A'));
+ fprintf(stderr, "enable queue#%d access(%d) -> %d",
+ queueid, context, (c == 'A'));
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case 'c': /* new client: ID */
+ context = atoi(optarg);
+ sts = pmdaEventNewClient(context);
+ fprintf(stderr, "new client(%d) -> %d", context, sts);
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case 'C': /* remove client: ID */
+ context = atoi(optarg);
+ sts = pmdaEventEndClient(context);
+ fprintf(stderr, "end client(%d) -> %d", context, sts);
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'e': /* create an event on named queue of given size */
+ s = optarg;
+ name = strsep(&s, ",");
+ if (!s) {
+ fprintf(stderr, "%s: invalid event size specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ break;
+ }
+ size = atoi(s);
+ queueid = pmdaEventQueueHandle(name);
+ if (queueid < 0) {
+ fprintf(stderr, "%s: invalid event queue specification (%s)\n",
+ pmProgname, name);
+ errflag++;
+ break;
+ }
+ event = make_event(size, &tv);
+ sts = pmdaEventQueueAppend(queueid, event, size, &tv);
+ fprintf(stderr, "add event(%s,%d) -> %d ", name, (int)size, sts);
+ if (sts < 0) fprintf(stderr, "%s", pmErrStr(sts));
+ else __pmPrintStamp(stderr, &tv);
+ fputc('\n', stderr);
+ break;
+
+ case 'E': /* create an event on queue ID of given size */
+ s = optarg;
+ name = strsep(&s, ",");
+ if (!s) {
+ fprintf(stderr, "%s: invalid event size specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ break;
+ }
+ queueid = atoi(name);
+ size = atoi(s);
+ event = make_event(size, &tv);
+ sts = pmdaEventQueueAppend(queueid, event, size, &tv);
+ fprintf(stderr, "add queue#%d event(%s,%d) -> %d ",
+ queueid, name, (int)size, sts);
+ if (sts < 0) fprintf(stderr, "%s", pmErrStr(sts));
+ else __pmPrintStamp(stderr, &tv);
+ fputc('\n', stderr);
+ break;
+
+ case 'q': /* create queue with name and a max memory size */
+ s = optarg;
+ name = strsep(&s, ",");
+ if (!s) {
+ fprintf(stderr, "%s: invalid queue memory specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ break;
+ }
+ size = atoi(s);
+ sts = pmdaEventNewQueue(name, size);
+ fprintf(stderr, "new queue(%s,%d) -> %d", name, (int)size, sts);
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case 'f': /* create client filter, limits size */
+ s = optarg;
+ name = strsep(&s, ",");
+ if (!s) {
+ fprintf(stderr, "%s: invalid client filter queue specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ break;
+ }
+ context = atoi(name);
+ name = strsep(&s, ",");
+ if (!s) {
+ fprintf(stderr, "%s: invalid client filter size specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ break;
+ }
+ queueid = pmdaEventQueueHandle(name);
+ filter_size = atoi(s);
+ sts = pmdaEventSetFilter(context, queueid, (void *)&filter_size,
+ apply_filter, release_filter);
+ fprintf(stderr, "client#%d set filter(sz<%d) on queue#%d-> %d",
+ context, (int)filter_size, queueid, sts);
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case 'F': /* remove a clients filter */
+ s = optarg;
+ name = strsep(&s, ",");
+ if (!s) {
+ fprintf(stderr, "%s: invalid client filter queue specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ break;
+ }
+ context = atoi(name);
+ queueid = pmdaEventQueueHandle(s);
+
+ sts = pmdaEventSetFilter(context, queueid, NULL, NULL, NULL);
+ fprintf(stderr, "end queue#%d filter(%d) -> %d", queueid, context, sts);
+ if (sts < 0) fprintf(stderr, " %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ break;
+
+ case 's': /* dump queue, events, clients counters */
+ name = optarg;
+ queueid = pmdaEventQueueHandle(name);
+ if (queueid < 0) {
+ fprintf(stderr, "%s: invalid queue specification (%s)\n",
+ pmProgname, name);
+ errflag++;
+ break;
+ }
+ queue_statistics(queueid);
+ break;
+
+ case 'S': /* dump queue contents, check events */
+ s = optarg;
+ name = strsep(&s, ",");
+ if (!s) {
+ fprintf(stderr, "%s: invalid client filter queue specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ break;
+ }
+ context = atoi(name);
+ queueid = pmdaEventQueueHandle(s);
+ queue_events(queueid, context);
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s ...\n", pmProgname);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -a id,name disable a clients access\n");
+ fprintf(stderr, " -A id,name enable a clients access\n");
+ fprintf(stderr, " -c id create a new client\n");
+ fprintf(stderr, " -C id remove a client by id\n");
+ fprintf(stderr, " -e name,size append an event of size on queue\n");
+ fprintf(stderr, " -E id,size append an event of size on queue\n");
+ fprintf(stderr, " -q name,size create a new queue with max size\n");
+ fprintf(stderr, " -f id,name,sz client queue filter, limit size\n");
+ fprintf(stderr, " -F id,name remove a clients queue filter\n");
+ fprintf(stderr, " -D debug\n");
+ fprintf(stderr, " -s name report statistics for a queue\n");
+ fprintf(stderr, " -S id,name report clients events in a queue\n");
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/qa/src/pmdashutdown.c b/qa/src/pmdashutdown.c
new file mode 100644
index 0000000..fe1a0e3
--- /dev/null
+++ b/qa/src/pmdashutdown.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s [options]\n\n", pmProgname);
+ fputs("Options:\n"
+ " -D N set pmDebug debugging flag to N\n"
+ " -d domain use domain (numeric) for metrics domain of PMDA\n"
+ " -h helpfile get help text from helpfile rather then default path\n"
+ " -l logfile write log into logfile rather than using default log name\n"
+ "\nExactly one of the following options may appear:\n"
+ " -i port expect PMCD to connect on given inet port (number or name)\n"
+ " -p expect PMCD to supply stdin/stdout (pipe)\n"
+ " -u socket expect PMCD to connect on given unix domain socket\n"
+ " -6 port expect PMCD to connect on given ipv6 port (number or name)\n",
+ stderr);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int err = 0;
+ pmdaInterface desc = { 0 };
+
+ __pmSetProgname(argv[0]);
+
+ /*
+ * Honour the pmcd connection protocol ...
+ */
+ pmdaDaemon(&desc, PMDA_INTERFACE_3, pmProgname, desc.domain, "pmdashutdown.log", NULL);
+ if (desc.status != 0) {
+ fprintf(stderr, "pmdaDaemon() failed!\n");
+ exit(1);
+ }
+ if (pmdaGetOpt(argc, argv, "D:d:h:i:l:pu:6:", &desc, &err) != EOF)
+ err++;
+ if (err)
+ usage();
+
+ pmdaOpenLog(&desc);
+ pmdaConnect(&desc);
+
+ /*
+ * if we exit immediately the smarter pmcd agent initialization
+ * will notice, and report unexpected end-of-file ... so sleep
+ * for longer than pmcd is willing to wait, then exit
+ */
+ sleep(10);
+
+ fprintf(stderr, "%s terminated\n", pmProgname);
+ exit(0);
+}
diff --git a/qa/src/pmlcmacro.c b/qa/src/pmlcmacro.c
new file mode 100644
index 0000000..a3a036b
--- /dev/null
+++ b/qa/src/pmlcmacro.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * exercise the state bit fiddling macros for pmlogger and friends
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main()
+{
+ int boo = 0x96969696;
+ int inlog;
+ int avail;
+ int mand;
+ int on;
+ int state;
+
+ for (inlog = 0; inlog < 2; inlog++) {
+ PMLC_SET_INLOG(boo, inlog);
+ for (avail = 0; avail < 2; avail++) {
+ PMLC_SET_AVAIL(boo, avail);
+ for (mand = 0; mand < 2; mand++) {
+ PMLC_SET_MAND(boo, mand);
+ for (on = 0; on < 2; on++) {
+ PMLC_SET_ON(boo, on);
+ printf("low-order bits: %2d\n", boo & 0xf);
+ if ((boo & 0xfffffff0) != 0x96969690)
+ printf("high-order bit botch: 0x%x (got) != 0x%x (expect)\n",
+ boo & 0xfffffff0, 0x96969690);
+ if (PMLC_GET_ON(boo) != on)
+ printf("PMLC_GET_ON botch: %d (got) != %d (expect)\n",
+ PMLC_GET_ON(boo), on);
+ if (PMLC_GET_MAND(boo) != mand)
+ printf("PMLC_GET_MAND botch: %d (got) != %d (expect)\n",
+ PMLC_GET_MAND(boo), mand);
+ if (PMLC_GET_AVAIL(boo) != avail)
+ printf("PMLC_GET_AVAIL botch: %d (got) != %d (expect)\n",
+ PMLC_GET_AVAIL(boo), avail);
+ if (PMLC_GET_INLOG(boo) != inlog)
+ printf("PMLC_GET_INLOG botch: %d (got) != %d (expect)\n",
+ PMLC_GET_INLOG(boo), inlog);
+ state = (inlog << 3) | (avail << 2) | (mand << 1) | on;
+ if (PMLC_GET_STATE(boo) != state)
+ printf("PMLC_GET_STATE botch: %d (got) != %d (expect)\n",
+ PMLC_GET_STATE(boo), state);
+ PMLC_SET_STATE(boo, state);
+ if ((boo & 0xfffffff0) != 0x96969690)
+ printf("high-order bit botch: 0x%x (got) != 0x%x (expect)\n",
+ boo & 0xfffffff0, 0x96969690);
+ }
+ }
+ }
+ }
+ exit(0);
+}
diff --git a/qa/src/pmnsinarchives.c b/qa/src/pmnsinarchives.c
new file mode 100644
index 0000000..8712566
--- /dev/null
+++ b/qa/src/pmnsinarchives.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * main - test the code which adds PMNS to archives
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+void
+parse_args(int argc, char **argv)
+{
+ extern char *optarg;
+ extern int optind;
+ int errflag = 0;
+ int c;
+ int sts;
+ static char *usage = "[-v]";
+
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N]";
+#else
+ static char *debug = "";
+#endif
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:?")) != EOF) {
+ switch (c) {
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+
+}
+
+typedef struct {
+ char *name;
+ pmID pmid;
+}Metric;
+
+static Metric metric_list[] = {
+ {"abc.def.ghi", 100},
+ {"abc.def.jkl", 200},
+ {"abc.mno", 300},
+ {"pqr.rst.uvw", 400},
+ {"pqr.xyz", 500}
+};
+static char *parents[] = {
+ "abc", "pqr", "abc.def", "def", "abc.def.ghi"
+};
+
+const int num_metrics = sizeof(metric_list) / sizeof(Metric);
+const int num_parents = sizeof(parents) / sizeof(char*);
+
+int
+main(int argc, char **argv)
+{
+ int sts = 0;
+ int i = 0;
+ __pmnsTree *pmns = NULL;
+
+ parse_args(argc, argv);
+
+
+ printf("\n*** Build up the PMNS from metrics... ***\n");
+ printf("Number of metrics = %d\n", num_metrics);
+
+ if ((sts = __pmNewPMNS(&pmns)) < 0) {
+ fprintf(stderr, "%s: __pmNewPMNS: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ for(i = 0; i < num_metrics; i++) {
+ pmID pmid = metric_list[i].pmid;
+ char *name = metric_list[i].name;
+ sts = __pmAddPMNSNode(pmns, pmid, name);
+ printf("Adding node: \"%s\"[%d]\n", name, pmid);
+ if (sts < 0) {
+ fprintf(stderr, "%s: __pmAddPMNSNode: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ if ((sts = __pmFixPMNSHashTab(pmns, num_metrics, 1)) < 0) {
+ fprintf(stderr, "%s: __pmFixPMNSHashTab: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ __pmUsePMNS(pmns);
+
+
+ printf("\n*** Check PMNS is ok ***\n");
+
+ printf("\n--- Dump out PMNS ---\n");
+ __pmDumpNameSpace(stdout, 1);
+
+ printf("\n--- Test out pmLookupName ---\n");
+ for(i = 0; i < num_metrics; i++) {
+ pmID pmid = metric_list[i].pmid;
+ char *name = metric_list[i].name;
+ pmID thepmid = 0;
+
+ if ((sts = pmLookupName(1, &name, &thepmid)) < 0) {
+ fprintf(stderr, "%s: _pmLookupName: %s\n",
+ pmProgname, pmErrStr(sts));
+ }
+ if (thepmid == pmid) {
+ printf("%d matches for name lookup\n", pmid);
+ }
+ else {
+ printf("%d does not match with %d\n", pmid, thepmid);
+ }
+ }
+
+ printf("\n--- Test out pmNameID for matches ---\n");
+ for(i = 0; i < num_metrics; i++) {
+ pmID pmid = metric_list[i].pmid;
+ char *name = metric_list[i].name;
+ char *thename = NULL;
+
+ if ((sts = pmNameID(pmid, &thename)) < 0) {
+ fprintf(stderr, "%s: _pmNameID: %s\n",
+ pmProgname, pmErrStr(sts));
+ }
+ if (strcmp(name, thename) == 0) {
+ printf("%s matches for id lookup\n", name);
+ }
+ else {
+ printf("%s does not match with %s\n", name, thename);
+ }
+ }
+
+ printf("\n--- Test out pmGetChildren ---\n");
+ for (i = 0; i < num_parents; i++) {
+ char *parent = parents[i];
+ int num_childs = 0;
+ int j;
+ char **offspring = NULL;
+
+ printf("Children of %s:\n", parent);
+ if ((sts = pmGetChildren(parent, &offspring)) < 0) {
+ fprintf(stderr, "%s: _pmGetChildren: %s\n",
+ pmProgname, pmErrStr(sts));
+ }
+ num_childs = sts;
+ for (j = 0; j < num_childs; j++) {
+ printf(" %s\n", offspring[j]);
+ }
+ }/*for*/
+
+ exit(0);
+}
diff --git a/qa/src/pmnsunload.c b/qa/src/pmnsunload.c
new file mode 100644
index 0000000..4400ef9
--- /dev/null
+++ b/qa/src/pmnsunload.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * check open/close archive for mem leaks
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#include "localconfig.h"
+
+static int vflag;
+static int tflag;
+
+void
+do_PMNS_op(char *msg)
+{
+ int sts;
+ char *name = "pmcd.control.debug";
+ pmID pmid;
+
+ printf("---%s---\n", msg);
+ printf("PMNS location = %d\n", pmGetPMNSLocation());
+ if ((sts = pmLookupName(1, &name, &pmid)) < 0) {
+ fprintf(stderr, "%s: lookup failed: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *archive = "foo";
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+ static char *usage = "[-D N] [-L] [-h host] [-a archive] [-n namespace] [-v] [-i iterations]";
+ int niter=100;
+ int i;
+ int contype = PM_CONTEXT_HOST;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "Li:h:a:D:n:tv")) != EOF) {
+ switch (c) {
+
+ case 'i': /* iterations */
+ niter = atoi(optarg);
+ break;
+ case 'L': /* local */
+ contype = PM_CONTEXT_LOCAL;
+ break;
+ case 'h': /* host */
+ host = optarg;
+ contype = PM_CONTEXT_HOST;
+ break;
+
+ case 'a': /* archive */
+ archive = optarg;
+ contype = PM_CONTEXT_ARCHIVE;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'v': /* verbose output */
+ vflag++;
+ break;
+
+ case 't': /* trim namespace */
+ tflag++;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ switch (contype) {
+ case PM_CONTEXT_LOCAL:
+ if ((sts = pmNewContext(PM_CONTEXT_LOCAL, NULL)) < 0) {
+ printf("%s: Cannot create local context: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ break;
+ case PM_CONTEXT_ARCHIVE:
+ if ((sts = pmNewContext(PM_CONTEXT_ARCHIVE, archive)) < 0) {
+ printf("%s: Cannot connect to archive \"%s\": %s\n", pmProgname, archive, pmErrStr(sts));
+ exit(1);
+ }
+ break;
+ case PM_CONTEXT_HOST:
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ printf("%s: Cannot connect to host \"%s\": %s\n", pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+ break;
+ }
+
+ for (i=0; i < niter; i++) {
+ printf("***iteration %d***\n", i);
+ do_PMNS_op("pre-unload");
+ pmUnloadNameSpace();
+ do_PMNS_op("post-unload");
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ do_PMNS_op("post-load");
+ }
+ pmUnloadNameSpace();
+
+ (void)pmDestroyContext(pmWhichContext());
+
+#if PCP_VER >= 3611
+ __pmShutdown();
+#endif
+
+ exit(0);
+}
+
diff --git a/qa/src/pmprintf.c b/qa/src/pmprintf.c
new file mode 100644
index 0000000..b00a86c
--- /dev/null
+++ b/qa/src/pmprintf.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pcp/pmapi.h>
+
+int
+main(int argc, char *argv[])
+{
+ int sts, i;
+ int fd;
+
+ if (argc < 2) {
+ fprintf(stderr, "Bad pmprintf invocation (need more args)\n");
+ exit(1);
+ }
+
+ /*
+ * Some stdio environments start with strange fd's open ... close
+ * 'em all to give us some breathing space
+ */
+ for (fd = 3; fd < 100; fd++)
+ close(fd);
+
+ /*
+ * for testing #634665 it helps to have a couple of extra
+ * open files ... see qa/505
+ * ProPack 2.2 increased this to need 5 extra ones
+ */
+ (void)open("/dev/null", O_RDONLY);
+ (void)open("/dev/null", O_RDONLY);
+ (void)open("/dev/null", O_RDONLY);
+ (void)open("/dev/null", O_RDONLY);
+ (void)open("/dev/null", O_RDONLY);
+ (void)open("/dev/null", O_RDONLY);
+ (void)open("/dev/null", O_RDONLY);
+
+ for (i = 1; i < argc; i++) {
+ if ((sts = pmprintf("%s ", argv[i])) < 0) {
+ fprintf(stderr, "pmprintf: %s\n", pmErrStr(sts));
+ }
+ }
+
+ pmprintf("\n");
+ pmflush();
+ exit(0);
+}
diff --git a/qa/src/pmsocks_objstyle.c b/qa/src/pmsocks_objstyle.c
new file mode 100644
index 0000000..2ce8cc9
--- /dev/null
+++ b/qa/src/pmsocks_objstyle.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <unistd.h>
+#include <limits.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ char *host = NULL; /* pander to gcc */
+ int mode = PM_MODE_INTERP; /* mode for archives */
+ char *start = NULL;
+ char *finish = NULL;
+ char *align = NULL;
+ char *offset = NULL;
+ char *logfile = NULL;
+ pmLogLabel label; /* get hostname for archives */
+ int zflag = 0; /* for -z */
+ char *tz = NULL; /* for -Z timezone */
+ int tzh; /* initial timezone handle */
+ char local[MAXHOSTNAMELEN];
+ char *pmnsfile = PM_NS_DEFAULT;
+ char *endnum;
+ struct timeval startTime;
+ struct timeval endTime;
+ struct timeval appStart;
+ struct timeval appEnd;
+ struct timeval appOffset;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:h:?")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (zflag && type == 0) {
+ fprintf(stderr, "%s: -z requires an explicit -a, -h or -U option\n", pmProgname);
+ errflag++;
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -D debug standard PCP debug flag\n\
+ -h host metrics source is PMCD on host\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (logfile != NULL) {
+ __pmOpenLog(pmProgname, logfile, stderr, &sts);
+ if (sts < 0) {
+ fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmProgname, logfile);
+ }
+ }
+
+ if (pmnsfile != PM_NS_DEFAULT && (sts = pmLoadNameSpace(pmnsfile)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname,
+ pmnsfile, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if (mode != PM_MODE_INTERP) {
+ if ((sts = pmSetMode(mode, &label.ll_start, 0)) < 0) {
+ fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ startTime = label.ll_start;
+ sts = pmGetArchiveEnd(&endTime);
+ if (sts < 0) {
+ fprintf(stderr, "%s: pmGetArchiveEnd: %s\n", pmProgname,
+ pmErrStr(sts));
+ exit(1);
+ }
+ }
+ else {
+ gettimeofday(&startTime, NULL);
+ endTime.tv_sec = INT_MAX;
+ }
+
+ if (zflag) {
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+ if (type == PM_CONTEXT_ARCHIVE)
+ printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n",
+ label.ll_hostname);
+ else
+ printf("Note: timezone set to local timezone of host \"%s\"\n\n", host);
+ }
+ else if (tz != NULL) {
+ if ((tzh = pmNewZone(tz)) < 0) {
+ fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n",
+ pmProgname, tz, pmErrStr(tzh));
+ exit(1);
+ }
+ printf("Note: timezone set to \"TZ=%s\"\n\n", tz);
+ }
+ else
+ tzh = pmNewContextZone();
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ while (optind < argc) {
+ printf("extra argument[%d]: %s\n", optind, argv[optind]);
+ optind++;
+ }
+
+ if (align != NULL && type != PM_CONTEXT_ARCHIVE) {
+ fprintf(stderr, "%s: -A option only supported for PCP archives, alignment request ignored\n",
+ pmProgname);
+ align = NULL;
+ }
+
+ sts = pmParseTimeWindow(start, finish, align, offset, &startTime,
+ &endTime, &appStart, &appEnd, &appOffset,
+ &endnum);
+
+ if (sts < 0) {
+ fprintf(stderr, "%s: %s\n", pmProgname, endnum);
+ exit(1);
+ }
+
+ pmDestroyContext(pmWhichContext());
+ return 0;
+}
diff --git a/qa/src/proc.0 b/qa/src/proc.0
new file mode 100644
index 0000000..55cb74b
--- /dev/null
+++ b/qa/src/proc.0
Binary files differ
diff --git a/qa/src/proc.index b/qa/src/proc.index
new file mode 100644
index 0000000..fe2bc6f
--- /dev/null
+++ b/qa/src/proc.index
Binary files differ
diff --git a/qa/src/proc.meta b/qa/src/proc.meta
new file mode 100644
index 0000000..ff17655
--- /dev/null
+++ b/qa/src/proc.meta
Binary files differ
diff --git a/qa/src/proc_test.c b/qa/src/proc_test.c
new file mode 100644
index 0000000..a8a5ec1
--- /dev/null
+++ b/qa/src/proc_test.c
@@ -0,0 +1,624 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * Test Plan
+ * ---------
+ *
+ * 0. Agent has associated PMNS, testable say thru PMNS functions.
+ *
+ * Test the agent exported functions using the PMAPI:
+ * (We could call the agent functions directly but we might as well test
+ * that the whole package is working - i.e. communication via pmcd).
+ *
+ * 1. proc_desc - pmGetDesc
+ * 2. proc_text - pmLookupText, pmLookupInDomText
+ * 3. proc_instance - pmGetInDom, pmNameInDom, pmLookupInDom
+ * 4. proc_profile - pmAddProfile, pmDelProfile
+ * 5. proc_fetch - pmFetch
+ * 6. proc_store - pmStore
+ *
+ * Not used: proc_control
+ *
+ *
+ * Method
+ * ------
+ *
+ * 1. desc
+ * a. Test that all specified metrics can have their desc retrieved without error
+ * b. Test that all spec. metrics have the same indom.
+ * Note: ideally we would want to make sure that all the desc values returned are
+ * correct but that means basically just duplicating the agent's code.
+ *
+ * 3. instance
+ * a. Output the instance map, name-->inst, inst-->name
+ * This output can be tested by a script to look for certain
+ * processes.
+ * b. Verify that names and ids are consistent with each other.
+ *
+ * 4.5. profile/fetch
+ * a. Profile is set correctly - look at context dump
+ * b. Fetch on profile and ensure that the results only have the specified
+ * instances.
+ * Note: ideally we would to ensure that the values returned are correct.
+ * This, however, would be a tricky thing for a lot of metrics.
+ * The metrics are continually changing for the processes.
+ *
+ * 6. store
+ * a. Ensure it fails appropriately.
+ *
+ * TODO
+ * ----
+ * 0, 2,
+ *
+ */
+
+#include <ctype.h>
+#include <sys/wait.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#ifdef HAVE_PROCFS
+#ifdef IS_NETBSD
+#include <miscfs/procfs/procfs.h>
+#else
+#include <sys/procfs.h>
+#endif
+
+#define MAXMETRICS 1024
+
+int verbose = 0;
+char *host = "localhost";
+char *pmnsfile = PM_NS_DEFAULT;
+int nmetrics;
+char *metrics[MAXMETRICS];
+pmID pmids[MAXMETRICS];
+pmInDom indom;
+int iterations = 1;
+int all_n;
+int *all_inst;
+char **all_names;
+pid_t child_pid;
+int is_hotproc = 0;
+int refresh = 1;
+
+/* format of an entry in /proc */
+char proc_fmt[8]; /* export for procfs fname conversions */
+
+
+/*
+ * getargs
+ */
+
+void
+getargs(int argc, char **argv)
+{
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N]";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = " [-h hostname] [-n pmnsfile] "
+ "[-i iterations] [-t refresh] [-v] "
+ "metric [metric ...]";
+ int errflag = 0;
+ char *endnum;
+ int c;
+ int i;
+ int sts;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:h:n:i:t:v")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ host = optarg;
+ break;
+
+ case 'i': /* iterations */
+ iterations = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: -i requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'n': /* alternative name space file */
+ pmnsfile = optarg;
+ break;
+
+ case 't':
+ refresh = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ fprintf(stderr, "%s: -t requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'v':
+ verbose = 1;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+USAGE:
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ if (optind >= argc)
+ goto USAGE;
+
+ /* note metrics and dump them out */
+ for (i = 0; i < argc - optind; i++) {
+ metrics[i] = argv[optind+i];
+ if (strncmp(metrics[i], "hotproc.", 8) == 0) {
+ if (i > 0 && !is_hotproc) {
+ printf("%s: Error: all metrics should be from same agent\n",
+ pmProgname);
+ exit(1);
+ }
+ is_hotproc = 1;
+ }
+ else if (strncmp(metrics[i], "proc.", 5) == 0) {
+ if (i > 0 && is_hotproc) {
+ printf("%s: Error: all metrics should be from same agent\n",
+ pmProgname);
+ exit(1);
+ }
+ is_hotproc = 0;
+ }
+ else {
+ printf("%s: Error: all metrics should be from "
+ "proc or hotproc agent: %s\n", pmProgname, metrics[i]);
+ exit(1);
+ }
+ printf("metrics[%d] = <%s>\n", i, metrics[i]);
+ }
+ nmetrics = i;
+
+ if (nmetrics <= 0)
+ goto USAGE;
+}
+
+
+void
+print_banner_start(char *msg)
+{
+ int len = strlen(msg);
+ int i;
+
+ printf("\n");
+ for (i = 0; i < len+14; i++) printf("=");
+ printf("\n");
+ printf("=== Test: %s ===\n", msg);
+ for (i = 0; i < len+14; i++) printf("=");
+ printf("\n");
+
+}
+
+void
+print_banner_end(char *msg)
+{
+ int len = strlen(msg);
+ int i;
+
+ printf("\n");
+ for (i = 0; i < len+21; i++) printf("=");
+ printf("\n");
+ printf("=== End Of Test: %s ===\n", msg);
+ for (i = 0; i < len+21; i++) printf("=");
+ printf("\n");
+
+}
+
+static void
+set_proc_fmt(void)
+{
+ DIR *procdir;
+ const char *procfs = "/proc";
+ struct dirent *directp;
+ int ndigit;
+ int proc_entry_len; /* number of chars in procfs entry */
+
+ if ((procdir = opendir(procfs)) == NULL) {
+ perror(procfs);
+ return;
+ }
+ proc_entry_len = -1;
+ for (rewinddir(procdir); (directp = readdir(procdir));) {
+ if (!isdigit((int)directp->d_name[0]))
+ continue;
+ ndigit = (int)strlen(directp->d_name);
+ if (proc_entry_len == -1) {
+ proc_entry_len = ndigit;
+ sprintf(proc_fmt, "%%0%dd", proc_entry_len);
+ }
+ else if (ndigit != proc_entry_len) {
+ /*
+ * different lengths, so not fixed width ... this is the
+ * Linux way
+ */
+ sprintf(proc_fmt, "%%d");
+ break;
+ }
+ }
+ closedir(procdir);
+}
+
+/*
+ * 0.
+ * Does NOT really verify PMNS
+ * get pmids for rest of pm functions
+ */
+void
+test_PMNS(void)
+{
+ int sts;
+ int i;
+
+ print_banner_start("PMNS");
+ if ((sts = pmLookupName(nmetrics, metrics, pmids)) < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(sts));
+ for (i = 0; i < nmetrics; i++) {
+ if (pmids[i] == PM_ID_NULL)
+ printf(" %s - not known\n", metrics[i]);
+ }
+ exit(1);
+ }
+ print_banner_end("PMNS");
+
+}
+
+/*
+ * 1. check all the descriptors
+ */
+void
+test_desc(void)
+{
+ int sts;
+ int i;
+ pmDesc desc;
+
+ print_banner_start("desc");
+
+ /* test if possible to get one of them and get its indom */
+ if ((sts = pmLookupDesc(pmids[0], &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc: %s\n", pmErrStr(sts));
+ fprintf(stderr, "Associated metric = %s (%s)\n", metrics[0], pmIDStr(pmids[0]));
+ exit(1);
+ }
+ indom = desc.indom;
+ for (i=0; i < nmetrics; i++) {
+ if ((sts = pmLookupDesc(pmids[i], &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc: %s\n", pmErrStr(sts));
+ fprintf(stderr, "Associated metric = %s (%s)\n", metrics[i], pmIDStr(pmids[i]));
+ exit(1);
+ }
+ if (desc.indom != indom) {
+ fprintf(stderr, "metric <%s> has indom = %d, different to metric <%s> indom = %d\n",
+ metrics[i], desc.indom, metrics[0], indom);
+ fprintf(stderr, "This test requires all metrics have the same indom\n");
+ exit(1);
+ }
+ }
+
+ print_banner_end("desc");
+
+}
+
+
+/*
+ * 3.
+ * Test out proc_instance
+ * Using pmGetInDom(), pmNameInDom(), pmLookupInDom()
+ * Now get metrics for the entire instance domain
+ *
+ * Does some sanity checks on names and ids
+ */
+
+void
+test_instance(void)
+{
+ int sts;
+ int i;
+
+ print_banner_start("instance");
+ if (indom == PM_INDOM_NULL)
+ return;
+
+ fflush(stdout);
+ if ((child_pid=fork()) == 0) {
+ /* child sleeps and then exits */
+ sleep(2*refresh+1);
+ exit(0);
+ }
+ printf("cpid=%" FMT_PID "\n", child_pid);
+
+ if (is_hotproc) {
+ /* sleep so that hotprocs can update active list */
+ sleep(2*refresh);
+ }
+ printf("\n--- GetInDom ---\n");
+ sts = pmGetInDom(indom, &all_inst, &all_names);
+ if (sts < 0) {
+ printf("%s: pmGetInDom: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ else
+ all_n = sts;
+
+ /* print the instance id's (i.e. pids) match the first field in the name */
+ for (i=0; i < all_n; i++) {
+ int inst;
+ if (verbose)
+ printf(" instance map [%d \"%s\"]\n", all_inst[i], all_names[i]);
+
+ /* e.g. inst=0, name="00000 sched" */
+ if (sscanf(all_names[i], proc_fmt, &inst) != 1) {
+ printf("%s: Error: cannot get PID from instname\n", pmProgname);
+ printf("%s: <id,name> = <%ld,\"%s\">\n", pmProgname,
+ (long)all_inst[i], all_names[i]);
+ exit(1);
+ }
+ if (inst != all_inst[i]) {
+ printf("%s: Error: instname is wrong\n", pmProgname);
+ printf("%s: <id,name> = <%ld,\"%s\"> != %d (fmt=%s)\n", pmProgname,
+ (long)all_inst[i], all_names[i], inst, proc_fmt);
+ exit(1);
+ }
+ }
+
+ /* parent waits for child to exit */
+ /* so that the the following lookups will NOT be able to find it */
+ wait(&sts);
+
+
+ printf("\n--- LookupInDom ---\n");
+ for (i = 0; i < all_n; i++) {
+ int inst, x;
+ sts = pmLookupInDom(indom, all_names[i]);
+ if (sts < 0) {
+ if (sts == PM_ERR_INST) {
+ if (all_inst[i] == child_pid)
+ printf(" Death of child detected, pid=%" FMT_PID "\n", child_pid);
+ /* ignore deaths */
+ continue;
+ }
+ else {
+ printf("%s: pmLookupInDom: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ inst = sts;
+ if (verbose)
+ printf(" instance lookup \"%s\" --> %d\n", all_names[i], inst);
+ sscanf(all_names[i], proc_fmt, &x);
+ if (x != inst) {
+ printf("%s: Error: inst is wrong, expect: %d got: %d\n",
+ pmProgname, inst, x);
+ printf("%s: Expected=%d, Actual=%d\n", pmProgname, x, inst);
+ exit(1);
+ }
+ }/*for*/
+
+ printf("\n--- NameInDom ---\n");
+ for (i = 0; i < all_n; i++) {
+ char *name;
+ char x[100];
+
+ sts = pmNameInDom(indom, all_inst[i], &name);
+ if (sts < 0) {
+ if (sts == PM_ERR_INST) {
+ if (all_inst[i] == child_pid)
+ printf(" Death of child detected\n");
+ /* ignore deaths */
+ continue;
+ }
+ else {
+ printf("%s: pmNameInDom: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ if (verbose)
+ printf(" instance name %d --> \"%s\"\n", all_inst[i], name);
+ sprintf(x, proc_fmt, all_inst[i]);
+ if (strncmp(name, x, strlen(x)) != 0 ||
+ (name[strlen(x)] != '\0' && name[strlen(x)] != ' ')) {
+ /* try w/out leading zeroes */
+ char *q;
+ sprintf(x, "%d", all_inst[i]);
+ for (q = name; *q && *q == '0'; q++)
+ ;
+ if (strncmp(q, x, strlen(x)) != 0 ||
+ (q[strlen(x)] != '\0' && q[strlen(x)] != ' ')) {
+ printf("%s: Error: name is wrong\n", pmProgname);
+ printf("%s: Expected=\"%s\", Actual=\"%s\"\n", pmProgname, x, name);
+ exit(1);
+ }
+ }
+ free(name);
+ }/*for*/
+
+ print_banner_end("instance");
+}
+
+
+/*
+ * Tests 4. and 5.
+ * Set up an explicit profile of ourself and our parent
+ * If any of the metrics are not in the proc indom, we'll get no values back.
+ * Checks if profile is being handled correctly.
+ * Checks if fetch is using profile correctly.
+ */
+void
+test_prof_fetch(void)
+{
+ int sts;
+ int i;
+ int pids[2];
+ pmResult *result1, *result2;
+
+ print_banner_start("profile/fetch");
+
+ pids[0] = (int)getpid();
+ pids[1] = (int)getppid();
+ pmDelProfile(indom, 0, NULL);
+ pmAddProfile(indom, 2, pids);
+
+ printf("\n--- Check profile in context dump... ---\n");
+ if ((sts = pmWhichContext()) < 0) {
+ printf("%s: pmWhichContext: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ __pmDumpContext(stdout, sts, PM_INDOM_NULL);
+ printf("--- End Check profile in context dump... ---\n");
+
+ printf("\n--- Fetch Over Restricted Instance Domain ... ---\n");
+ for (i=0; i < iterations; i++) {
+ int j,k;
+
+ sts = pmFetch(nmetrics, pmids, &result1);
+ if (sts < 0) {
+ printf("%s: iteration %d : %s\n", pmProgname, i, pmErrStr(sts));
+ exit(1);
+ }
+ __pmDumpResult(stdout, result1);
+
+
+ for (j = 0; j < result1->numpmid; j++) {
+ pmValueSet *set = result1->vset[j];
+
+ if (set->numval != 2) {
+ printf("%s: Error: num of inst == %d\n", pmProgname, set->numval);
+ }
+
+ for (k = 0; k < set->numval; k++) {
+ pmValue *val = &set->vlist[k];
+ if (val->inst != pids[0] && val->inst != pids[1]) {
+ printf("%s: Error: inst ids do not match pids\n", pmProgname);
+ exit(1);
+ }
+ }
+ }
+
+ pmFreeResult(result1);
+ }
+ printf("--- End Fetch Over Restricted Instance Domain ... ---\n");
+
+
+
+ printf("\n--- Fetch Over Entire Instance Domain ... ---\n");
+ if (indom != PM_INDOM_NULL) {
+ pmDelProfile(indom, 0, NULL);
+ pmAddProfile(indom, all_n, all_inst);
+ }
+ sts = pmFetch(nmetrics, pmids, &result2);
+ if (sts < 0) {
+ printf("%s: fetch all %d instances : %s\n", pmProgname, all_n, pmErrStr(sts));
+ exit(1);
+ }
+ __pmDumpResult(stdout, result2);
+ pmFreeResult(result2);
+ printf("--- End Fetch Over Entire Instance Domain ... ---\n");
+
+ print_banner_end("profile/fetch");
+
+}
+
+void
+test_store(void)
+{
+ int sts;
+ pmResult *result;
+
+ print_banner_start("store");
+
+ sts = pmFetch(nmetrics, pmids, &result);
+ if (sts < 0) {
+ printf("%s: fetch failed : %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmStore(result)) != -EACCES && sts != PM_ERR_PERMISSION) {
+ printf("%s: Error: pmStore did not fail correctly\n", pmProgname);
+ printf("Expected: %s\n", pmErrStr(-EACCES));
+ printf("or: %s\n", pmErrStr(PM_ERR_PERMISSION));
+ printf("Got: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ pmFreeResult(result);
+
+ print_banner_end("store");
+}
+
+/*
+ * main
+ */
+int
+main(int argc, char **argv)
+{
+ int sts;
+
+ set_proc_fmt();
+ printf("pid=%" FMT_PID " ppid=%" FMT_PID "\n", getpid(), getppid());
+ getargs(argc, argv);
+
+ if (pmnsfile != PM_NS_DEFAULT) {
+ if ((sts = pmLoadNameSpace(pmnsfile)) < 0) {
+ printf("%s: Cannot load pmnsfile from \"%s\": %s\n",
+ pmProgname, pmnsfile, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ test_PMNS();
+ test_desc();
+ test_instance();
+ test_prof_fetch();
+ if (!is_hotproc)
+ test_store();
+
+ if ((sts = pmWhichContext()) < 0) {
+ printf("%s: pmWhichContext: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ pmDestroyContext(sts);
+
+ exit(0);
+}
+#else
+int
+main(int argc, char **argv)
+{
+ printf("No /proc pseudo filesystem on this platform\n");
+ exit(1);
+}
+#endif /* HAVE_PROCFS */
diff --git a/qa/src/pthread_barrier.h b/qa/src/pthread_barrier.h
new file mode 100644
index 0000000..a01028e
--- /dev/null
+++ b/qa/src/pthread_barrier.h
@@ -0,0 +1,86 @@
+/*
+ * pthread_barrier code if libpthread does not have it ...
+ *
+ * Original code from Brent Priddy's code fragment at
+ * http://stackoverflow.com/questions/3640853
+ *
+ * Copyright (c) 2010 Brent Priddy.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+typedef int pthread_barrierattr_t;
+typedef struct
+{
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int count;
+ int tripCount;
+} pthread_barrier_t;
+
+
+int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
+{
+ if(count == 0)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ if(pthread_mutex_init(&barrier->mutex, 0) < 0)
+ {
+ return -1;
+ }
+ if(pthread_cond_init(&barrier->cond, 0) < 0)
+ {
+ pthread_mutex_destroy(&barrier->mutex);
+ return -1;
+ }
+ barrier->tripCount = count;
+ barrier->count = 0;
+
+ return 0;
+}
+
+int pthread_barrier_destroy(pthread_barrier_t *barrier)
+{
+ pthread_cond_destroy(&barrier->cond);
+ pthread_mutex_destroy(&barrier->mutex);
+ return 0;
+}
+
+int pthread_barrier_wait(pthread_barrier_t *barrier)
+{
+ pthread_mutex_lock(&barrier->mutex);
+ ++(barrier->count);
+ if(barrier->count >= barrier->tripCount)
+ {
+ barrier->count = 0;
+ pthread_cond_broadcast(&barrier->cond);
+ pthread_mutex_unlock(&barrier->mutex);
+ return 1;
+ }
+ else
+ {
+ pthread_cond_wait(&barrier->cond, &(barrier->mutex));
+ pthread_mutex_unlock(&barrier->mutex);
+ return 0;
+ }
+}
diff --git a/qa/src/pv.c b/qa/src/pv.c
new file mode 100644
index 0000000..a290aa7
--- /dev/null
+++ b/qa/src/pv.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "pcp/pmapi.h"
+
+/*
+ * exercise pmPrintValue() ... should produce very similar answers
+ * when compiled both 32 and 64 bit ... see pv and pv64 targets in
+ * the Makefile
+ */
+
+int
+main(void)
+{
+ pmValue v;
+ int l;
+ unsigned int ul;
+ long long ll;
+ unsigned long long ull;
+ float f;
+ float *fp;
+ double d;
+ struct {
+ int len;
+ char vbuf[sizeof(double)];
+ } vb;
+
+ v.inst = 1;
+
+ l = -1 & (~0xffff);
+ memcpy((void *)&v.value.lval, (void *)&l, sizeof(l));
+ printf("PM_TYPE_32: ");
+ pmPrintValue(stdout, PM_VAL_INSITU, PM_TYPE_32, &v, 1);
+ printf(" correct: %i (0x%x)\n", l, l);
+
+ ul = 0x87654321;
+ memcpy((void *)&v.value.lval, (void *)&ul, sizeof(ul));
+ printf("PM_TYPE_U32: ");
+ pmPrintValue(stdout, PM_VAL_INSITU, PM_TYPE_U32, &v, 1);
+ printf(" correct: %u (0x%x)\n", ul, ul);
+
+ f = 123456.78;
+ fp = (float *)&v.value.lval;
+ *fp = f;
+ printf("PM_TYPE_FLOAT: ");
+ pmPrintValue(stdout, PM_VAL_INSITU, PM_TYPE_FLOAT, &v, 9);
+ printf(" correct: %.2f\n", (double)f);
+
+ d = 123456.789012345;
+ memcpy((void *)vb.vbuf, (void *)&d, sizeof(double));
+ vb.len = sizeof(vb.len) + sizeof(double);
+ v.value.pval = (pmValueBlock *)&vb;
+ printf("PM_TYPE_DOUBLE: ");
+ pmPrintValue(stdout, PM_VAL_SPTR, PM_TYPE_DOUBLE, &v, 16);
+ printf(" correct: %.9f\n", d);
+
+ ll = -1 & (~0xffff);
+ memcpy((void *)vb.vbuf, (void *)&ll, sizeof(long long));
+ vb.len = sizeof(vb.len) + sizeof(long long);
+ v.value.pval = (pmValueBlock *)&vb;
+ printf("PM_TYPE_64: ");
+ pmPrintValue(stdout, PM_VAL_SPTR, PM_TYPE_64, &v, 1);
+ printf(" correct: %lli (0x%llx)\n", ll, ll);
+
+ ull = 0x8765432112340000LL;
+ memcpy((void *)vb.vbuf, (void *)&ull, sizeof(unsigned long long));
+ vb.len = sizeof(vb.len) + sizeof(unsigned long long);
+ v.value.pval = (pmValueBlock *)&vb;
+ printf("PM_TYPE_U64: ");
+ pmPrintValue(stdout, PM_VAL_SPTR, PM_TYPE_U64, &v, 1);
+ printf(" correct: %llu (0x%llx)\n", ull, ull);
+
+ exit(0);
+}
diff --git a/qa/src/pyapi.0 b/qa/src/pyapi.0
new file mode 100644
index 0000000..eb76a2b
--- /dev/null
+++ b/qa/src/pyapi.0
Binary files differ
diff --git a/qa/src/pyapi.index b/qa/src/pyapi.index
new file mode 100644
index 0000000..5bcebf9
--- /dev/null
+++ b/qa/src/pyapi.index
Binary files differ
diff --git a/qa/src/pyapi.meta b/qa/src/pyapi.meta
new file mode 100644
index 0000000..ae4ff59
--- /dev/null
+++ b/qa/src/pyapi.meta
Binary files differ
diff --git a/qa/src/qa_test.c b/qa/src/qa_test.c
new file mode 100644
index 0000000..8c0305d
--- /dev/null
+++ b/qa/src/qa_test.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+
+main(int argc, char *argv[]) {
+ printf("This program does nothing, and wastes a lot of space doing it!\n");
+ exit(0);
+}
diff --git a/qa/src/qa_timezone.c b/qa/src/qa_timezone.c
new file mode 100644
index 0000000..a9c46a1
--- /dev/null
+++ b/qa/src/qa_timezone.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2009 Ken McDonell. All Rights Reserved.
+ *
+ * Based on from tz.c in libpcp/src ... use $PCPQA_TZ not $TZ and
+ * no squashing and default is EST-10 for everyone ... 8^)>
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#if !defined(HAVE_UNDERBAR_ENVIRON)
+#define _environ environ
+#endif
+
+extern char **_environ;
+
+/*
+ * __pmTimezone: work out local timezone
+ */
+char *
+__pmTimezone(void)
+{
+ char *tz = getenv("PCPQA_TZ");
+
+ if (tz == NULL) {
+ fprintf(stderr, "__pmTimezone: BOZO $PCPQA_TZ not set, using EST-10\n");
+ tz = strdup("EST-10");
+ }
+ if (strlen(tz) > PM_TZ_MAXLEN) {
+ fprintf(stderr, "__pmTimezone: BOZO $PCPQA_TZ (%s) must be shorter than %d chars!\n", tz, PM_TZ_MAXLEN);
+ tz[PM_TZ_MAXLEN-1] = '\0';
+ }
+
+ fprintf(stderr, "Burglar alert tz=%s\n", tz);
+
+ return tz;
+}
diff --git a/qa/src/rattle.0 b/qa/src/rattle.0
new file mode 100644
index 0000000..194a1c4
--- /dev/null
+++ b/qa/src/rattle.0
Binary files differ
diff --git a/qa/src/rattle.index b/qa/src/rattle.index
new file mode 100644
index 0000000..8bbc452
--- /dev/null
+++ b/qa/src/rattle.index
Binary files differ
diff --git a/qa/src/rattle.meta b/qa/src/rattle.meta
new file mode 100644
index 0000000..0fcf3f0
--- /dev/null
+++ b/qa/src/rattle.meta
Binary files differ
diff --git a/qa/src/read-bf.c b/qa/src/read-bf.c
new file mode 100644
index 0000000..31ac173
--- /dev/null
+++ b/qa/src/read-bf.c
@@ -0,0 +1,106 @@
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+typedef struct {
+ unsigned int a:16;
+ unsigned int b:7;
+ unsigned int c:3;
+ unsigned int d:3;
+ unsigned int e:3;
+ unsigned int f:4;
+ unsigned int g:12;
+} ext_bits_t;
+
+typedef struct {
+ unsigned int a:16;
+ unsigned int b:7;
+ unsigned int c:3;
+ unsigned int d:3;
+ unsigned int e:3;
+ unsigned int f:4;
+ unsigned int g:12;
+} bits_t;
+
+bits_t outbits = { 0xdead, 0x5f, 0x3, 0x5, 0x7, 0xc, 0xafe };
+
+int
+main(int argc, char *argv[])
+{
+ bits_t inbits;
+ ext_bits_t extbits;
+ __uint32_t *ip;
+ int i;
+ int sts;
+
+ fprintf(stderr, "sizeof(bits_t): %d\n", (int)sizeof(bits_t));
+
+ if (strcmp(basename(argv[0]), "read-bf") == 0) {
+ sts = read(0, &extbits, sizeof(ext_bits_t));
+ if (sts != sizeof(ext_bits_t)) {
+ fprintf(stderr, "read() returns %d not %d as expected\n", sts, (int)sizeof(ext_bits_t));
+ exit(1);
+ }
+
+ fprintf(stderr, "read: ");
+ for (i = 0, ip = (__uint32_t *)&extbits; i < sizeof(ext_bits_t); i += sizeof(*ip), ip++)
+ fprintf(stderr, " %08x", *ip);
+ fputc('\n', stderr);
+
+ /*
+ * swap bytes, then assign fields
+ */
+ for (i = 0, ip = (__uint32_t *)&extbits; i < sizeof(ext_bits_t); i += sizeof(*ip), ip++)
+ *ip = ntohl(*ip);
+
+ inbits.a = extbits.a;
+ inbits.b = extbits.b;
+ inbits.c = extbits.c;
+ inbits.d = extbits.d;
+ inbits.e = extbits.e;
+ inbits.f = extbits.f;
+ inbits.g = extbits.g;
+
+ if (inbits.a != outbits.a)
+ fprintf(stderr, "Error: \"a\" got %x expected %x\n", inbits.a, outbits.a);
+ if (inbits.b != outbits.b)
+ fprintf(stderr, "Error: \"b\" got %x expected %x\n", inbits.b, outbits.b);
+ if (inbits.c != outbits.c)
+ fprintf(stderr, "Error: \"c\" got %x expected %x\n", inbits.c, outbits.c);
+ if (inbits.d != outbits.d)
+ fprintf(stderr, "Error: \"d\" got %x expected %x\n", inbits.d, outbits.d);
+ if (inbits.e != outbits.e)
+ fprintf(stderr, "Error: \"e\" got %x expected %x\n", inbits.e, outbits.e);
+ if (inbits.f != outbits.f)
+ fprintf(stderr, "Error: \"f\" got %x expected %x\n", inbits.f, outbits.f);
+ if (inbits.g != outbits.g)
+ fprintf(stderr, "Error: \"g\" got %x expected %x\n", inbits.g, outbits.g);
+ }
+ else {
+ /*
+ * assign fields, then swap bytes
+ */
+ memset(&extbits, 0, sizeof(ext_bits_t));
+ extbits.a = outbits.a;
+ extbits.b = outbits.b;
+ extbits.c = outbits.c;
+ extbits.d = outbits.d;
+ extbits.e = outbits.e;
+ extbits.f = outbits.f;
+ extbits.g = outbits.g;
+
+ for (i = 0, ip = (__uint32_t *)&extbits; i < sizeof(ext_bits_t); i += sizeof(*ip), ip++)
+ *ip = htonl(*ip);
+
+ fprintf(stderr, "write: ");
+ for (i = 0, ip = (__uint32_t *)&extbits; i < sizeof(ext_bits_t); i += sizeof(*ip), ip++)
+ fprintf(stderr, " %08x", *ip);
+ fputc('\n', stderr);
+
+ sts = write(1, &extbits, sizeof(bits_t));
+ if (sts != sizeof(bits_t)) {
+ fprintf(stderr, "write() returns %d not %d as expected\n", sts, (int)sizeof(bits_t));
+ exit(1);
+ }
+ }
+ exit(0);
+}
diff --git a/qa/src/recon.c b/qa/src/recon.c
new file mode 100644
index 0000000..882f281
--- /dev/null
+++ b/qa/src/recon.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * ping pmcd ... when the connection is lost, note time.
+ * keep pinging ... when connection is resumed, report time delta.
+ *
+ * Has to be run as root to control pmcd
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ struct timeval now;
+ struct timeval then;
+ pmResult *rp;
+ int i;
+ char *namelist[4];
+ pmID pmidlist[4];
+ int numpmid;
+ int ctx;
+ int c;
+ int sts;
+ int errflag = 0;
+ static const struct timeval delay = { 0, 10000 };
+ /*
+ * was sginap(10) ... I think this dated from the sgi days when this
+ * was, 10 * 1/100 (1/HZ) seconds, so 100,000 usec or 100 msec ...
+ * but this is not reliable for the QA test (200), so changed to
+ * 10 msec
+ */
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options:\n\
+ -D N set pmDebug debugging flag to N\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) {
+ fprintf(stderr, "pmLoadNameSpace: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((ctx = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ fprintf(stderr, "pmNewContext: %s\n", pmErrStr(ctx));
+ exit(1);
+ }
+
+ i = 0;
+ namelist[i++] = "sample.long.write_me";
+ numpmid = i;
+ sts = pmLookupName(numpmid, namelist, pmidlist);
+ if (sts < 0) {
+ fprintf(stderr, "pmLookupName: %s\n", pmErrStr(sts));
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ fprintf(stderr, " %s - not known\n", namelist[i]);
+ }
+ exit(1);
+ }
+
+ for ( ; ; ) {
+ if ((sts = pmFetch(1, pmidlist, &rp)) < 0) {
+ fprintf(stderr, "pmFetch failed: %s\n", pmErrStr(sts));
+ if (sts != PM_ERR_IPC && sts != -ECONNRESET) {
+ /* unexpected */
+ fprintf(stderr, "Bogus error?\n");
+ exit(1);
+ }
+ gettimeofday(&then, (struct timezone *)0);
+ break;
+ }
+ pmFreeResult(rp);
+ __pmtimevalSleep(delay);
+ }
+
+ for ( ; ; ) {
+ if ((sts = pmReconnectContext(ctx)) >= 0) {
+ fprintf(stderr, "pmReconnectContext: success\n");
+ gettimeofday(&now, (struct timezone *)0);
+ fprintf(stderr, "delay: %.0f secs\n", __pmtimevalSub(&now, &then));
+ break;
+ }
+ __pmtimevalSleep(delay);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/record-setarg.c b/qa/src/record-setarg.c
new file mode 100644
index 0000000..d745d47
--- /dev/null
+++ b/qa/src/record-setarg.c
@@ -0,0 +1,69 @@
+/*
+ * record-setarg - simulate pmRecord*() usage
+ *
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmafm.h>
+
+/*
+ * Usage: record-setarg folio
+ */
+
+int
+main(int argc, char **argv)
+{
+ pmRecordHost *rhp;
+ int sts;
+ FILE *f;
+ extern int errno;
+ char buf[20];
+
+ if (argc < 2) {
+ printf("Usage: record-setarg folio\n");
+ exit(1);
+ }
+
+ f = pmRecordSetup(argv[1], "record-setarg", 0);
+ if (f == NULL) {
+ printf("pmRecordSetup(\"%s\", ...): %s\n",
+ argv[1], pmErrStr(-errno));
+ exit(1);
+ }
+
+ sts = pmRecordAddHost("localhost", 1, &rhp);
+ if (sts < 0) {
+ printf("pmRecordAddHost: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ fprintf(rhp->f_config, "log mandatory on default sample.bin [ \"bin-400\" \"bin-800\" ]\n");
+
+ sts = pmRecordControl(NULL, PM_REC_SETARG, "-t");
+ sprintf(buf, "%dsec", 1);
+ sts += pmRecordControl(NULL, PM_REC_SETARG, buf);
+ sprintf(buf, "-T%dsec", 10);
+ sts += pmRecordControl(NULL, PM_REC_SETARG, buf);
+ if (sts < 0) {
+ printf("pmRecordControl(NULL, PM_REC_SETARG, NULL): %s\n",
+ pmErrStr(sts));
+ exit(1);
+ }
+
+ sts = pmRecordControl(NULL, PM_REC_ON, NULL);
+ if (sts < 0) {
+ printf("pmRecordControl(NULL, PM_REC_ON, NULL): %s\n",
+ pmErrStr(sts));
+ exit(1);
+ }
+
+ printf("\nsleeping ...\n\n");
+ sleep(12);
+
+ sts = pmRecordControl(rhp, PM_REC_OFF, NULL);
+ if (sts < 0)
+ printf("pmRecordControl(..., PM_REC_OFF, ...): %s\n", pmErrStr(sts));
+
+ exit(0);
+}
diff --git a/qa/src/record.c b/qa/src/record.c
new file mode 100644
index 0000000..1483c5e
--- /dev/null
+++ b/qa/src/record.c
@@ -0,0 +1,120 @@
+/*
+ * record - play pmRecord*() games
+ *
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmafm.h>
+
+/*
+ * Usage: record folio creator replay host [...]
+ */
+
+int
+main(int argc, char **argv)
+{
+ pmRecordHost *rhp[10];
+ int sts;
+ int i;
+ FILE *f;
+ extern int errno;
+
+ if (argc < 5) {
+ printf("Usage: record folio creator replay host [...]\n");
+ exit(1);
+ }
+
+ f = pmRecordSetup(argv[1], argv[2], atoi(argv[3]));
+ if (f == NULL) {
+ printf("pmRecordSetup(\"%s\", ...): %s\n",
+ argv[1], pmErrStr(-errno));
+ exit(1);
+ }
+
+ for (i = 4; i < argc; i++) {
+ printf("host: %s\n", argv[i]);
+ sts = pmRecordAddHost(argv[i], i == 4, &rhp[i-4]);
+ if (sts < 0) {
+ printf("pmRecordAddHost(\"%s\", %d, ...): %s\n",
+ argv[i], i==4, pmErrStr(sts));
+ exit(1);
+ }
+ printf("f_config: %s", rhp[i-4]->f_config == NULL ? "NULL" : "OK");
+ printf(" f_ipc: %d pid: %" FMT_PID " status: %d\n", rhp[i-4]->fd_ipc, rhp[i-4]->pid, rhp[i-4]->status);
+ printf("logfile: %s\n", rhp[i-4]->logfile);
+ fprintf(rhp[i-4]->f_config, "log mandatory on 30sec pmcd.control.timeout\n");
+ }
+
+ sts = pmRecordControl(NULL, PM_REC_ON, NULL);
+ if (sts < 0) {
+ printf("pmRecordControl(NULL, PM_REC_ON, NULL): %s\n",
+ pmErrStr(sts));
+ exit(1);
+ }
+
+ printf("\nsleeping ...\n\n");
+ sleep(3);
+
+ for (i = 4; i < argc; i++) {
+ printf("host: %s\n", argv[i]);
+ printf("f_config: %s", rhp[i-4]->f_config == NULL ? "NULL" : "OK");
+ printf(" f_ipc: %d pid: %" FMT_PID " status: %d\n", rhp[i-4]->fd_ipc, rhp[i-4]->pid, rhp[i-4]->status);
+ printf("logfile: %s\n", rhp[i-4]->logfile);
+ }
+
+ printf("\nsend some control requests ...\n");
+ for (i = 4; i < argc; i++) {
+ printf("host: %s\n", argv[i]);
+ if (i % 4 == 0) {
+ printf(" OFF\n");
+ sts = pmRecordControl(rhp[i-4], PM_REC_OFF, NULL);
+ if (sts < 0)
+ printf("pmRecordControl: %s\n", pmErrStr(sts));
+ }
+ else if (i % 4 == 1) {
+ printf(" DETACH\n");
+ sts = pmRecordControl(rhp[i-4], PM_REC_DETACH, NULL);
+ if (sts < 0)
+ printf("pmRecordControl: %s\n", pmErrStr(sts));
+ }
+ else if (i % 4 == 2) {
+ printf(" STATUS\n");
+ sts = pmRecordControl(rhp[i-4], PM_REC_STATUS, NULL);
+ if (sts < 0)
+ printf("pmRecordControl: %s\n", pmErrStr(sts));
+ }
+ else {
+ printf(" close(fd_ipc)\n");
+ close(rhp[i-4]->fd_ipc);
+ }
+ sleep(1);
+ }
+
+ printf("\nnow stop 'em all ...\n");
+ for (i = 4; i < argc; i++) {
+ printf("host: %s\n", argv[i]);
+ sts = pmRecordControl(rhp[i-4], PM_REC_OFF, NULL);
+ if (sts < 0)
+ printf("pmRecordControl(... OFF ...): %s\n", pmErrStr(sts));
+ }
+
+ sleep(2);
+
+ printf("\nand again to get any exit status ...\n");
+ sts = pmRecordControl(NULL, PM_REC_OFF, NULL);
+ if (sts < 0)
+ printf("pmRecordControl( ... OFF ...): %s\n", pmErrStr(sts));
+
+ printf("\n\ndiscover what's happened ...\n");
+ putchar('\n');
+ for (i = 4; i < argc; i++) {
+ printf("host: %s\n", argv[i]);
+ printf("f_config: %s", rhp[i-4]->f_config == NULL ? "NULL" : "OK");
+ printf(" f_ipc: %d pid: %" FMT_PID " status: %d\n", rhp[i-4]->fd_ipc, rhp[i-4]->pid, rhp[i-4]->status);
+ printf("logfile: %s\n", rhp[i-4]->logfile);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/reduce-1.0 b/qa/src/reduce-1.0
new file mode 100644
index 0000000..fa4d753
--- /dev/null
+++ b/qa/src/reduce-1.0
Binary files differ
diff --git a/qa/src/reduce-1.index b/qa/src/reduce-1.index
new file mode 100644
index 0000000..f3cdfba
--- /dev/null
+++ b/qa/src/reduce-1.index
Binary files differ
diff --git a/qa/src/reduce-1.meta b/qa/src/reduce-1.meta
new file mode 100644
index 0000000..366e0b2
--- /dev/null
+++ b/qa/src/reduce-1.meta
Binary files differ
diff --git a/qa/src/reduce-2.0 b/qa/src/reduce-2.0
new file mode 100644
index 0000000..768e633
--- /dev/null
+++ b/qa/src/reduce-2.0
Binary files differ
diff --git a/qa/src/reduce-2.index b/qa/src/reduce-2.index
new file mode 100644
index 0000000..c482a68
--- /dev/null
+++ b/qa/src/reduce-2.index
Binary files differ
diff --git a/qa/src/reduce-2.meta b/qa/src/reduce-2.meta
new file mode 100644
index 0000000..ac61dc5
--- /dev/null
+++ b/qa/src/reduce-2.meta
Binary files differ
diff --git a/qa/src/reduce.config b/qa/src/reduce.config
new file mode 100644
index 0000000..5895c2d
--- /dev/null
+++ b/qa/src/reduce.config
@@ -0,0 +1,21 @@
+log mandatory on default {
+# instantaneous constant value
+ sample.load
+ sample.longlong
+ sample.float
+ sample.double
+# instantaneous drifting value
+ sample.drift
+# constant counter, singular value
+ sample.milliseconds
+# constant counter and reset, with instance domain
+ sample.colour
+# non-constant counter
+ sample.step_counter
+# wrap a lot
+ sample.wrap.ulong
+ sample.wrap.longlong
+# cannot deal with these
+ sample.string
+ sample.aggregate
+}
diff --git a/qa/src/rewrite.0 b/qa/src/rewrite.0
new file mode 100644
index 0000000..76ccb86
--- /dev/null
+++ b/qa/src/rewrite.0
Binary files differ
diff --git a/qa/src/rewrite.index b/qa/src/rewrite.index
new file mode 100644
index 0000000..9d69d97
--- /dev/null
+++ b/qa/src/rewrite.index
Binary files differ
diff --git a/qa/src/rewrite.meta b/qa/src/rewrite.meta
new file mode 100644
index 0000000..d6c77d3
--- /dev/null
+++ b/qa/src/rewrite.meta
Binary files differ
diff --git a/qa/src/root_irix b/qa/src/root_irix
new file mode 100644
index 0000000..8720cf8
--- /dev/null
+++ b/qa/src/root_irix
@@ -0,0 +1,2114 @@
+/*
+ * libirixpmda Performance Metrics Name Space Definition
+ *
+ * From IRIX 6.5.5 ... for reference and V1 PCP archives.
+ */
+
+root {
+ buffer_cache
+ disk
+ efs
+ filesys
+ gfx
+ hinv
+ hw
+ ipc
+ kaio
+ kernel
+ mem
+ name_cache
+ network
+ nfs
+ nfs3
+ origin
+ pmda
+ resource
+ rpc
+ stream
+ swap
+ swapdev
+ vnodes
+ xbow
+ xfs
+ xlv
+ xpc
+ proc
+ sample
+ sampledso
+ pmcd
+}
+
+
+origin {
+ node
+ numa
+}
+
+hinv {
+ ncpu 1:18:2
+ cpuclock 1:26:1
+ mincpuclock 1:26:10
+ maxcpuclock 1:26:11
+ cputype 1:26:13
+ dcache 1:26:2
+ icache 1:26:3
+ secondarycache 1:26:4
+ machine 1:26:12
+ physmem 1:26:5
+ pmeminterleave 1:26:6
+ ndisk 1:26:7
+ disk_sn 1:80:14
+ nnode 1:26:8
+ nrouter 1:38:0
+ nrouterport 1:38:11
+ interconnect 1:38:13
+ nxbow 1:42:1
+ ncell 1:26:14
+ pagesize 1:26:15
+ map
+ nxlv_volumes 1:45:1
+ nfilesys 1:27:9
+ nctl 1:81:22
+ ctl
+}
+
+hinv.map {
+ cpu 1:26:9
+ disk 1:80:13
+ node 1:39:49
+ router 1:38:1
+ routerport 1:38:12
+ xbow 1:42:2
+}
+
+hinv.ctl {
+ ndisk 1:81:23
+}
+
+kernel {
+ all
+ percpu
+}
+
+kernel.all {
+ cpu
+ io
+ swap
+ load 1:18:3
+ users 1:18:4
+ pswitch 1:10:3
+ kswitch 1:10:79
+ kpreempt 1:10:80
+ readch 1:10:14
+ writech 1:10:29
+ runocc 1:10:15
+ runque 1:10:16
+ syscall 1:10:19
+ sysexec 1:10:20
+ sysfork 1:10:21
+ sysread 1:10:22
+ syswrite 1:10:23
+ sysioctl 1:10:81
+ sysother 1:10:59
+ tty
+ intr
+ ipc
+ pty
+ flock
+ idl
+ waitio
+}
+
+kernel.all.idl {
+ mesgsnt 1:10:82
+ mesgrcv 1:10:83
+}
+
+kernel.all.waitio {
+ queue 1:10:84
+ occ 1:10:85
+}
+
+kernel.all.cpu {
+ idle 1:10:7
+ intr 1:10:8
+ sys 1:10:9
+ sxbrk 1:10:10
+ user 1:10:11
+ wait
+}
+
+kernel.all.io {
+ iget 1:10:13
+ bread 1:10:30
+ bwrite 1:10:31
+ lread 1:10:32
+ lwrite 1:10:33
+ phread 1:10:34
+ phwrite 1:10:35
+ wcancel 1:10:36
+ namei 1:10:37
+ dirblk 1:10:38
+}
+
+kernel.all.swap {
+ swpocc 1:10:17
+ swpque 1:10:18
+}
+
+kernel.all.cpu.wait {
+ total 1:10:12
+ gfxc 1:10:24
+ gfxf 1:10:25
+ io 1:10:26
+ pio 1:10:27
+ swap 1:10:28
+}
+
+
+kernel.all.flock {
+ alloc 1:10:57
+ inuse 1:10:58
+}
+
+kernel.all.intr {
+ vme 1:10:51
+ non_vme 1:10:52
+}
+
+kernel.all.ipc {
+ msg 1:10:53
+ sema 1:10:54
+}
+
+kernel.all.pty {
+ masterch 1:10:55
+ slavech 1:10:56
+}
+
+kernel.all.tty {
+ recvintr 1:10:39
+ xmitintr 1:10:40
+ mdmintr 1:10:41
+ out 1:10:42
+ raw 1:10:43
+ canon 1:10:44
+}
+
+gfx {
+ ioctl 1:10:45
+ ctxswitch 1:10:46
+ swapbuf 1:10:47
+ intr 1:10:48
+ fifonowait 1:10:49
+ fifowait 1:10:50
+}
+
+kernel.percpu {
+ cpu
+ io
+ swap
+ pswitch 1:28:3
+ kswitch 1:28:79
+ kpreempt 1:28:80
+ readch 1:28:14
+ writech 1:28:29
+ runocc 1:28:15
+ runque 1:28:16
+ syscall 1:28:19
+ sysexec 1:28:20
+ sysfork 1:28:21
+ sysread 1:28:22
+ syswrite 1:28:23
+ sysioctl 1:28:81
+ sysother 1:28:59
+ tty
+ intr
+ ipc
+ pty
+ flock
+ idl
+ waitio
+}
+
+
+kernel.percpu.idl {
+ mesgsnt 1:28:82
+ mesgrcv 1:28:83
+}
+
+kernel.percpu.waitio {
+ queue 1:28:84
+ occ 1:28:85
+}
+
+kernel.percpu.cpu {
+ idle 1:28:7
+ intr 1:28:8
+ sys 1:28:9
+ sxbrk 1:28:10
+ user 1:28:11
+ wait
+}
+
+kernel.percpu.io {
+ iget 1:28:13
+ bread 1:28:30
+ bwrite 1:28:31
+ lread 1:28:32
+ lwrite 1:28:33
+ phread 1:28:34
+ phwrite 1:28:35
+ wcancel 1:28:36
+ namei 1:28:37
+ dirblk 1:28:38
+}
+
+kernel.percpu.swap {
+ in 1:28:5
+ out 1:28:6
+ pagesin 1:28:1
+ pagesout 1:28:2
+ procout 1:28:4
+ swpocc 1:28:17
+ swpque 1:28:18
+}
+
+kernel.percpu.cpu.wait {
+ total 1:28:12
+ gfxc 1:28:24
+ gfxf 1:28:25
+ io 1:28:26
+ pio 1:28:27
+ swap 1:28:28
+}
+
+kernel.percpu.flock {
+ alloc 1:28:57
+ inuse 1:28:58
+}
+
+kernel.percpu.intr {
+ vme 1:28:51
+ non_vme 1:28:52
+}
+
+kernel.percpu.ipc {
+ msg 1:28:53
+ sema 1:28:54
+}
+
+kernel.percpu.pty {
+ masterch 1:28:55
+ slavech 1:28:56
+}
+
+kernel.percpu.tty {
+ recvintr 1:28:39
+ xmitintr 1:28:40
+ mdmintr 1:28:41
+ out 1:28:42
+ raw 1:28:43
+ canon 1:28:44
+}
+
+disk {
+ dev
+ ctl
+ all
+}
+
+disk.dev {
+ read 1:80:1
+ write 1:80:2
+ total 1:80:7
+ blkread 1:80:5
+ blkwrite 1:80:6
+ blktotal 1:80:4
+ active 1:80:3
+ response 1:80:8
+ bytes 1:80:15
+ read_bytes 1:80:16
+ write_bytes 1:80:17
+ qlen 1:80:21
+ sum_qlen 1:80:22
+}
+
+disk.ctl {
+ read 1:81:10
+ write 1:81:11
+ total 1:81:9
+ blkread 1:81:15
+ blkwrite 1:81:16
+ blktotal 1:81:14
+ active 1:81:12
+ response 1:81:13
+ bytes 1:81:17
+ read_bytes 1:81:18
+ write_bytes 1:81:19
+ avg_disk
+ qlen 1:81:24
+ sum_qlen 1:81:25
+}
+
+disk.ctl.avg_disk {
+ active 1:81:20
+ response 1:81:21
+}
+
+disk.all {
+ read 1:82:10
+ write 1:82:11
+ total 1:82:9
+ blkread 1:82:15
+ blkwrite 1:82:16
+ blktotal 1:82:14
+ active 1:82:12
+ response 1:82:13
+ bytes 1:82:17
+ read_bytes 1:82:18
+ write_bytes 1:82:19
+ avg_disk
+ qlen 1:82:22
+ sum_qlen 1:82:23
+}
+
+disk.all.avg_disk {
+ active 1:82:20
+ response 1:82:21
+}
+
+mem {
+ fault
+ tlb
+ paging
+ system
+ lpage
+ util
+ freemem 1:18:1
+ availsmem 1:18:5
+ availrmem 1:18:6
+ bufmem 1:18:7
+ physmem 1:18:8
+ dchunkpages 1:18:9
+ pmapmem 1:18:10
+ strmem 1:18:11
+ chunkpages 1:18:12
+ dpages 1:18:13
+ emptymem 1:18:14
+ freeswap 1:11:18
+ halloc 1:11:9
+ heapmem 1:11:10
+ hfree 1:11:11
+ hovhd 1:11:12
+ hunused 1:11:13
+ zfree 1:11:14
+ zonemem 1:11:15
+ zreq 1:11:16
+ iclean 1:11:17
+ bsdnet 1:11:19
+ palloc 1:11:30
+ unmodfl 1:11:31
+ unmodsw 1:11:32
+}
+
+mem.fault {
+ prot
+ addr
+}
+
+mem.paging {
+ reclaim 1:11:29
+}
+
+mem.tlb {
+ flush 1:11:20
+ invalid 1:11:22
+ rfault 1:11:24
+ sync 1:11:25
+ tfault 1:11:26
+ purge 1:11:27
+ idnew 1:11:21
+ idwrap 1:11:23
+ kvmwrap 1:11:28
+}
+
+mem.fault.addr {
+ total 1:11:4
+ cache 1:11:5
+ demand 1:11:6
+ file 1:11:7
+ swap 1:11:8
+}
+
+mem.fault.prot {
+ total 1:11:1
+ cow 1:11:2
+ steal 1:11:3
+}
+
+mem.system {
+ sptalloc 1:11:33
+ sptfree 1:11:34
+ sptclean 1:11:35
+ sptdirty 1:11:36
+ sptintrans 1:11:37
+ sptaged 1:11:38
+ sptbp 1:11:39
+ sptheap 1:11:40
+ sptzone 1:11:41
+ sptpt 1:11:42
+}
+
+mem.lpage {
+ coalesce
+ faults 1:41:3
+ allocs 1:41:4
+ downgrade 1:41:5
+ page_splits 1:41:6
+ basesize 1:41:7
+ maxsize 1:41:8
+ maxenabled 1:41:9
+ enabled 1:41:10
+}
+
+mem.lpage.coalesce {
+ scans 1:41:1
+ success 1:41:2
+}
+
+mem.util {
+ kernel 1:18:15
+ fs_ctl 1:18:16
+ fs_dirty 1:18:17
+ fs_clean 1:18:18
+ free 1:18:19
+ user 1:18:20
+}
+
+swap {
+ in 1:10:5
+ out 1:10:6
+ pagesin 1:10:1
+ pagesout 1:10:2
+ procout 1:10:4
+ free 1:16:6
+ length 1:16:7
+ maxswap 1:16:8
+ vlength 1:16:9
+ alloc 1:16:10
+ reserve 1:16:11
+ used 1:16:12
+ unused 1:16:13
+}
+
+swapdev {
+ free 1:16:1
+ length 1:16:2
+ maxswap 1:16:3
+ vlength 1:16:4
+ priority 1:16:5
+}
+
+network {
+ icmp
+ igmp
+ ip
+ tcp
+ udp
+ interface
+ mbuf
+ mcr
+ socket
+}
+
+network.icmp {
+ error 1:17:52
+ oldshort 1:17:53
+ oldicmp 1:17:54
+ badcode 1:17:55
+ tooshort 1:17:56
+ checksum 1:17:57
+ badlen 1:17:58
+ reflect 1:17:59
+ inhist
+ outhist
+}
+
+network.igmp {
+ rcv_total 1:17:90
+ rcv_tooshort 1:17:91
+ rcv_badsum 1:17:92
+ rcv_queries 1:17:93
+ rcv_badqueries 1:17:94
+ rcv_reports 1:17:95
+ rcv_badreports 1:17:96
+ rcv_ourreports 1:17:97
+ snd_reports 1:17:98
+}
+
+network.ip {
+ badhlen 1:17:99
+ badlen 1:17:100
+ badoptions 1:17:101
+ badsum 1:17:102
+ cantforward 1:17:103
+ cantfrag 1:17:104
+ delivered 1:17:105
+ forward 1:17:106
+ fragdropped 1:17:107
+ fragmented 1:17:108
+ fragments 1:17:109
+ fragtimeout 1:17:110
+ localout 1:17:111
+ noproto 1:17:112
+ noroute 1:17:113
+ odropped 1:17:114
+ ofragments 1:17:115
+ reassembled 1:17:116
+ redirect 1:17:117
+ tooshort 1:17:118
+ toosmall 1:17:119
+ badvers 1:17:137
+ rawout 1:17:138
+ total 1:17:120
+}
+
+network.tcp {
+ connattempt 1:17:1
+ accepts 1:17:2
+ connects 1:17:3
+ drops 1:17:4
+ conndrops 1:17:5
+ closed 1:17:6
+ segstimed 1:17:7
+ rttupdated 1:17:8
+ delack 1:17:9
+ timeoutdrop 1:17:10
+ rexmttimeo 1:17:11
+ persisttimeo 1:17:12
+ keeptimeo 1:17:13
+ keepprobe 1:17:14
+ keepdrops 1:17:15
+ sndtotal 1:17:16
+ sndpack 1:17:17
+ sndbyte 1:17:18
+ sndrexmitpack 1:17:19
+ sndrexmitbyte 1:17:20
+ sndacks 1:17:21
+ sndprobe 1:17:22
+ sndurg 1:17:23
+ sndwinup 1:17:24
+ sndctrl 1:17:25
+ sndrst 1:17:26
+ rcvtotal 1:17:27
+ rcvpack 1:17:28
+ rcvbyte 1:17:29
+ rcvbadsum 1:17:30
+ rcvbadoff 1:17:31
+ rcvshort 1:17:32
+ rcvduppack 1:17:33
+ rcvdupbyte 1:17:34
+ rcvpartduppack 1:17:35
+ rcvpartdupbyte 1:17:36
+ rcvoopack 1:17:37
+ rcvoobyte 1:17:38
+ rcvpackafterwin 1:17:39
+ rcvbyteafterwin 1:17:40
+ rcvafterclose 1:17:41
+ rcvwinprobe 1:17:42
+ rcvdupack 1:17:43
+ rcvacktoomuch 1:17:44
+ rcvackpack 1:17:45
+ rcvackbyte 1:17:46
+ rcvwinupd 1:17:47
+ pcbcachemiss 1:17:48
+ predack 1:17:49
+ preddat 1:17:50
+ pawsdrop 1:17:51
+ badsyn 1:17:152
+ listendrop 1:17:153
+ persistdrop 1:17:154
+ synpurge 1:17:155
+}
+
+network.udp {
+ ipackets 1:17:121
+ hdrops 1:17:122
+ badsum 1:17:123
+ badlen 1:17:124
+ noport 1:17:125
+ noportbcast 1:17:126
+ fullsock 1:17:127
+ opackets 1:17:128
+ pcbcachemiss 1:17:129
+}
+
+network.icmp.inhist {
+ echoreply 1:17:60
+ unreach 1:17:61
+ sourcequench 1:17:62
+ redirect 1:17:63
+ echo 1:17:64
+ routeradvert 1:17:65
+ routersolicit 1:17:66
+ timxceed 1:17:67
+ paramprob 1:17:68
+ tstamp 1:17:69
+ tstampreply 1:17:70
+ ireq 1:17:71
+ ireqreply 1:17:72
+ maskreq 1:17:73
+ maskreply 1:17:74
+}
+
+network.icmp.outhist {
+ echoreply 1:17:75
+ unreach 1:17:76
+ sourcequench 1:17:77
+ redirect 1:17:78
+ echo 1:17:79
+ routeradvert 1:17:80
+ routersolicit 1:17:81
+ timxceed 1:17:82
+ paramprob 1:17:83
+ tstamp 1:17:84
+ tstampreply 1:17:85
+ ireq 1:17:86
+ ireqreply 1:17:87
+ maskreq 1:17:88
+ maskreply 1:17:89
+}
+
+network.mbuf {
+ alloc 1:17:130
+ typealloc 1:17:136
+ clustalloc 1:17:131
+ clustfree 1:17:132
+ failed 1:17:133
+ waited 1:17:134
+ drained 1:17:135
+ pcb
+ mcb
+}
+
+network.mbuf.pcb {
+ total 1:17:156
+ bytes 1:17:157
+}
+
+network.mbuf.mcb {
+ total 1:17:158
+ bytes 1:17:159
+ fail 1:17:160
+}
+
+network.mcr {
+ mfc_lookups 1:17:139
+ mfc_misses 1:17:140
+ upcalls 1:17:141
+ no_route 1:17:142
+ bad_tunnel 1:17:143
+ cant_tunnel 1:17:144
+ wrong_if 1:17:145
+ upq_ovflw 1:17:146
+ cache_cleanups 1:17:147
+ drop_sel 1:17:148
+ q_overflow 1:17:149
+ pkt2large 1:17:150
+ upq_sockfull 1:17:151
+}
+
+network.interface {
+ collisions 1:25:1
+ mtu 1:25:2
+ noproto 1:25:3
+ baudrate 1:25:4
+ in
+ out
+ total
+}
+
+network.interface.in {
+ errors 1:25:5
+ packets 1:25:6
+ bytes 1:25:7
+ mcasts 1:25:8
+ drops 1:25:9
+}
+
+network.interface.out {
+ errors 1:25:10
+ packets 1:25:11
+ bytes 1:25:12
+ mcasts 1:25:13
+ drops 1:25:14
+ qdrops 1:25:15
+ qlength 1:25:16
+ qmax 1:25:17
+}
+
+network.interface.total {
+ errors 1:25:18
+ packets 1:25:19
+ bytes 1:25:20
+ mcasts 1:25:21
+ drops 1:25:22
+}
+
+network.socket {
+ type 1:43:1
+ state 1:43:2
+}
+
+resource {
+ nproc 1:19:1
+ nbuf 1:19:2
+ hbuf 1:19:3
+ syssegsz 1:19:4
+ maxpmem 1:19:5
+ maxdmasz 1:19:6
+ dquot 1:19:7
+ nstream_queue 1:19:8
+ nstream_head 1:19:9
+ fileovf 1:20:1
+ procovf 1:20:2
+}
+
+name_cache {
+ hits 1:21:1
+ misses 1:21:2
+ enters 1:21:3
+ dbl_enters 1:21:4
+ long_enter 1:21:5
+ long_look 1:21:6
+ lru_empty 1:21:7
+ purges 1:21:8
+ vfs_purges 1:21:9
+ removes 1:21:10
+ searches 1:21:11
+ stale_hits 1:21:12
+ steps 1:21:13
+}
+
+buffer_cache {
+ getblks 1:22:1
+ getblockmiss 1:22:2
+ getfound 1:22:3
+ getbchg 1:22:4
+ getloops 1:22:5
+ getfree 1:22:6
+ getfreeempty 1:22:7
+ getfreehmiss 1:22:8
+ getfreehmissx 1:22:9
+ getfreealllck 1:22:10
+ getfreedelwri 1:22:11
+ flush 1:22:12
+ flushloops 1:22:13
+ getfreeref 1:22:14
+ getfreerelse 1:22:15
+ getoverlap 1:22:16
+ clusters 1:22:17
+ clustered 1:22:18
+ getfrag 1:22:19
+ getpatch 1:22:20
+ trimmed 1:22:21
+ inserts 1:22:22
+ irotates 1:22:23
+ deletes 1:22:24
+ drotates 1:22:25
+ decomms 1:22:26
+ flush_decomms 1:22:27
+ delrsv 1:22:28
+ delrsvclean 1:22:29
+ delrsvdirty 1:22:30
+ delrsvfree 1:22:31
+ delrsvwait 1:22:32
+ sync_commits 1:22:33
+ commits 1:22:34
+ getfreecommit 1:22:35
+ inactive 1:22:36
+ active 1:22:37
+ force 1:22:38
+}
+
+vnodes {
+ vnodes 1:23:1
+ extant 1:23:2
+ active 1:23:3
+ alloc 1:23:4
+ aheap 1:23:5
+ afree 1:23:6
+ afreeloops 1:23:7
+ get 1:23:8
+ gchg 1:23:9
+ gfree 1:23:10
+ rele 1:23:11
+ reclaim 1:23:12
+ destroy 1:23:13
+ afreemiss 1:23:14
+}
+
+efs {
+ attempts 1:24:1
+ found 1:24:2
+ frecycle 1:24:3
+ missed 1:24:4
+ dup 1:24:5
+ reclaims 1:24:6
+ itobp 1:24:7
+ itobpf 1:24:8
+ iupdat 1:24:9
+ iupacc 1:24:10
+ iupupd 1:24:11
+ iupchg 1:24:12
+ iupmod 1:24:13
+ iupunk 1:24:14
+ iallocrd 1:24:15
+ iallocrdf 1:24:16
+ ialloccoll 1:24:17
+ bmaprd 1:24:18
+ bmapfbm 1:24:19
+ bmapfbc 1:24:20
+ dirupd 1:24:21
+ truncs 1:24:22
+ icreat 1:24:23
+ attrchg 1:24:24
+ readcancel 1:24:25
+}
+
+rpc {
+ client
+ server
+}
+
+rpc.client {
+ badcalls 1:14:1
+ badxid 1:14:2
+ calls 1:14:3
+ newcred 1:14:4
+ retrans 1:14:5
+ timeout 1:14:6
+ wait 1:14:7
+ badverfs 1:14:8
+}
+
+rpc.server {
+ badcalls 1:15:1
+ badlen 1:15:2
+ calls 1:15:3
+ dupage 1:15:4
+ duphits 1:15:5
+ nullrecv 1:15:6
+ xdrcall 1:15:7
+}
+
+nfs {
+ client
+ server
+}
+
+nfs.client {
+ badcalls 1:12:1
+ calls 1:12:2
+ nclget 1:12:3
+ nclsleep 1:12:4
+ reqs 1:12:5
+}
+
+nfs.server {
+ badcalls 1:13:1
+ calls 1:13:2
+ reqs 1:13:3
+}
+
+nfs3 {
+ client
+ server
+}
+
+nfs3.client {
+ badcalls 1:33:1
+ calls 1:33:2
+ nclget 1:33:3
+ nclsleep 1:33:4
+ reqs 1:33:5
+}
+
+nfs3.server {
+ badcalls 1:37:1
+ calls 1:37:2
+ reqs 1:37:3
+}
+
+filesys {
+ capacity 1:27:1
+ used 1:27:2
+ free 1:27:3
+ maxfiles 1:27:4
+ usedfiles 1:27:5
+ freefiles 1:27:6
+ mountdir 1:27:7
+ full 1:27:8
+}
+
+ipc {
+ sem
+ msg
+ shm
+}
+
+ipc.shm {
+ segsz 1:29:1
+ nattch 1:29:2
+}
+
+ipc.msg {
+ cbytes 1:30:1
+ qnum 1:30:2
+ qbytes 1:30:3
+}
+
+ipc.sem {
+ nsems 1:31:1
+ ncnt 1:31:2
+ zcnt 1:31:3
+}
+
+xfs {
+ allocx 1:32:1
+ allocb 1:32:2
+ freex 1:32:3
+ freeb 1:32:4
+ abt_lookup 1:32:5
+ abt_compare 1:32:6
+ abt_insrec 1:32:7
+ abt_delrec 1:32:8
+ blk_mapr 1:32:9
+ blk_mapw 1:32:10
+ blk_unmap 1:32:11
+ add_exlist 1:32:12
+ del_exlist 1:32:13
+ look_exlist 1:32:14
+ cmp_exlist 1:32:15
+ bmbt_lookup 1:32:16
+ bmbt_compare 1:32:17
+ bmbt_insrec 1:32:18
+ bmbt_delrec 1:32:19
+ dir_lookup 1:32:20
+ dir_create 1:32:21
+ dir_remove 1:32:22
+ dir_getdents 1:32:23
+ trans_sync 1:32:24
+ trans_async 1:32:25
+ trans_empty 1:32:26
+ ig_attempts 1:32:27
+ ig_found 1:32:28
+ ig_frecycle 1:32:29
+ ig_missed 1:32:30
+ ig_dup 1:32:31
+ ig_reclaims 1:32:32
+ ig_attrchg 1:32:33
+ log_writes 1:32:34
+ log_blocks 1:32:35
+ log_noiclogs 1:32:36
+ xfsd_bufs 1:32:37
+ xstrat_bytes 1:32:38
+ xstrat_quick 1:32:39
+ xstrat_split 1:32:40
+ write_calls 1:32:41
+ write_bytes 1:32:42
+ write_bufs 1:32:43
+ read_calls 1:32:44
+ read_bytes 1:32:45
+ read_bufs 1:32:46
+ attr_get 1:32:47
+ attr_set 1:32:48
+ attr_remove 1:32:49
+ attr_list 1:32:50
+ log_force 1:32:51
+ log_force_sleep 1:32:52
+ sleep_logspace 1:32:53
+ try_logspace 1:32:54
+ tail_push
+ quota
+ iflush_count 1:32:71
+ icluster_flushzero 1:32:72
+}
+
+xfs.tail_push {
+ npush 1:32:55
+ flush 1:32:56
+ flushing 1:32:57
+ locked 1:32:58
+ pinned 1:32:59
+ pushbuf 1:32:60
+ restarts 1:32:61
+ success 1:32:62
+}
+
+xfs.quota {
+ cachehits 1:32:63
+ cachemisses 1:32:64
+ inact_reclaims 1:32:65
+ reclaim_misses 1:32:66
+ reclaims 1:32:67
+ shake_reclaims 1:32:68
+ dquot_dups 1:32:69
+ wants 1:32:70
+}
+
+kaio {
+ reads 1:36:3
+ writes 1:36:4
+ read_bytes 1:36:5
+ write_bytes 1:36:6
+ inuse 1:36:2
+ free 1:36:8 /* added in IRIX 6.5 */
+ nobuf 1:36:1
+ proc_maxinuse 1:36:9 /* added in IRIX 6.5 */
+ inprogress 1:36:10 /* added in IRIX 6.5 */
+ errors 1:36:7
+}
+
+hw {
+ r10kevctr
+ router
+ hub
+}
+
+hw.r10kevctr {
+ state 1:35:255
+ cpurev 1:35:254
+ cycles 1:35:0
+ grad
+ issue
+ fail
+ pcache
+ scache
+ fucomp 1:35:32
+ extint 1:35:12
+ extinv 1:35:13
+ vcc 1:35:14
+ tlb 1:35:23
+}
+
+hw.r10kevctr.grad {
+ instrg 1:35:15
+ loadg 1:35:18
+ storeg 1:35:19
+ scondg 1:35:20
+ fp 1:35:21
+}
+
+hw.r10kevctr.issue {
+ instri 1:35:1
+ loadi 1:35:2
+ storei 1:35:3
+ scondi 1:35:4
+ brd 1:35:6
+}
+
+hw.r10kevctr.fail {
+ scondf 1:35:5
+ brmp 1:35:24
+}
+
+hw.r10kevctr.pcache {
+ imiss 1:35:9
+ dmiss 1:35:25
+ wb 1:35:22
+}
+
+hw.r10kevctr.scache {
+ imiss 1:35:10
+ dmiss 1:35:26
+ wb 1:35:7
+ iwaymp 1:35:11
+ dwaymp 1:35:27
+ extinthit 1:35:28
+ extinvhit 1:35:29
+ upclean 1:35:30
+ upshare 1:35:31
+ ecc 1:35:8
+}
+
+hw.router {
+ portmask 1:38:2
+ rev_id 1:38:3
+ send_util 1:38:4
+ recv
+ retry_errors 1:38:8
+ sn_errors 1:38:9
+ cb_errors 1:38:10
+ perport
+ type 1:38:22
+}
+
+hw.router.recv {
+ bypass_util 1:38:5
+ queued_util 1:38:6
+ total_util 1:38:7
+}
+
+hw.router.perport {
+ send_util 1:38:14
+ recv
+ retry_errors 1:38:18
+ sn_errors 1:38:19
+ cb_errors 1:38:20
+ excess_errors 1:38:21
+}
+
+hw.router.perport.recv {
+ bypass_util 1:38:15
+ queued_util 1:38:16
+ total_util 1:38:17
+}
+
+hw.hub {
+ ni
+ ii
+ nasid 1:44:8
+}
+
+hw.hub.ni {
+ retry 1:44:1
+ sn_errors 1:44:2
+ cb_errors 1:44:3
+ overflows 1:44:4
+}
+
+hw.hub.ii {
+ sn_errors 1:44:5
+ cb_errors 1:44:6
+ overflows 1:44:7
+}
+
+xpc {
+ kernel
+ network
+ disk
+}
+
+xpc.kernel {
+ all
+ percpu
+}
+
+xpc.kernel.all {
+ cpu
+ io
+}
+
+xpc.kernel.all.cpu {
+ idle 1:10:60
+ intr 1:10:61
+ sys 1:10:62
+ sxbrk 1:10:63
+ user 1:10:64
+ wait
+}
+
+xpc.kernel.all.cpu.wait {
+ total 1:10:65
+ gfxc 1:10:66
+ gfxf 1:10:67
+ io 1:10:68
+ pio 1:10:69
+ swap 1:10:70
+}
+
+xpc.kernel.all.io {
+ bread 1:10:71
+ bwrite 1:10:72
+ lread 1:10:73
+ lwrite 1:10:74
+ phread 1:10:75
+ phwrite 1:10:76
+ wcancel 1:10:77
+ dirblk 1:10:78
+}
+
+xpc.kernel.percpu {
+ cpu
+ io
+}
+
+xpc.kernel.percpu.cpu {
+ idle 1:28:60
+ intr 1:28:61
+ sys 1:28:62
+ sxbrk 1:28:63
+ user 1:28:64
+ wait
+}
+
+xpc.kernel.percpu.cpu.wait {
+ total 1:28:65
+ gfxc 1:28:66
+ gfxf 1:28:67
+ io 1:28:68
+ pio 1:28:69
+ swap 1:28:70
+}
+
+xpc.kernel.percpu.io {
+ bread 1:28:71
+ bwrite 1:28:72
+ lread 1:28:73
+ lwrite 1:28:74
+ phread 1:28:75
+ phwrite 1:28:76
+ wcancel 1:28:77
+ dirblk 1:28:78
+}
+
+xpc.network {
+ interface
+}
+
+xpc.network.interface {
+ in
+ out
+ total
+}
+
+xpc.network.interface.in {
+ bytes 1:25:23
+}
+
+xpc.network.interface.out {
+ bytes 1:25:24
+}
+
+xpc.network.interface.total {
+ bytes 1:25:25
+}
+
+xpc.disk {
+ dev
+}
+
+xpc.disk.dev {
+ read 1:80:9
+ active 1:80:10
+ blkread 1:80:11
+ response 1:80:12
+ bytes 1:80:18
+ read_bytes 1:80:19
+ write_bytes 1:80:20
+}
+
+pmda {
+ version 1:0:2
+ uname 1:0:3
+ reset 1:0:1
+ debug 1:0:4
+}
+
+origin.numa {
+ routerload 1:39:1
+ migr
+ memory
+ unpegger
+ bouncectl
+ memoryd
+}
+
+origin.numa.migr {
+ threshold 1:39:2
+ intr
+ auto
+ user
+ queue
+ coalesc
+ triggers
+}
+
+origin.numa.migr.intr {
+ total 1:39:3
+ failstate 1:39:4
+ failenabled 1:39:5
+ failfrozen 1:39:6
+}
+
+origin.numa.migr.auto {
+ total 1:39:7
+ in 1:39:8
+ out 1:39:9
+ fail 1:39:10
+ queue_len 1:39:11
+}
+
+origin.numa.migr.user {
+ total 1:39:12
+ in 1:39:13
+ out 1:39:14
+ fail 1:39:15
+ queue_len 1:39:16
+}
+
+origin.numa.migr.queue {
+ total 1:39:17
+ in 1:39:18
+ out 1:39:19
+ fail
+}
+
+origin.numa.migr.queue.fail {
+ total 1:39:20
+ overflow 1:39:21
+ state 1:39:22
+ failq 1:39:23
+}
+
+origin.numa.migr.coalesc {
+ total 1:39:24
+ in 1:39:25
+ out 1:39:26
+ fail 1:39:27
+}
+
+origin.numa.migr.triggers {
+ capacity 1:39:28
+ time 1:39:29
+ traffic 1:39:30
+}
+
+origin.numa.memory {
+ lent 1:39:31
+ replicated
+}
+
+origin.numa.memory.replicated {
+ page_count 1:39:32
+ page_dest 1:39:33
+ page_reuse 1:39:34
+ page_notavail 1:39:35
+ control_refuse 1:39:36
+}
+
+origin.numa.unpegger {
+ calls 1:39:37
+ npages 1:39:38
+ last_npages 1:39:39
+}
+
+origin.numa.bouncectl {
+ calls 1:39:40
+ frozen_pages 1:39:41
+ melt_pages 1:39:42
+ last_melt_pages 1:39:43
+ dampened_pages 1:39:44
+}
+
+origin.numa.memoryd {
+ activations 1:39:45
+ periodic 1:39:46
+}
+
+origin.node {
+ physmem 1:40:1
+ free
+}
+
+origin.node.free {
+ total 1:40:2
+ pages_64k 1:40:3
+ pages_256k 1:40:4
+ pages_1m 1:40:5
+ pages_4m 1:40:6
+ pages_16m 1:40:7
+}
+
+xbow {
+ active
+ switch 1:42:5
+ nports 1:42:6
+ gen 1:42:7
+ total
+ port
+}
+
+xbow.active {
+ xbows 1:42:3
+ ports 1:42:4
+}
+
+xbow.total {
+ src 1:42:8
+ dst 1:42:9
+ rrcv 1:42:10
+ rxmt 1:42:11
+}
+
+xbow.port {
+ flags 1:42:12
+ src 1:42:13
+ dst 1:42:14
+ rrcv 1:42:15
+ rxmt 1:42:16
+}
+
+xlv {
+ read 1:45:2
+ write 1:45:3
+ read_bytes 1:45:4
+ write_bytes 1:45:5
+ stripe_ops 1:45:6
+ stripe_units 1:45:7
+ aligned
+ unaligned
+ largest_io
+}
+
+xlv.aligned {
+ full_width 1:45:8
+ lt_width 1:45:9
+ gt_width 1:45:10
+ part_unit 1:45:11
+}
+
+xlv.unaligned {
+ full_width 1:45:12
+ lt_width 1:45:13
+ gt_width 1:45:14
+ part_unit 1:45:15
+}
+
+xlv.largest_io {
+ stripes 1:45:16
+ count 1:45:17
+}
+
+stream {
+ streams
+ queues
+ msg_blks
+ msg_dblks
+ bufsz_64
+ bufsz_256
+ bufsz_512
+ bufsz_2048
+ bufsz_page
+ link_blks
+ events
+ qbinfo
+ cur_pages 1:46:37
+ min_pages 1:46:38
+ max_pages 1:46:39
+}
+
+stream.streams {
+ use 1:46:1
+ max 1:46:2
+ fail 1:46:3
+}
+
+stream.queues {
+ use 1:46:4
+ max 1:46:5
+ fail 1:46:6
+}
+
+stream.msg_blks {
+ use 1:46:7
+ max 1:46:8
+ fail 1:46:9
+}
+
+stream.msg_dblks {
+ use 1:46:10
+ max 1:46:11
+ fail 1:46:12
+}
+
+stream.bufsz_64 {
+ use 1:46:13
+ max 1:46:14
+ fail 1:46:15
+}
+
+stream.bufsz_256 {
+ use 1:46:16
+ max 1:46:17
+ fail 1:46:18
+}
+
+stream.bufsz_512 {
+ use 1:46:19
+ max 1:46:20
+ fail 1:46:21
+}
+
+stream.bufsz_2048 {
+ use 1:46:22
+ max 1:46:23
+ fail 1:46:24
+}
+
+stream.bufsz_page {
+ use 1:46:25
+ max 1:46:26
+ fail 1:46:27
+}
+
+stream.link_blks {
+ use 1:46:28
+ max 1:46:29
+ fail 1:46:30
+}
+
+stream.events {
+ use 1:46:31
+ max 1:46:32
+ fail 1:46:33
+}
+
+stream.qbinfo {
+ use 1:46:34
+ max 1:46:35
+ fail 1:46:36
+}
+
+proc {
+ nprocs 3:0:0
+ psinfo
+ pstatus
+ pscred
+ psusage
+ memory
+ accounting
+}
+
+proc.psinfo {
+ state 3:1:0
+ sname 3:1:1
+ zomb 3:1:2
+ nice 3:1:3
+ flag 3:1:4
+ uid 3:1:5
+ gid 3:1:6
+ pid 3:1:7
+ ppid 3:1:8
+ pgrp 3:1:9
+ sid 3:1:10
+ addr 3:1:11
+ size 3:1:12
+ rssize 3:1:13
+ wchan 3:1:15
+ start 3:1:16
+ time 3:1:17
+ pri 3:1:18
+ oldpri 3:1:19
+ cpu 3:1:20
+ ttydev 3:1:21
+ clname 3:1:22
+ fname 3:1:23
+ psargs 3:1:24
+ uname 3:1:25
+ gname 3:1:26
+ ttyname 3:1:27
+ ttymajor 3:1:28
+ ttyminor 3:1:29
+ ctime 3:1:30
+ shareuid 3:1:31
+ pset 3:1:32
+ sonproc 3:1:33
+ spid 3:1:34
+ qtime 3:1:35
+ thds 3:1:36
+ wname 3:1:37
+}
+
+proc.pstatus {
+ flags 3:2:0
+ why 3:2:1
+ what 3:2:2
+ cursig 3:2:3
+ sigpend 3:2:4
+ sighold 3:2:5
+ info 3:2:6
+ altstack 3:2:7
+ action 3:2:8
+ syscall 3:2:9
+ nsysarg 3:2:10
+ errno 3:2:11
+ rval1 3:2:12
+ rval2 3:2:13
+ sysarg 3:2:14
+ pid 3:2:15
+ ppid 3:2:16
+ pgrp 3:2:17
+ sid 3:2:18
+ utime 3:2:19
+ stime 3:2:20
+ cutime 3:2:21
+ cstime 3:2:22
+ clname 3:2:23
+ instr 3:2:24
+ reg 3:2:25
+ nthreads 3:2:26
+ thsigpend 3:2:27
+ who 3:2:28
+}
+
+proc.pscred {
+ euid 3:3:0
+ ruid 3:3:1
+ suid 3:3:2
+ egid 3:3:3
+ rgid 3:3:4
+ sgid 3:3:5
+ ngroups 3:3:6
+}
+
+proc.psusage {
+ tstamp 3:4:0
+ starttime 3:4:1
+ utime 3:4:2
+ stime 3:4:3
+ minf 3:4:4
+ majf 3:4:5
+ utlb 3:4:6
+ nswap 3:4:7
+ gbread 3:4:8
+ bread 3:4:9
+ gbwrit 3:4:10
+ bwrit 3:4:11
+ sigs 3:4:12
+ vctx 3:4:13
+ ictx 3:4:14
+ sysc 3:4:15
+ syscr 3:4:16
+ syscw 3:4:17
+ syscps 3:4:18
+ sysci 3:4:19
+ graphfifo 3:4:20
+ graph_req 3:4:21
+ graph_wait 3:4:22
+ size 3:4:23
+ rss 3:4:24
+ inblock 3:4:25
+ oublock 3:4:26
+ ktlb 3:4:27
+ vfault 3:4:28
+}
+
+proc.memory {
+ virtual
+ physical
+}
+
+proc.memory.virtual {
+ txt 3:5:1
+ dat 3:5:3
+ bss 3:5:5
+ stack 3:5:7
+ shm 3:5:9
+}
+
+proc.memory.physical {
+ txt 3:5:0
+ dat 3:5:2
+ bss 3:5:4
+ stack 3:5:6
+ shm 3:5:8
+}
+
+proc.accounting {
+ flag 3:6:0
+ ash 3:6:1
+ prid 3:6:2
+ timers
+ counts
+}
+
+proc.accounting.timers {
+ utime 3:6:3
+ stime 3:6:4
+ bwtime 3:6:5
+ rwtime 3:6:6
+ qwtime 3:6:7
+}
+
+proc.accounting.counts {
+ mem 3:6:8
+ swaps 3:6:9
+ chr 3:6:10
+ chw 3:6:11
+ br 3:6:12
+ bw 3:6:13
+ syscr 3:6:14
+ syscw 3:6:15
+}
+
+sample {
+ control 29:0:0
+ daemon_pid 29:0:1
+ seconds 29:0:2
+ milliseconds 29:0:3
+ load 29:0:4
+ colour 29:0:5
+ bin 29:0:6
+ bucket 29:0:48
+ part_bin 29:0:50
+ bogus_bin 29:0:51
+ drift 29:0:7
+ step 29:0:8
+ step_counter 29:0:63
+ mirage 29:0:37
+ mirage_longlong 29:0:38
+ write_me 29:0:36
+ lights 29:0:46
+ magnitude 29:0:47
+ sysinfo 29:0:39
+ pdu 29:0:40
+ recv_pdu 29:0:41
+ xmit_pdu 29:0:42
+ noinst 29:0:9
+ needprofile 29:0:49
+ not_ready 29:0:56
+ rapid 29:0:64
+ error_code 29:0:74
+ error_check 29:0:75
+ long
+ longlong
+ float
+ double
+ string
+ aggregate
+ hordes
+ bad
+ wrap
+ dodgey
+ dynamic
+ scale_step
+ const_rate
+}
+
+sample.long {
+ one 29:0:10
+ ten 29:0:11
+ hundred 29:0:12
+ million 29:0:13
+ write_me 29:0:14
+}
+
+sample.longlong {
+ one 29:0:20
+ ten 29:0:21
+ hundred 29:0:22
+ million 29:0:23
+ write_me 29:0:24
+}
+
+sample.float {
+ one 29:0:15
+ ten 29:0:16
+ hundred 29:0:17
+ million 29:0:18
+ write_me 29:0:19
+}
+
+sample.double {
+ one 29:0:25
+ ten 29:0:26
+ hundred 29:0:27
+ million 29:0:28
+ write_me 29:0:29
+}
+
+sample.string {
+ null 29:0:30
+ hullo 29:0:31
+ write_me 29:0:32
+}
+
+sample.aggregate {
+ null 29:0:33
+ hullo 29:0:34
+ write_me 29:0:35
+}
+
+sample.hordes {
+ one 29:0:52
+ two 29:0:53
+}
+
+sample.bad {
+ unknown 29:0:54
+ nosupport 29:0:55
+}
+
+sample.wrap {
+ long 29:0:57
+ ulong 29:0:58
+ longlong 29:0:59
+ ulonglong 29:0:60
+}
+
+sample.dodgey {
+ control 29:0:61
+ value 29:0:62
+}
+
+sample.dynamic {
+ counter 29:0:76
+ discrete 29:0:77
+ instant 29:0:78
+}
+
+sample.scale_step {
+ bytes_up 29:0:65
+ bytes_down 29:0:66
+ count_up 29:0:67
+ count_down 29:0:68
+ time_up_secs 29:0:69
+ time_up_nanosecs 29:0:70
+ none_up 29:0:71
+}
+
+sample.const_rate {
+ value 29:0:72
+ gradient 29:0:73
+}
+
+sampledso {
+ control 30:0:0
+ daemon_pid 30:0:1
+ seconds 30:0:2
+ milliseconds 30:0:3
+ load 30:0:4
+ colour 30:0:5
+ bin 30:0:6
+ bucket 30:0:48
+ part_bin 30:0:50
+ bogus_bin 30:0:51
+ drift 30:0:7
+ step 30:0:8
+ step_counter 30:0:63
+ mirage 30:0:37
+ mirage_longlong 30:0:38
+ write_me 30:0:36
+ lights 30:0:46
+ magnitude 30:0:47
+ sysinfo 30:0:39
+ pdu 30:0:40
+ recv_pdu 30:0:41
+ xmit_pdu 30:0:42
+ noinst 30:0:9
+ needprofile 30:0:49
+ not_ready 30:0:56
+ rapid 30:0:64
+ error_code 30:0:74
+ error_check 30:0:75
+ long
+ longlong
+ float
+ double
+ string
+ aggregate
+ hordes
+ bad
+ wrap
+ dodgey
+ dynamic
+ scale_step
+ const_rate
+}
+
+sampledso.long {
+ one 30:0:10
+ ten 30:0:11
+ hundred 30:0:12
+ million 30:0:13
+ write_me 30:0:14
+}
+
+sampledso.longlong {
+ one 30:0:20
+ ten 30:0:21
+ hundred 30:0:22
+ million 30:0:23
+ write_me 30:0:24
+}
+
+sampledso.float {
+ one 30:0:15
+ ten 30:0:16
+ hundred 30:0:17
+ million 30:0:18
+ write_me 30:0:19
+}
+
+sampledso.double {
+ one 30:0:25
+ ten 30:0:26
+ hundred 30:0:27
+ million 30:0:28
+ write_me 30:0:29
+}
+
+sampledso.string {
+ null 30:0:30
+ hullo 30:0:31
+ write_me 30:0:32
+}
+
+sampledso.aggregate {
+ null 30:0:33
+ hullo 30:0:34
+ write_me 30:0:35
+}
+
+sampledso.hordes {
+ one 30:0:52
+ two 30:0:53
+}
+
+sampledso.bad {
+ unknown 30:0:54
+ nosupport 30:0:55
+}
+
+sampledso.wrap {
+ long 30:0:57
+ ulong 30:0:58
+ longlong 30:0:59
+ ulonglong 30:0:60
+}
+
+sampledso.dodgey {
+ control 30:0:61
+ value 30:0:62
+}
+
+sampledso.dynamic {
+ counter 30:0:76
+ discrete 30:0:77
+ instant 30:0:78
+}
+
+sampledso.scale_step {
+ bytes_up 30:0:65
+ bytes_down 30:0:66
+ count_up 30:0:67
+ count_down 30:0:68
+ time_up_secs 30:0:69
+ time_up_nanosecs 30:0:70
+ none_up 30:0:71
+}
+
+sampledso.const_rate {
+ value 30:0:72
+ gradient 30:0:73
+}
+
+pmcd {
+ datasize 2:0:1
+ numagents 2:0:2
+ numclients 2:0:3
+ timezone 2:0:5
+ simabi 2:0:6
+ version 2:0:7
+ license 2:0:16
+ openfds 2:0:17
+ control
+ pdu_in
+ pdu_out
+ agent
+ pmlogger
+ pmie
+ buf
+}
+
+pmcd.control {
+ debug 2:0:0
+ timeout 2:0:4
+ register 2:0:8
+ traceconn 2:0:9
+ tracepdu 2:0:10
+ tracenobuf 2:0:14
+ tracebufs 2:0:11
+ dumptrace 2:0:12
+ dumpconn 2:0:13
+ sighup 2:0:15
+}
+
+pmcd.pdu_in {
+ error 2:1:0
+ result 2:1:1
+ profile 2:1:2
+ fetch 2:1:3
+ desc_req 2:1:4
+ desc 2:1:5
+ instance_req 2:1:6
+ instance 2:1:7
+ text_req 2:1:8
+ text 2:1:9
+ control_req 2:1:10
+ datax 2:1:11
+ creds 2:1:12
+ pmns_ids 2:1:13
+ pmns_names 2:1:14
+ pmns_child 2:1:15
+ total 2:1:16
+ pmns_traverse 2:1:17
+}
+
+pmcd.pdu_out {
+ error 2:2:0
+ result 2:2:1
+ profile 2:2:2
+ fetch 2:2:3
+ desc_req 2:2:4
+ desc 2:2:5
+ instance_req 2:2:6
+ instance 2:2:7
+ text_req 2:2:8
+ text 2:2:9
+ control_req 2:2:10
+ datax 2:2:11
+ creds 2:2:12
+ pmns_ids 2:2:13
+ pmns_names 2:2:14
+ pmns_child 2:2:15
+ total 2:2:16
+ pmns_traverse 2:2:17
+}
+
+pmcd.agent {
+ type 2:4:0
+ status 2:4:1
+}
+
+pmcd.pmlogger {
+ host 2:3:3
+ port 2:3:0
+ archive 2:3:2
+ pmcd_host 2:3:1
+}
+
+pmcd.pmie {
+ configfile 2:5:0
+ logfile 2:5:1
+ pmcd_host 2:5:2
+ numrules 2:5:3
+ actions 2:5:4
+ eval
+}
+
+pmcd.pmie.eval {
+ true 2:5:5
+ false 2:5:6
+ unknown 2:5:7
+ expected 2:5:8
+ actual 2:5:9
+}
+
+pmcd.buf {
+ alloc 2:0:18
+ free 2:0:19
+}
diff --git a/qa/src/root_pmns b/qa/src/root_pmns
new file mode 100644
index 0000000..104e587
--- /dev/null
+++ b/qa/src/root_pmns
@@ -0,0 +1,2146 @@
+root {
+ news
+ txmon
+ shping
+ simple
+ trivial
+ web
+ webping
+ sample
+ sampledso
+ cisco
+ irix
+ hinv
+ hw
+ pmcd
+ proc
+}
+
+news {
+ articles
+ readers
+}
+
+news.articles {
+ total 28:0:201
+ count 28:0:301
+ last 28:0:302
+}
+
+news.readers {
+ nnrpd 28:0:101
+ rn 28:0:111
+ trn 28:0:112
+ xrn 28:0:113
+ vn 28:0:114
+}
+
+txmon {
+ count 248:0:0
+ ave_time 248:0:1
+ max_time 248:0:2
+ reset_count 248:0:3
+ control
+}
+
+txmon.control {
+ level 248:0:4
+ reset 248:0:5
+}
+
+shping {
+ status 19:0:6
+ error 19:0:10
+ cmd 19:0:7
+ time
+ control
+}
+
+shping.time {
+ real 19:0:0
+ cpu_usr 19:0:1
+ cpu_sys 19:0:2
+}
+
+shping.control {
+ numcmd 19:0:3
+ cycles 19:0:9
+ cycletime 19:0:4
+ timeout 19:0:5
+ debug 19:0:8
+}
+
+simple {
+ numfetch 253:0:0
+ color 253:0:1
+ time
+}
+
+simple.time {
+ user 253:1:2
+ sys 253:1:3
+}
+
+trivial {
+ time 250:0:0
+}
+
+web {
+ config
+ allservers
+ perserver
+}
+
+web.config {
+ numservers 22:0:0
+ catchup 22:0:1
+ catchuptime 22:0:2
+ check 22:0:3
+}
+
+web.allservers {
+ numwatched 22:0:4
+ numalive 22:0:5
+ errors 22:1:6
+ requests
+ bytes
+}
+
+web.allservers.requests {
+ total 22:1:7
+ get 22:1:8
+ head 22:1:9
+ post 22:1:10
+ other 22:1:11
+ size
+}
+
+web.allservers.requests.size {
+ zero 22:1:17
+ le3k 22:1:18
+ le10k 22:1:19
+ le30k 22:1:20
+ le100k 22:1:21
+ le300k 22:1:22
+ le1m 22:1:23
+ le3m 22:1:24
+ gt3m 22:1:25
+ unknown 22:1:66
+}
+
+web.allservers.bytes {
+ total 22:1:12
+ get 22:1:13
+ head 22:1:14
+ post 22:1:15
+ other 22:1:16
+ size
+}
+
+web.allservers.bytes.size {
+ zero 22:1:26
+ le3k 22:1:27
+ le10k 22:1:28
+ le30k 22:1:29
+ le100k 22:1:30
+ le300k 22:1:31
+ le1m 22:1:32
+ le3m 22:1:33
+ gt3m 22:1:34
+}
+
+web.perserver {
+ watched 22:0:35
+ numlogs 22:2:36
+ errors 22:2:37
+ logidletime 22:2:68
+ requests
+ bytes
+}
+
+web.perserver.requests {
+ total 22:2:38
+ get 22:2:39
+ head 22:2:40
+ post 22:2:41
+ other 22:2:42
+ size
+}
+
+web.perserver.requests.size {
+ zero 22:2:48
+ le3k 22:2:49
+ le10k 22:2:50
+ le30k 22:2:51
+ le100k 22:2:52
+ le300k 22:2:53
+ le1m 22:2:54
+ le3m 22:2:55
+ gt3m 22:2:56
+ unknown 22:2:67
+}
+
+web.perserver.bytes {
+ total 22:2:43
+ get 22:2:44
+ head 22:2:45
+ post 22:2:46
+ other 22:2:47
+ size
+}
+
+web.perserver.bytes.size {
+ zero 22:2:57
+ le3k 22:2:58
+ le10k 22:2:59
+ le30k 22:2:60
+ le100k 22:2:61
+ le300k 22:2:62
+ le1m 22:2:63
+ le3m 22:2:64
+ gt3m 22:2:65
+}
+
+webping {
+ active 21:0:8
+ kbytes 21:0:1
+ xferrate 21:0:2
+ count 21:0:3
+ errors
+ perurl
+ time
+ workload
+}
+
+webping.errors {
+ sockerr 21:0:9
+ httperr 21:0:10
+ htmlerr 21:0:11
+ othererr 21:0:12
+}
+
+webping.perurl {
+ kbytes 21:0:19
+ xferrate 21:0:20
+ httpcode 21:0:21
+ time
+}
+
+webping.perurl.time {
+ connect 21:0:22
+ head 21:0:23
+ body 21:0:24
+ total 21:0:25
+}
+
+webping.time {
+ connect 21:0:4
+ head 21:0:5
+ body 21:0:6
+ total 21:0:7
+}
+
+webping.workload {
+ buffersize 21:0:18
+ numread 21:0:13
+ numurls 21:0:14
+ control
+}
+
+webping.workload.control {
+ fxdbufsize 21:0:15
+ pingdelay 21:0:16
+ urldelay 21:0:17
+}
+
+sample {
+ control 29:0:0
+ daemon_pid 29:0:1
+ seconds 29:0:2
+ milliseconds 29:0:3
+ load 29:0:4
+ colour 29:0:5
+ bin 29:0:6
+ bucket 29:0:48
+ part_bin 29:0:50
+ bogus_bin 29:0:51
+ drift 29:0:7
+ step 29:0:8
+ step_counter 29:0:63
+ mirage 29:0:37
+ mirage_longlong 29:0:38
+ write_me 29:0:36
+ lights 29:0:46
+ magnitude 29:0:47
+ sysinfo 29:0:39
+ pdu 29:0:40
+ recv_pdu 29:0:41
+ xmit_pdu 29:0:42
+ noinst 29:0:9
+ needprofile 29:0:49
+ not_ready 29:0:56
+ rapid 29:0:64
+ error_code 29:0:74
+ error_check 29:0:75
+ long
+ longlong
+ float
+ double
+ string
+ aggregate
+ hordes
+ bad
+ wrap
+ dodgey
+ scale_step
+ const_rate
+}
+
+sample.long {
+ one 29:0:10
+ ten 29:0:11
+ hundred 29:0:12
+ million 29:0:13
+ write_me 29:0:14
+}
+
+sample.longlong {
+ one 29:0:20
+ ten 29:0:21
+ hundred 29:0:22
+ million 29:0:23
+ write_me 29:0:24
+}
+
+sample.float {
+ one 29:0:15
+ ten 29:0:16
+ hundred 29:0:17
+ million 29:0:18
+ write_me 29:0:19
+}
+
+sample.double {
+ one 29:0:25
+ ten 29:0:26
+ hundred 29:0:27
+ million 29:0:28
+ write_me 29:0:29
+}
+
+sample.string {
+ null 29:0:30
+ hullo 29:0:31
+ write_me 29:0:32
+}
+
+sample.aggregate {
+ null 29:0:33
+ hullo 29:0:34
+ write_me 29:0:35
+}
+
+sample.hordes {
+ one 29:0:52
+ two 29:0:53
+}
+
+sample.bad {
+ unknown 29:0:54
+ nosupport 29:0:55
+}
+
+sample.wrap {
+ long 29:0:57
+ ulong 29:0:58
+ longlong 29:0:59
+ ulonglong 29:0:60
+}
+
+sample.dodgey {
+ control 29:0:61
+ value 29:0:62
+}
+
+sample.scale_step {
+ bytes_up 29:0:65
+ bytes_down 29:0:66
+ count_up 29:0:67
+ count_down 29:0:68
+ time_up_secs 29:0:69
+ time_up_nanosecs 29:0:70
+ none_up 29:0:71
+}
+
+sample.const_rate {
+ value 29:0:72
+ gradient 29:0:73
+}
+
+sampledso {
+ control 30:0:0
+ daemon_pid 30:0:1
+ seconds 30:0:2
+ milliseconds 30:0:3
+ load 30:0:4
+ colour 30:0:5
+ bin 30:0:6
+ bucket 30:0:48
+ part_bin 30:0:50
+ bogus_bin 30:0:51
+ drift 30:0:7
+ step 30:0:8
+ step_counter 30:0:63
+ mirage 30:0:37
+ mirage_longlong 30:0:38
+ write_me 30:0:36
+ lights 30:0:46
+ magnitude 30:0:47
+ sysinfo 30:0:39
+ pdu 30:0:40
+ recv_pdu 30:0:41
+ xmit_pdu 30:0:42
+ noinst 30:0:9
+ needprofile 30:0:49
+ not_ready 30:0:56
+ rapid 30:0:64
+ error_code 30:0:74
+ error_check 30:0:75
+ long
+ longlong
+ float
+ double
+ string
+ aggregate
+ hordes
+ bad
+ wrap
+ dodgey
+ scale_step
+ const_rate
+}
+
+sampledso.long {
+ one 30:0:10
+ ten 30:0:11
+ hundred 30:0:12
+ million 30:0:13
+ write_me 30:0:14
+}
+
+sampledso.longlong {
+ one 30:0:20
+ ten 30:0:21
+ hundred 30:0:22
+ million 30:0:23
+ write_me 30:0:24
+}
+
+sampledso.float {
+ one 30:0:15
+ ten 30:0:16
+ hundred 30:0:17
+ million 30:0:18
+ write_me 30:0:19
+}
+
+sampledso.double {
+ one 30:0:25
+ ten 30:0:26
+ hundred 30:0:27
+ million 30:0:28
+ write_me 30:0:29
+}
+
+sampledso.string {
+ null 30:0:30
+ hullo 30:0:31
+ write_me 30:0:32
+}
+
+sampledso.aggregate {
+ null 30:0:33
+ hullo 30:0:34
+ write_me 30:0:35
+}
+
+sampledso.hordes {
+ one 30:0:52
+ two 30:0:53
+}
+
+sampledso.bad {
+ unknown 30:0:54
+ nosupport 30:0:55
+}
+
+sampledso.wrap {
+ long 30:0:57
+ ulong 30:0:58
+ longlong 30:0:59
+ ulonglong 30:0:60
+}
+
+sampledso.dodgey {
+ control 30:0:61
+ value 30:0:62
+}
+
+sampledso.scale_step {
+ bytes_up 30:0:65
+ bytes_down 30:0:66
+ count_up 30:0:67
+ count_down 30:0:68
+ time_up_secs 30:0:69
+ time_up_nanosecs 30:0:70
+ none_up 30:0:71
+}
+
+sampledso.const_rate {
+ value 30:0:72
+ gradient 30:0:73
+}
+
+cisco {
+ bandwidth 5:0:5
+ bytes_in 5:0:1
+ bytes_out 5:0:2
+ rate_in 5:0:3
+ rate_out 5:0:4
+}
+
+irix {
+ kernel
+ disk
+ mem
+ swap
+ swapdev
+ network
+ numa
+ node
+ gfx
+ rpc
+ nfs
+ nfs3
+ resource
+ filesys
+ ipc
+ xfs
+ kaio
+ xpc
+ pmda
+ engr
+ xbow
+ xlv
+}
+
+irix.kernel {
+ all
+ percpu
+}
+
+irix.kernel.all {
+ load 1:18:3
+ users 1:18:4
+ pswitch 1:10:3
+ readch 1:10:14
+ writech 1:10:29
+ runocc 1:10:15
+ runque 1:10:16
+ syscall 1:10:19
+ sysexec 1:10:20
+ sysfork 1:10:21
+ sysread 1:10:22
+ syswrite 1:10:23
+ sysother 1:10:59
+ cpu
+ io
+ swap
+ tty
+ intr
+ ipc
+ pty
+ flock
+}
+
+irix.kernel.all.cpu {
+ idle 1:10:7
+ intr 1:10:8
+ sys 1:10:9
+ sxbrk 1:10:10
+ user 1:10:11
+ wait
+}
+
+irix.kernel.all.cpu.wait {
+ total 1:10:12
+ gfxc 1:10:24
+ gfxf 1:10:25
+ io 1:10:26
+ pio 1:10:27
+ swap 1:10:28
+}
+
+irix.kernel.all.io {
+ iget 1:10:13
+ bread 1:10:30
+ bwrite 1:10:31
+ lread 1:10:32
+ lwrite 1:10:33
+ phread 1:10:34
+ phwrite 1:10:35
+ wcancel 1:10:36
+ namei 1:10:37
+ dirblk 1:10:38
+}
+
+irix.kernel.all.swap {
+ swpocc 1:10:17
+ swpque 1:10:18
+}
+
+irix.kernel.all.tty {
+ recvintr 1:10:39
+ xmitintr 1:10:40
+ mdmintr 1:10:41
+ out 1:10:42
+ raw 1:10:43
+ canon 1:10:44
+}
+
+irix.kernel.all.intr {
+ vme 1:10:51
+ non_vme 1:10:52
+}
+
+irix.kernel.all.ipc {
+ msg 1:10:53
+ sema 1:10:54
+}
+
+irix.kernel.all.pty {
+ masterch 1:10:55
+ slavech 1:10:56
+}
+
+irix.kernel.all.flock {
+ alloc 1:10:57
+ inuse 1:10:58
+}
+
+irix.kernel.percpu {
+ pswitch 1:28:3
+ readch 1:28:14
+ writech 1:28:29
+ runocc 1:28:15
+ runque 1:28:16
+ syscall 1:28:19
+ sysexec 1:28:20
+ sysfork 1:28:21
+ sysread 1:28:22
+ syswrite 1:28:23
+ sysother 1:28:59
+ cpu
+ io
+ swap
+ tty
+ intr
+ ipc
+ pty
+ flock
+}
+
+irix.kernel.percpu.cpu {
+ idle 1:28:7
+ intr 1:28:8
+ sys 1:28:9
+ sxbrk 1:28:10
+ user 1:28:11
+ wait
+}
+
+irix.kernel.percpu.cpu.wait {
+ total 1:28:12
+ gfxc 1:28:24
+ gfxf 1:28:25
+ io 1:28:26
+ pio 1:28:27
+ swap 1:28:28
+}
+
+irix.kernel.percpu.io {
+ iget 1:28:13
+ bread 1:28:30
+ bwrite 1:28:31
+ lread 1:28:32
+ lwrite 1:28:33
+ phread 1:28:34
+ phwrite 1:28:35
+ wcancel 1:28:36
+ namei 1:28:37
+ dirblk 1:28:38
+}
+
+irix.kernel.percpu.swap {
+ swpocc 1:28:17
+ swpque 1:28:18
+}
+
+irix.kernel.percpu.tty {
+ recvintr 1:28:39
+ xmitintr 1:28:40
+ mdmintr 1:28:41
+ out 1:28:42
+ raw 1:28:43
+ canon 1:28:44
+}
+
+irix.kernel.percpu.intr {
+ vme 1:28:51
+ non_vme 1:28:52
+}
+
+irix.kernel.percpu.ipc {
+ msg 1:28:53
+ sema 1:28:54
+}
+
+irix.kernel.percpu.pty {
+ masterch 1:28:55
+ slavech 1:28:56
+}
+
+irix.kernel.percpu.flock {
+ alloc 1:28:57
+ inuse 1:28:58
+}
+
+irix.disk {
+ dev
+ ctl
+ all
+}
+
+irix.disk.dev {
+ read 1:80:1
+ write 1:80:2
+ total 1:80:7
+ blkread 1:80:5
+ blkwrite 1:80:6
+ blktotal 1:80:4
+ active 1:80:3
+ response 1:80:8
+ bytes 1:80:15
+ read_bytes 1:80:16
+ write_bytes 1:80:17
+}
+
+irix.disk.ctl {
+ read 1:81:10
+ write 1:81:11
+ total 1:81:9
+ blkread 1:81:15
+ blkwrite 1:81:16
+ blktotal 1:81:14
+ active 1:81:12
+ response 1:81:13
+ bytes 1:81:17
+ read_bytes 1:81:18
+ write_bytes 1:81:19
+ avg_disk
+}
+
+irix.disk.ctl.avg_disk {
+ active 1:81:20
+ response 1:81:21
+}
+
+irix.disk.all {
+ read 1:82:10
+ write 1:82:11
+ total 1:82:9
+ blkread 1:82:15
+ blkwrite 1:82:16
+ blktotal 1:82:14
+ active 1:82:12
+ response 1:82:13
+ bytes 1:82:17
+ read_bytes 1:82:18
+ write_bytes 1:82:19
+ avg_disk
+}
+
+irix.disk.all.avg_disk {
+ active 1:82:20
+ response 1:82:21
+}
+
+irix.mem {
+ freemem 1:18:1
+ availsmem 1:18:5
+ availrmem 1:18:6
+ bufmem 1:18:7
+ physmem 1:18:8
+ dchunkpages 1:18:9
+ pmapmem 1:18:10
+ strmem 1:18:11
+ chunkpages 1:18:12
+ dpages 1:18:13
+ emptymem 1:18:14
+ freeswap 1:11:18
+ halloc 1:11:9
+ heapmem 1:11:10
+ hfree 1:11:11
+ hovhd 1:11:12
+ hunused 1:11:13
+ zfree 1:11:14
+ zonemem 1:11:15
+ zreq 1:11:16
+ iclean 1:11:17
+ bsdnet 1:11:19
+ palloc 1:11:30
+ unmodfl 1:11:31
+ unmodsw 1:11:32
+ fault
+ tlb
+ paging
+ system
+ lpage
+ util
+}
+
+irix.mem.fault {
+ prot
+ addr
+}
+
+irix.mem.fault.prot {
+ total 1:11:1
+ cow 1:11:2
+ steal 1:11:3
+}
+
+irix.mem.fault.addr {
+ total 1:11:4
+ cache 1:11:5
+ demand 1:11:6
+ file 1:11:7
+ swap 1:11:8
+}
+
+irix.mem.tlb {
+ flush 1:11:20
+ invalid 1:11:22
+ rfault 1:11:24
+ sync 1:11:25
+ tfault 1:11:26
+ purge 1:11:27
+ idnew 1:11:21
+ idwrap 1:11:23
+ kvmwrap 1:11:28
+}
+
+irix.mem.paging {
+ reclaim 1:11:29
+}
+
+irix.mem.system {
+ sptalloc 1:11:33
+ sptfree 1:11:34
+ sptclean 1:11:35
+ sptdirty 1:11:36
+ sptintrans 1:11:37
+ sptaged 1:11:38
+ sptbp 1:11:39
+ sptheap 1:11:40
+ sptzone 1:11:41
+ sptpt 1:11:42
+}
+
+irix.mem.lpage {
+ faults 1:41:3
+ allocs 1:41:4
+ downgrade 1:41:5
+ page_splits 1:41:6
+ basesize 1:41:7
+ maxsize 1:41:8
+ maxenabled 1:41:9
+ enabled 1:41:10
+ coalesce
+}
+
+irix.mem.lpage.coalesce {
+ scans 1:41:1
+ success 1:41:2
+}
+
+irix.mem.util {
+ kernel 1:18:15
+ fs_ctl 1:18:16
+ fs_dirty 1:18:17
+ fs_clean 1:18:18
+ free 1:18:19
+ user 1:18:20
+}
+
+irix.swap {
+ in 1:10:5
+ out 1:10:6
+ pagesin 1:10:1
+ pagesout 1:10:2
+ procout 1:10:4
+ free 1:16:6
+ length 1:16:7
+ maxswap 1:16:8
+ vlength 1:16:9
+ alloc 1:16:10
+ reserve 1:16:11
+ used 1:16:12
+ unused 1:16:13
+}
+
+irix.swapdev {
+ free 1:16:1
+ length 1:16:2
+ maxswap 1:16:3
+ vlength 1:16:4
+ priority 1:16:5
+}
+
+irix.network {
+ icmp
+ igmp
+ ip
+ tcp
+ udp
+ interface
+ mbuf
+ mcr
+ socket
+}
+
+irix.network.icmp {
+ error 1:17:52
+ oldshort 1:17:53
+ oldicmp 1:17:54
+ badcode 1:17:55
+ tooshort 1:17:56
+ checksum 1:17:57
+ badlen 1:17:58
+ reflect 1:17:59
+ inhist
+ outhist
+}
+
+irix.network.icmp.inhist {
+ echoreply 1:17:60
+ unreach 1:17:61
+ sourcequench 1:17:62
+ redirect 1:17:63
+ echo 1:17:64
+ routeradvert 1:17:65
+ routersolicit 1:17:66
+ timxceed 1:17:67
+ paramprob 1:17:68
+ tstamp 1:17:69
+ tstampreply 1:17:70
+ ireq 1:17:71
+ ireqreply 1:17:72
+ maskreq 1:17:73
+ maskreply 1:17:74
+}
+
+irix.network.icmp.outhist {
+ echoreply 1:17:75
+ unreach 1:17:76
+ sourcequench 1:17:77
+ redirect 1:17:78
+ echo 1:17:79
+ routeradvert 1:17:80
+ routersolicit 1:17:81
+ timxceed 1:17:82
+ paramprob 1:17:83
+ tstamp 1:17:84
+ tstampreply 1:17:85
+ ireq 1:17:86
+ ireqreply 1:17:87
+ maskreq 1:17:88
+ maskreply 1:17:89
+}
+
+irix.network.igmp {
+ rcv_total 1:17:90
+ rcv_tooshort 1:17:91
+ rcv_badsum 1:17:92
+ rcv_queries 1:17:93
+ rcv_badqueries 1:17:94
+ rcv_reports 1:17:95
+ rcv_badreports 1:17:96
+ rcv_ourreports 1:17:97
+ snd_reports 1:17:98
+}
+
+irix.network.ip {
+ badhlen 1:17:99
+ badlen 1:17:100
+ badoptions 1:17:101
+ badsum 1:17:102
+ cantforward 1:17:103
+ cantfrag 1:17:104
+ delivered 1:17:105
+ forward 1:17:106
+ fragdropped 1:17:107
+ fragmented 1:17:108
+ fragments 1:17:109
+ fragtimeout 1:17:110
+ localout 1:17:111
+ noproto 1:17:112
+ noroute 1:17:113
+ odropped 1:17:114
+ ofragments 1:17:115
+ reassembled 1:17:116
+ redirect 1:17:117
+ tooshort 1:17:118
+ toosmall 1:17:119
+ badvers 1:17:137
+ rawout 1:17:138
+ total 1:17:120
+}
+
+irix.network.tcp {
+ connattempt 1:17:1
+ accepts 1:17:2
+ connects 1:17:3
+ drops 1:17:4
+ conndrops 1:17:5
+ closed 1:17:6
+ segstimed 1:17:7
+ rttupdated 1:17:8
+ delack 1:17:9
+ timeoutdrop 1:17:10
+ rexmttimeo 1:17:11
+ persisttimeo 1:17:12
+ keeptimeo 1:17:13
+ keepprobe 1:17:14
+ keepdrops 1:17:15
+ sndtotal 1:17:16
+ sndpack 1:17:17
+ sndbyte 1:17:18
+ sndrexmitpack 1:17:19
+ sndrexmitbyte 1:17:20
+ sndacks 1:17:21
+ sndprobe 1:17:22
+ sndurg 1:17:23
+ sndwinup 1:17:24
+ sndctrl 1:17:25
+ sndrst 1:17:26
+ rcvtotal 1:17:27
+ rcvpack 1:17:28
+ rcvbyte 1:17:29
+ rcvbadsum 1:17:30
+ rcvbadoff 1:17:31
+ rcvshort 1:17:32
+ rcvduppack 1:17:33
+ rcvdupbyte 1:17:34
+ rcvpartduppack 1:17:35
+ rcvpartdupbyte 1:17:36
+ rcvoopack 1:17:37
+ rcvoobyte 1:17:38
+ rcvpackafterwin 1:17:39
+ rcvbyteafterwin 1:17:40
+ rcvafterclose 1:17:41
+ rcvwinprobe 1:17:42
+ rcvdupack 1:17:43
+ rcvacktoomuch 1:17:44
+ rcvackpack 1:17:45
+ rcvackbyte 1:17:46
+ rcvwinupd 1:17:47
+ pcbcachemiss 1:17:48
+ predack 1:17:49
+ preddat 1:17:50
+ pawsdrop 1:17:51
+ badsyn 1:17:152
+ listendrop 1:17:153
+ persistdrop 1:17:154
+ synpurge 1:17:155
+}
+
+irix.network.udp {
+ ipackets 1:17:121
+ hdrops 1:17:122
+ badsum 1:17:123
+ badlen 1:17:124
+ noport 1:17:125
+ noportbcast 1:17:126
+ fullsock 1:17:127
+ opackets 1:17:128
+ pcbcachemiss 1:17:129
+}
+
+irix.network.interface {
+ collisions 1:25:1
+ mtu 1:25:2
+ noproto 1:25:3
+ baudrate 1:25:4
+ in
+ out
+ total
+}
+
+irix.network.interface.in {
+ errors 1:25:5
+ packets 1:25:6
+ bytes 1:25:7
+ mcasts 1:25:8
+ drops 1:25:9
+}
+
+irix.network.interface.out {
+ errors 1:25:10
+ packets 1:25:11
+ bytes 1:25:12
+ mcasts 1:25:13
+ drops 1:25:14
+ qdrops 1:25:15
+ qlength 1:25:16
+ qmax 1:25:17
+}
+
+irix.network.interface.total {
+ errors 1:25:18
+ packets 1:25:19
+ bytes 1:25:20
+ mcasts 1:25:21
+ drops 1:25:22
+}
+
+irix.network.mbuf {
+ alloc 1:17:130
+ typealloc 1:17:136
+ clustalloc 1:17:131
+ clustfree 1:17:132
+ failed 1:17:133
+ waited 1:17:134
+ drained 1:17:135
+}
+
+irix.network.mcr {
+ mfc_lookups 1:17:139
+ mfc_misses 1:17:140
+ upcalls 1:17:141
+ no_route 1:17:142
+ bad_tunnel 1:17:143
+ cant_tunnel 1:17:144
+ wrong_if 1:17:145
+ upq_ovflw 1:17:146
+ cache_cleanups 1:17:147
+ drop_sel 1:17:148
+ q_overflow 1:17:149
+ pkt2large 1:17:150
+ upq_sockfull 1:17:151
+}
+
+irix.network.socket {
+ type 1:43:1
+ state 1:43:2
+}
+
+irix.numa {
+ routerload 1:39:1
+ migr
+ memory
+ unpegger
+ bouncectl
+ memoryd
+}
+
+irix.numa.migr {
+ threshold 1:39:2
+ intr
+ auto
+ user
+ queue
+ coalesc
+ triggers
+}
+
+irix.numa.migr.intr {
+ total 1:39:3
+ failstate 1:39:4
+ failenabled 1:39:5
+ failfrozen 1:39:6
+}
+
+irix.numa.migr.auto {
+ total 1:39:7
+ in 1:39:8
+ out 1:39:9
+ fail 1:39:10
+ queue_len 1:39:11
+}
+
+irix.numa.migr.user {
+ total 1:39:12
+ in 1:39:13
+ out 1:39:14
+ fail 1:39:15
+ queue_len 1:39:16
+}
+
+irix.numa.migr.queue {
+ total 1:39:17
+ in 1:39:18
+ out 1:39:19
+ fail
+}
+
+irix.numa.migr.queue.fail {
+ total 1:39:20
+ overflow 1:39:21
+ state 1:39:22
+ failq 1:39:23
+}
+
+irix.numa.migr.coalesc {
+ total 1:39:24
+ in 1:39:25
+ out 1:39:26
+ fail 1:39:27
+}
+
+irix.numa.migr.triggers {
+ capacity 1:39:28
+ time 1:39:29
+ traffic 1:39:30
+}
+
+irix.numa.memory {
+ lent 1:39:31
+ replicated
+}
+
+irix.numa.memory.replicated {
+ page_count 1:39:32
+ page_dest 1:39:33
+ page_reuse 1:39:34
+ page_notavail 1:39:35
+ control_refuse 1:39:36
+}
+
+irix.numa.unpegger {
+ calls 1:39:37
+ npages 1:39:38
+ last_npages 1:39:39
+}
+
+irix.numa.bouncectl {
+ calls 1:39:40
+ frozen_pages 1:39:41
+ melt_pages 1:39:42
+ last_melt_pages 1:39:43
+ dampened_pages 1:39:44
+}
+
+irix.numa.memoryd {
+ activations 1:39:45
+ periodic 1:39:46
+}
+
+irix.node {
+ physmem 1:40:1
+ free
+}
+
+irix.node.free {
+ total 1:40:2
+ pages_64k 1:40:3
+ pages_256k 1:40:4
+ pages_1m 1:40:5
+ pages_4m 1:40:6
+ pages_16m 1:40:7
+}
+
+irix.gfx {
+ ioctl 1:10:45
+ ctxswitch 1:10:46
+ swapbuf 1:10:47
+ intr 1:10:48
+ fifonowait 1:10:49
+ fifowait 1:10:50
+}
+
+irix.rpc {
+ client
+ server
+}
+
+irix.rpc.client {
+ badcalls 1:14:1
+ badxid 1:14:2
+ calls 1:14:3
+ newcred 1:14:4
+ retrans 1:14:5
+ timeout 1:14:6
+ wait 1:14:7
+ badverfs 1:14:8
+}
+
+irix.rpc.server {
+ badcalls 1:15:1
+ badlen 1:15:2
+ calls 1:15:3
+ dupage 1:15:4
+ duphits 1:15:5
+ nullrecv 1:15:6
+ xdrcall 1:15:7
+}
+
+irix.nfs {
+ client
+ server
+}
+
+irix.nfs.client {
+ badcalls 1:12:1
+ calls 1:12:2
+ nclget 1:12:3
+ nclsleep 1:12:4
+ reqs 1:12:5
+}
+
+irix.nfs.server {
+ badcalls 1:13:1
+ calls 1:13:2
+ reqs 1:13:3
+}
+
+irix.nfs3 {
+ client
+ server
+}
+
+irix.nfs3.client {
+ badcalls 1:33:1
+ calls 1:33:2
+ nclget 1:33:3
+ nclsleep 1:33:4
+ reqs 1:33:5
+}
+
+irix.nfs3.server {
+ badcalls 1:37:1
+ calls 1:37:2
+ reqs 1:37:3
+}
+
+irix.resource {
+ nproc 1:19:1
+ nbuf 1:19:2
+ hbuf 1:19:3
+ syssegsz 1:19:4
+ maxpmem 1:19:5
+ maxdmasz 1:19:6
+ dquot 1:19:7
+ nstream_queue 1:19:8
+ nstream_head 1:19:9
+ fileovf 1:20:1
+ procovf 1:20:2
+ name_cache
+ buffer_cache
+ vnodes
+ efs
+}
+
+irix.resource.name_cache {
+ hits 1:21:1
+ misses 1:21:2
+ enters 1:21:3
+ dbl_enters 1:21:4
+ long_enter 1:21:5
+ long_look 1:21:6
+ lru_empty 1:21:7
+ purges 1:21:8
+ vfs_purges 1:21:9
+ removes 1:21:10
+ searches 1:21:11
+ stale_hits 1:21:12
+ steps 1:21:13
+}
+
+irix.resource.buffer_cache {
+ getblks 1:22:1
+ getblockmiss 1:22:2
+ getfound 1:22:3
+ getbchg 1:22:4
+ getloops 1:22:5
+ getfree 1:22:6
+ getfreeempty 1:22:7
+ getfreehmiss 1:22:8
+ getfreehmissx 1:22:9
+ getfreealllck 1:22:10
+ getfreedelwri 1:22:11
+ flush 1:22:12
+ flushloops 1:22:13
+ getfreeref 1:22:14
+ getfreerelse 1:22:15
+ getoverlap 1:22:16
+ clusters 1:22:17
+ clustered 1:22:18
+ getfrag 1:22:19
+ getpatch 1:22:20
+ trimmed 1:22:21
+ inserts 1:22:22
+ irotates 1:22:23
+ deletes 1:22:24
+ drotates 1:22:25
+ decomms 1:22:26
+ flush_decomms 1:22:27
+ delrsv 1:22:28
+ delrsvclean 1:22:29
+ delrsvdirty 1:22:30
+ delrsvfree 1:22:31
+ delrsvwait 1:22:32
+}
+
+irix.resource.vnodes {
+ vnodes 1:23:1
+ extant 1:23:2
+ active 1:23:3
+ alloc 1:23:4
+ aheap 1:23:5
+ afree 1:23:6
+ afreeloops 1:23:7
+ get 1:23:8
+ gchg 1:23:9
+ gfree 1:23:10
+ rele 1:23:11
+ reclaim 1:23:12
+ destroy 1:23:13
+ afreemiss 1:23:14
+}
+
+irix.resource.efs {
+ attempts 1:24:1
+ found 1:24:2
+ frecycle 1:24:3
+ missed 1:24:4
+ dup 1:24:5
+ reclaims 1:24:6
+ itobp 1:24:7
+ itobpf 1:24:8
+ iupdat 1:24:9
+ iupacc 1:24:10
+ iupupd 1:24:11
+ iupchg 1:24:12
+ iupmod 1:24:13
+ iupunk 1:24:14
+ iallocrd 1:24:15
+ iallocrdf 1:24:16
+ ialloccoll 1:24:17
+ bmaprd 1:24:18
+ bmapfbm 1:24:19
+ bmapfbc 1:24:20
+ dirupd 1:24:21
+ truncs 1:24:22
+ icreat 1:24:23
+ attrchg 1:24:24
+ readcancel 1:24:25
+}
+
+irix.filesys {
+ capacity 1:27:1
+ used 1:27:2
+ free 1:27:3
+ maxfiles 1:27:4
+ usedfiles 1:27:5
+ freefiles 1:27:6
+ mountdir 1:27:7
+ full 1:27:8
+}
+
+irix.ipc {
+ sem
+ msg
+ shm
+}
+
+irix.ipc.sem {
+ nsems 1:31:1
+ ncnt 1:31:2
+ zcnt 1:31:3
+}
+
+irix.ipc.msg {
+ cbytes 1:30:1
+ qnum 1:30:2
+ qbytes 1:30:3
+}
+
+irix.ipc.shm {
+ segsz 1:29:1
+ nattch 1:29:2
+}
+
+irix.xfs {
+ allocx 1:32:1
+ allocb 1:32:2
+ freex 1:32:3
+ freeb 1:32:4
+ abt_lookup 1:32:5
+ abt_compare 1:32:6
+ abt_insrec 1:32:7
+ abt_delrec 1:32:8
+ blk_mapr 1:32:9
+ blk_mapw 1:32:10
+ blk_unmap 1:32:11
+ add_exlist 1:32:12
+ del_exlist 1:32:13
+ look_exlist 1:32:14
+ cmp_exlist 1:32:15
+ bmbt_lookup 1:32:16
+ bmbt_compare 1:32:17
+ bmbt_insrec 1:32:18
+ bmbt_delrec 1:32:19
+ dir_lookup 1:32:20
+ dir_create 1:32:21
+ dir_remove 1:32:22
+ dir_getdents 1:32:23
+ trans_sync 1:32:24
+ trans_async 1:32:25
+ trans_empty 1:32:26
+ ig_attempts 1:32:27
+ ig_found 1:32:28
+ ig_frecycle 1:32:29
+ ig_missed 1:32:30
+ ig_dup 1:32:31
+ ig_reclaims 1:32:32
+ ig_attrchg 1:32:33
+ log_writes 1:32:34
+ log_blocks 1:32:35
+ log_noiclogs 1:32:36
+ xfsd_bufs 1:32:37
+ xstrat_bytes 1:32:38
+ xstrat_quick 1:32:39
+ xstrat_split 1:32:40
+ write_calls 1:32:41
+ write_bytes 1:32:42
+ write_bufs 1:32:43
+ read_calls 1:32:44
+ read_bytes 1:32:45
+ read_bufs 1:32:46
+ attr_get 1:32:47
+ attr_set 1:32:48
+ attr_remove 1:32:49
+ attr_list 1:32:50
+}
+
+irix.kaio {
+ reads 1:36:3
+ writes 1:36:4
+ read_bytes 1:36:5
+ write_bytes 1:36:6
+ inuse 1:36:2
+ free 1:36:8
+ nobuf 1:36:1
+ proc_maxinuse 1:36:9
+ inprogress 1:36:10
+ errors 1:36:7
+}
+
+irix.xpc {
+ kernel
+ network
+ disk
+}
+
+irix.xpc.kernel {
+ all
+ percpu
+}
+
+irix.xpc.kernel.all {
+ cpu
+ io
+}
+
+irix.xpc.kernel.all.cpu {
+ idle 1:10:60
+ intr 1:10:61
+ sys 1:10:62
+ sxbrk 1:10:63
+ user 1:10:64
+ wait
+}
+
+irix.xpc.kernel.all.cpu.wait {
+ total 1:10:65
+ gfxc 1:10:66
+ gfxf 1:10:67
+ io 1:10:68
+ pio 1:10:69
+ swap 1:10:70
+}
+
+irix.xpc.kernel.all.io {
+ bread 1:10:71
+ bwrite 1:10:72
+ lread 1:10:73
+ lwrite 1:10:74
+ phread 1:10:75
+ phwrite 1:10:76
+ wcancel 1:10:77
+ dirblk 1:10:78
+}
+
+irix.xpc.kernel.percpu {
+ cpu
+ io
+}
+
+irix.xpc.kernel.percpu.cpu {
+ idle 1:28:60
+ intr 1:28:61
+ sys 1:28:62
+ sxbrk 1:28:63
+ user 1:28:64
+ wait
+}
+
+irix.xpc.kernel.percpu.cpu.wait {
+ total 1:28:65
+ gfxc 1:28:66
+ gfxf 1:28:67
+ io 1:28:68
+ pio 1:28:69
+ swap 1:28:70
+}
+
+irix.xpc.kernel.percpu.io {
+ bread 1:28:71
+ bwrite 1:28:72
+ lread 1:28:73
+ lwrite 1:28:74
+ phread 1:28:75
+ phwrite 1:28:76
+ wcancel 1:28:77
+ dirblk 1:28:78
+}
+
+irix.xpc.network {
+ interface
+}
+
+irix.xpc.network.interface {
+ in
+ out
+ total
+}
+
+irix.xpc.network.interface.in {
+ bytes 1:25:23
+}
+
+irix.xpc.network.interface.out {
+ bytes 1:25:24
+}
+
+irix.xpc.network.interface.total {
+ bytes 1:25:25
+}
+
+irix.xpc.disk {
+ dev
+}
+
+irix.xpc.disk.dev {
+ read 1:80:9
+ active 1:80:10
+ blkread 1:80:11
+ response 1:80:12
+ bytes 1:80:18
+ read_bytes 1:80:19
+ write_bytes 1:80:20
+}
+
+irix.pmda {
+ version 1:0:2
+ uname 1:0:3
+ reset 1:0:1
+ debug 1:0:4
+}
+
+irix.engr {
+ one 1:34:1
+ two 1:34:2
+ three 1:34:3
+ four 1:34:4
+}
+
+irix.xbow {
+ switch 1:42:5
+ nports 1:42:6
+ gen 1:42:7
+ active
+ total
+ port
+}
+
+irix.xbow.active {
+ xbows 1:42:3
+ ports 1:42:4
+}
+
+irix.xbow.total {
+ src 1:42:8
+ dst 1:42:9
+ rrcv 1:42:10
+ rxmt 1:42:11
+}
+
+irix.xbow.port {
+ flags 1:42:12
+ src 1:42:13
+ dst 1:42:14
+ rrcv 1:42:15
+ rxmt 1:42:16
+}
+
+irix.xlv {
+ read 1:45:2
+ write 1:45:3
+ read_bytes 1:45:4
+ write_bytes 1:45:5
+ stripe_ops 1:45:6
+ stripe_units 1:45:7
+ aligned
+ unaligned
+ largest_io
+}
+
+irix.xlv.aligned {
+ full_width 1:45:8
+ lt_width 1:45:9
+ gt_width 1:45:10
+ part_unit 1:45:11
+}
+
+irix.xlv.unaligned {
+ full_width 1:45:12
+ lt_width 1:45:13
+ gt_width 1:45:14
+ part_unit 1:45:15
+}
+
+irix.xlv.largest_io {
+ stripes 1:45:16
+ count 1:45:17
+}
+
+hinv {
+ ncpu 1:18:2
+ cpuclock 1:26:1
+ mincpuclock 1:26:10
+ maxcpuclock 1:26:11
+ cputype 1:26:13
+ dcache 1:26:2
+ icache 1:26:3
+ secondarycache 1:26:4
+ machine 1:26:12
+ physmem 1:26:5
+ pmeminterleave 1:26:6
+ ndisk 1:26:7
+ disk_sn 1:80:14
+ nnode 1:26:8
+ nrouter 1:38:0
+ nrouterport 1:38:11
+ interconnect 1:38:13
+ nxbow 1:42:1
+ ncell 1:26:14
+ pagesize 1:26:15
+ nxlv_volumes 1:45:1
+ nfilesys 1:27:9
+ nctl 1:81:22
+ map
+ ctl
+}
+
+hinv.map {
+ cpu 1:26:9
+ disk 1:80:13
+ node 1:39:49
+ router 1:38:1
+ routerport 1:38:12
+ xbow 1:42:2
+}
+
+hinv.ctl {
+ ndisk 1:81:23
+}
+
+hw {
+ r10kevctr
+ router
+ hub
+}
+
+hw.r10kevctr {
+ state 1:35:255
+ cpurev 1:35:254
+ cycles 1:35:0
+ fucomp 1:35:32
+ extint 1:35:12
+ extinv 1:35:13
+ vcc 1:35:14
+ tlb 1:35:23
+ grad
+ issue
+ fail
+ pcache
+ scache
+}
+
+hw.r10kevctr.grad {
+ instrg 1:35:15
+ loadg 1:35:18
+ storeg 1:35:19
+ scondg 1:35:20
+ fp 1:35:21
+}
+
+hw.r10kevctr.issue {
+ instri 1:35:1
+ loadi 1:35:2
+ storei 1:35:3
+ scondi 1:35:4
+ brd 1:35:6
+}
+
+hw.r10kevctr.fail {
+ scondf 1:35:5
+ brmp 1:35:24
+}
+
+hw.r10kevctr.pcache {
+ imiss 1:35:9
+ dmiss 1:35:25
+ wb 1:35:22
+}
+
+hw.r10kevctr.scache {
+ imiss 1:35:10
+ dmiss 1:35:26
+ wb 1:35:7
+ iwaymp 1:35:11
+ dwaymp 1:35:27
+ extinthit 1:35:28
+ extinvhit 1:35:29
+ upclean 1:35:30
+ upshare 1:35:31
+ ecc 1:35:8
+}
+
+hw.router {
+ portmask 1:38:2
+ rev_id 1:38:3
+ send_util 1:38:4
+ retry_errors 1:38:8
+ sn_errors 1:38:9
+ cb_errors 1:38:10
+ type 1:38:22
+ recv
+ perport
+}
+
+hw.router.recv {
+ bypass_util 1:38:5
+ queued_util 1:38:6
+ total_util 1:38:7
+}
+
+hw.router.perport {
+ send_util 1:38:14
+ retry_errors 1:38:18
+ sn_errors 1:38:19
+ cb_errors 1:38:20
+ excess_errors 1:38:21
+ recv
+}
+
+hw.router.perport.recv {
+ bypass_util 1:38:15
+ queued_util 1:38:16
+ total_util 1:38:17
+}
+
+hw.hub {
+ nasid 1:44:8
+ ni
+ ii
+}
+
+hw.hub.ni {
+ retry 1:44:1
+ sn_errors 1:44:2
+ cb_errors 1:44:3
+ overflows 1:44:4
+}
+
+hw.hub.ii {
+ sn_errors 1:44:5
+ cb_errors 1:44:6
+ overflows 1:44:7
+}
+
+pmcd {
+ datasize 2:0:1
+ numagents 2:0:2
+ numclients 2:0:3
+ timezone 2:0:5
+ simabi 2:0:6
+ version 2:0:7
+ license 2:0:16
+ control
+ pdu_in
+ pdu_out
+ agent
+ pmlogger
+}
+
+pmcd.control {
+ debug 2:0:0
+ timeout 2:0:4
+ register 2:0:8
+ traceconn 2:0:9
+ tracepdu 2:0:10
+ tracenobuf 2:0:14
+ tracebufs 2:0:11
+ dumptrace 2:0:12
+ dumpconn 2:0:13
+ sighup 2:0:15
+}
+
+pmcd.pdu_in {
+ error 2:1:0
+ result 2:1:1
+ profile 2:1:2
+ fetch 2:1:3
+ desc_req 2:1:4
+ desc 2:1:5
+ instance_req 2:1:6
+ instance 2:1:7
+ text_req 2:1:8
+ text 2:1:9
+ control_req 2:1:10
+ datax 2:1:11
+ creds 2:1:12
+ pmns_ids 2:1:13
+ pmns_names 2:1:14
+ pmns_child 2:1:15
+ total 2:1:16
+ pmns_traverse 2:1:17
+}
+
+pmcd.pdu_out {
+ error 2:2:0
+ result 2:2:1
+ profile 2:2:2
+ fetch 2:2:3
+ desc_req 2:2:4
+ desc 2:2:5
+ instance_req 2:2:6
+ instance 2:2:7
+ text_req 2:2:8
+ text 2:2:9
+ control_req 2:2:10
+ datax 2:2:11
+ creds 2:2:12
+ pmns_ids 2:2:13
+ pmns_names 2:2:14
+ pmns_child 2:2:15
+ total 2:2:16
+ pmns_traverse 2:2:17
+}
+
+pmcd.agent {
+ type 2:4:0
+ status 2:4:1
+}
+
+pmcd.pmlogger {
+ host 2:3:3
+ port 2:3:0
+ archive 2:3:2
+ pmcd_host 2:3:1
+}
+
+proc {
+ nprocs 3:0:0
+ psinfo
+ pstatus
+ pscred
+ psusage
+ memory
+ accounting
+}
+
+proc.psinfo {
+ state 3:1:0
+ sname 3:1:1
+ zomb 3:1:2
+ nice 3:1:3
+ flag 3:1:4
+ uid 3:1:5
+ gid 3:1:6
+ pid 3:1:7
+ ppid 3:1:8
+ pgrp 3:1:9
+ sid 3:1:10
+ addr 3:1:11
+ size 3:1:12
+ rssize 3:1:13
+ wchan 3:1:15
+ start 3:1:16
+ time 3:1:17
+ pri 3:1:18
+ oldpri 3:1:19
+ cpu 3:1:20
+ ttydev 3:1:21
+ clname 3:1:22
+ fname 3:1:23
+ psargs 3:1:24
+ uname 3:1:25
+ gname 3:1:26
+ ttyname 3:1:27
+ ttymajor 3:1:28
+ ttyminor 3:1:29
+ ctime 3:1:30
+ shareuid 3:1:31
+ pset 3:1:32
+ sonproc 3:1:33
+ spid 3:1:34
+ qtime 3:1:35
+ thds 3:1:36
+ wname 3:1:37
+}
+
+proc.pstatus {
+ flags 3:2:0
+ why 3:2:1
+ what 3:2:2
+ cursig 3:2:3
+ sigpend 3:2:4
+ sighold 3:2:5
+ info 3:2:6
+ altstack 3:2:7
+ action 3:2:8
+ syscall 3:2:9
+ nsysarg 3:2:10
+ errno 3:2:11
+ rval1 3:2:12
+ rval2 3:2:13
+ sysarg 3:2:14
+ pid 3:2:15
+ ppid 3:2:16
+ pgrp 3:2:17
+ sid 3:2:18
+ utime 3:2:19
+ stime 3:2:20
+ cutime 3:2:21
+ cstime 3:2:22
+ clname 3:2:23
+ instr 3:2:24
+ reg 3:2:25
+ nthreads 3:2:26
+ thsigpend 3:2:27
+ who 3:2:28
+}
+
+proc.pscred {
+ euid 3:3:0
+ ruid 3:3:1
+ suid 3:3:2
+ egid 3:3:3
+ rgid 3:3:4
+ sgid 3:3:5
+ ngroups 3:3:6
+}
+
+proc.psusage {
+ tstamp 3:4:0
+ starttime 3:4:1
+ utime 3:4:2
+ stime 3:4:3
+ minf 3:4:4
+ majf 3:4:5
+ utlb 3:4:6
+ nswap 3:4:7
+ gbread 3:4:8
+ bread 3:4:9
+ gbwrit 3:4:10
+ bwrit 3:4:11
+ sigs 3:4:12
+ vctx 3:4:13
+ ictx 3:4:14
+ sysc 3:4:15
+ syscr 3:4:16
+ syscw 3:4:17
+ syscps 3:4:18
+ sysci 3:4:19
+ graphfifo 3:4:20
+ graph_req 3:4:21
+ graph_wait 3:4:22
+ size 3:4:23
+ rss 3:4:24
+ inblock 3:4:25
+ oublock 3:4:26
+ ktlb 3:4:27
+ vfault 3:4:28
+}
+
+proc.memory {
+ virtual
+ physical
+}
+
+proc.memory.virtual {
+ txt 3:5:1
+ dat 3:5:3
+ bss 3:5:5
+ stack 3:5:7
+ shm 3:5:9
+}
+
+proc.memory.physical {
+ txt 3:5:0
+ dat 3:5:2
+ bss 3:5:4
+ stack 3:5:6
+ shm 3:5:8
+}
+
+proc.accounting {
+ flag 3:6:0
+ ash 3:6:1
+ prid 3:6:2
+ timers
+ counts
+}
+
+proc.accounting.timers {
+ utime 3:6:3
+ stime 3:6:4
+ bwtime 3:6:5
+ rwtime 3:6:6
+ qwtime 3:6:7
+}
+
+proc.accounting.counts {
+ mem 3:6:8
+ swaps 3:6:9
+ chr 3:6:10
+ chw 3:6:11
+ br 3:6:12
+ bw 3:6:13
+ syscr 3:6:14
+ syscw 3:6:15
+}
diff --git a/qa/src/rtimetest.c b/qa/src/rtimetest.c
new file mode 100644
index 0000000..51e1ca3
--- /dev/null
+++ b/qa/src/rtimetest.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2013-2014 Red Hat.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public
+ * License for more details.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+void
+set_tm(struct timeval *ntv, struct tm *ntm, struct tm *btm, int mon,
+ int mday, int hour, int min)
+{
+ memcpy(ntm, btm, sizeof(struct tm));
+ if (mon > 0)
+ ntm->tm_mon = mon;
+ if (mday > 0)
+ ntm->tm_mday = mday;
+ if (hour > 0)
+ ntm->tm_hour = hour;
+ if (min > 0)
+ ntm->tm_min = min;
+
+ if (ntv != NULL) {
+ ntv->tv_sec = mktime(ntm);
+ ntv->tv_usec = 0;
+ }
+}
+
+void
+dump_dt(char *str, struct tm *atm)
+{
+ int pfx;
+ printf("\"%s\"%n", str, &pfx);
+ printf("%*s", 31 - pfx, " ");
+ printf("%d-%.2d-%.2d %.2d:%.2d:%.2d\n",
+ atm->tm_year + 1900,
+ atm->tm_mon + 1,
+ atm->tm_mday, atm->tm_hour, atm->tm_min, atm->tm_sec);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct timeval tvstart; // .tv_sec .tv_usec
+ struct timeval tvend;
+ struct timeval tvrslt;
+ struct tm tmstart; // .tm_sec .tm_min .tm_hour .tm_mday
+ // .tm_mon .tm_year .tm_wday .tm_yday
+ struct tm tmend;
+ struct tm tmrslt;
+ struct tm tmtmp;
+ time_t ttstart;
+ char buffer[256];
+ char *errmsg;
+ char *tmtmp_str;
+
+ ttstart = 1392649730; // time(&ttstart) => time_t
+ ttstart = 1390057730;
+ tvstart.tv_sec = ttstart;
+ tvstart.tv_usec = 0;
+ localtime_r(&ttstart, &tmstart); // time_t => tm
+ set_tm(&tvend, &tmend, &tmstart, 0, 27, 11, 28);
+ dump_dt("start ", &tmstart);
+ dump_dt("end ", &tmend);
+
+ printf("These time terms are relative to the start/end time.\n"
+ "#1 __pmParseTime #2 pmParseTimeWindow/Start #3 pmParseTimeWindow/End.\n");
+ set_tm(NULL, &tmtmp, &tmstart, 0, 19, 11, 45);
+ tmtmp_str = asctime(&tmtmp);
+ char *tmtmp_c = strchr(tmtmp_str, '\n');
+ *tmtmp_c = ' ';
+ if (__pmParseTime(tmtmp_str, &tvstart, &tvend, &tvrslt, &errmsg) != 0) {
+ printf ("%s: %s\n", errmsg, tmtmp_str);
+ }
+
+ localtime_r(&tvrslt.tv_sec, &tmrslt); // time_t => tm
+ dump_dt(tmtmp_str, &tmrslt);
+
+ // See strftime for a description of the % formats
+ char *strftime_fmt[] = {
+ "+1minute",
+ "-1 minute",
+ "-1minute",
+ "%F",
+ "%D",
+ "%D %r",
+ "%D %r -1month",
+ "%D %r tomorrow",
+ "%D %r yesterday",
+ "%D %R",
+ "%D %T",
+ "%d %b %Y %X",
+ "1 day ago",
+ "1 week ago",
+ "@%F",
+ "@%D",
+ "@%D %r",
+ "@%D %R",
+ "@%D %T",
+ "@%D %T GMT",
+ "@%d %b %Y %X",
+ "@next day",
+ "@1 day ago",
+ "1 day",
+ "5 minutes 5 seconds",
+ "last week",
+ "last day",
+ "next day",
+ // relative to current time terms begin here
+ "now",
+ "today",
+ "@yesterday",
+ "yesterday",
+ "tomorrow",
+ "sunday",
+ "first sunday",
+ "last monday",
+ "next tuesday"
+ };
+
+ int sfx;
+ for (sfx = 0; sfx < (sizeof(strftime_fmt) / sizeof(void *)); sfx++) {
+ int len = strftime(buffer, sizeof(buffer), strftime_fmt[sfx], &tmtmp);
+ if (len != 0) {
+ struct timeval rsltStart;
+ struct timeval rsltEnd;
+ struct timeval rsltOffset;
+ if (strcmp(strftime_fmt[sfx], "now") == 0)
+ printf
+ ("These time terms for a specific day are relative to the current time.\n");
+ if (__pmParseTime(buffer, &tvstart, &tvend, &tvrslt, &errmsg) != 0) {
+ printf ("%s: %s\n", errmsg, tmtmp_str);
+ }
+ localtime_r(&tvrslt.tv_sec, &tmrslt); // time_t => tm
+ dump_dt(buffer, &tmrslt);
+ if (pmParseTimeWindow(buffer, NULL, NULL, NULL, &tvstart, &tvend, &rsltStart, &rsltEnd, &rsltOffset, &errmsg) < 0) {
+ printf ("%s: %s\n", errmsg, tmtmp_str);
+ }
+ localtime_r(&rsltStart.tv_sec, &tmrslt); // time_t => tm
+ dump_dt(buffer, &tmrslt);
+ localtime_r(&rsltEnd.tv_sec, &tmrslt); // time_t => tm
+ dump_dt(buffer, &tmrslt);
+ }
+ else
+ printf("strftime format \"%s\" not recognized\n",
+ strftime_fmt[sfx]);
+ }
+
+ return 0;
+}
diff --git a/qa/src/sa-sysstat-10.0.1 b/qa/src/sa-sysstat-10.0.1
new file mode 100644
index 0000000..5c46b8f
--- /dev/null
+++ b/qa/src/sa-sysstat-10.0.1
Binary files differ
diff --git a/qa/src/sa-sysstat-10.0.5 b/qa/src/sa-sysstat-10.0.5
new file mode 100644
index 0000000..068d170
--- /dev/null
+++ b/qa/src/sa-sysstat-10.0.5
Binary files differ
diff --git a/qa/src/sa-sysstat-10.2.0 b/qa/src/sa-sysstat-10.2.0
new file mode 100644
index 0000000..80d0623
--- /dev/null
+++ b/qa/src/sa-sysstat-10.2.0
Binary files differ
diff --git a/qa/src/sa-sysstat-9.0.4 b/qa/src/sa-sysstat-9.0.4
new file mode 100644
index 0000000..a3f5ca2
--- /dev/null
+++ b/qa/src/sa-sysstat-9.0.4
Binary files differ
diff --git a/qa/src/sa-sysstat-9.0.6 b/qa/src/sa-sysstat-9.0.6
new file mode 100644
index 0000000..6432923
--- /dev/null
+++ b/qa/src/sa-sysstat-9.0.6
Binary files differ
diff --git a/qa/src/sa-sysstat-9.0.6.1 b/qa/src/sa-sysstat-9.0.6.1
new file mode 100644
index 0000000..7fb6a38
--- /dev/null
+++ b/qa/src/sa-sysstat-9.0.6.1
Binary files differ
diff --git a/qa/src/sa-sysstat-9.1.7 b/qa/src/sa-sysstat-9.1.7
new file mode 100644
index 0000000..37409c4
--- /dev/null
+++ b/qa/src/sa-sysstat-9.1.7
Binary files differ
diff --git a/qa/src/sample-secs.0 b/qa/src/sample-secs.0
new file mode 100644
index 0000000..7a3b89f
--- /dev/null
+++ b/qa/src/sample-secs.0
Binary files differ
diff --git a/qa/src/sample-secs.index b/qa/src/sample-secs.index
new file mode 100644
index 0000000..f074d33
--- /dev/null
+++ b/qa/src/sample-secs.index
Binary files differ
diff --git a/qa/src/sample-secs.meta b/qa/src/sample-secs.meta
new file mode 100644
index 0000000..20abe37
--- /dev/null
+++ b/qa/src/sample-secs.meta
Binary files differ
diff --git a/qa/src/sample_expr.0 b/qa/src/sample_expr.0
new file mode 100644
index 0000000..bf5de05
--- /dev/null
+++ b/qa/src/sample_expr.0
Binary files differ
diff --git a/qa/src/sample_expr.index b/qa/src/sample_expr.index
new file mode 100644
index 0000000..048eb52
--- /dev/null
+++ b/qa/src/sample_expr.index
Binary files differ
diff --git a/qa/src/sample_expr.meta b/qa/src/sample_expr.meta
new file mode 100644
index 0000000..1528e8f
--- /dev/null
+++ b/qa/src/sample_expr.meta
Binary files differ
diff --git a/qa/src/scale.c b/qa/src/scale.c
new file mode 100644
index 0000000..7acf861
--- /dev/null
+++ b/qa/src/scale.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * scale - exercise scale conversion, pmConvScale and pmUnitsStr
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+static pmUnits iu = PMDA_PMUNITS( 0, 1, 1, 0, PM_TIME_SEC, 0 );
+static pmUnits ou = PMDA_PMUNITS( 0, 1, 1, 0, PM_TIME_SEC, 0 );
+
+static int tval[] = { 1, 7200 };
+static int tscale[] =
+ { PM_TIME_NSEC, PM_TIME_USEC, PM_TIME_MSEC, PM_TIME_SEC, PM_TIME_MIN, PM_TIME_HOUR };
+static int sval[] = { 1, 1024*1024 };
+static int sscale[] =
+ { PM_SPACE_BYTE, PM_SPACE_KBYTE, PM_SPACE_MBYTE, PM_SPACE_GBYTE, PM_SPACE_TBYTE };
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ const char *u;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N] ";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-v]";
+ int vflag = 0;
+ pmAtomValue iv;
+ pmAtomValue ov;
+ pmAtomValue tv;
+ int d;
+ int i;
+ int j;
+ int k;
+ int l;
+ int underflow = 0;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:v")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'v': /* verbose */
+ vflag++;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+
+ for (d = 1; d >= -1; d -=2) {
+ iu.dimTime = d;
+ ou.dimTime = d;
+ if (d == 1) {
+ iu.dimCount = -1;
+ ou.dimCount = -1;
+ }
+ else {
+ iu.dimCount = 1;
+ ou.dimCount = 1;
+ }
+ for (i = 0; i < sizeof(tval)/sizeof(tval[0]); i++) {
+ iv.ll = tval[i];
+ for (j = 0; j < sizeof(tscale)/sizeof(tscale[0]); j++) {
+ iu.scaleTime = tscale[j];
+ for (k = 0; k < sizeof(tscale)/sizeof(tscale[0]); k++) {
+ ou.scaleTime = tscale[k];
+
+ if ((sts = pmConvScale(PM_TYPE_64, &iv, &iu, &ov, &ou)) < 0) {
+ printf("convert: %s\n", pmErrStr(sts));
+ }
+ else {
+ if (vflag) {
+ u = pmUnitsStr(&iu);
+ printf("%lld %s", (long long)iv.ll, *u == '\0' ? "none" : u);
+ u = pmUnitsStr(&ou);
+ printf(" -> %lld %s\n", (long long)ov.ll, *u == '\0' ? "none" : u);
+ }
+ if ((sts = pmConvScale(PM_TYPE_64, &ov, &ou, &tv, &iu)) < 0) {
+ printf("reconvert: %s\n", pmErrStr(sts));
+ }
+ else {
+ if (tv.ll != iv.ll) {
+ if (ov.ll == 0)
+ underflow++;
+ else {
+ u = pmUnitsStr(&iu);
+ printf("error? %lld %s", (long long)iv.ll, *u == '\0' ? "none" : u);
+ u = pmUnitsStr(&ou);
+ printf(" -> %lld %s", (long long)ov.ll, *u == '\0' ? "none" : u);
+ u = pmUnitsStr(&iu);
+ printf(" -> %lld %s\n", (long long)tv.ll, *u == '\0' ? "none" : u);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ printf("\nPass 1: plus %d underflows to zero\n\n", underflow);
+ underflow = 0;
+
+ ou.dimTime = 0;
+ iu.dimTime = 0;
+ ou.dimCount = 0;
+ iu.dimCount = 0;
+ ou.dimSpace = 1;
+ iu.dimSpace = 1;
+ iu.scaleTime = PM_TIME_SEC;
+ for (d = 0; d < 4; d +=2) {
+ ou.dimTime = -d;
+ iu.dimTime = -d;
+ for (i = 0; i < sizeof(sval)/sizeof(sval[0]); i++) {
+ iv.ll = sval[i];
+ for (j = 0; j < sizeof(sscale)/sizeof(sscale[0]); j++) {
+ iu.scaleSpace = sscale[j];
+ for (k = 0; k < sizeof(sscale)/sizeof(sscale[0]); k++) {
+ ou.scaleSpace = sscale[k];
+ for (l = 2; l < sizeof(tscale)/sizeof(tscale[0]); l += 2) {
+ ou.scaleTime = tscale[l];
+
+ if ((sts = pmConvScale(PM_TYPE_64, &iv, &iu, &ov, &ou)) < 0) {
+ printf("convert: %s\n", pmErrStr(sts));
+ }
+ else {
+ if (vflag) {
+ u = pmUnitsStr(&iu);
+ printf("%lld %s", (long long)iv.ll, *u == '\0' ? "none" : u);
+ u = pmUnitsStr(&ou);
+ printf(" -> %lld %s\n", (long long)ov.ll, *u == '\0' ? "none" : u);
+ }
+ if ((sts = pmConvScale(PM_TYPE_64, &ov, &ou, &tv, &iu)) < 0) {
+ printf("reconvert: %s\n", pmErrStr(sts));
+ }
+ else {
+ if (tv.ll != iv.ll) {
+ if (ov.ll == 0)
+ underflow++;
+ else {
+ u = pmUnitsStr(&iu);
+ printf("error? %lld %s", (long long)iv.ll, *u == '\0' ? "none" : u);
+ u = pmUnitsStr(&ou);
+ printf(" -> %lld %s", (long long)ov.ll, *u == '\0' ? "none" : u);
+ u = pmUnitsStr(&iu);
+ printf(" -> %lld %s\n", (long long)tv.ll, *u == '\0' ? "none" : u);
+ }
+ }
+ }
+ }
+ if (d == 0)
+ break;
+ }
+ }
+ }
+ }
+ }
+ printf("\nPass 2: plus %d underflows to zero\n", underflow);
+
+ iu.dimSpace = 0;
+ iu.scaleSpace = 0;
+ iu.scaleTime = PM_TIME_MSEC;
+ for (d = 1; d > -2; d -= 2) {
+ iu.dimTime = d;
+ iu.dimCount = -d;
+ for (i = 3; i >= -3; i--) {
+ iu.scaleCount = i;
+ printf("{ %3d,%3d,%3d,%3d,%3d,%3d } %s\n",
+ iu.dimSpace, iu.dimTime, iu.dimCount,
+ iu.scaleSpace, iu.scaleTime, iu.scaleCount,
+ pmUnitsStr(&iu));
+ }
+ }
+ printf("\nPass 3:\n");
+
+ exit(0);
+}
diff --git a/qa/src/section-a.0 b/qa/src/section-a.0
new file mode 100644
index 0000000..fa21a30
--- /dev/null
+++ b/qa/src/section-a.0
Binary files differ
diff --git a/qa/src/section-a.index b/qa/src/section-a.index
new file mode 100644
index 0000000..10204b2
--- /dev/null
+++ b/qa/src/section-a.index
Binary files differ
diff --git a/qa/src/section-a.meta b/qa/src/section-a.meta
new file mode 100644
index 0000000..f595d2a
--- /dev/null
+++ b/qa/src/section-a.meta
Binary files differ
diff --git a/qa/src/section-b.0 b/qa/src/section-b.0
new file mode 100644
index 0000000..40c87af
--- /dev/null
+++ b/qa/src/section-b.0
Binary files differ
diff --git a/qa/src/section-b.index b/qa/src/section-b.index
new file mode 100644
index 0000000..757434d
--- /dev/null
+++ b/qa/src/section-b.index
Binary files differ
diff --git a/qa/src/section-b.meta b/qa/src/section-b.meta
new file mode 100644
index 0000000..48e721d
--- /dev/null
+++ b/qa/src/section-b.meta
Binary files differ
diff --git a/qa/src/section-c.0 b/qa/src/section-c.0
new file mode 100644
index 0000000..a305cd4
--- /dev/null
+++ b/qa/src/section-c.0
Binary files differ
diff --git a/qa/src/section-c.index b/qa/src/section-c.index
new file mode 100644
index 0000000..dbad675
--- /dev/null
+++ b/qa/src/section-c.index
Binary files differ
diff --git a/qa/src/section-c.meta b/qa/src/section-c.meta
new file mode 100644
index 0000000..2813aa6
--- /dev/null
+++ b/qa/src/section-c.meta
Binary files differ
diff --git a/qa/src/section-d.0 b/qa/src/section-d.0
new file mode 100644
index 0000000..b5d4bc4
--- /dev/null
+++ b/qa/src/section-d.0
Binary files differ
diff --git a/qa/src/section-d.index b/qa/src/section-d.index
new file mode 100644
index 0000000..a59b24f
--- /dev/null
+++ b/qa/src/section-d.index
Binary files differ
diff --git a/qa/src/section-d.meta b/qa/src/section-d.meta
new file mode 100644
index 0000000..e3bf01c
--- /dev/null
+++ b/qa/src/section-d.meta
Binary files differ
diff --git a/qa/src/sgi.bf b/qa/src/sgi.bf
new file mode 100644
index 0000000..e2fefc2
--- /dev/null
+++ b/qa/src/sgi.bf
Binary files differ
diff --git a/qa/src/show-args b/qa/src/show-args
new file mode 100755
index 0000000..4fc3ed9
--- /dev/null
+++ b/qa/src/show-args
@@ -0,0 +1,11 @@
+#!/bin/sh
+#
+# quick and dirty "show me your arguments" tool
+
+echo $0 called
+i=1
+for arg
+do
+ echo "arg[$i] $arg"
+ i=`expr $i + 1`
+done
diff --git a/qa/src/simple-resave.csv b/qa/src/simple-resave.csv
new file mode 100644
index 0000000..3cbe531
--- /dev/null
+++ b/qa/src/simple-resave.csv
@@ -0,0 +1,5 @@
+"DATE","Metric A","Metric B","Metric C","Metric D","Metric E"
+26/01/10 01:02,100,200,300,1,"foo bar first"
+26/01/10 05:02,110,200,290,2,"foo bar second"
+26/01/10 09:02,120,200,280,3,"foo bar third"
+26/01/10 13:02,130,200,270,4,"foo bar last"
diff --git a/qa/src/simple-resave.xlsx b/qa/src/simple-resave.xlsx
new file mode 100644
index 0000000..306b903
--- /dev/null
+++ b/qa/src/simple-resave.xlsx
Binary files differ
diff --git a/qa/src/simple.csv b/qa/src/simple.csv
new file mode 100644
index 0000000..d9b9329
--- /dev/null
+++ b/qa/src/simple.csv
@@ -0,0 +1,5 @@
+"DATE";"Metric A";"Metric B";"Metric C";"Metric D";"Metric E"
+26/01/2010 01:02:03;100.00;200.00;300.00;1;"foo bar first"
+26/01/2010 05:02:03;110.00;200.00;290.00;2;"foo bar second"
+26/01/2010 09:02:03;120.00;200.00;280.00;3;"foo bar third"
+26/01/2010 13:02:03;130.00;200.00;270.00;4;"foo bar last"
diff --git a/qa/src/simple.ods b/qa/src/simple.ods
new file mode 100644
index 0000000..b4491d4
--- /dev/null
+++ b/qa/src/simple.ods
Binary files differ
diff --git a/qa/src/simple.sxc b/qa/src/simple.sxc
new file mode 100644
index 0000000..163539c
--- /dev/null
+++ b/qa/src/simple.sxc
Binary files differ
diff --git a/qa/src/simple.xls b/qa/src/simple.xls
new file mode 100644
index 0000000..d875c31
--- /dev/null
+++ b/qa/src/simple.xls
Binary files differ
diff --git a/qa/src/simple.xlsx b/qa/src/simple.xlsx
new file mode 100644
index 0000000..3d804bc
--- /dev/null
+++ b/qa/src/simple.xlsx
Binary files differ
diff --git a/qa/src/slow.0 b/qa/src/slow.0
new file mode 100644
index 0000000..39230c0
--- /dev/null
+++ b/qa/src/slow.0
Binary files differ
diff --git a/qa/src/slow.index b/qa/src/slow.index
new file mode 100644
index 0000000..63b3f9e
--- /dev/null
+++ b/qa/src/slow.index
Binary files differ
diff --git a/qa/src/slow.meta b/qa/src/slow.meta
new file mode 100644
index 0000000..fe60e74
--- /dev/null
+++ b/qa/src/slow.meta
Binary files differ
diff --git a/qa/src/slow_af.c b/qa/src/slow_af.c
new file mode 100644
index 0000000..78ad458
--- /dev/null
+++ b/qa/src/slow_af.c
@@ -0,0 +1,152 @@
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static struct timeval start;
+
+#ifdef IS_MINGW
+void pause(void) { SleepEx(INFINITE, TRUE); }
+#endif
+
+static int reg[4];
+
+static void
+printstamp(struct timeval *tp)
+{
+ static struct tm *tmp;
+ time_t tt = (time_t)tp->tv_sec;
+
+ tmp = localtime(&tt);
+ fprintf(stderr, "%02d:%02d:%02d.%06d", tmp->tm_hour, tmp->tm_min, tmp->tm_sec, (int)tp->tv_usec);
+}
+
+void
+onevent(int afid, void *data)
+{
+ struct timeval now;
+ static int delay = -3;
+ int evnum;
+ double elapsed;
+ struct timeval sec = { 0, 0 };
+
+ gettimeofday(&now, NULL);
+
+ if (pmDebug & DBG_TRACE_AF) {
+ fprintf(stderr, "onevent(%d, " PRINTF_P_PFX "%p) called: ", afid, data);
+ printstamp(&now);
+ fputc('\n', stderr);
+ }
+
+ elapsed = now.tv_sec - start.tv_sec + (double)(now.tv_usec - start.tv_usec) / 1000000.0;
+
+ if (afid == reg[2])
+ printf("event %d callback\n", afid);
+ else {
+ if (afid == reg[0])
+ evnum = (int)(elapsed / 2.5);
+ else
+ evnum = (int)(elapsed / 1.5);
+ /* evnum not reliable for small elapsed intervals */
+ if (evnum >= 3)
+ printf("event %d callback #%d\n", afid, evnum);
+ else
+ printf("event %d callback #?\n", afid);
+ }
+
+ if (delay > 6) {
+ /* only report the unexpected */
+ if (__pmAFunregister(reg[0]) < 0)
+ printf("unregister %d failed\n", reg[0]);
+ if (__pmAFunregister(reg[1]) == 0)
+ printf("unregister %d success\n", reg[1]);
+ if (__pmAFunregister(reg[2]) == 0)
+ printf("unregister %d success\n", reg[2]);
+ if (__pmAFunregister(reg[3]) < 0)
+ printf("unregister %d failed\n", reg[0]);
+ exit(0);
+ }
+ if (delay > 0) {
+ /*
+ * was sginap(delay * CLK_TCK) ... usleep() for
+ * delay*CLK_TCK*10^6/CLK_TCK microseconds so "delay" sec
+ */
+ sec.tv_sec = delay;
+ __pmtimevalSleep(sec);
+ }
+ delay++;
+
+ if (pmDebug & DBG_TRACE_AF) {
+ gettimeofday(&now, NULL);
+ fprintf(stderr, "onevent done: ");
+ printstamp(&now);
+ fputc('\n', stderr);
+ }
+
+ fflush(stderr);
+ fflush(stdout);
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ struct timeval delta = { 2, 500000 };
+ struct timeval now;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:?")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -D debug standard PCP debug flag\n",
+ pmProgname);
+ exit(1);
+ }
+
+ __pmAFblock();
+ gettimeofday(&start, NULL);
+ reg[0] = __pmAFregister(&delta, NULL, onevent);
+ delta.tv_sec = 1;
+ reg[1] = __pmAFregister(&delta, NULL, onevent);
+ delta.tv_sec = 0;
+ delta.tv_usec = 0;
+ reg[2] = __pmAFregister(&delta, NULL, onevent);
+ delta.tv_sec = 60; /* will never fire */
+ reg[3] = __pmAFregister(&delta, NULL, onevent);
+ __pmAFunblock();
+
+ for ( ; ; ) {
+ fflush(stderr);
+ pause();
+ if (pmDebug & DBG_TRACE_AF) {
+ gettimeofday(&now, NULL);
+ fprintf(stderr, "returned from pause(): ");
+ printstamp(&now);
+ fputc('\n', stderr);
+ }
+ }
+}
diff --git a/qa/src/snort-disks.0 b/qa/src/snort-disks.0
new file mode 100644
index 0000000..e19ae7a
--- /dev/null
+++ b/qa/src/snort-disks.0
Binary files differ
diff --git a/qa/src/snort-disks.index b/qa/src/snort-disks.index
new file mode 100644
index 0000000..e4f266a
--- /dev/null
+++ b/qa/src/snort-disks.index
Binary files differ
diff --git a/qa/src/snort-disks.meta b/qa/src/snort-disks.meta
new file mode 100644
index 0000000..329c4b8
--- /dev/null
+++ b/qa/src/snort-disks.meta
Binary files differ
diff --git a/qa/src/store.c b/qa/src/store.c
new file mode 100644
index 0000000..3e4daac
--- /dev/null
+++ b/qa/src/store.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+void
+_compare(pmResult *orp, pmResult *nrp)
+{
+ pmValue *ovp;
+ pmValue *nvp;
+ int i;
+ int j;
+ int delta;
+ int err = 0;
+
+ if (orp->numpmid != nrp->numpmid) {
+ printf("ERROR: numpmid mismatch\n");
+ goto bad;
+ }
+
+ for (i = 0; i < orp->numpmid; i++) {
+ if (orp->vset[i]->numval != nrp->vset[i]->numval) {
+ printf("ERROR: [metric %d] numval mismatch\n", i);
+ err = 1;
+ continue;
+ }
+ if (orp->vset[i]->valfmt != nrp->vset[i]->valfmt) {
+ printf("ERROR: [metric %d] valfmt mismatch\n", i);
+ err = 1;
+ continue;
+ }
+ if (orp->vset[i]->valfmt != PM_VAL_INSITU) {
+ printf("ERROR: [metric %d] bogus valfmt\n", i);
+ err = 1;
+ continue;
+ }
+ for (j = 0; j < orp->vset[i]->numval; j++) {
+ ovp = &orp->vset[i]->vlist[j];
+ nvp = &nrp->vset[i]->vlist[j];
+ delta = ovp->value.lval - nvp->value.lval;
+ if (delta != 0) {
+ printf("ERROR: [metric %d][instance %d] value mismatch\n", i, j);
+ err = 1;
+ if (i == 1 && j == 0)
+ printf("NOTE: this is expected for sampledso.drift\n");
+ }
+ }
+ }
+
+ if (err)
+ goto bad;
+
+ return;
+
+bad:
+
+ __pmDumpResult(stdout, orp);
+ __pmDumpResult(stdout, nrp);
+}
+
+int
+main(int argc, char **argv)
+{
+ int type = PM_CONTEXT_HOST;
+ int c;
+ int sts;
+ int errflag = 0;
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N] ";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-x] [-h hostname] [-n namespace]";
+ int i;
+ int n;
+ char *namelist[20];
+ pmID midlist[20];
+ int numpmid;
+ pmResult *old;
+ pmResult *new;
+ pmResult pr;
+ pmValueSet pvs;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:h:Ln:")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ host = optarg;
+ break;
+
+ case 'L': /* LOCAL, no PMCD */
+ host = NULL;
+ type = PM_CONTEXT_LOCAL;
+ putenv("PMDA_LOCAL_SAMPLE=");
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ printf("%s: Cannot connect standalone on localhost: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ i = 0;
+ namelist[i++] = "sampledso.write_me";
+ namelist[i++] = "sampledso.control";
+ namelist[i++] = "sampledso.long.one";
+ numpmid = i;
+ n = pmLookupName(numpmid, namelist, midlist);
+ if (n < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(n));
+ for (i = 0; i < numpmid; i++) {
+ if (midlist[i] == PM_ID_NULL)
+ printf(" %s is bad\n", namelist[i]);
+ }
+ exit(1);
+ }
+
+ if ((n = pmFetch(numpmid, midlist, &old)) < 0) {
+ printf("pmFetch old: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ old->numpmid--;
+ if ((n = pmStore(old)) < 0) {
+ printf("pmStore no change: %s\n", pmErrStr(n));
+ }
+ if ((n = pmFetch(numpmid - 1, midlist, &new)) < 0) {
+ printf("pmFetch new: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ else {
+ _compare(old, new);
+ pmFreeResult(new);
+ }
+
+ old->vset[0]->vlist[0].value.lval++;
+ if ((n = pmStore(old)) < 0) {
+ printf("pmStore change: %s\n", pmErrStr(n));
+ }
+ if ((n = pmFetch(numpmid - 1, midlist, &new)) < 0) {
+ printf("pmFetch new again: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ else {
+ _compare(old, new);
+ pmFreeResult(new);
+ }
+
+ old->vset[0]->vlist[0].value.lval--;
+ if ((n = pmStore(old)) < 0) {
+ printf("pmStore restore: %s\n", pmErrStr(n));
+ }
+ if ((n = pmFetch(numpmid - 1, midlist, &new)) < 0) {
+ printf("pmFetch new once more: %s\n", pmErrStr(n));
+ }
+ else {
+ _compare(old, new);
+ pmFreeResult(new);
+ }
+
+ old->numpmid++; /* cannot change sampledso.long.one */
+ n = pmStore(old);
+ if (n != -EACCES && n != PM_ERR_PERMISSION) {
+ printf("ERROR: expected EACCES or PM_ERR_PERMISSION error\n");
+ printf("pmStore all 3: %s\n", pmErrStr(n));
+ }
+ pmFreeResult(old);
+
+ /*
+ * see http://people.redhat.com/mgoodwin/pcp-cov/1/127dostore.c.html#error
+ */
+ pr.numpmid = 1;
+ pr.vset[0] = &pvs;
+ /* assume BROKEN PMDA is not installed */
+ pr.vset[0]->pmid = pmid_build(249,123,456);
+ pr.vset[0]->numval = 1;
+ pr.vset[0]->valfmt = PM_VAL_INSITU;
+ pr.vset[0]->vlist[0].inst = PM_INDOM_NULL;
+ pr.vset[0]->vlist[0].value.lval = 123456;
+ n = pmStore(&pr);
+ if (n != PM_ERR_NOAGENT) {
+ printf("ERROR: expected PM_ERR_NOAGENT error\n");
+ printf("pmStore bad agent domain: %s\n", pmErrStr(n));
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/storepast.c b/qa/src/storepast.c
new file mode 100644
index 0000000..3898706
--- /dev/null
+++ b/qa/src/storepast.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * storepast - illegal pmStore wrt to current
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ char *host = NULL; /* pander to gcc */
+ char local[MAXHOSTNAMELEN];
+ char *namespace = PM_NS_DEFAULT;
+ pmResult req;
+ char *name = "sample.write_me";
+ pmID pmid;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:h:n:")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options:\n\
+ -a archive use archive log, not host source\n\
+ -D N set pmDebug debugging flag to N\n\
+ -h hostname connect to PMCD on this host\n\
+ -n namespace alternative PMNS specification file\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_HOST) {
+ struct timeval back;
+ gettimeofday(&back, (struct timezone *)0);
+ back.tv_sec -= 3600; /* an hour ago */
+ if ((sts = pmSetMode(PM_MODE_BACK, &back, 0)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ if ((sts = pmLookupName(1, &name, &pmid)) < 0) {
+ printf("%s: pmLookupName: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ req.numpmid = 1;
+ req.vset[0] = (pmValueSet *)malloc(sizeof(pmValueSet));
+ req.vset[0]->pmid = pmid;
+ req.vset[0]->numval = 1;
+ req.vset[0]->valfmt = PM_VAL_INSITU;
+ req.vset[0]->vlist[0].inst = PM_IN_NULL;
+ req.vset[0]->vlist[0].value.lval = 1;
+
+ sts = pmStore(&req);
+
+ printf("pmStore, should produce PM_ERR_NOHOST, ...\n%s\n", pmErrStr(sts));
+
+ exit(0);
+}
diff --git a/qa/src/storepdu.c b/qa/src/storepdu.c
new file mode 100644
index 0000000..08383c7
--- /dev/null
+++ b/qa/src/storepdu.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *host = "localhost";
+ char *namespace = PM_NS_DEFAULT;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N] ";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-h hostname] [-n namespace]";
+ int i;
+ int n;
+ char *namelist[20];
+ pmID midlist[20];
+ int numpmid;
+ pmResult *rslt;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "D:h:n:")) != EOF) {
+ switch (c) {
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* hostname for PMCD to contact */
+ host = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, host)) < 0) {
+ printf("%s: Cannot connect to PMCD on host \"%s\": %s\n", pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ i = 0;
+ namelist[i++] = "sampledso.long.one";
+ namelist[i++] = "sample.long.write_me";
+ numpmid = i;
+ n = pmLookupName(numpmid, namelist, midlist);
+ if (n < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(n));
+ for (i = 0; i < numpmid; i++) {
+ if (midlist[i] == PM_ID_NULL)
+ printf(" %s is bad\n", namelist[i]);
+ }
+ exit(1);
+ }
+
+ if ((n = pmFetch(1, &midlist[0], &rslt)) < 0) {
+ printf("pmFetch rslt: %s\n", pmErrStr(n));
+ exit(1);
+ }
+
+ rslt->vset[0]->pmid = midlist[1];
+ if ((n = pmStore(rslt)) < 0) {
+ printf("pmStore: %s\n", pmErrStr(n));
+ exit(1);
+ }
+ printf("pmStore: ok\n");
+ exit(0);
+}
diff --git a/qa/src/stripmark.c b/qa/src/stripmark.c
new file mode 100644
index 0000000..0809c3f
--- /dev/null
+++ b/qa/src/stripmark.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+/*
+ * filter to copy archive.0 and strip mark records
+ */
+
+int
+main(int argc, char *argv[])
+{
+ int *len;
+ int buflen;
+ char *buf ;
+ int in;
+ int out;
+ int nb;
+ int sts;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: stripmark in.0 out.0\n");
+ exit(1);
+ }
+
+ if ((in = open(argv[1], O_RDONLY)) < 0) {
+ fprintf(stderr, "Failed to open %s: %s\n", argv[1], strerror(errno));
+ exit(1);
+ }
+ if ((out = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
+ fprintf(stderr, "Failed to create %s: %s\n", argv[2], strerror(errno));
+ exit(1);
+ }
+ buflen = sizeof(*len);
+ buf = (char *)malloc(buflen);
+ len = (int *)buf;
+
+ for ( ; ; ) {
+ if ((nb = read(in, buf, sizeof(*len))) != sizeof(*len)) {
+ if (nb == 0) break;
+ if (nb < 0)
+ fprintf(stderr, "read error: %s\n", strerror(errno));
+ else
+ fprintf(stderr, "read error: expected %d bytes, got %d\n",
+ (int)sizeof(*len), nb);
+ exit(1);
+ }
+ if (htonl(*len) > buflen) {
+ buflen = htonl(*len);
+ buf = (char *)realloc(buf, buflen);
+ len = (int *)buf;
+ }
+ if ((nb = read(in, &buf[sizeof(*len)], htonl(*len)-sizeof(*len))) != htonl(*len)-sizeof(*len)) {
+ if (nb == 0)
+ fprintf(stderr, "read error: end of file\n");
+ else if (nb < 0)
+ fprintf(stderr, "read error: %s\n", strerror(errno));
+ else
+ fprintf(stderr, "read error: expected %d bytes, got %d\n",
+ (int)(htonl(*len)-sizeof(*len)), nb);
+ exit(1);
+ }
+ if (htonl(*len) > sizeof(__pmPDUHdr) - sizeof(*len) + sizeof(__pmTimeval) + sizeof(int)) {
+ sts = write(out, buf, htonl(*len));
+ if (sts != htonl(*len)) {
+ fprintf(stderr, "Error: write %d returns %d\n", htonl(*len), sts);
+ exit(1);
+ }
+ }
+ else
+ fprintf(stderr, "Skip mark @ byte %d into input\n", (int)(lseek(in, 0, SEEK_CUR) - sizeof(*len)));
+ }
+ return 0;
+}
diff --git a/qa/src/t_fetch.c b/qa/src/t_fetch.c
new file mode 100644
index 0000000..7c8d6f2
--- /dev/null
+++ b/qa/src/t_fetch.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/* Timeout test for FETCH PDUs in text mode.
+*/
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#define StuffDom(metric, newdom) (((__pmID_int *)&(metric))->domain = (newdom))
+
+#define NMETRICS 3
+
+int
+main(int argc, char *argv[])
+{
+ pmID *ids;
+ pmResult *res;
+ int i, j;
+ int nm;
+ int s;
+ long dom;
+ char *end;
+
+ __pmSetProgname(argv[0]);
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s domain ...\n", pmProgname);
+ exit(1);
+ }
+ if ((ids = (pmID *)malloc((argc - 1) * NMETRICS * sizeof(pmID))) == (pmID *)0) {
+ perror("pmID malloc");
+ exit(1);
+ }
+ nm = 0;
+ for (i = 1; i < argc; i++) {
+ dom = strtol(argv[i], &end, 10);
+ if (*end != '\0') {
+ fprintf(stderr, "'%s' is not a numeric domain\n", argv[1]);
+ exit(1);
+ }
+ for (j = 0; j < NMETRICS; j++) {
+ ids[nm] = 1234;
+ StuffDom(ids[nm], dom);
+ nm++;
+ }
+
+ }
+
+ if ((s = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ fprintf(stderr, "pmNewContext(..., \"localhost\"): %s\n",
+ pmErrStr(s));
+ exit(1);
+ }
+
+ if ((s = pmFetch(nm, ids, &res)) < 0) {
+ fprintf(stderr, "pmFetch: %s\n", pmErrStr(s));
+ exit(1);
+ }
+ else {
+ for (i = 0; i < nm; i++) {
+ if (res->vset[0]->numval == 0)
+ fprintf(stderr, "pmid[%d]: No value(s) returned!\n", i);
+ else if (res->vset[0]->numval < 0)
+ fprintf(stderr, "pmid[%d]: %s\n", i, pmErrStr(res->vset[0]->numval));
+ }
+ }
+
+ exit(0);
+}
diff --git a/qa/src/tabort.c b/qa/src/tabort.c
new file mode 100644
index 0000000..a99b5e1
--- /dev/null
+++ b/qa/src/tabort.c
@@ -0,0 +1,31 @@
+#include <pcp/trace.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ int sts;
+
+ if ((sts = pmtracebegin("foo")) < 0) {
+ fprintf(stderr, "pmtracebegin failed: %s\n", pmtraceerrstr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmtraceabort("foo")) < 0) {
+ fprintf(stderr, "pmtraceabort failed: %s\n", pmtraceerrstr(sts));
+ exit(1);
+ }
+
+ if ((sts = pmtracebegin("foo")) < 0) {
+ fprintf(stderr, "pmtraceabort isn't working properly!\n");
+ exit(1);
+ }
+
+ if ((sts = pmtraceend("foo")) < 0) {
+ fprintf(stderr, "pmtraceend failed: %s\n", pmtraceerrstr(sts));
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/template.c b/qa/src/template.c
new file mode 100644
index 0000000..0cf21f1
--- /dev/null
+++ b/qa/src/template.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ int type = 0;
+ char *host = NULL; /* pander to gcc */
+ int mode = PM_MODE_INTERP; /* mode for archives */
+ char *configfile = NULL;
+ char *start = NULL;
+ char *finish = NULL;
+ char *align = NULL;
+ char *offset = NULL;
+ char *logfile = NULL;
+ pmLogLabel label; /* get hostname for archives */
+ int zflag = 0; /* for -z */
+ char *tz = NULL; /* for -Z timezone */
+ int tzh; /* initial timezone handle */
+ char local[MAXHOSTNAMELEN];
+ char *pmnsfile = PM_NS_DEFAULT;
+ int samples = -1;
+ char *endnum;
+ struct timeval delta = { 1, 0 };
+ struct timeval startTime;
+ struct timeval endTime;
+ struct timeval appStart;
+ struct timeval appEnd;
+ struct timeval appOffset;
+
+ /* trim cmd name of leading directory components */
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:A:c:D:h:l:Ln:O:s:S:t:T:U:zZ:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+#ifdef BUILD_STANDALONE
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+#else
+ fprintf(stderr, "%s: at most one of -a and -h allowed\n", pmProgname);
+#endif
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+ case 'A': /* time alignment */
+ align = optarg;
+ break;
+
+ case 'c': /* configfile */
+ if (configfile != NULL) {
+ fprintf(stderr, "%s: at most one -c option allowed\n", pmProgname);
+ errflag++;
+ }
+ configfile = optarg;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+#ifdef BUILD_STANDALONE
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+#else
+ fprintf(stderr, "%s: at most one of -a and -h allowed\n", pmProgname);
+#endif
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+#ifdef BUILD_STANDALONE
+ case 'L': /* LOCAL, no PMCD */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+ errflag++;
+ }
+ host = NULL;
+ type = PM_CONTEXT_LOCAL;
+ putenv("PMDA_LOCAL_PROC="); /* if proc PMDA needed */
+ putenv("PMDA_LOCAL_SAMPLE="); /* if sampledso PMDA needed */
+ break;
+#endif
+
+ case 'l': /* logfile */
+ logfile = optarg;
+ break;
+
+ case 'n': /* alternative name space file */
+ pmnsfile = optarg;
+ break;
+
+ case 'O': /* sample offset time */
+ offset = optarg;
+ break;
+
+ case 's': /* sample count */
+ samples = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0' || samples < 0) {
+ fprintf(stderr, "%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case 'S': /* start time */
+ start = optarg;
+ break;
+
+ case 't': /* change update interval */
+ if (pmParseInterval(optarg, &delta, &endnum) < 0) {
+ fprintf(stderr, "%s: illegal -t argument\n", pmProgname);
+ fputs(endnum, stderr);
+ free(endnum);
+ errflag++;
+ }
+ break;
+
+ case 'T': /* terminate time */
+ finish = optarg;
+ break;
+
+ case 'U': /* uninterpolated archive log */
+ if (type != 0) {
+#ifdef BUILD_STANDALONE
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -U allowed\n", pmProgname);
+#else
+ fprintf(stderr, "%s: at most one of -a, -h and -U allowed\n", pmProgname);
+#endif
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ mode = PM_MODE_FORW;
+ host = optarg;
+ break;
+
+ case 'z': /* timezone from host */
+ if (tz != NULL) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ zflag++;
+ break;
+
+ case 'Z': /* $TZ timezone */
+ if (zflag) {
+ fprintf(stderr, "%s: at most one of -Z and/or -z allowed\n", pmProgname);
+ errflag++;
+ }
+ tz = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (zflag && type == 0) {
+ fprintf(stderr, "%s: -z requires an explicit -a, -h or -U option\n", pmProgname);
+ errflag++;
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s [options] [metrics ...]\n\
+\n\
+Options:\n\
+ -a archive metrics source is a PCP log archive\n\
+ -A align align sample times on natural boundaries\n\
+ -c configfile file to load configuration from\n\
+ -h host metrics source is PMCD on host\n\
+ -l logfile redirect diagnostics and trace output\n"
+#ifdef BUILD_STANDALONE
+" -L use local context instead of PMCD\n"
+#endif
+" -n pmnsfile use an alternative PMNS\n\
+ -O offset initial offset into the time window\n\
+ -s samples terminate after this many samples\n\
+ -S starttime start of the time window\n\
+ -t interval sample interval [default 1.0 seconds]\n\
+ -T endtime end of the time window\n\
+ -z set reporting timezone to local time of metrics source\n\
+ -Z timezone set reporting timezone\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (logfile != NULL) {
+ __pmOpenLog(pmProgname, logfile, stderr, &sts);
+ if (sts < 0) {
+ fprintf(stderr, "%s: Could not open logfile \"%s\"\n", pmProgname, logfile);
+ }
+ }
+
+ if (pmnsfile != PM_NS_DEFAULT && (sts = pmLoadNameSpace(pmnsfile)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname,
+ pmnsfile, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_HOST;
+ (void)gethostname(local, MAXHOSTNAMELEN);
+ local[MAXHOSTNAMELEN-1] = '\0';
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if (mode != PM_MODE_INTERP) {
+ if ((sts = pmSetMode(mode, &label.ll_start, 0)) < 0) {
+ fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ startTime = label.ll_start;
+ if ((sts = pmGetArchiveEnd(&endTime)) < 0) {
+ endTime.tv_sec = INT_MAX;
+ endTime.tv_usec = 0;
+ fflush(stdout);
+ fprintf(stderr, "%s: Cannot locate end of archive: %s\n",
+ pmProgname, pmErrStr(sts));
+ fprintf(stderr, "\nWARNING: This archive is sufficiently damaged that it may not be possible to\n");
+ fprintf(stderr, " produce complete information. Continuing and hoping for the best.\n\n");
+ fflush(stderr);
+ }
+ }
+ else {
+ gettimeofday(&startTime, NULL);
+ endTime.tv_sec = INT_MAX;
+ }
+
+ if (zflag) {
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+ if (type == PM_CONTEXT_ARCHIVE)
+ printf("Note: timezone set to local timezone of host \"%s\" from archive\n\n",
+ label.ll_hostname);
+ else
+ printf("Note: timezone set to local timezone of host \"%s\"\n\n", host);
+ }
+ else if (tz != NULL) {
+ if ((tzh = pmNewZone(tz)) < 0) {
+ fprintf(stderr, "%s: Cannot set timezone to \"%s\": %s\n",
+ pmProgname, tz, pmErrStr(tzh));
+ exit(1);
+ }
+ printf("Note: timezone set to \"TZ=%s\"\n\n", tz);
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+ while (optind < argc) {
+ printf("extra argument[%d]: %s\n", optind, argv[optind]);
+ optind++;
+ }
+
+ if (align != NULL && type != PM_CONTEXT_ARCHIVE) {
+ fprintf(stderr, "%s: -A option only supported for PCP archives, alignment request ignored\n",
+ pmProgname);
+ align = NULL;
+ }
+
+ sts = pmParseTimeWindow(start, finish, align, offset, &startTime,
+ &endTime, &appStart, &appEnd, &appOffset,
+ &endnum);
+
+ if (sts < 0) {
+ fprintf(stderr, "%s: illegal time window specification\n%s", pmProgname, endnum);
+ exit(1);
+ }
+
+ while (samples == -1 || samples-- > 0) {
+ /* put real stuff here */
+ break;
+ }
+
+ return 0;
+}
diff --git a/qa/src/test_mmv.py b/qa/src/test_mmv.py
new file mode 120000
index 0000000..e407799
--- /dev/null
+++ b/qa/src/test_mmv.py
@@ -0,0 +1 @@
+test_mmv.python \ No newline at end of file
diff --git a/qa/src/test_mmv.python b/qa/src/test_mmv.python
new file mode 100755
index 0000000..255d5c3
--- /dev/null
+++ b/qa/src/test_mmv.python
@@ -0,0 +1,109 @@
+""" Test creation of PCP MMV metrics via the pcp.mmv python module """
+#
+# Copyright (C) 2013 Red Hat Inc.
+#
+# 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.
+#
+
+import sys
+import unittest
+from pcp import mmv, pmapi
+from cpmapi import PM_COUNT_ONE, PM_TIME_USEC
+import cmmv
+
+class TestSequenceFunctions(unittest.TestCase):
+ """ Test driver class for pcp.mmv module verification """
+
+ def test_mmv(self):
+ """ Worker which creates mmv instances, indoms, metrics
+ and ties 'em all together via the MemoryMappedValues
+ class.
+ Once executed, this test create an MMV file that can
+ be queried using pmdammv (by a PCP test driver script).
+ """
+
+ instances = [mmv.mmv_instance(0, "zero"), mmv.mmv_instance(1, "hero")]
+ woodlands = [mmv.mmv_instance(0, "bird"), mmv.mmv_instance(1, "tree"),
+ mmv.mmv_instance(2, "eggs"), mmv.mmv_instance(3, "frog")]
+ indoms = [mmv.mmv_indom(serial = 1,
+ shorttext = "We can be heroes",
+ helptext = "Set of instances from zero to hero"),
+ mmv.mmv_indom(serial = 2)]
+ indoms[0].set_instances(instances)
+ indoms[1].set_instances(woodlands)
+ metrics = [mmv.mmv_metric(name = "counter",
+ item = 1,
+ typeof = cmmv.MMV_TYPE_U32,
+ semantics = cmmv.MMV_SEM_COUNTER,
+ dimension = pmapi.pmUnits(0,0,1,0,0,PM_COUNT_ONE),
+ shorttext = "Example counter metric",
+ helptext = "Yep, a test counter metric"),
+ mmv.mmv_metric(name = "instant",
+ item = 2,
+ typeof = cmmv.MMV_TYPE_I32,
+ semantics = cmmv.MMV_SEM_INSTANT,
+ dimension = pmapi.pmUnits(0,0,0,0,0,0),
+ shorttext = "Example instant metric",
+ helptext = "Yep, a test instantaneous metric"),
+ mmv.mmv_metric(name = "indom",
+ item = 3,
+ typeof = cmmv.MMV_TYPE_U32,
+ semantics = cmmv.MMV_SEM_DISCRETE,
+ dimension = pmapi.pmUnits(0,0,0,0,0,0),
+ indom = 1),
+ mmv.mmv_metric(name = "interval",
+ item = 4,
+ typeof = cmmv.MMV_TYPE_ELAPSED,
+ semantics = cmmv.MMV_SEM_COUNTER,
+ dimension = pmapi.pmUnits(0,1,0,0,PM_TIME_USEC,0),
+ indom = 2),
+ mmv.mmv_metric(name = "string",
+ item = 5,
+ typeof = cmmv.MMV_TYPE_STRING,
+ dimension = pmapi.pmUnits(0,0,0,0,0,0),
+ semantics = cmmv.MMV_SEM_INSTANT),
+ mmv.mmv_metric(name = "strings",
+ item = 6,
+ typeof = cmmv.MMV_TYPE_STRING,
+ semantics = cmmv.MMV_SEM_INSTANT,
+ dimension = pmapi.pmUnits(0,0,0,0,0,0),
+ indom = 1,
+ shorttext = "test string metrics",
+ helptext = "Yep, string metric with instances")]
+
+ values = mmv.MemoryMappedValues("test")
+ self.assertTrue(values != None)
+ self.assertTrue(values.started() == 0)
+ values.add_indoms(indoms)
+ self.assertTrue(values.started() == 0)
+ values.add_metrics(metrics)
+ self.assertTrue(values.started() == 0)
+
+ values.start()
+ self.assertTrue(values.started() == 1)
+ caliper = values.lookup_interval_start("interval", "eggs")
+ self.assertTrue(caliper != None)
+ instant = values.lookup_mapping("instant", None)
+ self.assertTrue(instant != None)
+ values.add(instant, 41)
+ values.inc(instant)
+ values.interval_end(caliper)
+ values.stop()
+ self.assertTrue(values.started() == 0)
+
+ # verification of the metrics values, semantics, indoms
+ # and so on is performed in conjunction with pmdammv in
+ # a driver script in the pcp/qa sources
+
+if __name__ == '__main__':
+
+ sys.exit(unittest.main())
+
diff --git a/qa/src/test_pcp.py b/qa/src/test_pcp.py
new file mode 120000
index 0000000..8ad37ac
--- /dev/null
+++ b/qa/src/test_pcp.py
@@ -0,0 +1 @@
+test_pcp.python \ No newline at end of file
diff --git a/qa/src/test_pcp.python b/qa/src/test_pcp.python
new file mode 100755
index 0000000..e165705
--- /dev/null
+++ b/qa/src/test_pcp.python
@@ -0,0 +1,481 @@
+#
+# Copyright (C) 2012-2014 Red Hat Inc.
+#
+# 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.
+#
+
+import sys
+import unittest
+from pcp import pmapi
+import cpmapi as api
+
+# Utilities
+
+def dump_seq(name_p, seq_p):
+ print(name_p)
+ for text in seq_p:
+ if type(text) == type(int()) or type(text) == type(long()):
+ print(hex(text))
+ else:
+ print(text)
+ print('')
+
+def dump_array_ptrs(name_p, arr_p):
+ print(name_p)
+ for i in xrange(len(arr_p)):
+ if (i > 0):
+ print(" ", arr_p[i].contents)
+ else:
+ print(arr_p[i].contents)
+
+def dump_array(name_p, arr_p):
+ print(name_p)
+ for i in xrange(len(arr_p)):
+ if (i > 0):
+ print(" ", hex(arr_p[i]))
+ else:
+ print(hex(arr_p[i]))
+
+ARCHIVE = "" # For testing either localhost or archive
+
+TRAVERSE_CALLBACK_COUNT = 0 # callback for pmTraversePMNS
+
+def traverse_callback(arg):
+ global TRAVERSE_CALLBACK_COUNT
+ TRAVERSE_CALLBACK_COUNT += 1
+
+def test_pcp(self):
+
+ if (ARCHIVE == ""):
+ print('Running as localhost')
+ ctx = pmapi.pmContext(api.PM_CONTEXT_HOST, "localhost")
+ self.local_type = True
+ else:
+ print('Running as archive', ARCHIVE)
+ ctx = pmapi.pmContext(api.PM_CONTEXT_ARCHIVE, ARCHIVE)
+ self.archive_type = True
+
+ # pmGetContextHostName
+ hostname = ctx.pmGetContextHostName()
+ print("pmGetContextHostName:", hostname)
+ self.assertTrue(len(hostname) >= 0)
+
+ # pmParseMetricSpec
+ source = 'localhost'
+ try:
+ (rsltp, errmsg) = ctx.pmParseMetricSpec("kernel.all.load", 0, source)
+ print("pmParseMetricSpec:", rsltp.contents.source)
+ self.assertTrue(rsltp.contents.source == source)
+ except pmapi.pmErr as error:
+ print("pmParseMetricSpec error: ", error)
+
+ # Get number of cpus
+ # pmLookupName
+ try:
+ self.ncpu_id = ctx.pmLookupName(("hinv.ncpu", "kernel.all.load", "hinv.machine"))
+ print("pmLookupName:", self.ncpu_id)
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ self.assertTrue(False)
+
+ # pmIDStr
+ print("pmIDStr:", ctx.pmIDStr(self.ncpu_id[0]))
+ self.assertTrue(ctx.pmIDStr(self.ncpu_id[0]).count(".") > 1)
+
+ # pmLookupDesc
+ try:
+ descs = ctx.pmLookupDescs(self.ncpu_id)
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ self.assertTrue(False)
+
+ # pmFetch
+ try:
+ results = ctx.pmFetch(self.ncpu_id)
+ print("pmFetch:", results)
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmFetch: ", error)
+ self.assertTrue(False)
+
+ # pmExtractValue
+ atom = ctx.pmExtractValue(results.contents.get_valfmt(0),
+ results.contents.get_vlist(0, 0),
+ descs[0].contents.type,
+ api.PM_TYPE_U32)
+ self.assertTrue(atom.ul > 0)
+ print("pmExtractValue:", atom.ul)
+ atom = ctx.pmExtractValue(results.contents.get_valfmt(0),
+ results.contents.get_vlist(2, 0),
+ descs[0].contents.type,
+ api.PM_TYPE_U32)
+ machine_u32 = atom.ll
+ atom = ctx.pmExtractValue(results.contents.get_valfmt(2),
+ results.contents.get_vlist(2, 0),
+ descs[2].contents.type,
+ api.PM_TYPE_STRING)
+ machine_vp = atom.vp
+ self.assertTrue(machine_u32 != machine_vp)
+ self.assertTrue(type(atom.cp) == type(''))
+
+ # pmGetChildren
+ if not self.archive_type:
+ gcs = ctx.pmGetChildren("kernel")
+ print("pmGetChildren:", gcs)
+ self.assertTrue(len(gcs) >=2)
+
+ # pmGetChildrenStatus
+ gcs = ctx.pmGetChildrenStatus("kernel")
+ print("pmGetChildrenStatus:", gcs)
+ self.assertTrue(len(gcs[0]) == len(gcs[1]))
+
+ # pmGetPMNSLocation
+ index = ctx.pmGetPMNSLocation()
+ print("pmGetPMNSLocation:", index)
+ self.assertTrue(index == api.PMNS_ARCHIVE or
+ index == api.PMNS_LOCAL or
+ index == api.PMNS_REMOTE)
+
+ # pmTraversePMNS
+ ctx.pmTraversePMNS("kernel", traverse_callback)
+ print("pmTraversePMNS:", TRAVERSE_CALLBACK_COUNT)
+ self.assertTrue(TRAVERSE_CALLBACK_COUNT > 0)
+
+ # pmLookupName
+ try:
+ badid = ctx.pmLookupName("A_BAD_METRIC")
+ self.assertTrue(False)
+ except pmapi.pmErr as error:
+ print("pmLookupName:", error)
+ self.assertTrue(True)
+
+ metrics = ("no.such.metric.name", "sample.bin")
+ try:
+ pmidlist = ctx.pmLookupName(metrics, relaxed = 1)
+ print("pmLookupName relaxed mode", metrics)
+ self.assertTrue(len(pmidlist) == 2)
+ self.assertTrue(pmidlist[0] == api.PM_ID_NULL)
+ self.assertTrue(pmidlist[1] != api.PM_ID_NULL)
+ except pmapi.pmErr as error:
+ print("pmLookupName relaxed mode:", error)
+ self.assertTrue(False)
+
+ metrics = ("kernel.all.load", "sample.bin",
+ "kernel.percpu.cpu.sys", "mem.freemem")
+ try:
+ self.metric_ids = ctx.pmLookupName(metrics)
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmLookupName:", error)
+ self.assertTrue(False)
+ dump_array("pmLookupName", self.metric_ids)
+ self.assertTrue(len(self.metric_ids) == 4)
+
+ for i in xrange(len(metrics)):
+ # pmNameAll
+ nameall = ctx.pmNameAll(self.metric_ids[i])
+ print("pmNameAll:", nameall[0])
+ self.assertTrue(nameall[0] == metrics[i])
+
+ # pmNameID
+ name = ctx.pmNameID(self.metric_ids[i])
+ print("pmNameID:", name)
+ self.assertTrue(name == metrics[i])
+
+ # pmLookupDesc
+ descs = ctx.pmLookupDescs(self.metric_ids[i])
+ dump_array_ptrs("pmLookupDesc", descs)
+ self.assertTrue(len(descs) == 1)
+
+ descs = ctx.pmLookupDescs(self.metric_ids)
+ if self.local_type:
+ # pmGetInDom - sample.bin
+ (inst, name) = ctx.pmGetInDom(descs[1])
+ print("pmGetInDom:", name)
+ self.assertTrue(len(inst) == 9 and len(name) == 9)
+ else:
+ # pmGetInDomArchive - sample.bin
+ (inst, name) = ctx.pmGetInDomArchive(descs[1])
+ print("pmGetInDomArchive:", name)
+ self.assertTrue(len(inst) == 9 and len(name) == 9)
+
+ # pmInDomStr
+ indomstr = ctx.pmInDomStr(descs[0])
+ print("pmInDomStr:", indomstr)
+ self.assertTrue(indomstr.count(".") >= 1)
+
+ # pmDelProfile
+ try:
+ ctx.pmDelProfile(descs[0], None)
+ print("pmDelProfile: ok")
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmDelProfile: ", error)
+ self.assertTrue(False)
+
+ if self.local_type:
+ # pmLookupInDom
+ inst1 = ctx.pmLookupInDom(descs[0], "1 minute")
+ print("pmLookupInDom:", inst1)
+ else:
+ # pmLookupInDomArchive
+ inst1 = ctx.pmLookupInDomArchive(descs[0], "1 minute")
+ print("pmLookupInDomArchive:", inst1)
+ self.assertTrue(inst1 >= 0)
+
+ if self.local_type:
+ # pmNameInDom
+ instname = ctx.pmNameInDom(descs[0], inst1)
+ print("pmNameInDom:", instname)
+ else:
+ # pmNameInDomArchive
+ instname = ctx.pmNameInDomArchive(descs[0], inst1)
+ print("pmNameInDomArchive:", instname)
+ self.assertTrue(instname == "1 minute")
+
+ try:
+ # pmLookupInDomText
+ ctx.pmLookupInDomText(descs[0])
+ self.assertTrue(False)
+ except pmapi.pmErr as error:
+ print("pmLookupInDomText:", error)
+ self.assertTrue(True)
+
+ # pmAddProfile
+ try:
+ ctx.pmAddProfile(descs[0], inst1)
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmAddProfile: ", error)
+ self.assertTrue(False)
+
+ inst = 0
+ try:
+ # pmLookupInDom
+ inst = ctx.pmLookupInDom(descs[0], "gg minute")
+ self.assertTrue(False)
+ except pmapi.pmErr as error:
+ print("pmLookupInDom:", error)
+ self.assertTrue(True)
+
+ if self.local_type:
+ # pmLookupInDom
+ inst5 = ctx.pmLookupInDom(descs[0], "5 minute")
+ inst15 = ctx.pmLookupInDom(descs[0], "15 minute")
+ print("pmLookupInDom:", inst5, inst15)
+ else:
+ # pmLookupInDomArchive
+ inst5 = ctx.pmLookupInDomArchive(descs[0], "5 minute")
+ inst15 = ctx.pmLookupInDomArchive(descs[0], "15 minute")
+ print("pmLookupInDomArchive:", inst5, inst15)
+ self.assertTrue(inst15 >= 0)
+
+ # pmAddProfile
+ try:
+ ctx.pmAddProfile(descs[0], inst15)
+ print("pmAddProfile:")
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmAddProfile: ", error)
+ self.assertTrue(False)
+
+ # pmParseInterval
+ try:
+ (delta, errmsg) = ctx.pmParseInterval("3 seconds")
+ print("pmParseInterval:", delta)
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmFetch: ", error)
+ self.assertTrue(False)
+
+ # pmFetch
+ try:
+ results = ctx.pmFetch(self.metric_ids)
+ print("pmFetch:", results)
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmFetch: ", error)
+ self.assertTrue(False)
+
+ # pmSortInstances
+ try:
+ ctx.pmSortInstances(results)
+ print("pmSortInstances: ok")
+ except pmapi.pmErr as error:
+ print("pmSortInstances: ", error)
+ self.assertTrue(False)
+
+ # pmStore
+ try:
+ ctx.pmStore(results)
+ self.assertTrue(False)
+ except pmapi.pmErr as error:
+ print("pmStore: ", error)
+ self.assertTrue(True)
+
+ for i in xrange(results.contents.numpmid):
+ if (results.contents.get_pmid(i) != self.metric_ids[1]):
+ continue
+ for val in xrange(9):
+ # sample.bin - each instance in turn
+ atom = ctx.pmExtractValue(results.contents.get_valfmt(i),
+ results.contents.get_vlist(i, val),
+ descs[i].contents.type,
+ api.PM_TYPE_FLOAT)
+ print("pmExtractValue", val, atom.f)
+ self.assertTrue(99*(val+1) <= atom.f and atom.f <= 101*(val+1))
+
+ # pmExtractValue
+ for i in xrange(results.contents.numpmid):
+ if (results.contents.get_pmid(i) != self.metric_ids[3]):
+ continue
+ # mem.freemem
+ tmpatom = ctx.pmExtractValue(results.contents.get_valfmt(i),
+ results.contents.get_vlist(i, 0),
+ descs[i].contents.type,
+ api.PM_TYPE_FLOAT)
+ self.assertTrue(tmpatom.f > 0)
+
+ # pmConvScale
+ atom = ctx.pmConvScale(api.PM_TYPE_FLOAT, tmpatom, descs, 3,
+ api.PM_SPACE_MBYTE)
+ print("pmConvScale, integer arg", tmpatom.f, atom.f)
+ self.assertTrue(atom.f > 0)
+ atom = ctx.pmConvScale(api.PM_TYPE_FLOAT, tmpatom, descs, 3,
+ pmapi.pmUnits(1,0,0,api.PM_SPACE_MBYTE,0,0))
+ print("pmConvScale, pmUnits arg", tmpatom.f, atom.f)
+ self.assertTrue(atom.f > 0)
+
+ # pmAtomStr
+ atomstr = ctx.pmAtomStr(atom, api.PM_TYPE_FLOAT)
+ print("pmAtomStr", atomstr)
+
+ # pmtimevalSleep
+ ctx.pmtimevalSleep(delta)
+ print("pmtimevalSleep")
+
+ # pmDupContext
+ context = ctx.pmDupContext()
+ print("pmDupContext", context)
+ self.assertTrue(context >= 0)
+
+ # pmWhichContext
+ try:
+ ctx.pmWhichContext()
+ print("pmWhichContext: ok")
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmWhichContext: ", error)
+ self.assertTrue(False)
+
+ # pmTypeStr
+ typestr = ctx.pmTypeStr(api.PM_TYPE_FLOAT)
+ print("pmTypeStr", typestr)
+ self.assertTrue(typestr == "FLOAT")
+
+ if self.archive_type:
+ # pmSetMode
+ try:
+ ctx.pmSetMode(api.PM_MODE_INTERP, results.contents.timestamp, 0)
+ print("pmSetMode: ok")
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmSetMode: ", error)
+ self.assertTrue(False)
+
+
+ # pmGetArchiveLabel
+ try:
+ loglabel = ctx.pmGetArchiveLabel()
+ print("pmGetArchiveLabel: ok")
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmGetArchiveLabel: ", error)
+ self.assertTrue(False)
+
+ # pmGetArchiveEnd
+ try:
+ tval = ctx.pmGetArchiveEnd()
+ print("pmGetArchiveEnd: ", tval)
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmGetArchiveEnd: ", error)
+ self.assertTrue(False)
+
+ # pmPrintValue
+ if not self.archive_type:
+ print("pmPrintValue:")
+ ctx.pmPrintValue(sys.__stdout__, results, descs[0], 0, 0, 8)
+ print('')
+
+ # pmReconnectContext
+ try:
+ ctx.pmReconnectContext()
+ print("pmReconnectContext: ok")
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ print("pmReconnectContext: ", error)
+ self.assertTrue(False)
+
+ # pmRegisterDerived
+ try:
+ ctx.pmRegisterDerived("pcpqa.derivation",
+ "sample.double.bin * delta(sample.double.bin_ctr)")
+ average = ctx.pmLookupName("pcpqa.derivation")
+ descs = ctx.pmLookupDescs(average)
+ results = ctx.pmFetch(average)
+ ctx.pmtimevalSleep(delta)
+ results = ctx.pmFetch(average)
+ atom = ctx.pmExtractValue(results.contents.get_valfmt(0),
+ results.contents.get_vlist(0, 0),
+ descs[0].contents.type,
+ api.PM_TYPE_DOUBLE)
+ self.assertTrue(True)
+ except pmapi.pmErr as error:
+ self.assertTrue(False)
+ try:
+ ctx.pmRegisterDerived("a.bad.expression", "a $ bad @ expression")
+ self.assertTrue(False)
+ except pmapi.pmErr as error:
+ print("pmRegisterDerived: ", ctx.pmDerivedErrStr())
+ self.assertTrue(True)
+
+ # pmFreeResult
+ ctx.pmFreeResult(results)
+ print("pmFreeResult")
+
+ del ctx
+
+class TestSequenceFunctions(unittest.TestCase):
+
+ ncpu_id = []
+ metric_ids = []
+ archive_type = False
+ local_type = False
+
+ def test_context(self):
+ test_pcp(self)
+
+
+if __name__ == '__main__':
+
+ if (len(sys.argv) == 2):
+ ARCHIVE = sys.argv[1]
+ elif (len(sys.argv) > 2):
+ print("Usage: " + sys.argv[0] + " OptionalArchivePath")
+ sys.exit()
+ else:
+ ARCHIVE = ""
+
+ sys.argv[1:] = ()
+
+ STS = unittest.main()
+ sys.exit(STS)
diff --git a/qa/src/test_pcp_getopts.py b/qa/src/test_pcp_getopts.py
new file mode 120000
index 0000000..dc779ed
--- /dev/null
+++ b/qa/src/test_pcp_getopts.py
@@ -0,0 +1 @@
+test_pcp_getopts.python \ No newline at end of file
diff --git a/qa/src/test_pcp_getopts.python b/qa/src/test_pcp_getopts.python
new file mode 100755
index 0000000..776aa92
--- /dev/null
+++ b/qa/src/test_pcp_getopts.python
@@ -0,0 +1,113 @@
+#
+# Copyright (C) 2014 Red Hat.
+#
+# 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.
+#
+
+import sys as system
+from pcp import pmapi
+import cpmapi as c_api
+
+""" Create an options object and set/get everything possible """
+
+options = pmapi.pmOptions("a:bfl:D:h:H:K:LS:T:O:A:s:t:VZ:z?")
+options.pmSetOptionFlags(c_api.PM_OPTFLAG_BOUNDARIES)
+options.pmSetOptionFlags(c_api.PM_OPTFLAG_MULTI)
+options.pmSetOptionFlags(c_api.PM_OPTFLAG_MIXED)
+
+options.pmSetLongOptionHeader("General Options")
+options.pmSetLongOptionAlign()
+options.pmSetLongOptionArchive()
+options.pmSetLongOptionDebug()
+options.pmSetLongOptionGuiMode()
+options.pmSetLongOptionHost()
+options.pmSetLongOptionHostsFile()
+options.pmSetLongOptionSpecLocal()
+options.pmSetLongOptionLocalPMDA()
+options.pmSetLongOptionOrigin()
+options.pmSetLongOptionGuiPort()
+options.pmSetLongOptionStart()
+options.pmSetLongOptionSamples()
+options.pmSetLongOptionFinish()
+options.pmSetLongOptionInterval()
+options.pmSetLongOptionVersion()
+options.pmSetLongOptionTimeZone()
+options.pmSetLongOptionHostZone()
+options.pmSetLongOptionHelp()
+
+# extract any options we can (many are consumed internally) & dump 'em;
+# this test variant focusses on context creation and using time windows.
+
+ctx = c_api.PM_ERR_NOCONTEXT
+try:
+ ctx = pmapi.pmContext.fromOptions(options, system.argv)
+except pmapi.pmUsageErr as usage:
+ usage.message()
+ system.exit(1)
+except pmapi.pmErr as error:
+ print(error)
+
+nonoptions = options.pmNonOptionsFromList(system.argv)
+if nonoptions != None:
+ print("Non-option arguments: %s" % nonoptions)
+
+# for host and archive lists exercise the creation of multiple contexts
+hosts = options.pmGetOptionHosts()
+if hosts != None:
+ print("Host list: %s" % hosts)
+ print("Host %s pmcd.hostname: %s" % (hosts[0], ctx.pmGetContextHostName()))
+ if len(hosts) > 1:
+ typed = c_api.PM_CONTEXT_HOST
+ for index in range(1, len(hosts)):
+ try:
+ ctx = pmapi.pmContext.fromOptions(options, system.argv, typed, index)
+ print("Host %s pmcd.hostname: %s" % (hosts[index], ctx.pmGetContextHostName()))
+ except pmapi.pmErr as error:
+ print("pmContext failed for host %s - %s" %s (hosts[index], error))
+
+archives = options.pmGetOptionArchives()
+if archives != None:
+ print("Archive list: %s" % archives)
+ print("Archive %s hostname: %s" % (archives[0], ctx.pmGetContextHostName()))
+ if len(archives) > 1:
+ typed = c_api.PM_CONTEXT_ARCHIVE
+ for index in range(1, len(archives)):
+ try:
+ ctx = pmapi.pmContext.fromOptions(options, system.argv, typed, index)
+ print("Archive %s hostname: %s" % (archives[index], ctx.pmGetContextHostName()))
+ except pmapi.pmErr as error:
+ print("pmContext failed for archive %s - %s" % (archives[index], error))
+
+timezone = options.pmGetOptionTimezone()
+if timezone != None:
+ print("Timezone: %s" % timezone)
+
+samples = options.pmGetOptionSamples()
+if samples != None:
+ print("Samples: %d" % samples)
+
+interval = options.pmGetOptionInterval()
+if interval != None:
+ print("Interval: %s" % interval)
+
+start = options.pmGetOptionStart()
+if start != None:
+ print("Start: %s" % start)
+
+finish = options.pmGetOptionFinish()
+if finish != None:
+ print("Finish: %s" % finish)
+
+origin = options.pmGetOptionOrigin()
+if origin != None:
+ print("Origin: %s" % origin)
+
+print("Done!")
diff --git a/qa/src/test_pcp_options.py b/qa/src/test_pcp_options.py
new file mode 120000
index 0000000..080f74e
--- /dev/null
+++ b/qa/src/test_pcp_options.py
@@ -0,0 +1 @@
+test_pcp_options.python \ No newline at end of file
diff --git a/qa/src/test_pcp_options.python b/qa/src/test_pcp_options.python
new file mode 100755
index 0000000..2a87249
--- /dev/null
+++ b/qa/src/test_pcp_options.python
@@ -0,0 +1,96 @@
+#
+# Copyright (C) 2014 Red Hat.
+#
+# 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.
+#
+
+import sys as system
+from pcp import pmapi
+import cpmapi as c_api
+
+def optionsCB(opt, optarg, index):
+ arg = "'" + opt + "'"
+ if optarg != None:
+ arg = arg + " (" + optarg + ")"
+ arg = arg + " [index=" + str(index) + "]"
+ print("optionsCB: got option '" + arg)
+
+def overrideCB(opt):
+ print("overrideCB: got option '" + str(opt) + "'")
+ if opt == 'b':
+ return 1
+ return 0
+
+""" Create an options object and set/get everything possible """
+
+options = pmapi.pmOptions("a:bfl:D:h:H:K:LS:T:O:A:s:t:VZ:z?")
+options.pmSetShortUsage("[options] parameters ...")
+
+options.pmSetLongOptionHeader("General Options")
+options.pmSetLongOptionAlign()
+options.pmSetLongOptionArchive()
+options.pmSetLongOptionDebug()
+options.pmSetLongOptionGuiMode()
+options.pmSetLongOptionHost()
+options.pmSetLongOptionHostsFile()
+options.pmSetLongOptionSpecLocal()
+options.pmSetLongOptionLocalPMDA()
+options.pmSetLongOptionOrigin()
+options.pmSetLongOptionGuiPort()
+options.pmSetLongOptionStart()
+options.pmSetLongOptionSamples()
+options.pmSetLongOptionFinish()
+options.pmSetLongOptionInterval()
+options.pmSetLongOptionVersion()
+options.pmSetLongOptionTimeZone()
+options.pmSetLongOptionHostZone()
+options.pmSetLongOptionHelp()
+
+options.pmSetLongOptionHeader("Test Options")
+options.pmSetLongOption("force", 0, 'f', '', "force some behaviour")
+options.pmSetLongOption("list", 1, 'l', "FILE", "open a list file")
+options.pmSetLongOptionText("")
+options.pmSetLongOptionText("The parameter parameter is not optional.")
+
+options.pmSetOptionCallback(optionsCB)
+options.pmSetOverrideCallback(overrideCB)
+
+# parse options, extract values
+if c_api.pmGetOptionsFromList(system.argv) != 0:
+ c_api.pmUsageMessage()
+ system.exit(1)
+
+# extract any options we can (many are consumed internally) & dump
+hosts = options.pmGetOptionHosts()
+if hosts != None:
+ print("Host list: %s" % hosts)
+
+archives = options.pmGetOptionArchives()
+if archives != None:
+ print("Archive list: %s" % archives)
+
+timezone = options.pmGetOptionTimezone()
+if timezone != None:
+ print("Timezone: %s" % timezone)
+
+samples = options.pmGetOptionSamples()
+if samples != None:
+ print("Samples: %d" % samples)
+
+interval = options.pmGetOptionInterval()
+if interval != None:
+ print("Interval: %s" % interval)
+
+nonoptions = options.pmNonOptionsFromList(system.argv)
+if nonoptions != None:
+ print("Non-option arguments: %s" % nonoptions)
+
+print("Done!")
diff --git a/qa/src/test_pcp_time.py b/qa/src/test_pcp_time.py
new file mode 120000
index 0000000..f17979c
--- /dev/null
+++ b/qa/src/test_pcp_time.py
@@ -0,0 +1 @@
+test_pcp_time.python \ No newline at end of file
diff --git a/qa/src/test_pcp_time.python b/qa/src/test_pcp_time.python
new file mode 100755
index 0000000..aa18e6f
--- /dev/null
+++ b/qa/src/test_pcp_time.python
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2014 Red Hat.
+#
+# 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.
+#
+
+""" Exercise the pmCtime and pmLocaltime interfaces """
+
+from pcp import pmapi
+
+""" Create a live PMAPI context, set as UTC and report time """
+context = pmapi.pmContext()
+context.pmNewZone("UTC")
+
+# seconds-since-epoch for: "Mon Feb 3 15:46:19 2014 UTC"
+sample_time_i = 1391402779 # integer
+sample_time_f = 1391402779.0 # float
+
+print("pmLocaltime from int: %s" % str(context.pmLocaltime(sample_time_i)))
+print("pmLocaltime from float: %s" % context.pmLocaltime(sample_time_f))
+
+print("pmCtime from int: %s" % str(context.pmCtime(sample_time_i)).rstrip())
+print("pmCtime from float: %s" % str(context.pmCtime(sample_time_f)).rstrip())
+
+print("pmWhichZone: %s" % str(context.pmWhichZone()))
diff --git a/qa/src/test_pmcc.py b/qa/src/test_pmcc.py
new file mode 120000
index 0000000..9ed0d74
--- /dev/null
+++ b/qa/src/test_pmcc.py
@@ -0,0 +1 @@
+test_pmcc.python \ No newline at end of file
diff --git a/qa/src/test_pmcc.python b/qa/src/test_pmcc.python
new file mode 100644
index 0000000..cc0be3a
--- /dev/null
+++ b/qa/src/test_pmcc.python
@@ -0,0 +1,140 @@
+""" Test metric value extraction/reporting using the pcp.pmcc module """
+#
+# Copyright (C) 2013-2014 Red Hat Inc.
+#
+# 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.
+#
+
+import unittest
+from pcp import pmcc, pmapi
+
+CPU_METRICS = [ "kernel.all.cpu.sys", "kernel.all.cpu.user",
+ "kernel.all.cpu.nice", "kernel.all.cpu.idle", ]
+MEM_METRICS = [ "mem.physmem", "mem.freemem", ]
+DISK_METRICS = [ "disk.all.read", "disk.all.write", "disk.dev.read", ]
+
+class TestPrinter(pmcc.MetricGroupPrinter):
+ """ Report latest values from group manager """
+
+ def unavailable(self, metric):
+ """ Determine whether metric has values for rate conversion """
+ if metric.netValues == None or len(metric.netValues) == 0:
+ return 1
+ if metric.netPrevValues == None or len(metric.netPrevValues) == 0:
+ return 1
+ return 0
+
+ def cpu_print(self, group):
+ """ Report on processor metric group """
+ ticks = {}
+ total = 0.0
+ for name in CPU_METRICS:
+ metric = group[name]
+ if self.unavailable(metric):
+ ticks.update({ name : None })
+ continue
+ # metric.value is the result from pmFetch
+ # metric.netValues is (inst, name, value) from computeValues
+ values = dict(map(lambda x: (x[1], x[2]), metric.netValues))
+ prevs = dict(map(lambda x: (x[1], x[2]), metric.netPrevValues))
+ inst_val = reduce(lambda x, y: x + y,
+ map(lambda x: values[x] - prevs[x], values.keys()))
+ ticks.update({ name : inst_val })
+ total += inst_val
+ for name in CPU_METRICS:
+ if ticks[name] != None:
+ print(" ", name, round(ticks[name] / total * 100, 2), "%")
+ else:
+ print(" ", name, "? %") # no value, first sample usually
+
+ def mem_print(self, group):
+ """ Report on memory metric group """
+ for name in MEM_METRICS:
+ metric = group[name]
+ values = dict(map(lambda x: (x[1], x[2]), metric.netValues))
+
+ for inst_name in values.keys():
+ inst_val = values[inst_name]
+ unit_str = metric.ctx.pmUnitsStr(metric.desc.contents.units)
+ print(" ", name, inst_val, unit_str)
+
+ def disk_print(self, group):
+ """ Report on disk metric group """
+ for name in DISK_METRICS:
+ metric = group[name]
+ values = dict(map(lambda x: (x[1], x[2]), metric.netValues))
+ for inst_name in values.keys():
+ inst_val = values[inst_name]
+ unit_str = metric.ctx.pmUnitsStr(metric.desc.contents.units)
+ print(" ", name, inst_name, inst_val, unit_str)
+
+ def report(self, manager):
+ """ Overrides the base class report, called after each fetch """
+ self.cpu_print(manager["cpu"])
+ self.mem_print(manager["mem"])
+ self.disk_print(manager["disk"])
+
+
+class TestOptions(pmapi.pmOptions):
+ """ Setup a command line option processing object for the test """
+
+ def __init__(self):
+ pmapi.pmOptions.__init__(self, "A:a:D:h:O:S:s:T:t:VZ:z?")
+ self.pmSetLongOptionHeader("General options")
+ self.pmSetLongOptionAlign()
+ self.pmSetLongOptionArchive()
+ self.pmSetLongOptionDebug()
+ self.pmSetLongOptionHost()
+ self.pmSetLongOptionOrigin()
+ self.pmSetLongOptionStart()
+ self.pmSetLongOptionSamples()
+ self.pmSetLongOptionFinish()
+ self.pmSetLongOptionInterval()
+ self.pmSetLongOptionVersion()
+ self.pmSetLongOptionTimeZone()
+ self.pmSetLongOptionHostZone()
+ self.pmSetLongOptionHelp()
+
+class TestConvenienceClasses(unittest.TestCase):
+ """
+ Test driver class for pcp.pmcc module verification
+ """
+
+ def test_context(self):
+ """ Create a metric group manager, add some groups,
+ then cycle, fetching and printing, depending on
+ command line arguments presented.
+ """
+ try:
+ manager = pmcc.MetricGroupManager.builder(OPTS, ARGS)
+ except pmapi.pmUsageErr as usage:
+ return usage.message()
+ self.assertTrue(manager != None)
+ manager.printer = TestPrinter()
+
+ # Each entry is a MetricGroup
+ manager["cpu"] = CPU_METRICS
+ manager["mem"] = MEM_METRICS
+ manager["disk"] = DISK_METRICS
+
+ # Real QA test starts here ;)
+ return manager.run()
+
+
+if __name__ == '__main__':
+ import sys
+ import copy
+ ARGS = copy.deepcopy(sys.argv)
+ OPTS = TestOptions()
+
+ sys.argv[1:] = ()
+ STS = unittest.main()
+ sys.exit(STS)
diff --git a/qa/src/test_pmi.py b/qa/src/test_pmi.py
new file mode 120000
index 0000000..2b6f1d9
--- /dev/null
+++ b/qa/src/test_pmi.py
@@ -0,0 +1 @@
+test_pmi.python \ No newline at end of file
diff --git a/qa/src/test_pmi.python b/qa/src/test_pmi.python
new file mode 100755
index 0000000..2a22a55
--- /dev/null
+++ b/qa/src/test_pmi.python
@@ -0,0 +1,108 @@
+""" Test creation of a PCP archive with metrics via pcp.pmi module """
+#
+# Copyright (C) 2012-2013 Red Hat Inc.
+#
+# 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.
+#
+
+import sys
+import unittest
+import cpmapi
+from pcp import pmi
+from pcp import pmapi
+
+OUTFILE = ""
+
+def test_pmi(self, path = OUTFILE, inherit = 0):
+ """ Worker utility which creates a pmi object and exercises it """
+
+ hostname = "fu.bar.com"
+ timezone = "UTC"
+
+ print("Writing to new PCP archive:", path)
+ log = pmi.pmiLogImport(path, inherit)
+
+ code = log.pmiSetHostname(hostname)
+ print("pmiSetHostname:", hostname)
+ self.assertTrue(code >= 0)
+
+ code = log.pmiSetTimezone(timezone)
+ print("pmiSetTimezone:", timezone)
+ self.assertTrue(code >= 0)
+
+ pmid = log.pmiID(60, 2, 0)
+ indom = log.pmiInDom(60, 2)
+ units = log.pmiUnits(0, 0, 0, 0, 0, 0)
+
+ # create a metric without instances (hinv.ncpu)
+ code = log.pmiAddMetric("hinv.ncpu", cpmapi.PM_ID_NULL,
+ cpmapi.PM_TYPE_U32, cpmapi.PM_INDOM_NULL,
+ cpmapi.PM_SEM_DISCRETE, units)
+ print("pmiAddMetric: hinv.ncpu")
+ self.assertTrue(code >= 0)
+
+ # give it a value
+ code = log.pmiPutValue("hinv.ncpu", "", "42")
+ print("pmiPutValue: hinv.ncpu")
+ self.assertTrue(code >= 0)
+
+ # create a metric with instances (kernel.all.load)
+ code = log.pmiAddMetric("kernel.all.load", pmid,
+ cpmapi.PM_TYPE_FLOAT, indom,
+ cpmapi.PM_SEM_DISCRETE, units)
+ print("pmiAddMetric: kernel.all.load")
+ self.assertTrue(code >= 0)
+ code = log.pmiAddInstance(indom, "1 minute", 1)
+ print("pmiAddInstance: kernel.all.load[1 minute]")
+ self.assertTrue(code >= 0)
+ code = log.pmiAddInstance(indom, "5 minute", 5)
+ print("pmiAddMetric: kernel.all.load[5 minute]")
+ self.assertTrue(code >= 0)
+ code = log.pmiAddInstance(indom, "15 minute", 15)
+ print("pmiAddMetric: kernel.all.load[15 minute]")
+ self.assertTrue(code >= 0)
+
+ # give them values
+ code = log.pmiPutValue("kernel.all.load", "1 minute", "42.01")
+ print("pmiPutValue: kernel.all.load[1 minute]")
+ self.assertTrue(code >= 0)
+ code = log.pmiPutValue("kernel.all.load", "5 minute", "42.05")
+ print("pmiPutValue: kernel.all.load[5 minute]")
+ self.assertTrue(code >= 0)
+ code = log.pmiPutValue("kernel.all.load", "15 minute", "42.15")
+ print("pmiPutValue: kernel.all.load[15 minute]")
+ self.assertTrue(code >= 0)
+
+ del log
+
+
+class TestSequenceFunctions(unittest.TestCase):
+ """
+ Test driver class for pcp.pmi module verification
+ """
+
+ def test_context(self):
+ """ Wrapper for test_pmi helper which does the heavy lifting """
+ test_pmi(self, OUTFILE)
+
+if __name__ == '__main__':
+
+ if (len(sys.argv) == 2):
+ OUTFILE = sys.argv[1]
+ else:
+ print("Usage: " + sys.argv[0] + " OutFile")
+ sys.exit(1)
+
+ sys.argv[1:] = ()
+
+ STS = unittest.main()
+ sys.exit(STS)
+
diff --git a/qa/src/test_webapi.py b/qa/src/test_webapi.py
new file mode 120000
index 0000000..de1ff65
--- /dev/null
+++ b/qa/src/test_webapi.py
@@ -0,0 +1 @@
+test_webapi.python \ No newline at end of file
diff --git a/qa/src/test_webapi.python b/qa/src/test_webapi.python
new file mode 100644
index 0000000..3ffdd4e
--- /dev/null
+++ b/qa/src/test_webapi.python
@@ -0,0 +1,131 @@
+""" Test creation of a PCP web daemon via the requests module """
+#
+# Copyright (C) 2013-2014 Red Hat.
+#
+# 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.
+#
+
+import requests, argparse, subprocess, os
+
+parser = argparse.ArgumentParser(description='test_webapi.py pmwebapi check')
+parser.add_argument('--version', action='version', version='1')
+parser.add_argument('--host', required=True)
+parser.add_argument('--port', default=44323)
+args = parser.parse_args()
+
+url = 'http://' + args.host + ':' + str(args.port) + '/'
+devnull = os.open(os.devnull, os.O_RDWR)
+os.unsetenv('http_proxy')
+os.unsetenv('HTTP_PROXY')
+
+# ------------------------------------------------------------------------
+
+# test - create contexts
+req = requests.get(url=url + 'pmapi/context?local=foo')
+resp = req.json()
+ctx_local = resp['context']
+print('Received PM_CONTEXT_LOCAL #' + str(ctx_local))
+
+req = requests.get(url=url + 'pmapi/context?hostname=' + args.host)
+resp = req.json()
+ctx_host = resp['context']
+print('Received PM_CONTEXT_HOST #' + str(ctx_host))
+
+# ------------------------------------------------------------------------
+
+# all these should get an error
+req = requests.get(url=url + 'pmapi/context?archivefile=/dev/null')
+print('bad archive /dev/null response code ' + str(req.status_code))
+
+req = requests.get(url=url + 'pmapi/context?archivefile=../etc/passwd')
+print('bad archive ../etc/passwd response code ' + str(req.status_code))
+
+req = requests.get(url=url + 'pmapi/context?archivefile=../../etc/shadow')
+print('bad archive ../../etc/shadow response code ' + str(req.status_code))
+
+req = requests.get(url=url + 'pmapi/NOSUCHAPI')
+print('command NOSUCHAPI response code ' + str(req.status_code))
+
+req = requests.get(url=url + 'pmapi/NOSUCHCONTEXT/_metric')
+print('context NOSUCHCONTEXT response code ' + str(req.status_code))
+
+req = requests.get(url=url + 'pmapi/0/_metric')
+print('context 0 response code ' + str(req.status_code))
+
+req = requests.get(url=url + 'random_nonpmwebapi_url')
+print('non-pmwebapi response code ' + str(req.status_code))
+
+# ------------------------------------------------------------------------
+
+def test_metric_enumeration(ctx, prefix):
+ ctxurl = url + 'pmapi/' + str(ctx) + '/'
+ if (ctx == ctx_local):
+ procargs = ['pminfo', '-L', '-t']
+ dbg = 'local'
+ else:
+ procargs = ['pminfo', '-h', args.host, '-t']
+ dbg = 'host'
+ if (prefix != ''):
+ procargs.append(prefix)
+ dbg = dbg + '-' + prefix
+ proc = subprocess.Popen(procargs,
+ stdout=subprocess.PIPE,
+ stderr=devnull)
+ num_metrics = 0
+ # f = open('/tmp/pmcd-' + dbg, 'w')
+ while True:
+ line = proc.stdout.readline()
+ if (line == ''):
+ break # eof
+ if line.strip() == '':
+ continue # blank line pminfo sometimes does that
+ if line.find('Error: No PMCD agent') == -1 and \
+ line.find('Not known to the PMDA') == -1:
+ num_metrics = num_metrics + 1
+ # f.write(line)
+ # f.write('Total ' + str(num_metrics) + ' metrics\n')
+ # f.close()
+
+ testprefix='test #'+str(ctx)+' metric '+prefix+'.*'
+ print(testprefix + ' enumeration with pminfo #'+str(num_metrics))
+
+ req = requests.get(url=ctxurl + '_metric' + \
+ ('?prefix='+prefix if prefix != '' else ''))
+ resp = req.json()
+ print(testprefix + ' enumeration with pmwebinfo #'+str(len(resp['metrics'])))
+
+ # web_metrics = 0
+ # f = open('/tmp/webd-' + dbg, 'w')
+ # for metric in resp['metrics']:
+ # web_metrics = web_metrics + 1
+ # f.write(metric['name'] + '\n')
+ # f.write('Total ' + str(web_metrics) + ' metrics\n')
+ # f.close()
+
+ if (abs(len(resp['metrics']) - num_metrics) < 10): # allow some variation
+ print(testprefix + ' enumeration match count PASS')
+ else:
+ print(testprefix + ' enumeration match count FAIL')
+
+
+test_metric_enumeration(ctx_local,'')
+test_metric_enumeration(ctx_host,'')
+test_metric_enumeration(ctx_local,'kernel')
+test_metric_enumeration(ctx_host,'kernel')
+
+# ------------------------------------------------------------------------
+
+# empty _fetch should get an error
+req = requests.get(url=url + 'pmapi/'+str(ctx_host)+'/_fetch')
+print('context #'+str(ctx_host)+' response code ' + str(req.status_code))
+
+# ------------------------------------------------------------------------
+
diff --git a/qa/src/tiny.pmns b/qa/src/tiny.pmns
new file mode 100644
index 0000000..698a703
--- /dev/null
+++ b/qa/src/tiny.pmns
@@ -0,0 +1,15 @@
+
+root {
+ one 0:0:1
+ two 0:0:2
+ buckle
+}
+
+buckle {
+ my
+}
+
+buckle.my {
+ shoe 0:0:3
+}
+
diff --git a/qa/src/torture-eol.c b/qa/src/torture-eol.c
new file mode 100644
index 0000000..e54522f
--- /dev/null
+++ b/qa/src/torture-eol.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * torture pmGetArchiveEnd
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+#ifdef IS_MINGW
+int
+truncate(const char *fname, off_t offset)
+{
+ int fd;
+
+ if ((fd = open(fname, O_WRONLY)) < 0)
+ return -1;
+ if (ftruncate(fd, offset) < 0)
+ return -1;
+ close(fd);
+ return 0;
+}
+#endif
+
+static void
+printstamp(struct timeval *tp)
+{
+ static struct tm *tmp;
+
+ tmp = localtime(&tp->tv_sec);
+ printf("%02d:%02d:%02d.%03d", (int)tmp->tm_hour, (int)tmp->tm_min, (int)tmp->tm_sec, (int)(tp->tv_usec/1000));
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int e_sts = 0;
+ int errflag = 0;
+ int ahtype = 0;
+ int verbose = 0;
+ int quick = 0;
+ char *host = NULL; /* pander to gcc */
+ pmResult *result;
+ pmResult *prev = NULL;
+ struct timeval start = { 0,0 };
+ struct timeval end;
+ int tzh;
+ off_t trunc_size = 0;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:t:qv?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (ahtype != 0) {
+ fprintf(stderr, "%s: at most one of -a and/or -h allowed\n", pmProgname);
+ errflag++;
+ }
+ ahtype = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 't': /* truncate */
+ trunc_size = atol(optarg);
+ break;
+
+ case 'q': /* quick */
+ quick = 1;
+ break;
+
+ case 'v': /* verbose */
+ verbose++;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind < argc) {
+ fprintf(stderr,
+"Usage: %s options ...\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -t size truncate archive to size bytes\n\
+ -q quick (read last 3 records, not the whole archive)\n\
+ -v verbose\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (ahtype != PM_CONTEXT_ARCHIVE) {
+ fprintf(stderr, "%s: -a is not optional!\n", pmProgname);
+ exit(1);
+ }
+
+ /* truncate if -t specified, _before_ opening archive */
+ if (trunc_size != 0) {
+ if (access(host, W_OK) == 0) {
+ if (truncate(host, trunc_size) != 0) {
+ fprintf(stderr, "%s: file %s exists, but cannot truncate\n",
+ pmProgname, host);
+ exit(1);
+ }
+ }
+ else {
+ char path[MAXPATHLEN];
+
+ sprintf(path, "%s.0", host);
+ if (access(path, W_OK) == 0) {
+ if (truncate(path, trunc_size) != 0) {
+ fprintf(stderr, "%s: file %s exists, but cannot truncate\n",
+ pmProgname, path);
+ exit(1);
+ }
+ }
+ else {
+ fprintf(stderr, "%s: cannot find writeable %s or %s\n",
+ pmProgname, host, path);
+ exit(1);
+ }
+ }
+ }
+
+ if ((sts = pmNewContext(ahtype, host)) < 0) {
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ /* force -z (timezone of archive */
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+
+ sts = pmGetArchiveEnd(&end);
+ if (sts < 0) {
+ printf("pmGetArchiveEnd: %s\n", pmErrStr(sts));
+ }
+ else {
+ if (verbose) {
+ printf("pmGetArchiveEnd time: ");
+ printstamp(&end);
+ printf("\n");
+ }
+ }
+
+ sts = pmSetMode(PM_MODE_BACK, &end, 0);
+ if (sts < 0) {
+ printf("pmSetMode PM_MODE_BACK: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ sts = pmFetchArchive(&result);
+ if (sts < 0) {
+ printf("pmFetchArchive: %s\n", pmErrStr(sts));
+ e_sts = 1;
+ }
+ else {
+ if (verbose) {
+ printf("last result time (direct): ");
+ printstamp(&result->timestamp);
+ printf("\n");
+ }
+ if (result->timestamp.tv_sec != end.tv_sec ||
+ result->timestamp.tv_usec != end.tv_usec) {
+ printf("Mismatch: end=");
+ printstamp(&end);
+ printf(" direct=");
+ printstamp(&result->timestamp);
+ printf("\n");
+ e_sts = 1;
+ }
+ start.tv_sec = result->timestamp.tv_sec;
+ start.tv_usec = result->timestamp.tv_usec;
+ pmFreeResult(result);
+ }
+
+ if (quick && e_sts == 0) {
+ int i;
+ for (i = 0; i < 2; i++) {
+ sts = pmFetchArchive(&result);
+ if (sts >= 0) {
+ start.tv_sec = result->timestamp.tv_sec;
+ start.tv_usec = result->timestamp.tv_usec;
+ pmFreeResult(result);
+ }
+ }
+ }
+ else {
+ /* start from the epoch and move forward */
+ start.tv_sec = 0;
+ start.tv_usec = 0;
+ }
+ sts = pmSetMode(PM_MODE_FORW, &start, 0);
+ if (sts < 0) {
+ printf("pmSetMode PM_MODE_FORW: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ while ((sts = pmFetchArchive(&result)) >= 0) {
+ if (prev != NULL)
+ pmFreeResult(prev);
+ prev = result;
+ }
+ if (verbose) printf("pmFetchArchive: %s\n", pmErrStr(sts));
+ if (prev == NULL) {
+ printf("no results!\n");
+ }
+ else {
+ if (verbose) {
+ printf("last result time (serial): ");
+ printstamp(&prev->timestamp);
+ printf("\n");
+ }
+ if (prev->timestamp.tv_sec != end.tv_sec ||
+ prev->timestamp.tv_usec != end.tv_usec) {
+ printf("Mismatch: end=");
+ printstamp(&end);
+ printf(" serial=");
+ printstamp(&prev->timestamp);
+ printf("\n");
+ e_sts = 1;
+ }
+ pmFreeResult(prev);
+ }
+
+ exit(e_sts);
+}
diff --git a/qa/src/torture_api.c b/qa/src/torture_api.c
new file mode 100644
index 0000000..0fe065f
--- /dev/null
+++ b/qa/src/torture_api.c
@@ -0,0 +1,516 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * main - general purpose exerciser of much of the PMAPI
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int _op; /* number of api operations */
+static int _err; /* number of api errors */
+static int vflag;
+static char *context_name = "localhost";
+static int context_type; /* archive, host or local */
+static char *namespace = PM_NS_DEFAULT;
+static int all_children = 1; /* do the children of "" test */
+static int root_children; /* only do the children of "" test */
+static int dump_metrics; /* just dump the metrics and exit */
+/*
+ * pmns_style == 1 => do PMNS style loading the old way
+ * pmns_style == 2 => try to use the distributed PMNS
+ */
+static int pmns_style = 1;
+
+/* The list of metrics to test out */
+static char *namelist[] = {
+ "disk.all.total",
+ "pmcd",
+ "kernel.all.pswitch",
+ "kernel.all.cpu.user",
+ "kernel.all.cpu.wait.total",
+ "hinv.ncpu",
+ "pmcd.control",
+ "sampledso.aggregate.hullo",
+ "sample.seconds",
+ "sample.colour",
+ "sample.longlong",
+ "bozo.the.clown"
+};
+
+#define MAXNAMES (sizeof(namelist)/sizeof(char*))
+
+
+typedef struct name_status {
+ char *name;
+ int status;
+}name_status;
+
+static int
+compar_str(const void *a, const void *b)
+{
+ char **ca = (char **)a;
+ char **cb = (char **)b;
+ return strcmp(*ca, *cb);
+}
+
+static int
+compar_name_status(const void *a, const void *b)
+{
+ name_status *ca = (name_status*)a;
+ name_status *cb = (name_status*)b;
+ return strcmp(ca->name, cb->name);
+}
+
+void
+do_chn(char *name)
+{
+ int n;
+ int j;
+ char **enfants = NULL;
+ name_status *ns_table = NULL;
+ int has_children = 0;
+
+ _op++;
+ n = pmGetChildren(name, &enfants);
+ if (n < 0) {
+ _err++;
+ printf("pmGetChildren: %s\n", pmErrStr(n));
+ }
+ else if (n > 0) {
+ qsort(enfants, n, sizeof(enfants[0]), compar_str);
+ has_children = 1;
+ }
+
+ /* test out pmGetChildrenStatus */
+ {
+ char **s_enfants = NULL;
+ int *status = NULL;
+
+ _op++;
+ n = pmGetChildrenStatus(name, &s_enfants, &status);
+ if (n < 0) {
+ _err++;
+ printf("pmGetChildrenStatus: %s\n", pmErrStr(n));
+ }
+ else if (n > 0) {
+ /* create a ns_table for sorting */
+ ns_table = (name_status*)malloc(sizeof(name_status)*n);
+ if (ns_table == 0) {
+ printf("Malloc failed\n");
+ exit(1);
+ }
+ for(j = 0; j < n; j++) {
+ ns_table[j].name = s_enfants[j];
+ ns_table[j].status = status[j];
+ }
+
+ qsort(ns_table, n, sizeof(ns_table[0]), compar_name_status);
+
+ for (j = 0; j < n; j++) {
+ if (strcmp(ns_table[j].name, enfants[j]) != 0) {
+ printf("pmGetChildrenStatus mismatch: \"%s\" vs \"%s\"\n",
+ enfants[j], ns_table[j].name);
+ }
+ }/*for*/
+ }/*if*/
+ if (s_enfants) free(s_enfants);
+ if (status) free(status);
+ }
+
+ if (has_children && vflag) {
+ printf("children of \"%s\" ...\n", name);
+ for (j = 0; j < n; j++) {
+
+ printf(" %-20s", enfants[j]);
+ if (ns_table)
+ printf("<s = %d>", ns_table[j].status);
+ printf("\n");
+ }
+ }
+
+ if (enfants) free(enfants);
+ if (ns_table) free(ns_table);
+
+}
+
+void
+parse_args(int argc, char **argv)
+{
+ extern char *optarg;
+ extern int optind;
+ int errflag = 0;
+ int c;
+ static char *usage = "[-bcLmv] [-a archive] [-h host] [-n namespace] [-s 1|2]";
+ char *endnum;
+ int sts;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D <dbg>]";
+#else
+ static char *debug = "";
+#endif
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:h:iLmn:s:vbc")) != EOF) {
+ switch (c) {
+ case 'a': /* archive name for context */
+ if (context_type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n",
+ pmProgname);
+ errflag++;
+ }
+ context_type = PM_CONTEXT_ARCHIVE;
+ context_name = optarg;
+ break;
+
+ case 'b': /* dont do the children of "" test */
+ all_children = 0;
+ break;
+
+ case 'c': /* only do the children of "" test */
+ root_children = 1;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'h': /* context_namename for live context */
+ if (context_type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n",
+ pmProgname);
+ errflag++;
+ }
+ context_type = PM_CONTEXT_HOST;
+ context_name = optarg;
+ break;
+
+ case 'i': /* non-IRIX names (always true now) */
+ break;
+
+ case 'L': /* LOCAL context */
+ if (context_type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n",
+ pmProgname);
+ errflag++;
+ }
+ context_type = PM_CONTEXT_LOCAL;
+ context_name = NULL;
+ break;
+
+ case 'm': /* dump out the list of metrics to be tested */
+ dump_metrics = 1;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'v': /* verbose */
+ vflag++;
+ break;
+
+ case 's': /* pmns style */
+ pmns_style = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ printf("%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+}
+
+void
+load_namespace(char *namespace)
+{
+ struct timeval now, then;
+ int sts;
+
+ gettimeofday(&then, (struct timezone *)0);
+ _op++;
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ _err++;
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ gettimeofday(&now, (struct timezone *)0);
+ printf("Name space load: %.2f msec\n", __pmtimevalSub(&now, &then)*1000);
+}
+
+void
+test_api(void)
+{
+ int sts;
+ int i;
+ pmID midlist[MAXNAMES];
+ int *instlist;
+ char **inamelist;
+ int n;
+ int numpmid = MAXNAMES;
+ char *back;
+ pmResult *resp;
+ pmDesc desc;
+
+ _op++;
+
+ if (context_type == 0) {
+ char local[MAXHOSTNAMELEN];
+ context_type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ context_name = local;
+ }
+
+ if ((sts = pmNewContext(context_type, context_name)) < 0) {
+ _err++;
+ printf("%s: Error in creating %s context for \"%s\": %s\n",
+ pmProgname,
+ context_type == PM_CONTEXT_HOST ? "host" :
+ context_type == PM_CONTEXT_ARCHIVE ? "archive" :
+ "local",
+ context_name,
+ pmErrStr(sts));
+ }
+
+ if (vflag > 1) {
+ _op++;
+ __pmDumpNameSpace(stdout, 1);
+ }
+
+
+ _op++;
+ n = pmLookupName(numpmid, namelist, midlist);
+ if (n != PM_ERR_NONLEAF) { /* expect failure due to pmcd */
+ _err++;
+ printf("pmLookupName: Unexpected error: %s\n", pmErrStr(n));
+ for (i = 0; i < numpmid; i++) {
+ printf("name[%d] %s -> %s\n", i, namelist[i], pmIDStr(midlist[i]));
+ }
+ }
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_APPL0) {
+ for (i = 0; i < numpmid; i++) {
+ printf("%s: id[%d] = %d\n", namelist[i], i, midlist[i]);
+ }
+ }
+#endif
+
+ /* Set mode for archive so that an indom can be retrieved
+ * if necessary.
+ * Getting an indom is done based on current time.
+ * If we try and get an indom from the start then we may not
+ * have one yet.
+ */
+ if (context_type == PM_CONTEXT_ARCHIVE) {
+ struct timeval when;
+
+ _op++;
+ if ((n = pmGetArchiveEnd(&when)) < 0) {
+ _err++;
+ printf("pmGetArchiveEnd: %s\n", pmErrStr(n));
+ }
+
+ _op++;
+ if ((n = pmSetMode(PM_MODE_BACK, &when, 1000)) < 0) {
+ _err++;
+ printf("pmSetMode(PM_MODE_BACK): %s\n", pmErrStr(n));
+ }
+ }
+
+ for (i = 0; i < numpmid && !root_children; i++) {
+ putchar('\n');
+ if (vflag) printf("pmid: %s ", pmIDStr(midlist[i]));
+ printf("name: %s\n", namelist[i]);
+ if (strcmp(namelist[i], "bozo.the.clown") != 0)
+ do_chn(namelist[i]);
+ if (midlist[i] != PM_ID_NULL) {
+ _op++;
+ n = pmNameID(midlist[i], &back);
+ if (n < 0) {
+ _err++;
+ printf("pmNameID: %s\n", pmErrStr(n));
+ }
+ else {
+ if (strcmp(namelist[i], back) != 0 &&
+ strcmp(&namelist[i][5], back) != 0) {
+ _err++;
+ printf("pmNameID botch: expected \"%s\", got \"%s\"\n",
+ namelist[i], back);
+ }
+ free(back);
+ }
+ _op++;
+ if ((n = pmLookupDesc(midlist[i], &desc)) < 0) {
+ _err++;
+ printf("pmLookupDesc: %s\n", pmErrStr(n));
+ }
+ else {
+ if (vflag > 1) {
+ const char *u = pmUnitsStr(&desc.units);
+ printf("desc: type=%d indom=0x%x sem=%d units=%s\n",
+ desc.type, desc.indom, desc.sem,
+ *u == '\0' ? "none" : u);
+ }
+ if (desc.indom == PM_INDOM_NULL)
+ continue;
+ _op++;
+ if ((n = pmGetInDom(desc.indom, &instlist, &inamelist)) < 0) {
+ _err++;
+ printf("pmGetInDom: %s\n", pmErrStr(n));
+ }
+ else {
+ int j;
+ int numinst = n;
+ char *name;
+ for (j = 0; j < numinst; j++) {
+ if (vflag > 1)
+ printf(" instance id: 0x%x\n", instlist[j]);
+ _op++;
+ if ((n = pmNameInDom(desc.indom, instlist[j], &name)) < 0) {
+ _err++;
+ printf("pmNameInDom: %s\n", pmErrStr(n));
+ }
+ else {
+ if (vflag > 1)
+ printf(" %s (== %s?)\n", name, inamelist[j]);
+ _op++;
+ if ((n = pmLookupInDom(desc.indom, name)) < 0) {
+ _err++;
+ printf("pmLookupInDom: %s\n", pmErrStr(n));
+ }
+ else {
+ if (n != instlist[j]) {
+ _err++;
+ printf("botch: pmLookupInDom returns 0x%x, expected 0x%x\n",
+ n, instlist[j]);
+ }
+ }
+ free(name);
+ }
+ }
+ free(instlist);
+ free(inamelist);
+ }
+ }
+ }
+ }/*for each named metric*/
+
+ if (all_children || root_children) {
+ /* root check */
+ /*
+ * This is only useful in a namspace where irix has not been stripped from the
+ * names. Once irix is stripped from the names, the list returned becomes
+ * to variable to do a QA in this manner.
+ * Test #568 using pmns_xlate tests the root.
+ */
+ printf("\n");
+ do_chn("");
+ }
+
+ if (context_type == PM_CONTEXT_ARCHIVE) {
+ struct timeval when;
+
+ when.tv_sec = 0;
+ when.tv_usec = 0;
+
+ if (vflag)
+ printf("\nArchive result ...\n");
+ for (i = 0; i < numpmid; i++) {
+ if (midlist[i] == PM_ID_NULL)
+ continue;
+ _op++;
+ if ((n = pmSetMode(PM_MODE_FORW, &when, 0)) < 0) {
+ _err++;
+ printf("pmSetMode(PM_MODE_FORW): %s\n", pmErrStr(n));
+ }
+ else {
+ _op++;
+ if (vflag)
+ printf("Fetch of %s:\n", namelist[i]);
+ if ((n = pmFetch(1, &midlist[i], &resp)) < 0) {
+ _err++;
+ printf("Archive pmFetch: %s\n", pmErrStr(n));
+ }
+ else {
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ _op++;
+ pmFreeResult(resp);
+ }
+ }
+ }/*for*/
+ }
+
+ else if (context_type == PM_CONTEXT_HOST) {
+ _op++;
+ if ((n = pmSetMode(PM_MODE_LIVE, (struct timeval *)0, 0)) < 0) {
+ _err++;
+ printf("pmSetMode(PM_MODE_LIVE): %s\n", pmErrStr(n));
+ }
+ else {
+ _op++;
+ if ((n = pmFetch(numpmid, midlist, &resp)) < 0) {
+ _err++;
+ printf("real-time pmFetch: %s\n", pmErrStr(n));
+ }
+ else {
+ if (vflag) {
+ printf("\nReal-time result ...\n");
+ __pmDumpResult(stdout, resp);
+ }
+ _op++;
+ pmFreeResult(resp);
+ }
+ }
+ }
+
+}
+
+int
+main(int argc, char **argv)
+{
+ parse_args(argc, argv);
+
+ if (dump_metrics == 1) {
+ int i;
+ for(i = 0; i < MAXNAMES; i++) {
+ printf("%s\n", namelist[i]);
+ }
+ exit(0);
+ }
+
+ if (pmns_style == 2) {
+ /* test it the new way with distributed namespace */
+ /* i.e. no client loaded namespace */
+ test_api();
+ }
+ else {
+ /* test it the old way with namespace file */
+ load_namespace(namespace);
+ test_api();
+ }
+
+ printf("\nUnexpected failure for %d of %d PMAPI operations\n", _err, _op);
+ exit(0);
+}
diff --git a/qa/src/torture_cache.c b/qa/src/torture_cache.c
new file mode 100644
index 0000000..843863b
--- /dev/null
+++ b/qa/src/torture_cache.c
@@ -0,0 +1,599 @@
+/*
+ * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+static pmInDom indom;
+static __pmInDom_int *indomp;
+static char *xxx = "xxxsomefunnyinstancenamestringthatcanbechoppedabout";
+static char nbuf[80]; /* at least as big as xxx[] */
+static int ncount;
+
+static void
+_a(int load, int verbose, int extra)
+{
+ int inst;
+ int sts;
+
+ indomp->domain = 123;
+ indomp->serial = 7;
+
+ if (load) {
+ fprintf(stderr, "Load the instance domain ...\n");
+ sts = pmdaCacheOp(indom, PMDA_CACHE_LOAD);
+ if (sts < 0) {
+ fprintf(stderr, "PMDA_CACHE_LOAD failed: %s\n", pmErrStr(sts));
+ return;
+ }
+ }
+
+ fprintf(stderr, "Add foo ...\n");
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, "foo", NULL);
+ fprintf(stderr, "return -> %d", inst);
+ if (inst < 0) fprintf(stderr, ": %s", pmErrStr(inst));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDumpAll(stderr, 0);
+
+ fprintf(stderr, "\nAdd bar ...\n");
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, "bar", (void *)((__psint_t)0xdeadbeef));
+ fprintf(stderr, "return -> %d", inst);
+ if (inst < 0) fprintf(stderr, ": %s", pmErrStr(inst));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDumpAll(stderr, 0);
+
+ fprintf(stderr, "\nAdd java coffee beans ...\n");
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, "java coffee beans", (void *)((__psint_t)0xcafecafe));
+ fprintf(stderr, "return -> %d", inst);
+ if (inst < 0) fprintf(stderr, ": %s", pmErrStr(inst));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDumpAll(stderr, 0);
+
+ fprintf(stderr, "\nAdd another one ...\n");
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, "another one", NULL);
+ fprintf(stderr, "return -> %d", inst);
+ if (inst < 0) fprintf(stderr, ": %s", pmErrStr(inst));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDumpAll(stderr, 0);
+
+ fprintf(stderr, "\nHide another one ...\n");
+ inst = pmdaCacheStore(indom, PMDA_CACHE_HIDE, "another one", NULL);
+ fprintf(stderr, "return -> %d", inst);
+ if (inst < 0) fprintf(stderr, ": %s", pmErrStr(inst));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDump(stderr, indom, 0);
+
+ fprintf(stderr, "\nCull foo ...\n");
+ inst = pmdaCacheStore(indom, PMDA_CACHE_CULL, "foo", NULL);
+ fprintf(stderr, "return -> %d", inst);
+ if (inst < 0) fprintf(stderr, ": %s", pmErrStr(inst));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDump(stderr, indom, 0);
+
+ fprintf(stderr, "\nCull foo again, should fail ...\n");
+ inst = pmdaCacheStore(indom, PMDA_CACHE_CULL, "foo", NULL);
+ fprintf(stderr, "return -> %d", inst);
+ if (inst < 0) fprintf(stderr, ": %s", pmErrStr(inst));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDump(stderr, indom, 0);
+
+ fprintf(stderr, "\nCount instances ...\n");
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SIZE);
+ fprintf(stderr, "entries: %d\n", sts);
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SIZE_ACTIVE);
+ fprintf(stderr, "active entries: %d\n", sts);
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SIZE_INACTIVE);
+ fprintf(stderr, "inactive entries: %d\n", sts);
+
+ fprintf(stderr, "\nProbe bar ...\n");
+ sts = pmdaCacheLookupName(indom, "bar", &inst, NULL);
+ fprintf(stderr, "return ->");
+ if (sts >= 0) fprintf(stderr, " %d", inst);
+ if (sts == PMDA_CACHE_INACTIVE) fprintf(stderr, " [inactive]");
+ if (sts < 0) fprintf(stderr, " %d: %s", sts, pmErrStr(sts));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDump(stderr, indom, 0);
+
+ fprintf(stderr, "\nProbe another one (hidden) ...\n");
+ sts = pmdaCacheLookupName(indom, "another one", &inst, NULL);
+ fprintf(stderr, "return ->");
+ if (sts >= 0) fprintf(stderr, " %d", inst);
+ if (sts == PMDA_CACHE_INACTIVE) fprintf(stderr, " [inactive]");
+ if (sts < 0) fprintf(stderr, " %d: %s", sts, pmErrStr(sts));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDump(stderr, indom, 0);
+
+ if (load) {
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ if (sts < 0) {
+ fprintf(stderr, "PMDA_CACHE_SAVE failed: %s\n", pmErrStr(sts));
+ }
+ return;
+ }
+
+ if (extra == 0)
+ return;
+
+ indomp->serial = 8;
+ fprintf(stderr, "\nAdd foo in another indom ...\n");
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, "foo", NULL);
+ fprintf(stderr, "return -> %d", inst);
+ if (inst < 0) fprintf(stderr, ": %s", pmErrStr(inst));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDumpAll(stderr, 0);
+
+ fprintf(stderr, "\nProbe bar (not in this indom) ...\n");
+ sts = pmdaCacheLookupName(indom, "bar", &inst, NULL);
+ fprintf(stderr, "return ->");
+ if (sts >= 0) fprintf(stderr, " %d", inst);
+ if (sts == PMDA_CACHE_INACTIVE) fprintf(stderr, " [inactive]");
+ if (sts < 0) fprintf(stderr, " %d: %s", sts, pmErrStr(sts));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDump(stderr, indom, 0);
+
+
+ indomp->serial = 7;
+
+ fprintf(stderr, "\nMark all active ...\n");
+ sts = pmdaCacheOp(indom, PMDA_CACHE_ACTIVE);
+ fprintf(stderr, "return -> %d", sts);
+ if (sts < 0) fprintf(stderr, ": %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDump(stderr, indom, 0);
+
+ fprintf(stderr, "\nMark all inactive ...\n");
+ sts = pmdaCacheOp(indom, PMDA_CACHE_INACTIVE);
+ fprintf(stderr, "return -> %d", sts);
+ if (sts < 0) fprintf(stderr, ": %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDump(stderr, indom, 0);
+
+ fprintf(stderr, "\nCull all ...\n");
+ sts = pmdaCacheOp(indom, PMDA_CACHE_CULL);
+ fprintf(stderr, "return -> %d", sts);
+ if (sts < 0) fprintf(stderr, ": %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ if (verbose) __pmdaCacheDump(stderr, indom, 0);
+
+}
+
+static void
+_b(void)
+{
+ int i;
+ int j;
+ int inst;
+ int sts;
+ char cmd[2*MAXPATHLEN+30];
+
+ indomp->domain = 123;
+ indomp->serial = 8;
+
+ sprintf(cmd, "rm -f %s/config/pmda/%s", pmGetConfig("PCP_VAR_DIR"), pmInDomStr(indom));
+ sts = system(cmd);
+ if (sts != 0)
+ fprintf(stderr, "Warning: %s: exit status %d\n", cmd, sts);
+ sprintf(cmd, "[ -f %s/config/pmda/%s ] || exit 0; cat %s/config/pmda/%s", pmGetConfig("PCP_VAR_DIR"), pmInDomStr(indom), pmGetConfig("PCP_VAR_DIR"), pmInDomStr(indom));
+
+ fprintf(stderr, "\nPopulate the instance domain ...\n");
+ j = 1;
+ for (i = 0; i < 20; i++) {
+ strncpy(nbuf, xxx, ncount+3);
+ sprintf(nbuf, "%03d", ncount);
+ ncount++;
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, nbuf, (void *)((__psint_t)(0xbeef0000+ncount)));
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_ADD failed for \"%s\": %s\n", nbuf, pmErrStr(inst));
+ else if (i > 14) {
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ fprintf(stderr, "Save -> %d\n", sts);
+ }
+ if (i == j) {
+ j <<= 1;
+ inst = pmdaCacheStore(indom, PMDA_CACHE_HIDE, nbuf, NULL);
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_HIDE failed for \"%s\": %s\n", nbuf, pmErrStr(inst));
+ }
+ if (i == 6 || i == 13) {
+ fprintf(stderr, "Save ...\n");
+ fprintf(stderr, "Before:\n");
+ sts = system(cmd);
+ if (sts != 0)
+ fprintf(stderr, "Warning: _b:1: %s: exit status %d\n", cmd, sts);
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ fprintf(stderr, "return -> %d", sts);
+ if (sts < 0) fprintf(stderr, ": %s", pmErrStr(sts));
+ fputc('\n', stderr);
+ fprintf(stderr, "After:\n");
+ sts = system(cmd);
+ if (sts != 0)
+ fprintf(stderr, "Warning: _b:2: %s: exit status %d\n", cmd, sts);
+ }
+ if (i == 14) {
+ fprintf(stderr, "Start save after changes ...\n");
+ }
+ if (i > 14) {
+ sts = system(cmd);
+ if (sts != 0)
+ fprintf(stderr, "Warning: _b:3: %s: exit status %d\n", cmd, sts);
+ }
+ }
+ __pmdaCacheDump(stderr, indom, 0);
+ strncpy(nbuf, xxx, 11+3);
+ sprintf(nbuf, "%03d", 11);
+ fprintf(stderr, "\nHide %s ...\n", nbuf);
+ inst = pmdaCacheStore(indom, PMDA_CACHE_HIDE, nbuf, NULL);
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_HIDE failed for \"%s\": %s\n", nbuf, pmErrStr(inst));
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ fprintf(stderr, "Save -> %d\n", sts);
+ sts = system(cmd);
+ if (sts != 0)
+ fprintf(stderr, "Warning: _b:4: %s: exit status %d\n", cmd, sts);
+ fprintf(stderr, "Add %s ...\n", nbuf);
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, nbuf, (void *)((__psint_t)0xdeadbeef));
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_ADD failed for \"%s\": %s\n", nbuf, pmErrStr(inst));
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ fprintf(stderr, "Save -> %d\n", sts);
+ sts = system(cmd);
+ if (sts != 0)
+ fprintf(stderr, "Warning: _b:5: %s: exit status %d\n", cmd, sts);
+ fprintf(stderr, "Cull %s ...\n", nbuf);
+ inst = pmdaCacheStore(indom, PMDA_CACHE_CULL, nbuf, NULL);
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_CULL failed for \"%s\": %s\n", nbuf, pmErrStr(inst));
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ fprintf(stderr, "Save -> %d\n", sts);
+ sts = system(cmd);
+ if (sts != 0)
+ fprintf(stderr, "Warning: _b:6: %s: exit status %d\n", cmd, sts);
+ fprintf(stderr, "Add %s ...\n", nbuf);
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, nbuf, (void *)((__psint_t)0xdeadbeef));
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_ADD failed for \"%s\": %s\n", nbuf, pmErrStr(inst));
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ fprintf(stderr, "Save -> %d\n", sts);
+ sts = system(cmd);
+ if (sts != 0)
+ fprintf(stderr, "Warning: _b:7: %s: exit status %d\n", cmd, sts);
+
+}
+
+static void
+_c(void)
+{
+ int inst;
+ int sts;
+
+ indomp->domain = 123;
+ indomp->serial = 13;
+
+ fprintf(stderr, "Load the instance domain ...\n");
+ sts = pmdaCacheOp(indom, PMDA_CACHE_LOAD);
+ if (sts < 0) {
+ fprintf(stderr, "PMDA_CACHE_LOAD failed: %s\n", pmErrStr(sts));
+ return;
+ }
+
+ inst = pmdaCacheStore(indom, PMDA_CACHE_HIDE, "fubar-001", NULL);
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_HIDE failed for \"fubar-001\": %s\n", pmErrStr(inst));
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, "fubar-002", NULL);
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_ADD failed for \"fubar-002\": %s\n", pmErrStr(inst));
+ inst = pmdaCacheStore(indom, PMDA_CACHE_CULL, "fubar-003", NULL);
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_CULL failed for \"fubar-003\": %s\n", pmErrStr(inst));
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, "fubar-009", NULL);
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_ADD failed for \"fubar-009\": %s\n", pmErrStr(inst));
+
+ __pmdaCacheDump(stderr, indom, 0);
+
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ if (sts < 0) {
+ fprintf(stderr, "PMDA_CACHE_SAVE failed: %s\n", pmErrStr(sts));
+ return;
+ }
+}
+
+static void
+_e(int since)
+{
+ int i;
+ int j;
+ int sts;
+ int inst;
+
+ indomp->domain = 123;
+ indomp->serial = 11;
+
+ sts = pmdaCacheOp(indom, PMDA_CACHE_LOAD);
+ if (sts < 0) {
+ fprintf(stderr, "PMDA_CACHE_LOAD failed: %s\n", pmErrStr(sts));
+ return;
+ }
+
+ j = 1;
+ for (i = 0; i < 10; i++) {
+ sprintf(nbuf, "boring-instance-%03d", i);
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, nbuf, (void *)((__psint_t)(0xcaffe000+i)));
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_ADD failed for \"%s\": %s\n", nbuf, pmErrStr(inst));
+ if (i == j) {
+ j <<= 1;
+ inst = pmdaCacheStore(indom, PMDA_CACHE_HIDE, nbuf, NULL);
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_HIDE failed for \"%s\": %s\n", nbuf, pmErrStr(inst));
+ }
+ }
+
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ fprintf(stderr, "Save -> %d\n", sts);
+ fprintf(stderr, "Before purge ...\n");
+ __pmdaCacheDump(stderr, indom, 0);
+
+ sleep(1);
+
+ sts = pmdaCachePurge(indom, since);
+ if (sts < 0) {
+ fprintf(stderr, "pmdaCachePurge failed: %s\n", pmErrStr(sts));
+ return;
+ }
+ fprintf(stderr, "Purged %d entries\nAfter purge ...\n", sts);
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ fprintf(stderr, "Save -> %d\n", sts);
+ __pmdaCacheDump(stderr, indom, 0);
+}
+
+static void
+_g(void)
+{
+ int inst;
+ int i;
+
+ indomp->domain = 123;
+ indomp->serial = 7;
+
+ for (i = 0; i < 254; i++) {
+ sprintf(nbuf, "hashing-instance-%03d", i);
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, nbuf, (void *)((__psint_t)(0xdeaf0000+i)));
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_ADD failed for \"%s\": %s\n", nbuf, pmErrStr(inst));
+ if (i % 2 == 0) {
+ inst = pmdaCacheStore(indom, PMDA_CACHE_HIDE, nbuf, NULL);
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_HIDE failed for \"%s\": %s\n", nbuf, pmErrStr(inst));
+ }
+ if (i % 7 == 0) {
+ sprintf(nbuf, "hashing-instance-%03d", i);
+ inst = pmdaCacheStore(indom, PMDA_CACHE_CULL, nbuf, NULL);
+ if (inst < 0)
+ fprintf(stderr, "PMDA_CACHE_CULL failed for \"%s\": %s\n", nbuf, pmErrStr(inst));
+ }
+ }
+
+ __pmdaCacheDump(stderr, indom, 1);
+
+ _a(0, 0, 0);
+
+ __pmdaCacheDump(stderr, indom, 1);
+}
+
+static char *h_tab[] = { "foo", "foobar", "foo bar", NULL };
+
+static void
+_h(void)
+{
+ int sts;
+ int inst;
+ int i;
+
+ indomp->domain = 123;
+ indomp->serial = 17;
+
+ sts = pmdaCacheOp(indom, PMDA_CACHE_LOAD);
+ if (sts < 0) {
+ fprintf(stderr, "PMDA_CACHE_LOAD failed: %s\n", pmErrStr(sts));
+ return;
+ }
+
+ for (i = 0; h_tab[i] != NULL; i++) {
+ fprintf(stderr, "[%s]\n", h_tab[i]);
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, h_tab[i], NULL);
+ if (inst < 0) {
+ fprintf(stderr, "ADD failed: %s\n", pmErrStr(inst));
+ continue;
+ }
+ fprintf(stderr, "ADD -> %d\n", inst);
+
+ inst = pmdaCacheStore(indom, PMDA_CACHE_HIDE, h_tab[i], NULL);
+ if (inst < 0) {
+ fprintf(stderr, "HIDE failed: %s\n", pmErrStr(inst));
+ continue;
+ }
+ fprintf(stderr, "HIDE -> %d\n", inst);
+
+ }
+}
+
+static char *i_tab[] = { "ernie", "bert", "kermit", "oscar", "big bird", "miss piggy", NULL };
+
+/*
+ * revised dirty cache semantics
+ * style & 1 => SAVE
+ * style & 2 => SYNC
+ */
+static void
+_i(int style)
+{
+ int sts;
+ int inst;
+ int i;
+ static int first = 1;
+
+ indomp->domain = 123;
+ indomp->serial = 15;
+
+ if (first) {
+ sts = pmdaCacheOp(indom, PMDA_CACHE_LOAD);
+ if (sts < 0) {
+ fprintf(stderr, "PMDA_CACHE_LOAD failed: %s\n", pmErrStr(sts));
+ }
+ first = 0;
+ }
+
+ for (i = 0; i_tab[i] != NULL; i++) {
+ fprintf(stderr, "[%s]\n", i_tab[i]);
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, i_tab[i], NULL);
+ if (inst < 0) {
+ fprintf(stderr, "ADD failed: %s\n", pmErrStr(inst));
+ continue;
+ }
+ fprintf(stderr, "ADD -> %d\n", inst);
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ if (sts < 0) {
+ fprintf(stderr, "PMDA_CACHE_SAVE failed: %s\n", pmErrStr(sts));
+ }
+ else
+ fprintf(stderr, "SAVE -> %d\n", sts);
+
+ if (i == 0) {
+ /* last one -> INACTIVE */
+ inst = pmdaCacheStore(indom, PMDA_CACHE_HIDE, i_tab[i], NULL);
+ if (inst < 0) {
+ fprintf(stderr, "HIDE failed: %s\n", pmErrStr(inst));
+ continue;
+ }
+ fprintf(stderr, "HIDE -> %d\n", inst);
+ }
+ else if (i == 1) {
+ /* last one -> INACTIVE -> ACTIVE */
+ inst = pmdaCacheStore(indom, PMDA_CACHE_HIDE, i_tab[i], NULL);
+ if (inst < 0) {
+ fprintf(stderr, "HIDE failed: %s\n", pmErrStr(inst));
+ continue;
+ }
+ fprintf(stderr, "HIDE -> %d\n", inst);
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, i_tab[i], NULL);
+ if (inst < 0) {
+ fprintf(stderr, "ADD failed: %s\n", pmErrStr(inst));
+ continue;
+ }
+ fprintf(stderr, "ADD -> %d\n", inst);
+ }
+ else if (i == 2) {
+ /* last one -> EMPTY */
+ inst = pmdaCacheStore(indom, PMDA_CACHE_CULL, i_tab[i], NULL);
+ if (inst < 0) {
+ fprintf(stderr, "CULL failed: %s\n", pmErrStr(inst));
+ continue;
+ }
+ fprintf(stderr, "CULL -> %d\n", inst);
+ }
+ else if (i == 3) {
+ /* add another one */
+ fprintf(stderr, "extra [%s]\n", "felix-the-cat");
+ inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, "felix-the-cat", NULL);
+ if (inst < 0) {
+ fprintf(stderr, "ADD failed: %s\n", pmErrStr(inst));
+ continue;
+ }
+ fprintf(stderr, "ADD -> %d\n", inst);
+ }
+ else if (i == 4) {
+ /* do nothing! */
+ ;
+ }
+ else {
+ /* empty cache */
+ sts = pmdaCacheOp(indom, PMDA_CACHE_CULL);
+ if (sts < 0) {
+ fprintf(stderr, "PMDA_CACHE_CULL failed: %s\n", pmErrStr(sts));
+ return;
+ }
+ fprintf(stderr, "CULL ALL -> %d\n", inst);
+ }
+
+ if (style & 1) {
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SAVE);
+ if (sts < 0) {
+ fprintf(stderr, "PMDA_CACHE_SAVE failed: %s\n", pmErrStr(sts));
+ }
+ else
+ fprintf(stderr, "SAVE -> %d\n", sts);
+ }
+
+ if (style & 2) {
+ sts = pmdaCacheOp(indom, PMDA_CACHE_SYNC);
+ if (sts < 0) {
+ fprintf(stderr, "PMDA_CACHE_SYNC failed: %s\n", pmErrStr(sts));
+ }
+ else
+ fprintf(stderr, "SYNC -> %d\n", sts);
+ }
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int errflag = 0;
+ int sts;
+ int c;
+
+ __pmSetProgname(argv[0]);
+
+ indomp = (__pmInDom_int *)&indom;
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s [-D...] [a|b|c|d|...|i 1|2|3}\n", pmProgname);
+ exit(1);
+ }
+
+ while (optind < argc) {
+ if (strcmp(argv[optind], "a") == 0) _a(0, 1, 1);
+ else if (strcmp(argv[optind], "b") == 0) _b();
+ else if (strcmp(argv[optind], "c") == 0) _c();
+ else if (strcmp(argv[optind], "d") == 0) _a(1, 0, 1);
+ else if (strcmp(argv[optind], "e") == 0) _e(0);
+ else if (strcmp(argv[optind], "f") == 0) _e(3600);
+ else if (strcmp(argv[optind], "g") == 0) _g();
+ else if (strcmp(argv[optind], "h") == 0) _h();
+ else if (strcmp(argv[optind], "i") == 0) {
+ optind++;
+ _i(atoi(argv[optind]));
+ }
+ else
+ fprintf(stderr, "torture_cache: no idea what to do with option \"%s\"\n", argv[optind]);
+ optind++;
+ }
+
+ exit(0);
+}
diff --git a/qa/src/torture_indom.c b/qa/src/torture_indom.c
new file mode 100644
index 0000000..4f15d47
--- /dev/null
+++ b/qa/src/torture_indom.c
@@ -0,0 +1,374 @@
+/*
+ * indom_match - exercise indom fetching with a profile
+ *
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+result_instlist(pmResult *r, int **list)
+{
+ int *l;
+ int i;
+
+ l = malloc(r->vset[0]->numval * sizeof(int));
+ for (i=0; i < r->vset[0]->numval; i++) {
+ l[i] = r->vset[0]->vlist[i].inst;
+ }
+ *list = l;
+ return r->vset[0]->numval;
+}
+
+int
+cmp_list(int n, int *list1, int *list2)
+{
+ int i;
+ int j;
+ for (i=0; i < n; i++) {
+ for (j=0; j < n; j++) {
+ if (list1[i] == list2[j])
+ break;
+ }
+ if (j == n) {
+ /* fail */
+ return 1;
+ }
+ }
+
+ /* success */
+ return 0;
+}
+
+int
+do_test(char *name)
+{
+ pmDesc desc;
+ pmID pmid;
+ int err;
+ char *metriclist[1];
+ char **namelist;
+ int *instlist;
+ int n_instlist;
+ pmResult *r1;
+ pmResult *r2;
+ int n_r1, n_r2;
+ int *r1_instlist;
+ int *r2_instlist;
+ int *half_instlist;
+ int n_half_instlist;
+ int i;
+
+ metriclist[0] = name;
+
+ if ((err = pmLookupName(1, metriclist, &pmid)) < 0) {
+ fprintf(stderr, "pmLookupName failed for %s: %s\n", name, pmErrStr(err));
+ return err;
+ }
+
+ if ((err = pmLookupDesc(pmid, &desc)) < 0) {
+ fprintf(stderr, "pmLookupDesc failed for %s: %s\n", name, pmErrStr(err));
+ return err;
+ }
+
+ if (desc.indom == PM_INDOM_NULL) {
+ fprintf(stderr, "this test only works for non-singular instance domains\n");
+ return PM_ERR_INDOM;
+ }
+
+ if ((err = pmGetInDom(desc.indom, &instlist, &namelist)) < 0) {
+ fprintf(stderr, "pmGetInDom failed for %s: %s\n", name, pmErrStr(err));
+ return err;
+ }
+ else
+ n_instlist = err;
+
+ /*
+ * check lookup for instances in both directions
+ */
+ for (i = 0; i < n_instlist; i++) {
+ char *myname;
+ if ((err = pmLookupInDom(desc.indom, namelist[i])) < 0) {
+ fprintf(stderr, "pmLookupInDom failed for %s[%s]: %s\n", name, namelist[i], pmErrStr(err));
+ return err;
+ }
+ if (err != instlist[i]) {
+ fprintf(stderr, "pmLookupInDom %s[%s] -> %d, expecting %d\n", name, namelist[i], err, instlist[i]);
+ return PM_ERR_GENERIC;
+ }
+ if ((err = pmNameInDom(desc.indom, instlist[i], &myname)) < 0) {
+ fprintf(stderr, "pmNameInDom failed for %s[#%d]: %s\n", name, instlist[i], pmErrStr(err));
+ return err;
+ }
+ if (strcmp(namelist[i], myname) != 0) {
+ fprintf(stderr, "pmNameInDom %s[#%d] -> %s, expecting %s\n", name, instlist[i], myname, namelist[i]);
+ free(myname);
+ return PM_ERR_GENERIC;
+ }
+ free(myname);
+ }
+
+ if ((err = pmFetch(1, &pmid, &r1)) < 0) {
+ fprintf(stderr, "pmFetch failed for %s: %s\n", name, pmErrStr(err));
+ return err;
+ }
+
+ if ((err = pmDelProfile(desc.indom, 0, (int *)0)) < 0) {
+ fprintf(stderr, "pmDelProfile failed for %s: %s\n", name, pmErrStr(err));
+ return err;
+ }
+
+ /*
+ * DupContext should inherit profile ...
+ */
+ if ((err = pmDupContext()) < 0) {
+ fprintf(stderr, "pmDupContext failed: %s\n", pmErrStr(err));
+ return err;
+ }
+
+ if ((err = pmAddProfile(desc.indom, n_instlist, instlist)) < 0) {
+ fprintf(stderr, "pmAddProfile failed for %s: %s\n", name, pmErrStr(err));
+ return err;
+ }
+
+ if ((err = pmFetch(1, &pmid, &r2)) < 0) {
+ fprintf(stderr, "second pmFetch failed for %s: %s\n", name, pmErrStr(err));
+ return err;
+ }
+
+ /* now do the checking */
+ n_r1 = result_instlist(r1, &r1_instlist);
+ n_r2 = result_instlist(r2, &r2_instlist);
+
+ if (n_r1 != n_r2) {
+ fprintf(stderr, "number of instances for unprofiled fetch (%d) != that for the profiled fetch (%d)\n", n_r1, n_r2);
+ return PM_ERR_INDOM;
+ }
+
+ if (n_r1 != n_instlist) {
+ fprintf(stderr, "number of instances from unprofiled fetch (%d) != that for pmGetInDom (%d)\n", n_r1, n_instlist);
+ return PM_ERR_INDOM;
+ }
+
+ if (cmp_list(n_instlist, instlist, r1_instlist) != 0) {
+ fprintf(stderr, "instances from pmGetIndom do not match those from unprofiled fetch\n");
+ return PM_ERR_INDOM;
+ }
+
+ if (cmp_list(n_instlist, instlist, r2_instlist) != 0) {
+ fprintf(stderr, "instances from pmGetIndom do not match those from profiled fetch\n");
+ return PM_ERR_INDOM;
+ }
+
+ if (cmp_list(n_instlist, r1_instlist, r2_instlist) != 0) {
+ fprintf(stderr, "instances from unprofiled fetch do not match those from unprofiled fetch\n");
+ return PM_ERR_INDOM;
+ }
+
+ /* delete the whole profile, then add only every second instance */
+ if ((err = pmDelProfile(desc.indom, 0, (int *)0)) < 0) {
+ fprintf(stderr, "pmDelProfile failed for %s: %s\n", name, pmErrStr(err));
+ return err;
+ }
+
+ half_instlist = malloc(n_instlist * sizeof(int));
+ n_half_instlist = 0;
+ for (i=0; i < n_instlist; i+=2) {
+ if ((err = pmAddProfile(desc.indom, 1, &instlist[i])) < 0) {
+ fprintf(stderr, "failed to add instance from profile: %s\n", pmErrStr(err));
+ return err;
+ }
+ half_instlist[n_half_instlist++] = instlist[i];
+ }
+
+ pmFreeResult(r1);
+ pmFreeResult(r2);
+ free(r1_instlist);
+ free(r2_instlist);
+
+ if ((err = pmFetch(1, &pmid, &r1)) < 0) {
+ fprintf(stderr, "first half-profile pmFetch failed for %s: %s\n", name, pmErrStr(err));
+ return err;
+ }
+
+ if ((err = pmFetch(1, &pmid, &r2)) < 0) {
+ fprintf(stderr, "second half-profile pmFetch failed for %s: %s\n", name, pmErrStr(err));
+ return err;
+ }
+
+ n_r1 = result_instlist(r1, &r1_instlist);
+ n_r2 = result_instlist(r2, &r2_instlist);
+
+ if (n_r1 != n_r2) {
+ fprintf(stderr, "number of instances for first half-profile fetch (%d) != that for the second half-profile fetch (%d)\n", n_r1, n_r2);
+ return PM_ERR_INDOM;
+ }
+
+ if (n_r1 != n_half_instlist) {
+ fprintf(stderr, "number of instances from first half-profile fetch (%d) != that for the half-profile list (%d)\n", n_r1, n_instlist);
+ return PM_ERR_INDOM;
+ }
+
+ if (cmp_list(n_half_instlist, half_instlist, r1_instlist) != 0) {
+ fprintf(stderr, "instances from half-profile list do not match those from half-profile fetch\n");
+ return PM_ERR_INDOM;
+ }
+
+ if (cmp_list(n_half_instlist, half_instlist, r2_instlist) != 0) {
+ fprintf(stderr, "instances from half-profile list do not match those from half-profile fetch\n");
+ return PM_ERR_INDOM;
+ }
+
+ if (cmp_list(n_half_instlist, r1_instlist, r2_instlist) != 0) {
+ fprintf(stderr, "instances from first half-profile fetch do not match those from second half-profile fetch\n");
+ return PM_ERR_INDOM;
+ }
+
+ /* success */
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int errflag = 0;
+ char *errmsg;
+ int type = 0;
+ char *host = NULL; /* pander to gcc */
+ pmLogLabel label; /* get hostname for archives */
+ char local[MAXHOSTNAMELEN];
+ char *namespace = PM_NS_DEFAULT;
+ char *metricname = (char *)0;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:h:K:Ln:?")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive name */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_ARCHIVE;
+ host = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'h': /* contact PMCD on this hostname */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ host = optarg;
+ type = PM_CONTEXT_HOST;
+ break;
+
+ case 'K': /* update local PMDA table */
+ if ((errmsg = __pmSpecLocalPMDA(optarg)) != NULL) {
+ fprintf(stderr, "%s: __pmSpecLocalPMDA failed: %s\n", pmProgname, errmsg);
+ errflag++;
+ }
+ break;
+
+ case 'L': /* local PMDA connection, no PMCD */
+ if (type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h and -L allowed\n", pmProgname);
+ errflag++;
+ }
+ type = PM_CONTEXT_LOCAL;
+ gethostname(local, sizeof(local));
+ host = local;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ /* non-flag args are argv[optind] ... argv[argc-1] */
+
+ if (optind == argc-1) {
+ metricname = argv[optind];
+ optind++;
+ }
+ else {
+ fprintf(stderr, "metricname is a required argument\n");
+ errflag++;
+ }
+
+ if (errflag) {
+ fprintf(stderr,
+"Usage: %s [options] metricname\n\
+\n\
+Options\n\
+ -a archive metrics source is an archive log\n\
+ -D debug standard PCP debug flag\n\
+ -h host metrics source is PMCD on host (default is local libirixpmda)\n\
+ -L metrics source is local connection to PMDA, no PMCD\n\
+ -K spec optional additional PMDA spec for local connection\n\
+ spec is of the form op,domain,dso-path,init-routine\n\
+ -n namespace use an alternative PMNS\n",
+ pmProgname);
+ exit(1);
+ }
+
+ if (namespace != PM_NS_DEFAULT) {
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ if (type == 0) {
+ type = PM_CONTEXT_LOCAL;
+ gethostname(local, sizeof(local));
+ host = local;
+ }
+ if ((sts = pmNewContext(type, host)) < 0) {
+ if (type == PM_CONTEXT_HOST)
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ else if (type == PM_CONTEXT_LOCAL) {
+ fprintf(stderr, "%s: pmNewContext failed for PM_CONTEXT_LOCAL: %s\n",
+ pmProgname, pmErrStr(sts));
+ }
+ else
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, host, pmErrStr(sts));
+ exit(1);
+ }
+
+ if (type == PM_CONTEXT_ARCHIVE) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ exit(do_test(metricname));
+}
+
diff --git a/qa/src/torture_logmeta.c b/qa/src/torture_logmeta.c
new file mode 100644
index 0000000..0e74f20
--- /dev/null
+++ b/qa/src/torture_logmeta.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int i;
+ int sts = 0; /* pander to gcc */
+ int fault = 0;
+ int errflag = 0;
+ char *offset = NULL;
+ pmLogLabel label; /* get hostname for archives */
+ int tzh; /* initial timezone handle */
+ char local[MAXHOSTNAMELEN];
+ char *endnum;
+ struct timeval startTime;
+ struct timeval endTime;
+ struct timeval appStart;
+ struct timeval appEnd;
+ struct timeval appOffset;
+ int *instlist;
+ char **namelist;
+ char *name;
+ int xinst = -1;
+ char *xname = NULL;
+ char *xxname = NULL;
+ pmInDom indom[3]; /* null, good, bad */
+
+ /* trim cmd name of leading directory components */
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "fD:O:?")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'f': /* fault injection mode */
+ fault = 1;
+ break;
+
+ case 'O': /* sample offset time */
+ offset = optarg;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag || optind != argc-4) {
+ fprintf(stderr,
+"Usage: %s [options] archive domain good-serial bad-serial\n\
+\n\
+Options:\n\
+ -f fault injection mode ... only do good archive ops\n\
+ -O offset initial offset into the time window\n",
+ pmProgname);
+ exit(1);
+ }
+ indom[0] = PM_INDOM_NULL;
+ indom[1] = pmInDom_build(atoi(argv[optind+1]), atoi(argv[optind+2]));
+ indom[2] = pmInDom_build(atoi(argv[optind+1]), atoi(argv[optind+3]));
+
+ /*
+ * once per context type ... invalid, localhost, archive
+ */
+ for (c = 0; c < 3; c++) {
+ if (fault && c != 2)
+ continue;
+ if (c == 0) {
+ /* invalid context, none created yet */
+ sts = -1;
+ }
+ else if (c == 1) {
+ /* pmcd on localhost */
+ (void)gethostname(local, MAXHOSTNAMELEN);
+ local[MAXHOSTNAMELEN-1] = '\0';
+ if ((sts = pmNewContext(PM_CONTEXT_HOST, local)) < 0) {
+ fprintf(stderr, "%s: Cannot connect to PMCD on host \"%s\": %s\n",
+ pmProgname, local, pmErrStr(sts));
+ exit(1);
+ }
+ }
+ else if (c == 2) {
+ if ((sts = pmNewContext(PM_CONTEXT_ARCHIVE, argv[optind])) < 0) {
+ fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n",
+ pmProgname, argv[optind], pmErrStr(sts));
+ exit(1);
+ }
+ }
+ fprintf(stderr, "\n=== iteration %d context %d ===\n", c, sts);
+
+ if (c == 2) {
+ if ((sts = pmGetArchiveLabel(&label)) < 0) {
+ fprintf(stderr, "%s: Cannot get archive label record: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ startTime = label.ll_start;
+ if ((sts = pmGetArchiveEnd(&endTime)) < 0) {
+ fprintf(stderr, "%s: Cannot locate end of archive: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if ((tzh = pmNewContextZone()) < 0) {
+ fprintf(stderr, "%s: Cannot set context timezone: %s\n",
+ pmProgname, pmErrStr(tzh));
+ exit(1);
+ }
+ sts = pmParseTimeWindow(NULL, NULL, NULL, offset, &startTime,
+ &endTime, &appStart, &appEnd, &appOffset,
+ &endnum);
+ if (sts < 0) {
+ fprintf(stderr, "%s: illegal time window specification\n%s",
+ pmProgname, endnum);
+ exit(1);
+ }
+ if ((sts = pmSetMode(PM_MODE_FORW, &appOffset, 0)) < 0) {
+ fprintf(stderr, "%s: pmSetMode: %s\n",
+ pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ }
+
+ /*
+ * routines to be tested ...
+ *
+ * PMAPI
+ * [y] pmGetInDomArchive
+ * [y] pmLookupInDomArchive
+ * [y] pmNameInDomArchive
+ *
+ * internal
+ * [ ] __pmLogPutDesc
+ * [ ] __pmLogPutInDom
+ * [ ] __pmLogPutIndex
+ * [ ] __pmLogLookupDesc
+ * [y] __pmLogGetInDom
+ * [y] __pmLogLookupInDom
+ * [y] __pmLogNameInDom
+ */
+
+ /* once per indom ... null, good and bad */
+ for (i = 0; i < 3; i++) {
+ if (fault && i != 1)
+ continue;
+ if (i == 0) {
+ /* tests that do not use the indom ... */
+ ;
+ }
+
+ if ((sts = pmGetInDomArchive(indom[i], &instlist, &namelist)) < 0) {
+ fprintf(stderr, "pmGetInDomArchive(%s) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ int j;
+ fprintf(stderr, "pmGetInDomArchive(%s) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%d\n", sts);
+ for (j = 0; j < sts; j++)
+ fprintf(stderr, " [%d] %s\n", instlist[j], namelist[j]);
+ if (xname == NULL) {
+ char *q;
+ xname = strdup(namelist[0]);
+ for (q = xname; *q; q++) {
+ if (*q == ' ') {
+ xxname = strdup(xname);
+ xxname[q-xname] = '\0';
+ break;
+ }
+ }
+ }
+ free(instlist);
+ free(namelist);
+ }
+
+ if (!fault) {
+ if ((sts = pmLookupInDomArchive(indom[i], "foobar")) < 0) {
+ fprintf(stderr, "pmLookupInDomArchive(%s, foobar) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ fprintf(stderr, "pmLookupInDomArchive(%s, foobar) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%d\n", sts);
+ }
+ }
+
+ if (xname != NULL) {
+ if ((sts = pmLookupInDomArchive(indom[i], xname)) < 0) {
+ fprintf(stderr, "pmLookupInDomArchive(%s, %s) -> ", pmInDomStr(indom[i]), xname);
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ fprintf(stderr, "pmLookupInDomArchive(%s, %s) -> ", pmInDomStr(indom[i]), xname);
+ fprintf(stderr, "%d\n", sts);
+ if (xinst == -1)
+ xinst = sts;
+ }
+ }
+
+ if (xxname != NULL) {
+ if ((sts = pmLookupInDomArchive(indom[i], xxname)) < 0) {
+ fprintf(stderr, "pmLookupInDomArchive(%s, %s) -> ", pmInDomStr(indom[i]), xxname);
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ fprintf(stderr, "pmLookupInDomArchive(%s, %s) -> ", pmInDomStr(indom[i]), xxname);
+ fprintf(stderr, "%d\n", sts);
+ }
+ }
+
+ if (!fault) {
+ if ((sts = pmNameInDomArchive(indom[i], 1234567, &name)) < 0) {
+ fprintf(stderr, "pmNameInDomArchive(%s, 1234567) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ fprintf(stderr, "pmNameInDomArchive(%s, 1234567) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%s\n", name);
+ free(name);
+ }
+ }
+
+ if (xinst != -1) {
+ if ((sts = pmNameInDomArchive(indom[i], xinst, &name)) < 0) {
+ fprintf(stderr, "pmNameInDomArchive(%s, %d) -> ", pmInDomStr(indom[i]), xinst);
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ fprintf(stderr, "pmNameInDomArchive(%s, %d) -> ", pmInDomStr(indom[i]), xinst);
+ fprintf(stderr, "%s\n", name);
+ free(name);
+ }
+ }
+
+ if ((sts = pmWhichContext()) >= 0) {
+ __pmContext *ctxp;
+ ctxp = __pmHandleToPtr(sts);
+ if (ctxp != NULL && ctxp->c_archctl != NULL) {
+ __pmTimeval now;
+ int iter;
+ for (iter=0; iter < 2; iter++) {
+ /*
+ * use -O time (defaults to start time) on first
+ * iteration, then half the time between there
+ * and the end
+ */
+ if (fault && iter != 1)
+ continue;
+ if (iter == 0) {
+ now.tv_sec = appOffset.tv_sec;
+ now.tv_usec = appOffset.tv_usec;
+ }
+ else {
+ /*
+ * danger! need to promote arithmetic to 64-bit
+ * for platforms where tv_sec is 32-bit and
+ * tv_sec + tv_sec => overflow
+ */
+ now.tv_sec = ((__int64_t)appOffset.tv_sec+(__int64_t)appEnd.tv_sec)/2;
+ now.tv_usec = ((__int64_t)appOffset.tv_usec+(__int64_t)appEnd.tv_usec)/2;
+ }
+ if ((sts = __pmLogGetInDom(ctxp->c_archctl->ac_log, indom[i], &now, &instlist, &namelist)) < 0) {
+ fprintf(stderr, "__pmLogGetInDom(%s) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ int j;
+ fprintf(stderr, "__pmLogGetInDom(%s) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%d\n", sts);
+ for (j = 0; j < sts; j++)
+ fprintf(stderr, " [%d] %s\n", instlist[j], namelist[j]);
+ }
+ if (!fault) {
+ if ((sts = __pmLogLookupInDom(ctxp->c_archctl->ac_log, indom[i], &now, "foobar")) < 0) {
+ fprintf(stderr, "__pmLogLookupInDom(%s, foobar) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ fprintf(stderr, "__pmLogLookupInDom(%s, foobar) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%d\n", sts);
+ }
+ }
+ if (xname != NULL) {
+ if ((sts = __pmLogLookupInDom(ctxp->c_archctl->ac_log, indom[i], &now, xname)) < 0) {
+ fprintf(stderr, "__pmLogLookupInDom(%s, %s) -> ", pmInDomStr(indom[i]), xname);
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ fprintf(stderr, "__pmLogLookupInDom(%s, %s) -> ", pmInDomStr(indom[i]), xname);
+ fprintf(stderr, "%d\n", sts);
+ }
+ }
+ if (xxname != NULL) {
+ if ((sts = __pmLogLookupInDom(ctxp->c_archctl->ac_log, indom[i], &now, xxname)) < 0) {
+ fprintf(stderr, "__pmLogLookupInDom(%s, %s) -> ", pmInDomStr(indom[i]), xxname);
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ fprintf(stderr, "__pmLogLookupInDom(%s, %s) -> ", pmInDomStr(indom[i]), xxname);
+ fprintf(stderr, "%d\n", sts);
+ }
+ }
+ if (!fault) {
+ if ((sts = __pmLogNameInDom(ctxp->c_archctl->ac_log, indom[i], &now, 1234567, &name)) < 0) {
+ fprintf(stderr, "__pmLogNameInDom(%s, 1234567) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ fprintf(stderr, "__pmLogNameInDom(%s, 1234567) -> ", pmInDomStr(indom[i]));
+ fprintf(stderr, "%s\n", name);
+ }
+ }
+ if (xinst != -1) {
+ if ((sts = __pmLogNameInDom(ctxp->c_archctl->ac_log, indom[i], &now, xinst, &name)) < 0) {
+ fprintf(stderr, "__pmLogNameInDom(%s, %d) -> ", pmInDomStr(indom[i]), xinst);
+ fprintf(stderr, "%s\n", pmErrStr(sts));
+ }
+ else {
+ fprintf(stderr, "__pmLogNameInDom(%s, %d) -> ", pmInDomStr(indom[i]), xinst);
+ fprintf(stderr, "%s\n", name);
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ }
+
+ return 0;
+}
diff --git a/qa/src/torture_pmns.c b/qa/src/torture_pmns.c
new file mode 100644
index 0000000..17e986c
--- /dev/null
+++ b/qa/src/torture_pmns.c
@@ -0,0 +1,495 @@
+/*
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) 2009 Ken McDonell. All Rights Reserved.
+ *
+ * Exercise just the PMNS functions ... intended for dynamic PMNS testing
+ * ... this is really torture_api re-tweaked
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int vflag;
+static char *context_name = "localhost";
+static int context_type = 0; /* archive, host or local */
+static char *namespace = PM_NS_DEFAULT;
+static int all_children = 1; /* do the children of "" test */
+static int root_children; /* only do the children of "" test */
+static int dump_metrics; /* just dump the metrics and exit */
+/*
+ * pmns_style == 1 => do PMNS style loading the old way
+ * pmns_style == 2 => try to use the distributed PMNS
+ */
+static int pmns_style = 2;
+
+static int numpmid = 0;
+static char **namelist; /* The list of metrics to test out */
+static pmID *midlist;
+
+typedef struct name_status {
+ char *name;
+ int status;
+}name_status;
+
+#define REPORT(str, sts) \
+printf("%s() returns %d", str, sts);\
+if (sts < 0) printf(" (%s)", pmErrStr(sts));\
+putchar('\n');
+
+static int
+compar_str(const void *a, const void *b)
+{
+ char **ca = (char **)a;
+ char **cb = (char **)b;
+ return strcmp(*ca, *cb);
+}
+
+static int
+compar_name_status(const void *a, const void *b)
+{
+ name_status *ca = (name_status*)a;
+ name_status *cb = (name_status*)b;
+ return strcmp(ca->name, cb->name);
+}
+
+void
+do_chn(char *name)
+{
+ int n;
+ int j;
+ char **enfants = NULL;
+ name_status *ns_table = NULL;
+ int has_children = 0;
+
+ n = pmGetChildren(name, &enfants);
+ REPORT("pmGetChildren", n);
+ if (n > 0) {
+ qsort(enfants, n, sizeof(enfants[0]), compar_str);
+ has_children = 1;
+ }
+
+ /* test out pmGetChildrenStatus */
+ {
+ char **s_enfants = NULL;
+ int *status = NULL;
+
+ n = pmGetChildrenStatus(name, &s_enfants, &status);
+ REPORT("pmGetChildrenStatus", n);
+ if (n > 0) {
+ /* create a ns_table for sorting */
+ ns_table = (name_status*)malloc(sizeof(name_status)*n);
+ if (ns_table == 0) {
+ printf("Malloc failed\n");
+ exit(1);
+ }
+ for(j = 0; j < n; j++) {
+ ns_table[j].name = s_enfants[j];
+ ns_table[j].status = status[j];
+ }
+
+ qsort(ns_table, n, sizeof(ns_table[0]), compar_name_status);
+
+ for (j = 0; j < n; j++) {
+ if (strcmp(ns_table[j].name, enfants[j]) != 0) {
+ printf("pmGetChildrenStatus mismatch: \"%s\" vs \"%s\"\n",
+ enfants[j], ns_table[j].name);
+ }
+ }/*for*/
+ }/*if*/
+ if (s_enfants) free(s_enfants);
+ if (status) free(status);
+ }
+
+ if (has_children && vflag) {
+ printf("children of \"%s\" ...\n", name);
+ for (j = 0; j < n; j++) {
+
+ printf(" %-20s", enfants[j]);
+ if (ns_table)
+ printf("<s = %d>", ns_table[j].status);
+ printf("\n");
+ }
+ }
+
+ if (enfants) free(enfants);
+ if (ns_table) free(ns_table);
+
+}
+
+void
+parse_args(int argc, char **argv)
+{
+ extern char *optarg;
+ extern int optind;
+ int errflag = 0;
+ int c;
+ static char *usage = "[-bcLmvx] [-a archive] [-h host] [-n namespace] [-s 1|2] metricname ...";
+ char *endnum;
+ int sts;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D <dbg>]";
+#else
+ static char *debug = "";
+#endif
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:bcD:h:iLmn:s:vx")) != EOF) {
+ switch (c) {
+ case 'a': /* archive name for context */
+ if (context_type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -x allowed\n",
+ pmProgname);
+ errflag++;
+ }
+ context_type = PM_CONTEXT_ARCHIVE;
+ context_name = optarg;
+ break;
+
+ case 'b': /* dont do the children of "" test */
+ all_children = 0;
+ break;
+
+ case 'c': /* only do the children of "" test */
+ root_children = 1;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'h': /* context_namename for live context */
+ if (context_type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -x allowed\n",
+ pmProgname);
+ errflag++;
+ }
+ context_type = PM_CONTEXT_HOST;
+ context_name = optarg;
+ break;
+
+ case 'i': /* non-IRIX names (always true now) */
+ break;
+
+ case 'L': /* LOCAL context */
+ if (context_type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -x allowed\n",
+ pmProgname);
+ errflag++;
+ }
+ context_type = PM_CONTEXT_LOCAL;
+ context_name = NULL;
+ break;
+
+ case 'm': /* dump out the list of metrics to be tested */
+ dump_metrics = 1;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'v': /* verbose */
+ vflag++;
+ break;
+
+ case 'x': /* NO context */
+ if (context_type != 0) {
+ fprintf(stderr, "%s: at most one of -a, -h, -L and -x allowed\n",
+ pmProgname);
+ errflag++;
+ }
+ context_type = -1;
+ context_name = NULL;
+ break;
+
+ case 's': /* pmns style */
+ pmns_style = (int)strtol(optarg, &endnum, 10);
+ if (*endnum != '\0') {
+ printf("%s: -s requires numeric argument\n", pmProgname);
+ errflag++;
+ }
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (context_type == 0) context_type = PM_CONTEXT_HOST;
+
+ numpmid = argc - optind;
+ if (numpmid < 1) {
+ errflag++;
+ }
+ else {
+ int i;
+ if ((midlist = (pmID *)malloc(numpmid*sizeof(pmID))) == NULL) {
+ fprintf(stderr, "malloc failed for midlist[]: %s\n", strerror(errno));
+ exit(1);
+ }
+ if ((namelist = (char **)malloc(numpmid*sizeof(char *))) == NULL) {
+ fprintf(stderr, "malloc failed for namelist[]: %s\n", strerror(errno));
+ exit(1);
+ }
+ for (i = 0; i < numpmid; i++)
+ namelist[i] = argv[optind+i];
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+}
+
+void
+load_namespace(char *namespace)
+{
+ struct timeval now, then;
+ int sts;
+
+ gettimeofday(&then, (struct timezone *)0);
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+ gettimeofday(&now, (struct timezone *)0);
+ printf("Name space load: %.2f msec\n", __pmtimevalSub(&now, &then)*1000);
+}
+
+void
+test_api(void)
+{
+ int sts;
+ int i;
+ int *instlist;
+ char **inamelist;
+ char **allnames;
+ int n;
+ char *back;
+ pmResult *resp;
+ pmDesc desc;
+
+ if (context_type != -1) {
+ if (context_type == 0) {
+ char local[MAXHOSTNAMELEN];
+ context_type = PM_CONTEXT_HOST;
+ gethostname(local, sizeof(local));
+ context_name = local;
+ }
+
+ if ((sts = pmNewContext(context_type, context_name)) < 0) {
+ printf("%s: Error in creating %s context for \"%s\": %s\n",
+ pmProgname,
+ context_type == PM_CONTEXT_HOST ? "host" :
+ context_type == PM_CONTEXT_ARCHIVE ? "archive" :
+ "local",
+ context_name,
+ pmErrStr(sts));
+ }
+ }
+
+ if (vflag > 1) {
+ __pmDumpNameSpace(stdout, 1);
+ }
+
+ n = pmLookupName(numpmid, namelist, midlist);
+ REPORT("pmLookupName", n);
+
+ for (i = 0; i < numpmid; i++) {
+ printf("%s: id[%d] = %s\n", namelist[i], i, pmIDStr(midlist[i]));
+ }
+
+ /* Set mode for archive so that an indom can be retrieved
+ * if necessary.
+ * Getting an indom is done based on current time.
+ * If we try and get an indom from the start then we may not
+ * have one yet.
+ */
+ if (context_type == PM_CONTEXT_ARCHIVE) {
+ struct timeval when;
+
+ n = pmGetArchiveEnd(&when);
+ REPORT("pmGetArchiveEnd", n);
+
+ n = pmSetMode(PM_MODE_BACK, &when, 1000);
+ REPORT("pmSetMode", n);
+ }
+
+ for (i = 0; i < numpmid && !root_children; i++) {
+ putchar('\n');
+ if (vflag) {
+ printf("=== metric %d === name: %s pmid %s\n", i, namelist[i], pmIDStr(midlist[i]));
+ }
+ if (midlist[i] != PM_ID_NULL) {
+ n = pmNameID(midlist[i], &back);
+ REPORT("pmNameID", n);
+ if (n >= 0) {
+ if (vflag) {
+ printf("pmid: %s ", pmIDStr(midlist[i]));
+ printf(" name: %s\n", back);
+ }
+ if (strcmp(namelist[i], back) != 0) {
+ printf("pmNameID botch: expected \"%s\", got \"%s\"\n",
+ namelist[i], back);
+ }
+ free(back);
+ }
+ n = pmNameAll(midlist[i], &allnames);
+ REPORT("pmNameAll", n);
+ if (n >= 0) {
+ int j;
+ for (j = 0; j < n; j++) {
+ if (vflag) {
+ printf("pmid: %s ", pmIDStr(midlist[i]));
+ printf(" name: %s\n", allnames[j]);
+ }
+ if (strcmp(namelist[i], allnames[j]) != 0) {
+ printf("pmNameAll info: expected \"%s\", got \"%s\"\n",
+ namelist[i], allnames[j]);
+ }
+ }
+ free(allnames);
+ }
+ if (context_type != -1) {
+ n = pmLookupDesc(midlist[i], &desc);
+ REPORT("pmLookupDesc", n);
+ if (n >= 0) {
+ if (vflag > 1) {
+ const char *u = pmUnitsStr(&desc.units);
+ printf("desc: type=%d indom=0x%x sem=%d units=%s\n",
+ desc.type, desc.indom, desc.sem,
+ *u == '\0' ? "none" : u);
+ }
+ if (desc.indom == PM_INDOM_NULL)
+ continue;
+ n = pmGetInDom(desc.indom, &instlist, &inamelist);
+ REPORT("pmGetInDom", n);
+ if (n >= 0) {
+ int j;
+ int numinst = n;
+ char *name;
+ for (j = 0; j < numinst; j++) {
+ if (vflag > 1)
+ printf(" instance id: 0x%x\n", instlist[j]);
+ n = pmNameInDom(desc.indom, instlist[j], &name);
+ REPORT("pmNameInDom", n);
+ if (n >= 0) {
+ if (vflag > 1)
+ printf(" %s (== %s?)\n", name, inamelist[j]);
+ n = pmLookupInDom(desc.indom, name);
+ REPORT("pmLookupInDom", n);
+ if (n >= 0) {
+ if (n != instlist[j]) {
+ printf("botch: pmLookupInDom returns 0x%x, expected 0x%x\n",
+ n, instlist[j]);
+ }
+ }
+ free(name);
+ }
+ }
+ free(instlist);
+ free(inamelist);
+ }
+ }
+ }
+ }
+ do_chn(namelist[i]);
+ } /* for each named metric */
+
+ if (all_children || root_children) {
+ /* root check */
+ /*
+ * This is only useful in a namspace where irix has not been stripped from the
+ * names. Once irix is stripped from the names, the list returned becomes
+ * to variable to do a QA in this manner.
+ * Test #568 using pmns_xlate tests the root.
+ */
+ printf("\n");
+ do_chn("");
+ }
+
+ if (context_type == PM_CONTEXT_ARCHIVE) {
+ struct timeval when;
+
+ when.tv_sec = 0;
+ when.tv_usec = 0;
+
+ if (vflag)
+ printf("\nArchive result ...\n");
+ for (i = 0; i < numpmid; i++) {
+ if (midlist[i] == PM_ID_NULL)
+ continue;
+ if ((n = pmSetMode(PM_MODE_FORW, &when, 0)) < 0) {
+ printf("pmSetMode(PM_MODE_FORW): %s\n", pmErrStr(n));
+ }
+ else {
+ if (vflag)
+ printf("Fetch of %s:\n", namelist[i]);
+ if ((n = pmFetch(1, &midlist[i], &resp)) < 0) {
+ printf("Archive pmFetch: %s\n", pmErrStr(n));
+ }
+ else {
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ pmFreeResult(resp);
+ }
+ }
+ }/*for*/
+ }
+
+ else if (context_type == PM_CONTEXT_HOST) {
+ if ((n = pmSetMode(PM_MODE_LIVE, (struct timeval *)0, 0)) < 0) {
+ printf("pmSetMode(PM_MODE_LIVE): %s\n", pmErrStr(n));
+ }
+ else {
+ if ((n = pmFetch(numpmid, midlist, &resp)) < 0) {
+ printf("real-time pmFetch: %s\n", pmErrStr(n));
+ }
+ else {
+ if (vflag) {
+ printf("\nReal-time result ...\n");
+ __pmDumpResult(stdout, resp);
+ }
+ pmFreeResult(resp);
+ }
+ }
+ }
+
+}
+
+int
+main(int argc, char **argv)
+{
+ parse_args(argc, argv);
+
+ if (dump_metrics == 1) {
+ int i;
+ for(i = 0; i < numpmid; i++) {
+ printf("%s\n", namelist[i]);
+ }
+ exit(0);
+ }
+
+ if (pmns_style == 2) {
+ /* test it the new way with distributed namespace */
+ /* i.e. no client loaded namespace */
+ test_api();
+ }
+ else {
+ /* test it the old way with namespace file */
+ load_namespace(namespace);
+ test_api();
+ }
+
+ exit(0);
+}
diff --git a/qa/src/torture_trace.c b/qa/src/torture_trace.c
new file mode 100644
index 0000000..6e48182
--- /dev/null
+++ b/qa/src/torture_trace.c
@@ -0,0 +1,156 @@
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/trace.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <time.h>
+#ifdef IS_SOLARIS
+#include <sys/rtpriocntl.h>
+#include <sys/tspriocntl.h>
+#include <sys/processor.h>
+#endif
+#ifdef HAVE_PRCTL
+#include <sys/prctl.h>
+#endif
+#include <sys/wait.h>
+
+#ifndef HAVE_SPROC
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#endif /*HAVE_SPROC*/
+
+#define MAXTAGNAMELEN 256
+
+static int obscount = 0;
+static int pointcount = 0;
+static int transactcount = 0;
+
+void
+gentag(char *buf)
+{
+ int i, len;
+
+ len = (int)lrand48() % 10 + 1;
+ for (i=0; i < len; i++)
+ buf[i] = (char)((int)lrand48() % 88 + 40); /* some ascii */
+ buf[i] = '\0';
+ /*fprintf(stderr, "Generated tag \"%s\" for pid=%d\n", buf, getpid());*/
+}
+
+void
+run(int sts, char *tag)
+{
+ char *err;
+ err = pmtraceerrstr(sts);
+ if (sts < 0)
+ fprintf(stderr, "failed on tag \"%s\": %s\n", tag, err);
+}
+
+/*ARGSUSED*/
+void
+sproc1(void *foo)
+{
+ int i;
+ char buf[64];
+ double nan=0.0;
+
+ for (i = 0; i < 5; i++)
+ nan = 0.0/nan;
+ for (i = 0; i < 1000; i++) {
+ gentag(buf);
+ run(pmtraceobs(buf, nan), buf);
+ run(pmtraceobs(buf, 2.239801), buf);
+ obscount++;
+ }
+}
+
+/*ARGSUSED*/
+void
+sproc2(void *foo)
+{
+ int i;
+ char buf[64];
+
+ for (i = 0; i < 2000; i++) {
+ gentag(buf);
+ run(pmtracepoint(buf), buf);
+ pointcount++;
+ }
+}
+
+/*ARGSUSED*/
+void
+sproc3(void *foo)
+{
+ int i;
+ char buf1[64], buf2[64], buf3[64], buf4[64];
+
+ gentag(buf1);
+ gentag(buf2);
+ gentag(buf3);
+ gentag(buf4);
+
+ for (i=0; i < 500; i++) {
+ run(pmtracebegin(buf1), buf1);
+ run(pmtracebegin(buf2), buf2);
+ run(pmtracebegin(buf3), buf3);
+ run(pmtraceend(buf2), buf2); transactcount++;
+ run(pmtracebegin(buf4), buf4);
+ run(pmtraceend(buf4), buf4); transactcount++;
+ run(pmtraceend(buf3), buf3); transactcount++;
+ run(pmtraceend(buf1), buf1); transactcount++;
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ int i;
+#ifndef HAVE_SPROC
+ pthread_t threads[3];
+#endif
+
+ /* exercise the zero-observation case */
+ run(pmtraceobs("zero", 0), "zero");
+ obscount++;
+
+ srand48((long)time(0));
+ /*pmtracestate(PMTRACE_STATE_COMMS | PMTRACE_STATE_API);*/
+
+ /* eat this, pmdatrace! */
+#ifdef HAVE_SPROC
+ sproc(sproc1, PR_SADDR, NULL);
+ sproc(sproc2, PR_SADDR, NULL);
+ sproc(sproc3, PR_SADDR, NULL);
+#else
+ pthread_create(threads, NULL, (void (*))sproc1, NULL);
+ pthread_create(threads+1, NULL, (void (*))sproc2, NULL);
+ pthread_create(threads+2, NULL, (void (*))sproc3, NULL);
+#endif
+
+ for (i=0; i < 3; i++) {
+#ifdef HAVE_SPROC
+ wait(NULL);
+#else
+ void * rv;
+
+ pthread_join (threads[i], &rv);
+#endif
+ fprintf(stderr, "reaped sproc #%d\n", i);
+ }
+
+ fprintf(stderr, "torture_trace counters:\n");
+ fprintf(stderr, " pmtraceobs %d\n", obscount);
+ fprintf(stderr, " pmtracepoint %d\n", pointcount);
+ fprintf(stderr, " pmtracetransact %d\n", transactcount);
+
+ exit(0);
+}
diff --git a/qa/src/tstate.c b/qa/src/tstate.c
new file mode 100644
index 0000000..2a581b4
--- /dev/null
+++ b/qa/src/tstate.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <pcp/trace.h>
+
+
+int
+tracestate(int flag)
+{
+ int tmp = pmtracestate(0);
+ int var;
+
+ tmp |= flag;
+ var = pmtracestate(tmp);
+ fprintf(stderr, "tstate: state now is 0x%x\n", tmp);
+ return var;
+}
+
+int
+main(int argc, char **argv)
+{
+ int sts;
+
+ if (argc != 2) {
+ fprintf(stderr, "tstate: takes one argument.\n");
+ exit(1);
+ }
+
+ /*
+ * this exercises the state setting routine in libpcp_trace,
+ * particularly the async protocol flag setting, since this
+ * is a little more involved.
+ */
+
+ if (argv[1][0] == '1') {
+ fprintf(stderr, "--- Test 1 ---\n");
+ tracestate(PMTRACE_STATE_API);
+ tracestate(PMTRACE_STATE_PDU | PMTRACE_STATE_PDUBUF);
+ sts = pmtracepoint("tstate1"); /* no longer able to change protocol */
+ if (sts < 0) {
+ fprintf(stderr, "tstate pmtracepoint: %s\n", pmtraceerrstr(sts));
+ exit(1);
+ }
+ fprintf(stderr, "state should be only ASYNC 0x%x ...\n", PMTRACE_STATE_ASYNC);
+ tracestate(PMTRACE_STATE_ASYNC);
+ }
+ else if (argv[1][0] == '2') {
+ fprintf(stderr, "--- Test 2 ---\n");
+ tracestate(PMTRACE_STATE_ASYNC);
+ fprintf(stderr, "state should be same as previous ...\n");
+ tracestate(PMTRACE_STATE_ASYNC);
+ }
+ else if (argv[1][0] == '3') {
+ fprintf(stderr, "--- Test 3 ---\n");
+ pmtracepoint("tstate3");
+ fprintf(stderr, "state change should fail ... ");
+ if ((sts = pmtracestate(PMTRACE_STATE_ASYNC)) < 0)
+ fprintf(stderr, "OK\n");
+ else
+ fprintf(stderr, "urk - non-negative returned (%d)!\n", sts);
+ }
+ else if (argv[1][0] == '4') {
+ fprintf(stderr, "--- Test 4 ---\n");
+ tracestate(PMTRACE_STATE_ASYNC|PMTRACE_STATE_API);
+ sts = pmtracepoint("tstate4");
+ if (sts < 0) {
+ fprintf(stderr, "tstate pmtracepoint: %s\n", pmtraceerrstr(sts));
+ exit(1);
+ }
+ fprintf(stderr, "change to async only (0x%x)...\n", PMTRACE_STATE_ASYNC);
+ tracestate(PMTRACE_STATE_ASYNC);
+ }
+ else {
+ fprintf(stderr, "Don't know what to do with \"%s\"\n", argv[1]);
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/tzchange-10-a.0 b/qa/src/tzchange-10-a.0
new file mode 100644
index 0000000..5692826
--- /dev/null
+++ b/qa/src/tzchange-10-a.0
Binary files differ
diff --git a/qa/src/tzchange-10-a.index b/qa/src/tzchange-10-a.index
new file mode 100644
index 0000000..03ccb57
--- /dev/null
+++ b/qa/src/tzchange-10-a.index
Binary files differ
diff --git a/qa/src/tzchange-10-a.meta b/qa/src/tzchange-10-a.meta
new file mode 100644
index 0000000..c3a36f8
--- /dev/null
+++ b/qa/src/tzchange-10-a.meta
Binary files differ
diff --git a/qa/src/tzchange-10-b.0 b/qa/src/tzchange-10-b.0
new file mode 100644
index 0000000..b94ac52
--- /dev/null
+++ b/qa/src/tzchange-10-b.0
Binary files differ
diff --git a/qa/src/tzchange-10-b.index b/qa/src/tzchange-10-b.index
new file mode 100644
index 0000000..015ddfa
--- /dev/null
+++ b/qa/src/tzchange-10-b.index
Binary files differ
diff --git a/qa/src/tzchange-10-b.meta b/qa/src/tzchange-10-b.meta
new file mode 100644
index 0000000..8a5dbde
--- /dev/null
+++ b/qa/src/tzchange-10-b.meta
Binary files differ
diff --git a/qa/src/tzchange-11-a.0 b/qa/src/tzchange-11-a.0
new file mode 100644
index 0000000..590dab2
--- /dev/null
+++ b/qa/src/tzchange-11-a.0
Binary files differ
diff --git a/qa/src/tzchange-11-a.index b/qa/src/tzchange-11-a.index
new file mode 100644
index 0000000..41b61af
--- /dev/null
+++ b/qa/src/tzchange-11-a.index
Binary files differ
diff --git a/qa/src/tzchange-11-a.meta b/qa/src/tzchange-11-a.meta
new file mode 100644
index 0000000..7cef963
--- /dev/null
+++ b/qa/src/tzchange-11-a.meta
Binary files differ
diff --git a/qa/src/tzchange-11-b.0 b/qa/src/tzchange-11-b.0
new file mode 100644
index 0000000..dabb12b
--- /dev/null
+++ b/qa/src/tzchange-11-b.0
Binary files differ
diff --git a/qa/src/tzchange-11-b.index b/qa/src/tzchange-11-b.index
new file mode 100644
index 0000000..43793b5
--- /dev/null
+++ b/qa/src/tzchange-11-b.index
Binary files differ
diff --git a/qa/src/tzchange-11-b.meta b/qa/src/tzchange-11-b.meta
new file mode 100644
index 0000000..8311271
--- /dev/null
+++ b/qa/src/tzchange-11-b.meta
Binary files differ
diff --git a/qa/src/tzchange-12-a.0 b/qa/src/tzchange-12-a.0
new file mode 100644
index 0000000..ac963c8
--- /dev/null
+++ b/qa/src/tzchange-12-a.0
Binary files differ
diff --git a/qa/src/tzchange-12-a.index b/qa/src/tzchange-12-a.index
new file mode 100644
index 0000000..642f780
--- /dev/null
+++ b/qa/src/tzchange-12-a.index
Binary files differ
diff --git a/qa/src/tzchange-12-a.meta b/qa/src/tzchange-12-a.meta
new file mode 100644
index 0000000..6e00b93
--- /dev/null
+++ b/qa/src/tzchange-12-a.meta
Binary files differ
diff --git a/qa/src/tzchange-12-b.0 b/qa/src/tzchange-12-b.0
new file mode 100644
index 0000000..bd6c5d5
--- /dev/null
+++ b/qa/src/tzchange-12-b.0
Binary files differ
diff --git a/qa/src/tzchange-12-b.index b/qa/src/tzchange-12-b.index
new file mode 100644
index 0000000..51ca138
--- /dev/null
+++ b/qa/src/tzchange-12-b.index
Binary files differ
diff --git a/qa/src/tzchange-12-b.meta b/qa/src/tzchange-12-b.meta
new file mode 100644
index 0000000..13d6025
--- /dev/null
+++ b/qa/src/tzchange-12-b.meta
Binary files differ
diff --git a/qa/src/tztest.c b/qa/src/tztest.c
new file mode 100644
index 0000000..b5c6c2a
--- /dev/null
+++ b/qa/src/tztest.c
@@ -0,0 +1,81 @@
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+char * __pmTimezone(void);
+
+int main()
+{
+ time_t sept = (30*365.25+244)*24*3600; /* 1 Septemnber 2000 */
+ time_t march = (30*365.25+60)*24*3600; /* 1 March 2000 */
+
+ /* Two sets of timezone strings - one works for the first half
+ * of the year, another for the second. Make sure that in the case
+ * where we cannot reduce the timezone string and have to re-write it
+ * same timezone is choosen */
+ char *zones[][8] = {
+ {
+ "ABC-10",
+ "ABC-10:01:02XYZ-11:03:04,M12.5.0/3:04:05,M7.1.0/2:06:07",
+ "ABC-10:00:00XYZ-11:00:00,M12.5.0/3:00:00,M7.5.0/2:00:00",
+ "ABC-10XYZ-11,M12.5.0/3:00:00,M7.1.0/2:00:00",
+ "ABC-10XYZ-11,M12.5.0/3:01:02,M7.1.0/2:03:04",
+ "ABC-10",
+ ":Someplace/Somewhere",
+ NULL
+ },
+ {
+ "ABC-10",
+ "XYZ-11:03:04ABC-10:01:02,M12.5.0/3:04:05,M7.1.0/2:06:07",
+ "ABC-10:00:00XYZ-11:00:00,M12.5.0/3:00:00,M7.5.0/2:00:00",
+ "ABC-10XYZ-11,M12.5.0/3:00:00,M7.1.0/2:00:00",
+ "XYZ-11ABC-10,M12.5.0/3:01:02,M7.1.0/2:03:04",
+ "ABC-10",
+ ":Someplace/Somewhere",
+ NULL
+ }};
+ char * tz = getenv("TZ");
+
+ if (tz == NULL) {
+ puts("Timezone is not set, abort the test");
+ } else {
+ int i;
+ time_t now = time(NULL);
+ struct tm * today = localtime(&now);
+ int which = today->tm_mon / 6;
+ char tb[256];
+ char * newtz = __pmTimezone();
+
+ printf("%s -> %s\n", tz, newtz);
+
+ for (i=0; zones[which][i] != NULL; i++) {
+ char * tz;
+ struct tm *tmp;
+ char tstr[64];
+ int dst;
+
+ sprintf(tb, "TZ=%s", zones[which][i]);
+ putenv(tb);
+ tzset();
+ tz = getenv("TZ");
+ newtz = __pmTimezone();
+
+ printf("%s -> %s\n", tz, newtz);
+ tmp = localtime(&march);
+ dst = tmp->tm_isdst;
+
+ strftime(tstr, 64, "%d %B %Y %H:%M %Z", tmp);
+ printf("In March daylight saving is %s, and the time is %s\n",
+ (dst ? "on" : "off"), tstr);
+ tmp = localtime(&sept);
+ dst = tmp->tm_isdst;
+ strftime(tstr, 64, "%d %B %Y %H:%M %Z", tmp);
+ printf("In September daylight saving is %s, and the time is %s\n\n",
+ (dst ? "on" : "off"), tstr);
+ }
+ }
+
+ return 0;
+}
diff --git a/qa/src/unpack.c b/qa/src/unpack.c
new file mode 100644
index 0000000..71bacdc
--- /dev/null
+++ b/qa/src/unpack.c
@@ -0,0 +1,479 @@
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <pcp/pmda.h>
+
+/* === begin largely copied from samplepmda events.c === */
+
+static int mydomain = 29;
+
+static pmValueSet vs;
+static char *ebuf;
+static int ebuflen;
+static char *eptr;
+static char *ebufend;
+static pmEventArray *eap;
+static pmEventRecord *erp;
+
+static int
+check_buf(int need)
+{
+ int offset = eptr - ebuf;
+
+ while (&eptr[need] >= ebufend) {
+ ebuflen *= 2;
+ if ((ebuf = (char *)realloc(ebuf, ebuflen)) == NULL)
+ return -errno;
+ eptr = &ebuf[offset];
+ ebufend = &ebuf[ebuflen-1];
+ vs.vlist[0].value.pval = (pmValueBlock *)ebuf;
+ }
+ return 0;
+}
+
+static int
+add_param(pmID pmid, int type, pmAtomValue *avp)
+{
+ int need; /* bytes in the buffer */
+ int vlen; /* value only length */
+ int sts;
+ pmEventParameter *epp;
+ void *src;
+
+ need = sizeof(pmEventParameter);
+ switch (type) {
+ case PM_TYPE_32:
+ case PM_TYPE_U32:
+ vlen = sizeof(avp->l);
+ need += vlen;
+ src = &avp->l;
+ break;
+ case PM_TYPE_64:
+ case PM_TYPE_U64:
+ vlen = sizeof(avp->ll);
+ need += vlen;
+ src = &avp->ll;
+ break;
+ case PM_TYPE_FLOAT:
+ vlen = sizeof(avp->f);
+ need += vlen;
+ src = &avp->f;
+ break;
+ case PM_TYPE_DOUBLE:
+ vlen = sizeof(avp->d);
+ need += vlen;
+ src = &avp->d;
+ break;
+ case PM_TYPE_STRING:
+ vlen = strlen(avp->cp);
+ need += PM_PDU_SIZE_BYTES(vlen);
+ src = avp->cp;
+ break;
+ case PM_TYPE_AGGREGATE:
+ case PM_TYPE_AGGREGATE_STATIC:
+ vlen = avp->vbp->vlen - PM_VAL_HDR_SIZE;
+ need += PM_PDU_SIZE_BYTES(vlen);
+ src = avp->vbp->vbuf;
+ break;
+ default:
+ fprintf(stderr, "add_parameter failed: bad type (%d)\n", type);
+ exit(1);
+ }
+ if ((sts = check_buf(need)) < 0) {
+ fprintf(stderr, "add_parameter failed: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ epp = (pmEventParameter *)eptr;
+ epp->ep_pmid = pmid;
+ epp->ep_len = PM_VAL_HDR_SIZE + vlen;
+ epp->ep_type = type;
+ memcpy((void *)(eptr + sizeof(pmEventParameter)), src, vlen);
+ eptr += need;
+ erp->er_nparams++;
+ return 0;
+}
+
+static void
+reset(void)
+{
+ eptr = ebuf;
+ eap = (pmEventArray *)eptr;
+ eap->ea_nrecords = 0;
+ eptr += sizeof(pmEventArray) - sizeof(pmEventRecord);
+ vs.numval = 1;
+ vs.valfmt = PM_VAL_DPTR;
+ vs.vlist[0].inst = PM_IN_NULL;
+}
+
+static int
+add_record(struct timeval *tp, int flags)
+{
+ int sts;
+
+ if ((sts = check_buf(sizeof(pmEventRecord) - sizeof(pmEventParameter))) < 0) {
+ fprintf(stderr, "add_record failed: %s\n", pmErrStr(sts));
+ exit(1);
+ }
+ eap->ea_nrecords++;
+ erp = (pmEventRecord *)eptr;
+ erp->er_timestamp.tv_sec = (__int32_t)tp->tv_sec;
+ erp->er_timestamp.tv_usec = (__int32_t)tp->tv_usec;
+ erp->er_nparams = 0;
+ erp->er_flags = flags;
+ eptr += sizeof(pmEventRecord) - sizeof(pmEventParameter);
+ return 0;
+}
+/* === end copied from samplepmda events.c === */
+
+static void
+dump(char *xpect)
+{
+ pmResult **res;
+ int nmissed;
+ int nrecords;
+ int r;
+ int k;
+ static pmID pmid_flags = 0;
+ static pmID pmid_missed;
+
+ fprintf(stderr, "Expecting ... %s\n", xpect);
+
+ for (k = 0; k < vs.numval || vs.numval == PM_ERR_GENERIC; k++) {
+ if (vs.vlist[k].inst != PM_IN_NULL)
+ fprintf(stderr, "[instance %d]\n", vs.vlist[k].inst);
+ nrecords = pmUnpackEventRecords(&vs, k, &res);
+
+ if (nrecords < 0) {
+ fprintf(stderr, "pmUnpackEventRecords: %s\n", pmErrStr(nrecords));
+ return;
+ }
+
+ /* lifted from pminfo.c */
+ if (pmid_flags == 0) {
+ /*
+ * get PMID for event.flags and event.missed
+ * note that pmUnpackEventRecords() will have called
+ * __pmRegisterAnon(), so the anon metrics
+ * should now be in the PMNS
+ */
+ char *name_flags = "event.flags";
+ char *name_missed = "event.missed";
+ int sts;
+ sts = pmLookupName(1, &name_flags, &pmid_flags);
+ if (sts < 0) {
+ /* should not happen! */
+ fprintf(stderr, "Warning: cannot get PMID for %s: %s\n", name_flags, pmErrStr(sts));
+ /* avoid subsequent warnings ... */
+ __pmid_int(&pmid_flags)->item = 1;
+ }
+ sts = pmLookupName(1, &name_missed, &pmid_missed);
+ if (sts < 0) {
+ /* should not happen! */
+ fprintf(stderr, "Warning: cannot get PMID for %s: %s\n", name_missed, pmErrStr(sts));
+ /* avoid subsequent warnings ... */
+ __pmid_int(&pmid_missed)->item = 1;
+ }
+ }
+
+ nmissed = 0;
+ for (r = 0; r < nrecords; r++) {
+ if (res[r]->numpmid == 2 && res[r]->vset[0]->pmid == pmid_flags &&
+ (res[r]->vset[0]->vlist[0].value.lval & PM_EVENT_FLAG_MISSED) &&
+ res[r]->vset[1]->pmid == pmid_missed) {
+ nmissed += res[r]->vset[1]->vlist[0].value.lval;
+ }
+ }
+
+ fprintf(stderr, "Array contains %d records and %d missed records\n", nrecords, nmissed);
+ if (nrecords == 0)
+ continue;
+
+ for (r = 0; r < nrecords; r++) {
+ fprintf(stderr, "pmResult[%d]\n", r);
+ __pmDumpResult(stderr, res[r]);
+ }
+ pmFreeEventResult(res);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int errflag = 0;
+ int sts;
+ int c;
+ struct timeval stamp;
+ pmAtomValue atom;
+ int savelen;
+ pmEventParameter *epp;
+/* === begin largely copied from samplepmda events.c === */
+ static pmValueBlock *aggr;
+ static char aggrval[] = { '\01', '\03', '\07', '\017', '\037', '\077', '\177', '\377' };
+ pmID pmid_array = PMDA_PMID(4095,0); /* event.records */
+ pmID pmid_type = PMDA_PMID(0,127); /* event.type */
+ pmID pmid_32 = PMDA_PMID(0,128); /* event.param_32 */
+ pmID pmid_u32 = PMDA_PMID(0,129); /* event.param_u32 */
+ pmID pmid_64 = PMDA_PMID(0,130); /* event.param_64 */
+ pmID pmid_u64 = PMDA_PMID(0,131); /* event.param_u64 */
+ pmID pmid_float = PMDA_PMID(0,132); /* event.param_float */
+ pmID pmid_double = PMDA_PMID(0,133); /* event.param_double */
+ pmID pmid_string = PMDA_PMID(0,134); /* event.param_string */
+ pmID pmid_aggregate = PMDA_PMID(0,135); /* event.param_string */
+
+ /* first time, punt on a 512 byte buffer */
+ ebuflen = 512;
+ ebuf = eptr = (char *)malloc(ebuflen);
+ if (ebuf == NULL) {
+ fprintf(stderr, "initial ebuf malloc failed: %s\n", strerror(errno));
+ exit(1);
+ }
+ ebufend = &ebuf[ebuflen-1];
+ /*
+ * also, fix the domain field in the event parameter PMIDs ...
+ * note these PMIDs must match the corresponding metrics in
+ * desctab[] and this cannot easily be done automatically
+ */
+ ((__pmID_int *)&pmid_array)->domain = mydomain;
+ ((__pmID_int *)&pmid_type)->domain = mydomain;
+ ((__pmID_int *)&pmid_32)->domain = mydomain;
+ ((__pmID_int *)&pmid_u32)->domain = mydomain;
+ ((__pmID_int *)&pmid_64)->domain = mydomain;
+ ((__pmID_int *)&pmid_u64)->domain = mydomain;
+ ((__pmID_int *)&pmid_float)->domain = mydomain;
+ ((__pmID_int *)&pmid_double)->domain = mydomain;
+ ((__pmID_int *)&pmid_string)->domain = mydomain;
+ ((__pmID_int *)&pmid_aggregate)->domain = mydomain;
+ /* build pmValueBlock for aggregate value */
+ aggr = (pmValueBlock *)malloc(PM_VAL_HDR_SIZE + sizeof(aggrval));
+ aggr->vtype = PM_TYPE_AGGREGATE;
+ aggr->vlen = PM_VAL_HDR_SIZE + sizeof(aggrval);
+ memcpy(aggr->vbuf, (void *)aggrval, sizeof(aggrval));
+
+/* === end copied from samplepmda events.c === */
+
+ vs.pmid = pmid_array;
+ vs.numval = 1;
+ vs.valfmt = PM_VAL_DPTR;
+ vs.vlist[0].inst = PM_IN_NULL;
+ vs.vlist[0].value.pval = (pmValueBlock *)ebuf;
+
+ __pmSetProgname(argv[0]);
+
+
+ while ((c = getopt(argc, argv, "D:")) != EOF) {
+ switch (c) {
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ fprintf(stderr, "Usage: %s ...\n", pmProgname);
+ fprintf(stderr, "options:\n");
+ fprintf(stderr, "-D debug\n");
+ exit(1);
+ }
+
+ reset();
+ gettimeofday(&stamp, NULL);
+ /* rebase event records 10 secs in past, add 1 sec for each new record */
+ stamp.tv_sec -= 10;
+
+ eap->ea_type = 0;
+ eap->ea_len = 0;
+ dump("Unknown or illegal metric type");
+ eap->ea_type = PM_TYPE_EVENT;
+
+ eap->ea_nrecords = -1;
+ eap->ea_len = eptr - ebuf;
+ dump("Error - ea_nrecords < 0");
+ eap->ea_nrecords = 0;
+
+ eap->ea_len = PM_VAL_HDR_SIZE;
+ dump("Error - vlen way too small");
+
+ eap->ea_len = eptr - ebuf;
+ dump("No records");
+
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ eap->ea_len = eptr - ebuf;
+ dump("1 record, no params");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 1;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ eap->ea_len = eptr - ebuf;
+ dump("1 record, u32 param = 1");
+
+ reset();
+ add_record(&stamp, 1);
+ stamp.tv_sec++;
+ atom.ul = 2;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.ll = -3;
+ add_param(pmid_64, PM_TYPE_64, &atom);
+ eap->ea_len = eptr - ebuf;
+ dump("1 record, u32 param = 2, u64 param = -3");
+ eap->ea_len--;
+ dump("Error - buffer overrun @ parameter");
+
+ reset();
+ add_record(&stamp, PM_EVENT_FLAG_MISSED);
+ stamp.tv_sec++;
+ erp->er_nparams = 3;
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 4;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.ull = 5;
+ add_param(pmid_u64, PM_TYPE_U64, &atom);
+ atom.cp = "6";
+ add_param(pmid_string, PM_TYPE_STRING, &atom);
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 7;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.d = 8;
+ add_param(pmid_double, PM_TYPE_DOUBLE, &atom);
+ atom.d = -9;
+ add_param(pmid_double, PM_TYPE_DOUBLE, &atom);
+ add_record(&stamp, 2);
+ stamp.tv_sec++;
+ atom.ul = 10;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.ull = 11;
+ add_param(pmid_u64, PM_TYPE_U64, &atom);
+ atom.cp = "twelve";
+ add_param(pmid_string, PM_TYPE_STRING, &atom);
+ atom.cp = "thirteen";
+ add_param(pmid_string, PM_TYPE_STRING, &atom);
+ atom.l = 14;
+ add_param(pmid_32, PM_TYPE_32, &atom);
+ atom.ul = 15;
+ add_param(pmid_u32, PM_TYPE_U32, &atom);
+ add_record(&stamp, PM_EVENT_FLAG_MISSED);
+ stamp.tv_sec++;
+ erp->er_nparams = 4;
+ savelen = eptr - ebuf;
+ add_record(&stamp,0);
+ stamp.tv_sec++;
+ atom.ul = 16;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.f = -17;
+ add_param(pmid_float, PM_TYPE_FLOAT, &atom);
+ atom.vbp = aggr;
+ add_param(pmid_aggregate, PM_TYPE_AGGREGATE, &atom);
+ eap->ea_len = eptr - ebuf;
+ dump("6 records, 7 missed [u32=4 u64=5 str=\"6\"][u32=7 d=8 d=-9][u32=10 u64=11 str=\"twelve\" str=\"thirteen\" 32=-14 u32=15][u32=16 f=-17 aggr=...]");
+
+ eap->ea_len = savelen;
+ dump("Error - buffer overrun @ record");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 1;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ eap->ea_len = eptr - ebuf;
+ vs.numval = PM_ERR_GENERIC;
+ dump("bad numval");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 1;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ eap->ea_len = eptr - ebuf;
+ vs.valfmt = 42;
+ dump("bad valfmt");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 1;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ eap->ea_len = eptr - ebuf;
+ vs.vlist[0].inst = 42;
+ dump("odd instance");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.vbp = aggr;
+ epp = (pmEventParameter *)eptr;
+ add_param(pmid_aggregate, PM_TYPE_AGGREGATE, &atom);
+ epp->ep_type = PM_TYPE_EVENT;
+ eap->ea_len = eptr - ebuf;
+ dump("1 record, nested event type @ 1st parameter");
+
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 18;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 19;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ atom.vbp = aggr;
+ epp = (pmEventParameter *)eptr;
+ add_param(pmid_aggregate, PM_TYPE_AGGREGATE, &atom);
+ epp->ep_type = PM_TYPE_EVENT;
+ atom.ul = 20;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.ul = 21;
+ add_param(pmid_type, PM_TYPE_U32, &atom);
+ eap->ea_len = eptr - ebuf;
+ dump("3 records, nested event type @ 2nd parameter of 2nd record");
+
+ printf("\n");
+ printf("__pmDumpEventRecords coverage test ...\n");
+ reset();
+ add_record(&stamp, 0);
+ stamp.tv_sec++;
+ atom.l = 22;
+ add_param(pmid_type, PM_TYPE_32, &atom);
+ atom.ul = 23;
+ add_param(pmid_u32, PM_TYPE_U32, &atom);
+ atom.ll = -24;
+ add_param(pmid_64, PM_TYPE_64, &atom);
+ atom.ull = 25;
+ add_param(pmid_u64, PM_TYPE_U64, &atom);
+ atom.f = -26;
+ add_param(pmid_float, PM_TYPE_FLOAT, &atom);
+ atom.d = 27;
+ add_param(pmid_double, PM_TYPE_DOUBLE, &atom);
+ atom.cp = "minus twenty-eight";
+ add_param(pmid_string, PM_TYPE_STRING, &atom);
+ atom.vbp = aggr;
+ add_param(pmid_aggregate, PM_TYPE_AGGREGATE, &atom);
+ add_param(pmid_aggregate, PM_TYPE_AGGREGATE_STATIC, &atom);
+ epp = (pmEventParameter *)eptr;
+ atom.l = 29;
+ add_param(pmid_32, PM_TYPE_32, &atom);
+ eap->ea_len = eptr - ebuf;
+ pmDebug |= DBG_TRACE_FETCH;
+ dump("all good");
+ epp->ep_type = PM_TYPE_UNKNOWN;
+ __pmDumpEventRecords(stdout, &vs, 0);
+
+ return 0;
+}
diff --git a/qa/src/username.c b/qa/src/username.c
new file mode 100644
index 0000000..6984997
--- /dev/null
+++ b/qa/src/username.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012 Red Hat.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <unistd.h>
+
+#include "localconfig.h"
+
+#if PCP_VER < 3611
+#define __pmSetProcessIdentity(x) (exit(1), 1)
+#endif
+
+static void
+usage (void)
+{
+ fprintf(stderr, "Usage %s: username\n", pmProgname);
+ exit(1);
+}
+
+int
+main(int argc, char* argv[])
+{
+ int sts;
+
+ __pmSetProgname(argv[0]);
+ if (argc != 2)
+ usage();
+ sts = __pmSetProcessIdentity(argv[1]);
+ pause();
+ return sts;
+}
diff --git a/qa/src/uwrap.0 b/qa/src/uwrap.0
new file mode 100644
index 0000000..6a646d8
--- /dev/null
+++ b/qa/src/uwrap.0
Binary files differ
diff --git a/qa/src/uwrap.config b/qa/src/uwrap.config
new file mode 100644
index 0000000..de8a408
--- /dev/null
+++ b/qa/src/uwrap.config
@@ -0,0 +1,8 @@
+#
+# pmlogger(1) configuration file suitable creating an archive to be
+# used with pmdahotproc(1)
+#
+
+log advisory on 1 seconds {
+ sample.wrap.ulong
+}
diff --git a/qa/src/uwrap.index b/qa/src/uwrap.index
new file mode 100644
index 0000000..63d7f61
--- /dev/null
+++ b/qa/src/uwrap.index
Binary files differ
diff --git a/qa/src/uwrap.meta b/qa/src/uwrap.meta
new file mode 100644
index 0000000..4ec48ce
--- /dev/null
+++ b/qa/src/uwrap.meta
Binary files differ
diff --git a/qa/src/versiondefs b/qa/src/versiondefs
new file mode 100644
index 0000000..d90074d
--- /dev/null
+++ b/qa/src/versiondefs
@@ -0,0 +1,18 @@
+# From the system on which the test is being run
+#
+
+#if !defined(RELEASE_MAJOR)
+include $(ROOT)/usr/include/make/releasedefs
+#endif
+OS_REL = $(RELEASE_MAJOR).$(RELEASE_MINOR)
+IRIX = IRIX$(OS_REL:S/./_/g)
+
+# IMPORTANT
+# set this to match the style of the IRIX kernel you are
+# testing on locally
+#
+IRIX_OBJECT != ../src/get-irix-object
+
+# Stuff that varies ...
+HAVE_DEV_IN_LIBPCP != sed -n '/^\#ifdef HAVE_DEV_IN_LIBPCP/s/\#ifdef /-D/p' /usr/include/pcp/impl.h
+
diff --git a/qa/src/vldb-disks.0 b/qa/src/vldb-disks.0
new file mode 100644
index 0000000..cd03022
--- /dev/null
+++ b/qa/src/vldb-disks.0
Binary files differ
diff --git a/qa/src/vldb-disks.index b/qa/src/vldb-disks.index
new file mode 100644
index 0000000..0ef9ff2
--- /dev/null
+++ b/qa/src/vldb-disks.index
Binary files differ
diff --git a/qa/src/vldb-disks.meta b/qa/src/vldb-disks.meta
new file mode 100644
index 0000000..60cff25
--- /dev/null
+++ b/qa/src/vldb-disks.meta
Binary files differ
diff --git a/qa/src/whichtimezone.c b/qa/src/whichtimezone.c
new file mode 100644
index 0000000..35cfe0e
--- /dev/null
+++ b/qa/src/whichtimezone.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+#include <time.h>
+
+int
+main(int argc, char *argv[])
+{
+ time_t clock;
+ char *p;
+ int i;
+ char buf[28];
+
+ i = pmLoadNameSpace(PM_NS_DEFAULT);
+ if (i < 0) {
+ printf("pmLoadNameSpace: %s\n", pmErrStr(i));
+ exit(1);
+ }
+
+ for (--argc; argc > 0; argc--, argv++) {
+ printf("Trying %s ...\n", argv[1]);
+ i = pmNewContext(PM_CONTEXT_HOST, argv[1]);
+ if (i < 0) {
+ printf("pmNewContext: %s\n", pmErrStr(i));
+ goto more;
+ }
+ i = pmNewContextZone();
+ if (i < 0) {
+ printf("pmNewContextZone: %s\n", pmErrStr(i));
+ goto more;
+ }
+
+ i = pmWhichZone(&p);
+ time(&clock);
+ printf("zone: %d TZ: %s ctime: %s\n", i, p, pmCtime(&clock, buf));
+more: continue;
+ }
+
+ exit(0);
+}
diff --git a/qa/src/wrap.0 b/qa/src/wrap.0
new file mode 100644
index 0000000..3a75a48
--- /dev/null
+++ b/qa/src/wrap.0
Binary files differ
diff --git a/qa/src/wrap.config b/qa/src/wrap.config
new file mode 100644
index 0000000..236d4d7
--- /dev/null
+++ b/qa/src/wrap.config
@@ -0,0 +1,8 @@
+#
+# pmlogger(1) configuration file suitable creating an archive to be
+# used with pmdahotproc(1)
+#
+
+log advisory on 1 seconds {
+ sample.wrap.long
+}
diff --git a/qa/src/wrap.index b/qa/src/wrap.index
new file mode 100644
index 0000000..504d68a
--- /dev/null
+++ b/qa/src/wrap.index
Binary files differ
diff --git a/qa/src/wrap.meta b/qa/src/wrap.meta
new file mode 100644
index 0000000..bfe93f9
--- /dev/null
+++ b/qa/src/wrap.meta
Binary files differ
diff --git a/qa/src/wrap_int.c b/qa/src/wrap_int.c
new file mode 100644
index 0000000..f91746b
--- /dev/null
+++ b/qa/src/wrap_int.c
@@ -0,0 +1,120 @@
+/*
+ * Generate sequences of values with wrapping for testing how
+ * tools deal with this. Note: wrapping of *signed* integers
+ * is undefined (according to gcc folks) and they take that as
+ * meaning "anything can happen". For some compilers, that's
+ * taken literally at higher optimisation levels, resulting in
+ * crashes, infinite loops, early exit; so *anything goes* for
+ * this test program. Do not rely on its output when signed
+ * integers are being used (the default, without -u).
+ *
+ * http://thiemonagel.de/2010/01/signed-integer-overflow/
+ * https://patchwork.kernel.org/patch/34925/
+ */
+#include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define NUM_SAMPLES 20
+
+#ifndef LONGLONG_MAX
+#define LONGLONG_MAX 9223372036854775807LL /* max "long long int" */
+#endif
+
+#ifndef ULONGLONG_MAX
+#define ULONGLONG_MAX 18446744073709551615LLU /* max "unsigned long long" */
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int use_longlong = 0;
+ int num_samples = NUM_SAMPLES;
+ int notsigned = 0;
+ int c;
+ extern char *optarg;
+
+ while ((c = getopt(argc, argv, "ln:u")) != EOF) {
+ switch (c) {
+ case 'l':
+ /* use long long */
+ use_longlong = 1;
+ break;
+
+ case 'n':
+ num_samples = atoi(optarg);
+ break;
+
+ case 'u':
+ notsigned = 1;
+ break;
+ }
+ }
+
+ if (! notsigned ) {
+ if (! use_longlong) {
+ int x = 0;
+ int prev = 0;
+ int i;
+ double a;
+
+ for (i=0;i<=num_samples;i++) {
+ x += INT_MAX/2 - 1;
+ a = (double)x - (double)prev;
+ prev = x;
+ if (i > 0)
+ printf("%.4g\n", a);
+ }
+ }
+ else {
+ long long x = 0;
+ long long prev = 0;
+ int i;
+ double a;
+
+ for (i=0;i<=num_samples;i++) {
+ x += LONGLONG_MAX/2 - 1;
+ a = (double)x - (double)prev;
+ prev = x;
+ if (i > 0)
+ printf("%.4g\n", a);
+ }
+
+ }
+ }
+ else {
+ if (! use_longlong) {
+ unsigned int x = 0;
+ unsigned int prev = 0;
+ int i;
+ double a;
+
+ for (i=0;i<=num_samples;i++) {
+ x += UINT_MAX/2 - 1;
+ a = (double)x - (double)prev;
+ prev = x;
+ if (i > 0)
+ printf("%.4g\n", a);
+ }
+ }
+ else {
+ unsigned long long x = 0;
+ unsigned long long prev = 0;
+ int i;
+ double a;
+
+ for (i=0;i<=num_samples;i++) {
+ x += ULONGLONG_MAX/2 - 1;
+ a = (double)x - (double)prev;
+ prev = x;
+ if (i > 0)
+ printf("%.4g\n", a);
+ }
+
+ }
+ }
+
+ exit(0);
+
+}
diff --git a/qa/src/write-bf.c b/qa/src/write-bf.c
new file mode 100644
index 0000000..8eff75f
--- /dev/null
+++ b/qa/src/write-bf.c
@@ -0,0 +1,106 @@
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+typedef struct {
+ unsigned int a:16;
+ unsigned int b:7;
+ unsigned int c:3;
+ unsigned int d:3;
+ unsigned int e:3;
+ unsigned int f:4;
+ unsigned int g:12;
+} ext_bits_t;
+
+typedef struct {
+ unsigned int a:16;
+ unsigned int b:7;
+ unsigned int c:3;
+ unsigned int d:3;
+ unsigned int e:3;
+ unsigned int f:4;
+ unsigned int g:12;
+} bits_t;
+
+bits_t outbits = { 0xdead, 0x5f, 0x3, 0x5, 0x7, 0xc, 0xafe };
+
+int
+main(int argc, char *argv[])
+{
+ bits_t inbits;
+ ext_bits_t extbits;
+ __uint32_t *ip;
+ int i;
+ int sts;
+
+ fprintf(stderr, "sizeof(bits_t): %d\n", (int)sizeof(bits_t));
+
+ if (strcmp(basename(argv[0]), "read-bf") == 0) {
+ sts = read(0, &extbits, sizeof(ext_bits_t));
+ if (sts != sizeof(ext_bits_t)) {
+ fprintf(stderr, "read() returns %d not %d as expected\n", sts, (int)sizeof(ext_bits_t));
+ exit(1);
+ }
+
+ fprintf(stderr, "read: ");
+ for (i = 0, ip = (__uint32_t *)&extbits; i < sizeof(ext_bits_t); i += sizeof(*ip), ip++)
+ fprintf(stderr, " %08x", *ip);
+ fputc('\n', stderr);
+
+ /*
+ * swap bytes, then assign fields
+ */
+ for (i = 0, ip = (__uint32_t *)&extbits; i < sizeof(ext_bits_t); i += sizeof(*ip), ip++)
+ *ip = ntohl(*ip);
+
+ inbits.a = extbits.a;
+ inbits.b = extbits.b;
+ inbits.c = extbits.c;
+ inbits.d = extbits.d;
+ inbits.e = extbits.e;
+ inbits.f = extbits.f;
+ inbits.g = extbits.g;
+
+ if (inbits.a != outbits.a)
+ fprintf(stderr, "Error: \"a\" got %x expected %x\n", inbits.a, outbits.a);
+ if (inbits.b != outbits.b)
+ fprintf(stderr, "Error: \"b\" got %x expected %x\n", inbits.b, outbits.b);
+ if (inbits.c != outbits.c)
+ fprintf(stderr, "Error: \"c\" got %x expected %x\n", inbits.c, outbits.c);
+ if (inbits.d != outbits.d)
+ fprintf(stderr, "Error: \"d\" got %x expected %x\n", inbits.d, outbits.d);
+ if (inbits.e != outbits.e)
+ fprintf(stderr, "Error: \"e\" got %x expected %x\n", inbits.e, outbits.e);
+ if (inbits.f != outbits.f)
+ fprintf(stderr, "Error: \"f\" got %x expected %x\n", inbits.f, outbits.f);
+ if (inbits.g != outbits.g)
+ fprintf(stderr, "Error: \"g\" got %x expected %x\n", inbits.g, outbits.g);
+ }
+ else {
+ /*
+ * assign fields, then swap bytes
+ */
+ memset((void *)&extbits, 0, sizeof(ext_bits_t));
+ extbits.a = outbits.a;
+ extbits.b = outbits.b;
+ extbits.c = outbits.c;
+ extbits.d = outbits.d;
+ extbits.e = outbits.e;
+ extbits.f = outbits.f;
+ extbits.g = outbits.g;
+
+ for (i = 0, ip = (__uint32_t *)&extbits; i < sizeof(ext_bits_t); i += sizeof(*ip), ip++)
+ *ip = htonl(*ip);
+
+ fprintf(stderr, "write: ");
+ for (i = 0, ip = (__uint32_t *)&extbits; i < sizeof(ext_bits_t); i += sizeof(*ip), ip++)
+ fprintf(stderr, " %08x", *ip);
+ fputc('\n', stderr);
+
+ sts = write(1, &extbits, sizeof(bits_t));
+ if (sts != sizeof(bits_t)) {
+ fprintf(stderr, "write() returns %d not %d as expected\n", sts, (int)sizeof(bits_t));
+ exit(1);
+ }
+ }
+ exit(0);
+}
diff --git a/qa/src/xarch.c b/qa/src/xarch.c
new file mode 100644
index 0000000..cc34de4
--- /dev/null
+++ b/qa/src/xarch.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * exercise archive-based pmFetch and pmSetMode ops
+ */
+
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int vflag;
+static int tflag;
+static int numpmid;
+static pmID pmidlist[20];
+static char *namelist[20];
+
+static void
+cmpres(int n, pmResult *e, pmResult *g)
+{
+ int i;
+ int j;
+ int err = 0;
+
+ if (e->timestamp.tv_sec != g->timestamp.tv_sec ||
+ e->timestamp.tv_usec != g->timestamp.tv_usec) {
+ printf("[sample %d] pmResult.timestamp: expected %ld.%06ld, got %ld.%06ld\n",
+ n, (long)e->timestamp.tv_sec, (long)e->timestamp.tv_usec,
+ (long)g->timestamp.tv_sec, (long)g->timestamp.tv_usec);
+ goto FAILED;
+ }
+ if (e->numpmid != g->numpmid) {
+ printf("[sample %d] pmResult.numpmid: expected %d, got %d\n",
+ n, e->numpmid, g->numpmid);
+ goto FAILED;
+ }
+
+ for (i = 0; i < e->numpmid; i++) {
+ if (e->vset[i]->pmid != g->vset[i]->pmid) {
+ printf("[sample %d] pmResult.vset[%d].pmid: expected %s",
+ n, i, pmIDStr(e->vset[i]->pmid));
+ printf(" got %s\n", pmIDStr(g->vset[i]->pmid));
+ err++;
+ }
+ if (e->vset[i]->numval != g->vset[i]->numval) {
+ printf("[sample %d] pmResult.vset[%d].numval: expected %d, got %d\n",
+ n, i, e->vset[i]->numval, g->vset[i]->numval);
+ err++;
+ continue;
+ }
+ if (e->vset[i]->valfmt != g->vset[i]->valfmt) {
+ printf("[sample %d] pmResult.vset[%d].valfmt: expected %d, got %d\n",
+ n, i, e->vset[i]->valfmt, g->vset[i]->valfmt);
+ err++;
+ continue;
+ }
+ if (e->vset[i]->valfmt != PM_VAL_INSITU)
+ continue;
+ for (j = 0; j < e->vset[i]->numval; j++) {
+ if (e->vset[i]->vlist[j].inst != g->vset[i]->vlist[j].inst) {
+ printf("[sample %d] pmResult.vset[%d].vlist[%d].inst: expected %d, got %d\n",
+ n, i, j, e->vset[i]->vlist[j].inst, g->vset[i]->vlist[j].inst);
+ err++;
+ }
+ if (e->vset[i]->vlist[j].value.lval != g->vset[i]->vlist[j].value.lval) {
+ printf("[sample %d] pmResult.vset[%d].vlist[%d].lval: expected %d, got %d\n",
+ n, i, j, e->vset[i]->vlist[j].value.lval, g->vset[i]->vlist[j].value.lval);
+ err++;
+ }
+ }
+ }
+
+ if (err == 0)
+ return;
+
+FAILED:
+ printf("Expected ...\n");
+ __pmDumpResult(stdout, e);
+ printf("Got ...\n");
+ __pmDumpResult(stdout, g);
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int ctx[2];
+ int errflag = 0;
+ char *archive = "foo";
+ char *namespace = PM_NS_DEFAULT;
+ static char *usage = "[-D N] [-a archive] [-n namespace] [-v] [metric ...]";
+ int i;
+ int j;
+ int k;
+ int n;
+ pmLogLabel loglabel;
+ pmResult *resp;
+ pmResult **resvec = (pmResult **)0;
+ int resnum = 0;
+ struct timeval when;
+ int done;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:n:tv")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive */
+ archive = optarg;
+ break;
+
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'v': /* verbose output */
+ vflag++;
+ break;
+
+ case 't': /* trim namespace */
+ tflag++;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s\n", pmProgname, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((ctx[0] = pmNewContext(PM_CONTEXT_ARCHIVE, archive)) < 0) {
+ printf("%s: Cannot connect to archive \"%s\": %s\n", pmProgname, archive, pmErrStr(ctx[0]));
+ exit(1);
+ }
+ if ((sts = pmGetArchiveLabel(&loglabel)) < 0) {
+ printf("%s: pmGetArchiveLabel(%d): %s\n", pmProgname, ctx[0], pmErrStr(sts));
+ exit(1);
+ }
+
+ when.tv_sec = 0;
+ when.tv_usec = 0;
+ if ((sts = pmSetMode(PM_MODE_FORW, &when, 0)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((ctx[1] = pmDupContext()) < 0) {
+ printf("%s: Cannot dup context to archive \"%s\": %s\n", pmProgname, archive, pmErrStr(ctx[0]));
+ exit(1);
+ }
+ if ((sts = pmSetMode(PM_MODE_FORW, &when, 0)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ pmUseContext(ctx[0]);
+ if (tflag)
+ pmTrimNameSpace();
+
+ i = 0;
+ while (optind < argc - 1) {
+ if (i == 20) {
+ fprintf(stderr, "%s: Too many metrics, re-build me\n", pmProgname);
+ exit(1);
+ }
+ namelist[i++] = argv[optind]++;
+ }
+
+ if (i == 0) {
+ /*
+ * default metrics biased towards log "foo"
+ */
+ namelist[i++] = "sample.seconds";
+ namelist[i++] = "sample.colour";
+ namelist[i++] = "sample.drift";
+ namelist[i++] = "sample.lights";
+ namelist[i++] = "sampledso.milliseconds";
+ namelist[i++] = "sampledso.bin";
+ }
+ numpmid = i;
+
+ sts = pmLookupName(numpmid, namelist, pmidlist);
+ if (sts < 0) {
+ printf("pmLookupName: %s\n", pmErrStr(sts));
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ printf(" %s - not known\n", namelist[i]);
+ }
+ }
+
+ printf("\nPass 1: forward scan\n");
+ for (;;) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ resnum++;
+ resvec = (pmResult **)realloc(resvec, resnum * sizeof(resvec[0]));
+ resvec[resnum - 1] = resp;
+ if (vflag)
+ __pmDumpResult(stdout, resp);
+ }
+ fflush(stderr);
+ printf("Found %d samples\n", resnum);
+ fflush(stdout);
+
+ printf("\nPass 2: backwards scan\n");
+ when.tv_sec = 0x7fffffff;
+ when.tv_usec = 0;
+ if ((sts = pmSetMode(PM_MODE_BACK, &when, 0)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ n = 0;
+ for (;;) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ n++;
+ cmpres(n, resvec[resnum - n], resp);
+ pmFreeResult(resp);
+ }
+ fflush(stderr);
+ printf("Found %d samples\n", n);
+ fflush(stdout);
+
+ printf("\nPass 3: concurrent forwards and backwards scans\n");
+ pmUseContext(ctx[0]);
+ when.tv_sec = 0;
+ when.tv_usec = 0;
+ if ((sts = pmSetMode(PM_MODE_FORW, &when, 0)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ pmUseContext(ctx[1]);
+ when.tv_sec = 0x7fffffff;
+ when.tv_usec = 0;
+ if ((sts = pmSetMode(PM_MODE_BACK, &when, 0)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ done = 0;
+ n = 0;
+ while (!done) {
+ pmUseContext(ctx[0]);
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ done = 1;
+ }
+ else {
+ n++;
+ cmpres(n, resvec[n/2], resp);
+ pmFreeResult(resp);
+ }
+
+ pmUseContext(ctx[1]);
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ done = 1;
+ }
+ else {
+ n++;
+ cmpres(n, resvec[resnum - n/2], resp);
+ pmFreeResult(resp);
+ }
+ }
+ fflush(stderr);
+ printf("Found %d samples\n", n);
+ fflush(stdout);
+
+ printf("\nPass 4: cascading forward scan, 100%%, 75%%, 50%%, 25%%, 0%%\n");
+ pmUseContext(ctx[0]);
+ for (k = 0; k < 5; k++) {
+ j = 0;
+ if (resnum > 0) {
+ i = ( k * resnum ) / 4;
+ if (i <= resnum - 1) {
+ when = resvec[i]->timestamp;
+ when.tv_usec--;
+ if (when.tv_usec < 0) {
+ when.tv_usec = 0;
+ when.tv_sec--;
+ }
+ }
+ else {
+ when = resvec[resnum - 1]->timestamp;
+ when.tv_usec++;
+ if (when.tv_usec >= 1000000) {
+ when.tv_usec = 0;
+ when.tv_sec++;
+ }
+ }
+ if ((sts = pmSetMode(PM_MODE_FORW, &when, 0)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ n = i;
+ for (;;) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ j++;
+ n++;
+ cmpres(j, resvec[n - 1], resp);
+ pmFreeResult(resp);
+ }
+ fflush(stderr);
+ }
+ printf("Found %d samples\n", j);
+ fflush(stdout);
+ }
+
+ printf("\nPass 5: cascading backward scan, 100%%, 75%%, 50%%, 25%%, 0%%\n");
+ pmUseContext(ctx[0]);
+ for (k = 0; k < 5; k++) {
+ j = 0;
+ if (resnum > 0) {
+ i = resnum - ( k * resnum ) / 4 - 1;
+ if (i < 0)
+ i = 0;
+ if (i > 0) {
+ when = resvec[i]->timestamp;
+ when.tv_usec++;
+ if (when.tv_usec >= 1000000) {
+ when.tv_usec = 0;
+ when.tv_sec++;
+ }
+ }
+ else {
+ when = resvec[0]->timestamp;
+ when.tv_usec--;
+ if (when.tv_usec < 0) {
+ when.tv_usec = 0;
+ when.tv_sec--;
+ }
+ }
+ if ((sts = pmSetMode(PM_MODE_BACK, &when, 0)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+
+ for (;;) {
+ if ((sts = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetch: %s\n", pmProgname, pmErrStr(sts));
+ break;
+ }
+ cmpres(i, resvec[i], resp);
+ pmFreeResult(resp);
+ i--;
+ j++;
+ }
+ fflush(stderr);
+ }
+ printf("Found %d samples\n", j);
+ fflush(stdout);
+ }
+
+ printf("\nPass 6: EOL tests, forwards and backwards\n");
+ when = loglabel.ll_start;
+ when.tv_sec--;
+ if ((sts = pmSetMode(PM_MODE_BACK, &when, 0)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmFetchArchive(&resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetchArchive: %s\n", pmProgname, pmErrStr(sts));
+ }
+ else {
+ printf("%s: pmFetchArchive: unexpected success before start of log\n", pmProgname);
+ __pmDumpResult(stdout, resp);
+ pmFreeResult(resp);
+ }
+
+ when.tv_sec = 0x7fffffff;
+ when.tv_usec = 0;
+ if ((sts = pmSetMode(PM_MODE_FORW, &when, 0)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmFetchArchive(&resp)) < 0) {
+ if (sts != PM_ERR_EOL)
+ printf("%s: pmFetchArchive: %s\n", pmProgname, pmErrStr(sts));
+ }
+ else {
+ printf("%s: pmFetchArchive: unexpected success after end of log\n", pmProgname);
+ __pmDumpResult(stdout, resp);
+ pmFreeResult(resp);
+ }
+
+ exit(0);
+}
diff --git a/qa/src/xbug1.0 b/qa/src/xbug1.0
new file mode 100644
index 0000000..3de2094
--- /dev/null
+++ b/qa/src/xbug1.0
Binary files differ
diff --git a/qa/src/xbug1.index b/qa/src/xbug1.index
new file mode 100644
index 0000000..9bf8ca6
--- /dev/null
+++ b/qa/src/xbug1.index
Binary files differ
diff --git a/qa/src/xbug1.meta b/qa/src/xbug1.meta
new file mode 100644
index 0000000..eac96ad
--- /dev/null
+++ b/qa/src/xbug1.meta
Binary files differ
diff --git a/qa/src/xlog.c b/qa/src/xlog.c
new file mode 100644
index 0000000..918c7fe
--- /dev/null
+++ b/qa/src/xlog.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+/*
+ * exercise meta-Data services for an archive
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int vflag;
+static int numpmid;
+static pmID pmidlist[20];
+static char *namelist[20];
+
+static void
+grind(void)
+{
+ int sts;
+ int i;
+ int *instlist;
+ char **inamelist;
+ pmDesc desc;
+
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] != PM_ID_NULL) {
+ printf("\npmid: 0x%x name: %s", pmidlist[i], namelist[i]);
+ if ((sts = pmLookupDesc(pmidlist[i], &desc)) < 0) {
+ printf("\npmLookupDesc: %s\n", pmErrStr(sts));
+ }
+ else {
+ printf(" indom: 0x%x", desc.indom);
+ if (vflag) {
+ const char *u = pmUnitsStr(&desc.units);
+ printf("\ndesc: type=%d indom=0x%x sem=%d units=%s",
+ desc.type, desc.indom, desc.sem,
+ *u == '\0' ? "none" : u);
+ }
+ if (desc.indom == PM_INDOM_NULL) {
+ printf("\n");
+ continue;
+ }
+ if (vflag)
+ putchar('\n');
+ if ((sts = pmGetInDomArchive(desc.indom, &instlist, &inamelist)) < 0) {
+ printf("pmGetInDomArchive: %s\n", pmErrStr(sts));
+ }
+ else {
+ int j;
+ int numinst = sts;
+ char *name;
+ printf(" numinst: %d\n", numinst);
+ for (j = 0; j < numinst; j++) {
+ if (vflag)
+ printf(" instance id: 0x%x ", instlist[j]);
+ if ((sts = pmNameInDomArchive(desc.indom, instlist[j], &name)) < 0) {
+ printf("pmNameInDomArchive: %s\n", pmErrStr(sts));
+ }
+ else {
+ if (vflag)
+ printf("%s (== %s?)", name, inamelist[j]);
+ if ((sts = pmLookupInDomArchive(desc.indom, name)) < 0) {
+ printf(" pmLookupInDomArchive: %s\n", pmErrStr(sts));
+ }
+ else {
+ if (sts != instlist[j]) {
+ printf(" botch: pmLookupInDom returns 0x%x, expected 0x%x\n",
+ sts, instlist[j]);
+ }
+ else if (vflag)
+ putchar('\n');
+ }
+ free(name);
+ }
+ }
+ free(instlist);
+ free(inamelist);
+ }
+ }
+ }
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int sts;
+ int ctx[2];
+ int errflag = 0;
+ char *archive = "foo";
+ char *namespace = PM_NS_DEFAULT;
+#ifdef PCP_DEBUG
+ static char *debug = "[-D N]";
+#else
+ static char *debug = "";
+#endif
+ static char *usage = "[-D N] [-a archive] [-n namespace] [-v]";
+ int i;
+ pmLogLabel loglabel;
+ pmLogLabel duplabel;
+
+ __pmSetProgname(argv[0]);
+
+ while ((c = getopt(argc, argv, "a:D:n:v")) != EOF) {
+ switch (c) {
+
+ case 'a': /* archive */
+ archive = optarg;
+ break;
+
+#ifdef PCP_DEBUG
+ case 'D': /* debug flag */
+ sts = __pmParseDebug(optarg);
+ if (sts < 0) {
+ fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
+ pmProgname, optarg);
+ errflag++;
+ }
+ else
+ pmDebug |= sts;
+ break;
+#endif
+
+ case 'n': /* alternative name space file */
+ namespace = optarg;
+ break;
+
+ case 'v': /* verbose output */
+ vflag++;
+ break;
+
+ case '?':
+ default:
+ errflag++;
+ break;
+ }
+ }
+
+ if (errflag) {
+ printf("Usage: %s %s%s\n", pmProgname, debug, usage);
+ exit(1);
+ }
+
+ if ((sts = pmLoadNameSpace(namespace)) < 0) {
+ printf("%s: Cannot load namespace from \"%s\": %s\n", pmProgname, namespace, pmErrStr(sts));
+ exit(1);
+ }
+
+ if ((ctx[0] = pmNewContext(PM_CONTEXT_ARCHIVE, archive)) < 0) {
+ printf("%s: Cannot connect to archive \"%s\": %s\n", pmProgname, archive, pmErrStr(ctx[0]));
+ exit(1);
+ }
+ if ((sts = pmGetArchiveLabel(&loglabel)) < 0) {
+ printf("%s: pmGetArchiveLabel(%d): %s\n", pmProgname, ctx[0], pmErrStr(sts));
+ exit(1);
+ }
+ if ((sts = pmSetMode(PM_MODE_INTERP, &loglabel.ll_start, 5)) < 0) {
+ printf("%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts));
+ exit(1);
+ }
+ if ((ctx[1] = pmDupContext()) < 0) {
+ printf("%s: Cannot dup context: %s\n", pmProgname, pmErrStr(ctx[1]));
+ exit(1);
+ }
+ if ((sts = pmGetArchiveLabel(&duplabel)) < 0) {
+ printf("%s: pmGetArchiveLabel(%d): %s\n", pmProgname, ctx[1], pmErrStr(sts));
+ exit(1);
+ }
+ if (loglabel.ll_magic != duplabel.ll_magic ||
+ loglabel.ll_pid != duplabel.ll_pid ||
+ loglabel.ll_start.tv_sec != duplabel.ll_start.tv_sec ||
+ loglabel.ll_start.tv_usec != duplabel.ll_start.tv_usec ||
+ strcmp(loglabel.ll_hostname, duplabel.ll_hostname) != 0 ||
+ strcmp(loglabel.ll_tz, duplabel.ll_tz) != 0) {
+ printf("Error: pmLogLabel mismatch\n");
+ printf("First context: magic=0x%x pid=%" FMT_PID " start=%ld.%06ld\n",
+ loglabel.ll_magic, loglabel.ll_pid,
+ (long)loglabel.ll_start.tv_sec,
+ (long)loglabel.ll_start.tv_usec);
+ printf("host=%s TZ=%s\n", loglabel.ll_hostname, loglabel.ll_tz);
+ printf("Error: pmLogLabel mismatch\n");
+ printf("Dup context: magic=0x%x pid=%" FMT_PID " start=%ld.%06ld\n",
+ duplabel.ll_magic, duplabel.ll_pid,
+ (long)duplabel.ll_start.tv_sec,
+ (long)duplabel.ll_start.tv_usec);
+ printf("host=%s TZ=%s\n", duplabel.ll_hostname, duplabel.ll_tz);
+ exit(1);
+ }
+
+ /*
+ * metrics biased towards log "foo"
+ */
+ i = 0;
+ namelist[i++] = "sample.seconds";
+ namelist[i++] = "sample.bin";
+ namelist[i++] = "sample.colour";
+ namelist[i++] = "sample.drift";
+ namelist[i++] = "sample.lights";
+ namelist[i++] = "sampledso.milliseconds";
+ namelist[i++] = "sampledso.bin";
+ numpmid = i;
+
+
+ for (c = 0; c < 2; c++) {
+ printf("\n=== Context %d ===\n", ctx[c]);
+ pmUseContext(ctx[c]);
+ __pmDumpContext(stdout, ctx[c], PM_INDOM_NULL);
+
+ pmTrimNameSpace();
+
+ sts = pmLookupName(numpmid, namelist, pmidlist);
+ if (sts != numpmid) {
+ if (sts < 0)
+ printf("pmLookupName: %s\n", pmErrStr(sts));
+ else
+ printf("pmLookupName: Warning: some metrics unknown\n");
+
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ printf(" %s - not known\n", namelist[i]);
+ }
+ }
+
+ grind();
+ }
+ exit(0);
+}
diff --git a/qa/src/xmktime.c b/qa/src/xmktime.c
new file mode 100644
index 0000000..08aab4b
--- /dev/null
+++ b/qa/src/xmktime.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <sys/types.h>
+#include <time.h>
+#include <stdio.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+time_t xx[] = { 8*60*60, 825042862, -1 };
+
+char *tz[] = {
+ "EST-11EST-10,86/2:00,303/2:00", "UTC", "PST7PDT7", (char *)0
+};
+
+int
+main()
+{
+ struct tm *tmp;
+ struct tm mytm;
+ char buf[28];
+ time_t ans;
+ int i;
+ int j;
+ int m;
+
+ printf("standard libc routines\n");
+ for (i = 0; xx[i] != -1; i++) {
+ tmp = localtime(&xx[i]);
+ ans = mktime(tmp);
+ printf("initial %d -> %d %s", (int)xx[i], (int)ans, ctime(&ans));
+ for (m = -3; m < 4; m++) {
+ if (m == 0) continue;
+ tmp = localtime(&xx[i]);
+ tmp->tm_mon += m;
+ ans = mktime(tmp);
+ if (m < 0)
+ printf("%d months -> %d %s", m, (int)ans, ctime(&ans));
+ else
+ printf("+%d months -> %d %s", m, (int)ans, ctime(&ans));
+ }
+ printf("\n");
+ }
+
+ for (j = 0; tz[j] != (char *)0; j++) {
+ printf("pmNewZone(\"%s\")\n", tz[j]);
+ pmNewZone(tz[j]);
+ for (i = 0; xx[i] != -1; i++) {
+ tmp = pmLocaltime(&xx[i], &mytm);
+ ans = __pmMktime(tmp);
+ printf("initial %d -> %d %s", (int)xx[i], (int)ans, pmCtime(&ans, buf));
+ for (m = -3; m < 4; m++) {
+ if (m == 0) continue;
+ tmp = pmLocaltime(&xx[i], &mytm);
+ tmp->tm_mon += m;
+ ans = __pmMktime(tmp);
+ if (m < 0)
+ printf("%d months -> %d %s", m, (int)ans, pmCtime(&ans, buf));
+ else
+ printf("+%d months -> %d %s", m, (int)ans, pmCtime(&ans, buf));
+ }
+ printf("\n");
+ }
+ }
+
+ exit(0);
+}
diff --git a/qa/src/xval.c b/qa/src/xval.c
new file mode 100644
index 0000000..239d219
--- /dev/null
+++ b/qa/src/xval.c
@@ -0,0 +1,525 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * xval [-D] [-e] [-u] [-v] value-in-hex
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+static int type[] = {
+ PM_TYPE_32, PM_TYPE_U32, PM_TYPE_64, PM_TYPE_U64, PM_TYPE_FLOAT, PM_TYPE_DOUBLE, PM_TYPE_STRING, PM_TYPE_AGGREGATE, PM_TYPE_EVENT, PM_TYPE_HIGHRES_EVENT };
+static char *name[] = {
+ "long", "ulong", "longlong", "ulonglong", "float", "double", "char *", "pmValueBlock *", "pmEventArray", "pmHighResEventArray" };
+
+/*
+ * ap may point into a vbuf[] and so is not necessarily aligned correctly
+ */
+static void
+_y(void *ap, int type)
+{
+ int i;
+ int vlen;
+ char *cp;
+ pmAtomValue av;
+
+ memcpy((void *)&av, (void *)ap, sizeof(av));
+
+ switch (type) {
+ case PM_TYPE_32:
+ printf("%d", av.l);
+ break;
+ case PM_TYPE_U32:
+ printf("%u", av.ul);
+ break;
+ case PM_TYPE_64:
+ /* avoid alignment problems */
+ printf("%lld", (long long)av.ll);
+ break;
+ case PM_TYPE_U64:
+ /* avoid alignment problems */
+ printf("%llu", (unsigned long long)av.ull);
+ break;
+ case PM_TYPE_FLOAT:
+ printf("%e", (double)av.f);
+ break;
+ case PM_TYPE_DOUBLE:
+ printf("%e", av.d);
+ break;
+ case PM_TYPE_STRING:
+ if (av.cp == (char *)0)
+ printf("(char *)0");
+ else
+ printf("\"%s\"", av.cp);
+ break;
+ case PM_TYPE_AGGREGATE:
+ vlen = av.vbp->vlen - PM_VAL_HDR_SIZE;
+ printf("[vlen=%d]", vlen);
+ cp = (char *)av.vbp->vbuf;
+ for (i = 0; i < vlen && i < 12; i++) {
+ if ((i % 4) == 0)
+ putchar(' ');
+ printf("%02x", *cp & 0xff);
+ cp++;
+ }
+ if (vlen > 12) printf(" ...");
+ break;
+ case PM_TYPE_EVENT: {
+ pmEventArray *eap;
+ /* this seems alignment safe */
+ eap = (pmEventArray *)ap;
+ printf("[%d event records]", eap->ea_nrecords);
+ break;
+ }
+ case PM_TYPE_HIGHRES_EVENT: {
+ pmHighResEventArray *hreap;
+ /* this seems alignment safe */
+ hreap = (pmHighResEventArray *)ap;
+ printf("[%d event records]", hreap->ea_nrecords);
+ break;
+ }
+ }
+}
+
+static pmEventArray ea;
+static pmHighResEventArray hrea;
+
+int
+main(int argc, char *argv[])
+{
+ int e;
+ int k;
+ int i;
+ int o;
+ void *avp;
+ pmValue pv;
+ pmAtomValue av;
+ pmAtomValue bv;
+ pmAtomValue iv;
+ pmAtomValue *ap;
+ pmValueBlock *vbp;
+ __int32_t *foo;
+ int valfmt;
+ int vflag = 0; /* set to 1 to show all results */
+ int sgn = 1; /* -u to force 64 unsigned from command line value */
+ long long llv;
+
+ ea.ea_nrecords = 1;
+ ea.ea_record[0].er_nparams = 0;
+ vbp = (pmValueBlock *)&ea;
+ vbp->vtype = PM_TYPE_EVENT;
+ vbp->vlen = sizeof(ea); /* not quite correct, but close enough */
+ hrea.ea_nrecords = 1;
+ hrea.ea_record[0].er_nparams = 0;
+ vbp = (pmValueBlock *)&hrea;
+ vbp->vtype = PM_TYPE_HIGHRES_EVENT;
+ vbp->vlen = sizeof(hrea); /* not quite correct, but close enough */
+
+ vbp = (pmValueBlock *)malloc(sizeof(pmValueBlock)+7*sizeof(int));
+ if (vbp == NULL) {
+ fprintf(stderr, "initial malloc failed!\n");
+ exit(1);
+ }
+
+ while (argc > 1) {
+ argc--;
+ argv++;
+ if (strcmp(argv[0], "-D") == 0) {
+ pmDebug = DBG_TRACE_VALUE;
+ continue;
+ }
+ if (strcmp(argv[0], "-e") == 0) {
+ goto error_cases;
+ }
+ if (strcmp(argv[0], "-u") == 0) {
+ sgn = 0;
+ continue;
+ }
+ if (strcmp(argv[0], "-v") == 0) {
+ vflag = 1;
+ continue;
+ }
+ /* note value is in hex! */
+ sscanf(argv[0], "%llx", &llv);
+ if (sgn)
+ printf("\nValue: %lld 0x%016llx\n", llv, llv);
+ else
+ printf("\nValue: %llu 0x%016llx\n", (unsigned long long)llv, llv);
+
+ for (i = 0; i < sizeof(type)/sizeof(type[0]); i++) {
+ valfmt = PM_VAL_INSITU;
+ ap = (pmAtomValue *)&pv.value.lval;
+ switch (type[i]) {
+ case PM_TYPE_32:
+ case PM_TYPE_U32:
+ pv.value.lval = llv;
+ break;
+ case PM_TYPE_64:
+ valfmt = PM_VAL_SPTR;
+ pv.value.pval = vbp;
+ vbp->vlen = PM_VAL_HDR_SIZE + sizeof(__int64_t);
+ vbp->vtype = PM_TYPE_64;
+ avp = (void *)vbp->vbuf;
+ bv.ll = llv;
+ memcpy(avp, (void *)&bv, sizeof(bv));
+ ap = &bv;
+ break;
+ case PM_TYPE_U64:
+ valfmt = PM_VAL_SPTR;
+ pv.value.pval = vbp;
+ vbp->vlen = PM_VAL_HDR_SIZE + sizeof(__uint64_t);
+ vbp->vtype = PM_TYPE_U64;
+ avp = (void *)vbp->vbuf;
+ bv.ll = llv;
+ memcpy(avp, (void *)&bv, sizeof(bv));
+ ap = &bv;
+ break;
+ case PM_TYPE_FLOAT:
+ valfmt = PM_VAL_SPTR;
+ pv.value.pval = vbp;
+ vbp->vlen = PM_VAL_HDR_SIZE + sizeof(float);
+ vbp->vtype = PM_TYPE_FLOAT;
+ avp = (void *)vbp->vbuf;
+ if (sgn)
+ bv.f = llv;
+ else
+ bv.f = (unsigned long long)llv;
+ memcpy(avp, (void *)&bv, sizeof(bv));
+ ap = &bv;
+ break;
+ case PM_TYPE_DOUBLE:
+ valfmt = PM_VAL_SPTR;
+ pv.value.pval = vbp;
+ vbp->vlen = PM_VAL_HDR_SIZE + sizeof(double);
+ vbp->vtype = PM_TYPE_DOUBLE;
+ avp = (void *)vbp->vbuf;
+ if (sgn)
+ bv.d = llv;
+ else
+ bv.d = (unsigned long long)llv;
+ memcpy(avp, (void *)&bv, sizeof(bv));
+ ap = &bv;
+ break;
+ case PM_TYPE_STRING:
+ valfmt = PM_VAL_SPTR;
+ pv.value.pval = vbp;
+ sprintf(vbp->vbuf, "%lld", llv);
+ vbp->vlen = PM_VAL_HDR_SIZE + strlen(vbp->vbuf) + 1;
+ vbp->vtype = PM_TYPE_STRING;
+ ap = &bv;
+ bv.cp = (char *)vbp->vbuf;
+ break;
+ case PM_TYPE_AGGREGATE:
+ valfmt = PM_VAL_SPTR;
+ pv.value.pval = vbp;
+ vbp->vlen = PM_VAL_HDR_SIZE + 3 * sizeof(foo[0]);
+ vbp->vtype = PM_TYPE_AGGREGATE;
+ foo = (__int32_t *)vbp->vbuf;
+ foo[0] = foo[1] = foo[2] = llv;
+ foo[0]--;
+ foo[2]++;
+ /* remove endian diff in value dump output */
+ foo[0] = htonl(foo[0]);
+ foo[1] = htonl(foo[1]);
+ foo[2] = htonl(foo[2]);
+ ap = &bv;
+ bv.vbp = vbp;
+ break;
+ case PM_TYPE_EVENT:
+ valfmt = PM_VAL_DPTR;
+ ap = (void *)&ea;
+ break;
+ case PM_TYPE_HIGHRES_EVENT:
+ valfmt = PM_VAL_DPTR;
+ ap = (void *)&hrea;
+ break;
+ }
+ for (o = 0; o < sizeof(type)/sizeof(type[0]); o++) {
+ if ((e = pmExtractValue(valfmt, &pv, type[i], &av, type[o])) < 0) {
+ if (vflag == 0) {
+ /* silently ignore the expected failures */
+ if (type[i] != type[o] &&
+ (type[i] == PM_TYPE_STRING || type[o] == PM_TYPE_STRING ||
+ type[i] == PM_TYPE_AGGREGATE || type[o] == PM_TYPE_AGGREGATE))
+ continue;
+ if (type[i] == PM_TYPE_EVENT || type[i] == PM_TYPE_HIGHRES_EVENT ||
+ type[o] == PM_TYPE_EVENT || type[o] == PM_TYPE_HIGHRES_EVENT)
+ continue;
+ }
+ printf("(%s) ", name[i]);
+ _y(ap, type[i]);
+ printf(" => (%s) ", name[o]);
+ printf(": %s\n", pmErrStr(e));
+ }
+ else {
+ int match;
+ /* avoid ap-> alignment issues */
+ memcpy((void *)&iv, (void *)ap, sizeof(iv));
+ switch (type[o]) {
+ case PM_TYPE_32:
+ if (type[i] == PM_TYPE_32)
+ match = (pv.value.lval == av.l);
+ else if (type[i] == PM_TYPE_U32)
+ match = ((unsigned)pv.value.lval == av.l);
+ else if (type[i] == PM_TYPE_FLOAT)
+ match = (fabs((iv.f - av.l)/iv.f) < 0.00001);
+ else
+ match = (llv == av.l);
+ break;
+ case PM_TYPE_U32:
+ if (type[i] == PM_TYPE_32)
+ match = (pv.value.lval == av.ul);
+ else if (type[i] == PM_TYPE_U32)
+ match = ((unsigned)pv.value.lval == av.ul);
+ else if (type[i] == PM_TYPE_FLOAT)
+ match = (fabs((iv.f - av.ul)/iv.f) < 0.00001);
+ else
+ match = (llv == av.ul);
+ break;
+ case PM_TYPE_64:
+ if (type[i] == PM_TYPE_32)
+ match = (pv.value.lval == av.ll);
+ else if (type[i] == PM_TYPE_U32)
+ match = ((unsigned)pv.value.lval == av.ll);
+ else if (type[i] == PM_TYPE_FLOAT)
+ match = (fabs((iv.f - av.ll)/iv.f) < 0.00001);
+ else if (type[i] == PM_TYPE_DOUBLE)
+ match = (fabs((iv.d - av.ll)/iv.d) < 0.00001);
+ else
+ match = (llv == av.ll);
+ break;
+ case PM_TYPE_U64:
+ if (type[i] == PM_TYPE_32)
+ match = (pv.value.lval == av.ull);
+ else if (type[i] == PM_TYPE_U32)
+ match = ((unsigned)pv.value.lval == av.ull);
+ else if (type[i] == PM_TYPE_FLOAT)
+ match = (fabs((iv.f - av.ull)/iv.f) < 0.00001);
+ else if (type[i] == PM_TYPE_DOUBLE)
+ match = (fabs((iv.d - av.ull)/iv.d) < 0.00001);
+ else
+ match = (llv == av.ull);
+ break;
+ case PM_TYPE_FLOAT:
+ if (type[i] == PM_TYPE_32)
+ match = (fabs((pv.value.lval - av.f)/pv.value.lval) < 0.00001);
+ else if (type[i] == PM_TYPE_U32)
+ match = (fabs(((unsigned)pv.value.lval - av.f)/(unsigned)pv.value.lval) < 0.00001);
+ else if (type[i] == PM_TYPE_64)
+ match = (fabs((llv - av.f)/llv) < 0.00001);
+ else if (type[i] == PM_TYPE_U64)
+ match = (fabs(((unsigned long long)llv - av.f)/(unsigned long long)llv) < 0.00001);
+ else if (type[i] == PM_TYPE_DOUBLE)
+ match = (fabs((iv.d - av.f)/iv.d) < 0.00001);
+ else
+ match = (iv.f == av.f);
+ break;
+ case PM_TYPE_DOUBLE:
+ if (type[i] == PM_TYPE_32)
+ match = (fabs((pv.value.lval - av.d)/pv.value.lval) < 0.00001);
+ else if (type[i] == PM_TYPE_U32)
+ match = (fabs(((unsigned)pv.value.lval - av.d)/(unsigned)pv.value.lval) < 0.00001);
+ else if (type[i] == PM_TYPE_64)
+ match = (fabs((llv - av.d)/llv) < 0.00001);
+ else if (type[i] == PM_TYPE_U64)
+ match = (fabs(((unsigned long long)llv - av.d)/(unsigned long long)llv) < 0.00001);
+ else if (type[i] == PM_TYPE_FLOAT)
+ match = (fabs((iv.f - av.d)/iv.f) < 0.00001);
+ else
+ match = (iv.d == av.d);
+ break;
+ case PM_TYPE_STRING:
+ match = (strcmp(bv.cp, av.cp) == 0);
+ break;
+ case PM_TYPE_AGGREGATE:
+ match = 0;
+ for (k = 0; match == 0 && k < vbp->vlen - PM_VAL_HDR_SIZE; k++)
+ match = (bv.cp[k] == av.cp[k]);
+ break;
+ case PM_TYPE_EVENT:
+ case PM_TYPE_HIGHRES_EVENT:
+ default:
+ /* should never get here */
+ match = 0;
+ break;
+ }
+ if (match == 0 || vflag) {
+ printf("(%s) ", name[i]);
+ _y(ap, type[i]);
+ printf(" => (%s) ", name[o]);
+ _y(&av, type[o]);
+ if (match == 0)
+ printf(" : value mismatch");
+ putchar('\n');
+ }
+ if (type[o] == PM_TYPE_STRING)
+ free(av.cp);
+ else if (type[o] == PM_TYPE_AGGREGATE)
+ free(av.vbp);
+ }
+ }
+ }
+ }
+
+ exit(0);
+
+error_cases:
+ /*
+ * a series of error and odd cases driven by QA coverage analysis
+ */
+ avp = (void *)&pv.value.lval;
+ bv.f = 123.456;
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %15.3f -> 32: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_32)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%d\n", av.l);
+
+ bv.f = (float)0xf7777777;
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %15.3f -> 32: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_32)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%d\n", av.l);
+
+ bv.f = 123.456;
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %15.3f -> U32: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_U32)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%u\n", av.ul);
+
+ bv.f = (float)((unsigned)0xffffffff);
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %15.3f -> U32: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_U32)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%u\n", av.ul);
+
+ bv.f = -123.456;
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %15.3f -> U32: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_U32)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%u\n", av.ul);
+
+ bv.f = 123.456;
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %15.3f -> 64: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_64)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%lld\n", (long long)av.ll);
+
+ bv.f = (float)0x7fffffffffffffffLL;
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %22.1f -> 64: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_64)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%lld\n", (long long)av.ll);
+
+ bv.f = 123.456;
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %15.3f -> U64: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_U64)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%llu\n", (unsigned long long)av.ull);
+
+ bv.f = (float)((unsigned long long)0xffffffffffffffffLL);
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %22.1f -> U64: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_U64)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%llu\n", (unsigned long long)av.ull);
+
+ bv.f = -123.456;
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %15.3f -> U64: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_U64)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%llu\n", (unsigned long long)av.ull);
+
+ bv.f = 123.45678;
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %15.5f -> DOUBLE: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_DOUBLE)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%15.5f\n", av.d);
+
+ bv.f = 123.45678;
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("old FLOAT: %15.5f -> STRING: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_INSITU, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_STRING)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%15.6f\n", av.d);
+
+ pv.value.pval = vbp;
+ vbp->vlen = PM_VAL_HDR_SIZE + sizeof(bv.ll);
+ vbp->vtype = PM_TYPE_NOSUPPORT;
+ avp = (void *)vbp->vbuf;
+ bv.ll = 12345;
+ memcpy(avp, (void *)&bv.ll, sizeof(bv.ll));
+ printf("bad 64: %12lld -> 64: ", (long long)bv.ll);
+ if ((e = pmExtractValue(PM_VAL_SPTR, &pv, PM_TYPE_64, &av, PM_TYPE_64)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%12lld\n", (long long)av.ll);
+
+ vbp->vlen = PM_VAL_HDR_SIZE + sizeof(bv.ull);
+ memcpy(avp, (void *)&bv.ull, sizeof(bv.ull));
+ printf("bad U64: %12llu -> U64: ", (unsigned long long)bv.ull);
+ if ((e = pmExtractValue(PM_VAL_SPTR, &pv, PM_TYPE_U64, &av, PM_TYPE_U64)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%12llu\n", (unsigned long long)av.ull);
+
+ vbp->vlen = PM_VAL_HDR_SIZE + sizeof(bv.f);
+ bv.f = 123.456;
+ memcpy(avp, (void *)&bv.f, sizeof(bv.f));
+ printf("bad FLOAT: %15.3f -> FLOAT: ", bv.f);
+ if ((e = pmExtractValue(PM_VAL_SPTR, &pv, PM_TYPE_FLOAT, &av, PM_TYPE_FLOAT)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%15.3f\n", av.f);
+
+ vbp->vlen = PM_VAL_HDR_SIZE + sizeof(bv.d);
+ bv.d = 123.456;
+ memcpy(avp, (void *)&bv.d, sizeof(bv.d));
+ printf("bad DOUBLE: %15.3f -> DOUBLE: ", bv.d);
+ if ((e = pmExtractValue(PM_VAL_SPTR, &pv, PM_TYPE_DOUBLE, &av, PM_TYPE_DOUBLE)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%15.3f\n", av.d);
+
+ bv.cp = "not me";
+ memcpy(avp, (void *)&bv, sizeof(bv));
+ vbp->vlen = PM_VAL_HDR_SIZE + strlen(bv.cp);
+ printf("bad STRING: %s -> STRING: ", bv.cp);
+ if ((e = pmExtractValue(PM_VAL_SPTR, &pv, PM_TYPE_STRING, &av, PM_TYPE_STRING)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("%s\n", av.cp);
+
+ vbp->vlen = PM_VAL_HDR_SIZE;
+ printf("bad AGGREGATE: len=%d -> AGGREGATE: ", vbp->vlen - PM_VAL_HDR_SIZE);
+ if ((e = pmExtractValue(PM_VAL_SPTR, &pv, PM_TYPE_AGGREGATE, &av, PM_TYPE_AGGREGATE)) < 0)
+ printf("%s\n", pmErrStr(e));
+ else
+ printf("len=%d\n", av.vbp->vlen);
+
+ exit(0);
+}
+
diff --git a/qa/src/xxx.c b/qa/src/xxx.c
new file mode 100644
index 0000000..91a0a2a
--- /dev/null
+++ b/qa/src/xxx.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1995-2001 Silicon Graphics, Inc. All Rights Reserved.
+ */
+
+#include <ctype.h>
+#include <pcp/pmapi.h>
+#include <pcp/impl.h>
+
+int
+main()
+{
+ int i;
+ char *namelist[20];
+ pmID pmidlist[20];
+ int n;
+ int numpmid;
+ pmResult *resp;
+ unsigned long mem;
+
+ if ((n = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) {
+ fprintf(stderr, "pmLoadNameSpace: %s\n", pmErrStr(n));
+ exit(1);
+ }
+
+ if ((n = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) {
+ fprintf(stderr, "pmNewContext(..., \"localhost\"): %s\n",
+ pmErrStr(n));
+ exit(1);
+ }
+
+ i = 0;
+ namelist[i++] = "sample.sysinfo";
+ namelist[i++] = "sampledso.seconds";
+ namelist[i++] = "sample.colour";
+ namelist[i++] = "sampledso.mirage";
+ namelist[i++] = "sample.lights";
+ namelist[i++] = "sampledso.string.hullo";
+ namelist[i++] = "sample.aggregate.hullo";
+ namelist[i++] = "sampledso.longlong.one";
+ numpmid = i;
+ n = pmLookupName(numpmid, namelist, pmidlist);
+ if (n < 0) {
+ fprintf(stderr, "pmLookupName: %s\n", pmErrStr(n));
+ for (i = 0; i < numpmid; i++) {
+ if (pmidlist[i] == PM_ID_NULL)
+ printf(" %s - not known\n", namelist[i]);
+ }
+ exit(1);
+ }
+
+ __pmProcessDataSize(NULL);
+ for (i = 0; i < 10000; i++) {
+ if ((n = pmFetch(numpmid, pmidlist, &resp)) < 0) {
+ fprintf(stderr, "pmFetch: %s\n", pmErrStr(n));
+ abort();
+ }
+ pmFreeResult(resp);
+ }
+ __pmProcessDataSize(&mem);
+ printf("mem growth: %lu Kbytes\n", mem);
+
+ exit(0);
+}