Commit a0e8f8a8 authored by Shane Snyder's avatar Shane Snyder

initial rewrite of logutils for new file format

parent 01d0a980
all: darshan-parser darshan-convert darshan-diff darshan-analyzer darshan-log-params darshan-util-lib
all: darshan-posix-parser darshan-util-lib
#all: darshan-parser darshan-convert darshan-diff darshan-analyzer darshan-log-params darshan-util-lib
DESTDIR =
srcdir = @srcdir@
......@@ -41,25 +42,28 @@ mktestdir::
uthash-1.9.2:
tar xjvf $(srcdir)/extern/uthash-1.9.2.tar.bz2
darshan-parser: darshan-parser.c $(DARSHAN_LOG_FORMAT) darshan-logutils.h darshan-logutils.o | uthash-1.9.2
darshan-posix-parser: darshan-posix-parser.c $(DARSHAN_LOG_FORMAT) darshan-logutils.h darshan-logutils.o | uthash-1.9.2
$(CC) $(CFLAGS) $(LDFLAGS) $< darshan-logutils.o -o $@ $(LIBS)
darshan-convert: darshan-convert.c $(DARSHAN_LOG_FORMAT) darshan-logutils.h darshan-logutils.o lookup3.o
$(CC) $(CFLAGS) $(LDFLAGS) $< darshan-logutils.o lookup3.o -o $@ $(LIBS)
#darshan-parser: darshan-parser.c $(DARSHAN_LOG_FORMAT) darshan-logutils.h darshan-logutils.o | uthash-1.9.2
# $(CC) $(CFLAGS) $(LDFLAGS) $< darshan-logutils.o -o $@ $(LIBS)
darshan-analyzer: darshan-analyzer.c $(DARSHAN_LOG_FORMAT) darshan-logutils.h darshan-logutils.o
$(CC) $(CFLAGS) $(LDFLAGS) $< darshan-logutils.o -o $@ $(LIBS)
#darshan-convert: darshan-convert.c $(DARSHAN_LOG_FORMAT) darshan-logutils.h darshan-logutils.o lookup3.o
# $(CC) $(CFLAGS) $(LDFLAGS) $< darshan-logutils.o lookup3.o -o $@ $(LIBS)
darshan-log-params: darshan-log-params.c $(DARSHAN_LOG_FORMAT)
$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ $(LIBS)
#darshan-analyzer: darshan-analyzer.c $(DARSHAN_LOG_FORMAT) darshan-logutils.h darshan-logutils.o
# $(CC) $(CFLAGS) $(LDFLAGS) $< darshan-logutils.o -o $@ $(LIBS)
#darshan-log-params: darshan-log-params.c $(DARSHAN_LOG_FORMAT)
# $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ $(LIBS)
jenkins: util/bin/jenkins.o lookup3.o
$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ lookup3.o $(LIBS)
darshan-diff: darshan-diff.o $(DARSHAN_LOG_FORMAT) darshan-logutils.o darshan-logutils.h
$(CC) $(CFLAGS) $(LDFLAGS) $< darshan-logutils.o -o $@ $(LIBS)
darshan-diff.o: darshan-diff.c
$(CC) $(CFLAGS) -c $< -o $@
#darshan-diff: darshan-diff.o $(DARSHAN_LOG_FORMAT) darshan-logutils.o darshan-logutils.h
# $(CC) $(CFLAGS) $(LDFLAGS) $< darshan-logutils.o -o $@ $(LIBS)
#darshan-diff.o: darshan-diff.c
# $(CC) $(CFLAGS) -c $< -o $@
darshan-logutils.o: darshan-logutils.c
$(CC) $(CFLAGS) -c $< -o $@
darshan-logutils.po: darshan-logutils.c
......@@ -71,11 +75,11 @@ libdarshan-util.so: darshan-logutils.po
darshan-util-lib: darshan-logutils.o
ar rcs libdarshan-util.a $<
test/gztest: test/gztest.c mktestdir
$(CC) $(CFLAGS) $(LDFLAGS) -lz $< -o $@
#test/gztest: test/gztest.c mktestdir
# $(CC) $(CFLAGS) $(LDFLAGS) -lz $< -o $@
test/gz-bench: test/gz-bench.c mktestdir
$(CC) $(CFLAGS) $(LDFLAGS) -lz $< -o $@
#test/gz-bench: test/gz-bench.c mktestdir
# $(CC) $(CFLAGS) $(LDFLAGS) -lz $< -o $@
lookup3.o: lookup3.c
$(CC) $(CFLAGS) -c $< -o $@
......@@ -85,25 +89,26 @@ install:: all
install -d $(libdir)
install -d $(includedir)
install -d $(pkgconfigdir)
install -m 755 darshan-parser $(bindir)
install -m 755 darshan-convert $(bindir)
install -m 755 darshan-diff $(bindir)
install -m 755 darshan-analyzer $(bindir)
install -m 755 $(srcdir)/darshan-summary-per-file.sh $(bindir)
# install -m 755 darshan-parser $(bindir)
install -m 755 darshan-posix-parser $(bindir)
# install -m 755 darshan-convert $(bindir)
# install -m 755 darshan-diff $(bindir)
# install -m 755 darshan-analyzer $(bindir)
# install -m 755 $(srcdir)/darshan-summary-per-file.sh $(bindir)
install -m 755 libdarshan-util.a $(libdir)
ifeq ($(DARSHAN_ENABLE_SHARED),1)
install -m 755 libdarshan-util.so $(libdir)
endif
install -m 644 $(srcdir)/darshan-logutils.h $(includedir)
install -m 644 $(DARSHAN_LOG_FORMAT) $(includedir)
install -m 755 darshan-job-summary/bin/darshan-job-summary.pl $(bindir)
# install -m 755 darshan-job-summary/bin/darshan-job-summary.pl $(bindir)
install -d $(libdir)/TeX
install -m 644 $(srcdir)/darshan-job-summary/lib/TeX/Encode.pm $(libdir)/TeX/
install -d $(libdir)/Number
install -d $(libdir)/Number/Bytes
install -m 644 $(srcdir)/darshan-job-summary/lib/Number/Bytes/Human.pm $(libdir)/Number/Bytes
install -d $(datarootdir)
install -m 644 $(srcdir)/darshan-job-summary/share/* $(datarootdir)
# install -m 644 $(srcdir)/darshan-job-summary/share/* $(datarootdir)
install -m 644 maint/darshan-util.pc $(pkgconfigdir)
......
......@@ -24,250 +24,40 @@
struct darshan_fd_s
{
gzFile gzf;
#ifdef HAVE_LIBBZ2
BZFILE* bzf;
#endif
int pf;
int64_t pos;
char mode[2];
int swap_flag;
char version[10];
int job_struct_size;
char version[8];
char* name;
int COMPAT_CP_EXE_LEN;
};
/* isn't there a clever c way to avoid this? */
char *darshan_names[] = {
"CP_INDEP_OPENS",
"CP_COLL_OPENS", /* count of MPI collective opens */
"CP_INDEP_READS", /* count of independent MPI reads */
"CP_INDEP_WRITES", /* count of independent MPI writes */
"CP_COLL_READS", /* count of collective MPI reads */
"CP_COLL_WRITES", /* count of collective MPI writes */
"CP_SPLIT_READS", /* count of split collective MPI reads */
"CP_SPLIT_WRITES", /* count of split collective MPI writes */
"CP_NB_READS", /* count of nonblocking MPI reads */
"CP_NB_WRITES", /* count of nonblocking MPI writes */
"CP_SYNCS", /* count of MPI_File_sync */
"CP_POSIX_READS", /* count of posix reads */
"CP_POSIX_WRITES", /* count of posix writes */
"CP_POSIX_OPENS", /* count of posix opens */
"CP_POSIX_SEEKS", /* count of posix seeks */
"CP_POSIX_STATS", /* count of posix stat/lstat/fstats */
"CP_POSIX_MMAPS", /* count of posix mmaps */
"CP_POSIX_FREADS",
"CP_POSIX_FWRITES",
"CP_POSIX_FOPENS",
"CP_POSIX_FSEEKS",
"CP_POSIX_FSYNCS",
"CP_POSIX_FDSYNCS",
"CP_INDEP_NC_OPENS",
"CP_COLL_NC_OPENS",
"CP_HDF5_OPENS",
"CP_COMBINER_NAMED", /* count of each MPI datatype category */
"CP_COMBINER_DUP",
"CP_COMBINER_CONTIGUOUS",
"CP_COMBINER_VECTOR",
"CP_COMBINER_HVECTOR_INTEGER",
"CP_COMBINER_HVECTOR",
"CP_COMBINER_INDEXED",
"CP_COMBINER_HINDEXED_INTEGER",
"CP_COMBINER_HINDEXED",
"CP_COMBINER_INDEXED_BLOCK",
"CP_COMBINER_STRUCT_INTEGER",
"CP_COMBINER_STRUCT",
"CP_COMBINER_SUBARRAY",
"CP_COMBINER_DARRAY",
"CP_COMBINER_F90_REAL",
"CP_COMBINER_F90_COMPLEX",
"CP_COMBINER_F90_INTEGER",
"CP_COMBINER_RESIZED",
"CP_HINTS", /* count of MPI hints used */
"CP_VIEWS", /* count of MPI set view calls */
"CP_MODE", /* mode of file */
"CP_BYTES_READ", /* total bytes read */
"CP_BYTES_WRITTEN", /* total bytes written */
"CP_MAX_BYTE_READ", /* highest offset byte read */
"CP_MAX_BYTE_WRITTEN", /* highest offset byte written */
"CP_CONSEC_READS", /* count of consecutive reads */
"CP_CONSEC_WRITES", /* count of consecutive writes */
"CP_SEQ_READS", /* count of sequential reads */
"CP_SEQ_WRITES", /* count of sequential writes */
"CP_RW_SWITCHES",
"CP_MEM_NOT_ALIGNED", /* count of accesses not mem aligned */
"CP_MEM_ALIGNMENT", /* mem alignment in bytes */
"CP_FILE_NOT_ALIGNED", /* count of accesses not file aligned */
"CP_FILE_ALIGNMENT", /* file alignment in bytes */
"CP_MAX_READ_TIME_SIZE",
"CP_MAX_WRITE_TIME_SIZE",
"CP_SIZE_READ_0_100", /* count of posix read size ranges */
"CP_SIZE_READ_100_1K",
"CP_SIZE_READ_1K_10K",
"CP_SIZE_READ_10K_100K",
"CP_SIZE_READ_100K_1M",
"CP_SIZE_READ_1M_4M",
"CP_SIZE_READ_4M_10M",
"CP_SIZE_READ_10M_100M",
"CP_SIZE_READ_100M_1G",
"CP_SIZE_READ_1G_PLUS",
"CP_SIZE_WRITE_0_100", /* count of posix write size ranges */
"CP_SIZE_WRITE_100_1K",
"CP_SIZE_WRITE_1K_10K",
"CP_SIZE_WRITE_10K_100K",
"CP_SIZE_WRITE_100K_1M",
"CP_SIZE_WRITE_1M_4M",
"CP_SIZE_WRITE_4M_10M",
"CP_SIZE_WRITE_10M_100M",
"CP_SIZE_WRITE_100M_1G",
"CP_SIZE_WRITE_1G_PLUS",
"CP_SIZE_READ_AGG_0_100", /* count of MPI read size ranges */
"CP_SIZE_READ_AGG_100_1K",
"CP_SIZE_READ_AGG_1K_10K",
"CP_SIZE_READ_AGG_10K_100K",
"CP_SIZE_READ_AGG_100K_1M",
"CP_SIZE_READ_AGG_1M_4M",
"CP_SIZE_READ_AGG_4M_10M",
"CP_SIZE_READ_AGG_10M_100M",
"CP_SIZE_READ_AGG_100M_1G",
"CP_SIZE_READ_AGG_1G_PLUS",
"CP_SIZE_WRITE_AGG_0_100", /* count of MPI write size ranges */
"CP_SIZE_WRITE_AGG_100_1K",
"CP_SIZE_WRITE_AGG_1K_10K",
"CP_SIZE_WRITE_AGG_10K_100K",
"CP_SIZE_WRITE_AGG_100K_1M",
"CP_SIZE_WRITE_AGG_1M_4M",
"CP_SIZE_WRITE_AGG_4M_10M",
"CP_SIZE_WRITE_AGG_10M_100M",
"CP_SIZE_WRITE_AGG_100M_1G",
"CP_SIZE_WRITE_AGG_1G_PLUS",
"CP_EXTENT_READ_0_100", /* count of MPI read extent ranges */
"CP_EXTENT_READ_100_1K",
"CP_EXTENT_READ_1K_10K",
"CP_EXTENT_READ_10K_100K",
"CP_EXTENT_READ_100K_1M",
"CP_EXTENT_READ_1M_4M",
"CP_EXTENT_READ_4M_10M",
"CP_EXTENT_READ_10M_100M",
"CP_EXTENT_READ_100M_1G",
"CP_EXTENT_READ_1G_PLUS",
"CP_EXTENT_WRITE_0_100", /* count of MPI write extent ranges */
"CP_EXTENT_WRITE_100_1K",
"CP_EXTENT_WRITE_1K_10K",
"CP_EXTENT_WRITE_10K_100K",
"CP_EXTENT_WRITE_100K_1M",
"CP_EXTENT_WRITE_1M_4M",
"CP_EXTENT_WRITE_4M_10M",
"CP_EXTENT_WRITE_10M_100M",
"CP_EXTENT_WRITE_100M_1G",
"CP_EXTENT_WRITE_1G_PLUS",
"CP_STRIDE1_STRIDE", /* the four most frequently appearing strides */
"CP_STRIDE2_STRIDE",
"CP_STRIDE3_STRIDE",
"CP_STRIDE4_STRIDE",
"CP_STRIDE1_COUNT", /* count of each of the most frequent strides */
"CP_STRIDE2_COUNT",
"CP_STRIDE3_COUNT",
"CP_STRIDE4_COUNT",
"CP_ACCESS1_ACCESS",
"CP_ACCESS2_ACCESS",
"CP_ACCESS3_ACCESS",
"CP_ACCESS4_ACCESS",
"CP_ACCESS1_COUNT",
"CP_ACCESS2_COUNT",
"CP_ACCESS3_COUNT",
"CP_ACCESS4_COUNT",
"CP_DEVICE",
"CP_SIZE_AT_OPEN",
"CP_FASTEST_RANK",
"CP_FASTEST_RANK_BYTES",
"CP_SLOWEST_RANK",
"CP_SLOWEST_RANK_BYTES",
"CP_NUM_INDICES"
};
/* isn't there a clever c way to avoid this? */
char *darshan_f_names[] = {
"CP_F_OPEN_TIMESTAMP", /* timestamp of first open */
"CP_F_READ_START_TIMESTAMP", /* timestamp of first read */
"CP_F_WRITE_START_TIMESTAMP", /* timestamp of first write */
"CP_F_CLOSE_TIMESTAMP", /* timestamp of last close */
"CP_F_READ_END_TIMESTAMP", /* timestamp of last read */
"CP_F_WRITE_END_TIMESTAMP", /* timestamp of last write */
"CP_F_POSIX_READ_TIME", /* cumulative posix read time */
"CP_F_POSIX_WRITE_TIME", /* cumulative posix write time */
"CP_F_POSIX_META_TIME", /* cumulative posix meta time */
"CP_F_MPI_META_TIME", /* cumulative mpi-io metadata time */
"CP_F_MPI_READ_TIME", /* cumulative mpi-io read time */
"CP_F_MPI_WRITE_TIME", /* cumulative mpi-io write time */
"CP_F_MAX_READ_TIME",
"CP_F_MAX_WRITE_TIME",
"CP_F_FASTEST_RANK_TIME",
"CP_F_SLOWEST_RANK_TIME",
"CP_F_VARIANCE_RANK_TIME",
"CP_F_VARIANCE_RANK_BYTES",
"CP_F_NUM_INDICES"
/* TODO: ultimately store indices here */
};
/* function pointers so that we can switch functions depending on what file
* version is detected
*/
int (*getjob_internal)(darshan_fd file, struct darshan_job *job);
int (*getfile_internal)(darshan_fd fd,
struct darshan_job *job,
struct darshan_file *file);
#define JOB_SIZE_124 28
#define JOB_SIZE_200 56
#define JOB_SIZE_201 120
#define CP_JOB_RECORD_SIZE_200 1024
#define CP_JOB_RECORD_SIZE_1x 1024
/* internal routines for parsing different file versions */
static int getjob_internal_204(darshan_fd file, struct darshan_job *job);
static int getjob_internal_201(darshan_fd file, struct darshan_job *job);
static int getjob_internal_200(darshan_fd file, struct darshan_job *job);
static int getfile_internal_204(darshan_fd fd, struct darshan_job *job,
struct darshan_file *file);
static int getfile_internal_200(darshan_fd fd, struct darshan_job *job,
struct darshan_file *file);
static int getjob_internal_124(darshan_fd file, struct darshan_job *job);
static int getfile_internal_124(darshan_fd fd, struct darshan_job *job,
struct darshan_file *file);
static int getfile_internal_122(darshan_fd fd, struct darshan_job *job,
struct darshan_file *file);
static int getfile_internal_121(darshan_fd fd, struct darshan_job *job,
struct darshan_file *file);
static int getfile_internal_1x(darshan_fd fd, struct darshan_job *job,
struct darshan_file *file, int n_counters, int n_fcounters);
static void shift_missing_1_24(struct darshan_file* file);
static void shift_missing_1_22(struct darshan_file* file);
static void shift_missing_1_21(struct darshan_file* file);
static int darshan_log_seek(darshan_fd fd, int64_t offset);
static int darshan_log_read(darshan_fd fd, void* buf, int len);
static int darshan_log_write(darshan_fd fd, void* buf, int len);
static const char* darshan_log_error(darshan_fd fd, int* errnum);
static int darshan_log_seek(darshan_fd fd, off_t offset);
static int darshan_log_read(darshan_fd fd, void *buf, int len);
static int darshan_log_write(darshan_fd fd, void *buf, int len);
//static const char* darshan_log_error(darshan_fd fd, int* errnum);
/* a rather crude API for accessing raw binary darshan files */
darshan_fd darshan_log_open(const char *name, const char* mode)
darshan_fd darshan_log_open(const char *name, const char *mode)
{
int test_fd;
uint8_t magic[2];
int ret;
int try_bz2 = 1;
int len = strlen(name);
int o_flags;
/* we only allows "w" or "r" modes, nothing fancy */
assert(strlen(mode) == 1);
assert(mode[0] == 'r' || mode[0] == 'w');
if(mode[0] == 'r')
o_flags = O_RDONLY;
else
o_flags = O_WRONLY;
darshan_fd tmp_fd = malloc(sizeof(*tmp_fd));
if(!tmp_fd)
return(NULL);
memset(tmp_fd, 0, sizeof(*tmp_fd));
/* TODO: why is mode needed??? */
/* TODO: why is name needed??? */
tmp_fd->mode[0] = mode[0];
tmp_fd->mode[1] = mode[1];
tmp_fd->name = strdup(name);
......@@ -277,417 +67,180 @@ darshan_fd darshan_log_open(const char *name, const char* mode)
return(NULL);
}
if(strcmp(mode, "r") == 0)
{
/* Try to detect if existing file is a bzip2 file or not. Both
* libbz2 and libz will fall back to normal I/O (without compression)
* automatically, so we need to do some detection manually up front
* in order to get a chance to try both compression formats.
*/
test_fd = open(name, O_RDONLY);
if(test_fd < 0)
{
perror("open");
free(tmp_fd->name);
free(tmp_fd);
return(NULL);
}
ret = read(test_fd, &magic, 2);
if(ret != 2)
{
fprintf(stderr, "Error: failed to read any data from %s.\n",
name);
free(tmp_fd->name);
free(tmp_fd);
close(test_fd);
return(NULL);
}
/* header magic for bz2 */
if(magic[0] != 0x42 && magic[1] != 0x5A)
{
try_bz2 = 0;
}
close(test_fd);
}
if(strcmp(mode, "w") == 0)
{
/* TODO: is this the behavior that we want? */
/* if we are writing a new file, go by the file extension to tell
* whether to use bz2 or not?
*/
if(len >= 3 && name[len-3] == 'b' && name[len-2] == 'z' && name[len-1] == '2')
try_bz2 = 1;
else
try_bz2 = 0;
}
#ifdef HAVE_LIBBZ2
if(try_bz2)
{
tmp_fd->bzf = BZ2_bzopen(name, mode);
if(!tmp_fd->bzf)
{
free(tmp_fd->name);
free(tmp_fd);
return(NULL);
}
return(tmp_fd);
}
#else
if(try_bz2)
{
fprintf(stderr, "Error: this Darshan build does not support bz2 files.\n");
fprintf(stderr, "Error: please install libbz2-dev and reconfigure.\n");
return(NULL);
}
#endif
tmp_fd->gzf = gzopen(name, mode);
if(!tmp_fd->gzf)
tmp_fd->pf = open(name, o_flags);
if(tmp_fd->pf < 0)
{
free(tmp_fd->name);
free(tmp_fd);
tmp_fd = NULL;
return(NULL);
}
return tmp_fd;
return(tmp_fd);
}
/* darshan_log_getjob()
*
* returns 0 on success, -1 on failure
*/
int darshan_log_getjob(darshan_fd file, struct darshan_job *job)
int darshan_log_getheader(darshan_fd file, struct darshan_header *header)
{
int ret;
char buffer[DARSHAN_JOB_METADATA_LEN];
ret = darshan_log_seek(file, 0);
if(ret < 0)
{
fprintf(stderr, "Error: unable to seek in darshan log file.\n");
return(ret);
}
/* read version number first so we know how to digest the rest of the
* file
*/
ret = darshan_log_read(file, file->version, 10);
if(ret < 10)
/* read header from log file */
ret = darshan_log_read(file, header, sizeof(*header));
if(ret < sizeof(*header))
{
fprintf(stderr, "Error: invalid log file (failed to read version).\n");
fprintf(stderr, "Error: invalid darshan log file (failed to read header).\n");
return(-1);
}
if(strcmp(file->version, "2.05") == 0)
{
getjob_internal = getjob_internal_204;
getfile_internal = getfile_internal_204;
file->job_struct_size = sizeof(*job);
file->COMPAT_CP_EXE_LEN = CP_EXE_LEN;
}
else if(strcmp(file->version, "2.04") == 0)
{
getjob_internal = getjob_internal_204;
getfile_internal = getfile_internal_204;
file->job_struct_size = sizeof(*job);
file->COMPAT_CP_EXE_LEN = CP_EXE_LEN;
}
else if(strcmp(file->version, "2.03") == 0)
{
getjob_internal = getjob_internal_201;
getfile_internal = getfile_internal_200;
file->job_struct_size = JOB_SIZE_201;
file->COMPAT_CP_EXE_LEN = CP_JOB_RECORD_SIZE_200-file->job_struct_size-1;
}
else if(strcmp(file->version, "2.02") == 0)
{
getjob_internal = getjob_internal_201;
getfile_internal = getfile_internal_200;
file->job_struct_size = JOB_SIZE_201;
file->COMPAT_CP_EXE_LEN = CP_JOB_RECORD_SIZE_200-file->job_struct_size-1;
}
else if(strcmp(file->version, "2.01") == 0)
{
getjob_internal = getjob_internal_201;
getfile_internal = getfile_internal_200;
file->job_struct_size = JOB_SIZE_201;
file->COMPAT_CP_EXE_LEN = CP_JOB_RECORD_SIZE_200-file->job_struct_size-1;
}
else if(strcmp(file->version, "2.00") == 0)
{
getjob_internal = getjob_internal_200;
getfile_internal = getfile_internal_200;
file->job_struct_size = JOB_SIZE_200;
file->COMPAT_CP_EXE_LEN = CP_JOB_RECORD_SIZE_200-file->job_struct_size-1;
}
else if(strcmp(file->version, "1.24") == 0)
{
getjob_internal = getjob_internal_124;
getfile_internal = getfile_internal_124;
file->job_struct_size = JOB_SIZE_124;
file->COMPAT_CP_EXE_LEN = CP_JOB_RECORD_SIZE_1x-file->job_struct_size-1;
}
else if(strcmp(file->version, "1.23") == 0)
{
/* same as 1.24, except that mnt points may be incorrect */
getjob_internal = getjob_internal_124;
getfile_internal = getfile_internal_124;
file->job_struct_size = JOB_SIZE_124;
file->COMPAT_CP_EXE_LEN = CP_JOB_RECORD_SIZE_1x-file->job_struct_size-1;
}
else if(strcmp(file->version, "1.22") == 0)
{
getjob_internal = getjob_internal_124;
getfile_internal = getfile_internal_122;
file->job_struct_size = JOB_SIZE_124;
file->COMPAT_CP_EXE_LEN = CP_JOB_RECORD_SIZE_1x-file->job_struct_size-1;
}
else if(strcmp(file->version, "1.21") == 0)
{
getjob_internal = getjob_internal_124;
getfile_internal = getfile_internal_121;
file->job_struct_size = JOB_SIZE_124;
file->COMPAT_CP_EXE_LEN = CP_JOB_RECORD_SIZE_1x-file->job_struct_size-1;
}
else
/* save the version string -- this can be used to support multiple log versions */
strncpy(file->version, header->version_string, 8);
if(header->magic_nr == CP_MAGIC_NR)
{
fprintf(stderr, "Error: incompatible darshan file.\n");
fprintf(stderr, "Error: expected version %s, but got %s\n",
CP_VERSION, file->version);
return(-1);
/* no byte swapping needed, this file is in host format already */
file->swap_flag = 0;
return(0);
}
ret = getjob_internal(file, job);
if (ret == 0)
/* try byte swapping */
DARSHAN_BSWAP64(&header->magic_nr);
if(header->magic_nr == CP_MAGIC_NR)
{
#ifdef HAVE_STRNDUP
char *metadata = strndup(job->metadata, sizeof(job->metadata));
#else
char *metadata = strdup(job->metadata);
#endif
char *kv;
char *key;
char *value;
char *save;
for(kv=strtok_r(metadata, "\n", &save);
kv != NULL;
kv=strtok_r(NULL, "\n", &save))
{
/* NOTE: we intentionally only split on the first = character.
* There may be additional = characters in the value portion
* (for example, when storing mpi-io hints).
*/
strcpy(buffer, kv);
key = buffer;
value = index(buffer, '=');
if(!value)
continue;
/* convert = to a null terminator to split key and value */
value[0] = '\0';
value++;
if (strcmp(key, "prev_ver") == 0)
{
strncpy(job->version_string, value, sizeof(job->version_string));
}
}
free(metadata);
file->swap_flag = 1;
return(0);
}
return(ret);
/* otherwise this file is just broken */
fprintf(stderr, "Error: bad magic number in darshan log file.\n");
return(-1);
}
/* darshan_putjob()
* write job header in gzfile
/* darshan_log_getjob()
*
* return 0 on success, -1 on failure.
* returns 0 on success, -1 on failure
*/
int darshan_log_putjob(darshan_fd file, struct darshan_job *job)
int darshan_log_getjob(darshan_fd file, struct darshan_job *job)
{
struct darshan_job job_copy;
char pv_str[64];
int ret;
int len;
int ret;
char buffer[DARSHAN_JOB_METADATA_LEN];
ret = darshan_log_seek(file, 0);
ret = darshan_log_seek(file, sizeof(struct darshan_header));
if(ret < 0)
return(ret);
memset(&job_copy, 0, sizeof(job_copy));
memcpy(&job_copy, job, sizeof(job_copy));
/* check for newline in existing metadata, add if needed */
len = strlen(job_copy.metadata);
if(len > 0 && len < DARSHAN_JOB_METADATA_LEN)
{
if(job_copy.metadata[len-1] != '\n')
{
job_copy.metadata[len] = '\n';
job_copy.metadata[len+1] = '\0';
}
fprintf(stderr, "Error: unable to seek in darshan log file.\n");
return(ret);
}
sprintf(pv_str, "prev_ver=%s\n", job->version_string);
sprintf(job_copy.version_string, "%s", CP_VERSION);
if(strlen(job_copy.metadata) + strlen(pv_str) < DARSHAN_JOB_METADATA_LEN)
strncat(job_copy.metadata, pv_str, strlen(pv_str));
else
sprintf(job_copy.metadata, "%s", pv_str);
job_copy.magic_nr = CP_MAGIC_NR;
ret = darshan_log_write(file, &job_copy, sizeof(job_copy));
if (ret != sizeof(job_copy))
/* read the job data from the log file */
ret = darshan_log_read(file, job, sizeof(*job));
if(ret < sizeof(*job))
{
fprintf(stderr, "Error: failed to write job header: %d\n", ret);
fprintf(stderr, "Error: invalid darshan log file (failed to read job data).\n");
return(-1);
}
return(0);
}
/* darshan_log_getfile()
*
* return 1 if file record found, 0 on eof, and -1 on error
*/
int darshan_log_getfile(darshan_fd fd, struct darshan_job *job, struct darshan_file *file)
{
int ret;
ret = getfile_internal(fd, job, file);
return(ret);
}
/* darshan_log_putfile()
*
* return 0 if file record written, -1 on error.
*/
int darshan_log_putfile(darshan_fd fd, struct darshan_job *job, struct darshan_file *file)
{
int ret;
if(fd->pos < CP_JOB_RECORD_SIZE)
{
ret = darshan_log_seek(fd, CP_JOB_RECORD_SIZE);
if(ret < 0)
return(ret);
}
ret = darshan_log_write(fd, file, sizeof(*file));
if (ret != sizeof(*file))
if(file->swap_flag)
{
fprintf(stderr, "Error: writing file record failed: %d\n", ret);
return(-1);
/* swap bytes if necessary */
DARSHAN_BSWAP64(&job->uid);
DARSHAN_BSWAP64(&job->start_time);
DARSHAN_BSWAP64(&job->end_time);
DARSHAN_BSWAP64(&job->nprocs);
DARSHAN_BSWAP64(&job->jobid);
}
return(0);
}