summaryrefslogtreecommitdiff
path: root/src/pmlogreduce/logio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmlogreduce/logio.c')
-rw-r--r--src/pmlogreduce/logio.c260
1 files changed, 260 insertions, 0 deletions
diff --git a/src/pmlogreduce/logio.c b/src/pmlogreduce/logio.c
new file mode 100644
index 0000000..09a135b
--- /dev/null
+++ b/src/pmlogreduce/logio.c
@@ -0,0 +1,260 @@
+/*
+ * utils for pmlogextract
+ *
+ * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+#include "pmlogreduce.h"
+
+/*
+ * raw read of next log record - largely stolen from __pmLogRead in libpcp
+ */
+int
+_pmLogGet(__pmLogCtl *lcp, int vol, __pmPDU **pb)
+{
+ int head;
+ int tail;
+ int sts;
+ long offset;
+ char *p;
+ __pmPDU *lpb;
+ FILE *f;
+
+ if (vol == PM_LOG_VOL_META)
+ f = lcp->l_mdfp;
+ else
+ f = lcp->l_mfp;
+
+ offset = ftell(f);
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG) {
+ fprintf(stderr, "_pmLogGet: fd=%d vol=%d posn=%ld ",
+ fileno(f), vol, offset);
+ }
+#endif
+
+again:
+ sts = (int)fread(&head, 1, sizeof(head), f);
+ if (sts != sizeof(head)) {
+ if (sts == 0) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, "AFTER end\n");
+#endif
+ fseek(f, offset, SEEK_SET);
+ if (vol != PM_LOG_VOL_META) {
+ if (lcp->l_curvol < lcp->l_maxvol) {
+ if (__pmLogChangeVol(lcp, lcp->l_curvol+1) == 0) {
+ f = lcp->l_mfp;
+ goto again;
+ }
+ }
+ }
+ return PM_ERR_EOL;
+ }
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, "Error: hdr fread=%d %s\n", sts, osstrerror());
+#endif
+ if (sts > 0)
+ return PM_ERR_LOGREC;
+ else
+ return -oserror();
+ }
+
+ if ((lpb = (__pmPDU *)malloc(ntohl(head))) == NULL) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, "Error: _pmLogGet:(%d) %s\n",
+ (int)ntohl(head), osstrerror());
+#endif
+ fseek(f, offset, SEEK_SET);
+ return -oserror();
+ }
+
+ lpb[0] = head;
+ if ((sts = (int)fread(&lpb[1], 1, ntohl(head) - sizeof(head), f)) != ntohl(head) - sizeof(head)) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, "Error: data fread=%d %s\n", sts, osstrerror());
+#endif
+ if (sts == 0) {
+ fseek(f, offset, SEEK_SET);
+ free(lpb);
+ return PM_ERR_EOL;
+ }
+ else if (sts > 0) {
+ free(lpb);
+ return PM_ERR_LOGREC;
+ }
+ else {
+ int e = -oserror();
+ free(lpb);
+ return e;
+ }
+ }
+
+
+ p = (char *)lpb;
+ memcpy(&tail, &p[ntohl(head) - sizeof(head)], sizeof(head));
+ if (head != tail) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, "Error: head-tail mismatch (%d-%d)\n",
+ (int)ntohl(head), (int)ntohl(tail));
+#endif
+ return PM_ERR_LOGREC;
+ }
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG) {
+ if (vol != PM_LOG_VOL_META || ntohl(lpb[1]) == TYPE_INDOM) {
+ fprintf(stderr, "@");
+ if (sts >= 0) {
+ struct timeval stamp;
+ __pmTimeval *tvp = (__pmTimeval *)&lpb[vol == PM_LOG_VOL_META ? 2 : 1];
+ stamp.tv_sec = ntohl(tvp->tv_sec);
+ stamp.tv_usec = ntohl(tvp->tv_usec);
+ __pmPrintStamp(stderr, &stamp);
+ }
+ else
+ fprintf(stderr, "unknown time");
+ }
+ fprintf(stderr, " len=%d (incl head+tail)\n", (int)ntohl(head));
+ }
+#endif
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_PDU) {
+ int i, j;
+ struct timeval stamp;
+ __pmTimeval *tvp = (__pmTimeval *)&lpb[vol == PM_LOG_VOL_META ? 2 : 1];
+ fprintf(stderr, "_pmLogGet");
+ if (vol != PM_LOG_VOL_META || ntohl(lpb[1]) == TYPE_INDOM) {
+ fprintf(stderr, " timestamp=");
+ stamp.tv_sec = ntohl(tvp->tv_sec);
+ stamp.tv_usec = ntohl(tvp->tv_usec);
+ __pmPrintStamp(stderr, &stamp);
+ }
+ fprintf(stderr, " " PRINTF_P_PFX "%p ... " PRINTF_P_PFX "%p", lpb, &lpb[ntohl(head)/sizeof(__pmPDU) - 1]);
+ fputc('\n', stderr);
+ fprintf(stderr, "%03d: ", 0);
+ for (j = 0, i = 0; j < ntohl(head)/sizeof(__pmPDU); j++) {
+ if (i == 8) {
+ fprintf(stderr, "\n%03d: ", j);
+ i = 0;
+ }
+ fprintf(stderr, "0x%x ", lpb[j]);
+ i++;
+ }
+ fputc('\n', stderr);
+ }
+#endif
+
+ *pb = lpb;
+ return 0;
+}
+
+int
+_pmLogPut(FILE *f, __pmPDU *pb)
+{
+ int rlen = ntohl(pb[0]);
+ int sts;
+
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG) {
+ fprintf(stderr, "_pmLogPut: fd=%d rlen=%d\n",
+ fileno(f), rlen);
+ }
+#endif
+
+ if ((sts = (int)fwrite(pb, 1, rlen, f)) != rlen) {
+#ifdef PCP_DEBUG
+ if (pmDebug & DBG_TRACE_LOG)
+ fprintf(stderr, "_pmLogPut: fwrite=%d %s\n", sts, osstrerror());
+#endif
+ return -oserror();
+ }
+ return 0;
+}
+
+/*
+ * construct new external label, and check label records from
+ * input archives
+ */
+void
+newlabel(void)
+{
+ __pmLogLabel *lp = &logctl.l_label;
+
+ /* check version number */
+ if ((ilabel.ll_magic & 0xff) != PM_LOG_VERS02) {
+ fprintf(stderr,"%s: Error: version number %d (not %d as expected) in archive (%s)\n",
+ pmProgname, ilabel.ll_magic & 0xff, PM_LOG_VERS02, iname);
+ exit(1);
+ }
+
+ /* copy magic number, host and timezone, use our pid */
+ lp->ill_magic = ilabel.ll_magic;
+ lp->ill_pid = (int)getpid();
+ strncpy(lp->ill_hostname, ilabel.ll_hostname, PM_LOG_MAXHOSTLEN);
+ lp->ill_hostname[PM_LOG_MAXHOSTLEN-1] = '\0';
+ strncpy(lp->ill_tz, ilabel.ll_tz, PM_TZ_MAXLEN);
+ lp->ill_tz[PM_TZ_MAXLEN-1] = '\0';
+}
+
+
+/*
+ * write label records into all files of the output archive
+ */
+void
+writelabel(void)
+{
+ logctl.l_label.ill_vol = 0;
+ __pmLogWriteLabel(logctl.l_mfp, &logctl.l_label);
+ logctl.l_label.ill_vol = PM_LOG_VOL_TI;
+ __pmLogWriteLabel(logctl.l_tifp, &logctl.l_label);
+ logctl.l_label.ill_vol = PM_LOG_VOL_META;
+ __pmLogWriteLabel(logctl.l_mdfp, &logctl.l_label);
+}
+
+/*
+ * switch output volumes
+ */
+void
+newvolume(char *base, __pmTimeval *tvp)
+{
+ FILE *newfp;
+ int nextvol = logctl.l_curvol + 1;
+ struct timeval stamp;
+
+ if ((newfp = __pmLogNewFile(base, nextvol)) != NULL) {
+ fclose(logctl.l_mfp);
+ logctl.l_mfp = newfp;
+ logctl.l_label.ill_vol = logctl.l_curvol = nextvol;
+ __pmLogWriteLabel(logctl.l_mfp, &logctl.l_label);
+ fflush(logctl.l_mfp);
+ stamp.tv_sec = tvp->tv_sec;
+ stamp.tv_usec = tvp->tv_usec;
+ fprintf(stderr, "%s: New log volume %d, at ",
+ pmProgname, nextvol);
+ __pmPrintStamp(stderr, &stamp);
+ fputc('\n', stderr);
+ return;
+ }
+ else {
+ fprintf(stderr, "%s: Error: volume %d: %s\n",
+ pmProgname, nextvol, pmErrStr(-oserror()));
+ exit(1);
+ }
+}