diff --git a/src/common/slurm_protocol_defs.c b/src/common/slurm_protocol_defs.c index bed46de185a3862344cd14005eccffeddf59bd85..6cb3c0cb6a42fa6dc91dd7f7ab83ea49fe71ec18 100644 --- a/src/common/slurm_protocol_defs.c +++ b/src/common/slurm_protocol_defs.c @@ -75,10 +75,14 @@ void slurm_free_ctl_conf ( slurm_ctl_conf_info_msg_t * build_ptr ) void slurm_free_job_desc_msg ( job_desc_msg_t * msg ) { + int i; + if ( msg ) { - if ( msg->environment ) - xfree ( msg->environment ) ; + for (i = 0; i < msg->env_size; i++) { + if ( msg->environment[i] ) + xfree ( msg->environment[i] ) ; + } if ( msg->features ) xfree ( msg->features ) ; if ( msg->groups ) @@ -366,6 +370,7 @@ void slurm_init_job_desc_msg ( job_desc_msg_t * job_desc_msg ) { job_desc_msg -> contiguous = (uint16_t) SLURM_JOB_DESC_DEFAULT_CONTIGUOUS ; job_desc_msg -> environment = SLURM_JOB_DESC_DEFAULT_ENVIRONMENT ; + job_desc_msg -> env_size = SLURM_JOB_DESC_DEFAULT_ENV_SIZE ; job_desc_msg -> features = SLURM_JOB_DESC_DEFAULT_FEATURES ; job_desc_msg -> groups = SLURM_JOB_DESC_DEFAULT_GROUPS ; /* will be set by api */ job_desc_msg -> job_id = SLURM_JOB_DESC_DEFAULT_JOB_ID ; /* will be set by api */ diff --git a/src/common/slurm_protocol_defs.h b/src/common/slurm_protocol_defs.h index 4d4343bcd4700c63305fb83cd4ab59a147e515f1..f41c54e499aa8f9c8c79fa3ba9e13adcf5b11b78 100644 --- a/src/common/slurm_protocol_defs.h +++ b/src/common/slurm_protocol_defs.h @@ -293,8 +293,9 @@ typedef struct submit_response_msg typedef struct job_desc_msg { /* Job descriptor for submit, allocate, and update requests */ uint16_t contiguous; /* 1 if job requires contiguous nodes, 0 otherwise, * default=0 */ - char *environment; /* environment variables to set for job, + char **environment; /* environment variables to set for job, * name=value pairs, one per line */ + uint16_t env_size; /* element count in environment */ char *features; /* comma separated list of required features, default NONE */ char *groups; /* comma separated list of groups the user can access, * default set output of "/usr/bin/groups" by API, @@ -469,7 +470,8 @@ extern char *job_state_string(uint16_t inx); extern char *node_state_string(uint16_t inx); #define SLURM_JOB_DESC_DEFAULT_CONTIGUOUS NO_VAL -#define SLURM_JOB_DESC_DEFAULT_ENVIRONMENT NULL +#define SLURM_JOB_DESC_DEFAULT_ENVIRONMENT ((char **) NULL) +#define SLURM_JOB_DESC_DEFAULT_ENV_SIZE 0 #define SLURM_JOB_DESC_DEFAULT_FEATURES NULL #define SLURM_JOB_DESC_DEFAULT_GROUPS NULL #define SLURM_JOB_DESC_DEFAULT_JOB_ID NO_VAL diff --git a/src/common/slurm_protocol_pack.c b/src/common/slurm_protocol_pack.c index 8a70b9f562675fc873300a2d9265b9aa18d38f6f..0e24b82830f0f0d2b80a5d781450a8122169428e 100644 --- a/src/common/slurm_protocol_pack.c +++ b/src/common/slurm_protocol_pack.c @@ -914,7 +914,7 @@ void pack_job_desc ( job_desc_msg_t * job_desc_ptr, void ** buf_ptr , int * buff pack32 (job_desc_ptr->priority, buf_ptr, buffer_size); packstr (job_desc_ptr->req_nodes, buf_ptr, buffer_size); - packstr (job_desc_ptr->environment, buf_ptr, buffer_size); + packstring_array (job_desc_ptr->environment, job_desc_ptr->env_size, buf_ptr, buffer_size); packstr (job_desc_ptr->script, buf_ptr, buffer_size); packstr (job_desc_ptr->stderr, buf_ptr, buffer_size); @@ -969,7 +969,7 @@ int unpack_job_desc ( job_desc_msg_t **job_desc_buffer_ptr, void ** buf_ptr , in unpack32 (&job_desc_ptr->priority, buf_ptr, buffer_size); unpackstr_xmalloc (&job_desc_ptr->req_nodes, &uint16_tmp, buf_ptr, buffer_size); - unpackstr_xmalloc (&job_desc_ptr->environment, &uint16_tmp, buf_ptr, buffer_size); + unpackstring_array (&job_desc_ptr->environment, &job_desc_ptr->env_size, buf_ptr, buffer_size); unpackstr_xmalloc (&job_desc_ptr->script, &uint16_tmp, buf_ptr, buffer_size); unpackstr_xmalloc (&job_desc_ptr->stderr, &uint16_tmp, buf_ptr, buffer_size); diff --git a/src/slurmctld/controller.c b/src/slurmctld/controller.c index 6f82b239044573a2cf0084f201c8a6fb1048f43d..c1b7253456da06690294e3b79c3e66176e118f04 100644 --- a/src/slurmctld/controller.c +++ b/src/slurmctld/controller.c @@ -41,6 +41,7 @@ #include <src/common/pack.h> #include <src/common/slurm_protocol_api.h> #include <src/common/macros.h> +#include <src/common/xstring.h> #include <src/slurmctld/slurmctld.h> #define BUF_SIZE 1024 diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c index 4341a8f111510a009220723e1790fea4c2d573d5..9201d8d6c38ef4ad1208e76b3ef795dc4542eece 100644 --- a/src/slurmctld/job_mgr.c +++ b/src/slurmctld/job_mgr.c @@ -78,6 +78,7 @@ int rmdir2 (char * path); int top_priority (struct job_record *job_ptr); int validate_job_desc ( job_desc_msg_t * job_desc_msg , int allocate ) ; int write_data_to_file ( char * file_name, char * data ) ; +int write_data_array_to_file ( char * file_name, char ** data, uint16_t size ) ; #if DEBUG_MODULE /* main is used here for module testing purposes only */ @@ -334,8 +335,15 @@ dump_job_desc(job_desc_msg_t * job_specs) debug3(" script=\"%s\"", job_specs->script); - debug3(" environment=\"%s\"", - job_specs->environment); + if (job_specs->env_size == 1) + debug3(" environment=\"%s\"", job_specs->environment[0]); + else if (job_specs->env_size == 2) + debug3(" environment=%s,%s", + job_specs->environment[0], job_specs->environment[1]); + else if (job_specs->env_size > 2) + debug3(" environment=%s,%s,%s,...", + job_specs->environment[0], job_specs->environment[1], + job_specs->environment[2]); debug3(" stdin=%s stdout=%s stderr=%s work_dir=%s groups=%s", job_specs->stdin, job_specs->stdout, job_specs->stderr, @@ -709,7 +717,7 @@ copy_job_desc_to_file ( job_desc_msg_t * job_desc , uint32_t job_id ) /* Create environment file, and write data to it */ file_name = xstrdup (dir_name); xstrcat (file_name, "/environment"); - error_code = write_data_to_file (file_name, job_desc->environment); + error_code = write_data_array_to_file (file_name, job_desc->environment, job_desc->env_size); xfree (file_name); /* Create script file */ @@ -771,6 +779,40 @@ rmdir2 (char * path) return 0; } +/* Create file with specified name and write the supplied data array to it */ +int +write_data_array_to_file ( char * file_name, char ** data, uint16_t size ) +{ + int fd, i, pos, nwrite; + + if (data == NULL) { + (void) unlink (file_name); + return 0; + } + + fd = creat (file_name, 0600); + if (fd < 0) { + error ("create file %s errno %d", file_name, errno); + return ESLURM_WRITING_TO_FILE; + } + + for (i = 0; i < size; i++) { + nwrite = strlen(data[i]) + 1; + pos = 0; + while (nwrite > 0) { + pos = write (fd, &data[i][pos], nwrite); + if (pos < 0) { + error ("write file %s errno %d", file_name, errno); + return ESLURM_WRITING_TO_FILE; + } + nwrite -= pos; + } + } + + close (fd); + return 0; +} + /* Create file with specified name and write the supplied data to it */ int write_data_to_file ( char * file_name, char * data ) diff --git a/testsuite/slurm_unit/api/manual/submit-tst.c b/testsuite/slurm_unit/api/manual/submit-tst.c index 2098d8343c4de5e0829861d9ac02eeac203c5215..87faa1e46b8ee5c0bf23aee1f00af16086f3ee7d 100644 --- a/testsuite/slurm_unit/api/manual/submit-tst.c +++ b/testsuite/slurm_unit/api/manual/submit-tst.c @@ -13,6 +13,7 @@ main (int argc, char *argv[]) int error_code, i, count; job_desc_msg_t job_mesg; submit_response_msg_t *resp_msg; + char *env[2]; slurm_init_job_desc_msg( &job_mesg ); job_mesg. contiguous = 1; @@ -35,7 +36,10 @@ main (int argc, char *argv[]) job_mesg. stdin = "/tmp/slurm.stdin"; job_mesg. stdout = "/tmp/slurm.stdout"; job_mesg. work_dir = "/tmp\0"; - job_mesg. environment = "SLURM_ENV=looking_good\n"; + job_mesg. env_size = 2; + env[0] = "SLURM_ENV_0=looking_good"; + env[1] = "SLURM_ENV_1=still_good"; + job_mesg. environment = env; error_code = slurm_submit_batch_job( &job_mesg, &resp_msg ); if (error_code) {