Merge branch 'master' of git://git.pcp.io/pcp into qt
[pcp.git] / qa / pmlogconv / logio.c
blob655d21b2ec9e4dfc46617f939d945ea200431069
1 /*
2 * utils for pmlogconv
4 * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* pinched from pmlogextract and libpcp */
23 #include "pcp/pmapi.h"
24 #include "pcp/impl.h"
27 * raw read of next log record - largely stolen from __pmLogRead in libpcp
29 int
30 _pmLogGet(__pmLogCtl *lcp, int vol, __pmPDU **pb)
32 int head;
33 int tail;
34 int sts;
35 long offset;
36 char *p;
37 __pmPDU *lpb;
38 FILE *f;
40 if (vol == PM_LOG_VOL_META)
41 f = lcp->l_mdfp;
42 else
43 f = lcp->l_mfp;
45 offset = ftell(f);
46 #ifdef PCP_DEBUG
47 if (pmDebug & DBG_TRACE_LOG) {
48 fprintf(stderr, "_pmLogGet: fd=%d vol=%d posn=%ld ",
49 fileno(f), vol, offset);
51 #endif
53 again:
54 sts = (int)fread(&head, 1, sizeof(head), f);
55 if (sts != sizeof(head)) {
56 if (sts == 0) {
57 #ifdef PCP_DEBUG
58 if (pmDebug & DBG_TRACE_LOG)
59 fprintf(stderr, "AFTER end\n");
60 #endif
61 fseek(f, offset, SEEK_SET);
62 if (vol != PM_LOG_VOL_META) {
63 if (lcp->l_curvol < lcp->l_maxvol) {
64 if (__pmLogChangeVol(lcp, lcp->l_curvol+1) == 0) {
65 f = lcp->l_mfp;
66 goto again;
70 return PM_ERR_EOL;
72 #ifdef PCP_DEBUG
73 if (pmDebug & DBG_TRACE_LOG)
74 fprintf(stderr, "Error: hdr fread=%d %s\n", sts, strerror(errno));
75 #endif
76 if (sts > 0)
77 return PM_ERR_LOGREC;
78 else
79 return -errno;
82 if ((lpb = (__pmPDU *)malloc(ntohl(head))) == NULL) {
83 #ifdef PCP_DEBUG
84 if (pmDebug & DBG_TRACE_LOG)
85 fprintf(stderr, "Error: __pmFindPDUBuf(%d) %s\n",
86 (int)ntohl(head), strerror(errno));
87 #endif
88 fseek(f, offset, SEEK_SET);
89 return -errno;
92 lpb[0] = head;
93 if ((sts = (int)fread(&lpb[1], 1, ntohl(head) - sizeof(head), f)) != ntohl(head) - sizeof(head)) {
94 #ifdef PCP_DEBUG
95 if (pmDebug & DBG_TRACE_LOG)
96 fprintf(stderr, "Error: data fread=%d %s\n", sts, strerror(errno));
97 #endif
98 if (sts == 0) {
99 fseek(f, offset, SEEK_SET);
100 return PM_ERR_EOL;
102 else if (sts > 0)
103 return PM_ERR_LOGREC;
104 else
105 return -errno;
109 p = (char *)lpb;
110 memcpy(&tail, &p[ntohl(head) - sizeof(head)], sizeof(head));
111 if (head != tail) {
112 #ifdef PCP_DEBUG
113 if (pmDebug & DBG_TRACE_LOG)
114 fprintf(stderr, "Error: head-tail mismatch (%d-%d)\n",
115 (int)ntohl(head), (int)ntohl(tail));
116 #endif
117 return PM_ERR_LOGREC;
120 #ifdef PCP_DEBUG
121 if (pmDebug & DBG_TRACE_LOG) {
122 if (vol != PM_LOG_VOL_META || ntohl(lpb[1]) == TYPE_INDOM) {
123 fprintf(stderr, "@");
124 if (sts >= 0) {
125 struct timeval stamp;
126 __pmTimeval *tvp = (__pmTimeval *)&lpb[vol == PM_LOG_VOL_META ? 2 : 1];
127 stamp.tv_sec = ntohl(tvp->tv_sec);
128 stamp.tv_usec = ntohl(tvp->tv_usec);
129 __pmPrintStamp(stderr, &stamp);
131 else
132 fprintf(stderr, "unknown time");
134 fprintf(stderr, " len=%d (incl head+tail)\n", (int)ntohl(head));
136 #endif
138 #ifdef PCP_DEBUG
139 if (pmDebug & DBG_TRACE_PDU) {
140 int i, j;
141 struct timeval stamp;
142 __pmTimeval *tvp = (__pmTimeval *)&lpb[vol == PM_LOG_VOL_META ? 2 : 1];
143 fprintf(stderr, "_pmLogGet");
144 if (vol != PM_LOG_VOL_META || ntohl(lpb[1]) == TYPE_INDOM) {
145 fprintf(stderr, " timestamp=");
146 stamp.tv_sec = ntohl(tvp->tv_sec);
147 stamp.tv_usec = ntohl(tvp->tv_usec);
148 __pmPrintStamp(stderr, &stamp);
150 fprintf(stderr, " " PRINTF_P_PFX "%p ... " PRINTF_P_PFX "%p", lpb, &lpb[ntohl(head)/sizeof(__pmPDU) - 1]);
151 fputc('\n', stderr);
152 fprintf(stderr, "%03d: ", 0);
153 for (j = 0, i = 0; j < ntohl(head)/sizeof(__pmPDU); j++) {
154 if (i == 8) {
155 fprintf(stderr, "\n%03d: ", j);
156 i = 0;
158 fprintf(stderr, "0x%x ", lpb[j]);
159 i++;
161 fputc('\n', stderr);
163 #endif
165 *pb = lpb;
166 return 0;
170 _pmLogPut(FILE *f, __pmPDU *pb)
172 int rlen = ntohl(pb[0]);
173 int sts;
175 #ifdef PCP_DEBUG
176 if (pmDebug & DBG_TRACE_LOG) {
177 fprintf(stderr, "_pmLogPut: fd=%d rlen=%d\n",
178 fileno(f), rlen);
180 #endif
182 if ((sts = (int)fwrite(pb, 1, rlen, f)) != rlen) {
183 #ifdef PCP_DEBUG
184 if (pmDebug & DBG_TRACE_LOG)
185 fprintf(stderr, "_pmLogPut: fwrite=%d %s\n", sts, strerror(errno));
186 #endif
187 return -errno;
189 return 0;
193 * like __pmDecodeDesc but pmDesc in metadata not PDU
195 typedef struct {
196 __pmLogHdr hdr;
197 pmDesc desc;
198 } desc_t;
200 void
201 _pmUnpackDesc(__pmPDU *pdubuf, pmDesc *desc)
203 desc_t *pp;
205 pp = (desc_t *)pdubuf;
206 desc->type = ntohl(pp->desc.type);
207 desc->sem = ntohl(pp->desc.sem);
208 desc->indom = __ntohpmInDom(pp->desc.indom);
209 desc->units = __ntohpmUnits(pp->desc.units);
210 desc->pmid = __ntohpmID(pp->desc.pmid);
211 return;
215 * like rewrite_pdu() from pmlogger
218 typedef struct {
219 pmID pmid;
220 int numval; /* no. of vlist els to follow, or error */
221 int valfmt; /* insitu or pointer */
222 __pmValue_PDU vlist[1]; /* zero or more */
223 } vlist_t;
225 typedef struct {
226 int hdr;
227 // __pmPDUHdr hdr;
228 __pmTimeval timestamp; /* when returned */
229 int numpmid; /* no. of PMIDs to follow */
230 __pmPDU data[1]; /* zero or more */
231 } result_t;
233 #define PM_ERR_BASE1 1000
234 #define XLATE_ERR_1TO2(e) \
235 ((e) <= -PM_ERR_BASE1 ? (e)+PM_ERR_BASE1-PM_ERR_BASE2 : (e))
237 void
238 rewrite_pdu(__pmPDU *pb)
240 result_t *pp = (result_t *)pb;
241 int vsize;
242 int numpmid;
243 int numval;
244 vlist_t *vlp;
245 int i;
247 numpmid = ntohl(pp->numpmid);
248 vsize = 0;
249 for (i = 0; i < numpmid; i++) {
250 vlp = (vlist_t *)&pp->data[vsize/sizeof(__pmPDU)];
251 numval = ntohl(vlp->numval);
252 vsize += sizeof(vlp->pmid) + sizeof(vlp->numval);
253 if (numval > 0)
254 vsize += sizeof(vlp->valfmt) + numval * sizeof(__pmValue_PDU);
255 if (numval < 0)
256 vlp->numval = htonl(XLATE_ERR_1TO2(numval));
259 return;