diff --git a/NEWS b/NEWS index eaafb996fbbef45ed0e214bc9245d852bf955781..ac45ce2adb508b887f36245cdbbcfd85e158bbd6 100644 --- a/NEWS +++ b/NEWS @@ -143,6 +143,8 @@ documents those changes that are of interest to users and admins. record error when "*" is used at the end of the file for the task ID. -- Let operators see reservation data even if "PrivateData=reservations" flag is set in slurm.conf. Patch from Don Albert, Bull. + -- Added new sbatch option "--export-file" as needed for latest version of + Moab. Patch from Phil Eckert, LLNL. * Changes in SLURM 2.3.2 ======================== diff --git a/doc/html/team.shtml b/doc/html/team.shtml index 49a347a47f3db858a25ce67800669cacb429e86e..f9151f79d87104b2a01b7635af66ac5b3793e260 100644 --- a/doc/html/team.shtml +++ b/doc/html/team.shtml @@ -27,6 +27,7 @@ organizations. The current SLURM development staff includes: </p> <li>Daniel Christians (HP)</li> <li>Gilles Civario (Bull)</li> <li>Chuck Clouston (Bull)</li> +<li>Phil Eckert (Lawrence Livermore National Laboratory)</li> <li>Yuri D'Elia (Center for Biomedicine, EURAC Research, Italy)</li> <li>Carles Fenoy (Barcelona Supercomputer Center, Spain)</li> <li>Joseph Donaghy (Lawrence Livermore National Laboratory)</li> diff --git a/doc/man/man1/sbatch.1 b/doc/man/man1/sbatch.1 index 6a6c125914d37176024fdbdd76fae46f18d8837e..37b61ceaf1d3cde344feaadd3e6ed717c09b9d37 100644 --- a/doc/man/man1/sbatch.1 +++ b/doc/man/man1/sbatch.1 @@ -397,6 +397,15 @@ specific environment variable names, then the \fB\-\-get\-user\-env\fR option will implicitly be set to load other environment variables based upon the user's configuration on the cluster which executes the job. +.TP +\fB\-\-export\-file\fR=<\filename\fR> +Export environment variables defined in <\filename\fR> to the job's +execution environment. The file contains one or more environemnt +variable definitions of the form NAME=VALUE spearated by a null +character to allow the use of special characters in environment +definitions. The \fB\-\-get\-user\-env\fR option will be ignored if +\-\-export\-file is defined. + .TP \fB\-F\fR, \fB\-\-nodefile\fR=<\fInode file\fR> Much like \-\-nodelist, but the list is contained in a file of name diff --git a/src/common/env.c b/src/common/env.c index fa54d58c384beea55f38307961bc339bac0630b7..0d13b60121acbf2573e29a15bfa184e7b3a394a1 100644 --- a/src/common/env.c +++ b/src/common/env.c @@ -56,6 +56,7 @@ #include "slurm/slurm.h" #include "src/common/log.h" #include "src/common/env.h" +#include "src/common/fd.h" #include "src/common/read_config.h" #include "src/common/xassert.h" #include "src/common/xmalloc.h" @@ -1591,6 +1592,81 @@ static int _bracket_cnt(char *value) return count; } +/* + * Load user environment from a specified file. + * + * This will read in a user specified file, that is invoked + * via the --export-file option in sbatch. This file must + * have NULL separated line. The NULL character is to allow + * special characters in the environment definitons. + * + * (Note: This is being added to a minor release. For the + * next major release, it might be a consideration to merge + * this funcitonality with that of load_env_cache and update + * env_cache_builder to use the NULL character.) + */ +char **env_array_from_file(const char *fname) +{ + char *buf = NULL, *ptr = NULL, *eptr = NULL; + char *line, *value; + char **env = NULL; + char name[256]; + struct stat buffer; + ssize_t n; + int separator = '\0'; + int file_size = 0; + int fd; + + fd = open(fname,O_RDONLY ); + if (fd == -1) { + error("Could not open user environment file at %s", + fname); + return NULL; + } + + /* + * Then read in the user's environment file data. + */ + fstat(fd, &buffer); + file_size = buffer.st_size; + buf = xmalloc(file_size); + if ((n = fd_read_n(fd, buf, file_size)) < 0) { + error("Could not read of environment file at %s", fname); + close (fd); + xfree(buf); + return NULL; + } + close(fd); + + /* + * Parse the buffer into indivudal environment variable names + * and build the environment. + */ + verbose("Getting file of environment variables at %s", fname); + env = env_array_create(); + line = xmalloc(ENV_BUFSIZE); + value = xmalloc(ENV_BUFSIZE); + ptr = buf; + while (ptr) { + memset(line, 0, ENV_BUFSIZE); + eptr = strchr(ptr, separator); + if ((ptr == eptr) || (eptr == NULL)) + break; + strncpy(line, ptr,(eptr - ptr)); + ptr = eptr+1; + if (_env_array_entry_splitter(line, name, sizeof(name), + value, ENV_BUFSIZE) && + (!_discard_env(name, value)) && + (name[0] != ' ')) { + env_array_overwrite(&env, name, value); + } + } + xfree(buf); + xfree(line); + xfree(value); + + return env; +} /* * Load user environment from a cache file located in diff --git a/src/common/env.h b/src/common/env.h index 776e01ae3c5cb80c60c6224ea647ee072afec86b..e2e5478bbf7bb39a4ac0275a5b28a861c7d9b077 100644 --- a/src/common/env.h +++ b/src/common/env.h @@ -251,6 +251,11 @@ int env_array_overwrite_fmt(char ***array_ptr, const char *name, */ void env_array_set_environment(char **env_array); +/* + * load environment from specified file name. + */ +char **env_array_from_file(const char *filename); + /* * Return an array of strings representing the specified user's default * environment variables following a two-prongged approach. diff --git a/src/sbatch/opt.c b/src/sbatch/opt.c index 154e015ff7d625a9f45e7a5cc6e07ee71cf1502b..3ab4147bb332e6b07d937445c07b1a9950246dd6 100644 --- a/src/sbatch/opt.c +++ b/src/sbatch/opt.c @@ -168,6 +168,7 @@ #define LONG_OPT_WAIT_ALL_NODES 0x150 #define LONG_OPT_EXPORT 0x151 #define LONG_OPT_REQ_SWITCH 0x152 +#define LONG_OPT_EXPORT_FILE 0x153 /*---- global variables, defined in opt.h ----*/ opt_t opt; @@ -365,6 +366,7 @@ static void _opt_default() opt.efname = NULL; opt.export_env = NULL; + opt.export_file = NULL; opt.get_user_env_time = -1; opt.get_user_env_mode = -1; opt.acctg_freq = -1; @@ -707,6 +709,7 @@ static struct option long_options[] = { {"cpu_bind", required_argument, 0, LONG_OPT_CPU_BIND}, {"exclusive", no_argument, 0, LONG_OPT_EXCLUSIVE}, {"export", required_argument, 0, LONG_OPT_EXPORT}, + {"export-file", required_argument, 0, LONG_OPT_EXPORT_FILE}, {"get-user-env", optional_argument, 0, LONG_OPT_GET_USER_ENV}, {"gres", required_argument, 0, LONG_OPT_GRES}, {"gid", required_argument, 0, LONG_OPT_GID}, @@ -1638,6 +1641,10 @@ static void _set_options(int argc, char **argv) xfree(opt.export_env); opt.export_env = xstrdup(optarg); break; + case LONG_OPT_EXPORT_FILE: + xfree(opt.export_file); + opt.export_file = xstrdup(optarg); + break; case LONG_OPT_REQ_SWITCH: pos_delimit = strstr(optarg,"@"); if (pos_delimit != NULL) { @@ -2803,7 +2810,7 @@ static void _usage(void) " [--network=type] [--mem-per-cpu=MB] [--qos=qos] [--gres=list]\n" " [--cpu_bind=...] [--mem_bind=...] [--reservation=name]\n" " [--switch=max-switches{@max-time-to-wait}]\n" -" [--export[=names]] executable [args...]\n"); +" [--export[=names]] [--export-file=file] executable [args...]\n"); } static void _help(void) @@ -2822,6 +2829,7 @@ static void _help(void) " -D, --workdir=directory set working directory for batch script\n" " -e, --error=err file for batch script's standard error\n" " --export[=names] specify environment variables to export\n" +" --export-file=file specify environment variables file to export\n" " --get-user-env load environment from local cluster\n" " --gid=group_id group ID to run job as (user root only)\n" " --gres=list required generic resources\n" diff --git a/src/sbatch/opt.h b/src/sbatch/opt.h index 556cae705d1cd5d355cc0432ee7a827343733b34..f61dd1adb55d2a94888bfd1e12f4e7ebbe379b4f 100644 --- a/src/sbatch/opt.h +++ b/src/sbatch/opt.h @@ -163,6 +163,7 @@ typedef struct sbatch_options { int get_user_env_time; /* --get-user-env[=timeout] */ int get_user_env_mode; /* --get-user-env=[S|L] */ char *export_env; /* --export */ + char *export_file; /* --export-file=file */ char *wckey; /* --wckey workload characterization key */ char *reservation; /* --reservation */ int ckpt_interval; /* --checkpoint (int minutes) */ diff --git a/src/sbatch/sbatch.c b/src/sbatch/sbatch.c index 564313fed0baa7506f8802d17f129866157989f4..3f9a9ee09b304083235c1c45ae0836e2a2a9b377 100644 --- a/src/sbatch/sbatch.c +++ b/src/sbatch/sbatch.c @@ -388,7 +388,12 @@ static int _fill_job_desc_from_opts(job_desc_msg_t *desc) desc->warn_time = opt.warn_time; desc->environment = NULL; - if (opt.export_env == NULL) { + if (opt.export_file) { + desc->environment = env_array_from_file(opt.export_file); + if (desc->environment == NULL) + exit(1); + opt.get_user_env_time = -1; + } else if (opt.export_env == NULL) { env_array_merge(&desc->environment, (const char **)environ); } else if (!strcasecmp(opt.export_env, "ALL")) { env_array_merge(&desc->environment, (const char **)environ);