2 * Copyright (c) 1995-2002,2004 Silicon Graphics, Inc. All Rights Reserved.
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.
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"
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 ...
30 __pmLogChkLabel(__pmLogCtl
*lcp
, FILE *f
, __pmLogLabel
*lp
, int vol
)
33 int version
= UNKNOWN_VERSION
;
34 int xpectlen
= sizeof(__pmLogLabel
) + 2 * sizeof(len
);
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
);
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
)
49 for (i
= lcp
->l_numseen
; i
< vol
; i
++)
51 lcp
->l_numseen
= vol
+1;
56 if (pmDebug
& DBG_TRACE_LOG
)
57 fprintf(stderr
, "__pmLogChkLabel: fd=%d vol=%d", fileno(f
), vol
);
60 fseek(f
, (long)0, SEEK_SET
);
61 n
= (int)fread(&len
, 1, sizeof(len
), f
);
63 if (n
!= sizeof(len
) || len
!= xpectlen
) {
67 if (pmDebug
& DBG_TRACE_LOG
)
68 fprintf(stderr
, " file is empty\n");
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
);
87 if ((n
= (int)fread(lp
, 1, sizeof(__pmLogLabel
), f
)) != sizeof(__pmLogLabel
)) {
89 if (pmDebug
& DBG_TRACE_LOG
)
90 fprintf(stderr
, " bad label len=%d: expected %d\n",
91 n
, (int)sizeof(__pmLogLabel
));
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
);
111 if (n
!= sizeof(len
) || len
!= xpectlen
) {
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
);
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
) {
130 if (pmDebug
& DBG_TRACE_LOG
)
131 fprintf(stderr
, " version %d not supported\n", version
);
136 if (__pmSetVersionIPC(fileno(f
), version
) < 0)
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
);
145 if (vol
>= 0 && vol
< lcp
->l_numseen
)
146 lcp
->l_seen
[vol
] = 1;
156 StrTimeval(__pmTimeval
*tp
)
159 static char *null_timeval
= "<null timeval>";
163 static char sbuf
[13];
164 static struct tm
*tmp
;
165 time_t t
= tp
->tv_sec
;
167 sprintf(sbuf
, "%02d:%02d:%02d.%03d", /* safe */
168 tmp
->tm_hour
, tmp
->tm_min
, tmp
->tm_sec
, tp
->tv_usec
/1000);
174 addindom(__pmLogCtl
*lcp
, pmInDom indom
, const __pmTimeval
*tp
, int numinst
,
175 int *instlist
, char **namelist
, int *indom_buf
, int allinbuf
)
181 if ((idp
= (__pmLogInDom
*)malloc(sizeof(__pmLogInDom
))) == NULL
)
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
;
191 if (pmDebug
& DBG_TRACE_LOGMETA
)
192 fprintf(stderr
, "addindom( ..., %s, %s, numinst=%d)\n",
193 pmInDomStr(indom
), StrTimeval((__pmTimeval
*)tp
), numinst
);
197 if ((hp
= __pmHashSearch((unsigned int)indom
, &lcp
->l_hashindom
)) == NULL
) {
199 sts
= __pmHashAdd((unsigned int)indom
, (void *)idp
, &lcp
->l_hashindom
);
202 idp
->next
= (__pmLogInDom
*)hp
->data
;
203 hp
->data
= (void *)idp
;
210 * load _all_ of the hashed pmDesc and __pmLogInDom structures from the metadata
211 * log file -- used at the initialization (NewContext) of an archive
213 * load all the names from the meta data and create l_pmns.
216 __pmLogLoadMeta(__pmLogCtl
*lcp
)
223 FILE *f
= lcp
->l_mdfp
;
224 int version2
= ((lcp
->l_label
.ill_magic
& 0xff) == PM_LOG_VERS02
);
229 if ((sts
= __pmNewPMNS(&(lcp
->l_pmns
))) < 0) {
234 fseek(f
, (long)(sizeof(__pmLogLabel
) + 2*sizeof(int)), SEEK_SET
);
236 n
= (int)fread(&h
, 1, sizeof(__pmLogHdr
), f
);
239 h
.len
= ntohl(h
.len
);
240 h
.type
= ntohl(h
.type
);
242 if (n
!= sizeof(__pmLogHdr
) || h
.len
<= 0) {
249 if (pmDebug
& DBG_TRACE_LOGMETA
) {
250 fprintf(stderr
, "__pmLogLoadMeta: header read -> %d: expected: %d\n",
251 n
, (int)sizeof(__pmLogHdr
));
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
)));
268 rlen
= h
.len
- (int)sizeof(__pmLogHdr
) - (int)sizeof(int);
269 if (h
.type
== TYPE_DESC
) {
271 if ((dp
= (pmDesc
*)malloc(sizeof(pmDesc
))) == NULL
) {
275 if ((n
= (int)fread(dp
, 1, sizeof(pmDesc
), f
)) != sizeof(pmDesc
)) {
277 if (pmDebug
& DBG_TRACE_LOGMETA
) {
278 fprintf(stderr
, "__pmLogLoadMeta: pmDesc read -> %d: expected: %d\n",
279 n
, (int)sizeof(pmDesc
));
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)
303 char name
[MAXPATHLEN
];
308 /* read in the names & store in PMNS tree ... */
309 if ((n
= (int)fread(&numnames
, 1, sizeof(numnames
), f
)) !=
312 if (pmDebug
& DBG_TRACE_LOGMETA
) {
313 fprintf(stderr
, "__pmLogLoadMeta: numnames read -> %d: expected: %d\n",
314 n
, (int)sizeof(numnames
));
327 numnames
= ntohl(numnames
);
330 for (i
= 0; i
< numnames
; i
++) {
331 if ((n
= (int)fread(&len
, 1, sizeof(len
), f
)) !=
334 if (pmDebug
& DBG_TRACE_LOGMETA
) {
335 fprintf(stderr
, "__pmLogLoadMeta: len name[%d] read -> %d: expected: %d\n",
336 i
, n
, (int)sizeof(len
));
352 if ((n
= (int)fread(name
, 1, len
, f
)) != len
) {
354 if (pmDebug
& DBG_TRACE_LOGMETA
) {
355 fprintf(stderr
, "__pmLogLoadMeta: name[%d] read -> %d: expected: %d\n",
369 if (pmDebug
& DBG_TRACE_LOGMETA
) {
370 fprintf(stderr
, "__pmLogLoadMeta: PMID: %s name: %s\n",
371 pmIDStr(dp
->pmid
), name
);
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
)
390 else if (h
.type
== TYPE_INDOM
) {
403 if ((tbuf
= (int *)malloc(rlen
)) == NULL
) {
407 if ((n
= (int)fread(tbuf
, 1, rlen
, f
)) != rlen
) {
409 if (pmDebug
& DBG_TRACE_LOGMETA
) {
410 fprintf(stderr
, "__pmLogLoadMeta: indom read -> %d: expected: %d\n",
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
++]);
434 #if defined(HAVE_32BIT_PTR)
435 namelist
= (char **)stridx
;
436 allinbuf
= 1; /* allocation is all in tbuf */
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
) {
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
])];
454 /* no instances, or an error */
458 if ((sts
= addindom(lcp
, indom
, when
, numinst
, instlist
, namelist
, tbuf
, allinbuf
)) < 0)
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
) {
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
)));
483 fseek(f
, (long)(sizeof(__pmLogLabel
) + 2*sizeof(int)), SEEK_SET
);
485 if (version2
&& sts
== 0) {
486 __pmFixPMNSHashTab(lcp
->l_pmns
, numpmid
, 1);