/
libpcp.h
1268 lines (1173 loc) · 51.6 KB
/
libpcp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* CAVEAT
* The interfaces and data structures defined in this header are
* intended for internal Performance Co-Pilot (PCP) developer use.
*
* They are not part of the PCP APIs that are guaranteed to
* remain fixed across releases, and they may not work, or may
* provide different semantics at some point in the future.
*
* Copyright (c) 2012-2017 Red Hat.
* Copyright (c) 2008-2009 Aconex. All Rights Reserved.
* Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
*
* 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.
*/
#ifndef PCP_LIBPCP_H
#define PCP_LIBPCP_H
/*
* TODO
* demote names from pm... to __pm... for
* - pmHostSpec
* - pmTimeZone
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* internal libpcp state ... PM_STATE_APPL means we are at or above the
* PMAPI in a state where PMAPI calls can safely be made ... PM_STATE_PMCS
* means we are in the PMCD, or a PMDA, or low-level PDU code, and
* PMAPI calls are a bad idea.
*/
#define PM_STATE_APPL 0
#define PM_STATE_PMCS 1
PCP_CALL extern void __pmSetInternalState(int);
PCP_CALL extern int __pmGetInternalState(void);
/*
* Thread-safe support ... #define to enable thread-safe protection of
* global data structures and mutual exclusion when required.
*
* We require pthread.h and working mutex, the rest can be faked
* by the libpcp itself.
*/
#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_T)
#define PM_MULTI_THREAD 1
#include <pthread.h>
typedef pthread_mutex_t __pmMutex;
#else
typedef void * __pmMutex;
#endif
/*
* Multi-thread support
* Use PM_MULTI_THREAD_DEBUG for lock debugging with -Dlock[,appl?...]
*/
PCP_CALL extern void __pmInitLocks(void);
PCP_CALL extern int __pmLock(void *, const char *, int);
PCP_CALL extern int __pmUnlock(void *, const char *, int);
PCP_CALL extern int __pmIsLocked(void *);
#ifdef BUILD_WITH_LOCK_ASSERTS
PCP_CALL extern void __pmCheckIsUnlocked(void *, char *, int);
#endif /* BUILD_WITH_LOCK_ASSERTS */
/*
* Each of these scopes defines one or more PMAPI routines that will
* not allow calls from more than one thread.
*/
#define PM_SCOPE_DSO_PMDA 0
#define PM_SCOPE_ACL 1
#define PM_SCOPE_AF 2
#define PM_SCOPE_LOGPORT 3
#define PM_SCOPE_MAX 3
PCP_CALL extern int __pmMultiThreaded(int);
#define PM_INIT_LOCKS() __pmInitLocks()
#define PM_MULTIPLE_THREADS(x) __pmMultiThreaded(x)
#define PM_LOCK(lock) __pmLock(&(lock), __FILE__, __LINE__)
#define PM_UNLOCK(lock) __pmUnlock(&(lock), __FILE__, __LINE__)
#define PM_IS_LOCKED(lock) __pmIsLocked(&(lock))
#ifdef HAVE_PTHREAD_MUTEX_T
/* the big libpcp lock */
PCP_CALL extern pthread_mutex_t __pmLock_libpcp;
/* mutex for calls to external routines that are not thread-safe */
PCP_CALL extern pthread_mutex_t __pmLock_extcall;
#else
PCP_CALL extern void *__pmLock_libpcp; /* symbol exposure */
PCP_CALL extern void *__pmLock_extcall; /* symbol exposure */
#endif
/*
* Internally, this is how to decode a PMID!
* - flag is to denote state internally in some operations
* - domain is usually the unique domain number of a PMDA, but see
* below for some special cases
* - cluster and item together uniquely identify a metric within a domain
*/
typedef struct {
#ifdef HAVE_BITFIELDS_LTOR
unsigned int flag : 1;
unsigned int domain : 9;
unsigned int cluster : 12;
unsigned int item : 10;
#else
unsigned int item : 10;
unsigned int cluster : 12;
unsigned int domain : 9;
unsigned int flag : 1;
#endif
} __pmID_int;
/*
* Internally, this is how to decode an Instance Domain Identifier
* - flag is to denote state internally in some operations
* - domain is usually the unique domain number of a PMDA, but DYNAMIC_PMID
* (number 511) is reserved (see above for PMID encoding rules)
* - serial uniquely identifies an InDom within a domain
*/
typedef struct {
#ifdef HAVE_BITFIELDS_LTOR
int flag : 1;
unsigned int domain : 9;
unsigned int serial : 22;
#else
unsigned int serial : 22;
unsigned int domain : 9;
int flag : 1;
#endif
} __pmInDom_int;
/*
* Internal structure of a PMNS node
*/
typedef struct __pmnsNode {
struct __pmnsNode *parent;
struct __pmnsNode *next;
struct __pmnsNode *first;
struct __pmnsNode *hash; /* used as "last" in build, then pmid hash synonym */
char *name;
pmID pmid;
} __pmnsNode;
/*
* Internal structure of a PMNS tree
*/
typedef struct __pmnsTree {
__pmnsNode *root; /* root of tree structure */
__pmnsNode **htab; /* hash table of nodes keyed on pmid */
int htabsize; /* number of nodes in the table */
int mark_state; /* the total mark value for trimming */
} __pmnsTree;
/* used by pmnsmerge... */
PCP_CALL extern __pmnsTree *__pmExportPMNS(void);
/* for PMNS in archives */
PCP_CALL extern int __pmNewPMNS(__pmnsTree **);
PCP_CALL extern void __pmFreePMNS(__pmnsTree *);
PCP_CALL extern void __pmUsePMNS(__pmnsTree *); /* for debugging */
PCP_CALL extern int __pmFixPMNSHashTab(__pmnsTree *, int, int);
PCP_CALL extern int __pmAddPMNSNode(__pmnsTree *, int, const char *);
PCP_CALL extern void __pmDumpNameNode(FILE *, __pmnsNode *, int);
/* return true if the named pmns file has changed */
PCP_CALL extern int __pmHasPMNSFileChanged(const char *);
/* PDU types */
#define PDU_START 0x7000
#define PDU_ERROR PDU_START
#define PDU_RESULT 0x7001
#define PDU_PROFILE 0x7002
#define PDU_FETCH 0x7003
#define PDU_DESC_REQ 0x7004
#define PDU_DESC 0x7005
#define PDU_INSTANCE_REQ 0x7006
#define PDU_INSTANCE 0x7007
#define PDU_TEXT_REQ 0x7008
#define PDU_TEXT 0x7009
#define PDU_CONTROL_REQ 0x700a
#define PDU_CREDS 0x700c
#define PDU_PMNS_IDS 0x700d
#define PDU_PMNS_NAMES 0x700e
#define PDU_PMNS_CHILD 0x700f
#define PDU_PMNS_TRAVERSE 0x7010
#define PDU_ATTR 0x7011
#define PDU_AUTH PDU_ATTR
#define PDU_LABEL_REQ 0x7012
#define PDU_LABEL 0x7013
#define PDU_FINISH 0x7013
#define PDU_MAX (PDU_FINISH - PDU_START)
typedef __uint32_t __pmPDU;
/*
* round a size up to the next multiple of a __pmPDU size
*
* PM_PDU_SIZE is in units of __pmPDU size
* PM_PDU_SIZE_BYTES is in units of bytes
*/
#define PM_PDU_SIZE(x) (((x)+sizeof(__pmPDU)-1)/sizeof(__pmPDU))
#define PM_PDU_SIZE_BYTES(x) (sizeof(__pmPDU)*PM_PDU_SIZE(x))
/* timeout options for PDU handling */
#define TIMEOUT_NEVER 0
#define TIMEOUT_DEFAULT -1
/* deprecated #define TIMEOUT_ASYNC -2 */
#define TIMEOUT_CONNECT -3
/*
* For the help text PDUs, the type (PM_TEXT_ONELINE or PM_TEXT_HELP)
* is 'or'd with the following to encode the request for a PMID or
* a pmInDom. Default is to fallback to ONELINE if HELP unavailable;
* the (internal) PM_TEXT_DIRECT flag disables this behaviour.
* Note the values must therefore be (a) bit fields and (b) different
* to the public macros PM_TEXT_* in pmapi.h
*/
#define PM_TEXT_PMID 4
#define PM_TEXT_INDOM 8
#define PM_TEXT_DIRECT 16
/* Version and capabilities information for PDU exchanges */
#define UNKNOWN_VERSION 0
#define PDU_VERSION2 2
#define PDU_VERSION PDU_VERSION2
#define PDU_OVERRIDE2 -1002
typedef struct {
#ifdef HAVE_BITFIELDS_LTOR
unsigned int zero : 1; /* ensure this is zero for 1.x compatibility */
unsigned int version : 7; /* PDU_VERSION collector protocol preference */
unsigned int licensed : 8; /* ensure this is one for 2.x compatibility */
unsigned int features : 16; /* advertised (enabled) collector features */
#else
unsigned int features : 16;
unsigned int licensed : 8;
unsigned int version : 7;
unsigned int zero : 1;
#endif
} __pmPDUInfo;
/*
* Protocol data unit support
* Note: int is OK here, because configure ensures int is a 32-bit integer
*/
typedef struct {
int len; /* length of pdu_header + PDU */
int type; /* PDU type */
int from; /* pid of PDU originator */
} __pmPDUHdr;
/* credentials stuff */
/* Types of credential PDUs (c_type) */
#define CVERSION 0x1
typedef struct {
#ifdef HAVE_BITFIELDS_LTOR
unsigned int c_type: 8; /* Credentials PDU type */
unsigned int c_vala: 8;
unsigned int c_valb: 8;
unsigned int c_valc: 8;
#else
unsigned int c_valc: 8;
unsigned int c_valb: 8;
unsigned int c_vala: 8;
unsigned int c_type: 8;
#endif
} __pmCred;
/* Flags for CVERSION credential PDUs, and __pmPDUInfo features */
#define PDU_FLAG_SECURE (1U<<0)
#define PDU_FLAG_COMPRESS (1U<<1)
#define PDU_FLAG_AUTH (1U<<2)
#define PDU_FLAG_CREDS_REQD (1U<<3)
#define PDU_FLAG_SECURE_ACK (1U<<4)
#define PDU_FLAG_NO_NSS_INIT (1U<<5)
#define PDU_FLAG_CONTAINER (1U<<6)
#define PDU_FLAG_CERT_REQD (1U<<7)
#define PDU_FLAG_LABEL (1U<<8)
/* Credential CVERSION PDU elements look like this */
typedef struct {
#ifdef HAVE_BITFIELDS_LTOR
unsigned int c_type: 8; /* Credentials PDU type */
unsigned int c_version: 8; /* PCP protocol version */
unsigned int c_flags: 16; /* All feature requests */
#else
unsigned int c_flags: 16;
unsigned int c_version: 8;
unsigned int c_type: 8;
#endif
} __pmVersionCred;
#if defined(HAVE_64BIT_LONG)
/*
* A pmValue contains the union of a 32-bit int and a pointer. In the world
* of 64-bit pointers, a pmValue is therefore larger than in the 32-bit world.
* The structures below are used in all PDUs containing pmResults to ensure
* 32-bit and 64-bit programs exchanging PDUs can communicate.
* Note that a pmValue can only hold a 32-bit value in situ regardless of
* whether the pointer size is 32 or 64 bits.
*/
typedef struct {
int inst; /* instance identifier */
union {
unsigned int pval; /* offset into PDU buffer for value */
int lval; /* 32-bit value in situ */
} value;
} __pmValue_PDU;
typedef struct {
pmID pmid; /* metric identifier */
int numval; /* number of values */
int valfmt; /* value style */
__pmValue_PDU vlist[1]; /* set of instances/values */
} __pmValueSet_PDU;
#elif defined(HAVE_32BIT_LONG)
/* In the 32-bit world, structures may be used in PDUs as defined */
typedef pmValue __pmValue_PDU;
typedef pmValueSet __pmValueSet_PDU;
#else
bozo - unknown size of long !!!
#endif
/* mode options for __pmGetPDU */
#define ANY_SIZE 0 /* replacement for old PDU_BINARY */
#define LIMIT_SIZE 2 /* replacement for old PDU_CLIENT */
/*
* PDU encoding formats
* These have been retired ...
* #define PDU_BINARY 0
* #define PDU_ASCII 1
* And this has been replaced by LIMIT_SIZE for __pmGetPDU
* #define PDU_CLIENT 2
*/
/* Unit of space allocation for PDU buffer */
#define PDU_CHUNK 1024
/*
* Anonymous PDU sender, when context does not matter, e.g. PDUs from
* a PMDA sent to PMCD
*/
#define FROM_ANON 0
/* PDU type independent send-receive routines */
PCP_CALL extern int __pmXmitPDU(int, __pmPDU *);
PCP_CALL extern int __pmGetPDU(int, int, int, __pmPDU **);
PCP_CALL extern int __pmGetPDUCeiling(void);
PCP_CALL extern int __pmSetPDUCeiling(int);
/* PDU type specfic send-encode-decode routines */
PCP_CALL extern int __pmSendError(int, int, int);
PCP_CALL extern int __pmDecodeError(__pmPDU *, int *);
PCP_CALL extern int __pmSendXtendError(int, int, int, int);
PCP_CALL extern int __pmDecodeXtendError(__pmPDU *, int *, int *);
PCP_CALL extern int __pmSendResult(int, int, const pmResult *);
PCP_CALL extern int __pmEncodeResult(int, const pmResult *, __pmPDU **);
PCP_CALL extern int __pmDecodeResult(__pmPDU *, pmResult **);
PCP_CALL extern int __pmSendProfile(int, int, int, __pmProfile *);
PCP_CALL extern int __pmDecodeProfile(__pmPDU *, int *, __pmProfile **);
PCP_CALL extern int __pmSendFetch(int, int, int, __pmTimeval *, int, pmID *);
PCP_CALL extern int __pmDecodeFetch(__pmPDU *, int *, __pmTimeval *, int *, pmID **);
PCP_CALL extern int __pmSendDescReq(int, int, pmID);
PCP_CALL extern int __pmDecodeDescReq(__pmPDU *, pmID *);
PCP_CALL extern int __pmSendDesc(int, int, pmDesc *);
PCP_CALL extern int __pmDecodeDesc(__pmPDU *, pmDesc *);
PCP_CALL extern int __pmSendInstanceReq(int, int, const __pmTimeval *, pmInDom, int, const char *);
PCP_CALL extern int __pmDecodeInstanceReq(__pmPDU *, __pmTimeval *, pmInDom *, int *, char **);
PCP_CALL extern int __pmSendInstance(int, int, __pmInResult *);
PCP_CALL extern int __pmDecodeInstance(__pmPDU *, __pmInResult **);
PCP_CALL extern int __pmSendTextReq(int, int, int, int);
PCP_CALL extern int __pmDecodeTextReq(__pmPDU *, int *, int *);
PCP_CALL extern int __pmSendText(int, int, int, const char *);
PCP_CALL extern int __pmDecodeText(__pmPDU *, int *, char **);
PCP_CALL extern int __pmSendCreds(int, int, int, const __pmCred *);
PCP_CALL extern int __pmDecodeCreds(__pmPDU *, int *, int *, __pmCred **);
PCP_CALL extern int __pmSendIDList(int, int, int, const pmID *, int);
PCP_CALL extern int __pmDecodeIDList(__pmPDU *, int, pmID *, int *);
PCP_CALL extern int __pmSendNameList(int, int, int, char **, const int *);
PCP_CALL extern int __pmDecodeNameList(__pmPDU *, int *, char ***, int **);
PCP_CALL extern int __pmSendChildReq(int, int, const char *, int);
PCP_CALL extern int __pmDecodeChildReq(__pmPDU *, char **, int *);
PCP_CALL extern int __pmSendTraversePMNSReq(int, int, const char *);
PCP_CALL extern int __pmDecodeTraversePMNSReq(__pmPDU *, char **);
PCP_CALL extern int __pmSendAuth(int, int, int, const char *, int);
PCP_CALL extern int __pmDecodeAuth(__pmPDU *, int *, char **, int *);
PCP_CALL extern int __pmSendAttr(int, int, int, const char *, int);
PCP_CALL extern int __pmDecodeAttr(__pmPDU *, int *, char **, int *);
PCP_CALL extern int __pmSendLabelReq(int, int, int, int);
PCP_CALL extern int __pmDecodeLabelReq(__pmPDU *, int *, int *);
PCP_CALL extern int __pmSendLabel(int, int, int, int, pmLabelSet *, int);
PCP_CALL extern int __pmDecodeLabel(__pmPDU *, int *, int *, pmLabelSet **, int *);
PCP_CALL unsigned int __pmServerGetFeaturesFromPDU(__pmPDU *);
/* PDU buffer services */
PCP_CALL extern __pmPDU *__pmFindPDUBuf(int);
PCP_CALL extern void __pmPinPDUBuf(void *);
PCP_CALL extern int __pmUnpinPDUBuf(void *);
PCP_CALL extern void __pmCountPDUBuf(int, int *, int *);
PCP_DATA extern unsigned int *__pmPDUCntIn;
PCP_DATA extern unsigned int *__pmPDUCntOut;
PCP_CALL extern void __pmSetPDUCntBuf(unsigned *, unsigned *);
/* internal IPC protocol stuff */
typedef int (*__pmConnectHostType)(int, int);
PCP_CALL extern int __pmSetSocketIPC(int);
PCP_CALL extern int __pmSetVersionIPC(int, int);
PCP_CALL extern int __pmSetFeaturesIPC(int, int, int);
PCP_CALL extern int __pmSetDataIPC(int, void *);
PCP_CALL extern int __pmDataIPCSize(void);
PCP_CALL extern int __pmLastVersionIPC(void);
PCP_CALL extern int __pmVersionIPC(int);
PCP_CALL extern int __pmSocketIPC(int);
PCP_CALL extern int __pmFeaturesIPC(int);
PCP_CALL extern int __pmDataIPC(int, void *);
PCP_CALL extern void __pmOverrideLastFd(int);
PCP_CALL extern void __pmPrintIPC(void);
PCP_CALL extern void __pmResetIPC(int);
/* platform independent socket services */
typedef fd_set __pmFdSet;
typedef struct __pmSockAddr __pmSockAddr;
typedef struct __pmHostEnt __pmHostEnt;
PCP_CALL extern int __pmCreateSocket(void);
PCP_CALL extern int __pmCreateIPv6Socket(void);
PCP_CALL extern int __pmCreateUnixSocket(void);
PCP_CALL extern int __pmBind(int, void *, __pmSockLen);
PCP_CALL extern int __pmListen(int, int);
PCP_CALL extern int __pmConnect(int, void *, __pmSockLen);
PCP_CALL extern int __pmAccept(int, void *, __pmSockLen *);
PCP_CALL extern void __pmCloseSocket(int);
PCP_CALL extern int __pmSetSockOpt(int, int, int, const void *, __pmSockLen);
PCP_CALL extern int __pmGetSockOpt(int, int, int, void *, __pmSockLen *);
PCP_CALL extern ssize_t __pmWrite(int, const void *, size_t);
PCP_CALL extern ssize_t __pmRead(int, void *, size_t);
PCP_CALL extern ssize_t __pmSend(int, const void *, size_t, int);
PCP_CALL extern ssize_t __pmRecv(int, void *, size_t, int);
PCP_CALL extern int __pmConnectTo(int, const __pmSockAddr *, int);
PCP_CALL extern int __pmConnectCheckError(int);
PCP_CALL extern int __pmConnectRestoreFlags(int, int);
PCP_CALL extern int __pmSocketClosed(void);
PCP_CALL extern int __pmGetFileStatusFlags(int);
PCP_CALL extern int __pmSetFileStatusFlags(int, int);
PCP_CALL extern int __pmGetFileDescriptorFlags(int);
PCP_CALL extern int __pmSetFileDescriptorFlags(int, int);
PCP_CALL extern int __pmFD(int);
PCP_CALL extern void __pmFD_CLR(int, __pmFdSet *);
PCP_CALL extern int __pmFD_ISSET(int, __pmFdSet *);
PCP_CALL extern void __pmFD_SET(int, __pmFdSet *);
PCP_CALL extern void __pmFD_ZERO(__pmFdSet *);
PCP_CALL extern void __pmFD_COPY(__pmFdSet *, const __pmFdSet *);
PCP_CALL extern int __pmSelectRead(int, __pmFdSet *, struct timeval *);
PCP_CALL extern int __pmSelectWrite(int, __pmFdSet *, struct timeval *);
PCP_CALL extern __pmSockAddr *__pmSockAddrAlloc(void);
PCP_CALL extern void __pmSockAddrFree(__pmSockAddr *);
PCP_CALL extern size_t __pmSockAddrSize(void);
PCP_CALL extern void __pmSockAddrInit(__pmSockAddr *, int, int, int);
PCP_CALL extern int __pmSockAddrCompare(const __pmSockAddr *, const __pmSockAddr *);
PCP_CALL extern __pmSockAddr *__pmSockAddrDup(const __pmSockAddr *);
PCP_CALL extern __pmSockAddr *__pmSockAddrMask(__pmSockAddr *, const __pmSockAddr *);
PCP_CALL extern void __pmSockAddrSetFamily(__pmSockAddr *, int);
PCP_CALL extern int __pmSockAddrGetFamily(const __pmSockAddr *);
PCP_CALL extern void __pmSockAddrSetPort(__pmSockAddr *, int);
PCP_CALL extern int __pmSockAddrGetPort(const __pmSockAddr *);
PCP_CALL extern void __pmSockAddrSetScope(__pmSockAddr *, int);
PCP_CALL extern void __pmSockAddrSetPath(__pmSockAddr *, const char *);
PCP_CALL extern int __pmSockAddrIsLoopBack(const __pmSockAddr *);
PCP_CALL extern int __pmSockAddrIsInet(const __pmSockAddr *);
PCP_CALL extern int __pmSockAddrIsIPv6(const __pmSockAddr *);
PCP_CALL extern int __pmSockAddrIsUnix(const __pmSockAddr *);
PCP_CALL extern char * __pmSockAddrToString(const __pmSockAddr *);
PCP_CALL extern char * __pmGetNameInfo(__pmSockAddr *);
PCP_CALL extern __pmSockAddr *__pmStringToSockAddr(const char *);
PCP_CALL extern __pmSockAddr *__pmLoopBackAddress(int);
PCP_CALL extern __pmSockAddr *__pmSockAddrFirstSubnetAddr(const __pmSockAddr *, int);
PCP_CALL extern __pmSockAddr *__pmSockAddrNextSubnetAddr(__pmSockAddr *, int);
PCP_CALL extern __pmSockAddr *__pmHostEntGetSockAddr(const __pmHostEnt *, void **);
PCP_CALL extern __pmHostEnt * __pmHostEntAlloc(void);
PCP_CALL extern __pmHostEnt * __pmGetAddrInfo(const char *);
PCP_CALL extern void __pmHostEntFree(__pmHostEnt *);
PCP_CALL extern char * __pmHostEntGetName(__pmHostEnt *);
/* Hashed Data Structures for the Processing of Logs and Archives */
typedef struct __pmHashNode {
struct __pmHashNode *next;
unsigned int key;
void *data;
} __pmHashNode;
typedef struct __pmHashCtl {
int nodes;
int hsize;
__pmHashNode **hash;
__pmHashNode *next;
unsigned int index;
} __pmHashCtl;
typedef enum {
PM_HASH_WALK_START = 0,
PM_HASH_WALK_NEXT,
PM_HASH_WALK_STOP,
PM_HASH_WALK_DELETE_NEXT,
PM_HASH_WALK_DELETE_STOP,
} __pmHashWalkState;
PCP_CALL extern void __pmHashInit(__pmHashCtl *);
PCP_CALL extern int __pmHashPreAlloc(int, __pmHashCtl *);
typedef __pmHashWalkState(*__pmHashWalkCallback)(const __pmHashNode *, void *);
PCP_CALL extern void __pmHashWalkCB(__pmHashWalkCallback, void *, const __pmHashCtl *);
PCP_CALL extern __pmHashNode *__pmHashWalk(__pmHashCtl *, __pmHashWalkState);
PCP_CALL extern __pmHashNode *__pmHashSearch(unsigned int, __pmHashCtl *);
PCP_CALL extern int __pmHashAdd(unsigned int, void *, __pmHashCtl *);
PCP_CALL extern int __pmHashDel(unsigned int, void *, __pmHashCtl *);
PCP_CALL extern void __pmHashClear(__pmHashCtl *);
/*
* Host specification allowing one or more pmproxy host, and port numbers
* within the one string, i.e. pmcd host specifications of the form:
* host:port,port@proxy:port,port
*/
typedef struct {
char *name; /* hostname (always valid) */
int *ports; /* array of host port numbers */
int nports; /* number of ports in host port array */
} pmHostSpec;
PCP_CALL extern int __pmParseHostSpec(const char *, pmHostSpec **, int *, char **);
PCP_CALL extern int __pmUnparseHostSpec(pmHostSpec *, int, char *, size_t);
PCP_CALL extern void __pmFreeHostSpec(pmHostSpec *, int);
/* Control for connection to a PMCD */
typedef struct {
int pc_fd; /* socket for comm with pmcd */
/* ... -1 means no connection */
pmHostSpec *pc_hosts; /* pmcd and proxy host specifications */
int pc_nhosts; /* number of pmHostSpec entries */
int pc_timeout; /* set if connect times out */
int pc_tout_sec; /* timeout for __pmGetPDU */
time_t pc_again; /* time to try again */
} __pmPMCDCtl;
PCP_CALL extern int __pmConnectPMCD(pmHostSpec *, int, int, __pmHashCtl *);
PCP_CALL extern int __pmConnectLocal(__pmHashCtl *);
PCP_CALL extern int __pmAuxConnectPMCD(const char *);
PCP_CALL extern int __pmAuxConnectPMCDPort(const char *, int);
PCP_CALL extern int __pmAuxConnectPMCDUnixSocket(const char *);
PCP_CALL extern int __pmAddHostPorts(pmHostSpec *, int *, int);
PCP_CALL extern void __pmDropHostPort(pmHostSpec *);
PCP_CALL extern void __pmConnectGetPorts(pmHostSpec *);
/* internal archive data structures */
/*
* record header in the metadata log file ... len (by itself) also is
* used as a trailer
*/
typedef struct __pmLogHdr {
int len; /* record length, includes header and trailer */
int type; /* see TYPE_* #defines below */
} __pmLogHdr;
#define TYPE_DESC 1 /* header, pmDesc, trailer */
#define TYPE_INDOM 2 /* header, __pmLogInDom, trailer */
#define TYPE_LABEL 3 /* header, __pmLogLabelSet, trailer */
#define TYPE_TEXT 4 /* header, __pmLogText, trailer */
/*
* __pmLogInDom is used to hold the instance identifiers for an instance
* domain internally ... if multiple sets are observed over time, these
* are linked together in reverse chronological order
* -- externally we write these as
* timestamp
* indom <- note, added wrt indom_t
* numinst
* inst[0], .... inst[numinst-1]
* nameindex[0] .... nameindex[numinst-1]
* string (name) table, all null-byte terminated
*
* NOTE: 3 types of allocation
* (1)
* buf is NULL,
* namelist and instlist have been allocated
* separately and so must each be freed.
* (2)
* buf is NOT NULL, allinbuf == 1,
* all allocations were in the buffer and so only
* the buffer should be freed,
* (3)
* buf is NOT NULL, allinbuf == 0,
* as well as buffer allocation,
* the namelist has been allocated separately and so
* both the buf and namelist should be freed.
*/
typedef struct __pmLogInDom {
struct __pmLogInDom *next;
__pmTimeval stamp;
int numinst;
int *instlist;
char **namelist;
int *buf;
int allinbuf;
} __pmLogInDom;
/*
* __pmLogText is used to hold the metric and instance domain help text
* internally, for help text associated with an archive context.
*/
typedef struct __pmLogText {
int type; /* oneline/full and pmid/indom */
int ident; /* metric or indom identifier */
char *text;
} __pmLogText;
/*
* __pmLogLabelSet is used to hold the sets of labels for the label
* hierarchy in memory. Only in the case of instances will it have
* multiple labelsets. For all other (higher) hierarchy levels, a
* single labelset suffices (nsets == 1, and nlabels >= 0). Also,
* in memory labelsets are linked together in reverse chronological
* order (just like the __pmLogInDom structure above).
* -- externally we write these as
* timestamp
* type (int - PM_LABEL_* types)
* ident (int - PM_IN_NULL, domain, indom, pmid)
* nsets (int - usually 1, except for instances)
* jsonb offset (int - offset to jsonb start)
* labelset[0] ... labelset[numsets-1]
* jsonb table (strings, concatenated)
*
* -- with each labelset array entry as
* inst (int)
* nlabels (int)
* jsonb offset (int)
* jsonb length (int)
* label[0] ... label[nlabels-1] (struct pmLabel)
*/
typedef struct __pmLogLabelSet {
struct __pmLogLabelSet *next;
__pmTimeval stamp;
int type;
int ident;
int nsets;
pmLabelSet *labelsets;
} __pmLogLabelSet;
/*
* External file and internal (below PMAPI) format for an archive label
* Note: int is OK here, because configure ensures int is a 32-bit integer
*/
typedef struct {
int ill_magic; /* PM_LOG_MAGIC | log format version no. */
int ill_pid; /* PID of logger */
__pmTimeval ill_start; /* start of this log */
int ill_vol; /* current log volume no. */
char ill_hostname[PM_LOG_MAXHOSTLEN];/* name of collection host */
char ill_tz[PM_TZ_MAXLEN]; /* $TZ at collection host */
} __pmLogLabel;
/*
* Temporal Index Record
* Note: int is OK here, because configure ensures int is a 32-bit integer
*/
typedef struct {
__pmTimeval ti_stamp; /* now */
int ti_vol; /* current log volume no. */
__pm_off_t ti_meta; /* end of meta data file */
__pm_off_t ti_log; /* end of metrics log file */
} __pmLogTI;
/*
* Log/Archive Control
*/
typedef struct {
int l_refcnt; /* number of contexts using this log */
char *l_name; /* external log base name */
__pmFILE *l_tifp; /* temporal index */
__pmFILE *l_mdfp; /* meta data */
__pmFILE *l_mfp; /* current metrics log */
int l_curvol; /* current metrics log volume no. */
int l_state; /* (when writing) log state */
__pmHashCtl l_hashpmid; /* PMID hashed access */
__pmHashCtl l_hashindom; /* instance domain hashed access */
__pmHashCtl l_hashrange; /* ptr to first and last value in log for */
/* each metric */
__pmHashCtl l_hashlabels; /* maps the various metadata label types */
__pmHashCtl l_hashtext; /* maps the various help text types */
int l_minvol; /* (when reading) lowest known volume no. */
int l_maxvol; /* (when reading) highest known volume no. */
int l_numseen; /* (when reading) size of l_seen */
int *l_seen; /* (when reading) volumes opened OK */
__pmLogLabel l_label; /* (when reading) log label */
__pm_off_t l_physend; /* (when reading) offset to physical EOF */
/* for last volume */
__pmTimeval l_endtime; /* (when reading) timestamp at logical EOF */
int l_numti; /* (when reading) no. temporal index entries */
__pmLogTI *l_ti; /* (when reading) temporal index */
struct __pmnsTree *l_pmns; /* namespace from meta data */
int l_multi; /* part of a multi-archive context */
} __pmLogCtl;
/* l_state values */
#define PM_LOG_STATE_NEW 0
#define PM_LOG_STATE_INIT 1
/*
* Minimal information to retain for each archive in a multi-archive context
*/
typedef struct {
char *ml_name; /* external log base name */
__pmTimeval ml_starttime; /* start time of the archive */
char *ml_hostname; /* name of collection host */
char *ml_tz; /* $TZ at collection host */
} __pmMultiLogCtl;
/*
* Per-context controls for archives and logs
*/
typedef struct {
__pmLogCtl *ac_log; /* Current global logging and archive
control */
long ac_offset; /* fseek ptr for archives */
int ac_vol; /* volume for ac_offset */
int ac_serial; /* serial access pattern for archives */
__pmHashCtl ac_pmid_hc; /* per PMID controls for INTERP */
double ac_end; /* time at end of archive */
void *ac_want; /* used in interp.c */
void *ac_unbound; /* used in interp.c */
void *ac_cache; /* used in interp.c */
int ac_cache_idx; /* used in interp.c */
/*
* These were added to the ABI in order to support multiple archives
* in a single context. In order to maintain ABI compatibility they must
* be at the end of this structure.
*/
int ac_mark_done; /* mark record between archives */
/* has been generated */
int ac_num_logs; /* The number of archives */
int ac_cur_log; /* The currently open archive */
__pmMultiLogCtl **ac_log_list; /* Current set of archives */
} __pmArchCtl;
/*
* PMAPI context. We keep an array of these,
* one for each context created by the application.
*/
typedef struct {
__pmMutex c_lock; /* mutex for multi-thread access */
int c_type; /* HOST, ARCHIVE, LOCAL or INIT or FREE */
int c_mode; /* current mode PM_MODE_* */
__pmPMCDCtl *c_pmcd; /* pmcd control for HOST contexts */
__pmArchCtl *c_archctl; /* log control for ARCHIVE contexts */
__pmTimeval c_origin; /* pmFetch time origin / current time */
int c_delta; /* for updating origin */
int c_sent; /* profile has been sent to pmcd */
__pmProfile *c_instprof; /* instance profile */
void *c_dm; /* derived metrics, if any */
int c_flags; /* ctx flags (set via type/env/attrs) */
__pmHashCtl c_attrs; /* various optional context attributes */
int c_handle; /* context number above PMAPI */
int c_slot; /* index to contexts[] below PMAPI */
} __pmContext;
#define PM_CONTEXT_INIT -2 /* special type: being initialized, do not use */
/* mask for (archive) directional parts of c_mode */
#define __PM_MODE_MASK 0xffff
/* internal archive routines */
PCP_CALL extern int __pmLogOpen(const char *, __pmContext *);
PCP_CALL extern const char *__pmLogName_r(const char *, int, char *, int);
PCP_CALL extern const char *__pmLogName(const char *, int); /* NOT thread-safe */
PCP_CALL extern char *__pmLogBaseName(char *);
PCP_CALL extern int __pmLogChkLabel(__pmLogCtl *, __pmFILE *, __pmLogLabel *, int);
PCP_CALL extern int __pmLogCreate(const char *, const char *, int, __pmLogCtl *);
PCP_CALL extern __pmFILE *__pmLogNewFile(const char *, int);
PCP_CALL extern void __pmLogClose(__pmLogCtl *);
PCP_CALL extern int __pmLogPutDesc(__pmLogCtl *, const pmDesc *, int, char **);
PCP_CALL extern int __pmLogPutInDom(__pmLogCtl *, pmInDom, const __pmTimeval *, int, int *, char **);
PCP_CALL extern int __pmLogPutResult(__pmLogCtl *, __pmPDU *);
PCP_CALL extern int __pmLogPutResult2(__pmLogCtl *, __pmPDU *);
PCP_CALL extern void __pmLogPutIndex(const __pmLogCtl *, const __pmTimeval *);
PCP_CALL extern int __pmLogPutLabel(__pmLogCtl *, unsigned int, unsigned int, int, pmLabelSet *, const __pmTimeval *);
PCP_CALL extern int __pmLogPutText(__pmLogCtl *, unsigned int , unsigned int, char *, int);
PCP_CALL extern int __pmLogWriteLabel(__pmFILE *, const __pmLogLabel *);
PCP_CALL extern int __pmLogGenerateMark(__pmLogCtl *, int, pmResult **);
PCP_CALL extern int __pmLogLoadLabel(__pmLogCtl *, const char *);
PCP_CALL extern int __pmLogLoadIndex(__pmLogCtl *);
PCP_CALL extern int __pmLogLoadMeta(__pmLogCtl *);
#define PMLOGREAD_NEXT 0
#define PMLOGREAD_TO_EOF 1
PCP_CALL extern int __pmLogRead(__pmLogCtl *, int, __pmFILE *, pmResult **, int);
PCP_CALL extern int __pmLogRead_ctx(__pmContext *, int, __pmFILE *, pmResult **, int);
PCP_CALL extern int __pmLogChangeVol(__pmLogCtl *, int);
PCP_CALL extern int __pmLogFetch(__pmContext *, int, pmID *, pmResult **);
PCP_CALL extern int __pmLogFetchInterp(__pmContext *, int, pmID *, pmResult **);
PCP_CALL extern int __pmLogGetInDom(__pmLogCtl *, pmInDom, __pmTimeval *, int **, char ***);
PCP_CALL extern int __pmGetArchiveLabel(__pmLogCtl *, pmLogLabel *);
PCP_CALL extern int __pmGetArchiveEnd(__pmLogCtl *, struct timeval *);
PCP_CALL extern int __pmLogLookupDesc(__pmLogCtl *, pmID, pmDesc *);
#define PMLOGPUTINDOM_DUP 1
PCP_CALL extern int __pmLogLookupInDom(__pmLogCtl *, pmInDom, __pmTimeval *, const char *);
PCP_CALL extern int __pmLogLookupLabel(__pmLogCtl *, unsigned int, unsigned int, pmLabelSet **, const __pmTimeval *);
PCP_CALL extern int __pmLogLookupText(__pmLogCtl *, unsigned int , unsigned int, char **);
PCP_CALL extern int __pmLogNameInDom(__pmLogCtl *, pmInDom, __pmTimeval *, int, char **);
PCP_CALL extern __pmTimeval *__pmLogStartTime(__pmArchCtl *);
PCP_CALL extern void __pmLogSetTime(__pmContext *);
PCP_CALL extern void __pmLogCacheClear(__pmFILE *);
PCP_CALL extern void __pmLogResetInterp(__pmContext *);
PCP_CALL extern void __pmFreeInterpData(__pmContext *);
PCP_CALL extern int __pmLogChangeArchive(__pmContext *, int);
PCP_CALL extern int __pmLogCheckForNextArchive(__pmLogCtl *, int, pmResult **);
PCP_CALL extern int __pmLogChangeToNextArchive(__pmLogCtl **);
PCP_CALL extern int __pmLogChangeToPreviousArchive(__pmLogCtl **);
PCP_CALL extern void __pmArchCtlFree(__pmArchCtl *);
PCP_CALL extern const char *__pmLogLocalSocketDefault(int, char *buf, size_t bufSize);
PCP_CALL extern const char *__pmLogLocalSocketUser(int, char *buf, size_t bufSize);
PCP_DATA extern int __pmLogReads;
/* Convert opaque context handle to __pmContext pointer */
PCP_CALL extern __pmContext *__pmHandleToPtr(int);
/* Like __pmHandleToPtr(pmWhichContext()), but with no locking */
PCP_CALL __pmContext *__pmCurrentContext(void);
/*
* Dump the current context (source details + instance profile),
* for a particular instance domain.
* If indom == PM_INDOM_NULL, then print all instance domains
*/
PCP_CALL extern void __pmDumpContext(FILE *, int, pmInDom);
/* pmFetch helper routines, hooks for derivations and local contexts */
PCP_CALL extern int __pmPrepareFetch(__pmContext *, int, const pmID *, pmID **);
PCP_CALL extern int __pmFinishResult(__pmContext *, int, pmResult **);
PCP_CALL extern int __pmFetchLocal(__pmContext *, int, pmID *, pmResult **);
/* Archive context helper. */
int __pmFindOrOpenArchive(__pmContext *, const char *, int);
/* Generic access control routines */
PCP_CALL extern int __pmAccAddOp(unsigned int);
PCP_CALL extern int __pmAccAddHost(const char *, unsigned int, unsigned int, int);
PCP_CALL extern int __pmAccAddUser(const char *, unsigned int, unsigned int, int);
PCP_CALL extern int __pmAccAddGroup(const char *, unsigned int, unsigned int, int);
PCP_CALL extern int __pmAccAddClient(__pmSockAddr *, unsigned int *);
PCP_CALL extern int __pmAccAddAccount(const char *, const char *, unsigned int *);
PCP_CALL extern void __pmAccDelClient(__pmSockAddr *);
PCP_CALL extern void __pmAccDelAccount(const char *, const char *);
PCP_CALL extern void __pmAccDumpHosts(FILE *);
PCP_CALL extern void __pmAccDumpUsers(FILE *);
PCP_CALL extern void __pmAccDumpGroups(FILE *);
PCP_CALL extern void __pmAccDumpLists(FILE *);
PCP_CALL extern int __pmAccSaveHosts(void);
PCP_CALL extern int __pmAccSaveUsers(void);
PCP_CALL extern int __pmAccSaveGroups(void);
PCP_CALL extern int __pmAccSaveLists(void);
PCP_CALL extern int __pmAccRestoreHosts(void);
PCP_CALL extern int __pmAccRestoreUsers(void);
PCP_CALL extern int __pmAccRestoreGroups(void);
PCP_CALL extern int __pmAccRestoreLists(void);
PCP_CALL extern void __pmAccFreeSavedHosts(void);
PCP_CALL extern void __pmAccFreeSavedUsers(void);
PCP_CALL extern void __pmAccFreeSavedGroups(void);
PCP_CALL extern void __pmAccFreeSavedLists(void);
/* AF - general purpose asynchronous event management routines */
PCP_CALL extern int __pmAFsetup(const struct timeval *, const struct timeval *, void *, void (*)(int, void *));
PCP_CALL extern int __pmAFregister(const struct timeval *, void *, void (*)(int, void *));
PCP_CALL extern int __pmAFunregister(int);
PCP_CALL extern void __pmAFblock(void);
PCP_CALL extern void __pmAFunblock(void);
PCP_CALL extern int __pmAFisempty(void);
/* private PDU protocol between pmlc and pmlogger */
#define LOG_PDU_VERSION2 2 /* private pdus & PCP 2.0 error codes */
#define LOG_PDU_VERSION LOG_PDU_VERSION2
#define LOG_REQUEST_NEWVOLUME 1
#define LOG_REQUEST_STATUS 2
#define LOG_REQUEST_SYNC 3
typedef struct {
__pmTimeval ls_start; /* start time for log */
__pmTimeval ls_last; /* last time log written */
__pmTimeval ls_timenow; /* current time */
int ls_state; /* state of log (from __pmLogCtl) */
int ls_vol; /* current volume number of log */
__int64_t ls_size; /* size of current volume */
char ls_hostname[PM_LOG_MAXHOSTLEN];
/* name of pmcd host */
char ls_fqdn[PM_LOG_MAXHOSTLEN];
/* fully qualified domain name of pmcd host */
char ls_tz[PM_TZ_MAXLEN];
/* $TZ at collection host */
char ls_tzlogger[PM_TZ_MAXLEN];
/* $TZ at pmlogger */
} __pmLoggerStatus;
#define PDU_LOG_CONTROL 0x8000
#define PDU_LOG_STATUS 0x8001
#define PDU_LOG_REQUEST 0x8002
PCP_CALL extern int __pmConnectLogger(const char *, int *, int *);
PCP_CALL extern int __pmSendLogControl(int, const pmResult *, int, int, int);
PCP_CALL extern int __pmDecodeLogControl(const __pmPDU *, pmResult **, int *, int *, int *);
PCP_CALL extern int __pmSendLogRequest(int, int);
PCP_CALL extern int __pmDecodeLogRequest(const __pmPDU *, int *);
PCP_CALL extern int __pmSendLogStatus(int, __pmLoggerStatus *);
PCP_CALL extern int __pmDecodeLogStatus(__pmPDU *, __pmLoggerStatus **);
/* logger timeout helper function */
PCP_CALL extern int __pmLoggerTimeout(void);
/* other interfaces shared by pmlc and pmlogger */
PCP_CALL extern int __pmControlLog(int, const pmResult *, int, int, int, pmResult **);
#define PM_LOG_OFF 0 /* state */
#define PM_LOG_MAYBE 1
#define PM_LOG_ON 2
#define PM_LOG_MANDATORY 11 /* control */
#define PM_LOG_ADVISORY 12
#define PM_LOG_ENQUIRE 13
/* macros for logging control values from __pmControlLog() */
#define PMLC_SET_ON(val, flag) \
(val) = ((val) & ~0x1) | ((flag) & 0x1)
#define PMLC_GET_ON(val) \
((val) & 0x1)
#define PMLC_SET_MAND(val, flag) \
(val) = ((val) & ~0x2) | (((flag) & 0x1) << 1)
#define PMLC_GET_MAND(val) \
(((val) & 0x2) >> 1)
#define PMLC_SET_AVAIL(val, flag) \
(val) = ((val) & ~0x4) | (((flag) & 0x1) << 2)
#define PMLC_GET_AVAIL(val) \
(((val) & 0x4) >> 2)
#define PMLC_SET_INLOG(val, flag) \
(val) = ((val) & ~0x8) | (((flag) & 0x1) << 3)
#define PMLC_GET_INLOG(val) \
(((val) & 0x8) >> 3)
#define PMLC_SET_STATE(val, state) \
(val) = ((val) & ~0xf) | ((state) & 0xf)
#define PMLC_GET_STATE(val) \
((val) & 0xf)
/* 28 bits of delta, 32 bits of state */
#define PMLC_MAX_DELTA 0x0fffffff
#define PMLC_SET_DELTA(val, delta) \
(val) = ((val) & 0xf) | ((delta) << 4)
#define PMLC_GET_DELTA(val) \
((((val) & ~0xf) >> 4) & PMLC_MAX_DELTA)
/* Optimized fetch bundling ("optfetch") services */
typedef struct __optreq {
struct __optreq *r_next; /* next request */
struct __fetchctl *r_fetch; /* back ptr */
pmDesc *r_desc; /* pmDesc for request pmID */
int r_numinst; /* request instances */
int *r_instlist; /* request instances */
void *r_aux; /* generic pointer to aux data */
} optreq_t;
typedef struct __pmidctl {
struct __pmidctl *p_next; /* next pmid control */
optreq_t *p_rqp; /* first request for this metric */
pmID p_pmid; /* my pmID */
int p_numinst; /* union over requests */
int *p_instlist; /* union over requests */
void *p_aux; /* generic pointer to aux data */
} pmidctl_t;
typedef struct __indomctl {
struct __indomctl *i_next; /* next indom control */
pmidctl_t *i_pmp; /* first metric, in this group */
pmInDom i_indom; /* my pmInDom */
int i_numinst; /* arg for pmAddProfile */
int *i_instlist; /* arg for pmAddProfile */
void *i_aux; /* generic pointer to aux data */
} indomctl_t;
typedef struct __fetchctl {
struct __fetchctl *f_next; /* next fetch control */
indomctl_t *f_idp; /* first indom, in this group */
int f_state; /* state changes during updates */
int f_cost; /* used internally for optimization */
int f_newcost; /* used internally for optimization */
int f_numpmid; /* arg for pmFetch() */
pmID *f_pmidlist; /* arg for pmFetch() */
void *f_aux; /* generic pointer to aux data */
} fetchctl_t;
/* states relevant to user */
#define OPT_STATE_NEW 1 /* newly created group */
#define OPT_STATE_PMID 2 /* list of pmids changed */
#define OPT_STATE_PROFILE 4 /* instance profile changed */
/* states used during optimization */
#define OPT_STATE_UMASK 7 /* preserve user state bits */
#define OPT_STATE_XREQ 8 /* things that may have changed */
#define OPT_STATE_XPMID 16
#define OPT_STATE_XINDOM 32
#define OPT_STATE_XFETCH 64
#define OPT_STATE_XPROFILE 128
/* Objective function parameters */
typedef struct {
int c_pmid; /* cost per PMD for PMIDs in a fetch */
int c_indom; /* cost per PMD for indoms in a fetch */
int c_fetch; /* cost of a new fetch group */
int c_indomsize; /* expected numer of instances for an indom */
int c_xtrainst; /* cost of retrieving an unwanted metric inst */
int c_scope; /* cost opt., 0 for incremental, 1 for global */