summaryrefslogtreecommitdiff
path: root/qa/pmlogconv/libpcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'qa/pmlogconv/libpcp.c')
-rw-r--r--qa/pmlogconv/libpcp.c489
1 files changed, 489 insertions, 0 deletions
diff --git a/qa/pmlogconv/libpcp.c b/qa/pmlogconv/libpcp.c
new file mode 100644
index 0000000..44ebc59
--- /dev/null
+++ b/qa/pmlogconv/libpcp.c
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 1995-2002,2004 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.
+ */
+
+#include "pcp/pmapi.h"
+#include "pcp/impl.h"
+
+#define PM_LOG_VERS01 1
+
+/*
+ * Routines in this file are lifted from libpcp to allow obsolete
+ * functionality to be restored to read V1 archives ...
+ */
+
+/*
+ * logutil.c
+ */
+
+int
+__pmLogChkLabel(__pmLogCtl *lcp, FILE *f, __pmLogLabel *lp, int vol)
+{
+ int len;
+ int version = UNKNOWN_VERSION;
+ int xpectlen = sizeof(__pmLogLabel) + 2 * sizeof(len);
+ int n;
+
+ if (vol >= 0 && vol < lcp->l_numseen && lcp->l_seen[vol]) {
+ /* FastPath, cached result of previous check for this volume */
+ fseek(f, (long)(sizeof(__pmLogLabel) + 2*sizeof(int)), SEEK_SET);
+ return 0;
+ }
+
+ if (vol >= 0 && vol >= lcp->l_numseen) {
+ lcp->l_seen = (int *)realloc(lcp->l_seen, (vol+1)*(int)sizeof(lcp->l_seen[0]));
+ if (lcp->l_seen == NULL)
+ lcp->l_numseen = 0;
+ else {
+ int i;
+ for (i = lcp->l_numseen; i < vol; i++)
+ lcp->l_seen[i] = 0;
+ lcp->l_numseen = vol+1;
+ }
+ }
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, "__pmLogChkLabel: fd=%d vol=%d", fileno(f), vol);
+#endif
+
+ fseek(f, (long)0, SEEK_SET);
+ n = (int)fread(&len, 1, sizeof(len), f);
+ len = ntohl(len);
+ if (n != sizeof(len) || len != xpectlen) {
+ if (feof(f)) {
+ clearerr(f);
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, " file is empty\n");
+#endif
+ return PM_ERR_NODATA;
+ }
+ else {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, " header read -> %d (expect %d) or bad header len=%d (expected %d)\n",
+ n, (int)sizeof(len), len, xpectlen);
+#endif
+ if (ferror(f)) {
+ clearerr(f);
+ return -errno;
+ }
+ else
+ return PM_ERR_LABEL;
+ }
+ }
+
+ if ((n = (int)fread(lp, 1, sizeof(__pmLogLabel), f)) != sizeof(__pmLogLabel)) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, " bad label len=%d: expected %d\n",
+ n, (int)sizeof(__pmLogLabel));
+#endif
+ if (ferror(f)) {
+ clearerr(f);
+ return -errno;
+ }
+ else
+ return PM_ERR_LABEL;
+ }
+ else {
+ /* swab internal log label */
+ lp->ill_magic = ntohl(lp->ill_magic);
+ lp->ill_pid = ntohl(lp->ill_pid);
+ lp->ill_start.tv_sec = ntohl(lp->ill_start.tv_sec);
+ lp->ill_start.tv_usec = ntohl(lp->ill_start.tv_usec);
+ lp->ill_vol = ntohl(lp->ill_vol);
+ }
+
+ n = (int)fread(&len, 1, sizeof(len), f);
+ len = ntohl(len);
+ if (n != sizeof(len) || len != xpectlen) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, " trailer read -> %d (expect %d) or bad trailer len=%d (expected %d)\n",
+ n, (int)sizeof(len), len, xpectlen);
+#endif
+ if (ferror(f)) {
+ clearerr(f);
+ return -errno;
+ }
+ else
+ return PM_ERR_LABEL;
+ }
+
+ version = lp->ill_magic & 0xff;
+ if ((lp->ill_magic & 0xffffff00) != PM_LOG_MAGIC ||
+ (version != PM_LOG_VERS01 && version != PM_LOG_VERS02) ||
+ lp->ill_vol != vol) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, " version %d not supported\n", version);
+#endif
+ return PM_ERR_LABEL;
+ }
+ else {
+ if (__pmSetVersionIPC(fileno(f), version) < 0)
+ return -errno;
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, " [magic=%8x version=%d vol=%d pid=%d host=%s]\n",
+ lp->ill_magic, version, lp->ill_vol, (int)lp->ill_pid, lp->ill_hostname);
+#endif
+ }
+
+ if (vol >= 0 && vol < lcp->l_numseen)
+ lcp->l_seen[vol] = 1;
+
+ return version;
+}
+
+/*
+ * logmeta.c
+ */
+
+static char *
+StrTimeval(__pmTimeval *tp)
+{
+ if (tp == NULL) {
+ static char *null_timeval = "<null timeval>";
+ return null_timeval;
+ }
+ else {
+ static char sbuf[13];
+ static struct tm *tmp;
+ time_t t = tp->tv_sec;
+ tmp = localtime(&t);
+ sprintf(sbuf, "%02d:%02d:%02d.%03d", /* safe */
+ tmp->tm_hour, tmp->tm_min, tmp->tm_sec, tp->tv_usec/1000);
+ return sbuf;
+ }
+}
+
+static int
+addindom(__pmLogCtl *lcp, pmInDom indom, const __pmTimeval *tp, int numinst,
+ int *instlist, char **namelist, int *indom_buf, int allinbuf)
+{
+ __pmLogInDom *idp;
+ __pmHashNode *hp;
+ int sts;
+
+ if ((idp = (__pmLogInDom *)malloc(sizeof(__pmLogInDom))) == NULL)
+ return -errno;
+ idp->stamp = *tp; /* struct assignment */
+ idp->numinst = numinst;
+ idp->instlist = instlist;
+ idp->namelist = namelist;
+ idp->buf = indom_buf;
+ idp->allinbuf = allinbuf;
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOGMETA)
+ fprintf(stderr, "addindom( ..., %s, %s, numinst=%d)\n",
+ pmInDomStr(indom), StrTimeval((__pmTimeval *)tp), numinst);
+#endif
+
+
+ if ((hp = __pmHashSearch((unsigned int)indom, &lcp->l_hashindom)) == NULL) {
+ idp->next = NULL;
+ sts = __pmHashAdd((unsigned int)indom, (void *)idp, &lcp->l_hashindom);
+ }
+ else {
+ idp->next = (__pmLogInDom *)hp->data;
+ hp->data = (void *)idp;
+ sts = 0;
+ }
+ return sts;
+}
+
+/*
+ * load _all_ of the hashed pmDesc and __pmLogInDom structures from the metadata
+ * log file -- used at the initialization (NewContext) of an archive
+ * If version 2 then
+ * load all the names from the meta data and create l_pmns.
+ */
+int
+__pmLogLoadMeta(__pmLogCtl *lcp)
+{
+ int rlen;
+ int check;
+ pmDesc *dp;
+ int sts = 0;
+ __pmLogHdr h;
+ FILE *f = lcp->l_mdfp;
+ int version2 = ((lcp->l_label.ill_magic & 0xff) == PM_LOG_VERS02);
+ int numpmid = 0;
+ int n;
+
+ if (version2) {
+ if ((sts = __pmNewPMNS(&(lcp->l_pmns))) < 0) {
+ goto end;
+ }
+ }
+
+ fseek(f, (long)(sizeof(__pmLogLabel) + 2*sizeof(int)), SEEK_SET);
+ for ( ; ; ) {
+ n = (int)fread(&h, 1, sizeof(__pmLogHdr), f);
+
+ /* swab hdr */
+ h.len = ntohl(h.len);
+ h.type = ntohl(h.type);
+
+ if (n != sizeof(__pmLogHdr) || h.len <= 0) {
+ if (feof(f)) {
+ clearerr(f);
+ sts = 0;
+ goto end;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOGMETA) {
+ fprintf(stderr, "__pmLogLoadMeta: header read -> %d: expected: %d\n",
+ n, (int)sizeof(__pmLogHdr));
+ }
+#endif
+ if (ferror(f)) {
+ clearerr(f);
+ sts = -errno;
+ }
+ else
+ sts = PM_ERR_LOGREC;
+ goto end;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOGMETA) {
+ fprintf(stderr, "__pmLogLoadMeta: record len=%d, type=%d @ offset=%d\n",
+ h.len, h.type, (int)(ftell(f) - sizeof(__pmLogHdr)));
+ }
+#endif
+ rlen = h.len - (int)sizeof(__pmLogHdr) - (int)sizeof(int);
+ if (h.type == TYPE_DESC) {
+ numpmid++;
+ if ((dp = (pmDesc *)malloc(sizeof(pmDesc))) == NULL) {
+ sts = -errno;
+ goto end;
+ }
+ if ((n = (int)fread(dp, 1, sizeof(pmDesc), f)) != sizeof(pmDesc)) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOGMETA) {
+ fprintf(stderr, "__pmLogLoadMeta: pmDesc read -> %d: expected: %d\n",
+ n, (int)sizeof(pmDesc));
+ }
+#endif
+ if (ferror(f)) {
+ clearerr(f);
+ sts = -errno;
+ }
+ else
+ sts = PM_ERR_LOGREC;
+ goto end;
+ }
+ else {
+ /* swab desc */
+ dp->type = ntohl(dp->type);
+ dp->sem = ntohl(dp->sem);
+ dp->indom = __ntohpmInDom(dp->indom);
+ dp->units = __ntohpmUnits(dp->units);
+ dp->pmid = __ntohpmID(dp->pmid);
+ }
+
+ if ((sts = __pmHashAdd((int)dp->pmid, (void *)dp, &lcp->l_hashpmid)) < 0)
+ goto end;
+
+ if (version2) {
+ char name[MAXPATHLEN];
+ int numnames;
+ int i;
+ int len;
+
+ /* read in the names & store in PMNS tree ... */
+ if ((n = (int)fread(&numnames, 1, sizeof(numnames), f)) !=
+ sizeof(numnames)) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOGMETA) {
+ fprintf(stderr, "__pmLogLoadMeta: numnames read -> %d: expected: %d\n",
+ n, (int)sizeof(numnames));
+ }
+#endif
+ if (ferror(f)) {
+ clearerr(f);
+ sts = -errno;
+ }
+ else
+ sts = PM_ERR_LOGREC;
+ goto end;
+ }
+ else {
+ /* swab numnames */
+ numnames = ntohl(numnames);
+ }
+
+ for (i = 0; i < numnames; i++) {
+ if ((n = (int)fread(&len, 1, sizeof(len), f)) !=
+ sizeof(len)) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOGMETA) {
+ fprintf(stderr, "__pmLogLoadMeta: len name[%d] read -> %d: expected: %d\n",
+ i, n, (int)sizeof(len));
+ }
+#endif
+ if (ferror(f)) {
+ clearerr(f);
+ sts = -errno;
+ }
+ else
+ sts = PM_ERR_LOGREC;
+ goto end;
+ }
+ else {
+ /* swab len */
+ len = ntohl(len);
+ }
+
+ if ((n = (int)fread(name, 1, len, f)) != len) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOGMETA) {
+ fprintf(stderr, "__pmLogLoadMeta: name[%d] read -> %d: expected: %d\n",
+ i, n, len);
+ }
+#endif
+ if (ferror(f)) {
+ clearerr(f);
+ sts = -errno;
+ }
+ else
+ sts = PM_ERR_LOGREC;
+ goto end;
+ }
+ name[len] = '\0';
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOGMETA) {
+ fprintf(stderr, "__pmLogLoadMeta: PMID: %s name: %s\n",
+ pmIDStr(dp->pmid), name);
+ }
+#endif
+
+ if ((sts = __pmAddPMNSNode(lcp->l_pmns, dp->pmid, name)) < 0) {
+ /*
+ * If we see a duplicate PMID, its a recoverable error.
+ * We wont be able to see all of the data in the log, but
+ * its better to provide access to some rather than none,
+ * esp. when only one or two metric IDs may be corrupted
+ * in this way (which we may not be interested in anyway).
+ */
+ if (sts != PM_ERR_PMID)
+ goto end;
+ sts = 0;
+ }
+ }/*for*/
+ }/*version2*/
+ }
+ else if (h.type == TYPE_INDOM) {
+ int *tbuf;
+ pmInDom indom;
+ __pmTimeval *when;
+ int numinst;
+ int *instlist;
+ char **namelist;
+ char *namebase;
+ int *stridx;
+ int i;
+ int k;
+ int allinbuf;
+
+ if ((tbuf = (int *)malloc(rlen)) == NULL) {
+ sts = -errno;
+ goto end;
+ }
+ if ((n = (int)fread(tbuf, 1, rlen, f)) != rlen) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOGMETA) {
+ fprintf(stderr, "__pmLogLoadMeta: indom read -> %d: expected: %d\n",
+ n, rlen);
+ }
+#endif
+ if (ferror(f)) {
+ clearerr(f);
+ sts = -errno;
+ }
+ else
+ sts = PM_ERR_LOGREC;
+ goto end;
+ }
+
+ k = 0;
+ when = (__pmTimeval *)&tbuf[k];
+ when->tv_sec = ntohl(when->tv_sec);
+ when->tv_usec = ntohl(when->tv_usec);
+ k += sizeof(*when)/sizeof(int);
+ indom = __ntohpmInDom((unsigned int)tbuf[k++]);
+ numinst = ntohl(tbuf[k++]);
+ if (numinst > 0) {
+ instlist = &tbuf[k];
+ k += numinst;
+ stridx = &tbuf[k];
+#if defined(HAVE_32BIT_PTR)
+ namelist = (char **)stridx;
+ allinbuf = 1; /* allocation is all in tbuf */
+#else
+ allinbuf = 0; /* allocation for namelist + tbuf */
+ /* need to allocate to hold the pointers */
+ namelist = (char **)malloc(numinst*sizeof(char*));
+ if (namelist == NULL) {
+ sts = -errno;
+ goto end;
+ }
+#endif
+ k += numinst;
+ namebase = (char *)&tbuf[k];
+ for (i = 0; i < numinst; i++) {
+ instlist[i] = ntohl(instlist[i]);
+ namelist[i] = &namebase[ntohl(stridx[i])];
+ }
+ }
+ else {
+ /* no instances, or an error */
+ instlist = NULL;
+ namelist = NULL;
+ }
+ if ((sts = addindom(lcp, indom, when, numinst, instlist, namelist, tbuf, allinbuf)) < 0)
+ goto end;
+ }
+ else
+ fseek(f, (long)rlen, SEEK_CUR);
+ n = (int)fread(&check, 1, sizeof(check), f);
+ check = ntohl(check);
+ if (n != sizeof(check) || h.len != check) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOGMETA) {
+ fprintf(stderr, "__pmLogLoadMeta: trailer read -> %d or len=%d: expected %d @ offset=%d\n",
+ n, check, h.len, (int)(ftell(f) - sizeof(check)));
+ }
+#endif
+ if (ferror(f)) {
+ clearerr(f);
+ sts = -errno;
+ }
+ else
+ sts = PM_ERR_LOGREC;
+ goto end;
+ }
+ }/*for*/
+end:
+
+ fseek(f, (long)(sizeof(__pmLogLabel) + 2*sizeof(int)), SEEK_SET);
+
+ if (version2 && sts == 0) {
+ __pmFixPMNSHashTab(lcp->l_pmns, numpmid, 1);
+ }
+ return sts;
+}