diff options
Diffstat (limited to 'src/pmlogreduce/logio.c')
-rw-r--r-- | src/pmlogreduce/logio.c | 260 |
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); + } +} |