Skip to content

Commit 60a4efc

Browse files
committed
a standalone log file reader
Useful for debugging and for demonstrating how the logfs data structures are stored.
1 parent 9680f94 commit 60a4efc

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/* here's a simple utility to read the logfs .logfs and .meta files. These
2+
* structures are all internal to logfs and defined in ad_logfs/logfs.c, so if
3+
* they are modified there, one will have to manually update the structures
4+
* here.
5+
*
6+
* if while reading the file you get an assertion (see the 'UNKNOWN RECORD TYPE
7+
* IN LOG ' comment below), that might be because the log file was generatd
8+
* with (or without) magic guards */
9+
10+
#include <sys/types.h>
11+
#include <sys/stat.h>
12+
#include <fcntl.h>
13+
14+
#include <unistd.h>
15+
16+
#include <stdlib.h>
17+
18+
#include <stdio.h>
19+
20+
#include <assert.h>
21+
typedef struct
22+
{
23+
char magic[64]; /* file magic */
24+
int flags;
25+
int logfilecount; /* max. number of lock files possibly created for
26+
this file (acros reopens) (== number of CPUs
27+
used in open/create) */
28+
int epoch; /* next epoch number (used in reopen) */
29+
char logfilebase[255]; /* base filename for logfiles */
30+
} logfs_logfsfile_header;
31+
32+
/* from logfs_file.c */
33+
/* ======================================================================= */
34+
/* ============= LOGFS_FILE RECORDTYPE =================================== */
35+
/* ======================================================================= */
36+
37+
/*
38+
* The displacement and datatype follow the record header
39+
*/
40+
#define LOGFS_FILE_RECORD_VIEW 1
41+
42+
/*
43+
* After this header kind:
44+
* - seek position (in etypes)
45+
* - datasize (in bytes)
46+
*
47+
* The datasize (in bytes) followed by the
48+
* actual data
49+
*/
50+
#define LOGFS_FILE_RECORD_DATA 2
51+
52+
/*
53+
* Followed by the epoch number
54+
*/
55+
#define LOGFS_FILE_RECORD_SYNC 3
56+
57+
/*
58+
* followed by filesize (MPI_Offset)
59+
*/
60+
#define LOGFS_FILE_RECORD_SETSIZE 4
61+
62+
/* used for debugging; If enabled, magicstart and magicstop will
63+
* be written before and after the recordheader */
64+
//#define LOGFS_FILE_RECORDMAGIC
65+
66+
#define LOGFS_FILE_RECORDMAGIC_START "[magicstart] "
67+
#define LOGFS_FILE_RECORDMAGIC_STOP "[magicstop ] "
68+
69+
70+
/* Record struct for in the logfs metalog */
71+
typedef struct
72+
{
73+
#ifdef LOGFS_FILE_RECORDMAGIC
74+
char magic_start[16];
75+
#endif
76+
int recordtype;
77+
double timestamp;
78+
#ifdef LOGFS_FILE_RECORDMAGIC
79+
char magic_stop[16];
80+
#endif
81+
} logfs_file_recordstruct;
82+
83+
84+
/* Header that goes at the beginning of both metadata and datafiles */
85+
typedef struct
86+
{
87+
char magic[64];
88+
/* don't store epoch here; otherwise we need an alreduce when we lazily
89+
* open the logfile to inform other CPUs of the highest epoch number */
90+
/*int epoch; */ /* epoch number of last epoch in file */
91+
} logfs_file_headerstruct;
92+
93+
94+
95+
char * logfs_flags_to_string(int flags)
96+
{
97+
if (flags == 2) return "REPLAY";
98+
if (flags == 3) return "ACTIVE";
99+
return NULL;
100+
}
101+
void dump_logfs(char *filename)
102+
{
103+
int fd, ret;
104+
logfs_logfsfile_header h;
105+
106+
fd = open(filename, O_RDONLY);
107+
ret = read(fd, &h, sizeof(h));
108+
printf("magic: %s flags %s count %d epoch %d base |%s|\n",
109+
h.magic, logfs_flags_to_string(h.flags),
110+
h.logfilecount, h.epoch, h.logfilebase);
111+
112+
}
113+
114+
void extract_typemap(char *prefix, int fd, FILE *output)
115+
{
116+
int64_t count;
117+
int64_t *indices;
118+
int64_t *blocklens;
119+
int ret, i;
120+
ret = read(fd, &count, sizeof(count));
121+
indices = malloc(count*sizeof(*indices));
122+
blocklens = malloc(count*sizeof(*blocklens));
123+
ret = read(fd, indices, count*sizeof(*indices));
124+
ret = read(fd, blocklens, count*sizeof(*blocklens));
125+
fprintf(output, "%s ", prefix);
126+
for (i=0; i<count; i++) {
127+
fprintf(output, "(%ld %ld) ", indices[i], blocklens[i]);
128+
}
129+
free(indices);
130+
free(blocklens);
131+
}
132+
133+
void dump_logfs_view(int fd_in, FILE *output)
134+
{
135+
int ret;
136+
int64_t displacement;
137+
ret = read(fd_in, &displacement, sizeof(displacement));
138+
fprintf(output, "\ndisplacement: %ld ", displacement);
139+
extract_typemap("etype:", fd_in, output);
140+
extract_typemap("ftype:", fd_in, output);
141+
}
142+
143+
void dump_logfs_meta_data(int fd_in, FILE *output)
144+
{
145+
int ret, size;
146+
int64_t fileofs, datalogofs;
147+
ret = read(fd_in, &size, sizeof(size));
148+
ret = read(fd_in, &fileofs, sizeof(fileofs));
149+
ret = read(fd_in, &datalogofs, sizeof(datalogofs));
150+
fprintf(output, "\nsize: %d fileofs: %ld datalogofs: %ld\n",
151+
size, fileofs, datalogofs);
152+
}
153+
154+
void dump_logfs_meta(char *filename, FILE * output)
155+
{
156+
int fd, ret, epoch;
157+
logfs_file_recordstruct record;
158+
logfs_file_headerstruct h;
159+
fd = open(filename, O_RDONLY);
160+
/* read header, but mostly to just skip over it */
161+
ret = read(fd, &h, sizeof(h));
162+
163+
164+
while(1) {
165+
ret = read(fd, &record, sizeof(record));
166+
if (ret <= 0) break;
167+
168+
switch (record.recordtype) {
169+
case LOGFS_FILE_RECORD_VIEW:
170+
dump_logfs_view(fd, output);
171+
break;
172+
173+
case LOGFS_FILE_RECORD_DATA:
174+
dump_logfs_meta_data(fd, output);
175+
break;
176+
case LOGFS_FILE_RECORD_SYNC:
177+
ret = read(fd, &epoch, sizeof(epoch));
178+
fprintf(output, "\nsync-epoch: %d ", epoch);
179+
break;
180+
181+
default:
182+
printf("found record type %d\n", record.recordtype);
183+
assert (0 /* UNKNOWN RECORD TYPE IN LOG */);
184+
}
185+
}
186+
187+
}
188+
void dump_logfs_data(char *filename)
189+
{
190+
}
191+
192+
int main(int argc, char **argv)
193+
{
194+
int c;
195+
while ((c = getopt(argc, argv, "l:m:d:")) != -1) {
196+
switch (c) {
197+
case 'l':
198+
dump_logfs(optarg);
199+
break;
200+
case 'm':
201+
dump_logfs_meta(optarg, stdout);
202+
break;
203+
case 'd':
204+
dump_logfs_data(optarg);
205+
break;
206+
default:
207+
printf("unknown argument\n");
208+
}
209+
}
210+
}

0 commit comments

Comments
 (0)