Commit 26532885 authored by Shane Snyder's avatar Shane Snyder

simplified posix module and added core lookup

parent 29cc3cd6
......@@ -40,9 +40,7 @@ struct darshan_core_job_runtime
struct darshan_core_module *mod_list_head;
char comp_buf[CP_COMP_BUF_SIZE];
int flags;
int file_count;
double wtime_offset;
char* trailing_data;
};
#endif /* __DARSHAN_CORE_H */
......@@ -12,6 +12,7 @@
#include <mpi.h>
#include "darshan-log-format.h"
/* TODO these go where ? */
#define DARSHAN_MPI_CALL(func) func
typedef uint64_t darshan_file_id;
......
......@@ -25,9 +25,6 @@ extern char* __progname_full;
static void darshan_core_initialize(int *argc, char ***argv);
static void darshan_core_shutdown(void);
static char *darshan_get_exe_and_mounts(int rank);
static void darshan_get_exe_and_mounts_root(char* trailing_data, int space_left);
/* internal variables */
static struct darshan_core_job_runtime *darshan_global_job = NULL;
static pthread_mutex_t darshan_mutex = PTHREAD_MUTEX_INITIALIZER;
......@@ -35,19 +32,6 @@ static pthread_mutex_t darshan_mutex = PTHREAD_MUTEX_INITIALIZER;
#define DARSHAN_LOCK() pthread_mutex_lock(&darshan_mutex)
#define DARSHAN_UNLOCK() pthread_mutex_unlock(&darshan_mutex)
#define DARSHAN_MAX_MNTS 64
#define DARSHAN_MAX_MNT_PATH 256
#define DARSHAN_MAX_MNT_TYPE 32
struct mnt_data
{
int64_t hash;
int64_t block_size;
char path[DARSHAN_MAX_MNT_PATH];
char type[DARSHAN_MAX_MNT_TYPE];
};
static struct mnt_data mnt_data_array[DARSHAN_MAX_MNTS];
static int mnt_data_count = 0;
/* intercept MPI initialize and finalize to initialize darshan */
int MPI_Init(int *argc, char ***argv)
{
......@@ -161,11 +145,6 @@ static void darshan_core_initialize(int *argc, char ***argv)
sprintf(&darshan_global_job->exe[truncate_offset], "%s",
truncate_string);
}
/* collect information about command line and
* mounted file systems
*/
darshan_global_job->trailing_data = darshan_get_exe_and_mounts(rank);
}
}
......@@ -196,184 +175,7 @@ static void darshan_core_shutdown()
return;
}
static int mnt_data_cmp(const void* a, const void* b)
{
const struct mnt_data *d_a = (const struct mnt_data*)a;
const struct mnt_data *d_b = (const struct mnt_data*)b;
if(strlen(d_a->path) > strlen(d_b->path))
return(-1);
else if(strlen(d_a->path) < strlen(d_b->path))
return(1);
else
return(0);
}
/* adds an entry to table of mounted file systems */
static void add_entry(char* trailing_data, int* space_left, struct mntent *entry)
{
int ret;
char tmp_mnt[256];
struct statfs statfsbuf;
strncpy(mnt_data_array[mnt_data_count].path, entry->mnt_dir,
DARSHAN_MAX_MNT_PATH-1);
strncpy(mnt_data_array[mnt_data_count].type, entry->mnt_type,
DARSHAN_MAX_MNT_TYPE-1);
mnt_data_array[mnt_data_count].hash =
darshan_hash((void*)mnt_data_array[mnt_data_count].path,
strlen(mnt_data_array[mnt_data_count].path), 0);
/* NOTE: we now try to detect the preferred block size for each file
* system using fstatfs(). On Lustre we assume a size of 1 MiB
* because fstatfs() reports 4 KiB.
*/
#ifndef LL_SUPER_MAGIC
#define LL_SUPER_MAGIC 0x0BD00BD0
#endif
ret = statfs(entry->mnt_dir, &statfsbuf);
if(ret == 0 && statfsbuf.f_type != LL_SUPER_MAGIC)
mnt_data_array[mnt_data_count].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;
else
mnt_data_array[mnt_data_count].block_size = 4096;
/* store mount information for use in header of darshan log */
ret = snprintf(tmp_mnt, 256, "\n%" PRId64 "\t%s\t%s",
mnt_data_array[mnt_data_count].hash,
entry->mnt_type, entry->mnt_dir);
if(ret < 256 && strlen(tmp_mnt) <= (*space_left))
{
strcat(trailing_data, tmp_mnt);
(*space_left) -= strlen(tmp_mnt);
}
mnt_data_count++;
return;
}
/* darshan_get_exe_and_mounts_root()
*
* collects command line and list of mounted file systems into a string that
* will be stored with the job header
*/
static void darshan_get_exe_and_mounts_root(char* trailing_data, int space_left)
{
FILE* tab;
struct mntent *entry;
char* exclude;
int tmp_index = 0;
int skip = 0;
/* skip these fs types */
static char* fs_exclusions[] = {
"tmpfs",
"proc",
"sysfs",
"devpts",
"binfmt_misc",
"fusectl",
"debugfs",
"securityfs",
"nfsd",
"none",
"rpc_pipefs",
"hugetlbfs",
"cgroup",
NULL
};
/* length of exe has already been safety checked in darshan-posix.c */
strcat(trailing_data, darshan_global_job->exe);
space_left = CP_EXE_LEN - strlen(trailing_data);
/* we make two passes through mounted file systems; in the first pass we
* grab any non-nfs mount points, then on the second pass we grab nfs
* mount points
*/
tab = setmntent("/etc/mtab", "r");
if(!tab)
return;
/* loop through list of mounted file systems */
while(mnt_data_count<DARSHAN_MAX_MNTS && (entry = getmntent(tab)) != NULL)
{
/* filter out excluded fs types */
tmp_index = 0;
skip = 0;
while((exclude = fs_exclusions[tmp_index]))
{
if(!(strcmp(exclude, entry->mnt_type)))
{
skip =1;
break;
}
tmp_index++;
}
if(skip || (strcmp(entry->mnt_type, "nfs") == 0))
continue;
add_entry(trailing_data, &space_left, entry);
}
endmntent(tab);
tab = setmntent("/etc/mtab", "r");
if(!tab)
return;
/* loop through list of mounted file systems */
while(mnt_data_count<DARSHAN_MAX_MNTS && (entry = getmntent(tab)) != NULL)
{
if(strcmp(entry->mnt_type, "nfs") != 0)
continue;
add_entry(trailing_data, &space_left, entry);
}
endmntent(tab);
/* Sort mount points in order of longest path to shortest path. This is
* necessary so that if we try to match file paths to mount points later
* we don't match on "/" every time.
*/
qsort(mnt_data_array, mnt_data_count, sizeof(mnt_data_array[0]), mnt_data_cmp);
return;
}
/* darshan_get_exe_and_mounts()
*
* collects command line and list of mounted file systems into a string that
* will be stored with the job header
*/
static char *darshan_get_exe_and_mounts(int rank)
{
char* trailing_data;
int space_left;
space_left = CP_EXE_LEN + 1;
trailing_data = malloc(space_left);
if(!trailing_data)
{
return(NULL);
}
memset(trailing_data, 0, space_left);
if(rank == 0)
{
darshan_get_exe_and_mounts_root(trailing_data, space_left);
}
/* broadcast trailing data to all nodes */
DARSHAN_MPI_CALL(PMPI_Bcast)(trailing_data, space_left, MPI_CHAR, 0,
MPI_COMM_WORLD);
/* broadcast mount count to all nodes */
DARSHAN_MPI_CALL(PMPI_Bcast)(&mnt_data_count, 1, MPI_INT, 0,
MPI_COMM_WORLD);
/* broadcast mount data to all nodes */
DARSHAN_MPI_CALL(PMPI_Bcast)(mnt_data_array,
mnt_data_count*sizeof(mnt_data_array[0]), MPI_BYTE, 0, MPI_COMM_WORLD);
return(trailing_data);
}
/* ********************************************************* */
void darshan_core_register_module(
char *name,
......
......@@ -33,6 +33,8 @@ typedef int64_t off64_t;
#define aiocb64 aiocb
#endif
/* TODO these go where ? */
#define DARSHAN_FORWARD_DECL(name,ret,args) \
extern ret __real_ ## name args;
......@@ -40,6 +42,10 @@ typedef int64_t off64_t;
#define MAP_OR_FAIL(func)
#define POSIX_HASH_BITS 8
#define POSIX_HASH_SIZE (1 << POSIX_HASH_BITS)
#define POSIX_HASH_MASK (POSIX_HASH_SIZE - 1)
/* TODO: where do these file record structs go? (some needed for darshan-util) */
/* TODO: DARSHAN_* OR CP_* */
......@@ -155,6 +161,7 @@ enum f_darshan_posix_indices
struct darshan_posix_file
{
darshan_file_id f_id;
int64_t counters[CP_NUM_INDICES];
double fcounters[CP_F_NUM_INDICES];
};
......@@ -162,16 +169,21 @@ struct darshan_posix_file
struct darshan_posix_runtime_file
{
struct darshan_posix_file file_record;
struct darshan_posix_runtime_file *next_file;
};
struct darshan_posix_runtime
{
struct darshan_posix_file_runtime *file_array;
int file_array_sz;
struct darshan_posix_runtime_file* file_array;
int file_array_size;
int file_count;
struct darshan_posix_runtime_file* file_table[POSIX_HASH_SIZE];
};
static pthread_mutex_t posix_runtime_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static struct darshan_posix_runtime *posix_runtime = NULL;
static int my_rank = -1;
static int darshan_mem_alignment = 1;
/* these are paths that we will not trace */
static char* exclusions[] = {
......@@ -188,7 +200,6 @@ static char* exclusions[] = {
NULL
};
static int darshan_mem_alignment = 1;
DARSHAN_FORWARD_DECL(open, int, (const char *path, int flags, ...));
//DARSHAN_FORWARD_DECL(close, int, (int fd));
......@@ -202,19 +213,6 @@ static void posix_get_output_data(void **buffer, int size);
#define POSIX_LOCK() pthread_mutex_lock(&posix_runtime_mutex)
#define POSIX_UNLOCK() pthread_mutex_unlock(&posix_runtime_mutex)
#ifdef __DARSHAN_STAT_AT_OPEN
#define DARSHAN_STAT_FILE(_f, _p, _r) do { \
if(!DARSHAN_VALUE((_f), DARSHAN_POSIX_STATS) && !DARSHAN_VALUE((_f), DARSHAN_POSIX_OPENS)){ \
if(fstat64(_r, &cp_stat_buf) == 0) { \
DARSHAN_SET(_f, DARSHAN_FILE_ALIGNMENT, cp_stat_buf.st_blksize); \
DARSHAN_SET(_f, DARSHAN_SIZE_AT_OPEN, cp_stat_buf.st_size); \
}\
}\
}while(0)
#else
#define DARSHAN_STAT_FILE(_f, _p, _r) do { }while(0)
#endif
#define POSIX_RECORD_OPEN(__ret, __path, __mode, __stream_flag, __tm1, __tm2) do { \
struct darshan_posix_runtime_file* file; \
char* exclude; \
......@@ -226,9 +224,8 @@ static void posix_get_output_data(void **buffer, int size);
tmp_index++; \
} \
if(exclude) break; \
file = *************darshan_file_by_name_setfd(__path, __ret); \
if(!file_rec) break; \
DARSHAN_STAT_FILE(file, __path, __ret); \
file = darshan_file_by_name(__path, __ret); \
if(!file) break; \
file->log_file->rank = my_rank; \
if(__mode) \
DARSHAN_SET(file, DARSHAN_MODE, __mode); \
......@@ -244,39 +241,6 @@ static void posix_get_output_data(void **buffer, int size);
DARSHAN_F_INC_NO_OVERLAP(file, __tm1, __tm2, file->last_posix_meta_end, DARSHAN_F_POSIX_META_TIME); \
} while (0)
#if 0
int DARSHAN_DECL(close)(int fd)
{
struct darshan_file_runtime* file;
int tmp_fd = fd;
double tm1, tm2;
int ret;
MAP_OR_FAIL(close);
tm1 = darshan_core_wtime();
ret = __real_close(fd);
tm2 = darshan_core_wtime();
POSIX_LOCK();
posix_runtime_initialize();
file = darshan_file_by_fd(tmp_fd);
if(file)
{
file->last_byte_written = 0;
file->last_byte_read = 0;
DARSHAN_F_SET(file, DARSHAN_F_CLOSE_TIMESTAMP, posix_wtime());
DARSHAN_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_meta_end, DARSHAN_F_POSIX_META_TIME);
darshan_file_close_fd(tmp_fd);
}
POSIX_UNLOCK();
return(ret);
}
#endif
int DARSHAN_DECL(open)(const char *path, int flags, ...)
{
int mode = 0;
......@@ -285,7 +249,7 @@ int DARSHAN_DECL(open)(const char *path, int flags, ...)
MAP_OR_FAIL(open);
if (flags & O_CREAT)
if(flags & O_CREAT)
{
va_list arg;
va_start(arg, flags);
......@@ -306,14 +270,47 @@ int DARSHAN_DECL(open)(const char *path, int flags, ...)
POSIX_LOCK();
posix_runtime_initialize();
// POSIX_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
//POSIX_RECORD_OPEN(ret, path, mode, 0, tm1, tm2);
POSIX_UNLOCK();
return(ret);
}
/* ***************************************************** */
#if 0
int DARSHAN_DECL(close)(int fd)
{
struct darshan_file_runtime* file;
int tmp_fd = fd;
double tm1, tm2;
int ret;
MAP_OR_FAIL(close);
tm1 = darshan_core_wtime();
ret = __real_close(fd);
tm2 = darshan_core_wtime();
POSIX_LOCK();
posix_runtime_initialize();
file = darshan_file_by_fd(tmp_fd);
if(file)
{
file->last_byte_written = 0;
file->last_byte_read = 0;
DARSHAN_F_SET(file, DARSHAN_F_CLOSE_TIMESTAMP, posix_wtime());
DARSHAN_F_INC_NO_OVERLAP(file, tm1, tm2, file->last_posix_meta_end, DARSHAN_F_POSIX_META_TIME);
darshan_file_close_fd(tmp_fd);
}
POSIX_UNLOCK();
return(ret);
}
#endif
/* ***************************************************** */
static void posix_runtime_initialize()
{
......@@ -327,15 +324,16 @@ static void posix_runtime_initialize()
.get_output_data = &posix_get_output_data,
};
if (posix_runtime)
if(posix_runtime)
return;
#if 0
/* set the memory alignment according to config or environment variables */
#if (__CP_MEM_ALIGNMENT < 1)
#error Darshan must be configured with a positive value for --with-mem-align
#endif
alignstr = getenv("DARSHAN_MEMALIGN");
if (alignstr)
if(alignstr)
{
ret = sscanf(alignstr, "%d", &tmpval);
/* silently ignore if the env variable is set poorly */
......@@ -350,14 +348,16 @@ static void posix_runtime_initialize()
}
/* avoid floating point errors on faulty input */
if (darshan_mem_alignment < 1)
if(darshan_mem_alignment < 1)
{
darshan_mem_alignment = 1;
}
#endif
posix_runtime = malloc(sizeof(*posix_runtime));
if (!posix_runtime)
if(!posix_runtime)
return;
memset(posix_runtime, 0, sizeof(*posix_runtime));
/* register the posix module with darshan core */
darshan_core_register_module(
......@@ -365,17 +365,20 @@ static void posix_runtime_initialize()
&posix_mod_fns,
&mem_limit);
/* initialize posix runtime variables */
posix_runtime->file_array_size = mem_limit / sizeof(struct darshan_posix_runtime_file);
posix_runtime->file_count = 0;
/* allocate array of runtime file records no larger than the returned mem_limit */
posix_runtime->file_array_sz = mem_limit / sizeof(struct darshan_posix_runtime_file);
posix_runtime->file_array = malloc(sizeof(struct darshan_posix_runtime_file) *
posix_runtime->file_array_sz);
if (!posix_runtime->file_array)
posix_runtime->file_array_size);
if(!posix_runtime->file_array)
{
posix_runtime->file_array_sz = 0;
posix_runtime->file_array_size = 0;
return;
}
memset(posix_runtime->file_array, 0, sizeof(struct darshan_posix_runtime_file) *
posix_runtime->file_array_sz);
posix_runtime->file_array_size);
return;
}
......@@ -384,19 +387,54 @@ static struct darshan_posix_runtime_file* posix_file_by_name(const char *name)
{
struct darshan_posix_runtime_file *tmp_file;
char *newname = NULL;
darshan_file_id tmp_id;
int hash_index;
if (!posix_runtime)
if(!posix_runtime)
return(NULL);
newname = darshan_clean_file_path(name);
if (!newname)
if(!newname)
newname = (char*)name;
if (newname != name)
/* get a unique id for this file from darshan core */
darshan_core_lookup_id(
(void*)newname,
strlen(newname),
1,
&tmp_id);
/* search the hash table for this file record */
hash_index = tmp_id & POSIX_HASH_MASK;
tmp_file = posix_runtime->file_table[hash_index];
while(tmp_file)
{
if(tmp_file->file_record.f_id == tmp_id)
{
if(newname != name)
free(newname);
return(tmp_file);
}
tmp_file = tmp_file->next_file;
}
/* no existing record, assign a new file record from the global array */
tmp_file = &posix_runtime->file_array[posix_runtime->file_count];
tmp_file->file_record.f_id = tmp_id;
posix_runtime->file_count++;
/* put record into hash table, head of list at that index */
tmp_file->next_file = posix_runtime->file_table[hash_index];
posix_runtime->file_table[hash_index] = tmp_file;
if(newname != name)
free(newname);
return(tmp_file);
}
/* ***************************************************** */
static void posix_prepare_for_shutdown()
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment