Commit 6eae98bd authored by Shane Snyder's avatar Shane Snyder

Merge branch 'lustre-mod'

Conflicts:
	darshan-bgq-log-format.h
	darshan-runtime/darshan.h
	darshan-runtime/lib/darshan-bgq.c
	darshan-runtime/lib/darshan-core.c
	darshan-runtime/lib/darshan-posix.c
	darshan-util/darshan-convert.c
	darshan-util/darshan-diff.c
parents 301fd492 7d9b5b37
......@@ -111,6 +111,7 @@ struct darshan_base_record
#include "darshan-hdf5-log-format.h"
#include "darshan-pnetcdf-log-format.h"
#include "darshan-bgq-log-format.h"
#include "darshan-lustre-log-format.h"
/* X-macro for keeping module ordering consistent */
/* NOTE: first val used to define module enum values,
......@@ -128,7 +129,8 @@ struct darshan_base_record
X(DARSHAN_MPIIO_MOD, "MPI-IO", DARSHAN_MPIIO_VER, &mpiio_logutils) \
X(DARSHAN_HDF5_MOD, "HDF5", DARSHAN_HDF5_VER, &hdf5_logutils) \
X(DARSHAN_PNETCDF_MOD, "PNETCDF", DARSHAN_PNETCDF_VER, &pnetcdf_logutils) \
X(DARSHAN_BGQ_MOD, "BG/Q", DARSHAN_BGQ_VER, &bgq_logutils)
X(DARSHAN_BGQ_MOD, "BG/Q", DARSHAN_BGQ_VER, &bgq_logutils) \
X(DARSHAN_LUSTRE_MOD, "LUSTRE", DARSHAN_LUSTRE_VER, &lustre_logutils)
/* unique identifiers to distinguish between available darshan modules */
/* NOTES: - valid ids range from [0...DARSHAN_MAX_MODS-1]
......
/*
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#ifndef __DARSHAN_LUSTRE_LOG_FORMAT_H
#define __DARSHAN_LUSTRE_LOG_FORMAT_H
/* NOTE -- redefining the size of OST_ID will require changing the DARSHAN_BSWAP
* macro used in darshan-util/darshan-lustre-logutils.c as well
*/
typedef int64_t OST_ID;
/* current Lustre log format version */
#define DARSHAN_LUSTRE_VER 1
#define LUSTRE_COUNTERS \
/* number of OSTs for file system */\
X(LUSTRE_OSTS) \
/* number of MDTs for file system */\
X(LUSTRE_MDTS) \
/* index of first OST for file */\
X(LUSTRE_STRIPE_OFFSET) \
/* bytes per stripe for file */\
X(LUSTRE_STRIPE_SIZE) \
/* number of stripes (OSTs) for file */\
X(LUSTRE_STRIPE_WIDTH) \
/* end of counters */\
X(LUSTRE_NUM_INDICES)
#define X(a) a,
/* integer statistics for Lustre file records */
enum darshan_lustre_indices
{
LUSTRE_COUNTERS
};
#undef X
/* record structure for the Lustre module. a record is created and stored for
* every file opened that belongs to a Lustre file system. This record includes:
* - a corresponding record identifier (created by hashing the file path)
* - the rank of the process which opened the file (-1 for shared files)
* - integer file I/O statistics (stripe size, width, # of OSTs, etc.)
*/
struct darshan_lustre_record
{
darshan_record_id rec_id;
int64_t rank;
int64_t counters[LUSTRE_NUM_INDICES];
OST_ID ost_ids[1];
};
/*
* helper function to calculate the size of a record
*/
#define LUSTRE_RECORD_SIZE( osts ) ( sizeof(struct darshan_lustre_record) + sizeof(OST_ID) * (osts - 1) )
#endif /* __DARSHAN_LUSTRE_LOG_FORMAT_H */
......@@ -37,6 +37,10 @@ LIBS = -lz @LIBBZ2@
DARSHAN_STATIC_MOD_OBJS = lib/darshan-posix.o lib/darshan-mpiio.o lib/darshan-hdf5.o lib/darshan-pnetcdf.o
DARSHAN_DYNAMIC_MOD_OBJS = lib/darshan-posix.po lib/darshan-mpiio.po lib/darshan-hdf5.po lib/darshan-pnetcdf.po
# TODO: make the lustre module enabled using config options
DARSHAN_STATIC_MOD_OBJS += lib/darshan-lustre.o
DARSHAN_DYNAMIC_MOD_OBJS += lib/darshan-lustre.po
ifdef DARSHAN_USE_BGQ
DARSHAN_STATIC_MOD_OBJS += lib/darshan-bgq.o
DARSHAN_DYNAMIC_MOD_OBJS += lib/darshan-bgq.po
......@@ -50,63 +54,69 @@ lib::
lib/darshan-core-init-finalize.o: lib/darshan-core-init-finalize.c darshan.h darshan-core.h $(DARSHAN_LOG_FORMAT) | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-core-init-finalize.po: lib/darshan-core-init-finalize.c darshan.h darshan-core.h $(DARSHAN_LOG_FORMAT) | lib
lib/darshan-core-init-finalize.po: lib/darshan-core-init-finalize.c darshan.h darshan-dynamic.h darshan-core.h $(DARSHAN_LOG_FORMAT) | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/darshan-core.o: lib/darshan-core.c darshan.h darshan-core.h $(DARSHAN_LOG_FORMAT) | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-core.po: lib/darshan-core.c darshan.h darshan-core.h $(DARSHAN_LOG_FORMAT) | lib
lib/darshan-core.po: lib/darshan-core.c darshan.h darshan-dynamic.h darshan-core.h $(DARSHAN_LOG_FORMAT) | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/darshan-common.o: lib/darshan-common.c darshan.h $(DARSHAN_LOG_FORMAT) | lib
lib/darshan-common.o: lib/darshan-common.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-common.po: lib/darshan-common.c darshan.h $(DARSHAN_LOG_FORMAT) | lib
lib/darshan-common.po: lib/darshan-common.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/darshan-null.o: lib/darshan-null.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-null-log-format.h | lib
lib/darshan-null.o: lib/darshan-null.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-null-log-format.h | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-null.po: lib/darshan-null.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-null-log-format.h | lib
lib/darshan-null.po: lib/darshan-null.c darshan.h darshan-dynamic.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-null-log-format.h | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/darshan-posix.o: lib/darshan-posix.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-posix-log-format.h | lib
lib/darshan-posix.o: lib/darshan-posix.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-posix-log-format.h | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-posix.po: lib/darshan-posix.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-posix-log-format.h | lib
lib/darshan-posix.po: lib/darshan-posix.c darshan.h darshan-dynamic.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-posix-log-format.h | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/darshan-mpiio.o: lib/darshan-mpiio.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
lib/darshan-mpiio.o: lib/darshan-mpiio.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-mpiio.po: lib/darshan-mpiio.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
lib/darshan-mpiio.po: lib/darshan-mpiio.c darshan.h darshan-dynamic.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/darshan-bgq.o: lib/darshan-bgq.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
lib/darshan-bgq.o: lib/darshan-bgq.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-bgq.po: lib/darshan-bgq.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
lib/darshan-bgq.po: lib/darshan-bgq.c darshan.h darshan-dynamic.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-mpiio-log-format.h | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/darshan-hdf5.o: lib/darshan-hdf5.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-hdf5-log-format.h | lib
lib/darshan-hdf5.o: lib/darshan-hdf5.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-hdf5-log-format.h | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-hdf5.po: lib/darshan-hdf5.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-hdf5-log-format.h | lib
lib/darshan-hdf5.po: lib/darshan-hdf5.c darshan.h darshan-dynamic.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-hdf5-log-format.h | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/darshan-hdf5-stubs.o: lib/darshan-hdf5-stubs.c darshan.h $(DARSHAN_LOG_FORMAT) | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-pnetcdf.o: lib/darshan-pnetcdf.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-pnetcdf-log-format.h | lib
lib/darshan-pnetcdf.o: lib/darshan-pnetcdf.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-pnetcdf-log-format.h | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-pnetcdf.po: lib/darshan-pnetcdf.c darshan.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-pnetcdf-log-format.h | lib
lib/darshan-pnetcdf.po: lib/darshan-pnetcdf.c darshan.h darshan-dynamic.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-pnetcdf-log-format.h | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/darshan-pnetcdf-stubs.o: lib/darshan-pnetcdf-stubs.c darshan.h $(DARSHAN_LOG_FORMAT) | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-lustre.o: lib/darshan-lustre.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-lustre-log-format.h | lib
$(CC) $(CFLAGS) -c $< -o $@
lib/darshan-lustre.po: lib/darshan-lustre.c darshan.h darshan-dynamic.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-lustre-log-format.h | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/lookup3.o: lib/lookup3.c
$(CC) $(CFLAGS) -c $< -o $@
......
struct lustre_record_runtime
{
struct darshan_lustre_record *record;
size_t record_size;
UT_hash_handle hlink;
};
struct lustre_runtime
{
int record_count; /* number of records defined */
size_t record_buffer_max; /* size of the allocated buffer pointed to by record_buffer */
size_t record_buffer_used; /* size of the allocated buffer actually used */
void *next_free_record; /* pointer to end of record_buffer */
void *record_buffer; /* buffer in which records are created */
struct lustre_record_runtime *record_runtime_array;
struct lustre_record_runtime *record_runtime_hash;
};
......@@ -73,6 +73,15 @@ typedef void (*darshan_module_shutdown)(
int *mod_buf_sz /* output parameter to save module buffer size */
);
/* stores FS info from statfs calls for a given mount point */
struct darshan_fs_info
{
int fs_type;
int block_size;
int ost_count;
int mdt_count;
};
/*****************************************************
* darshan-core functions exported to darshan modules *
*****************************************************/
......@@ -122,17 +131,18 @@ darshan_record_id darshan_core_gen_record_id(
* Darshan record (e.g., the full file path), which for now is just a
* string. 'mod_id' is the identifier of the calling module. 'rec_len'
* is the size of the record being registered with Darshan. If given,
* 'file_alignment' is a pointer to an integer which on return will
* contain the corresponding file system alignment of the file system
* path 'name' resides on. Returns a pointer to the address the record
* should be written to on success, NULL on failure.
* 'fs_info' is a pointer to a structure containing information on
* the underlying FS this record is associated with (determined by
* matching the file name prefix with Darshan's list of tracked mount
* points). Returns a pointer to the address the record should be
* written to on success, NULL on failure.
*/
void *darshan_core_register_record(
darshan_record_id rec_id,
const char *name,
darshan_module_id mod_id,
int rec_len,
int *file_alignment);
struct darshan_fs_info *fs_info);
/* darshan_core_wtime()
*
......
......@@ -15,6 +15,7 @@
#include "darshan.h"
#include "darshan-core.h"
#include "darshan-dynamic.h"
#ifdef DARSHAN_PRELOAD
......
......@@ -19,6 +19,8 @@
#include <limits.h>
#include <pthread.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
......@@ -32,6 +34,9 @@
#include "darshan-core.h"
#include "darshan-dynamic.h"
/* XXX stick this into autoconf .h */
#include <lustre/lustre_user.h>
extern char* __progname;
extern char* __progname_full;
......@@ -83,9 +88,9 @@ void (*mod_static_init_fns[])(void) =
#define DARSHAN_MAX_MNT_TYPE 32
struct mnt_data
{
int block_size;
char path[DARSHAN_MAX_MNT_PATH];
char type[DARSHAN_MAX_MNT_TYPE];
struct darshan_fs_info fs_info;
};
static struct mnt_data mnt_data_array[DARSHAN_MAX_MNTS];
static int mnt_data_count = 0;
......@@ -99,11 +104,11 @@ static void darshan_log_record_hints_and_ver(
struct darshan_core_runtime* core);
static void darshan_get_exe_and_mounts(
struct darshan_core_runtime *core, int argc, char **argv);
static void darshan_fs_info_from_path(
const char *path, struct darshan_fs_info *fs_info);
static int darshan_add_name_record_ref(
struct darshan_core_runtime *core, darshan_record_id rec_id,
const char *name, darshan_module_id mod_id);
static int darshan_block_size_from_path(
const char *path);
static void darshan_get_user_name(
char *user);
static void darshan_get_logfile_name(
......@@ -919,12 +924,42 @@ static void add_entry(char* buf, int* space_left, struct mntent* entry)
#define LL_SUPER_MAGIC 0x0BD00BD0
#endif
ret = statfs(entry->mnt_dir, &statfsbuf);
mnt_data_array[mnt_data_count].fs_info.fs_type = statfsbuf.f_type;
if(ret == 0 && statfsbuf.f_type != LL_SUPER_MAGIC)
mnt_data_array[mnt_data_count].block_size = statfsbuf.f_bsize;
mnt_data_array[mnt_data_count].fs_info.block_size = statfsbuf.f_bsize;
else if(ret == 0 && statfsbuf.f_type == LL_SUPER_MAGIC)
mnt_data_array[mnt_data_count].block_size = 1024*1024;
mnt_data_array[mnt_data_count].fs_info.block_size = 1024*1024;
else
mnt_data_array[mnt_data_count].block_size = 4096;
mnt_data_array[mnt_data_count].fs_info.block_size = 4096;
/* XXX */
/* attempt to retrieve OST and MDS counts from Lustre */
mnt_data_array[mnt_data_count].fs_info.ost_count = -1;
mnt_data_array[mnt_data_count].fs_info.mdt_count = -1;
if ( statfsbuf.f_type == LL_SUPER_MAGIC )
{
int n_ost, n_mdt;
int ret_ost, ret_mdt;
DIR *mount_dir;
mount_dir = opendir( entry->mnt_dir );
if ( mount_dir )
{
/* n_ost and n_mdt are used for both input and output to ioctl */
n_ost = 0;
n_mdt = 1;
ret_ost = ioctl( dirfd(mount_dir), LL_IOC_GETOBDCOUNT, &n_ost );
ret_mdt = ioctl( dirfd(mount_dir), LL_IOC_GETOBDCOUNT, &n_mdt );
if ( !(ret_ost < 0 || ret_mdt < 0) )
{
mnt_data_array[mnt_data_count].fs_info.ost_count = n_ost;
mnt_data_array[mnt_data_count].fs_info.mdt_count = n_mdt;
}
closedir( mount_dir );
}
}
/* store mount information with the job-level metadata in darshan log */
ret = snprintf(tmp_mnt, 256, "\n%s\t%s",
......@@ -1059,21 +1094,55 @@ static void darshan_get_exe_and_mounts(struct darshan_core_runtime *core,
return;
}
static int darshan_block_size_from_path(const char *path)
static void darshan_fs_info_from_path(const char *path, struct darshan_fs_info *fs_info)
{
int i;
int block_size = -1;
fs_info->fs_type = -1;
fs_info->block_size = -1;
for(i=0; i<mnt_data_count; i++)
{
if(!(strncmp(mnt_data_array[i].path, path, strlen(mnt_data_array[i].path))))
{
block_size = mnt_data_array[i].block_size;
break;;
*fs_info = mnt_data_array[i].fs_info;
return;
}
}
return block_size;
return;
}
static int darshan_add_name_record_ref(struct darshan_core_runtime *core,
darshan_record_id rec_id, const char *name, darshan_module_id mod_id)
{
struct darshan_core_name_record_ref *ref;
int record_size = sizeof(darshan_record_id) + strlen(name) + 1;
if((record_size + core->name_mem_used) > DARSHAN_NAME_RECORD_BUF_SIZE)
return(0);
ref = malloc(sizeof(*ref));
if(!ref)
return(0);
memset(ref, 0, sizeof(*ref));
/* initialize the name record */
ref->name_record = (struct darshan_name_record *)
((char *)core->log_name_p + core->name_mem_used);
memset(ref->name_record, 0, record_size);
ref->name_record->id = rec_id;
strcpy(ref->name_record->name, name);
DARSHAN_MOD_FLAG_SET(ref->mod_flags, mod_id);
/* add the record to the hash table */
HASH_ADD(hlink, core->name_hash, name_record->id,
sizeof(darshan_record_id), ref);
core->name_mem_used += record_size;
#ifdef __DARSHAN_ENABLE_MMAP_LOGS
core->log_hdr_p->name_map.len += record_size;
#endif
return(1);
}
static void darshan_get_user_name(char *cuser)
......@@ -1239,39 +1308,6 @@ static void darshan_get_logfile_name(char* logfile_name, int jobid, struct tm* s
return;
}
static int darshan_add_name_record_ref(struct darshan_core_runtime *core,
darshan_record_id rec_id, const char *name, darshan_module_id mod_id)
{
struct darshan_core_name_record_ref *ref;
int record_size = sizeof(darshan_record_id) + strlen(name) + 1;
if((record_size + core->name_mem_used) > DARSHAN_NAME_RECORD_BUF_SIZE)
return(0);
ref = malloc(sizeof(*ref));
if(!ref)
return(0);
memset(ref, 0, sizeof(*ref));
/* initialize the name record */
ref->name_record = (struct darshan_name_record *)
((char *)core->log_name_p + core->name_mem_used);
memset(ref->name_record, 0, record_size);
ref->name_record->id = rec_id;
strcpy(ref->name_record->name, name);
DARSHAN_MOD_FLAG_SET(ref->mod_flags, mod_id);
/* add the record to the hash table */
HASH_ADD(hlink, core->name_hash, name_record->id,
sizeof(darshan_record_id), ref);
core->name_mem_used += record_size;
#ifdef __DARSHAN_ENABLE_MMAP_LOGS
core->log_hdr_p->name_map.len += record_size;
#endif
return(1);
}
static void darshan_get_shared_records(struct darshan_core_runtime *core,
darshan_record_id **shared_recs, int *shared_rec_cnt)
{
......@@ -1889,7 +1925,7 @@ void *darshan_core_register_record(
const char *name,
darshan_module_id mod_id,
int rec_len,
int *file_alignment)
struct darshan_fs_info *fs_info)
{
struct darshan_core_name_record_ref *ref;
void *rec_buf;
......@@ -1942,8 +1978,8 @@ void *darshan_core_register_record(
#endif
DARSHAN_CORE_UNLOCK();
if(file_alignment)
*file_alignment = darshan_block_size_from_path(name);
if(fs_info)
darshan_fs_info_from_path(name, fs_info);
return(rec_buf);;
}
......
......@@ -4,6 +4,9 @@
*
*/
#define _XOPEN_SOURCE 500
#define _GNU_SOURCE
#include "darshan-runtime-config.h"
#include <stdio.h>
#include <unistd.h>
......@@ -16,7 +19,6 @@
#include <errno.h>
#include <search.h>
#include <assert.h>
#define __USE_GNU
#include <pthread.h>
#include "darshan.h"
......
This diff is collapsed.
This diff is collapsed.
......@@ -4,6 +4,9 @@
*
*/
#define _XOPEN_SOURCE 500
#define _GNU_SOURCE
#include "darshan-runtime-config.h"
#include <stdio.h>
#include <unistd.h>
......@@ -16,7 +19,6 @@
#include <errno.h>
#include <search.h>
#include <assert.h>
#define __USE_GNU
#include <pthread.h>
#include "darshan.h"
......
......@@ -37,6 +37,10 @@ typedef int64_t off64_t;
#define aiocb64 aiocb
#endif
#ifndef LL_SUPER_MAGIC
#define LL_SUPER_MAGIC 0x0BD00BD0
#endif
DARSHAN_FORWARD_DECL(open, int, (const char *path, int flags, ...));
DARSHAN_FORWARD_DECL(open64, int, (const char *path, int flags, ...));
DARSHAN_FORWARD_DECL(creat, int, (const char* path, mode_t mode));
......@@ -117,6 +121,7 @@ struct posix_file_record_ref
int access_count;
void *stride_root;
int stride_count;
int fs_type; /* same as darshan_fs_info->fs_type */
struct posix_aio_tracker* aio_list;
};
......@@ -161,6 +166,11 @@ static void posix_shutdown(
MPI_Comm mod_comm, darshan_record_id *shared_recs,
int shared_rec_count, void **posix_buf, int *posix_buf_sz);
/* XXX modules don't expose an API for other modules, so use extern to get
* Lustre instrumentation function
*/
extern void darshan_instrument_lustre_file(const char *filepath, int fd);
static struct posix_runtime *posix_runtime = NULL;
static pthread_mutex_t posix_runtime_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static int instrumentation_disabled = 0;
......@@ -216,6 +226,8 @@ static int darshan_mem_alignment = 1;
DARSHAN_TIMER_INC_NO_OVERLAP(rec_ref->file_rec->fcounters[POSIX_F_META_TIME], \
__tm1, __tm2, rec_ref->last_meta_end); \
darshan_add_record_ref(&(posix_runtime->fd_hash), &__ret, sizeof(int), rec_ref); \
if(rec_ref->fs_type == LL_SUPER_MAGIC) \
darshan_instrument_lustre_file(__path, __ret); \
if(newpath != __path) free(newpath); \
} while(0)
......@@ -1444,7 +1456,7 @@ static struct posix_file_record_ref *posix_track_new_file_record(
{
struct darshan_posix_file *file_rec = NULL;
struct posix_file_record_ref *rec_ref = NULL;
int file_alignment;
struct darshan_fs_info fs_info;
int ret;
rec_ref = malloc(sizeof(*rec_ref));
......@@ -1469,7 +1481,7 @@ static struct posix_file_record_ref *posix_track_new_file_record(
path,
DARSHAN_POSIX_MOD,
sizeof(struct darshan_posix_file),
&file_alignment);
&fs_info);
if(!file_rec)
{
......@@ -1483,8 +1495,9 @@ static struct posix_file_record_ref *posix_track_new_file_record(
file_rec->base_rec.id = rec_id;
file_rec->base_rec.rank = my_rank;
file_rec->counters[POSIX_MEM_ALIGNMENT] = darshan_mem_alignment;
file_rec->counters[POSIX_FILE_ALIGNMENT] = file_alignment;
file_rec->counters[POSIX_FILE_ALIGNMENT] = fs_info.block_size;
rec_ref->file_rec = file_rec;
rec_ref->fs_type = fs_info.fs_type;
posix_runtime->file_rec_count++;
return(rec_ref);
......
/*
* (C) 2012 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*/
/* llapi-perf.c
* Time how long it takes to extract various file data from Lustre via
* ioctl and llapi calls from every process. -i uses ioctl, -a uses the
* Lustre API. This also retains the features of stat-perf.c, which
* times how long it takes to issue a stat64() call to the designated file
* from every process. -f causes it to use fstat64() rather than stat64().
* -l causes it to use lseek(SEEK_END) instead of stat64().
* -c causes it to create the file from scratch rather than operating on an
* existing file. -r issues a realpath() call on the file.
*/
#define _LARGEFILE64_SOURCE
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <mpi.h>
#include <errno.h>
#include <getopt.h>
#include <sys/ioctl.h>
#ifndef NO_LUSTRE
#include <lustre/lustreapi.h>
#endif
static char* opt_file = NULL;
static int opt_create = 0;
static int opt_fstat = 0;
static int opt_lseek = 0;
static int opt_realpath = 0;
static int opt_ioctl = 0;
static int opt_llapi = 0;
static int opt_fpp = 0;
static int rank = -1;
static int parse_args(int argc, char **argv);
static void usage(void);
int main(int argc, char **argv)
{
int fd;
int ret;
double stime, etime, elapsed, slowest;
struct stat64 statbuf;
int nprocs;
off64_t offset, orig_offset;
char* new_path;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
/* parse the command line arguments */
parse_args(argc, argv);
MPI_Barrier(MPI_COMM_WORLD);
/* open specified file */
if(!opt_create)
{
fd = open(opt_file, O_RDWR);
if(fd < 0)
{
perror("open");
exit(1);
}
}
else
{
/* rank 0 create, everyone else open */
if(rank == 0 || opt_fpp)
{
fd = open(opt_file, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
if(fd < 0)
{
perror("open");
exit(1);
}
MPI_Barrier(MPI_COMM_WORLD);
}
else
{
MPI_Barrier(MPI_COMM_WORLD);
fd = open(opt_file, O_RDWR);
if(fd < 0)
{
perror("open");
exit(1);
}
}
}
MPI_Barrier(MPI_COMM_WORLD);
stime = MPI_Wtime();
ret = 0;
if(opt_fstat)
ret = fstat64(fd, &statbuf);
else if(opt_lseek)
{
/* find current position */
orig_offset = lseek64(fd, 0, SEEK_CUR);
if(orig_offset < 0)
ret = -1;
else
{
/* find end of file; this is the size */
offset = lseek64(fd, 0, SEEK_END);
if(offset < 0)
ret = -1;
else
{
/* go back to original position */
offset = lseek64(fd, orig_offset, SEEK_SET);
if(offset < 0)
ret = -1;
}
}
}
else if(opt_realpath)
{
new_path = realpath(opt_file, NULL);
if(!new_path)
ret = -1;
else
free(new_path);
}
else if ( opt_llapi || opt_ioctl )
{
#ifdef NO_LUSTRE
fprintf(stderr, "Not compiled with Lustre support\n");
ret = -1;
#else
struct lov_user_md *lum;
size_t lumsize = sizeof(struct lov_user_md) +
LOV_MAX_STRIPE_COUNT * sizeof(struct lov_user_ost_data);
lum = calloc(1, lumsize);
if (lum == NULL) {
ret = ENOMEM;
fprintf(stderr, "No memory\n");
}
else {
if ( opt_llapi )
{
ret = llapi_file_get_stripe(opt_file, lum);
}
else if ( opt_ioctl )
{
lum->lmm_magic = LOV_USER_MAGIC;
lum->lmm_stripe_count = LOV_MAX_STRIPE_COUNT;
ret = ioctl( fd, LL_IOC_LOV_GETSTRIPE, (void *)lum );
}
#ifdef DEBUG
/* different API/ioctl calls populate only parts of lum */
printf( "stripe_width=%d stripe_size=%d starting_ost=%d\n",
lum->lmm_stripe_count,
lum->lmm_stripe_size,