qa: update 660 to generate index.html, fixing pcp-testsuite runs
[pcp.git] / qa / pmlogconv / libpcp.c
blob44ebc59183c248421326db096bd444a98c2dd049
1 /*
2 * Copyright (c) 1995-2002,2004 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12 * License for more details.
15 #include "pcp/pmapi.h"
16 #include "pcp/impl.h"
18 #define PM_LOG_VERS01 1
21 * Routines in this file are lifted from libpcp to allow obsolete
22 * functionality to be restored to read V1 archives ...
26 * logutil.c
29 int
30 __pmLogChkLabel(__pmLogCtl *lcp, FILE *f, __pmLogLabel *lp, int vol)
32 int len;
33 int version = UNKNOWN_VERSION;
34 int xpectlen = sizeof(__pmLogLabel) + 2 * sizeof(len);
35 int n;
37 if (vol >= 0 && vol < lcp->l_numseen && lcp->l_seen[vol]) {
38 /* FastPath, cached result of previous check for this volume */
39 fseek(f, (long)(sizeof(__pmLogLabel) + 2*sizeof(int)), SEEK_SET);
40 return 0;
43 if (vol >= 0 && vol >= lcp->l_numseen) {
44 lcp->l_seen = (int *)realloc(lcp->l_seen, (vol+1)*(int)sizeof(lcp->l_seen[0]));
45 if (lcp->l_seen == NULL)
46 lcp->l_numseen = 0;
47 else {
48 int i;
49 for (i = lcp->l_numseen; i < vol; i++)
50 lcp->l_seen[i] = 0;
51 lcp->l_numseen = vol+1;
55 #ifdef PCP_DEBUG
56 if (pmDebug & DBG_TRACE_LOG)
57 fprintf(stderr, "__pmLogChkLabel: fd=%d vol=%d", fileno(f), vol);
58 #endif
60 fseek(f, (long)0, SEEK_SET);
61 n = (int)fread(&len, 1, sizeof(len), f);
62 len = ntohl(len);
63 if (n != sizeof(len) || len != xpectlen) {
64 if (feof(f)) {
65 clearerr(f);
66 #ifdef PCP_DEBUG
67 if (pmDebug & DBG_TRACE_LOG)
68 fprintf(stderr, " file is empty\n");
69 #endif
70 return PM_ERR_NODATA;
72 else {
73 #ifdef PCP_DEBUG
74 if (pmDebug & DBG_TRACE_LOG)
75 fprintf(stderr, " header read -> %d (expect %d) or bad header len=%d (expected %d)\n",
76 n, (int)sizeof(len), len, xpectlen);
77 #endif
78 if (ferror(f)) {
79 clearerr(f);
80 return -errno;
82 else
83 return PM_ERR_LABEL;
87 if ((n = (int)fread(lp, 1, sizeof(__pmLogLabel), f)) != sizeof(__pmLogLabel)) {
88 #ifdef PCP_DEBUG
89 if (pmDebug & DBG_TRACE_LOG)
90 fprintf(stderr, " bad label len=%d: expected %d\n",
91 n, (int)sizeof(__pmLogLabel));
92 #endif
93 if (ferror(f)) {
94 clearerr(f);
95 return -errno;
97 else
98 return PM_ERR_LABEL;
100 else {
101 /* swab internal log label */
102 lp->ill_magic = ntohl(lp->ill_magic);
103 lp->ill_pid = ntohl(lp->ill_pid);
104 lp->ill_start.tv_sec = ntohl(lp->ill_start.tv_sec);
105 lp->ill_start.tv_usec = ntohl(lp->ill_start.tv_usec);
106 lp->ill_vol = ntohl(lp->ill_vol);
109 n = (int)fread(&len, 1, sizeof(len), f);
110 len = ntohl(len);
111 if (n != sizeof(len) || len != xpectlen) {
112 #ifdef PCP_DEBUG
113 if (pmDebug & DBG_TRACE_LOG)
114 fprintf(stderr, " trailer read -> %d (expect %d) or bad trailer len=%d (expected %d)\n",
115 n, (int)sizeof(len), len, xpectlen);
116 #endif
117 if (ferror(f)) {
118 clearerr(f);
119 return -errno;
121 else
122 return PM_ERR_LABEL;
125 version = lp->ill_magic & 0xff;
126 if ((lp->ill_magic & 0xffffff00) != PM_LOG_MAGIC ||
127 (version != PM_LOG_VERS01 && version != PM_LOG_VERS02) ||
128 lp->ill_vol != vol) {
129 #ifdef PCP_DEBUG
130 if (pmDebug & DBG_TRACE_LOG)
131 fprintf(stderr, " version %d not supported\n", version);
132 #endif
133 return PM_ERR_LABEL;
135 else {
136 if (__pmSetVersionIPC(fileno(f), version) < 0)
137 return -errno;
138 #ifdef PCP_DEBUG
139 if (pmDebug & DBG_TRACE_LOG)
140 fprintf(stderr, " [magic=%8x version=%d vol=%d pid=%d host=%s]\n",
141 lp->ill_magic, version, lp->ill_vol, (int)lp->ill_pid, lp->ill_hostname);
142 #endif
145 if (vol >= 0 && vol < lcp->l_numseen)
146 lcp->l_seen[vol] = 1;
148 return version;
152 * logmeta.c
155 static char *
156 StrTimeval(__pmTimeval *tp)
158 if (tp == NULL) {
159 static char *null_timeval = "<null timeval>";
160 return null_timeval;
162 else {
163 static char sbuf[13];
164 static struct tm *tmp;
165 time_t t = tp->tv_sec;
166 tmp = localtime(&t);
167 sprintf(sbuf, "%02d:%02d:%02d.%03d", /* safe */
168 tmp->tm_hour, tmp->tm_min, tmp->tm_sec, tp->tv_usec/1000);
169 return sbuf;
173 static int
174 addindom(__pmLogCtl *lcp, pmInDom indom, const __pmTimeval *tp, int numinst,
175 int *instlist, char **namelist, int *indom_buf, int allinbuf)
177 __pmLogInDom *idp;
178 __pmHashNode *hp;
179 int sts;
181 if ((idp = (__pmLogInDom *)malloc(sizeof(__pmLogInDom))) == NULL)
182 return -errno;
183 idp->stamp = *tp; /* struct assignment */
184 idp->numinst = numinst;
185 idp->instlist = instlist;
186 idp->namelist = namelist;
187 idp->buf = indom_buf;
188 idp->allinbuf = allinbuf;
190 #ifdef PCP_DEBUG
191 if (pmDebug & DBG_TRACE_LOGMETA)
192 fprintf(stderr, "addindom( ..., %s, %s, numinst=%d)\n",
193 pmInDomStr(indom), StrTimeval((__pmTimeval *)tp), numinst);
194 #endif
197 if ((hp = __pmHashSearch((unsigned int)indom, &lcp->l_hashindom)) == NULL) {
198 idp->next = NULL;
199 sts = __pmHashAdd((unsigned int)indom, (void *)idp, &lcp->l_hashindom);
201 else {
202 idp->next = (__pmLogInDom *)hp->data;
203 hp->data = (void *)idp;
204 sts = 0;
206 return sts;
210 * load _all_ of the hashed pmDesc and __pmLogInDom structures from the metadata
211 * log file -- used at the initialization (NewContext) of an archive
212 * If version 2 then
213 * load all the names from the meta data and create l_pmns.
216 __pmLogLoadMeta(__pmLogCtl *lcp)
218 int rlen;
219 int check;
220 pmDesc *dp;
221 int sts = 0;
222 __pmLogHdr h;
223 FILE *f = lcp->l_mdfp;
224 int version2 = ((lcp->l_label.ill_magic & 0xff) == PM_LOG_VERS02);
225 int numpmid = 0;
226 int n;
228 if (version2) {
229 if ((sts = __pmNewPMNS(&(lcp->l_pmns))) < 0) {
230 goto end;
234 fseek(f, (long)(sizeof(__pmLogLabel) + 2*sizeof(int)), SEEK_SET);
235 for ( ; ; ) {
236 n = (int)fread(&h, 1, sizeof(__pmLogHdr), f);
238 /* swab hdr */
239 h.len = ntohl(h.len);
240 h.type = ntohl(h.type);
242 if (n != sizeof(__pmLogHdr) || h.len <= 0) {
243 if (feof(f)) {
244 clearerr(f);
245 sts = 0;
246 goto end;
248 #ifdef PCP_DEBUG
249 if (pmDebug & DBG_TRACE_LOGMETA) {
250 fprintf(stderr, "__pmLogLoadMeta: header read -> %d: expected: %d\n",
251 n, (int)sizeof(__pmLogHdr));
253 #endif
254 if (ferror(f)) {
255 clearerr(f);
256 sts = -errno;
258 else
259 sts = PM_ERR_LOGREC;
260 goto end;
262 #ifdef PCP_DEBUG
263 if (pmDebug & DBG_TRACE_LOGMETA) {
264 fprintf(stderr, "__pmLogLoadMeta: record len=%d, type=%d @ offset=%d\n",
265 h.len, h.type, (int)(ftell(f) - sizeof(__pmLogHdr)));
267 #endif
268 rlen = h.len - (int)sizeof(__pmLogHdr) - (int)sizeof(int);
269 if (h.type == TYPE_DESC) {
270 numpmid++;
271 if ((dp = (pmDesc *)malloc(sizeof(pmDesc))) == NULL) {
272 sts = -errno;
273 goto end;
275 if ((n = (int)fread(dp, 1, sizeof(pmDesc), f)) != sizeof(pmDesc)) {
276 #ifdef PCP_DEBUG
277 if (pmDebug & DBG_TRACE_LOGMETA) {
278 fprintf(stderr, "__pmLogLoadMeta: pmDesc read -> %d: expected: %d\n",
279 n, (int)sizeof(pmDesc));
281 #endif
282 if (ferror(f)) {
283 clearerr(f);
284 sts = -errno;
286 else
287 sts = PM_ERR_LOGREC;
288 goto end;
290 else {
291 /* swab desc */
292 dp->type = ntohl(dp->type);
293 dp->sem = ntohl(dp->sem);
294 dp->indom = __ntohpmInDom(dp->indom);
295 dp->units = __ntohpmUnits(dp->units);
296 dp->pmid = __ntohpmID(dp->pmid);
299 if ((sts = __pmHashAdd((int)dp->pmid, (void *)dp, &lcp->l_hashpmid)) < 0)
300 goto end;
302 if (version2) {
303 char name[MAXPATHLEN];
304 int numnames;
305 int i;
306 int len;
308 /* read in the names & store in PMNS tree ... */
309 if ((n = (int)fread(&numnames, 1, sizeof(numnames), f)) !=
310 sizeof(numnames)) {
311 #ifdef PCP_DEBUG
312 if (pmDebug & DBG_TRACE_LOGMETA) {
313 fprintf(stderr, "__pmLogLoadMeta: numnames read -> %d: expected: %d\n",
314 n, (int)sizeof(numnames));
316 #endif
317 if (ferror(f)) {
318 clearerr(f);
319 sts = -errno;
321 else
322 sts = PM_ERR_LOGREC;
323 goto end;
325 else {
326 /* swab numnames */
327 numnames = ntohl(numnames);
330 for (i = 0; i < numnames; i++) {
331 if ((n = (int)fread(&len, 1, sizeof(len), f)) !=
332 sizeof(len)) {
333 #ifdef PCP_DEBUG
334 if (pmDebug & DBG_TRACE_LOGMETA) {
335 fprintf(stderr, "__pmLogLoadMeta: len name[%d] read -> %d: expected: %d\n",
336 i, n, (int)sizeof(len));
338 #endif
339 if (ferror(f)) {
340 clearerr(f);
341 sts = -errno;
343 else
344 sts = PM_ERR_LOGREC;
345 goto end;
347 else {
348 /* swab len */
349 len = ntohl(len);
352 if ((n = (int)fread(name, 1, len, f)) != len) {
353 #ifdef PCP_DEBUG
354 if (pmDebug & DBG_TRACE_LOGMETA) {
355 fprintf(stderr, "__pmLogLoadMeta: name[%d] read -> %d: expected: %d\n",
356 i, n, len);
358 #endif
359 if (ferror(f)) {
360 clearerr(f);
361 sts = -errno;
363 else
364 sts = PM_ERR_LOGREC;
365 goto end;
367 name[len] = '\0';
368 #ifdef PCP_DEBUG
369 if (pmDebug & DBG_TRACE_LOGMETA) {
370 fprintf(stderr, "__pmLogLoadMeta: PMID: %s name: %s\n",
371 pmIDStr(dp->pmid), name);
373 #endif
375 if ((sts = __pmAddPMNSNode(lcp->l_pmns, dp->pmid, name)) < 0) {
377 * If we see a duplicate PMID, its a recoverable error.
378 * We wont be able to see all of the data in the log, but
379 * its better to provide access to some rather than none,
380 * esp. when only one or two metric IDs may be corrupted
381 * in this way (which we may not be interested in anyway).
383 if (sts != PM_ERR_PMID)
384 goto end;
385 sts = 0;
387 }/*for*/
388 }/*version2*/
390 else if (h.type == TYPE_INDOM) {
391 int *tbuf;
392 pmInDom indom;
393 __pmTimeval *when;
394 int numinst;
395 int *instlist;
396 char **namelist;
397 char *namebase;
398 int *stridx;
399 int i;
400 int k;
401 int allinbuf;
403 if ((tbuf = (int *)malloc(rlen)) == NULL) {
404 sts = -errno;
405 goto end;
407 if ((n = (int)fread(tbuf, 1, rlen, f)) != rlen) {
408 #ifdef PCP_DEBUG
409 if (pmDebug & DBG_TRACE_LOGMETA) {
410 fprintf(stderr, "__pmLogLoadMeta: indom read -> %d: expected: %d\n",
411 n, rlen);
413 #endif
414 if (ferror(f)) {
415 clearerr(f);
416 sts = -errno;
418 else
419 sts = PM_ERR_LOGREC;
420 goto end;
423 k = 0;
424 when = (__pmTimeval *)&tbuf[k];
425 when->tv_sec = ntohl(when->tv_sec);
426 when->tv_usec = ntohl(when->tv_usec);
427 k += sizeof(*when)/sizeof(int);
428 indom = __ntohpmInDom((unsigned int)tbuf[k++]);
429 numinst = ntohl(tbuf[k++]);
430 if (numinst > 0) {
431 instlist = &tbuf[k];
432 k += numinst;
433 stridx = &tbuf[k];
434 #if defined(HAVE_32BIT_PTR)
435 namelist = (char **)stridx;
436 allinbuf = 1; /* allocation is all in tbuf */
437 #else
438 allinbuf = 0; /* allocation for namelist + tbuf */
439 /* need to allocate to hold the pointers */
440 namelist = (char **)malloc(numinst*sizeof(char*));
441 if (namelist == NULL) {
442 sts = -errno;
443 goto end;
445 #endif
446 k += numinst;
447 namebase = (char *)&tbuf[k];
448 for (i = 0; i < numinst; i++) {
449 instlist[i] = ntohl(instlist[i]);
450 namelist[i] = &namebase[ntohl(stridx[i])];
453 else {
454 /* no instances, or an error */
455 instlist = NULL;
456 namelist = NULL;
458 if ((sts = addindom(lcp, indom, when, numinst, instlist, namelist, tbuf, allinbuf)) < 0)
459 goto end;
461 else
462 fseek(f, (long)rlen, SEEK_CUR);
463 n = (int)fread(&check, 1, sizeof(check), f);
464 check = ntohl(check);
465 if (n != sizeof(check) || h.len != check) {
466 #ifdef PCP_DEBUG
467 if (pmDebug & DBG_TRACE_LOGMETA) {
468 fprintf(stderr, "__pmLogLoadMeta: trailer read -> %d or len=%d: expected %d @ offset=%d\n",
469 n, check, h.len, (int)(ftell(f) - sizeof(check)));
471 #endif
472 if (ferror(f)) {
473 clearerr(f);
474 sts = -errno;
476 else
477 sts = PM_ERR_LOGREC;
478 goto end;
480 }/*for*/
481 end:
483 fseek(f, (long)(sizeof(__pmLogLabel) + 2*sizeof(int)), SEEK_SET);
485 if (version2 && sts == 0) {
486 __pmFixPMNSHashTab(lcp->l_pmns, numpmid, 1);
488 return sts;