docs: describe the pmdaroot process interfaces
[pcp.git] / src / pmlogreduce / logio.c
blob09a135bb208695bb81cd60609c5239a64182d746
1 /*
2 * utils for pmlogextract
4 * Copyright (c) 1997-2002 Silicon Graphics, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
17 #include "pmlogreduce.h"
20 * raw read of next log record - largely stolen from __pmLogRead in libpcp
22 int
23 _pmLogGet(__pmLogCtl *lcp, int vol, __pmPDU **pb)
25 int head;
26 int tail;
27 int sts;
28 long offset;
29 char *p;
30 __pmPDU *lpb;
31 FILE *f;
33 if (vol == PM_LOG_VOL_META)
34 f = lcp->l_mdfp;
35 else
36 f = lcp->l_mfp;
38 offset = ftell(f);
39 #ifdef PCP_DEBUG
40 if (pmDebug & DBG_TRACE_LOG) {
41 fprintf(stderr, "_pmLogGet: fd=%d vol=%d posn=%ld ",
42 fileno(f), vol, offset);
44 #endif
46 again:
47 sts = (int)fread(&head, 1, sizeof(head), f);
48 if (sts != sizeof(head)) {
49 if (sts == 0) {
50 #ifdef PCP_DEBUG
51 if (pmDebug & DBG_TRACE_LOG)
52 fprintf(stderr, "AFTER end\n");
53 #endif
54 fseek(f, offset, SEEK_SET);
55 if (vol != PM_LOG_VOL_META) {
56 if (lcp->l_curvol < lcp->l_maxvol) {
57 if (__pmLogChangeVol(lcp, lcp->l_curvol+1) == 0) {
58 f = lcp->l_mfp;
59 goto again;
63 return PM_ERR_EOL;
65 #ifdef PCP_DEBUG
66 if (pmDebug & DBG_TRACE_LOG)
67 fprintf(stderr, "Error: hdr fread=%d %s\n", sts, osstrerror());
68 #endif
69 if (sts > 0)
70 return PM_ERR_LOGREC;
71 else
72 return -oserror();
75 if ((lpb = (__pmPDU *)malloc(ntohl(head))) == NULL) {
76 #ifdef PCP_DEBUG
77 if (pmDebug & DBG_TRACE_LOG)
78 fprintf(stderr, "Error: _pmLogGet:(%d) %s\n",
79 (int)ntohl(head), osstrerror());
80 #endif
81 fseek(f, offset, SEEK_SET);
82 return -oserror();
85 lpb[0] = head;
86 if ((sts = (int)fread(&lpb[1], 1, ntohl(head) - sizeof(head), f)) != ntohl(head) - sizeof(head)) {
87 #ifdef PCP_DEBUG
88 if (pmDebug & DBG_TRACE_LOG)
89 fprintf(stderr, "Error: data fread=%d %s\n", sts, osstrerror());
90 #endif
91 if (sts == 0) {
92 fseek(f, offset, SEEK_SET);
93 free(lpb);
94 return PM_ERR_EOL;
96 else if (sts > 0) {
97 free(lpb);
98 return PM_ERR_LOGREC;
100 else {
101 int e = -oserror();
102 free(lpb);
103 return e;
108 p = (char *)lpb;
109 memcpy(&tail, &p[ntohl(head) - sizeof(head)], sizeof(head));
110 if (head != tail) {
111 #ifdef PCP_DEBUG
112 if (pmDebug & DBG_TRACE_LOG)
113 fprintf(stderr, "Error: head-tail mismatch (%d-%d)\n",
114 (int)ntohl(head), (int)ntohl(tail));
115 #endif
116 return PM_ERR_LOGREC;
119 #ifdef PCP_DEBUG
120 if (pmDebug & DBG_TRACE_LOG) {
121 if (vol != PM_LOG_VOL_META || ntohl(lpb[1]) == TYPE_INDOM) {
122 fprintf(stderr, "@");
123 if (sts >= 0) {
124 struct timeval stamp;
125 __pmTimeval *tvp = (__pmTimeval *)&lpb[vol == PM_LOG_VOL_META ? 2 : 1];
126 stamp.tv_sec = ntohl(tvp->tv_sec);
127 stamp.tv_usec = ntohl(tvp->tv_usec);
128 __pmPrintStamp(stderr, &stamp);
130 else
131 fprintf(stderr, "unknown time");
133 fprintf(stderr, " len=%d (incl head+tail)\n", (int)ntohl(head));
135 #endif
137 #ifdef PCP_DEBUG
138 if (pmDebug & DBG_TRACE_PDU) {
139 int i, j;
140 struct timeval stamp;
141 __pmTimeval *tvp = (__pmTimeval *)&lpb[vol == PM_LOG_VOL_META ? 2 : 1];
142 fprintf(stderr, "_pmLogGet");
143 if (vol != PM_LOG_VOL_META || ntohl(lpb[1]) == TYPE_INDOM) {
144 fprintf(stderr, " timestamp=");
145 stamp.tv_sec = ntohl(tvp->tv_sec);
146 stamp.tv_usec = ntohl(tvp->tv_usec);
147 __pmPrintStamp(stderr, &stamp);
149 fprintf(stderr, " " PRINTF_P_PFX "%p ... " PRINTF_P_PFX "%p", lpb, &lpb[ntohl(head)/sizeof(__pmPDU) - 1]);
150 fputc('\n', stderr);
151 fprintf(stderr, "%03d: ", 0);
152 for (j = 0, i = 0; j < ntohl(head)/sizeof(__pmPDU); j++) {
153 if (i == 8) {
154 fprintf(stderr, "\n%03d: ", j);
155 i = 0;
157 fprintf(stderr, "0x%x ", lpb[j]);
158 i++;
160 fputc('\n', stderr);
162 #endif
164 *pb = lpb;
165 return 0;
169 _pmLogPut(FILE *f, __pmPDU *pb)
171 int rlen = ntohl(pb[0]);
172 int sts;
174 #ifdef PCP_DEBUG
175 if (pmDebug & DBG_TRACE_LOG) {
176 fprintf(stderr, "_pmLogPut: fd=%d rlen=%d\n",
177 fileno(f), rlen);
179 #endif
181 if ((sts = (int)fwrite(pb, 1, rlen, f)) != rlen) {
182 #ifdef PCP_DEBUG
183 if (pmDebug & DBG_TRACE_LOG)
184 fprintf(stderr, "_pmLogPut: fwrite=%d %s\n", sts, osstrerror());
185 #endif
186 return -oserror();
188 return 0;
192 * construct new external label, and check label records from
193 * input archives
195 void
196 newlabel(void)
198 __pmLogLabel *lp = &logctl.l_label;
200 /* check version number */
201 if ((ilabel.ll_magic & 0xff) != PM_LOG_VERS02) {
202 fprintf(stderr,"%s: Error: version number %d (not %d as expected) in archive (%s)\n",
203 pmProgname, ilabel.ll_magic & 0xff, PM_LOG_VERS02, iname);
204 exit(1);
207 /* copy magic number, host and timezone, use our pid */
208 lp->ill_magic = ilabel.ll_magic;
209 lp->ill_pid = (int)getpid();
210 strncpy(lp->ill_hostname, ilabel.ll_hostname, PM_LOG_MAXHOSTLEN);
211 lp->ill_hostname[PM_LOG_MAXHOSTLEN-1] = '\0';
212 strncpy(lp->ill_tz, ilabel.ll_tz, PM_TZ_MAXLEN);
213 lp->ill_tz[PM_TZ_MAXLEN-1] = '\0';
218 * write label records into all files of the output archive
220 void
221 writelabel(void)
223 logctl.l_label.ill_vol = 0;
224 __pmLogWriteLabel(logctl.l_mfp, &logctl.l_label);
225 logctl.l_label.ill_vol = PM_LOG_VOL_TI;
226 __pmLogWriteLabel(logctl.l_tifp, &logctl.l_label);
227 logctl.l_label.ill_vol = PM_LOG_VOL_META;
228 __pmLogWriteLabel(logctl.l_mdfp, &logctl.l_label);
232 * switch output volumes
234 void
235 newvolume(char *base, __pmTimeval *tvp)
237 FILE *newfp;
238 int nextvol = logctl.l_curvol + 1;
239 struct timeval stamp;
241 if ((newfp = __pmLogNewFile(base, nextvol)) != NULL) {
242 fclose(logctl.l_mfp);
243 logctl.l_mfp = newfp;
244 logctl.l_label.ill_vol = logctl.l_curvol = nextvol;
245 __pmLogWriteLabel(logctl.l_mfp, &logctl.l_label);
246 fflush(logctl.l_mfp);
247 stamp.tv_sec = tvp->tv_sec;
248 stamp.tv_usec = tvp->tv_usec;
249 fprintf(stderr, "%s: New log volume %d, at ",
250 pmProgname, nextvol);
251 __pmPrintStamp(stderr, &stamp);
252 fputc('\n', stderr);
253 return;
255 else {
256 fprintf(stderr, "%s: Error: volume %d: %s\n",
257 pmProgname, nextvol, pmErrStr(-oserror()));
258 exit(1);