Commit d20ef28f authored by Shane Snyder's avatar Shane Snyder

Merge branch 'fileno-wrapping'

parents 66216227 db253374
......@@ -7,11 +7,15 @@
#define __DARSHAN_POSIX_LOG_FORMAT_H
/* current POSIX log format version */
#define DARSHAN_POSIX_VER 3
#define DARSHAN_POSIX_VER 4
#define POSIX_COUNTERS \
/* count of posix opens */\
X(POSIX_OPENS) \
/* count of number of filenos */\
X(POSIX_FILENOS) \
/* count of number of dups */\
X(POSIX_DUPS) \
/* count of posix reads */\
X(POSIX_READS) \
/* count of posix writes */\
......
......@@ -178,6 +178,14 @@ void *darshan_core_register_record(
int rec_len,
struct darshan_fs_info *fs_info);
/* darshan_core_lookup_record_name()
*
* Looks up the name associated with a given Darshan record ID.
*/
char *darshan_core_lookup_record_name(
darshan_record_id rec_id);
/* darshan_core_wtime()
*
* Returns the elapsed time relative to (roughly) the start of
......
......@@ -2108,6 +2108,21 @@ void *darshan_core_register_record(
return(rec_buf);;
}
char *darshan_core_lookup_record_name(darshan_record_id rec_id)
{
struct darshan_core_name_record_ref *ref;
char *name = NULL;
DARSHAN_CORE_LOCK();
HASH_FIND(hlink, darshan_core->name_hash, &rec_id,
sizeof(darshan_record_id), ref);
if(ref)
name = ref->name_record->name;
DARSHAN_CORE_UNLOCK();
return(name);
}
void darshan_instrument_fs_data(int fs_type, const char *path, int fd)
{
#ifdef DARSHAN_LUSTRE
......
......@@ -43,6 +43,10 @@ DARSHAN_FORWARD_DECL(open64, int, (const char *path, int flags, ...));
DARSHAN_FORWARD_DECL(__open_2, int, (const char *path, int oflag));
DARSHAN_FORWARD_DECL(creat, int, (const char* path, mode_t mode));
DARSHAN_FORWARD_DECL(creat64, int, (const char* path, mode_t mode));
DARSHAN_FORWARD_DECL(dup, int, (int oldfd));
DARSHAN_FORWARD_DECL(dup2, int, (int oldfd, int newfd));
DARSHAN_FORWARD_DECL(dup3, int, (int oldfd, int newfd, int flags));
DARSHAN_FORWARD_DECL(fileno, int, (FILE *stream));
DARSHAN_FORWARD_DECL(mkstemp, int, (char *template));
DARSHAN_FORWARD_DECL(mkostemp, int, (char *template, int flags));
DARSHAN_FORWARD_DECL(mkstemps, int, (char *template, int suffixlen));
......@@ -166,6 +170,9 @@ extern void dxt_posix_write(darshan_record_id rec_id, int64_t offset,
extern void dxt_posix_read(darshan_record_id rec_id, int64_t offset,
int64_t length, double start_time, double end_time);
/* extern function def for querying record name from a STDIO stream */
extern char *darshan_stdio_lookup_record_name(FILE *stream);
static struct posix_runtime *posix_runtime = NULL;
static pthread_mutex_t posix_runtime_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static int my_rank = -1;
......@@ -192,38 +199,49 @@ static int enable_dxt_io_trace = 0;
} while(0)
#define POSIX_RECORD_OPEN(__ret, __path, __mode, __tm1, __tm2) do { \
darshan_record_id rec_id; \
struct posix_file_record_ref *rec_ref; \
char *newpath; \
darshan_record_id __rec_id; \
struct posix_file_record_ref *__rec_ref; \
char *__newpath; \
if(__ret < 0) break; \
newpath = darshan_clean_file_path(__path); \
if(!newpath) newpath = (char *)__path; \
if(darshan_core_excluded_path(newpath)) { \
if(newpath != __path) free(newpath); \
__newpath = darshan_clean_file_path(__path); \
if(!__newpath) __newpath = (char *)__path; \
if(darshan_core_excluded_path(__newpath)) { \
if(__newpath != __path) free(__newpath); \
break; \
} \
rec_id = darshan_core_gen_record_id(newpath); \
rec_ref = darshan_lookup_record_ref(posix_runtime->rec_id_hash, &rec_id, sizeof(darshan_record_id)); \
if(!rec_ref) rec_ref = posix_track_new_file_record(rec_id, newpath); \
if(!rec_ref) { \
if(newpath != __path) free(newpath); \
__rec_id = darshan_core_gen_record_id(__newpath); \
__rec_ref = darshan_lookup_record_ref(posix_runtime->rec_id_hash, &__rec_id, sizeof(darshan_record_id)); \
if(!__rec_ref) __rec_ref = posix_track_new_file_record(__rec_id, __newpath); \
if(!__rec_ref) { \
if(__newpath != __path) free(__newpath); \
break; \
} \
if(__mode) \
rec_ref->file_rec->counters[POSIX_MODE] = __mode; \
rec_ref->offset = 0; \
rec_ref->last_byte_written = 0; \
rec_ref->last_byte_read = 0; \
rec_ref->file_rec->counters[POSIX_OPENS] += 1; \
if(rec_ref->file_rec->fcounters[POSIX_F_OPEN_START_TIMESTAMP] == 0 || \
rec_ref->file_rec->fcounters[POSIX_F_OPEN_START_TIMESTAMP] > __tm1) \
rec_ref->file_rec->fcounters[POSIX_F_OPEN_START_TIMESTAMP] = __tm1; \
rec_ref->file_rec->fcounters[POSIX_F_OPEN_END_TIMESTAMP] = __tm2; \
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); \
darshan_instrument_fs_data(rec_ref->fs_type, newpath, __ret); \
if(newpath != __path) free(newpath); \
_POSIX_RECORD_OPEN(__ret, __rec_ref, __mode, __tm1, __tm2, 1, -1); \
darshan_instrument_fs_data(__rec_ref->fs_type, __newpath, __ret); \
if(__newpath != __path) free(__newpath); \
} while(0)
#define POSIX_RECORD_REFOPEN(__ret, __rec_ref, __tm1, __tm2, __ref_counter) do { \
if(__ret < 0 || !__rec_ref) break; \
_POSIX_RECORD_OPEN(__ret, __rec_ref, 0, __tm1, __tm2, 0, __ref_counter); \
} while(0)
#define _POSIX_RECORD_OPEN(__ret, __rec_ref, __mode, __tm1, __tm2, __reset_flag, __ref_counter) do { \
if(__mode) __rec_ref->file_rec->counters[POSIX_MODE] = __mode; \
if(__reset_flag) { \
__rec_ref->offset = 0; \
__rec_ref->last_byte_written = 0; \
__rec_ref->last_byte_read = 0; \
} \
__rec_ref->file_rec->counters[POSIX_OPENS] += 1; \
if(__ref_counter >= 0) __rec_ref->file_rec->counters[__ref_counter] += 1; \
if(__rec_ref->file_rec->fcounters[POSIX_F_OPEN_START_TIMESTAMP] == 0 || \
__rec_ref->file_rec->fcounters[POSIX_F_OPEN_START_TIMESTAMP] > __tm1) \
__rec_ref->file_rec->fcounters[POSIX_F_OPEN_START_TIMESTAMP] = __tm1; \
__rec_ref->file_rec->fcounters[POSIX_F_OPEN_END_TIMESTAMP] = __tm2; \
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); \
} while(0)
#define POSIX_RECORD_READ(__ret, __fd, __pread_flag, __pread_offset, __aligned, __tm1, __tm2) do { \
......@@ -491,6 +509,111 @@ int DARSHAN_DECL(creat64)(const char* path, mode_t mode)
return(ret);
}
int DARSHAN_DECL(dup)(int oldfd)
{
int ret;
struct posix_file_record_ref *rec_ref;
double tm1, tm2;
MAP_OR_FAIL(dup);
tm1 = darshan_core_wtime();
ret = __real_dup(oldfd);
tm2 = darshan_core_wtime();
if(ret >= 0)
{
POSIX_PRE_RECORD();
rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash,
&oldfd, sizeof(oldfd));
POSIX_RECORD_REFOPEN(ret, rec_ref, tm1, tm2, POSIX_DUPS);
POSIX_POST_RECORD();
}
return(ret);
}
int DARSHAN_DECL(dup2)(int oldfd, int newfd)
{
int ret;
struct posix_file_record_ref *rec_ref;
double tm1, tm2;
MAP_OR_FAIL(dup2);
tm1 = darshan_core_wtime();
ret = __real_dup2(oldfd, newfd);
tm2 = darshan_core_wtime();
if(ret >=0)
{
POSIX_PRE_RECORD();
rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash,
&oldfd, sizeof(oldfd));
POSIX_RECORD_REFOPEN(ret, rec_ref, tm1, tm2, POSIX_DUPS);
POSIX_POST_RECORD();
}
return(ret);
}
int DARSHAN_DECL(dup3)(int oldfd, int newfd, int flags)
{
int ret;
struct posix_file_record_ref *rec_ref;
double tm1, tm2;
MAP_OR_FAIL(dup3);
tm1 = darshan_core_wtime();
ret = __real_dup3(oldfd, newfd, flags);
tm2 = darshan_core_wtime();
if(ret >=0)
{
POSIX_PRE_RECORD();
rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash,
&oldfd, sizeof(oldfd));
POSIX_RECORD_REFOPEN(ret, rec_ref, tm1, tm2, POSIX_DUPS);
POSIX_POST_RECORD();
}
return(ret);
}
int DARSHAN_DECL(fileno)(FILE *stream)
{
int ret;
double tm1, tm2;
darshan_record_id rec_id;
struct posix_file_record_ref *rec_ref;
MAP_OR_FAIL(fileno);
tm1 = darshan_core_wtime();
ret = __real_fileno(stream);
tm2 = darshan_core_wtime();
if(ret >= 0)
{
char *rec_name = darshan_stdio_lookup_record_name(stream);
if(rec_name)
{
rec_id = darshan_core_gen_record_id(rec_name);
POSIX_PRE_RECORD();
rec_ref = darshan_lookup_record_ref(posix_runtime->rec_id_hash,
&rec_id, sizeof(darshan_record_id));
if(!rec_ref)
rec_ref = posix_track_new_file_record(rec_id, rec_name);
POSIX_RECORD_REFOPEN(ret, rec_ref, tm1, tm2, POSIX_FILENOS);
POSIX_POST_RECORD();
}
}
return(ret);
}
int DARSHAN_DECL(mkstemp)(char* template)
{
int ret;
......@@ -1760,6 +1883,24 @@ static void posix_cleanup_runtime()
return;
}
char *darshan_posix_lookup_record_name(int fd)
{
struct posix_file_record_ref *rec_ref;
char *rec_name = NULL;
POSIX_LOCK();
if(posix_runtime)
{
rec_ref = darshan_lookup_record_ref(posix_runtime->fd_hash,
&fd, sizeof(fd));
if(rec_ref)
rec_name = darshan_core_lookup_record_name(rec_ref->file_rec->base_rec.id);
}
POSIX_UNLOCK();
return(rec_name);
}
/* posix module shutdown benchmark routine */
void darshan_posix_shutdown_bench_setup(int test_case)
{
......
......@@ -162,6 +162,16 @@ static struct stdio_file_record_ref *stdio_track_new_file_record(
darshan_record_id rec_id, const char *path);
static void stdio_cleanup_runtime();
/* extern function def for querying record name from a POSIX fd */
extern char *darshan_posix_lookup_record_name(int fd);
/* we need access to fileno (defined in POSIX module) for instrumenting fopen calls */
#ifdef DARSHAN_PRELOAD
extern int (*__real_fileno)(FILE *stream);
#else
extern int __real_fileno(FILE *stream);
#endif
#define STDIO_LOCK() pthread_mutex_lock(&stdio_runtime_mutex)
#define STDIO_UNLOCK() pthread_mutex_unlock(&stdio_runtime_mutex)
......@@ -180,35 +190,46 @@ static void stdio_cleanup_runtime();
} while(0)
#define STDIO_RECORD_OPEN(__ret, __path, __tm1, __tm2) do { \
darshan_record_id rec_id; \
struct stdio_file_record_ref* rec_ref; \
char *newpath; \
darshan_record_id __rec_id; \
struct stdio_file_record_ref *__rec_ref; \
char *__newpath; \
int __fd; \
if(__ret == NULL) break; \
newpath = darshan_clean_file_path(__path); \
if(!newpath) newpath = (char*)__path; \
if(darshan_core_excluded_path(newpath)) { \
if(newpath != (char*)__path) free(newpath); \
MAP_OR_FAIL(fileno); \
if(!__ret || !__path) break; \
__newpath = darshan_clean_file_path(__path); \
if(!__newpath) __newpath = (char*)__path; \
if(darshan_core_excluded_path(__newpath)) { \
if(__newpath != (char*)__path) free(__newpath); \
break; \
} \
rec_id = darshan_core_gen_record_id(newpath); \
rec_ref = darshan_lookup_record_ref(stdio_runtime->rec_id_hash, &rec_id, sizeof(rec_id)); \
if(!rec_ref) rec_ref = stdio_track_new_file_record(rec_id, newpath); \
if(!rec_ref) { \
if(newpath != (char*)__path) free(newpath); \
__rec_id = darshan_core_gen_record_id(__newpath); \
__rec_ref = darshan_lookup_record_ref(stdio_runtime->rec_id_hash, &__rec_id, sizeof(darshan_record_id)); \
if(!__rec_ref) __rec_ref = stdio_track_new_file_record(__rec_id, __newpath); \
if(!__rec_ref) { \
if(__newpath != (char*)__path) free(__newpath); \
break; \
} \
rec_ref->offset = 0; \
rec_ref->file_rec->counters[STDIO_OPENS] += 1; \
if(rec_ref->file_rec->fcounters[STDIO_F_OPEN_START_TIMESTAMP] == 0 || \
rec_ref->file_rec->fcounters[STDIO_F_OPEN_START_TIMESTAMP] > __tm1) \
rec_ref->file_rec->fcounters[STDIO_F_OPEN_START_TIMESTAMP] = __tm1; \
rec_ref->file_rec->fcounters[STDIO_F_OPEN_END_TIMESTAMP] = __tm2; \
DARSHAN_TIMER_INC_NO_OVERLAP(rec_ref->file_rec->fcounters[STDIO_F_META_TIME], __tm1, __tm2, rec_ref->last_meta_end); \
darshan_add_record_ref(&(stdio_runtime->stream_hash), &(__ret), sizeof(__ret), rec_ref); \
__fd = fileno(__ret); \
darshan_instrument_fs_data(rec_ref->fs_type, newpath, __fd); \
if(newpath != (char*)__path) free(newpath); \
_STDIO_RECORD_OPEN(__ret, __rec_ref, __tm1, __tm2, 1, -1); \
__fd = __real_fileno(__ret); \
darshan_instrument_fs_data(__rec_ref->fs_type, __newpath, __fd); \
if(__newpath != (char*)__path) free(__newpath); \
} while(0)
#define STDIO_RECORD_REFOPEN(__ret, __rec_ref, __tm1, __tm2, __ref_counter) do { \
if(!ret || !rec_ref) break; \
_STDIO_RECORD_OPEN(__ret, __rec_ref, __tm1, __tm2, 0, __ref_counter); \
} while(0)
#define _STDIO_RECORD_OPEN(__ret, __rec_ref, __tm1, __tm2, __reset_flag, __ref_counter) do { \
if(__reset_flag) __rec_ref->offset = 0; \
__rec_ref->file_rec->counters[STDIO_OPENS] += 1; \
if(__ref_counter >= 0) __rec_ref->file_rec->counters[__ref_counter] += 1; \
if(__rec_ref->file_rec->fcounters[STDIO_F_OPEN_START_TIMESTAMP] == 0 || \
__rec_ref->file_rec->fcounters[STDIO_F_OPEN_START_TIMESTAMP] > __tm1) \
__rec_ref->file_rec->fcounters[STDIO_F_OPEN_START_TIMESTAMP] = __tm1; \
__rec_ref->file_rec->fcounters[STDIO_F_OPEN_END_TIMESTAMP] = __tm2; \
DARSHAN_TIMER_INC_NO_OVERLAP(__rec_ref->file_rec->fcounters[STDIO_F_META_TIME], __tm1, __tm2, __rec_ref->last_meta_end); \
darshan_add_record_ref(&(stdio_runtime->stream_hash), &(__ret), sizeof(__ret), __rec_ref); \
} while(0)
......@@ -291,6 +312,8 @@ FILE* DARSHAN_DECL(fdopen)(int fd, const char *mode)
{
FILE* ret;
double tm1, tm2;
darshan_record_id rec_id;
struct stdio_file_record_ref *rec_ref;
MAP_OR_FAIL(fdopen);
......@@ -298,9 +321,23 @@ FILE* DARSHAN_DECL(fdopen)(int fd, const char *mode)
ret = __real_fdopen(fd, mode);
tm2 = darshan_core_wtime();
STDIO_PRE_RECORD();
STDIO_RECORD_OPEN(ret, "UNKNOWN-FDOPEN", tm1, tm2);
STDIO_POST_RECORD();
if(ret)
{
char *rec_name = darshan_posix_lookup_record_name(fd);
if(rec_name)
{
rec_id = darshan_core_gen_record_id(rec_name);
STDIO_PRE_RECORD();
rec_ref = darshan_lookup_record_ref(stdio_runtime->rec_id_hash,
&rec_id, sizeof(darshan_record_id));
if(!rec_ref)
rec_ref = stdio_track_new_file_record(rec_id, rec_name);
STDIO_RECORD_REFOPEN(ret, rec_ref, tm1, tm2, STDIO_FDOPENS);
STDIO_POST_RECORD();
}
}
return(ret);
}
......@@ -949,7 +986,6 @@ int DARSHAN_DECL(fsetpos64)(FILE *stream, const fpos64_t *pos)
return(ret);
}
/**********************************************************
* Internal functions for manipulating STDIO module state *
**********************************************************/
......@@ -1228,18 +1264,26 @@ static void stdio_shutdown(
* logic above has likely broken the mapping to the static array.
* We walk it manually here instead.
*/
darshan_record_id stdin_rec_id = darshan_core_gen_record_id("<STDIN>");
darshan_record_id stdout_rec_id = darshan_core_gen_record_id("<STDOUT>");
darshan_record_id stderr_rec_id = darshan_core_gen_record_id("<STDERR>");
for(i=0; i<stdio_rec_count; i++)
{
if(stdio_rec_buf[i].counters[STDIO_WRITES] == 0 &&
stdio_rec_buf[i].counters[STDIO_READS] == 0)
if((stdio_rec_buf[i].base_rec.id == stdin_rec_id) ||
(stdio_rec_buf[i].base_rec.id == stdout_rec_id) ||
(stdio_rec_buf[i].base_rec.id == stderr_rec_id))
{
if(i != (stdio_rec_count-1))
if(stdio_rec_buf[i].counters[STDIO_WRITES] == 0 &&
stdio_rec_buf[i].counters[STDIO_READS] == 0)
{
memmove(&stdio_rec_buf[i], &stdio_rec_buf[i+1],
(stdio_rec_count-i-1)*sizeof(stdio_rec_buf[i]));
i--;
if(i != (stdio_rec_count-1))
{
memmove(&stdio_rec_buf[i], &stdio_rec_buf[i+1],
(stdio_rec_count-i-1)*sizeof(stdio_rec_buf[i]));
i--;
}
stdio_rec_count--;
}
stdio_rec_count--;
}
}
......@@ -1398,6 +1442,23 @@ static void stdio_shared_record_variance(MPI_Comm mod_comm,
return;
}
char *darshan_stdio_lookup_record_name(FILE *stream)
{
struct stdio_file_record_ref *rec_ref;
char *rec_name = NULL;
STDIO_LOCK();
if(stdio_runtime)
{
rec_ref = darshan_lookup_record_ref(stdio_runtime->stream_hash,
&stream, sizeof(stream));
if(rec_ref)
rec_name = darshan_core_lookup_record_name(rec_ref->file_rec->base_rec.id);
}
STDIO_UNLOCK();
return(rec_name);
}
/*
* Local variables:
......
......@@ -3,6 +3,9 @@
--wrap=__open_2
--wrap=creat
--wrap=creat64
--wrap=dup
--wrap=dup2
--wrap=dup3
--wrap=mkstemp
--wrap=mkostemp
--wrap=mkstemps
......@@ -36,3 +39,4 @@
--wrap=aio_return64
--wrap=lio_listio
--wrap=lio_listio64
--wrap=fileno
......@@ -13,6 +13,8 @@
#define STDIO_COUNTERS \
/* count of fopens */\
X(STDIO_OPENS) \
/* count of fdopens */\
X(STDIO_FDOPENS) \
/* number of reads */ \
X(STDIO_READS) \
/* number of writes */ \
......
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