Commit c768c10e authored by Shane Snyder's avatar Shane Snyder
Browse files

add support for user specified logfile path

parent f32fc8df
...@@ -414,4 +414,5 @@ behavior at runtime: ...@@ -414,4 +414,5 @@ behavior at runtime:
in which files that were accessed by all ranks are collapsed into a single in which files that were accessed by all ranks are collapsed into a single
cumulative file record at rank 0. This option retains more per-process cumulative file record at rank 0. This option retains more per-process
information at the expense of creating larger log files. information at the expense of creating larger log files.
* DARSHAN_LOGPATH: specifies the path to write Darshan log files to. Note that this directory needs to be formatted using the darshan-mk-log-dirs script.
* DARSHAN_LOGFILE: specifies the path (directory + Darshan log file name) to write the output Darshan log to. This overrides the default Darshan behavior of automatically generating a log file name and adding to a log file directory formatted using darshan-mk-log-dirs script.
...@@ -278,6 +278,7 @@ void darshan_shutdown(int timing_flag) ...@@ -278,6 +278,7 @@ void darshan_shutdown(int timing_flag)
int all_ret = 0; int all_ret = 0;
int local_ret = 0; int local_ret = 0;
MPI_Offset next_offset = 0; MPI_Offset next_offset = 0;
char* user_logfile_name;
char* jobid_str; char* jobid_str;
char* envjobid; char* envjobid;
char* logpath; char* logpath;
...@@ -366,9 +367,6 @@ void darshan_shutdown(int timing_flag) ...@@ -366,9 +367,6 @@ void darshan_shutdown(int timing_flag)
/* construct log file name */ /* construct log file name */
if(rank == 0) if(rank == 0)
{ {
char cuser[L_cuserid] = {0};
struct tm* my_tm;
/* Use CP_JOBID_OVERRIDE for the env var or CP_JOBID */ /* Use CP_JOBID_OVERRIDE for the env var or CP_JOBID */
envjobid = getenv(CP_JOBID_OVERRIDE); envjobid = getenv(CP_JOBID_OVERRIDE);
if (!envjobid) if (!envjobid)
...@@ -376,15 +374,6 @@ void darshan_shutdown(int timing_flag) ...@@ -376,15 +374,6 @@ void darshan_shutdown(int timing_flag)
envjobid = CP_JOBID; envjobid = CP_JOBID;
} }
/* Use CP_LOG_PATH_OVERRIDE for the value or __CP_LOG_PATH */
logpath = getenv(CP_LOG_PATH_OVERRIDE);
if (!logpath)
{
#ifdef __CP_LOG_PATH
logpath = __CP_LOG_PATH;
#endif
}
/* find a job id */ /* find a job id */
jobid_str = getenv(envjobid); jobid_str = getenv(envjobid);
if(jobid_str) if(jobid_str)
...@@ -398,122 +387,150 @@ void darshan_shutdown(int timing_flag) ...@@ -398,122 +387,150 @@ void darshan_shutdown(int timing_flag)
jobid = getpid(); jobid = getpid();
} }
/* break out time into something human readable */ /* add jobid to darshan runtime info */
start_time_tmp += final_job->log_job.start_time; final_job->log_job.jobid = (int64_t)jobid;
my_tm = localtime(&start_time_tmp);
/* if user specifies a logfile name (and path), use that. otherwise automatically generate */
/* get the username for this job. In order we will try each of the user_logfile_name = getenv("DARSHAN_LOGFILE");
* following until one of them succeeds: if(user_logfile_name)
* {
* - cuserid() if(strlen(user_logfile_name) >= PATH_MAX)
* - getenv("LOGNAME") {
* - snprintf(..., geteuid()); logfile_name[0] = '\0';
* fprintf(stderr, "darshan library warning: user given log file path too long\n");
* Note that we do not use getpwuid() because it generally will not }
* work in statically compiled binaries. else
*/ {
strncpy(logfile_name, user_logfile_name, PATH_MAX);
}
}
else
{
char cuser[L_cuserid] = {0};
struct tm* my_tm;
/* Use CP_LOG_PATH_OVERRIDE for the value or __CP_LOG_PATH */
logpath = getenv(CP_LOG_PATH_OVERRIDE);
if (!logpath)
{
#ifdef __CP_LOG_PATH
logpath = __CP_LOG_PATH;
#endif
}
/* break out time into something human readable */
start_time_tmp += final_job->log_job.start_time;
my_tm = localtime(&start_time_tmp);
/* get the username for this job. In order we will try each of the
* following until one of them succeeds:
*
* - cuserid()
* - getenv("LOGNAME")
* - snprintf(..., geteuid());
*
* Note that we do not use getpwuid() because it generally will not
* work in statically compiled binaries.
*/
#ifndef DARSHAN_DISABLE_CUSERID #ifndef DARSHAN_DISABLE_CUSERID
cuserid(cuser); cuserid(cuser);
#endif #endif
/* if cuserid() didn't work, then check the environment */ /* if cuserid() didn't work, then check the environment */
if (strcmp(cuser, "") == 0) if (strcmp(cuser, "") == 0)
{
char* logname_string;
logname_string = getenv("LOGNAME");
if(logname_string)
{ {
strncpy(cuser, logname_string, (L_cuserid-1)); char* logname_string;
} logname_string = getenv("LOGNAME");
if(logname_string)
{
strncpy(cuser, logname_string, (L_cuserid-1));
}
} }
/* if cuserid() and environment both fail, then fall back to uid */ /* if cuserid() and environment both fail, then fall back to uid */
if (strcmp(cuser, "") == 0) if (strcmp(cuser, "") == 0)
{ {
uid_t uid = geteuid(); uid_t uid = geteuid();
snprintf(cuser, sizeof(cuser), "%u", uid); snprintf(cuser, sizeof(cuser), "%u", uid);
} }
/* generate a random number to help differentiate the log */ /* generate a random number to help differentiate the log */
hlevel=DARSHAN_MPI_CALL(PMPI_Wtime)() * 1000000; hlevel=DARSHAN_MPI_CALL(PMPI_Wtime)() * 1000000;
(void) gethostname(hname, sizeof(hname)); (void) gethostname(hname, sizeof(hname));
logmod = darshan_hash((void*)hname,strlen(hname),hlevel); logmod = darshan_hash((void*)hname,strlen(hname),hlevel);
/* see if darshan was configured using the --with-logpath-by-env /* see if darshan was configured using the --with-logpath-by-env
* argument, which allows the user to specify an absolute path to * argument, which allows the user to specify an absolute path to
* place logs via an env variable. * place logs via an env variable.
*/ */
#ifdef __CP_LOG_ENV #ifdef __CP_LOG_ENV
/* just silently skip if the environment variable list is too big */ /* just silently skip if the environment variable list is too big */
if(strlen(__CP_LOG_ENV) < 256) if(strlen(__CP_LOG_ENV) < 256)
{
/* copy env variable list to a temporary buffer */
strcpy(env_check, __CP_LOG_ENV);
/* tokenize the comma-separated list */
env_tok = strtok(env_check, ",");
if(env_tok)
{ {
do /* copy env variable list to a temporary buffer */
strcpy(env_check, __CP_LOG_ENV);
/* tokenize the comma-separated list */
env_tok = strtok(env_check, ",");
if(env_tok)
{ {
/* check each env variable in order */ do
logpath_override = getenv(env_tok);
if(logpath_override)
{ {
/* stop as soon as we find a match */ /* check each env variable in order */
break; logpath_override = getenv(env_tok);
} if(logpath_override)
}while((env_tok = strtok(NULL, ","))); {
/* stop as soon as we find a match */
break;
}
}while((env_tok = strtok(NULL, ",")));
}
} }
}
#endif #endif
if(logpath_override)
if(logpath_override) {
{ ret = snprintf(logfile_name, PATH_MAX,
ret = snprintf(logfile_name, PATH_MAX, "%s/%s_%s_id%d_%d-%d-%d-%" PRIu64 ".darshan_partial",
"%s/%s_%s_id%d_%d-%d-%d-%" PRIu64 ".darshan_partial", logpath_override,
logpath_override, cuser, __progname, jobid,
cuser, __progname, jobid, (my_tm->tm_mon+1),
(my_tm->tm_mon+1),
my_tm->tm_mday, my_tm->tm_mday,
(my_tm->tm_hour*60*60 + my_tm->tm_min*60 + my_tm->tm_sec), (my_tm->tm_hour*60*60 + my_tm->tm_min*60 + my_tm->tm_sec),
logmod); logmod);
if(ret == (PATH_MAX-1)) if(ret == (PATH_MAX-1))
{
/* file name was too big; squish it down */
snprintf(logfile_name, PATH_MAX,
"%s/id%d.darshan_partial",
logpath_override, jobid);
}
}
else if(logpath)
{ {
/* file name was too big; squish it down */ ret = snprintf(logfile_name, PATH_MAX,
snprintf(logfile_name, PATH_MAX, "%s/%d/%d/%d/%s_%s_id%d_%d-%d-%d-%" PRIu64 ".darshan_partial",
"%s/id%d.darshan_partial", logpath, (my_tm->tm_year+1900),
logpath_override, jobid); (my_tm->tm_mon+1), my_tm->tm_mday,
cuser, __progname, jobid,
(my_tm->tm_mon+1),
my_tm->tm_mday,
(my_tm->tm_hour*60*60 + my_tm->tm_min*60 + my_tm->tm_sec),
logmod);
if(ret == (PATH_MAX-1))
{
/* file name was too big; squish it down */
snprintf(logfile_name, PATH_MAX,
"%s/id%d.darshan_partial",
logpath, jobid);
}
} }
} else
else if(logpath)
{
ret = snprintf(logfile_name, PATH_MAX,
"%s/%d/%d/%d/%s_%s_id%d_%d-%d-%d-%" PRIu64 ".darshan_partial",
logpath, (my_tm->tm_year+1900),
(my_tm->tm_mon+1), my_tm->tm_mday,
cuser, __progname, jobid,
(my_tm->tm_mon+1),
my_tm->tm_mday,
(my_tm->tm_hour*60*60 + my_tm->tm_min*60 + my_tm->tm_sec),
logmod);
if(ret == (PATH_MAX-1))
{ {
/* file name was too big; squish it down */ logfile_name[0] = '\0';
snprintf(logfile_name, PATH_MAX,
"%s/id%d.darshan_partial",
logpath, jobid);
} }
} }
else
{
logfile_name[0] = '\0';
}
/* add jobid */
final_job->log_job.jobid = (int64_t)jobid;
} }
/* broadcast log file name */ /* broadcast log file name */
...@@ -525,7 +542,7 @@ void darshan_shutdown(int timing_flag) ...@@ -525,7 +542,7 @@ void darshan_shutdown(int timing_flag)
{ {
/* failed to generate log file name */ /* failed to generate log file name */
darshan_finalize(final_job); darshan_finalize(final_job);
return; return;
} }
final_job->log_job.end_time = time(NULL); final_job->log_job.end_time = time(NULL);
...@@ -609,6 +626,15 @@ void darshan_shutdown(int timing_flag) ...@@ -609,6 +626,15 @@ void darshan_shutdown(int timing_flag)
*/ */
unlink(logfile_name); unlink(logfile_name);
} }
else if (user_logfile_name)
{
/* we do not need to rename file, just change the permissions */
#ifdef __CP_GROUP_READABLE_LOGS
chmod(user_logfile_name, (S_IRUSR|S_IRGRP));
#else
chmod(user_logfile_name, (S_IRUSR));
#endif
}
else else
{ {
/* rename from *.darshan_partial to *-<logwritetime>.darshan.gz, /* rename from *.darshan_partial to *-<logwritetime>.darshan.gz,
......
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