/* * Copyright (C) 2015 University of Chicago. * See COPYRIGHT notice in top-level directory. * */ #define _XOPEN_SOURCE 500 #define _GNU_SOURCE #include "darshan-runtime-config.h" #include #ifdef HAVE_MNTENT_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "uthash.h" #include "darshan.h" #include "darshan-core.h" #include "darshan-dynamic.h" extern char* __progname; extern char* __progname_full; /* internal variable delcarations */ static struct darshan_core_runtime *darshan_core = NULL; static pthread_mutex_t darshan_core_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; static int my_rank = -1; static int nprocs = -1; static int darshan_mem_alignment = 1; /* paths prefixed with the following directories are not traced by darshan */ char* darshan_path_exclusions[] = { "/etc/", "/dev/", "/usr/", "/bin/", "/boot/", "/lib/", "/opt/", "/sbin/", "/sys/", "/proc/", NULL }; #define DARSHAN_CORE_LOCK() pthread_mutex_lock(&darshan_core_mutex) #define DARSHAN_CORE_UNLOCK() pthread_mutex_unlock(&darshan_core_mutex) /* FS mount information */ #define DARSHAN_MAX_MNTS 64 #define DARSHAN_MAX_MNT_PATH 256 #define DARSHAN_MAX_MNT_TYPE 32 struct mnt_data { int 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; /* prototypes for internal helper functions */ static void darshan_get_logfile_name( char* logfile_name, int jobid, struct tm* start_tm); static void darshan_log_record_hints_and_ver( struct darshan_core_runtime* core); static void darshan_get_exe_and_mounts_root( struct darshan_core_runtime *core, char* trailing_data, int space_left); static char* darshan_get_exe_and_mounts( struct darshan_core_runtime *core); static void darshan_block_size_from_path( const char *path, int *block_size); static void darshan_get_shared_records( struct darshan_core_runtime *core, darshan_record_id *shared_recs); static int darshan_log_open_all( char *logfile_name, MPI_File *log_fh); static int darshan_deflate_buffer( void **pointers, int *lengths, int count, int nocomp_flag, char *comp_buf, int *comp_length); static int darshan_log_write_record_hash( MPI_File log_fh, struct darshan_core_runtime *core, uint64_t *inout_off); static int darshan_log_append_all( MPI_File log_fh, struct darshan_core_runtime *core, void *buf, int count, uint64_t *inout_off, uint64_t *agg_uncomp_sz); static void darshan_core_cleanup( struct darshan_core_runtime* core); /* *********************************** */ void darshan_core_initialize(int argc, char **argv) { int i; int internal_timing_flag = 0; double init_start, init_time, init_max; char *envstr; char* truncate_string = ""; int truncate_offset; int chars_left = 0; int ret; int tmpval; DARSHAN_MPI_CALL(PMPI_Comm_size)(MPI_COMM_WORLD, &nprocs); DARSHAN_MPI_CALL(PMPI_Comm_rank)(MPI_COMM_WORLD, &my_rank); if(getenv("DARSHAN_INTERNAL_TIMING")) internal_timing_flag = 1; if(internal_timing_flag) init_start = DARSHAN_MPI_CALL(PMPI_Wtime)(); /* setup darshan runtime if darshan is enabled and hasn't been initialized already */ if(!getenv("DARSHAN_DISABLE") && !darshan_core) { #if (__CP_MEM_ALIGNMENT < 1) #error Darshan must be configured with a positive value for --with-mem-align #endif envstr = getenv("DARSHAN_MEMALIGN"); if(envstr) { ret = sscanf(envstr, "%d", &tmpval); /* silently ignore if the env variable is set poorly */ if(ret == 1 && tmpval > 0) { darshan_mem_alignment = tmpval; } } else { darshan_mem_alignment = __CP_MEM_ALIGNMENT; } /* avoid floating point errors on faulty input */ if (darshan_mem_alignment < 1) { darshan_mem_alignment = 1; } /* allocate structure to track darshan_core_runtime information */ darshan_core = malloc(sizeof(*darshan_core)); if(darshan_core) { memset(darshan_core, 0, sizeof(*darshan_core)); darshan_core->log_job.uid = getuid(); darshan_core->log_job.start_time = time(NULL); darshan_core->log_job.nprocs = nprocs; darshan_core->wtime_offset = DARSHAN_MPI_CALL(PMPI_Wtime)(); /* record exe and arguments */ for(i=0; iexe); strncat(darshan_core->exe, argv[i], chars_left); if(i < (argc-1)) { chars_left = DARSHAN_EXE_LEN-strlen(darshan_core->exe); strncat(darshan_core->exe, " ", chars_left); } } /* if we don't see any arguments, then use glibc symbol to get * program name at least (this happens in fortran) */ if(argc == 0) { chars_left = DARSHAN_EXE_LEN-strlen(darshan_core->exe); strncat(darshan_core->exe, __progname_full, chars_left); chars_left = DARSHAN_EXE_LEN-strlen(darshan_core->exe); strncat(darshan_core->exe, " ", chars_left); } if(chars_left == 0) { /* we ran out of room; mark that string was truncated */ truncate_offset = DARSHAN_EXE_LEN - strlen(truncate_string); sprintf(&darshan_core->exe[truncate_offset], "%s", truncate_string); } /* collect information about command line and mounted file systems */ darshan_core->trailing_data = darshan_get_exe_and_mounts(darshan_core); } } if(internal_timing_flag) { init_time = DARSHAN_MPI_CALL(PMPI_Wtime)() - init_start; DARSHAN_MPI_CALL(PMPI_Reduce)(&init_time, &init_max, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); if(my_rank == 0) { printf("#darshan:\t\t