1 /*****************************************************************************\ 2 * src/common/env.h - environment vector manipulation 3 ***************************************************************************** 4 * Copyright (C) 2002-2006 The Regents of the University of California. 5 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). 6 * Written by Mark Grondona <mgrondona@llnl.gov>. 7 * CODE-OCEC-09-009. All rights reserved. 8 * 9 * This file is part of Slurm, a resource management program. 10 * For details, see <https://slurm.schedmd.com/>. 11 * Please also read the included file: DISCLAIMER. 12 * 13 * Slurm is free software; you can redistribute it and/or modify it under 14 * the terms of the GNU General Public License as published by the Free 15 * Software Foundation; either version 2 of the License, or (at your option) 16 * any later version. 17 * 18 * Slurm is distributed in the hope that it will be useful, but WITHOUT ANY 19 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 20 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 21 * details. 22 * 23 * You should have received a copy of the GNU General Public License along 24 * with Slurm; if not, write to the Free Software Foundation, Inc., 25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 26 \*****************************************************************************/ 27 #ifndef _ENV_H 28 #define _ENV_H 29 30 #include <sys/types.h> 31 #include <unistd.h> 32 #include <sys/utsname.h> 33 34 #include "slurm/slurm.h" 35 #include "src/common/macros.h" 36 #include "src/common/slurm_opt.h" 37 #include "src/common/slurm_protocol_api.h" 38 39 typedef struct env_options { 40 int ntasks; /* --ntasks=n, -n n */ 41 char *task_count; 42 bool ntasks_set; /* true if ntasks explicitly set */ 43 bool cpus_set; /* true if cpus_per_task explicitly set */ 44 task_dist_states_t distribution; /* --distribution=, -m dist */ 45 uint16_t plane_size; /* plane_size for SLURM_DIST_PLANE */ 46 cpu_bind_type_t 47 cpu_bind_type; /* --cpu-bind= */ 48 char *cpu_bind; /* binding map for map/mask_cpu */ 49 uint32_t cpu_freq_min; /* Minimum cpu frequency */ 50 uint32_t cpu_freq_max; /* Maximum cpu frequency */ 51 uint32_t cpu_freq_gov; /* cpu frequency governor */ 52 mem_bind_type_t 53 mem_bind_type; /* --mem-bind= */ 54 char *mem_bind; /* binding map for tasks to memory */ 55 bool overcommit; /* --overcommit, -O */ 56 int slurmd_debug; /* --slurmd-debug, -D */ 57 bool labelio; /* --label-output, -l */ 58 dynamic_plugin_data_t *select_jobinfo; 59 int nhosts; 60 char *nodelist; /* nodelist in string form */ 61 char *partition; /* partition name */ 62 char **env; /* job environment */ 63 uint16_t comm_port; /* srun's communication port */ 64 slurm_addr_t *cli; /* launch node address */ 65 slurm_addr_t *self; 66 char *job_name; /* assigned job name */ 67 int jobid; /* assigned job id */ 68 int stepid; /* assigned step id */ 69 int procid; /* global task id (across nodes) */ 70 int localid; /* local task id (within node) */ 71 int nodeid; 72 int cpus_per_task; /* --cpus-per-task=n, -c n */ 73 int ntasks_per_node; /* --ntasks-per-node=n */ 74 int ntasks_per_socket; /* --ntasks-per-socket=n */ 75 int ntasks_per_core; /* --ntasks-per-core=n */ 76 int cpus_on_node; 77 pid_t task_pid; 78 char *sgtids; /* global ranks array of integers */ 79 uint16_t pty_port; /* used to communicate window size changes */ 80 uint16_t ws_col; /* window size, columns */ 81 uint16_t ws_row; /* window size, row count */ 82 uint16_t restart_cnt; /* count of job restarts */ 83 uint16_t batch_flag; /* 1 if batch: queued job with script */ 84 uint32_t uid; /* user ID */ 85 char *user_name; /* user name */ 86 char *account; /* job's account */ 87 char *qos; /* job's qos */ 88 char *resv_name; /* job's reservation */ 89 } env_t; 90 91 92 /* NOTE: These functions operate on the job's current environment 93 * if env is NULL, otherwise they operate on the argument array */ 94 int envcount (char **env); 95 char * getenvp(char **env, const char *name); 96 int setenvf(char ***envp, const char *name, const char *fmt, ...) 97 __attribute__ ((format (printf, 3, 4))); 98 int setenvfs(const char *fmt, ...); 99 void unsetenvp(char **env, const char *name); 100 101 int setup_env(env_t *env, bool preserve_env); 102 103 /********************************************************************** 104 * Newer environment variable handling scheme 105 **********************************************************************/ 106 /* 107 * Set in "dest" the environment variables relevant to a Slurm job 108 * allocation, overwriting any environment variables of the same name. 109 * If the address pointed to by "dest" is NULL, memory will automatically be 110 * xmalloc'ed. The array is terminated by a NULL pointer, and thus is 111 * suitable for use by execle() and other env_array_* functions. 112 * 113 * dest OUT - array in which to the set environment variables 114 * alloc IN - resource allocation response 115 * desc IN - job allocation request 116 * het_job_offset IN - component offset into hetjob, -1 if not hetjob 117 * 118 * Sets the variables: 119 * SLURM_JOB_ID 120 * SLURM_JOB_NUM_NODES 121 * SLURM_JOB_NODELIST 122 * SLURM_JOB_CPUS_PER_NODE 123 * LOADLBATCH (AIX only) 124 * 125 * Sets OBSOLETE variables: 126 * ? probably only needed for users... 127 */ 128 extern int env_array_for_job(char ***dest, 129 const resource_allocation_response_msg_t *alloc, 130 const job_desc_msg_t *desc, int het_job_offset); 131 132 /* 133 * Set in "dest" the environment variables relevant to a Slurm batch 134 * job allocation, overwriting any environment variables of the same name. 135 * If the address pointed to by "dest" is NULL, memory will automatically be 136 * xmalloc'ed. The array is terminated by a NULL pointer, and thus is 137 * suitable for use by execle() and other env_array_* functions. 138 * 139 * Sets the variables: 140 * SLURM_JOB_ID 141 * SLURM_JOB_NUM_NODES 142 * SLURM_JOB_NODELIST 143 * SLURM_JOB_CPUS_PER_NODE 144 * ENVIRONMENT=BATCH 145 * HOSTNAME 146 * LOADLBATCH (AIX only) 147 * 148 * Sets OBSOLETE variables: 149 * SLURM_JOBID 150 * SLURM_NNODES 151 * SLURM_NODELIST 152 * SLURM_TASKS_PER_NODE <- poorly named, really CPUs per node 153 * ? probably only needed for users... 154 */ 155 extern int env_array_for_batch_job(char ***dest, 156 const batch_job_launch_msg_t *batch, 157 const char* node_name); 158 159 /* 160 * Set in "dest" the environment variables relevant to a Slurm job step, 161 * overwriting any environment variables of the same name. If the address 162 * pointed to by "dest" is NULL, memory will automatically be xmalloc'ed. 163 * The array is terminated by a NULL pointer, and thus is suitable for 164 * use by execle() and other env_array_* functions. If preserve_env is 165 * true, the variables SLURM_NNODES and SLURM_NTASKS remain unchanged. 166 * 167 * Sets variables: 168 * SLURM_STEP_ID 169 * SLURM_STEP_NUM_NODES 170 * SLURM_STEP_NUM_TASKS 171 * SLURM_STEP_TASKS_PER_NODE 172 * SLURM_STEP_LAUNCHER_PORT 173 * SLURM_STEP_LAUNCHER_IPADDR 174 * SLURM_STEP_RESV_PORTS 175 * 176 * Sets OBSOLETE variables: 177 * SLURM_STEPID 178 * SLURM_NNODES 179 * SLURM_NTASKS 180 * SLURM_NODELIST 181 * SLURM_TASKS_PER_NODE 182 * SLURM_SRUN_COMM_HOST 183 * SLURM_SRUN_COMM_PORT 184 * SLURM_LAUNCH_NODE_IPADDR 185 * 186 */ 187 extern void 188 env_array_for_step(char ***dest, 189 const job_step_create_response_msg_t *step, 190 launch_tasks_request_msg_t *launch, 191 uint16_t launcher_port, 192 bool preserve_env); 193 194 /* 195 * Return an empty environment variable array (contains a single 196 * pointer to NULL). 197 */ 198 char **env_array_create(void); 199 200 /* 201 * Unset all of the environment variables in a user's current 202 * environment. 203 */ 204 void env_unset_environment(void); 205 206 /* 207 * Merge all of the environment variables in src_array into the 208 * array dest_array. Any variables already found in dest_array 209 * will be overwritten with the value from src_array. 210 */ 211 void env_array_merge(char ***dest_array, const char **src_array); 212 213 /* 214 * Merge the environment variables in src_array beginning with "SLURM" into the 215 * array dest_array. Any variables already found in dest_array will be 216 * overwritten with the value from src_array. 217 */ 218 void env_array_merge_slurm(char ***dest_array, const char **src_array); 219 220 /* 221 * Copy env_array must be freed by env_array_free 222 */ 223 char **env_array_copy(const char **array); 224 225 /* 226 * Free the memory used by an environment variable array. 227 */ 228 void env_array_free(char **env_array); 229 230 /* 231 * Append a single environment variable to an environment variable array, 232 * if and only if a variable by that name does not already exist in the 233 * array. 234 * 235 * Return 1 on success, and 0 on error. 236 */ 237 int env_array_append(char ***array_ptr, const char *name, 238 const char *value); 239 240 /* 241 * Append a single environment variable to an environment variable array, 242 * if and only if a variable by that name does not already exist in the 243 * array. 244 * 245 * "value_fmt" supports printf-style formatting. 246 * 247 * Return 1 on success, and 0 on error. 248 */ 249 int env_array_append_fmt(char ***array_ptr, const char *name, 250 const char *value_fmt, ...) 251 __attribute__ ((format (printf, 3, 4))); 252 253 /* 254 * Append a single environment variable to an environment variable array 255 * if a variable by that name does not already exist. If a variable 256 * by the same name is found in the array, it is overwritten with the 257 * new value. 258 * 259 * Return 1 on success, and 0 on error. 260 */ 261 int env_array_overwrite(char ***array_ptr, const char *name, 262 const char *value); 263 264 /* 265 * Append a single environment variable to an environment variable array 266 * if a variable by that name does not already exist. If a variable 267 * by the same name is found in the array, it is overwritten with the 268 * new value. The "value_fmt" string may contain printf-style options. 269 * 270 * "value_fmt" supports printf-style formatting. 271 * 272 * Return 1 on success, and 0 on error. 273 */ 274 int env_array_overwrite_fmt(char ***array_ptr, const char *name, 275 const char *value_fmt, ...) 276 __attribute__ ((format (printf, 3, 4))); 277 278 /* 279 * Append a single environment variable to an environment variable array 280 * if a variable by that name does not already exist. If a variable 281 * by the same name is found in the array, it is overwritten with the 282 * new value. The "value_fmt" string may contain printf-style options. 283 * 284 * "value_fmt" supports printf-style formatting. 285 * 286 * Return 1 on success, and 0 on error. 287 */ 288 int env_array_overwrite_het_fmt(char ***array_ptr, const char *name, 289 int het_job_offset, 290 const char *value_fmt, ...) 291 __attribute__ ((format (printf, 4, 5))); 292 293 /* 294 * Set in the running process's environment all of the environment 295 * variables in a supplied environment variable array. 296 */ 297 void env_array_set_environment(char **env_array); 298 299 /* 300 * load environment from specified file name. 301 */ 302 char **env_array_from_file(const char *filename); 303 304 /* 305 * Return an array of strings representing the specified user's default 306 * environment variables following a two-prongged approach. 307 * 1. Execute (more or less): "/bin/su - <username> -c /usr/bin/env" 308 * Depending upon the user's login scripts, this may take a very 309 * long time to complete or possibly never return 310 * 2. Load the user environment from a cache file. This is used 311 * in the event that option 1 times out. This only happens if no_cache isn't 312 * set. If it is set then NULL will be returned if the normal load fails. 313 * 314 * timeout value is in seconds or zero for default (8 secs) 315 * mode is 1 for short ("su <user>"), 2 for long ("su - <user>") 316 * On error, returns NULL. 317 * 318 * NOTE: The calling process must have an effective uid of root for 319 * this function to succeed. 320 */ 321 char **env_array_user_default(const char *username, int timeout, int mode, 322 bool no_cache); 323 324 /* 325 * Return a string representation of an array of uint16_t elements. 326 * Each value in the array is printed in decimal notation and elements 327 * are separated by a comma. If sequential elements in the array 328 * contain the same value, the value is written out just once followed 329 * by "(xN)", where "N" is the number of times the value is repeated. 330 * 331 * Example: 332 * The array "1, 2, 1, 1, 1, 3, 2" becomes the string "1,2,1(x3),3,2" 333 * 334 * Returns an xmalloc'ed string. Free with xfree(). 335 */ 336 extern char *uint16_array_to_str(int array_len, const uint16_t *array); 337 338 /* 339 * The cpus-per-node representation in Slurm (and perhaps tasks-per-node 340 * in the future) is stored in a compressed format comprised of two 341 * equal-length arrays, and an integer holding the array length. In one 342 * array an element represents a count (number of cpus, number of tasks, 343 * etc.), and the corresponding element in the other array contains the 344 * number of times the count is repeated sequentially in the uncompressed 345 * something-per-node array. 346 * 347 * This function returns the string representation of the compressed 348 * array. Free with xfree(). 349 */ 350 char *uint32_compressed_to_str(uint32_t array_len, 351 const uint16_t *array, 352 const uint32_t *array_reps); 353 354 /* 355 * Set TRES related env vars. Set here rather than env_array_for_job() since 356 * we don't have array of opt values and the raw values are not stored in the 357 * job_desc_msg_t structure (only the strings with possibly combined TRES) 358 * 359 * opt IN - options set by command parsing 360 * dest IN/OUT - location to write environment variables 361 * het_job_offset IN - component offset into hetjob, -1 if not hetjob 362 */ 363 extern void set_env_from_opts(slurm_opt_t *opt, char ***dest, 364 int het_job_offset); 365 366 /* 367 * Parse token's skipping nested commas. 368 * 369 * Similar to strtok_r but handles nested commas. 370 * 371 * e.g. FOO='a,b,c',BAR='d,e,f' 372 */ 373 extern char *find_quote_token(char *tmp, char *sep, char **last); 374 375 #endif 376